/* Hallmark · macrostructure: Narrative Workflow · tone: editorial-dark · anchor hue: warm (gold 84°)
 * genre: atmospheric-on-brand · theme: brand-matched (homepage-derived)
 * nav: N9 edge-aligned · footer: Ft1 mast-headed · enrichment: E-ledger (Tier A CSS art, labelled illustrative)
 * pre-emit critique: P5 H5 E5 S5 R4 V5
 */

@import url("/assets/tokens.css?v=20260830q");

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

html, body { overflow-x: clip; margin: 0; padding: 0; }

body {
  background: var(--color-paper);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

.wrap { max-width: 74rem; margin-inline: auto; padding-inline: var(--page-gutter); }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-style: normal;                /* italic headers banned — gate 38a */
  line-height: 1.02;
  letter-spacing: -0.022em;
  overflow-wrap: anywhere;
  /* The h1 was breaking mid-phrase ('Not just the / one you're in.') and .climb's heading
     dropped SERVE onto a line of its own. balance evens the rag and kills the orphan. */
  text-wrap: balance;
  min-width: 0;
  margin: 0;
}
h1 { font-size: var(--text-display); }
h2 { font-size: var(--text-3xl); margin-block: var(--space-xl) var(--space-sm); }
h3 { font-size: var(--text-lg); margin-block: var(--space-lg) var(--space-2xs); }

p { margin: 0 0 var(--space-sm); max-width: var(--measure); text-wrap: pretty; }
ul, ol { max-width: var(--measure); padding-left: 1.15rem; }
li { margin-bottom: var(--space-2xs); text-wrap: pretty; }

a { color: var(--color-ink); text-decoration-color: var(--color-accent); text-underline-offset: 0.18em; }
a:hover { color: var(--color-accent-deep); }
:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }

strong { font-weight: 700; }
mark { background: var(--color-accent-wash); padding: 0 0.15em; }

/* ============================================================ N9 · nav ==== */

.nav-edge {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-md);
  padding: var(--space-sm) var(--page-gutter);
  background: var(--color-night);
  border-bottom: var(--rule-hair) solid var(--color-night-rule);
  flex-wrap: wrap;
}
.nav-edge__mark {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--text-lg); color: var(--color-on-night);
  text-decoration: none; white-space: nowrap; letter-spacing: -0.02em;
}
.nav-edge__mark span { color: var(--color-accent); }
.nav-edge__links { display: flex; gap: var(--space-md); list-style: none; margin: 0; padding: 0; flex-wrap: wrap; }
.nav-edge__links a {
  font-size: var(--text-sm); color: var(--color-on-night-2); text-decoration: none;
  white-space: nowrap; padding-block: var(--space-3xs);
  border-bottom: 2px solid transparent;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.nav-edge__links a:hover { color: var(--color-on-night); border-bottom-color: var(--color-accent); }

/* ====================================================== the dark hero ===== */

.lede {
  background: var(--color-night);
  color: var(--color-on-night);
  /* Measured: at 1280x720 the old fixed padding pushed the band to 795px in a 720px viewport,
   * so the fold cut it. Sizing against dvh keeps the whole argument on one screen without
   * forcing a rigid 100vh box on tall screens. 4.5rem is the nav. */
  padding-block: clamp(1.75rem, 4.5vh, 4rem);
  min-height: min(46rem, calc(100dvh - var(--nav-h)));
  display: grid; align-content: center;
  position: relative;
  isolation: isolate;
}
/* A single warm bloom anchored behind the headline — depth without a gradient wash. */
.lede::before {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(58rem 34rem at 18% 12%, oklch(30% 0.055 74 / 0.55), transparent 62%),
    radial-gradient(40rem 28rem at 88% 72%, oklch(26% 0.040 84 / 0.40), transparent 66%);
}
.lede__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: var(--space-xl);
  align-items: center;
}
.lede__kicker {
  font-size: var(--text-xs); letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--color-accent); margin: 0 0 var(--space-md);
  display: flex; align-items: center; gap: var(--space-2xs);
}
.lede__kicker::before {
  content: ""; width: 2.25rem; height: 2px; background: var(--color-accent); flex: none;
}
/* min(vw, vh) so a short laptop viewport shrinks the headline instead of pushing the CTA under the fold. */
.lede h1 { color: var(--color-on-night); max-width: 19ch;
  font-size: clamp(2rem, min(4.2vw, 5.4vh), 3.5rem); line-height: 1.04; }
.lede h1 em { font-style: normal; color: var(--color-accent); }
.lede__standfirst {
  font-size: var(--text-lg); color: var(--color-on-night-2);
  max-width: 46ch; margin-top: var(--space-md);
}
.lede__standfirst strong { color: var(--color-on-night); font-weight: 600; }
/* The standfirst is a <div>, not a <p>, so it missed the `p { text-wrap: pretty }` rule.
   It is the hero's body copy and rags over six lines -- it needs it more than most. */
.lede__standfirst { text-wrap: pretty; }
/* The scarcity line. It was authored inline in index.html as #b23b0f at 15px, which broke
   the tokens rule at the top of tokens.css, measured 3.25:1 on the night band, and put a
   15px step into a scale that has none. --color-alert measures 6.36:1 here. */
.lede__slots {
  margin: 0 0 var(--space-sm);
  font-size: var(--text-sm); font-weight: 600;
  color: var(--color-alert);
}
.lede__slots b { font-weight: 700; }
.lede__cta { margin-top: var(--space-lg); display: flex; flex-wrap: wrap; gap: var(--space-sm); align-items: center; }

@media (max-width: 60rem) {
  .lede__grid { grid-template-columns: minmax(0, 1fr); gap: var(--space-lg); }
  .lede { padding-block: var(--space-lg); min-height: 0; }
  /* On a phone the visual was pushing the CTA to 877px in an 844px viewport -- i.e. the button
   * was below the fold. Copy and CTA first, sequence second. */
  .lede__copy { order: 1; }
  .lede .climb, .lede .ledger, .lede__demo, .lede > .wrap .demo { order: 2; }
  .lede__standfirst { font-size: var(--text-base); }
}

/* ================================================ the ledger artifact ===== */
/* Tier-A CSS art. Dramatises the offer: which pages earned their fee, which did not.
   Explicitly labelled illustrative — it is a diagram of the billing rule, not a screenshot
   of anyone's data, and it must never be presented as one. */

.ledger {
  background: var(--color-night-2);
  border: var(--rule-hair) solid var(--color-night-rule);
  border-radius: var(--radius-lg);
  padding: var(--space-md);
  box-shadow: 0 1px 2px oklch(0% 0 0 / .28), 0 6px 14px -8px oklch(0% 0 0 / .5);
  font-size: var(--text-sm);
  min-width: 0;
}
.ledger__head {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--space-sm);
  padding-bottom: var(--space-xs);
  border-bottom: var(--rule-hair) solid var(--color-night-rule);
  color: var(--color-on-night-2);
  font-size: var(--text-xs); letter-spacing: 0.1em; text-transform: uppercase;
}
.ledger__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 4.2rem 3.4rem 4.6rem;
  gap: var(--space-2xs);
  align-items: center;
  padding-block: var(--space-2xs);
  border-bottom: var(--rule-hair) solid oklch(30% 0.014 70 / 0.5);
}
.ledger__row:last-of-type { border-bottom: 0; }
.ledger__page { color: var(--color-on-night); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ledger__num { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--color-on-night-2); text-align: right; font-variant-numeric: tabular-nums; }
.ledger__fee { font-family: var(--font-mono); font-size: var(--text-xs); text-align: right; font-variant-numeric: tabular-nums; }
.ledger__row--on  .ledger__fee  { color: var(--color-accent); font-weight: 600; }
.ledger__row--off .ledger__fee  { color: var(--color-dim); }
.ledger__row--off .ledger__page { color: var(--color-dim); }
.ledger__row--off .ledger__num  { color: var(--color-dim); }

.ledger__total {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-top: var(--space-xs); padding-top: var(--space-xs);
  border-top: var(--rule-hair) solid var(--color-night-rule);
}
.ledger__total span { color: var(--color-on-night-2); font-size: var(--text-xs); letter-spacing: 0.08em; text-transform: uppercase; }
.ledger__total strong {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--text-2xl); color: var(--color-accent); letter-spacing: -0.02em;
}
.ledger__note { margin: var(--space-xs) 0 0; font-size: var(--text-xs); color: var(--color-dim); max-width: none; }

/* ==================================================== workflow stages ===== */

.stage {
  display: grid;
  grid-template-columns: minmax(0, 6rem) minmax(0, 1fr);
  gap: var(--space-md) var(--space-lg);
  padding-block: var(--space-lg);
  border-top: var(--rule-hair) solid var(--color-rule);
  align-items: start;
}
.stage__no {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--text-4xl); line-height: 0.9;
  color: var(--color-accent-deep); letter-spacing: -0.04em;
}
.stage__body { min-width: 0; }
.stage__body h3 { margin-top: 0; font-size: var(--text-xl); }

@media (max-width: 46rem) {
  .stage { grid-template-columns: minmax(0, 1fr); gap: var(--space-2xs); }
  .stage__no { font-size: var(--text-2xl); }
}

/* ============================================================== proof ===== */

.proof {
  margin-block: var(--space-xl);
  padding: var(--space-lg);
  background: var(--color-night);
  color: var(--color-on-night);
  border-radius: var(--radius-md);
}
.proof h3, .proof strong { color: var(--color-on-night); }
.proof p { color: var(--color-on-night-2); }
.proof p:last-child { margin-bottom: 0; }
.proof .btn { margin-top: var(--space-sm); }

/* ============================================================== table ===== */

.table-scroll { overflow-x: auto; margin-block: var(--space-md); }
table { border-collapse: collapse; width: 100%; font-size: var(--text-sm); }
th, td { text-align: left; padding: var(--space-xs) var(--space-sm); border-bottom: var(--rule-hair) solid var(--color-rule); vertical-align: top; }
th { font-size: var(--text-xs); letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-ink-3); font-weight: 600; }

/* ================================================================ CTA ===== */

.btn {
  display: inline-flex; align-items: center; gap: var(--space-2xs);
  font-family: var(--font-body); font-size: var(--text-base); font-weight: 600;
  padding: 0.78em 1.5em;
  background: var(--color-accent);
  color: var(--color-ink);
  border: 0; border-radius: var(--radius-sm);
  text-decoration: none; white-space: nowrap;
  transition: transform var(--dur-fast) var(--ease-out), filter var(--dur-fast) var(--ease-out);
}
.btn:hover { filter: brightness(1.08); color: var(--color-ink); }
.btn:active { transform: translateY(1px); }
/* Authored for the dark band, but as of 2026-08-30 there is exactly ONE .btn--ghost on the whole
   site and it sits in a .cta-row inside the cream article, where --color-on-night rendered a
   near-white label on cream at 1.04:1 -- an invisible button. Default is the cream case now;
   the night case is scoped to the containers that actually have a night ground, so putting one
   back on the dark band still works. */
.btn--ghost {
  background: transparent; color: var(--color-ink);
  box-shadow: inset 0 0 0 1px var(--color-rule-strong);
}
.btn--ghost:hover { color: var(--color-accent-deep); box-shadow: inset 0 0 0 1px var(--color-accent-deep); }
.lede .btn--ghost, .duo .btn--ghost, .cta-band .btn--ghost,
.cta-final .btn--ghost, .cta-banner .btn--ghost, .foot-mast .btn--ghost {
  color: var(--color-on-night);
  box-shadow: inset 0 0 0 1px var(--color-night-rule);
}
.lede .btn--ghost:hover, .duo .btn--ghost:hover, .cta-band .btn--ghost:hover,
.cta-final .btn--ghost:hover, .cta-banner .btn--ghost:hover, .foot-mast .btn--ghost:hover {
  color: var(--color-accent); box-shadow: inset 0 0 0 1px var(--color-accent);
}

.cta-note { display: block; margin-top: var(--space-2xs); font-size: var(--text-sm); color: var(--color-ink-3); }
.lede .cta-note { color: var(--color-on-night-2); margin-top: 0; }

/* ================================================================ FAQ ===== */

.faq-item { padding-block: var(--space-md); border-top: var(--rule-hair) solid var(--color-rule); max-width: var(--measure); }
.faq-item h3 { font-size: var(--text-lg); margin: 0 0 var(--space-2xs); }
.faq-item p { margin: 0; color: var(--color-ink-2); }

/* ============================================================= footer ===== */

.foot-mast {
  margin-top: var(--space-2xl);
  padding: var(--space-xl) var(--page-gutter);
  background: var(--color-night);
  color: var(--color-on-night-2);
}
.foot-mast__mark { font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--text-xl); color: var(--color-on-night); margin: 0; }
.foot-mast__mark span { color: var(--color-accent); }
.foot-mast__line { font-size: var(--text-sm); margin: var(--space-3xs) 0 0; }
.foot-mast__links { margin-top: var(--space-sm); font-size: var(--text-sm); }
.foot-mast a { color: var(--color-on-night-2); white-space: nowrap; }
.foot-mast a:hover { color: var(--color-accent); }

/* ---- the tagline: one large-type statement of the deal ---------------------------------
   Its own moment between what we do and what it costs, not a heading stacked under the hero.
   Words light in reading order as the block scrolls in -- decorative, so the split spans are
   aria-hidden and `.u-vh` carries the unsplit sentence for assistive technology. */
.tagline {
  background: var(--color-night);
  padding-block: var(--space-2xl);
}
.tagline p {
  margin: 0; max-width: 22ch;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: clamp(2rem, 4.4vw, 3.4rem); line-height: 1.08; letter-spacing: -0.022em;
  text-wrap: balance;
}
.tagline p + p { margin-top: var(--space-2xs); }
.tagline__w {
  /* Starts at the muted end of the night palette and resolves to full. Never a hard on/off:
     the same --ease-out the rest of the site uses, over a beat long enough to read as a sweep. */
  color: var(--color-dim);
  transition: color var(--dur-slow) var(--ease-out);
}
.tagline__w[data-lit] { color: var(--color-on-night); }
.tagline__w--accent[data-lit] { color: var(--color-accent); }
/* `.tagline p` is (0,1,1) and this was (0,1,0), so the note rendered in Playfair at display
   size -- the fine print was the biggest thing in the section. Matched specificity. */
.tagline p.tagline__note {
  margin: var(--space-md) 0 0; max-width: 46ch;
  font-family: var(--font-body); font-weight: 400; font-size: var(--text-base);
  line-height: 1.5; color: var(--color-on-night-2); letter-spacing: 0;
  text-wrap: pretty;
}
@media (prefers-reduced-motion: reduce) {
  .tagline__w { transition: none; }
}

/* ---- utilities ------------------------------------------------------------------------- */
/* Visually hidden, still announced. The site had no such class before the tagline needed one. */
.u-vh {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; border: 0; overflow: hidden; white-space: nowrap;
  clip-path: inset(50%);
}
/* Keyboard users had no way past the nav on any page. */
.skip-link {
  position: absolute; left: var(--space-sm); top: -100%; z-index: 100;
  padding: 0.6em 1em; border-radius: var(--radius-sm);
  background: var(--color-accent); color: var(--color-ink);
  font-family: var(--font-body); font-weight: 600; text-decoration: none;
}
.skip-link:focus { top: var(--space-sm); color: var(--color-ink); }

/* ---- breadcrumbs sitting on the dark band --------------------------------- */
.crumbs { font-size: var(--text-sm); }
.crumbs--night { color: var(--color-on-night-2); margin-bottom: var(--space-lg); }
.crumbs--night a { color: var(--color-on-night-2); text-decoration-color: var(--color-night-rule); }
.crumbs--night a:hover { color: var(--color-accent); }

/* ---- links inside the dark hero ------------------------------------------- */
/* Same tokens as .crumbs--night a. Without this a link here inherits the light-body link
   colour and renders black on the night background — invisible, not just low contrast.
   Covers .cta-note too: moving one link from the standfirst down to the note re-created the
   exact same bug one element lower. */
.lede__standfirst a, .lede .cta-note a { color: var(--color-accent); text-decoration-color: var(--color-night-rule); }
.lede__standfirst a:hover, .lede .cta-note a:hover { color: var(--color-on-night); }

/* ---- the pulled-out argument under the pricing table ---------------------- */
.pull {
  margin-block: var(--space-lg);
  padding-left: var(--space-md);
  border-left: var(--rule-thick) solid var(--color-accent);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--text-xl);
  line-height: 1.25;
  letter-spacing: -0.015em;
  max-width: 34ch;
}

/* ---- nav dropdowns: the old theme's link graph, on the dark ground -------- */
.nav-edge__nav { min-width: 0; }
.nav-edge__links > li { position: relative; }
.nav-edge__links button {
  font: inherit; font-size: var(--text-sm); color: var(--color-on-night-2);
  background: none; border: 0; padding: var(--space-3xs) 0; cursor: pointer;
  border-bottom: 2px solid transparent;
}
.nav-edge__links button::after { content: " \25BE"; font-size: 0.7em; }
.nav-edge__links button:hover { color: var(--color-on-night); border-bottom-color: var(--color-accent); }
.nav-edge__menu {
  position: absolute; top: 100%; left: 0; z-index: 20;
  display: none; min-width: 17rem;
  margin: var(--space-2xs) 0 0; padding: var(--space-2xs);
  list-style: none;
  background: var(--color-night-2);
  border: var(--rule-hair) solid var(--color-night-rule);
  border-radius: var(--radius-md);
  box-shadow: 0 1px 2px oklch(0% 0 0 / .28), 0 6px 14px -8px oklch(0% 0 0 / .5);
}
.has-menu:hover .nav-edge__menu,
.has-menu:focus-within .nav-edge__menu { display: block; }
/* The pointer has to cross the gap between the button and the menu to reach a link. The li is
 * only as tall as its button, so that gap is outside `.has-menu` and the menu closed under the
 * cursor on the way to being clicked. This bridge is a transparent extension of the menu's own
 * hover area across the gap; it changes nothing visible. */
.nav-edge__menu::before {
  content: ""; position: absolute; left: -0.5rem; right: -0.5rem;
  top: calc(-1 * var(--space-2xs) - 3px); height: calc(var(--space-2xs) + 4px);
}
.nav-edge__menu a { display: block; padding: var(--space-2xs) var(--space-xs); border-radius: var(--radius-sm); white-space: normal; }
.nav-edge__menu a:hover { background: var(--color-night); color: var(--color-accent); }
.nav-edge__cta { color: var(--color-accent) !important; }

/* On a phone the dropdowns must stay CLOSED. Forcing them open turned the nav into ~750px of
 * links above the fold -- the first thing a mobile visitor saw was a link dump, not the offer.
 * Tapping a <button> focuses it, so :focus-within opens the menu with no JavaScript and no
 * markup change across 37 pages. Tapping elsewhere blurs it and it closes. */
@media (max-width: 46rem) {
  .nav-edge { padding-block: var(--space-sm); }
  .nav-edge__links { gap: var(--space-md); flex-wrap: wrap; }
  .nav-edge__menu {
    position: absolute; left: 0; top: 100%;
    min-width: min(20rem, calc(100vw - 2 * var(--page-gutter)));
  }
  .has-menu:focus-within .nav-edge__menu { display: block; }
}

/* ---- single-column hero for the pages without a ledger ------------------- */
.lede__grid--single { grid-template-columns: minmax(0, 1fr); }
.lede__grid--single h1 { max-width: 24ch; }
.lede__grid--single .lede__standfirst { max-width: 60ch; }

/* A hero with no visual has nothing to fill the 46rem band the .lede rule reserves.
 * Measured on /pricing-calculator/ at 1920x900: band 736px, copy 241px -- 495px of empty space
 * split above and below by align-content:center. The floor exists so a two-column hero reaches
 * the fold with its ledger or climb graphic beside the copy; a copy-only hero has nothing to
 * reach it with, so drop the floor and let the band size to what is actually in it.
 * Keyed on the visual, not on the CTA: adding a button to a copy-only hero does not give it
 * 500px of content, and keying on the button would silently re-inflate the band the moment
 * anyone added one. */
.lede:not(:has(.climb, .ledger)) {
  min-height: 0;
  padding-block: clamp(2.5rem, 7vh, 5rem);
}

/* ---- footer link grid ---------------------------------------------------- */
.foot-mast__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) repeat(4, minmax(0, 1fr));
  gap: var(--space-lg);
}
.foot-mast__brand .foot-mast__line { max-width: 42ch; }
.foot-mast__grid h4 {
  font-family: var(--font-body); font-size: var(--text-xs); font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-on-night);
  margin: 0 0 var(--space-2xs);
}
.foot-mast__grid a { display: block; font-size: var(--text-sm); padding-block: var(--space-3xs); white-space: normal; }
.foot-mast__legal {
  margin-top: var(--space-lg); padding-top: var(--space-md);
  border-top: var(--rule-hair) solid var(--color-night-rule);
  font-size: var(--text-xs); color: var(--color-dim); max-width: 90ch;
}
@media (max-width: 60rem) {
  .foot-mast__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .foot-mast__brand { grid-column: 1 / -1; }
}

/* ---- breathing room where the band hands off to the page ----------------- */
.lede + article > .wrap, .lede + article, article > .wrap { padding-top: var(--space-lg); }

/* ---- forms (the diagnostic page is the conversion point) ----------------- */
article form { max-width: 30rem; margin-block: var(--space-md) var(--space-lg); }
article form label { display: block; font-size: var(--text-sm); font-weight: 600; margin-bottom: var(--space-3xs); }
article form input[type=text], article form input[type=email], article form input[type=number],
article form textarea, article form select {
  width: 100%; margin-bottom: var(--space-sm);
  padding: 0.7rem 0.85rem;
  font: inherit; font-size: var(--text-base);
  color: var(--color-ink);
  background: var(--color-paper-2);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-sm);
}
article form input:focus-visible, article form textarea:focus-visible { border-color: var(--color-accent); }
article form button, article form input[type=submit] {
  display: inline-flex; align-items: center; justify-content: center;
  font: inherit; font-weight: 600;
  padding: 0.78em 1.5em;
  background: var(--color-accent); color: var(--color-ink);
  border: 0; border-radius: var(--radius-sm); cursor: pointer;
}
article form button:hover, article form input[type=submit]:hover { filter: brightness(1.08); }

/* ==================================================== legacy components ====
 * The 31 pages that predate the Hallmark shell carry their own class names
 * (.plans-grid, .cta-band, .toc, .related-grid ...). Their inline <style> block
 * is removed when the shell is applied, so those class names are restyled here
 * against the tokens rather than renamed in 31 files -- renaming would touch
 * body copy, and body copy is not what this pass is allowed to change.
 * ========================================================================= */

.key-answer {
  margin-block: var(--space-md);
  padding: var(--space-md);
  background: var(--color-accent-wash);
  border-left: var(--rule-thick) solid var(--color-accent);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-size: var(--text-lg);
  max-width: var(--measure);
}
.key-answer strong { font-weight: 600; }

/* The colour and margin here used to be on a second `.crumbs` rule further down the file.
   Same specificity as .crumbs--night but later in source order, so it silently won and every
   night breadcrumb on 27 pages rendered a light-ground grey on the dark band. Scoped now. */
.crumbs:not(.crumbs--night) { color: var(--color-ink-3); margin-bottom: var(--space-md); }

.byline {
  font-size: var(--text-sm); color: var(--color-ink-3);
  padding-bottom: var(--space-md);
  border-bottom: var(--rule-hair) solid var(--color-rule);
}

.toc {
  margin-block: var(--space-lg);
  padding: var(--space-md) var(--space-lg);
  background: var(--color-paper-2);
  border-radius: var(--radius-md);
  max-width: var(--measure);
}
.toc strong {
  display: block; margin-bottom: var(--space-2xs);
  font-family: var(--font-body); font-size: var(--text-xs); font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-ink-3);
}
.toc ol { margin: 0; padding-left: 1.2em; }
.toc li { margin-block: var(--space-3xs); }

/* --- the pricing cards ---------------------------------------------------- */
.plans-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: var(--space-md); margin-block: var(--space-lg); }
.plan-card {
  padding: var(--space-md);
  background: var(--color-paper-2);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-md);
}
.plan-card h3 { margin-top: 0; font-size: var(--text-lg); }
.plan-card p:last-child { margin-bottom: 0; }
.plan-price { font-family: var(--font-display); font-weight: var(--weight-display); color: var(--color-accent-deep); white-space: nowrap; }
.plan-founding {
  margin-block: var(--space-md);
  padding: var(--space-sm) var(--space-md);
  border-left: var(--rule-thick) solid var(--color-accent);
  background: var(--color-accent-wash);
  max-width: var(--measure);
}

/* --- numbered steps ------------------------------------------------------- */
.steps { display: grid; gap: var(--space-md); margin-block: var(--space-lg); }
.step-card { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-md); align-items: start; }
.step-num {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--text-3xl); line-height: 0.9; letter-spacing: -0.04em;
  color: var(--color-accent-deep);
}
.step-card h3 { margin-top: 0; font-size: var(--text-lg); }

/* --- the closing call to action ------------------------------------------ */
.cta-band, .cta-final, .cta-banner {
  margin-block: var(--space-xl);
  padding: var(--space-lg);
  background: var(--color-night);
  color: var(--color-on-night-2);
  border-radius: var(--radius-md);
}
.cta-band .head, .cta-final .head, .cta-banner .head {
  margin: 0 0 var(--space-2xs);
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--text-2xl); line-height: 1.15; letter-spacing: -0.02em;
  color: var(--color-on-night);
  max-width: 28ch;
}
.cta-band .sub, .cta-final .sub, .cta-banner .sub { margin: 0 0 var(--space-md); max-width: var(--measure); }
.sub--tight { margin-top: var(--space-2xs); }
.cta-band h2, .cta-final h2, .cta-banner h2 { color: var(--color-on-night); margin-top: 0; }
.cta-band p, .cta-final p, .cta-banner p { color: var(--color-on-night-2); }
/* These three bands are night-grounded, but only h2 and p were ever recoloured for it, so a
   bare <a> kept the light-ground default (--color-ink) and rendered near-black on near-black.
   Measured 1.02:1 on the homepage's final CTA -- the 'Start the build' link was invisible.
   :hover inherited --color-accent-deep, which is darker still. */
.cta-band a:not(.btn):not(.btn-gold), .cta-final a:not(.btn):not(.btn-gold),
.cta-banner a:not(.btn):not(.btn-gold) {
  color: var(--color-accent);
  text-decoration-color: color-mix(in oklab, var(--color-accent) 55%, transparent);
}
.cta-band a:not(.btn):not(.btn-gold):hover, .cta-final a:not(.btn):not(.btn-gold):hover,
.cta-banner a:not(.btn):not(.btn-gold):hover {
  color: var(--color-on-night);
  text-decoration-color: var(--color-on-night);
}

/* --- gold button (the legacy name for .btn) ------------------------------- */
.btn-gold {
  display: inline-flex; align-items: center; gap: var(--space-2xs);
  font-family: var(--font-body); font-size: var(--text-base); font-weight: 600;
  padding: 0.78em 1.5em;
  background: var(--color-accent); color: var(--color-ink);
  border: 0; border-radius: var(--radius-sm);
  text-decoration: none; white-space: nowrap;
  transition: filter var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.btn-gold:hover { filter: brightness(1.08); color: var(--color-ink); }
.btn-gold:active { transform: translateY(1px); }

/* --- related links -------------------------------------------------------- */
.related-grid, .rel-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: var(--space-sm); margin-block: var(--space-lg); }
.related-grid > a, .rel-grid > a, .related-grid > .rel-item, .rel-card, .related-card {
  display: block; padding: var(--space-sm) var(--space-md);
  background: var(--color-paper-2);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-md);
  font-weight: 600; text-decoration: none; color: var(--color-ink);
}
.related-grid > a:hover, .rel-grid > a:hover { border-color: var(--color-accent); color: var(--color-ink); }
.related-grid > a span, .rel-grid > a span, .related-grid > .rel-item span { display: block; margin-top: var(--space-3xs); font-weight: 400; font-size: var(--text-sm); color: var(--color-ink-3); }

/* --- priority / effort chips used in the audit-style tables --------------- */
.lk-high, .lk-med, .lk-low, .pri-high, .pri-med, .pri-2, .prio-high, .prio-med,
.eff-low, .eff-med, .tag {
  display: inline-block; padding: 0.15em 0.6em;
  font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.04em;
  border-radius: 999px;
  background: var(--color-paper-3); color: var(--color-ink-2);
}
.lk-high, .pri-high, .prio-high { background: var(--color-accent-wash); color: var(--color-accent-deep); }
/* The qualifier under a price inside an .lk-* chip. It was an inline #7c8698 -- a slate grey
   from the legacy navy layer -- on the chip's LIGHT --color-paper-3 ground, at 2.63:1. */
.chip-sub { color: var(--color-ink-2); font-weight: 400; }

/* --- misc leftovers ------------------------------------------------------- */
.card, .stat-card, .script-card, .tpl {
  padding: var(--space-md);
  background: var(--color-paper-2);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-md);
  margin-block: var(--space-md);
}
.stat-card .num { font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--text-3xl); color: var(--color-accent-deep); display: block; }
.stat-card .lbl { font-size: var(--text-sm); color: var(--color-ink-3); }
.tpl-label { font-size: var(--text-xs); letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-ink-3); }
.container { max-width: 74rem; margin-inline: auto; padding-inline: var(--page-gutter); }

/* ---- the reputation -> local-SEO bridge ----------------------------------
 * Deliberately NOT another dark CTA band. These pages already end with one, and a third
 * shouting block reads as a sales page rather than an argument. This is editorial: it makes
 * a point, then offers a link. */
.bridge {
  display: block;
  margin-block: var(--space-xl);
  padding: var(--space-lg);
  background: var(--color-paper-2);
  border-left: var(--rule-thick) solid var(--color-accent);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
}
.bridge h2 {
  margin-top: 0;
  font-size: var(--text-2xl);
  max-width: 26ch;
}
.bridge p { max-width: var(--measure); }
.bridge p:last-child { margin-bottom: 0; }

/* ================================================== the hero sequence =====
 * Replaces the static ledger card. Four acts, driven by data-act on .stage:
 *   1 towns unranked -> 2 pages built -> 3 three climb, two do not -> 4 the bill and the calls
 * Motion is transform/opacity only. Reduced motion jumps straight to act 4.
 * ========================================================================= */

.climb {
  --row-h: 2.15rem;
  display: flex; flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-md);
  background: var(--color-night-2);
  border: var(--rule-hair) solid var(--color-night-rule);
  border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px oklch(0% 0 0 / .3), 0 8px 15px -9px oklch(0% 0 0 / .55);
  container-type: inline-size;
}

.climb__head {
  display: grid;
  grid-template-columns: minmax(0, 10.5rem) minmax(0, 1fr) 5.25rem;
  align-items: baseline; gap: var(--space-2xs);
}
.climb__phase {
  font-size: var(--text-xs); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--color-accent);
  transition: opacity var(--dur-base) var(--ease-out);
}
/* The scale sits over the track column so "page 1" lines up with the page-one rule. */
.climb__scale { display: flex; justify-content: space-between; font-size: var(--text-xs); color: var(--color-dim); }
.climb__scale i:last-child { transform: translateX(0.4rem); }
.climb__scale i { font-style: normal; }

.climb__rows { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3xs); }
.climb__row {
  display: grid;
  grid-template-columns: minmax(0, 10.5rem) minmax(0, 1fr) 5.25rem;
  align-items: center; gap: var(--space-2xs);
  min-height: var(--row-h);
}
.climb__town {
  font-family: var(--font-mono); font-size: var(--text-xs);
  color: var(--color-on-night-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  opacity: 0.35;
  transition: opacity var(--dur-slow) var(--ease-out), color var(--dur-slow) var(--ease-out);
}
.climb__track {
  position: relative; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, var(--color-night-rule), oklch(30% 0.014 70 / 0.35));
}
/* The page-one line: everything right of it is on page one. */
.climb__track::after {
  content: ""; position: absolute; top: -0.55rem; bottom: -0.55rem; left: 78%;
  width: 1px; background: var(--color-night-rule);
}
.climb__runner {
  position: absolute; inset: 0;
  transform: translateX(0);
  transition: transform var(--dur-slow) var(--ease-out);
}
.climb__dot {
  position: absolute; top: 50%; left: 0;
  width: 0.5rem; height: 0.5rem; border-radius: 50%;
  background: var(--color-dim);
  transform: translate(-50%, -50%);
  transition: transform var(--dur-slow) var(--ease-out), background var(--dur-slow) var(--ease-out),
              box-shadow var(--dur-slow) var(--ease-out);
}
.climb__fee {
  font-family: var(--font-mono); font-size: var(--text-xs); text-align: right;
  color: var(--color-dim); opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out), color var(--dur-base) var(--ease-out);
}

.climb__foot {
  display: flex; align-items: flex-end; justify-content: space-between; gap: var(--space-md);
  padding-top: var(--space-sm);
  border-top: var(--rule-hair) solid var(--color-night-rule);
}
.climb__bill span {
  display: block; font-size: var(--text-xs); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--color-on-night-2);
}
.climb__bill strong {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--text-3xl); line-height: 1; color: var(--color-accent);
  font-variant-numeric: tabular-nums lining-nums;
}
.climb__calls { text-align: right; opacity: 0; transform: translateY(6px);
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out); }
.climb__calls-lbl { display: block; font-size: var(--text-xs); color: var(--color-on-night-2); margin-bottom: var(--space-3xs); }
.climb__bars { display: flex; align-items: flex-end; gap: 5px; height: 3rem; }
.climb__bars i {
  width: 0.65rem; height: 100%; border-radius: 2px 2px 0 0;
  background: var(--color-accent);
  transform: scaleY(0.12); transform-origin: bottom;
  transition: transform var(--dur-slow) var(--ease-out);
}
.climb__bars i:nth-child(1) { --h: 0.22; }
.climb__bars i:nth-child(2) { --h: 0.34; }
.climb__bars i:nth-child(3) { --h: 0.5; }
.climb__bars i:nth-child(4) { --h: 0.68; }
.climb__bars i:nth-child(5) { --h: 0.85; }
.climb__bars i:nth-child(6) { --h: 1; }

.climb__cap {
  margin: 0; font-size: var(--text-sm); color: var(--color-on-night-2);
  min-height: 2.6em;
  transition: opacity var(--dur-base) var(--ease-out);
}
.climb__meta { display: flex; align-items: center; justify-content: space-between; gap: var(--space-sm); }
.climb__note { font-size: var(--text-xs); color: var(--color-dim); }
.climb__replay {
  flex: none; font: inherit; font-size: var(--text-xs); font-weight: 600;
  color: var(--color-on-night-2); background: none; cursor: pointer;
  padding: 0.35em 0.9em; border-radius: 999px;
  border: 1px solid var(--color-night-rule);
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.climb__replay:hover { color: var(--color-accent); border-color: var(--color-accent); }

/* ---- act 2: the pages exist ------------------------------------------- */
.climb[data-act="2"] .climb__town,
.climb[data-act="3"] .climb__town,
.climb[data-act="4"] .climb__town { opacity: 1; }

/* ---- act 3: three climb past the page-one line, two stall -------------- */
.climb[data-act="3"] .climb__runner,
.climb[data-act="4"] .climb__runner { transform: translateX(var(--pos)); }
.climb[data-act="3"] .is-won .climb__dot,
.climb[data-act="4"] .is-won .climb__dot {
  background: var(--color-accent);
  box-shadow: 0 0 0 4px oklch(76% 0.121 84 / 0.18);
}
.climb[data-act="3"] .climb__row:not(.is-won) .climb__town,
.climb[data-act="4"] .climb__row:not(.is-won) .climb__town { color: var(--color-dim); }

/* ---- act 4: the bill, and what it bought ------------------------------- */
.climb[data-act="4"] .climb__fee { opacity: 1; }
.climb[data-act="4"] .is-won .climb__fee { color: var(--color-accent); font-weight: 600; }
.climb[data-act="4"] .climb__calls { opacity: 1; transform: none; }
.climb[data-act="4"] .climb__bars i { transform: scaleY(var(--h)); }

/* The dot travels along the track, so its offset is a share of the track width. */
.climb__row { position: relative; }
.climb__track { overflow: visible; }

@container (max-width: 26rem) {
  .climb__row { grid-template-columns: minmax(0, 7rem) minmax(0, 1fr) 4.5rem; }
  .climb__bill strong { font-size: var(--text-2xl); }
}

@media (prefers-reduced-motion: reduce) {
  .stage *, .climb { transition: none !important; }
}

/* ============================================================= motion ===== */

@keyframes hm-rise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

.lede__grid > * { animation: hm-rise var(--dur-slow) var(--ease-out) both; }
.lede__grid > *:nth-child(2) { animation-delay: 90ms; }
.ledger__row { animation: hm-rise var(--dur-base) var(--ease-out) both; }
.ledger__row:nth-child(2) { animation-delay: 160ms; }
.ledger__row:nth-child(3) { animation-delay: 200ms; }
.ledger__row:nth-child(4) { animation-delay: 240ms; }
.ledger__row:nth-child(5) { animation-delay: 280ms; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .lede__grid > *, .ledger__row { animation: none; opacity: 1; transform: none; }
}

/* ---- looping screen-recording demo (/local-seo-agency/) -------------------------------
 * Reads as watching someone's screen: browser chrome, a cursor that moves, a query typed a
 * character at a time, results, then the same search again after the pages exist.
 *
 * Sized to sit in the hero column without pushing the CTA under the fold -- the whole frame is
 * height-capped and scales its own type down, rather than growing to fit its content.
 *
 * What it must not imply: that we control Google. The organic result lands at #4, the AI
 * Overview citation is described as eligibility, and the frame carries a visible notice.
 */
.demo {
  --demo-radius: 12px;
  position: relative;
  background: oklch(19% 0.006 70);
  border: 1px solid var(--color-night-rule);
  border-radius: var(--demo-radius);
  overflow: hidden;
  font-size: clamp(.62rem, .85cqw + .45rem, .78rem);
  container-type: inline-size;
  box-shadow: 0 1px 2px oklch(0% 0 0 / .28), 0 6px 14px -8px oklch(0% 0 0 / .5);
  display: grid;
  grid-template-rows: auto 1fr auto;
  height: clamp(23rem, 52vh, 30rem);
}

/* --- browser chrome --- */
.demo__chrome {
  display: flex; align-items: center; gap: .5rem;
  padding: .45rem .6rem;
  background: oklch(24% 0.008 70);
  border-bottom: 1px solid var(--color-night-rule);
}
.demo__dots { display: flex; gap: .28rem; flex: none; }
.demo__dots i { width: .5rem; height: .5rem; border-radius: 50%; background: oklch(34% 0.01 70); }
.demo__addr {
  flex: 1; min-width: 0;
  background: oklch(17% 0.006 70); border-radius: 999px;
  padding: .22rem .6rem; color: var(--color-on-night-2);
  font-size: .92em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* --- viewport --- */
.demo__view { position: relative; overflow: hidden; padding: .6rem; }
.demo__scene { position: absolute; inset: 0; overflow: hidden; z-index: 1;
  padding: .6rem .6rem calc(var(--demo-cap-h, 3.1rem) + .5rem);
  opacity: 0; pointer-events: none;
  /* The scenes are stacked, so a plain crossfade parks a SERP and the build scene at ~50%
   * each and double-exposes. Making the incoming scene opaque and raising it above the
   * outgoing one means it covers rather than blends -- no double-expose and no dip to an
   * empty frame, which is what an asymmetric fade traded the double-expose for. Ground is
   * .demo's own. z-index stays under .demo__cap (3) and .demo__cursor (5). */
  background: oklch(19% 0.006 70);
  transition: opacity var(--dur-base) var(--ease-out); }
.demo__scene[data-on] { opacity: 1; z-index: 2; }

/* The results scene is a page, not a poster: its content runs ~944px against a ~510px viewport,
   so it scrolls and the script drives the scroll. pointer-events stays off (inherited from
   .demo__scene) so a wheel over the hero scrolls the document, never this panel. The scrollbar is
   shown, thin -- it is the affordance that says "this is a page", and a real recording has one. */
.demo__scene[data-scene="search"] {
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Scroll anchoring silently restores scrollTop when the scene is repainted between acts, which
     put act 3 back where act 1 left it instead of at the top of the results. Measured, not guessed. */
  overflow-anchor: none;
  scrollbar-width: thin;
  scrollbar-color: oklch(38% 0.01 70) transparent;
}
.demo__scene[data-scene="search"]::-webkit-scrollbar { width: 6px; }
.demo__scene[data-scene="search"]::-webkit-scrollbar-track { background: transparent; }
.demo__scene[data-scene="search"]::-webkit-scrollbar-thumb {
  background: oklch(38% 0.01 70); border-radius: 999px;
}

.demo__search {
  display: flex; align-items: center; gap: .45rem;
  background: oklch(24% 0.008 70); border: 1px solid var(--color-night-rule);
  border-radius: 999px; padding: .38rem .7rem; color: var(--color-on-night);
  margin-bottom: .5rem;
}
.demo__search svg { flex: none; opacity: .6; }
.demo__typed { font-weight: 600; }
.demo__caret { display: inline-block; width: 1px; height: 1em; background: var(--color-accent);
  vertical-align: -.12em; animation: demo-blink .9s steps(1) infinite; }
@keyframes demo-blink { 50% { opacity: 0; } }

.demo__block { border: 1px solid var(--color-night-rule); border-radius: 8px;
  padding: .42rem .55rem; background: oklch(22% 0.008 70); margin-bottom: .4rem; }
/* Was <h5>. These sit inside a role="img" frame -- they are labels on a picture, not
   headings, and as h5 after the page's h1 they made the outline jump four levels. */
.demo__block .demo__lbl {
  margin: 0 0 .25rem; font-family: var(--font-body); font-size: .82em; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--color-on-night-2);
}
.demo__ai { border-color: oklch(38% 0.045 250); background: oklch(23% 0.018 250); }
.demo__ai p { margin: 0; color: var(--color-on-night); line-height: 1.45; max-width: none; font-size: .98em; }
.demo__cites { display: flex; flex-wrap: wrap; gap: .25rem; margin-top: .35rem; }
.demo__cite { font-size: .84em; padding: .12rem .42rem; border-radius: 999px;
  border: 1px solid var(--color-night-rule); color: var(--color-on-night-2); }
.demo__cite--yours { border-color: var(--color-accent); color: var(--color-accent); font-weight: 600; }

.demo__paa li { list-style: none; display: flex; justify-content: space-between; gap: .4rem;
  padding: .2rem 0; border-bottom: 1px solid oklch(30% 0.014 70 / .5); color: var(--color-on-night); }
.demo__paa ul { margin: 0; padding: 0; }
.demo__paa li:last-child { border-bottom: 0; }
.demo__src { font-size: .86em; color: var(--color-on-night-2); white-space: nowrap; }
.demo__src--yours { color: var(--color-accent); font-weight: 600; }

.demo__row { display: grid; grid-template-columns: 1.1rem 1fr; gap: .45rem;
  padding: .3rem .45rem; border-radius: 6px; background: oklch(22% 0.008 70); margin-bottom: .25rem; }
.demo__row--yours { border: 1px solid var(--color-accent); background: oklch(26% 0.030 84); }
.demo__rank { color: var(--color-on-night-2); font-variant-numeric: tabular-nums; }
.demo__url { color: oklch(72% 0.055 200); font-size: .88em; overflow-wrap: anywhere; }
.demo__title { color: var(--color-on-night); line-height: 1.25; }
.demo__absent { display: flex; gap: .4rem; padding: .35rem .45rem; border-radius: 6px;
  border: 1px dashed var(--color-night-rule); color: var(--color-on-night-2); font-size: .92em; }

/* --- the build beat: what happens between the two searches --- */
.demo__build { display: grid; align-content: center; gap: .5rem; height: 100%; text-align: center; }
.demo__cta {
  justify-self: center; padding: .4rem .9rem; border-radius: 999px;
  background: var(--color-accent); color: oklch(20% 0.02 70); font-weight: 700; font-size: 1.02em;
}
.demo__cta[data-pressed] { transform: scale(.96); filter: brightness(.92); }
.demo__pages { display: grid; gap: .22rem; justify-self: center; min-width: min(15rem, 80cqw); }
.demo__page {
  display: flex; justify-content: space-between; gap: .5rem;
  padding: .22rem .5rem; border-radius: 6px; background: oklch(22% 0.008 70);
  color: var(--color-on-night-2); font-size: .9em; opacity: 0; transform: translateY(4px);
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.demo__page[data-live] { opacity: 1; transform: none; }
.demo__page b { color: var(--color-accent); font-weight: 600; }
.demo__step { color: var(--color-on-night-2); font-size: .95em; margin: 0; }

/* --- the cursor --- */
.demo__cursor {
  position: absolute; left: 0; top: 0; width: 15px; height: 15px; z-index: 5;
  pointer-events: none; transform: translate(-100px, -100px);
  transition: transform 1.05s cubic-bezier(.5, 0, .2, 1);
  filter: drop-shadow(0 1px 2px oklch(0% 0 0 / .6));
}
.demo__cursor[data-off] { opacity: 0; }
.demo__cursor[data-click] { transition-duration: .12s; transform-origin: 0 0; }

.demo__foot {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  padding: .35rem .6rem; border-top: 1px solid var(--color-night-rule);
  background: oklch(21% 0.006 70); color: var(--color-on-night-2); font-size: .88em;
}
.demo__note { opacity: .8; }
.demo__replay {
  background: none; border: 1px solid var(--color-night-rule); border-radius: 999px;
  color: var(--color-on-night-2); font: inherit; font-size: .92em;
  padding: .12rem .55rem; cursor: pointer; flex: none;
}
.demo__replay:hover { border-color: var(--color-accent); color: var(--color-accent); }

/* ============================================ the two-product panel ===== */
/* A dark panel inside the cream article, not a full-bleed band: it has to sit between two <h2>s
   inside .wrap, and both animations are night-coloured frames -- on cream they read as two holes
   in the page. Night ground also makes .btn--ghost correct as authored (it is coloured for the
   dark band) instead of needing a paper variant. */
.duo {
  background: var(--color-night);
  border: var(--rule-hair) solid var(--color-night-rule);
  border-radius: var(--radius-lg);
  padding: var(--space-lg);
  margin-block: var(--space-xl);
  color: var(--color-on-night);
}
.duo__head { margin-top: 0; color: var(--color-on-night); }
.duo .pull { color: var(--color-on-night); margin-block: var(--space-md); }
.duo__grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-lg); margin-block: var(--space-lg);
}
.duo__card { display: flex; flex-direction: column; gap: var(--space-sm); min-width: 0; }
.duo__card h3 { margin: 0; color: var(--color-on-night); font-size: var(--text-xl); }
.duo__card p { margin: 0; max-width: none; color: var(--color-on-night-2); }
.duo__card p strong { color: var(--color-on-night); font-weight: 600; }
.duo__card .demo { margin: 0; max-width: none; }
/* Pushes both CTAs to the bottom of their card so they line up whatever the copy does. */
.duo__cta { margin-top: auto; }
.duo__close {
  margin: 0; max-width: 70ch; color: var(--color-on-night);
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--text-lg); line-height: 1.3;
}
@media (max-width: 60rem) {
  .duo { padding: var(--space-md); }
  .duo__grid { grid-template-columns: minmax(0, 1fr); }
}
/* At 320px the panel's own padding was taking 48px off a frame that is already the narrowest
   thing on the page -- 230px of animation inside a 320px screen. Give the width back. */
@media (max-width: 30rem) {
  .duo { padding: var(--space-md) var(--space-sm); border-radius: var(--radius-md); }
}


/* --- the trade index inside the two-product panel -------------------------------------
   The panel used to be two cards side by side, each with its own animation. That layout was
   built around a frame that is already the narrowest element on the page, so at 320px it read as
   two tall moving panels stacked ahead of a single link. The search frame is gone from here (the
   hero still has it) and the room went to links a visitor can act on.

   Mobile-first literally: one column is the base rule and the grid only widens at a min-width,
   and every link is its own >=44px target rather than a run of inline text links. */
.duo__pair {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: var(--space-md); margin-block: var(--space-md);
}
.duo__prod { margin: 0; max-width: none; color: var(--color-on-night-2); }
.duo__prod strong { color: var(--color-on-night); font-weight: 600; }
.duo__prod a { color: var(--color-on-night); }
/* The automation frame's internals were measured at 471px wide. Stretching it across a desktop
   panel distorts the one thing this section still moves, so cap it and centre it instead. */
.duo__solo { max-width: 34rem; margin-inline: auto; }
.duo__solo .demo { margin: 0; max-width: none; }
.duo__sub {
  margin: var(--space-lg) 0 var(--space-sm); color: var(--color-on-night);
  font-size: var(--text-lg);
}
.trades {
  /* `ul, ol` caps every list at --measure (620px) for reading. This is an index, not prose, so
     it takes the panel's full width -- without this the grid could never be more than 2 columns
     on a desktop and the section stayed ~2000px tall. */
  list-style: none; margin: 0 0 var(--space-md); padding: 0; max-width: none;
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-md);
  /* One label per trade wraps to a third line ('consultation intake + engagement follow-up'),
     which made its card taller than its row siblings. Equal rows, links filling them. */
  grid-auto-rows: 1fr;
}
.trade { display: flex; flex-direction: column; gap: var(--space-3xs); min-width: 0; }
.trade__demo { flex: 1 1 auto; }
/* The page link is the primary of the pair -- the demo is what you look at, the page is what you
   buy from. `--color-night-2` is the design system's own raised-surface-on-night, so the primary
   sits up and the secondary stays flush. Deliberately not an accent rail: the panel is already a
   dark card inside a cream article and a coloured bar on top of that is one device too many. */
.trade__page { background: var(--color-night-2); }
.trade a {
  display: block; padding: 0.62rem 0.8rem; min-height: 2.75rem;
  border: var(--rule-hair) solid var(--color-night-rule); border-radius: var(--radius-md);
  color: var(--color-on-night); text-decoration: none;
  font-size: var(--text-sm); font-weight: 600; line-height: 1.35;
}
.trade a span {
  display: block; margin-top: 0.1rem;
  color: var(--color-on-night-2); font-weight: 400;
}
.trade a:hover, .trade a:focus-visible { border-color: var(--color-accent); }
.duo__more { margin: 0 0 var(--space-md); color: var(--color-on-night-2); font-size: var(--text-sm); }
.duo__more a { color: var(--color-on-night); }
@media (min-width: 40rem) {
  .trades { grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
}
@media (min-width: 52rem) {
  .duo__pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --- the booking automation, drawn as work somebody no longer does -------------------
   Three versions drew the MESSAGES (an inbox, a two-lane spine, a day strip with a spotlight).
   All three were correct about what gets sent and useless at saying who is no longer sending it,
   which is the entire product. Screenshots showed what DOM sampling could not: an unlabelled
   sparkline, a grey card that only swapped text, and a black void between them.

   So the subject is the person. Their job list, ticking itself off, with the right-hand column --
   where a name would go -- filling in with the automation. The two counters are the argument:
   `done` climbs to nine, `by you` never leaves zero. Every row exists from the first frame, so
   nothing reflows; scrollHeight must stay equal to clientHeight for the whole loop. */
.demo--auto { max-width: none; }

.demo__scene--form { display: grid; place-items: center; }
.auto__form {
  width: 100%; max-width: 20rem; display: grid; gap: .4rem;
  border: 1px solid var(--color-night-rule); border-radius: var(--radius-md);
  background: var(--color-night-2); padding: .75rem .8rem;
}
.auto__form-title { font-weight: 700; color: var(--color-on-night); }
.auto__fields { display: grid; gap: .38rem; }
.auto__field { display: grid; gap: .1rem; min-width: 0; }
.auto__label {
  font-size: .8em; letter-spacing: .06em; text-transform: uppercase;
  color: var(--color-on-night-2);
}
/* Deliberately not real inputs: the aside is one image to a screen reader, and a focusable field
   inside it would be a tab stop that does nothing. */
.auto__input {
  display: flex; align-items: center; min-height: 1.6em; min-width: 0;
  border: 1px solid var(--color-night-rule); border-radius: var(--radius-sm);
  background: var(--color-night); color: var(--color-on-night); padding: .16rem .42rem;
  transition: border-color var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
.auto__value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.auto__input[data-active] {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-accent) 18%, transparent);
}
.auto__input[data-done] {
  border-color: color-mix(in oklab, var(--color-positive) 55%, var(--color-night-rule));
}
.auto__caret { display: none; flex: none; }
.auto__input[data-active] .auto__caret { display: inline-block; }
.auto__submit { justify-self: stretch; text-align: center; margin-top: .3rem; }
.auto__submit[data-busy] { filter: saturate(.7) brightness(.9); }

/* --- the job list ------------------------------------------------------------------ */
.auto__work { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: .5rem; height: 100%; }

.auto__work-head {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end;
  column-gap: .5rem; padding-bottom: .35rem;
  border-bottom: 1px solid var(--color-night-rule);
}
.auto__who {
  grid-column: 1; font-weight: 700; color: var(--color-on-night);
  font-size: 1.06em; line-height: 1.2;
}
.auto__role {
  grid-column: 1; grid-row: 2; font-size: .86em; color: var(--color-on-night-2); line-height: 1.25;
}
.auto__scores { grid-column: 2; grid-row: 1 / span 2; display: flex; gap: .9rem; align-items: flex-end; }
.auto__score {
  display: grid; justify-items: center; font-size: .78em; letter-spacing: .07em;
  text-transform: uppercase; color: var(--color-on-night-2); line-height: 1.3;
}
.auto__score b {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 2.1em; line-height: 1; font-variant-numeric: tabular-nums;
}
.auto__score--done b { color: var(--color-positive); }
/* The number that never moves. That is the argument, so it gets the accent. */
.auto__score--you b { color: var(--color-accent); }

.auto__jobs {
  list-style: none; margin: 0; padding: 0;
  display: grid; align-content: center; gap: .06rem; min-height: 0;
}
.auto__job {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center; column-gap: .45rem;
  padding: .2rem .35rem; border-radius: var(--radius-sm);
  transition: background var(--dur-base) var(--ease-out);
}
.auto__job[data-now] { background: color-mix(in oklab, var(--color-on-night) 9%, transparent); }

.auto__box {
  flex: none; width: .78rem; height: .78rem; border-radius: 3px;
  border: 1px solid var(--color-night-rule); background: transparent;
  position: relative;
  transition: background var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out);
}
.auto__box::after {
  content: ""; position: absolute; left: 50%; top: 46%;
  width: .3rem; height: .16rem; margin: -.14rem 0 0 -.17rem;
  border-left: 2px solid var(--color-ink); border-bottom: 2px solid var(--color-ink);
  /* Never scale(0) -- nothing in the real world appears from nothing. It arrives from
   * almost-there and fades in; opacity is what makes it invisible at rest. */
  transform: rotate(-45deg) scale(.4); transform-origin: center; opacity: 0;
  transition: transform var(--dur-base) var(--ease-out), opacity var(--dur-fast) var(--ease-out);
}
.auto__job[data-done] .auto__box {
  background: var(--color-positive); border-color: var(--color-positive);
}
.auto__job[data-done] .auto__box::after { transform: rotate(-45deg) scale(1); opacity: 1; }

.auto__job-text {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--color-on-night-2); line-height: 1.3;
  transition: color var(--dur-base) var(--ease-out);
}
.auto__job[data-done] .auto__job-text { color: var(--color-on-night); }
.auto__job--offer[data-done] .auto__job-text { color: var(--color-accent); font-weight: 600; }
.auto__job-when {
  font-size: .82em; font-variant-numeric: tabular-nums;
  color: var(--color-on-night-2); opacity: .55; white-space: nowrap;
}
/* Where a person's name would go. */
.auto__job-by {
  font-size: .78em; letter-spacing: .05em; text-transform: uppercase;
  padding: .04rem .4rem; border-radius: 999px; white-space: nowrap;
  border: 1px solid var(--color-night-rule); color: var(--color-on-night-2);
  opacity: 0; transform: translateX(.3rem);
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.auto__job[data-done] .auto__job-by {
  opacity: 1; transform: none;
  border-color: color-mix(in oklab, var(--color-positive) 55%, var(--color-night-rule));
  color: var(--color-positive);
}

.auto__close {
  margin: 0; padding: .55rem .65rem; border-radius: var(--radius-md);
  border: 1px solid var(--color-accent);
  background: color-mix(in oklab, var(--color-accent) 14%, var(--color-night-2));
  color: var(--color-on-night);
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 1.08em; line-height: 1.28;
  opacity: 0; transform: translateY(.35rem);
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
}
.auto__close[data-in] { opacity: 1; transform: none; }

/* Narrow: the timestamp is the first thing to go — the job and who did it are the point. */
@container (max-width: 26rem) {
  .auto__job-when { display: none; }
  .auto__job { column-gap: .35rem; padding: .16rem .25rem; }
  .auto__score b { font-size: 1.8em; }
  .auto__role { display: none; }
}
@container (max-width: 19rem) {
  .auto__job-by { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .auto__close { opacity: 1; transform: none; transition: none; }
  .auto__job, .auto__box, .auto__box::after, .auto__job-by, .auto__job-text { transition: none; }
  .auto__caret { animation: none; }
}

/* --- the before/after animation ------------------------------------------------------
   Argues for the automation rather than describing it: the same nine messages, once as they go
   out on their own and once as they go out when a person has to remember them. Nine rows, all
   present from the first frame, three columns (`1fr auto 1fr`) so the day sits dead centre and
   the two columns are read against each other rather than in sequence.

   Colour does the least work here on purpose -- the signal is that the left column is a stack of
   struck-through "not sent" and the right is a stack of filled marks. */
.demo--split { max-width: none; }
.split {
  display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: .5rem;
  height: 100%; align-content: stretch;
}

.split__head {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: end; gap: .4rem;
  padding-bottom: .35rem; border-bottom: 1px solid var(--color-night-rule);
}
.split__col { display: grid; gap: .02rem; min-width: 0; }
.split__col--left { text-align: right; }
.split__col b {
  font-family: var(--font-display); font-weight: var(--weight-display); font-size: 1.7em;
  line-height: 1; font-variant-numeric: tabular-nums;
}
.split__col--left b { color: var(--color-on-night-2); }
.split__col--right b { color: var(--color-accent); }
.split__col-label {
  font-size: .88em; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--color-on-night);
}
.split__col-note { font-size: .84em; color: var(--color-on-night-2); line-height: 1.25; }
.split__axis-label {
  font-size: .74em; letter-spacing: .1em; text-transform: uppercase;
  color: var(--color-on-night-2); opacity: .7; width: 2.4rem; text-align: center;
}

.split__rows { display: grid; align-content: center; gap: .1rem; min-height: 0; }
.split__row {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  column-gap: .4rem; padding: .12rem .1rem; border-radius: var(--radius-sm);
  transition: background var(--dur-base) var(--ease-out);
}
.split__row[data-now] { background: color-mix(in oklab, var(--color-on-night) 9%, transparent); }
.split__day {
  width: 2.4rem; text-align: center; font-size: .82em; font-variant-numeric: tabular-nums;
  color: var(--color-on-night-2); opacity: .55;
}
.split__row[data-now] .split__day { opacity: 1; color: var(--color-on-night); }

.split__cell { display: flex; align-items: center; gap: .35rem; min-width: 0; }
.split__cell--left { justify-content: flex-end; text-align: right; }
.split__label {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  line-height: 1.3;
}
.split__mark {
  flex: none; width: .52rem; height: .52rem; border-radius: 50%;
  border: 1px solid var(--color-night-rule); background: transparent;
  transform: scale(.7); opacity: .45;
  transition: transform var(--dur-base) var(--ease-out), opacity var(--dur-base) var(--ease-out),
              background var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out);
}
.split__row[data-in] .split__mark { transform: none; opacity: 1; }

/* The right-hand column: every one of the nine lands. */
.split__row[data-in] .split__cell--right .split__mark {
  background: var(--color-accent); border-color: var(--color-accent);
}
.split__cell--right .split__label { color: var(--color-on-night); }
.split__row:not([data-in]) .split__cell--right .split__label { color: var(--color-on-night-2); opacity: .5; }
.split__cell--right[data-offer] .split__label { color: var(--color-accent); font-weight: 700; }

/* The left-hand column: one of the nine lands, eight are struck through. */
.split__row[data-sent="both"][data-in] .split__cell--left .split__mark {
  background: var(--color-positive); border-color: var(--color-positive);
}
.split__row[data-sent="both"] .split__cell--left .split__label { color: var(--color-on-night); }
.split__row[data-sent="right"] .split__cell--left .split__label {
  color: var(--color-on-night-2); opacity: .5;
  font-size: .92em; letter-spacing: .04em; text-transform: uppercase;
}
.split__row[data-sent="right"][data-in] .split__cell--left .split__label {
  opacity: .85; text-decoration: line-through; text-decoration-thickness: 1px;
}
.split__row[data-sent="right"][data-in] .split__cell--left .split__mark {
  border-style: dashed; opacity: .6; background: transparent;
}

.split__close {
  margin: 0; padding: .5rem .6rem; border-radius: var(--radius-md);
  border: 1px solid var(--color-accent);
  background: color-mix(in oklab, var(--color-accent) 14%, var(--color-night-2));
  color: var(--color-on-night);
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 1.06em; line-height: 1.28;
  opacity: 0; transform: translateY(.35rem);
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
}
.split__close[data-in] { opacity: 1; transform: none; }

/* Narrow: the left column's labels are all the same two words, so they stop earning their width
   before the right column's do. Drop them to marks only and let the right column have the room. */
@container (max-width: 30rem) {
  .split__row { grid-template-columns: auto auto minmax(0, 1fr); }
  .split__head { grid-template-columns: auto auto minmax(0, 1fr); }
  .split__col--left { text-align: left; }
  .split__row[data-sent="right"] .split__cell--left .split__label,
  .split__row[data-sent="both"] .split__cell--left .split__label { display: none; }
  .split__col--left .split__col-note { display: none; }
  .split__day { width: 1.9rem; }
  .split__axis-label { width: 1.9rem; }
}

@media (prefers-reduced-motion: reduce) {
  .split__close { opacity: 1; transform: none; transition: none; }
  .split__mark, .split__row { transition: none; }
}

/* --- the running caption -------------------------------------------------------------
   Five acts with no narration read as a slideshow of unrelated screens. This is an overlay,
   not a grid row: a row would cost ~50px off a scene that already scrolls to fit its content.
   Every scene carries a matching padding-bottom so content scrolls clear of it rather than
   hiding behind it. */
.demo__cap {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  display: flex; align-items: flex-start; gap: .5rem;
  padding: .5rem .7rem;
  background: oklch(15% 0.006 70 / .93);
  backdrop-filter: blur(7px); -webkit-backdrop-filter: blur(7px);
  border-top: 1px solid var(--color-night-rule);
  box-shadow: 0 -12px 26px -20px oklch(0% 0 0 / .95);
}
.demo__cap-step {
  flex: none; font-variant-numeric: tabular-nums; font-weight: 700; font-size: .82em;
  letter-spacing: .05em; color: var(--color-accent);
  border: 1px solid var(--color-accent); border-radius: 999px; padding: .08rem .42rem;
  line-height: 1.4;
}
.demo__cap-text {
  color: var(--color-on-night); line-height: 1.35; font-weight: 600; min-width: 0;
}
.demo__cap[data-in] .demo__cap-text,
.demo__cap[data-in] .demo__cap-step {
  animation: demo-cap-in .42s cubic-bezier(.2,.7,.3,1) both;
}
.demo__cap[data-in] .demo__cap-step { animation-delay: .04s; }
@keyframes demo-cap-in { from { opacity: 0; transform: translateY(.5rem); } }

/* Where am I in the loop, and does it end? */
.demo__progress { position: absolute; left: 0; top: 0; right: 0; height: 2px; z-index: 3;
  overflow: hidden; background: oklch(30% 0.008 70 / .5); }
.demo__progress i { display: block; height: 100%; width: 100%;
  background: var(--color-accent); opacity: .9; transform: scaleX(0); transform-origin: 0 50%; }

@media (prefers-reduced-motion: reduce) {
  .demo__progress { display: none; }
  .demo__cap[data-in] .demo__cap-text,
  .demo__cap[data-in] .demo__cap-step { animation: none; }
  .demo__cursor { display: none; }
  .demo__scene { transition: none; }
  .demo__caret { animation: none; }
}

/* --- demo: roomier on a real screen -------------------------------------------------
   NOTE: this is a min-width query. The rest of this stylesheet is desktop-first with
   max-width breakpoints; do not assume mobile-first when adding rules near here. */
@media (min-width: 60rem) {
  .demo { height: clamp(30rem, 68vh, 40rem); font-size: clamp(.72rem, .8cqw + .52rem, .92rem); }
  .demo__view { padding: .85rem; }
  .demo__scene { padding: .85rem .85rem calc(var(--demo-cap-h, 3.4rem) + .6rem); }
}

/* A result needs a snippet to read as a result. */
.demo__snippet {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  color: var(--color-on-night-2); font-size: .88em; line-height: 1.4; margin-top: .12rem;
}
.demo__row--yours .demo__snippet { color: var(--color-on-night); }
.demo__title { color: oklch(78% 0.085 250); }
.demo__row--yours .demo__title { color: var(--color-accent); }

/* A real result stacks: URL line, then the title, then the snippet. Without this the
   breadcrumb and the headline run together on one line and the block stops reading as a SERP. */
.demo__row > span:last-child { display: block; }
.demo__url { display: block; margin-bottom: .05rem; }
.demo__title { display: block; font-size: 1.08em; }

/* --- demo: the search homepage state ------------------------------------------------- */
.demo__scene--home { display: grid; place-items: center; }
.demo__home { width: 100%; max-width: 22rem; text-align: center; }
.demo__wordmark {
  font-family: var(--font-display, Georgia, serif); font-size: 2.1em; letter-spacing: -.02em;
  color: var(--color-on-night); margin-bottom: .9rem; opacity: .92;
}
.demo__homebar {
  display: flex; align-items: center; gap: .45rem; padding: .5rem .55rem .5rem .7rem;
  border: 1px solid var(--color-night-rule); border-radius: 999px;
  background: oklch(24% 0.008 70); text-align: left;
}
.demo__homebar svg { flex: none; opacity: .55; }
.demo__homebar .demo__typed { flex: 1 1 auto; min-width: 0; }
.demo__go {
  flex: none; display: grid; place-items: center; width: 1.7em; height: 1.7em;
  border-radius: 50%; border: 0; cursor: default;
  background: var(--color-accent); color: oklch(18% 0 0);
  transition: transform var(--dur-fast) var(--ease-out), filter var(--dur-fast) var(--ease-out);
}
.demo__go[data-pressed] { transform: scale(.88); filter: brightness(1.15); }

/* --- demo: an AI Overview shaped like an AI Overview ---------------------------------- */
.demo__ai-lead { margin: 0 0 .4rem; }
.demo__ai-points { margin: 0 0 .1rem; padding: 0; list-style: none; display: grid; gap: .32rem; }
.demo__ai-points li {
  display: grid; grid-template-columns: .5rem 1fr; gap: .45rem; align-items: start;
  color: var(--color-on-night); line-height: 1.42;
}
.demo__ai-points li::before {
  content: ""; width: .28rem; height: .28rem; border-radius: 50%; margin-top: .55em;
  background: var(--color-on-night-2);
}
.demo__ai-points b { font-weight: 600; }
.demo__inline-src {
  display: inline-block; margin-left: .3rem; font-size: .82em; padding: .02rem .34rem;
  border: 1px solid var(--color-night-rule); border-radius: 999px; color: var(--color-on-night-2);
  white-space: nowrap; vertical-align: baseline;
}
.demo__inline-src--yours { border-color: var(--color-accent); color: var(--color-accent); font-weight: 600; }

/* --- demo: People Also Ask that actually opens ----------------------------------------- */
.demo__paa-q {
  display: flex; width: 100%; align-items: center; justify-content: space-between; gap: .5rem;
  padding: 0; border: 0; background: none; cursor: default; text-align: left;
  color: var(--color-on-night); font: inherit; line-height: 1.35;
}
.demo__chev {
  flex: none; width: .5rem; height: .5rem; border-right: 1.5px solid var(--color-on-night-2);
  border-bottom: 1.5px solid var(--color-on-night-2); transform: rotate(45deg);
  transition: transform var(--dur-base) var(--ease-out); margin-bottom: .18em;
}
.demo__paa li[data-open] .demo__chev { transform: rotate(225deg); margin-bottom: -.1em; }
.demo__paa-a {
  display: grid; grid-template-rows: 0fr; overflow: hidden;
  transition: grid-template-rows var(--dur-base) var(--ease-out),
              opacity var(--dur-base) var(--ease-out);
  opacity: 0;
  /* grid-template-rows is a layout property; contain bounds the reflow to this subtree. */
  contain: layout paint;
}
.demo__paa li[data-open] .demo__paa-a { grid-template-rows: 1fr; opacity: 1; }
.demo__paa-a > div { min-height: 0; }
.demo__paa-a p { margin: .35rem 0 .25rem; color: var(--color-on-night-2); line-height: 1.45; }

/* --- the chat assistant animation ------------------------------------------------------ */
.chat {
  --chat-radius: 14px;
  position: relative; display: grid; grid-template-rows: auto 1fr auto auto;
  background: oklch(19% 0.006 70); border: 1px solid var(--color-night-rule);
  border-radius: var(--chat-radius); overflow: hidden; container-type: inline-size;
  font-size: clamp(.68rem, .8cqw + .5rem, .86rem);
  box-shadow: 0 1px 2px oklch(0% 0 0 / .28), 0 6px 14px -8px oklch(0% 0 0 / .5);
  min-height: 17rem;
}
.chat__head {
  display: flex; align-items: center; gap: .5rem; padding: .5rem .7rem;
  border-bottom: 1px solid var(--color-night-rule); color: var(--color-on-night-2);
  font-size: .92em; letter-spacing: .06em; text-transform: uppercase;
}
.chat__dot { width: .45rem; height: .45rem; border-radius: 50%; background: var(--color-accent); }
.chat__body { padding: .8rem; display: flex; flex-direction: column; gap: .6rem; justify-content: flex-end; }
.chat__msg { max-width: 88%; padding: .5rem .7rem; border-radius: 12px; line-height: 1.45; opacity: 0;
  transform: translateY(.35rem);
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out); }
.chat__msg[data-on] { opacity: 1; transform: none; }
.chat__msg--you { align-self: flex-end; background: oklch(30% 0.02 250); color: var(--color-on-night);
  border-bottom-right-radius: 4px; }
.chat__msg--bot { align-self: flex-start; background: oklch(23% 0.018 250);
  border: 1px solid oklch(38% 0.045 250); color: var(--color-on-night); border-bottom-left-radius: 4px; }
.chat__typing { display: inline-flex; gap: .22rem; align-items: center; }
.chat__typing i { width: .3rem; height: .3rem; border-radius: 50%; background: var(--color-on-night-2);
  animation: chat-bounce 1s infinite ease-in-out; }
.chat__typing i:nth-child(2) { animation-delay: .15s; }
.chat__typing i:nth-child(3) { animation-delay: .3s; }
@keyframes chat-bounce { 0%,60%,100% { transform: translateY(0); opacity: .45; }
                          30% { transform: translateY(-.18rem); opacity: 1; } }
.chat__cites { display: flex; flex-wrap: wrap; gap: .25rem; margin-top: .45rem; }
.chat__foot { display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  padding: .5rem .7rem; border-top: 1px solid var(--color-night-rule); }
.chat__note { color: var(--color-on-night-2); font-size: .86em; line-height: 1.4; }
/* The message box. Deliberately not a real <input>: the panel is one image to a screen reader,
   and a focusable field inside it would be a tab stop that does nothing. */
.chat__composer {
  display: flex; align-items: center; gap: .5rem;
  padding: .55rem .7rem; border-top: 1px solid var(--color-night-rule);
  background: oklch(16% 0.006 70);
}
.chat__field {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center;
  padding: .4rem .75rem; border: 1px solid var(--color-night-rule); border-radius: 999px;
  background: oklch(23% 0.008 70); color: var(--color-on-night); line-height: 1.4;
  white-space: nowrap; overflow: hidden;
  transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.chat__field[data-focus] { border-color: oklch(55% 0.10 250);
  box-shadow: 0 0 0 3px oklch(55% 0.10 250 / .16); }
.chat__ph { color: var(--color-on-night-2); }
.chat__field[data-typed] .chat__ph { display: none; }
.chat__caret { flex: none; width: 1px; height: 1.05em; margin-left: 1px; display: none;
  background: var(--color-on-night); animation: chat-caret 1.05s steps(1) infinite; }
.chat__field[data-focus] .chat__caret { display: block; }
@keyframes chat-caret { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
.chat__send {
  flex: none; display: grid; place-items: center; width: 1.9rem; height: 1.9rem;
  border-radius: 50%; background: oklch(28% 0.012 70); color: var(--color-on-night-2);
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.chat__send svg { width: .95rem; height: .95rem; display: block; }
.chat__field[data-typed] ~ .chat__send { background: var(--color-accent); color: oklch(20% 0.02 70); }
.chat__send[data-press] { transform: scale(.85); }

@media (prefers-reduced-motion: reduce) {
  .chat__msg { opacity: 1; transform: none; }
  .chat__typing i { animation: none; }
  .chat__caret { animation: none; }
}
@media (min-width: 60rem) { .chat { min-height: 21rem; } }
