/* ============================================================================
   draft.css — the shared DRAFT web design foundation
   ----------------------------------------------------------------------------
   ONE token layer for every rider surface (report · train · compare), carrying
   the native iOS app's palette (ios/DraftApp/UI/Shared/DraftStyle.swift). Pages
   link this, delete their own drifted :root block, and inherit an
   appearance-adaptive theme for free — their CSS already reads
   var(--ink)/var(--accent)/… .

   DARK is the brand default (locked 2026-06-14); LIGHT follows the device
   (prefers-color-scheme), same hues with teal deepened just enough to read on
   paper. This is the inverse nesting of a light-default page, but the same
   result — and it keeps DRAFT dark-first. Keep the hexes in lock-step with
   DraftStyle.swift (the web dark theme IS the app dark theme, swatch for swatch).

   Ported technique-for-technique from WAKE's wake.css (the sibling app's Phase-0
   foundation) — the token layer, the branded spinner, and the a11y baseline —
   but on DRAFT's teal/D-mark brand, not WAKE's navy/crimson.

   SCOPE (2026-07-08, issue #32): this now backs the SPECTATOR surfaces too
   (viewer + landing), not just the rider pages — one token layer for every web
   surface. The spectator-only semantic colors (--live/--warn/--stop/--cp) live
   here so both sides agree and both themes are honest.

   THEME PIN (a capability, currently unused): a page that must stay dark regardless of
   the device can set <html data-theme="dark">, and the light overrides below are gated
   on :not([data-theme="dark"]) so it keeps the dark palette while every normal page
   FOLLOWS the device. The viewer USED this pin (#32) but now goes adaptive too —
   spectators watch outdoors in daylight, where a light basemap reads better in direct
   sun — so no surface pins today; the hook stays for any future always-dark page.
   ============================================================================ */

:root{
  color-scheme: dark light;   /* dark is the brand default; native controls follow */

  /* — core palette (dark — the brand default) — */
  --ink:#e8edf2;      /* primary text + data */
  --dim:#8b95a1;      /* secondary text / labels */
  --bg:#06080a;       /* page ground */
  --panel:#11161c;    /* floating overlays only (readout, toast, full-screen) — never behind data */
  --line:#3a4452;     /* control borders */
  --accent:#0fb5a4;   /* the ONE signal — teal (leader, "now", the single CTA) */
  --up:#cf7a52;       /* warm — climb / positive grade / behind-ghost */
  --down:#6f86ac;     /* cool — descent / negative grade / ahead-ghost pair */
  --scaf:#1b232c;     /* the 1px hairline rule — the workhorse of the unboxed language */
  --fill:#141b22;     /* chart area fill / sparkline tint */
  --bar:#46535d;      /* calm context bars (splits, weekly volume) */
  --link:#7fb2ff;     /* links */
  --danger:#ff5b5b;   /* Guardian's semantic red */
  --shadow:rgba(0,0,0,.45);

  /* — spectator semantics (viewer live-tracking; distinct from the ONE teal signal) — */
  --live:#39d98a;     /* fresh / riding — a green that is NOT the teal accent */
  --warn:#e2a33b;     /* stale fix / waiting */
  --stop:#e6484d;     /* off-course / dead / danger on the map */
  --cp:#e0a13a;       /* rest-stop checkpoint pin */

  /* — radii — */
  --r-sm:6px;   --r-md:10px;

  /* — motion (the native easeOut + its two durations) — */
  --ease:cubic-bezier(.22,.61,.36,1);
  --dur-1:.12s;   /* press / tap feedback */
  --dur-2:.22s;   /* reveals, tray + overlay transitions */
}

@media (prefers-color-scheme: light){
  :root:not([data-theme="dark"]){
    --ink:#151e26; --dim:#5b6673; --bg:#fafbfc; --panel:#eef2f5; --line:#c3ccd4;
    --accent:#0a8578;   /* deepened so teal still reads on paper */
    --up:#a8552c; --down:#4f648a; --scaf:#e4e9ee; --fill:#e9eef2;
    --bar:#b7c2cc; --link:#2668c5; --danger:#c8323e; --shadow:rgba(21,30,38,.18);
    /* spectator semantics, deepened for paper */
    --live:#1f9d63; --warn:#b6791d; --stop:#c8323e; --cp:#b6791d;
  }
}

/* ── DraftSpinner — the branded loading mark (teal flywheel + the speed-lean D +
   a pulsing teal beat-dot). A drop-in replacement for every static "Loading…" /
   CSS-border spinner. Theme-aware because every stroke reads a CSS var; inline
   the markup for the pre-JS first paint. ── */
.dsp{ display:block; width:var(--dsp-size,68px); height:var(--dsp-size,68px); }
.dsp-arc{ transform-box:fill-box; transform-origin:center; animation:dsp-rot 1.15s linear infinite; }
.dsp-dot{ transform-box:fill-box; transform-origin:center; animation:dsp-pulse 1.05s ease-in-out infinite; }
@keyframes dsp-rot{ to{ transform:rotate(360deg); } }
@keyframes dsp-pulse{ 0%,100%{ opacity:.5; transform:scale(.62); } 50%{ opacity:1; transform:scale(1); } }
.dsp-wrap{ display:flex; flex-direction:column; align-items:center; gap:14px;
  padding:56px 8px; text-align:center; }
.dsp-label{ font-weight:800; font-size:14px; letter-spacing:.02em; color:var(--dim); }

/* ── a11y baseline every rider surface inherits — a visible keyboard-focus ring
   in the brand teal, and a reduced-motion guard for the spinner ── */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, [tabindex]:focus-visible{
  outline:2px solid var(--accent); outline-offset:2px; border-radius:4px;
}
@media (prefers-reduced-motion: reduce){
  .dsp-arc, .dsp-dot{ animation:none; }
  .dsp-dot{ opacity:1; transform:none; }
}
