/**
 * LAYER 1–4 — THE TOKEN SET
 *
 * Ported verbatim from the platform's token engine (src/lib/tokens/). Values are
 * identical by intent: when the Next.js platform resumes on the VPS, both sites must
 * render the same brand, and the only way to guarantee that is for the numbers to have
 * a single origin. If a value changes here it changes there.
 *
 * Nothing below is a "nice number". The gold ramp extends unusually dark because
 * #D4AF37 measures 9.57:1 on the Cosmos ground but 1.92:1 on ivory, so the light theme
 * needs genuine bronzes to carry text while staying the same colour family.
 */

/* ── Registered properties ───────────────────────────────────────────────────
   Pointer position and hover strength are registered rather than left as plain
   custom properties, so calc() resolves before the first pointermove lands. An
   unregistered custom property is invalid-at-computed-value-time and every calc()
   consuming it falls back to unset for the whole element. */
@property --px      { syntax: '<number>'; inherits: false; initial-value: 0.5; }
@property --py      { syntax: '<number>'; inherits: false; initial-value: 0.5; }
@property --hover-t { syntax: '<number>'; inherits: false; initial-value: 0; }

:root {
  /* ── Type families ──
     Retuned 2026-08 (second pass): Space Grotesk display over Satoshi body, replacing
     Inter Tight over Inter. The Helvetica register was clean but anonymous; the founder
     asked for a face that could not be mistaken for the default. Space Grotesk is a
     geometric grotesk that inherits Space Mono's machined quirks — a technical
     signature that fits an AI/deep-tech brand without resorting to a literal monospace
     headline. Satoshi keeps the body quiet and warm. See base.css for licensing and
     the @font-face declarations.

     The fallback chain is unchanged and still Helvetica-class on purpose: a visitor
     who never receives the woff2 gets a neutral grotesque at roughly the right metrics
     rather than a humanist system font. No free system face approximates Space
     Grotesk's character, so the fallback aims for its skeleton, not its voice. */
  --font-display: 'Space Grotesk', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --font-body:    'Satoshi', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* ── Fluid type scale. clamp() means no breakpoint-specific font sizes anywhere.
     The gap between --text-lg and --text-xl is deliberate: heading and body must
     never look like neighbouring steps of one ramp. ── */
  --text-2xs:  clamp(0.6875rem, 0.67rem + 0.09vw, 0.75rem);
  --text-xs:   clamp(0.75rem, 0.72rem + 0.14vw, 0.8125rem);
  --text-sm:   clamp(0.875rem, 0.85rem + 0.12vw, 0.9375rem);
  --text-base: clamp(1rem, 0.97rem + 0.15vw, 1.0625rem);
  --text-lg:   clamp(1.125rem, 1.07rem + 0.28vw, 1.25rem);
  --text-xl:   clamp(1.5rem, 1.34rem + 0.8vw, 2rem);
  --text-2xl:  clamp(1.875rem, 1.55rem + 1.6vw, 2.75rem);
  --text-3xl:  clamp(2.375rem, 1.85rem + 2.6vw, 3.875rem);
  --text-4xl:  clamp(2.875rem, 1.9rem + 4.9vw, 5.5rem);
  --text-5xl:  clamp(3.375rem, 1.85rem + 7.6vw, 7.5rem);

  /* Optical tracking — tightens as size grows, because large type looks progressively
     looser at a fixed letter-spacing. Never applied to body.

     Retuned 2026-08 (second pass) for Space Grotesk, replacing the Inter Tight ramp.
     Space Grotesk sets naturally wide — generous sidebearings around its geometric
     rounds — so it does need tightening at display sizes, but far less than Inter
     Tight took: its quirks (the g's flat ear, the angular counters) live in the
     letter-to-letter rhythm, and the old -0.032em floor crushed exactly the space
     where that rhythm reads. The ramp is roughly 40% shallower across the board.
     Still monotonic, still tightening with size; only the depth is retuned for the
     new face. */
  --track-5xl: -0.018em;
  --track-4xl: -0.016em;
  --track-3xl: -0.014em;
  --track-2xl: -0.011em;
  --track-xl:  -0.008em;
  /* Satoshi is a touch narrower than Inter at text sizes; a hair of positive tracking
     opens the word-shapes back up at --text-base. Anything past +0.002em reads as
     letterspaced lowercase, which is a typographic crime, not a tuning value. */
  --track-body: 0.001em;
  --track-label: 0.18em;

  /* Space Grotesk's variable axis runs 300–700 — there is no 800 to reach for, and
     declaring one would make the browser synthesise it (the exact failure the variable
     files exist to prevent). So the display register compresses: Heavy and default
     display are both the axis cap at 700, and the hierarchy that 800-vs-700 used to
     carry is delegated to the size and tracking ramps, which at hero scale were doing
     most of that work anyway. --weight-displayHeavy is kept as a name because site.css
     and identity.css consume it; it is now an alias, not a heavier cut.
     --weight-display-medium is the new mid register (subheads, large pull-quotes) —
     Space Grotesk at 500 keeps its character where 400 starts to look like body.
     Satoshi's axis runs 300–900; body sits 400/500 and Strong moves 600 → 700 because
     700 is one of Satoshi's five designed instances (300/400/500/700/900) where 600
     was interpolation between drawings — at bold's job of flagging a phrase inside
     body text, the designed instance is visibly crisper. */
  --weight-displayHeavy: 700;
  --weight-display: 700;
  --weight-display-medium: 500;
  --weight-displaySoft: 500;
  --weight-body: 400;
  --weight-bodyMedium: 500;
  --weight-bodyStrong: 700;

  /* Tuned against Inter's tall x-height (each display step gained ~0.04 over the
     Cabinet Grotesk values because lines read as touching) and kept unchanged through
     the Space Grotesk/Satoshi swap: both new faces carry slightly smaller x-heights
     than Inter, so the same leading reads a shade airier — the right direction for a
     premium register — and headline blocks keep their layout height. */
  --leading-displayTight: 1.02;
  --leading-display: 1.1;
  --leading-snug: 1.38;
  --leading-body: 1.6;

  /* ── 8-point spacing baseline ── */
  --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; --space-11: 192px;

  /* Tight on controls (precision), generous on containers. No huge pills. */
  --radius-none: 0px; --radius-sm: 4px;  --radius-md: 6px;
  --radius-lg: 12px;  --radius-xl: 20px; --radius-2xl: 28px;

  /* ── Layout ── */
  --content: 760px;
  --wide: 1240px;
  --gutter: clamp(20px, 5vw, 56px);
  /* Raised from clamp(72px, 11vw, 160px) in the 2026-08 redesign — the sections were
     reading as a list rather than as rooms. Air is the cheapest premium there is. */
  --section-y: clamp(84px, 12vw, 176px);
  --header-h: 68px;

  /* ── Motion ── */
  --duration-instant: 90ms;
  --duration-fast: 160ms;
  --duration-normal: 260ms;
  --duration-slow: 420ms;
  --duration-deliberate: 720ms;

  /* Scramble. --scramble-tick is how often a still-unresolved character swaps glyph:
     50ms is 20 changes a second, fast enough to read as churn and slow enough that the
     individual glyphs register rather than blurring into grey noise.

     --scramble-settle is the per-character resolve interval on hover. At 22ms a
     twelve-character nav link is fully locked in ~260ms — inside --duration-normal, so
     the effect finishes about when the rest of the hover state does rather than
     trailing it. --scramble-settle-slow is the arrival variant for the hero headline,
     where 43 characters at 22ms would finish before the eye reached the line. */
  --scramble-tick: 50ms;
  --scramble-settle: 22ms;
  --scramble-settle-slow: 34ms;

  /* Convergent curves only. A coupled oscillator settling into phase lock approaches
     its target and stays there; overshoot is a system that has not settled.
     --ease-entrance passes its target by 8% and is the only curve permitted above 1.0. */
  --ease-standard: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-entrance: cubic-bezier(0.16, 1.08, 0.32, 1);
  --ease-exit: cubic-bezier(0.55, 0, 0.68, 0.19);

  --reveal-phase-distance: 14px;
  --reveal-rise-distance: 14px;
  --reveal-settle-distance: 24px;
  --reveal-settle-scale: 0.985;
  --reveal-sweep-distance: 0.35em;

  --hover-lift-lift: -2px;
  --press-distance: 1px;

  /* Template tilt runs 8–15° and reads as rotation. Below ~1.5° it reads as a surface
     catching light at a different angle. This number is a brand rule, not a tuning
     value — raising it is a brand decision. */
  --tilt-max: 1.2deg;

  --parallax-atmosphere: 18px;
  --parallax-foreground: -10px;

  /* ── WP-site display extensions (2026-08 UI redesign) ─────────────────────────
     Additive only — nothing above this comment changed. A true display register for
     the two moments that bracket the page (hero, closing CTA), a ghost-numeral size
     for section indices, and the larger button. Named --text-hero rather than
     --text-6xl because its ceiling is not a scale step: "Designing the Future." is
     21 glyphs, and 21 × ~0.5em must fit a 1128px shell, which caps the size at
     ~6.75rem — below 5xl's own ceiling. It is a fit-to-measure display size, not the
     next rung of the ramp. */
  --text-hero: clamp(2.9rem, 1.6rem + 6.8vw, 6.75rem);
  /* Retuned 2026-08 with the ramp above: the deepest tracking on the site, but 40%
     shallower than the Inter Tight value (-0.036em) for the same reason as the rest of
     the ramp — Space Grotesk's drawing needs room at exactly the size where it is the
     whole show. */
  --track-hero: -0.022em;
  --leading-displayHero: 0.98;
  --text-ghost: clamp(3.25rem, 2.1rem + 5.8vw, 6.5rem);

  /* ── Typography-motion tokens (2026-08 typeface pass) ─────────────────────────
     Consumed by motion.css / JS, defined here because they are typographic values
     first: what the animation moves BETWEEN is a design decision, how it moves is a
     motion one.

     --track-hero-from — the tracking a hero line reveals FROM, animating down to
     --track-hero. Wide-to-tight is the classic cinematic title move: the line arrives
     as scattered glyphs and condenses into a word. +0.06em is wide enough to read as a
     deliberate state (≈4px at hero size) without the glyphs losing adjacency. Animate
     letter-spacing only on one-shot reveals — it relayouts every frame, which a single
     720ms entrance absorbs and a scroll-linked effect would not.

     --blur-reveal — starting blur for text reveals, resolving to 0. 12px is past the
     legibility threshold, so the line genuinely arrives rather than merely sharpens;
     filter is compositor-friendly, unlike the letter-spacing half of the same move.

     --ease-cinematic — near-exponential decay (Robert Penner's easeOutExpo drawn as a
     bezier): almost all travel in the first third, then a long asymptotic settle.
     Reserved for typographic reveals; interface motion keeps using --ease-standard /
     --ease-entrance, so text arrivals feel like a different order of event than a
     hover. Convergent — it never crosses 1.0, honouring the no-overshoot rule. */
  --track-hero-from: 0.06em;
  --blur-reveal: 12px;
  --ease-cinematic: cubic-bezier(.19, 1, .22, 1);
}

/* ════════════════════════════════════════════════════════════════════════════
   COSMOS — the primary expression. Deep space ground, gold as a light source.
   ════════════════════════════════════════════════════════════════════════════ */
:root,
:root[data-theme='cosmos'] {
  color-scheme: dark;

  --surface-base: #07070A;
  --surface-raised: #0C0D11;
  --surface-overlay: #131419;
  --surface-sunken: #000000;
  --surface-glass: rgb(255 255 255 / 0.05);

  --text-primary: #F5F5F2;
  --text-secondary: #C2C8D0;
  --text-muted: #838C99;
  --text-on-accent: #000000;
  --text-accent: #D4AF37;

  --accent-decorative: #D4AF37;
  --accent-interactive: #D4AF37;
  --accent-hover: #E8CE7A;
  --accent-solid: #D4AF37;
  --accent-glow: rgb(212 175 55 / 0.30);

  --sync-base: #C2C8D0;
  --sync-muted: #68717E;

  /* The one place the logo's two metals carry a literal meaning: platinum is an
     oscillator that has not synchronised, gold is one that has. */
  --field-cold: #A0A8B3;
  --field-hot: #D4AF37;

  --border-subtle: rgb(255 255 255 / 0.07);
  --border-default: #2D3038;
  --border-interactive: #68717E;
  --border-strong: #363C45;
  --border-accent: rgb(212 175 55 / 0.45);

  --focus-ring: #DCBE55;
  --success: #6FD1A0;
  --warning: #E8B860;
  --danger: #F08B8B;
  --info: #7FC4E8;

  /* On Cosmos a raised surface is defined by light — a faint rim and a glow. */
  --elevation-1: 0 1px 0 0 rgb(255 255 255 / 0.04) inset, 0 2px 8px -2px rgb(0 0 0 / 0.6);
  --elevation-2: 0 1px 0 0 rgb(255 255 255 / 0.06) inset, 0 8px 24px -6px rgb(0 0 0 / 0.7);
  --elevation-3: 0 1px 0 0 rgb(255 255 255 / 0.08) inset, 0 20px 56px -12px rgb(0 0 0 / 0.8);
  --elevation-glow: 0 0 32px -4px rgb(212 175 55 / 0.28);

  --glass-tint: rgb(255 255 255 / 0.05);
  --glass-blur: 16px;

  --field-blend: lighter;
  --field-intensity: 2.4;

  /* WP-site extension (2026-08): film grain over the ground. On the deep ground the
     noise is light lifting out of black, so it can run slightly stronger. */
  --grain-opacity: 0.05;
}

/* ════════════════════════════════════════════════════════════════════════════
   HORIZON — warm ivory counterpart. Same brand, different hour of the day.
   Deliberately not white: pure white reads clinical and kills the brand warmth.
   ════════════════════════════════════════════════════════════════════════════ */
:root[data-theme='horizon'] {
  color-scheme: light;

  /* ── PLATINUM ─────────────────────────────────────────────────────────────
     Rebuilt 2026-08-07. The two earlier attempts were both warm ivory, and both
     were wrong for the same reason: ivory is the default light theme every AI
     company ships, and it fought a brand whose whole identity is metal.

     The idea here comes out of the logo instead of a palette. The mark carries TWO
     metals — gold and platinum. Cosmos is gold on black. Horizon is gold on the
     other metal: a cool machined-steel ground, the same brand at a different hour
     rather than a different brand. It also solves the field problem for free, since
     platinum particles on a platinum ground are finally the same material.

     GLARE IS A DESIGN CONSTRAINT HERE, not an afterthought. The first platinum pass
     used #EDEFF2 (L* 94) with near-black ink at 15.8:1 and was reported as painful
     to look at, which is the predictable result: on an emissive display a near-white
     field is a lamp, and maximum contrast on top of it is glare, not legibility.

     So the whole ramp is dimmed. Base sits at L* 91.5 — bright enough to read as
     white paper, roughly 8% less light than the ivory it replaces — and the ink
     stops at 11.4:1 rather than driving to black. Comfortable light UI lives around
     L* 88–92 with body text near 10–13:1; that is the window these values target.
     Nothing here is below AA, and nothing is above it for its own sake. */
  --surface-base: #E4E7EC;
  --surface-raised: #EFF1F4;
  --surface-overlay: #F6F7F9;
  --surface-sunken: #D7DCE3;
  --surface-glass: rgb(246 247 249 / 0.70);

  /* Deep slate, not black. #1C232B keeps the cool cast of the ground so the page
     reads as one material lit from one source. */
  --text-primary: #1C232B;
  --text-secondary: #414A56;
  /* Tuned against SUNKEN, the darkest ground small type ever sits on. */
  --text-muted: #575F6B;
  --text-on-accent: #F6F7F9;
  --text-accent: #875612;

  /* THE ACCENT — burnished copper.
     The previous #7A6019 was derived from its contrast ratio alone, and reaching a
     ratio by luminance pushes green up relative to red until the hue lands at 46°:
     olive. Cosmos gold is 46° too, but at high value, and the eye names dark yellow
     "olive" while naming dark orange "bronze". The ramp therefore turns warm as it
     descends — 27° here — holding a metal relationship to the Cosmos gold rather
     than a numeric one. On the cool ground the warmth also has somewhere to sit:
     copper against steel is a real material pairing, which cream never gave it.
     4.6:1 at worst across all four surfaces. */
  --accent-interactive: #875612;
  --accent-hover: #684109;
  --accent-solid: #875612;
  --accent-glow: rgb(135 86 18 / 0.18);

  /* Decorative gold carries the logo, and #D4AF37 on this ground is under 2:1 — the
     emblem dissolved. Antique gold clears 3:1 everywhere and still reads as gold. */
  --accent-decorative: #9E781F;

  /* Platinum is structural on this theme rather than incidental: it is the ground's
     own metal, so the logo's silver, the orbit and the rules are all the same alloy. */
  --sync-base: #48525E;
  --sync-muted: #6B7683;

  /* THE FIELD. Platinum #A0A8B3 scattered on cream was two desaturated neutrals a
     few percent apart — soil, not structure. On steel the cold points are the ground
     one shade deeper (3.5:1) and the hot points are copper (3.9:1): the same
     unsynchronised/synchronised reading as Cosmos, in reflected light instead of
     emitted. */
  --field-cold: #6A7583;
  --field-hot: #96601A;

  --border-subtle: rgb(28 35 43 / 0.10);
  --border-default: #C8CFD8;
  --border-interactive: #6B7683;
  --border-strong: #AEB7C2;
  --border-accent: rgb(135 86 18 / 0.36);

  --focus-ring: #875612;
  --success: #1E6549;
  --warning: #8A5A12;
  --danger: #9E2B2B;
  --info: #1F567D;

  /* Elevation is a soft shadow here rather than light, tinted to the ground's own
     cool cast — a warm shadow on a steel page reads as a stain. */
  --elevation-1: 0 1px 2px 0 rgb(20 26 34 / 0.06);
  --elevation-2: 0 8px 24px -8px rgb(20 26 34 / 0.13);
  --elevation-3: 0 20px 52px -14px rgb(20 26 34 / 0.17);
  --elevation-glow: 0 0 28px -6px rgb(135 86 18 / 0.18);

  --glass-tint: rgb(246 247 249 / 0.70);
  --glass-blur: 16px;

  /* The two themes composite in opposite directions. On the deep ground the points
     are light sources and accumulate; on a light ground an additive pass converges
     on white and erases the field exactly where it is strongest, so here the points
     cover instead. Intensity drops again with the darker field colours — the same
     alpha over darker ink is a stronger mark. */
  --field-blend: source-over;
  --field-intensity: 1.45;

  /* Grain reads darker-on-light. On a dimmed ground it needs very little to register,
     and anything more looks like sensor noise rather than film. */
  --grain-opacity: 0.016;
}



/* Reduced motion collapses every duration at the source, so a component cannot opt out
   by accident and no setting can re-enable motion for a visitor who asked for none. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-instant: 0ms;
    --duration-fast: 0ms;
    --duration-normal: 0ms;
    --duration-slow: 0ms;
    --duration-deliberate: 0ms;

    /* Collapsed for the same reason as the rest, and belt-and-braces: text.js already
       declines to scramble under this preference, so these should never be read. If one
       ever is, an interval of 0 resolves every character in a single frame rather than
       leaving a word stranded as random glyphs. */
    --scramble-tick: 0ms;
    --scramble-settle: 0ms;
    --scramble-settle-slow: 0ms;
  }
}
