/* ═══════════════════════════════════════════════════════════════════════════
   INHOUSE — foundations
   Dark-first, because the demo is paper-light and Dheeraj shows both sites in
   one call. They must not read as one template.
   Type: Fraunces (display, variable opsz/SOFT/WONK) + Schibsted Grotesk (text)
   + JetBrains Mono (measurements). Deliberately NOT Bodoni Moda + Jost (the
   demo), not Libre Caslon + Archivo, not Instrument, not Inter.
   Three colours: ground, ink, clay.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* light is defined first and in full; dark redefines only tokens */
  --bg:      #F6F4F0;
  --bg-2:    #EEEBE4;
  --bg-3:    #E4E0D6;
  --fg:      #14171A;
  --fg-2:    #494F57;
  --fg-3:    #7A8189;
  --clay:    #B44A26;
  --clay-fg: #FFF6F2;
  --line:    rgba(20, 23, 26, .14);
  --line-2:  rgba(20, 23, 26, .07);
  --good:    #1E6B4F;
  --sh-1: 0 1px 2px rgba(20,23,26,.05), 0 2px 8px rgba(20,23,26,.04);
  --sh-2: 0 2px 6px rgba(20,23,26,.07), 0 14px 36px rgba(20,23,26,.08);
  --sh-3: 0 6px 12px rgba(20,23,26,.1), 0 36px 72px rgba(20,23,26,.16);
  --ring:  #2F6BD1;
  /* Safari fallback: color-mix() needs 16.2 and backdrop-filter needs the
     -webkit- prefix. Without both the sticky header had no ground and no blur
     on an older iPhone, and page text scrolled under the nav. */
  --veil-hd: rgba(246, 244, 240, .87);

  --display: "Fraunces", "Georgia", "Times New Roman", serif;
  --text:    "Schibsted Grotesk", "Helvetica Neue", system-ui, sans-serif;
  --mono:    "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;

  /* 11px was the smallest step. At 390px that is 160 text nodes a client
     squints at, so the floor is 12px — mono uppercase labels included. */
  --t--2: .75rem;    --t--1: .8125rem;  --t-0: 1.0625rem;
  --t-1:  1.3125rem; --t-2:  1.625rem;  --t-3: 2.125rem;
  --t-4:  clamp(1.9rem, 1.3rem + 2.2vw, 2.9rem);
  --t-5:  clamp(2.3rem, 1.2rem + 3.5vw, 4rem);
  --t-6:  clamp(2.5rem, 1rem + 4.6vw, 4.5rem);
  --t-num: clamp(2.6rem, 1.4rem + 4.4vw, 5rem);

  --s-1: .25rem; --s-2: .5rem;  --s-3: .75rem; --s-4: 1rem;
  --s-5: 1.5rem; --s-6: 2rem;   --s-7: 3rem;   --s-8: 4rem;
  --s-9: 6rem;   --s-10: 8rem;
  --gutter: clamp(1.125rem, 4vw, 3.25rem);
  --wrap: 76rem;
  --wrap-wide: 92rem;
  --measure: 36rem;
  --sec-y: clamp(4.5rem, 8.5vw, 9rem);

  --ease-out:    cubic-bezier(.23, 1, .32, 1);
  --ease-in-out: cubic-bezier(.77, 0, .175, 1);
  --ease-drawer: cubic-bezier(.32, .72, 0, 1);
  --d-press: 120ms; --d-hover: 180ms; --d-pop: 220ms;
  --d-sheet: 280ms; --d-reveal: 620ms; --d-count: 900ms;

  --r: 3px; --r-lg: 5px;
  color-scheme: light dark;
}

/* dark is the intended look; the guard means an explicit light choice wins */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0E1012; --bg-2: #15181B; --bg-3: #1D2126;
    --fg: #EAE7E0; --fg-2: #A2A8B0; --fg-3: #767D85;
    --clay: #E0764F; --clay-fg: #180A05;
    --line: rgba(234,231,224,.15); --line-2: rgba(234,231,224,.07);
    --good: #4FBF92;
    --sh-1: 0 1px 2px rgba(0,0,0,.5);
    --sh-2: 0 2px 8px rgba(0,0,0,.5), 0 18px 44px rgba(0,0,0,.45);
    --sh-3: 0 6px 16px rgba(0,0,0,.55), 0 40px 80px rgba(0,0,0,.6);
    --veil-hd: rgba(14, 16, 18, .87);
    --ring: #79A6F0;
  }
}
:root[data-theme="dark"] {
  --bg: #0E1012; --bg-2: #15181B; --bg-3: #1D2126;
  --fg: #EAE7E0; --fg-2: #A2A8B0; --fg-3: #767D85;
  --clay: #E0764F; --clay-fg: #180A05;
  --line: rgba(234,231,224,.15); --line-2: rgba(234,231,224,.07);
  --good: #4FBF92;
  --sh-1: 0 1px 2px rgba(0,0,0,.5);
  --sh-2: 0 2px 8px rgba(0,0,0,.5), 0 18px 44px rgba(0,0,0,.45);
  --sh-3: 0 6px 16px rgba(0,0,0,.55), 0 40px 80px rgba(0,0,0,.6);
  --veil-hd: rgba(14, 16, 18, .87);
  --ring: #79A6F0;
}

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body {
  background: var(--bg); color: var(--fg);
  font-family: var(--text); font-size: var(--t-0); line-height: 1.66;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
img, svg, video { display: block; max-width: 100%; }
img { height: auto; background: var(--bg-3); }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; }
[hidden] { display: none !important; }
:focus-visible { outline: 2px solid var(--ring); outline-offset: 3px; border-radius: 2px; }
::selection { background: var(--clay); color: var(--clay-fg); }

/* ── type ──────────────────────────────────────────────────────────────────── */
.display {
  font-family: var(--display); font-weight: 500; line-height: 1.06;
  letter-spacing: -.024em; text-wrap: balance;
  /* Fraunces carries an optical-size axis (9–144). Pinning it at 100 for every
     size leaves the small display text too delicate and the large text not
     delicate enough; the axis exists to be moved. Set per size class below. */
  font-variation-settings: "SOFT" 0, "WONK" 1, "opsz" 48;
}
.hero-h, .card-stat-n, .headline-stat .n { font-variation-settings: "SOFT" 0, "WONK" 1, "opsz" 120; }
.sec-h, .stage-h, .who-h, .ok-h { font-variation-settings: "SOFT" 0, "WONK" 1, "opsz" 72; }
.pillar-h, .gap-q, .item-h, .demo-h, .run-h, .hd-mark b, .ft-mark b,
.card-stat-l { font-variation-settings: "SOFT" 0, "WONK" 1, "opsz" 24; }
h1, h2, h3, h4 { font-weight: 500; }
.eyebrow {
  font-family: var(--mono); font-size: var(--t--2); font-weight: 500;
  letter-spacing: .17em; text-transform: uppercase; color: var(--fg-3);
}
/* An eyebrow is a label FOR the heading under it, and with no margin it sat
   flush against a 56px display line on every section head on both pages —
   fourteen of them, measured at 0px. The gap is set on the adjacency rather
   than on .eyebrow itself, because the same class labels cards and stats where
   the tighter setting is right. */
.eyebrow + h1, .eyebrow + h2, .eyebrow + h3,
.eyebrow + .sec-h, .eyebrow + .display { margin-top: var(--s-4); }
.lede { font-size: var(--t-1); line-height: 1.5; color: var(--fg-2); max-width: 34rem; }
.prose { max-width: var(--measure); color: var(--fg-2); }
.prose strong, .lede strong { color: var(--fg); font-weight: 600; }
.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.clay { color: var(--clay); }

/* ── layout ────────────────────────────────────────────────────────────────── */
.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gutter); }
.wrap--wide { max-width: var(--wrap-wide); }
.wrap--tight { max-width: 48rem; }
.sec { padding-block: var(--sec-y); position: relative; }
.sec--raised { background: var(--bg-2); }
.sec--sunk { background: var(--bg-3); }
.sec-hd { display: grid; gap: var(--s-4) var(--s-8); margin-bottom: var(--s-8); }
@media (min-width: 62rem) {
  .sec-hd { grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); align-items: end; }
}
.sec-h { font-size: var(--t-4); }
.sec-sub { color: var(--fg-2); max-width: 32rem; }
.rule { height: 1px; background: var(--line); border: 0; }

/* ── buttons ───────────────────────────────────────────────────────────────── */
.btn {
  --bbg: transparent; --bfg: var(--fg); --bbd: var(--fg);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  min-height: 2.9rem; padding: 0 var(--s-5); max-width: 100%;
  background: var(--bbg); color: var(--bfg);
  border: 1px solid var(--bbd); border-radius: var(--r);
  font-size: var(--t--1); font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; text-decoration: none; white-space: nowrap;
  transition: background var(--d-hover) var(--ease-out),
              color var(--d-hover) var(--ease-out),
              border-color var(--d-hover) var(--ease-out),
              transform var(--d-press) var(--ease-out);
}
.btn--solid { --bbg: var(--fg); --bfg: var(--bg); --bbd: var(--fg); }
.btn--clay  { --bbg: var(--clay); --bfg: var(--clay-fg); --bbd: var(--clay); }
.btn--ghost { --bbd: var(--line); --bfg: var(--fg-2); }
.btn--sm { min-height: 2.3rem; padding: 0 var(--s-4); font-size: var(--t--2); }
.btn--wrap { white-space: normal; text-align: center; line-height: 1.35; padding-block: var(--s-3); }
@media (hover: hover) and (pointer: fine) {
  .btn--solid:hover { --bbg: var(--clay); --bbd: var(--clay); --bfg: var(--clay-fg); }
  .btn--clay:hover  { filter: brightness(1.1); }
  .btn--ghost:hover { --bbd: var(--fg); --bfg: var(--fg); }
}
.btn:active { transform: scale(.97); }
.btn[disabled] { opacity: .4; cursor: not-allowed; }
.btn[disabled]:active { transform: none; }
.press { transition: transform var(--d-press) var(--ease-out); }
.press:active { transform: scale(.97); }

/* ── reveal: IntersectionObserver baseline ────────────────────────────────────
   Hidden state armed by JS, never by the stylesheet alone — see the demo's
   copy of this comment. A plain `.rv { opacity: 0 }` turned a stale cached
   script into a blank page. */
html.rv-armed .rv { opacity: 0; transform: translateY(16px); }
/* SPECIFICITY. `html.rv-armed .rv` is (0,2,1); a bare `.rv-on` is (0,1,0) and
   LOSES to it — so arming the reveal hid the content permanently and nothing
   could turn it back on. The revealed state has to be scoped the same way.
   Caught only by reading the h1's computed opacity: the aggregate "418 visible
   elements" looked perfectly healthy while every heading on the page sat at
   opacity 0. */
html.rv-armed .rv.rv-on, .rv-on {
  opacity: 1; transform: none;
  transition: opacity var(--d-reveal) var(--ease-out), transform var(--d-reveal) var(--ease-out);
  transition-delay: calc(var(--rvi, 0) * 65ms);
}
.no-js .rv, html:not(.rv-armed) .rv,
html:not(.rv-armed) .rv.rv-on { opacity: 1; transform: none; }

/* ── reduced motion: drop MOVEMENT, never LAYOUT ──────────────────────────
   Deliberately no `transform: none !important` — that rule once deleted a
   fanned card layout built from static transforms. */
@media (prefers-reduced-motion: reduce) {
  /* an unarmed page is already visible; this keeps it that way */
  html.rv-armed .rv, html.rv-armed .rv.rv-on { opacity: 1; transform: none; }
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  .rv { opacity: 1; transform: none; }
}

.skip {
  position: absolute; left: var(--s-4); top: var(--s-4); z-index: 100;
  padding: var(--s-2) var(--s-4); background: var(--fg); color: var(--bg);
  text-decoration: none; font-size: var(--t--1); border-radius: var(--r);
  transform: translateY(-160%); transition: transform var(--d-pop) var(--ease-out);
}
.skip:focus { transform: none; }
.vh { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* ── single-column grids must be allowed to be narrower than their widest
      child; an `auto` track is floored at the child's min-content width, and
      one nowrap button can push a whole column past the viewport ─────────── */
.stack, .stack > *, .cards, .card, .sec-hd, .sec-hd > *,
.pillars > *, .gaps > *, .stages > *, .stage > *, .menu > *, .demos > *,
.demo > *, .runs > *, .who > *, .call > *, .closer > *, .ft-in > *,
.audit-lead > *, .findings > *, .finding > *, .agenda-i > *, .fgrid > *,
.picks > *, .enqs > *, .scan-row > *, .ok-list > *, .mini-grid > * { min-width: 0; }
/* the closer frame holds a 2880px-wide screenshot; without this it set its own
   grid track 5px wider than a 320px viewport */
.closer-frame, .closer-frame img { max-width: 100%; }

/* smooth scroll (js/smooth.js): the browser's own smooth behaviour fights it */
html.is-smooth { scroll-behavior: auto !important; }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-stopped { overflow: clip; }
