/* Pickscreen site - retro-theater identity. Tokens mirror the app's Theme class. */
@font-face { font-family: "Bebas Neue"; src: url("assets/fonts/BebasNeue-latin.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "IBM Plex Sans"; src: url("assets/fonts/IBMPlexSans-latin-400.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "IBM Plex Sans"; src: url("assets/fonts/IBMPlexSans-latin-600.woff2") format("woff2"); font-weight: 600; font-display: swap; }

:root {
  --void: #000000;
  --canvas: #101012;         /* Theme.Canvas 16,16,18 */
  --cell: #16161a;           /* Theme.CellResting 22,22,26 */
  --surface: #1e1e22;        /* Theme.Surface 30,30,34 */
  --face: #303036;           /* Theme.ControlFace 48,48,54 */
  --face-hover: #42424c;     /* Theme.ControlFaceHover 66,66,76 */
  --face-pressed: #1a1a1e;   /* Theme.ControlFacePressed 26,26,30 */
  --accent: #e8d8b4;         /* champagne, Theme.AccentPalette[0] */
  --accent-ink: #0c0c0e;     /* Theme.TextOnAccent 12,12,14 */
  --text-1: rgba(255,255,255,.95);  /* TextPrimary 242/255 */
  --text-2: rgba(255,255,255,.77);  /* TextSecondary 197/255 */
  --text-3: rgba(255,255,255,.53);  /* TextTertiary 135/255 */
  --hairline: rgba(117,117,117,.40);
  --stroke: rgba(255,255,255,.07);
  --stroke-strong: rgba(255,255,255,.16);
  --shadow: rgba(0,0,0,.78);        /* ShadowColor 200/255 black */
  --font-display: "Bebas Neue", "Arial Narrow", sans-serif;
  --font-body: "IBM Plex Sans", "Segoe UI", system-ui, sans-serif;
  --max-w: 70rem;
  --header-h: 3.8125rem;     /* sticky bar 3.75rem + its 1px hairline */
}

* { margin: 0; padding: 0; box-sizing: border-box; }

/* Author rules that set `display` beat the UA sheet's `[hidden] { display: none }`
   at equal specificity, so every config-gated block that also carries a display
   value (the capture forms are flex) would render before its gate opened. */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; }

body {
  background: var(--canvas);
  color: var(--text-2);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

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

.wrap { max-width: var(--max-w); margin: 0 auto; padding: 0 1.25rem; }

/* ---- display voice: Bebas Neue, marquee-only ---- */
h1,
.section-title,
.display {
  font-family: var(--font-display);
  letter-spacing: .02em;
  text-transform: uppercase;
}

/* ---- header / nav ---- */
.site-header {
  border-bottom: 1px solid var(--hairline);
  background: var(--canvas);
  position: sticky;
  top: 0;
  z-index: 10;
}
.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 3.75rem;
}
.brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.05rem;
  letter-spacing: .01em;
  color: var(--text-1);
}
.brand:hover { text-decoration: none; }
.brand-mark {
  display: inline-grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px;
  width: 20px;
  height: 20px;
}
.brand-mark span {
  background: var(--face);
  border-radius: 0;
  animation: brand-mark-walk 8s ease-in-out infinite;
}
/* Grid order is TL,TR,BL,BR (children 1,2,3,4). Clockwise walk visits
   1 (TL) -> 2 (TR) -> 4 (BR) -> 3 (BL), each holding the accent for one
   quarter (2s) of the 8s cycle. Negative delays put each child at the
   right point in the shared cycle from the very first frame. */
.brand-mark span:nth-child(1) { animation-delay: 0s; }   /* accent during 0%-25% */
.brand-mark span:nth-child(2) { animation-delay: -6s; }  /* accent during 25%-50% */
.brand-mark span:nth-child(4) { animation-delay: -4s; }  /* accent during 50%-75% */
.brand-mark span:nth-child(3) { animation-delay: -2s; }  /* accent during 75%-100% */

@keyframes brand-mark-walk {
  0%, 24% { background: var(--accent); }
  26%, 100% { background: var(--face); }
}
.site-nav { display: flex; gap: 1.4rem; align-items: center; }
.site-nav a { color: var(--text-2); font-size: 0.95rem; }
.site-nav a:hover { color: var(--text-1); text-decoration: none; }
.site-nav a.nav-cta {
  color: var(--accent-ink);
  background: var(--accent);
  padding: 0.4rem 1rem;
  border-radius: 0;
  font-weight: 600;
}
.site-nav a.nav-cta:hover { background: var(--text-1); text-decoration: none; }

/* ---- hero ---- */
.hero { padding: 4.5rem 0 3.5rem; text-align: center; }
.hero h1 {
  font-size: clamp(2.4rem, 7vw, 4.6rem);
  line-height: 1.05;
  max-width: 46rem;
  margin: 0 auto 1rem;
  color: var(--text-1);
}
.hero .sub {
  color: var(--text-2);
  max-width: 38rem;
  margin: 0 auto 2rem;
  font-size: 1.15rem;
}
.cta-row {
  display: flex;
  gap: 1.1rem;
  justify-content: center;
  flex-wrap: wrap;
}
.cta-note { color: var(--text-3); font-size: 0.9rem; margin-top: 1.4rem; }

/* ---- buttons: hard offset shadow, no blur, squared ---- */
.btn {
  display: inline-block;
  padding: 0.8rem 1.7rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.02rem;
  letter-spacing: .02em;
  text-transform: uppercase;
  border-radius: 0;
  border: 1px solid transparent;
  cursor: pointer;
  box-shadow: 5px 5px 0 var(--shadow);
  transition: transform .06s, box-shadow .06s;
}
.btn:hover { text-decoration: none; }
.btn:active {
  box-shadow: none;
  transform: translate(5px, 5px);
}
.btn-primary { background: var(--accent); color: var(--accent-ink); }
.btn-secondary {
  background: var(--face);
  color: var(--text-1);
  border: 1px solid var(--stroke-strong);
}
.btn-secondary:hover { background: var(--face-hover); }

/* ---- hero stage: empty pre-Task-3, holds the animated grid preview ---- */
.stage {
  aspect-ratio: 16 / 9;
  background: var(--void);
  border: 1px solid var(--stroke);
  box-shadow: 10px 10px 0 var(--shadow);
  width: 100%;
  margin: 3.5rem auto 0;
}

/* ---- sections ---- */
section { padding: 3.5rem 0; }
section + section { border-top: 1px solid var(--hairline); }
.section-title {
  font-size: 2rem;
  margin-bottom: 0.6rem;
  color: var(--text-1);
}
.section-lede { color: var(--text-2); margin-bottom: 2rem; max-width: 40rem; }

/* ---- plaque pattern: base for .price-card, .feature, .notice ---- */
.plaque,
.price-card,
.feature,
.notice {
  background: var(--surface);
  border: 1px solid var(--stroke);
  box-shadow: 8px 8px 0 var(--shadow);
  border-radius: 0;
  padding: 1.5rem;
}

/* ---- features ---- */
.feature-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1.5rem;
}
.feature h3 { font-size: 1.05rem; margin-bottom: 0.5rem; color: var(--text-1); }
.feature p { color: var(--text-2); font-size: 0.95rem; }

/* ---- credibility strip ---- */
.cred-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: center;
}
.cred-chip {
  padding: 0.7rem 1.2rem;
  font-size: 0.9rem;
  color: var(--text-1);
  text-align: center;
}
.legit {
  color: var(--text-3);
  font-size: 0.85rem;
  max-width: 44rem;
  margin: 1.5rem auto 0;
  text-align: center;
}

/* ---- how it works ---- */
.steps {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
  margin-bottom: 2rem;
}
.step { display: flex; gap: 1rem; align-items: flex-start; }
.step-num {
  flex: none;
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  background: var(--face);
  color: var(--accent);
  font-family: var(--font-display);
  font-size: 1.2rem;
  border: 1px solid var(--stroke-strong);
}
.step-body h3 { font-size: 1.02rem; margin-bottom: 0.4rem; color: var(--text-1); }
.step-body p { color: var(--text-2); font-size: 0.95rem; }

/* ---- pricing ---- */
.price-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1.5rem;
  align-items: stretch;
}
.price-card {
  display: flex;
  flex-direction: column;
}
.price-card.featured { border-color: var(--accent); }
.price-card h3 { font-size: 1.1rem; margin-bottom: 0.3rem; color: var(--text-1); }
.price-card .price { font-size: 2.2rem; font-weight: 600; margin: 0.5rem 0 0.3rem; color: var(--text-1); }
.price-card .price small { font-size: 0.9rem; font-weight: 400; color: var(--text-2); }
.price-card ul {
  list-style: none;
  margin: 1rem 0 1.4rem;
  color: var(--text-2);
  font-size: 0.95rem;
  flex: 1;
}
.price-card li { padding: 0.3rem 0 0.3rem 1.4rem; position: relative; }
.price-card li::before {
  content: "\2713";
  position: absolute;
  left: 0;
  color: var(--accent);
}
.price-card .btn { text-align: center; }
.price-fineprint { color: var(--text-3); font-size: 0.82rem; margin-top: 0.8rem; text-align: center; }
/* ---- the two offers under the price grid (ruling 23) ----
   Trial on the left, launch discount on the right. A centring flex line rather
   than a two-column grid, so the row degrades on its own: with the capture
   gated off (BUTTONDOWN_USERNAME still REPLACE_ME) the banner is the only child
   and grows back to exactly the 40rem centred block that shipped before, and
   the pricing segment is unchanged. Below the flex basis the two stack. */
.pricing-offers {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: stretch;
  gap: 1.5rem;
  margin-top: 2rem;
}
/* min-width: 0 is load-bearing, not tidying. A flex item's min-width defaults to
   auto, which floors it at its min-content width, and the capture plaque's is set
   by an un-wrapping control row (input plus a nowrap button): 454.5px against a
   343px row on a 390px phone. Without this the row refuses to shrink, the
   document scrolls sideways and the button leaves the screen. */
.pricing-offers > * { flex: 1 1 20rem; min-width: 0; max-width: 40rem; }
/* The banner is a grid so its copy sits centred in a plaque stretched to the
   row's height. Its whole sentence is wrapped in one span in the markup for
   exactly that reason: every child element of a grid container is a grid item,
   so the bare trailing link would otherwise be laid out on a row of its own. */
.trial-banner {
  display: grid;
  align-content: center;
  text-align: center;
  color: var(--text-2);
  font-size: 0.95rem;
}
/* the call to action at the end of the banner reads as one thing, so it breaks
   before itself rather than through itself when the plaque is half a column */
.trial-link { font-weight: 600; white-space: nowrap; }
.pricing-capture {
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: center;
}
.pricing-capture-lede {
  color: var(--text-1);
  font-size: 0.95rem;
  margin-bottom: 0.75rem;
}
.pricing-capture-note { margin-top: 0.6rem; }

/* and on a phone the control row stops being a row: side by side in a full-width
   plaque at 390px the field is squeezed to about 90px, which is not a field
   anyone can read what they typed in */
@media (max-width: 34rem) {
  .pricing-capture .email-form { flex-wrap: wrap; }
  .pricing-capture .email-form input[type="email"] { flex: 1 1 100%; }
  .pricing-capture .email-form .btn { flex: 1 1 auto; }
}
.anchor {
  color: var(--text-3);
  font-size: 0.9rem;
  text-align: center;
  max-width: 36rem;
  margin: 1.5rem auto 0;
}

/* ---- FAQ ---- */
.faq details {
  border: 1px solid var(--stroke);
  background: var(--surface);
  border-radius: 0;
  margin-bottom: 0.8rem;
  padding: 1rem 1.3rem;
}
.faq summary { cursor: pointer; font-weight: 600; color: var(--text-1); }
.faq details p { margin-top: 0.8rem; color: var(--text-2); }

/* ---- FAQ split view (ruling 20) ----
   Opening an answer used to push the rest of the questions down the page, so in
   deck mode the nine questions become a fixed list on the left and the selected
   answer a plaque on the right. faq.js builds this out of the details markup and
   marks the container; the deck gate further down is what switches the two
   presentations, so everything here rests at display:none until then and a
   window below the gate keeps the native accordion.

   Nothing outside the panel may move when the answer changes, so the panes are
   absolutely positioned inside a stretched cell and contribute no height of
   their own: the row is exactly as tall as the nine-question list and the
   longest answer cannot resize the composition. The list is the tallest thing in
   either column at every gated size, so the panel has room to spare and its
   overflow rule is a guard, not a working scrollbar. */
.faq-split {
  display: none;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  column-gap: clamp(1.5rem, 2.4vw, 2.6rem);
}
.faq-tablist { display: flex; flex-direction: column; gap: 0.3rem; }
.faq-tab {
  font: inherit;
  font-weight: 600;
  line-height: 1.35;
  color: var(--text-2);
  text-align: left;
  background: none;
  border: 0;
  border-left: 3px solid transparent;
  border-radius: 0;
  padding: 0.45rem 0.85rem;
  cursor: pointer;
}
.faq-tab:hover { color: var(--text-1); background: var(--cell); }
.faq-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.faq-tab[aria-selected="true"] {
  background: var(--face);
  border-left-color: var(--accent);
  color: var(--accent);
}
/* ---- the answer panel is a mini Pickscreen wall (rulings 22 and 26) ----
   Nine panes wearing the app's own surface: --cell ground, hairline edge, a
   gutter of void between them, a numbered plaque in the corner. At rest they
   divide the box into an even 3x3 grid with nothing selected, which is what the
   app looks like sitting there. Pick a question and its pane becomes the focused
   one - it takes the top band across the full width, carries the accent ring and
   holds the answer, while the other eight queue along the bottom as a tile strip
   showing nothing but their number, because the menu on the left is the text
   carrier. Picking it again sends the wall back to the grid.

   faq.js positions every pane by fraction, so a selection change is a transition
   of left/top/width/height rather than a reflow: the chosen pane grows into the
   focused slot and the rest fall into the strip, the same choreography the hero
   demo uses when its layout changes. `is-live` is added a frame after the first
   layout so the wall does not assemble itself on arrival, and reduced motion
   drops the transitions entirely for an instant swap.

   The tints are static. This panel is chrome, not the showpiece, so it borrows
   the demo's palette and its lit-screen falloff but none of its animation. */
.faq-wall { position: relative; min-height: 0; }
.faq-pane {
  position: absolute;
  overflow: hidden;
  background: var(--cell);
  border: 1px solid var(--stroke);
  border-radius: 0;
  /* every square is a way of asking its question (ruling 26) */
  cursor: pointer;
}
.faq-wall.is-live .faq-pane {
  transition: left .5s cubic-bezier(.22,.61,.36,1),
              top .5s cubic-bezier(.22,.61,.36,1),
              width .5s cubic-bezier(.22,.61,.36,1),
              height .5s cubic-bezier(.22,.61,.36,1),
              border-color .18s ease;
}
/* the affordance is the edge and the plaque lifting, never a size change: a
   square that grew under the pointer would shove its neighbours around */
.faq-pane:not(.is-focused):hover { border-color: var(--stroke-strong); }
.faq-pane:not(.is-focused):hover .faq-chip {
  background: var(--face);
  color: var(--text-1);
}
/* the tint sits under the content, the falloff over the tint but still under it,
   so neither pseudo can wash out the answer copy */
.faq-pane::before,
.faq-pane::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.faq-pane::before {
  background: radial-gradient(ellipse at 32% 38%, var(--tint-a), transparent 62%),
              linear-gradient(160deg, var(--tint-b), transparent 76%);
  opacity: .55;
}
.faq-pane::after {
  background: repeating-linear-gradient(0deg, rgba(0,0,0,.09) 0 1px, transparent 1px 4px),
              radial-gradient(135% 135% at 50% 34%, transparent 54%, rgba(0,0,0,.3));
}
/* same wall, nine different rooms */
.faq-pane:nth-child(1)  { --tint-a: #1d3a26; --tint-b: #12241a; }
.faq-pane:nth-child(2)  { --tint-a: #16303f; --tint-b: #0e1e2a; }
.faq-pane:nth-child(3)  { --tint-a: #3f2d16; --tint-b: #241a0e; }
.faq-pane:nth-child(4)  { --tint-a: #2a1d33; --tint-b: #180f1f; }
.faq-pane:nth-child(5)  { --tint-a: #14322d; --tint-b: #0c1f1c; }
.faq-pane:nth-child(6)  { --tint-a: #332020; --tint-b: #1f1414; }
.faq-pane:nth-child(7)  { --tint-a: #1b2b3d; --tint-b: #101a26; }
.faq-pane:nth-child(8)  { --tint-a: #34331a; --tint-b: #1e1d10; }
.faq-pane:nth-child(9)  { --tint-a: #22193a; --tint-b: #140f22; }

/* outline, not a fatter border: the ring must not resize the pane mid-morph */
.faq-pane.is-focused { outline: 2px solid var(--accent); outline-offset: -2px; z-index: 2; }
/* the focused pane is the tabpanel and a scrollable region, so it is in the tab
   order and needs a ring the resting one cannot be mistaken for */
.faq-pane.is-focused:focus-visible { outline-width: 3px; outline-color: var(--text-1); }

.faq-chip {
  position: absolute;
  left: 0.4rem;
  top: 0.4rem;
  z-index: 1;
  min-width: 1.5em;
  padding: 0.16em 0.3em 0.1em;
  background: var(--surface);
  border: 1px solid var(--stroke-strong);
  box-shadow: 3px 3px 0 var(--shadow);
  font-family: var(--font-display);
  font-size: 0.95rem;
  line-height: 1.14;
  letter-spacing: 0.04em;
  text-align: center;
  color: var(--text-2);
}
.faq-pane.is-focused .faq-chip { font-size: 1.5rem; color: var(--accent); }
.faq-wall.is-live .faq-chip {
  transition: font-size .5s cubic-bezier(.22,.61,.36,1),
              color .3s ease,
              background-color .18s ease;
}

/* the tiles keep their copy of the answer out of the layout and out of the
   accessibility tree; only the focused pane renders one */
.faq-answer { display: none; }
.faq-pane.is-focused .faq-answer {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow-y: auto;
  padding: 2.4rem 1.8rem;
  /* the focused pane is taller than most answers need, so the copy sits in the
     middle of the screen rather than leaving a deep well under three lines.
     `safe` keeps the first line reachable if an answer ever did outgrow the
     pane; browsers without it ignore that line and keep plain centring. */
  display: flex;
  flex-direction: column;
  justify-content: center;
  justify-content: safe center;
  /* the copy is full size the instant its pane is picked, so without this it
     spends the first half of the morph clipped by a pane still growing under
     it. One shot, held at zero until the pane has most of its width. */
  animation: faq-answer-in 0.42s cubic-bezier(.22,.61,.36,1) 0.14s both;
}
@keyframes faq-answer-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.faq-answer p { color: var(--text-2); }
.faq-answer p + p { margin-top: 0.8rem; }

/* ---- maker note ---- */
.maker-note {
  max-width: 40rem;
  margin: 0 auto;
  text-align: center;
  color: var(--text-2);
  font-size: 0.95rem;
}
.maker-note a { color: var(--accent); }

/* ---- final CTA ---- */
.final-cta { text-align: center; }
.final-cta .btn { margin-top: 0.5rem; }
.final-cta .cta-note { margin-top: 1.2rem; }

/* ---- email capture: Buttondown embed, config-gated (ruling 12) ---- */
.email-capture {
  max-width: 25rem;
  margin: 1.6rem auto 0;
  text-align: center;
}
.email-form { display: flex; gap: 0.6rem; }
.email-form input[type="email"] {
  flex: 1;
  min-width: 0;
  background: var(--cell);
  border: 1px solid var(--stroke-strong);
  border-radius: 0;
  color: var(--text-1);
  font-family: var(--font-body);
  font-size: 0.97rem;
  padding: 0.7rem 0.9rem;
}
.email-form input[type="email"]::placeholder { color: var(--text-3); }
.email-form input[type="email"]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.email-form .btn { padding: 0.7rem 1.3rem; white-space: nowrap; }
.email-form-note { color: var(--text-3); font-size: 0.82rem; margin-top: 0.7rem; }

/* ---- footer capture: the sub-pages' compact row (ruling 18) ----
   The download flow carries no inline form any more, so the sub-pages (download,
   EULA, privacy) collect at the very bottom instead. It has to stay a footer, so
   the row is one line of controls at footer scale with the microcopy wrapping
   underneath, not a plaque. The home page's closing plaque is the loud version
   and its footer stays form-free, because the two would share one screen. */
.footer-capture {
  flex-wrap: wrap;
  align-items: center;
  row-gap: 0.5rem;
}
.footer-capture-lede {
  font-family: var(--font-display);
  font-size: 1.15rem;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--text-1);
  line-height: 1.2;
}
.footer-capture input[type="email"] {
  flex: 0 1 15rem;
  font-size: 0.9rem;
  padding: 0.5rem 0.75rem;
}
.footer-capture .btn {
  padding: 0.5rem 1.1rem;
  font-size: 0.85rem;
  box-shadow: 3px 3px 0 var(--shadow);
}
.footer-capture .btn:active { box-shadow: none; transform: translate(3px, 3px); }
.footer-capture-note {
  flex: 1 0 100%;
  color: var(--text-3);
  font-size: 0.8rem;
  margin: 0;
}

/* ---- launch offer card (ruling 23) ----
   The same squared plaque with a hard offset shadow as everything else, fixed
   to the bottom-right corner and shown by offer.js when the visitor reaches
   pricing. position: fixed keeps it out of the snap deck entirely: it is not a
   scroll-flow box, so no segment's height and no snap point moves because of
   it. Its stacking order clears the sticky header (z-index 10) so a card that
   arrives while the header is on screen still reads as the top layer.

   It rests offset and transparent and is moved into place by .is-in one frame
   after it is unhidden, which is what gives the slide something to animate
   from. Under reduced motion the rest state IS the final state and nothing
   moves (see the reduced-motion block at the end of this file). */
.launch-offer {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 20;
  width: min(22rem, calc(100vw - 2.5rem));
  background: var(--surface);
  border: 1px solid var(--stroke-strong);
  border-radius: 0;
  box-shadow: 8px 8px 0 var(--shadow);
  padding: 1.3rem 1.25rem;
  opacity: 0;
  transform: translateY(1.5rem);
  transition: opacity .28s ease, transform .28s ease;
}
.launch-offer.is-in { opacity: 1; transform: none; }
.launch-offer-close {
  position: absolute;
  top: 0.2rem;
  right: 0.2rem;
  width: 2.1rem;
  height: 2.1rem;
  background: none;
  border: 0;
  border-radius: 0;
  color: var(--text-3);
  font-family: var(--font-body);
  font-size: 1.35rem;
  line-height: 1;
  cursor: pointer;
}
.launch-offer-close:hover { color: var(--text-1); }
.launch-offer-close:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.launch-offer-title {
  font-size: 1.55rem;
  line-height: 1.05;
  color: var(--accent);
  margin-bottom: 0.5rem;
  padding-right: 1.6rem;
}
.launch-offer-body {
  color: var(--text-2);
  font-size: 0.88rem;
  line-height: 1.5;
  margin-bottom: 0.9rem;
}
.launch-offer .email-form { flex-wrap: wrap; gap: 0.5rem; }
.launch-offer .email-form input[type="email"] {
  flex: 1 1 100%;
  font-size: 0.9rem;
  padding: 0.55rem 0.75rem;
}
.launch-offer .email-form .btn {
  flex: 1 1 auto;
  padding: 0.55rem 1rem;
  font-size: 0.85rem;
  box-shadow: 4px 4px 0 var(--shadow);
}
.launch-offer .email-form .btn:active { box-shadow: none; transform: translate(4px, 4px); }

/* phones: the card spans the gutter width but never the whole screen, and it
   keeps a bottom margin so it sits above rather than over the page's own
   actions */
@media (max-width: 30rem) {
  .launch-offer {
    left: 1rem;
    right: 1rem;
    bottom: 1rem;
    width: auto;
    max-width: 22rem;
    margin-inline: auto;
  }
}

/* ---- accessible-only labels ---- */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---- notice: plaque with an accent flag on the edge ---- */
.notice {
  border-left: 4px solid var(--accent);
  color: var(--text-2);
  font-size: 0.95rem;
}
.notice strong { color: var(--text-1); }

/* ---- placeholder: build-time scaffold marker, not a themed component ---- */
.placeholder {
  background: var(--cell);
  border: 1px dashed var(--stroke-strong);
  color: var(--text-3);
  border-radius: 0;
  padding: 1rem 1.2rem;
  font-size: 0.9rem;
}

/* ---- next-steps: page-narrow's numbered list, same badge as .step-num ---- */
.next-steps {
  list-style: none;
  counter-reset: next-step;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin: 0 0 2rem;
  padding: 0;
}
.next-steps li {
  counter-increment: next-step;
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  color: var(--text-2);
  font-size: 0.95rem;
  margin-bottom: 0;
}
.next-steps li::before {
  content: counter(next-step);
  flex: none;
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  background: var(--face);
  color: var(--accent);
  font-family: var(--font-display);
  font-size: 1.2rem;
  border: 1px solid var(--stroke-strong);
  border-radius: 0;
}

/* ---- narrow utility pages (download / redirect / 404) ---- */
.page-narrow {
  max-width: 40rem;
  margin: 0 auto;
  padding: 4rem 1.25rem;
  text-align: center;
}
.page-narrow h1 { font-size: 2.6rem; margin-bottom: 1rem; color: var(--text-1); }
.page-narrow p { color: var(--text-2); margin-bottom: 1.2rem; }
.page-narrow .btn { margin-bottom: 1rem; }
.page-narrow .placeholder, .page-narrow .notice { text-align: left; margin: 1.2rem 0; }

/* the legal pages run long-form body copy, so they take a wider measure than the
   download page's short centred stack */
.page-legal { max-width: 46rem; }

/* ---- footer ---- */
.site-footer {
  border-top: 1px solid var(--hairline);
  padding: 2.75rem 0 3rem;
  color: var(--text-3);
  font-size: 0.88rem;
}
.site-footer .wrap { display: grid; gap: 1rem; }
.footer-links { display: flex; gap: 1.4rem; flex-wrap: wrap; }
.footer-links a { color: var(--text-2); }
.footer-links a:hover { color: var(--text-1); }
.footer-legal { max-width: 52rem; }

/* ---- responsive ---- */
@media (max-width: 45rem) {
  .site-nav { gap: 0.9rem; }
  .site-nav a.nav-plain-hide { display: none; }
  .hero { padding: 3rem 0 2.5rem; }
  section { padding: 2.5rem 0; }
  .feature-grid,
  .price-grid,
  .steps {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 24.375rem) {
  .wrap { padding: 0 1rem; }
  .hero h1 { font-size: clamp(2rem, 10vw, 2.6rem); }
}

/* ============ full-segment scroll (index.html only) ============
   Rulings 15 and 17. Every major section is exactly one segment, one segment
   fills exactly one screen, and MANDATORY snap makes the page read like a
   slide deck: each flick lands hard on the next composition. The footer is a
   child of the closing segment, so it can never trail as a partial screen.

   No segment boundary draws a rule. A hairline at a boundary would sit right
   under the sticky header's own hairline at rest, and any mid-transition view
   would show a second break lower down. The only rule left in the body is the
   one above the footer, inside the closing segment, and it can never share a
   viewport with another.

   min-height, never height: if copy grows, the segment grows with it and the
   snap point just moves. Nothing clips, and an oversized segment stays freely
   scrollable. No segment is oversized today: the FAQ was the one that grew as
   you used it, and ruling 20's split view gave it a fixed height.

   Phones and short windows never enter this mode: natural document flow, no
   snap, and the section hairlines below do the dividing instead.

   The height gate is measured, not chosen. Below it the tallest segment stops
   fitting one viewport and mandatory snap then hides the overflow behind every
   ordinary flick: pricing ran 62px past its band at 1366x660 and 122px at
   1366x600. Sweeping the boundary at 1366 wide, pricing is still 18px over at
   704px of viewport and 6px over at 716px, and first fits at about 723px, which
   set the original 46rem (736px) floor.

   The floor is 48rem (768px) now, and the segment that sets it is the closing
   one rather than pricing. Once BUTTONDOWN_USERNAME is filled in, the capture
   plaque joins the closing segment; compacted for the deck (see the plaque rules
   below) it fits from 768px of viewport up, and at 736px it is still a few px
   over. So 736 falls back to natural flow, where nothing is hidden, and every
   gated height keeps headroom with the plaque visible. Verified at 1366x768,
   1366x800 and 1440x900 with the plaque forced on, and at 1024, 1366, 1920 and
   2560 wide. Above the gate the deck fits and the lock is safe; below it,
   natural flow reaches every line.

   The width floor is measured the same way, and for the same reason. It is
   62rem (992px), the point where the FAQ leaves the accordion behind: below
   that the FAQ is a single stack and, with the trust and pricing screens,
   outgrows its band while snap is still on. At 800x736 the overflow was
   76 / 7 / 176px on trust / pricing / FAQ, all of it hidden behind an
   ordinary flick. So the
   floor moved from 45.0625rem to 62rem and windows between about 721 and 991px
   wide scroll naturally instead. The deck is a desktop showpiece; a
   half-width window is not the screen it was composed for. */

html { scroll-padding-top: var(--header-h); }   /* anchor jumps clear the sticky bar */

/* natural-flow mode only: keep the hairline that section + section used to draw */
.screen + .screen,
.screen + section,
section + .screen,
main + .screen { border-top: 1px solid var(--hairline); }

/* .closing-body is an element only so the closing block sits in a landmark of
   its own. It is a wrapper, not a composition, so it takes none of the padding
   a section normally carries, in either mode. */
.closing-body { padding: 0; }

/* ---- prose measures that hold outside the snap gate ----
   The reading column widens on a wide monitor (see the bottom of this file),
   and that widening is not gated on snap mode. Every prose block above already
   carries an unconditional cap of its own: .section-lede 40rem, .legit 44rem,
   .pricing-offers children 40rem, .anchor 36rem,
   .maker-note 40rem. The
   FAQ column was the one block with no cap of its own, so on a wide window with
   the gate off (a short viewport) its lines ran the full widened column. These
   rules sit before the gate, so the wider in-gate measures still win in snap
   mode, where the FAQ is a two-column split and each column is half this. */
.faq { max-width: 70rem; }
@media (min-width: 110rem) {
  .faq { max-width: 62rem; }
}

@media (min-width: 62rem) and (min-height: 48rem) {

  html.snap { scroll-snap-type: y mandatory; }

  .screen {
    min-height: calc(100vh - var(--header-h));
    min-height: calc(100svh - var(--header-h));
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-block: 2rem;
    scroll-snap-align: start;
  }

  /* a flex item with auto side margins refuses to stretch, so .wrap would
     shrink to its max-content width and each screen would set its own margins */
  .screen > .wrap { width: 100%; }

  /* a segment is one composition, never two sections stacked, and no segment
     boundary draws a rule (see the note above). .closing-body is a landmark
     wrapper rather than a composition of its own, so it is held out of this
     rule and keeps the zero padding set below. */
  .screen > section:not(.closing-body),
  .closing-body > section { padding-block: 1.5rem; }

  .screen + .screen,
  .screen + section,
  section + .screen,
  main + .screen,
  .screen > section + section,
  .closing-body > section + section { border-top: 0; }

  /* hero: the preview takes whatever height the copy leaves it, still 16:9.
     The 38rem reserve is the header and the copy stack, so the preview can
     never push the screen past one viewport. */
  .hero.screen .stage {
    width: clamp(22rem, calc((100svh - 38rem) * 16 / 9), 100%);
    margin-top: 2rem;
  }

  /* big monitors: the preview is the product, so let the hero outrun the
     70rem reading width the rest of the page keeps */
  @media (min-width: 90rem) and (min-height: 50rem) {
    .hero.screen { max-width: min(84rem, 100%); }
  }

  /* ---- the offers row, compacted for the deck (ruling 23) ----
     Of the two plaques the capture is the taller, so it is the one that sets
     the row's height and the one the trimming has to come out of: tighter
     controls, tighter gaps between its three parts, and a microcopy line that
     sets closer than body rhythm because it is a footnote, not prose. */
  .pricing-capture-lede { margin-bottom: 0.5rem; }
  .pricing-capture .email-form input[type="email"] { padding: 0.55rem 0.8rem; }
  .pricing-capture .email-form .btn { padding: 0.55rem 1.1rem; }
  .pricing-capture-note { margin-top: 0.45rem; line-height: 1.45; }

  /* short windows: spend the saved rhythm rather than let the tallest screen
     outgrow the viewport */
  @media (max-height: 54rem) {
    .screen { padding-block: 1.25rem; }
    .section-lede { margin-bottom: 1.25rem; }
    .price-card { padding: 1.25rem; }
    .price-card .price { font-size: 2rem; }
    .price-card ul { margin: 0.7rem 0 1.1rem; }
    .pricing-offers { margin-top: 1.25rem; gap: 1.25rem; }
    .trial-banner, .pricing-capture { padding: 1.1rem 1.5rem; }
    .anchor { margin-top: 1rem; }
    .legit { margin-top: 1rem; }
  }

  /* ---- pricing pays for the capture row out of its own rhythm (ruling 23) ----
     Pricing was already the segment with the least headroom on the page: at
     1366x768 it filled 621px of a 707px band before the row existed, and the
     row is a plaque taller than the banner it stands beside. Compacted as
     above it costs about 155px against 46px of slack, so the rest comes from
     this segment alone, in the sizes below rather than from any global step.

     Everything here hangs off .has-capture, which the page's config gate adds
     only once BUTTONDOWN_USERNAME is filled in and the row is actually on
     screen. A page that is still gated off, or one with no script at all, is
     not paying for a row it does not show, so it keeps the exact spacing it
     had before this section existed. */
  @media (max-height: 54rem) {
    #pricing.has-capture.screen { padding-block: 0.75rem; }
    #pricing.has-capture .section-title { margin-bottom: 0.35rem; }
    #pricing.has-capture .section-lede { margin-bottom: 0.9rem; }
    #pricing.has-capture .price-card { padding: 1.1rem 1.25rem; }
    #pricing.has-capture .price-card ul { margin: 0.55rem 0 0.85rem; }
    #pricing.has-capture .price-fineprint { margin-top: 0.5rem; }
    #pricing.has-capture .pricing-offers { margin-top: 0.9rem; }
    #pricing.has-capture .trial-banner,
    #pricing.has-capture .pricing-capture { padding: 0.95rem 1.4rem; }
    #pricing.has-capture .anchor { margin-top: 0.7rem; }
  }

  /* Just above the global short-window step there is a band of window heights
     the step has stopped helping with and the segment does not yet have the
     room for on its own: uncompacted with the row in place, pricing needs
     about 888px of viewport, and the step above ends at 864px. Measured at
     1366 wide, the segment ran 16px past its band at 866px of viewport and
     first cleared it with under 10px to spare at 897px. So this band gets a
     light version of the same trimming, four sizes rather than nine, and it
     runs to 58rem so the compacted and uncompacted sides meet with headroom
     on both rather than at a knife edge. Above it nothing here applies, and
     it ends below the 64rem floor of the wide-monitor type scale, so the two
     never contradict each other. */
  @media (min-height: 54.0625rem) and (max-height: 58rem) {
    #pricing.has-capture.screen { padding-block: 1.5rem; }
    #pricing.has-capture .section-lede { margin-bottom: 1.5rem; }
    #pricing.has-capture .pricing-offers { margin-top: 1.5rem; }
    #pricing.has-capture .trial-banner,
    #pricing.has-capture .pricing-capture { padding-block: 1.15rem; }
    #pricing.has-capture .anchor { margin-top: 1.1rem; }
  }

  /* Narrow deck windows: the two plaques are each half of a 62rem column, and
     at that width a plaque's side padding is what pushes both the trial
     sentence and the capture lede onto an extra line apiece. Spend less on the
     gutters and the row keeps its shape down to the deck's own width floor. */
  @media (max-width: 75rem) {
    #pricing.has-capture .trial-banner,
    #pricing.has-capture .pricing-capture { padding-inline: 1.05rem; }
  }

  /* wide and short (laptops at 768p): stacking the copy above a 16:9 preview
     would squeeze the preview down to a postage stamp, so the hero turns sideways
     and spends the width it has instead. */
  @media (min-width: 60rem) and (max-height: 54rem) {
    .hero.screen {
      display: grid;
      grid-template-columns: minmax(19rem, 0.9fr) minmax(0, 1.1fr);
      grid-template-rows: auto auto auto auto;
      align-content: center;
      column-gap: clamp(2rem, 3.5vw, 3.5rem);
      max-width: min(92rem, 100%);
      padding-inline: clamp(1.25rem, 4vw, 4rem);
      text-align: left;
    }
    .hero.screen h1 { margin-inline: 0; font-size: clamp(2.6rem, 3.3vw, 3.9rem); }
    .hero.screen .sub { margin-inline: 0; max-width: 34rem; font-size: 1.08rem; }
    .hero.screen .cta-row { justify-content: flex-start; }
    .hero.screen .stage {
      grid-column: 2;
      grid-row: 1 / span 4;
      align-self: center;
      width: 100%;
      margin-top: 0;
    }
  }

  /* ---- the closing segment: goodbye above, footer along the bottom edge ----
     .closing-body takes all the free height and centres the maker note and the
     marquee inside it; the footer keeps its natural height and sits on the
     bottom of the segment, so the page simply ends where the deck ends. */
  .screen-close { justify-content: flex-start; padding-bottom: 0; }
  .closing-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  .screen-close .site-footer { padding: 1.2rem 0 0.9rem; }
  .screen-close .final-cta { padding-bottom: 0.5rem; }

  /* the goodbye screen has room for a marquee, so give it one */
  .screen-close .final-cta .section-title {
    font-size: clamp(2.2rem, 1.6rem + 1.4vw, 3.2rem);
    margin-bottom: 0.6rem;
  }
  .screen-close .final-cta .cta-note { margin-top: 0.7rem; }

  /* ---- the capture plaque, compacted for the deck ----
     Out of deck mode the plaque is a centred stack: title, then form, then the
     microcopy. Stacked, it costs the closing segment about 117px, which is more
     height than the segment has to give once BUTTONDOWN_USERNAME is set: at
     1366x768 the segment measured 824px against a 707px band, and mandatory snap
     then parks the overflow (the footer's legal line) below the fold at rest on
     every laptop height. In deck mode the same three parts read as one centred
     band instead, title and field on one line with the microcopy under them, and
     the segment fits with the plaque showing. */
  .screen-close .email-capture {
    max-width: 44rem;
    margin-inline: auto;
    margin-top: 0.8rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    column-gap: 0.7rem;
    row-gap: 0.4rem;
    padding: 0.85rem 1.2rem;
  }
  .screen-close .email-capture .email-form { flex: 0 1 24rem; }
  .screen-close .email-form-note { flex: 1 0 100%; margin-top: 0; font-size: 0.8rem; }

  /* five features read as 3 + 2 centered, never 4 + 1 orphan */
  @media (min-width: 62rem) {
    .feature-grid { grid-template-columns: repeat(6, 1fr); }
    .feature { grid-column: span 2; }
    .feature:nth-child(4) { grid-column: 2 / span 2; }
    .feature:nth-child(5) { grid-column: 4 / span 2; }
  }

  /* ---- the FAQ is an ordinary one-viewport segment now (ruling 20) ----
     The earlier two-column accordion fitted one screen closed but grew a row
     every time an answer opened, which both shoved the other questions around
     and pushed the segment past its band, and mandatory snap then parked the
     overflow below the fold. The split view has a fixed height instead: the
     list of nine questions sets it and the answer panel is laid out inside that
     height, so the segment fits one viewport whatever is selected and needs no
     special case of its own. */
  #faq .section-title { margin-bottom: 1rem; line-height: 1.15; }
  .faq.is-split > details { display: none; }
  .faq.is-split .faq-split { display: grid; }

  /* ---- and what the deck does without faq.js ----
     If the script 404s or is blocked, .is-split never lands and the nine details
     are the whole FAQ again. A single stacked column of them runs well past the
     band, so the fallback is the two-column accordion this segment carried
     before ruling 20: closed, it fits one screen; opened, it grows its own row
     and the segment scrolls freely, which mandatory snap allows an oversized
     area. Degraded rather than trapped, and no reader of the enhanced page ever
     sees these rules.

     Each card keeps its own natural height. Stretching them to a shared row
     height looks tidier closed, but the moment one answer opens its closed
     row-mate grows into a tall empty card, which is much worse. */
  #faq .faq:not(.is-split) {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 1.5rem;
    row-gap: 0.8rem;
  }
  #faq .faq:not(.is-split) .section-title { grid-column: 1 / -1; margin-bottom: 0; }
  #faq .faq:not(.is-split) details { margin-bottom: 0; align-self: start; }

  /* tall monitors: grow the composition rather than let a small block of ink
     float in the middle of a very large dark field */
  @media (min-height: 56rem) {
    .section-title { font-size: clamp(2rem, 1.1rem + 1.6vh, 3rem); }
    .section-lede { font-size: clamp(1.0625rem, 0.95rem + 0.4vh, 1.22rem); }
    .feature-grid, .price-grid, .steps { gap: clamp(1.5rem, 2.8vh, 3rem); }
    .feature, .price-card { padding: clamp(1.5rem, 2.8vh, 2.5rem); }
    .feature h3, .step-body h3 { font-size: clamp(1.05rem, 0.9rem + 0.5vh, 1.3rem); }
    .feature p, .step-body p { font-size: clamp(0.95rem, 0.85rem + 0.35vh, 1.12rem); }
    .maker-note { font-size: clamp(1.0625rem, 0.95rem + 0.35vh, 1.18rem); }
    .cred-row { gap: clamp(1rem, 1.8vh, 1.8rem); }
    .cred-chip {
      padding: clamp(0.7rem, 1.4vh, 1.3rem) clamp(1.2rem, 2.2vh, 2.1rem);
      font-size: clamp(0.9rem, 0.8rem + 0.3vh, 1.08rem);
    }
    .step-num { width: 2.6rem; height: 2.6rem; font-size: 1.35rem; }

    /* the FAQ grows the same way: a taller list of questions, which also gives
       the answer panel beside it more room */
    .faq-tablist { gap: clamp(0.3rem, 1.1vh, 0.9rem); }
    .faq-tab { padding-block: clamp(0.45rem, 1vh, 1rem); }
  }

  /* ---- wide monitors, part 1: layout (ruling 17) ----
     Below 110rem the 70rem reading column is the composition. Above it that
     column is a strip in a large dark field, so the page spends the width:
     five features on one row, steps and chips stretched across, pricing on its
     own slightly narrower column. Prose blocks keep their own narrower measures
     on top of the wider column, because a 1900px line of body copy is not a
     line anyone reads. Everything here is width- or height-relative, so it is
     safe on a short wide window too. */
  @media (min-width: 110rem) {
    .section-lede { max-width: 52rem; }
    .faq { max-width: 92rem; }
    .pricing-offers > * { max-width: 60rem; }
    .anchor { max-width: 48rem; }
    .legit { max-width: 62rem; }
    .maker-note { max-width: 54rem; }

    /* five features, one row, as panels rather than a ribbon of short cards */
    .feature-grid { grid-template-columns: repeat(5, 1fr); }
    .feature,
    .feature:nth-child(4),
    .feature:nth-child(5) { grid-column: auto; min-height: clamp(14rem, 32vh, 28rem); }

    /* pricing spreads with the column but keeps two readable cards. The whole
       pricing screen sits on a slightly narrower column than the rest, so its
       title, its cards and its banner all share one left edge instead of a
       flush-left title over an indented, centred card grid. */
    #pricing .wrap { max-width: 88rem; }
  }

  /* ---- wide monitors, part 2: the type and spacing scale ----
     Widening alone makes a screen emptier, not fuller: a wider column means
     fewer lines. This scale is what puts the height back, so that a 2560
     monitor is not reading the 1366 type size across a much bigger field.

     Every step is vmin, not vw, and the block is gated on height as well as
     width. A 2560x1080 or 1920x800 window is wide but has no height to spend,
     and a vw-driven scale there pushed the pricing segment past one viewport.
     vmin tracks the limiting dimension, so on a 16:9 monitor the scale is
     unchanged and on a short wide window it stands down on its own. The 64rem
     height gate is measured, not chosen: below it a wide window no longer has
     the room for the extra type, and pricing is the segment that says so.

     Buttons and the hero are deliberately left out: the hero already fills 94%
     of its segment and has no height to give. */
  @media (min-width: 110rem) and (min-height: 64rem) {
    .section-title { font-size: clamp(2.4rem, 1rem + 3.9vmin, 4.4rem); }
    .section-lede { font-size: clamp(1.15rem, 1rem + 0.89vmin, 1.6rem); }
    .feature h3, .step-body h3 { font-size: clamp(1.15rem, 0.95rem + 0.98vmin, 1.75rem); }
    .feature p, .step-body p { font-size: clamp(1rem, 0.9rem + 0.75vmin, 1.45rem); }
    .maker-note, .trial-banner { font-size: clamp(1.0625rem, 0.95rem + 0.75vmin, 1.45rem); }
    /* the capture lede takes a gentler step than the prose beside it: it is a
       one-line ask above a form, and at the prose scale it wraps to two lines
       in a half-column plaque and takes the pricing segment past its band */
    .pricing-capture-lede { font-size: clamp(1rem, 0.92rem + 0.45vmin, 1.22rem); }
    .legit, .anchor, .price-fineprint { font-size: clamp(0.9rem, 0.82rem + 0.46vmin, 1.15rem); }
    .faq-tab { font-size: clamp(1rem, 0.9rem + 0.75vmin, 1.4rem); }
    .faq-answer p { font-size: clamp(1rem, 0.9rem + 0.64vmin, 1.32rem); }
    .faq-chip { font-size: clamp(0.95rem, 0.85rem + 0.53vmin, 1.3rem); }
    .faq-pane.is-focused .faq-chip { font-size: clamp(1.5rem, 1.2rem + 1.07vmin, 2.3rem); }
    .cred-chip { font-size: clamp(0.95rem, 0.85rem + 0.75vmin, 1.4rem); padding: clamp(0.8rem, 1.6vh, 1.6rem) clamp(1.3rem, 2.5vmin, 2.4rem); }
    .price-card h3 { font-size: clamp(1.15rem, 0.95rem + 0.89vmin, 1.7rem); }
    .price-card .price { font-size: clamp(2.4rem, 1.6rem + 2.85vmin, 4rem); }
    .price-card ul { font-size: clamp(1rem, 0.9rem + 0.75vmin, 1.45rem); }
    .step-num { width: clamp(2.6rem, 1.9rem + 1.78vmin, 3.6rem); height: clamp(2.6rem, 1.9rem + 1.78vmin, 3.6rem); font-size: clamp(1.35rem, 1rem + 1.07vmin, 2rem); }

    /* pricing is the height budget on every window, so the scale buys its extra
       type back out of its own vertical rhythm. The offers row is the reason
       the group grew: two plaques side by side cost the segment more than the
       single banner did, and the scale makes each of them taller again. */
    .section-lede { margin-bottom: 1.5rem; }
    .price-card ul { margin: 0.9rem 0 1.2rem; }
    #pricing.has-capture .section-lede { margin-bottom: 1.15rem; }
    #pricing.has-capture .price-card ul { margin: 0.75rem 0 1rem; }
    #pricing.has-capture .price-fineprint { margin-top: 0.6rem; }
    #pricing.has-capture .pricing-offers { margin-top: 1.4rem; }
    #pricing.has-capture .anchor { margin-top: 1rem; }
    #pricing.has-capture .trial-banner,
    #pricing.has-capture .pricing-capture { padding: clamp(1.2rem, 0.75rem + 1.15vmin, 1.9rem); }

    .feature, .price-card { padding: clamp(1.5rem, 0.7rem + 2.4vmin, 3.2rem); }
    .feature-grid, .price-grid, .steps { gap: clamp(1.5rem, 0.8rem + 2.14vmin, 3rem); }
    .faq-pane.is-focused .faq-answer { padding: clamp(2.4rem, 1.6rem + 2vmin, 3.6rem) clamp(1.8rem, 1.1rem + 1.6vmin, 3rem); }
    .trial-banner, .pricing-capture { padding: clamp(1.5rem, 0.9rem + 1.6vmin, 2.4rem); }
    .maker-note { padding: clamp(1.5rem, 0.9rem + 1.6vmin, 2.4rem); }

    /* the goodbye marquee has its own clamp, so it needs its own wide step or
       it ends up smaller than every other title on the page */
    .screen-close .final-cta .section-title { font-size: clamp(2.6rem, 1.2rem + 4.27vmin, 4.8rem); }
  }
}

/* The reading column itself widens on a wide monitor, so the header, content and
   footer stay on one set of margins (ruling 19: every page, not just home).
   The first pass scoped this to the home page because the utility pages kept a
   40rem content column under a 118rem header and footer, which read as a strip
   in a very wide field. Raising the utility pages' own cap to the same 92rem the
   home page's wide prose uses is the real fix: the three bands then sit on
   proportionate margins instead of one sweeping around the other. Below 110rem
   nothing here applies and every page is unchanged. */
@media (min-width: 110rem) {
  :root { --max-w: clamp(100rem, 74vw, 118rem); }
  .page-narrow, .page-legal { max-width: 92rem; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .brand-mark span { animation: none; background: var(--face); }
  .brand-mark span:first-child { background: var(--accent); }
  /* the FAQ wall still rearranges itself, it just does so instantly (ruling 22) */
  .faq-wall.is-live .faq-pane,
  .faq-wall.is-live .faq-chip { transition: none; }
  .faq-pane.is-focused .faq-answer { animation: none; }
  /* the launch offer still arrives, it just does not slide (ruling 23) */
  .launch-offer { opacity: 1; transform: none; transition: none; }
}
