3005e57367
One card per timeframe (M5/M15/H1/H4) in a Bootstrap column grid, above a direction board that charts every timeframe's score as a diverging bar. Each card carries its own indicator-vote chart, and the newswire gets a headline-tone bar. Bootstrap Icons and the hand-rolled CSS gauges are gone; dashboard.css is now the token set plus the app-specific pieces only. Chart marks use a diverging pair validated on this surface (#0d9f7a / #e8503a: lightness band, chroma floor, colour-vision separation, contrast). Lighter steps of the same two hues carry the colour where it has to work as text, and direction never travels as colour alone -- an arrow icon and the word ride with it. Behaviour is unchanged: same snapshot.json / news.json contract, the same coordinated refresh loop (boundary poll, 60 s fallback, 15 s retry, in-flight guard, stale-snapshot guard), per-timeframe change detection, modal state preservation, HTML escaping, the news_summary.php contract and the warming / scan-failed / weekend states. Nothing on the signal path is touched, so no book moves. Verified headlessly against a fixture replayed through the real signal code (wide / laptop / tablet / mobile, both dialogs, every degraded state): no console errors, html-validate clean. Suite 553 -- the old static-UI test splits into one that pins the CDN stack and one that pins a card and a chart per timeframe against dashboard_publisher.DASHBOARD_TFS.
176 lines
7.8 KiB
HTML
176 lines
7.8 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" data-bs-theme="dark">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Gold Desk — XAU/USD</title>
|
|
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='7' fill='%23f5b301'/%3E%3C/svg%3E">
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" crossorigin="anonymous">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" crossorigin="anonymous" referrerpolicy="no-referrer">
|
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
|
|
<link rel="stylesheet" href="dashboard.css">
|
|
</head>
|
|
<body>
|
|
|
|
<header class="desk-bar sticky-top">
|
|
<div class="desk-shell d-flex align-items-center flex-wrap gap-3">
|
|
<div class="d-flex align-items-baseline gap-2">
|
|
<i class="fa-solid fa-coins desk-mark" aria-hidden="true"></i>
|
|
<span class="desk-symbol">XAU/USD</span>
|
|
<span class="desk-price num" id="bar-price">—</span>
|
|
</div>
|
|
<nav class="desk-rail" id="bar-rail" aria-label="Jump to a timeframe"></nav>
|
|
<div class="desk-status ms-auto">
|
|
<span id="bar-market"><span class="live-dot"></span>Connecting</span>
|
|
<span class="desk-meta"><i class="fa-solid fa-hourglass-half" aria-hidden="true"></i>
|
|
5-minute close <span class="num" id="bar-cd">--:--</span></span>
|
|
<span class="desk-meta" id="bar-updated">waiting for data</span>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<main class="desk-shell pb-5">
|
|
|
|
<div class="alert alert-warning d-none mt-3" id="banner-closed" role="alert">
|
|
<i class="fa-solid fa-moon me-2" aria-hidden="true"></i>
|
|
Gold is closed for the weekend. The cards below hold Friday's last reading; news and the calendar keep updating.
|
|
</div>
|
|
<div class="alert alert-danger d-none mt-3" id="banner-fail" role="alert"></div>
|
|
<div class="visually-hidden" id="dashboard-live" aria-live="polite"></div>
|
|
|
|
<section class="board mt-3" aria-labelledby="board-heading">
|
|
<div class="row g-0">
|
|
<div class="col-lg-4 board-read">
|
|
<h1 class="board-headline" id="board-heading">Reading the market</h1>
|
|
<p class="board-sub" id="board-sub">Waiting for the first scan to finish.</p>
|
|
<div class="board-news d-none" id="context">
|
|
<p class="context-text" id="ctx-blurb"></p>
|
|
<div class="context-chips" id="ctx-chips"></div>
|
|
</div>
|
|
<div class="board-stats" id="board-stats"></div>
|
|
</div>
|
|
<div class="col-lg-8 board-plot">
|
|
<h2 class="plot-title">Direction by timeframe</h2>
|
|
<div class="chart-wrap chart-direction">
|
|
<canvas id="chart-direction" role="img"
|
|
aria-label="Direction score of each timeframe, from minus 100 selling to plus 100 buying"></canvas>
|
|
</div>
|
|
<p class="plot-note">Bars grow out of the centre line. Right is buying pressure, left is selling
|
|
pressure, and the full scale runs to 100 either way.</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="mt-4" aria-labelledby="tf-heading">
|
|
<div class="sec-head">
|
|
<h2 class="sec-title" id="tf-heading">Four reads on one market</h2>
|
|
<span class="sec-note">Every card is an independent scan. They are allowed to disagree.</span>
|
|
</div>
|
|
<div class="row g-3 row-cols-1 row-cols-md-2 row-cols-xxl-4" id="tf-grid"></div>
|
|
</section>
|
|
|
|
<section class="mt-4" aria-labelledby="fund-heading">
|
|
<div class="sec-head">
|
|
<h2 class="sec-title" id="fund-heading">What else is moving gold</h2>
|
|
<span class="sec-note">Context only. None of it changes a signal.</span>
|
|
</div>
|
|
<div class="row g-3">
|
|
<div class="col-xl-7">
|
|
<div class="card h-100">
|
|
<div class="card-body">
|
|
<div class="card-head">
|
|
<h3 class="card-title"><i class="fa-solid fa-calendar-day" aria-hidden="true"></i>Economic calendar</h3>
|
|
<span class="card-note" id="calendar-note">loading</span>
|
|
<div class="form-check form-switch ms-auto mb-0">
|
|
<input class="form-check-input" type="checkbox" id="hi-only">
|
|
<label class="form-check-label" for="hi-only">High impact only</label>
|
|
</div>
|
|
</div>
|
|
<div class="table-responsive cal-scroll">
|
|
<table class="table table-sm align-middle cal-table">
|
|
<thead>
|
|
<tr>
|
|
<th scope="col">Time</th>
|
|
<th scope="col">Cur</th>
|
|
<th scope="col">Impact</th>
|
|
<th scope="col">Event</th>
|
|
<th scope="col" class="text-end">Forecast</th>
|
|
<th scope="col" class="text-end">Previous</th>
|
|
<th scope="col" class="text-end">Actual</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="cal-body">
|
|
<tr><td colspan="7" class="empty">Loading the calendar</td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-5">
|
|
<div class="card h-100">
|
|
<div class="card-body">
|
|
<div class="card-head">
|
|
<h3 class="card-title"><i class="fa-solid fa-newspaper" aria-hidden="true"></i>Newswire</h3>
|
|
<span class="card-note ms-auto" id="wire-note"></span>
|
|
</div>
|
|
<div id="wire-tone" class="tone d-none">
|
|
<div class="chart-wrap chart-tone">
|
|
<canvas id="chart-tone" role="img" aria-label="Share of headlines leaning bullish, neutral or bearish for gold"></canvas>
|
|
</div>
|
|
<div class="tone-legend" id="tone-legend"></div>
|
|
</div>
|
|
<div id="wire"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<footer class="desk-foot">
|
|
<i class="fa-solid fa-circle-info" aria-hidden="true"></i>
|
|
Every signal is built from closed candles and refreshes when the next candle closes.
|
|
Educational and research use, not financial advice.
|
|
</footer>
|
|
|
|
</main>
|
|
|
|
<div class="modal fade" id="tf-detail" tabindex="-1" aria-labelledby="detail-title">
|
|
<div class="modal-dialog modal-xl modal-dialog-scrollable">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<div>
|
|
<h5 class="modal-title" id="detail-title">Timeframe</h5>
|
|
<div class="modal-sub">
|
|
<span class="num" id="detail-price">—</span>
|
|
<span id="detail-sub"></span>
|
|
</div>
|
|
</div>
|
|
<button id="detail-close" type="button" class="btn-close" aria-label="Close the full analysis"></button>
|
|
</div>
|
|
<div class="modal-body" id="detail-body"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal fade" id="news-detail" tabindex="-1" aria-labelledby="nd-title">
|
|
<div class="modal-dialog modal-lg modal-dialog-scrollable">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="nd-title">News detail</h5>
|
|
<button id="nd-close" type="button" class="btn-close" aria-label="Close the news detail"></button>
|
|
</div>
|
|
<div class="modal-body" id="nd-body"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js" crossorigin="anonymous"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.min.js" crossorigin="anonymous"></script>
|
|
<script src="dashboard.js"></script>
|
|
</body>
|
|
</html>
|