/* Cove landing — screenshot-led rebuild of the "2A Premium cinematic" direction.
   Tokens inherit from design/design-system.md; see DESIGN.md. */

/* ---------- Tokens ---------- */
:root {
  --paper: #FCFBF8;
  --paper-band: #F4F1EB;
  --ink: #2B2926;
  --ink-soft: #6B665E;
  --line: rgba(56, 52, 44, 0.14);
  --accent: #0C8F8C;
  --accent-text: #0A7370;      /* accent darkened to ≥4.5:1 for small text on paper AND band */
  --accent-bright: #36C7C1;
  --error: #B3261E;            /* invalid-input border; 5.8:1 on --paper-band, non-text 1.4.11 */
  --hero-base: #0D1F24;
  --night: #101B1F;            /* dark gallery band */
  --set-aside-band: #E9F1EF;   /* Set-aside chapter: the page's one cool accent-washed band */
  --footer-bg: #2B2926;
  --footer-ink: #FCFBF8;

  --serif: ui-serif, 'New York', Georgia, 'Times New Roman', serif;
  --sans: -apple-system, 'SF Pro Text', 'SF Pro Display', system-ui, sans-serif;
  --mono: ui-monospace, 'SF Mono', Menlo, monospace;

  /* Type scale. Seven steps anchored on the 16px body DESIGN.md commits to,
     stepping ~1.07-1.13, with the small end generally tighter than the middle.
     Steps are roles, not sizes: a step can carry a sans paragraph and a serif
     subhead at once, with family, weight, and color doing the rest of the
     hierarchy. Two things sit outside the scale on purpose -- the seven
     clamp() headings (.hero h1, the shared chapter h2, .turn, .signup h3,
     .footer h2, .doc h1, .doc h2), which stay fluid, and `.doc code`, which is
     relative to whatever prose contains it.
     --type-label is a floor as well as a step. It carries the hero kicker and
     the CTA qualifier over photography -- raised from 11px/11.5px because a
     scrim over a photograph does not hold a fixed contrast ratio, so the two
     smallest sizes on the page had the least margin exactly where the
     background was least predictable (commit 343ab0e; not a WCAG 1.4.3 size
     threshold, which only distinguishes 24px+ large text). It also carries the
     nav links, whose 24px hit area (WCAG 2.5.8) is measured from it. Nothing on
     the page may go below it. --type-body is likewise load-bearing: the signup
     input zooms iOS Safari on focus below 16px. */
  --type-label: 12.5px;      /* mono chapter labels, nav, fine print */
  --type-meta: 13.5px;       /* figure captions, form status, secondary links */
  --type-compact: 14.5px;    /* list prose, the signup button, the skip link */
  --type-body: 16px;         /* default prose, and the primary .cta-btn */
  --type-lead: 18px;         /* hero sub, serif subheads */
  --type-title: 20px;        /* serif h3, the wordmark, the FAQ +/x glyph */
  --type-title-lg: 22px;     /* the promoted Before 1.0 h3 */

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --overhang: clamp(60px, 11vw, 140px);   /* how far the hero screenshot dips into the problem band */
  --pad-x: clamp(20px, 5vw, 52px);

  --z-skip: 20;
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  overflow-x: clip;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--type-body);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3 { text-wrap: balance; }
p { text-wrap: pretty; }
img { max-width: 100%; }
::selection { background: rgba(12, 143, 140, 0.22); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Over photography and dark bands, a white outline with a dark halo stays
   visible on both light and dark photo regions. */
.hero :focus-visible, .footer :focus-visible, .page-top :focus-visible {
  outline-color: #fff;
  box-shadow: 0 0 0 5px rgba(10, 18, 20, 0.65);
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: fixed; top: 10px; left: 10px; z-index: var(--z-skip);
  background: var(--ink); color: var(--paper);
  padding: 10px 16px; border-radius: 8px; font-size: var(--type-compact); font-weight: 600;
  text-decoration: none; transform: translateY(-64px); transition: transform 0.2s var(--ease);
}
.skip-link:focus { transform: translateY(0); }

.shell { max-width: 1104px; margin: 0 auto; padding-inline: var(--pad-x); }
.shell--wide { max-width: 1200px; }
.shell--narrow { max-width: 840px; }

/* ---------- Hero ---------- */
.hero { position: relative; background: var(--hero-base); }
.hero-photo {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center 40%;
}
.hero-scrim { position: absolute; inset: 0; }
.hero-scrim::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg,
    rgba(14, 22, 25, 0.62) 0%,
    rgba(15, 23, 26, 0.42) 30%,
    rgba(14, 22, 25, 0.34) 56%,
    rgba(233, 229, 222, 0) 72%,
    rgba(233, 229, 222, 0.82) 88%,
    var(--paper) 100%);
}
/* Second layer: top radial plus a copy-centered vignette so hero text and its
   focus indicators keep AA contrast over the photo's bright mist band. */
.hero-scrim::after {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(120% 60% at 50% 0%, rgba(10, 18, 20, 0.32), rgba(10, 18, 20, 0) 55%),
    radial-gradient(64% 38% at 50% 36%,
      rgba(10, 18, 20, 0.42) 0%,
      rgba(10, 18, 20, 0.30) 55%,
      rgba(10, 18, 20, 0) 80%);
}
.hero-inner {
  position: relative; max-width: 1240px; margin: 0 auto;
  padding: 30px var(--pad-x) 0;
}

/* Nav */
.site-nav { display: flex; align-items: center; gap: 14px; }
.brand { display: inline-flex; align-items: center; gap: 12px; text-decoration: none; }
.brand-mark { width: 28px; height: 28px; border-radius: 8px; display: block; }
.brand-name { font-family: var(--serif); font-size: var(--type-title); font-weight: 600; color: #fff; letter-spacing: 0.01em; }
.nav-links { display: flex; gap: 32px; margin: 0 0 0 auto; padding: 0; list-style: none; }
.nav-links a {
  font-size: var(--type-label); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  white-space: nowrap;
  color: rgba(255, 255, 255, 0.88); text-decoration: none;
  /* Two-value form is deliberate: block-end stays 3px (unchanged, it sets the
     gap to the :hover border-bottom below); block-start is new, added only to
     grow the hit area past the 24px minimum. A single-value padding-block
     would silently move the underline instead. `a` stays inline, so this
     padding grows the clickable/hoverable box without affecting the line
     box the nav row is sized from -- text position and row height hold. */
  padding-block: 8px 3px; border-bottom: 1px solid transparent;
  transition: border-color 0.25s var(--ease), color 0.25s var(--ease);
}
.nav-links a:hover { color: #fff; border-bottom-color: rgba(255, 255, 255, 0.6); }
.nav-cta {
  margin-left: 18px; height: 36px; padding: 0 18px; border-radius: 18px;
  display: inline-flex; align-items: center;
  background: rgba(255, 255, 255, 0.13); border: 0.5px solid rgba(255, 255, 255, 0.35);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  font-size: var(--type-label); font-weight: 600; letter-spacing: 0.03em; color: #fff; text-decoration: none;
  transition: background 0.25s var(--ease);
}
.nav-cta:hover { background: rgba(255, 255, 255, 0.22); }

/* Hero copy */
.hero-copy { max-width: 820px; margin: clamp(52px, 8vh, 84px) auto 0; text-align: center; }
.hero-kicker {
  display: inline-flex; align-items: center; gap: 9px; margin: 0 0 28px;
  font-family: var(--mono); font-size: var(--type-label); font-weight: 600;
  letter-spacing: 0.22em; text-transform: uppercase; color: rgba(255, 255, 255, 0.92);
}
.hero-kicker .rule { width: 24px; height: 1px; background: rgba(255, 255, 255, 0.55); }
.hero h1 {
  margin: 0; font-family: var(--serif); font-weight: 600;
  font-size: clamp(2.5rem, 6.2vw, 4.25rem); line-height: 1.05; letter-spacing: -0.02em;
  color: #fff; text-shadow: 0 2px 36px rgba(10, 20, 22, 0.45);
}
.hero-sub {
  max-width: 560px; margin: 24px auto 0; font-size: var(--type-lead); line-height: 1.65;
  color: rgba(255, 255, 255, 0.95); text-shadow: 0 1px 18px rgba(10, 20, 22, 0.55);
}

/* CTA block (hero + footer) */
.cta { display: flex; flex-direction: column; align-items: center; gap: 12px; margin: 34px auto 0; }
.cta-btn {
  height: 54px; padding: 0 34px; border-radius: 27px;
  display: inline-flex; align-items: center;
  background: var(--paper); color: #1C1B19; text-decoration: none;
  font-size: var(--type-body); font-weight: 600; letter-spacing: 0.01em;
  box-shadow: 0 10px 30px -8px rgba(10, 20, 22, 0.55);
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.cta-btn:hover { transform: translateY(-1px); }
.cta-btn:active { transform: translateY(0); }
.cta-fine {
  margin: 0; font-family: var(--mono); font-size: var(--type-label); letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.92);
  text-shadow: 0 1px 14px rgba(10, 20, 22, 0.85), 0 0 4px rgba(10, 20, 22, 0.5);
}
.cta-alt {
  margin-top: 10px; padding: 4px 8px;
  font-size: var(--type-meta); color: #fff; text-decoration: underline; text-underline-offset: 3px;
  text-shadow: 0 1px 14px rgba(10, 20, 22, 0.85);
}
.cta--dark .cta-btn { background: var(--accent-bright); color: #0F2B2A; box-shadow: none; }
.cta--dark .cta-fine { color: rgba(255, 251, 244, 0.78); text-shadow: none; }
.cta--dark .cta-alt { color: rgba(255, 251, 244, 0.88); text-shadow: none; }

/* Hero screenshot, overhanging into the problem band */
/* .shot.hero-shot: outranks the later `.shot { margin: 0 }` reset, which was
   silently zeroing this margin (and the overhang) at equal specificity. */
.shot.hero-shot {
  width: min(1104px, 100%);
  margin: clamp(60px, 8vw, 96px) auto calc(var(--overhang) * -1);
}
.hero-shot .shot-clip {
  box-shadow: 0 60px 80px rgba(12, 20, 22, 0.35), 0 24px 40px rgba(12, 20, 22, 0.28),
              0 0 0 0.5px rgba(0, 0, 0, 0.12);
}

/* ---------- Screenshot figures ---------- */
.shot { margin: 0; }
.shot-clip {
  position: relative;   /* containing block for the injected .shot-open overlay */
  display: block; overflow: hidden; border-radius: 14px;
  background: var(--paper-band);
  box-shadow: 0 24px 48px -18px rgba(40, 34, 20, 0.35), 0 0 0 0.5px rgba(0, 0, 0, 0.10);
}
.shot img { display: block; width: 100%; height: auto; }
.shot figcaption, .term-figure figcaption {
  margin-top: 14px; font-size: var(--type-meta); line-height: 1.55; color: var(--ink-soft);
}
.hero-shot figcaption { text-align: center; max-width: 620px; margin-inline: auto; }
.shot--dark figcaption { color: rgba(252, 251, 248, 0.78); }
.crop-note { display: none; }

/* Purposeful crops on narrow screens: never a full 1440pt window at 25% scale.
   --cx/--cy position the 210%-wide image inside a 5:4 clip, per figure. */
@media (max-width: 720px) {
  .shot--crop .shot-clip { aspect-ratio: 5 / 4; }
  .shot--crop img {
    width: 210%; max-width: none; height: auto;
    margin-left: var(--cx, -55%); margin-top: var(--cy, -5%);
  }
  .shot--crop .crop-note { display: inline; }
}

/* ---------- Screenshot lightbox ---------- */
/* Progressive enhancement. `app.js` injects `.shot-open` into every
   `.shot-clip` and builds the `<dialog>` on first open; without JS neither
   exists and the figures render exactly as they did before. */
.shot-open {
  position: absolute; inset: 0;
  /* Bottom-right, not top-right: the captures all carry a macOS toolbar along
     their top edge, and a pill up there reads as part of the app. */
  display: flex; align-items: flex-end; justify-content: flex-end;
  padding: clamp(10px, 1.4vw, 16px);
  margin: 0; border: 0; background: transparent;
  -webkit-appearance: none; appearance: none; cursor: zoom-in;
}
/* The page's over-photography focus treatment (white line, dark halo) turned
   inward, because `.shot-clip` clips an outline away. Dark outermost so the
   ring's outer edge clears 3:1 against the light paper bands; the white line
   inside it carries the same job over the dark gallery band. */
.shot-open:focus-visible {
  outline: none;
  background: rgba(10, 18, 20, 0.30);
  box-shadow: inset 0 0 0 3px rgba(8, 16, 18, 0.92), inset 0 0 0 6px #fff;
}
/* The affordance itself: the nav pill's recipe at icon size, inverted to a
   dark fill. Light-on-light is not an option here, since what sits underneath
   is whatever the capture happens to show. */
.shot-zoom {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 16px;
  background: rgba(10, 18, 20, 0.82);
  border: 0.5px solid rgba(255, 255, 255, 0.35);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  color: #fff;
  /* Held back until the pointer is on the capture, so the figures read as
     photographs of the app rather than as controls. */
  opacity: 0; transform: translateY(4px);
  transition: opacity 0.2s var(--ease), transform 0.2s var(--ease);
}
.shot-zoom svg { display: block; flex: none; }
/* Plain `:focus` as well as `:focus-visible`: whether the ring is drawn is a
   heuristic, but a focused control must never be an invisible one. */
.shot-open:hover .shot-zoom, .shot-open:focus .shot-zoom {
  opacity: 1; transform: none;
}
.shot-open:active .shot-zoom { transform: translateY(1px); }
/* Nothing hovers on a touch screen, so there the affordance is always shown. */
@media (hover: none) {
  .shot-zoom { opacity: 1; transform: none; }
}

/* Page scroll is locked behind the modal; the gutter var replaces the width a
   classic scrollbar gives up, so nothing shifts on open. */
html.has-lightbox { overflow: hidden; padding-right: var(--scrollbar-gutter, 0px); }

.lightbox {
  /* What the capture yields to the chrome around it. The top inset clears the
     close button (26px offset + 44px button, plus a gap) so the two can never
     overlap on a short window; 92px covers the caption's margin plus about
     three wrapped lines. `.lightbox-inner` scrolls if a caption runs longer. */
  --lightbox-pad: clamp(16px, 4vw, 56px);
  --lightbox-pad-top: max(var(--lightbox-pad), 82px);
  --lightbox-chrome: calc(var(--lightbox-pad-top) + var(--lightbox-pad) + 92px);
  position: fixed; inset: 0;
  width: 100%; max-width: none; height: 100%; max-height: none;
  margin: 0; padding: 0; border: 0; background: transparent;
}
.lightbox::backdrop {
  background: rgba(8, 16, 18, 0.90);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.lightbox-inner {
  height: 100%; overflow: auto;
  display: flex; justify-content: center;
  /* `safe` so a figure taller than the viewport overflows downward and stays
     scrollable, instead of centring its top edge out of reach. */
  align-items: center;
  align-items: safe center;
  padding: var(--lightbox-pad-top) var(--lightbox-pad) var(--lightbox-pad);
  cursor: zoom-out;
}
.lightbox-figure { margin: 0; max-width: 100%; cursor: default; }
.lightbox-img {
  display: block; width: auto; height: auto;
  max-width: 100%;
  max-height: calc(100vh - var(--lightbox-chrome));
  max-height: calc(100dvh - var(--lightbox-chrome));
  border-radius: clamp(8px, 1vw, 14px);
  background: var(--paper-band);
  box-shadow: 0 44px 90px -28px rgba(0, 0, 0, 0.75), 0 0 0 0.5px rgba(255, 255, 255, 0.16);
}
.lightbox-caption {
  margin: 16px auto 0; max-width: 66ch; text-align: center;
  font-size: var(--type-meta); line-height: 1.6; color: rgba(252, 251, 248, 0.84);
}
.lightbox-close {
  position: absolute; top: clamp(12px, 2.2vw, 26px); right: clamp(12px, 2.2vw, 26px);
  width: 44px; height: 44px; padding: 0; border-radius: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, 0.14); border: 0.5px solid rgba(255, 255, 255, 0.35);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  color: #fff; cursor: pointer;
  transition: background 0.25s var(--ease);
}
.lightbox-close:hover { background: rgba(255, 255, 255, 0.26); }
.lightbox-close:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

/* ---------- Section scaffolding ---------- */
/* Chapter rhythm, tightened 2026-08-02 in the page-length pass (was
   clamp(72px, 9vw, 108px)): still the page's dominant breathing room, just
   ~50px per chapter cheaper across thirteen of them. */
.problem, .chapter, .compare, .roadmap, .faq {
  padding: clamp(56px, 6.5vw, 84px) 0;
}
.chapter--band, .roadmap { background: var(--paper-band); }

.kicker {
  font-family: var(--mono); font-size: var(--type-label); font-weight: 600; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--accent-text); margin: 0 0 18px;
}
.problem h2, .chapter h2, .gallery h2, .compare h2, .roadmap h2, .faq h2 {
  font-family: var(--serif); font-size: clamp(1.9rem, 3.8vw, 2.5rem); line-height: 1.1;
  font-weight: 600; letter-spacing: -0.018em; color: var(--ink); margin: 0 0 18px;
}
.lede { font-size: var(--type-body); line-height: 1.7; color: var(--ink-soft); margin: 0; max-width: 62ch; }

.chap-head { max-width: 680px; margin: 0 0 clamp(36px, 5vw, 52px); }
.chap-head--center { margin-inline: auto; text-align: center; }
.chap-head--center .lede { margin-inline: auto; }

/* ---------- 2 · Problem ---------- */
/* The two numbered beats (and the .problem-grid split that held them) were
   folded into the lede 2026-08-02 in the page-length pass; the chapter is now
   headline, lede, and the turn line that hands off to the product. */
.problem { padding-top: calc(var(--overhang) + clamp(56px, 7vw, 84px)); }
.turn {
  margin: clamp(48px, 7vw, 80px) auto 0; max-width: 720px; text-align: center;
  font-family: var(--serif); font-size: clamp(1.3rem, 2.6vw, 1.7rem); line-height: 1.4;
  color: var(--ink);
}
.turn em { font-style: italic; }

/* ---------- 3–4 · Screenshot chapters ---------- */
.split {
  display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(32px, 5vw, 72px); align-items: center;
}
.split + .split { margin-top: clamp(56px, 8vw, 88px); }
.split--rev { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); }
.split--rev .shot { order: 2; }
.featlist { display: flex; flex-direction: column; gap: 26px; }
.feat h3 {
  font-family: var(--serif); font-size: var(--type-lead); font-weight: 600; letter-spacing: -0.01em;
  margin: 0 0 7px;
}
.feat p { margin: 0; font-size: var(--type-compact); line-height: 1.68; color: var(--ink-soft); }
/* .feat--lead (headline-weight promoted feature) was the code-highlighting
   item's treatment while it owned its own split. Retired 2026-08-02: at list
   size it competed with the chapter headline instead of leading a column. */

/* ---------- 5 · Set aside ---------- */
/* The page's one accent-washed band: a cool tint of the teal between warm
   paper and warm band, so the shipped differentiator reads as its own
   material moment. Figure composition matches Listen's centered single shot. */
.chapter--set-aside {
  background: var(--set-aside-band);
  /* Cool-tinted hairlines: the wash reads as a set-in band, not a color drift. */
  border-block: 1px solid rgba(10, 82, 80, 0.16);
}
.set-aside-shot { max-width: 920px; margin: 0 auto; }

/* ---------- Proof lists (Listen, Made for the Mac) ---------- */
.prooflist {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: 1fr 1fr; gap: 34px 56px;
}
.prooflist li { border-top: 1px solid var(--line); padding-top: 20px; }
/* An odd count would orphan the last item beside an empty cell; span it and cap its measure. */
.prooflist li:last-child:nth-child(odd) { grid-column: 1 / -1; }
.prooflist li:last-child:nth-child(odd) p { max-width: 62ch; }
.prooflist h3 {
  font-family: var(--serif); font-size: var(--type-lead); font-weight: 600; letter-spacing: -0.01em;
  margin: 0 0 8px;
}
.prooflist p { margin: 0; font-size: var(--type-compact); line-height: 1.68; color: var(--ink-soft); }

/* ---------- 7 · Listen ---------- */
.listen-shot { max-width: 920px; margin: 0 auto clamp(44px, 6vw, 72px); }

/* ---------- 7b · Agents (MCP) ---------- */
/* The page's one figure that is not a capture: an agent's transcript re-set
   as live HTML in the page's mono voice, on the gallery's --night so it reads
   as the same material as the dark band that follows it. Live text, never an
   image: a screen reader gets the transcript, the numbers stay selectable, and
   it costs no bytes. It is not a `.shot`, so app.js injects no lightbox. The
   alpha values below flatten against --night to >= 5.5:1 for the dim voice
   (0.58) and ~13:1 for the reply voice (0.86). */
.term-figure { margin: 0; min-width: 0; }
.split--rev .term-figure { order: 2; }
/* The transcript runs taller than its feature list, so this split top-aligns:
   centered, the list would float in a hole under the lede. */
.split--agents { align-items: start; }
.split--agents .featlist { padding-top: 6px; }
.term {
  overflow: hidden; border-radius: 14px;
  background: var(--night); color: rgba(252, 251, 248, 0.86);
  font-family: var(--mono); font-size: var(--type-meta); line-height: 1.6;
  box-shadow: 0 32px 60px -20px rgba(16, 27, 31, 0.55), 0 0 0 0.5px rgba(0, 0, 0, 0.18);
}
.term-bar {
  display: flex; align-items: center; gap: 8px; padding: 12px 16px;
  background: rgba(255, 255, 255, 0.05); border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.term-dot { width: 12px; height: 12px; border-radius: 6px; background: rgba(255, 255, 255, 0.18); }
.term-title {
  /* Centered over the whole bar: the three dots plus two gaps are 52px wide, so
     an equal right inset keeps the label on the bar's true middle. */
  flex: 1; text-align: center; padding-right: 52px;
  font-size: var(--type-label); letter-spacing: 0.04em; color: rgba(252, 251, 248, 0.58);
}
.term-body { padding: 20px 24px 18px; }
.term-body p, .term-body ul, .term-body ol { margin: 0; }
.term-body b { font-weight: 600; color: var(--paper); }
.term-body > * + * { margin-top: 12px; }
.term-prompt {
  display: flex; gap: 10px; align-items: baseline;
  margin-inline: -10px; padding: 5px 10px; border-radius: 6px;
  background: rgba(255, 255, 255, 0.07); color: var(--paper); font-weight: 600;
}
.term-line + .term-prompt { margin-top: 22px; }
/* A prompt row and the reply that answers it breathe apart, like the real
   session: the reply is a new paragraph, not a continuation of the row. */
.term-prompt + .term-reply { margin-top: 22px; }
.term-caret, .term-bullet { flex: none; color: var(--accent-bright); }
.term-reply { display: flex; gap: 10px; align-items: baseline; }
.term-line, .term-list { padding-left: 20px; }
.term-list { list-style: none; }
/* Hanging indent in exact mono units, and the alt-text form on generated
   glyphs (as the FAQ marker does) so a screen reader never speaks them. */
.term-list li { padding-left: 2ch; text-indent: -2ch; }
.term-list li::before { content: "- "; content: "- " / ""; color: rgba(252, 251, 248, 0.58); }
.term-list li + li { margin-top: 2px; }

/* ---------- 8 · Made for the Mac (light/dark gallery) ---------- */
.gallery { background: var(--night); padding: clamp(72px, 9vw, 108px) 0; }
/* Dark-band variants of the chapter voice. */
.gallery h2 { color: var(--paper); }
.gallery .kicker { color: var(--accent-bright); }
.gallery .lede { color: rgba(252, 251, 248, 0.78); }
.gallery .prooflist { margin-bottom: clamp(48px, 7vw, 80px); }
.gallery .prooflist li { border-top-color: rgba(255, 255, 255, 0.16); }
.gallery .prooflist h3 { color: var(--paper); }
.gallery .prooflist p { color: rgba(252, 251, 248, 0.74); }
.gallery-pair {
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(20px, 3vw, 36px);
  align-items: start;
}
.gallery .shot-clip {
  box-shadow: 0 32px 60px -20px rgba(0, 0, 0, 0.6), 0 0 0 0.5px rgba(255, 255, 255, 0.10);
  background: #1C1B19;
}
.gallery-note {
  margin: 30px auto 0; max-width: 640px; text-align: center;
  font-size: var(--type-compact); line-height: 1.6; color: rgba(252, 251, 248, 0.85);
}

/* ---------- 9 · Comparison ---------- */
.compare-rows { border-bottom: 1px solid var(--line); }
.compare-row {
  display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 16px 40px;
  border-top: 1px solid var(--line); padding: 28px 0;
}
.compare-row h3 {
  font-family: var(--serif); font-size: var(--type-title); font-weight: 600; letter-spacing: -0.01em;
  margin: 0;
}
.compare-row p { margin: 0; font-size: var(--type-compact); line-height: 1.7; color: var(--ink-soft); }
/* .compare-close styled the comparison chapter's closing italic line; removed 2026-08-02. */

/* 10 · Coastal interlude was here; the chapter was cut 2026-08-02 in the
   page-length pass and its rules went with it. */

/* ---------- 11 · Roadmap + signup ---------- */
.roadmap-item { border-top: 1px solid var(--line); padding-top: 20px; }
.roadmap-item h3 {
  font-family: var(--serif); font-size: var(--type-title-lg); font-weight: 600; letter-spacing: -0.01em;
  margin: 0 0 10px;
}
.roadmap-item p { margin: 0; font-size: var(--type-body); line-height: 1.7; color: var(--ink-soft); max-width: 52ch; }
.signup {
  margin: clamp(56px, 8vw, 80px) auto 0; padding-top: clamp(40px, 6vw, 56px);
  border-top: 1px solid var(--line);
  max-width: 620px; text-align: center;
}
.signup h3 {
  font-family: var(--serif); font-size: clamp(1.5rem, 2.8vw, 1.75rem); font-weight: 600;
  letter-spacing: -0.015em; margin: 0 0 10px;
}
.signup-lede { margin: 0 0 24px; font-size: var(--type-body); color: var(--ink-soft); }
.signup-form {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 10px;
  max-width: 460px; margin: 0 auto;
}
.signup-form input {
  flex: 1; min-width: 220px; height: 50px; border-radius: 25px; padding: 0 22px;
  font-family: var(--sans); font-size: var(--type-body); color: var(--ink);
  background: #fff; border: 1px solid rgba(56, 52, 44, 0.60);
}
.signup-form input::placeholder { color: var(--ink-soft); }
.signup-form input[aria-invalid="true"] {
  border-color: var(--error);
  box-shadow: 0 0 0 3px rgba(179, 38, 30, 0.16);
}
.signup-form button {
  height: 50px; padding: 0 24px; border: 0; border-radius: 25px; cursor: pointer;
  background: var(--accent-text); color: #fff;
  font-family: var(--sans); font-size: var(--type-compact); font-weight: 600; letter-spacing: 0.01em;
  transition: transform 0.25s var(--ease);
}
.signup-form button:hover { transform: translateY(-1px); }
.signup-form button:active { transform: translateY(0); }
.signup-form button[aria-disabled="true"] {
  background: rgba(10, 115, 112, 0.9); /* flattens to #21807C on --paper-band; 4.75:1 for #fff text */
  cursor: default;
}
.signup-form button[aria-disabled="true"]:hover,
.signup-form button[aria-disabled="true"]:active {
  transform: none;
}
.signup-status {
  flex-basis: 100%; margin: 6px 0 0; min-height: 1.4em; font-size: var(--type-meta);
  color: var(--ink); text-align: center;
}
.signup-status:empty { margin: 0; min-height: 0; }
.signup-note {
  margin: 16px auto 0; max-width: 46ch; font-size: var(--type-label); line-height: 1.6;
  color: var(--ink-soft);
}

/* ---------- 12 · FAQ ---------- */
.faq details { border-top: 1px solid var(--line); }
.faq details:last-of-type { border-bottom: 1px solid var(--line); }
.faq summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: baseline; justify-content: space-between; gap: 24px;
  padding: 20px 0;
  font-family: var(--serif); font-size: var(--type-lead); font-weight: 600; letter-spacing: -0.01em;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  /* Plain content first: browsers without alt-text syntax keep the marker. */
  content: "+";
  content: "+" / "";
  flex: none; font-family: var(--sans); font-size: var(--type-title); font-weight: 400;
  line-height: 1; color: var(--accent-text); transition: rotate 0.25s var(--ease);
}
.faq details[open] summary::after { rotate: 45deg; }
.faq details p {
  margin: 0; padding: 0 0 26px; max-width: 68ch;
  font-size: var(--type-body); line-height: 1.7; color: var(--ink-soft);
}

/* ---------- 13 · Final CTA / footer ---------- */
.footer { background: var(--footer-bg); padding: clamp(64px, 8vw, 92px) var(--pad-x) clamp(56px, 7vw, 80px); }
.footer-inner { max-width: 640px; margin: 0 auto; text-align: center; }
.footer h2 {
  font-family: var(--serif); font-size: clamp(2rem, 4.2vw, 2.75rem); line-height: 1.1;
  font-weight: 600; letter-spacing: -0.02em; color: var(--footer-ink); margin: 0 0 18px;
}
.footer-lede { font-size: var(--type-body); line-height: 1.7; color: rgba(255, 251, 244, 0.78); margin: 0; }
.footer .cta { margin-top: 30px; }
.footer-brand {
  margin: 48px 0 0; display: flex; align-items: center; justify-content: center;
  gap: 11px; flex-wrap: wrap;
}
.footer-brand .brand-mark { width: 24px; height: 24px; border-radius: 7px; }
.footer-brand b { font-family: var(--serif); font-size: var(--type-body); font-weight: 600; color: var(--footer-ink); }
.footer-brand span { font-size: var(--type-label); color: rgba(255, 251, 244, 0.68); margin-left: 6px; }
.footer-credits { margin: 26px 0 0; font-size: var(--type-label); line-height: 1.7; color: rgba(255, 251, 244, 0.68); }
.footer-credits a, .footer-meta a { color: rgba(255, 251, 244, 0.85); text-decoration: underline; text-underline-offset: 2px; }
.footer-credits a:hover, .footer-meta a:hover { color: var(--footer-ink); }
.footer-meta { margin: 14px 0 0; font-size: var(--type-label); line-height: 1.7; color: rgba(255, 251, 244, 0.68); }
.footer--slim { padding-block: clamp(40px, 5vw, 56px); }
.footer--slim .footer-brand { margin-top: 0; }
/* Short pages (pro/thanks): keep the footer at the window's bottom edge. */
.body--stick { min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; }
.body--stick main { flex: 1 0 auto; }

/* ---------- Subpages (privacy) ---------- */
/* Same nav shell as the hero, on a solid dark band instead of photography. */
.page-top { background: var(--hero-base); }
.page-top-inner { max-width: 1240px; margin: 0 auto; padding: 30px var(--pad-x) 32px; }

.doc { padding: clamp(56px, 8vw, 88px) 0 clamp(72px, 9vw, 108px); }
.doc-head { margin: 0 0 clamp(36px, 5vw, 52px); }
.doc h1 {
  font-family: var(--serif); font-size: clamp(2.1rem, 4.6vw, 3rem); line-height: 1.08;
  font-weight: 600; letter-spacing: -0.02em; color: var(--ink); margin: 0 0 18px;
}
.doc-updated {
  margin: 22px 0 0; font-family: var(--mono); font-size: var(--type-label); font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-soft);
}
.doc section { border-top: 1px solid var(--line); padding-top: clamp(28px, 4vw, 40px); }
.doc section + section { margin-top: clamp(32px, 5vw, 48px); }
.doc h2 {
  font-family: var(--serif); font-size: clamp(1.4rem, 2.6vw, 1.75rem); line-height: 1.15;
  font-weight: 600; letter-spacing: -0.015em; color: var(--ink); margin: 0 0 14px;
}
.doc section p, .doc section li { font-size: var(--type-body); line-height: 1.7; color: var(--ink-soft); max-width: 68ch; }
.doc section p { margin: 0 0 14px; }
.doc section p:last-child { margin-bottom: 0; }
.doc ul { margin: 0 0 14px; padding-left: 1.25em; }
.doc li { margin-bottom: 10px; }
.doc li:last-child { margin-bottom: 0; }
.doc li strong { color: var(--ink); font-weight: 600; }
.doc a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 3px; }
.doc a:hover { color: var(--ink); }
.doc code { font-family: var(--mono); font-size: 0.92em; }

/* The secondary pages (download, FAQ, changelog, comparisons) share the
   privacy page's chrome and add a few roles the policy page never needed. */
.doc h3 {
  font-family: var(--serif); font-size: var(--type-lead); font-weight: 600; letter-spacing: -0.01em;
  color: var(--ink); margin: 26px 0 8px;
}
.doc h2 + h3 { margin-top: 0; }
.doc .doc-meta {
  margin: 0 0 14px; font-family: var(--mono); font-size: var(--type-label); letter-spacing: 0.06em;
  color: var(--ink-soft);
}
.doc ol { margin: 0 0 14px; padding-left: 1.4em; }
.doc-head .lede { margin-bottom: 26px; }
/* The download block on paper: the button at left, and beside it a two-line
   meta column (the mono qualifier, then the secondary links) so nothing
   stacks into a ragged column. The hero's .cta-btn is paper-on-photograph, so
   here the fill flips to the accent and the qualifier loses its halo. On a
   narrow screen the column wraps under the button and left-aligns with it.
   `.doc a` (underline, ink on hover) and `.doc section p` (body size, 14px
   margin, 68ch measure) outrank the bare component rules, so these are
   written at .doc specificity on purpose. */
.doc .cta--paper {
  flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: flex-start;
  gap: 16px 24px; margin: 0;
}
.doc section .cta--paper { margin-top: 28px; }
.doc .cta-btn, .doc .cta-btn:hover { background: var(--accent-text); color: #fff; box-shadow: none; text-decoration: none; }
.doc .cta-meta { display: flex; flex-direction: column; gap: 5px; flex: 1 1 240px; min-width: 0; }
.doc .cta-fine, .doc .cta-links { margin: 0; max-width: none; text-shadow: none; line-height: 1.5; }
.doc .cta-fine { font-size: var(--type-label); color: var(--ink-soft); }
.doc .cta-links { font-size: var(--type-meta); color: var(--ink-soft); }
.doc .cta-alt { margin: 0; padding: 0; color: var(--accent-text); text-shadow: none; }
/* Comparison hub: the homepage's hairline rows, each row a link to its page. */
.doc .compare-row h3 { margin: 0; }
.doc .compare-row p { font-size: var(--type-compact); }
.compare-row h3 a { color: inherit; text-decoration: none; }
.compare-row h3 a:hover { text-decoration: underline; text-underline-offset: 3px; }
/* Changelog: one section per release, categories as mono labels. */
.release-head { display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap; margin: 0 0 6px; }
.release-head h2 { margin: 0; }
.release-head h2 a { color: inherit; text-decoration: none; }
.release-head h2 a:hover { text-decoration: underline; text-underline-offset: 3px; }
.release-date { font-family: var(--mono); font-size: var(--type-label); letter-spacing: 0.06em; color: var(--ink-soft); }
.doc .release h3 {
  font-family: var(--mono); font-size: var(--type-label); font-weight: 600; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--accent-text); margin: 20px 0 8px;
}
/* A quiet pointer from a homepage chapter to its full page. */
.more-link, .doc .more-link { margin: 26px 0 0; font-size: var(--type-compact); }
.more-link a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 3px; }
.more-link a:hover { color: var(--ink); }

/* ---------- Motion ---------- */
/* The hero entrance animates transform only — never opacity — so a stalled
   animation clock (headless renderers, throttled tabs, no-JS edge cases) can
   never leave content invisible; worst case it sits 22px low. */
@media (prefers-reduced-motion: no-preference) {
  .rise { animation: rise 0.9s var(--ease) both; animation-delay: calc(var(--d, 0) * 95ms); }
  @keyframes rise {
    from { transform: translateY(22px); }
    to   { transform: translateY(0); }
  }
  /* The lightbox opening: the capture rises into an already-drawn veil.
     Transform only, for the same reason the hero rise is transform only — a
     stalled animation clock must never leave a focus-trapping modal without
     its scrim or its content. Worst case the capture sits 10px low. */
  .lightbox[open] .lightbox-figure { animation: lightbox-rise 0.36s var(--ease) both; }
  @keyframes lightbox-rise {
    from { transform: scale(0.97) translateY(10px); }
    to   { transform: none; }
  }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .faq summary::after { transition: none; }
  .cta-btn, .signup-form button, .skip-link { transition: none; }
  .shot-zoom, .lightbox-close { transition: none; }
}

/* ---------- Forced colors ---------- */
/* Windows High Contrast (and any UA in forced-colors mode) drops box-shadow
   and translucency outright and remaps most author colors to a small system
   palette. Nothing above this block accounts for that, and five affordances
   on this page are drawn entirely from the properties forced colors removes.
   System color keywords only (Canvas / CanvasText / ButtonFace / ButtonText /
   Highlight / HighlightText) so every value below is one the UA already
   recognizes as its own palette; none of it is a `forced-color-adjust: none`
   escape hatch, since nothing here needs to survive as a literal brand color. */
@media (forced-colors: active) {
  /* The worst of the set. `.shot-open:focus-visible` sets `outline: none`
     and draws its whole ring from `inset` box-shadow, because `.shot-clip`'s
     `overflow: hidden` clips a real outline away. Forced colors drops
     box-shadow, so unpatched this control has no focus indicator at all --
     the only true keyboard-blocking failure in the set.
     `outline` is honored under forced colors, and is not clipped the way a
     bare outline would be here: `.shot-open` is `position: absolute; inset: 0`
     with no border or padding of its own, so its border box exactly coincides
     with `.shot-clip`'s clip boundary. Setting `outline-offset` to the
     negative of `outline-width` puts the outline's outer edge exactly at that
     boundary (inner edge -3px, outer edge -3px + 3px = 0), so the whole ring
     sits flush with the edge and inside it, never in the region that gets
     clipped away. Re-derive this if either rule's box model changes. */
  .shot-open:focus-visible {
    outline: 3px solid Highlight;
    outline-offset: -3px;
    background: transparent; /* keep the capture visible under the ring */
  }

  /* `.shot-zoom` and `.lightbox-close` are translucent glass pills over
     arbitrary photo content, with a `backdrop-filter` blur and a
     `currentColor`-stroked SVG glyph. Forced colors drops the blur and the
     alpha, so a literal system-color fill replaces the glass: ButtonFace
     reads as a control surface against whatever capture sits underneath,
     ButtonText keeps a visible edge and also recolors the `currentColor`
     glyph inside each pill. */
  .shot-zoom, .lightbox-close {
    background: ButtonFace;
    border: 1px solid ButtonText;
    color: ButtonText;
  }

  /* `.faq summary::after` marks open/closed by rotating
     a generated "+"/"x" glyph. The rotation carries the state on its own and
     survives forced colors untouched; the `--accent-text` color that draws
     the glyph does not. ButtonText keeps it visible in either state. */
  .faq summary::after {
    color: ButtonText;
  }

  /* `.lightbox::backdrop` is a translucent scrim; it is
     the only thing separating the modal from the page behind it. Forced
     colors drops the alpha, and without an explicit value a `::backdrop`
     can resolve to the same Canvas as the page it is meant to cover. An
     explicit Canvas fill keeps it opaque and reads as distinct from the
     ButtonFace close button and the capture itself. */
  .lightbox::backdrop {
    background: Canvas;
  }

  /* `.skip-link` relies on `--ink`/`--paper`. ButtonFace/
     ButtonText render it as the same kind of control forced colors already
     draws real buttons as, with a border so its edge holds against Canvas. */
  .skip-link {
    background: ButtonFace;
    color: ButtonText;
    border: 1px solid ButtonText;
  }

  /* `.term` is drawn entirely from its dark fill and two shadow layers, and
     forced colors drops both, leaving the transcript with no window edge.
     The text itself survives (CanvasText on Canvas). */
  .term {
    border: 1px solid CanvasText;
  }
}

/* ---------- Responsive ---------- */
/* Three decision links (Comparison / Before 1.0 / FAQ): hide them before
   they can crowd the brand and wrap the download pill. */
@media (max-width: 700px) {
  .site-nav { gap: 8px; }
  .nav-links { display: none; }
  .nav-cta { margin-left: auto; padding-inline: 14px; }
}
@media (max-width: 860px) {
  .split, .split--rev { grid-template-columns: 1fr; gap: 28px; }
  .split--rev .shot, .split--rev .term-figure { order: 0; }
  .gallery-pair { grid-template-columns: 1fr; gap: 40px; }
}
@media (max-width: 720px) {
  .term-body { padding: 16px 16px 14px; }
  .term-prompt { margin-inline: -6px; padding-inline: 6px; }
  .term-line, .term-list { padding-left: 0; }
  .prooflist { grid-template-columns: 1fr; gap: 26px; }
  .prooflist li:last-child:nth-child(odd) p { max-width: none; }
  .compare-row { grid-template-columns: 1fr; gap: 8px; padding: 24px 0; }
}
