/* FOHS landing — production port of "FOHS Landing v2" canvas.
   Tokens extracted from the approved design; see DESIGN.md. */

:root {
  --paper: #FFFFFF;
  --surface: #F9FAFC;
  --surface-2: #FAFBFD;
  --code-bg: #131418;
  --code-bg-deep: #0E0F12;

  /* The floating nav takes zero flow height (negative bottom margin), so every page's
     first band extends up behind the glass pill. First-section top paddings add this. */
  --nav-clear: 70px; /* 10 wrapper padding + 58 pill + 2 border */

  /* Neutrals are blue-cast toward the accent hue (≈227°) — pure-neutral greys
     retired 2026-07-15 (Stripe research pass); contrast preserved or improved. */
  --ink: #0E1220;
  --body: #4C5063;
  --muted: #686D7E;
  --faint: #959AAC;

  --border: #E4E6EF;
  --border-ctrl: #D9DCE8;
  --border-soft: #DDE0EA;
  --hairline: #EEF0F6;
  --border-hover: #A0A5B4;
  --grid-line: rgba(43, 73, 182, 0.05); /* drafting grid on the tinted hero band (banded pass; was #EDF1FA on white) */

  --indigo: #2B49B6;
  --indigo-hover: #23399A;
  --tint-edge: #C9D2EE;
  --tint-edge-2: #D5DCF2;
  --tint-fill: #DCE3F7;
  --tint-fill-2: #D8DFF5;
  --tint-face: #EDF1FA;
  --tint-face-2: #F7F8FD;
  --tint-open: #E7EDFB;   /* accordion open row (DESIGN.md platform grammar) */

  /* Signal palette (2026-07-15, founder direction "Ledger signals"): color = state.
     Cyan = live / data-in-motion, amber = standby / roadmap / pending.
     Annotation scale only — never CTAs, links, headings, body text, or band surfaces. */
  --signal-cyan: #0E7490;
  --signal-cyan-deep: #155E75;
  --signal-cyan-edge: #BEE7F2;
  --signal-cyan-face: #E4F6FB;
  --signal-amber: #B45309;
  --signal-amber-deep: #92400E;
  --signal-amber-edge: #F0DCBC;
  --signal-amber-face: #FDF2E3;

  /* Canary signal (2026-07-20, founder "Infra Stack Hero" canvas): pink = canary
     deploy / promotion-in-flight. Same law as cyan/amber — annotation and
     illustration scale only. --canary-deep is the chip text value: the canvas's
     #B44FA6 darkened one step so 11px text holds 4.5:1 on --canary-face
     (accessibility floor, NOT lifted). */
  --canary-bright: #DD79D2;
  --canary-ghost: #DD8FD3;
  --canary-soft: #EFB3E7;
  --canary-edge: #E9B6DF;
  --canary-fill: #F3D3EF;
  --canary-face: #FDF3FB;
  --canary-deep: #A8489A;

  --code-text: #E7E9EE;
  --code-dim: #C9CFDA;
  --code-comment: #767E8E;
  --code-accent: #93ACF2;

  --cta: #2B49B6;      /* primary actions carry the brand accent (2026-07-14; ink CTAs retired) */
  --cta-hover: #23399A;

  --font-sans: 'General Sans', sans-serif;
  --font-mono: 'IBM Plex Mono', monospace;

  --ease-hover: cubic-bezier(0.25, 1, 0.5, 1); /* Stripe pass 2026-07-15 */
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.55;
  overflow-x: clip;
}
::selection { background: var(--indigo); color: #FFFFFF; }
:focus-visible { outline: 2px solid var(--indigo); outline-offset: 2px; }

.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--ink); color: #FFFFFF;
  padding: 10px 16px; border-radius: 0 0 6px 0;
  font-size: 14px; font-weight: 500; text-decoration: none;
}
.skip-link:focus { left: 0; }

/* Visually hidden, available to screen readers (hero email label) */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}
.blue { color: var(--indigo); }
.ink { color: var(--ink); }
/* Two-tone headings (2026-07-15): the continuation clause dims to --body;
   the opening statement stays ink. Dark bands use --code-dim. */
.dim { color: var(--body); }
.section-cta .dim { color: var(--code-dim); }

/* Wide-canvas pass 2026-07-21 (founder: the page "appears narrow in the middle" on a
   big monitor, citing poly.ai). Was a fixed 1168px box / 1120px content, which fills
   only 61% of a 1920 viewport and 46% of a 2560 one. The gutter now scales with the
   viewport instead of the content column being frozen, and the cap rises to 1600.
   Fill at 1920 goes 61% → 83%. It stops short of poly.ai's ~92% full-bleed on
   purpose: their hero type is 128px, which is what lets an ~1760px content column
   read as deliberate. At this site's type scale an uncapped column stretches the
   04/05 card paragraphs past comfortable line length on a 2560 monitor. */
.container { max-width: 1600px; margin-inline: auto; padding-inline: clamp(24px, 4.2vw, 72px); }

h1, h2, h3, p { margin: 0; }

/* ============ Hover motion (Stripe pass 2026-07-15) ============ */
/* Color-only transitions — not "motion", so no reduced-motion gate needed. */
.btn, .nav-link, .nav-menu-title, .nav-m-row, .nav-m-sublink, .acc-link, .code-note-link,
.strip-operator-link, .footer-col a, a.inline-code, .tab, .code-btn {
  transition: color 150ms var(--ease-hover), background-color 150ms var(--ease-hover),
              border-color 150ms var(--ease-hover);
}
/* Arrow links: the chevron nudges right on hover (transform transition lives in
   the prefers-reduced-motion: no-preference block — instant under reduced motion). */
.link-arrow::after { content: "\2192"; content: "\2192" / ""; display: inline-block; margin-left: 6px; } /* alt-text syntax: decorative, hidden from screen readers */
.link-arrow:hover::after, .link-arrow:focus-visible::after { transform: translateX(3px); }

/* ============ Buttons ============ */
.btn {
  display: inline-block;
  text-decoration: none;
  font-size: 15px;
  font-weight: 500;
  border-radius: 6px;
}
.btn-primary { background: var(--cta); color: #FFFFFF; padding: 12px 20px; }
.btn-primary:hover { background: var(--cta-hover); }
.btn-outline { color: var(--ink); padding: 11px 18px; border: 1px solid var(--tint-edge-2); background: var(--paper); } /* tinted control border (Stripe pass 2026-07-15) */
.btn-outline:hover { border-color: var(--indigo); color: var(--indigo); }
.btn-sm { font-size: 14px; padding: 9px 16px; }
.nav-links .btn-outline.btn-sm { padding: 8px 15px; } /* optical: the 1px border must not make Log in taller than Book demo */
/* Hover lift (2026-07-15 freedoms pass): the lifted state applies always — it's a
   discrete state change (accordion-chevron precedent); only the tween is gated,
   inside the prefers-reduced-motion: no-preference block below. */
.btn:hover { transform: translateY(-1px); box-shadow: 0 4px 12px -4px rgba(14, 18, 32, 0.16); }
.btn-primary:hover { box-shadow: 0 4px 12px -4px rgba(43, 73, 182, 0.35); } /* indigo shadow under the indigo CTA */
/* Dark surfaces: a drop shadow reads invisible-to-muddy on #0E0F12 — lift only */
.section-cta .btn:hover, .demo-side .btn:hover { box-shadow: none; }
/* Nav: excluded — a lifting button inside the sticky 64px bar reads as jitter next
   to non-lifting links; covers the mobile panel CTA too (both live in nav.nav). */
.nav .btn:hover { transform: none; box-shadow: none; }

/* ============ Nav (floating glass pill, 2026-07-17) ============ */
/* The wrapper is transparent and full-width; pointer-events off so page content in the
   gutters around the pill stays clickable. The pill itself re-enables them. The negative
   bottom margin removes the nav from the flow so each page's first band (hero tint,
   /compliance dark) runs up behind the pill — no white strip above it. */
.nav {
  position: sticky; top: 0; z-index: 50;
  padding: 10px 14px 0; /* 14px = minimum side gap before .container's auto margins take over */
  margin-bottom: calc(-1 * var(--nav-clear));
  pointer-events: none;
}
.nav-inner {
  pointer-events: auto;
  display: flex; align-items: center; justify-content: space-between; height: 58px;
  padding-inline: 22px 9px; /* right side hugs the pill-shaped CTA */
  background: rgba(255, 255, 255, 0.6);
  backdrop-filter: blur(16px) saturate(1.5);
  -webkit-backdrop-filter: blur(16px) saturate(1.5);
  border: 1px solid rgba(213, 220, 242, 0.85); /* --tint-edge-2 at glass alpha */
  border-radius: 999px;
  box-shadow: 0 1px 2px rgba(14, 18, 32, 0.05), 0 12px 32px -14px rgba(14, 18, 32, 0.2),
              inset 0 1px 0 rgba(255, 255, 255, 0.85); /* top highlight = the glass edge */
}
.nav .btn { border-radius: 999px; } /* buttons echo the pill (covers bar + mobile card CTAs) */
.nav-brand { display: flex; align-items: center; gap: 10px; }
.nav-mark { height: 28px; width: auto; display: block; flex-shrink: 0; }
.nav-logo { font-weight: 600; font-size: 18px; letter-spacing: -0.01em; }
.nav-links { display: flex; align-items: center; gap: 28px; }
.nav-links .btn { white-space: nowrap; } /* the CTA is the only shrinkable flex item — never let it wrap inside the 64px bar */
.nav-link { color: var(--ink); text-decoration: none; font-size: 14px; font-weight: 500; }
.nav-link:hover { color: var(--indigo); }
.nav-brand { text-decoration: none; color: inherit; }
.nav-brand:hover .nav-logo { color: var(--indigo); }

/* ---- Nav dropdowns (CSS-only: hover + focus-within; JS-free by design) ---- */
.nav-group { position: relative; display: flex; align-items: center; height: 58px; } /* = pill height: no hover gap */
.nav-trigger {
  appearance: none; background: none; border: 0; padding: 0;
  font-family: inherit; /* longhand on purpose: `font: inherit` would reset the size/weight set by .nav-link */
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
}
.nav-caret {
  width: 6px; height: 6px; margin-top: -3px;
  border-right: 1px solid currentColor; border-bottom: 1px solid currentColor;
  transform: rotate(45deg);
  opacity: 0.55;
}
.nav-menu {
  position: absolute; top: 100%; left: -18px; z-index: 60;
  padding-top: 9px; /* invisible hover bridge across the nav hairline + 8px of air */
  display: none;
}
/* Hover-open only for devices that truly hover — on touch, app.js's click toggle owns it */
@media (hover: hover) and (pointer: fine) {
  .nav-group:hover .nav-menu { display: block; }
}
.nav-group.open .nav-menu { display: block; } /* set by app.js (disclosure pattern) */
html:not(.js) .nav-group:focus-within .nav-menu { display: block; } /* keyboard fallback without JS */
.nav-menu-panel {
  min-width: 176px; /* narrow single-line items (kilo.ai reference, 2026-07-17) */
  background: rgba(255, 255, 255, 0.88); /* glass to match the pill */
  backdrop-filter: blur(16px) saturate(1.5);
  -webkit-backdrop-filter: blur(16px) saturate(1.5);
  border: 1px solid var(--tint-edge-2);
  border-radius: 16px;
  box-shadow: 0 12px 32px -12px rgba(14, 18, 32, 0.18);
  padding: 6px;
}
.nav-menu-item { display: block; padding: 9px 12px 10px; text-decoration: none; border-radius: 10px; white-space: nowrap; }
.nav-menu-title { display: block; font-size: 14px; font-weight: 500; color: var(--ink); }
.nav-menu-item:hover { background: var(--tint-face); }
.nav-menu-item:hover .nav-menu-title,
.nav-menu-item:focus-visible .nav-menu-title { color: var(--indigo); }
.nav-link[aria-current="page"],
.nav-trigger[data-current] { color: var(--indigo); }
.nav-menu-item[aria-current="page"] .nav-menu-title { color: var(--indigo); }

/* ---- Mobile menu (burger + floating card panel; ≤800px only, driven by app.js) ---- */
.nav-burger {
  display: none; /* flex ≤800px */
  appearance: none; background: none; border: 0; padding: 0;
  width: 44px; height: 44px; margin-right: -8px; /* optical: bars balance the pill's 9px end padding */
  cursor: pointer; border-radius: 999px;
  flex-direction: column; align-items: center; justify-content: center; gap: 5px;
}
.nav-burger-bar { display: block; width: 18px; height: 1.5px; background: var(--ink); }
.nav-open .nav-burger-bar:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav-open .nav-burger-bar:nth-child(2) { opacity: 0; }
.nav-open .nav-burger-bar:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }
.nav-mobile { display: none; } /* .nav-open shows it inside the ≤800px media block */
/* Scroll lock lives in the ≤800px block below: scoping it to the breakpoint means a
   resize past 800px can never strand the page unscrollable, even if the JS close-on-
   resize listener never fires. */
/* Card rows: flat hairline-divided list mirroring the desktop nav order (2026-07-17,
   kilo.ai-style card). Dividers between top-level items only — subs sit inside their row. */
.nav-mobile > * + * { border-top: 1px solid var(--hairline); }
.nav-m-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 13px 4px;
  font-size: 15px; font-weight: 500; color: var(--ink); text-decoration: none;
  cursor: pointer;
}
.nav-m-trigger { list-style: none; } /* native details marker off — the caret chevron carries the affordance */
.nav-m-trigger::-webkit-details-marker { display: none; }
.nav-m-caret {
  width: 7px; height: 7px; margin-top: -4px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  opacity: 0.55;
}
.nav-m-group[open] > .nav-m-trigger .nav-m-caret { transform: rotate(-135deg); margin-top: 4px; }
.nav-m-sub { display: grid; gap: 2px; padding: 0 4px 12px; }
.nav-m-sublink {
  display: block; padding: 9px 10px; border-radius: 10px;
  font-size: 14.5px; color: var(--body); text-decoration: none;
}
.nav-m-sublink:hover { color: var(--ink); background: var(--tint-face); }
.nav-m-row[aria-current="page"],
.nav-m-trigger[data-current],
.nav-m-sublink[aria-current="page"] { color: var(--indigo); }
.nav-m-ctas { display: grid; gap: 10px; padding: 16px 2px 4px; }
.nav-m-ctas .btn { display: block; text-align: center; }

/* ============ Hero (solid tinted band — D9: no fade, painted-gradient ban intact) ============ */
.hero {
  position: relative; overflow: hidden;
  /* Painted wash (2026-07-15 freedoms pass — first sanctioned painted gradient since
     the ban lift): indigo tint drifting into the cyan face on the illustration side,
     where the cyan data-in-motion elements live. Sits under .hero-grid-bg.
     --body on #E4F6FB = 7.16:1 — tint text floor holds. */
  background-color: var(--tint-face);
  background-image: linear-gradient(112deg, var(--tint-face) 45%, var(--signal-cyan-face) 100%);
  border-bottom: 1px solid var(--tint-edge-2);
}
.hero-grid-bg {
  position: absolute; inset: 0;
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: 40px 40px;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 92%);
  mask-image: linear-gradient(to bottom, #000 0%, transparent 92%);
}
.hero-cross {
  position: absolute; width: 40px; height: 40px;
  background: rgba(43, 73, 182, 0.05);
  border: 1px solid rgba(43, 73, 182, 0.22);
  pointer-events: none;
}
.hero-cross-label {
  position: absolute; left: 46px; top: 13px;
  font-size: 10px; color: var(--indigo); white-space: nowrap; opacity: 0.7;
}
.hero-blip {
  position: absolute; width: 40px; height: 40px; pointer-events: none;
  background: rgba(43, 73, 182, 0.07);
  border: 1px solid rgba(43, 73, 182, 0.16);
  opacity: 0;
}
/* padding-block only — the element is `.container .hero-inner`, and a `padding`
   shorthand here would clobber .container's fluid inline gutter. Top pad 72 → 36px
   (2026-07-21, founder: "move the hero page a bit up"). */
.hero-inner { position: relative; padding-block: calc(36px + var(--nav-clear)) 40px; }
/* The artwork track stays a hard 500px — that is the Infra Stack Hero canvas width,
   and it only zooms below 560px viewports, so a fluid track here would clip it under
   .hero's overflow: hidden. All the container's new width goes to the copy column.
   Gap floors at 40px (the pre-2026-07-21 value) so the ~1025px two-column edge case
   is no tighter than it already was. */
.hero-cols {
  display: grid; grid-template-columns: minmax(0, 1fr) 500px; gap: clamp(40px, 3.5vw, 64px);
  align-items: center; margin-bottom: 56px;
}
.hero-status { display: flex; align-items: center; gap: 8px; margin-bottom: 24px; }
.hero-status-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--indigo); display: inline-block; }
.hero-status-text { font-size: 12px; letter-spacing: 0.08em; color: var(--indigo); } /* carries the residency claim on the band — indigo, not muted */
.hero-caret { display: inline-block; width: 6px; height: 12px; background: var(--faint); }
/* Cap 50 → 76px (2026-07-21): the wider container hands the copy column ~360px more
   room, and a 50px headline sitting in it is what read as "small on a big monitor".
   Coefficient drops 6vw → 4.75vw so the cap lands at the container's own 1600px cap
   rather than at ~1270px — at 6vw the headline hit 76px while the copy column was
   still ~550px wide and wrapped to five lines. */
.hero-headline {
  font-weight: 600; font-size: clamp(34px, 4.75vw, 76px);
  line-height: 1.07; letter-spacing: -0.026em; margin: 0 0 22px;
}
.hero-sub { margin: 0 0 32px; max-width: 640px; font-size: 18px; line-height: 1.6; color: var(--body); }
.hero-ctas { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.hero-pip { font-size: 12.5px; color: var(--body); margin-left: 8px; } /* --body, not --muted: tinted surfaces never carry lighter text */
/* One-field demo capture (2026-07-17): email pill posting straight to Web3Forms —
   the frictionless sibling of the /demo full form. Echoes the glass nav pill. */
.hero-capture {
  display: flex; align-items: center; gap: 8px;
  flex: 1 1 300px; max-width: 430px;
  padding: 5px 5px 5px 18px;
  background: rgba(255, 255, 255, 0.72);
  border: 1px solid var(--tint-edge-2);
  border-radius: 999px;
  box-shadow: 0 1px 2px rgba(14, 18, 32, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.9);
}
/* The input's own outline is off; the capsule carries a visible focus ring instead */
.hero-capture:focus-within { border-color: var(--indigo); box-shadow: 0 0 0 3px rgba(43, 73, 182, 0.14); }
.hero-email {
  /* width: 0 kills the input's intrinsic size-attribute width (~177px), which would
     otherwise inflate the hero grid column's min-content and overflow ≤350px viewports;
     flex-grow gives it all the pill's spare width anyway. */
  flex: 1; min-width: 0; width: 0; padding: 8px 0;
  border: 0; outline: 0; background: none;
  font-family: inherit; font-size: 15px; color: var(--ink);
}
.hero-email::placeholder { color: var(--muted); }
.hero-capture .btn { border-radius: 999px; padding: 10px 18px; font-size: 14px; white-space: nowrap; }

/* ---- Isometric plates (shared construction) ---- */
.plate { position: absolute; width: var(--w); height: var(--ch); }
.plate i { position: absolute; left: 0; width: var(--w); display: block; }
.plate .plate-bottom { bottom: 0; height: var(--eh); border-radius: 50%; background: var(--fill); }
.plate .plate-band { top: var(--bt); height: var(--bh); background: var(--fill); }
/* Material shading (DESIGN.md 2026-07-14 evening): radial highlight on the top face —
   stops are paper + the palette's own ramp face value, never a new hue. */
.plate .plate-top { top: 0; height: var(--eh); border-radius: 50%; background: radial-gradient(ellipse at 38% 30%, #FFFFFF 0%, var(--face) 72%); border: 1px solid var(--edge); }

/* Soft ground shadow under aria-hidden illustration groups (grey alpha only).
   Geometry is per-instance; the base is shared. */
.ground {
  position: absolute; border-radius: 50%;
  background: radial-gradient(ellipse at center, rgba(14, 18, 32, 0.13), transparent 68%);
}

.pal-indigo { --fill: var(--indigo); --face: var(--tint-face-2); --edge: var(--tint-edge); }
.pal-tint   { --fill: var(--tint-fill); --face: var(--tint-face-2); --edge: var(--tint-edge); }
.pal-tint3  { --fill: var(--tint-fill); --face: var(--surface-2); --edge: var(--tint-edge-2); }
.pal-grey   { --fill: var(--border); --face: var(--surface); --edge: var(--border-soft); }
.pal-canary { --fill: var(--canary-fill); --face: var(--canary-face); --edge: var(--canary-edge); }

/* ---- Chips ---- */
.chip {
  position: absolute;
  background: var(--paper);
  border: 1px solid var(--border-ctrl);
  border-radius: 4px;
  padding: 4px 9px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink);
  white-space: nowrap;
}
.chip-stat { letter-spacing: 0.06em; font-variant-numeric: tabular-nums; }
.chip-label { letter-spacing: 0.1em; padding: 4px 10px; color: var(--body); border-color: var(--tint-edge); }
.chip-indigo { background: rgba(43, 73, 182, 0.05); border-color: var(--indigo); color: var(--indigo); }
.chip-faint { color: var(--muted); border-color: var(--border-soft); }
/* Signal chips: cyan = live/data-in-motion, amber = standby (annotation scale only) */
.chip-cyan { background: var(--signal-cyan-face); border-color: var(--signal-cyan); color: var(--signal-cyan-deep); }
.chip-amber { background: var(--signal-amber-face); border-color: var(--signal-amber); color: var(--signal-amber-deep); }
.chip-canary { background: var(--canary-face); border-color: var(--canary-edge); color: var(--canary-deep); letter-spacing: 0.1em; padding: 4px 10px; }

/* ---- Hero serving stack — "Infra Stack Hero" v2 (founder canvas, 2026-07-20) ---- */
/* 500×590 canvas. Geometry is a 1:1 port of the approved canvas; neutrals snap to
   the site's blue-cast tokens, pinks are the new canary signal (see :root). */
.stack { position: relative; width: 500px; height: 590px; }
/* Local dot-grid backdrop, radially masked out — sits over the band's drafting grid */
.stack::before {
  content: ""; position: absolute; inset: -36px;
  background-image: radial-gradient(var(--tint-fill) 1px, transparent 1px);
  background-size: 24px 24px; opacity: 0.55;
  -webkit-mask-image: radial-gradient(ellipse at center, #000 42%, transparent 76%);
  mask-image: radial-gradient(ellipse at center, #000 42%, transparent 76%);
}
/* White chips need a whisper of lift off the tinted band / illustration fields */
.stack .chip, .vault .chip, .netmap .chip, .relay .chip, .autoscale .chip { box-shadow: 0 1px 3px rgba(14, 18, 32, 0.06); }

/* Axis: the request path. Endpoint caps, traveling request dots (dwelling at the
   diamond nodes), and the feed junction dot. */
.stack-axis {
  position: absolute; left: 239px; top: 6px; bottom: 14px; width: 1px;
  background: repeating-linear-gradient(180deg, var(--tint-edge) 0px, var(--tint-edge) 4px, transparent 4px, transparent 9px);
}
.axis-cap { position: absolute; width: 5px; height: 5px; border-radius: 50%; background: var(--indigo); }
.axis-cap-t { left: 237px; top: 0; }
.axis-cap-b { left: 237px; top: 576px; }
.axis-dot-feed { left: 236px; top: 228px; z-index: 1; }
/* Base opacity 0: the travel dots only exist while their (gated) animation runs */
.axis-req { position: absolute; left: 237px; top: 8px; width: 6px; height: 6px; background: var(--indigo); opacity: 0; }
.axis-req-3 { background: rgba(43, 73, 182, 0.5); }
.axis-node { position: absolute; left: 236px; width: 7px; height: 7px; background: #FFFFFF; transform: rotate(45deg) scaleY(0.55); z-index: 1; }
.axis-node-s { top: 296px; border: 1px solid var(--indigo); }
.axis-node-d { top: 426px; border: 1px solid var(--tint-edge); }

/* Canary promotion: pink deploy rising from the canary disc to the staging ghost */
.promote { position: absolute; left: 236px; top: 430px; width: 7px; height: 7px; z-index: 2; opacity: 0; }

/* Diamond shape primitive (wrapper positions/drifts; the shape rotates) */
.dmd { display: block; width: 100%; height: 100%; transform: rotate(45deg) scaleY(0.55); }
.dmd-outline { border: 1px solid var(--tint-edge); background: #FFFFFF; }
.dmd-hollow { border: 1px solid var(--tint-edge); }
.dmd-wash { background: rgba(43, 73, 182, 0.35); }
.dmd-pink { background: var(--canary-soft); }
.dmd-promote { background: var(--canary-bright); }

/* Ground shadows (the smaller stacks cast the lighter --soft variant) */
.ground-prod { left: 130px; top: 190px; width: 200px; height: 26px; }
.ground-staging { left: 155px; top: 372px; width: 150px; height: 18px; }
.ground-deploys { left: 155px; top: 520px; width: 150px; height: 14px; }
.ground-soft { background: radial-gradient(ellipse at center, rgba(14, 18, 32, 0.11), transparent 68%); }

/* Confetti seated on dashed flow lines + two free drifters */
.cf-line { position: absolute; height: 20px; transform: rotate(-16deg); }
.cf-line-a { left: 380px; top: 196px; width: 96px; }
.cf-line-b { left: 22px; top: 508px; width: 88px; }
.cf-dash { position: absolute; left: 0; top: 9px; width: 100%; height: 1px; background: repeating-linear-gradient(90deg, var(--tint-edge) 0px, var(--tint-edge) 3px, transparent 3px, transparent 7px); }
.cf-item { position: absolute; }
.cf-a1 { left: 10px; top: 2px; width: 16px; height: 16px; }
.cf-a2 { left: 54px; top: 5px; width: 10px; height: 10px; }
.cf-b1 { left: 12px; top: 3px; width: 13px; height: 13px; }
.cf-b2 { left: 50px; top: 2px; width: 15px; height: 15px; }
.cf-solo { left: 30px; top: 60px; width: 22px; height: 22px; }
.cf-cross { left: 160px; top: 12px; width: 12px; height: 12px; }
.cf-cross i { position: absolute; background: var(--tint-edge); }
.cf-cross i:first-child { left: 5.5px; top: 0; width: 1px; height: 12px; }
.cf-cross i:last-child { left: 0; top: 5.5px; width: 12px; height: 1px; }

.stack-group { position: absolute; }

/* PRODUCTION: four stacked ellipse layers (tint shadow → tonal indigo band →
   white → working face), dashed inner ring, pulsing replica dots, a tethered
   label, leader-line stat chips, and the scaling-event chip. */
.g-prod { left: 110px; top: 64px; width: 240px; height: 150px; }
.prod-l4, .prod-l3, .prod-l2, .prod-l1 { position: absolute; left: 0; width: 240px; height: 62px; border-radius: 50%; }
.prod-l4 { top: 40px; background: var(--tint-fill); }
/* Tonal stops of the accent (canvas values), not new hues — material shading */
.prod-l3 { top: 26px; background: linear-gradient(100deg, #4059C8 0%, var(--indigo) 40%, #22389B 100%); }
.prod-l2 { top: 12px; background: #FFFFFF; border: 1px solid var(--tint-edge-2); }
.prod-l1 { top: 0; background: var(--tint-face-2); border: 1px solid var(--tint-edge); }
.prod-ring { position: absolute; left: 26px; top: 8px; width: 188px; height: 46px; border-radius: 50%; border: 1px dashed var(--tint-edge); }
.prod-dot { position: absolute; border-radius: 50%; background: var(--indigo); }
.prod-dot-1 { left: 54px; top: 27px; width: 6px; height: 6px; }
.prod-dot-2 { left: 92px; top: 20px; width: 5px; height: 5px; }
.prod-dot-3 { left: 124px; top: 34px; width: 5px; height: 5px; }
.prod-dot-4 { left: 154px; top: 24px; width: 4px; height: 4px; }
.prod-dot-5 { left: 78px; top: 40px; width: 4px; height: 4px; }
.prod-tether { position: absolute; left: 30px; top: -14px; width: 1px; height: 24px; background: repeating-linear-gradient(180deg, var(--indigo) 0px, var(--indigo) 3px, transparent 3px, transparent 7px); opacity: 0.55; }
.prod-tether-dot { position: absolute; left: 28px; top: 8px; width: 4px; height: 4px; border-radius: 50%; background: var(--indigo); }
.g-prod-tag { left: -48px; top: -40px; }
.chip-event { left: 252px; top: -18px; z-index: 6; background: var(--tint-face-2); border-color: var(--tint-edge); color: var(--indigo); font-size: 10px; letter-spacing: 0.08em; padding: 3px 8px; }
.anchor-dot { position: absolute; left: 234px; width: 4px; height: 4px; border-radius: 50%; background: var(--indigo); z-index: 5; }
.anchor-dot-1 { top: 15px; }
.anchor-dot-2 { top: 47px; }
.anchor-dot-3 { top: 79px; }
.anchor-line { position: absolute; left: 240px; width: 10px; height: 1px; z-index: 5; background: repeating-linear-gradient(90deg, var(--tint-edge) 0px, var(--tint-edge) 3px, transparent 3px, transparent 7px); }
.anchor-line-1 { top: 16px; }
.anchor-line-2 { top: 48px; }
.anchor-line-3 { top: 80px; }
.g-prod-c1 { left: 250px; top: 6px; z-index: 5; }
.g-prod-c2 { left: 250px; top: 38px; z-index: 5; }
.g-prod-c3 { left: 250px; top: 70px; z-index: 5; }

/* Requests feed, anchored to the axis (static: the dashed link ties it there) */
.stack-feed { position: absolute; left: 4px; top: 220px; width: 235px; height: 22px; }
.stack-feed .chip { position: static; display: inline-block; }
.feed-d { position: absolute; top: 4px; width: 14px; height: 14px; background: var(--indigo); transform: rotate(45deg) scaleY(0.55); }
.feed-d-1 { left: 140px; }
.feed-d-2 { left: 154px; }
.feed-d-3 { left: 168px; }
.feed-line { position: absolute; left: 186px; top: 10px; width: 48px; height: 1px; background: repeating-linear-gradient(90deg, var(--tint-edge) 0px, var(--tint-edge) 3px, transparent 3px, transparent 7px); }

/* STAGING: three flat layers + the dashed canary ghost slot above the face */
.g-staging { left: 145px; top: 300px; width: 190px; height: 80px; }
.staging-l { position: absolute; left: 0; width: 190px; height: 50px; border-radius: 50%; }
.staging-l3 { top: 26px; background: var(--tint-fill); }
.staging-l2 { top: 12px; background: #FFFFFF; border: 1px solid var(--tint-edge-2); }
.staging-l1 { top: 0; background: var(--surface-2); border: 1px solid var(--tint-edge-2); }
.staging-ghost { position: absolute; left: 10px; top: -16px; width: 170px; height: 44px; border-radius: 50%; border: 1px dashed var(--canary-ghost); }
.staging-lead { position: absolute; left: 188px; top: 25px; width: 14px; height: 1px; background: repeating-linear-gradient(90deg, var(--tint-edge) 0px, var(--tint-edge) 3px, transparent 3px, transparent 7px); }
.g-staging-tag { left: 202px; top: 14px; }

/* DEPLOYMENTS: three cylinder discs; the top one is the pink canary build */
.g-deploys { left: 145px; top: 410px; width: 190px; height: 116px; }
.plate-dep-1 { --w: 190px; --ch: 56px; --eh: 48px; --bt: 24px; --bh: 8px; left: 0; top: 0; }
.plate-dep-2 { --w: 190px; --ch: 56px; --eh: 48px; --bt: 24px; --bh: 8px; left: 0; top: 20px; }
.plate-dep-3 { --w: 190px; --ch: 56px; --eh: 48px; --bt: 24px; --bh: 8px; left: 0; top: 40px; }
.dep-lead { position: absolute; width: 14px; height: 1px; background: repeating-linear-gradient(90deg, var(--tint-edge) 0px, var(--tint-edge) 3px, transparent 3px, transparent 7px); }
.dep-lead-canary { left: 188px; top: 24px; background: repeating-linear-gradient(90deg, var(--canary-edge) 0px, var(--canary-edge) 3px, transparent 3px, transparent 7px); }
.g-canary-tag { left: 202px; top: 13px; }
.dep-lead-label { left: -12px; top: 45px; }
.g-deploys-tag { left: -104px; top: 34px; }

/* ---- Lab logo marquee (absorbed at the hero band's bottom) ---- */
/* Row-width law (2026-07-21, after the wide-canvas pass): the strip's repeat period IS
   the width of one .lab-marquee-row, so two copies of a mark are on screen together
   whenever row < strip viewport. The same inequality also punches a hole: the track is
   2 rows, the keyframe travels -50% = one row, so the visible window runs off the track's
   end by (viewport - row) — at the old 1074px row and a 1466px strip that was a 391px
   empty band for 36% of every loop, of which ~207px sat outside the edge mask's reach.
   The marquee lives inside .container, so its viewport is hard-capped at ~1466px (widest
   at exactly a 1600px page; 1456px beyond). Both clamps below are sized so row >= that
   cap, and both bottom out at the pre-existing values — at <=~1290px nothing changes at
   all, which is why phones are untouched. If you ever edit the logo set or these numbers,
   re-check row >= 1466px. */
.lab-marquee {
  margin-bottom: 0;
  --logo-h: clamp(22px, 1.7vw, 27px);
  --logo-gap: clamp(56px, 5.9vw, 92px);
}
.lab-marquee-kicker { font-size: 11px; letter-spacing: 0.1em; color: var(--body); text-align: center; margin: 0 0 22px; } /* --body: it sits on the tinted band */
.lab-marquee-viewport {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 12%, #000 88%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 12%, #000 88%, transparent 100%);
}
.lab-marquee-track { display: flex; width: max-content; }
/* padding-right MUST track gap: the row is duplicated, so this padding is the only
   spacing between copy 1's last mark and copy 2's first one. Leave it at 56 while gap
   grows and that one join reads as a permanent tight spot — it is on screen ~97% of
   the loop, not a once-per-cycle blip. */
.lab-marquee-row { display: flex; align-items: center; gap: var(--logo-gap); padding-right: var(--logo-gap); }
.lab-logo { display: flex; align-items: center; color: var(--ink); } /* currentColor marks (OpenAI, Kimi, wordmarks) read ink in the hover-color state */
.lab-logo svg {
  height: var(--logo-h); width: auto; display: block;
  /* At rest the strip is uniformly greyed: contrast(0) collapses every opaque pixel
     to the identical mid-grey (alpha preserved), so multi-color brand marks can't
     read as a patchwork. Brand color reveals on hover only (grey-only marquee rule
     lifted 2026-07-15, founder decision). Filter/opacity crossfade is color-only —
     exempt from reduced-motion gating, same as the house color transitions. */
  filter: grayscale(1) contrast(0);
  opacity: 0.8;
  transition: filter 180ms var(--ease-hover), opacity 180ms var(--ease-hover);
}
@media (hover: hover) and (pointer: fine) {
  .lab-logo:hover svg { filter: none; opacity: 1; }
  /* Pause (not stop) so a moving logo can actually be hovered; loop position is kept,
     so nothing jumps on mouse-leave. Guarded to fine pointers: touch never freezes
     the strip, and under reduced motion there is no running animation to pause. */
  .lab-marquee-viewport:hover .lab-marquee-track { animation-play-state: paused; }
}
/* Optical compensation: square icons read small, heavy letterforms read big.
   Each is its original px height expressed against the 22px default, so --logo-h scales
   all nine by ONE factor and the ratios never drift. DESIGN.md's model-ecosystem marks
   carve-out requires a "common optical cap height" — tuning an individual mark to buy
   row width would break the one sizing rule the carve-out states. Keep the /22. */
.lab-logo-meta svg { height: calc(var(--logo-h) * 24 / 22); }
.lab-logo-qwen svg { height: calc(var(--logo-h) * 24 / 22); }
.lab-logo-microsoft svg { height: calc(var(--logo-h) * 20 / 22); }
.lab-logo-google svg { height: calc(var(--logo-h) * 20 / 22); }
.lab-logo-mistral svg { height: calc(var(--logo-h) * 20 / 22); }
.lab-logo-openai svg { height: calc(var(--logo-h) * 26 / 22); }
.lab-logo-deepseek svg { height: calc(var(--logo-h) * 24 / 22); }
.lab-logo-kimi svg { height: calc(var(--logo-h) * 14 / 22); }
.lab-logo-nvidia svg { height: calc(var(--logo-h) * 20 / 22); }

/* ---- 01 · Platform — deploy pipeline on a tinted frame (moved from the hero) ---- */
.pipe { margin-top: 44px; background: var(--tint-face); border: 1px solid var(--tint-edge-2); border-radius: 8px; padding: 8px; }
.pipe-head, .pipe-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 6px 16px; flex-wrap: wrap;
  font-size: 11.5px; color: var(--body); /* --body: the frame is a tinted surface */
}
.pipe-head { padding: 10px 14px 12px; letter-spacing: 0.08em; }
.pipe-foot { padding: 12px 14px 8px; }
.pipe-body { background: var(--paper); border: 1px solid var(--tint-edge-2); border-radius: 6px; padding: 24px 22px; }

.flow { display: flex; align-items: stretch; gap: 0; }
.node { flex: 1; border: 1px solid var(--border); border-radius: 6px; padding: 18px 20px; background: var(--paper); }
.node-active { flex: 1.15; border-color: var(--indigo); box-shadow: 0 0 0 3px rgba(43, 73, 182, 0.08); }
.node-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 9px; }
.node-kicker { font-size: 10.5px; letter-spacing: 0.08em; color: var(--indigo); }
.node-title { font-weight: 600; font-size: 16px; margin-bottom: 8px; }
.node-lines { font-size: 12px; line-height: 1.75; color: var(--body); }

.connector {
  width: 84px; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; flex-shrink: 0; padding-inline: 14px;
}
.connector-label { font-size: 10.5px; letter-spacing: 0.08em; color: var(--muted); }
.connector-line { display: flex; align-items: center; align-self: stretch; }
.connector-track { flex: 1; height: 1.5px; background: repeating-linear-gradient(90deg, var(--indigo) 0 6px, transparent 6px 11px); }
.connector-head {
  width: 0; height: 0;
  border-left: 7px solid var(--indigo);
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
}

/* ---- 01 · Platform — product accordion (native details/summary, zero new JS) ---- */
/* The product accordion itself was retired 2026-07-17 (its rows moved into the
   .sx-panel overlay as open panels); .acc-link survives as the house learn-more
   link style. Revert via git if the expand-card trial is rolled back. */
.acc-link { font-size: 14px; font-weight: 500; color: var(--indigo); text-decoration: none; white-space: nowrap; }
.acc-link:hover { color: var(--indigo-hover); text-decoration: underline; text-underline-offset: 3px; }

/* ============ Stripe expand cards (2026-07-17 trial; 2×2 merge 2026-07-22) ============ */
/* Collapsed: kicker + h2 + lede + artwork on a raised half-card with a corner ⤢.
   Expanded: an HTML-popover overlay (zero JS — popovertarget) with checklist,
   CTAs, and the section's full content. Radius 12/16 + the resting shadow are
   deliberately one step past the house card default (radius 8, flat) so the
   card reads "expandable object", not "another tinted panel". */
.sx-card {
  position: relative;
  background: var(--paper);
  border: 1px solid var(--tint-edge-2);
  border-radius: 12px;
  padding: 40px 44px 44px;
  box-shadow: 0 1px 2px rgba(14, 18, 32, 0.04), 0 12px 32px -16px rgba(14, 18, 32, 0.14);
}

.sx-btn {
  display: grid; place-items: center;
  width: 44px; height: 44px;
  border: 0; border-radius: 10px; cursor: pointer;
  background: var(--tint-open); color: var(--indigo);
  transition: background-color 150ms var(--ease-hover); /* color-only ⇒ ungated */
}
.sx-btn:hover { background: var(--tint-fill); }
.sx-expand { position: absolute; top: 22px; right: 22px; }

.sx-panel[popover] {
  /* UA popover styles keep position:fixed + inset:0; margin:auto centers it.
     The panel is a non-scrolling box; .sx-body scrolls inside it so the
     absolutely-pinned × never moves (sticky-in-scroller is off by the scroll
     container's padding in Chromium). NO display here: it would override the
     UA's [popover]:not(:popover-open) { display: none } and resurrect the
     closed panel as a permanent fixed overlay — flex lives on :popover-open. */
  width: min(1120px, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  max-height: calc(100dvh - 32px);
  margin: auto;
  border: 0; border-radius: 16px;
  background: var(--paper);
  color: var(--ink);
  padding: 0;
  overflow: hidden;
  box-shadow: 0 40px 96px -32px rgba(14, 18, 32, 0.5);
}
.sx-panel:popover-open { display: flex; flex-direction: column; }
.sx-body { overflow-y: auto; min-height: 0; padding: clamp(28px, 5vw, 56px); }
.sx-panel::backdrop { background: rgba(14, 18, 32, 0.45); }
/* Scroll lock on html, NOT body — a body lock resets the scroll position.
   The gutter stays reserved on pages carrying the panel (classic-scrollbar
   platforms only) so locking doesn't shift the centered layout sideways. */
html:has(.sx-panel) { scrollbar-gutter: stable; }
html:has(.sx-panel:popover-open) { overflow: hidden; }

.sx-close { position: absolute; top: 20px; right: 20px; z-index: 2; }

.sx-head { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 32px 72px; align-items: start; }
.sx-intro { padding-right: 40px; }
.sx-ctas { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
.sx-checks {
  list-style: none; margin: 0; padding: 44px 44px 0 0; /* top inset ≈ clears the ×; sits level with the h2 */
  display: grid; gap: 16px; align-content: start;
}
.sx-checks li { position: relative; padding-left: 34px; font-size: 15.5px; font-weight: 500; line-height: 1.5; color: var(--ink); }
.sx-checks li::before {
  content: "✓";
  position: absolute; left: 0; top: 0;
  width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--tint-open); color: var(--indigo);
  font-family: var(--font-mono); font-size: 12px; font-weight: 600;
}

.sx-prods { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-top: 44px; }
.sx-prod {
  background: var(--tint-face-2); border: 1px solid var(--tint-edge-2); border-radius: 8px;
  padding: 26px 24px 24px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
}
.sx-prod-kicker { font-size: 11px; letter-spacing: 0.1em; color: var(--indigo); }
.sx-prod h3 { font-weight: 600; font-size: 17.5px; letter-spacing: -0.01em; }
.sx-prod-chip {
  font-size: 11px; letter-spacing: 0.06em; color: var(--indigo);
  background: var(--paper); border: 1px solid var(--tint-edge); border-radius: 4px;
  padding: 3px 8px; white-space: nowrap;
}
.sx-prod p { font-size: 15px; line-height: 1.6; color: var(--body); flex-grow: 1; }

/* Card rows (2026-07-17 rollout; 2026-07-22 merge): the four sections are four
   half-width expand cards — 01+02 on one row, 03+04 on the next. Row-A bottom
   padding equals the column gap so the four cards read as one 2×2 grid. Band
   identities live on the cards: 01 (the merged platform+integrate card) keeps
   the terminal-room dark surface + dot grid, 03 keeps the compliance tint. */
section.section-cards { padding: 0 0 18px; }
/* The first row also opens the card grid after the hero band (the old full-width
   01 section carried this breathing room before the 2026-07-22 merge). */
section.section-cards-first { padding-top: 104px; }
/* position: relative at all widths — the hash field anchors to this section */
section.section-cards-last { padding: 0 0 104px; position: relative; }

/* Hash density field (2026-07-18): a faint dome of receipt-hash hex glyphs
   behind the 04/05 card row — the receipt story rendered as texture, and the
   one background element from the blueprint study the founder kept. Generated
   deterministically at build time (index.astro frontmatter). Decorative and
   aria-hidden; the cards above it are opaque, so it never underlaps text. */
.hash-field {
  position: absolute; left: 50%; bottom: 0; transform: translateX(-50%);
  margin: 0; font-size: 11px; line-height: 1.5; letter-spacing: 0.3em;
  color: rgba(43, 73, 182, 0.07); /* --grid-line family */
  pointer-events: none; user-select: none;
}
@media (max-width: 768px) { .hash-field { display: none; } }
.sx-row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.sx-card-half { padding: 32px 32px 36px; }
.sx-card-half .kicker, .sx-card-half h2 { padding-right: 48px; } /* clear the corner ⤢ */
.sx-card-half h2 { font-size: 28px; }
/* Card artworks center in the card (founder 2026-07-23): inline at every width,
   block only ≥1025px where the 2×2 rows leave free height (below that the cards
   stack and hug their content — auto block margins would collapse to zero gap).
   The flex column stops sibling margins collapsing, so each artwork's fixed
   margin-top (here and in the illustration blocks) is trimmed to keep the
   stacked-width rhythm identical: gap = text margin-bottom + artwork margin-top. */
.sx-card-half { display: flex; flex-direction: column; }
.sx-card .autoscale, .sx-card .vault, .sx-card .netmap, .sx-card .relay { margin-inline: auto; }
.sx-card .autoscale { margin-top: 10px; }
.sx-card .compliance-link { margin-top: 0; }
@media (min-width: 1025px) {
  .sx-card .autoscale, .sx-card .vault, .sx-card .netmap, .sx-card .relay { margin-block: auto; }
}
.sx-card-tint { background: var(--tint-face-2); }
/* (The dark expand card + dark sheet — the old 02 · INTEGRATE terminal room,
   briefly carried by the merged 01 card — were retired 2026-07-22, same day
   as the merge: founder un-darked the card. .section-dark went with them;
   the code card's own light chrome + dark codeblock is the surviving
   terminal moment. Revert via git if a dark band ever returns.) */

/* Sheet body content (below the sx-head grid). The merged 01 sheet stacks
   pipe → code card → product tiles; .sx-content's own margin opens the stack,
   so the pipe drops its standalone-section top margin. */
.sx-content { margin-top: 44px; }
.sx-content .pipe { margin-top: 0; }
.sx-content .code-card { max-width: 720px; margin-top: 44px; }

/* The no-Popover-API fallback for .sx-* lives at the END of this file — it must
   out-cascade the sx rules in the media queries below. */

/* ============ Operator strip (grey buffer above the dark closing CTA) ============ */
.strip-operator { background: var(--surface); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }

/* ============ Sections (shared grammar) ============ */
.section { padding: 104px 0; }

/* Ruled ledger margins RETIRED 2026-07-21 (founder: "remove the vertical lines
   running top to bottom"). They were 1px full-height rails at the container edges
   on every band ≥1216px. They were also anchored to a fixed 584px half-width, so
   they could not survive the fluid container below. Bands now separate by surface
   + hairline alone. .section-cta and .section-cards-last keep their own
   position: relative — the rails block is not what gives them a containing block. */
.section-band { background: var(--tint-face-2); border-top: 1px solid var(--tint-edge-2); border-bottom: 1px solid var(--tint-edge-2); padding: 96px 0; }
/* Tinted band: hairline discipline continues inside it */
.section-band .rows { border-top-color: var(--tint-edge-2); }
.section-band .row-item { border-bottom-color: var(--tint-edge-2); }
.section-cta {
  padding: 120px 0 128px;
  /* .cta-photo needs a containing block here at every width */
  position: relative;
  background-color: var(--code-bg-deep);
  /* Soft indigo glow (2026-07-15 freedoms pass): paints under all children.
     --code-dim over the brightest glow pixel ≥10:1. */
  background-image: radial-gradient(120% 70% at 50% 0%, rgba(43, 73, 182, 0.22), transparent 62%);
}
/* Duotone London underlay (2026-07-15 freedoms pass — photography sanctioned here only).
   Stacking: glow (element bg) → photo (positioned img) → .container (positioned).
   No negative z-index: it would drop the img below the section's own background
   paint. (A rail ::before used to sit on top of this stack; retired 2026-07-21.) */
.cta-photo {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center 38%;
  /* HARD CAP 0.25 — above it, --code-dim body text over a worst-case white photo
     pixel breaks the 4.5:1 WCAG floor (unlifted accessibility rule). 0.18 ≈ 6.1:1. */
  opacity: 0.18;
  pointer-events: none;
  /* Fades the photo out of the text column; a trimming mask, not a painted gradient */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, rgba(0, 0, 0, 0.55) 40%, #000 72%);
  mask-image: linear-gradient(90deg, transparent 0, rgba(0, 0, 0, 0.55) 40%, #000 72%);
}
.section-cta > .container { position: relative; } /* text paints above the photo */

/* (.section-dark — the "terminal room" band — retired 2026-07-22 with the
   dark 01 card. The closing CTA (.section-cta) is now the page's one dark band.) */

.kicker { font-size: 12px; letter-spacing: 0.1em; color: var(--indigo); margin-bottom: 14px; }
.section h2 { font-weight: 600; font-size: clamp(28px, 4.5vw, 36px); line-height: 1.12; letter-spacing: -0.02em; margin: 0 0 18px; }
.lede { margin: 0 0 24px; font-size: 16px; color: var(--body); }
#compliance .lede, #network .lede { margin-bottom: 28px; }
.inline-code { font-size: 14px; color: var(--ink); background: rgba(43, 73, 182, 0.08); padding: 1px 6px; border-radius: 4px; } /* pill per approved mock A1 */
a.inline-code { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
a.inline-code:hover { color: var(--indigo); }

/* ============ Interior pages ============ */
.page-intro { padding: calc(96px + var(--nav-clear)) 0 104px; }
.page-title {
  /* Matches the documented section-h2 scale (DESIGN.md type scale) — the homepage hero h1 stays the only 50px display. */
  font-weight: 600; font-size: clamp(28px, 4.5vw, 36px);
  line-height: 1.12; letter-spacing: -0.02em; margin: 0 0 18px; max-width: 720px;
}
.page-intro .lede { max-width: 600px; }

/* ============ /compliance — "terminal ledger" (page-scoped dark theme, 2026-07-16) ============ */
/* The site's one dark page (kilo.ai/eu study, founder-approved 2026-07-16): html.theme-dark
   comes from BaseLayout's theme="dark" prop. Page content is IBM Plex Mono throughout; cyan
   is the loud accent; status colors stay semantic (cyan live / amber standby+manual / grey
   roadmap); indigo-light (--code-accent) stays on shared chrome + attestation moments.
   Nav and footer keep General Sans but flip to the code palette. */
:root {
  --dk-cyan: #2FD4EE;      /* dark-surface loud accent: kickers, icons, LIVE, h1 highlight */
  --dk-cyan-ink: #062A31;  /* text on a cyan-filled button */
  --dk-amber: #F0B44C;     /* dark-surface standby / manual */
  --dk-line: rgba(255, 255, 255, 0.08);
  --dk-line-2: rgba(255, 255, 255, 0.15);
  --dk-panel-2: #1A1C22;   /* table header row, icon tiles */
}
.theme-dark body { background: var(--code-bg-deep); color: var(--code-dim); }
.theme-dark main { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.theme-dark :focus-visible { outline-color: var(--code-accent); } /* dark-surface focus ring (accessibility floor) */
.theme-dark .btn:hover { box-shadow: none; } /* shadowless hover-lift on dark (house law) */
.theme-dark .btn-outline { background: transparent; color: var(--code-text); border-color: var(--dk-line-2); }
.theme-dark .btn-outline:hover { border-color: var(--code-dim); color: #FFFFFF; }

/* Shared chrome flipped to the code palette */
.theme-dark .nav-inner {
  background: rgba(19, 20, 24, 0.62);
  border-color: var(--dk-line-2);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 12px 32px -14px rgba(0, 0, 0, 0.55),
              inset 0 1px 0 rgba(255, 255, 255, 0.07);
}
.theme-dark .nav-logo, .theme-dark .nav-link { color: var(--code-text); }
.theme-dark .nav-link:hover, .theme-dark .nav-brand:hover .nav-logo { color: #FFFFFF; }
.theme-dark .nav-link[aria-current="page"], .theme-dark .nav-trigger[data-current] { color: var(--code-accent); }
.theme-dark .nav-menu-panel { background: var(--code-bg); border-color: var(--dk-line-2); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); }
.theme-dark .nav-menu-title { color: var(--code-text); }
.theme-dark .nav-menu-item:hover { background: rgba(255, 255, 255, 0.05); }
.theme-dark .nav-menu-item:hover .nav-menu-title,
.theme-dark .nav-menu-item:focus-visible .nav-menu-title { color: var(--code-accent); }
.theme-dark .nav-menu-item[aria-current="page"] .nav-menu-title { color: var(--code-accent); }
.theme-dark .nav .btn-primary { background: #FFFFFF; color: var(--ink); }
.theme-dark .nav .btn-primary:hover { background: var(--code-text); }
.theme-dark .nav-burger-bar { background: var(--code-text); }
.theme-dark .nav-open .nav-mobile {
  background: rgba(19, 20, 24, 0.88);
  border-color: var(--dk-line-2);
  box-shadow: 0 24px 48px -16px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.06);
}
.theme-dark .nav-mobile > * + * { border-top-color: var(--dk-line); }
.theme-dark .nav-m-row { color: var(--code-text); }
.theme-dark .nav-m-sublink { color: var(--code-dim); }
.theme-dark .nav-m-sublink:hover { color: #FFFFFF; background: rgba(255, 255, 255, 0.05); }
.theme-dark .nav-m-row[aria-current="page"],
.theme-dark .nav-m-trigger[data-current],
.theme-dark .nav-m-sublink[aria-current="page"] { color: var(--code-accent); }
.theme-dark .footer { border-top-color: var(--dk-line); }
.theme-dark .footer-logo { color: var(--code-text); }
.theme-dark .footer-tag, .theme-dark .footer-col a { color: var(--code-dim); }
.theme-dark .footer-col a:hover, .theme-dark .footer-credit:hover { color: var(--code-accent); }
.theme-dark .footer-col-kicker, .theme-dark .footer-meta { color: var(--code-comment); }
.theme-dark .footer-meta-row { border-top-color: var(--dk-line); }

/* Hero */
.tl-hero { padding: calc(88px + var(--nav-clear)) 0 56px; text-align: center; }
.tl-pill {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 12px; letter-spacing: 0.08em; color: var(--code-dim);
  border: 1px solid var(--dk-line-2); border-radius: 999px; padding: 7px 14px;
}
.tl-pill-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--dk-cyan); }
.tl-h1 {
  margin: 26px auto 20px; max-width: 880px;
  font-weight: 600; font-size: clamp(32px, 4.8vw, 54px);
  line-height: 1.16; letter-spacing: -0.02em; color: var(--code-text);
}
.tl-hl { color: var(--dk-cyan); }
.tl-sub { margin: 0 auto; max-width: 680px; font-size: 15.5px; line-height: 1.75; color: var(--code-dim); }
.tl-ctas { display: flex; justify-content: center; align-items: center; gap: 16px; margin-top: 30px; flex-wrap: wrap; }
.btn-cyan { background: var(--dk-cyan); color: var(--dk-cyan-ink); padding: 12px 20px; }
.btn-cyan:hover { background: #56DEF3; }
.tl-pip { font-size: 12.5px; color: var(--code-comment); }

/* Trust strip — the four LIVE truths */
.tl-strip {
  display: grid; grid-template-columns: repeat(4, 1fr);
  background: var(--code-bg); border: 1px solid var(--dk-line-2); border-radius: 10px;
  padding: 24px 10px;
}
.tl-strip-item { display: grid; grid-template-columns: 22px 1fr; gap: 4px 10px; padding: 0 20px; align-items: start; }
.tl-strip-item + .tl-strip-item { border-left: 1px solid var(--dk-line); }
.tl-check { width: 15px; height: 15px; margin-top: 3px; color: var(--dk-cyan); }
.tl-strip-item strong { font-weight: 600; font-size: 13.5px; color: var(--code-text); }
.tl-strip-item span { grid-column: 2; font-size: 12.5px; line-height: 1.6; color: var(--code-dim); }

/* Section grammar */
.tl-section { padding: 88px 0; }
.tl-head { max-width: 800px; margin: 0 auto 44px; text-align: center; }
.tl-head-left { max-width: 720px; margin-bottom: 36px; }
.tl-kicker { font-size: 12px; letter-spacing: 0.14em; color: var(--dk-cyan); text-transform: uppercase; }
.tl-h2 { margin: 14px 0 12px; font-weight: 600; font-size: clamp(26px, 3.4vw, 38px); line-height: 1.22; letter-spacing: -0.02em; color: var(--code-text); }
.tl-lede { margin: 0; font-size: 15px; line-height: 1.75; color: var(--code-dim); }

/* Cards */
.tl-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.tl-cards-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.tl-card { background: var(--code-bg); border: 1px solid var(--dk-line); border-radius: 10px; padding: 26px; }
.tl-icon {
  width: 40px; height: 40px; display: grid; place-items: center;
  background: var(--dk-panel-2); border: 1px solid var(--dk-line-2); border-radius: 8px;
  color: var(--dk-cyan); margin-bottom: 18px;
}
.tl-icon svg { width: 18px; height: 18px; display: block; }
.tl-card h3 { margin: 0 0 10px; font-weight: 600; font-size: 16px; letter-spacing: -0.01em; color: var(--code-text); }
.tl-card p { margin: 0; font-size: 13.5px; line-height: 1.7; color: var(--code-dim); }
.tl-card-kicker { font-size: 11px; letter-spacing: 0.14em; color: var(--dk-cyan); text-transform: uppercase; margin-bottom: 12px; }

/* Status table — the honesty matrix as a real table */
.tl-table-wrap { border: 1px solid var(--dk-line-2); border-radius: 10px; background: var(--code-bg); overflow-x: auto; }
.tl-table { width: 100%; min-width: 760px; border-collapse: collapse; font-size: 13.5px; text-align: left; }
.tl-table th {
  background: var(--dk-panel-2); color: var(--code-text);
  font-weight: 600; font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 14px 22px;
}
.tl-table td { padding: 19px 22px; border-top: 1px solid var(--dk-line); vertical-align: top; line-height: 1.65; }
.tl-cap { width: 218px; font-weight: 600; color: var(--code-text); }
.tl-status { width: 120px; white-space: nowrap; font-weight: 600; letter-spacing: 0.04em; }
.st-live { color: var(--dk-cyan); }
.st-amber { color: var(--dk-amber); }
.st-roadmap { color: var(--code-comment); }
.tl-notes { color: var(--code-dim); }

/* Panel sections (data, faq, closing cta) */
.tl-panel { background: var(--code-bg); border: 1px solid var(--dk-line-2); border-radius: 12px; padding: 44px; }
.tl-panel .tl-card { background: rgba(255, 255, 255, 0.02); }
.tl-panel .tl-head-left { margin-bottom: 30px; }
.tl-fine { display: flex; flex-wrap: wrap; gap: 10px 36px; margin-top: 22px; padding-top: 20px; border-top: 1px dashed var(--dk-line-2); font-size: 12.5px; line-height: 1.6; color: var(--code-dim); }

/* Proves / doesn't-prove lists */
.tl-list { margin: 0; padding: 0; list-style: none; }
.tl-list li { position: relative; padding: 10px 0 10px 26px; font-size: 13.5px; line-height: 1.7; color: var(--code-dim); border-top: 1px solid var(--dk-line); }
.tl-list li:first-child { border-top: 0; padding-top: 0; }
.tl-list li::before { position: absolute; left: 2px; font-weight: 600; }
.tl-list-yes li::before { content: "✓"; color: var(--dk-cyan); }
.tl-list-no li::before { content: "✕"; color: var(--dk-amber); }

/* Verify terminal (the honest "product screenshot": FOHS is CLI + receipt) */
.theme-dark .split > * { min-width: 0; } /* the terminal pre must scroll inside its panel, not widen the grid track (same trap as .demo-grid) */
.tl-term { background: var(--code-bg); border: 1px solid var(--dk-line-2); border-radius: 10px; overflow: hidden; }
.tl-term-head { display: flex; align-items: center; gap: 7px; padding: 12px 18px; border-bottom: 1px solid var(--dk-line); }
.tl-term-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--dk-line-2); }
.tl-term-title { margin-left: 8px; font-size: 11.5px; letter-spacing: 0.08em; color: var(--code-comment); }
.tl-term pre { margin: 0; padding: 24px 26px; font-family: var(--font-mono); font-size: 13px; line-height: 1.8; color: var(--code-dim); overflow-x: auto; }
.t-cmd { color: var(--code-text); font-weight: 500; }
.t-ok { color: var(--dk-cyan); }
.t-cmt { color: var(--code-comment); }
.t-key { color: var(--code-accent); }
.tl-term-link { display: inline-block; margin-top: 22px; font-size: 14px; font-weight: 500; color: var(--dk-cyan); text-decoration: none; }
.tl-term-link:hover { color: #56DEF3; text-decoration: underline; text-underline-offset: 3px; }

/* Steps */
.tl-step-kicker { font-size: 11px; letter-spacing: 0.14em; color: var(--dk-cyan); margin-bottom: 10px; }
.tl-step-note { margin-top: 16px; padding-top: 14px; border-top: 1px dashed var(--dk-line-2); font-size: 12px; line-height: 1.6; color: var(--code-dim); }

/* FAQ */
.tl-faq-sub { margin: 8px 0 0; font-size: 13px; color: var(--code-dim); }
.tl-faq { margin-top: 28px; }
.tl-q { border-top: 1px solid var(--dk-line); }
.tl-q summary {
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  padding: 18px 2px; cursor: pointer; list-style: none;
  font-size: 14px; font-weight: 600; color: var(--code-text);
}
.tl-q summary::-webkit-details-marker { display: none; }
.tl-chev {
  flex-shrink: 0; width: 8px; height: 8px;
  border-right: 1.5px solid var(--code-comment); border-bottom: 1.5px solid var(--code-comment);
  transform: rotate(45deg); margin-top: -4px;
}
.tl-q[open] .tl-chev { transform: rotate(225deg); margin-top: 4px; }
.tl-q p { margin: 0; padding: 0 2px 20px; max-width: 880px; font-size: 13.5px; line-height: 1.75; color: var(--code-dim); }

/* Closing CTA panel */
.tl-cta { display: flex; align-items: center; justify-content: space-between; gap: 40px; border-color: rgba(47, 212, 238, 0.28); box-shadow: 0 0 80px rgba(47, 212, 238, 0.06); }
.tl-cta .tl-h2 { margin-top: 0; max-width: 560px; }
.tl-cta .tl-lede { max-width: 520px; }
.tl-cta-actions { flex-shrink: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }

/* Motion (tweens only when motion is allowed — accessibility floor) */
@media (prefers-reduced-motion: no-preference) {
  .tl-chev { transition: transform 160ms ease-out, margin-top 160ms ease-out; }
  .tl-term-link { transition: color 150ms var(--ease-hover); }
}

/* Responsive */
@media (max-width: 940px) {
  .tl-strip { grid-template-columns: 1fr 1fr; gap: 20px 0; padding: 22px 0; }
  .tl-strip-item + .tl-strip-item { border-left: 0; }
  .tl-strip-item:nth-child(even) { border-left: 1px solid var(--dk-line); }
}
@media (max-width: 900px) {
  .tl-cards, .tl-cards-2 { grid-template-columns: 1fr; }
  .tl-cta { flex-direction: column; align-items: flex-start; }
}
@media (max-width: 768px) {
  .tl-section { padding: 64px 0; }
  .tl-hero { padding: calc(64px + var(--nav-clear)) 0 44px; }
}
@media (max-width: 640px) {
  .tl-panel { padding: 26px 20px; }
  .tl-strip { grid-template-columns: 1fr; gap: 18px; }
  .tl-strip-item:nth-child(even) { border-left: 0; }
  .tl-strip-item { padding: 0 14px; }
}

/* Homepage 04 → /compliance arrow link (light context) */
.compliance-link { display: block; width: fit-content; margin-top: 16px; font-size: 14.5px; font-weight: 500; color: var(--indigo); text-decoration: none; }
.compliance-link:hover, .compliance-link:focus-visible { color: var(--indigo-hover); }

/* ============ Demo page ============ */
/* Band (2026-07-21): /demo was the only page floating on naked paper — the glass
   nav pill had nothing behind it and the form read like a generic contact page.
   Same tint + drafting grid as the homepage hero band, so the page reads as its
   sibling. The form card sits white on the tint (the .pipe surface idiom). */
.demo-section {
  position: relative; overflow: hidden;
  background: var(--tint-face);
  border-bottom: 1px solid var(--tint-edge-2);
  padding: calc(64px + var(--nav-clear)) 0 96px;
}
.demo-grid-bg {
  position: absolute; inset: 0;
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: 40px 40px;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 78%);
  mask-image: linear-gradient(to bottom, #000 0%, transparent 78%);
}
/* Both columns are capped and anchored to the container's own edges (gap absorbs
   the slack) rather than the pair being centred — a centred block would sit 108px
   inboard of the nav and footer edges at 1920. Before this pass the form was a
   fixed 560px in a 1fr track, which left ~500px of dead band mid-page. */
.demo-grid {
  position: relative;
  display: grid; grid-template-columns: minmax(0, 760px) minmax(340px, 420px);
  justify-content: space-between; gap: 64px; align-items: start;
}
.demo-grid > * { min-width: 0; } /* the receipt pre's intrinsic width must scroll inside the panel, not widen the track */
.demo-main .lede { max-width: 620px; }

/* ---- The form as a framed ledger card (.pipe grammar: tinted frame, white body) ---- */
.form {
  display: block; margin-top: 36px;
  background: var(--tint-face-2); border: 1px solid var(--tint-edge-2); border-radius: 8px; padding: 8px;
}
/* `display` here out-cascades the UA's [hidden] rule, so initDemoForm's
   form.hidden = true would be a no-op without this (cf. .codeblock[hidden]) */
.form[hidden] { display: none; }
.form-head {
  display: flex; align-items: center; justify-content: space-between; gap: 6px 16px; flex-wrap: wrap;
  padding: 10px 14px 12px; font-size: 11px; letter-spacing: 0.08em;
}
.form-head-kicker { color: var(--indigo); }
.form-body { background: var(--paper); border: 1px solid var(--tint-edge-2); border-radius: 6px; padding: 4px 26px; }
.form-foot { padding: 14px 14px 6px; }

/* Field groups are hairline-separated rows — the house label/copy row grammar */
.form-group { padding: 20px 0; border-top: 1px solid var(--hairline); }
.form-group:first-child { border-top: 0; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.field { display: grid; gap: 8px; }
/* Mono uppercase labels: the site sets every label and every number in Plex Mono
   ("numbers are testimony"). Sans 13.5px labels were the loudest tell that this
   form was borrowed from somewhere else. */
.field-label { font-size: 11px; letter-spacing: 0.08em; color: var(--muted); font-weight: 400; }
.field input, .field textarea {
  font: inherit; font-size: 15px; color: var(--ink);
  padding: 11px 13px; border: 1px solid var(--border-ctrl); border-radius: 6px; background: var(--surface);
}
.field input::placeholder, .field textarea::placeholder { color: var(--faint); }
/* Same focus treatment as the hero capture pill — border + 3px indigo ring */
.field input:focus, .field textarea:focus {
  border-color: var(--indigo); outline: none; background: var(--paper);
  box-shadow: 0 0 0 3px rgba(43, 73, 182, 0.14);
}
.field textarea { resize: vertical; }
.checks { border: 0; padding: 20px 0; margin: 0; }
.checks legend { padding: 0; margin-bottom: 12px; }
.checks-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
/* Selectable rows, not naked native boxes: ramp border, tint face when checked */
.check {
  display: flex; gap: 10px; align-items: center; font-size: 14.5px; color: var(--body);
  padding: 11px 14px; cursor: pointer;
  border: 1px solid var(--border-ctrl); border-radius: 6px; background: var(--surface);
  transition: border-color 150ms var(--ease-hover), background-color 150ms var(--ease-hover);
}
.check:hover { border-color: var(--tint-edge); }
.check:has(input:checked) { border-color: var(--indigo); background: var(--tint-face); color: var(--ink); }
.check:has(input:focus-visible) { outline: 2px solid var(--indigo); outline-offset: 2px; }
.check input { accent-color: var(--indigo); width: 16px; height: 16px; margin: 0; flex-shrink: 0; }
.hp { display: none; } /* Web3Forms honeypot */
/* Intrinsic width — a stretched primary is the one button on the site that did
   not match the house button scale */
.form-submit { border: 0; cursor: pointer; font-family: inherit; }
.form-submit:disabled { opacity: 0.6; cursor: default; }

/* Required-field marking (2026-07-18): indigo star + a mono legend. The stars are
   aria-hidden in the markup — the inputs' own `required` is what assistive tech
   announces, so reading "star" too would just be noise. */
.form-req { margin: 0; color: var(--body); } /* --body: the frame is a tinted surface */
.req { color: var(--indigo); font-weight: 500; }

/* In-page submit result (2026-07-18): replaces the form on success, sits under it
   on error. White card on the tinted band (the band is now --tint-face, so the old
   --tint-face-2 face would read as a smudge rather than a card). */
.form-result {
  max-width: 620px; margin-top: 36px; padding: 32px 30px 30px;
  background: var(--paper); border: 1px solid var(--tint-edge-2); border-radius: 8px;
}
.form-result:focus-visible { outline: 2px solid var(--indigo); outline-offset: 2px; }
.form-result-tick {
  width: 34px; height: 34px; margin-bottom: 16px; border-radius: 999px;
  background: var(--indigo); color: #FFFFFF; font-size: 17px;
  display: flex; align-items: center; justify-content: center;
}
.form-result-title { font-size: 24px; letter-spacing: -0.015em; margin-bottom: 10px; }
/* --body is the tinted-surface text floor (accessibility, not lifted) */
.form-result-copy { margin: 0 0 10px; font-size: 15px; line-height: 1.6; color: var(--body); }
.form-result-copy:last-child { margin-bottom: 0; }
.form-result-copy a { color: var(--indigo); }
/* Error state: amber = pending/attention in the signal palette, at annotation scale */
.form-result-error { background: var(--signal-amber-face); border-color: var(--signal-amber-edge); margin-top: 18px; }
.form-result-error .form-result-copy { color: var(--signal-amber-deep); }
/* The indigo ring reads as a clash on the amber face */
.form-result-error:focus-visible { outline-color: var(--signal-amber-deep); }

/* Dark side panel (sanctioned dark band — DESIGN.md 2026-07-14) */
/* Soft shadow so the dark panel reads as raised off the tinted band rather than
   punched into it (it sat on white paper before the band). */
.demo-side {
  position: sticky; top: 88px; background: var(--code-bg); border-radius: 8px; padding: 30px 30px 26px;
  box-shadow: 0 10px 28px -14px rgba(14, 18, 32, 0.4);
}
.demo-side-kicker { font-size: 11px; letter-spacing: 0.1em; color: var(--code-comment); margin-bottom: 14px; }
.expect-list { list-style: none; margin: 0 0 30px; padding: 0; }
.expect-list li {
  display: flex; gap: 14px; padding: 12px 0; font-size: 14.5px; line-height: 1.55; color: var(--code-dim);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.expect-num { color: var(--code-accent); font-size: 12px; padding-top: 2px; }
.demo-receipt {
  margin: 0 0 30px; padding: 16px 18px; background: var(--code-bg-deep);
  border: 1px solid rgba(255, 255, 255, 0.06); border-radius: 6px;
  font-size: 12.5px; line-height: 1.9; color: var(--code-dim); white-space: pre; overflow-x: auto;
}
.demo-facts { list-style: none; margin: 0; padding: 0; }
.demo-facts li { padding: 10px 0; font-size: 11px; letter-spacing: 0.08em; color: var(--code-comment); border-top: 1px solid rgba(255, 255, 255, 0.08); }

/* Focus rings on dark surfaces: the global indigo ring is ~2.5:1 on the code
   palette (fails WCAG 1.4.11) — lighten it wherever the background goes dark. */
.demo-side :focus-visible, .section-cta :focus-visible, .code-note :focus-visible { outline-color: var(--code-accent); }

.split { display: grid; grid-template-columns: 400px 1fr; gap: 80px; } /* still used by /compliance */

/* ============ 01 · Platform — code card (in the merged sheet) ============ */
.code-card {
  border: 1px solid var(--border); border-radius: 8px; overflow: hidden;
  box-shadow: 0 1px 2px rgba(14, 18, 32, 0.04);
}
.code-head {
  display: flex; align-items: center; justify-content: space-between;
  background: var(--surface); border-bottom: 1px solid var(--border); padding: 8px 12px;
}
.code-tabs { display: flex; gap: 2px; }
.tab {
  font-size: 12px; padding: 6px 12px; border-radius: 5px;
  border: 1px solid transparent; background: transparent; color: var(--muted); cursor: pointer;
}
.tab.is-active { border-color: var(--border-ctrl); background: var(--paper); color: var(--ink); }
.code-actions { display: flex; gap: 8px; align-items: center; }
.code-btn {
  font-size: 12px; padding: 6px 12px; border-radius: 5px;
  border: 1px solid var(--border-ctrl); background: var(--paper); color: var(--body);
  cursor: pointer; min-width: 84px;
}
.code-btn:hover { border-color: var(--border-hover); }

.codeblock {
  margin: 0; padding: 24px 24px 26px; background: var(--code-bg);
  font-size: 13.5px; line-height: 1.8; color: var(--code-text);
  white-space: pre; overflow-x: auto;
}
.codeblock[hidden] { display: none; }
.code-comment { color: var(--code-comment); }
.code-accent { color: var(--code-accent); }

/* Static receipt note: keeps the card's dark footer silhouette (the retired
   streaming demo lived here) while pointing at the verify page. */
.code-note {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  background: var(--code-bg-deep); border-top: 1px solid rgba(255, 255, 255, 0.1);
  padding: 12px 24px 13px; font-size: 12px; color: var(--code-comment);
}
.code-note-link { color: var(--code-accent); text-decoration: none; white-space: nowrap; }
.code-note-link:hover { color: #FFFFFF; }

/* ============ 02 · Runtime — autoscale staircase (v2 2026-07-23) ============ */
/* Requests pulse in at the foot of a flowing dashed scale path (arrowhead on the
   .pipe connector idiom, same as the relay axis); three replica discs step up it
   — indigo top disc = the newest live replica; the dashed ghost slot + the
   "+1 REPLICA" event chip carry the next spawn (hero scaling-event vocabulary,
   replacing the retired scalePop blink-in discs). */
.autoscale { position: relative; width: 340px; height: 212px; }
.as-path {
  position: absolute; left: -6px; top: 130px; width: 360px; height: 1px;
  background: repeating-linear-gradient(90deg, rgba(43, 73, 182, 0.5) 0px, rgba(43, 73, 182, 0.5) 4px, transparent 4px, transparent 9px);
  transform: rotate(-21deg);
}
.as-path::after {
  content: ""; position: absolute; right: -2px; top: -3.5px;
  border-left: 7px solid var(--indigo);
  border-top: 4px solid transparent; border-bottom: 4px solid transparent;
}
.ground-as1 { left: 14px; top: 170px; width: 100px; height: 22px; }
.ground-as2 { left: 119px; top: 128px; width: 100px; height: 22px; }
.ground-as3 { left: 224px; top: 86px; width: 100px; height: 22px; }
.as-req { position: absolute; width: 9px; height: 9px; background: var(--indigo); transform: rotate(45deg) scaleY(0.55); }
.as-req-1 { left: 15px; top: 184px; }
.as-req-2 { left: 31px; top: 178px; }
.as-1 { --w: 110px; --ch: 40px; --eh: 30px; --bt: 15px; --bh: 10px; left: 10px; top: 140px; }
.as-2 { --w: 110px; --ch: 40px; --eh: 30px; --bt: 15px; --bh: 10px; left: 115px; top: 98px; }
.as-3 { --w: 110px; --ch: 40px; --eh: 30px; --bt: 15px; --bh: 10px; left: 220px; top: 56px; }
/* Ghost at top 16: disc 3's floating top face peaks at y≈47 — the slot never
   collides. Event chip centered over the ghost (alignment pass 2026-07-23). */
.as-ghost { position: absolute; left: 228px; top: 16px; width: 108px; height: 30px; border-radius: 50%; border: 1px dashed rgba(43, 73, 182, 0.4); }
.as-event { left: 232px; top: -8px; background: var(--tint-face-2); border-color: var(--tint-edge); color: var(--indigo); font-size: 10px; letter-spacing: 0.08em; padding: 3px 8px; }
.autoscale-caption { position: absolute; left: 0; top: 196px; font-size: 11px; letter-spacing: 0.08em; color: var(--muted); }

/* Three tinted-face cards (D11: compat card cut — 02 owns that message); the
   autoscale card carries the sim and spans the full left column. */
.features-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.feature-card { padding: 26px 28px 28px; background: var(--tint-face-2); border: 1px solid var(--tint-edge-2); border-radius: 8px; }
.feature-card-tall { grid-row: span 2; }
.feature-kicker { font-size: 12px; color: var(--indigo); margin-bottom: 12px; }
.feature-kicker-row { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.feature-kicker-row .feature-kicker { margin-bottom: 0; }
.badge-signed {
  font-size: 10.5px; color: var(--indigo); border: 1px solid var(--tint-edge);
  border-radius: 4px; padding: 1px 6px; letter-spacing: 0.08em;
  background: var(--paper); /* lifts off the tinted card face */
}
.feature-card h3 { font-weight: 600; font-size: 18px; margin: 0 0 10px; letter-spacing: -0.01em; }
.feature-card p { margin: 0; font-size: 15px; color: var(--body); }
.feature-card .inline-code { font-size: 13px; }

.sim { margin-top: 22px; border: 1px solid var(--tint-edge-2); border-radius: 6px; background: var(--paper); padding: 16px 18px 18px; } /* white on the tinted card face */
.sim-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.sim-kicker { font-size: 11px; letter-spacing: 0.08em; color: var(--body); } /* --body, not --muted: tinted surfaces never carry lighter text */
.sim-value { font-size: 12px; color: var(--ink); }
.sim input[type="range"] { width: 100%; accent-color: var(--indigo); margin: 0 0 14px; display: block; cursor: pointer; }
.sim-foot { display: flex; align-items: center; justify-content: space-between; }
.cells { display: flex; gap: 4px; }
.replica-cell {
  width: 14px; height: 14px; border-radius: 3px;
  border: 1px solid var(--border-soft); background: var(--paper);
  transition: background 150ms ease-out, border-color 150ms ease-out;
}
.replica-cell.on { border-color: var(--indigo); background: rgba(43, 73, 182, 0.16); }
/* The newest replica renders cyan (scaling live = data in motion); settled cells stay indigo.
   :has-less browsers simply keep every cell indigo. */
.replica-cell.on:not(:has(~ .replica-cell.on)) { border-color: var(--signal-cyan); background: rgba(14, 116, 144, 0.16); }
.sim-readout { font-size: 12px; color: var(--body); }

/* ============ 03/04 · label/copy rows ============ */
.rows { display: flex; flex-direction: column; gap: 0; border-top: 1px solid var(--border); }
.row-item { display: grid; grid-template-columns: 220px 1fr; gap: 32px; padding: 26px 0; border-bottom: 1px solid var(--border); }
.row-label { font-weight: 600; font-size: 16px; }
/* Inline state tag on a ledger row (signal palette, annotation scale) */
.row-state {
  display: inline-block; margin-left: 10px; vertical-align: 2px;
  font-size: 10.5px; letter-spacing: 0.08em; padding: 2px 7px;
  border-radius: 4px; border: 1px solid;
}
.row-state-amber { color: var(--signal-amber-deep); background: var(--signal-amber-face); border-color: var(--signal-amber-edge); }
.row-item p { margin: 0; font-size: 15px; color: var(--body); }

/* ---- Compliance vault illustration (v2 2026-07-23: perimeter registration
        ticks, visible dashed orbit path, second counter-phased orbit dot,
        indigo seal on the cube's top face) ---- */
/* 56 (not the lede-minus math of its siblings): the link above it never
   collapsed with this margin even pre-flex, so 56 IS the stacked-width gap */
.vault { position: relative; width: 340px; height: 250px; margin-top: 56px; }
.ground-vault { left: 116px; top: 160px; width: 110px; height: 26px; }
.vault-perimeter { position: absolute; left: 8px; top: 12px; width: 322px; height: 196px; border: 1px dashed var(--tint-edge); border-radius: 8px; }
/* Drafting registration marks on the perimeter corners (hero cf-cross idiom) */
.vault-tick { position: absolute; width: 9px; height: 9px; }
.vault-tick::before { content: ""; position: absolute; left: 4px; top: 0; width: 1px; height: 9px; background: var(--tint-edge); }
.vault-tick::after { content: ""; position: absolute; left: 0; top: 4px; width: 9px; height: 1px; background: var(--tint-edge); }
.vt-tl { left: 4px; top: 8px; }
.vt-tr { left: 326px; top: 8px; }
.vt-bl { left: 4px; top: 204px; }
.vt-br { left: 326px; top: 204px; }
.vault-tag { left: 24px; top: 2px; background: var(--surface-2); font-size: 10.5px; padding: 2px 8px; color: var(--muted); }
.vault-base { position: absolute; left: 80px; top: 150px; width: 180px; height: 46px; border-radius: 50%; background: var(--tint-face); border: 1px solid var(--tint-edge-2); }
.vault-cube { position: absolute; left: 122px; top: 62px; width: 96px; height: 110px; }
.vault-face-l { position: absolute; left: 1px; top: 26px; width: 47px; height: 52px; background: #D3DCF4; transform-origin: top left; transform: skewY(26.57deg); }
.vault-face-r { position: absolute; left: 48px; top: 49px; width: 47px; height: 52px; background: #BFCBEF; transform-origin: top left; transform: skewY(-26.57deg); }
.vault-face-t { position: absolute; left: 15px; top: -7px; width: 66px; height: 66px; background: #E7EDFB; border: 1px solid var(--tint-edge); transform: scaleY(0.5) rotate(45deg); }
/* The attestation seal rides the cube's top face (floats with the cube).
   Etched outline crest, 18px — smaller/solid versions read as a stray orbit
   dot at card scale (2026-07-23 alignment pass) */
.vault-seal { position: absolute; left: 39px; top: 17px; width: 18px; height: 18px; border: 1px solid rgba(43, 73, 182, 0.55); transform: rotate(45deg) scaleY(0.55); }
/* Dashed path the orbit dots travel — its own element so it sits BEHIND the cube */
.vault-orbit-path { position: absolute; left: 60px; top: 60px; width: 220px; height: 220px; border-radius: 50%; border: 1px dashed rgba(43, 73, 182, 0.28); transform: scaleY(0.5); transform-origin: 110px 55px; }
.vault-orbit { position: absolute; left: 60px; top: 60px; width: 220px; height: 220px; transform: scaleY(0.5); transform-origin: 110px 55px; }
/* Static park angles put both dots on the ellipse's visible side arcs when the
   spin isn't running (reduced motion / frozen): at 0° the primary dot parked
   exactly on the cube's top face, stacking on the seal. Live, anim-spin's
   keyframes override these transforms — no effect while orbiting. */
.vault-orbit-ring { position: absolute; inset: 0; transform: rotate(125deg); }
/* Static dot transforms counter their ring's park angle (spinCounter's job while
   animating) — without it the scaleY(2) roundness fix works in the wrong frame
   and the parked dot smears into a slanted ellipse */
.vault-orbit-dot { position: absolute; left: 106px; top: -4px; width: 9px; height: 9px; border-radius: 50%; background: var(--indigo); transform: rotate(-125deg) scaleY(2); }
/* Second dot: counter-phased (static offset when reduced motion parks the spin) */
.vault-orbit-ring-2 { transform: rotate(160deg); }
.vault-orbit-dot-2 { width: 6px; height: 6px; left: 108px; top: -2px; background: #BFCBEF; transform: rotate(-160deg) scaleY(2); }
.vault-chip-1 { left: 218px; top: 44px; }
.vault-chip-2 { left: 24px; top: 186px; }

/* ---- 04 · Network site constellation (v2 2026-07-23) ---- */
/* ONE ENDPOINT junction fans three flowing cyan dashed branches (the netmap's
   sanctioned cyan placement, now three segments instead of one axis) down to
   the sites: LON1 active (indigo), STANDBY (tint + amber tag), and ROADMAP as
   a dashed ghost slot — that site isn't built, so it isn't drawn as built. */
.netmap { position: relative; width: 340px; height: 300px; margin-top: 20px; }
.nm-junction-tag { left: 116px; top: 0; }
.nm-junction { position: absolute; left: 166px; top: 26px; width: 11px; height: 11px; background: #FFFFFF; border: 1px solid var(--indigo); transform: rotate(45deg) scaleY(0.55); }
/* Branch dashes: deep-cyan wash (the pale --signal-cyan-edge vanished at 1px on
   paper). Widths OVERSHOOT ~12px into each disc's top face on purpose: branches
   draw behind the sites, so the extra length hides at rest and the line stays
   attached through the whole hoverY float cycle (±9px) instead of detaching. */
.netmap-branch {
  position: absolute; left: 172px; top: 34px; height: 1px; transform-origin: 0 50%;
  background: repeating-linear-gradient(90deg, rgba(14, 116, 144, 0.35) 0px, rgba(14, 116, 144, 0.35) 4px, transparent 4px, transparent 9px);
}
.nb-1 { width: 78px; transform: rotate(121.6deg); }
.nb-2 { width: 158px; transform: rotate(55.6deg); }
.nb-3 { width: 203px; transform: rotate(96.3deg); } /* ghost is static — 2px inside its edge */
.netmap-site { position: absolute; }
.ground-nm1 { left: 48px; top: 138px; width: 170px; height: 30px; }
.ground-nm2 { left: 206px; top: 194px; width: 115px; height: 22px; }
.nm-1 { left: 28px; top: 84px; width: 200px; height: 116px; }
.nm-plate-1 { --w: 200px; --ch: 64px; --eh: 52px; --bt: 26px; --bh: 12px; left: 0; top: 0; }
.nm-tag-1 { left: -16px; top: -24px; }
.nm-2 { left: 192px; top: 152px; width: 140px; height: 90px; }
.nm-plate-2 { --w: 140px; --ch: 52px; --eh: 42px; --bt: 21px; --bh: 10px; left: 0; top: 0; }
.nm-tag-2 { left: 30px; top: 60px; }
.nm-ghost { position: absolute; left: 70px; top: 234px; width: 150px; height: 40px; border-radius: 50%; border: 1px dashed var(--border-ctrl); }
.nm-tag-3 { left: 230px; top: 246px; }

/* ---- 01 · Deploy relay illustration (merged card, 2026-07-22; v2 same day) ---- */
/* The 01+02 story as one drawing: the weights cube rides the indigo dashed axis
   (the .pipe connector idiom — arrowhead included) through the LON1 serving-disc
   stack, past two pulsing response diamonds, out to the endpoint node; the
   receipt chip signs off the response path. v2 un-darked the card, so the
   standard light vocabulary applies (grey grounds, house chips). */
.relay { position: relative; width: 340px; height: 210px; margin-top: 12px; }
.relay-axis {
  position: absolute; left: -8px; top: 126px; width: 366px; height: 1px;
  background: repeating-linear-gradient(90deg, rgba(43, 73, 182, 0.5) 0px, rgba(43, 73, 182, 0.5) 4px, transparent 4px, transparent 9px);
  transform: rotate(-8deg);
}
.relay-axis::after {
  content: ""; position: absolute; right: -2px; top: -3.5px;
  border-left: 7px solid var(--indigo);
  border-top: 4px solid transparent; border-bottom: 4px solid transparent;
}
.ground-rl1 { left: 8px; top: 148px; width: 92px; height: 22px; }
.ground-rl2 { left: 108px; top: 128px; width: 150px; height: 30px; }
/* Weights cube: the vault-cube construction at 0.68 (same skew geometry, no seams) */
.relay-weights { position: absolute; left: 12px; top: 82px; width: 66px; height: 76px; }
.relay-cube { position: absolute; left: 0; top: 0; width: 96px; height: 110px; transform: scale(0.68); transform-origin: top left; }
.relay-face-l { position: absolute; left: 1px; top: 26px; width: 47px; height: 52px; background: #D3DCF4; transform-origin: top left; transform: skewY(26.57deg); }
.relay-face-r { position: absolute; left: 48px; top: 49px; width: 47px; height: 52px; background: #BFCBEF; transform-origin: top left; transform: skewY(-26.57deg); }
.relay-face-t { position: absolute; left: 15px; top: -7px; width: 66px; height: 66px; background: #E7EDFB; border: 1px solid var(--tint-edge); transform: scaleY(0.5) rotate(45deg); }
/* Runtime: a three-disc serving stack (indigo top = live), netmap plate ratios */
.relay-runtime { position: absolute; left: 115px; top: 68px; width: 130px; height: 71px; }
.rl-plate-1 { --w: 130px; --ch: 41px; --eh: 33px; --bt: 16px; --bh: 8px; left: 0; top: 0; }
.rl-plate-2 { --w: 130px; --ch: 41px; --eh: 33px; --bt: 16px; --bh: 8px; left: 0; top: 15px; }
.rl-plate-3 { --w: 130px; --ch: 41px; --eh: 33px; --bt: 16px; --bh: 8px; left: 0; top: 30px; }
.relay-tag-model { left: 4px; top: 176px; }
.relay-tag-runtime { left: 90px; top: 30px; }
/* Height overshoots ~13px into the top disc's face (the lead draws BEFORE the
   disc group, so the extra hides behind it and the line stays attached while
   the discs float ±9px — alignment pass 2026-07-23) */
.relay-lead-runtime { position: absolute; left: 168px; top: 52px; width: 1px; height: 30px; background: repeating-linear-gradient(180deg, rgba(43, 73, 182, 0.45) 0px, rgba(43, 73, 182, 0.45) 3px, transparent 3px, transparent 7px); }
/* Responses in flight, seated on the axis just before the endpoint */
.relay-req { position: absolute; width: 10px; height: 10px; background: var(--indigo); transform: rotate(45deg) scaleY(0.55); }
.relay-req-1 { left: 249px; top: 110px; }
.relay-req-2 { left: 263px; top: 108px; }
/* Endpoint layer floats as one piece (node + tether + base-URL chip) */
.relay-endpoint { position: absolute; inset: 0; }
.relay-node { position: absolute; left: 294px; top: 104px; width: 9px; height: 9px; background: #FFFFFF; border: 1px solid var(--indigo); transform: rotate(45deg) scaleY(0.55); }
.relay-tether { position: absolute; left: 299px; top: 80px; width: 1px; height: 24px; background: repeating-linear-gradient(180deg, rgba(43, 73, 182, 0.45) 0px, rgba(43, 73, 182, 0.45) 3px, transparent 3px, transparent 7px); }
.relay-chip-endpoint { left: 214px; top: 58px; }
.relay-chip-receipt { left: 204px; top: 182px; }

/* ============ Operator strip ============ */
.strip-operator-inner { display: flex; align-items: center; justify-content: space-between; gap: 24px; padding-block: 18px; }
.strip-operator-copy { font-size: 15px; font-weight: 500; color: var(--ink); }
.strip-operator-link { font-size: 14px; font-weight: 500; color: var(--ink); text-decoration: none; }
.strip-operator-link:hover { color: var(--indigo); }

/* ============ Closing CTA (dark band — DESIGN.md 2026-07-14) ============ */
.section-cta h2.cta-h2 { font-weight: 600; font-size: clamp(32px, 5.5vw, 48px); line-height: 1.06; letter-spacing: -0.025em; margin: 0 0 18px; max-width: 640px; color: #FFFFFF; }
.cta-sub { margin: 0 0 36px; font-size: 17px; color: var(--code-dim); max-width: 480px; }
.cta-sub .inline-code { font-size: 15px; color: var(--code-dim); background: rgba(147, 172, 242, 0.12); }
.cta-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.cta-pip { font-size: 12.5px; color: var(--code-dim); margin-left: 8px; } /* --code-dim on dark (mock critic correction) */
/* Indigo is ~2.5:1 on the code palette — on dark bands the primary inverts to white/ink */
.section-cta .btn-primary { background: #FFFFFF; color: var(--ink); }
.section-cta .btn-primary:hover { background: var(--code-text); }

/* ============ Footer (sitemap layout — Stripe pass 2026-07-15) ============ */
.footer { border-top: 1px solid var(--border); }
.footer-grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr 1fr; gap: 40px; padding-block: 56px 48px; }
.footer-brand { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
.footer-logo { font-weight: 600; font-size: 15px; display: flex; align-items: center; gap: 8px; }
.footer-mark { height: 18px; width: auto; display: block; flex-shrink: 0; }
.footer-tag { margin: 0; font-size: 13.5px; color: var(--body); }
.footer-col-kicker { font-size: 11px; letter-spacing: 0.1em; color: var(--muted); margin-bottom: 10px; }
.footer-col a { display: block; padding: 5px 0; font-size: 14px; color: var(--body); text-decoration: none; }
.footer-col a:hover { color: var(--indigo); }
.footer-meta-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; border-top: 1px solid var(--hairline); padding-block: 20px; }
.footer-meta { font-size: 12px; color: var(--muted); }
.footer-credit { color: inherit; text-decoration: none; }
.footer-credit:hover { color: var(--indigo); }
/* Dashed column separators (house vocabulary: vault perimeter, stack axis) —
   4-column mode only; below 1025px the columns are too narrow ("Provenance
   Receipts" wraps under ~947px) so the grid collapses to 2-up instead. */
@media (min-width: 1025px) {
  .footer-col { border-left: 1px dashed var(--border); padding-left: 32px; }
}

/* ============ Scroll reveals ============ */
.js [data-reveal] .reveal-item {
  opacity: 0; transform: translateY(14px);
  transition: opacity 300ms ease-out, transform 300ms ease-out;
}
.js [data-reveal].revealed .reveal-item { opacity: 1; transform: none; }
.d60 { transition-delay: 60ms !important; }
.d80 { transition-delay: 80ms !important; }
.d120 { transition-delay: 120ms !important; }

/* ============ Keyframes (verbatim from canvas) ============ */
@keyframes blinkCaret { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
@keyframes blipA { 0% { opacity: 0; } 25% { opacity: 1; } 100% { opacity: 0; } }
@keyframes blipB { 0% { opacity: 0; } 25% { opacity: 1; } 100% { opacity: 0; } }
@keyframes hoverY { from { transform: translateY(0px); } to { transform: translateY(-9px); } }
@keyframes dashFlow { from { background-position: 0 0; } to { background-position: 0 18px; } }
/* Infra Stack Hero v2 vocabulary (2026-07-20 canvas) */
@keyframes shadowBreathe { from { transform: scaleX(1); opacity: 1; } to { transform: scaleX(0.88); opacity: 0.65; } }
@keyframes ghostPulse { from { opacity: 0.35; } to { opacity: 0.9; } }
@keyframes driftX { from { transform: translateX(0); } to { transform: translateX(8px); } }
@keyframes driftY { from { transform: translateY(0); } to { transform: translateY(-5px); } }
@keyframes enterFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes enterUp { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
@keyframes eventPop { 0% { opacity: 0; transform: translateY(5px); } 12% { opacity: 1; transform: translateY(0); } 78% { opacity: 1; } 100% { opacity: 0; transform: translateY(-4px); } }
@keyframes promoteUp {
  0% { transform: translateY(0) scale(0.8); opacity: 0; }
  6% { transform: translateY(-6px) scale(1); opacity: 1; }
  34% { transform: translateY(-132px) scale(1); }
  40% { transform: translateY(-138px) scale(1.6); }
  46% { transform: translateY(-138px) scale(1); }
  60% { opacity: 1; }
  70% { transform: translateY(-138px) scale(1); opacity: 0; }
  100% { transform: translateY(-138px) scale(1); opacity: 0; }
}
@keyframes axisTravel {
  0% { transform: translateY(0) scale(1); opacity: 0; }
  5% { opacity: 1; }
  48% { transform: translateY(285px) scale(1); }
  52% { transform: translateY(288px) scale(1.8); }
  56% { transform: translateY(292px) scale(1); }
  71% { transform: translateY(415px) scale(1); }
  75% { transform: translateY(418px) scale(1.8); }
  79% { transform: translateY(422px) scale(1); }
  95% { transform: translateY(554px) scale(1); opacity: 1; }
  100% { transform: translateY(558px) scale(1); opacity: 0; }
}
@keyframes pulseBar { 0%, 100% { opacity: 0.25; } 50% { opacity: 1; } }
/* (scalePop retired 2026-07-23 with the autoscale v2 — the ghost slot + event
   chip tell the spawn story without discs blinking out of existence) */
@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes spinCounter { from { transform: rotate(0deg) scaleY(2); } to { transform: rotate(-360deg) scaleY(2); } }
@keyframes menuIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@keyframes marqueeX { from { transform: translateX(0); } to { transform: translateX(-50%); } }
/* dashFlow's horizontal twin — the 01 relay's axis flows left→right (downstream) */
@keyframes dashFlowX { from { background-position: 0 0; } to { background-position: 18px 0; } }

/* Ambient animations run only when the user hasn't asked for reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  .hero-blip.on { animation: blipA 1.8s ease-out forwards; }
  .hero-caret { animation: blinkCaret 1.1s step-end infinite; }

  .anim-dashflow { animation: dashFlow 1.6s linear infinite; }
  .anim-dashflow-x { animation: dashFlowX 1.6s linear infinite; }

  .anim-hover { animation: hoverY 6s ease-in-out infinite alternate; }
  .vault-cube.anim-hover { animation-delay: -1s; }
  .vault-chip-1.anim-hover { animation-duration: 7s; animation-delay: -3s; }
  .vault-chip-2.anim-hover { animation-duration: 6.5s; animation-delay: -5s; }
  .nm-1.anim-hover { animation-delay: -1s; }
  .nm-2.anim-hover { animation-duration: 7s; animation-delay: -3s; }
  .relay-weights.anim-hover { animation-delay: -1s; }
  .relay-runtime.anim-hover { animation-duration: 7s; animation-delay: -3s; }
  .relay-chip-receipt.anim-hover { animation-duration: 6.5s; animation-delay: -5s; }
  .relay-req.anim-pulse, .as-req.anim-pulse { animation: pulseBar 1.6s ease-in-out infinite; }
  .relay-req-2.anim-pulse, .as-req-2.anim-pulse { animation-delay: 0.4s; }

  /* Autoscale staircase + ghost slots (02 v2 / 04 v2, 2026-07-23) */
  .as-1.anim-hover { animation-delay: -1s; }
  .as-2.anim-hover { animation-duration: 7s; animation-delay: -3s; }
  .as-3.anim-hover { animation-duration: 6.5s; animation-delay: -5s; }
  .anim-ghost { animation: ghostPulse 3s ease-in-out infinite alternate; }
  /* Second attestation orbit: half a revolution out of phase with the first */
  .vault-orbit-ring-2.anim-spin, .vault-orbit-ring-2 .vault-orbit-dot.anim-spin-counter { animation-delay: -4.5s; }

  /* Infra Stack v2: staggered entries composed with the ambient loops.
     Everything here is decoration — outside this gate the stack is simply
     static and fully visible (the entry animations carry the opacity ramp). */
  .stack .anim-dashflow { animation: enterFade 0.5s ease-out both, dashFlow 1.6s linear 0.5s infinite; }
  .axis-cap { animation: enterFade 0.5s ease-out both; }
  .axis-dot-feed { animation: enterFade 0.5s ease-out 0.4s both; }
  .axis-node { animation: enterFade 0.5s ease-out 0.1s both; }
  .axis-req { animation: axisTravel 5s linear infinite; }
  .axis-req-2 { animation-delay: -1.7s; }
  .axis-req-3 { animation-delay: -3.4s; }
  .promote { animation: promoteUp 7s ease-in-out 1.6s infinite; }
  .staging-ghost { animation: ghostPulse 3s ease-in-out infinite alternate; }
  .ground-prod { animation: enterFade 0.7s ease-out 0.15s both, shadowBreathe 6s ease-in-out infinite alternate; }
  .ground-staging { animation: enterFade 0.7s ease-out 0.3s both, shadowBreathe 6s ease-in-out -2s infinite alternate; }
  .ground-deploys { animation: enterFade 0.7s ease-out 0.4s both, shadowBreathe 6s ease-in-out -4s infinite alternate; }
  .g-prod.anim-hover { animation: enterFade 0.7s ease-out 0.15s both, hoverY 6s ease-in-out infinite alternate; }
  .g-staging.anim-hover { animation: enterFade 0.7s ease-out 0.3s both, hoverY 6s ease-in-out -2s infinite alternate; }
  .g-deploys.anim-hover { animation: enterFade 0.7s ease-out 0.4s both, hoverY 6s ease-in-out -4s infinite alternate; }
  .stack-feed { animation: enterUp 0.6s ease-out 0.4s both; }
  .cf-line { animation: enterFade 0.8s ease-out 0.65s both; }
  .cf-a1 { animation: driftX 7s ease-in-out -1s infinite alternate; }
  .cf-a2 { animation: driftX 6s ease-in-out -3s infinite alternate; }
  .cf-b1 { animation: driftX 7.5s ease-in-out -2s infinite alternate; }
  .cf-b2 { animation: driftX 6.5s ease-in-out -4s infinite alternate; }
  .cf-solo { animation: enterFade 0.8s ease-out 0.65s both, driftY 7s ease-in-out -1s infinite alternate; }
  .cf-cross { animation: enterFade 0.8s ease-out 0.65s both, driftY 6.5s ease-in-out -4s infinite alternate; }
  .prod-dot.anim-pulse { animation: pulseBar 2.2s ease-in-out infinite; }
  .prod-dot-2.anim-pulse { animation-delay: 0.4s; }
  .prod-dot-3.anim-pulse { animation-delay: 0.9s; }
  .prod-dot-4.anim-pulse { animation-delay: 1.4s; }
  .prod-dot-5.anim-pulse { animation-delay: 0.6s; }
  .feed-d.anim-pulse { animation: pulseBar 1.6s ease-in-out infinite; }
  .feed-d-2.anim-pulse { animation-delay: 0.25s; }
  .feed-d-3.anim-pulse { animation-delay: 0.5s; }
  .chip-event.on { animation: eventPop 2s ease-in-out both; }


  .anim-spin { animation: spin 9s linear infinite; }
  .anim-spin-counter { animation: spinCounter 9s linear infinite; }

  .nav-group:hover .nav-menu-panel,
  .nav-group.open .nav-menu-panel,
  html:not(.js) .nav-group:focus-within .nav-menu-panel { animation: menuIn 140ms ease-out; }
  .nav-open .nav-mobile { animation: menuIn 140ms ease-out; }
  .nav-burger-bar { transition: transform 160ms ease-out, opacity 120ms ease-out; }

  /* 36s → 50s (2026-07-21): duration is fixed but the row is now fluid, so the same 36s
     over a 1528px row would have run the strip 42% faster (29.8 → 42.4 px/s). 50s holds
     the original 29.8 px/s at desktop widths. Below ~1290px the row is unchanged, so
     narrow viewports get a calmer 19–21 px/s — fine for an ambient strip. */
  .lab-marquee-track { animation: marqueeX 50s linear infinite; }

  /* Expand-panel motion (Stripe sheet, founder 2026-07-17): the panel slides
     up from below the viewport, opaque, while the backdrop fades in; on close
     it slides back down. display/overlay transition with allow-discrete so the
     panel stays rendered and in the top layer for the exit slide — browsers
     without allow-discrete simply close instantly. The :not(:popover-open)
     rules are dropped whole by non-popover browsers, so the in-flow @supports
     fallback never inherits the off-screen transform. Under reduced motion
     none of this exists: the panel appears/disappears instantly. */
  .sx-panel[popover] {
    transition: transform 480ms cubic-bezier(0.32, 0.72, 0, 1),
                display 480ms allow-discrete, overlay 480ms allow-discrete;
  }
  .sx-panel[popover]:not(:popover-open) { transform: translateY(100vh); }
  .sx-panel::backdrop {
    transition: background-color 320ms ease-out,
                display 480ms allow-discrete, overlay 480ms allow-discrete;
  }
  .sx-panel[popover]:not(:popover-open)::backdrop { background: rgba(14, 18, 32, 0); }
  @starting-style {
    .sx-panel:popover-open { transform: translateY(100vh); }
    .sx-panel:popover-open::backdrop { background: rgba(14, 18, 32, 0); }
  }

  /* Arrow-link chevron nudge (instant discrete state change under reduced motion) */
  .link-arrow::after { transition: transform 200ms var(--ease-hover); }

  /* Button hover-lift tween. transition is ONE property: this rule must restate the
     full list from the ungated hover-motion block, or it clobbers the color tweens. */
  .btn {
    transition: color 150ms var(--ease-hover), background-color 150ms var(--ease-hover),
                border-color 150ms var(--ease-hover), transform 150ms var(--ease-hover),
                box-shadow 150ms var(--ease-hover);
  }
}

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] .reveal-item { transition: none; }
  .replica-cell { transition: none; }
  /* Marquee degrades to a static, centered, wrapped logo grid (a clipped
     non-moving row would hide labs; a fade mask on it would look broken). */
  /* Reset to the pre-2026-07-21 density. The widened row exists solely to outrun the
     SCROLLING strip's viewport; a static grid has no repeat and no hole, so it would
     pay the cost for nothing — the row's `gap` shorthand supplies column-gap here (the
     override below only sets row-gap), so without this the wrapped grid gains a line. */
  .lab-marquee { --logo-h: 22px; --logo-gap: 56px; }
  .lab-marquee-viewport { -webkit-mask-image: none; mask-image: none; }
  .lab-marquee-track { width: auto; }
  .lab-marquee-row { flex-wrap: wrap; justify-content: center; row-gap: 18px; padding-right: 0; }
  .lab-marquee-row[aria-hidden="true"] { display: none; }
}

/* ============ Responsive ============ */
@media (max-width: 1024px) {
  .nav-links { gap: 20px; }
  /* Footer sitemap: two columns; the brand block spans the full first row
     (4-up squeezes nav columns below the longest link's width under ~1025px) */
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 32px 24px; padding-block: 48px 40px; }
  .footer-brand { grid-column: 1 / -1; }
  .hero-cols { grid-template-columns: 1fr; }
  /* Single column ⇒ single centered axis: copy centers with the stack below it */
  .hero-copy { text-align: center; }
  .hero-status { justify-content: center; }
  .hero-sub { margin-inline: auto; }
  .hero-ctas { justify-content: center; }
  .stack { margin: 24px auto 0; }
  .split { grid-template-columns: 1fr; gap: 48px; }
  /* Expand panel: intro and checklist stack; the checklist's desktop-only
     insets (h2-level top pad, ×-clearance right pad) come off. The intro
     keeps its right pad — its first line still runs beside the ×. */
  .sx-head { grid-template-columns: 1fr; }
  .sx-checks { padding: 0; }
  .sx-row { grid-template-columns: 1fr; }
  /* Demo page: form first, dark panel after; the sticky must release */
  .demo-grid { grid-template-columns: 1fr; gap: 48px; }
  .demo-side { position: static; }
}

@media (max-width: 940px) {
  /* Two buttons + 7 links need ~940px unwrapped; Log in yields first (it returns
     at the bottom of the burger panel ≤800px — /login stays a holding page). */
  .nav-links .nav-login { display: none; }
}

@media (max-width: 900px) {
  /* Static pipeline: nodes stack; the numbered kickers carry the sequence */
  .flow { flex-direction: column; gap: 10px; }
  .connector { display: none; }
  .sx-prods { grid-template-columns: 1fr; }
}

@media (max-width: 800px) {
  /* The 8-item nav needs ~800px unwrapped; below that: brand + CTA + burger menu. */
  .nav-links .nav-link { display: none; }
  .nav-links .nav-group { display: none; }
  .nav-links .btn { display: none; } /* Book demo lives in the menu card ≤800px — bar is brand + burger only */
  .nav-links { gap: 14px; }
  .nav-inner { padding-inline: 18px 9px; }
  .nav-burger { display: flex; }
  body.nav-locked { overflow: hidden; }
  /* Floating card anchored under the pill's right end (kilo.ai pattern, 2026-07-17).
     right: 14px = the .nav wrapper's inline padding, so the card tracks the pill edge. */
  .nav-open .nav-mobile {
    display: block;
    position: absolute; top: 100%; right: 14px; left: auto;
    margin-top: 8px;
    width: min(340px, calc(100vw - 28px));
    padding: 6px 14px 14px;
    background: rgba(255, 255, 255, 0.82);
    backdrop-filter: blur(20px) saturate(1.5);
    -webkit-backdrop-filter: blur(20px) saturate(1.5);
    border: 1px solid rgba(213, 220, 242, 0.9);
    border-radius: 22px;
    box-shadow: 0 24px 48px -16px rgba(14, 18, 32, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.85);
    max-height: calc(100dvh - 100px); /* 10 sticky offset + 60 pill + 8 gap + breathing room */
    overflow-y: auto;
    pointer-events: auto; /* the .nav wrapper is pointer-events: none */
  }
  .features-grid { grid-template-columns: 1fr; }
  .feature-card-tall { grid-row: auto; }
}

@media (max-width: 768px) {
  .hero-inner { padding-top: calc(48px + var(--nav-clear)); padding-bottom: 30px; }
  .hero-cols { margin-bottom: 44px; }
  .section { padding: 72px 0; }
  section.section-cards-first { padding-top: 72px; }
  .page-intro { padding: calc(64px + var(--nav-clear)) 0 72px; }
  .section-band { padding: 64px 0; }
  .section-cta { padding: 80px 0 88px; }
  .demo-section { padding: calc(56px + var(--nav-clear)) 0 72px; }
}

@media (max-width: 640px) {
  .row-item { grid-template-columns: 1fr; gap: 8px; }
  .strip-operator-inner { flex-direction: column; align-items: flex-start; gap: 8px; }

  /* Hero: the pip reads as a hanging fragment when flex-wrap drops it — give it its own line */
  .hero-pip { flex-basis: 100%; margin-left: 0; }

  /* Code card: tabs + actions need ~414px on one line; let the actions wrap under, right-aligned */
  .code-head { flex-wrap: wrap; row-gap: 8px; }
  .code-actions { margin-left: auto; }
  .codeblock { padding: 18px 16px 20px; }
  .code-note { padding: 12px 16px; flex-wrap: wrap; }

  /* Pipeline: desktop paddings are too generous at phone widths */
  .pipe-body { padding: 16px 12px; }
  .node { padding: 16px; }

  /* Expand card + panel at phone widths */
  .sx-card { padding: 24px 18px 20px; border-radius: 10px; }
  .sx-btn { width: 40px; height: 40px; border-radius: 9px; }
  .sx-expand { top: 14px; right: 14px; }
  /* True bottom sheet at phone widths (Stripe mobile pattern): full width,
     anchored to the bottom edge, top corners only */
  .sx-panel[popover] { width: 100vw; max-height: calc(100dvh - 24px); margin: auto 0 0; border-radius: 16px 16px 0 0; }
  .sx-close { top: 12px; right: 12px; }
  .sx-prod { padding: 20px 18px 18px; }

  /* Marquee: scale the whole strip down a notch (logos + gaps together) */
  .lab-marquee-viewport { zoom: 0.88; }

  /* Feature cards + autoscale sim */
  .feature-card { padding: 26px 20px; }
  .sim-foot { flex-wrap: wrap; row-gap: 10px; }

  /* Demo page: name fields + interest chips stack; the card frame tightens and the
     dark panel loses desktop-scale padding */
  .form-row, .checks-grid { grid-template-columns: 1fr; }
  .form-body { padding: 2px 16px; }
  .form-head { padding: 8px 8px 10px; }
  .form-foot { padding: 12px 8px 4px; }
  .form-submit { width: 100%; } /* the one place a stretched primary earns its width */
  .demo-side { padding: 24px 20px 20px; }
}

@media (max-width: 560px) {
  /* zoom (not transform: scale) shrinks the layout box and the right/bottom-
     anchored children coherently, so the 440px design no longer overflows. */
  .stack { zoom: 0.72; }
}

@media (max-width: 480px) {
  /* Footer sitemap: single column, separators off */
  .footer-grid { grid-template-columns: 1fr; }
}

@media (max-width: 420px) {
  /* v2 artwork (2026-07-20): DEPLOYMENTS now carries the canary story, so the
     old drop-the-grey-tier rule is retired — keep the whole stack, step the zoom.
     Ladder is sized for the 500px canvas: each step must fit (viewport − 48px
     gutters) down to the next breakpoint. 0.62 × 500 = 310 ≤ 361 − 48. */
  .stack { zoom: 0.62; }
  /* Scale the fixed-geometry illustrations and shrink their layout boxes to match,
     so they stop forcing the section grid past the container padding. */
  .vault, .netmap, .relay { transform: scale(0.85); transform-origin: top left; }
  .vault { width: 289px; height: 213px; }
  .netmap { width: 289px; height: 255px; }
  .relay { width: 289px; height: 179px; }
  /* The autoscale (320px) overflows the card's ≤420 content box the same way */
  .sx-card .autoscale { zoom: 0.85; }
}

@media (max-width: 360px) {
  /* Keep brand + burger on one pill line down to 320px */
  .nav-links { gap: 10px; }
  .stack { zoom: 0.54; } /* 0.54 × 500 = 270 ≤ 320 − 48: no overflow at 320px */
  /* 11px mono at zoom .54 is illegible — compensate the chips */
  .stack .chip { font-size: 14px; }
}

/* Browsers without the Popover API (Safari ≤16, Chrome <114, Firefox <125): the
   closed-popover display:none is a UA rule that only exists where popover is
   implemented, so there the .sx-panel would render in-flow as a shadowed "modal"
   duplicate with dead buttons. Degrade honestly instead: hide the dead controls
   and the duplicate intro, and let the checklist + product panels flow after
   the card as a plain block — no product copy is lost. Kept at the END of the
   file so it out-cascades the sx rules inside the media queries above. */
@supports not selector(:popover-open) {
  .sx-expand, .sx-close, .sx-intro { display: none; }
  .sx-panel[popover] {
    width: auto; max-height: none; margin: 28px 0 0;
    border-radius: 0; box-shadow: none; overflow: visible; background: transparent;
  }
  .sx-body { padding: 0; overflow: visible; }
  .sx-head { grid-template-columns: 1fr; }
  .sx-checks { padding: 0; }
}

/* No backdrop-filter (old Safari/Firefox): the glass alphas leave nav text unreadable
   over scrolled content — fall back to near-solid surfaces. At the END of the file so
   these out-cascade the equal-specificity glass rules above. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nav-inner, .nav-menu-panel { background: rgba(255, 255, 255, 0.96); }
  .nav-open .nav-mobile { background: #FFFFFF; }
  .theme-dark .nav-inner { background: rgba(19, 20, 24, 0.97); }
  .theme-dark .nav-open .nav-mobile { background: var(--code-bg); }
}
