/* ============================================================================
   os-v3-tokens.css — LUDALIS Desktop OS design tokens (SHARED CHASSIS)
   ----------------------------------------------------------------------------
   Layer 1 of 2. Pair with os-v3-chassis.css. Seam 3 (04-UPGRADE/08-SEAMS-CONTRACT.md
   §3). This file plus the two desktops' skin blocks are the ONLY places in the pro
   surfaces where a colour value exists (§3.3 rule 1).

   ── WHAT LANDED HERE, AND WHERE IT CAME FROM (Stream L, 2026-08-10) ──────────
   The palette is the family app's, ported onto the frozen pro token names, so the
   product is one identity at two temperatures (01-BRAND/BRAND-BRIEF.md §2):

     dark  :root                     ← Crépuscule       (DECISIONS.md #16)
     light :root[data-theme=light]   ← Terrain de jeu   (DECISIONS.md #25)

   Values come from education/frontend/famille/tokens.css, which shipped them first.
   Same grammar, different surface: "la teinte change, la grammaire jamais".

   ── ACCENTS ARE NOT DEFINED HERE, ON PURPOSE ────────────────────────────────
   Each desktop supplies its own accent trio in an 8-line :root block (README.md
   §"Skin a new OS"). The two lights of #16 that name a product take those slots:

     School OS  → école blue   #9FBCEE dark · #2D50C7 light
     Club OS    → sport amber  #F0B26B dark · #B54A08 light

   The third light — the child's voice lavender #C9B3E8 — deliberately has NO job
   on these surfaces. There is no child's voice on a treasurer's screen; it stays
   the family app's. (It was tried as --info and failed the §7 separation check
   against the école blue: dE 16.7. The numbers agreed with the semantics.)

   ── WHERE THIS DEVIATES FROM THE FAMILY FILE, AND WHY ───────────────────────
   Every deviation below is an accessibility or disambiguation fix, verified
   numerically (WCAG 2.1 AA: body ≥ 4.5:1, UI/large ≥ 3:1) rather than by eye:

   · --ink-2  #97A0BE → #A3ACCA   the pro chassis prints muted text ON --surface-3
                                  (.tag, .chip, .row:hover); the family app never
                                  does. At #97A0BE that pairing is 4.04:1 — under
                                  AA. #A3ACCA reads as the same slate at 4.66:1.
   · --ink-3 / --offline
              #5E6680 → #828AA4   same reason, one tier down: court-dim was drawn
                                  on the drill court (#141B33), not on --surface-2.
   · --warn   sport amber → #E8D45C  the Club OS accent IS the sport amber, and a
                                  warn pill matching the primary button is not a
                                  warning. Pulled toward yellow (dE 16.0 → 33.6).
   · --alert (light)
              #B4351B → #B31235   Terrain's brick danger sits 13.7 dE from a burnt-
                                  orange Club accent — on a compliance surface,
                                  "delete" and "primary" must never be a hue apart.
                                  Crimson restores the separation (dE 34.9).
   Status colours are compliance-clock language, never decoration.

   Load order in each desktop:
       <link rel="stylesheet" href="/os/_shared/os-v3-tokens.css">
       <link rel="stylesheet" href="/os/_shared/os-v3-chassis.css">
       <style>:root{ --accent:…; --accent-deep:…; --accent-glow:…; --bg:…; }</style>

   DO NOT add per-OS colour here. Colour drift = the bug this chassis kills.
   Token NAMES are frozen (§3.2); values are Stream L's and iterate freely.
   ============================================================================ */

:root {
  /* ── Surface ramp (dark, default) — Crépuscule's sky, one vertical ramp.
     The family app's evening, carried into the office. ────────────────────── */
  --bg:#0E1428;          /* sky-0 */
  --surface:#1B2340;     /* sky-1 */
  --surface-2:#2B2B4E;   /* sky-2 */
  --surface-3:#463A56;   /* sky-3 */

  /* ── Hairlines — accent-agnostic, so every skin reads cleanly on them. ──── */
  --line:rgba(151,160,190,.16);
  --line-2:rgba(151,160,190,.35);

  /* ── Ink ramp ──────────────────────────────────────────────────────────── */
  --ink:#F1EDE3;         /* warm paper-white, not a blue-white — the dusk needs it */
  --ink-2:#A3ACCA;
  --ink-3:#828AA4;
  --ink-on-accent:#101A2E;   /* each desktop overrides for its own accent */

  /* Text aliases — LITERAL (not var(--ink)) so legacy files that already use the
     name --ink for their BACKGROUND can reference --fg/--fg-2/--fg-3 for
     theme-aware TEXT without the shadowing collision. See README "Brownfield". */
  --fg:#F1EDE3; --fg-2:#A3ACCA; --fg-3:#828AA4;

  /* ── Accent — FALLBACK ONLY. Each desktop MUST override the trio below.
     Muted dusk slate: an un-skinned file stays legible but looks unfinished. ─ */
  --accent:#8A93B4;
  --accent-deep:#6E7799;
  --accent-glow:rgba(151,160,190,.18);

  /* ── Semantic status — each in its own hue lane, none within dE 25 of either
     desktop's accent. Green and red are the family palette's. ─────────────── */
  --online:#6FCF97; --online-deep:#3CA06A;   /* 3CA06A = the voice green, #25 */
  --offline:#828AA4;
  --alert:#F0A0A0;  --alert-deep:#D25F5F;    /* F0A0A0 = the family's only red, #16 */
  --warn:#E8D45C;
  --info:#7FD0D8;

  /* ── Hero gradients — the dusk ramp, then a warm surge for pressure states.
     The chassis hero structure reads these three. ─────────────────────────── */
  --hero-offline:linear-gradient(135deg,#1B2340 0%,#2B2B4E 100%);
  --hero-idle:linear-gradient(135deg,#141B33 0%,#232B49 50%,#2B2B4E 100%);
  --hero-surge:linear-gradient(135deg,#3A2A16 0%,#5A4020 50%,#7A5526 100%);

  /* ── Map tokens — chassis inheritance. LUDALIS draws no maps; kept because
     deleting a token is a value change (§3.2), re-tinted into the dusk world so
     nothing can inherit a coastline palette from the upstream fleet surfaces. ─ */
  --map-water:#0A0F20; --map-land-fr:#1B2340; --map-land-nl:#232B49;
  --map-coast:#2B2B4E; --map-road-1:rgba(151,160,190,.085); --map-road-2:rgba(151,160,190,.05);
  --map-border:#5E6680; --map-label:#A3ACCA; --map-label-dim:#828AA4;

  /* ── Radii — tighter than the family app's 14–26px. The family app is a thing
     you hold; these are tools. Precision wins at the office (BRAND-BRIEF §5). ─ */
  --r-sm:8px; --r-md:12px; --r-lg:16px; --r-xl:20px;

  /* ── Shadows — cast in the dusk's own blue-black, not neutral black. ────── */
  --shadow-sm:0 1px 2px rgba(6,10,24,.30);
  --shadow-md:0 4px 14px rgba(6,10,24,.38);
  --shadow-lg:0 18px 48px rgba(6,10,24,.55);

  /* ── Typography — NOT part of #16/#25, which decide palette only. The type
     deliverable (BRAND-BRIEF §4.4, including the DYS pairing) is still open for
     the design pass; these hold until it rules. Both faces are loaded per file. */
  --font:"Geist",-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;
  --mono:"JetBrains Mono",ui-monospace,Menlo,Consolas,monospace;

  /* ── Layout metrics ────────────────────────────────────────────────────── */
  --sb-w:248px;

  color-scheme:dark;
  font-feature-settings:'tnum';
}

/* ── LIGHT THEME — Terrain de jeu (DECISIONS.md #25) ──────────────────────────
   The light twin, not a bleached dusk: warm off-white paper, flat stacked shadows
   instead of blur, and the saturated daylight cut of the palette. */
:root[data-theme="light"] {
  --bg:#F2F3EC;          /* sky-2 */
  --surface:#FFFFFF;
  --surface-2:#F6F7F3;
  --surface-3:#EDEFE6;
  --line:#E6E7E0;
  --line-2:#D8D9D0;
  --ink:#23252B;
  --ink-2:#5F626B;
  --ink-3:#83868F;
  --fg:#23252B; --fg-2:#5F626B; --fg-3:#83868F;
  --accent-glow:rgba(45,80,199,.14);

  /* status — daylight cut, all AA on white, paper and --surface-2 */
  --online:#2C7C50; --online-deep:#1F5C3A;
  --offline:#83868F;
  --alert:#B31235;  --alert-deep:#8C0D28;
  --warn:#8A6206;
  --info:#0F6E7A;

  --hero-offline:linear-gradient(135deg,#EDEFE6 0%,#F6F7F3 100%);
  --hero-idle:linear-gradient(135deg,#DDE4F7 0%,#B9C8EE 50%,#8CA3DF 100%);
  --hero-surge:linear-gradient(135deg,#FCEADB 0%,#F7C79B 50%,#F07C2E 100%);

  --map-water:#DDE4F7; --map-land-fr:#F6F7F3; --map-land-nl:#EDEFE6;
  --map-coast:#D8D9D0; --map-road-1:rgba(35,37,43,.16); --map-road-2:rgba(35,37,43,.09);
  --map-border:#9A9DA4; --map-label:#3F424A; --map-label-dim:#83868F;

  /* Flat, stacked shadows — Terrain's "0 2px 0" language, not a blur. */
  --shadow-sm:0 1px 0 rgba(35,37,43,.08);
  --shadow-md:0 2px 0 rgba(35,37,43,.12);
  --shadow-lg:0 8px 24px rgba(35,37,43,.14);

  color-scheme:light;
}

/* ── WARM dark surface ramp (opt-in) ─────────────────────────────────────────
   Kept from the chassis contract: data-surface="warm" on <html> carries a warm
   desktop's temperature into the surfaces themselves. On LUDALIS that is the Club
   OS's option — the sport amber reads cooler than it is on the plain dusk ramp.
   Dark only; the light theme stays as Terrain de jeu sets it. */
:root[data-theme="dark"][data-surface="warm"],
:root[data-surface="warm"]:not([data-theme="light"]) {
  --surface:#231F33; --surface-2:#332A47; --surface-3:#4A3A52;
}

/* ── Base reset (shared) ─────────────────────────────────────────────────── */
* { box-sizing:border-box; }
html,body { margin:0; padding:0; }
body {
  background:var(--bg); color:var(--ink); font-family:var(--font);
  font-size:14px; line-height:1.45; -webkit-font-smoothing:antialiased;
  font-feature-settings:'cv11','ss01','tnum';
  min-height:100vh;
}
.mono,.val,.num,.lab,.sub,.meta,.delta,.kpi-val { font-variant-numeric:tabular-nums; }
::-webkit-scrollbar { width:10px; height:10px; }
::-webkit-scrollbar-thumb { background:var(--surface-3); border-radius:8px; border:3px solid var(--bg); }
svg { display:block; }
