/* ==========================================================================
   PBE, LLC — "THIS SIDE UP"
   css/tokens.css — spec §2 (design tokens) + §3.8 (@property registration).

   Every hex in this file is sampled from a named PBE photograph. Five card
   grounds, because in this design the card ground is a variable, not a
   constant. Four monotone easing curves, zero overshoot. Two font families,
   three voices, and — by hard prohibition — NO MONOSPACE FAMILY. If anyone
   reaches for Spline Sans Mono or JetBrains Mono "just for the numbers", the
   rejected sites' display/body/mono stack is back and the whole distinctness
   argument collapses. Dimension numerals get their datasheet read from
   `font-variant-numeric: tabular-nums lining-nums` at Archivo `wdth 76`.

   Label tracking never exceeds 0.024em. Display tracking never exceeds
   -0.022em. Display line-height never below 0.80.
   ========================================================================== */

:root{

  /* ---- Card grounds (§2.1) --------------------------------------------- */
  /* Primary card ground: hero, band, manifest. A COOL white — the single most
     important anti-default decision in the palette. Sampled from the lit face
     of bubble rolls, carosel/IMG_0029.jpeg. NOT #F4F1EA. */
  --plate-foam:   #F6F6F3;
  /* Capabilities state. Lit paper, speciality/Paper Products….jpg */
  --plate-kraft:  #EFE7DA;
  /* Specification index + menu overlay. Translucent wall panels,
     optimus foam/IMG_1343.jpeg */
  --plate-seal:   #E3E8EE;
  /* Product-detail plate + close/colophon. optimus fill/peanuts.jpg */
  --plate-cream:  #F0EADF;
  /* Inverted state. Dark ground of Engineered Foam/Die Cut Foam.jpg */
  --plate-carbon: #14161A;

  /* ---- Type (§2.1) ----------------------------------------------------- */
  /* Primary type on all light grounds.
     13.4:1 on foam · 11.8:1 on kraft · 12.1:1 on cream · 11.6:1 on seal */
  --stencil:     #1B1D21;
  /* ALL secondary/body text on kraft, seal and cream.
     5.91:1 foam · 5.21:1 kraft · 5.34:1 cream · 4.90:1 seal */
  --stencil-2:   #5C5F66;
  /* Quiet secondary text — PERMITTED ON --plate-foam ONLY. 4.84:1 on foam.
     Fails on seal (4.25) / cream (4.37) / kraft (4.27) — never use there.
     The rule is mechanical: if the ground is not --plate-foam, secondary text
     is --stencil-2. This token replaces the original #8E8B85 (3.2:1). */
  --stencil-3:   #6F6C66;
  /* Primary type on carbon. 13.1:1 */
  --carbon-type: #F1F1EE;
  /* Secondary type on carbon. 7.80:1 */
  --carbon-soft: #A8ABA6;

  /* ---- Rules and edges (§2.1) ------------------------------------------ */
  --rule:        rgba(27,29,33,0.10);
  --rule-strong: rgba(27,29,33,0.18);
  --rule-dark:   rgba(241,241,238,0.16);
  --panel-edge:  rgba(27,29,33,0.18);  /* 1px inner hairline on every photo panel */

  /* ---- Warm family (kraft) (§2.1) -------------------------------------- */
  --kraft-lit:   #C69A6D;  /* non-text: callout leader lines on kraft */
  --kraft-mid:   #9A6B41;  /* rotated italic mark; capabilities rules. 4.6:1 on kraft — text >= 16px only */
  --kraft-gold:  #E0A24C;  /* non-text only: band type-panel ground, gallery label card */

  /* ---- Cool family (§2.1) --------------------------------------------- */
  --cobalt:      #235C8C;  /* SHADER ONLY — duotone midtone. Never a UI colour. */
  --seal-blue:   #2B3990;  /* the PBE mark blue. The ONE interactive colour: link hover, focus ring, pressed pill. 8.9:1 on foam */
  --focus-dark:  #F1F1EE;  /* focus ring on carbon — seal-blue is invisible there */

  /* ---- Grace note (§2.1) ----------------------------------------------- */
  /* Exactly two uses on the entire site, both on the carbon leaf:
     1: 2px strike rule through "recordings". 2: 5px live dot beside the phone
     number. Nothing else, ever. */
  --film-red:    #C7302B;
  --film-cyan:   #4FA6D4;  /* SHADER ONLY — film-refraction sheen tint */

  /* ---- Shader grade triplets — uShadow / uMid / uHigh (§2.1) -----------
     Consumed by js/engine/grade.js as uniforms, not by CSS. Recorded here so
     the palette lives in exactly one place.

       foam   (hero, band, manifest)  #1B1D21 / #6E7379 / #F6F6F3   steel, near-neutral
       kraft  (capabilities)          #2A1D12 / #9A6B41 / #F2E9DB   kraft
       seal   (spec index, menu)      #131A24 / #235C8C / #E9EEF3   seal
       carbon (inverted)              #05060A / #2B3138 / #7E858C   crushed steel
       cream  (detail, close)         #241B10 / #A87F55 / #F4EFE6   warm neutral
     --------------------------------------------------------------------- */

  /* ---- Fonts (§2.2) — two Google families, three voices, ZERO monospace */
  --f-display: "Bodoni Moda", "Bodoni MT", Didot, Georgia, serif;
  --f-label:   "Archivo", "Archivo Narrow", "Helvetica Neue", Arial, sans-serif;

  /* ---- Fluid type scale (§2.3) -----------------------------------------
     Sizes are in cqw against the card, because the card is the page. The card
     carries container-type: inline-size. Below 560px --t-giant sits on its
     4.25rem floor and the giant word switches to its 5-glyph variant (§7).

     THE svh CAP IS NOT DECORATION. cqw alone reads the card's WIDTH only, so on
     a wide, short window (a maximised browser on a 16:9 laptop is the common
     case) the display type grew to 80-300px inside a 600px-tall stage and the
     leaf no longer fit: the hero lede was cut mid-line and the capabilities
     table lost its last row, both behind an inner scrollbar. The card is inset
     4.4svh top and bottom, so the stage is ~70svh; every display size is now
     also capped against that, and the leaves fit at any aspect ratio.
     `container-type: inline-size` gives no cqh, which is why these are svh. */
  --t-giant:     min(clamp(4.25rem, 20.5cqw, 19rem),   26svh);
  --t-statement: min(clamp(2.1rem,  6.4cqw,  5rem),    7.6svh);
  --t-menu:      min(clamp(1.9rem,  7cqw,    4.25rem), 9svh);
  --t-plate:     min(clamp(1.75rem, 4cqw,    3.15rem), 7svh);
  --t-quote:     min(clamp(1.35rem, 3.1cqw,  2.35rem), 4.2svh);
  --t-row:       1.3125rem;
  --t-body:      clamp(0.875rem, 1.05cqw, 1rem);
  --t-mark:      0.9375rem;
  --t-label:     0.6875rem;
  --t-num:       0.75rem;

  /* ---- Spacing scale (§2.4) -------------------------------------------- */
  --s-1:0.25rem; --s-2:0.5rem;  --s-3:0.75rem; --s-4:1rem;
  --s-5:1.5rem;  --s-6:2rem;    --s-7:3rem;    --s-8:4.5rem; --s-9:7rem;
  --card-pad:  clamp(16px, 2.3cqw, 34px);   /* card interior padding */
  --card-gap:  clamp(12px, 1.6cqw, 20px);   /* corner-slot gap */
  --stack:     clamp(0.75rem, 1.4cqw, 1.5rem);

  /* ---- Easing (§2.5) — four curves, all monotone, ZERO OVERSHOOT --------
     No bounce, no spring, no cubic-bezier with a control point above 1.
     Neither rejected site's signature curve appears. */
  --e-lay:   cubic-bezier(.22,.86,.16,1);   /* arrives — reveals, lay-down, incoming leaf, menu open */
  --e-fall:  cubic-bezier(.66,.02,.86,.28); /* leaves decisively — outgoing leaf, menu close, lid off */
  --e-grade: cubic-bezier(.44,.02,.24,1);   /* grounds, grade, aperture, backdrop */
  --e-roll:  cubic-bezier(.3,.9,.1,1);      /* mechanical — pill roll, pill width, mark drift */

  /* ---- Durations (§2.6) ------------------------------------------------
     Declared with the `ms` unit so the spec's own CSS (e.g.
     `transition: opacity var(--d-ground) var(--e-grade)` in §3.3) is valid as
     written. JS reads them with parseFloat(), which discards the unit. */
  --d-lay:940ms; --d-lay-radius:620ms; --d-backdrop-lay:1180ms;
  --d-chrome:520ms; --d-chrome-stagger:60ms;
  --d-leaf-out:380ms; --d-leaf-hold:90ms; --d-leaf-in:720ms;
  /* THE CROSS-DISSOLVE. --d-leaf-lead is how long after the outgoing leaf
     starts leaving that the incoming one starts arriving. The original sequence
     was strictly serial — 380 out, then a 90 ms hold, then a further 90 ms CSS
     delay before the 720 ms in — which left the card measurably EMPTY from
     ~373 ms to ~569 ms on every single leaf change. That blank is why the site
     read as a deck of slides instead of one continuous surface. At 190 ms the
     incoming leaf is already resolving while the outgoing is still dissolving,
     the two overlap for ~190 ms, and the stage is never empty.
     Raise it toward 380 for a cleaner cut; lower it for a longer dissolve. */
  --d-leaf-lead:190ms;
  /* Depth either side of the dissolve. The outgoing leaf grows very slightly as
     it goes, the incoming resolves up from just behind the plane — a film
     dissolve rather than a cut. Scale only: zero vertical travel, and both ends
     land on exactly 1 so nothing's steady-state geometry is disturbed. */
  --leaf-depth-out:1.035; --leaf-depth-in:0.982;
  --d-glyph:760ms; --d-glyph-stagger:46ms;
  --d-cut:860ms; --d-cut-delay:240ms; --d-cut-img:1400ms; --d-cut-hair:300ms;
  --d-ground:620ms;                            /* ground cross-fade */
  --d-onplate:180ms; --d-onplate-delay:20ms;   /* corner chrome ink swap */
  --d-lid:460ms; --d-lid-stagger:40ms; --d-lid-off:340ms;
  --d-pill-out:260ms; --d-pill-in:440ms; --d-pill-w:520ms;
  --d-menu-open:620ms; --d-menu-close:420ms; --d-menu-row:480ms; --d-menu-stagger:34ms;
  --d-callout-line:520ms; --d-callout-tick:180ms; --d-callout-num:260ms; --d-callout-delay:420ms;
  --d-mask:900ms;                              /* silhouette dissolve — the universal threshold gesture */
  --d-mark-follow:520ms; --d-mark-release:900ms;
  --d-row:380ms; --d-row-stagger:40ms;
}

/* ---- Container-query-unit fallback (§2.3) ------------------------------
   The card is ~90.8vw wide at desktop, so 1cqw ~= 0.908vw. Verbatim from
   spec §2.3. */
@supports not (width: 1cqw){
  :root{
    --t-giant:     min(clamp(4.25rem, 18.6vw, 19rem),   26svh);
    --t-statement: min(clamp(2.1rem,  5.8vw,  5rem),    7.6svh);
    --t-menu:      min(clamp(1.9rem,  6.35vw, 4.25rem), 9svh);
    --t-plate:     min(clamp(1.75rem, 3.63vw, 3.15rem), 7svh);
    --t-quote:     min(clamp(1.35rem, 2.81vw, 2.35rem), 4.2svh);
    --t-body:      clamp(0.875rem, 0.95vw, 1rem);
  }
}

/* The spec's fallback block covers the type scale only. The three cqw
   spacing tokens in §2.4 would otherwise be invalid at computed-value time on
   a browser without container query units, collapsing the card's interior
   padding to zero. Same 0.908 conversion factor the spec states above; no new
   token is introduced. */
@supports not (width: 1cqw){
  :root{
    --card-pad: clamp(16px, 2.09vw, 34px);
    --card-gap: clamp(12px, 1.45vw, 20px);
    --stack:    clamp(0.75rem, 1.27vw, 1.5rem);
  }
}

/* ---- @property registration (§3.8) — MANDATORY ------------------------
   Unregistered custom properties do not interpolate at all. Every animated
   custom property is registered. */
@property --cut-t   { syntax:'<number>';     inherits:false; initial-value:0 }
@property --lid-t   { syntax:'<number>';     inherits:false; initial-value:0 }
@property --pill-w  { syntax:'<length>';     inherits:false; initial-value:0px }
@property --hair    { syntax:'<number>';     inherits:false; initial-value:0 }
@property --draw    { syntax:'<percentage>'; inherits:false; initial-value:0% }
