/* ============================================================================
   Solenix design tokens
   ----------------------------------------------------------------------------
   One source of truth for colour, light, type, space, radius, shadow, motion
   and data visualisation.

   Theming
     The site is dark only. Each colour has one value, written once in §1.
     :root sets color-scheme: dark. data-theme="dark" marks the page wrapper
     (app/(site)/layout.tsx), which takes the same tokens.

   Structure
     §1  colour                      — one value per token
     §2  derived colour and light    — written once, from §1
     §3  type
     §4  space and layout
     §5  radius
     §6  motion
     §7  focus
     §8  scene and page components
     Anything that can be derived with color-mix() from a §1 token lives in §2
     and is written exactly once.

   Rules
     - Never write a raw hex outside this file. The one exception: the brand's
       colours on a light surface, in brand/on-light.ts.
     - Derive tones with color-mix(in oklch, …), not new numbered tokens.
     - Action ember (a solid accent fill) is one per screen. Light ember —
       glow, gradient, orbit, lit edge, chart series one — is unlimited.
       See DESIGN.md.
   ========================================================================== */

/* ── 1. Colour ──────────────────────────────────────────────── */

:root { color-scheme: dark; }

/* One value per colour. The block is declared on [data-theme] too, so the page
   wrapper takes the same values. */
:root, [data-theme] {

  --bg: #0b0d12;
  --bg2: #11141b;
  --surface: rgba(20, 24, 32, 0.84);
  --surface-solid: #141820;
  --surface-sunken: rgba(244, 242, 238, 0.05);

  --text: #f4f2ee;
  --muted: #a39e97;
  --faint: #8f8983;

  --line: rgba(244, 242, 238, 0.09);
  --line-solid: #1e222b;
  --line-strong: rgba(244, 242, 238, 0.2);

  --accent: #f59e0b;
  --accent-hover: #fbbf24;
  --accent-ink: #1a1206;
  --accent-text: #fbbf24;

  --sun1: #fbbf24;
  --hot: #fde68a;                      /* the hottest point of a sun: sparks, peaks, a lit trail */
  --sun2: #f97316;
  --ring: #f59e0b;

  --ok: #34d399;
  --warn: #fbbf24;
  --down: #fb7185;

  --chart-1: #f59e0b;
  --chart-2: #2dd4bf;
  --chart-3: #818cf8;
  --chart-4: #e879f9;
  --chart-5: #38bdf8;
  --chart-tint-alpha: 14%;

  --glass-bg: rgba(20, 24, 32, 0.84);
  --glass-edge: rgba(244, 242, 238, 0.16);

  --grid-line: rgba(244, 242, 238, 0.05);
  --star: rgba(244, 242, 238, 0.32);
  --sweep-light: rgba(255, 255, 255, 0.4);

  --grad-headline: linear-gradient(96deg, var(--sun1), var(--sun2));

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
  --shadow-md: 0 1px 2px rgba(0, 0, 0, 0.3), 0 12px 32px rgba(0, 0, 0, 0.35);
  --shadow-lg: 0 2px 4px rgba(0, 0, 0, 0.35), 0 24px 56px rgba(0, 0, 0, 0.45);
  /* The world's glass cards and wells: the depth of the night sky, one value per depth. */
  --shadow-drop-1: 0 18px 40px -18px rgba(0, 0, 0, 0.7);
  --shadow-drop-2: 0 26px 50px -20px rgba(0, 0, 0, 0.75);
  --shadow-drop-3: 0 40px 80px -30px rgba(0, 0, 0, 0.8);
  --shadow-drop-4: 0 18px 40px -16px rgba(0, 0, 0, 0.85);
  --shadow-drop-5: 0 8px 20px -8px rgba(0, 0, 0, 0.8);
  --shadow-drop-6: 0 12px 24px -12px rgba(0, 0, 0, 0.9);
  --shadow-drop-7: 0 10px 24px -10px rgba(0, 0, 0, 0.9);
  --shadow-drop-8: 0 12px 24px -14px rgba(0, 0, 0, 0.9);
  --shadow-inset-well: inset 0 2px 12px rgba(0, 0, 0, 0.35);
}

/* The site is dark only. data-theme="dark" marks the page wrapper, which is dark too. */
[data-theme="dark"] { color-scheme: dark; }


/* ── 2. Derived colour and light ──────────────────────────────────────────── */
/* Written once. Every value below derives from §1. */

:root, [data-theme] {
  /* Soft accent and status fills */
  --accent-quiet: color-mix(in oklch, var(--accent) 12%, transparent);
  --ok-tint: color-mix(in oklch, var(--ok) 8%, transparent);
  --warn-tint: color-mix(in oklch, var(--warn) 8%, transparent);
  --down-tint: color-mix(in oklch, var(--down) 8%, transparent);

  /* Chart tints — the alpha is one token in §1, the derivation is written once. */
  --chart-1-tint: color-mix(in oklch, var(--chart-1) var(--chart-tint-alpha), transparent);
  --chart-2-tint: color-mix(in oklch, var(--chart-2) var(--chart-tint-alpha), transparent);
  --chart-3-tint: color-mix(in oklch, var(--chart-3) var(--chart-tint-alpha), transparent);
  --chart-4-tint: color-mix(in oklch, var(--chart-4) var(--chart-tint-alpha), transparent);
  --chart-5-tint: color-mix(in oklch, var(--chart-5) var(--chart-tint-alpha), transparent);

  /* Chart furniture */
  --chart-grid: color-mix(in oklch, var(--text) 8%, transparent);   /* graphic only */
  --chart-axis: var(--faint);                                       /* tick labels  */
  --chart-track: color-mix(in oklch, var(--text) 10%, transparent); /* unfilled bar */

  /* Trend. Direction only — the judgement is set per instance with
     data-sentiment, because a rise is not always good. */
  --trend-up: var(--ok);
  --trend-down: var(--down);
  --trend-flat: var(--muted);
  --trend-up-tint: var(--ok-tint);
  --trend-down-tint: var(--down-tint);
  --trend-flat-tint: color-mix(in oklch, var(--text) 7%, transparent);

  /* ── Gradients. Five named, plus the texture mask. ── */
  --grad-sun: radial-gradient(circle at 42% 38%, var(--sun1), var(--sun2));
  --grad-ember: linear-gradient(135deg, var(--accent-hover), var(--accent));
  --grad-sweep: linear-gradient(100deg,
    transparent 18%, var(--sweep-light) 48%, transparent 78%);
  /* --grad-headline is declared in §1. */

  /* ── Glow. Light, not elevation. Shadow says how high; glow says how alive. ── */
  --glow-soft: 0 0 32px color-mix(in srgb, var(--ring) 14%, transparent);
  --glow-ember:
    0 0 0 1px color-mix(in srgb, var(--accent) 34%, transparent),
    0 10px 32px color-mix(in srgb, var(--accent) 26%, transparent);
  --glow-hover: 0 0 28px color-mix(in srgb, var(--accent) 22%, transparent);
  /* Uses currentColor, so one token glows any chart series. */
  --glow-point:
    0 0 0 3px color-mix(in srgb, currentColor 16%, transparent),
    0 0 14px color-mix(in srgb, currentColor 45%, transparent);

  /* ── Glass ── */
  --glass-blur: 18px;
  --glass-inset: inset 0 1px 0 var(--glass-edge);

  /* ── Texture. Grid pitch is --grid-size (§4). ── */
  --texture-grid:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  --texture-stars:
    radial-gradient(1.5px 1.5px at 18% 24%, var(--star), transparent),
    radial-gradient(1px 1px at 64% 12%, var(--star), transparent),
    radial-gradient(1.5px 1.5px at 82% 58%, var(--star), transparent),
    radial-gradient(1px 1px at 33% 71%, var(--star), transparent),
    radial-gradient(1px 1px at 91% 31%, var(--star), transparent),
    radial-gradient(1.5px 1.5px at 48% 88%, var(--star), transparent);

  /* ── Elevation alias kept for site.css ── */
  --shadow: var(--shadow-md);
  --shadow-accent: 0 6px 20px color-mix(in srgb, var(--accent) 30%, transparent);

  /* ── Layering. Light behind texture behind content, every time. ── */
  --z-sky: 0;
  --z-texture: 1;
  --z-content: 2;
  --z-nav: 20;
  --z-sticky: 25;                     /* the one sticky CTA on phones */
  --z-skip: 30;
}

/* ── 3. Type ──────────────────────────────────────────────────────────────── */

:root, [data-theme] {
  /* Three roles, three faces. Sora carries display — a geometric grotesque
     whose bowls are the same circles as the mark, holding at 96px. Text and
     mono still does real work on every label, number, table header and status.
     brand/build.py still needs the same display face — see DESIGN.md §2. */
  --font-display: "Sora", ui-sans-serif, -apple-system, BlinkMacSystemFont,
    "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
  --font-text: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI",
    "Noto Sans", Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono",
    monospace;

  /* Size. clamp() so 375px and 1920px both land without a media query. */
  /* Display sizes grow 1.5–2× from phone to desktop and stop at 5rem (80px).
     The fluid part is rem + vw, so nothing balloons at 1920 or 2560. */
  --fs-beat: clamp(2.4rem, 1.7rem + 3.2vw, 5rem);      /* story beat word, scene only */
  --fs-hero: clamp(1.6rem, min(1.9rem + 3vw, 11svh), 5rem); /* scene headline, one per page; scales with width and height, so it fits any screen */
  --fs-statement: clamp(2.5rem, 1.85rem + 2.8vw, 4.75rem);   /* big statement, one per page */
  --fs-display: clamp(2.2rem, 1.7rem + 2.2vw, 3.75rem);   /* page-owning headline */
  --fs-h1: clamp(1.9rem, 5vw, 2.6rem);
  --fs-h2: clamp(1.4rem, 3.4vw, 1.75rem);
  --fs-h3: 1.2rem;
  --fs-h4: 1.02rem;
  --fs-stat: clamp(1.9rem, 5.5vw, 2.75rem);     /* a stat's numeral */
  --fs-lede: clamp(1.05rem, min(2.6vw, 3.4svh), 1.25rem); /* never under 1.05rem: a phone lede reads without zoom */
  --fs-body: 1rem;
  --fs-sm: 0.92rem;
  --fs-xs: 0.8rem;
  --fs-2xs: 0.75rem;                  /* badges, floor: 12px, never below this (Impeccable craft floor) */

  /* Weight. 650 is the brand's lockup weight; 800 is --fs-statement only. */
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-brand: 650;
  --fw-bold: 700;
  --fw-black: 800;

  /* Line height */
  --lh-hero: 0.98;                    /* --fs-hero and --fs-beat */
  --lh-display: 1.04;
  --lh-heading: 1.2;
  --lh-body: 1.5;
  --lh-relaxed: 1.6;

  /* Tracking. Negative as type grows, positive as it shrinks into a label.
     Sora needs less negative tracking at size than the system stack did. */
  --track-beat: -0.055em;             
  --track-hero: -0.045em;             
  --track-statement: -0.04em;
  --track-display: -0.03em;
  --track-heading: -0.015em;
  --track-stat: -0.02em;
  --track-body: 0;
  --track-label: 0.12em;
  --track-eyebrow: 0.14em;
}

/* ── 4. Space and layout ──────────────────────────────────────────────────── */

:root, [data-theme] {
  /* 4px base. Skip no steps; add none. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;
  --space-10: 128px;

  /* Section rhythm breathes with the viewport. */
  --space-section: clamp(2.5rem, 8vh, 4.5rem);
  --space-hero: clamp(3.5rem, 12vh, 8rem);

  --container: 64rem;                 /* 1024px — the live site's measure */
  --container-wide: 78rem;            /* bento, split, full-bleed, demo panel */
  --measure: 34rem;                   /* max line length for prose */
  --grid-size: 32px;                  /* texture grid pitch */
  --bento-min: 15rem;                 /* smallest bento cell */
  --gutter: var(--space-4);           /* 16px, 32px from 640px up */
  --nav-height: 72px;
  --tap-min: 44px;                    /* every interactive target clears this */
}

@media (min-width: 640px) {
  :root { --gutter: var(--space-6); }
}

/* ── 5. Radius ────────────────────────────────────────────────────────────── */

:root, [data-theme] {
  --radius-xs: 8px;
  --radius-sm: 10px;
  --radius-md: 12px;                  /* icon chips, code wells, inputs */
  --radius-lg: 16px;
  --radius-xl: 20px;                  /* cards */
  --radius-2xl: 28px;                 /* full-bleed panels, bento cells */
  --radius-pill: 999px;               /* buttons, badges, nav links */
}

/* ── 6. Motion ────────────────────────────────────────────────────────────── */

:root, [data-theme] {
  --dur-fast: 120ms;                  /* colour, border */
  --dur-base: 180ms;                  /* lift, shadow, glow */
  --dur-slow: 320ms;                  /* panels, disclosure */
  --dur-reveal: 700ms;                /* section entrance */
  --dur-sweep: 1400ms;                /* one pass of the light sweep */
  --dur-count: 1200ms;                /* a number counting to its value */
  --stagger: 40ms;                    /* delay between staggered siblings */

  --ease-out: cubic-bezier(0.2, 0.7, 0.2, 1);  /* the house curve */
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);


  /* Orbit periods — slow enough to read as ambient, not as animation. */

  --lift: -1px;                       /* buttons */
  --lift-card: -3px;                  /* cards */
  --reveal-rise: 12px;                /* how far a revealed child travels */
  --parallax: 0.12;                   /* sky drift as a fraction of scroll */
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast: 1ms;
    --dur-base: 1ms;
    --dur-slow: 1ms;
    --dur-reveal: 1ms;
    --dur-sweep: 1ms;
    --dur-count: 1ms;
    --stagger: 0ms;
    --lift: 0px;
    --lift-card: 0px;
    --reveal-rise: 0px;
    --parallax: 0;
  }
}

/* ── 7. Focus ─────────────────────────────────────────────────────────────── */

:root, [data-theme] {
  --focus-width: 2px;
  --focus-offset: 3px;
  --focus-color: var(--accent);
}

/* Every focusable element, no exceptions. Keyboard only. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--focus-width) solid var(--focus-color);
  outline-offset: var(--focus-offset);
}

/* ── 8. Scene and page components ───────────────────── */
/* data-theme marks the page wrapper, so every section takes the same tokens.
   --page-bg is the page floor, resolved here at :root: use it for the hand-off
   at the bottom of a scene. */

:root, [data-theme] {
  --page-bg: var(--bg);

  /* The three suns. CSS and SVG use these. WebGL reads --sun1, --sun2 and
     --ring from computed style and derives the same mixes in script. */

  /* Text over a scene always sits on the veil. Never on the bare canvas. */
  --scene-veil:
    linear-gradient(to top,
      color-mix(in oklch, var(--bg) 92%, transparent) 0%,
      color-mix(in oklch, var(--bg) 40%, transparent) 30%,
      transparent 52%),
    linear-gradient(100deg,
      color-mix(in oklch, var(--bg) 70%, transparent) 0%,
      transparent 48%);

  /* Scene labels: reticle brackets on a body, a backed label beside it. */
  --reticle: var(--ring);
  --reticle-size: 84px;
  --reticle-size-sm: 60px;
  --label-bg: color-mix(in oklch, var(--bg) 72%, transparent);
  --label-gap: 8px;                   /* minimum space between stacked labels */

  /* Honest placeholders. A number we have not committed to is a chip. */
  --tbd-fg: var(--warn);
  --tbd-bg: var(--warn-tint);
  --tbd-line: color-mix(in oklch, var(--warn) 55%, transparent);
  --example-line: var(--line-strong);

  /* Scene motion. Periods in seconds; the sim speed is read by script. */
}
