/* public/css/tokens.css — geoguess.es design tokens, redesign 2026-10-21 ("B × C"; since DECISIONS #26c the whole
   product is Quiet Minimal: a left sidebar, nothing pixelated). Source of truth: docs/redesign/FINAL.md.
   docs/redesign/design-tokens.css is a byte-for-byte copy of the token blocks (server/test/core.test.js diffs the
   colours of both files and the two Night blocks).
   Every text pair has a computed WCAG 2.x ratio in FINAL.md §3 — re-run the checker before changing a colour.
   NO hex value anywhere else in public/css: add a token here instead.
   Colour pass (DECISIONS #27, docs/redesign/colour/): the action colour (--action*), six calm hues (--rose, --plum,
   --sky, --teal, --green, --ochre; each with -ink for text and -wash for fills) and their ROLES (--tc-*, --up,
   --online, --team-*, --ascii-*) — ratios in colour.md §3, regenerated by `node docs/redesign/colour/contrast.mjs`.

   Themes
     Day (default) · Night: follows the OS, or <html data-theme="dark|light"> (prefs.js).
     The two Night blocks below are IDENTICAL on purpose (a media query and an attribute selector cannot share
     one block without a build step); the unit test diffs them.

   Fonts (SIL OFL 1.1, self-hosted; licences beside the files in public/fonts/)
     Geist Mono      — the whole UI. Two weights: the 400 files answer 100–450, the 500 files 451–1000, so old
                       `font-weight: 600/700` renders as 500 (calm, never faux-bold). Latin + Latin Extended.
     JetBrains Mono  — Cyrillic + Greek inside the same family name (Geist has neither; same 0.6 em advance).
     Doto            — dot-matrix hero words ONLY (result "Victory", the 404, rare heroes). Variable, ROND 100.
     (Departure Mono, the pixel face, left the product with DECISIONS #26c: the wordmark is Geist Mono.) */

/* The UI family is ONE composite of faces that all share exactly two weight descriptors — 100–450 ("regular") and
   451–1000 ("medium"). Chrome groups @font-face rules by their descriptors and picks ONE group per request, so a face
   with any other weight range would capture the whole family (and every glyph it lacks would fall to the system font).
   Within a group the last-declared face is tried first for a character: Geist (declared last) wins, the faces above
   it only fill its gaps — JetBrains Mono for Cyrillic, Greek and a few Latin letters, IBM Plex Mono for ʻ ʼ. */
@font-face { font-family: 'Geist Mono'; font-style: normal; font-weight: 100 450; font-display: swap;
  src: url(../fonts/IBMPlexMono-500.woff2) format('woff2');
  unicode-range: U+02BB-02BC; }
@font-face { font-family: 'Geist Mono'; font-style: normal; font-weight: 100 450; font-display: swap;
  src: url(../fonts/JetBrainsMono-var-latin-ext.woff2) format('woff2');
  unicode-range: U+0114-0115, U+012C-012D, U+0138, U+013F-0140, U+0149, U+014E-014F, U+017F, U+01A0-01A1, U+01AF-01B0, U+01EA-01EB, U+01F4-01F5, U+01FC-01FF, U+0232-0233, U+02BA, U+02C9, U+02F3, U+02F7, U+1EF4-1EF7, U+20AB, U+20AE, U+20BF, U+2113; }
@font-face { font-family: 'Geist Mono'; font-style: normal; font-weight: 100 450; font-display: swap;
  src: url(../fonts/JetBrainsMono-var-cyrillic.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
@font-face { font-family: 'Geist Mono'; font-style: normal; font-weight: 100 450; font-display: swap;
  src: url(../fonts/JetBrainsMono-var-greek.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; }
@font-face { font-family: 'Geist Mono'; font-style: normal; font-weight: 451 1000; font-display: swap;
  src: url(../fonts/IBMPlexMono-500.woff2) format('woff2');
  unicode-range: U+02BB-02BC; }
@font-face { font-family: 'Geist Mono'; font-style: normal; font-weight: 451 1000; font-display: swap;
  src: url(../fonts/JetBrainsMono-var-latin-ext.woff2) format('woff2');
  unicode-range: U+0114-0115, U+012C-012D, U+0138, U+013F-0140, U+0149, U+014E-014F, U+017F, U+01A0-01A1, U+01AF-01B0, U+01EA-01EB, U+01F4-01F5, U+01FC-01FF, U+0232-0233, U+02BA, U+02C9, U+02F3, U+02F7, U+1EF4-1EF7, U+20AB, U+20AE, U+20BF, U+2113; }
@font-face { font-family: 'Geist Mono'; font-style: normal; font-weight: 451 1000; font-display: swap;
  src: url(../fonts/JetBrainsMono-var-cyrillic.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
@font-face { font-family: 'Geist Mono'; font-style: normal; font-weight: 451 1000; font-display: swap;
  src: url(../fonts/JetBrainsMono-var-greek.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; }
@font-face { font-family: 'Geist Mono'; font-style: normal; font-weight: 100 450; font-display: swap;
  src: url(../fonts/GeistMono-400.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: 'Geist Mono'; font-style: normal; font-weight: 451 1000; font-display: swap;
  src: url(../fonts/GeistMono-500.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: 'Geist Mono'; font-style: normal; font-weight: 100 450; font-display: swap;
  src: url(../fonts/GeistMono-400-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: 'Geist Mono'; font-style: normal; font-weight: 451 1000; font-display: swap;
  src: url(../fonts/GeistMono-500-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: 'Doto'; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url(../fonts/Doto-var-full.woff2) format('woff2'); }

:root {
  color-scheme: light;

  /* ---------- type ---------- */
  --font-ui: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  --font-mono: var(--font-ui);
  --font-dot: 'Doto', 'Geist Mono', ui-monospace, monospace;               /* hero words only */
  --font-pixel: var(--font-ui);    /* legacy alias: the pixel face left the product (DECISIONS #26c) */
  --font-serif: var(--font-ui);    /* legacy alias: there is no serif any more */
  --font-display: var(--font-ui);  /* legacy alias: .display is plain Geist Mono; use .t-dot for a rare hero */
  --fs-11: 0.6875rem;  --fs-12: 0.75rem;  --fs-13: 0.8125rem; --fs-14: 0.875rem; --fs-15: 0.9375rem;
  --fs-16: 1rem;       --fs-18: 1.125rem; --fs-22: 1.375rem;  --fs-28: 1.75rem;  --fs-34: 2.125rem;
  --fs-36: 2.25rem;    --fs-40: 2.5rem;   --fs-48: 3rem;      --fs-56: 3.5rem;
  --lh-tight: 1.1; --lh-snug: 1.3; --lh-ui: 1.6; --lh-body: 1.6;
  --fw-regular: 400; --fw-medium: 500; --fw-semibold: 500; --fw-bold: 500;
  --tracking-label: 0.04em; --tracking-badge: 0.06em;
  --tracking-eyebrow: var(--tracking-label); --tracking-caps: var(--tracking-badge);

  /* ---------- space (4-pt; sections use 48 / 64 / 96) ---------- */
  --sp-0: 0; --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-6: 24px;
  --sp-8: 32px; --sp-10: 40px; --sp-12: 48px; --sp-14: 56px; --sp-16: 64px; --sp-20: 80px; --sp-24: 96px; --sp-32: 128px;

  /* ---------- shape: pills for controls, soft wells for the few surfaces ---------- */
  --r-1: 6px;      /* kbd caps, small wells, tooltips (flags use 2px) */
  --r-2: 12px;     /* legacy boxes (tiles, seats); never a button: buttons are pills */
  --r-3: 20px;     /* menus, banners, textareas */
  --r-4: 28px;     /* dialogs, sheets, the guess-map well */
  --r-pill: 999px; /* every button, input, chip, tab, HUD plate */
  --bw: 1px; --bw-strong: 1.5px;

  /* ---------- layout ---------- */
  --topbar-h: 72px; --tabbar-h: 0px;  /* no bottom tab bar any more: the phone menu is a sheet */
  --content-max: 1180px; --gutter: 48px; --side-col: 280px; --side-panel-w: 340px; --hit-min: 44px;
  --rail-w: 232px; --rail-w-collapsed: 72px;  /* the left sidebar: expanded / as the icon rail (layout.css, #26c) */
  --z-base: 0; --z-hud: 10; --z-rail: 20; --z-dropdown: 30; --z-sheet: 40; --z-modal: 50; --z-toast: 60; --z-tooltip: 70;

  /* ---------- motion: fade + 8 px slide; nothing bounces ---------- */
  --ease: cubic-bezier(.2, .7, .2, 1);
  --ease-in: cubic-bezier(.4, 0, 1, 1);
  --t-press: 100ms; --t-fast: 150ms; --t-base: 200ms; --t-panel: 240ms; --t-reveal: 600ms;

  /* ======================= DAY (light) ======================= */
  /* ground */
  --paper: #F4F3EF;        /* the page */
  --paper-2: #EAE8E2;      /* tracks, wells, secondary buttons */
  --paper-3: #E0DDD6;      /* hover on sunken */
  --raised: #FBFAF8;       /* dialogs, menus, the raised segment thumb */
  --raised-2: #EAE8E2;     /* a secondary button inside a raised surface */
  --raised-3: #E0DDD6;     /* …its hover */
  /* ink */
  --ink: #18191B;          /* text (the primary pill is --action since the colour pass) */
  --ink-2: #5A5C60;        /* secondary text (6.03:1) */
  --ink-faint: #8B8D91;    /* disabled + decoration ONLY (2.99:1): never text that matters */
  --line: #DEDCD5;         /* hairline (decorative) */
  --line-2: #CFCCC4;       /* a firmer hairline (decorative) */
  --edge: #86888C;         /* input / chip outline (3.2:1, non-text) */
  /* the signal: the sextant's index arm. It means now / here / careful (no other hue ever does) */
  --signal: #B0452A;
  --signal-wash: rgba(176, 69, 42, .10);
  --signal-ink: #963822;   /* signal TEXT on its wash (destructive, loss pills, ADMIN): ≥ 4.66:1 on every wash and hover */
  --on-signal: #F4F3EF;
  /* brass: the star only — the answer marker and the wordmark's star (DECISIONS #26c) */
  --brass: #B8892B;        /* the star (decoration) */
  /* over the panorama */
  --hud: rgba(244, 243, 239, .88);   /* + 18 px backdrop blur */
  --scrim: rgba(24, 25, 27, .32);
  --shadow-soft: 0 1px 2px rgba(24, 25, 27, .06), 0 8px 24px -12px rgba(24, 25, 27, .22);
  --shadow-pop: 0 2px 6px rgba(24, 25, 27, .06), 0 28px 64px -20px rgba(24, 25, 27, .34);
  --flag-edge: rgba(0, 0, 0, .10);
  /* data colours: team markers (always with a shape) and chart series only */
  --data-3: #3F6E78; --data-4: #7A5C8A;
  /* difficulty tiers T1–T8: a calm grey ramp (T1–T4 ink text, T5–T8 --depth-ink) */
  --depth-1: #EAE8E2; --depth-2: #E0DDD6; --depth-3: #D3D0C8; --depth-4: #C4C1B9;
  --depth-5: #6B6D71; --depth-6: #55575B; --depth-7: #3F4144; --depth-8: #2A2B2E;
  --depth-ink: #F4F3EF; --depth-ink-2: #E0DDD6;
  /* the flat guess map (land on a well, borders knocked out in the well colour) */
  --map-land: #D3D0C8; --map-water: var(--map-water-tint); --map-coast: #B4B1A9; --map-waterline: rgba(24, 25, 27, .08);
  --map-border: #EAE8E2; --map-border-4: #C4C1B9; --map-grat: #DEDCD5; --map-label: #3A3B3F;
  --map-label-2: #5A5C60; --map-water-label: #5A5C60; --map-grat-label: #8B8D91; --map-halo: #EAE8E2;
  --map-wood: #CBC8BF; --map-ice: #E4E2DC; --map-sand: #D9D5CA; --map-residential: #CCC9C1; --map-park: #C8C7BC;
  --map-road-1: #FBFAF8; --map-road-2: #F4F3EF; --map-road-3: #EAE8E2; --map-road-4: #E0DDD6; --map-rail: #A9A7A0;
  --map-building: #C6C3BB; --map-river: var(--map-water-tint);
  /* Google sign-in button (Google's own branding colours) */
  --google-bg: #FFFFFF; --google-edge: #747775; --google-ink: #1F1F1F;
  /* ---------- colour pass (DECISIONS #27; docs/redesign/colour/colour.md): one action colour + six calm hues ----------
     "a bit colourful … not too flashy but not completely monotone". Values are generated and WCAG-checked by
     docs/redesign/colour/contrast.mjs (OKLCH → sRGB): change a colour THERE, re-run, paste here. Grounds, ink,
     signal and brass are unchanged. */
  /* the action: the sextant's indigo frame. It fills ONE control per screen: the primary (Play, Guess, Challenge…) */
  --action: #2F4A86;            /* fill · its label 7.74:1 · as a shape on paper 7.74:1 */
  --action-hover: #3F5B99;      /* 5.97:1 under its label */
  --on-action: #F4F3EF;         /* the primary's label (= paper) */
  --action-ink: #355292;        /* action-coloured TEXT: 6.82 on paper, 6.08 on its wash */
  --action-wash: #DDE7F8;       /* the tonal button, the sidebar's current row, YOU, your leaderboard row */
  --action-wash-hover: #D1DDF4; /* tonal hover: 5.54 under action-ink */
  /* six hues: --X = MARK (dots, dial wedges, graph lines; ≥ 3:1) · --X-ink = TEXT (≥ 4.5:1 on paper, paper-2, raised
     and its own wash) · --X-wash = a tinted FILL (ink ≥ 13:1, ink-2 ≥ 5.4:1 on it). A hue says WHICH, never a state. */
  --rose:  #A75474; --rose-ink:  #8B3B5C; --rose-wash:  #FAE2EA;   /* Bullet · team 2 */
  --plum:  #88609F; --plum-ink:  #6E4885; --plum-wash:  #F0E5F7;   /* Blitz · BOT · team 4 */
  --sky:   #327BA3; --sky-ink:   #116289; --sky-wash:   #D9EDFA;   /* Rapid · info · the sea */
  --teal:  #2C8281; --teal-ink:  #056767; --teal-wash:  #D6F0EF;   /* Classical · MOD · team 3 */
  --green: #408455; --green-ink: #22683B; --green-wash: #DDEFE1;   /* up · won · online */
  --ochre: #8E6413; --ochre-ink: #6C4A04; --ochre-wash: #F4E8D6;   /* Daily (the noon sun) · CHART MAKER */
  --map-water-tint: #DDEBF3;    /* the barely-blue sea (flat maps, reveal, ASCII world): ink-2 on it 5.50, signal 4.62 */

}

/* ======================= NIGHT (dark): follows the OS ======================= */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --paper: #0F1011; --paper-2: #1B1C1E; --paper-3: #26272A; --raised: #1B1C1E; --raised-2: #26272A; --raised-3: #303134;
    --ink: #EDEBE5; --ink-2: #A3A5A9; --ink-faint: #6C6E72;
    --line: #26272A; --line-2: #323336; --edge: #6C6E72;
    --signal: #E8714B; --signal-wash: rgba(232, 113, 75, .14); --signal-ink: #EF8A69; --on-signal: #0F1011;
    --brass: #D6A64A;
    --hud: rgba(15, 16, 17, .84); --scrim: rgba(0, 0, 0, .56);
    --shadow-soft: none;
    --shadow-pop: 0 0 0 1px #26272A, 0 28px 64px -20px rgba(0, 0, 0, .7);
    --flag-edge: rgba(255, 255, 255, .16);
    --data-3: #7FB0B8; --data-4: #B9A0C8;
    --depth-1: #1B1C1E; --depth-2: #222326; --depth-3: #2A2B2E; --depth-4: #323336;
    --depth-5: #3B3C40; --depth-6: #45464A; --depth-7: #505155; --depth-8: #5C5D62;
    --depth-ink: #EDEBE5; --depth-ink-2: #C9C7C1;
    --map-land: #3A3B3F; --map-water: var(--map-water-tint); --map-coast: #4C4D52; --map-waterline: rgba(237, 235, 229, .06);
    --map-border: #1B1C1E; --map-border-4: #2E2F33; --map-grat: #26272A; --map-label: #EDEBE5;
    --map-label-2: #A3A5A9; --map-water-label: #A3A5A9; --map-grat-label: #6C6E72; --map-halo: #1B1C1E;
    --map-wood: #36373B; --map-ice: #45464A; --map-sand: #3E3E3F; --map-residential: #403F43; --map-park: #37393A;
    --map-road-1: #5A5B60; --map-road-2: #4E4F54; --map-road-3: #45464B; --map-road-4: #404145; --map-rail: #55565A;
    --map-building: #434448; --map-river: var(--map-water-tint);
    --google-bg: #131314; --google-edge: #8E918F; --google-ink: #E3E3E3;
    /* colour pass (DECISIONS #27): the action is the sextant's glass at Night; the six hues lifted for the dark ground */
    --action: #9EC0EE; --action-hover: #B8D3F9; --on-action: #0F1011; --action-ink: #A5C7F5; --action-wash: #1D2B44; --action-wash-hover: #243554;
    --rose:  #E993B2; --rose-ink:  #F1A3BF; --rose-wash:  #2E1D23;
    --plum:  #C69FDF; --plum-ink:  #D1ADE8; --plum-wash:  #271F2D;
    --sky:   #77BAE3; --sky-ink:   #8AC6EB; --sky-wash:   #15252F;
    --teal:  #74C1C0; --teal-ink:  #89CCCB; --teal-wash:  #112727;
    --green: #82C393; --green-ink: #94CEA3; --green-wash: #18271C;
    --ochre: #D4A965; --ochre-ink: #DEB77B; --ochre-wash: #2A2113;
    --map-water-tint: #121B23;
  }
}

/* ======================= NIGHT (dark): manual override — keep identical to the block above ======================= */
:root[data-theme="dark"] {
  color-scheme: dark;
  --paper: #0F1011; --paper-2: #1B1C1E; --paper-3: #26272A; --raised: #1B1C1E; --raised-2: #26272A; --raised-3: #303134;
  --ink: #EDEBE5; --ink-2: #A3A5A9; --ink-faint: #6C6E72;
  --line: #26272A; --line-2: #323336; --edge: #6C6E72;
  --signal: #E8714B; --signal-wash: rgba(232, 113, 75, .14); --signal-ink: #EF8A69; --on-signal: #0F1011;
  --brass: #D6A64A;
  --hud: rgba(15, 16, 17, .84); --scrim: rgba(0, 0, 0, .56);
  --shadow-soft: none;
  --shadow-pop: 0 0 0 1px #26272A, 0 28px 64px -20px rgba(0, 0, 0, .7);
  --flag-edge: rgba(255, 255, 255, .16);
  --data-3: #7FB0B8; --data-4: #B9A0C8;
  --depth-1: #1B1C1E; --depth-2: #222326; --depth-3: #2A2B2E; --depth-4: #323336;
  --depth-5: #3B3C40; --depth-6: #45464A; --depth-7: #505155; --depth-8: #5C5D62;
  --depth-ink: #EDEBE5; --depth-ink-2: #C9C7C1;
  --map-land: #3A3B3F; --map-water: var(--map-water-tint); --map-coast: #4C4D52; --map-waterline: rgba(237, 235, 229, .06);
  --map-border: #1B1C1E; --map-border-4: #2E2F33; --map-grat: #26272A; --map-label: #EDEBE5;
  --map-label-2: #A3A5A9; --map-water-label: #A3A5A9; --map-grat-label: #6C6E72; --map-halo: #1B1C1E;
  --map-wood: #36373B; --map-ice: #45464A; --map-sand: #3E3E3F; --map-residential: #403F43; --map-park: #37393A;
  --map-road-1: #5A5B60; --map-road-2: #4E4F54; --map-road-3: #45464B; --map-road-4: #404145; --map-rail: #55565A;
  --map-building: #434448; --map-river: var(--map-water-tint);
  --google-bg: #131314; --google-edge: #8E918F; --google-ink: #E3E3E3;
  /* colour pass (DECISIONS #27): the action is the sextant's glass at Night; the six hues lifted for the dark ground */
  --action: #9EC0EE; --action-hover: #B8D3F9; --on-action: #0F1011; --action-ink: #A5C7F5; --action-wash: #1D2B44; --action-wash-hover: #243554;
  --rose:  #E993B2; --rose-ink:  #F1A3BF; --rose-wash:  #2E1D23;
  --plum:  #C69FDF; --plum-ink:  #D1ADE8; --plum-wash:  #271F2D;
  --sky:   #77BAE3; --sky-ink:   #8AC6EB; --sky-wash:   #15252F;
  --teal:  #74C1C0; --teal-ink:  #89CCCB; --teal-wash:  #112727;
  --green: #82C393; --green-ink: #94CEA3; --green-wash: #18271C;
  --ochre: #D4A965; --ochre-ink: #DEB77B; --ochre-wash: #2A2113;
  --map-water-tint: #121B23;
}

/* ======================= SCOPED THEMES: any subtree can opt in (the /styleguide sheet shows Day and Night side by
   side). Keep them identical to the Day colours of :root and to the Night blocks above — core.test.js checks. */
.theme-day {
  color-scheme: light;
  /* ground */
  --paper: #F4F3EF;        /* the page */
  --paper-2: #EAE8E2;      /* tracks, wells, secondary buttons */
  --paper-3: #E0DDD6;      /* hover on sunken */
  --raised: #FBFAF8;       /* dialogs, menus, the raised segment thumb */
  --raised-2: #EAE8E2;     /* a secondary button inside a raised surface */
  --raised-3: #E0DDD6;     /* …its hover */
  /* ink */
  --ink: #18191B;          /* text (the primary pill is --action since the colour pass) */
  --ink-2: #5A5C60;        /* secondary text (6.03:1) */
  --ink-faint: #8B8D91;    /* disabled + decoration ONLY (2.99:1): never text that matters */
  --line: #DEDCD5;         /* hairline (decorative) */
  --line-2: #CFCCC4;       /* a firmer hairline (decorative) */
  --edge: #86888C;         /* input / chip outline (3.2:1, non-text) */
  /* the signal: the sextant's index arm. It means now / here / careful (no other hue ever does) */
  --signal: #B0452A;
  --signal-wash: rgba(176, 69, 42, .10);
  --signal-ink: #963822;   /* signal TEXT on its wash (destructive, loss pills, ADMIN): ≥ 4.66:1 on every wash and hover */
  --on-signal: #F4F3EF;
  /* brass: the star only — the answer marker and the wordmark's star (DECISIONS #26c) */
  --brass: #B8892B;        /* the star (decoration) */
  /* over the panorama */
  --hud: rgba(244, 243, 239, .88);   /* + 18 px backdrop blur */
  --scrim: rgba(24, 25, 27, .32);
  --shadow-soft: 0 1px 2px rgba(24, 25, 27, .06), 0 8px 24px -12px rgba(24, 25, 27, .22);
  --shadow-pop: 0 2px 6px rgba(24, 25, 27, .06), 0 28px 64px -20px rgba(24, 25, 27, .34);
  --flag-edge: rgba(0, 0, 0, .10);
  /* data colours: team markers (always with a shape) and chart series only */
  --data-3: #3F6E78; --data-4: #7A5C8A;
  /* difficulty tiers T1–T8: a calm grey ramp (T1–T4 ink text, T5–T8 --depth-ink) */
  --depth-1: #EAE8E2; --depth-2: #E0DDD6; --depth-3: #D3D0C8; --depth-4: #C4C1B9;
  --depth-5: #6B6D71; --depth-6: #55575B; --depth-7: #3F4144; --depth-8: #2A2B2E;
  --depth-ink: #F4F3EF; --depth-ink-2: #E0DDD6;
  /* the flat guess map (land on a well, borders knocked out in the well colour) */
  --map-land: #D3D0C8; --map-water: var(--map-water-tint); --map-coast: #B4B1A9; --map-waterline: rgba(24, 25, 27, .08);
  --map-border: #EAE8E2; --map-border-4: #C4C1B9; --map-grat: #DEDCD5; --map-label: #3A3B3F;
  --map-label-2: #5A5C60; --map-water-label: #5A5C60; --map-grat-label: #8B8D91; --map-halo: #EAE8E2;
  --map-wood: #CBC8BF; --map-ice: #E4E2DC; --map-sand: #D9D5CA; --map-residential: #CCC9C1; --map-park: #C8C7BC;
  --map-road-1: #FBFAF8; --map-road-2: #F4F3EF; --map-road-3: #EAE8E2; --map-road-4: #E0DDD6; --map-rail: #A9A7A0;
  --map-building: #C6C3BB; --map-river: var(--map-water-tint);
  /* Google sign-in button (Google's own branding colours) */
  --google-bg: #FFFFFF; --google-edge: #747775; --google-ink: #1F1F1F;
  /* ---------- colour pass (DECISIONS #27; docs/redesign/colour/colour.md): one action colour + six calm hues ----------
     "a bit colourful … not too flashy but not completely monotone". Values are generated and WCAG-checked by
     docs/redesign/colour/contrast.mjs (OKLCH → sRGB): change a colour THERE, re-run, paste here. Grounds, ink,
     signal and brass are unchanged. */
  /* the action: the sextant's indigo frame. It fills ONE control per screen: the primary (Play, Guess, Challenge…) */
  --action: #2F4A86;            /* fill · its label 7.74:1 · as a shape on paper 7.74:1 */
  --action-hover: #3F5B99;      /* 5.97:1 under its label */
  --on-action: #F4F3EF;         /* the primary's label (= paper) */
  --action-ink: #355292;        /* action-coloured TEXT: 6.82 on paper, 6.08 on its wash */
  --action-wash: #DDE7F8;       /* the tonal button, the sidebar's current row, YOU, your leaderboard row */
  --action-wash-hover: #D1DDF4; /* tonal hover: 5.54 under action-ink */
  /* six hues: --X = MARK (dots, dial wedges, graph lines; ≥ 3:1) · --X-ink = TEXT (≥ 4.5:1 on paper, paper-2, raised
     and its own wash) · --X-wash = a tinted FILL (ink ≥ 13:1, ink-2 ≥ 5.4:1 on it). A hue says WHICH, never a state. */
  --rose:  #A75474; --rose-ink:  #8B3B5C; --rose-wash:  #FAE2EA;   /* Bullet · team 2 */
  --plum:  #88609F; --plum-ink:  #6E4885; --plum-wash:  #F0E5F7;   /* Blitz · BOT · team 4 */
  --sky:   #327BA3; --sky-ink:   #116289; --sky-wash:   #D9EDFA;   /* Rapid · info · the sea */
  --teal:  #2C8281; --teal-ink:  #056767; --teal-wash:  #D6F0EF;   /* Classical · MOD · team 3 */
  --green: #408455; --green-ink: #22683B; --green-wash: #DDEFE1;   /* up · won · online */
  --ochre: #8E6413; --ochre-ink: #6C4A04; --ochre-wash: #F4E8D6;   /* Daily (the noon sun) · CHART MAKER */
  --map-water-tint: #DDEBF3;    /* the barely-blue sea (flat maps, reveal, ASCII world): ink-2 on it 5.50, signal 4.62 */

}
.theme-night {
  color-scheme: dark;
  --paper: #0F1011; --paper-2: #1B1C1E; --paper-3: #26272A; --raised: #1B1C1E; --raised-2: #26272A; --raised-3: #303134;
  --ink: #EDEBE5; --ink-2: #A3A5A9; --ink-faint: #6C6E72;
  --line: #26272A; --line-2: #323336; --edge: #6C6E72;
  --signal: #E8714B; --signal-wash: rgba(232, 113, 75, .14); --signal-ink: #EF8A69; --on-signal: #0F1011;
  --brass: #D6A64A;
  --hud: rgba(15, 16, 17, .84); --scrim: rgba(0, 0, 0, .56);
  --shadow-soft: none;
  --shadow-pop: 0 0 0 1px #26272A, 0 28px 64px -20px rgba(0, 0, 0, .7);
  --flag-edge: rgba(255, 255, 255, .16);
  --data-3: #7FB0B8; --data-4: #B9A0C8;
  --depth-1: #1B1C1E; --depth-2: #222326; --depth-3: #2A2B2E; --depth-4: #323336;
  --depth-5: #3B3C40; --depth-6: #45464A; --depth-7: #505155; --depth-8: #5C5D62;
  --depth-ink: #EDEBE5; --depth-ink-2: #C9C7C1;
  --map-land: #3A3B3F; --map-water: var(--map-water-tint); --map-coast: #4C4D52; --map-waterline: rgba(237, 235, 229, .06);
  --map-border: #1B1C1E; --map-border-4: #2E2F33; --map-grat: #26272A; --map-label: #EDEBE5;
  --map-label-2: #A3A5A9; --map-water-label: #A3A5A9; --map-grat-label: #6C6E72; --map-halo: #1B1C1E;
  --map-wood: #36373B; --map-ice: #45464A; --map-sand: #3E3E3F; --map-residential: #403F43; --map-park: #37393A;
  --map-road-1: #5A5B60; --map-road-2: #4E4F54; --map-road-3: #45464B; --map-road-4: #404145; --map-rail: #55565A;
  --map-building: #434448; --map-river: var(--map-water-tint);
  --google-bg: #131314; --google-edge: #8E918F; --google-ink: #E3E3E3;
  /* colour pass (DECISIONS #27): the action is the sextant's glass at Night; the six hues lifted for the dark ground */
  --action: #9EC0EE; --action-hover: #B8D3F9; --on-action: #0F1011; --action-ink: #A5C7F5; --action-wash: #1D2B44; --action-wash-hover: #243554;
  --rose:  #E993B2; --rose-ink:  #F1A3BF; --rose-wash:  #2E1D23;
  --plum:  #C69FDF; --plum-ink:  #D1ADE8; --plum-wash:  #271F2D;
  --sky:   #77BAE3; --sky-ink:   #8AC6EB; --sky-wash:   #15252F;
  --teal:  #74C1C0; --teal-ink:  #89CCCB; --teal-wash:  #112727;
  --green: #82C393; --green-ink: #94CEA3; --green-wash: #18271C;
  --ochre: #D4A965; --ochre-ink: #DEB77B; --ochre-wash: #2A2113;
  --map-water-tint: #121B23;
}

/* ======================= LEGACY ALIASES — resolved per theme scope (do not use in new code; FINAL.md §3.4) ======================= */
:root, .theme-day, .theme-night {
  --page: var(--paper); --card: var(--paper); --sunken: var(--paper-2);
  --ink-3: var(--ink-2);                         /* old "muted text": stays AA */
  --rule: var(--line); --rule-2: var(--line-2); --field: var(--edge);
  --chrome: var(--paper); --chrome-2: var(--paper-2); --chrome-3: var(--paper-3); --chrome-edge: var(--line);
  --chrome-ink: var(--ink); --chrome-ink-2: var(--ink-2);
  --accent: var(--ink); --accent-hover: color-mix(in srgb, var(--ink) 86%, var(--paper)); --accent-ink: var(--paper); --accent-soft: var(--paper-2);
  --cta: var(--action); --cta-hover: var(--action-hover); --cta-edge: var(--action); --cta-ink: var(--on-action);   /* the old CTA IS the primary */
  --brass-ink: var(--ink-2);
  --win: var(--up); --win-soft: var(--up-wash);   /* an old "win" really is a gain */
  --loss: var(--signal); --loss-soft: var(--signal-wash);
  --warn: var(--signal); --warn-soft: var(--signal-wash);
  --info: var(--ink); --info-soft: var(--paper-2);
  --self: var(--signal); --self-soft: var(--signal-wash);
  --opp: var(--ink); --opp-soft: var(--paper-2);
  --team-1: var(--action); --team-2: var(--rose); --team-3: var(--teal); --team-4: var(--plum);   /* Blue ● Red ◆ Teal ▲ Violet ■ — the
     teams' spoken names (game/model.js); the shape always goes with the colour */
  --focus: var(--signal);
  --shadow-1: none; --shadow-2: var(--shadow-pop);
  --grain: none;
  --logo-lockup-on-chrome: url(../img/brand/geoguess-lockup.svg);
}

/* ======================= ROLES (colour pass, DECISIONS #27) — what each hue means, resolved per theme scope.
   New code uses THESE names (colour.md §2.2). Rules: text in a hue uses --X-ink, shapes --X, fills --X-wash;
   colour is never the only signal (a word, sign, ring, weight, dot or shape always goes with it). */
:root, .theme-day, .theme-night {
  /* time controls: identity, never state (Bullet → Daily runs round the wheel, warm pink to the noon sun) */
  --tc-bullet: var(--rose);     --tc-bullet-ink: var(--rose-ink);     --tc-bullet-wash: var(--rose-wash);
  --tc-blitz: var(--plum);      --tc-blitz-ink: var(--plum-ink);      --tc-blitz-wash: var(--plum-wash);
  --tc-rapid: var(--sky);       --tc-rapid-ink: var(--sky-ink);       --tc-rapid-wash: var(--sky-wash);
  --tc-classical: var(--teal);  --tc-classical-ink: var(--teal-ink);  --tc-classical-wash: var(--teal-wash);
  --tc-daily: var(--ochre);     --tc-daily-ink: var(--ochre-ink);     --tc-daily-wash: var(--ochre-wash);
  /* outcomes: gains are green; losses and draws stay quiet ink-2 (the word and the sign carry them) */
  --up: var(--green-ink); --up-mark: var(--green); --up-wash: var(--green-wash);
  --down: var(--ink-2); --even: var(--ink-2);
  /* people: presence dot (always with "online now") / ring (always with "in a game") */
  --online: var(--green); --playing: var(--action);
  /* the landing's ASCII world: the sea's dot field, graticule, glints and limb; land glyphs stay ink */
  --ascii-sea: var(--sky); --ascii-land: var(--ink);
}

/* ---------- user preferences ---------- */
@media (prefers-contrast: more) {
  :root:not(#_) { --ink-2: var(--ink); --line: var(--edge); --line-2: var(--edge); --rose-ink: var(--ink); --plum-ink: var(--ink); --sky-ink: var(--ink); --teal-ink: var(--ink); --green-ink: var(--ink); --ochre-ink: var(--ink); --action-ink: var(--ink); } /* :not(#_) outranks the Night blocks; hue text → ink */
}
/* Settings → Appearance → High contrast (gate.js applyAppearance sets the attribute): the same overrides */
:root[data-contrast="more"]:not(#_) { --ink-2: var(--ink); --line: var(--edge); --line-2: var(--edge); --rose-ink: var(--ink); --plum-ink: var(--ink); --sky-ink: var(--ink); --teal-ink: var(--ink); --green-ink: var(--ink); --ochre-ink: var(--ink); --action-ink: var(--ink); }
@media (prefers-reduced-motion: reduce) {
  :root { --t-press: 0ms; --t-fast: 0ms; --t-base: 0ms; --t-panel: 0ms; --t-reveal: 0ms; }
}
:root[data-motion="reduce"] { --t-press: 0ms; --t-fast: 0ms; --t-base: 0ms; --t-panel: 0ms; --t-reveal: 0ms; }
