/* ==========================================================================
   Site — section layouts
   ==========================================================================

   One visual language, fourteen different layouts. The shared vocabulary:

     - Paper: the warm page, with a white band behind every other act from
       "Why" onward. The two whites differ by a few points of lightness, so
       the page gets a rhythm without ever changing theme mid-scroll.
     - Charcoal stages: the app's own interrupt gradient, with the brand's
       indigo corner circle. Used only where the product itself is on show
       (hero, demo, featured card type, heatmap) or where a card is the
       emphasised one (the Builder, Pro, the waitlist).
     - Tint chips: 40-48px rounded squares on indigo, sage or amber tint,
       with a stroke icon, exactly as the app draws them.
   ========================================================================== */

.act {
  position: relative;
  padding-block: var(--sp-11);
  z-index: var(--z-content);
}
.act > .wrap { position: relative; z-index: var(--z-content); }

/* Skip the layout, style and paint work for the acts nobody has scrolled to.

   The homepage is thirteen acts, and before this rule the browser laid out,
   styled, calculated and made a paint record for every one of them on every
   single load — including the ten that are four to ten screens down. On a
   device whose audience the site itself describes as mid-range Android, that
   is the largest avoidable cost on the page, and it lands on the main thread
   during exactly the window LCP is being measured in.

   `contain-intrinsic-size: auto 900px` reserves a height so the scrollbar,
   scroll anchoring and every reveal threshold stay stable; the `auto` form
   makes the browser swap in the real measurement after the first render and
   remember it.

   Listed act by act rather than as `.act:not(:first-of-type)` on purpose.
   Three of them are excluded because breaking them is visible:
     - act-problem is the first act and is what a reader lands on.
     - act-mechanic holds the interactive demo, whose measured geometry the
       reveal observer and the Playwright tests both depend on.
     - act-faq holds a <details> list whose height changes after render and
       would fight the reserved size every time a reader opened one. */
.act-turn,
.act-types,
.act-sources,
.act-permissions,
.act-setup,
.act-gains,
.act-who,
.act-compare,
.act-pricing,
.act-waitlist {
  content-visibility: auto;
  contain-intrinsic-size: auto 900px;
}

.act-head { margin-bottom: var(--sp-8); }
.act-head .act-lede { max-width: 58ch; }

/* Title on the left, lede on the right, both sitting on one baseline.
   Used where the lede is a counterweight to the title rather than its
   continuation; elsewhere the lede follows the title as usual. */
@media (min-width: 901px) {
  .act-head-split {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
    gap: var(--sp-6) var(--sp-8);
    align-items: end;
  }
  .act-head-split .act-lede { margin-top: 0; padding-bottom: 0.35em; }
  .act-head-split .act-title { max-width: none; }
}

/* A short line under an act that points somewhere else on the site.
   Its links sit on a 1.7 line box as 24px inline-blocks, which clears the
   WCAG 2.5.8 floor without changing the paragraph's rhythm. */
.act-note {
  margin-top: var(--sp-5);
  font-size: var(--fs-small);
  line-height: 1.7;
  color: var(--ink-soft);
  max-width: 62ch;
}
.act-note a {
  color: var(--indigo-deep);
  text-decoration: underline;
  text-decoration-color: rgba(75, 58, 192, 0.4);
  text-underline-offset: 3px;
  display: inline-block;
  min-height: 24px;
  transition: text-decoration-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.act-note a:hover { text-decoration-color: currentColor; color: var(--indigo); }

/* ── Page rhythm ────────────────────────────────────────────────────────
   Alternate acts sit on a white band. Same light theme throughout — the
   difference is a few points of lightness, which is enough to tell one act
   from the next without a hairline and never reads as a second website. */
.home .act-turn,
.home .act-types,
.home .act-permissions,
.home .act-gains,
.home .act-compare {
  background: var(--surface);
  box-shadow: inset 0 1px 0 var(--line), inset 0 -1px 0 var(--line);
}

/* ═══ SHARED SURFACES ════════════════════════════════════════════════
   The charcoal stage. The gradient is the interrupt overlay's, verbatim
   from the app, and the corner circle is the brand's signature on every
   dark card. The circle is a background on a box that fills its parent, so
   it is clipped by the card and never extends the page's scroll area. */
.stage-orb {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(circle var(--orb-r, 150px) at var(--orb-x, 100%) var(--orb-y, 0%),
      rgba(75, 58, 192, 0.55) 0 calc(var(--orb-r, 150px) - 1px),
      transparent var(--orb-r, 150px));
}

/* ═══ ACT PAIR ══════════════════════════════════════════════════════
   The FAQ and the waitlist are the same beat: the last thing a reader has to
   get through, and the ask that follows it. Stacked, the conversion sits a
   full screen below the last objection it exists to answer. */
.act-pair {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: var(--sp-8);
  align-items: start;
  padding-block: var(--sp-11);
  /* Matches .wrap exactly, so the pair's left edge is the page's. */
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.act-pair > .act { padding-block: 0; }
.act-pair .wrap { max-width: none; padding-inline: 0; }
.act-pair .waitlist-card { max-width: none; }

/* The waitlist card is shorter than the FAQ beside it, so it rides along
   with the reader while they work through the questions. */
@media (min-width: 901px) and (min-height: 760px) {
  .act-pair .act-waitlist {
    position: sticky;
    top: calc(var(--header-total) + var(--sp-5));
  }
}

@media (max-width: 900px) {
  .act-pair { grid-template-columns: minmax(0, 1fr); gap: var(--sp-8); }
}

/* ═══ SCENE CONTAINERS ═══════════════════════════════════════════════
   Every decorative canvas lives inside a bounded box. A canvas released
   full-bleed behind body copy is a collision waiting for a viewport width,
   and a 3D scene has no natural size to respect anyway. */

.visual {
  position: relative;
  border-radius: var(--r-xl);
  overflow: hidden;
  /* Never taller than the viewport minus the sticky header, so a scene can
     never push its own caption off the bottom of the screen. */
  max-height: min(460px, calc(100svh - var(--header-total) - var(--sp-8)));
  background:
    radial-gradient(80% 70% at 50% 40%, rgba(101, 76, 244, 0.10) 0%, transparent 70%),
    var(--bg-warm);
  border: 1px solid var(--line);
  box-shadow: var(--sh-md);
  display: grid;
}

.visual { aspect-ratio: 16 / 9; }
.visual-orbit { aspect-ratio: 5 / 4; }
.visual-dial { aspect-ratio: 4 / 3; }

/* The dark scene needs a dark stage, or it floats on a white card. */
.visual-streak {
  background: var(--stage);
  border-color: rgba(255, 255, 255, 0.08);
  box-shadow: var(--sh-dark);
}

.scene-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  opacity: 0;
  transition: opacity 900ms var(--ease-out);
  z-index: 1;
}
.scene-canvas.is-ready { opacity: 1; }

.visual-caption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 2;
  padding: var(--sp-7) var(--sp-5) var(--sp-4);
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--ink-faint);
  background: linear-gradient(transparent, var(--bg-warm) 45%);
  text-align: center;
}
.visual-streak .visual-caption {
  color: var(--on-dark-faint);
  background: linear-gradient(transparent, #0E0A20 55%);
}

/* The static card shown when WebGL is unavailable or a scene throws. Same
   box, same position — the reader loses the motion, never the meaning. */
.visual-fallback {
  position: relative;
  z-index: 1;
  grid-area: 1 / 1;
  align-self: center;
  justify-self: center;
  width: min(320px, 84%);
  margin: auto;
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: var(--sp-6);
  box-shadow: var(--sh-lg);
  border: 1px solid var(--line);
}
.js.webgl-ready .visual-fallback { display: none; }
/* With motion paused the canvases are hidden (see the end of this file), so
   the static version has to come back, or a reader who asked for less motion
   is shown five empty stages. */
html[data-motion='off'].webgl-ready .visual-fallback { display: block; }
html[data-motion='off'].webgl-ready .fallback-orbit { display: grid; }
.no-webgl .scene-canvas, .no-webgl .scene-bg { display: none; }

/* ── Static fallbacks ──────────────────────────────────────────────────
   Every scene needs a version that needs no WebGL and no JavaScript. These
   are not placeholders: each one says the same thing the scene says. */

/* Connector constellation → four tools, one core. */
.fallback-orbit { display: grid; gap: var(--sp-4); text-align: center; }
.orbit-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.orbit-list li {
  padding: 0.5rem 0.4rem;
  border-radius: var(--r-sm);
  background: var(--sage-tint);
  color: var(--sage-strong);
  font-size: var(--fs-micro);
  font-weight: 700;
}
.orbit-core {
  padding: var(--sp-3);
  border-radius: var(--r-md);
  background: var(--indigo);
  color: #fff;
  font-size: var(--fs-body);
  font-weight: 800;
  letter-spacing: var(--tracking-tight);
}

/* Frequency dial → ten countable pips, five lit. */
.fallback-dial { width: 100%; background: transparent; box-shadow: none; border: 0; }
.dial-pips {
  position: relative;
  display: flex;
  gap: 0.5rem;
  justify-content: center;
  align-items: center;
  width: 100%;
}
.dial-pips i {
  flex: 1 1 0;
  max-width: 34px;
  height: 46px;
  border-radius: 6px;
  background: #DCD7CE;
}
.dial-pips i.on { background: var(--indigo); }
.dial-gate {
  position: absolute;
  left: 50%;
  top: -6px;
  bottom: -6px;
  width: 12px;
  transform: translateX(-2px);
  border-radius: 4px;
  background: var(--charcoal);
  box-shadow: 0 2px 8px rgba(20, 16, 31, 0.3);
}

/* Streak → a 26×7 grid, drawn entirely in CSS. Layered radial gradients
   supply the variation and an intersect-composited mask punches out the
   cell grid, so this needs no script and no 182 elements of markup. */
.fallback-streak { width: 100%; background: transparent; box-shadow: none; border: 0; }
.heat {
  width: 100%;
  height: 100%;
  min-height: 120px;
  background:
    radial-gradient(ellipse 22% 40% at 12% 30%, rgba(139, 119, 255, 0.95), transparent 70%),
    radial-gradient(ellipse 18% 34% at 30% 70%, rgba(139, 119, 255, 0.45), transparent 70%),
    radial-gradient(ellipse 24% 44% at 50% 24%, rgba(139, 119, 255, 0.8), transparent 70%),
    radial-gradient(ellipse 14% 30% at 64% 66%, rgba(102, 199, 158, 0.7), transparent 70%),
    radial-gradient(ellipse 20% 38% at 80% 38%, rgba(139, 119, 255, 0.7), transparent 70%),
    radial-gradient(ellipse 16% 32% at 93% 72%, rgba(139, 119, 255, 0.4), transparent 70%),
    rgba(255, 255, 255, 0.08);
  --cell: 11px;
  --gap: 3px;
  mask-image:
    repeating-linear-gradient(90deg, #000 0 var(--cell), transparent var(--cell) calc(var(--cell) + var(--gap))),
    repeating-linear-gradient(0deg, #000 0 var(--cell), transparent var(--cell) calc(var(--cell) + var(--gap)));
  -webkit-mask-image:
    repeating-linear-gradient(90deg, #000 0 var(--cell), transparent var(--cell) calc(var(--cell) + var(--gap))),
    repeating-linear-gradient(0deg, #000 0 var(--cell), transparent var(--cell) calc(var(--cell) + var(--gap)));
  mask-composite: intersect;
  -webkit-mask-composite: source-in;
}

.fallback-label {
  font-size: var(--fs-eyebrow);
  text-transform: uppercase;
  letter-spacing: var(--tracking-eyebrow);
  font-weight: 700;
  color: var(--indigo);
}
.fallback-q { font-family: var(--font-serif); font-size: 1.5rem; line-height: 1.25; margin-top: var(--sp-3); }
.fallback-a { margin-top: var(--sp-4); padding-top: var(--sp-4); border-top: 1px solid var(--line); }
.fallback-answer { font-size: var(--fs-body); }
.fallback-source { font-size: var(--fs-micro); color: var(--ink-faint); margin-top: var(--sp-2); display: block; }

/* The one scene that IS a full-bleed background: a field of app icons
   behind the problem act's heading reads as texture, not as an object. It
   fades out before the rival list starts, so no paragraph is ever read
   against it. */
.scene-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: var(--z-canvas);
  pointer-events: none;
  opacity: 0;
  transition: opacity 1200ms var(--ease-out);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.6) 22%, transparent 42%);
  mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.6) 22%, transparent 42%);
}
.scene-bg.is-ready { opacity: 0.38; }

/* ═══ HEADER ════════════════════════════════════════════════════════
   A floating pill. At the top of the page it is invisible and the logo sits
   on the page's own left edge; once the reader scrolls, the pill frames the
   row in frosted paper. Base layout lives in base.css; this is the skin. */
.site-header .nav-row {
  width: calc(100% - 2 * var(--gutter) + 28px);
  max-width: calc(var(--wrap) - 2 * var(--gutter) + 28px);
  height: 54px;
  padding-inline: 14px 7px;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  transition:
    background var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out);
}
.site-header.is-stuck {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-bottom-color: transparent;
}
/* The legal pages load no header script, so their pill is always framed
   rather than left transparent over scrolling text. */
.site-header.is-stuck .nav-row,
.legal-page .site-header .nav-row {
  background: color-mix(in srgb, var(--surface) 80%, transparent);
  backdrop-filter: blur(16px) saturate(1.5);
  -webkit-backdrop-filter: blur(16px) saturate(1.5);
  border-color: color-mix(in srgb, var(--line-strong) 70%, transparent);
  box-shadow: 0 1px 2px rgba(20, 16, 31, 0.04), 0 10px 30px rgba(20, 16, 31, 0.08);
}
.nav-actions { margin-left: auto; }
.site-header::before {
  content: '';
  position: absolute;
  inset: 0 0 -10px;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(var(--bg-warm) 0%, color-mix(in srgb, var(--bg-warm) 88%, transparent) 62%, transparent 100%);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}
.site-header.is-stuck::before,
.legal-page .site-header::before { opacity: 1; }
.nav-links { gap: 2px; }
.nav-links a {
  padding-inline: 0.85rem;
  border-radius: var(--r-pill);
  transition: color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
}
.nav-links a::after { display: none; }
.nav-links a:hover { background: rgba(20, 16, 31, 0.05); color: var(--ink); }
.nav-actions .btn-sm { min-height: 40px; }

/* The sheet's two groups: acts on this page, then pages elsewhere. */
.nav-sheet-group {
  margin: var(--sp-5) var(--sp-2) var(--sp-1);
  font-size: var(--fs-eyebrow);
  font-weight: 700;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--on-dark-faint);
}
.nav-sheet-group:first-child { margin-top: var(--sp-2); }

/* ═══ ACT 0 · HERO ═══════════════════════════════════════════════════ */

.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* The whole hero, copy and phone, is the first screen. */
  min-height: 100svh;
  padding-block: calc(var(--header-total) + var(--sp-5)) var(--sp-5);
  overflow: hidden;
  background:
    radial-gradient(60% 70% at 82% 35%, rgba(101, 76, 244, 0.14) 0%, transparent 62%),
    radial-gradient(50% 60% at 6% 100%, rgba(244, 203, 61, 0.09) 0%, transparent 60%),
    var(--bg-warm);
}
/* A faint dot grid behind the stage: the page's one texture, and it fades
   out toward the copy so the headline never sits on it. */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: radial-gradient(rgba(20, 16, 31, 0.09) 1px, transparent 1.2px);
  background-size: 22px 22px;
  -webkit-mask-image: radial-gradient(55% 65% at 80% 45%, #000 0%, transparent 75%);
  mask-image: radial-gradient(55% 65% at 80% 45%, #000 0%, transparent 75%);
}

.hero-grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  align-items: center;
  gap: var(--sp-8);
  width: 100%;
}
.hero-copy { min-width: 0; }

.hero-badge {
  padding: 0.45rem 0.85rem;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  border: 1px solid var(--line-strong);
  color: var(--ink-soft);
  letter-spacing: 0.12em;
  margin-bottom: var(--sp-5);
}

.hero-title {
  font-size: var(--fs-display);
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-display);
  font-weight: 800;
  text-wrap: balance;
  /* A single long word in an 800-weight display face must never be allowed
     to overrun the column — this is the hard backstop under the type scale. */
  overflow-wrap: break-word;
  max-width: 18ch;
}
.hero-title .accent {
  background: linear-gradient(100deg, var(--indigo) 0%, var(--indigo-deep) 45%, var(--amber) 130%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.lede {
  margin-top: var(--sp-5);
  font-size: var(--fs-lede);
  line-height: var(--lh-loose);
  color: var(--ink-soft);
  text-wrap: pretty;
}
.hero .lede { max-width: 46ch; line-height: 1.6; }

.hero-cta { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-7); }

/* The stage: the phone, drawn and played as the app draws and plays its
   interrupt (app-ui.css, interrupt.js), with a soft indigo glow behind it.
   The phone is sized so the whole hero, copy and phone, fits one screen. */
.hero-stage { position: relative; min-width: 0; display: flex; justify-content: center; }
.hero-stage::before {
  content: '';
  position: absolute;
  inset: 6% 0;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(101, 76, 244, 0.26), transparent);
  pointer-events: none;
}
.hero-visual { --fit-reserve: calc(var(--header-total) + 124px); }

/* Out of the hero and into its own strip: a feature list inside the hero
   competes with the value prop instead of supporting it. Three columns
   divided by hairlines, the first flush to the page edge. */
.hero-facts {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: var(--sp-6) var(--gutter);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-5);
  font-size: var(--fs-small);
  color: var(--ink-soft);
  line-height: 1.5;
}
.hero-facts li { display: flex; gap: var(--sp-3); align-items: center; min-width: 0; }
.hero-facts li + li { border-left: 1px solid var(--line-strong); padding-left: var(--sp-5); }
.hero-facts strong { color: var(--ink); font-weight: 700; }

/* Tint chips: the app's icon pattern. */
.fact-icon,
.rule-icon,
.gain-icon,
.data-icon,
.source-icon,
.who-avatar {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: 12px;
  background: var(--indigo-tint);
  color: var(--indigo-deep);
}
.fact-icon-sage, .gain-icon-sage { background: var(--sage-tint); color: var(--sage-strong); }
.fact-icon-amber, .gain-icon-amber { background: var(--amber-soft); color: var(--amber-deep); }
.fact-icon-indigo { background: var(--indigo-tint); color: var(--indigo-deep); }

/* ═══ THE ANSWER ════════════════════════════════════════════════════
   Now directly under the fact strip. Typeset as a definition: the title as
   a label in its own column, the three sentences as three numbered columns.
   content.css styles the same block on the content pages; everything here is
   scoped to the homepage so those stay as they are. */
.home .answer-first {
  padding-block: var(--sp-8);
  background: transparent;
  border-top: 1px solid var(--line);
  border-bottom: 0;
}
.summary-grid {
  display: grid;
  grid-template-columns: minmax(0, 13rem) minmax(0, 1fr);
  gap: var(--sp-6) var(--sp-8);
  align-items: start;
}
.home .answer-first-title {
  font-size: var(--fs-eyebrow);
  font-weight: 700;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  line-height: 1.6;
  color: var(--indigo-deep);
  margin: 0;
  max-width: 16ch;
}
.home .answer-first-body {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-6);
  counter-reset: sentence;
}
.home .answer-first-body p {
  counter-increment: sentence;
  font-size: var(--fs-small);
  line-height: 1.7;
  color: var(--ink-soft);
  max-width: 62ch;
  margin: 0;
  padding-top: var(--sp-4);
  border-top: 2px solid var(--ink);
}
.home .answer-first-body p::before {
  content: '0' counter(sentence);
  display: block;
  margin-bottom: var(--sp-2);
  font-family: var(--font-serif);
  font-size: 1rem;
  color: var(--indigo);
}
.home .answer-first-body strong { font-weight: 700; color: var(--ink); }
.home .answer-first-body a {
  color: var(--indigo-deep);
  text-decoration: underline;
  text-decoration-color: rgba(75, 58, 192, 0.4);
  text-underline-offset: 3px;
}
.home .answer-first-body a:hover { text-decoration-color: currentColor; }

/* ═══ ACT 1 · PROBLEM ═══════════════════════════════════════════════ */

/* `clip`, not `hidden`: `hidden` makes the act a scroll container of its own,
   and every screen inside it then snaps within the act instead of within the
   page, so the browser stops treating them as places to come to rest. */
.act-problem { overflow: clip; }
.act-problem .act-head,
.act-problem .rival-list,
.act-problem .problem-turn { position: relative; z-index: 1; }

/* A ledger, not four boxes: numbered rows, each category with its own tag
   colour, the products named in bold, and the honest account beside them. */
.rival-list { counter-reset: rival; border-top: 2px solid var(--ink); }
.rival-row {
  counter-increment: rival;
  display: grid;
  grid-template-columns: 3rem minmax(0, 17rem) minmax(0, 1fr);
  gap: var(--sp-6);
  padding: var(--sp-6) var(--sp-4) var(--sp-6) 0;
  border-bottom: 1px solid var(--line);
  transition: background var(--dur-base) var(--ease-out);
}
.rival-row::before {
  content: '0' counter(rival);
  font-family: var(--font-serif);
  font-size: 1.125rem;
  line-height: 1.6;
  color: var(--indigo);
}
@media (hover: hover) and (pointer: fine) {
  .rival-row:hover { background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.85) 20%); }
}
.rival-row dt { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-3); }
.rival-kind {
  display: inline-flex;
  padding: 0.3rem 0.7rem;
  border-radius: var(--r-pill);
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.01em;
  background: #F1EFF6;
  color: var(--ink-soft);
}
.rival-kind-friction { background: var(--amber-soft); color: var(--amber-ink); }
.rival-kind-locked { background: #F1EFF6; color: var(--ink-soft); }
.rival-kind-byo { background: var(--sage-tint); color: var(--sage-strong); }
.rival-kind-wave { background: var(--indigo-tint); color: var(--indigo-deep); }
.rival-name {
  font-size: 1.1875rem;
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  line-height: 1.3;
  color: var(--ink);
}
.rival-row dd { margin: 0; font-size: var(--fs-body); color: var(--ink-soft); line-height: var(--lh-loose); max-width: 64ch; }
.rival-note { margin-top: var(--sp-4); font-size: var(--fs-micro); color: var(--ink-faint); }

/* The turn: the deeper problem in prose, beside the one reader who asked for
   the fix. */
.problem-turn {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--sp-8);
  align-items: center;
  margin-top: var(--sp-9);
}
.problem-close h3 {
  font-size: var(--fs-h3);
  letter-spacing: var(--tracking-tight);
  margin-bottom: var(--sp-3);
}
.problem-close p { color: var(--ink-soft); line-height: var(--lh-loose); max-width: 56ch; }
.problem-close em { font-style: italic; color: var(--ink); }
.problem-punch {
  margin-top: var(--sp-5);
  font-family: var(--font-serif);
  font-size: clamp(1.25rem, 1.05rem + 0.8vw, 1.625rem);
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: var(--ink) !important;
}

.pull-quote {
  position: relative;
  overflow: hidden;
  padding: var(--sp-8) var(--sp-7) var(--sp-6);
  background: var(--stage);
  color: var(--on-dark);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-dark);
  --orb-r: 130px;
  --orb-x: 102%;
  --orb-y: 104%;
}
.pull-quote::before {
  content: '“';
  position: absolute;
  z-index: 1;
  top: 0.05em; left: 0.32em;
  font-family: var(--font-serif);
  font-size: 7rem;
  color: rgba(139, 119, 255, 0.45);
  line-height: 1;
  pointer-events: none;
}
.pull-quote blockquote,
.pull-quote figcaption { position: relative; z-index: 1; }
.pull-quote blockquote p {
  font-family: var(--font-serif);
  font-size: clamp(1.1875rem, 1rem + 0.8vw, 1.5rem);
  line-height: 1.5;
  letter-spacing: -0.01em;
  text-wrap: pretty;
}
.pull-quote em { color: var(--amber); font-style: italic; }
.pull-quote figcaption {
  margin-top: var(--sp-5);
  padding-right: 4.5rem;
  font-size: var(--fs-micro);
  color: var(--on-dark-faint);
  letter-spacing: 0.02em;
}
.pull-quote figcaption a { color: var(--on-dark-soft); text-decoration: underline; text-underline-offset: 2px; }

/* ═══ ACT 2 · WHY IT WORKS ═══════════════════════════════════════════
   The heading holds still while the principles scroll past it. */

.why-layout {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: var(--sp-8);
  align-items: start;
}
.why-head { margin-bottom: 0; }
@media (min-width: 901px) {
  .why-head { position: sticky; top: calc(var(--header-total) + var(--sp-7)); }
}

.principle-list { border-top: 2px solid var(--ink); }
.principle {
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr);
  gap: var(--sp-5);
  align-items: start;
  padding-block: var(--sp-7);
  border-bottom: 1px solid var(--line);
}
.principle-n {
  font-size: clamp(2.5rem, 2rem + 2vw, 3.75rem);
  font-weight: 800;
  line-height: 0.9;
  letter-spacing: -0.05em;
  color: var(--indigo);
  font-variant-numeric: tabular-nums;
}
.principle-body h3 {
  font-size: clamp(1.25rem, 1.1rem + 0.7vw, 1.625rem);
  letter-spacing: var(--tracking-tight);
  line-height: 1.25;
  text-wrap: balance;
}
.principle-body p { margin-top: var(--sp-3); font-size: var(--fs-body); color: var(--ink-soft); line-height: var(--lh-loose); max-width: 54ch; }

.turn-punch {
  margin-top: var(--sp-10);
  max-width: 30ch;
  font-family: var(--font-serif);
  font-size: clamp(1.5rem, 1.05rem + 1.9vw, 2.5rem);
  line-height: 1.3;
  letter-spacing: -0.015em;
  color: var(--ink);
  text-wrap: pretty;
}
.turn-punch-mark {
  background: linear-gradient(transparent 62%, var(--indigo-tint) 62%);
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* ═══ ACT 3 · THE MECHANIC ══════════════════════════════════════════
   One screen. The copy and the phone are sized together so the whole
   two-tap story, question to app opening, is on screen at once. */

.act-mechanic,
.act-types {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: calc(100svh - var(--header-total));
  padding-block: clamp(var(--sp-3), 3vh, var(--sp-8));
}
/* A short laptop screen: the same content, set a notch tighter, so the copy
   column keeps pace with the phone beside it. */
@media (min-width: 901px) and (max-height: 820px) {
  .mechanic-copy .act-head,
  .types-copy .act-head { margin-bottom: var(--sp-4); }
  .rules { gap: var(--sp-3); }
  .rule { padding-top: var(--sp-3); }
  .rule-icon { top: var(--sp-3); }
  .rule p { font-size: 0.8125rem; line-height: 1.55; }
  .type-card { padding-block: var(--sp-2); }
  .type-q { font-size: 0.8125rem; }
}
.act-mechanic .act-title,
.act-types .act-title { font-size: clamp(2rem, 1.15rem + 2.5vw, 3.25rem); }
.act-mechanic .act-lede,
.act-types .act-lede { margin-top: var(--sp-4); font-size: var(--fs-body); line-height: 1.65; }

.mechanic-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.9fr);
  gap: var(--sp-8);
  align-items: center;
}
.mechanic-copy,
.mechanic-stage { min-width: 0; }
.mechanic-copy .act-head { margin-bottom: var(--sp-6); }

/* Each rule: its icon in the margin, the label, the line, the reason. */
.rules { display: grid; gap: var(--sp-4); }
.rule {
  position: relative;
  padding: var(--sp-4) 0 0 calc(40px + var(--sp-4));
  border-top: 1px solid var(--line);
}
.rule:first-child { border-top: 2px solid var(--ink); }
.rule dt { margin: 0; }
.rule dd { margin: 0; }
.rule-icon { position: absolute; left: 0; top: var(--sp-4); }
.rule-label {
  font-size: var(--fs-eyebrow);
  font-weight: 700;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--indigo-deep);
}
.rule h3 { margin-top: 2px; font-size: 1.0625rem; letter-spacing: var(--tracking-tight); line-height: 1.3; }
.rule p { margin-top: var(--sp-1); font-size: var(--fs-small); color: var(--ink-soft); line-height: 1.6; }

.demo-wrap { margin: 0; }
.demo { position: relative; }
.demo-stage { position: relative; display: flex; justify-content: center; }
.demo-stage::before {
  content: '';
  position: absolute;
  inset: 4% 6%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(101, 76, 244, 0.24), transparent);
  pointer-events: none;
}
.mechanic-stage .device-fit { --fit-reserve: calc(var(--header-total) + 152px); }

/* The live line under the phone: what just happened, for every reader. */
.demo-status {
  min-height: 2.8em;
  max-width: 44ch;
  margin: var(--sp-3) auto 0;
  font-size: var(--fs-micro);
  line-height: 1.4;
  text-align: center;
  color: var(--ink-soft);
}
.demo-caption { font-size: var(--fs-micro); font-weight: 600; text-align: center; color: var(--ink-faint); }

.demo-aside { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.float-chip {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0.5rem 0.875rem;
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--ink);
  font-size: var(--fs-micro);
  font-weight: 700;
  border: 1px solid var(--line);
  box-shadow: 0 1px 2px rgba(20, 16, 31, 0.06), 0 12px 32px rgba(20, 16, 31, 0.14);
  white-space: nowrap;
}
/* Positioned on the phone itself, so they hug its edge. Only where there is
   margin beside the phone for them: below a desktop width they would sit on
   the copy column. */
@media (max-width: 1100px) { .float-chip { display: none; } }
.float-chip-a { top: 20%; left: -20%; }
.float-chip-b { top: 50%; right: -17%; background: var(--sage-tint); color: var(--sage-strong); }
.float-chip-c { bottom: 18%; left: -16%; }

/* ═══ ACT 4 · CARD TYPES ════════════════════════════════════════════
   One screen: the eight types as a list beside a phone that puts up
   whichever one is chosen, exactly as the app renders it, and otherwise
   steps through all eight the way a review session does. */

.types-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(300px, 0.62fr);
  gap: var(--sp-8);
  align-items: center;
}
.types-copy { min-width: 0; }
.types-copy .act-head { margin-bottom: var(--sp-6); }
.types-stage { position: relative; display: flex; justify-content: center; min-width: 0; }
.types-stage::before {
  content: '';
  position: absolute;
  inset: 4% -6%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(101, 76, 244, 0.2), transparent);
  pointer-events: none;
}
.types-stage .device-fit { --fit-reserve: calc(var(--header-total) + 72px); }

.type-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-2);
}
.type-card {
  position: relative;
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr);
  column-gap: var(--sp-3);
  align-items: start;
  padding: var(--sp-3) var(--sp-4) var(--sp-3) var(--sp-3);
  border-radius: var(--r-md);
  border: 1px solid transparent;
  transition: background var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .type-card:hover { background: var(--bg-warm); }
}
.type-card.is-active {
  background: var(--bg-warm);
  border-color: var(--line);
  box-shadow: var(--sh-sm);
}
/* The whole row is the control. Without JavaScript there is nothing for it
   to do, so it is not there. */
.type-pick {
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  cursor: pointer;
}
html:not(.js) .type-pick { display: none; }
.type-pick:focus-visible { outline: 2px solid var(--indigo); outline-offset: 2px; }
.type-glyph {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 11px;
  background: var(--indigo-tint);
  color: var(--indigo-deep);
  transition: background var(--dur-base) var(--ease-out), color var(--dur-base) var(--ease-out);
}
.type-glyph svg { width: 18px; height: 18px; }
.type-card.is-active .type-glyph { background: var(--indigo); color: #fff; }
.type-text { min-width: 0; padding-top: 1px; }
.type-text h3 { font-size: 0.9375rem; font-weight: 700; letter-spacing: var(--tracking-tight); line-height: 1.3; }
.type-q {
  margin-top: 2px;
  font-family: var(--font-serif);
  font-size: 0.875rem;
  line-height: 1.4;
  color: var(--ink-soft);
}
.type-a { margin-top: 3px; font-size: 0.75rem; font-weight: 700; color: var(--sage-strong); }
.cloze-blank {
  display: inline-block;
  min-width: 40px;
  border-bottom: 2px solid var(--indigo);
  vertical-align: baseline;
}

/* ═══ ACT 5 · SOURCES ═══════════════════════════════════════════════ */

.act-sources { overflow: clip; }

.sources-intro {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: var(--sp-8);
  align-items: center;
  margin-bottom: var(--sp-8);
}
.sources-intro .act-head { margin-bottom: 0; }
.sources-intro .visual-orbit { max-height: 420px; }

/* Twelve columns: the four tools span three each, the three alternatives
   span four each, so the two rows have different rhythms and read as two
   groups without a label. */
.source-list {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--sp-4);
}
.source {
  grid-column: span 3;
  position: relative;
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--sp-5);
  display: flex;
  flex-direction: column;
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out);
}
.source-alt {
  grid-column: span 4;
  background: transparent;
  border: 1.5px dashed var(--line-strong);
}
@media (hover: hover) and (pointer: fine) {
  .source:hover { transform: translateY(-3px); box-shadow: var(--sh-md); border-color: var(--indigo-lift); }
}
.source-icon { width: 46px; height: 46px; border-radius: 14px; margin-bottom: var(--sp-5); }
.source-tool .source-icon { background: var(--sage-tint); color: var(--sage-strong); }
.source-alt .source-icon { background: var(--indigo-tint); color: var(--indigo-deep); }
.source-alt:last-child .source-icon { background: #F1EFF6; color: var(--ink-soft); }
.source-badge {
  position: absolute;
  top: var(--sp-5); right: var(--sp-5);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.3rem 0.55rem;
  border-radius: var(--r-pill);
}
.source-badge-free { background: var(--sage-tint); color: var(--sage-strong); }
.source-badge-ai    { background: var(--indigo-tint); color: var(--indigo-deep); }
.source-badge-manual{ background: #F1EFF6; color: var(--ink-soft); }

.source h3 { font-size: var(--fs-h3); letter-spacing: var(--tracking-tight); }
.source p { margin-top: var(--sp-2); font-size: var(--fs-small); color: var(--ink-soft); line-height: var(--lh-loose); }

/* The proof: a corner of a card with its source mark, beside the sentence
   that describes it. */
.source-proof {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--sp-8);
  align-items: center;
  margin-top: var(--sp-9);
}
.source-mock {
  position: relative;
  display: grid;
  gap: var(--sp-3);
  width: 270px;
  padding: var(--sp-5);
  border-radius: 22px;
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: var(--sh-lg);
  transform: rotate(-2.5deg);
}
.source-mock-mark {
  justify-self: end;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0.25rem 0.6rem;
  border-radius: var(--r-pill);
  background: var(--indigo-tint);
  color: var(--indigo-deep);
  font-size: 0.6875rem;
  font-weight: 700;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--indigo) 12%, transparent);
}
.source-mock-q { font-family: var(--font-serif); font-size: 1.125rem; line-height: 1.3; color: var(--ink); }
.source-mock-line { display: block; height: 8px; border-radius: 4px; background: #EEEBF3; }
.source-mock-line-short { width: 60%; }

.source-punch {
  max-width: 52ch;
  font-family: var(--font-serif);
  font-size: clamp(1.1875rem, 1.05rem + 0.55vw, 1.4375rem);
  line-height: 1.55;
  color: var(--ink);
}

/* ═══ ACT 6 · PERMISSIONS ═══════════════════════════════════════════
   A trust act reads top to bottom like a short contract, with the data
   ledger set beside it. */

.perm-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  gap: var(--sp-8);
  align-items: start;
}
.perm-list { border-top: 2px solid var(--ink); }
.perm {
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr);
  gap: var(--sp-4);
  align-items: baseline;
  padding-block: var(--sp-6);
  border-bottom: 1px solid var(--line);
}
.perm-n {
  font-family: var(--font-serif);
  font-size: 1.125rem;
  color: var(--indigo);
  line-height: 1.4;
}
.perm-last .perm-n { color: var(--amber-deep); }
.perm h3 { font-size: var(--fs-h3); letter-spacing: var(--tracking-tight); }
.perm-body { margin: var(--sp-2) 0 0; font-size: var(--fs-body); color: var(--ink-soft); line-height: var(--lh-loose); max-width: 58ch; }

.data-card { display: grid; gap: var(--sp-4); }
.data-panel {
  padding: var(--sp-6);
  border-radius: var(--r-lg);
  border: 1px solid transparent;
}
.data-panel-out { background: var(--indigo-tint); border-color: color-mix(in srgb, var(--indigo) 16%, transparent); }
.data-panel-stay { background: var(--sage-tint); border-color: color-mix(in srgb, var(--sage) 30%, transparent); }
.data-icon { width: 38px; height: 38px; border-radius: 11px; background: var(--surface); margin-bottom: var(--sp-4); }
.data-panel-stay .data-icon { color: var(--sage-strong); }
.data-panel h3 {
  font-size: var(--fs-eyebrow);
  font-weight: 700;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--indigo-deep);
}
.data-panel-stay h3 { color: var(--sage-strong); }
.data-panel p { margin-top: var(--sp-3); font-size: var(--fs-small); color: var(--ink); line-height: var(--lh-loose); }

.privacy-foot {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--sp-6) var(--sp-8);
  align-items: center;
  margin-top: var(--sp-9);
  padding-top: var(--sp-7);
  border-top: 1px solid var(--line);
}
.privacy-close {
  max-width: 52ch;
  font-family: var(--font-serif);
  font-size: clamp(1.1875rem, 1.05rem + 0.55vw, 1.4375rem);
  line-height: 1.5;
  color: var(--ink);
}
.legal-actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }

/* ═══ ACT 7 · SETUP ════════════════════════════════════════════════
   Five numbered stops on one line, with the ratio they end on held in view
   beside them. */

.act-setup { overflow-x: clip; }
.setup-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: var(--sp-9);
  align-items: start;
}
.setup-copy .act-head { margin-bottom: var(--sp-7); }
.setup-aside { display: grid; gap: var(--sp-4); }
@media (min-width: 901px) {
  .setup-aside { position: sticky; top: calc(var(--header-total) + var(--sp-6)); }
}

.act-setup .steps {
  position: relative;
  display: grid;
  gap: var(--sp-6);
  max-width: 620px;
  padding-left: 0;
  counter-reset: step;
}
/* The track, and the fill that follows the reader down it. */
.act-setup .steps::before,
.act-setup .steps::after {
  content: '';
  position: absolute;
  left: 19px; top: 20px; bottom: 20px;
  width: 2px;
  border-radius: 2px;
  background: var(--line-strong);
}
.act-setup .steps::after { background: var(--indigo); transform: scaleY(0); transform-origin: top; }
@supports (animation-timeline: view()) {
  html[data-motion='on'] .act-setup .steps::after {
    animation: stepFill linear both;
    animation-timeline: view();
    animation-range: entry 50% cover 70%;
  }
}
@keyframes stepFill { from { transform: scaleY(0); } to { transform: scaleY(1); } }

.act-setup .step {
  counter-increment: step;
  position: relative;
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  gap: var(--sp-5);
}
.act-setup .step::before {
  content: counter(step);
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--indigo);
  color: var(--indigo-deep);
  font-size: 0.9375rem;
  font-weight: 800;
  box-shadow: 0 0 0 6px var(--bg-warm);
}
.act-setup .step:last-child::before { background: var(--indigo); color: #fff; }
.act-setup .step:last-child::after {
  content: '';
  position: absolute;
  left: 0; top: 40px; bottom: -24px;
  z-index: 1;
  width: 40px;
  background: var(--bg-warm);
}
.step-body { padding-top: 0.45rem; }
.step-body h3 { font-size: var(--fs-h3); letter-spacing: var(--tracking-tight); }
.step-body p { margin-top: var(--sp-2); font-size: var(--fs-small); color: var(--ink-soft); line-height: var(--lh-loose); }

.setup-aside .visual-dial { max-height: none; }
.ratio-explainer {
  padding: var(--sp-6);
  border-radius: var(--r-lg);
  background: var(--indigo-tint);
  border: 1px solid color-mix(in srgb, var(--indigo) 16%, transparent);
}
.ratio-explainer h3 { font-size: var(--fs-h3); letter-spacing: var(--tracking-tight); line-height: 1.3; }
.ratio-explainer p { margin-top: var(--sp-3); font-size: var(--fs-small); color: var(--ink-soft); line-height: var(--lh-loose); }

/* ═══ ACT 8 · GAINS ════════════════════════════════════════════════ */

.act-gains { overflow-x: clip; }
.gains-layout {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: var(--sp-8);
  align-items: start;
}
.gains-layout .visual-streak {
  aspect-ratio: 1 / 1.05;
  max-height: none;
  --orb-r: 140px;
  --orb-x: 0%;
  --orb-y: 0%;
}
@media (min-width: 901px) {
  .gains-layout .visual-streak { position: sticky; top: calc(var(--header-total) + var(--sp-6)); }
}
.gains-layout .fallback-streak { width: 84%; }

/* Two up, never three: six items across a three-column grid is the exact
   shape the brief bans. */
.gain-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-7) var(--sp-6);
}
.gain { padding-top: var(--sp-5); border-top: 1px solid var(--line); }
.gain dt {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-4);
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  line-height: 1.35;
  margin-bottom: var(--sp-2);
}
.gain dd { margin: 0; font-size: var(--fs-small); color: var(--ink-soft); line-height: var(--lh-loose); }

/* ═══ ACT 9 · WHO ══════════════════════════════════════════════════ */

.who-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-5);
}
.who {
  position: relative;
  overflow: hidden;
  padding: var(--sp-8) var(--sp-7) var(--sp-7);
  border-radius: var(--r-xl);
  background: var(--surface);
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
}
.who > * { position: relative; z-index: 1; }
.who > .stage-orb { position: absolute; z-index: 0; }
.who-dark {
  background: var(--stage);
  color: var(--on-dark);
  border-color: transparent;
  box-shadow: var(--sh-dark);
  --orb-r: 120px;
  --orb-x: 100%;
  --orb-y: 0%;
}
.who-avatar { width: 48px; height: 48px; border-radius: 14px; margin-bottom: var(--sp-6); }
.who-dark .who-avatar { background: rgba(255, 255, 255, 0.1); color: var(--on-dark); }
.who-light .who-avatar { background: var(--amber-soft); color: var(--amber-deep); }
.who-kicker {
  font-size: var(--fs-eyebrow);
  text-transform: uppercase;
  letter-spacing: var(--tracking-eyebrow);
  font-weight: 700;
  color: var(--indigo);
}
.who-dark .who-kicker { color: var(--indigo-lift); }
.who h3 {
  font-family: var(--font-serif);
  font-size: clamp(1.375rem, 1.1rem + 1.1vw, 1.875rem);
  line-height: 1.25;
  margin-block: var(--sp-3) var(--sp-4);
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.who p { font-size: var(--fs-small); color: var(--ink-soft); line-height: var(--lh-loose); }
.who-dark p { color: var(--on-dark-soft); }
.who-meta {
  margin-top: auto;
  padding-top: var(--sp-6);
  font-size: var(--fs-micro) !important;
  font-weight: 700;
  color: var(--indigo-deep) !important;
  letter-spacing: 0.02em;
}
.who-dark .who-meta { color: var(--amber) !important; }

.who-honest {
  margin-top: var(--sp-7);
  max-width: 68ch;
  padding-left: var(--sp-5);
  border-left: 3px solid var(--line-strong);
  font-size: var(--fs-lede);
  line-height: var(--lh-loose);
  color: var(--ink-soft);
  text-wrap: pretty;
}

/* ═══ ACT 10 · COMPARE ══════════════════════════════════════════════
   Base table rules first: the content pages load content.css after this
   file and restyle the same table themselves, so these stay modest. The
   homepage's own treatment follows, scoped to .act-compare. */

.table-hint {
  display: none;
  align-items: center;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
  font-size: var(--fs-micro);
  font-weight: 600;
  color: var(--ink-faint);
}
.table-hint-icon {
  display: grid;
  place-items: center;
  width: 22px; height: 22px;
  border-radius: var(--r-pill);
  background: var(--indigo-tint);
  color: var(--indigo-deep);
  font-size: 13px;
  /* Three passes, not forever: a loop with no pause control is a WCAG 2.2.2
     failure past five seconds, and the hint has done its job by then. */
  animation: nudge 1.5s var(--ease-in-out) 3;
}
@keyframes nudge { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(3px); } }

.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  /* A fade on the trailing edge, so the cut-off column reads as "more this
     way". */
  mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 44px), transparent 100%);
}
@media (min-width: 780px) {
  /* Wide enough to show the lot — the fade would be a lie. */
  .table-scroll { mask-image: none; }
  .table-hint { display: none !important; }
}
.compare {
  width: 100%;
  min-width: 720px;
  border-collapse: separate;
  border-spacing: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.compare th, .compare td {
  padding: var(--sp-4) var(--sp-3);
  text-align: center;
  font-size: var(--fs-small);
}
.compare thead th { border-bottom: 1px solid var(--line-strong); }
.compare tbody tr:last-child th,
.compare tbody tr:last-child td { border-top: 1px solid var(--line-strong); }
.compare tbody tr:nth-child(even) { background: color-mix(in srgb, var(--bg) 55%, transparent); }
.compare thead th {
  font-weight: 700;
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--tracking-eyebrow);
  color: var(--ink-faint);
  background: var(--bg);
  padding-block: var(--sp-4);
}
.compare tbody th {
  text-align: left;
  font-weight: 500;
  color: var(--ink);
  width: 34%;
  min-width: 220px;
}
.compare-us { color: var(--indigo) !important; background: var(--indigo-tint) !important; }
.compare tbody td.yes { color: var(--sage-strong); }
.compare tbody td.no  { color: var(--line-strong); }
.compare-us.yes { color: var(--indigo-deep) !important; }
.compare-us.no  { color: var(--ink-faint) !important; }
.compare svg { display: inline-block; vertical-align: middle; }

.compare-foot { margin-top: var(--sp-6); font-size: var(--fs-small); color: var(--ink-soft); max-width: 70ch; line-height: var(--lh-loose); }
.compare-foot a { color: var(--indigo-deep); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(75, 58, 192, 0.4); }
/* Inline, padded to the 24px floor, so the sentence's closing full stop
   stays on the link's line instead of wrapping onto one of its own. */
.compare-foot a { display: inline; padding-block: 6px; }

/* The homepage table. Popcue's column is raised in indigo, the feature column
   stays pinned while a phone scrolls the rivals past it, and every verdict
   is a shape as well as a colour. */
.compare-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-5);
  margin-bottom: var(--sp-4);
  font-size: var(--fs-micro);
  font-weight: 600;
  color: var(--ink-soft);
}
.compare-legend li { display: inline-flex; align-items: center; gap: 6px; }
.compare-legend svg {
  width: 22px; height: 22px;
  padding: 4px;
  border-radius: 50%;
}
.compare-legend .yes svg { background: var(--sage-tint); color: var(--sage-strong); }
.compare-legend .partial svg { background: var(--amber-soft); color: var(--amber-deep); }
.compare-legend .no svg { background: #F1EFF6; color: var(--ink-faint); }

.act-compare .table-scroll {
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--sh-md);
}
.act-compare .compare { border: 0; border-radius: 0; background: transparent; overflow: visible; }
.act-compare .compare th,
.act-compare .compare td { padding: 0.85rem 0.6rem; border: 0; }
.act-compare .compare thead th {
  background: var(--surface);
  border-bottom: 1px solid var(--line-strong);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  vertical-align: bottom;
  line-height: 1.3;
}
.act-compare .compare tbody tr { transition: background var(--dur-fast) var(--ease-out); }
.act-compare .compare tbody tr:nth-child(even) { background: transparent; }
.act-compare .compare tbody tr + tr > * { border-top: 1px solid var(--line); }
.act-compare .compare tbody tr:last-child th,
.act-compare .compare tbody tr:last-child td { border-top: 1px solid var(--line-strong); }
@media (hover: hover) and (pointer: fine) {
  .act-compare .compare tbody tr:hover { background: color-mix(in srgb, var(--indigo-tint) 45%, transparent); }
}
.act-compare .compare tbody th { font-weight: 600; font-size: var(--fs-small); line-height: 1.4; padding-left: var(--sp-5); }
.act-compare .compare thead th:first-child { text-align: left; padding-left: var(--sp-5); }

/* Pinned feature column. Its background has to be opaque or the rival
   columns show through it as they scroll underneath. */
.act-compare .compare thead th:first-child,
.act-compare .compare tbody th {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--surface);
}
.act-compare .compare tbody th { box-shadow: 1px 0 0 var(--line); }

.act-compare .compare thead .compare-us {
  background: var(--indigo) !important;
  color: #fff !important;
  border-radius: 14px 14px 0 0;
  font-size: 0.75rem;
}
.act-compare .compare td[data-col='popcue'] { background: color-mix(in srgb, var(--indigo-tint) 75%, transparent) !important; }
.act-compare .compare tbody tr:last-child td[data-col='popcue'] { border-radius: 0 0 14px 14px; }

.act-compare .compare td svg {
  width: 24px; height: 24px;
  padding: 4px;
  border-radius: 50%;
}
.act-compare .compare td.yes svg { background: var(--sage-tint); color: var(--sage-strong); }
.act-compare .compare td.partial { color: var(--amber-deep); }
.act-compare .compare td.partial svg { background: var(--amber-soft); }
.act-compare .compare td.no { color: #CFC9D9; }
.act-compare .compare td[data-col='popcue'].yes svg { background: var(--indigo); color: #fff; }
.act-compare .compare td[data-col='popcue'].no svg { background: var(--surface); color: var(--ink-faint); box-shadow: inset 0 0 0 1px var(--line-strong); }

.act-compare .compare-notes { margin-top: var(--sp-5); }
.compare-notes-detail summary {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: 44px;
  font-size: var(--fs-small);
  font-weight: 600;
  color: var(--indigo-deep);
  cursor: pointer;
  list-style: none;
}
.compare-notes-detail summary::-webkit-details-marker { display: none; }
.compare-notes-detail summary::before {
  content: '';
  width: 7px; height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform var(--dur-base) var(--ease-out);
}
.compare-notes-detail[open] summary::before { transform: rotate(45deg); }
.compare-partials {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-4) var(--sp-6);
  margin-top: var(--sp-4);
  font-size: var(--fs-small);
  line-height: 1.6;
}
.compare-partials dt { color: var(--ink); }
.compare-partials dd { margin: var(--sp-1) 0 0; color: var(--ink-soft); }
.compare-sources { margin-top: var(--sp-5); font-size: var(--fs-micro); line-height: 1.8; color: var(--ink-soft); max-width: 90ch; }
.compare-sources a { color: var(--indigo-deep); text-decoration: underline; text-underline-offset: 2px; }

/* ═══ ACT 11 · PRICING ══════════════════════════════════════════════ */

.price-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-4);
  align-items: stretch;
}
.price {
  position: relative;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: var(--sp-7);
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  box-shadow: var(--sh-sm);
}
.price > * { position: relative; z-index: 1; }
.price > .stage-orb { position: absolute; z-index: 0; }
.price-pro {
  background: var(--stage);
  color: var(--on-dark);
  border-color: transparent;
  box-shadow: var(--sh-dark);
  --orb-r: 130px;
  --orb-x: 100%;
  --orb-y: 0%;
}
.price-flag {
  position: absolute !important;
  top: var(--sp-6); right: var(--sp-6);
  background: var(--amber);
  color: var(--charcoal);
  font-size: 0.625rem;
  font-weight: 800;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  padding: 0.3rem 0.7rem;
  border-radius: var(--r-pill);
}
.price-name { font-size: var(--fs-h3); font-weight: 700; letter-spacing: var(--tracking-tight); }
.price-amount {
  font-size: clamp(2.75rem, 2.2rem + 1.6vw, 3.5rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: var(--tracking-display);
  font-variant-numeric: tabular-nums;
}
.price-per {
  font-size: var(--fs-small);
  font-weight: 600;
  color: var(--ink-faint);
  letter-spacing: 0;
  margin-left: 0.4rem;
}
.price-pro .price-per { color: var(--on-dark-faint); }
.price-billed { font-size: var(--fs-micro); color: var(--ink-faint); margin-top: calc(var(--sp-2) * -1); }
.price-pro .price-billed { color: var(--on-dark-soft); }

.price-switch {
  display: inline-flex;
  padding: 4px;
  background: #F1EFF6;
  border-radius: var(--r-pill);
  gap: 2px;
  align-self: flex-start;
}
.price-pro .price-switch { background: rgba(255, 255, 255, 0.08); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08); }
.price-option {
  padding: 0.45rem 0.95rem;
  /* 44px: the Monthly/Yearly switch is a tap target. */
  min-height: 44px;
  border-radius: var(--r-pill);
  font-size: var(--fs-micro);
  font-weight: 700;
  color: var(--ink-soft);
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  transition: background var(--dur-base) var(--ease-out), color var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
.price-pro .price-option { color: var(--on-dark-soft); }
.price-option.is-active { background: var(--surface); color: var(--ink) !important; box-shadow: var(--sh-sm); }
.price-save { color: var(--amber); font-size: 0.625rem; }
.price-option.is-active .price-save { color: var(--sage-strong); }

.price-list { display: grid; gap: var(--sp-3); margin-block: var(--sp-2) var(--sp-4); }
.price-list li {
  position: relative;
  padding-left: 1.75rem;
  font-size: var(--fs-small);
  color: var(--ink-soft);
  line-height: 1.5;
}
.price-list li::before {
  content: '';
  position: absolute;
  left: 0; top: 0.12em;
  width: 18px; height: 18px;
  border-radius: 50%;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4.5 8.3l2.3 2.3 4.7-5' fill='none' stroke='%234B3AC0' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 13px no-repeat,
    var(--indigo-tint);
}
.price-pro .price-list li { color: var(--on-dark-soft); }
.price-pro .price-list li::before {
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4.5 8.3l2.3 2.3 4.7-5' fill='none' stroke='%230E0A20' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 13px no-repeat,
    var(--sage);
}
.price .btn { margin-top: auto; }
.price-trial { font-size: var(--fs-micro); color: var(--on-dark-soft); text-align: center; }

.price-honest {
  margin-top: var(--sp-7);
  max-width: 60ch;
  font-family: var(--font-serif);
  font-size: clamp(1.125rem, 1.02rem + 0.45vw, 1.3125rem);
  line-height: 1.55;
  color: var(--ink);
}

/* ═══ ACT 12 · FAQ ══════════════════════════════════════════════════
   Base rules are shared with the content pages; the homepage version is a
   hairline accordion with a plus that turns into a close mark. */

.faq { display: grid; gap: var(--sp-2); }
.faq-item {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
  transition: border-color var(--dur-fast) var(--ease-out);
}
.faq-item[open] { border-color: var(--indigo-lift); }
.faq-item summary {
  padding: var(--sp-4) var(--sp-5);
  font-size: var(--fs-body);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  transition: color var(--dur-fast) var(--ease-out);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--indigo-deep); }
.faq-item summary::after {
  content: '';
  flex-shrink: 0;
  width: 9px; height: 9px;
  border-right: 2px solid var(--ink-faint);
  border-bottom: 2px solid var(--ink-faint);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--dur-base) var(--ease-out);
}
.faq-item[open] summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.faq-body { padding: 0 var(--sp-5) var(--sp-5); }
.faq-body p { font-size: var(--fs-small); color: var(--ink-soft); line-height: var(--lh-loose); }

.act-faq .faq { gap: 0; border-top: 2px solid var(--ink); }
.act-faq .faq-item {
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
}
.act-faq .faq-item summary {
  min-height: 64px;
  padding: var(--sp-4) 0;
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
  line-height: 1.4;
}
.act-faq .faq-item summary::after {
  width: 30px; height: 30px;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  transform: none;
  background:
    linear-gradient(currentColor, currentColor) center / 11px 1.8px no-repeat,
    linear-gradient(currentColor, currentColor) center / 1.8px 11px no-repeat;
  color: var(--ink-soft);
  transition: transform var(--dur-base) var(--ease-out), background-color var(--dur-base) var(--ease-out), color var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out);
}
.act-faq .faq-item summary:hover::after { border-color: var(--indigo-lift); color: var(--indigo); }
.act-faq .faq-item[open] summary::after {
  transform: rotate(45deg);
  background-color: var(--ink);
  border-color: var(--ink);
  color: #fff;
}
.act-faq .faq-body { padding: 0 var(--sp-8) var(--sp-5) 0; }
.act-faq .faq-body p { font-size: var(--fs-body); max-width: 62ch; }

/* Open and close with height, where the browser can animate to `auto`. */
@supports (interpolate-size: allow-keywords) {
  .act-faq .faq { interpolate-size: allow-keywords; }
  .act-faq .faq-item::details-content {
    height: 0;
    overflow: clip;
    transition: height var(--dur-base) var(--ease-out), content-visibility var(--dur-base) allow-discrete;
  }
  .act-faq .faq-item[open]::details-content { height: auto; }
}

/* ═══ ACT 13 · WAITLIST ═════════════════════════════════════════════
   The page's last word, on the same charcoal stage it opened with. The
   section itself stays on the light page; only the card is dark. */

.waitlist-card {
  position: relative;
  overflow: hidden;
  container-type: inline-size;
  max-width: 620px;
  margin-inline: auto;
  background: var(--stage);
  color: var(--on-dark);
  border-radius: calc(var(--r-xl) + 4px);
  padding: clamp(var(--sp-6), 4vw, var(--sp-8));
  box-shadow: var(--sh-dark);
  --orb-r: 180px;
  --orb-x: 100%;
  --orb-y: 0%;
}
.waitlist-card > * { position: relative; z-index: 1; }
.waitlist-card > .stage-orb { position: absolute; z-index: 0; }
.waitlist-mark { display: inline-block; margin-bottom: var(--sp-5); }
.waitlist-mark .brand-mark { width: 44px; height: 44px; border-radius: 13px; box-shadow: 0 6px 20px rgba(101, 76, 244, 0.45); }
.waitlist-mark .brand-mark__svg { height: 32px; }
.waitlist-card .act-title {
  max-width: 14ch;
  font-size: clamp(1.875rem, 1.3rem + 2vw, 2.625rem);
  color: var(--on-dark);
}
.waitlist-card .act-lede { margin-top: var(--sp-4); font-size: var(--fs-body); color: var(--on-dark-soft); max-width: 52ch; }

.waitlist-form {
  margin-top: var(--sp-6);
  display: grid;
  gap: var(--sp-4);
  text-align: left;
}
.field-row { display: grid; gap: var(--sp-4); }
@container (min-width: 460px) {
  .field-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.waitlist-card .field label { color: var(--on-dark); }
.waitlist-card .field input[type='email'],
.waitlist-card .field select { border-color: transparent; }
.waitlist-card .field input[type='email']:focus,
.waitlist-card .field select:focus { border-color: var(--indigo-lift); box-shadow: 0 0 0 3px rgba(139, 119, 255, 0.45); }
.waitlist-card .field-check input { accent-color: var(--indigo-lift); }
.waitlist-card .field-check label { color: var(--on-dark-soft); }
.waitlist-form .btn { margin-top: var(--sp-2); }
.waitlist-form .btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none; }
.waitlist-card .form-status[data-tone='ok'] { color: var(--sage); }
.waitlist-card .form-status[data-tone='error'] { color: #FF9DB0; }
.waitlist-card .form-status[data-tone='info'] { color: var(--on-dark-soft); }
.waitlist-card .noscript-note a { color: var(--ink); }

/* ═══ FOOTER ════════════════════════════════════════════════════════ */

.site-footer { position: relative; overflow: hidden; }
.footer-orb {
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* Faint enough that the legal links passing over its edge keep AA. */
  background: radial-gradient(circle 260px at 100% 100%, rgba(75, 58, 192, 0.22) 0 259px, transparent 260px);
}
.site-footer > .wrap { position: relative; }
.footer-tag {
  font-size: clamp(1.25rem, 1.1rem + 0.6vw, 1.5rem);
  font-weight: 800;
  letter-spacing: var(--tracking-tight);
  line-height: 1.2;
  max-width: 14ch;
}

/* The legal links: each a full 24px target, laid out as one wrapping row
   so it costs the phone footer a line, not a column. */
.footer-legal {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--sp-4);
  font-size: var(--fs-small);
}
.footer-legal a {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color var(--dur-fast) var(--ease-out);
}
.footer-legal a:hover { color: var(--on-dark); }

/* ═══ RESPONSIVE ═════════════════════════════════════════════════════
   What is not the layout of a screen. How each screen lays out at every
   window size, the decks that small windows use, and the landscape-phone
   exemption all live in screens.css, so there is one place to read how the
   page fits.
   ═════════════════════════════════════════════════════════════════════ */

@media (max-width: 1080px) {
  .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
  .nav-links { display: none; }
  .table-hint { display: flex; }
}

@media (max-width: 640px) {
  :root { --header-h: 60px; }
  .site-header .nav-row { height: 50px; }
  .stage-orb { --orb-r: 110px; }
  /* Two columns of two: brand beside the "Product" list on row one, the other
     two lists side by side on row two. The tallest cell on each row sets the
     row height, so this is the arrangement that actually halves the footer. */
  .site-footer { padding-block: var(--sp-8) var(--sp-5); }
  .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-5) var(--sp-4); }
}

@media (max-width: 460px) {
  .footer-bottom { flex-direction: column; align-items: flex-start; }
}

/* Coarse pointers: give the primary controls the full 44px thumb target even
   where a finer pointer would be comfortable with less. */
@media (pointer: coarse) {
  .btn { min-height: 48px; }
  .faq-item summary { min-height: 56px; }
}

/* Motion toggle: kills every scripted animation for readers who ask for it,
   regardless of the prefers-reduced-motion media query. */
html[data-motion='off'] [data-reveal] { opacity: 1 !important; transform: none !important; transition: none !important; }
html[data-motion='off'] .scene-canvas,
html[data-motion='off'] .scene-bg { opacity: 0 !important; }
html[data-motion='off'] .table-hint-icon { animation: none; }
html[data-motion='off'] .act-setup .steps::after { transform: scaleY(1); }
@media (prefers-reduced-motion: reduce) {
  .act-setup .steps::after { transform: scaleY(1); }
  .type-card, .source { transition: none; }
}
