/* =============================================================================
   tokens.css — LexiLayers design token layer  (Phase 0 foundation)
   -----------------------------------------------------------------------------
   SINGLE SOURCE OF TRUTH for color / elevation / radius / type.
   See docs/design_token_system.md for the full plan.

   Two layers:
     1. PRIMITIVES  — the raw palette. Components must NOT reference these.
     2. SEMANTIC     — what components actually use (--surface, --ink, --mode …).

   Loaded FIRST (before lexilayers.css) on purpose: because it is the lowest-
   priority stylesheet, it can never override an existing rule, so adding it is
   visually a no-op until a page is deliberately migrated to consume the tokens.

   THEMING
     • Light is the :root default. Dark redefines the SEMANTIC layer under
       body.dark-mode (matching the site's existing dark-mode class).
     • Per-mode accent: set body[data-mode="sp|mp|vs|fo|daily"] to recolor the
       --mode* tokens. No data-mode => --mode falls back to --primary (blue).

   To recolor the whole site later: edit the PRIMITIVES. To restyle one mode:
   edit that mode's data-mode block. Nothing else needs to change.

   TYPOGRAPHY
     • --display = brand display face (Luckiest Guy) for headings/wordmark/tiles.
     • --ui      = clean body/UI face.
     To swap the site's type later, change the @font-face below or repoint the
     token. Luckiest Guy is bundled at /assets/fonts and cached by the SW.
   ============================================================================= */

@font-face {
  font-family: 'Luckiest Guy';
  /* Relative path (matches the url() convention used elsewhere in this
     codebase's CSS, e.g. lexilayers.css's "../images/..." references) —
     resolves against tokens.css's own location (assets/css/), not the
     domain root. An absolute "/assets/fonts/..." path can silently 404
     under a reverse proxy / subpath deployment, with no visible error:
     the browser just falls back to the next font in the stack. */
  src: url('../fonts/LuckiestGuy-Regular.ttf') format('truetype');
  font-weight: 400;
  font-display: swap;
}

:root {
  /* ----------------------------------------------------------------------- */
  /* 1. PRIMITIVES (raw palette — never reference directly in components)     */
  /* ----------------------------------------------------------------------- */
  --c-slate-950:#0E121C; --c-slate-900:#141824; --c-slate-850:#161C29;
  --c-slate-800:#1B2231; --c-slate-700:#252D3E; --c-slate-600:#3A4252;
  --c-slate-500:#697083; --c-slate-400:#98A0B2; --c-slate-300:#C9CEDC;
  --c-slate-200:#E4E8F2; --c-slate-150:#EAEEF7; --c-slate-100:#EEF1F8;
  --c-slate-050:#F4F6FB; --c-white:#FFFFFF;

  --c-blue-600:#2E3FC4;  --c-blue-500:#3D50E0;  --c-blue-400:#5C6DF2;  --c-blue-050:#EDEFFE;
  --c-amber-600:#C07F1C; --c-amber-500:#E19A2E; --c-amber-400:#EDB251; --c-amber-050:#FBF2E1;
  --c-green-600:#178050; --c-green-500:#209A5E; --c-green-400:#33BE7C; --c-green-050:#E5F5EC;
  --c-teal-600:#235FB0;  --c-teal-500:#2F76D6;  --c-teal-400:#4F91E8;  --c-teal-050:#E7F0FB;
  --c-violet-600:#6441B8;--c-violet-500:#7B54D6;--c-violet-400:#9B78EC;--c-violet-050:#F0EBFB;
  --c-coral-600:#C23F3A; --c-coral-500:#DD514B; --c-coral-400:#EC6A63; --c-coral-050:#FBEAE9;

  --c-gold:#E3A73A; --c-silver:#9AA6BD; --c-bronze:#C58146;

  /* ----------------------------------------------------------------------- */
  /* 2. SEMANTIC TOKENS — LIGHT (default). Components use ONLY these.         */
  /* ----------------------------------------------------------------------- */
  /* Surfaces */
  --paper:#F4F6FB; --paper-2:#EAEEF7;
  --surface:#FFFFFF; --surface-2:#F7F9FD;
  --line:#E4E8F2; --line-2:#EEF1F8;

  /* Text */
  --ink:#141824; --ink-2:#3A4252; --muted:#697083; --faint:#98A0B2;

  /* Brand */
  --primary:#3D50E0; --primary-600:#2E3FC4; --primary-050:#EDEFFE;
  --accent:#E19A2E; --accent-050:#FBF2E1;
  --good:#1C9B6A; --good-050:#E5F5EE;
  --bad:#DC2626; --bad-050:#FEE2E2;

  /* Per-mode accent palettes (named). These auto-theme: each is redefined
     under body.dark-mode, so [data-accent] blocks below need no dark variant. */
  --m-sp:#209A5E;    --m-sp-600:#178050;    --m-sp-050:#E5F5EC;    --m-sp-tint:#F1FAF5;
  --m-mp:#2F76D6;    --m-mp-600:#235FB0;    --m-mp-050:#E7F0FB;    --m-mp-tint:#F3F7FD;
  --m-vs:#7B54D6;    --m-vs-600:#6441B8;    --m-vs-050:#F0EBFB;    --m-vs-tint:#F7F4FD;
  --m-fo:#DD514B;    --m-fo-600:#C23F3A;    --m-fo-050:#FBEAE9;    --m-fo-tint:#FDF3F2;
  --m-daily:#E19A2E; --m-daily-600:#C07F1C; --m-daily-050:#FBF2E1; --m-daily-tint:#FDF8EE;

  /* Active mode accent — default = primary (blue). Set data-accent on <body>
     or any container to switch it (see [data-accent] blocks below). */
  --mode:#3D50E0; --mode-600:#2E3FC4; --mode-050:#EDEFFE; --mode-tint:#F5F6FE;

  /* Rank medals */
  --gold:#E3A73A; --silver:#9AA6BD; --bronze:#C58146;

  /* Chat avatar identity colors (Global Chat fallback avatar / activity feed) — fixed
     per-user identity swatches, same "named token even though themes don't change it"
     convention as the rank medals above, not raw hex inline in lexilayers.css. */
  --avatar-1:#E03131; --avatar-2:#7048E8; --avatar-3:#2F9E44; --avatar-4:#1971C2; --avatar-5:#F08C00;
  --avatar-6:#C2255C; --avatar-7:#0C8599; --avatar-8:#66A80F;

  /* Ranked-tier badges — bronze/silver/gold share the rank-medal colors above;
     these extend the same family for the higher tiers. */
  --tier-platinum:#7A7FA0; --tier-diamond:#2BA9D6; --tier-master:#8E5FD6; --tier-grandmaster:#D6524A;

  /* Time Attack's own established teal/cyan brand (a Face-Off variant, but kept visually
     distinct from --m-fo coral, same reasoning as Bonanza staying violet) — not part of the
     5-mode-accent system. */
  --ta:#00897B; --ta-600:#00695C; --ta-050:#E0F2F1;

  /* Tactile tile primitive */
  --tile-face:#F9FAFE; --tile-face2:#EDF0F9; --tile-edge:#DBE0EF;
  --tile-shadow:#CFD6E8; --tile-ink:#141824;

  /* Dark utility bar (ticker/footer) */
  --bar-bg:#141824; --bar-ink:#C9CEDC; --bar-ink-2:#889;

  /* Top-ticker accents — distinct brand colors (not part of the 5-mode-accent
     system; these predate it and are used only on the always-dark ticker bar,
     so no light/dark split is needed). */
  --tk-daily:#10b981; --tk-fo:#a78bfa; --tk-ta:#ff8c5a;

  /* Word Spotlight modal — its own deliberate violet brand identity (distinct from
     --primary/any mode accent), needs a real light/dark split unlike the ticker accents
     above. --wsm-phonetic doesn't change between modes (verified against the original
     hand-tuned values), the rest do. */
  --wsm-surface:#fff; --wsm-border:transparent; --wsm-header-border:#ede9fe;
  --wsm-word:#3b0764; --wsm-phonetic:#a78bfa; --wsm-phonetic-border:#ddd6fe;
  --wsm-audio-bg:#7c3aed; --wsm-audio-hover:#6d28d9;
  --wsm-close-hover:#374151; --wsm-tag-text:#6d28d9; --wsm-tag-bg:#ede9fe;

  /* Elevation */
  --shadow:0 1px 2px rgba(20,24,36,.04), 0 6px 20px rgba(20,24,36,.06);
  --shadow-lift:0 2px 4px rgba(20,24,36,.05), 0 16px 36px rgba(20,24,36,.11);

  /* Geometry / type */
  --r-sm:10px; --r:12px; --r-lg:18px;
  --maxw:1220px;
  --font: system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  /* Typography faces (swappable) */
  --ui: system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --display: 'Luckiest Guy', var(--ui);

  /* Responsive breakpoints (reference values — used in @media literals) */
  --bp-phone:480px; --bp-tablet:768px; --bp-laptop:1024px;

  /* ----------------------------------------------------------------------- */
  /* AUTH MODAL — fixed constants, NOT theme/dark-mode-reactive on purpose.   */
  /* The login/register box is deliberately kept light-styled regardless of  */
  /* site theme or dark mode (see the "Auth box should keep light styling in */
  /* dark mode" comment on its rules in lexilayers.css). These are named     */
  /* tokens purely to centralize the values in one place — never redefine    */
  /* these under [data-theme] or body.dark-mode.                            */
  /* ----------------------------------------------------------------------- */
  --auth-surface:#fff; --auth-shadow:#0003;
  --auth-text:#333; --auth-text-muted:#666; --auth-hint:#999; --auth-divider-text:#888;
  --auth-border:#e0e0e0; --auth-divider-line:#ccc;
  --auth-accent:#1487c6;
  --auth-error-bg-1:#f8d7da; --auth-error-bg-2:#f5c6cb; --auth-error-text:#721c24;
  --auth-success-bg-1:#d4edda; --auth-success-bg-2:#c3e6cb; --auth-success-text:#155724;
  --auth-signup-bg:#18a2ee; --auth-clear-bg:hsl(2, 74%, 48%); --auth-clear-text:#444;
}

/* --------------------------------------------------------------------------- */
/* SEMANTIC TOKENS — DARK. Redefines the semantic layer only; primitives stay. */
/* --------------------------------------------------------------------------- */
body.dark-mode {
  --paper:#0E121C; --paper-2:#151B28;
  --surface:#161C29; --surface-2:#1B2231;
  --line:#262E3F; --line-2:#212838;

  --ink:#ECEFF7; --ink-2:#BFC6D6; --muted:#8A93A8; --faint:#666F82;

  --primary:#5C6DF2; --primary-600:#4a5ce6; --primary-050:#1E2547;
  --accent:#EDB251; --accent-050:#2C2413;
  --good:#2FB37E; --good-050:#12261E;
  --bad:#F87171; --bad-050:#3A1616;

  --mode:#5C6DF2; --mode-600:#4a5ce6; --mode-050:#1E2547; --mode-tint:#161C29;

  --gold:#EBB457; --silver:#8C97AD; --bronze:#C8894F;

  /* Chat avatar identity colors — brighter dark-mode variants, same reasoning as gold/
     silver/bronze above. */
  --avatar-1:#FF6B6B; --avatar-2:#9775FA; --avatar-3:#51CF66; --avatar-4:#4DABF7; --avatar-5:#FFA94D;
  --avatar-6:#F06595; --avatar-7:#3BC9DB; --avatar-8:#A9E34B;

  --tier-platinum:#9DA1C2; --tier-diamond:#5DC3EA; --tier-master:#A883EC; --tier-grandmaster:#EC6A63;

  --ta:#2BBBAD; --ta-600:#1F9E92; --ta-050:#12312F;

  --tile-face:#252D3E; --tile-face2:#1D2433; --tile-edge:#333C51;
  --tile-shadow:#0D1119; --tile-ink:#ECEFF7;

  --bar-bg:#080B12; --bar-ink:#AEB6C7; --bar-ink-2:#5b6376;

  --shadow:0 1px 2px rgba(0,0,0,.3), 0 8px 24px rgba(0,0,0,.35);
  --shadow-lift:0 2px 6px rgba(0,0,0,.35), 0 18px 40px rgba(0,0,0,.5);

  /* Dark per-mode palettes (the [data-accent] blocks resolve through these). */
  --m-sp:#33BE7C;    --m-sp-600:#28a56b;    --m-sp-050:#12291F;    --m-sp-tint:#12211A;
  --m-mp:#4F91E8;    --m-mp-600:#3f7bd0;    --m-mp-050:#152538;    --m-mp-tint:#131C2B;
  --m-vs:#9B78EC;    --m-vs-600:#8460d4;    --m-vs-050:#221A3A;    --m-vs-tint:#1A1730;
  --m-fo:#EC6A63;    --m-fo-600:#d4544d;    --m-fo-050:#301A1A;    --m-fo-tint:#261414;
  --m-daily:#EDB251; --m-daily-600:#d29a3c; --m-daily-050:#2C2413; --m-daily-tint:#221D10;

  /* Word Spotlight modal dark variant (see the light-mode declaration for context). */
  --wsm-surface:#1e1b2e; --wsm-border:#3b2d6e; --wsm-header-border:#3b2d6e;
  --wsm-word:#e9d5ff; --wsm-phonetic-border:#4c1d95;
  --wsm-audio-bg:#6d28d9; --wsm-audio-hover:#7c3aed;
  --wsm-close-hover:#e9d5ff; --wsm-tag-text:#c4b5fd; --wsm-tag-bg:#3b2d6e;
}

/* --------------------------------------------------------------------------- */
/* PER-MODE ACCENT — set data-accent="sp|mp|vs|fo|daily" on <body> OR any       */
/* container. Because it maps --mode* onto the auto-theming --m-* palettes, a    */
/* single block covers BOTH light and dark. A distinct attribute (data-accent,  */
/* not data-mode) avoids colliding with the SP speed buttons' data-mode.        */
/* --------------------------------------------------------------------------- */
[data-accent="sp"]    { --mode:var(--m-sp);    --mode-600:var(--m-sp-600);    --mode-050:var(--m-sp-050);    --mode-tint:var(--m-sp-tint); }
[data-accent="mp"]    { --mode:var(--m-mp);    --mode-600:var(--m-mp-600);    --mode-050:var(--m-mp-050);    --mode-tint:var(--m-mp-tint); }
[data-accent="vs"]    { --mode:var(--m-vs);    --mode-600:var(--m-vs-600);    --mode-050:var(--m-vs-050);    --mode-tint:var(--m-vs-tint); }
[data-accent="fo"]    { --mode:var(--m-fo);    --mode-600:var(--m-fo-600);    --mode-050:var(--m-fo-050);    --mode-tint:var(--m-fo-tint); }
[data-accent="daily"] { --mode:var(--m-daily); --mode-600:var(--m-daily-600); --mode-050:var(--m-daily-050); --mode-tint:var(--m-daily-tint); }
/* Time Attack's own teal (--ta) piggybacks on the same [data-accent] mechanism so its
   mode-select card gets the standard top-stripe + quiet-tinted-button treatment for free,
   even though --ta lives outside the 5-mode-accent system everywhere else. */
[data-accent="ta"]    { --mode:var(--ta);    --mode-600:var(--ta-600);    --mode-050:var(--ta-050);    --mode-tint:var(--ta-050); }

/* ============================================================================= */
/* SITE THEMES — admin-selectable, site-wide color skins.                        */
/* Set html[data-theme="…"] (done server-side / by an inline <head> script before */
/* first paint, mirroring how body.dark-mode is applied) to swap the NEUTRAL      */
/* base + brand/primary + tile tokens for both light and dark. The 5 per-mode     */
/* --m-* accents are DELIBERATELY untouched — SP stays green, MP blue, etc,       */
/* in every theme, so a theme changes the site's overall vibe, not what a mode    */
/* "means". No data-theme attribute = the default "cool" look (the :root/         */
/* body.dark-mode values above). See docs/design_token_system.md for the plan.    */
/* ============================================================================= */

/* ---- "warm": cream/terracotta ---- */
html[data-theme="warm"] {
  --paper:#FBF6EC; --paper-2:#F5EBD9;
  --surface:#FFFDF8; --surface-2:#F8F0E0;
  --line:#EDE0C4; --line-2:#F3E9D3;
  --ink:#2B211A; --ink-2:#4A3D31; --muted:#7A6C58; --faint:#A99979;
  --primary:#D9762E; --primary-600:#B85F20; --primary-050:#FBE8D6;
  --tile-face:#FFF8ED; --tile-face2:#F5E9D3; --tile-edge:#E6D3AE;
  --tile-shadow:#D8C29A; --tile-ink:#2B211A;
}
html[data-theme="warm"] body.dark-mode {
  --paper:#1D1712; --paper-2:#241C15;
  --surface:#2A2119; --surface-2:#322820;
  --line:#3D3122; --line-2:#362B1F;
  --ink:#F5EAD9; --ink-2:#D9C7AC; --muted:#A9967D; --faint:#7A6C58;
  --primary:#E8934A; --primary-600:#D97E30; --primary-050:#3A2814;
  --tile-face:#3A2E22; --tile-face2:#30251B; --tile-edge:#4A3B29;
  --tile-shadow:#150F0A; --tile-ink:#F5EAD9;
}

/* ---- "slate": neutral gray, muted ---- */
html[data-theme="slate"] {
  --paper:#F1F2F4; --paper-2:#E7E9EC;
  --surface:#FFFFFF; --surface-2:#F5F6F8;
  --line:#E0E2E6; --line-2:#EAEBEE;
  --ink:#1C1E22; --ink-2:#45484F; --muted:#6B6F78; --faint:#9CA0A8;
  --primary:#4B5563; --primary-600:#374151; --primary-050:#E9EBEE;
  --tile-face:#FAFAFB; --tile-face2:#EFF0F2; --tile-edge:#DCDEE2;
  --tile-shadow:#CACDD3; --tile-ink:#1C1E22;
}
html[data-theme="slate"] body.dark-mode {
  --paper:#121316; --paper-2:#18191D;
  --surface:#1D1F24; --surface-2:#24262C;
  --line:#2E3036; --line-2:#292B31;
  --ink:#EDEEF0; --ink-2:#C4C6CB; --muted:#8B8E96; --faint:#5F626A;
  --primary:#9CA3AF; --primary-600:#C0C5CC; --primary-050:#2A2C31;
  --tile-face:#26282E; --tile-face2:#1F2126; --tile-edge:#34363D;
  --tile-shadow:#0B0C0E; --tile-ink:#EDEEF0;
}

/* ---- "arena": teal/navy esports vibe ---- */
html[data-theme="arena"] {
  --paper:#EAF6F6; --paper-2:#DCEEEF;
  --surface:#FFFFFF; --surface-2:#F0F9FA;
  --line:#D3E8E9; --line-2:#E3F2F3;
  --ink:#0D1B2E; --ink-2:#1F3A52; --muted:#4A6572; --faint:#8AA3AC;
  --primary:#14B8A6; --primary-600:#0F9488; --primary-050:#D7F5F1;
  --tile-face:#F5FBFB; --tile-face2:#E8F5F4; --tile-edge:#C7E5E3;
  --tile-shadow:#A8D2CE; --tile-ink:#0D1B2E;
}
html[data-theme="arena"] body.dark-mode {
  --paper:#0D1B2E; --paper-2:#12233A;
  --surface:#16283F; --surface-2:#1B3049;
  --line:#23405C; --line-2:#1E3550;
  --ink:#E8F4F3; --ink-2:#B8D4D1; --muted:#7FA3A0; --faint:#4D7370;
  --primary:#2DD4BF; --primary-600:#14B8A6; --primary-050:#123832;
  --tile-face:#1B3049; --tile-face2:#16283F; --tile-edge:#2A4964;
  --tile-shadow:#0A1520; --tile-ink:#E8F4F3;
}

/* ---- "cozy": cream/mustard-gold ---- */
html[data-theme="cozy"] {
  --paper:#F7EFDD; --paper-2:#F0E4CA;
  --surface:#FFFFFF; --surface-2:#FBF4E6;
  --line:#E8DBBE; --line-2:#F0E6CE;
  --ink:#2E2A1E; --ink-2:#52493A; --muted:#86795F; --faint:#B3A688;
  --primary:#D4A24C; --primary-600:#B3853A; --primary-050:#F7E7C9;
  --tile-face:#FFFBF2; --tile-face2:#F5EAD0; --tile-edge:#E4D2A6;
  --tile-shadow:#D1BC8C; --tile-ink:#2E2A1E;
}
html[data-theme="cozy"] body.dark-mode {
  --paper:#241F16; --paper-2:#2C2619;
  --surface:#332C1E; --surface-2:#3B3323;
  --line:#4A4029; --line-2:#423923;
  --ink:#F5EAD0; --ink-2:#D6C7A0; --muted:#A69670; --faint:#776950;
  --primary:#E0B563; --primary-600:#C99A46; --primary-050:#3D2F14;
  --tile-face:#3B3323; --tile-face2:#332C1E; --tile-edge:#4F4429;
  --tile-shadow:#161208; --tile-ink:#F5EAD0;
}

/* ---- "classic": the original pre-redesign site colors (light-blue gradient
   page + orange accent), kept on the NEW layout/font/tile-cards. Also flips
   the landing mode-card buttons back to solid-filled (see lexilayers.css,
   scoped under this same [data-theme="classic"]) since the original site
   never used the new tinted/outline button style. */
html[data-theme="classic"] {
  --paper: linear-gradient(180deg, #bcdcf0 0%, #dceaf5 40%, #f3f8fc 100%);
  --paper-2:#eaf3fb;
  --surface:#FFFFFF; --surface-2:#F5F9FC;
  --line:#DCE8F2; --line-2:#EAF1F8;
  --ink:#16233F; --ink-2:#2C3E5C; --muted:#5B6B85; --faint:#93A2B8;
  --primary:#F08A24; --primary-600:#D9721A; --primary-050:#FDEBD8;
  --tile-face:#F7E8C4; --tile-face2:#ECD099; --tile-edge:#C6B791;
  --tile-shadow:#B8A67D; --tile-ink:#16233F;
}
html[data-theme="classic"] body.dark-mode {
  --paper:#0F1B30; --paper-2:#13223B;
  --surface:#17273F; --surface-2:#1C2E48;
  --line:#2A3C58; --line-2:#24344C;
  --ink:#EEF3FA; --ink-2:#C3CFE0; --muted:#8695AE; --faint:#56607A;
  --primary:#FFA94D; --primary-600:#F08A24; --primary-050:#3A2A14;
  --tile-face:#3A2E22; --tile-face2:#30251B; --tile-edge:#4A3B29;
  --tile-shadow:#150F0A; --tile-ink:#EEF3FA;
}

/* ---- Seasonal: "seasonal-xmas" (Christmas — pine green + red) ---- */
html[data-theme="seasonal-xmas"] {
  --paper:#F7F3EE; --paper-2:#EFE7DC;
  --surface:#FFFFFF; --surface-2:#FAF6F0;
  --line:#E3D6C8; --line-2:#F0E8DC;
  --ink:#1B3A2A; --ink-2:#2F5240; --muted:#5C7A68; --faint:#96AC9E;
  /* --primary was a red (#B3242C) close enough to the site's hardcoded danger color
     (.btn-danger, #e74c3c) that every ordinary button/link/CTA site-wide (var(--primary) is
     used ~99 times across the CSS) read as a warning/delete action during this theme, not just
     "festive". Swapped to a holly green matching this theme's already-green --ink family; red
     stays as pure decoration elsewhere (backgrounds, ribbons) untouched. */
  --primary:#1F7A43; --primary-600:#186336; --primary-050:#DFF3E6;
  --tile-face:#FFFDF9; --tile-face2:#F3ECDD; --tile-edge:#E0CFAE;
  --tile-shadow:#CBAF7E; --tile-ink:#1B3A2A;
}
html[data-theme="seasonal-xmas"] body.dark-mode {
  --paper:#0F1F17; --paper-2:#15281D;
  --surface:#1A3024; --surface-2:#20392B;
  --line:#2C4636; --line-2:#263D2F;
  --ink:#F2EFE5; --ink-2:#CBD9CD; --muted:#8FA997; --faint:#5C7A68;
  --primary:#3FAE6C; --primary-600:#2F9457; --primary-050:#122A1C;
  --tile-face:#20392B; --tile-face2:#1A3024; --tile-edge:#2F4C3B;
  --tile-shadow:#0A150F; --tile-ink:#F2EFE5;
}

/* ---- Seasonal: "seasonal-stpatricks" (St. Patrick's Day — kelly green) ---- */
html[data-theme="seasonal-stpatricks"] {
  --paper:#F1F8F0; --paper-2:#E4F1E2;
  --surface:#FFFFFF; --surface-2:#F5FAF4;
  --line:#D3E8CE; --line-2:#E9F4E6;
  --ink:#14351F; --ink-2:#2A5136; --muted:#5F8468; --faint:#9BB8A0;
  --primary:#1E8E3E; --primary-600:#17702F; --primary-050:#E1F5E4;
  --tile-face:#FBFFF9; --tile-face2:#EFF7EA; --tile-edge:#D9E9D0;
  --tile-shadow:#C3D9B5; --tile-ink:#14351F;
}
html[data-theme="seasonal-stpatricks"] body.dark-mode {
  --paper:#0C1F10; --paper-2:#122A16;
  --surface:#17351D; --surface-2:#1D4023;
  --line:#2A5433; --line-2:#23492A;
  --ink:#EAF5E9; --ink-2:#BFDCC2; --muted:#7EA486; --faint:#4E7256;
  --primary:#34C759; --primary-600:#26A946; --primary-050:#123319;
  --tile-face:#1D4023; --tile-face2:#17351D; --tile-edge:#2D5233;
  --tile-shadow:#081208; --tile-ink:#EAF5E9;
}

/* ---- Seasonal: "seasonal-halloween" (orange + spooky purple). Deliberately
   NOT bright/cheerful even in "light" mode — genuinely dark (not just a
   medium-dusk compromise), so the toggle still does something (dark mode
   goes darker still) without ever looking like a cheerful daytime theme.
   --tile-face/--tile-ink are flipped dark-wood/light-cream here (unlike
   every other theme, where tiles stay light) so components that use
   --tile-face as a background (e.g. .daily-history-item) stay readable
   with the shared --ink text color instead of clashing cream-on-cream. */
html[data-theme="seasonal-halloween"] {
  --paper:#1D1526; --paper-2:#241B30;
  --surface:#2A2038; --surface-2:#302640;
  --line:#3D2F4E; --line-2:#362845;
  --ink:#F5EAD9; --ink-2:#D9C7B0; --muted:#B39FC7; --faint:#7A628F;
  --primary:#FF8A3D; --primary-600:#E8681F; --primary-050:#3A2414;
  --tile-face:#5A3818; --tile-face2:#4A2E12; --tile-edge:#6B4A22;
  --tile-shadow:#2A1A0A; --tile-ink:#F5EAD9;
}
html[data-theme="seasonal-halloween"] body.dark-mode {
  --paper:#0D0812; --paper-2:#120A18;
  --surface:#17101F; --surface-2:#1D1526;
  --line:#2C2038; --line-2:#251A30;
  --ink:#F2E9DE; --ink-2:#C7B8D6; --muted:#8E7A9E; --faint:#5C4C6E;
  --primary:#FF8A3D; --primary-600:#E8681F; --primary-050:#3A2414;
  --tile-face:#4A2E12; --tile-face2:#3A2410; --tile-edge:#6B4A22;
  --tile-shadow:#150F0A; --tile-ink:#F2E9DE;
}

/* ---- Seasonal: "seasonal-valentines" (pink/rose) ---- */
html[data-theme="seasonal-valentines"] {
  --paper:#FDF1F3; --paper-2:#FBE4E8;
  --surface:#FFFFFF; --surface-2:#FEF6F7;
  --line:#F5D6DD; --line-2:#FAEBEE;
  --ink:#3A1620; --ink-2:#5C2C38; --muted:#8C5E68; --faint:#C79AA5;
  /* --primary's original rose-red (#D6336C) sat close enough to the site's hardcoded danger
     color (.btn-danger, #e74c3c) to read as a warning/delete action on ordinary buttons
     site-wide (var(--primary) drives ~99 uses across the CSS), not just "romantic". Shifted
     hue further toward magenta/pink and away from red so it reads clearly as Valentine's pink
     rather than danger-red; red/rose stays as decoration elsewhere untouched. */
  --primary:#DB4A9C; --primary-600:#BB3781; --primary-050:#FBE3F1;
  --tile-face:#FFF5F7; --tile-face2:#F9E2E8; --tile-edge:#EFC9D3;
  --tile-shadow:#DDA9B7; --tile-ink:#3A1620;
}
html[data-theme="seasonal-valentines"] body.dark-mode {
  --paper:#22101A; --paper-2:#2A1420;
  --surface:#331926; --surface-2:#3D1F2E;
  --line:#502A3B; --line-2:#452334;
  --ink:#FBE9EE; --ink-2:#DDB5C3; --muted:#A2707F; --faint:#6B4552;
  --primary:#FF74C4; --primary-600:#F158AC; --primary-050:#3D1830;
  --tile-face:#3D1F2E; --tile-face2:#331926; --tile-edge:#502A3B;
  --tile-shadow:#170A11; --tile-ink:#FBE9EE;
}

/* ---- Seasonal: "seasonal-easter" (pastel lilac + spring green) ---- */
html[data-theme="seasonal-easter"] {
  --paper:#FBF6FC; --paper-2:#F3E9F6;
  --surface:#FFFFFF; --surface-2:#FAF3FB;
  --line:#E8D6EE; --line-2:#F1E4F5;
  --ink:#3A2A42; --ink-2:#5C4566; --muted:#8B7291; --faint:#C6AECC;
  --primary:#8E5FC9; --primary-600:#7248A8; --primary-050:#EDE0F7;
  --tile-face:#FFF8E8; --tile-face2:#FCEFC9; --tile-edge:#F0DFA0;
  --tile-shadow:#D9C57E; --tile-ink:#3A2A42;
}
html[data-theme="seasonal-easter"] body.dark-mode {
  --paper:#1E1526; --paper-2:#251A30;
  --surface:#2C2038; --surface-2:#332640;
  --line:#3F2E52; --line-2:#38284A;
  --ink:#F2E9F7; --ink-2:#D4C0DE; --muted:#9C82A8; --faint:#65506F;
  --primary:#C78EE8; --primary-600:#B073DA; --primary-050:#3A2850;
  --tile-face:#332640; --tile-face2:#2C2038; --tile-edge:#453357;
  --tile-shadow:#140D1A; --tile-ink:#F2E9F7;
}

/* ---- Seasonal: "seasonal-july4th" (patriotic red + navy) ---- */
html[data-theme="seasonal-july4th"] {
  --paper:#F5F8FC; --paper-2:#E9F0FA;
  --surface:#FFFFFF; --surface-2:#F7FAFE;
  --line:#D2E0F2; --line-2:#EAF1FB;
  --ink:#0B2545; --ink-2:#1E3A63; --muted:#5A7295; --faint:#9AAFC9;
  /* --primary was a red (#B22234) close enough to the site's hardcoded danger color
     (.btn-danger, #e74c3c) that every ordinary button/link/CTA site-wide (var(--primary) is
     used ~99 times across the CSS) read as a warning/delete action during this theme, not just
     "patriotic". Swapped to a patriotic blue matching this theme's already-navy --ink family;
     red stays as pure decoration elsewhere (backgrounds, ribbons) untouched. */
  --primary:#2158A6; --primary-600:#194580; --primary-050:#DEEAF9;
  --tile-face:#FFFFFF; --tile-face2:#EDF2FA; --tile-edge:#C9D9EE;
  --tile-shadow:#A9C0DE; --tile-ink:#0B2545;
}
html[data-theme="seasonal-july4th"] body.dark-mode {
  --paper:#0A1830; --paper-2:#0F2038;
  --surface:#152A48; --surface-2:#1A3256;
  --line:#26436C; --line-2:#213B60;
  --ink:#EAF1FB; --ink-2:#C2D4EC; --muted:#7E97BC; --faint:#4C6382;
  --primary:#5B93E0; --primary-600:#4A7FD1; --primary-050:#16233A;
  --tile-face:#1A3256; --tile-face2:#152A48; --tile-edge:#26436C;
  --tile-shadow:#081020; --tile-ink:#EAF1FB;
}

/* ---- Seasonal: "seasonal-thanksgiving" (harvest pumpkin-orange + deep brown) ---- */
html[data-theme="seasonal-thanksgiving"] {
  --paper:#FBF3E6; --paper-2:#F5E8D3;
  --surface:#FFFFFF; --surface-2:#FCF6EA;
  --line:#EAD9BA; --line-2:#F2E7CE;
  --ink:#3D2410; --ink-2:#5C3A1E; --muted:#8A6A45; --faint:#C4A878;
  --primary:#C1601C; --primary-600:#9C4B12; --primary-050:#FBE4CC;
  --tile-face:#FFFBF2; --tile-face2:#F7EAD3; --tile-edge:#E8D2A8;
  --tile-shadow:#C9AD79; --tile-ink:#3D2410;
}
html[data-theme="seasonal-thanksgiving"] body.dark-mode {
  --paper:#1F140B; --paper-2:#271A0E;
  --surface:#332211; --surface-2:#3D2914;
  --line:#4F3A1E; --line-2:#453118;
  --ink:#F7EAD5; --ink-2:#DEC49A; --muted:#A98B5F; --faint:#725B3B;
  --primary:#E8853B; --primary-600:#D2701F; --primary-050:#3A2410;
  --tile-face:#3D2914; --tile-face2:#332211; --tile-edge:#4F3A1E;
  --tile-shadow:#140D06; --tile-ink:#F7EAD5;
}

/* ---- Seasonal: "seasonal-newyears" (midnight gold + fireworks). Like
   Halloween, deliberately dark even in "light" mode — New Year's Eve is an
   inherently nocturnal celebration (the art itself is a midnight countdown
   clock + fireworks on black), so a bright pastel "light" variant wouldn't
   read as on-theme. Dark mode goes darker still so the toggle still does
   something. --tile-face/--tile-ink flipped dark/light for the same reason
   as Halloween's — --ink is light-toned here, so components using
   --tile-face as a background need a dark tile-face to avoid cream-on-cream. */
html[data-theme="seasonal-newyears"] {
  --paper:#141225; --paper-2:#1B1830;
  --surface:#211D3A; --surface-2:#282345;
  --line:#3A3358; --line-2:#332C4D;
  --ink:#F7EFD9; --ink-2:#DCCBA0; --muted:#A697C4; --faint:#6E5F94;
  --primary:#E8B923; --primary-600:#C79A12; --primary-050:#3A2E10;
  --tile-face:#282345; --tile-face2:#211D3A; --tile-edge:#3A3358;
  --tile-shadow:#100D1E; --tile-ink:#F7EFD9;
}
html[data-theme="seasonal-newyears"] body.dark-mode {
  --paper:#0A0815; --paper-2:#0F0C1E;
  --surface:#141025; --surface-2:#19142D;
  --line:#241D3D; --line-2:#1F1935;
  --ink:#F5EDD8; --ink-2:#D8C79E; --muted:#9587B8; --faint:#5C4F82;
  --primary:#FFD700; --primary-600:#E8B923; --primary-050:#3A2E10;
  --tile-face:#19142D; --tile-face2:#141025; --tile-edge:#241D3D;
  --tile-shadow:#08060F; --tile-ink:#F5EDD8;
}

/* ============================================================================= */
/* BRIDGE — legacy alias fallbacks.                                             */
/* Maps a few legacy variable names onto the new tokens so that if a legacy      */
/* rule ever references one without a local definition, it resolves sanely.      */
/* These are INERT wherever a legacy :root still defines the same name (that     */
/* definition, loaded later, wins) — so this changes nothing today. As legacy    */
/* files migrate, their local definitions are deleted and these take over.       */
/* ============================================================================= */
:root {
  --brand-green: var(--good);        /* legacy #40c455 -> semantic good/green   */
  --brand-blue:  var(--primary);     /* legacy #18a2ee -> semantic primary      */
  --surface-warm: var(--surface-2);
  --surface-hero: var(--surface-2);
  --text-strong: var(--good);
  --shadow-soft: var(--shadow);
}
