/* WYW — subpage styles: paper scaffolding, section rhythm, pills, cards,
   forms, prose (legal pages). Loads after base.css on every non-home page. */

body.subpage {
  background: var(--paper);
  color: var(--ink);
}

/* fixed paper sheet (same treatment as the landing page's s2 backdrop) */
.page-bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  background: var(--paper) url('../assets/bg-paper-3200.jpg') center / cover no-repeat;
}

/* ---------- Page hero ---------- */

.page-hero {
  display: grid;
  justify-items: center;
  text-align: center;
  padding: 24svh 7vw 10svh;
}

.page-hero__title {
  font-weight: 700;
  font-size: clamp(38px, 5.2vw, 82px);
  line-height: 1.08;
  letter-spacing: -0.04em;
  max-width: 14em;
}

.page-hero__sub {
  max-width: 32em;
  margin-top: 4svh;
  font-size: clamp(17px, 1.45vw, 26px);
  line-height: 1.45;
  color: rgba(38, 37, 31, 0.8);
}

.page-hero__cta { margin-top: 5.5svh; }

/* ---------- Section rhythm ---------- */

.sect {
  padding: 9svh 9vw;
  max-width: 1600px;
  margin: 0 auto;
}

.sect--center { text-align: center; }

.sect__title {
  font-weight: 700;
  font-size: clamp(28px, 3.4vw, 56px);
  letter-spacing: -0.04em;
  line-height: 1.1;
  max-width: 18em;
}

.sect--center .sect__title { margin: 0 auto; }

.sect__copy {
  max-width: 34em;
  margin-top: 2.6svh;
  font-size: clamp(16px, 1.25vw, 22px);
  line-height: 1.5;
  color: rgba(38, 37, 31, 0.8);
}

.sect--center .sect__copy { margin-left: auto; margin-right: auto; }

/* the venues section is centred throughout (founder, 2026-09-11 audit:
   headings and intros were left in every coloured chapter and centred in
   the heroes and closers). body.venues is on the five venues pages; cards
   keep their own left alignment, and the FAQ ledger is a list, not a
   statement, so its rows are untouched (they aren't .sect__title/.sect__copy). */
body.venues .sect__title,
body.venues .sect__copy { text-align: center; }
/* both carry a max-width, so text-align alone centred the words inside a
   box that still sat on the left - the box has to centre too */
body.venues .sect__title,
body.venues .sect__copy { margin-left: auto; margin-right: auto; }

/* ...and inside the cards (founder, same evening: "all text centred, and
   aligned centred"): titles, lines, badges and icons sit on the card's
   centre line. The two list structures keep their own alignment - the
   dashboard walkthrough's numbered rows inside a card, and the FAQ ledger
   and .index rows, which are tables of contents, not statements. */
body.venues .card,
body.venues .icard { text-align: center; }
body.venues .card__icon { margin-left: auto; margin-right: auto; }
body.venues .icard__badge { align-self: center; }
body.venues .vstat { text-align: center; }
body.venues .icard .walk { text-align: left; }

.mut { color: rgba(38, 37, 31, 0.72); }

/* ---------- Pill buttons (venues-style fill wipe) ---------- */

.pill {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 58px;
  padding: 0 34px;
  border: none;
  border-radius: 22px; /* rounded rect per the button component (rx24 @ 64px, scaled to 58px) */
  background: var(--green);
  color: var(--cream);
  text-decoration: none;
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 700;
  cursor: pointer;
}

.pill::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--ink);
  border-radius: inherit;
  transform: translateX(-101%);
  transition: transform 0.45s cubic-bezier(0.77, 0, 0.18, 1);
}

.pill > span { position: relative; z-index: 1; }

.pill:hover::before,
.pill:focus-visible::before { transform: translateX(0); }

.pill--ink { background: var(--ink); }
.pill--ink::before { background: var(--green); }

.pill--wide { width: 100%; }

/* ---------- Cards ---------- */

.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(14px, 1.6vw, 26px);
  margin-top: 6svh;
}

.cards--2 { grid-template-columns: repeat(2, 1fr); }
.cards--4 { grid-template-columns: repeat(4, 1fr); }

.card {
  border: 1.5px solid rgba(38, 37, 31, 0.18);
  border-radius: 18px;
  padding: clamp(20px, 2.1vw, 36px);
  background: rgba(243, 236, 218, 0.55);
  text-align: left;
  transition:
    transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1),
    border-color 0.3s ease, background 0.3s ease, box-shadow 0.5s ease;
}

/* rollover — springy lift with a hint of wag, alternating tilt per card.

   HOVER IS GATED to devices that actually have one. iOS resolves :hover
   against the last-tapped element and KEEPS it there until you tap
   somewhere else, so on a phone these cards lifted, tilted and filled with
   no input at all, then stayed that way — reported from an iPhone on
   2026-08-09 as cards animating "at random". They are not links, so the
   state it was advertising never led anywhere either. Keyboard
   :focus-within is NOT gated: it only fires on real focus, and the
   for-venues cards do contain links. */
.card:focus-within {
  transform: translateY(-8px) rotate(-0.7deg);
  border-color: rgba(38, 37, 31, 0.4);
  background: var(--cream);
  box-shadow: 0 20px 44px rgba(38, 37, 31, 0.12);
}

.cards > .card:nth-child(even):focus-within {
  transform: translateY(-8px) rotate(0.7deg);
}

@media (hover: hover) {
  .card:hover {
    transform: translateY(-8px) rotate(-0.7deg);
    border-color: rgba(38, 37, 31, 0.4);
    background: var(--cream);
    box-shadow: 0 20px 44px rgba(38, 37, 31, 0.12);
  }

  .cards > .card:nth-child(even):hover {
    transform: translateY(-8px) rotate(0.7deg);
  }
}

.card__icon {
  width: 34px;
  height: 34px;
  color: var(--green-deep);
  margin-bottom: 14px;
}

.card__title {
  font-weight: 700;
  font-size: clamp(17px, 1.35vw, 24px);
  letter-spacing: -0.02em;
}

.card__text {
  margin-top: 8px;
  font-size: clamp(14px, 1.05vw, 18px);
  line-height: 1.45;
  color: rgba(38, 37, 31, 0.7);
}

/* ---------- Surface chapters (for-venues) ----------

   The venues page is chaptered by surface the way the landing page is —
   paper for the pitch, DARK for the problem, GREEN HALFTONE for the promise,
   paper for the product, DARK again for "bigger than the queue". Each chapter
   is a full-bleed band holding an ordinary .sect inside it, so the type scale,
   max-width and rhythm stay identical to the paper sections: only the surface
   and the ink change.

   Chapters butt STRAIGHT up against each other — every join is a clean
   horizontal cut. Diagonal ribbon seams used to straddle the joins; they were
   cut on 2026-08-07 (founder: they read wonky). Nothing replaced them, so
   don't reintroduce negative margins here: the chapters are in normal flow
   and the joins are exact. */

.vchapter {
  position: relative;
  overflow: hidden; /* clips the background queue to the chapter */
}

.vchapter--dark { background: var(--dark); }

.vchapter--green {
  /* the hero's halftone - but NOT `cover`. Cover fits the 2560x1231 sheet to
     the chapter's own height, so a tall chapter blew the dots up (x1.74 on
     how-it-runs' product chapter at 1280, x3.28 at 375 - the "blurry
     texture" of the 2026-09-11 audit). This is the hero's scale instead:
     the hero covers a 100vw x 100svh box, i.e. the sheet at
     max(100vw, 100svh x 2560/1231) wide, and that same width tiles down
     the chapter (the field is uniform, so the repeat is invisible). */
  background: var(--green) url('../assets/bg-green-halftone-tile.webp') top center / max(100vw, 208svh) auto repeat-y;
  /* ...on its own copy of the sheet whose bottom 160 rows are feathered
     into its top, so the vertical repeat has no visible edge - the plain
     sheet drew a hairline across every chapter taller than one tile
     (Tom, 2026-09-11 evening). The hero and the menu keep the original
     with `cover`; the first tile here starts on the same rows they do. */
}

/* chapter content sits above the background queue */
.vchapter__in { position: relative; z-index: 1; }

/* .sect__title / .sect__copy are ink-on-paper by default — the chapters
   restate them in cream rather than forking the type rules */
.vchapter .sect__title { color: var(--cream); }
.vchapter--dark .sect__copy { color: rgba(243, 236, 218, 0.78); } /* 6.8:1 on #383838 */
/* cream on --green measures 2.38:1 site-wide (menu overlay, footer band) —
   a brand relationship, not a choice made here. Don't dim it further: the
   green chapter runs FULL cream so it is never worse than the rest of WYW. */
.vchapter--green .sect__copy { color: var(--cream); }

/* a chapter runs a little taller than a paper section — it is a stage, and
   the extra air at both ends is what keeps the type off a hard-cut join */
.vchapter .sect { padding-top: 12svh; padding-bottom: 11svh; }

/* DARK deliberately has no .hl override: --highlight is semi-transparent on
   purpose, so it composites DEEPER on #383838 (to #668363) exactly like the
   Figma dark frames, and the cream inherited from .sect__title reads 3.6:1
   on it — AA-large, which is what the display size needs. Don't "fix" the
   marker on dark by solidifying it; the whole token is built to composite.

   GREEN is the one that needs help — the brand marker is invisible on the
   halftone, so it becomes cream block + ink text, exactly the treatment the
   menu overlay uses on this same background. */
.vchapter--green .hl {
  background-image: linear-gradient(var(--cream), var(--cream));
  color: var(--ink);
}

/* (the .vchapter__label kicker idiom lived here until 2026-08-20 - the
   founder cut the eyebrow labels across the whole venues section) */

/* the queue marching behind the problem stats — same track, same 46s clock
   as the footer, dialled down to a texture */
.vchapter__queue {
  position: absolute;
  left: 0;
  right: 0;
  /* lifted off the chapter's foot so the figures walk on a floor rather than
     getting sliced by the join. Literal value: it is 0.75x the height of the
     ribbon seam this used to clear, kept so the composition the founder
     signed off doesn't move now the seams are gone. */
  bottom: clamp(54px, 6.6vw, 114px);
  height: clamp(120px, 17vw, 240px);
  overflow: hidden;
  color: rgba(243, 236, 218, 0.06); /* texture behind the figures, not objects */
  pointer-events: none;
}

.vchapter__queue .banner__figure { height: 100%; }

/* the cards keep the .card component and its springy wag — a chapter only
   recolours it for its surface. On DARK the tint inverts: the green chapter
   deepens its cards with an ink wash, the dark stage lifts them with a cream
   one, so on both surfaces a card reads as a panel and never as a hole.
   (base .card:hover fills with solid --cream, which would blow out on
   #383838 — the hover has to be restated here, same as on green.) */
.vchapter--dark .card {
  border-color: rgba(243, 236, 218, 0.26);
  /* 0.07 cream over #383838 lands at #454543: enough to separate the panel
     from the stage without becoming a grey box on it */
  background: rgba(243, 236, 218, 0.07);
}

/* :hover gated to pointer devices for the same reason as the base card */
.vchapter--dark .card:focus-within {
  border-color: rgba(243, 236, 218, 0.6);
  background: rgba(243, 236, 218, 0.14);
  /* the paper card's ink shadow is invisible here — the lift has to be true
     black to read against the stage */
  box-shadow: 0 20px 44px rgba(0, 0, 0, 0.35);
}

@media (hover: hover) {
  .vchapter--dark .card:hover {
    border-color: rgba(243, 236, 218, 0.6);
    background: rgba(243, 236, 218, 0.14);
    box-shadow: 0 20px 44px rgba(0, 0, 0, 0.35);
  }
}

.vchapter--dark .card__title { color: var(--cream); } /* 8.2:1 on the card */
.vchapter--dark .card__text { color: rgba(243, 236, 218, 0.8); } /* 5.9:1 */

/* the paper card's --green-deep icon measures 2.1:1 on this fill — under the
   3:1 a graphic needs. The brand --green reads 3.4:1 and is the tone the
   dark stage already uses for accents (the s4 finale dot) */
.vchapter--dark .card__icon { color: var(--green); }
/* on green the deep-green icon measured 1.12:1 against the card fill - gone.
   Cream reads ~3.2:1 there and matches the card's own type (audit 2026-09-11). */
.vchapter--green .card__icon { color: var(--cream); }

.vchapter--green .card {
  border-color: rgba(243, 236, 218, 0.42);
  /* the ink tint is doing legibility work as well as styling: at the mock's
     0.10 the cream card text sat at 2.35:1, at 0.24 it reads 3.0:1 and the
     bold titles clear AA-large */
  background: rgba(38, 37, 31, 0.24);
}

.vchapter--green .card:focus-within {
  border-color: rgba(243, 236, 218, 0.72);
  background: rgba(38, 37, 31, 0.36);
  box-shadow: 0 20px 44px rgba(38, 37, 31, 0.18);
}

@media (hover: hover) {
  .vchapter--green .card:hover {
    border-color: rgba(243, 236, 218, 0.72);
    background: rgba(38, 37, 31, 0.36);
    box-shadow: 0 20px 44px rgba(38, 37, 31, 0.18);
  }
}

.vchapter--green .card__title { color: var(--cream); }
.vchapter--green .card__text { color: rgba(243, 236, 218, 0.94); }

/* the film is the chapter's centrepiece — lift it off the halftone */
.vchapter--green .filmframe { box-shadow: 0 30px 70px rgba(38, 37, 31, 0.3); }

/* the problem stats — the section, not three cards */
.vstats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(18px, 3vw, 54px);
  margin-top: clamp(30px, 5vw, 68px);
}

.vstat {
  border-top: 2px solid rgba(243, 236, 218, 0.32);
  padding-top: clamp(14px, 1.6vw, 20px);
}

.vstat__value {
  font-weight: 700;
  font-size: clamp(48px, 7.4vw, 128px);
  line-height: 0.82;
  letter-spacing: -0.06em;
  color: var(--cream);
}

.vstat__label {
  margin-top: clamp(12px, 1.4vw, 18px);
  font-size: clamp(13px, 1.05vw, 18px);
  line-height: 1.35;
  color: rgba(243, 236, 218, 0.78);
  max-width: 13em;
}

/* ---------- Film frame (for-venues centrepiece) ---------- */

/* the ink frame holds 16:9 from first paint, and both children fill it
   absolutely, so starting playback can never shift the page */
.filmframe {
  position: relative;
  aspect-ratio: 16 / 9;
  max-width: 1100px;
  margin: 6svh auto 0;
  border-radius: clamp(18px, 2vw, 30px);
  background: var(--ink);
  color: var(--cream);
  overflow: hidden;
}

.filmframe__video {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* the whole frame IS the play button, so the badge affordance and the click
   target are one keyboard-reachable control (no duplicate frame handler) */
.filmframe__play {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-content: center;
  padding: 0;
  border: none;
  border-radius: inherit;
  /* a light veil so the still reads as a film at rest, plus a pool right
     behind the badge so it separates from whatever the frame is showing
     (the poster carries its own billboard copy - don't drown it) */
  background:
    radial-gradient(30% 34% at 50% 50%, rgba(38, 37, 31, 0.5), rgba(38, 37, 31, 0) 75%),
    linear-gradient(rgba(38, 37, 31, 0.22), rgba(38, 37, 31, 0.22));
  color: inherit;
  cursor: pointer;
  transition: background 0.3s ease;
}

.filmframe__play:hover,
.filmframe__play:focus-visible {
  background:
    radial-gradient(30% 34% at 50% 50%, rgba(38, 37, 31, 0.56), rgba(38, 37, 31, 0) 75%),
    linear-gradient(rgba(38, 37, 31, 0.3), rgba(38, 37, 31, 0.3));
}

/* once playing, the control leaves the tab order and native controls take over */
.filmframe.is-playing .filmframe__play { display: none; }

.filmframe__badge {
  width: clamp(64px, 6vw, 92px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--green);
  display: grid;
  place-items: center;
  box-shadow: 0 6px 26px rgba(38, 37, 31, 0.45);
  transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.filmframe__play:hover .filmframe__badge,
.filmframe__play:focus-visible .filmframe__badge { transform: scale(1.12); }

.filmframe__badge svg { width: 38%; margin-left: 8%; }

@media (prefers-reduced-motion: reduce) {
  .filmframe__badge { transition: none; }
}

/* ---------- Dashboard walkthrough (for-venues) ----------

   Supersedes the numbered-hotspot mockups. One component at every width: a
   numbered step list on one side, the dashboard on the other. The dashboard
   is ALWAYS shown WHOLE — never zoomed, never panned (the founder's call:
   "we see the whole dash"). Activating a step lights that step's pin at its
   --x/--y on the screenshot and dims the other four; those percentages are
   the same screenshot coordinates the hotspots used. */

.walk {
  display: grid;
  gap: clamp(22px, 3vw, 46px);
  margin-top: 7svh;
}

@media (min-width: 901px) {
  .walk {
    /* the dash carries the section, so it takes the bigger share; the list
       column still clears ~420px, which the five titles want */
    grid-template-columns: minmax(280px, 0.78fr) 1.22fr;
    align-items: start;
  }
}

.walk__title {
  font-weight: 700;
  font-size: clamp(22px, 2vw, 34px);
  letter-spacing: -0.03em;
}

.walk__copy {
  margin-top: 8px;
  max-width: 34em;
  font-size: clamp(15px, 1.15vw, 20px);
  line-height: 1.5;
  color: rgba(38, 37, 31, 0.75);
}

/* replaces "explore the dots ↓" — there are no dots to hunt any more */
.walk__hint {
  margin-top: 10px;
  font-weight: 700;
  font-size: clamp(12px, 0.95vw, 15px);
  color: var(--green-deep);
}

.walk__list {
  list-style: none;
  margin-top: clamp(16px, 2vw, 26px);
  border-top: 1.5px solid rgba(38, 37, 31, 0.2);
}

.walk__step { border-bottom: 1.5px solid rgba(38, 37, 31, 0.2); }

.walk__row {
  position: relative;
  z-index: 0; /* stacking context so the marker can sit behind the label */
  display: grid;
  grid-template-columns: 28px 1fr;
  gap: 14px;
  align-items: start;
  width: 100%;
  padding: 13px 12px;
  border: none;
  background: none;
  text-align: left;
  cursor: pointer;
  font-family: var(--font-display);
  color: var(--ink);
}

/* the marker sweeps across the active row — the ticket rail's --fill
   progress bar. Nothing scrubs it here, so a plain transform transition
   owns it (no per-frame JS writes, no layout in the animation) */
.walk__row::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--highlight);
  transform: scaleX(var(--fill, 0));
  transform-origin: left center;
  transition: transform 0.42s cubic-bezier(0.77, 0, 0.18, 1);
}

.walk__row[aria-expanded='true'] { --fill: 1; }

.walk__n {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1.5px solid rgba(38, 37, 31, 0.4);
  color: rgba(38, 37, 31, 0.62);
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 13px;
  transition: background 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}

.walk__row[aria-expanded='true'] .walk__n {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--cream);
}

.walk__t {
  padding-top: 4px;
  font-weight: 700;
  font-size: clamp(15px, 1.2vw, 19px);
  letter-spacing: -0.02em;
  line-height: 1.25;
}

/* ONE slot for the copy, not a panel per row. All five sit in the same grid
   cell and crossfade, so the cell is always as tall as the longest of them:
   the rows above it never move, nothing reflows under the pointer as you
   sweep the list, and the only thing animating is opacity. (Expanding each
   step in place — the obvious build — slid the hovered row 56px out from
   under the cursor. Measured; don't reintroduce it.)

   The slot is a SLAB, not a caption (founder, 2026-08-07: the copy under
   each point didn't read clearly). It is the site's card language — cream
   wash on paper, the same tint family as .card/.role-row — dropped below the
   list with a green-deep spine down its left edge, so it reads as the one
   thing the lit step is pointing at rather than a stray line of small print.
   The spine is the same green-deep as .walk__hint and the pins.

   The padding lives on the PANEL, not on the five copies: identical padding
   on five stacked copies is the same box either way, and this keeps the grid
   cell measuring only the copy — the fixed-size crossfading cell is
   untouched. Don't move it back onto .walk__c. */
.walk__panel {
  display: grid;
  margin-top: clamp(14px, 1.6vw, 22px);
  padding: clamp(15px, 1.4vw, 21px) clamp(16px, 1.5vw, 24px);
  border-left: 3px solid var(--green-deep);
  border-radius: 3px 14px 14px 3px;
  background: rgba(243, 236, 218, 0.78);
  box-shadow: 0 8px 20px rgba(38, 37, 31, 0.06);
}

.walk__c {
  grid-area: 1 / 1;
  /* full ink, not the old 0.72 wash: measured 12.8:1 on the panel against
     5.4:1 before, and a size up so it stops reading as a footnote */
  font-size: clamp(14px, 1.05vw, 17px);
  line-height: 1.5;
  color: var(--ink);
  opacity: 0;
  /* visibility keeps the cell's height but takes the inactive copy out of
     the a11y tree, so a screen reader hears the step it opened, not five */
  visibility: hidden;
  transition: opacity 0.24s ease, visibility 0s linear 0.24s;
}

.walk__c.is-on {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.24s ease;
}

/* ink bezel, the site's drawn-object language (same as the ticket phone) */
.walk__frame {
  position: relative;
  background: var(--ink);
  border-radius: clamp(14px, 1.6vw, 24px);
  padding: clamp(8px, 1vw, 14px);
  box-shadow: 0 24px 60px rgba(38, 37, 31, 0.18);
}

/* the stage is exactly the screenshot's box: pin --x/--y are % of it. The
   ring has to escape the rounded screen, so overflow lives on __screen */
.walk__stage { position: relative; }

.walk__screen {
  border-radius: clamp(7px, 0.9vw, 13px);
  overflow: hidden;
}

.walk__screen img { display: block; width: 100%; height: auto; }

.walk__pin {
  position: absolute;
  left: var(--x);
  top: var(--y);
  /* positioning only — every animated transform lives on the disc, so the
     two never fight (the footer-CTA lesson) */
  transform: translate(-50%, -50%);
  opacity: 0.42;
  transition: opacity 0.3s ease;
}

.walk__pin.is-on {
  opacity: 1;
  z-index: 2;
}

.walk__pin i {
  position: relative;
  display: grid;
  place-items: center;
  width: clamp(20px, 2.3vw, 30px);
  aspect-ratio: 1;
  border: 2px solid var(--cream);
  border-radius: 50%;
  background: var(--green-deep);
  color: var(--cream);
  font-style: normal;
  font-weight: 700;
  font-size: clamp(10px, 1vw, 14px);
  box-shadow: 0 2px 10px rgba(38, 37, 31, 0.35);
  transition: transform 0.34s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.walk__pin.is-on i { transform: scale(1.3); }

/* the ring springs out around the active pin and stays — this is the state,
   so it still reads with animation switched off */
.walk__pin i::after {
  content: '';
  position: absolute;
  inset: -7px;
  border: 2px solid var(--cream);
  border-radius: 50%;
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 0.3s ease, transform 0.34s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.walk__pin.is-on i::after {
  opacity: 0.9;
  transform: scale(1);
}

/* the ping — one pulse as a step becomes active. On a phone this is the
   "I tapped a row, the dash answered" feedback. */
@keyframes walk-ping {
  from { opacity: 0.5; transform: scale(0.9); }
  to { opacity: 0; transform: scale(2.6); }
}

.walk__pin i::before {
  content: '';
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  background: rgba(92, 127, 91, 0.55);
  opacity: 0;
  pointer-events: none;
}

.walk__pin.is-on i::before { animation: walk-ping 0.85s ease-out 1; }

@media (prefers-reduced-motion: reduce) {
  .walk__row::before,
  .walk__n,
  .walk__c,
  .walk__c.is-on, /* out-specifies its own crossfade rule */
  .walk__pin,
  .walk__pin i,
  .walk__pin i::after { transition: none; }
  .walk__pin.is-on i::before { animation: none; }
}

/* ---------- Forms (Netlify) ---------- */

.form {
  max-width: 560px;
  margin: 1svh auto 0; /* the intro copy above already carries the spacing */
  display: grid;
  gap: 20px;
  text-align: left;
}

.form__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

.form label {
  display: block;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin-bottom: 7px;
}

.form input,
.form select,
.form textarea {
  width: 100%;
  font-family: var(--font-display);
  font-size: 17px;
  color: var(--ink);
  padding: 14px 16px;
  border: 1.5px solid rgba(38, 37, 31, 0.35);
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.55);
  transition: border-color 0.25s ease, background 0.25s ease;
}

.form input:focus,
.form select:focus,
.form textarea:focus {
  outline: none;
  border-color: var(--green-deep);
  background: rgba(255, 255, 255, 0.8);
}

.form textarea { min-height: 140px; resize: vertical; }

.form select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--ink) 50%), linear-gradient(135deg, var(--ink) 50%, transparent 50%); background-position: calc(100% - 21px) 50%, calc(100% - 16px) 50%; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }

.form__note {
  text-align: center;
  font-size: 14px;
  color: rgba(38, 37, 31, 0.72);
}

.form__note a { color: inherit; }

/* shown by js/forms.js only when a submit fails — the fields keep their
   contents, so this is a "try again" line, not a dead end */
.form__error {
  margin-top: -6px;
  text-align: center;
  font-size: 14px;
  line-height: 1.5;
  color: #8c3b2e;
}

.form__error:empty { display: none; }

.form__error a { color: inherit; }

/* honeypot — visually gone, present for bots */
.form .hp { position: absolute; left: -9999px; }

/* ---------- Prose (legal pages) ---------- */

.prose {
  max-width: 46em;
  margin: 0 auto;
  padding: 22svh 7vw 12svh;
}

.prose h1 {
  font-size: clamp(34px, 4vw, 60px);
  letter-spacing: -0.04em;
  line-height: 1.05;
  margin-bottom: 0.4em;
}

.prose .updated {
  font-size: 14px;
  color: rgba(38, 37, 31, 0.72);
  margin-bottom: 3em;
}

.prose h2 {
  font-size: clamp(21px, 1.9vw, 30px);
  letter-spacing: -0.03em;
  margin: 2.4em 0 0.7em;
}

.prose p,
.prose li {
  font-size: clamp(16px, 1.1vw, 19px);
  line-height: 1.65;
  color: rgba(38, 37, 31, 0.85);
  margin-bottom: 1em;
  /* the legal pages spell URLs out in full, and a bare one is a single
     unbreakable token: policies.google.com/technologies/cookies wants 301px
     and ran 8px off a 320px screen. break-word only ever splits a word that
     could not fit a line on its own, so ordinary prose is untouched. */
  overflow-wrap: break-word;
}

.prose ul { margin: 0 0 1em 1.3em; }

.prose a { color: var(--green-deep); }

.prose table {
  width: 100%;
  border-collapse: collapse;
  margin: 1.5em 0;
  font-size: clamp(14px, 1vw, 17px);
}

.prose th,
.prose td {
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid rgba(38, 37, 31, 0.18);
  vertical-align: top;
  line-height: 1.5;
}

.prose th { font-weight: 700; }

/* ---------- Founder cards (investors) ---------- */

.founder__avatar {
  width: 116px;
  aspect-ratio: 1;
  border-radius: 50%;
  border: 2px solid rgba(38, 37, 31, 0.18);
  display: grid;
  place-items: center;
  color: rgba(38, 37, 31, 0.4);
  margin-bottom: 18px;
  overflow: hidden;
}

.founder__avatar img { width: 100%; height: 100%; object-fit: cover; }

.founder__role {
  margin-top: 2px;
  font-size: clamp(14px, 1vw, 17px);
  color: rgba(38, 37, 31, 0.72);
}

.founder__bio { margin-top: 12px; }

.founder__link {
  display: inline-block;
  margin-top: 14px;
  color: var(--green-deep);
  font-weight: 700;
  font-size: 15px;
  text-decoration: none;
  padding-bottom: 2px;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: left bottom;
  background-size: 0% 1.5px;
  transition: background-size 0.3s ease;
}

.founder__link:hover,
.founder__link:focus-visible { background-size: 100% 1.5px; }

/* ---------- Roles list (work with us) ---------- */

.roles {
  max-width: 720px;
  margin: 6svh auto 0;
  display: grid;
  gap: 12px;
}

.role-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  border: 1.5px solid rgba(38, 37, 31, 0.18);
  border-radius: 16px;
  padding: 20px 26px;
  background: rgba(243, 236, 218, 0.55);
  text-align: left;
}

.role-row__title { font-weight: 700; font-size: clamp(16px, 1.25vw, 21px); }

.role-row__meta { font-size: clamp(13px, 1vw, 16px); color: rgba(38, 37, 31, 0.72); }

/* ---------- Compact footer (subpages: green band only) ---------- */

.footer--compact {
  /* the base .footer min-height (100svh + gallery term) is home-finale
     geometry; without this reset every subpage ran ~960px of bare paper
     past the green band (was live on prod - fixed 2026-08-05) */
  min-height: 0;
}

.footer--compact .footer__bar {
  min-height: 19vw;
  padding-bottom: 13vw; /* keeps the row + legal line clear of the queue marquee */
}


/* ---------- Mobile ---------- */

@media (max-width: 900px) {
  .cards { grid-template-columns: repeat(2, 1fr); }
  .cards--2 { grid-template-columns: 1fr; }

  /* ---- the walkthrough, stacked ----
     From here down the walk is one column, so the dashboard goes on TOP
     (whole, smaller, but whole) and the list reads underneath it.

     It used to STICK here (`position: sticky; top: 105px; z-index: 3`) with
     an opaque full-bleed backing, so the list would scroll up underneath the
     dash. On a phone that is the whole component: the shelf sat over the
     numbered steps and the headings for the entire height of `.walk`, and it
     took the taps meant for the rows underneath it. It also carried
     `background-attachment: fixed`, which iOS composites badly on a sticky
     element — the shelf detached and stalled mid-scroll until an unrelated
     repaint flushed it, which is the "frozen stuck on top" half of the same
     report (three iPhones, 2026-08-09). Both blocks are inside one section,
     so the second shelf also slid over the FIRST block's steps, which is
     what read as the dashboard "changing at random" (bug #17).

     The founders' expectation is explicit and simpler: the image stays in
     its own space and never covers the steps. So it is a plain in-flow block
     now. The list below is still the navigation, and the copy slab sits
     directly under the list, so a tapped step always answers on screen. */
  .walk { gap: 22px; }

  .walk__view { order: -1; }
}

@media (max-width: 640px) {
  .page-hero { padding-top: 20svh; }
  .sect { padding: 6svh 7vw; }
  .cards { grid-template-columns: 1fr; }

  /* the chapters keep their extra air but scaled to a phone */
  .vchapter .sect { padding-top: 9svh; padding-bottom: 6svh; }
  .vchapter__queue { height: clamp(96px, 30vw, 150px); }

  /* one stat per line — each figure gets to be a statement */
  .vstats { grid-template-columns: 1fr; gap: 26px; }
  .vstat__label { max-width: none; }

  /* the stacked walkthrough (set up at 900px) retuned for a phone */
  .walk { gap: 14px; }

  .walk__frame {
    padding: 6px;
    border-radius: 12px;
    /* the desktop 60px shadow washed the whole sticky shelf a shade dark */
    box-shadow: 0 10px 24px rgba(38, 37, 31, 0.16);
  }
  .walk__screen { border-radius: 7px; }

  /* two operator pins sit 6% of the screenshot apart, which is ~10px once
     the dash is phone-sized: inactive pins drop their number and shrink to a
     plain dot, so the active one always reads clearly on top of them */
  .walk__pin i { width: 22px; font-size: 11px; }
  .walk__pin:not(.is-on) i { transform: scale(0.42); color: transparent; }
  .walk__pin i::after { inset: -5px; }

  /* the 16:9 frame is only ~190px tall on a phone - a 64px badge sits too
     heavy in it */
  .filmframe__badge { width: 54px; }
  /* the venues "get" row stays 2x2 on phones (copy doc's call) - the four
     short cards read better as a grid than a long stack */
  .cards--4 { grid-template-columns: repeat(2, 1fr); }
  .form__row { grid-template-columns: 1fr; }
  .role-row { flex-direction: column; align-items: flex-start; gap: 6px; }
  /* the stacked-row footer padding is handled in base.css; compact just needs
     the same clearance for the marquee (this selector out-specifies it) */
  .footer--compact .footer__bar { min-height: 0; padding-bottom: 26vw; }
}

/* ===== venues section: shared components (owner: CTO session) ===========
   (the .vnav ticket strip lived here 2026-08-19 -> 2026-09-11; the founder
   cut it - the section's wayfinding is the takeover menu's venues index
   and the .index rows in css/venues-index.css now) */

/* Placeholder frame - a visual slot the creative team still owes an asset
   for. The label inside names the asset; the ideal-asset spec lives in the
   dev report / creative brief, not on the page. */
.ph {
  display: grid;
  place-items: center;
  margin-top: 6svh;
  border: 1.5px dashed rgba(38, 37, 31, 0.35);
  border-radius: 18px;
  background: rgba(243, 236, 218, 0.4);
  color: rgba(38, 37, 31, 0.55);
  font-size: 15px;
  line-height: 1.5;
  text-align: center;
  padding: 24px;
  min-height: 220px;
}

.ph--photo { aspect-ratio: 3 / 2; min-height: 0; }
.ph--wide  { aspect-ratio: 16 / 7; min-height: 0; }

/* non-paper chapter surfaces flip the placeholder to cream */
.vchapter--dark .ph,
.vchapter--green .ph {
  border-color: rgba(243, 236, 218, 0.45);
  background: rgba(243, 236, 218, 0.08);
  color: rgba(243, 236, 218, 0.7);
}

/* ===== illustrated cards (2026-09-11 frames, owner: CTO session) ==========
   The five September frames share one component: a flat white card with a
   quiet label or a pill badge top-left, a REGULAR-weight title, a muted
   line, and a cream illustration panel. It is not .card and must not be
   styled like it: it stays white on every surface (paper, dark, green)
   instead of tinting with the chapter, it never lifts (these are not links -
   the 2026-08-09 phone round), and its title is Regular, not Bold - the
   founder's call on 2026-09-11: bold is for headings and statements. The
   frames' top-right (+) control was cut the same day; do not draw one.

   The art is the frame's own crop at 2x (assets/illus/), so the panel's
   ratio comes from the frame and `object-fit: cover` only trims a sliver
   when a breakpoint changes the box. Set --icard-ratio per row: 1.82 for
   the integrations stack, 1.74 for the questions, 1.52 for steps and
   feature cards, 1.7 for the brand row, 2.1 for the two routes. The panel
   cream is the illustrations' own background (#F5F0E8, measured), so a
   short picture and its padding read as one surface. */

.icards {
  /* the default lives on the GRID, not the card: a value set on .icard
     itself would beat any inherited one, so a row-level override (inline
     on the grid, or a page rule on .icards) could never reach the image.
     Caught by DEV-3 on the first build. */
  --icard-ratio: 1.52;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(14px, 1.6vw, 26px);
  margin-top: 6svh;
}

.icards--2 { grid-template-columns: repeat(2, 1fr); }
.icards--4 { grid-template-columns: repeat(4, 1fr); }

.icard {
  display: flex;
  flex-direction: column;
  padding: clamp(18px, 1.5vw, 26px);
  border-radius: 24px;
  background: #fff;
  color: var(--ink);
  text-align: left;
}

/* the top line: a quiet label ("route A", "01", the question) ... */
.icard__label {
  /* the label slot often holds an h3 (the question cards); the UA's bold
     must not win - the founder's rule is bold for headings and statements
     only, and this line is neither at 12px */
  font-weight: 400;
  font-size: clamp(12px, 0.85vw, 14px);
  line-height: 1.3;
  color: rgba(38, 37, 31, 0.62); /* 5.9:1 on white */
}

/* ... or a pill. Green is --green-deep, not --green: at 12px bold the
   brand cream-on-green (2.38:1) is illegible, and the deep tone is what
   small type already uses on paper for the same reason. */
.icard__badge {
  display: inline-block;
  /* as a direct child of the flex-column card the pill is a flex item and
     would stretch to the card's full width (measured 476px, DEV-2);
     flex-start shrink-wraps it to its text. Harmless when it's wrapped. */
  align-self: flex-start;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink);
  font-size: clamp(12px, 0.8vw, 13px);
  font-weight: 700;
  line-height: 1.3;
}

.icard__badge--green {
  background: var(--green-deep);
  color: var(--cream);
}

.icard__title {
  margin-top: 14px;
  font-weight: 400;
  font-size: clamp(20px, 1.65vw, 30px);
  line-height: 1.12;
  letter-spacing: -0.02em;
}

.icard__text {
  margin-top: 8px;
  font-size: clamp(14px, 1.05vw, 18px);
  line-height: 1.45;
  color: rgba(38, 37, 31, 0.7);
}

/* the panel sits on the card's floor, so a row of cards with one-line and
   two-line titles still lands its pictures on one baseline */
.icard__art {
  margin-top: auto;
  padding-top: 18px;
}

.icard__art img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: var(--icard-ratio);
  object-fit: cover;
  border-radius: 16px;
  background: #F5F0E8;
}

/* four-up goes 2x2 well before the house 900px collapse: a quarter-width
   card with a sentence badge ("unchanged, fed by your pos" needs 183px)
   and an illustration drops below its line at ~1135px, so iPad landscape
   sat in a band where every badge and every line wrapped (DEV-1, measured) */
@media (max-width: 1140px) {
  .icards--4 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 900px) {
  .icards,
  .icards--4 { grid-template-columns: repeat(2, 1fr); }
  .icards--2 { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
  /* one card per line: with a picture inside, a 2x2 at 320px shrinks the
     art to a postage stamp and wraps every title to three lines */
  .icards,
  .icards--4 { grid-template-columns: 1fr; }
  .icard { border-radius: 20px; }
  /* the reveal layer treats the swipe row's scrollport as its clip, so
     cards 3 and 4 sat at opacity 0 until swiped into view and arrived half
     a second late (DEV-C, measured). On phones the row is simply there;
     the desktop stagger on the same rows is untouched. */
  .icards--4 > .icard.vm { opacity: 1; transform: none; }

  /* ...except a FOUR-up row, which stacked is a thousand pixels of phone
     scroll on its own (how-it-runs' green chapter measured 4,028px at 375,
     the page 8.9 screens - CTO audit finding 7). Below the house minor
     breakpoint it swipes instead, and the cards keep their art. The flex
     display wins over the stack rule above and makes the grid columns
     inert. No dots, no arrows, no "swipe" label: the next card peeking at
     the right edge is the whole affordance. */
  .icards--4 {
    display: flex;
    overflow-x: auto;
    overscroll-behavior-x: contain; /* a swipe past the end must not page-turn */
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    gap: 14px;
    /* bleed to the viewport edges so cards scroll edge to edge, then put
       the gutter back INSIDE the scroller. 7vw is .sect's phone padding
       (the 640 block above), so the margin cancels it exactly and the row's
       border box lands at 100vw - no page overflow. scroll-padding keeps a
       snapped card off the screen edge rather than flush to it. */
    margin-inline: -7vw;
    padding-inline: 7vw;
    scroll-padding-inline: 7vw;
    scrollbar-width: none;
  }

  .icards--4::-webkit-scrollbar { display: none; }

  /* 78vw leaves ~15vw of the next card showing past the gutter */
  .icards--4 > .icard {
    flex: 0 0 78vw;
    scroll-snap-align: start;
  }
}

