/* ============================================================================
   Design tokens — the single source of truth for the Evolocity interface.
   Change a brand decision here and it propagates everywhere.

   Palette: ink and paper. Evolocity is a lab as much as a company, so the page
   is built like a publication — a near-white ground, near-black text, and a
   single research blue that appears only where the reader can act or where a
   measurement is marked. Colour is an instrument here, not decoration; if a
   surface does not need it, it does not get it.

   Type: ONE face at ONE weight for the entire interface — Latin Modern Sans,
   the typeface of the papers this work belongs beside. Hierarchy is carried by
   size, case, colour, and tracking, never by a second family or weight. Each
   size is paired with a fixed line-height on a 4px grid, and tracking tightens
   as size grows.
   ============================================================================ */

:root {
  /* --- Brand --------------------------------------------------------------
     One blue. Deep enough to hold body-size text on paper (8.8:1), saturated
     enough to read as an instrument rather than a corporate accent. */
  --brand: #1436e0;

  /* Provisional: black stand-ins where the brand hue is still being decided.
     Point these back at --brand (or a new hue) to restore colour in one edit. */
  --link: var(--ink);          /* standalone text links */
  --action: var(--ink);        /* solid buttons */
  --action-hover: #2b3138;
  --brand-on-ink: #8ba4ff;                /* accent on inverted surfaces */

  /* --- Grounds -------------------------------------------------------------
     Hue comes from the coloured mark's anchors in agents/logo/palette.json.
     Lightness and chroma are CHOSEN, not derived: three of the six anchors sit
     in the warm 30-47° band, so deriving all six mechanically produced tints
     that differed by 1-3 levels of 255 — a switcher that changed nothing you
     could see. They are now separated by chroma as well as hue, closest pair
     ~6 levels, and each still belongs to the mark. */
  --g-atelier: #f6f4f3;    --g-atelier-2: #eeeae6;   /* the mark's own ground */

  /* One ground per deck, each a tint of the mark's own anchors (hue from
     agents/logo/palette.json, lightness and chroma chosen so the decks read as
     distinct through the wash rather than as noise around one colour). The
     wash and the grain ride on top of all of them, so the light across the page
     and its tooth stay continuous while the decks differ in hue. */
  --deck-approach: #e8e0f2;   /* lavender, the ring's left */
  --deck-team: #f4ebe0;       /* sand, the ring's warm arc */
  --deck-contact: #ddedf1;    /* teal, the inner wall */

  /* Ground wash. The mark is lit: its face sweep runs sand at 0° (right) through
     pale blue at 90° (bottom) to periwinkle at 270° (top). The page borrows that
     light rather than inventing one — cool toward the upper left, warm toward the
     lower right.

     The ends are the ring's anchors ALREADY PULLED TO PAPER LIGHTNESS, so the wash
     drifts in hue and barely at all in brightness. A veil of the saturated anchors
     would have darkened the paper by ~9 levels, which would make the ground tokens
     stop describing what you actually see. Mixed against transparent so the chosen
     ground still shows through the middle.

     Exactly 90deg on purpose: a purely horizontal gradient is independent of the
     element's height, so it renders identically on a short section and a tall one
     and needs no `background-attachment: fixed` — which seams across surfaces and
     misbehaves on iOS Safari. */
  --wash: linear-gradient(90deg,
      color-mix(in srgb, #e6e1f5 30%, transparent) 0%,
      color-mix(in srgb, #e6e1f5 6%, transparent) 40%,
      color-mix(in srgb, #f7dcbb 7%, transparent) 60%,
      color-mix(in srgb, #f7dcbb 30%, transparent) 100%);

  /* The hero carries the wash at greater strength — it is the deck the page
     opens on, and the one with no colour of its own to read against. Same two
     pigments, both light, so the extra strength buys hue and not shadow. */
  --wash-strong: linear-gradient(90deg,
      color-mix(in srgb, #e6e1f5 52%, transparent) 0%,
      color-mix(in srgb, #e6e1f5 10%, transparent) 38%,
      color-mix(in srgb, #f7dcbb 12%, transparent) 62%,
      color-mix(in srgb, #f7dcbb 54%, transparent) 100%);

  /* Film grain. One octave at a high base frequency, so the noise is fine and
     near-random from pixel to pixel rather than clumped: measured neighbour
     correlation 0.13, against 0.63 for the three-octave version this replaces,
     which read as mottled paper rather than grain. Baked at low alpha and
     dropped on as a second background layer. Dark surfaces show noise far more
     readily and take roughly half the alpha for the same perceived weight. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='2.2' numOctaves='1' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.44'/%3E%3C/svg%3E");
  --grain-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='2.2' numOctaves='1' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.25'/%3E%3C/svg%3E");

  /* --- Neutrals ------------------------------------------------------------ */
  --paper: var(--g-atelier);      /* page ground */
  --paper-2: var(--g-atelier-2);  /* tinted band */
  --ink: #0e1116;               /* primary type, and the inverted band */
  --ink-2: #4a5158;             /* secondary type */
  --ink-3: #6e767e;             /* labels, captions */
  --on-ink: #f3f4f6;            /* type on the inverted band */
  --on-ink-2: #9aa3ad;
  --rule: rgba(14, 17, 22, .11);
  --rule-strong: rgba(14, 17, 22, .2);

  /* --- Family --------------------------------------------------------------
     One face sets the whole interface. --mark-nudge is the optical correction
     that centres the logo ring on the wordmark's cap band; it is measured per
     face, since cap height differs between them. */
  --font: "Libre Caslon Display", Georgia, "Times New Roman", serif;
  --w-reg: 400;

  /* Centres the ring on the wordmark's cap band. Measured, never estimated —
     see agents/test/measure.mjs. */
  --mark-nudge: .0097em;

  /* --- Type scale ---------------------------------------------------------
     Six sizes, no more. Fluid roles carry a ratio that lands on the grid at
     their cap; fixed roles carry a px line-height on the grid outright. */
  --fs-display: clamp(40px, 6vw, 80px);
  --lh-display: 1.05;    /* lands on the 4px grid at the 80px cap */
  --fs-h2: clamp(28px, 3.2vw, 40px);
  --lh-h2: 1.1;          /* lands on the 4px grid at the 40px cap */
  --fs-h3: 20px;
  --lh-h3: 28px;
  --fs-lede: 20px;
  --lh-lede: 32px;
  --fs-brand: 24px;
  --lh-brand: 32px;
  --fs-body: 16px;
  --lh-body: 24px;
  --fs-sm: 14px;
  --lh-sm: 20px;

  /* --- Tracking ladder -----------------------------------------------------
     One rule: the larger the type, the tighter it is set. Labels are the sole
     exception — uppercase always needs air. */
  --track-display: -.02em;
  --track-h2: -.015em;
  --track-h3: -.005em;
  --track-text: 0em;
  --track-label: .1em;

  /* --- Space (4px base) ---------------------------------------------------- */
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --s6: 32px;
  --s7: 48px;
  --s8: 64px;
  --s9: 96px;
  --pad-section: clamp(72px, 9vw, 128px);

  /* --- Structure ----------------------------------------------------------- */
  --max: 1200px;
  --measure: 60ch;
  --gutter: clamp(20px, 5vw, 40px);
  --radius: 4px;
  --radius-sm: 2px;
  --header-h: 56px;

  /* --- Motion --------------------------------------------------------------
     Motion shows a process happening; it never decorates an entrance.
     One curve, two durations. */
  --ease: cubic-bezier(.22, .68, .24, 1);
  --fast: .16s;
  --slow: .8s;

  color-scheme: light;
}
