/* =============================================================================
 * tokens.css — owned by the lead agent. Section builders must not edit this.
 *
 * Every colour and metric here was measured from the mockups with Pillow.
 * Source of truth: spec/global.md (and spec/typography.md for the faces).
 * Section stylesheets reference these tokens and never hardcode a hex.
 * ========================================================================== */

:root {
  /* ── the scale unit ─────────────────────────────────────────────────────
   * The mockups are 1586 x 992. `--u` is 1 mockup-pixel expressed fluidly:
   * 1/1586 of the viewport width = 0.0630517vw, which is EXACTLY 1px when the
   * viewport is 1586 wide. So `calc(46 * var(--u))` lands on the measured 46px
   * at reference width and scales proportionally elsewhere.
   * The clamp stops it collapsing on small screens or ballooning on 4K.
   * ------------------------------------------------------------------- */
  /* Scale on BOTH axes, not just width. 0.0630517vw == 1px at 1586 wide and
   * 0.1008065vh == 1px at 992 tall, so min() of the two makes the whole
   * 1586x992 frame behave like object-fit:contain: it fills whichever axis is
   * tighter and never overflows the other.
   * Width-only scaling was the bug behind the cut-off wordmark and the missing
   * footer bar — on a 1.90 aspect viewport the design was ~20% too tall. */
  /* Width-driven: the composition always fills the viewport width. On wide
   * (short) screens the 992u frame is TALLER than 100vh — sections grow via
   * their min-height: calc(992 * var(--u)) and the page simply scrolls more.
   * The old min(vw, vh) form let the height clamp u down on wide screens,
   * shrinking the whole UI into a centred box with dead gutters both sides. */
  --u: clamp(0.72px, 0.0630517vw, 2.60px);

  /* --uc is the COVER counterpart of --u.
   *   --u  = min(...)  contain — the whole 1586x992 frame fits, so LAYOUT never
   *                    overflows or clips. Letterboxes on the looser axis.
   *   --uc = max(...)  cover   — fills both axes and overflows the looser one,
   *                    which is what BACKGROUND ART wants so it always bleeds
   *                    edge to edge.
   * Size layout with --u and background plates with --uc. Using --u for art is
   * what left a 530px black band down the right at 2560x1440.
   * They are equal at the 1586x992 reference, so the A/B is unaffected. */
  --uc: max(0.0630517vw, 0.1008065vh);

  /* Horizontal offset that centres the contain-scaled frame in the viewport.
   * Zero at or below the reference aspect; grows as the viewport gets wider. */
  --frame-x: max(0px, calc((100vw - (1586 * var(--u))) / 2));

  --frame-w: 1586px;
  --frame-h: 992px;

  /* ── surfaces ─────────────────────────────────────────────────────────── */
  --bg-page:            #050505;   /* true page black — NOT #000 */
  --bg-page-warm:       #050503;   /* loading / hero warm cast */
  --bg-deep:            #020202;   /* contact / casestudy / about grade */
  --bg-void:            #010101;   /* vignette floor at frame corners */
  --bg-panel:           #070707;   /* modal / card body */
  --bg-panel-alt:       #060606;   /* modal right rail */
  --bg-elevated:        #2C2C2C;   /* filled button (hero) */
  --scrim:              rgba(0, 0, 0, .68);   /* casestudy modal scrim */

  /* ── ember / orange ───────────────────────────────────────────────────── */
  --ember-core:         #FFE47C;   /* white-hot centre (loading head dot) */
  --ember-hot:          #F5772F;   /* flame / lava / loading curve stroke */
  --accent:             #D9552A;   /* PRIMARY UI ORANGE */
  --accent-render:      #D26B42;   /* literal peak row of a 2px accent rule */
  --accent-solid:       #B83E15;   /* solid swatch (contact availability square) */
  --accent-solid-hero:  #A23216;   /* same swatch on hero's darker grade */
  --accent-mid:         #8C3A18;
  --accent-deep:        #5C1600;
  --accent-ember:       #3A1104;
  --accent-glow:        rgba(226, 86, 32, .45);
  --accent-glow-soft:   rgba(226, 86, 32, .18);

  /* ── text ─────────────────────────────────────────────────────────────── */
  --text-hi:            #FFFFFF;   /* display headings, nav, stat values */
  --text:               #E6E6E6;   /* body copy */
  --text-wordmark:      #DCDCDC;   /* "PORTFOLIO / 2026" only */
  --text-2:             #ABABAB;   /* secondary / meta / footer */
  --text-3:             #858585;   /* muted captions */
  --text-4:             #6A6A6A;   /* dimmest labels */

  /* ── lines ────────────────────────────────────────────────────────────── */
  --rule:               rgba(255, 255, 255, .13);
  --rule-strong:        rgba(255, 255, 255, .20);
  --border-panel:       rgba(255, 255, 255, .45);
  --border-chip:        rgba(255, 255, 255, .40);

  /* ── layout (measured left/right ink anchors) ─────────────────────────── */
  --gutter:             calc(46 * var(--u));   /* page gutter: chrome + hero rules */
  --gutter-r:           calc(70 * var(--u));   /* right gutter: nav ink ends x=1514 */
  --gutter-work:        calc(49 * var(--u));   /* work full-bleed rules 49 → 1537 */
  --content-bottom:     calc(44 * var(--u));

  --sp-1:               calc(11 * var(--u));
  --sp-2:               calc(22 * var(--u));
  --sp-3:               calc(34 * var(--u));
  --sp-4:               calc(46 * var(--u));
  --sp-5:               calc(56 * var(--u));
  --sp-6:               calc(68 * var(--u));
  --sp-8:               calc(90 * var(--u));
  --sp-10:              calc(112 * var(--u));

  /* ── fixed top bar ────────────────────────────────────────────────────── */
  --bar-cap-top:        calc(47 * var(--u));   /* cap-top of wordmark and nav */
  --bar-baseline:       calc(58 * var(--u));
  --bar-underline-off:  calc(12 * var(--u));   /* below baseline */
  --bar-underline-h:    calc(2.5 * var(--u));

  /* ── typography (identified empirically — see spec/typography.md) ─────── */
  /* The dot-matrix headlines are a REAL 5x7 bitmap font (Doto), not a CSS
   * gradient mask. Faces are self-hosted woff2 in assets/fonts/. */
  --f-dot:     'Doto', 'Courier New', monospace;
  --f-mono:    'Roboto Mono', ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
  --f-outline: 'Anton', 'Arial Narrow', Impact, sans-serif;
  --f-sans:    'Nunito Sans', 'Segoe UI', system-ui, Helvetica, Arial, sans-serif;

  /* dot-matrix engine constants (Doto) */
  --dot-pitch-em:    0.100;    /* dot cell  = 0.100em */
  --dot-adv-em:      0.600;    /* advance   = 0.600em (monospace) */
  --dot-cap-em:      0.682;    /* cap height at wght 800 */
  --dot-wght:        800;      /* fill ratio 0.82 == measured 4.6px dot in a 5.6px cell */

  /* measured chrome type (Roboto Mono advance ratio is 0.600) */
  --t-wordmark:      calc(13.5 * var(--u));    /* 13.5*0.6 + 1.00 = 9.10 advance */
  --t-nav:           calc(15 * var(--u));      /* 15*0.6   + 2.50 = 11.50 advance */
  --track-wordmark:  calc(1.00 * var(--u));
  --track-nav:       calc(2.50 * var(--u));
  --wght-wordmark:   500;
  --wght-nav:        340;        /* calibrated against measured ink, see base.css */
  --nav-ink:         #F0F0F0;

  /* general UI scale */
  --t-meta:          calc(19 * var(--u));      /* advance 12.40 */
  --t-ui:            calc(14.5 * var(--u));    /* advance 9.60 */
  --t-micro:         calc(13 * var(--u));
  --t-body:          calc(22 * var(--u));      /* hero sub-copy */
  --t-lead:          calc(25 * var(--u));

  /* ── grain (measured: monochrome, ~1.2px correlation, sigma ~1/255) ───── */
  --grain-tile:      240px;
  --grain-opacity:   .58;

  /* ── vignette (separable, tight edge crush — not a radial) ────────────── */
  --vig-x:           calc(72 * var(--u));
  --vig-y:           calc(56 * var(--u));
  --vig-l:           .26;
  --vig-r:           .24;
  --vig-t:           .15;
  --vig-b:           .12;

  /* ── motion ───────────────────────────────────────────────────────────── */
  --e-out:    cubic-bezier(0.16, 1, 0.3, 1);
  --e-inout:  cubic-bezier(0.65, 0, 0.35, 1);
  --e-soft:   cubic-bezier(0.33, 1, 0.68, 1);
  --d-fast:   280ms;
  --d-base:   620ms;
  --d-slow:   1100ms;
}

/* Below the desktop breakpoint the design re-lays-out rather than shrinking,
 * so the unit gets its own floor to keep type legible. */
@media (max-width: 1023px) {
  :root { --u: clamp(0.86px, 0.22vw, 1.1px); }
}

/* Screenshot + reduced-motion: everything at rest. */
.is-shot, .is-reduced {
  --d-fast: 0ms;
  --d-base: 0ms;
  --d-slow: 0ms;
}
