/* =========================================================================
   Vela Design System · tokens

   Release design system. Single source of truth for color, type, space, motion.
   Migrated to oklch() for perceptual uniformity. All existing semantic
   names (--paper-N, --ink-N, --rule-N, --gold, --state-*) are preserved
   as aliases so legacy code keeps working while the kit is rebuilt.

   Doctrine, in one line: one register, two modes (brand vs product),
   one scale, one signature accent (gold), one motion chord struck
   three ways. See docs/SITE-REDESIGN-PLAN.md.
   ========================================================================= */

:root {
  /* =======================================================================
     COLOR — oklch + brand-named
     -----------------------------------------------------------------------
     Hex literals listed in comments are the ΔE<2 visual targets the oklch
     values were calibrated against. Source CSS should never hard-code hex.
     ======================================================================= */

  /* ── Surfaces ── first-light register (cool, hue ~248; matches the
     production app at app.constellate.science — never warm cream) ─── */
  --paper-0:        oklch(97.2% 0.008 248);   /* page ground — first light, cool */
  --paper-1:        oklch(99.2% 0.004 248);   /* raised — cards, panels */
  --paper-2:        oklch(93.2% 0.011 250);   /* sunken well, hover, shell canvas */
  --paper-edge:     oklch(88.0% 0.012 250);   /* default border */
  --paper-deep:     var(--paper-2);           /* legacy alias */

  --background:     var(--paper-0);
  --surface:        var(--paper-1);
  --sand:           var(--paper-2);
  --border:         var(--paper-edge);

  --mist:           oklch(89.0% 0.014 240);   /* atmospheric depth, cool */
  --stone:          oklch(55.0% 0.022 80);   /* heavier divider, inactive */

  /* ── Ink ── Vela midnight family ──────────────────────────────────── */
  --ink-0:          oklch(20.0% 0.030 262);   /* hero headlines, logo (≈ #081320) */
  --ink-1:          oklch(25.0% 0.030 262);   /* body (≈ #0E1C2E) */
  --ink-2:          oklch(43.0% 0.026 258);   /* secondary, subhead (≈ #1E2F44) */
  --ink-3:          oklch(53.5% 0.018 250);   /* tertiary, captions (≈ #4A5A6F) */
  --ink-4:          oklch(62.0% 0.018 254);   /* faintest text (≈ #6E7B8B) */
  --navy-1:         var(--ink-0);             /* legacy alias */
  --navy-2:         var(--ink-2);
  --navy-deep:      oklch(17.4% 0.024 252);   /* dark-panel ground (≈ #0B1A2E) */

  --on-background:  var(--ink-0);
  --on-surface:     var(--ink-1);
  --muted:          var(--ink-4);

  /* ── Hairlines ── ink-with-alpha, never grey ──────────────────────── */
  --rule-1:         color-mix(in oklch, var(--ink-1) 6%, transparent);
  --rule-2:         color-mix(in oklch, var(--ink-1) 13%, transparent);
  --rule-3:         color-mix(in oklch, var(--ink-1) 22%, transparent);
  --rule-ink:       color-mix(in oklch, var(--ink-1) 86%, transparent);

  /* ── Signature — Luminous Gold ────────────────────────────────────── */
  --gold:           oklch(72.0% 0.130 86);    /* decorative — borders, halos (≈ #D4AF37) */
  --gold-ink:       oklch(46.8% 0.102 82);    /* WCAG-AA text on paper-0 (≈ #8a6d18) */
  --gold-soft:      color-mix(in oklch, var(--gold) 32%, transparent);
  --gold-glow:      color-mix(in oklch, var(--gold) 20%, transparent);
  --gold-light:     oklch(82.0% 0.082 78);    /* softer accent variant (≈ #D1B98C) */
  --tertiary:       var(--gold);
  --on-tertiary:    oklch(20.0% 0.018 60);
  --focus-ring:     oklch(76.6% 0.144 78);

  /* ── Atmospheric — for dark panels ───────────────────────────────── */
  --primary:        oklch(23.8% 0.028 250);   /* (≈ #1A2231) */
  --on-primary:     var(--paper-0);
  --secondary:      oklch(28.0% 0.030 250);   /* (≈ #232B3A) */
  --on-secondary:   var(--paper-1);

  /* ── Editorial state — never traffic-light ────────────────────────── */
  --cinnabar:       oklch(49.5% 0.128 35);    /* retraction, contradiction (≈ #B5443A) */
  --moss:           oklch(43.5% 0.043 128);   /* replicated, verified (≈ #59634E) */
  --brass:          oklch(45.5% 0.082 83);    /* contested, dissent (≈ #8A6A1F) */
  --winter:         oklch(68.5% 0.040 236);   /* inferred, speculative, cross-frontier (≈ #8FA7B7) */

  /* State washes — engraved-chip backgrounds for the materials above. */
  --moss-soft:      color-mix(in oklch, var(--moss) 14%, transparent);
  --brass-soft:     color-mix(in oklch, var(--brass) 14%, transparent);
  --cinnabar-soft:  color-mix(in oklch, var(--cinnabar) 9%, transparent);
  --winter-soft:    color-mix(in oklch, var(--winter) 14%, transparent);
  --stone-soft:     color-mix(in oklch, var(--stone) 12%, transparent);

  /* ── Aurora teal — calibration mark, cross-frontier signal, the cool
     counterpoint to gold. Used for instrument readouts where gold would
     overstate. Reads as "fiducial reference" not "luxury accent."     */
  --aurora:        oklch(72.0% 0.080 196);
  --aurora-soft:   color-mix(in oklch, var(--aurora) 32%, transparent);
  --aurora-glow:   color-mix(in oklch, var(--aurora) 18%, transparent);

  /* ── Twilight — cosmic indigo at the bottom of the horizon. Cream
     paper transitions into open sky here. Carries the "looking up" cue. */
  --twilight:      oklch(34.0% 0.072 280);
  --twilight-deep: oklch(22.0% 0.060 270);

  /* ── Dawn — warm amber at the horizon, paired with twilight indigo. */
  --dawn:          oklch(74.0% 0.094 64);
  --dawn-soft:     color-mix(in oklch, var(--dawn) 24%, transparent);

  /* ── Star — pinpoint warm-white for dot-fields, magnitude ticks,
     constellation cartography on dark grounds.                          */
  --star:          oklch(92.0% 0.022 78);
  --star-faint:    color-mix(in oklch, var(--star) 32%, transparent);

  /* Semantic aliases */
  --seafoam:        var(--moss);
  --success:        var(--moss);
  --state-ok:       var(--moss);
  --warning:        var(--brass);
  --state-warn:     var(--brass);
  --error:          var(--cinnabar);
  --contradiction:  var(--cinnabar);
  --state-lost:     var(--cinnabar);
  --state-stale:    var(--stone);

  /* Live state — gold is the live signal, not blue */
  --signal:         var(--gold);
  --signal-soft:    var(--gold-soft);
  --signal-edge:    var(--gold-glow);
  --state-live:     var(--gold);

  --speculative:    var(--winter);
  --inferred:       var(--winter);

  /* ── Star glow — lantern halo around focus ────────────────────────── */
  --star-glow:         oklch(95.0% 0.058 88);
  --star-glow-bright:  oklch(98.0% 0.040 88);

  /* ── Legacy named aliases (kept for migration period) ─────────────── */
  --vela-night-indigo:  var(--primary);
  --vela-deep-navy:     var(--secondary);
  --vela-lantern-gold:  var(--gold);
  --vela-warm-brass:    var(--brass);
  --vela-paper-ivory:   var(--paper-0);
  --vela-frost-blue:    var(--winter);
  --vela-ember-red:     var(--cinnabar);

  /* =======================================================================
     TYPE — one variable serif (Fraunces), one sans (Inter Tight),
     one mono (IBM Plex Mono). Cormorant + Newsreader deprecated.
     ======================================================================= */

  /* v0.180 (split-architecture polish): unified typography with the
     Next.js platform. Source Serif 4 carries display + emphasis (the
     observatory-notebook serif), Inter handles UI + body, JetBrains
     Mono carries code, ids, sha256 hashes. Fraunces + Inter Tight +
     IBM Plex Mono retained as fallbacks so any not-yet-migrated
     legacy pages still render legibly. */
  --font-sans:      "Inter", "Inter Tight", -apple-system, BlinkMacSystemFont, ui-sans-serif, system-ui, sans-serif;
  --font-mono:      "JetBrains Mono", "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --font-display:   "Source Serif 4", "Source Serif Pro", "Fraunces", Georgia, serif;
  --font-serif:     var(--font-display);
  --font-body:      var(--font-sans);
  --font-poetic:    var(--font-display);
  --font-literary:  var(--font-display);
  --font-jp:        var(--font-sans);

  /* ── Brand mode (fluid, marketing surfaces) ──────────────────────── */
  --display-xl:     clamp(48px, 6.4vw, 88px);     /* hero only */
  --display-l:      clamp(34px, 3.6vw, 52px);     /* section headlines */
  --display-m:      clamp(24px, 2.4vw, 34px);     /* sub-section */

  /* ── Product mode (fixed, workbench/replay/constellation) ────────── */
  --text-h1:        28px;
  --text-h2:        22px;
  --text-h3:        18px;
  --text-h4:        16px;

  /* ── Shared ──────────────────────────────────────────────────────── */
  --text-lede:      19px;
  --text-body:      16.5px;
  --text-small:     14.5px;
  --text-meta:      12px;
  --text-kicker:    10.5px;

  /* ── Legacy size tokens (kept; values aligned to plan) ───────────── */
  --size-xs:        11px;
  --size-sm:        13px;
  --size-base:      14px;
  --size-md:        17px;
  --size-lg:        22px;
  --size-xl:        32px;
  --size-2xl:       36px;
  --size-3xl:       48px;
  --size-display:   var(--display-xl);
  --size-h1:        var(--display-l);
  --size-h2:        var(--display-m);
  --size-prose:     17px;
  --size-prose-sm:  15px;
  --size-meta:      var(--text-meta);
  --size-kicker:    var(--text-kicker);
  --size-imprint:   var(--text-kicker);

  /* ── Leading ─────────────────────────────────────────────────────── */
  --leading-tight:    1.04;
  --leading-snug:     1.30;
  --leading-italic:   1.32;   /* epigraph, pull-quote */
  --leading-body:     1.55;
  --leading-read:     1.74;
  --leading-ui:       1.45;

  /* ── Tracking ────────────────────────────────────────────────────── */
  --track-display:   0;
  --track-tight:     0;
  --track-body:      0;
  --track-none:       0;
  --track-mono-label: 0.06em;
  --track-tick:       0.14em;
  --track-eyebrow:    0.18em;
  --track-imprint:    0.18em;
  --track-label:      0.08em;

  /* =======================================================================
     SPACE — 8-step scale (--s-0..--s-7)
     -----------------------------------------------------------------------
     Use these tokens. Improvised paddings drift; documented ones don't.
     ======================================================================= */

  --s-0: 4px;    /* tight, inline */
  --s-1: 8px;    /* between sibling labels */
  --s-2: 16px;   /* paragraph rhythm */
  --s-3: 24px;   /* between cards within a section */
  --s-4: 40px;   /* between sub-sections */
  --s-5: 72px;   /* between sections (tight register) */
  --s-6: 120px;  /* between sections (generous register) */
  --s-7: 200px;  /* hero-to-first-section */

  /* Legacy --space-N (kept for migration; values normalized to plan) */
  --space-1:  var(--s-0);
  --space-2:  var(--s-1);
  --space-3:  12px;
  --space-4:  var(--s-2);
  --space-5:  var(--s-3);
  --space-6:  32px;
  --space-7:  var(--s-4);
  --space-8:  56px;
  --space-9:  var(--s-5);
  --space-10: var(--s-6);

  /* =======================================================================
     LAYOUT — container, measure, gutter
     ======================================================================= */

  --measure:        41.5rem;                          /* prose reading column (≈ 66ch) */
  --measure-wide:   52rem;                            /* figure expansion */
  --measure-page:   1180px;                           /* full marketing page width */
  --container-px:   clamp(20px, 4vw, 48px);           /* horizontal page gutter */
  --container-py:   clamp(28px, 5vh, 52px);           /* vertical page padding */
  --gutter:         var(--container-px);              /* legacy alias */

  /* Vertical rhythm */
  --rhythm-section: var(--s-5);
  --rhythm-block:   var(--s-3);
  --rhythm-tight:   var(--s-1);

  /* =======================================================================
     BREAKPOINTS — documented scale
     ======================================================================= */

  --bp-narrow:  480px;   /* phone */
  --bp-mid:     720px;   /* small tablet */
  --bp-wide:    1024px;  /* desktop */
  --bp-cinema:  1440px;  /* large desktop */

  /* =======================================================================
     RADII
     ======================================================================= */

  --radius-0:    0;
  --radius-xs:   3px;
  --radius-sm:   4px;
  --radius-md:   6px;
  --radius-lg:   10px;
  --radius-xl:   14px;
  --radius-full: 9999px;
  --radius-1:    var(--radius-sm);
  --radius-2:    var(--radius-md);
  --radius-3:    var(--radius-lg);

  /* =======================================================================
     ELEVATION — quiet, paper-stack feel
     ======================================================================= */

  --lift-1:  0 1px 0 var(--rule-2);
  --lift-2:  0 2px 8px color-mix(in oklch, var(--ink-1) 6%, transparent),
             0 0 0 1px var(--rule-2);
  --lift-3:  0 8px 24px color-mix(in oklch, var(--ink-1) 10%, transparent),
             0 0 0 1px var(--rule-2);

  /* =======================================================================
     MOTION — 3 durations × 2 easings × 4 primitives. That is the chord.
     ======================================================================= */

  /* Durations */
  --dur-fast: 180ms;   /* UI hover/focus */
  --dur-mid:  360ms;   /* fold reveal, panel transition */
  --dur-slow: 1200ms;  /* kintsugi seam, cascade trace, hero entrance */

  /* Easings */
  --ease-out:   cubic-bezier(0.20, 0, 0.13, 1);
  --ease-trace: cubic-bezier(0.65, 0, 0.35, 1);

  /* Legacy aliases (kept; pointed at canonical) */
  --ease:        var(--ease-out);
  --ease-spring: var(--ease-out);
  --dur-1:       var(--dur-fast);
  --dur-2:       var(--dur-mid);
  --dur-3:       var(--dur-mid);
  --dur-4:       var(--dur-slow);
}

/* =========================================================================
   MOTION PRIMITIVES — four classes. If a property needs to animate, it
   uses one of these. Anything else is wrong.
   ========================================================================= */

/* 1. Fold entrance — fade up by 8px. Triggered on IntersectionObserver. */
.motion-fade-in-up {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--dur-mid) var(--ease-out),
              transform var(--dur-mid) var(--ease-out);
}
.motion-fade-in-up.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* 2. Gold trace — kintsugi seam, cascade propagation. Apply via
   stroke-dasharray + stroke-dashoffset on SVG paths. */
.motion-gold-trace {
  stroke-dasharray: var(--trace-length, 700);
  stroke-dashoffset: var(--trace-length, 700);
  transition: stroke-dashoffset var(--dur-slow) var(--ease-trace),
              opacity var(--dur-mid) var(--ease-out);
}
.motion-gold-trace.is-traced {
  stroke-dashoffset: 0;
}

/* 3. Scope narrow — pill shrink toward its anchor when scope is corrected. */
.motion-scope-narrow {
  transform-origin: left center;
  transition: transform 800ms var(--ease-trace),
              opacity var(--dur-mid) var(--ease-out);
}
.motion-scope-narrow.is-narrowed {
  transform: scaleX(0.74);
}

/* 4. Hover lift — buttons + interactive cards. */
.motion-hover-lift {
  transition: transform var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out);
}
.motion-hover-lift:hover,
.motion-hover-lift:focus-visible {
  transform: translateY(-1px);
}

/* =========================================================================
   Base — reading register
   ========================================================================= */

html {
  font-size: 17px;
  line-height: var(--leading-read);
  scroll-behavior: smooth;
  overscroll-behavior: none;
  overflow-x: clip;
}

@media (min-width: 768px) {
  html { font-size: 18px; }
}

body {
  background: var(--paper-0);
  color: var(--ink-1);
  font-family: var(--font-body);
  font-feature-settings: "ss01", "cv11", "calt";
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

h1, h2 {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: var(--track-display);
  color: var(--ink-0);
  text-wrap: balance;
}

code, pre, kbd, samp {
  font-family: var(--font-mono);
  font-size: 0.88em;
}

/* Quiet inline link — gold underline as a thin seam. Editorial, not CTA. */
a.quiet-link {
  color: inherit;
  text-decoration: none;
  background-image: linear-gradient(
    to right,
    color-mix(in oklch, var(--gold) 38%, transparent),
    color-mix(in oklch, var(--gold) 38%, transparent)
  );
  background-size: 100% 1px;
  background-repeat: no-repeat;
  background-position: 0 100%;
  padding-bottom: 0.06em;
  transition: color var(--dur-fast) var(--ease-out),
              background-image var(--dur-fast) var(--ease-out);
}
a.quiet-link:hover,
a.quiet-link:focus-visible {
  color: var(--gold-ink);
  background-image: linear-gradient(to right, var(--gold), var(--gold));
}

::selection {
  background-color: var(--star-glow);
}

/* =========================================================================
   Type roles — the eight roles the kit uses. Anything else, don't.
   ========================================================================= */

/* Display — once per page or hero. Fraunces, light weight, italic-aware. */
.t-display, .t-display-xl {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--display-xl);
  line-height: var(--leading-tight);
  letter-spacing: var(--track-display);
  color: var(--ink-0);
  text-wrap: balance;
  font-variation-settings: "opsz" 144;
}

.t-display-lg, .t-hero {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--display-l);
  line-height: 1.06;
  letter-spacing: var(--track-display);
  color: var(--ink-0);
  text-wrap: balance;
  font-variation-settings: "opsz" 144;
}

.t-h1 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--display-l);
  line-height: 1.1;
  letter-spacing: var(--track-tight);
  color: var(--ink-0);
  text-wrap: balance;
}

/* Poetic — italic Fraunces for the rare atmospheric moment. */
.t-poetic {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 350;
  letter-spacing: 0;
  color: var(--ink-0);
}

.t-h2, .t-section {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--display-m);
  line-height: 1.18;
  letter-spacing: var(--track-tight);
  color: var(--ink-0);
}

.t-h3 {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--text-h3);
  line-height: 1.41;
  letter-spacing: 0;
  color: var(--ink-0);
}

.t-body {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: var(--text-body);
  line-height: 1.57;
  letter-spacing: 0;
  color: var(--ink-1);
}

.t-body-sm {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: var(--text-small);
  line-height: 1.54;
  letter-spacing: 0;
  color: var(--ink-1);
}

.t-lede {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: var(--text-lede);
  line-height: 1.5;
  letter-spacing: 0;
  color: var(--ink-2);
  max-width: 60ch;
  text-wrap: pretty;
}

.t-read {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--size-prose);
  line-height: var(--leading-read);
  color: color-mix(in oklch, var(--ink-1) 88%, var(--ink-2));
  text-wrap: pretty;
}
.t-read p + p { margin-top: 1.1em; }
.t-read p:first-of-type { text-indent: 0; }

.t-label {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--size-xs);
  line-height: var(--leading-ui);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-3);
}

.t-tick {
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: var(--size-xs);
  letter-spacing: var(--track-tick);
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.t-mono {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.5;
  font-weight: 450;
  letter-spacing: 0;
  color: var(--ink-1);
  font-variant-numeric: tabular-nums;
}

.t-caption {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: var(--size-xs);
  line-height: var(--leading-ui);
  letter-spacing: 0.01em;
  color: var(--ink-3);
}

.t-kicker {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--text-kicker);
  letter-spacing: var(--track-imprint);
  text-transform: uppercase;
  color: color-mix(in oklch, var(--gold) 76%, var(--ink-2));
}

.t-imprint {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--text-kicker);
  letter-spacing: var(--track-imprint);
  text-transform: uppercase;
  color: color-mix(in oklch, var(--gold) 72%, var(--ink-2));
}

.t-jp {
  font-family: var(--font-sans);
  font-weight: 400;
}

/* =========================================================================
   Primitives — hairlines, tick rows, focal glow
   ========================================================================= */

.rule        { background: var(--rule-2); height: 1px; width: 100%; border: 0; }
.rule--v     { background: var(--rule-2); width: 1px; height: 100%; border: 0; }
.rule--heavy { background: var(--rule-3); }

.rule--gold {
  height: 1px;
  width: 100%;
  border: 0;
  background: linear-gradient(
    to right,
    transparent 0%,
    color-mix(in oklch, var(--gold) 38%, transparent) 18%,
    color-mix(in oklch, var(--gold) 56%, transparent) 50%,
    color-mix(in oklch, var(--gold) 38%, transparent) 82%,
    transparent 100%
  );
}

.ticks {
  height: 8px;
  background-image: linear-gradient(to right,
    var(--rule-3) 0 1px,
    transparent 1px 100%);
  background-size: 12px 100%;
  background-repeat: repeat-x;
  background-position: left bottom;
}
.ticks--tight { background-size: 6px 100%; }
.ticks--wide  { background-size: 24px 100%; }

.focal-glow {
  box-shadow: 0 0 24px var(--gold-glow);
  transition: box-shadow var(--dur-mid) var(--ease-out);
}

.alidade {
  height: 1px;
  background: var(--gold);
  box-shadow: 0 0 0 1px var(--gold-soft);
}

/* =========================================================================
   Focus
   ========================================================================= */

:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

/* =========================================================================
   Reduced motion — kill the chord
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .motion-fade-in-up { opacity: 1 !important; transform: none !important; }
  .motion-gold-trace { stroke-dashoffset: 0 !important; }
  .motion-scope-narrow { transform: none !important; }
}
