/* EMS Predictive Relocation -- visual system.
 *
 * Token contract follows shadcn/ui semantics (--background, --card, --muted,
 * --primary, --border, --ring) so the two themes are one structure with two
 * value sets. Both themes are defined below; [data-theme] on <html> selects.
 *
 * Semantic colour is load-bearing and is NOT part of the theme swap: STATIC
 * (today's fixed-post dispatch) is always red, DYNAMIC (compliance-table
 * restaging) is always green. Every chart, lane, bar and number obeys that
 * pairing, in both themes. The neutral chrome is grey; exactly one accent
 * (amber) marks interactive/branded surfaces so it never competes with the
 * red/green result colours.
 */

/* ============================================================ dark (default) */
:root,
:root[data-theme="dark"] {
  --background: #0e1013;
  --surface: #15181d;
  --surface-2: #1b1f26;
  --surface-3: #232830;
  --card: #15181d;
  --foreground: #eceef1;
  --muted: #98a0ab;
  --dim: #6b727d;
  --border: #262b33;
  --border-strong: #333a45;

  --primary: #f5a524;
  --primary-fg: #1a1204;
  --primary-soft: rgba(245, 165, 36, 0.14);
  --ring: rgba(245, 165, 36, 0.45);

  --static: #f04438;
  --static-soft: rgba(240, 68, 56, 0.14);
  --dynamic: #17c964;
  --dynamic-soft: rgba(23, 201, 100, 0.14);

  --map-tiles: dark_all;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 4px 16px -6px rgba(0, 0, 0, 0.6);
  --shadow-lg: 0 18px 44px -18px rgba(0, 0, 0, 0.75);
  --scrim: rgba(21, 24, 29, 0.92);
  color-scheme: dark;
}

/* ==================================================================== light */
:root[data-theme="light"] {
  --background: #f6f7f9;
  --surface: #ffffff;
  --surface-2: #f1f3f6;
  --surface-3: #e6e9ee;
  --card: #ffffff;
  --foreground: #14171c;
  --muted: #5b636f;
  --dim: #838b97;
  --border: #e2e6ec;
  --border-strong: #cdd3dc;

  --primary: #b26a00;
  --primary-fg: #ffffff;
  --primary-soft: rgba(178, 106, 0, 0.1);
  --ring: rgba(178, 106, 0, 0.35);

  --static: #d92d20;
  --static-soft: rgba(217, 45, 32, 0.09);
  --dynamic: #067647;
  --dynamic-soft: rgba(6, 118, 71, 0.09);

  --map-tiles: light_all;
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.05);
  --shadow-md: 0 4px 14px -6px rgba(16, 24, 40, 0.12);
  --shadow-lg: 0 18px 40px -18px rgba(16, 24, 40, 0.2);
  --scrim: rgba(255, 255, 255, 0.94);
  color-scheme: light;
}

:root {
  --r: 10px;
  --r-sm: 7px;
  --dock-h: 228px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; height: 100%; overflow: hidden;
  background: var(--background); color: var(--foreground);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 14px; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
.num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1, "cv01" 1; }

/* Icons inherit text colour and optical alignment from their container. */
.ico { display: inline-block; vertical-align: -0.15em; flex-shrink: 0; stroke-width: 2; }
button .ico, .citychip .ico, .tab .ico { vertical-align: -0.18em; }

#app { position: relative; z-index: 1; display: flex; flex-direction: column; height: 100vh; }

/* ------------------------------------------------------------- top bar */
#topbar {
  display: flex; align-items: center; gap: 16px; padding: 0 16px; height: 56px;
  border-bottom: 1px solid var(--border); background: var(--surface);
  flex-shrink: 0; position: relative; z-index: 20;
}
.brand { display: flex; align-items: center; gap: 10px; }
.brand .mark {
  width: 30px; height: 30px; border-radius: 8px; display: grid; place-items: center;
  background: var(--primary); color: var(--primary-fg);
}
.brand h1 {
  font-size: 12px; margin: 0; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
}
.brand .sub { font-size: 11.5px; color: var(--muted); margin-top: 1px; }

.cityswitch { display: flex; gap: 5px; align-items: center; margin-left: 8px; }
.citychip {
  display: flex; align-items: center; gap: 6px; padding: 6px 11px; border-radius: var(--r-sm);
  font-size: 12px; font-weight: 550; cursor: pointer; color: var(--muted);
  border: 1px solid var(--border); background: var(--surface-2); white-space: nowrap;
  transition: color 0.14s, border-color 0.14s, background 0.14s;
}
.citychip:hover { border-color: var(--border-strong); color: var(--foreground); }
.citychip.active {
  color: var(--foreground); border-color: var(--primary); background: var(--primary-soft);
}
.citychip .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: 0.6; }
.citychip.active .dot { background: var(--primary); opacity: 1; }
.citychip.ghost { border-style: dashed; }

.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.tabs {
  display: flex; gap: 2px; background: var(--surface-2); border-radius: var(--r-sm); padding: 3px;
  border: 1px solid var(--border);
}
.tab {
  display: flex; align-items: center; gap: 6px; padding: 6px 12px; font-size: 12px; font-weight: 550;
  border-radius: 5px; cursor: pointer; color: var(--muted); transition: color 0.14s, background 0.14s;
}
.tab:hover { color: var(--foreground); }
.tab.active { background: var(--surface); color: var(--foreground); box-shadow: var(--shadow-sm); }

.icon-btn {
  width: 32px; height: 32px; display: grid; place-items: center; border-radius: var(--r-sm);
  border: 1px solid var(--border); background: var(--surface-2); color: var(--muted);
  cursor: pointer; transition: color 0.14s, border-color 0.14s;
}
.icon-btn:hover { color: var(--foreground); border-color: var(--border-strong); }
:root[data-theme="dark"] .icon-btn .ico-sun { display: block; }
:root[data-theme="dark"] .icon-btn .ico-moon { display: none; }
:root[data-theme="light"] .icon-btn .ico-sun { display: none; }
:root[data-theme="light"] .icon-btn .ico-moon { display: block; }

/* --------------------------------------------------------------- layout */
#body { flex: 1; display: flex; overflow: hidden; min-height: 0; }
.view { display: none; flex: 1; overflow: hidden; min-width: 0; }
.view.active { display: flex; }

.sidebar {
  width: 340px; flex-shrink: 0; background: var(--surface); border-left: 1px solid var(--border);
  padding: 16px; overflow-y: auto; display: flex; flex-direction: column; gap: 11px;
}
/* Overview sidebar is two stacked regions instead of one long scroll, so the
   staging list is always visible rather than buried under the stat cards. */
.sidebar.split { overflow: hidden; }
.sidebar.split .sb-scroll {
  flex: 1 1 0; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 11px;
  margin: 0 -16px; padding: 0 16px 10px;
  /* fade the cut edge so a clipped card reads as "scroll for more" */
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 18px), transparent 100%);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 18px), transparent 100%);
}
.sidebar.split .sb-pinned {
  flex: 0 0 auto; display: flex; flex-direction: column; min-height: 0;
  max-height: 34%; margin: 0 -16px -16px; border-top: 1px solid var(--border);
}
/* The table has a fixed, knowable height (20 rows); the prose above can scroll
   to any size. So the pane takes its content height and the prose absorbs the
   remainder -- that is what lets all 20 rows show when the column can afford
   them, instead of both regions splitting the slack and the table ending one
   row short. min-height keeps it usable on short screens, max-height stops it
   from squeezing the prose to nothing on tall ones. */
.sidebar.split .sb-pinned.zone-pane {
  flex: 0 0 auto; max-height: 72%; min-height: 190px;
}
.sidebar.split .sb-pinned.zone-pane .zone-scroll { flex: 0 1 auto; }
.sidebar.left { border-left: none; border-right: 1px solid var(--border); }
.mapwrap { flex: 1; position: relative; min-width: 0; background: var(--surface-2); }
.leaflet-container { background: var(--surface-2); }
.leaflet-control-attribution { background: var(--scrim) !important; color: var(--dim) !important; }
.leaflet-control-attribution a { color: var(--muted) !important; }
.leaflet-bar a {
  background: var(--surface) !important; color: var(--foreground) !important;
  border-bottom-color: var(--border) !important;
}
.leaflet-bar a:hover { background: var(--surface-2) !important; }
.leaflet-tooltip {
  background: var(--surface) !important; color: var(--foreground) !important;
  border: 1px solid var(--border) !important; box-shadow: var(--shadow-md) !important;
  font-family: inherit !important; font-size: 11px !important;
}
.leaflet-tooltip::before { border-top-color: var(--border) !important; }

/* ---------------------------------------------------------------- cards */
.card {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r); padding: 13px 14px;
  transition: border-color 0.16s;
}
.card.tight { padding: 11px 13px; }
.card.hoverable:hover { border-color: var(--border-strong); }
.card.accent { border-color: var(--dynamic); background: var(--dynamic-soft); }

/* Section label: uppercase micro-caps with an optional leading icon. */
.label {
  display: flex; align-items: center; gap: 6px;
  font-size: 10px; color: var(--dim); text-transform: uppercase; letter-spacing: 0.09em; font-weight: 650;
}
.label .ico { color: var(--muted); opacity: 0.85; }
.value { font-size: 21px; font-weight: 700; letter-spacing: -0.02em; margin-top: 5px; }
.value.small { font-size: 12.5px; font-weight: 450; line-height: 1.65; color: var(--muted); letter-spacing: 0; }
.value.static { color: var(--static); }
.value.dynamic { color: var(--dynamic); }
.row { display: flex; gap: 10px; }
.row > * { flex: 1; min-width: 0; }
.note { font-size: 11px; color: var(--dim); line-height: 1.6; }
.note a, .value a { color: var(--primary); }
.sidebar .note.foot { margin-top: auto; padding-top: 10px; border-top: 1px solid var(--border); }
/* With a flex-growing table in the column, the footnote must not also claim
   the slack, or the two fight and the table loses. */
#sDemand .sidebar .note.foot { margin-top: 0; flex-shrink: 0; }

/* Delta: static value -> dynamic value, the app's most repeated figure. */
.delta { display: inline-flex; align-items: center; gap: 6px; }
.delta .from { color: var(--muted); }
.delta .to { color: var(--dynamic); font-weight: 700; }
.delta .ico { color: var(--dim); }

.badge {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 8px; border-radius: 999px;
  font-size: 10px; font-weight: 650; letter-spacing: 0.02em;
}
.badge.ok { background: var(--dynamic-soft); color: var(--dynamic); }
.badge.warn { background: var(--primary-soft); color: var(--primary); }
.badge.violet { background: var(--surface-3); color: var(--muted); }

/* --------------------------------------------------------- hero numbers */
.hero { display: flex; flex-direction: column; gap: 10px; padding-bottom: 2px; }
.hero-headline { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; }
.hero-big {
  font-size: 58px; line-height: 0.9; font-weight: 800; letter-spacing: -0.045em;
  color: var(--dynamic);
}
.hero-big .unit { font-size: 20px; font-weight: 650; color: var(--foreground); letter-spacing: -0.02em; }
.hero-sub { font-size: 12.5px; color: var(--muted); line-height: 1.55; }
.hero-sub b { color: var(--foreground); font-weight: 650; }

/* versus bars: the same two colours everywhere */
.vs { display: flex; flex-direction: column; gap: 8px; }
.vs-row { display: grid; grid-template-columns: 58px 1fr auto; align-items: center; gap: 10px; }
.vs-name { font-size: 9.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.vs-name.s { color: var(--static); }
.vs-name.d { color: var(--dynamic); }
.vs-track { height: 20px; background: var(--surface-3); border: 1px solid var(--border); border-radius: 5px; overflow: hidden; position: relative; }
.vs-fill { height: 100%; border-radius: 5px; transition: width 0.9s cubic-bezier(0.22, 1, 0.36, 1); }
.vs-fill.s { background: var(--static); }
.vs-fill.d { background: var(--dynamic); }
.vs-val { font-size: 13px; font-weight: 700; min-width: 60px; text-align: right; }

/* ------------------------------------------------------------- post list */
/* Provenance block: significance + window + sources as label/value rows
   rather than three full cards, so the post list clears the fold on a laptop. */
.provenance { display: flex; flex-direction: column; gap: 6px; }
.prov-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.prov-row .label { flex-shrink: 0; }
.prov-row .value { margin-top: 0; font-size: 13px; font-weight: 700; text-align: right; }
.prov-row .value.small { font-size: 11.5px; font-weight: 550; color: var(--muted); }
.provenance .note { font-size: 10.5px; }

.postlist-head { padding: 11px 16px 7px; background: var(--surface); flex-shrink: 0; }
#postList { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.post-card {
  display: flex; align-items: center; gap: 11px; padding: 11px 16px;
  border-bottom: 1px solid var(--border); cursor: pointer; transition: background 0.14s;
}
.post-card:hover { background: var(--surface-2); }
.post-card.selected { background: var(--primary-soft); box-shadow: inset 2px 0 0 var(--primary); }
.rank-badge {
  width: 26px; height: 26px; border-radius: var(--r-sm); font-weight: 700; font-size: 12px; flex-shrink: 0;
  display: grid; place-items: center; background: var(--surface-2); color: var(--muted);
  border: 1px solid var(--border); transition: background 0.14s, color 0.14s, border-color 0.14s;
}
.post-card.selected .rank-badge { background: var(--primary); color: var(--primary-fg); border-color: var(--primary); }
.post-info { min-width: 0; }
.post-info .street { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.post-info .hood { font-size: 11px; color: var(--dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.detail-card {
  position: absolute; bottom: 14px; left: 14px; right: 14px; max-width: 400px; z-index: 900;
  background: var(--scrim); border: 1px solid var(--border); border-radius: var(--r);
  padding: 13px; backdrop-filter: blur(12px); box-shadow: var(--shadow-lg);
}
.detail-card h3 { margin: 0; font-size: 14.5px; font-weight: 650; }
.detail-card .addr { font-size: 11px; color: var(--dim); margin: 5px 0 10px; line-height: 1.45; }
.mini-row { display: flex; gap: 8px; }
.mini { flex: 1; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-sm); padding: 8px 10px; }
.mini .l { font-size: 9.5px; color: var(--dim); text-transform: uppercase; letter-spacing: 0.07em; font-weight: 600; }
.mini .v { font-size: 14px; font-weight: 700; margin-top: 3px; }

.maplegend {
  position: absolute; top: 12px; right: 12px; z-index: 900; display: flex; flex-direction: column; gap: 6px;
  background: var(--scrim); border: 1px solid var(--border); border-radius: var(--r-sm);
  padding: 9px 11px; backdrop-filter: blur(10px); font-size: 10.5px; color: var(--muted);
  box-shadow: var(--shadow-md);
}
.maplegend .lg { display: flex; align-items: center; gap: 7px; }
.swatch { width: 9px; height: 9px; border-radius: 2px; flex-shrink: 0; }
.swatch.round { border-radius: 50%; }

/* The zone table carries this panel's actual evidence, so it claims the
   sidebar's leftover height instead of being squeezed to nothing by the
   explanatory cards above it. Header stays put while the rows scroll. */
.zone-pane { display: flex; flex-direction: column; }
.zone-head { padding: 10px 16px 3px; background: var(--surface); flex-shrink: 0; white-space: nowrap; }
.zone-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 0 16px 10px; }
/* Compact rows: all 20 zones fit without scrolling on a normal laptop. */
.zone-scroll table { font-size: 10px; }
.zone-scroll th { font-size: 8.5px; padding: 3px 4px; }
.zone-scroll td { padding: 2.5px 4px; line-height: 1.35; }
.zone-scroll .tbar { height: 4px; }
.zone-scroll .swatch { width: 7px; height: 7px; }
.zone-scroll thead th {
  position: sticky; top: 0; z-index: 1; background: var(--card);
  box-shadow: inset 0 -1px 0 var(--border);
}
.zone-scroll table { border-collapse: separate; border-spacing: 0; }
.zone-scroll th, .zone-scroll td { border-bottom: 1px solid var(--border); }

/* --------------------------------------------------------------- tables */
table { width: 100%; border-collapse: collapse; font-size: 11px; }
th, td { text-align: left; padding: 5px 4px; border-bottom: 1px solid var(--border); }
th { color: var(--dim); font-weight: 650; font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.07em; }
td.bar-cell { width: 44%; }
.tbar { height: 5px; border-radius: 3px; background: var(--primary); opacity: 0.85; }
.staffed { color: var(--dynamic); font-weight: 700; }

/* --------------------------------------------------------- sub-tabs/ctl */
.subtabs { display: flex; gap: 2px; padding: 8px 14px 0; border-bottom: 1px solid var(--border); background: var(--surface); }
.subtab {
  display: flex; align-items: center; gap: 6px; padding: 8px 12px; font-size: 11.5px; cursor: pointer;
  color: var(--muted); font-weight: 550; border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color 0.14s, border-color 0.14s;
}
.subtab:hover { color: var(--foreground); }
.subtab.active { color: var(--foreground); border-bottom-color: var(--primary); }
.subview { display: none; flex: 1; overflow: hidden; min-height: 0; }
.subview.active { display: flex; }

button.ctl {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--surface-2); color: var(--foreground); border: 1px solid var(--border); border-radius: var(--r-sm);
  padding: 7px 12px; font-size: 12px; font-weight: 550; cursor: pointer; font-family: inherit;
  transition: border-color 0.14s, background 0.14s;
}
button.ctl:hover { border-color: var(--border-strong); background: var(--surface-3); }
button.ctl.primary { background: var(--primary); border-color: var(--primary); color: var(--primary-fg); font-weight: 650; }
button.ctl.primary:hover { filter: brightness(1.06); border-color: var(--primary); }
button.ctl:focus-visible, select.ctl:focus-visible, .tab:focus-visible { outline: 2px solid var(--ring); outline-offset: 1px; }
button.ctl:disabled { opacity: 0.45; cursor: not-allowed; }
select.ctl {
  background: var(--surface-2); color: var(--foreground); border: 1px solid var(--border);
  border-radius: var(--r-sm); padding: 7px 9px; font-size: 12px; font-family: inherit;
}
.controls { display: flex; gap: 7px; align-items: center; flex-wrap: wrap; }
input[type=range] { width: 100%; accent-color: var(--primary); }

/* Map unit marker: ambulance glyph, not an emoji. */
.amb-icon {
  background: var(--surface); color: var(--primary); border-radius: 50%; display: grid; place-items: center;
  width: 22px; height: 22px; box-shadow: 0 0 0 1.5px var(--primary), var(--shadow-md);
}
.post-pin {
  width: 25px; height: 25px; border-radius: var(--r-sm); display: grid; place-items: center;
  background: var(--primary); color: var(--primary-fg); font-weight: 700; font-size: 11px;
  box-shadow: 0 0 0 1.5px var(--surface), var(--shadow-md);
}
.post-pin.small {
  width: 13px; height: 13px; border-radius: 50%; background: var(--dynamic);
  box-shadow: 0 0 0 2px var(--surface);
}

/* ----------------------------------------------------------- race dock */
#raceDock {
  flex-shrink: 0; border-top: 1px solid var(--border); background: var(--surface);
  height: var(--dock-h); display: flex; flex-direction: column;
  transition: height 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}
#raceDock.collapsed { height: 46px; }
#raceDock.collapsed .race-body { display: none; }
.race-head { display: flex; align-items: center; gap: 11px; padding: 0 16px; height: 46px; flex-shrink: 0; cursor: pointer; }
.race-head .title {
  display: flex; align-items: center; gap: 7px;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted);
}
.race-head .verdict { font-size: 12px; color: var(--dim); }
.race-head .verdict b { color: var(--dynamic); }
.race-ctl { margin-left: auto; display: flex; gap: 7px; align-items: center; }
.race-body { flex: 1; display: grid; grid-template-columns: 1fr 228px; gap: 16px; padding: 0 16px 14px; min-height: 0; }

.lanes { display: flex; flex-direction: column; gap: 9px; justify-content: center; }
.lane { position: relative; }
.lane-meta { display: flex; align-items: baseline; gap: 9px; margin-bottom: 4px; }
.lane-tag { font-size: 9.5px; font-weight: 750; letter-spacing: 0.09em; text-transform: uppercase; }
.lane-tag.s { color: var(--static); }
.lane-tag.d { color: var(--dynamic); }
.lane-desc { font-size: 10.5px; color: var(--dim); }
.lane-stat { margin-left: auto; font-size: 11px; color: var(--muted); }
.lane-stat b { color: var(--foreground); font-weight: 650; }
.track {
  position: relative; height: 32px; border-radius: var(--r-sm); background: var(--surface-2);
  border: 1px solid var(--border); overflow: hidden;
}
.track::after {
  content: ""; position: absolute; right: 0; top: 0; bottom: 0; width: 6px;
  background: repeating-linear-gradient(45deg, var(--border-strong) 0 4px, transparent 4px 8px);
}
.track-fill { position: absolute; left: 0; top: 0; bottom: 0; width: 0; transition: width 0.1s linear; }
.track-fill.s { background: var(--static-soft); border-right: 2px solid var(--static); }
.track-fill.d { background: var(--dynamic-soft); border-right: 2px solid var(--dynamic); }
.runner {
  position: absolute; top: 50%; transform: translate(-50%, -50%); z-index: 3;
  display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%;
  background: var(--surface); box-shadow: 0 0 0 1.5px var(--border-strong), var(--shadow-sm);
  transition: left 0.1s linear;
}
.runner.s { color: var(--static); }
.runner.d { color: var(--dynamic); }
.runner.lead { box-shadow: 0 0 0 2px var(--dynamic), var(--shadow-md); }
.tick { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--border); }

.race-side { display: flex; flex-direction: column; gap: 8px; justify-content: center; }
.saved-box {
  background: var(--dynamic-soft); border: 1px solid var(--dynamic); border-radius: var(--r); padding: 11px 13px;
}
.saved-box .label { color: var(--dynamic); opacity: 0.9; }
.saved-box .big { font-size: 29px; font-weight: 800; color: var(--dynamic); letter-spacing: -0.035em; line-height: 1.05; margin-top: 3px; }
.saved-box .cap { font-size: 10px; color: var(--muted); margin-top: 3px; line-height: 1.4; }
.winbar { display: flex; height: 6px; border-radius: 3px; overflow: hidden; background: var(--surface-3); }
.winbar .w-d { background: var(--dynamic); }
.winbar .w-s { background: var(--static); }
.winbar .w-t { background: var(--border-strong); }

/* ------------------------------------------------------------- upload */
.upload-wrap { flex: 1; overflow-y: auto; padding: 24px; display: flex; justify-content: center; }
.upload-inner { width: 100%; max-width: 940px; display: flex; flex-direction: column; gap: 15px; }
.upload-hero h2 { font-size: 24px; margin: 0 0 6px; letter-spacing: -0.028em; font-weight: 700; }
.upload-hero p { font-size: 13px; color: var(--muted); margin: 0; line-height: 1.65; max-width: 640px; }
.dropzone {
  border: 1.5px dashed var(--border-strong); border-radius: 14px; padding: 32px; text-align: center;
  background: var(--surface); cursor: pointer; transition: border-color 0.16s, background 0.16s;
}
.dropzone:hover, .dropzone.over { border-color: var(--primary); background: var(--primary-soft); }
.dropzone .big { color: var(--muted); display: flex; justify-content: center; }
.dropzone:hover .big, .dropzone.over .big { color: var(--primary); }
.dropzone h3 { margin: 10px 0 5px; font-size: 15px; font-weight: 650; }
.dropzone p { margin: 0; font-size: 11.5px; color: var(--dim); line-height: 1.6; }
code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace; font-size: 0.92em;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 4px; padding: 1px 5px;
}

.pipeline { display: flex; flex-direction: column; gap: 5px; }
.pstep {
  display: grid; grid-template-columns: 24px 1fr auto; align-items: center; gap: 11px;
  padding: 10px 13px; border-radius: var(--r-sm); background: var(--surface); border: 1px solid var(--border);
  opacity: 0.45; transition: opacity 0.3s, border-color 0.3s, background 0.3s;
}
.pstep.active { opacity: 1; border-color: var(--primary); background: var(--primary-soft); }
.pstep.done { opacity: 1; border-color: var(--border-strong); }
.pstep .icon {
  width: 24px; height: 24px; border-radius: 6px; display: grid; place-items: center;
  background: var(--surface-2); color: var(--dim); font-size: 11px;
}
.pstep.done .icon { background: var(--dynamic-soft); color: var(--dynamic); }
.pstep.active .icon { background: var(--primary); color: var(--primary-fg); }
.pstep .ptitle { font-size: 12.5px; font-weight: 600; }
.pstep .pdesc { font-size: 10.5px; color: var(--dim); margin-top: 1px; }
.pstep .presult { font-size: 11px; color: var(--dynamic); font-weight: 650; text-align: right; font-variant-numeric: tabular-nums; }

.grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.err { border-color: var(--static); background: var(--static-soft); }
.err .label, .err .value { color: var(--static) !important; }

/* --------------------------------------------------------------- charts */
.chart-card { background: var(--card); border: 1px solid var(--border); border-radius: var(--r); padding: 12px 13px; }
.chart-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 9px; }
.chart-head .t { font-size: 12px; font-weight: 650; }
.chart-head .s { font-size: 10.5px; color: var(--dim); margin-left: auto; }
svg.chart { display: block; width: 100%; overflow: visible; }
.proof-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 12px; align-items: start; max-width: 1180px; }
.proof-wide { grid-column: 1 / -1; max-width: 1180px; }
.chart-legend { display: flex; gap: 13px; font-size: 10px; color: var(--muted); margin-top: 7px; flex-wrap: wrap; }
.chart-legend span { display: flex; align-items: center; gap: 5px; }

::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 5px; }
::-webkit-scrollbar-thumb:hover { background: var(--dim); }

@media (max-width: 1100px) {
  .race-body { grid-template-columns: 1fr; }
  .race-side { display: none; }
  .sidebar { width: 292px; }
  .brand .sub { display: none; }
}
