/* ============================================================
   CryptoSignals.bot — Design Tokens (single source of truth, web)
   Extracted verbatim from prototype/css/app.css (2026-06-07).
   Dark is the DEFAULT theme; light is required.
   Set data-theme="dark" | "light" on the root element.

   EVOLUTION 2026-07-01 (owner-sanctioned, Fable 5 session — recorded
   in design_handoff/CLAUDE.md "TOKEN EVOLUTION" section):
   - NEW scales (additive): fluid type ramp (the --fz- and --lh- families), spacing
     (--sp-*), motion durations (--dur-*), elevation ramp
     (--shadow-1/2/3), a11y focus ring (--focus-ring).
   - PROMOTED: the admin amber status literal #f0b00b is now --warn /
     --warn-2 (theme-aware; light uses a contrast-safe deep amber).
   - ADJUSTED: --text-3 legibility nudge in both themes (muted text
     was under-contrast, esp. on light). Hierarchy preserved.
   Semantic color discipline is UNCHANGED: up/down semantic-only,
   accent = sole interactive hue, signal = logo + EMA only.
   ============================================================ */

:root{
  /* radii */
  --r-sm:6px; --r-md:9px; --r-lg:14px; --r-xl:20px;

  /* type — Geist for UI, Geist Mono for ALL numbers/prices (tabular) */
  --fs-mono:"Geist Mono","JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  --fs-ui:"Geist","Inter Tight",system-ui,-apple-system,Segoe UI,sans-serif;

  /* type scale (2026-07-01) — fluid ramp; terminal body stays 13px,
     marketing display sizes breathe with the viewport */
  --fz-2xs:11px; --fz-xs:12px; --fz-sm:13px; --fz-md:14px;
  --fz-lg:clamp(16px,.4vw + 14px,18px);
  --fz-xl:clamp(20px,.9vw + 16px,24px);
  --fz-2xl:clamp(26px,1.8vw + 18px,34px);
  --fz-3xl:clamp(34px,3vw + 20px,48px);
  --lh-tight:1.15; --lh-ui:1.45; --lh-relaxed:1.65;

  /* spacing scale (2026-07-01) — 4px base */
  --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-16:64px;

  /* motion */
  --ease:cubic-bezier(.2,.7,.2,1);
  --dur-fast:120ms; --dur-med:220ms; --dur-slow:420ms;   /* 2026-07-01 */

  /* elevation */
  --shadow-pop:0 18px 50px -12px rgba(0,0,0,.55), 0 2px 8px rgba(0,0,0,.3);
  --shadow-3:var(--shadow-pop);   /* ramp alias — 1/2 are per-theme below */

  /* a11y focus ring (2026-07-01) — layered on --bg so it reads on any fill;
     use with :focus-visible only, never :focus */
  --focus-ring:0 0 0 2px var(--bg), 0 0 0 4px var(--accent);

  /* theme-invariant inks (promoted prototype literals — same in both themes) */
  --on-accent:#fff;          /* text/glyphs on --accent / --up / --down fills */
  --ink-on-signal:#06120a;   /* logo glyph ink on the signal->up gradient tile */

  /* ============================================================
     ATMOSPHERE & ELEVATION LAYER  (beautification pass, 2026-06-08)
     Additive only — the semantic tokens above are untouched. These
     drive depth (ambient meshes), card elevation (surface gradient +
     hairline highlight), and accent glows. Recorded as a deviation in
     design_handoff/CLAUDE.md.
     ============================================================ */

  /* Coin identity palette — real per-asset brand colors, theme-invariant
     like the inks above. A distinct concern from semantic up/down/accent;
     used ONLY for coin badges/avatars, never for UI state. */
  --coin-btc:#f7931a; --coin-eth:#627eea; --coin-sol:#14e8b0;
  --coin-bnb:#f0b90b; --coin-xrp:#8b97a8; --coin-doge:#c2a633;
  --coin-ada:#3468d1; --coin-usdt:#26a17b; --coin-default:#7e8aa0;

  /* shared motion + radii extensions */
  --ease-out:cubic-bezier(.16,1,.3,1);   /* expressive ease for reveals/lifts */
  --r-2xl:26px;
}

/* ---------- DARK (default) ---------- */
[data-theme="dark"]{
  --bg:#080a10;
  --panel:#0f131c;
  --panel-2:#141925;
  --elev:#1a2030;
  --hover:#1d2433;
  --border:#212838;
  --border-2:#2c3447;
  --text:#e9edf4;
  --text-2:#94a0b3;
  --text-3:#77819a;                   /* 2026-09-01: was #6b7590 (3.82:1 on --panel-2) — now 4.51:1 worst case */
  --up:#1fc88a;                       /* buy / gain — semantic, NOT brand */
  --up-2:rgba(31,200,138,.15);
  --down:#f3596a;                     /* sell / loss — semantic, NOT brand */
  --down-2:rgba(243,89,106,.15);
  --accent:#5f8fff;                   /* interactive accent (links, focus, primary) */
  --accent-2:rgba(95,143,255,.16);
  /* FILL variants (2026-09-01). --accent/--up/--down are tuned to be READ on a
     dark background, where they measure 5.87 / 8.57 / 5.21 against --panel — so
     they are correct for links, figures and chart strokes. They are NOT correct
     as a SOLID FILL under white label text: white on --accent is 3.17:1, on --up
     2.17:1, on --down 3.57:1, i.e. every primary CTA, the pro badge and the user
     avatar sat below AA in the DEFAULT theme. Darkening the base tokens would
     fix the fill and break the text (on a dark ground, darker = less contrast) —
     the two uses pull in opposite directions, so they need separate tokens.
     Each -fill clears 4.5:1 with --on-accent AND stays >=3:1 against --panel so
     the button's own edge remains visible. */
  --accent-fill:#2b6bff;              /* white on it 4.52:1; vs --panel 4.11:1 */
  --up-fill:#15875d;                  /* white on it 4.51:1; vs --panel 4.12:1 */
  --down-fill:#eb1129;                /* white on it 4.52:1; vs --panel 4.11:1 */
  --signal:#c2f24e;                   /* signal-lime — logo mark + EMA line only */
  --warn:#f0b00b;                     /* 2026-07-01: promoted admin amber literal */
  --warn-2:rgba(240,176,11,.14);
  --grid:rgba(255,255,255,.045);
  --grid-2:rgba(255,255,255,.025);
  --crosshair:rgba(255,255,255,.35);
  --scrim:rgba(4,6,11,.66);

  /* elevation ramp (2026-07-01): 1 = resting card, 2 = dropdown/hover-lift,
     3 = modal/popover (alias of --shadow-pop in :root) */
  --shadow-1:0 1px 2px rgba(0,0,0,.35), 0 3px 10px -4px rgba(0,0,0,.4);
  --shadow-2:0 10px 28px -10px rgba(0,0,0,.5), 0 2px 6px rgba(0,0,0,.28);

  /* atmosphere (dark): ambient page glows + card elevation */
  --ambient-1:rgba(90,140,255,.11);    /* accent halo, top-right */
  --ambient-2:rgba(31,200,138,.06);    /* up halo, mid-left */
  --ambient-3:rgba(194,242,78,.045);   /* signal halo, low */
  --surface-grad:linear-gradient(180deg,rgba(255,255,255,.025),rgba(255,255,255,0) 42%);
  --hairline:rgba(255,255,255,.06);    /* inset top highlight on cards */
  --hairline-2:rgba(255,255,255,.10);
  --sheen:rgba(255,255,255,.07);       /* moving highlight for shimmer */
  /* Top-lit highlight INSIDE a saturated button fill. Deliberately
     theme-INVARIANT and defined here rather than per-theme: it sits on the
     accent/danger fill, not on a panel, so it is white in both themes —
     which is why --hairline-2 (white .10 dark, white 1.0 light) is the
     wrong token for it despite looking similar. Promoted 2026-09-01 from a
     literal repeated across 5 sheets and 20 sites. */
  --btn-sheen:rgba(255,255,255,.22);
  --btn-sheen-hover:rgba(255,255,255,.28);
  --glow-accent:0 14px 40px -14px rgba(90,140,255,.50);
  --glow-up:0 14px 40px -14px rgba(31,200,138,.42);
  --glow-signal:0 0 36px -8px rgba(194,242,78,.45);
  --grain-opacity:.035;
  color-scheme:dark;
}

/* ---------- LIGHT ---------- */
[data-theme="light"]{
  --bg:#eef1f6;
  --panel:#ffffff;
  --panel-2:#f6f8fc;
  --elev:#ffffff;
  --hover:#eef2f8;
  --border:#e3e8f0;
  --border-2:#d4dae4;
  --text:#0d1320;
  --text-2:#5a6577;
  /* 2026-09-01 CONTRAST PASS. Every value below was measured against ALL THREE
     grounds it actually appears on (--bg #eef1f6, --panel #ffffff, --panel-2
     #f6f8fc) and darkened along its OWN hue until the worst of the three
     cleared 4.5:1. Hue and saturation are unchanged — this is a lightness
     correction, not a new palette (handoff rule: no new hues).
     Before: --up 2.84:1 on --bg, --down 3.91, --accent 4.08, --warn 4.14,
     --text-3 3.37 — so every gain figure, every ok/paid pill, every error
     string and all tertiary copy failed AA in the required light theme.
     Each new value also happens to clear 4.5:1 with white ON it, which is why
     light needs no separate -fill tokens (dark does; see the dark block).

     SECOND PASS, same day: the first round measured only the SOLID grounds and
     still failed. Status pills render coloured text on the colour's OWN alpha
     tint (`background:var(--up-2);color:var(--up)`), and that composite is a
     LIGHTER ground than --panel, so it is the worst case, not an easier one —
     12 of 24 combinations were still under AA, including every one in light.
     The search is circular (the tint is derived from the base, so every
     candidate moves its own background) and is solved by iterating both
     together. unit_a11y_contract.php now measures the tint composites, which is
     the check whose absence let this through the first time. */
  --text-3:#626e84;                   /* was #77839a (3.37:1 on --bg) -> 4.54:1 */
  --up:#07714a;                       /* was #0aa46c (2.84:1 on --bg) -> 4.53:1 worst; white on it 6.05:1 */
  --up-2:rgba(7,113,74,.12);
  --down:#c11d35;                     /* was #e0334c (3.91:1 on --bg) -> 4.53:1 worst; white on it 6.01:1 */
  --down-2:rgba(193,29,53,.10);
  --accent:#0c4eff;                   /* was #2f68ff (4.08:1 on --bg) -> 4.51:1 worst; white on it 5.92:1 */
  --accent-2:rgba(12,78,255,.10);
  --signal:#5fae00;
  --warn:#845b00;                     /* was #9a6b00 (4.14:1 on --bg) -> 4.53:1 worst */
  --warn-2:rgba(132,91,0,.12);
  /* Light needs no darker fill: the bases above already clear 4.5:1 with white,
     so the -fill tokens simply alias them and every consumer can use -fill
     unconditionally. */
  --accent-fill:var(--accent);
  --up-fill:var(--up);
  --down-fill:var(--down);
  --grid:rgba(13,19,32,.05);
  --grid-2:rgba(13,19,32,.028);
  --crosshair:rgba(13,19,32,.4);
  --scrim:rgba(20,28,44,.32);

  /* elevation ramp (2026-07-01) — subtler in light */
  --shadow-1:0 1px 2px rgba(13,19,32,.06), 0 3px 10px -4px rgba(13,19,32,.08);
  --shadow-2:0 10px 28px -10px rgba(13,19,32,.14), 0 2px 6px rgba(13,19,32,.06);

  /* atmosphere (light): softer ambient + bright hairline */
  --ambient-1:rgba(47,104,255,.08);
  --ambient-2:rgba(10,164,108,.05);
  --ambient-3:rgba(95,174,0,.04);
  --surface-grad:linear-gradient(180deg,rgba(255,255,255,.75),rgba(255,255,255,0) 55%);
  --hairline:rgba(255,255,255,.85);
  --hairline-2:rgba(255,255,255,1);
  --sheen:rgba(255,255,255,.6);
  --glow-accent:0 18px 44px -16px rgba(47,104,255,.30);
  --glow-up:0 18px 44px -16px rgba(10,164,108,.26);
  --glow-signal:0 0 30px -8px rgba(95,174,0,.28);
  --grain-opacity:.02;
  color-scheme:light;
}
