/* Minimal — littlebitlabs.com
   Apple design language. Light by default, manual dark mode, mobile-first.
   Single stylesheet, no build step. */

:root {
  color-scheme: light;

  --max: 1180px;
  --pad: 32px;

  --accent: #0F6B57;
  /* derived from --accent so one swatch click retints the whole page */
  --accent-ink: var(--accent);    /* every offered accent holds >= 5:1 on white */
  --accent-wash: color-mix(in oklab, var(--accent) 11%, #ffffff);
  --accent-btn-text: #ffffff;      /* 6.44:1 on the fill */

  --bg: #ffffff;
  --surface: #ffffff;
  --tint: #f5f5f7;
  --text: #1d1d1f;
  --text-2: #636367;              /* holds 5:1 over the grained ground */
  --text-3: #86868b;
  --hair: rgba(0, 0, 0, 0.11);
  --hair-soft: rgba(0, 0, 0, 0.07);
  --nav-bg: rgba(255, 255, 255, 0.72);

  --shadow-sm: 0 0 0 1px rgba(0,0,0,0.06), 0 4px 12px -4px rgba(0,0,0,0.10);
  --shadow-md: 0 0 0 1px rgba(0,0,0,0.07), 0 14px 36px -14px rgba(0,0,0,0.16);
  --shadow-lg: 0 0 0 1px rgba(0,0,0,0.07), 0 24px 60px -20px rgba(0,0,0,0.20);

  --sans: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text', 'Segoe UI', 'Helvetica Neue', Helvetica, sans-serif;
  --mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;

  --ease: cubic-bezier(0.32, 0.72, 0, 1);

  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.19'/%3E%3C/svg%3E");
}

[data-theme="dark"] {
  color-scheme: dark;

  --accent-ink: color-mix(in oklab, var(--accent) 46%, #ffffff);   /* the fill is too dark to read on black */
  --accent-wash: color-mix(in oklab, var(--accent) 26%, #0c0c0e);
  --accent-btn-text: #ffffff;

  --bg: #111113;
  --surface: #1c1c1e;
  --tint: #17171a;
  --text: #f5f5f7;
  --text-2: #a1a1a6;              /* 8.1:1 on black */
  --text-3: #8e8e93;
  --hair: rgba(255, 255, 255, 0.15);
  --hair-soft: rgba(255, 255, 255, 0.09);
  --nav-bg: rgba(0, 0, 0, 0.68);

  /* grain has to lighten on black, not darken */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.15' style='mix-blend-mode:screen'/%3E%3C/svg%3E");

  --shadow-sm: 0 0 0 1px rgba(255,255,255,0.07);
  --shadow-md: 0 0 0 1px rgba(255,255,255,0.08), 0 14px 36px -14px rgba(0,0,0,0.7);
  --shadow-lg: 0 0 0 1px rgba(255,255,255,0.09), 0 24px 60px -20px rgba(0,0,0,0.8);
}

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background-color: var(--bg);
  /* fine paper grain — gives the ground tooth so white cards, pills and secondary
     buttons read as raised objects rather than dissolving into flat white */
  background-image: var(--grain);
  background-repeat: repeat;
  background-size: 160px 160px;
  color: var(--text);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  transition: background-color 0.35s var(--ease), color 0.35s var(--ease);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

a { color: var(--accent-ink); text-decoration: none; }

/* key-message marker. box-decoration-break keeps the wash continuous if the phrase wraps.
   The pull-back is LEADING ONLY so the wash starts flush with the text column when the
   highlight opens a line; trailing side keeps its padding so mid-sentence use doesn't
   collide with the next word. */
.hl {
  color: var(--accent-ink); font-weight: 600;
  background: var(--accent-wash);
  margin-inline: -0.24em 0; padding: 0.06em 0.24em 0.1em;
  border-radius: 5px;
  box-decoration-break: clone; -webkit-box-decoration-break: clone;
}

a:hover { opacity: 0.72; }
a:focus-visible, button:focus-visible, summary:focus-visible {
  outline: 2px solid var(--accent-ink);
  outline-offset: 3px;
  border-radius: 6px;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; text-wrap: balance; }
p { margin: 0; text-wrap: pretty; }
img, svg { max-width: 100%; }

/* ── layout ─────────────────────────────────────────────────────────── */

.wrap { max-width: var(--max); margin: 0 auto; padding-inline: var(--pad); }
.band { border-top: 1px solid var(--hair); }
.band--wash { background: var(--accent-wash); border-top: 1px solid var(--hair-soft); }
.band--tint { background: var(--tint); border-top: 1px solid var(--hair-soft); }

.sec { padding-block: clamp(52px, 5.6vw, 84px); }
.sec--tight { padding-block: clamp(40px, 4.2vw, 60px); }
.sec--hero { padding-block: clamp(38px, 4.2vw, 64px) clamp(22px, 2.4vw, 34px); }
/* the animation is the payoff for one inch of scroll: the band sits directly under
   the hero with only enough air to read as a separate object, so its top edge is
   visible above the fold on a laptop. */
.sec--stage { padding-block: clamp(20px, 2.2vw, 30px); }
/* escapes .wrap without 100vw (which would add a scrollbar's width of overflow) */
.bleed { margin-inline: calc(50% - 50vw + var(--sbw, 0px)); display: flex; }

.center { display: flex; flex-direction: column; align-items: center; text-align: center; }
.stack { display: flex; flex-direction: column; }
.gap-8 { gap: 8px; } .gap-10 { gap: 10px; } .gap-14 { gap: 14px; } .gap-18 { gap: 18px; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--surface); color: var(--text); padding: 12px 18px; border-radius: 10px;
}
.skip:focus { left: 16px; top: 12px; box-shadow: var(--shadow-md); }

/* ── type scale ─────────────────────────────────────────────────────── */

.eyebrow {
  font-size: 15px; font-weight: 600; letter-spacing: -0.004em;
  color: var(--accent-ink);
}
.h1 { font-size: clamp(34px, 5.4vw, 56px); line-height: 1.05; letter-spacing: -0.032em; }
/* brackets as marks, not letters — "database" still reads whole at a glance,
   "data" on the second look */
.brk { color: var(--text-3); font-weight: 400; }
.h2 { font-size: clamp(26px, 3.4vw, 38px); line-height: 1.09; letter-spacing: -0.027em; }
.h3 { font-size: clamp(20px, 2.3vw, 25px); line-height: 1.16; letter-spacing: -0.022em; }
.h4 { font-size: 18px; line-height: 1.25; letter-spacing: -0.018em; }

.lede {
  font-size: clamp(19px, 2.1vw, 24px); line-height: 1.32;
  letter-spacing: -0.016em; color: var(--text-2);
}
.body {
  font-size: clamp(16px, 1.2vw, 17px); line-height: 1.55;
  letter-spacing: -0.01em; color: var(--text-2);
}
.small { font-size: 15px; line-height: 1.55; letter-spacing: -0.008em; color: var(--text-2); }
.tiny { font-size: 13px; line-height: 1.5; letter-spacing: -0.004em; color: var(--text-3); }
.num { font-variant-numeric: tabular-nums; }
.measure { max-width: 62ch; }
.measure-s { max-width: 48ch; }

/* ── buttons ────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 46px; padding: 12px 24px; border-radius: 999px; border: 0;
  font-family: var(--sans); font-size: 16px; font-weight: 600; letter-spacing: -0.01em;
  cursor: pointer; white-space: nowrap;
  transition: transform 0.18s var(--ease), opacity 0.18s var(--ease), background-color 0.18s var(--ease);
}
.btn:hover { opacity: 1; transform: translateY(-1px); }
.btn:active { transform: translateY(0) scale(0.985); }

.btn--primary { background: var(--accent); color: var(--accent-btn-text); }
.btn--primary:hover { filter: brightness(1.04); }
.btn--ghost { background: var(--surface); color: var(--text); box-shadow: inset 0 0 0 1px rgba(0,0,0,0.19), 0 2px 8px -2px rgba(0,0,0,0.12); }
.btn--ghost:hover { background: var(--tint); }
[data-theme="dark"] .btn--ghost { box-shadow: inset 0 0 0 1px rgba(255,255,255,0.22); }
.btn--quiet { background: transparent; color: var(--text); box-shadow: inset 0 0 0 1px var(--hair); }
.btn--sm { min-height: 40px; padding: 9px 18px; font-size: 15px; }

.cta-row { display: flex; flex-wrap: wrap; gap: 10px; }
.center .cta-row { justify-content: center; }

.arrow-link {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 16px; font-weight: 500; letter-spacing: -0.01em; color: var(--accent-ink);
}
.arrow-link svg { transition: transform 0.2s var(--ease); }
.arrow-link:hover svg { transform: translateX(3px); }
.plate .arrow-link { color: #f5f5f7; }
.plate .arrow-link:hover { color: #ffffff; }

/* ── nav ────────────────────────────────────────────────────────────── */

.nav {
  position: sticky; top: 0; z-index: 40;
  background: var(--nav-bg);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--hair-soft);
}
.nav__in {
  max-width: var(--max); margin: 0 auto; padding-inline: var(--pad);
  height: 56px; display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.brand { display: flex; align-items: center; gap: 10px; color: var(--text); }
.brand:hover { opacity: 1; }
.brand__mark { width: 22px; height: 22px; flex: none; display: block; }
/* the mark alone carries the header, so it runs larger than it would beside a wordmark */
.brand--markonly .brand__mark { width: 30px; height: 30px; }
.brand__name { font-size: 19px; font-weight: 600; letter-spacing: -0.024em; }

/* Wordmark — brushed steel. A gradient can only reach type through background-clip,
   which needs a transparent fill, so the solid mid-tone is set first and the clip is
   applied only where it is supported (otherwise the name would vanish). The ramp runs
   dark-biased in light mode and light-biased in dark so it stays legible on both;
   the off-axis angle is what reads as a machined surface rather than a fade. */
/* 180deg, not an off-axis angle: over a 102×23 box a 168deg ramp is ~48% horizontal,
   so it fades left→right and drops the tail of the name out instead of banding across
   the cap height. Vertical keeps every letter on the same ramp. Lightest stop is held
   at ~4:1 on white so the highlight reads as steel without a letter vanishing. */
.brand__word {
  font-size: 20px; font-weight: 700; letter-spacing: -0.032em;
  color: #3b424b;
  background-image: linear-gradient(180deg,
    #6e767e 0%, #3b424b 28%, #242a31 48%, #5c646d 58%, #767e86 74%, #333a42 100%);
}
@supports (-webkit-background-clip: text) or (background-clip: text) {
  .brand__word {
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent;
  }
}
[data-theme="dark"] .brand__word {
  color: #cfd5db;
  background-image: linear-gradient(180deg,
    #eef1f4 0%, #a7afb7 28%, #f4f6f8 48%, #9aa2aa 60%, #e2e7eb 78%, #b6bdc4 100%);
}

.nav__links { display: flex; align-items: center; gap: 22px; margin-left: auto; }
/* The external-link arrow is a second child of the anchor, and the newline between it and
   the label is a break opportunity — in an inline anchor the arrow drops to its own line
   above the text. A flex context removes the text node and sizes the glyph. */
.nav__link:has(.ext) { display: inline-flex; align-items: center; gap: 4px; }
.nav__link .ext { width: 11px; height: 11px; flex: none; }
.nav__link {
  position: relative;
  font-size: 15px; font-weight: 500; letter-spacing: -0.01em; color: var(--text-2);
  padding: 6px 0;
}
.nav__link:hover { color: var(--text); opacity: 1; }
/* Current page. An underline as well as the ink lift: nav links sit at --text-2 and hover
   already promotes them to --text, so colour alone would be indistinguishable from a hover. */
.nav__link[aria-current="page"], .nav__link[data-current="true"] { color: var(--text); }
.nav__link[aria-current="page"]::after, .nav__link[data-current="true"]::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: var(--accent-ink); border-radius: 2px;
}
.nav__actions { display: flex; align-items: center; gap: 2px; margin-left: 8px; }

.icon-btn {
  width: 40px; height: 40px; flex: none; display: grid; place-items: center;
  border: 0; border-radius: 999px; background: transparent; color: var(--text-2); cursor: pointer;
}
.icon-btn:hover { background: var(--tint); color: var(--text); }
.icon-btn svg { width: 19px; height: 19px; display: block; }
.theme-btn .moon { display: none; }
[data-theme="dark"] .theme-btn .moon { display: block; }
[data-theme="dark"] .theme-btn .sun { display: none; }

.burger { display: none; }

.nav__panel {
  display: none;
  border-top: 1px solid var(--hair-soft);
  background: var(--bg);
  padding: 10px var(--pad) 22px;
}
.nav__panel[data-open="true"] { display: block; }
.nav__panel a {
  display: flex; align-items: center; min-height: 52px;
  font-size: 19px; font-weight: 500; letter-spacing: -0.02em; color: var(--text);
  border-bottom: 1px solid var(--hair-soft);
}
.nav__panel .btn { width: 100%; margin-top: 18px; }
/* .nav__panel a sets color/border/display for the link list; the CTA is a button
   in that list and must not inherit any of it — in dark mode --text on the mint
   fill is 1.56:1, and a hairline reads as a stroke across a rounded pill */
.nav__panel .btn--primary { color: var(--accent-btn-text); }
.nav__panel .btn { border-bottom: 0; min-height: 46px; }

@media (max-width: 860px) {
  .nav__links { display: none; }
  .burger { display: grid; }
}

/* ── the animation card ─────────────────────────────────────────────── */

.stage {
  position: relative; width: 100%;
  border-radius: 16px; overflow: hidden;
  background: var(--surface);
  box-shadow: var(--shadow-md);
  /* own compositing layer so the animating content isn't clipped into the page */
  transform: translateZ(0); will-change: transform; contain: paint; isolation: isolate;
  aspect-ratio: 16 / 9;
}
/* `Stage`'s auto-scale in animations-v2.jsx subtracts a hardcoded 44px playback-bar
   height before fitting the 1600×900 frame. That bar is hidden here, so the mount is
   grown by exactly that 44px — split above and below — and the frame fills the card. */
.stage__mount { position: absolute; left: 0; right: 0; top: -22px; height: calc(100% + 44px); }
/* the standalone stage ships a dark desk, a drop shadow and a scrubber toolbar,
   all meant for full-bleed use — the card wants none of them */
.stage [data-om-starter="animations-v2"] { background: #ffffff !important; }
.stage [data-om-starter="animations-v2"] > div + div { display: none !important; }
.stage [data-om-starter="animations-v2"] svg {
  box-shadow: none !important;
  /* the frame is authored at 1600×900 and scaled by the stage; the global
     `svg { max-width: 100% }` reset would clamp it first and halve it */
  max-width: none;
}

/* Bleed variant. The artwork is a fixed 1600×900 frame that animations-v2 fits to
   the container, so a container that isn't 16:9 letterboxes it — a height cap alone
   made the block 2.3:1 and shrank the artwork. Instead the block stays 16:9 and its
   WIDTH is derived: fill the bleed on narrow viewports, and on tall/wide ones take
   the largest 16:9 box that fits the height budget. Height never binds, so the frame
   always lands edge-to-edge inside the card at every size. */
.stage--bleed {
  width: min(100%, calc(min(78vh, 860px) * 16 / 9));
  min-width: min(100%, var(--max));
  margin-inline: auto;
  max-height: none;
  border-radius: 14px;
  box-shadow: var(--shadow-md);
}
/* the mount forces #ffffff (the frame is authored light and has no dark variant), so
   on a dark page the card is a bright panel — a ring and a softer shadow make it read
   as a screen inset in the band rather than a slab punched out of it */
[data-theme="dark"] .stage--bleed {
  box-shadow: 0 0 0 1px rgba(255,255,255,0.10), 0 22px 48px -28px rgba(0,0,0,0.9);
}

.stage__poster {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  transition: opacity 0.6s var(--ease);
}
.stage[data-live="true"] .stage__poster { opacity: 0; pointer-events: none; }

/* still frame: what the card shows before the runtime is fetched, and what it keeps
   showing if the fetch never lands. The live frame is authored on white in both
   themes, so the still frame pins white and its own inks to match — otherwise a
   dark-mode load flashes the whole card from black to white. */
.stage__still {
  position: absolute; inset: 0; z-index: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 16px; padding: 32px; text-align: center;
  background: #ffffff; color: #1d1d1f;
  transition: opacity 0.5s var(--ease);
}
.stage[data-live="true"] .stage__still { opacity: 0; pointer-events: none; }
.stage__path { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px; }
.stage__node {
  font-size: 14px; font-weight: 500; letter-spacing: -0.008em;
  padding: 8px 15px; border-radius: 999px;
  background: #ffffff; color: #1d1d1f;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.11), 0 2px 8px -3px rgba(0,0,0,0.10);
}
.stage__node--on { background: var(--accent); color: var(--accent-btn-text); box-shadow: none; }
.stage__caption { font-size: 15px; line-height: 1.55; letter-spacing: -0.008em; color: #636367; max-width: 48ch; }
.stage__tick { color: #86868b; font-size: 13px; }
.stage[data-state="loading"] .stage__play { opacity: 0.5; pointer-events: none; }

.stage__play {
  position: absolute; left: 50%; bottom: 16px; transform: translateX(-50%);
  z-index: 2; box-shadow: var(--shadow-sm);
}
.stage[data-live="true"] .stage__play { display: none; }

/* Phones get a portrait card carrying the still frame. The walkthrough itself is
   authored at 1600×900, so at 390px it would fit to ~316px wide — every label
   under 5px. Below 700px the still frame IS the experience; no tap-to-play. */
@media (max-width: 700px) {
  .stage { aspect-ratio: 4 / 5; }
  /* it touches both edges here, so the radius has nothing to describe */
  .stage--bleed { border-radius: 0; box-shadow: none; }
  .stage__play { display: none; }
  .stage[data-live="true"] { aspect-ratio: 16 / 9; }
}

/* ── cards & grids ──────────────────────────────────────────────────── */

.grid { display: grid; gap: 22px; }
.grid--5 { grid-template-columns: repeat(auto-fit, minmax(178px, 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(268px, 1fr)); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
/* Exactly two, not "as many 320px tracks as fit". auto-fit resolves to THREE columns once the
   container passes ~1004px, which orphans a fourth card on its own row on every desktop
   width — so a fixed 2-up is the only thing that holds a 2×2. */
.grid--2up { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 760px) { .grid--2up { grid-template-columns: minmax(0, 1fr); } }

.step { display: flex; flex-direction: column; gap: 9px; border-top: 1px solid var(--hair); padding-top: 16px; }
.step__n { font-size: 13px; font-weight: 500; letter-spacing: 0.03em; color: var(--text-3); font-variant-numeric: tabular-nums; }

.card {
  display: flex; flex-direction: column; gap: 12px;
  padding: 26px; border-radius: 18px;
  background: var(--surface); box-shadow: var(--shadow-sm);
}
.card--flush { padding: 0; overflow: hidden; }

/* Whole-card link. The arrow is pinned to the bottom by margin-top:auto so it lands on one
   line across a row of unequal-height cards, and the lift is on the shadow only — moving the
   card itself would shift the text under the cursor mid-read. */
.prod { gap: 11px; color: var(--text); position: relative; transition: box-shadow 0.2s var(--ease); }
.prod:hover { opacity: 1; box-shadow: var(--shadow-md); }
.prod .spec-list { margin-top: 2px; }
/* margin-top:auto pins the row to the bottom so it lands on one line across unequal-height cards */
.prod__go {
  margin-top: auto; padding-top: 14px; border-top: 1px solid var(--hair-soft);
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px; flex-wrap: wrap;
}
/* the primary link stretches over the whole card, so the card stays clickable without nesting
   anchors — which is invalid and would have swallowed the second link */
.prod__more::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.prod__open {
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 14px; font-weight: 500; letter-spacing: -0.008em; color: var(--text-2);
}
.prod__open:hover { color: var(--text); opacity: 1; }
@media (prefers-reduced-motion: reduce) { .prod { transition: none; } }

/* Step-section closer. The five cards are an inventory; this is the narrative that runs
   them as one sentence. Panel, not a sixth card — it must read as a summation. */
.summary {
  margin-top: 30px; padding: clamp(24px, 2.6vw, 34px) clamp(22px, 2.6vw, 36px);
  border-radius: 16px; background: var(--tint);
  box-shadow: inset 0 0 0 1px var(--hair-soft);
  display: flex; flex-direction: column; gap: 12px;
  max-width: 860px;
}
.summary .lede { max-width: 34ch; }
.summary .body { max-width: 76ch; }
/* the step number sits in the prose as a marker, not a word — mono and small so it reads
   as a cross-reference to the card above rather than part of the sentence */
.summary__n {
  font-family: var(--mono); font-size: 11px; font-weight: 600;
  color: var(--accent-ink); background: var(--accent-wash);
  padding: 2px 6px; border-radius: 5px;
  vertical-align: 0.14em; margin-inline: 1px;
}

.pill-row { display: flex; flex-wrap: wrap; gap: 10px; }
.pill {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 14px; font-weight: 500; letter-spacing: -0.008em;
  padding: 9px 16px; border-radius: 999px;
  background: var(--surface); box-shadow: var(--shadow-sm); color: var(--text);
}
.pill--quiet { background: var(--surface); box-shadow: inset 0 0 0 1px rgba(0,0,0,0.13), 0 2px 8px -3px rgba(0,0,0,0.10); color: var(--text-2); }
[data-theme="dark"] .pill--quiet { box-shadow: inset 0 0 0 1px rgba(255,255,255,0.16); }
.pill--accent { background: var(--accent); color: var(--accent-btn-text); box-shadow: none; }

/* Tested engines. Five-up: 15 names divide evenly into three full rows, so no
   orphan row to centre. Flex-wrap rather than grid so the basis can be restated
   per breakpoint without redeclaring the track list. */
.engines {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 8px; width: 100%; max-width: 940px;
  position: relative; isolation: isolate;
}
/* Glass needs something behind it to bend, and a flat band gives it nothing. Two very
   low-opacity accent pools sit under the grid purely so the tiles' backdrop-filter has
   content to refract — kept under 20% so it never reads as a gradient background.
   Painted before the tiles in DOM order, so no negative z-index is needed. */
.engines::before {
  content: ''; position: absolute; inset: -6% -3%; pointer-events: none;
  background:
    radial-gradient(40% 54% at 16% 20%, color-mix(in oklab, var(--accent) 20%, transparent), transparent 72%),
    radial-gradient(36% 48% at 84% 80%, color-mix(in oklab, var(--accent) 14%, transparent), transparent 72%);
  filter: blur(22px);
}
/* Neutral-density glass. saturate() in the backdrop filter is what stops the pane inheriting
   the band's teal — it desaturates what it transmits, so the tile stays neutral while still
   reading as glass rather than an opaque card. Fill is flat, not a gradient: a gradient plus a
   bright bevel reads as a curved dome, which is not what a flat pane looks like. */
.engine {
  flex: 0 0 calc((100% - 4 * 8px) / 5);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 11px;
  min-height: 132px; padding: 16px 10px; border-radius: 14px;
  color: var(--text-2);
  position: relative; overflow: hidden;
  background: rgba(255,255,255,0.44);
  -webkit-backdrop-filter: blur(9px) saturate(0.1) brightness(1.04);
  backdrop-filter: blur(9px) saturate(0.1) brightness(1.04);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.7),
    inset 0 0 0 1px rgba(0,0,0,0.07),
    1px 2px 3px -2px rgba(0,0,0,0.012);
  text-align: center;
  transition: box-shadow 0.24s var(--ease), background 0.24s var(--ease);
}
/* one light source for the whole grid: the sweep sits upper-left, so every pane casts the same
   short shadow down and to the right. Offset stays under 2px — enough to place the light,
   not enough to lift the tile off the band. */
.engine:hover {
  background: rgba(255,255,255,0.22);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.35),
    inset 0 0 0 1px color-mix(in oklab, var(--accent) 40%, transparent),
    1px 3px 5px -3px rgba(0,0,0,0.006);
}
.engine:hover .engine__mark { color: var(--accent-ink); opacity: 1; }
.engine:hover .engine__name { color: var(--text); }
/* the mark and label ride above the sweep */
.engine__mark, .engine__name { position: relative; }
/* Official marks, drawn as masks so a single-colour glyph inherits theme ink rather
   than burning in black. The URLs live here, not in an inline `--mark`: url() inside a
   custom property resolves against the stylesheet that CONSUMES it, so a
   document-relative path written in the HTML doubles to assets/assets/. These are
   relative to styles.css, which is what the browser actually resolves against.
   Band height matches .engine__slot so mask and drop-target tiles share a baseline;
   mask-size keeps the glyph itself small inside that band. */
/* The icon as its own light source. A blurred, oversized copy of the same mask sits inside
   the pane in accent, so the glass carries the glyph's shape as refracted colour instead of a
   generic frost. Sized and blurred so the shape is suggested, never legible as a second icon. */
.engine__glow {
  position: absolute; left: 0; right: 0; top: 22px; height: 72px;
  background-color: var(--accent);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: auto 66px; mask-size: auto 66px;
  filter: blur(15px); opacity: 0.14;
  pointer-events: none;
  transition: opacity 0.28s var(--ease), filter 0.28s var(--ease);
}
[data-theme="dark"] .engine__glow {
  background-color: var(--accent-ink);
  opacity: 0.12; mix-blend-mode: screen;
}
.engine:hover .engine__glow { opacity: 0.07; filter: blur(18px); }
[data-theme="dark"] .engine:hover .engine__glow { opacity: 0.06; filter: blur(18px); }
/* the glow tracks whichever marks were sized up */
.engine__glow[data-mark="risingwave"] {
  -webkit-mask-size: auto 96px; mask-size: auto 96px;
}
/* mysql's dolphin is a tight square glyph with no wordmark, so it matches on height not width */
.engine__glow[data-mark="mysql"] { -webkit-mask-size: auto 77px; mask-size: auto 77px; }

/* the mark itself is polished rather than flat: a vertical ramp through the glyph reads as
   light falling across a solid object sitting on the glass */
.engine__mark {
  width: 100%; height: 72px;
  background-color: currentColor;
  background-image: linear-gradient(180deg, rgba(255,255,255,0.26) 0%, rgba(255,255,255,0) 58%);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: auto 52px; mask-size: auto 52px;
  opacity: 0.82;
  transition: opacity 0.2s var(--ease), background-color 0.2s var(--ease);
}
.engine [data-mark="postgresql"] { -webkit-mask-image: url('images/engines/postgresql.svg'); mask-image: url('images/engines/postgresql.svg'); }
.engine [data-mark="timescale"] { -webkit-mask-image: url('images/engines/timescale.svg'); mask-image: url('images/engines/timescale.svg'); }
.engine [data-mark="cockroachlabs"] { -webkit-mask-image: url('images/engines/cockroachlabs.svg'); mask-image: url('images/engines/cockroachlabs.svg'); }
.engine [data-mark="mysql"] { -webkit-mask-image: url('images/engines/mysql.png'); mask-image: url('images/engines/mysql.png'); }
.engine [data-mark="mariadb"] { -webkit-mask-image: url('images/engines/mariadb.svg'); mask-image: url('images/engines/mariadb.svg'); }
.engine [data-mark="vitess"] { -webkit-mask-image: url('images/engines/vitess.svg'); mask-image: url('images/engines/vitess.svg'); }
.engine [data-mark="tidb"] { -webkit-mask-image: url('images/engines/tidb.svg'); mask-image: url('images/engines/tidb.svg'); }
.engine [data-mark="singlestore"] { -webkit-mask-image: url('images/engines/singlestore.svg'); mask-image: url('images/engines/singlestore.svg'); }
.engine [data-mark="clickhouse"] { -webkit-mask-image: url('images/engines/clickhouse.svg'); mask-image: url('images/engines/clickhouse.svg'); }
/* supplied as a transparent PNG rather than an SVG — its alpha channel masks just as
   well, so it takes the same theme ink and teal hover as the vector marks */
.engine [data-mark="yugabyte"] { -webkit-mask-image: url('images/engines/yugabyte.png'); mask-image: url('images/engines/yugabyte.png'); }
.engine [data-mark="citus"] { -webkit-mask-image: url('images/engines/citus.png'); mask-image: url('images/engines/citus.png'); }
.engine [data-mark="risingwave"] { -webkit-mask-image: url('images/engines/risingwave.png'); mask-image: url('images/engines/risingwave.png'); }
.engine [data-mark="percona"] { -webkit-mask-image: url('images/engines/percona.png'); mask-image: url('images/engines/percona.png'); }
.engine [data-mark="starrocks"] { -webkit-mask-image: url('images/engines/starrocks.png'); mask-image: url('images/engines/starrocks.png'); }
/* supplied as a JPEG on cream: keyed to alpha by luminance drop and cropped to the ink,
   so the line art keeps its antialiasing and the gradient diamond reads as tonal weight */
.engine [data-mark="aurora"] { -webkit-mask-image: url('images/engines/aurora.png'); mask-image: url('images/engines/aurora.png'); }
/* both carry vertical padding inside their own bounding box, so a uniform 52px band
   height renders the visible glyph noticeably smaller than its neighbours — sized up
   per mark rather than loosening the band for all fifteen */
.engine [data-mark="risingwave"] {
  -webkit-mask-size: auto 78px; mask-size: auto 78px;
}
.engine [data-mark="mysql"] { -webkit-mask-size: auto 57px; mask-size: auto 57px; }
.engine__name { font-size: 13px; font-weight: 500; letter-spacing: -0.012em; text-wrap: balance; transition: color 0.2s var(--ease); }

/* Accepted file formats. A row, not tiles: these are inputs to the same section, and
   giving them tile weight would read as five more engines. CSV, XLS and NDJSON have no
   brand mark — they get a generic document glyph rather than an invented logo. */
.fmts { display: flex; flex-wrap: wrap; justify-content: center; gap: 7px; }
.fmt {
  display: flex; align-items: center; gap: 7px;
  font-size: 13px; font-weight: 500; letter-spacing: -0.008em;
  color: var(--text-2);
  padding: 7px 13px 7px 11px; border-radius: 999px;
  background: rgba(255,255,255,0.3);
  -webkit-backdrop-filter: blur(16px) saturate(0.1) brightness(1.04);
  backdrop-filter: blur(16px) saturate(0.1) brightness(1.04);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.58),
    inset 0 0 0 1px rgba(0,0,0,0.07),
    1px 2px 3px -2px rgba(0,0,0,0.09);
  transition: box-shadow 0.2s var(--ease), color 0.2s var(--ease), background 0.2s var(--ease);
}
[data-theme="dark"] .fmt {
  background: rgba(255,255,255,0.05);
  -webkit-backdrop-filter: blur(16px) saturate(0.1) brightness(0.6);
  backdrop-filter: blur(16px) saturate(0.1) brightness(0.6);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.15),
    inset 0 0 0 1px rgba(255,255,255,0.08),
    1px 2px 4px -2px rgba(0,0,0,0.6);
}
.fmt:hover { color: var(--accent-ink); box-shadow: inset 0 1px 0 rgba(255,255,255,0.66), inset 0 0 0 1px color-mix(in oklab, var(--accent) 40%, transparent); }
.fmt:hover .fmt__mark { opacity: 1; }
.fmt__mark {
  width: 15px; height: 15px; flex: none;
  background-color: currentColor; opacity: 0.72;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
  transition: opacity 0.2s var(--ease);
}
.fmt__mark[data-mark="files"] { -webkit-mask-image: url('images/engines/files.svg'); mask-image: url('images/engines/files.svg'); }
.fmt__mark[data-mark="apacheparquet"] { -webkit-mask-image: url('images/engines/apacheparquet.svg'); mask-image: url('images/engines/apacheparquet.svg'); }
.fmt__mark[data-mark="json"] { -webkit-mask-image: url('images/engines/json.svg'); mask-image: url('images/engines/json.svg'); }

/* The other side of the same layer: the engines above feed it, these speak to it.
   Same glass panes as the databases, one size down. Marks are official SVGs
   (Simple Icons set) or the client PNGs already shipped, masked to theme ink. */
.ais {
  max-width: var(--max); margin: 46px auto 0; padding: 40px var(--pad) 0;
  border-top: 1px solid var(--hair);
  display: grid; gap: 36px; justify-items: center;
}
.ais__row { display: grid; gap: 14px; justify-items: center; width: 100%; }
.ais__row .eyebrow { font-size: 13px; }
.ais__row .tiny { text-align: center; }
.engines--sm .engine {
  flex-basis: calc((100% - 7 * 8px) / 8);
  min-height: 96px; padding: 12px 8px; gap: 8px; border-radius: 12px;
}
.engines--sm .engine__mark { height: 38px; -webkit-mask-size: auto 27px; mask-size: auto 27px; }
.engines--sm .engine__glow { top: 14px; height: 52px; -webkit-mask-size: auto 44px; mask-size: auto 44px; }
.engines--sm .engine__name { font-size: 12px; }
.engine [data-mark="ai-claude"] { -webkit-mask-image: url('images/ai/claude.svg'); mask-image: url('images/ai/claude.svg'); }
.engine [data-mark="ai-cursor"] { -webkit-mask-image: url('images/ai/cursor.svg'); mask-image: url('images/ai/cursor.svg'); }
.engine [data-mark="ai-vscode"] { -webkit-mask-image: url('images/clients/vscode.png'); mask-image: url('images/clients/vscode.png'); }
.engine [data-mark="ai-codex"] { -webkit-mask-image: url('images/clients/codex.png'); mask-image: url('images/clients/codex.png'); }
.engine [data-mark="ai-windsurf"] { -webkit-mask-image: url('images/ai/windsurf.svg'); mask-image: url('images/ai/windsurf.svg'); }
.engine [data-mark="ai-cline"] { -webkit-mask-image: url('images/ai/cline.svg'); mask-image: url('images/ai/cline.svg'); }
.engine [data-mark="ai-gemini"] { -webkit-mask-image: url('images/ai/gemini.svg'); mask-image: url('images/ai/gemini.svg'); }
.engine [data-mark="ai-openai"] { -webkit-mask-image: url('images/clients/openai.png'); mask-image: url('images/clients/openai.png'); }
.engine [data-mark="ai-deepseek"] { -webkit-mask-image: url('images/ai/deepseek.svg'); mask-image: url('images/ai/deepseek.svg'); }
.engine [data-mark="ai-qwen"] { -webkit-mask-image: url('images/ai/qwen.svg'); mask-image: url('images/ai/qwen.svg'); }
.engine [data-mark="ai-kimi"] { -webkit-mask-image: url('images/ai/kimi.svg'); mask-image: url('images/ai/kimi.svg'); }
.engine [data-mark="ai-minimax"] { -webkit-mask-image: url('images/ai/minimax.svg'); mask-image: url('images/ai/minimax.svg'); }
.engine [data-mark="ai-mimo"] { -webkit-mask-image: url('images/ai/mimo.svg'); mask-image: url('images/ai/mimo.svg'); }
@media (max-width: 900px) { .engines--sm .engine { flex-basis: calc((100% - 5 * 8px) / 6); } }
@media (max-width: 620px) { .engines--sm .engine { flex-basis: calc((100% - 3 * 8px) / 4); } }
@media (max-width: 420px) { .engines--sm .engine { flex-basis: calc((100% - 2 * 8px) / 3); } }
@media (max-width: 620px) { .ais { margin-top: 34px; padding-top: 30px; gap: 30px; } }
[data-theme="dark"] .engine {
  background: rgba(255,255,255,0.09);
  -webkit-backdrop-filter: blur(9px) saturate(0.1) brightness(0.6);
  backdrop-filter: blur(9px) saturate(0.1) brightness(0.6);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.2),
    inset 0 0 0 1px rgba(255,255,255,0.08),
    1px 2px 4px -2px rgba(0,0,0,0.07);
}
[data-theme="dark"] .engine:hover {
  background: rgba(255,255,255,0.045);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.1),
    inset 0 0 0 1px color-mix(in oklab, var(--accent-ink) 38%, transparent),
    1px 3px 6px -3px rgba(0,0,0,0.035);
}
@media (max-width: 900px) { .engine { flex-basis: calc((100% - 3 * 8px) / 4); } }
@media (max-width: 620px) { .engine { flex-basis: calc((100% - 2 * 8px) / 3); } }
@media (max-width: 420px) { .engine { flex-basis: calc((100% - 8px) / 2); } }.dot { width: 8px; height: 8px; border-radius: 999px; background: var(--accent-ink); flex: none; }

.tag {
  display: inline-flex; align-items: center; align-self: flex-start;
  font-size: 12px; font-weight: 600; letter-spacing: 0.02em; text-transform: uppercase;
  padding: 5px 10px; border-radius: 6px;
  background: var(--accent-wash); color: var(--accent-ink);
}
/* derived, not named — a literal here goes stale the moment the accent changes */
[data-theme="dark"] .tag { background: color-mix(in oklab, var(--accent-ink) 16%, transparent); }
.tag--soon { background: var(--tint); color: var(--text-2); }

/* ── feature rows ───────────────────────────────────────────────────── */

.feature {
  display: grid; gap: clamp(24px, 4vw, 56px); align-items: center;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  padding-block: clamp(40px, 4.4vw, 64px);
  border-top: 1px solid var(--hair);
}
.feature__body { display: flex; flex-direction: column; gap: 14px; }
.feature--flip .feature__art { order: -1; }
@media (max-width: 860px) {
  .feature { grid-template-columns: minmax(0, 1fr); }
  .feature--flip .feature__art { order: 0; }
}

.spec-list { display: flex; flex-direction: column; gap: 0; margin: 0; padding: 0; list-style: none; }
.spec-list li {
  display: flex; align-items: flex-start; gap: 12px;
  padding-block: 13px; border-bottom: 1px solid var(--hair-soft);
  font-size: 16px; line-height: 1.45; letter-spacing: -0.01em; color: var(--text-2);
}
.spec-list li:last-child { border-bottom: 0; }
.spec-list .check { flex: none; margin-top: 2px; color: var(--accent-ink); }

/* ── closing: the two doors ──────────────────────────────────────
   The headline claims two audiences; everything above it on the page is written for the human
   one. These two panels are the machine half made concrete — deliberately the same weight and
   size as each other, since the whole point is that neither is bolted on. */

.doors { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.door {
  position: relative; overflow: hidden; isolation: isolate;
  display: flex; flex-direction: column; gap: 8px;
  padding: 24px 26px 0; border-radius: 16px;
  background: var(--tint); box-shadow: inset 0 0 0 1px var(--hair-soft);
}
.door__who {
  font-size: 12px; font-weight: 600; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--accent-ink);
}
.door__lines { display: flex; flex-direction: column; gap: 13px; margin-top: 8px; }
.door__lines p { font-size: 16px; line-height: 1.5; letter-spacing: -0.01em; color: var(--text-2); }
/* The foot of each panel is a real frame of the product, cropped and bled off the bottom and
   right edges so it reads as the thing continuing past the card rather than a picture placed
   inside one. Drawn art was tried here and refused: everything else on this page that carries
   an image carries a real one, and an invented glyph at 11% opacity sits in a weaker class.
   margin-top:auto pins the slab to the foot so the two panels line up on unequal copy. */
.door__shot {
  position: relative; margin: 26px -26px 0 0; margin-top: auto; height: 156px;
  border-top-left-radius: 10px; overflow: hidden;
  box-shadow: inset 1px 1px 0 0 var(--hair-soft), -14px -14px 34px -20px rgba(0,0,0,0.28);
  background-repeat: no-repeat; background-color: #0d0f11;
}
.door__shot--studio {
  background-image: url('images/shots/agent-studio.png');
  background-size: 1065px auto; background-position: -247px -24px;
}
/* sized to the slab's own width so the map keeps its composition at any panel width */
.door__shot--map {
  background-image: url('images/shots/access-map-canvas.png');
  background-size: 100% auto; background-position: 0 0;
}
/* the frames run counter to the page: a dark slab under light copy, a light one under dark.
   Same-polarity screenshots disappear into the panel and stop reading as a separate object. */
[data-theme="dark"] .door__shot { background-color: #f7f7f8; }
[data-theme="dark"] .door__shot--studio {
  background-image: url('images/shots/agent-studio-light.png');
  background-size: 100% auto; background-position: 0 0;
}
[data-theme="dark"] .door__shot--map {
  background-image: url('images/shots/access-map-canvas-light.png');
}

.beats { margin-top: 30px; }
/* This line stopped being a label when the copy became the section's argument — uppercase at
   sentence length slows reading, and at 12px it ranked below the footnote explaining it. It now
   takes the same weight as the door headlines, which is the role it actually plays.
   The break is explicit, one sentence per line: left to a max-width the second sentence split
   mid-clause and orphaned "hour anyway." Both sentences are ~24ch, so neither wraps again. */
.beats__lead {
  font-size: 18px; font-weight: 600; letter-spacing: -0.018em; line-height: 1.35;
  color: var(--text); margin-bottom: 16px;
}
.beats__row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px 26px; }
/* hairline-topped, not boxed: three more panels directly under the doors would read as six
   equal things rather than a sequence inside one */
.beat { display: flex; flex-direction: column; gap: 7px; border-top: 1px solid var(--hair); padding-top: 14px; }
/* the honest footnote: there is no hour of labour to describe, so the section says what the
   hour is actually for rather than padding the build into one */
.beats__note { margin-top: 18px; max-width: 74ch; font-size: 16px; line-height: 1.55; letter-spacing: -0.01em; color: var(--text-2); }
.beat__t {
  font-family: var(--mono); font-size: 13px; font-weight: 600;
  color: var(--accent-ink); font-variant-numeric: tabular-nums;
}
@media (max-width: 760px) {
  .doors { grid-template-columns: minmax(0, 1fr); }
  .door__shot { height: 132px; }
  .beats__row { grid-template-columns: minmax(0, 1fr); gap: 0; }
}

/* ── product switcher (pricing) ─────────────────────────────────────── */

/* The same tab treatment as the product sub-nav — hairline row, accent underline on the active
   one — so the four product names look identical wherever they appear on the site. */
.switch__tabs {
  display: flex; gap: 26px; margin-bottom: 24px;
  border-bottom: 1px solid var(--hair-soft);
  overflow-x: auto; scrollbar-width: none;
}
.switch__tabs::-webkit-scrollbar { display: none; }
.switch__tab {
  flex: 0 0 auto; white-space: nowrap;
  font-family: inherit; font-size: 15px; font-weight: 500; letter-spacing: -0.01em;
  padding: 0 0 13px; margin-bottom: -1px; cursor: pointer;
  border: 0; border-bottom: 2px solid transparent;
  background: transparent; color: var(--text-2);
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease);
}
.switch__tab:hover { color: var(--text); }
.switch__tab[aria-selected="true"] { color: var(--text); border-bottom-color: var(--accent-ink); }
/* no measure cap: each product's line is written to sit on one line at full width, and a
   wrapped second line makes the tab row look like it changed height when you switch */
.switch__line { font-size: 16px; letter-spacing: -0.01em; color: var(--text-2); margin-bottom: 22px; }
.switch__note { font-size: 14px; letter-spacing: -0.008em; color: var(--text-2); max-width: 78ch; margin-top: 18px; }
@media (prefers-reduced-motion: reduce) { .switch__tab { transition: none; } }

/* ── changelog ──────────────────────────────────────────────────────── */

.log { display: flex; flex-direction: column; }
/* Date rail on the left, content on the right. The hairline runs along the top of each entry
   rather than between them so the first entry is separated from the heading too. */
.entry {
  display: grid; grid-template-columns: 170px minmax(0, 1fr); gap: 10px 32px;
  padding: 28px 0; border-top: 1px solid var(--hair);
}
.entry__meta { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.entry__date {
  font-family: var(--mono); font-size: 14px; font-weight: 500;
  color: var(--text-2); font-variant-numeric: tabular-nums;
}
.entry__body { display: flex; flex-direction: column; gap: 12px; }
@media (max-width: 700px) {
  .entry { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .entry__meta { flex-direction: row; align-items: center; gap: 12px; }
}

/* ── pricing ────────────────────────────────────────────────────────── */

.tiers { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(272px, 1fr)); align-items: start; }
.tier {
  display: flex; flex-direction: column; gap: 16px;
  padding: 28px; border-radius: 20px;
  background: var(--surface); box-shadow: var(--shadow-sm);
}
.tier--feature { box-shadow: var(--shadow-md); }
/* ── pricing matrix ──────────────────────────────────────────────────
   Values in cells rather than four lists in four boxes: the only shape where storage, or runs,
   or uptime can be read straight across all four tiers. Fixed layout so the four tier columns
   stay identical in width whatever lands in them — only the row-label column is sized. */
.mx-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.mx { width: 100%; min-width: 900px; border-collapse: separate; border-spacing: 0; table-layout: fixed; }
.mx col:first-child { width: 200px; }
.mx thead th:nth-child(3), .mx tbody td:nth-child(3), .mx tfoot td:nth-child(3) { background: var(--accent-wash); }
.mx thead th:nth-child(3) { border-radius: 10px 10px 0 0; }
.mx tfoot td:nth-child(3) { border-radius: 0 0 10px 10px; }
.mx th, .mx td {
  padding: 15px 18px; text-align: left; vertical-align: top;
  border-bottom: 1px solid var(--hair-soft);
  font-size: 15px; letter-spacing: -0.01em; text-wrap: pretty;
}
.mx thead td, .mx thead th { border-bottom: 1px solid var(--hair); vertical-align: bottom; padding-top: 0; }
.mx tbody th { font-weight: 500; color: var(--text-2); }
/* The three dial groups are the message: a reader should see in one pass which numbers can cost
   them money and which cannot. */
.mx tbody tr.mx__grp th {
  padding: 26px 18px 8px; border-bottom: 1px solid var(--hair);
  font-size: 12px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text);
}
.mx tbody tr:first-child.mx__grp th { padding-top: 16px; }
.mx tbody tr.mx__grp th sup {
  margin-left: 4px; font-size: 10px; font-weight: 600; color: var(--text-3); vertical-align: super;
}
/* The group definitions sit under the estimator rather than above the rows: the table stays
   scannable, and the explanation is there when a number prompts the question. */
.mx__fn {
  list-style: none; counter-reset: fn; margin: 22px 0 0; padding: 0;
  display: flex; flex-direction: column; gap: 9px; max-width: 92ch;
}
.mx__fn li {
  counter-increment: fn; position: relative; padding-left: 22px;
  font-size: 13.5px; line-height: 1.5; color: var(--text-2); text-wrap: pretty;
}
.mx__fn li::before {
  content: counter(fn); position: absolute; left: 0; top: 1px;
  font-size: 10px; font-weight: 600; color: var(--text-3);
}
.mx__fn b { font-weight: 600; color: var(--text); }
.mx tbody th span { display: block; margin-top: 2px; font-size: 13px; color: var(--text-3); }
.mx tbody td { font-variant-numeric: tabular-nums; }
.mx__n { display: block; font-size: 13px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-2); }
.mx__p { font-size: 28px; font-weight: 600; letter-spacing: -0.03em; line-height: 1.05; margin-top: 10px; }
.mx__p span { font-size: 14px; font-weight: 500; letter-spacing: -0.01em; color: var(--text-2); }
.mx__b {
  display: block; width: fit-content; max-width: 100%; margin: 0 auto 12px; text-align: center;
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase;
  padding: 4px 8px; border-radius: 6px; background: var(--accent); color: var(--accent-btn-text);
}
.mx tfoot td { border-bottom: 0; padding-top: 20px; }
.mx tfoot .btn { width: 100%; }
.tier--feature[data-badge]::before {
  content: attr(data-badge); align-self: flex-start;
  font-size: 12px; font-weight: 600; letter-spacing: 0.02em; text-transform: uppercase;
  padding: 5px 10px; border-radius: 6px; background: var(--accent); color: var(--accent-btn-text);
}
.tier__price { font-size: 30px; font-weight: 600; letter-spacing: -0.028em; }
.tier__meta { font-size: 15px; letter-spacing: -0.008em; color: var(--text-2); }
.tier .btn { width: 100%; }

.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.cmp { width: 100%; border-collapse: collapse; min-width: 620px; }
table.cmp th, table.cmp td {
  text-align: left; padding: 15px 18px;
  border-bottom: 1px solid var(--hair-soft);
  font-size: 16px; letter-spacing: -0.01em;
}
table.cmp thead th { font-size: 14px; font-weight: 600; color: var(--text-2); }
table.cmp td:not(:first-child), table.cmp th:not(:first-child) { text-align: center; }
table.cmp tbody th { font-weight: 500; color: var(--text); }
table.cmp .yes { color: var(--accent-ink); font-weight: 600; }
table.cmp .no { color: var(--text-3); }

/* ── answers ─────────────────────────────────────────────────────────
   Not an accordion. Every other section on this page shows its content outright, so a
   click-to-reveal list broke the page's contract at the last scroll. Cards instead, and
   the ANSWER is the headline — the question drops to an eyebrow, where it still carries
   the phrase someone would have searched for. */

.answers { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.answer {
  display: flex; flex-direction: column; gap: 7px;
  padding: 22px 24px 24px; border-radius: 16px;
  background: var(--tint); box-shadow: inset 0 0 0 1px var(--hair-soft);
}
/* the strongest claim closes the section on its own line */
/* Only span a genuinely dangling card. With an even count the last card has a partner, and
   spanning it leaves an empty cell in the final row. */
/* A spanning card is twice as wide as its siblings, so a single measure-capped column would
   leave two thirds of it empty. Label and headline take the left column, the body the right. */
.answer:last-child:nth-child(odd) {
  grid-column: 1 / -1;
  display: grid; grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr);
  grid-template-rows: max-content 1fr;
  column-gap: 40px; row-gap: 7px; align-content: start;
}
.answer:last-child:nth-child(odd) > .answer__q,
.answer:last-child:nth-child(odd) > .h4 { grid-column: 1; }
.answer:last-child:nth-child(odd) > .small { grid-column: 2; grid-row: 1 / span 2; max-width: 56ch; }
@media (max-width: 760px) {
  .answer:last-child:nth-child(odd) { grid-template-columns: minmax(0, 1fr); }
  .answer:last-child:nth-child(odd) > .small { grid-column: 1; grid-row: auto; }
}
/* --text-3 lands at 3.33:1 on --tint at this size — and this is the one line here that must
   stay readable, since it carries the phrase someone searched for. Contrast is the dimension
   that can't be traded, so the quietness comes from size and tracking instead: --text-2 at
   12px uppercase reads as a label rather than competing with the answer above it. */
.answer__q {
  font-size: 12px; font-weight: 600; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--text-2);
}
.answer .small { max-width: 64ch; }
/* MCP clients. The spanning card carries the question and caveat on the left and the eight
   marks on the right, so the answer is read as a set of things rather than a sentence. */
.answer--clients {
  grid-column: 1 / -1;
  display: grid; grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr);
  column-gap: 44px; row-gap: 7px; align-content: start; align-items: start;
}
.answer--clients > .answer__q, .answer--clients > .body { grid-column: 1; max-width: 42ch; }
.answer--clients > .clients { grid-column: 2; grid-row: 1 / span 2; }
.clients { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px 10px; }
.client { display: flex; flex-direction: column; align-items: center; gap: 9px; }
/* the two app icons that ship on their own coloured field keep it; the box only bounds the mark */
.client__mark {
  width: 36px; height: 36px; border-radius: 9px; overflow: hidden;
  display: grid; place-items: center;
}
/* max-* rather than width/height: the tile is a centred grid area with no definite height, so a
   percentage height on the img resolves to auto and a portrait mark overflows its own tile */
.client__mark img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }
.client__name { font-size: 12px; font-weight: 500; letter-spacing: -0.008em; color: var(--text-2); text-align: center; }
/* two marks are black line art with no light variant, so they invert in dark mode */
[data-theme="dark"] .client__mark img[data-ink="dark"] { filter: invert(1); }
@media (max-width: 760px) {
  .answer--clients { grid-template-columns: minmax(0, 1fr); }
  .answer--clients > .clients { grid-column: 1; grid-row: auto; margin-top: 8px; }
}
@media (max-width: 760px) { .answers { grid-template-columns: minmax(0, 1fr); } }

/* ── forms ──────────────────────────────────────────────────────────── */

.form { display: grid; gap: 16px; }
.field { display: flex; flex-direction: column; gap: 7px; }
.field label { font-size: 15px; font-weight: 500; letter-spacing: -0.01em; color: var(--text); }
.field input, .field select, .field textarea {
  font-family: var(--sans); font-size: 16px; letter-spacing: -0.01em;
  color: var(--text); background: var(--surface);
  border: 1px solid var(--hair); border-radius: 12px;
  padding: 13px 15px; min-height: 48px; width: 100%;
  transition: border-color 0.18s var(--ease), box-shadow 0.18s var(--ease);
}
.field textarea { min-height: 128px; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--accent-ink);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 40%, transparent);
}
.field--row { display: grid; gap: 16px; grid-template-columns: 1fr 1fr; }
@media (max-width: 640px) { .field--row { grid-template-columns: 1fr; } }

/* ── footer ─────────────────────────────────────────────────────────── */

/* No breather above the footer: it is invisible when the last section is untinted,
   and shows as a white strip under any tinted band or dark plate. */
.foot { border-top: 1px solid var(--hair); }
.foot__cols {
  display: grid; gap: 32px;
  grid-template-columns: minmax(220px, 1.4fr) repeat(auto-fit, minmax(140px, 1fr));
  padding-block: clamp(38px, 4vw, 54px);
}
/* The 220px+140px min tracks overflow a phone: stack to a 2-up with the brand full-width. */
@media (max-width: 760px) {
  .foot__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 20px; }
  .foot__cols > .foot__col:first-child { grid-column: 1 / -1; }
}
.foot__col { display: flex; flex-direction: column; gap: 11px; }
.foot__col h4 { font-size: 14px; font-weight: 600; letter-spacing: -0.006em; color: var(--text); margin-bottom: 2px; }
.foot__col a { font-size: 15px; letter-spacing: -0.008em; color: var(--text-2); }
.foot__col a:hover { color: var(--text); opacity: 1; }
.foot__base {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px;
  padding-block: 20px; border-top: 1px solid var(--hair-soft);
}

/* ── cookie banner ──────────────────────────────────────────────────── */

.cookie {
  position: fixed; z-index: 60; left: 16px; right: 16px; bottom: 16px;
  max-width: 560px; margin-inline: auto;
  display: none; gap: 16px; align-items: center; flex-wrap: wrap;
  padding: 18px 20px; border-radius: 18px;
  background: var(--surface); box-shadow: var(--shadow-lg);
  transform: translateY(12px); opacity: 0;
  transition: transform 0.4s var(--ease), opacity 0.4s var(--ease);
}
.cookie[data-show="true"] { display: flex; transform: translateY(0); opacity: 1; }
.cookie p { flex: 1 1 260px; }
.cookie .cta-row { flex: none; }

/* ── reveal on scroll ───────────────────────────────────────────────── */

.reveal { opacity: 0; transform: translateY(14px); }
.reveal[data-seen="true"] {
  opacity: 1; transform: none;
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; }
}

@media (max-width: 640px) {
  :root { --pad: 22px; }
}

/* ── accent picker — evaluation only, shown by appending ?picker to the URL ── */

.picker {
  position: fixed; z-index: 70; right: 16px; bottom: 16px; left: auto;
  /* width is bounded, never stretched: `left` + `right` together would override it,
     and aspect-ratio swatches then inflate the panel past the viewport */
  width: min(300px, calc(100vw - 32px));
  max-height: calc(100vh - 32px); overflow-y: auto;
  display: none; flex-direction: column; gap: 13px;
  padding: 16px; border-radius: 18px;
  background: var(--surface); box-shadow: var(--shadow-lg);
}
.picker[data-open="true"] { display: flex; }
.picker__head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.picker__label {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--text-3);
}
.picker__grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 7px; }
.picker__sw {
  aspect-ratio: 1; max-width: 52px;
  border: 0; border-radius: 10px; cursor: pointer; padding: 0;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.16);
}
.picker__sw[aria-pressed="true"] { box-shadow: inset 0 0 0 1px rgba(0,0,0,0.16), 0 0 0 2px var(--text); }
.picker__read { display: flex; flex-direction: column; gap: 4px; }
.picker__mono { font-family: var(--mono); font-size: 12px; color: var(--text-2); }
.picker__name { font-size: 14px; font-weight: 600; letter-spacing: -0.01em; color: var(--text); }
/* the panel is fixed, so the page it sits on reserves room for it — otherwise it
   covers exactly the cards it exists to let you judge */
@media (min-width: 640px) {
  body[data-picker="on"] main { padding-right: 332px; }
}
@media (max-width: 639px) {
  body[data-picker="on"] main { padding-bottom: 420px; }
}


/* ── worked example ─────────────────────────────────────────────────
   The screenshot is light in both appearances on purpose. A light frame under
   dark copy (and vice versa) keeps it reading as a captured object rather than
   dissolving into the page — same reasoning as the door slabs above. */

.shot { margin: 0; }
.shot__frame {
  border-radius: 16px; overflow: hidden; background: #ffffff;
  border: 1px solid var(--hair); box-shadow: var(--shadow-md);
}
.shot__frame img { display: block; width: 100%; height: auto; }
.shot__cap { margin-top: 13px; max-width: 72ch; font-size: 14px; line-height: 1.5; color: var(--text-2); }
.shot__cap code { font-family: var(--mono); font-size: 0.92em; color: var(--text); }
/* Counter-polarity, same reasoning as the door slabs: a screenshot in the page's own
   polarity dissolves into it. Both captures carry the same alt — each is the only
   visible image in its theme, and display:none drops the other out of the a11y tree. */
.shot--swap .shot__on-dark { display: none; }
[data-theme="dark"] .shot--swap .shot__frame { background: #ffffff; }
[data-theme="dark"] .shot--swap .shot__on-light { display: none; }
[data-theme="dark"] .shot--swap .shot__on-dark { display: block; }

/* the endpoint is the proof, so it is set as an address rather than prose —
   wrapping anywhere is correct here, a truncated URL proves nothing */
.trace {
  margin-top: 26px; max-width: 880px;
  padding: clamp(20px, 2.2vw, 28px) clamp(20px, 2.4vw, 30px);
  border-radius: 16px; background: var(--tint); border: 1px solid var(--hair-soft);
}
.trace__url {
  font-family: var(--mono); font-size: 12.5px; line-height: 1.7; color: var(--text-2);
  overflow-wrap: anywhere; margin-bottom: 14px; padding-bottom: 14px;
  border-bottom: 1px solid var(--hair-soft);
}
.trace__verb {
  display: inline-block; margin-right: 10px; padding: 2px 7px; border-radius: 5px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em;
  color: var(--accent-ink); background: var(--accent-wash);
}
.trace code {
  font-family: var(--mono); font-size: 0.9em; padding: 1px 5px; border-radius: 4px;
  color: var(--accent-ink); background: var(--accent-wash);
}

/* ── the concession ─────────────────────────────────────────────────
   Hairline above, no panel: this is an aside to the five steps, not a sixth one. */
/* ── the hero chain ───────────────────────────────────────────────────
   The sentence is a chain — schema to endpoints to MCP to identity to agents —
   so it is set as one: four floors of near-equal width stacked into a column,
   instead of a paragraph breaking wherever the measure happens to run out. The
   clauses fold back into ordinary prose below the breakpoint, where a stack of
   five short lines would read as a list rather than a sentence. */
.tower { max-width: 64ch; }
.tower > span { display: block; line-height: 1.5; }
.tower__lead { margin-bottom: 9px; }
@media (max-width: 720px) {
  .tower { max-width: 42ch; }
  .tower > span { display: inline; line-height: inherit; }
  .tower__lead { margin-bottom: 0; }
}

.bound { margin-top: 30px; padding-top: 22px; border-top: 1px solid var(--hair); }
.bound.grid--2 { column-gap: 40px; }
.bound.grid--2 > .body:first-child { border-right: 1px solid var(--hair); padding-right: 40px; }
.bound .body { max-width: 78ch; color: var(--text-2); }
.bound strong { color: var(--text); font-weight: 600; }
@media (max-width: 760px) {
  .bound.grid--2 { grid-template-columns: 1fr; }
  .bound.grid--2 > .body:first-child { border-right: 0; padding-right: 0; padding-bottom: 20px; border-bottom: 1px solid var(--hair); }
}

/* every step names the page that owns it — home routes, it does not answer */
.step__to {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 12px;
  font-size: 13px; font-weight: 600; color: var(--accent-ink); text-decoration: none;
}
.step__to span { transition: transform 0.25s var(--ease); }
.step__to:hover span { transform: translateX(3px); }

/* ── the four outlets ───────────────────────────────────────────────
   One stage, not four rows. Four identical rows teach the eye their shape by
   row two and the rest gets skipped (NN/g's bypassing pattern), and the choice
   this section exists for — which outcome is mine? — needs all four options in
   one glance. So the chooser is the console's own tab row, each tab carrying
   its outcome line, and only the evidence beneath swaps. Panes stay in the
   HTML — hidden, not absent — so crawlers and assistants read all four; with
   JS off the first pane stays visible, same contract as the pricing switcher. */
.otabs {
  border: 1px solid var(--hair-soft); border-radius: 18px; background: var(--surface);
  box-shadow: var(--shadow-md); overflow: hidden;
}
.otabs__bar {
  display: flex; gap: clamp(2px, 1.8vw, 24px); padding: 0 clamp(14px, 2.6vw, 28px);
  border-bottom: 1px solid var(--hair-soft);
  overflow-x: auto; scrollbar-width: none;
}
.otabs__bar::-webkit-scrollbar { display: none; }
.otab {
  appearance: none; background: none; border: 0; border-bottom: 2px solid transparent;
  font-family: inherit; cursor: pointer; text-align: left; white-space: nowrap;
  display: flex; flex-direction: column; gap: 3px; align-items: flex-start;
  padding: 15px 10px 13px; color: var(--text-2);
}
.otab__name { font-size: 15px; font-weight: 600; letter-spacing: -0.012em; line-height: 1.2; }
.otab__want { font-size: 12.5px; line-height: 1.2; color: var(--text-3); }
.otab:hover { color: var(--text); }
.otab[aria-selected="true"] { color: var(--text); border-bottom-color: var(--text); }
.otab[aria-selected="true"] .otab__want { color: var(--text-2); }
.opane {
  display: grid; grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(24px, 4vw, 54px); align-items: center;
  padding: clamp(20px, 3vw, 36px);
}
.opane[hidden] { display: none; }
@keyframes opane-in { from { opacity: 0; transform: translateY(7px); } }
.opane[data-in] { animation: opane-in 0.4s var(--ease); }
.opane__txt { display: flex; flex-direction: column; gap: 8px; }
.opane__want {
  margin: 0; font-size: clamp(20px, 2.1vw, 25px); font-weight: 600;
  letter-spacing: -0.022em; line-height: 1.25; color: var(--text); max-width: 22ch;
}
.opane__txt .small { color: var(--text-2); max-width: 46ch; }
.opane__caps { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; }
.opane__caps li {
  padding-block: 8px; border-top: 1px solid var(--hair-soft);
  font-size: 14px; line-height: 1.4; letter-spacing: -0.008em; color: var(--text-2);
}
.opane__go { font-size: 15px; font-weight: 600; color: var(--accent-ink); text-decoration: none; margin-top: 8px; }
.opane__go:hover { text-decoration: underline; }
.opane__frame { aspect-ratio: 16 / 9.9; }
.opane__frame img { width: 100%; height: 100%; object-fit: cover; object-position: top left; }

/* ── proof ──────────────────────────────────────────────────────────
   Hairline-topped columns, not tiles: four boxed numbers read as a feature grid,
   and these are one app's readings rather than four claims. */
.stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px 26px; }
.stat { border-top: 1px solid var(--hair); padding-top: 15px; }
.stat__n {
  display: block; font-size: clamp(30px, 3vw, 36px); font-weight: 600;
  letter-spacing: -0.032em; line-height: 1.05; color: var(--text);
}
.stat__l { display: block; margin-top: 6px; font-size: 13.5px; line-height: 1.4; color: var(--text-2); }
.stats__note { margin-top: 22px; max-width: 78ch; font-size: 15px; line-height: 1.55; color: var(--text-2); }

/* ── the ask ────────────────────────────────────────────────────────
   The obligations sit beside the offer, not under it: a dated, bounded, priced ask
   has to show its terms in the same glance as its promise. */
.ask { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: clamp(28px, 4vw, 56px); align-items: start; }
.terms { list-style: none; margin: 0; padding: 0; }
.terms li {
  padding: 14px 0; border-top: 1px solid var(--hair);
  font-size: 16px; line-height: 1.45; color: var(--text);
}

@media (max-width: 980px) {
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .opane { grid-template-columns: minmax(0, 1fr); }
  .otab { padding: 12px 8px 10px; }
  .ask { grid-template-columns: minmax(0, 1fr); }
}


/* ── the example, run live ───────────────────────────────────────────
   The result table is deliberately plain: it is evidence, and chrome around a
   payload starts to look like a rendering of a payload. */
.trace__act { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 4px; }
/* the Begin repeat of the runner: same instrument, centered lane */
.trace--center { width: 100%; max-width: 680px; margin: 22px auto 0; text-align: left; }
.trace--center [data-live-teaser] { margin-bottom: 14px; }
.trace--center .live { margin-bottom: 0; }
/* hero aisle directory — the four wants, easiest first, as anchors into #start */
.aisles {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: baseline;
  gap: 8px 18px; margin-top: 14px;
}
.aisles__k { font-size: 12px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-3); }
.aisles a {
  font-size: 14.5px; letter-spacing: -0.008em; color: var(--text-2);
  border-bottom: 1px solid var(--hair); padding-bottom: 2px;
}
.aisles a:hover { color: var(--accent-ink); border-bottom-color: currentColor; opacity: 1; }
.trace__stat { font-family: var(--mono); font-size: 12px; color: var(--text-3); }
.live { margin-top: 16px; margin-bottom: 22px; overflow-x: auto; }
.live__t { width: 100%; border-collapse: collapse; font-family: var(--mono); font-size: 12px; }
.live__t th, .live__t td { padding: 7px 14px 7px 0; text-align: left; white-space: nowrap; }
.live__t th {
  font-weight: 600; letter-spacing: 0.02em; color: var(--text-3);
  border-bottom: 1px solid var(--hair);
}
.live__t td { color: var(--text-2); border-bottom: 1px solid var(--hair-soft); }
.live__note { margin-top: 12px; font-size: 13px; line-height: 1.5; color: var(--text-3); }

/* ── capability cards ───────────────────────────────────────────────
   The title carries the hook, the line under it carries the fact. Three across
   so a dozen of them read as an inventory rather than a dozen separate claims. */
/* Fixed tracks, not auto-fit — auto-fit orphans the tail of any count that isn't a
   multiple of three (the same failure .grid--2up exists to avoid). A dangling last
   card instead spans the columns left in its row, so every row closes. */
.caps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.caps--2up { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.caps:not(.caps--2up) .cap:last-child:nth-child(3n + 1) { grid-column: span 3; }
.caps:not(.caps--2up) .cap:last-child:nth-child(3n + 2) { grid-column: span 2; }
@media (max-width: 1000px) {
  .caps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .caps:not(.caps--2up) .cap:last-child:nth-child(3n + 1),
  .caps:not(.caps--2up) .cap:last-child:nth-child(3n + 2) { grid-column: auto; }
  .caps:not(.caps--2up) .cap:last-child:nth-child(odd) { grid-column: span 2; }
}
@media (max-width: 660px) {
  .caps, .caps--2up { grid-template-columns: minmax(0, 1fr); }
  .caps:not(.caps--2up) .cap:last-child:nth-child(odd) { grid-column: auto; }
}
.cap {
  display: flex; flex-direction: column; gap: 6px;
  padding: 20px 22px 22px; border-radius: 14px;
  background: var(--tint); box-shadow: inset 0 0 0 1px var(--hair-soft);
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.cap:hover { transform: translateY(-2px); box-shadow: inset 0 0 0 1px var(--accent); }

/* A card reads against its ground, not against the token it happens to share with it.
   --surface and --tint sit one step apart in both themes, so a card on a tinted band
   swaps to surface and the pair never collapses into a single flat colour. */
.band--tint .cap,
.band--tint .answer,
.band--tint .door,
.band--tint .card { background: var(--surface); }
.cap__t { font-size: 16.5px; font-weight: 600; letter-spacing: -0.018em; line-height: 1.3; color: var(--text); }
.cap .small { color: var(--text-2); }

/* Hairline-separated lines inside an outlet card: three facts that make the card
   worth clicking, without turning into a second paragraph. */
.outlet__caps { list-style: none; margin: 9px 0 0; padding: 0; display: flex; flex-direction: column; }
.outlet__caps li {
  padding-block: 9px; border-top: 1px solid var(--hair-soft);
  font-size: 14px; line-height: 1.4; letter-spacing: -0.008em; color: var(--text-2);
}

/* Anchor targets and the skip link land under sticky chrome unless the scroll
   port is padded by its height: 57px for the nav, 103px where the sub-nav sits
   below it, plus a little air so the heading is not flush against the bar. */
html { scroll-padding-top: 68px; }
html:has(.subnav) { scroll-padding-top: 114px; }

/* ── product sub-nav ────────────────────────────────────────────────
   The four products are siblings, so they carry a strip that persists across all
   four rather than a directory page that lists them once and is never returned to.
   Sticks directly under the header at its exact height; the active page is the
   only one at full text colour, with the accent rule under it. */
.subnav {
  position: sticky; top: 56px; z-index: 39;
  background: var(--nav-bg);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--hair-soft);
}
.subnav__in {
  max-width: var(--max); margin: 0 auto; padding-inline: var(--pad);
  height: 46px; display: flex; align-items: stretch; justify-content: space-between; gap: 16px;
}
/* the tab row scrolls rather than wraps — a wrapped second row would change the
   strip's height and shift every sticky offset under it */
.subnav__tabs {
  display: flex; align-items: stretch; gap: 26px;
  min-width: 0; overflow-x: auto; scrollbar-width: none;
}
.subnav__tabs::-webkit-scrollbar { display: none; }
.subnav__tabs a {
  display: flex; align-items: center; white-space: nowrap;
  font-size: 14px; font-weight: 500; letter-spacing: -0.01em; color: var(--text-2);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease);
}
.subnav__tabs a:hover { color: var(--text); opacity: 1; }
.subnav__tabs a.is-on { color: var(--text); border-bottom-color: var(--accent-ink); }
.subnav__cta {
  display: flex; align-items: center; white-space: nowrap;
  font-size: 14px; font-weight: 500; letter-spacing: -0.01em; color: var(--accent-ink);
}
.subnav__cta:hover { opacity: 0.75; }
@media (max-width: 700px) {
  .subnav__in { height: 44px; gap: 12px; }
  .subnav__cta { display: none; }
  .subnav__tabs { gap: 20px; }
}
@media (prefers-reduced-motion: reduce) { .subnav__tabs a { transition: none; } }

/* ── named product surfaces ─────────────────────────────────────────
   Hairline-topped columns rather than filled cards: these sit next to the .caps
   inventory and would read as one long grid if they shared its treatment. The
   qualifier is the label the product itself puts beside the name in its sidebar. */
.surface { display: flex; flex-direction: column; gap: 8px; border-top: 1px solid var(--hair); padding-top: 16px; }
.surface__n {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 9px;
  font-size: 17px; font-weight: 600; letter-spacing: -0.018em; color: var(--text);
}
.surface__n span {
  font-family: var(--mono); font-size: 11px; font-weight: 500;
  letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-3);
}
.surface .small { color: var(--text-2); }

/* ── flow line and review cards ─────────────────────────────────────
   What survives of the deleted mega menu: the flow line still runs under every
   product page's closing CTA, and the card/grid/item trio is what accent-review
   uses to show the accent at its smallest sizes. */
.mega__flow {
  font-family: var(--mono); font-size: 11px; font-weight: 500;
  letter-spacing: 0.06em; color: var(--accent-ink);
}
.mega__card {
  background: var(--surface); border-radius: 16px; padding: 20px;
  box-shadow: var(--shadow-md);
}
.mega__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 12px; }
.mega__item {
  display: flex; flex-direction: column; gap: 6px;
  padding: 15px 16px 17px; border-radius: 12px; background: var(--tint);
}

/* ── worked-example reel ────────────────────────────────────────────
   Four screenshots stacked in one grid cell rather than four screens of scroll.
   The cell takes the height of the tallest panel, so advancing never shifts the
   page. The progress bar IS the timer: the tab's animation drives the advance
   (animationend), so pausing the animation pauses the sequence exactly. */
.reel { display: flex; flex-direction: column; gap: 22px; }
.reel__tabs { display: grid; grid-template-columns: repeat(var(--reel-n, 4), minmax(0, 1fr)); gap: 10px; }
.reel__tab {
  display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  padding: 0 0 11px; background: none; border: 0; cursor: pointer; text-align: left;
  color: var(--text-2); transition: color 0.25s var(--ease);
}
.reel__tab:hover { color: var(--text); }
.reel__tab[aria-selected="true"] { color: var(--text); }
.reel__n { font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; color: var(--text-2); }
.reel__l { font-size: 15px; font-weight: 600; letter-spacing: -0.015em; color: currentColor; }
.reel__bar { position: absolute; inset: auto 0 0 0; height: 2px; background: var(--hair); overflow: hidden; border-radius: 2px; }
.reel__tab { position: relative; }
.reel__bar i { display: block; height: 100%; background: var(--accent-ink); transform: scaleX(0); transform-origin: left; }
.reel__tab[aria-selected="true"] .reel__bar i { animation: reelbar 5s linear forwards; }
.reel[data-play="false"] .reel__bar i { animation-play-state: paused; }
@keyframes reelbar { from { transform: scaleX(0); } to { transform: scaleX(1); } }

.reel__stage { display: grid; }
.reel__p {
  grid-area: 1 / 1; display: flex; flex-direction: column; gap: 18px;
  opacity: 0; visibility: hidden; transition: opacity 0.4s var(--ease), visibility 0.4s;
}
.reel__p[data-on="true"] { opacity: 1; visibility: visible; }
.reel__say { max-width: 68ch; font-size: 16px; line-height: 1.55; color: var(--text-2); }

@media (max-width: 1100px) { .reel__tabs { grid-template-columns: repeat(min(var(--reel-n, 4), 4), minmax(0, 1fr)); gap: 13px 14px; } }
@media (max-width: 680px) {
  .reel__tabs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .reel__l { font-size: 14px; }
}
@media (prefers-reduced-motion: reduce) {
  .reel__p { transition: none; }
  .reel__tab[aria-selected="true"] .reel__bar i { animation: none; transform: scaleX(1); }
}
/* a near-square capture at full column width dwarfs the landscape ones around it */
.shot--inset .shot__frame { max-width: 580px; }


/* Estimator — the note used to list rates and leave the arithmetic to the reader; this applies
   them. Inputs left, all three plans priced against the same usage on the right. */
.est { margin-top: 26px; border: 1px solid var(--hair); border-radius: 16px; background: var(--surface); }
.est__head { padding: 26px 22px 0; }
.est__t { font-size: 17px; font-weight: 600; letter-spacing: -0.02em; }
.est__d { font-size: 14px; color: var(--text-2); margin-top: 5px; max-width: 66ch; text-wrap: pretty; }
.est__grid { display: grid; grid-template-columns: 320px 1fr; gap: 28px; padding: 24px 22px 24px; align-items: start; }
@media (max-width: 880px) { .est__grid { grid-template-columns: 1fr; gap: 22px; } }

.est__f { display: flex; flex-direction: column; gap: 11px; }
.est__row { display: grid; grid-template-columns: 1fr 96px; gap: 12px; align-items: center; }
.est__row label { font-size: 14.5px; letter-spacing: -0.01em; }
.est__row label span { display: block; font-size: 12.5px; color: var(--text-3); margin-top: 1px; }
.est__row input {
  width: 100%; font: 500 15px/1.2 var(--mono); color: var(--text);
  background: var(--tint); border: 1px solid var(--hair); border-radius: 9px;
  padding: 8px 10px; text-align: right; -moz-appearance: textfield;
}
.est__row input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent; }
.est__byo {
  display: flex; gap: 10px; align-items: flex-start; font-size: 13.5px; color: var(--text-2);
  border-top: 1px solid var(--hair-soft); padding-top: 13px; margin-top: 3px; cursor: pointer;
  text-wrap: pretty;
}
.est__byo input { margin: 2px 0 0; accent-color: var(--accent); flex: none; }

/* minmax(0,1fr), not 1fr: the subtitle changes as the user types, and an auto floor would let
   the longer strings starve the Free card and rebalance all three on every keystroke */
.est__plans { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
@media (max-width: 520px) { .est__plans { grid-template-columns: minmax(0, 1fr); } }
.est__plan {
  display: block; width: 100%; text-align: left; font: inherit; color: inherit; appearance: none;
  border: 1px solid var(--hair); border-radius: 12px; padding: 13px 15px; background: var(--bg);
  cursor: pointer; transition: border-color 0.15s var(--ease), background 0.15s var(--ease);
}
.est__plan:hover { border-color: var(--text-3); }
.est__plan[data-sel] { border-color: var(--accent); background: var(--accent-wash); }
.est__plan:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.est__pn { display: block; font-size: 11.5px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-2); }
.est__plan[data-sel] .est__pn { color: var(--accent-ink); }
/* The tracks are pinned, so the price has to fit them rather than the other way round: "/mo"
   takes its own line, and a long total steps the number down a size. */
.est__pv { display: block; font-size: 27px; font-weight: 600; letter-spacing: -0.03em; margin-top: 8px; font-variant-numeric: tabular-nums; }
.est__pv[data-wide] { font-size: 21px; }
.est__pv span { display: block; font-size: 12.5px; font-weight: 500; letter-spacing: -0.01em; color: var(--text-2); margin-top: 3px; }
.est__ps { display: block; font-size: 12.5px; color: var(--text-2); margin-top: 5px; text-wrap: pretty; }

.est__bd:not(:empty) { margin-top: 16px; border-top: 1px solid var(--hair-soft); padding-top: 12px; }
.est__li { display: flex; justify-content: space-between; gap: 16px; padding: 5px 0; font-size: 14px; color: var(--text-2); font-variant-numeric: tabular-nums; }
.est__li b { font-weight: 500; color: var(--text); }
.est__li b span { display: block; font-weight: 400; font-size: 13px; color: var(--text-3); margin-top: 1px; }
.est__li--sum { border-top: 1px solid var(--hair-soft); margin-top: 7px; padding-top: 10px; font-size: 15.5px; font-weight: 600; color: var(--text); }
.est__note { font-size: 12.5px; line-height: 1.45; color: var(--text-3); margin-top: 14px; text-wrap: pretty; }

/* The line under the estimators. A hairline above and centred type give it the weight of a
   closing statement about all four products rather than a footnote to the last one. */
.terms-line {
  margin: 34px auto 0; max-width: 68ch; padding-top: 22px; border-top: 1px solid var(--hair);
  font-size: 15px; line-height: 1.55; letter-spacing: -0.008em; color: var(--text-2);
  text-align: center; text-wrap: balance;
}
.terms-line a { color: var(--text); font-weight: 600; border-bottom: 1px solid var(--hair); }
.terms-line a:hover { color: var(--accent-ink); border-bottom-color: var(--accent); opacity: 1; }

/* ── legal ───────────────────────────────────────────────────────────
   A contract is read two ways: start to finish once, and by jumping to one clause
   forever after. So the prose column is capped at a reading measure and the jump
   list is a persistent rail rather than a block at the top that scrolls away. */

.legal { display: grid; grid-template-columns: minmax(0, 1fr) 224px; gap: 0 56px; align-items: start; --lg-g: 54px; }
/* the rail is written before the prose in the source so it is reachable early by keyboard and
   assistive tech; placement is explicit here rather than left to DOM order */
.legal__main { grid-column: 1; order: 1; max-width: 760px; }
.toc { grid-column: 2; order: 2; }
@media (max-width: 1000px) {
  .legal { grid-template-columns: minmax(0, 1fr); }
  .legal__main { grid-column: 1; max-width: none; order: 2; }
}

/* Numbering stays in the document — a clause you cannot cite by number is not much use in
   a dispute — but it hangs in a gutter so the prose keeps one flush left edge to read down.
   The gutter is one fixed width, not an em measure: em resolves against each element's own
   size, so a 26px heading and a 15.5px clause would indent to two different edges. */
.lg-sec { border-top: 1px solid var(--hair); padding-top: 30px; margin-top: 42px; }
.lg-sec:first-child { border-top: 0; padding-top: 0; margin-top: 0; }
.lg-h2 {
  display: grid; grid-template-columns: var(--lg-g) minmax(0, 1fr); gap: 0;
  font-size: clamp(21px, 2.3vw, 26px); line-height: 1.16; letter-spacing: -0.024em;
  margin-bottom: 20px; text-wrap: pretty;
}
.lg-h2 span { color: var(--text-3); font-weight: 500; letter-spacing: -0.01em; }
.lg-h3 {
  font-size: 16px; font-weight: 600; letter-spacing: -0.014em; color: var(--text);
  margin: 26px 0 12px var(--lg-g);
}
.lg-h3:first-child { margin-top: 0; }

.lg-c {
  display: grid; grid-template-columns: var(--lg-g) minmax(0, 1fr); gap: 0;
  font-size: 15.5px; line-height: 1.62; letter-spacing: -0.008em; color: var(--text-2);
  margin-bottom: 13px; text-wrap: pretty;
}
.lg-c > span:first-child { color: var(--text-3); font-variant-numeric: tabular-nums; }
/* A clause is cited by number, so the number is the handle: it deep-links and copies that link.
   Quiet until hovered — ninety-two visible affordances would be louder than the contract. */
.lg-a {
  color: inherit; text-decoration: none; border-radius: 4px;
  transition: color 0.15s var(--ease);
}
.lg-a:hover { color: var(--accent-ink); opacity: 1; }
.lg-a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* An inline cross-reference is a jump, not a citation, so it is marked in the text — an
   underline that only appears on the reference keeps the paragraph's rhythm intact. */
.lg-x {
  color: var(--text); font-weight: 500; text-decoration: none;
  border-bottom: 1px solid var(--hair); white-space: nowrap;
  transition: color 0.15s var(--ease), border-color 0.15s var(--ease);
}
.lg-x:hover { color: var(--accent-ink); border-bottom-color: var(--accent); opacity: 1; }
.lg-x:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.lg-c strong { color: var(--text); font-weight: 600; }
.lg-c em { font-style: normal; color: var(--text-2); }

/* body-column siblings of a clause: tables, insets */
.lg-in { margin: 0 0 13px var(--lg-g); }

/* carries its own gutter rather than borrowing .lg-in's, so resetting the UA list margins
   here cannot collide with it */
.lg-list { list-style: none; margin: 0 0 13px var(--lg-g); padding: 0; display: flex; flex-direction: column; }
.lg-list li {
  font-size: 15.5px; line-height: 1.6; letter-spacing: -0.008em; color: var(--text-2);
  padding-block: 11px; border-top: 1px solid var(--hair-soft); text-wrap: pretty;
}
.lg-list li:first-child { border-top: 0; padding-top: 0; }
.lg-list b { color: var(--text); font-weight: 600; }

/* Arriving from a cross-reference lands you mid-document with no sense of which line you were
   sent to. The wash marks it once and fades — a permanent highlight would outstay its purpose. */
.lg-sec:target > .lg-h2, .lg-c:target, .lg-h3:target { animation: lg-land 2.4s var(--ease) forwards; }
@keyframes lg-land {
  0%, 42% { background: var(--accent-wash); box-shadow: 0 0 0 7px var(--accent-wash); }
  100% { background: transparent; box-shadow: 0 0 0 7px transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .lg-sec:target > .lg-h2, .lg-c:target, .lg-h3:target { animation: none; background: var(--accent-wash); box-shadow: 0 0 0 7px var(--accent-wash); }
}

.lg-toast {
  position: fixed; left: 50%; bottom: 26px; z-index: 60; transform: translate(-50%, 12px);
  background: var(--text); color: var(--bg); border-radius: 999px; padding: 9px 18px;
  font-size: 13px; font-weight: 600; letter-spacing: -0.006em;
  opacity: 0; pointer-events: none; transition: opacity 0.2s var(--ease), transform 0.2s var(--ease);
}
.lg-toast[data-show="true"] { opacity: 1; transform: translate(-50%, 0); }

.lg-table { width: 100%; border-collapse: collapse; font-size: 14.5px; letter-spacing: -0.006em; }
.lg-table th {
  text-align: left; font-size: 11.5px; font-weight: 600; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--text-2); padding: 0 14px 9px 0;
  border-bottom: 1px solid var(--hair);
}
.lg-table td {
  padding: 11px 14px 11px 0; border-bottom: 1px solid var(--hair-soft);
  color: var(--text-2); font-variant-numeric: tabular-nums;
}
.lg-table td:last-child { color: var(--text); font-weight: 600; width: 5.5em; }

/* A schedule is a five-column table of prose, not a two-column table of figures — the credit
   table's narrow, emphasised last column would squeeze the retention text to a ribbon. */
.lg-in--scroll { overflow-x: auto; }
.lg-table--wide { min-width: 560px; }
.lg-table--wide th, .lg-table--wide td { padding-right: 20px; vertical-align: top; }
.lg-table--wide td { color: var(--text-2); font-variant-numeric: normal; }
.lg-table--wide td:first-child { color: var(--text); font-weight: 500; }
.lg-table--wide td:last-child { color: var(--text-2); font-weight: 400; width: auto; }

/* The document is a draft with fields still to be filled. Marking them inline is more honest
   than a silent blank, and it keeps the placeholder searchable before publication. */
.lg-tbd {
  font: 500 13px/1 var(--mono); color: var(--text-3); letter-spacing: 0;
  background: var(--tint); border: 1px solid var(--hair-soft); border-radius: 5px;
  padding: 2px 5px; white-space: nowrap;
}
/* long placeholders must wrap on a phone or they set the page width */
@media (max-width: 640px) { .lg-tbd { white-space: normal; } }

.lg-flag {
  border: 1px solid var(--accent); border-radius: 14px; background: var(--accent-wash);
  padding: 20px 22px; display: flex; flex-direction: column; gap: 8px; margin-bottom: 34px;
}
.lg-flag > p.lg-flag__t { font-size: 13px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--accent-ink); }
.lg-flag > p:not(.lg-flag__t) { font-size: 15px; line-height: 1.55; letter-spacing: -0.008em; color: var(--text-2); text-wrap: pretty; }

.lg-meta { display: grid; gap: 0; margin-bottom: 38px; }
.lg-meta div {
  display: grid; grid-template-columns: 8.5em minmax(0, 1fr); gap: 0 16px;
  padding-block: 12px; border-top: 1px solid var(--hair-soft);
  font-size: 15px; line-height: 1.5; letter-spacing: -0.008em; color: var(--text-2); text-wrap: pretty;
}
.lg-meta dt { font-size: 12px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-3); padding-top: 2px; }
.lg-meta dd { margin: 0; }
@media (max-width: 560px) {
  .legal { --lg-g: 42px; }
  .lg-meta div { grid-template-columns: minmax(0, 1fr); gap: 3px; }
}

/* ── the jump rail ───────────────────────────────────────────────────
   No numbers here: the reader is scanning for a subject, and a column of digits is
   noise in that task. Hierarchy carries by indent and weight instead. Children of the
   section being read are the only ones shown — the full tree is taller than a viewport,
   and a jump list you have to scroll is a second navigation problem. */

.toc { position: sticky; top: 78px; grid-column: 2; }
.toc__label {
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--text-3); padding-bottom: 12px; border-bottom: 1px solid var(--hair);
  width: 100%; text-align: left; background: none; border-inline: 0; border-top: 0;
  font-family: inherit; cursor: default;
}
.toc__chev { width: 12px; height: 12px; display: none; flex: none; transition: transform 0.2s var(--ease); }
.toc__box { max-height: calc(100vh - 168px); overflow-y: auto; scrollbar-width: thin; padding-block: 8px; }
.toc__g { display: flex; flex-direction: column; }
.toc__i {
  display: block; font-size: 13.5px; line-height: 1.35; letter-spacing: -0.008em;
  color: var(--text-2); padding: 5px 0 5px 11px; margin-left: -11px;
  border-left: 2px solid transparent; text-wrap: pretty;
  transition: color 0.15s var(--ease), border-color 0.15s var(--ease);
}
.toc__i:hover { color: var(--text); opacity: 1; }
.toc__i[data-on="true"] { color: var(--accent-ink); font-weight: 600; border-left-color: var(--accent); }
/* collapsed to a zero-height grid row rather than display:none so the reveal can be animated
   and the links stay in the accessibility tree */
.toc__subs { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.28s var(--ease); }
.toc__subs > div { overflow: hidden; min-height: 0; }
.toc__g[data-open="true"] .toc__subs { grid-template-rows: 1fr; }
.toc__i--sub { padding-left: 22px; font-size: 13px; color: var(--text-3); }
.toc__i--sub[data-on="true"] { color: var(--accent-ink); }
.toc__sep { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--hair-soft); }
@media (prefers-reduced-motion: reduce) { .toc__i, .toc__subs { transition: none; } }

/* Above the prose on a narrow screen, and folded: it is a jump list, not a preamble. */
@media (max-width: 1000px) {
  .toc { position: static; grid-column: 1; order: 1; margin-bottom: 34px; border: 1px solid var(--hair); border-radius: 14px; padding: 4px 18px 6px; }
  .toc__label { padding-block: 14px; border-bottom: 0; cursor: pointer; display: flex; justify-content: space-between; align-items: center; }
  .toc__chev { display: block; }
  .toc[data-open="true"] .toc__chev { transform: rotate(180deg); }
  .toc__box { max-height: none; border-top: 1px solid var(--hair-soft); }
  .toc:not([data-open="true"]) .toc__box { display: none; }
  .toc__g[data-open] .toc__subs { grid-template-rows: 1fr; }
}

/* Printed, it is a contract: the rail, the chrome and the sales close are not part of it. */
@media print {
  .nav, .toc, .foot, .cookie, .lg-toast, .skip, [data-screen-label="Terms closing"] { display: none !important; }
  .legal { display: block; }
  .legal__main { max-width: none; }
  .sec { padding-block: 0; }
  .lg-sec { break-inside: auto; page-break-inside: auto; margin-top: 26px; padding-top: 20px; }
  .lg-h2, .lg-h3 { break-after: avoid; page-break-after: avoid; }
  .lg-c, .lg-list li, .lg-table tr { break-inside: avoid; page-break-inside: avoid; }
  .lg-x, .lg-a { color: inherit; border-bottom: 0; }
  .lg-flag { border-radius: 0; }
}


/* ── Ostrich ────────────────────────────────────────────────────────────
   A grant programme, not a product, so it does not borrow the product pages'
   light ground, teal accent or card grid. Black canvas, one photograph, and a
   numbered ledger read top to bottom. The figures are the argument, so they sit
   inside the sentences rather than in stat tiles — the reader meets each number
   where it means something. Scoped to .os on <main>: nav and footer keep the
   site's own appearance, and the seam between them is the point. */

.os {
  /* Paper, not white: warm enough to separate the programme from the product pages
     without leaving the site's appearance behind. The dark set below is the same
     page inverted, so the theme switch does what it does everywhere else. */
  --os-bg: #FBFAF7;
  --os-ink: #14141A;
  --os-ink-2: #5A5A62;          /* 7.1:1 on the ground */
  --os-accent: #37637A;         /* 6.2:1 — slate, so a figure reads as ink and not as a link */
  --os-hair: rgba(20, 20, 26, 0.15);
  --os-fill: rgba(20, 20, 26, 0.035);
  --os-fill-2: rgba(20, 20, 26, 0.06);
  --os-shot-bg: #EDEBE6;
  background: var(--os-bg);
  color: var(--os-ink);
}
[data-theme="dark"] .os {
  --os-bg: #0B0B0C;
  --os-ink: #F2F0EC;
  --os-ink-2: #9C9C9F;          /* 7.4:1 on the ground */
  --os-accent: #A9C3CE;         /* 11.6:1 — desaturated enough to read as ink, not as a link */
  --os-hair: rgba(242, 240, 236, 0.14);
  --os-fill: rgba(242, 240, 236, 0.03);
  --os-fill-2: rgba(242, 240, 236, 0.06);
  --os-shot-bg: #17171a;
}
.os a { color: var(--os-accent); }
.os a:hover { opacity: 0.72; }
.os a:focus-visible { outline: 2px solid var(--os-accent); outline-offset: 3px; }
.os ::selection { background: var(--os-accent); color: var(--os-bg); }

.os-hero { padding-block: clamp(38px, 4.6vw, 68px) clamp(44px, 5.4vw, 84px); }
.os-hero__in {
  display: grid; align-items: end;
  gap: clamp(26px, 4vw, 60px);
  grid-template-columns: minmax(0, 0.78fr) minmax(0, 1fr);
}
.os-hero__txt { display: flex; flex-direction: column; gap: 18px; }
/* The copy starts level with the top of the ostrich's head and the buttons stay
   pinned to the bottom of the frame, so the column reads against the bird. */
.os-hero__in:has(.os-hero__txt--head) { align-items: stretch; }
.os-hero__txt--head { padding-top: clamp(4px, 1vw, 16px); }
.os-hero__txt--head .os-cta { margin-top: clamp(10px, 1.6vw, 22px); }

.os-kicker {
  font-family: var(--mono); font-size: 11.5px; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--os-accent);
}
.os-h1 {
  font-size: clamp(36px, 5.2vw, 66px); line-height: 1.02;
  letter-spacing: -0.032em; font-weight: 600; text-wrap: balance;
}
.os-lede {
  font-size: clamp(16.5px, 1.4vw, 19px); line-height: 1.58;
  letter-spacing: -0.01em; color: var(--os-ink-2); max-width: 48ch;
}

/* a figure carries the weight of the claim, so it is marked where it is read */
.os-n {
  font-family: var(--mono); font-size: 0.93em; color: var(--os-accent);
  letter-spacing: -0.01em; white-space: nowrap;
  border-bottom: 1px solid color-mix(in srgb, currentColor 42%, transparent); padding-bottom: 1px;
}

/* the word equivalent of .os-n: the site's .hl idiom carried into this palette */
.os-hl {
  color: var(--os-ink); font-weight: 600;
  background: color-mix(in srgb, var(--os-accent) 26%, transparent);
  margin-inline: -0.2em 0; padding: 0.04em 0.2em 0.08em;
  border-radius: 4px;
  box-decoration-break: clone; -webkit-box-decoration-break: clone;
}

.os-cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 8px; }
.os-cta--center { justify-content: center; margin-top: 30px; }
.os .os-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding-inline: 24px; border-radius: 999px;
  background: var(--os-ink); color: var(--os-bg);
  font-size: 15px; font-weight: 600; letter-spacing: -0.012em;
  transition: opacity 0.18s var(--ease), background-color 0.18s var(--ease);
}
.os .os-btn:hover { opacity: 0.86; }
.os .os-btn--quiet { background: transparent; color: var(--os-ink); box-shadow: inset 0 0 0 1px var(--os-hair); }
.os .os-btn--quiet:hover { opacity: 1; background: var(--os-fill-2); }

/* A cut-out, not a cropped photograph: it stands on the page ground with no frame
   and no fill behind it. On the dark ground the bird's own body is close to the
   background, so a soft lift sits behind it and the image is brightened enough to
   keep the feathers legible. */
.os-shot { position: relative; margin: 0; display: flex; flex-direction: column; gap: 14px; }
.os-shot img {
  display: block; width: 100%; height: auto; position: relative;
  filter: grayscale(1) contrast(1.04);
}
[data-theme="dark"] .os-shot img { filter: grayscale(1) brightness(1.55) contrast(0.92); }
[data-theme="dark"] .os-shot::before {
  content: ""; position: absolute; inset: -6% -10% 12%;
  background: radial-gradient(58% 52% at 52% 44%, rgba(169, 195, 206, 0.16), rgba(169, 195, 206, 0) 72%);
  pointer-events: none;
}
.os-shot__cap { font-size: 13px; line-height: 1.5; color: var(--os-ink-2); max-width: 34ch; }

.os-stmt { border-block: 1px solid var(--os-hair); padding-block: clamp(40px, 4.8vw, 70px); }
.os-stmt p {
  font-size: clamp(20px, 2.3vw, 29px); line-height: 1.38;
  letter-spacing: -0.022em; max-width: 36ch;
}

/* Ostrich on home: the same block sized to sit inside a product page rather than
   open one. The image loses its caption and the statement takes the weight the
   headline carries on the programme page itself. */
.os-home { padding-block: clamp(48px, 5.6vw, 86px); }
.os-home .os-hero__in { align-items: center; grid-template-columns: minmax(0, 0.62fr) minmax(0, 1fr); }
.os-home .os-shot img { max-width: 280px; margin-inline: auto; }
.os-said {
  font-size: clamp(18px, 1.75vw, 23px); line-height: 1.44;
  letter-spacing: -0.02em; color: var(--os-ink); max-width: 40ch;
}
@media (max-width: 820px) {
  .os-home .os-hero__in { grid-template-columns: 1fr; }
  .os-home .os-shot img { max-width: 170px; margin-inline: 0; }
}

/* each gift on its own line — the list is the argument, so it is set as a list */
.os-br { display: block; }
/* the turn: the debt is stated, then the answer to it starts on its own line */
.os-turn { display: block; margin-top: 0.62em; }

.os-body { padding-block: clamp(10px, 1.4vw, 20px) 0; }
.os-flow { display: flex; flex-direction: column; }
.os-item {
  display: grid; grid-template-columns: 76px minmax(0, 1fr); gap: 0 24px;
  padding-block: clamp(28px, 3.2vw, 44px); border-top: 1px solid var(--os-hair);
}
.os-item:first-child { border-top: 0; }
.os-no {
  font-family: var(--mono); font-size: 12.5px; letter-spacing: 0.1em;
  color: var(--os-accent); padding-top: 7px;
}
.os-h2 { font-size: clamp(21px, 2.1vw, 27px); letter-spacing: -0.022em; margin-bottom: 13px; }
.os-p { font-size: 16.5px; line-height: 1.64; letter-spacing: -0.009em; color: var(--os-ink-2); max-width: 62ch; }
.os-p + .os-p { margin-top: 13px; }
.os-p strong { color: var(--os-ink); font-weight: 600; }

.os-close { border-top: 1px solid var(--os-hair); padding-block: clamp(54px, 6.2vw, 96px); text-align: center; }
.os-tag {
  font-size: clamp(25px, 3.3vw, 44px); line-height: 1.12;
  letter-spacing: -0.028em; font-weight: 600; text-wrap: balance;
}

@media (max-width: 860px) {
  .os-hero__in { grid-template-columns: 1fr; align-items: start; }
  .os-hero__in:has(.os-hero__txt--head) { align-items: start; }
  .os-hero__txt--head { padding-top: 0; }
  .os-shot { max-width: 420px; }
}
@media (max-width: 640px) {
  .os-item { grid-template-columns: 1fr; gap: 10px; }
  .os-no { padding-top: 0; }
}

/* ── Ostrich: application flow ──────────────────────────────────────────
   The form is the ledger from the programme page with inputs in it: same
   numbered spine, same measure, same figures marked inline. Nothing here
   announces itself as a form until you are already reading a question. */

.os-hero--slim { padding-block: clamp(34px, 4vw, 56px) clamp(18px, 2vw, 26px); }
.os-lead { display: flex; flex-direction: column; gap: 14px; max-width: 62ch; }
.os-h1--sm { font-size: clamp(30px, 3.6vw, 46px); }
.os-fine { font-size: 13.5px; line-height: 1.6; color: var(--os-ink-2); max-width: 52ch; }
.os-fine strong { color: var(--os-ink); font-weight: 600; }

.os-auth { display: flex; flex-direction: column; gap: 10px; max-width: 330px; margin-top: 4px; }
.os-prov {
  display: flex; align-items: center; justify-content: center;
  min-height: 52px; padding-inline: 20px; border-radius: 999px;
  border: 1px solid var(--os-hair); background: var(--os-fill);
  font: inherit; font-size: 15px; font-weight: 600; letter-spacing: -0.012em;
  color: var(--os-ink); cursor: pointer;
  transition: background-color 0.15s var(--ease), border-color 0.15s var(--ease);
}
.os-prov:hover { background: var(--os-fill-2); border-color: var(--os-accent); }

.os-item fieldset, fieldset.os-item { border: 0; margin: 0; padding-inline: 0; }
.os-item legend { padding: 0; }

.os-choice { display: grid; gap: 10px; grid-template-columns: repeat(2, minmax(0, 1fr)); margin-bottom: 22px; }
.os-choice--three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.os-opt {
  display: flex; gap: 11px; align-items: flex-start; padding: 14px 15px;
  border: 1px solid var(--os-hair); border-radius: 12px; cursor: pointer;
  transition: border-color 0.15s var(--ease), background-color 0.15s var(--ease);
}
.os-opt:hover { border-color: color-mix(in srgb, var(--os-accent) 55%, transparent); }
.os-opt[data-on="true"] { border-color: var(--os-accent); background: var(--os-fill); }
.os-opt input { accent-color: var(--os-accent); margin: 3px 0 0; flex: none; }
.os-opt > span { display: flex; flex-direction: column; gap: 3px; }
.os-opt__t { font-size: 14.5px; font-weight: 600; letter-spacing: -0.01em; color: var(--os-ink); }
.os-opt__d { font-size: 12.5px; line-height: 1.45; color: var(--os-ink-2); }

.os-fields { display: grid; gap: 18px 20px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.os-fields--one, .os-f--wide { grid-column: 1 / -1; }
.os-fields--one { grid-template-columns: 1fr; }
.os-fields[hidden] { display: none; }
.os-f { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.os-label { font-size: 13.5px; font-weight: 600; letter-spacing: -0.006em; color: var(--os-ink); }
.os-opt-tag { font-family: var(--mono); font-size: 10.5px; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--os-ink-2); }
.os-hint { font-size: 12.5px; line-height: 1.5; color: var(--os-ink-2); }
.os-input, .os-textarea {
  width: 100%; font: inherit; font-size: 15.5px; letter-spacing: -0.009em; color: var(--os-ink);
  background: var(--os-fill); border: 1px solid var(--os-hair); border-radius: 10px;
  padding: 12px 14px; min-height: 48px;
  transition: border-color 0.15s var(--ease), background-color 0.15s var(--ease);
}
.os-input::placeholder, .os-textarea::placeholder { color: var(--os-ink-2); opacity: 0.75; }
.os-input:hover, .os-textarea:hover { border-color: color-mix(in srgb, var(--os-accent) 45%, transparent); }
.os-input:focus, .os-textarea:focus { outline: 2px solid var(--os-accent); outline-offset: 1px; border-color: transparent; }
.os-input[readonly] { color: var(--os-ink-2); background: transparent; }
.os-textarea { min-height: 150px; line-height: 1.58; resize: vertical; }
.os-textarea--sm { min-height: 104px; }
.os-count { font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em; color: var(--os-ink-2); align-self: flex-end; }
.os-check { display: flex; gap: 11px; align-items: flex-start; font-size: 14px; line-height: 1.55; color: var(--os-ink-2); cursor: pointer; }
.os-check input { accent-color: var(--os-accent); margin: 3px 0 0; flex: none; }
.os-check .os-hint { display: block; }

.os-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 26px; }
.os-msg { font-size: 13.5px; color: var(--os-ink-2); }
.os-msg.os-err { color: #B3372B; }
[data-theme="dark"] .os-msg.os-err { color: #FF8E7E; }

.os-hero__txt [data-state] { display: flex; flex-direction: column; gap: 16px; }
.os-hero__txt [data-state][hidden] { display: none; }

.os-meta { display: flex; flex-wrap: wrap; gap: 22px 34px; margin: 8px 0 0; padding-top: 20px; border-top: 1px solid var(--os-hair); }
.os-meta div { display: flex; flex-direction: column; gap: 5px; }
.os-meta dt { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--os-ink-2); }
.os-meta dd { margin: 0; font-size: 14.5px; font-weight: 600; letter-spacing: -0.01em; color: var(--os-ink); }

@media (max-width: 760px) {
  .os-choice, .os-choice--three, .os-fields { grid-template-columns: 1fr; }
}

/* the application header carries the bird at reading scale, not hero scale */
.os-head {
  display: grid; align-items: end;
  gap: clamp(18px, 3vw, 44px);
  grid-template-columns: minmax(0, 0.4fr) minmax(0, 1fr);
}
.os-shot--sm { max-width: 250px; }

/* A form asks more of the reader than prose does, so it is set tighter: the
   ledger rhythm survives, but nothing is separated by more than it needs. */
fieldset.os-item { padding-block: clamp(20px, 2.1vw, 30px); }
fieldset.os-item .os-h2 { font-size: clamp(19px, 1.8vw, 23px); margin-bottom: 12px; }
fieldset.os-item .os-choice { margin-bottom: 15px; gap: 9px; }
fieldset.os-item .os-opt { padding: 11px 13px; }
fieldset.os-item .os-fields { gap: 14px 18px; }
fieldset.os-item .os-f { gap: 6px; }
fieldset.os-item .os-input, fieldset.os-item .os-textarea { min-height: 44px; padding: 10px 13px; font-size: 15px; }
fieldset.os-item .os-textarea { min-height: 116px; }
fieldset.os-item .os-textarea--sm { min-height: 84px; }
fieldset.os-item .os-actions { margin-top: 20px; }
.os-select { appearance: none; cursor: pointer; padding-right: 38px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 19px) calc(50% + 1px), calc(100% - 14px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}

@media (max-width: 760px) {
  .os-head { grid-template-columns: 1fr; }
  .os-shot--sm { max-width: 150px; }
}


/* ── faq ──────────────────────────────────────────────────────────────
   Forty answers is a reference, not a read, so the way in has to survive the
   scroll: the field pins under the header the way the subnav does on the product
   pages, and filters in place rather than navigating anywhere. The rail below it
   is the terms page's, dropped to clear both bars. */

.faqbar {
  position: sticky; top: 56px; z-index: 39;
  background: var(--nav-bg);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--hair);
}
.faqbar__in { display: flex; align-items: center; gap: 16px; padding-block: 10px; }
.faqbar__n { font-family: var(--mono); font-size: 12px; letter-spacing: -0.01em; color: var(--text-3); white-space: nowrap; }

.faqfield { position: relative; flex: 1; display: flex; align-items: center; min-width: 0; }
.faqfield > svg { position: absolute; left: 15px; width: 15px; height: 15px; color: var(--text-3); pointer-events: none; }
.faqfield input {
  width: 100%; min-height: 44px; padding: 10px 42px 10px 40px;
  font-family: inherit; font-size: 15px; letter-spacing: -0.01em; color: var(--text);
  background: var(--surface); border: 1px solid var(--hair); border-radius: 999px;
  transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease);
  -webkit-appearance: none; appearance: none;
}
.faqfield input::-webkit-search-decoration, .faqfield input::-webkit-search-cancel-button { -webkit-appearance: none; }
.faqfield input::placeholder { color: var(--text-3); }
.faqfield input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-wash); }
.faqfield__x {
  position: absolute; right: 7px; display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border: 0; border-radius: 999px; padding: 0;
  background: transparent; color: var(--text-3); cursor: pointer;
}
.faqfield__x:hover { color: var(--text); background: var(--tint); }
.faqfield__x[hidden] { display: none; }
.faqfield__x svg { width: 14px; height: 14px; }

.faq .toc { top: 128px; }
.faq .toc__box { max-height: calc(100vh - 216px); }

.faq-g { margin-bottom: 46px; scroll-margin-top: 130px; }
.faq-g[hidden] { display: none; }
.faq-g__h {
  font-size: 12px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-3); padding-bottom: 12px; margin-bottom: 4px;
  border-bottom: 1px solid var(--hair);
}
.faq-q { padding-block: 20px; border-bottom: 1px solid var(--hair-soft); }
.faq-q[hidden] { display: none; }
.faq-q__q { font-size: 17px; font-weight: 600; letter-spacing: -0.018em; color: var(--text); margin-bottom: 7px; }
.faq-q__a { font-size: 15.5px; line-height: 1.62; letter-spacing: -0.008em; color: var(--text-2); max-width: 66ch; }

.faq-none { font-size: 16px; line-height: 1.6; color: var(--text-2); padding-block: 30px; }
.faq-none__x {
  font: inherit; color: var(--accent-ink); background: none; border: 0; padding: 0;
  cursor: pointer; text-decoration: underline; text-underline-offset: 3px;
}
.faq-end { margin-top: 34px; padding-top: 24px; border-top: 1px solid var(--hair); }

@media (max-width: 700px) {
  .faqbar__n { display: none; }
  .faqfield input { font-size: 16px; }
}

/* ── security ─────────────────────────────────────────────────────────
   Claims, each with its boundary attached. No panels: an auditor reads a list,
   and a list of assertions in a card grid reads as marketing. */
.sec-claims { display: flex; flex-direction: column; }
.sec-claim {
  display: grid; grid-template-columns: 62px minmax(0, 1fr); gap: 0 24px;
  padding-block: 26px; border-top: 1px solid var(--hair);
}
.sec-claim:first-child { border-top: 0; }
.sec-claim__n { font-family: var(--mono); font-size: 12px; letter-spacing: 0.08em; color: var(--text-3); padding-top: 5px; }
.sec-claim__h { font-size: clamp(19px, 1.9vw, 23px); letter-spacing: -0.022em; margin-bottom: 10px; }
.sec-claim__b { font-size: 16px; line-height: 1.62; letter-spacing: -0.008em; color: var(--text-2); max-width: 64ch; }
.sec-claim__b + .sec-claim__b { margin-top: 10px; }
.sec-claim__b strong { color: var(--text); font-weight: 600; }
@media (max-width: 620px) {
  .sec-claim { grid-template-columns: 1fr; gap: 8px; }
  .sec-claim__n { padding-top: 0; }
}

/* ── company/legal strip + social cards ──────────────────────────────
   ext arrows outside the nav were unsized and filled their container;
   the legal toc drops 46px when the section strip is above it. */
svg.ext { width: 12px; height: 12px; flex: none; }
.arrow-link .ext { width: 13px; height: 13px; }
html:has(.subnav) .toc { top: 124px; }
a.card { color: inherit; text-decoration: none; }

/* ── grants hero, image right (sparrow, pelican) ── */
.os-hero__in--flip { grid-template-columns: minmax(0, 1fr) minmax(0, 0.68fr); align-items: center; gap: clamp(20px, 3vw, 45px); justify-items: start; }
.os-hero__in--flip .os-hero__txt { max-width: 62ch; gap: 14px; }
.os-hero__in--flip .os-shot { align-items: flex-start; text-align: left; }
.os-hero__in--flip .os-shot img { margin-inline: 0; }
@media (max-width: 860px) {
  .os-hero__in--flip .os-shot { align-items: flex-start; text-align: left; }
  .os-hero__in--flip .os-shot img { margin-inline: 0; max-width: min(60vw, 320px) !important; }
}

/* folded pricing-table groups (see app.js): the group header becomes a disclosure */
.mx tr[hidden] { display: none; }
.mx__fold {
  display: inline-flex; align-items: baseline; gap: 12px;
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit;
}
.mx__fold-t {
  font-size: 11px; font-weight: 600; letter-spacing: 0.02em; text-transform: none;
  color: var(--accent-ink); text-decoration: underline; text-underline-offset: 3px;
  white-space: nowrap;
}
.mx__fold:hover .mx__fold-t { opacity: 0.72; }

/* ── two-sided manifest (api-bay) ───────────────────────────────────────
   The same four questions, answered by each side of the marketplace. A comparison
   grid rather than two lists of ticks: the reader finds the row they care about and
   reads across, and neither side can quietly claim more lines than the other. */
.manifest { width: 100%; border-collapse: separate; border-spacing: 0; table-layout: fixed; }
.manifest col:first-child { width: 176px; }
.manifest th, .manifest td {
  padding: 16px 20px; text-align: left; vertical-align: top;
  border-bottom: 1px solid var(--hair-soft);
  font-size: 15.5px; line-height: 1.55; letter-spacing: -0.01em; text-wrap: pretty;
}
.manifest thead th, .manifest thead td { padding-top: 0; padding-bottom: 14px; border-bottom: 1px solid var(--hair); }
.manifest__who {
  display: block; font-size: 12px; font-weight: 600; letter-spacing: 0.03em;
  text-transform: uppercase; color: var(--accent-ink);
}
.manifest__h { display: block; margin-top: 8px; font-size: 19px; font-weight: 500; letter-spacing: -0.021em; color: var(--text); }
.manifest tbody th {
  padding-top: 19px; font-size: 12px; font-weight: 600; letter-spacing: 0.03em;
  text-transform: uppercase; color: var(--text-2);
}
.manifest tbody td { color: var(--text-2); }
.manifest tbody td b { font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.manifest tbody tr:last-child th, .manifest tbody tr:last-child td { border-bottom: 0; }
.manifest tfoot td { padding-top: 18px; border-bottom: 0; }

@media (max-width: 720px) {
  .manifest, .manifest thead, .manifest tbody, .manifest tfoot, .manifest tr, .manifest th, .manifest td { display: block; }
  .manifest thead { display: none; }
  .manifest tbody tr { border-bottom: 1px solid var(--hair); }
  .manifest tbody tr:last-child { border-bottom: 0; }
  .manifest tbody th { padding: 22px 0 4px; border-bottom: 0; }
  .manifest tbody td { padding: 8px 0 0; border-bottom: 0; }
  .manifest tbody td:last-child { padding-bottom: 22px; }
  .manifest tbody td::before {
    content: attr(data-side); display: block; margin-bottom: 3px;
    font-size: 12px; font-weight: 600; letter-spacing: 0.02em; color: var(--accent-ink);
  }
  .manifest tfoot tr { display: flex; flex-direction: column; gap: 14px; }
  .manifest tfoot td:first-child { display: none; }
  .manifest tfoot td { padding: 18px 0 0; }
}

/* ── docs library (docs.html): the shelf ── */
.vols { display: flex; flex-direction: column; }
.vol { display: grid; grid-template-columns: 212px minmax(0, 1fr); gap: 38px; padding: 40px 0; border-top: 1px solid var(--hair); }
.vol:first-child { border-top: 0; padding-top: 8px; }
.vol-cover {
  position: relative; display: flex; flex-direction: column; aspect-ratio: 5 / 7;
  border-radius: 4px 14px 14px 4px; padding: 0; overflow: hidden;
  background: var(--surface); color: var(--text);
  box-shadow: inset 0 0 0 1px var(--hair-soft), 0 14px 30px -18px rgba(0,0,0,0.35);
  transition: transform 0.22s var(--ease), box-shadow 0.22s var(--ease);
}
.vol-cover::before { content: ""; position: absolute; top: 0; bottom: 0; left: 9px; width: 1px; background: rgba(0,0,0,0.14); }
.vol-cover:hover { transform: translateY(-5px); box-shadow: inset 0 0 0 1px var(--hair-soft), 0 24px 44px -18px rgba(0,0,0,0.4); opacity: 1; }

.vol-cover__head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; padding: 16px 16px 0 20px; }
.vol-cover__head span { white-space: nowrap; }
.vol-cover__mark { font: 600 9px var(--mono); letter-spacing: 0.16em; color: #0F6B57; opacity: 0.9; }
.vol-cover__num { font: 600 9px var(--mono); letter-spacing: 0.1em; color: #87847d; }
.vol-cover__t { font-family: 'Iowan Old Style', 'Palatino Linotype', 'Book Antiqua', Palatino, Georgia, serif; font-size: 19px; font-weight: 600; line-height: 1.22; color: #1d1d1f; }
.vol-body { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.vol-meta { font: 500 11.5px var(--mono); letter-spacing: 0.02em; color: var(--text-3); }
.vol-chapters { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 3px 26px; margin-top: 4px; }
.vol-chapters a { display: flex; gap: 9px; align-items: baseline; font-size: 14px; line-height: 1.45; color: var(--text-2); padding: 4px 0; }
.vol-chapters a:hover { color: var(--accent-ink); opacity: 1; }
.vol-chapters .n { font: 600 10.5px var(--mono); color: var(--text-3); min-width: 18px; flex: none; font-variant-numeric: tabular-nums; }
.vol-body .arrow-link { margin-top: 10px; }
.vol-resume { display: none; margin-top: 10px; padding: 10px 20px; border-radius: 999px; background: var(--accent-wash); color: var(--accent-ink); font-size: 14px; font-weight: 500; }
.vol-resume[data-on] { display: inline-flex; gap: 8px; align-items: baseline; }
.vol-resume strong { font-weight: 600; }
@media (max-width: 760px) {
  .vol { grid-template-columns: minmax(0, 1fr); gap: 22px; }
  .vol-cover { width: 200px; }
  .vol-chapters { grid-template-columns: minmax(0, 1fr); }
}

/* Quiet typographic cover: warm paper, small engraving, ink title bottom-left over an accent rule */
.vol-cover { background: #f7f6f2; }
[data-theme="dark"] .vol-cover, [data-theme="dark"] .toc__cover { background: #eceae3; }
.vol-cover__art { flex: 1; min-height: 0; width: 46%; align-self: center; object-fit: contain; margin: 26px auto 0; }
.vol-cover__art[src$="sparrow.png"] { width: 60%; }
.toc__cover .vol-cover__art[src$="sparrow.png"] { width: 55%; }
.vol-cover__band { display: flex; flex-direction: column; padding: 0 20px 20px; margin-top: auto; }
.vol-cover__band::before { content: ""; width: 28px; height: 2px; background: #0F6B57; margin-bottom: 11px; }
/* mini cover above the volume rail */
.toc__cover { position: relative; display: flex; flex-direction: column; width: 172px; aspect-ratio: 5 / 7; border-radius: 3px 10px 10px 3px; overflow: hidden; background: var(--surface); box-shadow: inset 0 0 0 1px var(--hair-soft), 0 10px 22px -14px rgba(0,0,0,0.35); margin-bottom: 18px; }
.toc__cover::before { content: ""; position: absolute; top: 0; bottom: 0; left: 6px; width: 1px; background: rgba(0,0,0,0.14); }
.toc__cover { background: #f7f6f2; }
.toc__cover .vol-cover__head { padding: 11px 11px 0 14px; }
.toc__cover .vol-cover__mark, .toc__cover .vol-cover__num { font-size: 7.5px; }
.toc__cover .vol-cover__art { width: 42%; margin: 14px auto 0; }
.toc__cover .vol-cover__band { padding: 0 14px 13px; }
.toc__cover .vol-cover__band::before { width: 20px; margin-bottom: 7px; }
.toc__cover .vol-cover__t { font-size: 12.5px; }
.toc__cover:hover { opacity: 1; }
@media (max-width: 1000px) { .toc__cover { display: none; } }



/* ── UnBuild overrides ───────────────────────────────────────────────
   The wordmark: same brushed-steel ramp as littlebit, with an italic "un".
   The child needs its own clip — -webkit-text-fill-color is inherited but the
   ramp is not, so an unclipped child would paint transparent on nothing. */
/* mid-sentence highlight: the base recipe pulls back the leading edge only, which
   leaves its trailing pad sitting before the next word's punctuation */
.hl--mid { margin-inline: -0.24em -0.24em; }

.brand__word--ub { letter-spacing: -0.034em; }

/* whole-card links on the app grids */
.card-a { color: inherit; text-decoration: none; transition: box-shadow 0.2s var(--ease); }
.card-a:hover { opacity: 1; box-shadow: var(--shadow-md); }

/* the workshop plate — a dark object in both appearances */
.plate { background: #131315; color: #f5f5f7; border-top: 1px solid var(--hair-soft); }
[data-theme="dark"] .plate { background: #1c1c1e; }
.plate .h1, .plate .h2, .plate .h3 { color: #f5f5f7; }
.plate .lede, .plate .body, .plate .small { color: #a1a1a6; }
.plate .tiny { color: #8e8e93; }
.plate .eyebrow { color: color-mix(in oklab, var(--accent) 52%, #ffffff); }
.plate .hl {
  color: color-mix(in oklab, var(--accent) 52%, #ffffff);
  background: color-mix(in oklab, var(--accent) 26%, #0c0c0e);
  font-weight: 500;
}
.plate .stat { border-top-color: rgba(255,255,255,0.15); }
.plate .stat__n { color: #f5f5f7; }
.plate .stat__l { color: #a1a1a6; }
.plate .field { border-color: rgba(255,255,255,0.28); background: transparent; color: #f5f5f7; }

/* the commotion wordmark and its caret */
.ubm { font-family: var(--mono); font-weight: 500; letter-spacing: -0.02em; }
.ubm__caret {
  display: inline-block; width: 0.55em; height: 1.05em; margin-left: 0.1em;
  vertical-align: -0.16em; background: color-mix(in oklab, var(--accent) 52%, #ffffff);
  animation: ub-blink 1.15s steps(1) infinite;
}
@keyframes ub-blink { 0%, 48% { opacity: 1; } 52%, 100% { opacity: 0; } }

/* app tiles on the grids */
.tile { aspect-ratio: 16 / 10; display: grid; place-items: center; border-bottom: 1px solid var(--hair-soft); overflow: hidden; }
.tile img { width: 88px; height: 88px; border-radius: 24%; box-shadow: 0 6px 18px rgba(0,0,0,.14); }
.tile--shot img { width: 100%; height: 100%; border-radius: 0; box-shadow: none; object-fit: cover; object-position: top; }
/* Full-bleed screenshot: pin the image to the tile box so its height never depends on the grid track. */
.tile--cover { position: relative; display: block; }
.tile--cover img { position: absolute; inset: 0; width: 100%; height: 100%; }

/* notify form on the workshop plate */
.field {
  flex: 1 1 190px; min-width: 0; min-height: 46px; padding: 12px 20px;
  border-radius: 999px; border: 1px solid var(--hair); background: var(--surface);
  color: var(--text); font-family: var(--mono); font-size: 14px; outline: none;
}
.form-row { display: flex; flex-wrap: wrap; gap: 10px; }

/* numbered principle columns */
.pcols { display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); gap: clamp(18px, 2.4vw, 34px); }
.pnum { font-family: var(--mono); font-size: 11px; letter-spacing: 0.14em; color: var(--accent-ink); margin-bottom: 8px; }
.plate .pnum { color: color-mix(in oklab, var(--accent) 52%, #ffffff); }

/* the studio ledger */
.ledger { display: grid; grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); border-top: 1px solid var(--hair-soft); }
.ledger__row { display: flex; align-items: baseline; gap: 18px; padding-block: 18px; border-bottom: 1px solid var(--hair-soft); }
.ledger__n { font-family: var(--mono); font-size: 11px; letter-spacing: 0.14em; color: var(--accent-ink); }
.ledger__t { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ledger__v { font-size: 14.5px; line-height: 1.45; color: var(--text-2); max-width: 46ch; text-wrap: pretty; }

/* accent picker — a circle of the current accent, opening a row of choices */
.swatchwrap { position: relative; display: flex; }
.swatch-btn .swatch__dot {
  width: 19px; height: 19px; border-radius: 999px; background: var(--accent);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.28);
}
[data-theme="dark"] .swatch-btn .swatch__dot { box-shadow: inset 0 0 0 1px rgba(255,255,255,0.3); }
.swatches {
  position: absolute; top: 46px; right: 0; z-index: 50;
  display: none; gap: 9px; padding: 11px;
  border-radius: 15px; background: var(--surface); box-shadow: var(--shadow-md);
}
.swatches[data-open="true"] { display: flex; }
.swatch {
  width: 26px; height: 26px; flex: none; border: 0; border-radius: 999px; padding: 0; cursor: pointer;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.22);
}
.swatch[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--accent-ink); }
@media (max-width: 420px) { .swatches { right: -40px; } }

/* tokens the app pages carry over from their design components */
:root {
  --accL: color-mix(in oklab, var(--accent) 46%, #ffffff);
  --accsoft: color-mix(in oklab, var(--accent) 26%, #ffffff);
  --ge: rgba(0,0,0,0.19);
  --dev: 0 2px 6px rgba(0,0,0,.08), 0 26px 60px -24px rgba(0,0,0,.30);
  --paper: 0 2px 6px rgba(0,0,0,.08), 0 18px 40px -20px rgba(0,0,0,.35);
  --serif: 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, serif;
  --plate: #131315;
}
[data-theme="dark"] {
  --accL: color-mix(in oklab, var(--accent) 55%, #ffffff);
  --accsoft: color-mix(in oklab, var(--accent) 34%, #111113);
  --ge: rgba(255,255,255,0.22);
  --dev: 0 0 0 1px rgba(255,255,255,0.08), 0 26px 60px -24px rgba(0,0,0,.7);
  --paper: 0 0 0 1px rgba(255,255,255,0.08), 0 18px 40px -20px rgba(0,0,0,.7);
  --plate: #1c1c1e;
}

/* Pop Task hero — the band is painted in the intro recording's own background
   colour (refined at runtime from the video's edge pixels) so the clip has no
   edge against the page. These two are the measured fallbacks. */
#pt-hero { background-color: rgb(248, 246, 242); transition: background-color 0.35s var(--ease); }
[data-theme="dark"] #pt-hero { background-color: rgb(16, 16, 19); }

/* Pop Task hero: copy sets the band height; the clip runs top to bottom of it. */
#pt-hero .pt-copy { padding-block: clamp(34px,3.8cqw,58px) clamp(44px,4.8cqw,76px); }
#pt-hero .pt-media { display: flex; justify-content: center; padding-bottom: 32px; }
#pt-hero .pt-media video { width: min(320px, 100%); height: auto; }
@media (min-width: 860px) {
  #pt-hero .pt-row { position: relative; }
  #pt-hero .pt-copy { padding-right: calc(var(--pt-vw, 300px) + clamp(40px, 5vw, 80px)); min-height: 600px; justify-content: center; }
  #pt-hero .pt-media { position: absolute; top: 0; bottom: 0; right: min(32px, 6%); padding: 0; }
  #pt-hero .pt-media video { width: auto; height: calc(100% - 44px); }
}
@media (max-width: 859px) { #pt-hero .pt-copy { padding-bottom: 28px; } }
