/* Dashboard styles. Lifted verbatim from the design prototype's <style> block
   (design/Colengo Watchdog.html), with additions at the end for the states the
   prototype had no need for: loading, fetch failure, and the fixture banner. */
body{margin:0;background:var(--color-bg-surface-subtle);font-family:var(--font-body);color:var(--color-text-primary)}
a{color:var(--color-bg-primary);text-decoration:none}a:hover{color:var(--color-bg-primary-hover);text-decoration:underline}
.wd-bar{position:sticky;top:0;z-index:30;height:64px;display:flex;align-items:center;justify-content:space-between;padding:0 32px;background:var(--color-bg-surface);border-bottom:1px solid var(--color-border-subtle,#E5E5E5)}
.wd-bar-left{display:flex;align-items:center;gap:16px}
.wd-divider{width:1px;height:20px;background:#E5E5E5}
.wd-appname{font-family:var(--font-heading);font-weight:var(--font-weight-bold);font-size:var(--font-size-text-l);letter-spacing:-.3px}
.wd-bar-right{display:flex;align-items:center;gap:16px}
.wd-stamp{display:inline-flex;align-items:center;gap:8px;font-size:var(--font-size-text-s);color:var(--color-text-secondary)}
.wd-dot{width:7px;height:7px;border-radius:999px;background:var(--color-text-success)}
.wd-main{padding:32px;max-width:1880px;margin:0 auto}
.wd-head{display:flex;align-items:flex-end;justify-content:space-between;gap:32px;margin-bottom:24px}
.wd-overline{margin:0 0 6px;font-size:var(--font-size-text-xs);letter-spacing:1px;text-transform:uppercase;font-weight:var(--font-weight-semibold);color:var(--color-bg-primary)}
.wd-title{margin:0;font-family:var(--font-heading);font-weight:var(--font-weight-bold);font-size:var(--font-size-h2);line-height:var(--line-height-h2);letter-spacing:-1px}
.wd-lede{margin:8px 0 0;max-width:660px;font-size:var(--font-size-text-m);line-height:var(--line-height-text-m);color:var(--color-text-secondary);text-wrap:pretty}
.wd-search{display:flex;align-items:center;gap:8px;height:40px;padding:0 12px;background:var(--color-bg-surface);border:1px solid var(--color-border-default);border-radius:var(--radius-md);min-width:260px}
.wd-search:focus-within{border-color:var(--color-border-focus);box-shadow:0 0 0 3px var(--color-border-focus-ring)}
.wd-search input{border:0;outline:0;background:none;font-family:var(--font-body);font-size:var(--font-size-text-m);color:var(--color-text-primary);width:100%}
.wd-metrics{display:flex;gap:24px;margin-bottom:24px;flex-wrap:wrap}
.wd-tablewrap{background:var(--color-bg-surface);border:1px solid #E5E5E5;border-radius:var(--radius-lg);overflow:auto;max-height:calc(100vh - 120px)}
.wd-table{border-collapse:separate;border-spacing:0;width:100%;font-variant-numeric:tabular-nums}
.wd-table th,.wd-table td{white-space:nowrap}
.wd-grouprow th,.wd-subrow th{position:sticky;background:var(--color-bg-surface-subtle);z-index:10}
.wd-grouprow th{top:0;height:36px}
/* 132px, not 112px: the rotated labels are sized by the REAL webfont now that
   Open Sans is installed, and "Cancelled orders" at -50deg needs about 90px of
   vertical extent plus the 10px offset. At 112px it overran the header boundary. */
.wd-subrow th{top:36px;height:132px;vertical-align:bottom}
.wd-group{font-family:var(--font-heading);font-weight:var(--font-weight-bold);font-size:var(--font-size-text-s);letter-spacing:-.2px;color:var(--color-text-primary);border-bottom:1px solid #E5E5E5;border-left:1px solid #E5E5E5;padding:0 12px;text-align:center}
/* The tooltip wraps the label, not the cell, so table layout is untouched. */
.wd-grouplabel{display:inline-block;cursor:help}
.wd-sub{font-size:var(--font-size-text-xs);letter-spacing:.6px;text-transform:uppercase;font-weight:var(--font-weight-semibold);color:var(--color-text-secondary);border-bottom:1px solid #E5E5E5;padding:0;position:relative;min-width:78px;max-width:78px}
.wd-diag{white-space:nowrap}
.wd-groupend{border-right:1px solid #E5E5E5}
/* Column banding for the 48-hour and 7-day groups, so adjacent period groups are
   distinguishable when scanning 15 numeric columns.
   Uses a translucent background-IMAGE rather than background-color: the image
   layers on top of whatever colour the row already has — white, the hover tint, or
   the amber cancel-spike fill — so it never has to win a specificity fight against
   .wd-row:hover or .wd-row--flag. */
.wd-band{background-image:linear-gradient(rgba(35,85,240,.05),rgba(35,85,240,.05))}
.wd-totalrow .wd-band{background-image:linear-gradient(rgba(255,255,255,.07),rgba(255,255,255,.07))}
.wd-sortbtn{all:unset;cursor:pointer;display:inline-flex;align-items:center;gap:4px;font:inherit;letter-spacing:inherit;text-transform:inherit;color:inherit;transition:color var(--motion-duration-fast) var(--motion-easing-standard)}
.wd-sortbtn:hover{color:var(--color-bg-primary)}
.wd-sub .wd-diag{position:absolute;bottom:10px;left:calc(50% - 4px);transform-origin:left bottom;transform:rotate(-50deg);white-space:nowrap}
.wd-caret{color:var(--color-bg-primary)}
.wd-cust{position:sticky;left:0;z-index:12;background:var(--color-bg-surface);text-align:left;padding:10px 16px;font-size:var(--font-size-text-m);font-weight:var(--font-weight-semibold);border-right:1px solid #E5E5E5;border-bottom:1px solid #E5E5E5;min-width:250px;display:table-cell;vertical-align:middle}
.wd-groupcust{z-index:40;background:var(--color-bg-surface-subtle);font-family:var(--font-heading);font-size:var(--font-size-text-s);letter-spacing:-.2px}
/* The Customer header cell spans both header rows (rowSpan=2) and must stick on
   BOTH axes. Its `top` came from `.wd-grouprow th` and its `left` from `.wd-cust`
   — two separate rules — which left it sticking horizontally but scrolling away
   vertically while the period headers stayed put. Stating both offsets on the one
   selector fixes it, and the raised z-index keeps the corner above both the
   sticky column and the sticky header row it overlaps. */
.wd-grouprow th.wd-cust{position:sticky;top:0;left:0;z-index:50}
.wd-cust .ds-badge,.wd-cust span[class*="badge"]{margin-top:4px}
.wd-row td,.wd-row th{border-bottom:1px solid #E5E5E5}
.wd-row:hover td,.wd-row:hover th{background:var(--color-bg-surface-subtle)}
.wd-row--flag th.wd-cust{box-shadow:inset 3px 0 0 var(--color-text-warning)}
.wd-row--flag td,.wd-row--flag th{background:#FEF4E3}
.wd-row--flag:hover td,.wd-row--flag:hover th{background:#FBEBD2}
.wd-cell{text-align:right;padding:9px 12px;line-height:1.15}
.wd-num{display:block;font-size:var(--font-size-text-m);font-weight:var(--font-weight-semibold);color:var(--color-text-primary)}
.wd-cell--zero .wd-num{color:var(--color-text-disabled);font-weight:var(--font-weight-regular)}
.wd-cell--cancel .wd-num{color:var(--color-text-primary)}
.wd-trend{display:block;margin-top:2px;font-size:11px;line-height:14px;color:var(--color-text-disabled)}
.wd-trend--good{color:var(--color-text-success)}
.wd-trend--bad{color:var(--color-text-error)}
.wd-trend--flat{color:var(--color-text-disabled)}
.wd-cardtrend{display:inline-flex;align-items:center;gap:6px}
.wd-controls{display:flex;align-items:center;gap:12px}
.wd-status{all:unset;cursor:pointer;display:inline-flex;align-items:center;gap:8px;height:32px;padding:0 12px;border-radius:999px;border:1px solid #E5E5E5;background:var(--color-bg-surface);font-family:var(--font-body);font-size:var(--font-size-text-s);font-weight:var(--font-weight-semibold);color:var(--color-text-primary);transition:border-color var(--motion-duration-fast) var(--motion-easing-standard)}
.wd-status:hover{border-color:var(--color-border-hover)}
.wd-status--live{background:#EAFBEA;border-color:#C6F0C5}
.wd-status--down{background:#FFECEC;border-color:#FFCFCF}
.wd-status--checking{background:#FEF4E3;border-color:#F7DFB4}
.wd-statusdot{width:8px;height:8px;border-radius:999px;flex:none}
.wd-status--live .wd-statusdot{animation:wd-pulse 2s var(--motion-easing-standard) infinite}
@keyframes wd-pulse{0%,100%{opacity:1}50%{opacity:.35}}
.wd-form{display:flex;flex-direction:column;gap:16px}
.wd-statusrow{display:flex;align-items:center;gap:8px;padding:12px;border:1px solid #E5E5E5;border-radius:var(--radius-md);background:var(--color-bg-surface-subtle);font-size:var(--font-size-text-s)}
.wd-statusrow-label{font-weight:var(--font-weight-semibold)}
.wd-statusrow-meta{color:var(--color-text-secondary)}
.wd-linkbtn{all:unset;cursor:pointer;margin-top:-8px;font-family:var(--font-body);font-size:var(--font-size-text-s);font-weight:var(--font-weight-semibold);color:var(--color-bg-primary)}
.wd-linkbtn:hover{color:var(--color-bg-primary-hover)}
.wd-modalfoot{display:flex;align-items:center;justify-content:space-between;gap:16px;width:100%}
.wd-modalfoot-right{display:flex;align-items:center;gap:12px}
.wd-modalfoot-left{display:flex;align-items:center;gap:4px}
.wd-conactions{display:flex;align-items:center;gap:6px;justify-content:flex-end}
.wd-iconbtn{all:unset;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:var(--radius-md);color:var(--color-icon-default);transition:background var(--motion-duration-fast) var(--motion-easing-standard),color var(--motion-duration-fast) var(--motion-easing-standard)}
.wd-iconbtn:hover{background:#FFECEC;color:var(--color-text-error)}
.wd-row--new td,.wd-row--new th{background:var(--color-bg-primary-subtle)}
.wd-row--new:hover td,.wd-row--new:hover th{background:#DEE6FC}
.wd-custline{display:flex;align-items:center;gap:10px}
.wd-custname{all:unset;cursor:pointer;font-weight:var(--font-weight-semibold);color:var(--color-text-primary);transition:color var(--motion-duration-fast) var(--motion-easing-standard)}
.wd-custname:hover{color:var(--color-bg-primary);text-decoration:underline}
.wd-spark{margin-left:auto;flex:none;opacity:.85}
.wd-sparkempty{display:block;margin-left:auto}
.wd-drawer{display:flex;flex-direction:column;gap:24px;width:100%;max-width:412px;min-width:0;box-sizing:border-box}
.wd-statgrid{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.wd-statblock{display:flex;flex-direction:column;gap:2px;padding:12px;border:1px solid #E5E5E5;border-radius:var(--radius-md);background:var(--color-bg-surface-subtle)}
.wd-statlabel{font-size:var(--font-size-text-xs);letter-spacing:.6px;text-transform:uppercase;font-weight:var(--font-weight-semibold);color:var(--color-text-secondary)}
.wd-statvalue{font-family:var(--font-heading);font-weight:var(--font-weight-bold);font-size:var(--font-size-h4,22px);letter-spacing:-.5px;font-variant-numeric:tabular-nums}
.wd-statsub{font-size:var(--font-size-text-s);color:var(--color-text-secondary)}
.wd-drawersec{display:flex;flex-direction:column;gap:10px}
.wd-drawerh{margin:0;font-family:var(--font-heading);font-weight:var(--font-weight-bold);font-size:var(--font-size-text-m);letter-spacing:-.3px}
.wd-daybars{display:flex;align-items:flex-end;justify-content:space-between;gap:2px;height:76px;padding:0 2px;border-bottom:1px solid #E5E5E5;max-width:412px;box-sizing:border-box}
.wd-daybar{width:9px;flex:none;background:var(--color-bg-primary);opacity:.75;border-radius:2px 2px 0 0}
.wd-daybar:hover{opacity:1}
/* Date axis under the 30-day histogram.
   Geometry MIRRORS .wd-daybars exactly — same flex, same gap, same 9px slots, same
   2px padding — so every label sits on its own bar. Percentage offsets would drift,
   because fixed-width bars under space-between are not at even fractions of the
   width. Labels are day-of-month only; the month and weekday live in the hover. */
/* Wrapper so the section's 10px gap does not land between bars and axis. */
.wd-daywrap{position:relative;max-width:412px}
.wd-dayaxis{display:flex;align-items:flex-start;justify-content:space-between;gap:2px;padding:0 2px;max-width:412px;box-sizing:border-box;height:12px;margin-top:3px}
.wd-dayslot{width:9px;flex:none;position:relative}
.wd-daytick{position:absolute;top:0;left:50%;transform:translateX(-50%);white-space:nowrap;font-size:9px;line-height:10px;color:var(--color-text-disabled);font-variant-numeric:tabular-nums}
.wd-daytick--last{left:auto;right:0;transform:none}

/* Hover tooltip. Replaces the native `title`, which the browser renders under the
   cursor — covering the very bar being pointed at. Overlaid on the same mirrored
   slot geometry as the axis so it tracks its bar exactly, and anchored to the LEFT
   of the bar, flipping right for the first week where there is no room. */
.wd-daytipslots{position:absolute;left:0;right:0;top:0;height:76px;display:flex;align-items:flex-end;justify-content:space-between;gap:2px;padding:0 2px;box-sizing:border-box;pointer-events:none}
.wd-daytip{position:absolute;top:50%;right:calc(100% + 8px);transform:translateY(-50%);white-space:nowrap;background:var(--color-bg-inverse);color:var(--color-text-on-primary);font-size:var(--font-size-text-xs);line-height:16px;padding:3px 8px;border-radius:var(--radius-sm);box-shadow:var(--shadow-md);z-index:5}
.wd-daytip--right{right:auto;left:calc(100% + 8px)}
.wd-daybar--on{opacity:1;background:var(--color-bg-primary-hover)}
.wd-minitable{width:100%;max-width:412px;table-layout:fixed;border-collapse:collapse;font-size:var(--font-size-text-s);font-variant-numeric:tabular-nums}
.wd-minitable th{text-align:right;padding:6px 8px;font-size:var(--font-size-text-xs);letter-spacing:.6px;text-transform:uppercase;color:var(--color-text-secondary);border-bottom:1px solid #E5E5E5}
.wd-minitable th:first-child,.wd-minitable td:first-child{text-align:left;font-weight:var(--font-weight-semibold)}
.wd-minitable td{text-align:right;padding:7px 8px;border-bottom:1px solid #E5E5E5}
.wd-custbadges{display:flex;flex-wrap:wrap;gap:6px;margin-top:4px;padding-left:22px}
.wd-custbadges:empty{display:none}
.wd-feeddot{all:unset;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;border-radius:999px;flex:none}
.wd-feeddot span{width:8px;height:8px;border-radius:999px;display:block;transition:transform var(--motion-duration-fast) var(--motion-easing-standard)}
.wd-feeddot:hover span{transform:scale(1.35)}
.wd-feeddot--live span{box-shadow:0 0 0 3px rgba(40,207,37,.18)}
.wd-feeddot--down span{box-shadow:0 0 0 3px rgba(255,0,0,.14);animation:wd-pulse 1.6s var(--motion-easing-standard) infinite}
.wd-feeddot--none span{box-shadow:0 0 0 3px rgba(153,153,153,.16)}
.wd-row--offline .wd-num{color:var(--color-text-secondary)}
.wd-note{margin:0;font-size:var(--font-size-text-s);color:var(--color-text-secondary)}
.wd-conlist{list-style:none;margin:0;padding:0;max-height:340px;overflow:auto;border:1px solid #E5E5E5;border-radius:var(--radius-md)}
.wd-conrow{display:grid;grid-template-columns:10px 1fr 170px 96px auto;align-items:center;gap:12px;padding:10px 14px;border-bottom:1px solid #E5E5E5;font-size:var(--font-size-text-s)}
.wd-conrow:last-child{border-bottom:0}
.wd-conrow:hover{background:var(--color-bg-surface-subtle)}
.wd-conname{font-weight:var(--font-weight-semibold);display:flex;flex-direction:column;gap:1px;min-width:0}
.wd-condomain{font-weight:var(--font-weight-regular);font-size:var(--font-size-text-xs);color:var(--color-text-secondary);overflow:hidden;text-overflow:ellipsis}
.wd-conkey{color:var(--color-text-secondary);font-variant-numeric:tabular-nums}
.wd-conmeta{color:var(--color-text-secondary)}
.wd-cardtrend .wd-trend{display:inline;margin:0;font-size:var(--font-size-text-s);font-weight:var(--font-weight-semibold)}
/* Two stacked sticky footer rows. The totals row gets an explicit height so the
   median row can sit exactly on top of it — without a known height the offset
   would drift with font metrics, which is how the sticky header broke earlier. */
.wd-totalrow th,.wd-totalrow td{position:sticky;bottom:0;z-index:14;height:44px;background:var(--color-bg-inverse);color:var(--color-text-on-primary);border-top:1px solid #E5E5E5}
/* Median: a light band above the dark totals, so the two read as different kinds
   of summary rather than one block. */
.wd-medianrow th,.wd-medianrow td{position:sticky;bottom:44px;z-index:13;height:38px;background:var(--color-bg-surface-subtle);border-top:1px solid #E5E5E5}
.wd-medianrow th.wd-cust{z-index:15;left:0;font-family:var(--font-heading);font-size:var(--font-size-text-s);letter-spacing:-.2px;cursor:help}
/* No colour here on purpose: the tone classes (.wd-trend--good/--bad/--flat) carry
   the signal, and a colour on this more-specific selector would silently win. */
.wd-medianrow .wd-num{font-weight:var(--font-weight-regular)}
/* Index cells inherit the trend palette so 'below normal cancellations' reads
   green and a spike reads red, matching the arrows in the body rows. The colour
   is the signal here, so it overrides the muted footer grey. */
.wd-medianrow .wd-idx{font-weight:var(--font-weight-semibold)}
/* Bottom-left corner: same two-axis problem as the header corner above. */
.wd-totalrow th.wd-cust{position:sticky;bottom:0;left:0;z-index:16;font-family:var(--font-heading);letter-spacing:-.2px;border-right-color:#333}
.wd-totalrow .wd-num{color:var(--color-text-on-primary)}
.wd-totalrow .wd-groupend{border-right:1px solid #333}
.wd-actcol{border-left:1px solid #E5E5E5}
.wd-foot{margin:16px 0 0;font-size:var(--font-size-text-s);color:var(--color-text-secondary)}
@media(max-width:1180px){.wd-main{padding:20px}.wd-head{flex-direction:column;align-items:stretch}}

/* ---- Additions beyond the prototype ---------------------------------- */

/* Fixture banner. Deliberately loud: nobody should mistake generated numbers
   for a customer's real trade, especially on a deployed review build. */
.wd-mockbar{display:flex;align-items:center;gap:10px;padding:8px 32px;background:#FEF4E3;border-bottom:1px solid #F7DFB4;font-size:var(--font-size-text-s);font-weight:var(--font-weight-semibold);color:#8A5A08}
.wd-mockbar code{background:rgba(138,90,8,.12);padding:1px 5px;border-radius:4px;font-weight:var(--font-weight-regular)}

/* First load. Mirrors the real table's geometry so the page does not jump. */
.wd-skel{display:flex;flex-direction:column;gap:12px}
.wd-skelrow{height:44px;border-radius:var(--radius-md);background:linear-gradient(90deg,#EFEFEF 25%,#F7F7F7 37%,#EFEFEF 63%);background-size:400% 100%;animation:wd-shimmer 1.4s linear infinite}
@keyframes wd-shimmer{0%{background-position:100% 0}100%{background-position:-100% 0}}
.wd-skelmetrics{display:flex;gap:24px;margin-bottom:24px}
.wd-skelcard{flex:1;height:96px;border-radius:var(--radius-lg);background:var(--color-bg-surface);border:1px solid #E5E5E5}

.wd-fail{max-width:560px;margin:64px auto;text-align:center}
.wd-failh{font-family:var(--font-heading);font-weight:var(--font-weight-bold);font-size:var(--font-size-h4);margin:0 0 8px}
.wd-failbody{color:var(--color-text-secondary);margin:0 0 20px}
.wd-faildetail{display:block;margin-top:12px;font-size:var(--font-size-text-s);color:var(--color-text-disabled);word-break:break-word}

/* Shown when the design-system bundle has not been dropped in. */
.wd-nods{max-width:620px;margin:64px auto;padding:24px;border:1px solid var(--color-border-warning);border-radius:var(--radius-lg);background:#FEF4E3;color:#8A5A08}
.wd-nods h2{font-family:var(--font-heading);font-size:var(--font-size-h5);margin:0 0 8px}
.wd-nods code{background:rgba(138,90,8,.12);padding:1px 5px;border-radius:4px}
