/* ============================================================
   Krew — Landing page styles
   Warm paper. Heavy ink. One Spark. Stamps and dashes.
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg-page);
  color: var(--fg-1);
  font-family: var(--font-sans);
  overflow-x: hidden;
}
img { max-width: 100%; display: block; }
button { font-family: inherit; cursor: pointer; }

/* ---------- grain paper ---------- */
.paper-grain::before {
  content: "";
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 1;
  opacity: 0.035;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240' viewBox='0 0 240 240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='3'/><feColorMatrix values='0 0 0 0 0.1  0 0 0 0 0.1  0 0 0 0 0.1  0 0 0 1 0'/></filter><rect width='240' height='240' filter='url(%23n)'/></svg>");
}

/* ---------- reusable layout ---------- */
.container {
  width: min(1240px, 100% - 48px);
  margin-inline: auto;
  position: relative;
  z-index: 2;
}
.eyebrow-row {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: var(--fs-12);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  font-weight: 700;
  color: var(--fg-3);
}
.eyebrow-row .dot { width: 6px; height: 6px; background: var(--accent); border-radius: 50%; box-shadow: 0 0 0 4px var(--accent-soft);}
.hand-note { font-family: var(--font-hand); font-weight: 600; color: var(--accent); font-size: var(--fs-24); line-height: 1; }

/* ---------- navigation ---------- */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  backdrop-filter: blur(8px);
  background: color-mix(in oklch, var(--bg-page) 82%, transparent);
  border-bottom: 1px solid var(--border-hair);
}
.nav-inner {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 0;
  gap: 24px;
}

.nav-logo {
  display: inline-flex; align-items: center; gap: 14px;
  text-decoration: none; color: var(--fg-1);
}
.nav-logo img { height: 28px; }

/* Flagship eyebrow pill — centered between logo and nav links */
.hero-flagship { margin-inline: 0; margin-bottom: 4px; }
.nav-flagship {
  margin-inline: auto;
  display: inline-flex; align-items: center; gap: 10px;
  padding: 7px 14px 7px 12px;
  border: 1px solid var(--border-soft);
  border-radius: var(--r-pill);
  background: var(--bg-surface);
  font-family: var(--font-sans);
  font-size: var(--fs-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps, 0.14em);
  text-transform: uppercase;
  color: var(--fg-1);
  white-space: nowrap;
  transition: border-color var(--dur-2) var(--ease-out),
              background var(--dur-2) var(--ease-out);
}
.nav-flagship::before {
  content: "";
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 5px var(--accent-soft);
  flex: none;
}
.nav-logo:hover .nav-flagship {
  border-color: var(--border-strong, var(--border-soft));
  background: var(--bg-raised);
}
@media (max-width: 960px) { .nav-flagship { display: none; } }
.nav-links { display: flex; align-items: center; gap: 28px; }
/* Mobile-only nav controls + sheet are hidden on desktop. The
   ≤720px media query at the bottom of this file flips them on
   and hides .nav-links. */
.nav-mobile { display: none; }
.nav-sheet { display: none; }
.nav-scrim { display: none; }
/* Mobile-only "How It Works" vertical step list — hidden by default,
   shown by the ≤720px media query at the bottom of this file. */
.how-mobile-steps { display: none; }
.nav-links a {
  text-decoration: none; color: var(--fg-2); font-size: var(--fs-14); font-weight: 600;
  letter-spacing: 0.01em;
  position: relative;
}
.nav-links a:hover { color: var(--accent); }
.nav-links a.underline-on-hover::after {
  content: ""; position: absolute; left: 0; right: 100%; bottom: -6px; height: 2px; background: var(--accent);
  transition: right var(--dur-2) var(--ease-out);
}
.nav-links a.underline-on-hover:hover::after { right: 0; }

/* ---------- buttons ---------- */
.btn {
  --btn-bg: var(--krew-ink);
  --btn-fg: var(--krew-grain);
  display: inline-flex; align-items: center; gap: 10px;
  padding: 12px 18px;
  background: var(--btn-bg); color: var(--btn-fg);
  border: 1px solid var(--krew-ink);
  border-radius: var(--r-1);
  font-weight: 800;
  font-size: var(--fs-14);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  box-shadow: var(--shadow-ink);
  transition: transform var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out), background var(--dur-2);
  text-decoration: none;
  position: relative;
  overflow: hidden;
}
.btn:hover { transform: translate(-1px, -1px); box-shadow: 4px 4px 0 var(--krew-ink); }
.btn:active { transform: translate(2px, 2px); box-shadow: 0 0 0 var(--krew-ink); }
.btn.spark { --btn-bg: var(--accent); --btn-fg: var(--krew-grain-pale); border-color: var(--krew-ink); box-shadow: var(--shadow-ink); }
.btn.spark:hover { box-shadow: 4px 4px 0 var(--krew-ink); background: var(--krew-spark-ink); color: var(--krew-ink); }
/* Nav spark button uses INVERTED colors: black text by default, lightest
   tan on hover — opposite of the hero/waitlist spark buttons. The
   nav-links cascade also tries to set color on hover, so pin both states. */
.nav-links a.btn.spark { color: var(--krew-ink); }
.nav-links a.btn.spark:hover { color: var(--krew-grain-pale); }
.btn.ghost { --btn-bg: transparent; --btn-fg: var(--krew-ink); box-shadow: none; }
.btn.ghost:hover { background: var(--krew-ink); color: var(--krew-grain); box-shadow: none; transform: none; }

.link-arrow {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--fg-1); text-decoration: none; font-weight: 700;
  border-bottom: 1px dashed var(--border-soft);
  padding-bottom: 2px;
}
.link-arrow:hover { color: var(--accent); border-bottom-color: var(--accent); }
.link-arrow svg { transition: transform var(--dur-2) var(--ease-out); }
.link-arrow:hover svg { transform: translateX(4px); }

/* ---------- stamp cards ---------- */
.stamp {
  background: var(--bg-raised);
  border: 1px solid var(--krew-ink);
  border-radius: var(--r-3);
  box-shadow: var(--shadow-ink);
}
.stamp.spark-shadow { box-shadow: var(--shadow-spark); }
.stamp.paper { background: var(--bg-surface); }

/* ---------- HERO ---------- */
.hero {
  position: relative;
  padding: 72px 0 120px;
  overflow: hidden;
}
.hero-grid {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: 96px;
  align-items: center;
  padding-left: 24px;
}
@media (max-width: 880px) { .hero-grid { grid-template-columns: 1fr; gap: 48px; } }

/* On narrow viewports the hero stacks (copy on top, mock below). Centering
   the grid in the available flex space pushes the top of the stacked block
   ABOVE the nav-clearance zone — clipping the mockups behind the fixed nav.
   Anchor to top instead so the nav padding stays inviolable. */
/* Belt-and-suspenders: regardless of breakpoint, when the rendered mock
   is taller than the available stage row, anchoring the grid to start
   prevents the overflow from spilling UPWARD behind the fixed nav.
   This applies at any viewport where the stage is height-constrained. */
@media (max-height: 720px) {
  .hero-stage .container { align-items: flex-start; }
  .hero-stage .hero-grid { align-items: start; }
}

@media (max-width: 900px) {
  .hero-stage .container { align-items: flex-start; }
  .hero-stage .hero-grid { align-items: start; }
}

.hero h1 {
  font-size: clamp(38px, 5.2vw, 76px);
  line-height: 1.02;
  letter-spacing: -0.035em;
  font-weight: 900;
  margin: 14px 0 0;
  color: var(--fg-1);
  padding-bottom: 0;
}
/* Word mask: generous clip so no glyphs are ever chopped */
.hero h1 .word {
  display: inline-block;
  line-height: 1.02;
  vertical-align: top;
}
.hero h1 .word > span {
  display: inline-block;
}
.hero h1 .spark-word > span { color: var(--accent); }
@keyframes wordUp { to { transform: translateY(0); } }

.hero .strike { position: relative; display: inline-block; }
.hero .strike::after {
  content: "";
  position: absolute; left: -4%; right: -4%; top: 55%; height: 6px;
  background: var(--accent);
  transform: scaleX(0); transform-origin: left center;
  animation: strike 600ms 700ms var(--ease-spark) forwards;
  border-radius: 2px;
}
@keyframes strike { to { transform: scaleX(1); } }

/* Hand-drawn underline accent — sits below text, not through it */
.hand-underline {
  position: relative; display: inline-block;
  font-weight: 700;
}
.hand-underline::after {
  content: "";
  position: absolute; left: -2%; right: -2%;
  bottom: -6px; height: 10px;
  background: transparent;
  border-bottom: 3px solid var(--accent);
  border-radius: 50%;
  transform: scaleX(0); transform-origin: left center;
  animation: underline 700ms 700ms var(--ease-spark) forwards;
}
@keyframes underline { to { transform: scaleX(1); } }

.hero-lead {
  margin-top: 24px;
  font-size: var(--fs-18);
  line-height: 1.48;
  color: var(--fg-2);
  max-width: 440px;
  text-wrap: balance;
}
.hero-ctas { margin-top: 20px; display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.hero-tag {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 6px 12px 6px 8px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-pill);
  font-size: var(--fs-12);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--fg-2);
  background: var(--bg-surface);
}
.hero-tag .pulse {
  width: 8px; height: 8px; border-radius: 50%; background: var(--krew-safe);
  box-shadow: 0 0 0 0 rgba(63,110,74,0.6);
  animation: pulse 2s infinite;
}
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(63,110,74,0.5); }
  70% { box-shadow: 0 0 0 10px rgba(63,110,74,0); }
  100% { box-shadow: 0 0 0 0 rgba(63,110,74,0); }
}

/* Hero right — email mockup */
.hero-mock {
  position: relative;
  perspective: 1500px;
  padding-bottom: 12px;
  /* Drift the whole mock column right as we cross from email → SMS
     so the SMS phone (intrinsically narrower than the email card)
     doesn't end up too far left of the grid column center. */
  transform: translateX(calc(50px * var(--p, 0)));
  transition: transform 60ms linear;
  /* CRITICAL: keep the mock column bounded to the grid row height.
     Without this, the mock-stack + switcher-row stack could exceed
     the flex-centered grid, causing the mock to overflow UPWARD
     and slip behind the fixed nav. `min-height: 0` lets flex
     children actually shrink. */
  min-height: 0;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: clamp(16px, 3vh, 48px);
}
.hero-switcher-row {
  /* Counter the parent .hero-mock translate so the Email/SMS toggle
     stays anchored while the mockups drift right. */
  transform: translateX(calc(-50px * var(--p, 0)));
  transition: transform 60ms linear;
  /* Was margin-top: 88px + padding-bottom: 88px — pushed the mock
     column ~176px past the grid row, forcing overflow above the
     nav. Both removed; the parent `.hero-mock` now spaces items. */
  margin-top: 10px;
  padding-bottom: 0;
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: nowrap;
}
/* ============================================================
   Hero scroll-pin stage
   The pin is tall enough to require ~1.2 viewports of scroll to
   complete the email→sms transition. The hero itself is sticky
   100vh, so everything stays in view. Progress is fed to CSS
   via `--p` on .hero-stage, 0 = full email, 1 = full sms.
   ============================================================ */
.hero-pin {
  position: relative;
  height: 220vh;
}
.hero-stage {
  position: sticky;
  top: 0;
  min-height: 100vh;
  max-height: 100vh;
  display: flex;
  flex-direction: column;
  /* Anchor from TOP (flex-start) — critical: `center` allows content
     taller than available space to overflow UPWARD, clipping behind
     the nav. Anchoring from top means the nav clearance is inviolable
     and any overflow spills to the bottom instead. On short viewports
     the mock-stack scales down via transform so overflow is bounded.
     On tall viewports the stage has extra room at bottom which the
     bottom padding absorbs. */
  justify-content: flex-start;
  padding-top: clamp(88px, 9vh, 120px);
  padding-bottom: clamp(56px, 7vh, 80px);
  box-sizing: border-box;
  --p: 0;
  overflow: hidden;
}
.hero-stage .container {
  width: 100%;
  /* Fill remaining vertical space and flex-center the grid within it.
     This is what centers the hero visually between the nav and the
     marquee — but ONLY when content fits; when it doesn't, the
     margin-block collapse on .mock-stack pulls it back up so the grid
     doesn't overflow the reserved space. */
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
}
.hero-stage .hero-grid {
  width: 100%;
  align-items: center;
  /* Grid rows must not exceed the container's height, otherwise the
     mock column overflows upward and clips behind the fixed nav.
     `min-height: 0` lets the grid shrink; its row height is the
     container's flex height. */
  min-height: 0;
  max-height: 100%;
}
.hero-stage .hero-grid > .hero-copy,
.hero-stage .hero-grid > .hero-mock {
  /* Same rule for grid-column items — prevents auto-row expansion
     when one child is intrinsically taller than the available space. */
  min-height: 0;
  max-height: 100%;
}

/* --- Text cross-fade ---------------------------------- */
.hero-text-stack {
  /* CSS-grid overlay: both variants occupy row 1, column 1 of a single
     1×1 grid. The taller variant sets the row height naturally — no
     manual breakpoints, no overflow into the CTAs. The variants stack
     visually via grid-area collision; opacity drives the cross-fade. */
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto;
  margin: 10px 0 12px;
}
.hero-text-stack .hero-text {
  grid-area: 1 / 1;
  transition: none;
  will-change: opacity, transform;
}
/* Email text: full at p=0, gone by p=0.6. Overlaps with SMS 0.4→0.6. */
.hero-text-stack .hero-text-email {
  opacity: calc(1.5 - var(--p) * 2.5);
  transform: translateY(calc(var(--p) * -24px));
  pointer-events: auto;
}
/* SMS text: starts appearing at p=0.4, full by p=0.8. */
.hero-text-stack .hero-text-sms {
  opacity: calc(var(--p) * 2.5 - 1);
  transform: translateY(calc(24px - var(--p) * 24px));
  pointer-events: none;
}
.hero-stage[style*="--p: 1"] .hero-text-sms,
.hero-stage[style*="--p:1"]  .hero-text-sms { pointer-events: auto; }

/* --- Mock stack --------------------------------------- */
/*
  Scale factor tied to viewport height so the stack never exceeds
  the space between the fixed nav and the bottom of the viewport.
  At 900+ vh the stack is its full 460px. On shorter windows it
  shrinks proportionally without ever overflowing the nav.
*/
.mock-stack {
  position: relative;
  /* Baseline footprint — scaled down on short viewports via transform.
     Scale must be unitless. We compute (100vh − 280px) / 520px; per
     CSS spec, <length> / <length> resolves to a unitless number. */
  /* Floor lowered: on short viewports we need to shrink the mock more
     aggressively to keep it inside the available stage height (stage − 88
     top pad − 56 bottom pad). At 600vh the available space is ~456px, so
     a 460px mock at 0.82 scale (377px) plus the 84px switcher row = 461px,
     which overflows. Allowing 0.65 fits it cleanly. */
  /* Default unitless scale — JS sets the real value from Hero's
     useEffect (window resize + initial mount). We keep a fallback of 1
     here so SSR / no-JS still renders something reasonable. */
  --mock-scale: 1;
  width: 460px;
  height: 460px;
  max-width: 100%;
  /* Shrink the WHOLE rendered thing, cards and all, so it always fits
     inside (stage_height − nav_clearance − marquee_clearance).
     transform-origin: top right keeps the mock pinned to the right edge
     of the grid column when it shrinks (rather than drifting toward the
     visual center, which leaves an awkward gap on the right). */
  transform: scale(var(--mock-scale));
  transform-origin: top right;
  margin-inline: auto;
  /* Collapse the reserved box to the scaled size so the grid column
     doesn't keep the unscaled height. */
  margin-block: calc((var(--mock-scale) - 1) * 230px);
  transform-style: preserve-3d;
  perspective: 1600px;
  overflow: visible;
}
.mock-stack .mock-card {
  position: absolute;
  top: 50%;
  left: 50%;
  /* Scale every card together so transforms stay proportional */
  --card-scale: var(--mock-scale);
  transform-origin: center center;
  will-change: transform, opacity, filter;
}
.mock-stack .mock-email > .email-card { width: 420px; }
.mock-stack .mock-sms > .mock-stack .mock-sms > .sms-phone { transform: none; }

/* ---- Email card: interpolates from FRONT → BACK as p: 0 → 1 ---- */
.mock-stack .mock-email {
  /* z-index flips mid-transition */
  z-index: calc(3 - var(--p) * 2);
  opacity: calc(1 - var(--p) * 0.45);
  filter: saturate(calc(1 - var(--p) * 0.2));
  transform:
    translate(-50%, -50%)
    translate3d(
      calc(var(--p) * -180px),
      calc(var(--p) * -20px),
      calc(60px + var(--p) * -180px)
    )
    rotateX(calc(6deg - var(--p) * 2deg))
    rotateY(calc(-10deg + var(--p) * 4deg))
    rotate(calc(1.5deg - var(--p) * 6.5deg))
    scale(calc(1 + var(--p) * 0.05));
}

/* ---- SMS phone: interpolates from BACK → FRONT as p: 0 → 1 ---- */
.mock-stack .mock-sms {
  z-index: calc(1 + var(--p) * 2);
  opacity: calc(0.55 + var(--p) * 0.45);
  filter: saturate(calc(0.8 + var(--p) * 0.2));
  transform:
    translate(-50%, -50%)
    translate3d(
      calc(-160px + var(--p) * 160px),
      calc(-20px + var(--p) * 20px),
      calc(-120px + var(--p) * 180px)
    )
    rotateX(calc(4deg + var(--p) * 2deg))
    rotateY(calc(-6deg - var(--p) * 4deg))
    rotate(calc(-5deg + var(--p) * 6.5deg))
    scale(calc(0.95 + var(--p) * 0.05));
}

/* Prevent pointer events on the card that's currently "in back" */
.hero-stage[style*="--p: 0"] .mock-sms,
.hero-stage[style*="--p:0"]  .mock-sms,
.hero-stage:not([style]) .mock-sms { pointer-events: none; }
.hero-stage[style*="--p: 1"] .mock-email,
.hero-stage[style*="--p:1"]  .mock-email { pointer-events: none; }


/* Phone: keep a constant size. No 3D perspective (no size change on rotate),
   subtle planar float only. */
.mock-stack.is-phone {
  transform: rotate(1.5deg);
  animation: phoneFloat 7s ease-in-out infinite alternate;
}
@keyframes phoneFloat {
  from { transform: rotate(1.5deg) translateY(0); }
  to   { transform: rotate(1.5deg) translateY(-10px); }
}

/* Mobile-only mock variants — rendered alongside desktop mocks but
   only shown inside the `(max-width: 720px)` media query below.
   Hidden by default so desktop never sees them. */
.email-card-mobile,
.sms-phone-mobile { display: none; }

.email-card {
  background: var(--bg-surface);
  border: 1px solid var(--krew-ink);
  border-radius: 10px;
  box-shadow: 6px 6px 0 var(--krew-ink), var(--shadow-3);
  overflow: hidden;
  transform-origin: top left;
}
.email-header {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border-hair);
  background: var(--krew-grain-pale);
  font-size: var(--fs-12);
  color: var(--fg-3);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.email-header .dots { display: flex; gap: 6px; }
.email-header .dots i { width: 10px; height: 10px; border-radius: 50%; background: var(--border-soft); display: inline-block; }
.email-header .dots i:nth-child(1) { background: #E06C5E; }
.email-header .dots i:nth-child(2) { background: #E8B13C; }
.email-header .dots i:nth-child(3) { background: #7FB071; }

.email-meta { padding: 20px 24px 8px; }
.email-meta .from {
  display: flex; align-items: center; gap: 12px;
}
/* Avatar — holds Krew circle icon */
.avatar-k {
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--accent);
  display: inline-flex; align-items: center; justify-content: center;
  overflow: hidden;
  border: 1.5px solid var(--krew-ink);
  flex-shrink: 0;
}
.avatar-k img { width: 100%; height: 100%; object-fit: cover; display: block; }
.email-meta .who { display: flex; flex-direction: column; line-height: 1.2; }
.email-meta .who strong { font-size: var(--fs-15); font-weight: 800; color: var(--fg-1); }
.email-meta .who span { font-size: var(--fs-12); color: var(--fg-3); }
.email-meta .time { margin-left: auto; font-size: var(--fs-12); color: var(--fg-4); }

.email-subject {
  padding: 16px 24px 6px;
  font-size: var(--fs-20);
  font-weight: 800;
  letter-spacing: -0.01em;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  line-height: 1.25;
}
.subject-tag {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  background: var(--krew-alert);
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  border-radius: var(--r-pill);
  flex-shrink: 0;
}
.email-body {
  padding: 10px 24px 16px;
  font-size: var(--fs-15);
  color: var(--fg-2);
  line-height: 1.55;
}

/* Email brief — Krew signature block, refreshed */
.email-brief {
  margin: 0 24px 22px;
  padding: 4px 0 0;
  border-top: 1px solid var(--krew-ink);
  position: relative;
}
.email-brief::before {
  content: "Krew · summary";
  position: absolute; top: -9px; left: 0;
  padding: 2px 10px;
  background: var(--krew-ink);
  color: var(--krew-grain);
  font-size: 10px; font-weight: 800;
  letter-spacing: 0.12em; text-transform: uppercase;
  border-radius: 2px;
}
/* Email brief — elevated reveal (all-at-once lift, then stagger on children) */
.brief-row {
  display: grid;
  grid-template-columns: 14px 1fr;
  gap: 12px;
  padding: 14px 0 12px;
  border-bottom: 1px dashed var(--border-soft);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 520ms var(--ease-out), transform 520ms var(--ease-out);
  transition-delay: var(--d, 0ms);
}
.email-brief.ready .brief-row { opacity: 1; transform: translateY(0); }
.email-brief { animation: briefLift 500ms var(--ease-out); }
@keyframes briefLift { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.brief-row:last-child { border-bottom: 0; padding-bottom: 4px; }
.brief-dot {
  width: 10px; height: 10px; border-radius: 50%;
  margin-top: 6px;
  position: relative;
}
.brief-row.risk .brief-dot { background: var(--krew-alert); box-shadow: 0 0 0 3px rgba(184,55,28,0.14); }
.brief-row.warn .brief-dot { background: #D98B1C; box-shadow: 0 0 0 3px rgba(217,139,28,0.14); }
.brief-row.note .brief-dot { background: var(--krew-safe); box-shadow: 0 0 0 3px rgba(63,110,74,0.14); }
.brief-title {
  font-size: var(--fs-14);
  font-weight: 700;
  color: var(--fg-1);
  line-height: 1.4;
}
.brief-meta {
  margin-top: 4px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.04em;
  color: var(--fg-4);
  text-transform: uppercase;
  font-weight: 600;
}

/* Findings block — Krew signature */
.findings {
  margin: 4px 24px 22px;
  border: 1px solid var(--krew-ink);
  border-radius: var(--r-3);
  background: var(--krew-grain-pale);
  overflow: hidden;
}
.findings-head {
  padding: 10px 14px;
  background: var(--krew-ink);
  color: var(--krew-grain);
  font-size: var(--fs-12);
  font-weight: 800;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  display: flex; align-items: center; gap: 8px;
}
.findings-head .mark { color: var(--accent); }
.finding {
  padding: 12px 14px;
  border-top: 1px dashed var(--border-soft);
  display: grid;
  grid-template-columns: 10px 1fr;
  gap: 10px;
}
.finding:first-of-type { border-top: 0; }
.finding .sev {
  width: 10px; height: 10px; border-radius: 50%; margin-top: 6px;
  background: var(--krew-alert);
  box-shadow: 0 0 0 3px rgba(184, 55, 28, 0.18);
}
.finding .sev.warn { background: #D98B1C; box-shadow: 0 0 0 3px rgba(217, 139, 28, 0.18); }
.finding .sev.ok { background: var(--krew-safe); box-shadow: 0 0 0 3px rgba(63, 110, 74, 0.18); }
.finding h5 { margin: 0 0 2px; font-size: var(--fs-14); font-weight: 800; }
.finding p { margin: 0; font-size: var(--fs-13); color: var(--fg-3); }
.finding .src {
  margin-top: 6px; font-size: 11px; letter-spacing: 0.04em; color: var(--fg-4);
  text-transform: uppercase; font-weight: 700;
}

.sig-line {
  padding: 0 24px 20px;
  font-family: var(--font-hand);
  font-size: 28px;
  color: var(--accent);
  line-height: 1.1;
}
.sig-line em { font-style: normal; color: var(--fg-3); font-family: var(--font-sans); font-size: 10px; display: block; margin-top: 14px; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 700; }

/* Subtle CTA in the email card — black outline, warm-beige interior */
.email-cta-row {
  padding: 4px 24px 16px;
}
.email-cta-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-1);
  background: var(--krew-grain-warm);
  border: 1.25px solid var(--krew-ink);
  border-radius: 4px;
  cursor: pointer;
  transition: transform 120ms var(--ease-out), box-shadow 120ms var(--ease-out);
}
.email-cta-btn:hover {
  transform: translate(-1px, -1px);
  box-shadow: 2px 2px 0 var(--krew-ink);
}

/* Ghost schedule card behind — VERTICAL prelim list */
.ghost-card {
  position: absolute;
  top: -22px; left: -72px;
  width: 320px;
  height: 480px;
  background: var(--bg-raised);
  border: 1px solid var(--krew-ink);
  border-radius: 10px;
  box-shadow: 5px 5px 0 var(--krew-ink);
  opacity: 0.78;
  z-index: -1;
  transform: rotate(-5deg);
  overflow: hidden;
}
.schedule-ghost { padding: 18px 20px; }
.sg-head {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border-hair);
}
.sg-label {
  font-size: 10px; letter-spacing: 0.14em; font-weight: 800;
  color: var(--fg-4); text-transform: uppercase;
}
.sg-badge {
  font-size: 9px; letter-spacing: 0.1em; font-weight: 800;
  color: var(--accent);
  padding: 3px 8px;
  border: 1px solid var(--accent);
  border-radius: var(--r-pill);
  text-transform: uppercase;
}
/* Vertical list of prelim rows */
.sg-list { display: flex; flex-direction: column; gap: 8px; }
.sg-row {
  display: grid; grid-template-columns: 44px 1fr; gap: 10px; align-items: center;
}
.sg-dayslot { display: flex; flex-direction: column; align-items: flex-end; line-height: 1; }
.sg-dayname { font-size: 10px; letter-spacing: 0.12em; font-weight: 800; color: var(--fg-3); text-transform: uppercase; }
.sg-date { font-family: var(--font-mono); font-size: 10px; color: var(--fg-4); margin-top: 2px; font-weight: 700; }
.sg-bar {
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px 10px;
  border: 1px solid rgba(10,10,12,0.35);
  border-radius: 3px;
  font-size: 9.5px; font-weight: 800; letter-spacing: 0.08em;
  color: rgba(10,10,12,0.78); text-transform: uppercase;
}
.sg-pages { font-family: var(--font-mono); }

/* Sticky tape */
.tape {
  position: absolute;
  width: 92px; height: 22px;
  background: rgba(196, 167, 122, 0.55);
  border: 1px solid rgba(107, 58, 31, 0.25);
  transform: rotate(-5deg);
  top: -10px; left: 24px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.08);
}
.tape.r { left: auto; right: 18px; transform: rotate(6deg); }

/* Hero email/sms switcher */
.hero-switcher {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px;
  background: var(--bg-surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--r-pill);
  position: relative;
}
.hero-switcher button {
  display: inline-flex; align-items: center; gap: 8px;
  background: transparent; border: 0;
  padding: 8px 14px;
  font-size: var(--fs-13);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--fg-3);
  border-radius: var(--r-pill);
  transition: all var(--dur-2);
}
.hero-switcher button.active {
  background: var(--krew-ink); color: var(--krew-grain);
  box-shadow: 2px 2px 0 var(--accent);
}
.hero-switcher .dot-mini { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.hero-switcher .hint {
  /* Outside the pill, far enough to never touch */
  position: absolute;
  left: calc(100% + 18px);
  top: 50%;
  transform: translateY(-50%) rotate(-4deg);
  color: var(--accent);
  font-size: 22px;
  line-height: 1;
  white-space: nowrap;
  padding-left: 0;
}

/* ======================================================
   SMS phone — Krew beige/paper reskin (matches email card)
   2D, heavy ink, warm grain. No iOS blue.
   ====================================================== */
.sms-phone {
  width: 270px;
  height: 410px;
  display: flex; flex-direction: column;
  background: var(--bg-surface);
  border: 1px solid var(--krew-ink);
  border-radius: 14px;
  box-shadow: 6px 6px 0 var(--krew-ink), var(--shadow-3);
  overflow: hidden;
  color: var(--fg-1);
  position: relative;
  font-family: var(--font-sans);
  transform-origin: top left;
}

/* Header bar — mimics email-header cap */
.sms-header {
  display: grid;
  grid-template-columns: 24px 1fr 24px;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border-hair);
  background: var(--krew-grain-pale);
}
.sms-back {
  font-size: 18px;
  font-weight: 800;
  color: var(--accent);
  line-height: 1;
}
.sms-video {
  font-size: 13px;
  color: var(--fg-3);
  text-align: right;
  line-height: 1;
}
.sms-who {
  display: flex; align-items: center; gap: 8px;
  justify-content: center;
}
.sms-who span {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: var(--fg-1);
}
.sms-who .sms-avatar {
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent);
  overflow: hidden;
  border: 1px solid var(--krew-ink);
  flex-shrink: 0;
}
.sms-who .sms-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Conversation pane */
.sms-thread {
  padding: 12px 12px 10px;
  display: flex; flex-direction: column; gap: 7px;
  flex: 1;
  overflow: hidden;
  background: var(--bg-surface);
  /* Anchor messages to the top of the thread */
  justify-content: flex-start;
}
/* Ripple-up: every bubble slides in from below as it appears */
.sms-thread > .sms-bubble,
.sms-thread > .sms-daystamp {
  animation: bubbleRise 360ms var(--ease-out) both;
}
@keyframes bubbleRise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
/* Prior history doesn't animate on every render */
.sms-thread > .sms-prior { animation: none; }

/* Rewind state — when scrolling back up, soften everything so the
   reverse-playback (bubbles peeling off, text erasing) reads as a graceful
   reset instead of a hard cut. */
.sms-thread.sms-rewind > .sms-bubble,
.sms-thread.sms-rewind > .sms-daystamp {
  animation: none;
  transition: opacity 320ms ease, transform 320ms ease;
}
.sms-thread.sms-rewind > .sms-bubble:last-child {
  opacity: 0.4;
  transform: translateY(4px);
}

/* Day stamp — small uppercase divider, just like email meta */
.sms-daystamp {
  align-self: center;
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-4);
  padding: 6px 0 2px;
}
.sms-daystamp + .sms-daystamp,
.sms-thread > .sms-daystamp:not(:first-child) {
  margin-top: 4px;
}

/* Bubbles — paper/ink, not glossy */
.sms-bubble {
  max-width: 84%;
  padding: 8px 12px;
  border-radius: 10px;
  font-size: 13.5px;
  line-height: 1.42;
  white-space: pre-wrap;
  word-wrap: break-word;
  border: 1px solid var(--krew-ink);
}
/* Outgoing — Krew replies, pale grain paper */
.sms-out {
  align-self: flex-end;
  background: var(--krew-grain-pale);
  color: var(--fg-1);
  border-bottom-right-radius: 3px;
}
/* Incoming — customer, brand orange */
.sms-in {
  align-self: flex-start;
  background: var(--accent);
  color: #fff;
  border-bottom-left-radius: 3px;
}
/* Prior messages — muted so today's exchange pops */
.sms-prior {
  opacity: 0.55;
}
.sms-bubble.sms-out.sms-prior { background: var(--krew-grain-pale); color: var(--fg-1); }
/* Prior incoming (user) bubbles: lighter orange + dark text so they read at low opacity */
.sms-bubble.sms-in.sms-prior {
  background: color-mix(in oklch, var(--accent) 22%, var(--bg-surface));
  color: var(--fg-1);
  border-color: var(--krew-ink);
}

/* Typing indicator — matches the final Krew reply: warm beige bubble,
   thin orange outline, orange dots. */
.sms-bubble.sms-typing {
  padding: 9px 12px !important;
  background: var(--krew-grain-warm);
  color: var(--accent);
  border: 1px solid color-mix(in oklch, var(--accent) 60%, transparent);
  box-shadow: 2px 2px 0 color-mix(in oklch, var(--accent) 30%, transparent);
}
.typing-dots { display: inline-flex; gap: 3px; }
.typing-dots i {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent);
  animation: dots 1.1s infinite;
  display: inline-block;
}
.typing-dots i:nth-child(2) { animation-delay: 0.15s; }
.typing-dots i:nth-child(3) { animation-delay: 0.3s; }
@keyframes dots {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
  30% { transform: translateY(-3px); opacity: 1; }
}

/* The fully-sourced Krew reply is long-form — render it on warm grain for readability,
   with a thin orange outline to distinguish it from the user's beige bubbles */
.sms-bubble.sms-reply {
  background: var(--krew-grain-warm);
  color: var(--fg-1);
  border: 1.5px solid var(--accent);
  box-shadow: 2px 2px 0 color-mix(in oklch, var(--accent) 30%, transparent);
}
.sms-bubble.sms-reply .reply-src { color: var(--fg-3); }

/* Reply lines cascade */
.sms-reply .reply-line {
  opacity: 0;
  transform: translateY(4px);
  animation: replyLineIn 360ms var(--ease-out) forwards;
}
@keyframes replyLineIn {
  to { opacity: 1; transform: translateY(0); }
}

/* Footer — subtle pill input, ink-on-paper */
.sms-footer {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px 12px;
  border-top: 1px solid var(--border-hair);
  background: var(--krew-grain-pale);
}
.sms-plus {
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--krew-grain-warm);
  border: 1px solid var(--krew-ink);
  color: var(--fg-1);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 800;
  line-height: 1;
}
.sms-input {
  flex: 1;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--krew-ink);
  background: var(--bg-surface);
  font-size: 11.5px;
  color: var(--fg-3);
  font-weight: 600;
}

/* Hero caption — sits BELOW the mock, never overlaps copy or pill */
.hero-caption {
  position: relative;
  margin-left: 12px;
  display: inline-block;
  color: var(--accent);
  font-size: 20px;
  line-height: 1;
  transform: rotate(-2deg);
  pointer-events: none;
  align-self: center;
}
.hero-caption svg { position: absolute; left: -60px; top: -14px; }

/* ---------- MARQUEE ---------- */
.marquee-prelude {
  text-align: center;
  font-family: var(--font-hand);
  font-size: 26px;
  line-height: 1;
  color: var(--fg-2);
  padding: 8px 0 36px;
}
.marquee {
  border-top: 1px solid var(--border-hair);
  border-bottom: 1px solid var(--border-hair);
  background: var(--krew-grain-warm);
  overflow: hidden;
  padding: 8px 0;
}
.marquee-track {
  display: flex; gap: 56px;
  white-space: nowrap;
  font-size: var(--fs-14);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--fg-3);
  will-change: transform;
}
.marquee-track span { display: inline-flex; align-items: center; gap: 14px; }
.marquee-track i { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }

/* ---------- SECTIONS ---------- */
.section { padding: 120px 0; position: relative; }
.section.tight { padding: 72px 0; }
.section-head {
  max-width: 880px;
  margin-bottom: 64px;
}
.section-head h2 {
  margin: 14px 0 0;
  font-size: clamp(36px, 4.6vw, 72px);
  line-height: 1.05;
  letter-spacing: -0.03em;
  font-weight: 900;
  text-wrap: balance;
}
@media (min-width: 1000px) {
  .section-head { max-width: 1000px; }
  .section-head h2 { font-size: clamp(44px, 4.2vw, 76px); }

  /* Cap pillar card width on wider screens — they were stretching to
     fill the container which made each card feel oversized. Lock to
     ~360px (their Claude-preview width) and center the group. */
  .pillars {
    max-width: 1140px;
    margin-inline: auto;
    grid-template-columns: repeat(3, minmax(0, 360px));
    justify-content: center;
  }

  /* How-It-Works visual: scale up on wider screens so the doc
     stack + overlays fill the larger stage proportionally. */
  .how-visual-stage { --how-zoom: 1.49; }
  .how-visual-stage { max-width: 1080px; height: 600px; }
}
.section-head p {
  margin-top: 20px;
  font-size: var(--fs-20);
  color: var(--fg-3);
  line-height: 1.5;
  max-width: 620px;
}

/* ---------- Pillars ---------- */
.pillars {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}
@media (max-width: 960px) { .pillars { grid-template-columns: minmax(0, 360px); justify-content: center; } }
.pillar {
  position: relative;
  padding: 28px 24px 26px;
  background: var(--bg-raised);
  border: 1px solid var(--krew-ink);
  border-radius: var(--r-3);
  box-shadow: var(--shadow-ink);
  transition: transform var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out);
  overflow: hidden;
}
.pillar:hover {
  transform: translate(-2px, -2px);
  box-shadow: 5px 5px 0 var(--accent);
}
.pillar .num {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--fg-4);
  text-transform: uppercase;
  font-weight: 700;
}
.pillar h3 {
  margin: 10px 0 14px;
  font-size: var(--fs-24);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.01em;
}
.pillar p { margin: 0; font-size: var(--fs-15); color: var(--fg-3); line-height: 1.55; }
.pillar .illustration {
  height: 140px;
  margin-bottom: 20px;
  border-radius: var(--r-2);
  border: 1px dashed var(--border-soft);
  background: var(--krew-grain-pale);
  position: relative;
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.pillar .illustration::after {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(circle at 70% 30%, rgba(255,84,5,0.06), transparent 60%);
}

/* ---------- HOW IT WORKS (big split) ---------- */
.how-grid {
  display: grid; grid-template-columns: 1fr 1.1fr; gap: 64px; align-items: center;
}
@media (max-width: 960px) { .how-grid { grid-template-columns: 1fr; } }
.how-steps { display: flex; flex-direction: column; gap: 16px; }
.step {
  display: grid;
  grid-template-columns: 44px 1fr;
  gap: 18px;
  padding: 18px 18px 18px 0;
  border-top: 1px dashed var(--border-soft);
  cursor: pointer;
  transition: background var(--dur-2);
}
.step:last-child { border-bottom: 1px dashed var(--border-soft); }
.step:hover { background: rgba(255,84,5,0.03); }
.step .badge {
  width: 36px; height: 36px;
  border-radius: 50%;
  border: 1.5px solid var(--krew-ink);
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 900; font-size: var(--fs-15);
  background: var(--bg-surface);
  transition: all var(--dur-2) var(--ease-out);
}
.step.active .badge { background: var(--accent); color: #fff; border-color: var(--krew-ink); transform: rotate(-8deg); }
.step h4 { margin: 4px 0 4px; font-size: var(--fs-20); font-weight: 800; letter-spacing: -0.01em; }
.step p { margin: 0; color: var(--fg-3); font-size: var(--fs-14); line-height: 1.55; }

/* ---------- HOW IT WORKS scroll-driven rail ---------- */
/* Default: show desktop header outside the pin, hide mobile-pinned
   duplicate. The ≤720px block at the bottom flips both. */
.how-section-head-mobile { display: none; }
.how-section-head-desktop { display: block; }
.how-section { padding: 140px 0; }
.how-scrolly { position: relative; align-items: start; }
.how-scrolly .how-steps {
  position: relative;
  padding-left: 24px;
}
.how-rail {
  position: absolute;
  left: 17px; top: 18px; bottom: 18px;
  width: 2px;
  background: var(--border-soft);
  border-radius: 2px;
  overflow: hidden;
}
.how-rail-fill {
  position: absolute; left: 0; top: 0; width: 100%;
  background: var(--accent);
  transition: height 180ms var(--ease-out);
}
.how-scrolly .step {
  grid-template-columns: 44px 1fr;
  opacity: 0.45;
  filter: blur(0);
  transition: opacity 300ms var(--ease-out);
  border-top: 0;
  padding: 22px 18px 22px 0;
}
.how-scrolly .step:first-child { padding-top: 0; }
.how-scrolly .step:last-child { border-bottom: 0; padding-bottom: 0; }
.how-scrolly .step.active { opacity: 1; }
.how-scrolly .step.done { opacity: 0.75; }
.how-scrolly .step.done .badge {
  background: var(--krew-safe); color: #fff; border-color: var(--krew-ink);
}
.how-scrolly .step .badge { transition: all 300ms var(--ease-spark); }
.how-scrolly .step.active .badge {
  background: var(--accent); color: #fff; border-color: var(--krew-ink);
  transform: rotate(-8deg) scale(1.06);
  box-shadow: 3px 3px 0 var(--krew-ink);
}

.how-preview-sticky {
  position: sticky;
  top: 120px;
}

/* ============================================================
   HOW IT WORKS — pin stage
   Progressive, Hero-style scroll-driven animation. The stage is
   position:sticky within a tall pin container; the visual stays
   centered while captions cross-fade underneath as scroll drives
   `phase`. Everything fits inside calc(100vh - nav).
   ============================================================ */
.how-pin { position: relative; }
.how-stage {
  position: sticky;
  top: 72px; /* clear the fixed nav */
  height: calc(100vh - 72px);
  min-height: 600px;
  display: flex;
  align-items: stretch;
  overflow: hidden;
  --phase: 0; --active: 0; --local: 0;
}
.how-stage-inner {
  width: 100%;
  display: grid;
  /* Was `auto 1fr auto` for a meta row that no longer exists, which
     left the visual flush with the top of the stage. Use uneven
     leading/trailing flex rows so the visual+captions block sits
     between top-of-viewport and dead-center. */
  grid-template-rows: 0.6fr auto auto 1.5fr;
  row-gap: 16px;
  padding: 16px 0 28px;
  position: relative;
  min-height: 0;
  height: 100%;
}
.how-stage-inner > .how-visual { grid-row: 2; }
.how-stage-inner > .how-captions { grid-row: 3; }

/* Top meta row — counter + dot rail on one horizontal strip */
.how-meta {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.how-counter {
  display: inline-flex; align-items: baseline; gap: 4px;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 11px; font-weight: 700; letter-spacing: 0.12em;
  color: var(--fg-3);
  padding: 6px 10px;
  border: 1px solid var(--krew-ink);
  background: var(--bg-raised);
  border-radius: 999px;
  box-shadow: 2px 2px 0 var(--krew-ink);
}
.how-counter-num { color: var(--accent); font-size: 13px; }
.how-counter-sep { color: var(--fg-4); }

.how-dots { display: flex; gap: 8px; align-items: center; }
.how-dot {
  position: relative;
  width: 56px; height: 6px;
  background: var(--border-soft);
  border-radius: 999px;
  overflow: hidden;
}
.how-dot-fill {
  position: absolute; inset: 0 auto 0 0;
  background: var(--accent);
  transition: width 80ms linear;
}

/* Pinned visual — flex-grow middle row, clips to available height */
.how-visual {
  min-height: 0;
  display: flex; align-items: center; justify-content: center;
  overflow: visible;
}
.how-visual-stage {
  position: relative;
  width: 100%;
  max-width: 900px;
  height: 520px;
  margin: 0 auto;
  /* Scale everything inside up so docs + overlays fill the stage
     without touching every individual size rule. */
  --how-zoom: 1.24;
}
.how-visual-stage > * {
  transform-origin: center center;
}
.how-visual-stage .how-doc,
.how-visual-stage .how-overlay {
  zoom: var(--how-zoom);
}

/* Caption — compact block below the visual, centered. Max-width
   tightened so the title+body reads as a square-ish block, not a
   wide horizontal stripe. */
.how-captions {
  position: relative;
  height: 104px;
  max-width: 380px;
  /* Pushed down ~15% of the captions block height to give the visual
     stage above more breathing room before the text begins. */
  margin: 16px auto 0;
  text-align: center;
  width: 100%;
}
.how-caption {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity 320ms var(--ease-out), transform 320ms var(--ease-out);
}
.how-caption.is-active {
  opacity: 1; transform: translateY(0); pointer-events: auto;
}
.how-caption.is-past { opacity: 0; transform: translateY(-8px); }
.how-caption-step {
  display: inline-flex; align-items: baseline; gap: 4px;
  align-self: center;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 11px; font-weight: 700; letter-spacing: 0.12em;
  color: var(--fg-3);
  padding: 6px 10px;
  border: 1px solid var(--krew-ink);
  background: var(--bg-raised);
  border-radius: 999px;
  box-shadow: 2px 2px 0 var(--krew-ink);
  margin-bottom: 14px;
}
.how-caption-step-num { color: var(--accent); font-size: 13px; }
.how-caption-step-sep { color: var(--fg-4); }
.how-caption-title {
  margin: 0;
  font-size: clamp(22px, 2.6vw, 30px);
  font-weight: 800; letter-spacing: -0.015em; line-height: 1.15;
  color: var(--fg-1);
  text-wrap: balance;
}
.how-caption-body {
  margin: 0;
  max-width: 60ch;
  font-size: var(--fs-15);
  line-height: 1.45;
  color: var(--fg-2);
  text-wrap: pretty;
}

/* Mobile-only line break — used inside body copy to force balanced
   wraps on narrow viewports without affecting desktop. <br> with
   display:none does NOT produce a break, so on desktop these are
   inert; the mobile media query below switches them on. */
.m-only { display: none; }
@media (max-width: 720px) {
  .m-only { display: inline; }
}

/* Mobile-only scroll-margin for nav anchors. The mobile nav is a
   floating pill that sits at top: 60px + safe-area-inset-top, with
   ~50-56px of pill height. So an anchored section needs ~96px of
   scroll-margin-top to land its eyebrow visibly below the pill —
   not tucked behind it. Scoped to ≤720px so desktop's anchor jumps
   stay at their default position. */
@media (max-width: 720px) {
  #capabilities,
  #team,
  #faq,
  #waitlist {
    scroll-margin-top: calc(96px + env(safe-area-inset-top, 0px));
  }
  /* #how is special: its content lives inside a position:sticky
     stage that sticks at top:64px once its pin container scrolls
     past. The stage also has 64px of inner top padding before the
     eyebrow, so the eyebrow rests at viewport y ≈ 128px once sticky.
     The section itself adds 50px of top padding before the pin, so
     anchor-scrolling needs to land the section top at viewport top
     (minus a small breathing inset) — that way the pin's top crosses
     the 64px sticky threshold immediately and the eyebrow lands at
     the natural sticky position rather than 50px lower (unstuck). */
  #how {
    scroll-margin-top: 14px;
  }
}

@media (max-height: 780px) {
  .how-stage-inner { padding: 8px 0 16px; row-gap: 10px; }
  .how-visual-stage { max-height: 280px; }
  .how-captions { height: 108px; }
  .how-caption-title { font-size: 22px; }
  .how-caption-body { font-size: 14px; line-height: 1.4; }
}
@media (max-width: 780px) {
  .how-stage { min-height: 560px; }
}

/* How preview — stacked doc pages */
.how-preview {
  position: relative;
  height: 480px;
}
.doc {
  position: absolute;
  background: var(--bg-raised);
  border: 1px solid var(--krew-ink);
  border-radius: 6px;
  box-shadow: var(--shadow-ink);
  padding: 18px;
  overflow: hidden;
  transition: transform 600ms var(--ease-spark), opacity 600ms var(--ease-out);
}
.doc h5 { margin: 0 0 12px; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--fg-4); }
.doc .lines { display: flex; flex-direction: column; gap: 6px; }
.doc .lines i { height: 8px; background: var(--border-hair); border-radius: 2px; display: block; }

/* The doc paper colors (#FBF7EC, #BBD4E8) are always light, so their inner
   text + gray content lines must use ink-tone colors in BOTH modes. In dark
   mode the global --fg-4 / --border-hair tokens flip light, which would
   make the doc contents invisible on the light paper. The shell tags the
   body with .is-dark when dark-mode tokens are active — override there
   with fixed ink-tone values so legibility holds. */
body.is-dark .doc h5 { color: rgba(28, 26, 24, 0.55); }
body.is-dark .doc .lines i { background: rgba(28, 26, 24, 0.18); }
.doc .lines i:nth-child(1) { width: 78%; }
.doc .lines i:nth-child(2) { width: 92%; }
.doc .lines i:nth-child(3) { width: 64%; }
.doc .lines i:nth-child(4) { width: 84%; }
.doc .lines i:nth-child(5) { width: 42%; }
.doc .hit { position: absolute; border-radius: 2px; border: 1.5px solid var(--accent); background: var(--accent-soft); }

/* ============================================================
   HOW IT WORKS — continuous phase-driven motion
   All fractions (--fan, --read, --report-in/out, --reply-in,
   --blue-glow) are precomputed in JS and written to .how-stage.
   CSS uses flat calc() — no per-element clamp, no attribute
   substring selectors.
   ============================================================ */
.how-visual-stage .how-doc {
  position: absolute;
  top: calc(50% - 90px + var(--i) * 12px);
  left: calc(50% - 120px);
  width: 240px;
  height: 180px;
  /* On step 3 (report), slide the whole stack left so the email card
     has room to center. We use --report-in (0 on steps 1-2, 1 on
     steps 3-4) so the shift happens once and persists. */
  transform:
    translateX(calc(
      var(--offset) * (10px + 42px * var(--fan, 0))
      - 160px * var(--report-in, 0)
    ))
    rotate(calc(var(--offset) * (2deg + 2deg * var(--fan, 0))));
}
.how-visual-stage .how-doc.is-blue {
  /* BLUE pops to foreground only while it's being read (steps 1-2).
     After that it settles back into the stack. --blue-glow is 1 on
     step 1, 0 elsewhere; we use it as the lift toggle. */
  z-index: calc(2 + 8 * var(--blue-glow, 0));
  transform:
    translate(
      calc(
        var(--offset) * (10px + 42px * var(--fan, 0))
        + 90px * var(--read, 0)
        - 160px * var(--report-in, 0)
      ),
      calc(-14px * var(--read, 0))
    )
    rotate(calc(var(--offset) * (2deg + 2deg * var(--fan, 0)) + 4deg * var(--read, 0)));
  /* Glow fades out as we leave step 1 */
  box-shadow:
    calc(5px * var(--blue-glow, 1)) calc(5px * var(--blue-glow, 1)) 0
    color-mix(in oklch, var(--accent) calc(100% * var(--blue-glow, 1)), transparent),
    var(--shadow-ink);
}

.how-visual-stage .how-hits { position: absolute; inset: 0; pointer-events: none; }
.how-visual-stage .how-hit-1,
.how-visual-stage .how-hit-2,
.how-visual-stage .how-hit-3 {
  position: absolute; left: 18px; height: 8px;
  opacity: var(--read, 0);
}
.how-visual-stage .how-hit-1 { top: 44px; width: calc(159px * var(--read, 0)); }
.how-visual-stage .how-hit-2 { top: 72px; width: calc(131px * var(--read, 0)); background: rgba(184,55,28,0.18); border-color: var(--krew-alert); }
.how-visual-stage .how-hit-3 { top: 100px; width: calc(86px * var(--read, 0)); }

/* Overlay panes — opacity driven directly by precomputed fractions */
.how-visual-stage .how-overlay {
  position: absolute;
  pointer-events: none;
  /* Always sit above the doc stack (docs top out at z-index 10 for
     the lifted BLUE doc). The overlays are steps 2–4 content, which
     should layer above everything. */
  z-index: 20;
}
.how-overlay-eyebrow {
  font-size: 10px; letter-spacing: 1.5px; color: var(--accent);
  font-weight: 800; margin-bottom: 8px; text-transform: uppercase;
}
.how-overlay-body { font-size: 12px; color: var(--fg-2); display: flex; flex-direction: column; gap: 5px; }

.how-overlay-read {
  right: calc(50% - 280px); top: calc(50% - 100px);
  width: 220px;
  background: var(--bg-raised);
  border: 1px solid var(--krew-ink);
  border-radius: var(--r-3);
  padding: 14px;
  box-shadow: var(--shadow-spark);
  opacity: calc(var(--read-in, 0) * (1 - var(--read-out, 0)));
  transform: translateY(calc((1 - var(--read-in, 0)) * 10px));
}

.how-overlay-report {
  right: calc(50% - 320px); top: calc(50% - 110px);
  width: 290px;
  background: transparent;
  border: none;
  box-shadow: none;
  padding: 0;
  opacity: calc(var(--report-in, 0) * (1 - var(--report-out, 0)));
  transform: rotate(calc(var(--report-in, 0) * 2deg)) translateY(calc((1 - var(--report-in, 0)) * 12px));
}
/* Stripped-down email card — same paper/ink language as the hero email
   but reduced to its essence (no Inbox bar, no signature, no full body) */
.how-email-mini {
  background: var(--bg-surface);
  border: 1px solid var(--krew-ink);
  border-radius: 8px;
  box-shadow: 4px 4px 0 var(--krew-ink), var(--shadow-2);
  padding: 14px 16px;
  font-family: var(--font-sans);
  color: var(--fg-1);
}
.how-email-mini-strip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border-hair);
  margin-bottom: 10px;
}
.how-email-mini-from {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 800;
  color: var(--fg-1);
}
.how-email-mini-avatar {
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 1px solid var(--krew-ink);
  background: var(--accent);
  overflow: hidden;
  display: inline-block;
  flex-shrink: 0;
}
.how-email-mini-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.how-email-mini-time {
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-4);
  font-weight: 700;
}
.how-email-mini-subj {
  font-size: 14px;
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.25;
  margin-bottom: 6px;
  color: var(--fg-1);
}
.how-email-mini-snip {
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--fg-3);
  margin-bottom: 10px;
}
.how-email-mini-cta {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: var(--accent);
  text-transform: uppercase;
}
.how-report-cta {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--accent); color: #fff;
  padding: 5px 10px; border-radius: 4px;
  font-size: 10.5px; font-weight: 800; letter-spacing: 0.5px; text-transform: uppercase;
}

.how-overlay-reply {
  right: calc(50% - 320px); top: calc(50% - 110px);
  width: 300px;
  opacity: var(--reply-in, 0);
  transform: translateY(calc((1 - var(--reply-in, 0)) * 12px));
}
.how-reply-user {
  background: var(--krew-grain-pale);
  color: var(--fg-1);
  border: 1px solid var(--krew-ink);
  border-radius: 16px 16px 4px 16px;
  padding: 10px 14px; margin-bottom: 8px;
  font-size: 12.5px;
  box-shadow: var(--shadow-2);
}
.how-reply-krew {
  background: var(--krew-grain-warm);
  color: var(--fg-1);
  border: 1.5px solid var(--accent);
  border-radius: 16px 16px 16px 4px;
  padding: 10px 14px;
  font-size: 12.5px;
  box-shadow: 2px 2px 0 color-mix(in oklch, var(--accent) 30%, transparent);
  margin-left: 24px;
  line-height: 1.45;
}
.how-reply-src {
  color: var(--fg-3);
  font-size: 9.5px; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  display: block; margin-top: 6px;
}
.how-reply-krew.how-reply-krew-2 {
  margin-top: 8px;
}

/* Dot fill: active dot fills with --local; done dots full */
.how-dot::before {
  content: "";
  position: absolute; inset: 0 auto 0 0;
  width: 0%;
  background: var(--accent);
}
.how-dot.done::before { width: 100%; }
.how-stage .how-dot.active::before { width: calc(var(--local, 0) * 100%); }

/* ---------- ASK / TERMINAL ---------- */
.ask-block {
  padding: 40px;
  background: var(--krew-ink);
  color: var(--krew-grain);
  border-radius: var(--r-4);
  border: 1px solid var(--krew-ink);
  box-shadow: var(--shadow-spark);
  position: relative;
  overflow: hidden;
}
.ask-block::after {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(circle at 0% 0%, rgba(255,84,5,0.18), transparent 60%);
  pointer-events: none;
}
.ask-block h3 {
  font-size: clamp(28px, 3.4vw, 44px);
  font-weight: 900;
  letter-spacing: -0.02em;
  margin: 0 0 10px;
}
.ask-block h3 .spark { color: var(--accent); }
.ask-block p { color: rgba(237, 228, 211, 0.7); margin: 0 0 24px; max-width: 640px; }

.terminal {
  background: rgba(0,0,0,0.35);
  border: 1px solid rgba(237, 228, 211, 0.12);
  border-radius: var(--r-3);
  padding: 20px 22px;
  font-family: var(--font-mono);
  font-size: var(--fs-14);
  line-height: 1.7;
  color: rgba(237, 228, 211, 0.85);
  position: relative;
}
.terminal .prompt { color: var(--accent); font-weight: 700; }
.terminal .cursor::after {
  content: "▍";
  color: var(--accent);
  animation: blink 1s steps(1) infinite;
  margin-left: 2px;
}
@keyframes blink { 50% { opacity: 0; } }

.ask-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 20px; }
.ask-chips button {
  background: rgba(237, 228, 211, 0.08);
  color: rgba(237, 228, 211, 0.9);
  border: 1px solid rgba(237, 228, 211, 0.18);
  padding: 8px 14px;
  border-radius: var(--r-pill);
  font-size: var(--fs-13);
  font-weight: 600;
  cursor: pointer;
  transition: all var(--dur-2);
}
.ask-chips button:hover { background: var(--accent); color: #fff; border-color: var(--accent); }
.ask-chips button.active { background: var(--accent); color: #fff; border-color: var(--accent); }

/* ============ Ask Krew — email thread UI ============ */
#ask { background: var(--krew-ink); color: var(--fg-inverse); position: relative; overflow: hidden; }
#ask::before {
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse at 80% 20%, rgba(255,84,5,0.12), transparent 50%),
    radial-gradient(ellipse at 20% 80%, rgba(196,167,122,0.06), transparent 50%);
  pointer-events: none;
}
#ask h3 { color: var(--fg-inverse); }
#ask p { color: rgba(237,228,211,0.7); }
.ask-block { position: relative; }
.ask-header { max-width: 700px; position: relative; z-index: 1; }
.ask-header .eyebrow-row .dot { background: var(--accent); box-shadow: 0 0 0 4px rgba(255,84,5,0.25); }
.thread-stage {
  margin-top: 36px;
  position: relative;
  z-index: 1;
}
.thread-window {
  background: #FBF7EC;
  color: var(--fg-1);
  border-radius: var(--r-4);
  border: 1px solid var(--krew-ink);
  box-shadow: 8px 8px 0 rgba(0,0,0,0.4);
  overflow: hidden;
  animation: wordUp 500ms var(--ease-out);
}
.thread-topbar {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 16px;
  background: #E5D9C4;
  border-bottom: 1px solid var(--border-soft);
}
.thread-dots { display: flex; gap: 6px; }
.thread-dots i { width: 11px; height: 11px; border-radius: 50%; background: rgba(0,0,0,0.15); }
.thread-dots i:nth-child(1) { background: #E06C5E; }
.thread-dots i:nth-child(2) { background: #E8B13C; }
.thread-dots i:nth-child(3) { background: #7FB071; }
.thread-channel {
  font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase;
  font-weight: 700; color: var(--fg-3);
  flex: 1; text-align: center;
}
.thread-body {
  padding: 0;
}
.thread-msg {
  padding: 20px 24px;
  border-bottom: 1px dashed var(--border-soft);
  opacity: 0; animation: threadIn 500ms var(--ease-out) forwards;
}
.thread-msg:last-child { border-bottom: 0; }
.thread-msg.is-in { background: #FFFBF0; border-left: 3px solid var(--accent); }
@keyframes threadIn { to { opacity: 1; } }

.thread-head {
  display: grid;
  grid-template-columns: 36px 1fr auto;
  gap: 12px;
  align-items: center;
  margin-bottom: 10px;
}
.thread-avatar {
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--krew-leader); color: var(--krew-ink);
  font-weight: 900; font-size: 13px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--krew-ink);
}
.is-in .thread-avatar { background: var(--accent); color: #fff; }
.thread-from { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.thread-from strong { font-size: var(--fs-14); font-weight: 800; color: var(--fg-1); }
.thread-from span {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--fg-4);
  letter-spacing: 0.02em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.thread-time {
  font-size: 11px;
  color: var(--fg-4);
  font-weight: 600;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.thread-content { padding-left: 48px; }
.thread-content p {
  margin: 0 0 10px;
  font-size: var(--fs-15);
  color: var(--fg-2);
  line-height: 1.55;
}
.thread-bullets {
  margin: 12px 0;
  border-top: 1px solid var(--border-hair);
  border-bottom: 1px solid var(--border-hair);
}
.thread-bullet {
  display: grid;
  grid-template-columns: 100px 1fr;
  gap: 14px;
  padding: 8px 0;
  border-bottom: 1px dashed var(--border-hair);
  font-size: var(--fs-14);
}
.thread-bullet:last-child { border-bottom: 0; }
.thread-bullet-label {
  font-weight: 800;
  color: var(--fg-1);
  font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase;
}
.thread-bullet-value { color: var(--fg-2); font-family: var(--font-mono); font-size: 12.5px; }
.thread-note {
  margin-top: 12px;
  padding: 10px 14px;
  background: rgba(255,84,5,0.08);
  border-left: 2px solid var(--accent);
  font-size: var(--fs-14);
  color: var(--fg-2);
  font-style: italic;
  line-height: 1.5;
}
.thread-sources {
  margin-top: 14px;
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
}
.thread-sources-label {
  font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--fg-4); font-weight: 800;
  margin-right: 4px;
}
.thread-source {
  font-family: var(--font-mono);
  font-size: 10.5px;
  padding: 3px 8px;
  background: var(--bg-surface);
  border: 1px dashed var(--border-soft);
  border-radius: var(--r-pill);
  color: var(--fg-3);
  font-weight: 600;
  letter-spacing: 0.02em;
}

/* SMS rows inside thread */
.sms-row {
  display: flex; flex-direction: column; gap: 2px;
  padding: 14px 24px 6px;
  opacity: 0; animation: threadIn 400ms var(--ease-out) forwards;
}
.sms-row.sms-out-row { align-items: flex-end; }
.sms-row.sms-in-row { align-items: flex-start; }
.sms-msg {
  max-width: 78%;
  padding: 10px 14px;
  border-radius: 18px;
  font-size: var(--fs-14);
  line-height: 1.4;
}
.sms-msg-out { background: #0A84FF; color: #fff; border-bottom-right-radius: 4px; }
.sms-msg-in { background: #F0E6D2; color: var(--fg-1); border-bottom-left-radius: 4px; border: 1px solid var(--border-soft); }
.sms-body { white-space: pre-wrap; word-wrap: break-word; }
.sms-sources {
  display: flex; flex-wrap: wrap; gap: 4px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed rgba(0,0,0,0.15);
}
.sms-sources span {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--accent);
  font-weight: 700;
  letter-spacing: 0.02em;
}
.sms-row .sms-time { font-size: 10px; color: var(--fg-4); font-weight: 600; padding: 0 6px; }

.ask-chips { margin-top: 24px; display: flex; flex-wrap: wrap; gap: 8px; position: relative; z-index: 1; }
.ask-chips button {
  background: rgba(237,228,211,0.08);
  color: rgba(237,228,211,0.85);
  border: 1px solid rgba(237,228,211,0.2);
  padding: 9px 16px;
  border-radius: var(--r-pill);
  font-size: var(--fs-13);
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: all var(--dur-2);
}
.ask-chips button:hover { background: rgba(255,84,5,0.18); border-color: var(--accent); color: #fff; }
.ask-chips button.active { background: var(--accent); color: #fff; border-color: var(--accent); box-shadow: 2px 2px 0 rgba(0,0,0,0.4); }

@media (max-width: 760px) {
  .thread-content { padding-left: 0; }
  .thread-bullet { grid-template-columns: 1fr; gap: 2px; }
}

/* ---------- Founders ---------- */
/* ---------- Founders ---------- */
.founders-layout {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 56px;
  align-items: center;
}
@media (max-width: 960px) { .founders-layout { grid-template-columns: 1fr; } }
.founders-photo {
  position: relative;
  border: 1px solid var(--krew-ink);
  box-shadow: 8px 8px 0 var(--krew-ink);
  background: var(--bg-raised);
  transform: rotate(-1deg);
  padding: 10px;
}
.founders-photo img { width: 100%; display: block; }
.founders-tape.tape { top: -14px; left: 24px; }
.founders-tape.tape.r { top: -14px; right: 24px; left: auto; }

.founders-list { display: flex; flex-direction: column; }
.founder-row {
  padding: 22px 0;
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: 24px;
  align-items: start;
}
.founder-row h4 { margin: 0 0 4px; font-size: var(--fs-20); font-weight: 800; letter-spacing: -0.01em; }
.founder-row .role { font-family: var(--font-mono); font-size: var(--fs-12); text-transform: uppercase; letter-spacing: 0.08em; color: var(--accent); font-weight: 700; }
.founder-row p { margin: 0; font-size: var(--fs-14); color: var(--fg-3); line-height: 1.6; }
@media (max-width: 560px) { .founder-row { grid-template-columns: 1fr; gap: 8px; } }

.founders { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
@media (max-width: 960px) { .founders { grid-template-columns: 1fr; } }
.founder {
  padding: 24px;
  background: var(--bg-surface);
  border: 1px solid var(--krew-ink);
  border-radius: var(--r-3);
  box-shadow: var(--shadow-ink);
  position: relative;
}
.founder .avatar {
  width: 64px; height: 64px; border-radius: 50%;
  background: var(--krew-leader);
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 900; color: var(--krew-ink);
  font-size: var(--fs-24);
  border: 1.5px solid var(--krew-ink);
  margin-bottom: 16px;
  position: relative;
}
.founder .avatar::after {
  content: ""; position: absolute;
  right: -6px; bottom: -6px;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--bg-surface);
}
.founder h4 { margin: 0; font-size: var(--fs-18); font-weight: 800; }
.founder .role { font-family: var(--font-mono); font-size: var(--fs-12); text-transform: uppercase; letter-spacing: 0.08em; color: var(--accent); margin-top: 2px; font-weight: 700; }
.founder p { margin: 12px 0 0; font-size: var(--fs-14); color: var(--fg-3); line-height: 1.55; }

/* ---------- Flagship callout ---------- */
.flagship {
  margin-top: 64px;
  padding: 40px 48px;
  background: var(--krew-grain-warm);
  border: 1px dashed var(--krew-ink);
  border-radius: var(--r-3);
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 32px;
  align-items: center;
  position: relative;
}
@media (max-width: 760px) { .flagship { grid-template-columns: 1fr; text-align: left; } }
.flagship .stamp-seal {
  width: 92px; height: 92px;
  border-radius: 50%;
  border: 2px solid var(--krew-reel);
  color: var(--krew-reel);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-weight: 900;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transform: rotate(-8deg);
  position: relative;
}
.flagship .stamp-seal::before {
  content: ""; position: absolute; inset: 6px; border-radius: 50%; border: 1px dashed var(--krew-reel);
}
.flagship .stamp-seal strong { font-size: 18px; letter-spacing: 0.04em; display: block; }
.flagship h3 { margin: 0 0 6px; font-size: var(--fs-24); font-weight: 800; letter-spacing: -0.01em; }
.flagship p { margin: 0; color: var(--fg-2); font-size: var(--fs-15); }

/* ---------- Waitlist ---------- */
.waitlist-wrap {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 64px;
  align-items: center;
}
@media (max-width: 960px) { .waitlist-wrap { grid-template-columns: 1fr; } }

/* Hide the inline form on mobile — the form is reachable via the
   Demo modal instead. The wrap also hides so we don't leave a hole.
   The dedicated mobile CTA inside the left column shows in its place. */
.waitlist-mobile-cta { display: none; }
@media (max-width: 720px) {
  .waitlist-form-wrap { display: none; }
  .waitlist-mobile-cta {
    /* Center just the CTA — headline and paragraph stay in normal block
       flow, left-justified. block + margin auto recenters the inline-flex
       button without disrupting surrounding text alignment. Larger top
       margin so the CTA has a clear visual exit from the testimonial
       card above it and doesn't feel crowded. */
    display: flex;
    width: max-content;
    margin: 36px auto 0;
  }
  /* Tighten the gap between the "Book a demo." headline and its
     supporting paragraph — the h2 carried a default browser
     margin-bottom that opened too much air on mobile. */
  #waitlist h2 {
    margin-bottom: 0;
  }
}

/* ---------- Demo modal (mobile fullscreen demo form) ---------- */
.demo-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: var(--krew-grain-warm, var(--bg-page));
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 64px 0 16px;
  animation: demo-modal-fade 180ms var(--ease-out, ease-out);
}

/* Hand-written accent inline within a heading (Architects Daughter font, accent color, slight tilt). */
.hand-accent {
  font-family: var(--font-hand);
  font-weight: 600;
  color: var(--accent);
  font-size: 0.92em;
  letter-spacing: 0.005em;
  display: inline-block;
  transform: translateY(-2px) rotate(-2deg);
  margin-right: 2px;
}

/* Same treatment, but only kicks in on mobile (used in waitlist h2). */
@media (max-width: 720px) {
  .demo-hand-accent {
    font-family: var(--font-hand);
    font-weight: 600;
    color: var(--accent);
    font-size: 0.92em;
    letter-spacing: 0.005em;
    display: inline-block;
    transform: translateY(-2px) rotate(-2deg);
    margin-right: 2px;
  }
}
@keyframes demo-modal-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.demo-modal-panel {
  position: relative;
  width: 100%;
  max-width: 520px;
  max-height: calc(100dvh - 32px);
  background: var(--krew-grain-warm, var(--bg-page));
  overflow-y: auto;
  padding: 24px 22px 40px;
  animation: demo-modal-slide 240ms var(--ease-out, ease-out);
}
@keyframes demo-modal-slide {
  from { transform: translateY(20px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}
.demo-modal-close {
  position: fixed;
  top: 16px;
  right: 22px;
  z-index: 3;
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: var(--fg-2);
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  cursor: pointer;
  transition: background 160ms var(--ease-out), color 160ms var(--ease-out), border-color 160ms var(--ease-out);
}
.demo-modal-close:hover {
  background: var(--bg-raised);
  color: var(--fg-1);
  border-color: var(--krew-ink);
}
.demo-modal-panel .waitlist-form {
  margin: 0;
  box-shadow: none;
}
.waitlist-form {
  background: var(--bg-raised);
  border: 1px solid var(--krew-ink);
  border-radius: var(--r-3);
  box-shadow: 6px 6px 0 var(--krew-ink);
  padding: 32px;
  position: relative;
}
.waitlist-form .stripe {
  display: flex; gap: 0;
  margin: -32px -32px 24px;
  padding: 10px 18px;
  background: var(--krew-ink);
  color: var(--krew-grain);
  border-radius: var(--r-3) var(--r-3) 0 0;
  font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 800;
  align-items: center; gap: 10px;
}
.waitlist-form .stripe .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
.field { margin-bottom: 16px; }
.field label { display: block; font-size: var(--fs-12); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 6px; text-wrap: balance; }
.field input, .field select {
  width: 100%;
  padding: 12px 14px;
  background: var(--bg-surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--r-2);
  font-size: var(--fs-15);
  font-family: inherit;
  color: var(--fg-1);
  transition: border-color var(--dur-2), box-shadow var(--dur-2);
}
.field input:focus, .field select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-soft);
}
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 560px) { .field-row { grid-template-columns: 1fr; } }

.success-stamp {
  padding: 40px 20px;
  text-align: center;
}
.success-stamp .k {
  width: 88px; height: 88px; margin: 0 auto 22px;
  border-radius: 50%;
  background: var(--bg-surface);
  border: 1.5px solid var(--krew-ink);
  box-shadow: 4px 4px 0 var(--krew-ink);
  display: flex; align-items: center; justify-content: center;
  animation: stampIn 500ms var(--ease-spark);
}
.success-stamp .k img {
  width: 48px; height: 48px;
  display: block;
  filter: none;
}
@keyframes stampIn { from { transform: scale(0) rotate(-20deg); } to { transform: scale(1) rotate(-4deg); } }
.success-stamp h3 { margin: 0 0 8px; }
.success-stamp p { color: var(--fg-3); margin: 0; }

/* ---------- FAQ ---------- */
.faq { display: flex; flex-direction: column; border-top: 1px dashed var(--border-soft); }
.faq-item { border-bottom: 1px dashed var(--border-soft); padding: 20px 0; cursor: pointer; }
.faq-item:last-child { border-bottom: 0; }
.faq-q { display: flex; justify-content: space-between; align-items: center; gap: 16px; }
/* Reset the native <button> styling so the FAQ row keeps its identical look,
   while remaining keyboard-accessible. */
button.faq-q {
  width: 100%;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.faq-q h4 { margin: 0; font-size: var(--fs-20); font-weight: 700; letter-spacing: -0.005em; }
.faq-q .plus {
  width: 28px; height: 28px; border: 1.5px solid var(--krew-ink); border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0;
  transition: transform var(--dur-2) var(--ease-out), background var(--dur-2);
  flex-shrink: 0;
}
.faq-q .plus svg {
  display: block;
  width: 14px;
  height: 14px;
  flex: none;
}
.faq-q .plus .plus-v {
  transition: opacity var(--dur-2) var(--ease-out);
}
.faq-item.open .faq-q .plus { background: var(--accent); color: #fff; border-color: var(--krew-ink); transform: rotate(45deg); }
.faq-item.open .faq-q .plus .plus-v { opacity: 0; }
.faq-a {
  max-height: 0; overflow: hidden;
  transition: max-height 400ms var(--ease-out), margin 400ms var(--ease-out);
  color: var(--fg-3); font-size: var(--fs-15); line-height: 1.6;
}
.faq-item.open .faq-a { max-height: 320px; margin-top: 12px; }

/* ---------- FOOTER ---------- */
.footer {
  background: var(--krew-ink);
  color: var(--krew-grain);
  padding: 80px 0 36px;
  position: relative;
  overflow: hidden;
}
.footer::before {
  content: none;
}
.footer-sth {
  position: relative;
  z-index: 1;
  padding: 0 0 40px;
  text-align: center;
  border-bottom: 1px dashed rgba(237, 228, 211, 0.15);
  margin: 0 auto 48px;
  max-width: 1240px;
  width: calc(100% - 48px);
}
.footer-sth img {
  max-width: min(640px, 80%);
  margin: 0 auto;
  display: block;
  filter: drop-shadow(0 0 0 var(--accent));
}
.footer-wordmark { height: 36px; filter: brightness(1.1); }
.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 40px;
  position: relative;
  z-index: 1;
}
@media (max-width: 760px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
.footer-brand img.footer-wordmark { height: 36px; filter: brightness(1.1); }
.footer-brand p { color: rgba(237, 228, 211, 0.6); font-size: var(--fs-14); margin: 16px 0 20px; max-width: 360px; }
.footer-col h5 { margin: 0 0 14px; font-size: var(--fs-12); text-transform: uppercase; letter-spacing: 0.12em; color: var(--accent); font-weight: 800; }
.footer-col ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; }
.footer-col a { color: rgba(237, 228, 211, 0.8); text-decoration: none; font-size: var(--fs-14); font-weight: 500; transition: color var(--dur-2); }
.footer-col a:hover { color: var(--accent); }
.footer-bottom {
  margin-top: 56px;
  padding-top: 24px;
  border-top: 1px dashed rgba(237, 228, 211, 0.15);
  display: flex; justify-content: space-between; align-items: center; gap: 20px; flex-wrap: wrap;
  position: relative; z-index: 1;
  font-size: var(--fs-13); color: rgba(237, 228, 211, 0.5);
}
.footer-bottom a { color: rgba(237, 228, 211, 0.6); text-decoration: none; margin-left: 16px; }
.footer-bottom a:hover { color: var(--accent); }

/* ---------- Founders — photo + 3 quote bubbles ---------- */
.founders-section { padding-top: 80px; }
.founders-layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 72px;
  align-items: center;
}
@media (max-width: 960px) { .founders-layout { grid-template-columns: 1fr; } }
.founders-photo {
  position: relative;
  border: 1px solid var(--krew-ink);
  box-shadow: 8px 8px 0 var(--krew-ink);
  background: var(--bg-raised);
  transform: rotate(-1deg);
  padding: 10px;
}
.founders-photo img { width: 100%; display: block; }
.founders-tape.tape { top: -14px; left: 24px; }
.founders-tape.tape.r { top: -14px; right: 24px; left: auto; }
.photo-caption {
  position: absolute;
  bottom: -38px; left: 16px;
  color: var(--accent);
  font-size: 22px;
  transform: rotate(-2deg);
  line-height: 1;
}

.founders-bubbles { display: flex; flex-direction: column; gap: 22px; }
.founder-bubble {
  position: relative;
  padding: 22px 24px 20px;
  background: var(--bg-raised);
  border: 1px solid var(--krew-ink);
  border-radius: 20px 20px 20px 4px;
  box-shadow: 5px 5px 0 var(--krew-ink);
  transform: rotate(calc(var(--i, 0) * 0.6deg - 0.6deg)) translateX(calc(var(--i, 0) * 10px));
}
.founder-bubble:nth-child(2) { border-radius: 20px 20px 4px 20px; margin-left: 24px; }
.founder-bubble:nth-child(3) { margin-left: 0; }
.bubble-quote {
  font-family: var(--font-hand);
  font-size: 28px;
  line-height: 1.2;
  color: var(--fg-1);
  margin: 0 0 14px;
  letter-spacing: -0.005em;
}
.bubble-meta {
  padding-top: 12px;
  border-top: 1px dashed var(--border-soft);
}
.bubble-name {
  font-size: var(--fs-15);
  font-weight: 800;
  letter-spacing: -0.005em;
  color: var(--fg-1);
}
.bubble-role {
  margin-top: 4px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  line-height: 1.55;
}
.bubble-tail {
  position: absolute;
  bottom: -10px; left: 22px;
  width: 14px; height: 14px;
  background: var(--bg-raised);
  border-right: 1px solid var(--krew-ink);
  border-bottom: 1px solid var(--krew-ink);
  transform: rotate(45deg);
}
.founder-bubble:nth-child(2) .bubble-tail { left: auto; right: 26px; }

/* ---------- FOOTER — Save the Humans bleeds beyond ---------- */
.footer-sth-bleed {
  background: var(--krew-ink);
  color: var(--krew-grain);
  padding: 80px 0 36px;
  position: relative;
  overflow: visible;
}
.footer-sth-img {
  position: relative;
  width: 120%;
  max-width: none;
  margin: 0 -10% 48px;
  display: block;
  /* Knock out dark against ink background */
  mix-blend-mode: screen;
  filter: brightness(1.1) contrast(1.05);
  pointer-events: none;
}
@media (max-width: 760px) {
  .footer-sth-img { width: 140%; margin: 0 -20% 32px; }
}
.footer-grid--slim {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 40px;
  max-width: 720px;
}
@media (max-width: 760px) { .footer-grid--slim { grid-template-columns: 1fr 1fr; max-width: none; } }

/* ---------- Founders — photo + 3 quote bubbles ---------- */
.founders-section { padding-top: 80px; }
.founders-layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 72px;
  align-items: center;
}
@media (max-width: 960px) { .founders-layout { grid-template-columns: 1fr; } }
.founders-photo {
  position: relative;
  border: 1px solid var(--krew-ink);
  box-shadow: 8px 8px 0 var(--krew-ink);
  background: var(--bg-raised);
  transform: rotate(-1deg);
  padding: 10px;
}
.founders-photo img { width: 100%; display: block; }
.founders-tape.tape { top: -14px; left: 24px; }
.founders-tape.tape.r { top: -14px; right: 24px; left: auto; }
.photo-caption {
  position: absolute;
  bottom: -38px; left: 16px;
  color: var(--accent);
  font-size: 22px;
  transform: rotate(-2deg);
  line-height: 1;
}
.founders-bubbles { display: flex; flex-direction: column; gap: 22px; }
.founder-bubble {
  position: relative;
  padding: 22px 24px 20px;
  background: var(--bg-raised);
  border: 1px solid var(--krew-ink);
  border-radius: 20px 20px 20px 4px;
  box-shadow: 5px 5px 0 var(--krew-ink);
}
.founder-bubble:nth-child(2) { border-radius: 20px 20px 4px 20px; margin-left: 24px; }
.founder-bubble:nth-child(3) { margin-left: 0; }
.bubble-quote {
  font-family: var(--font-hand);
  font-size: 28px;
  line-height: 1.2;
  color: var(--fg-1);
  margin: 0 0 14px;
  letter-spacing: -0.005em;
}
.bubble-meta {
  padding-top: 12px;
  border-top: 1px dashed var(--border-soft);
}
.bubble-name {
  font-size: var(--fs-15);
  font-weight: 800;
  letter-spacing: -0.005em;
  color: var(--fg-1);
}
.bubble-role {
  margin-top: 4px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  line-height: 1.55;
}
.bubble-tail {
  position: absolute;
  bottom: -10px; left: 22px;
  width: 14px; height: 14px;
  background: var(--bg-raised);
  border-right: 1px solid var(--krew-ink);
  border-bottom: 1px solid var(--krew-ink);
  transform: rotate(45deg);
}
.founder-bubble:nth-child(2) .bubble-tail { left: auto; right: 26px; }

/* ---------- FOOTER — Save the Humans bleeds beyond ---------- */
.footer-sth-bleed {
  background: var(--krew-ink);
  color: var(--krew-grain);
  padding: 80px 0 36px;
  position: relative;
  overflow: visible;
}
.footer-sth-img {
  position: relative;
  width: 120%;
  max-width: none;
  margin: 0 -10% 48px;
  display: block;
  pointer-events: none;
}
@media (max-width: 760px) {
  .footer-sth-img { width: 140%; margin: 0 -20% 32px; }
}
.footer-grid--slim {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 40px;
  max-width: 720px;
}
@media (max-width: 760px) { .footer-grid--slim { grid-template-columns: 1fr 1fr; max-width: none; } }
.footer .footer-sth { display: none; }

/* ---------- Cursor glow + custom cursor ----------
   Soft Krew-orange glow trailing the cursor, plus a custom arrow that
   echoes the rest of the UI: 1px ink stroke + a 2px offset hard drop
   shadow in the same Krew orange. Suppressed on touch/coarse pointers
   and when the OS reports reduced motion. */
.has-krew-cursor,
.has-krew-cursor * { cursor: none; }
/* Restore the system caret inside text-entry fields so people can still
   see where they're typing — the custom arrow alone is misleading. */
.has-krew-cursor input,
.has-krew-cursor textarea,
.has-krew-cursor [contenteditable="true"] { cursor: text; }

.cursor-arrow {
  position: fixed;
  top: 0; left: 0;
  width: 22px; height: 22px;
  pointer-events: none;
  z-index: 9999;
  /* SVG tip is at (3,3); offset so it lands on the actual pointer. */
  margin: -3px 0 0 -3px;
  /* SVG strokes use currentColor → flows from the brand spark orange. */
  color: var(--accent);
  opacity: 0;
  transition: opacity 200ms var(--ease-out), transform 120ms var(--ease-out);
  will-change: transform;
}
.has-krew-cursor .cursor-arrow.is-visible { opacity: 1; }
/* Subtle press feedback — small scale-down on mousedown. */
.has-krew-cursor .cursor-arrow.is-down { transform: scale(0.88); }

@media (prefers-reduced-motion: reduce) {
  .cursor-arrow { transition: opacity 200ms linear; }
}
@media (hover: none), (pointer: coarse) {
  .has-krew-cursor,
  .has-krew-cursor * { cursor: auto; }
  .has-krew-cursor input,
  .has-krew-cursor textarea,
  .has-krew-cursor [contenteditable="true"] { cursor: text; }
  .cursor-arrow { display: none; }
}

/* ---------- Cursor spark on click ---------- */
.click-spark {
  position: fixed;
  width: 40px; height: 40px;
  pointer-events: none;
  z-index: 9999;
  color: var(--accent);
  animation: sparkBurst 520ms var(--ease-spark) forwards;
}
@keyframes sparkBurst {
  0% { transform: translate(-50%, -50%) scale(0.4) rotate(0deg); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1.6) rotate(30deg); opacity: 0; }
}

/* ---------- reveal on scroll ---------- */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 700ms var(--ease-out), transform 700ms var(--ease-out);
}
.reveal.in { opacity: 1; transform: translateY(0); }

/* ---------- Tweaks Panel ---------- */
.tweaks-panel {
  position: fixed;
  bottom: 20px; right: 20px;
  width: 280px;
  background: var(--bg-raised);
  border: 1.5px solid var(--krew-ink);
  border-radius: var(--r-3);
  box-shadow: 5px 5px 0 var(--krew-ink);
  padding: 18px;
  z-index: 1000;
  font-family: var(--font-sans);
}
.tweaks-panel h4 {
  margin: 0 0 14px; font-size: var(--fs-14);
  text-transform: uppercase; letter-spacing: 0.12em;
  display: flex; align-items: center; justify-content: space-between;
}
.tweaks-panel h4 span { font-size: 10px; color: var(--fg-4); font-weight: 600; letter-spacing: 0.08em; }
.tweak-row { margin-bottom: 12px; }
.tweak-row label { display: block; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--fg-3); margin-bottom: 6px; }
.color-swatches { display: flex; gap: 6px; }
.color-swatches button {
  width: 28px; height: 28px; border-radius: 4px; border: 1.5px solid var(--krew-ink);
  cursor: pointer; padding: 0;
}
.color-swatches button.active { transform: scale(1.12); box-shadow: 0 0 0 2px var(--bg-raised), 0 0 0 4px var(--krew-ink); }
.tweaks-panel .switch-row { display: flex; justify-content: space-between; align-items: center; font-size: var(--fs-13); }
.tweaks-panel .switch {
  width: 40px; height: 22px; background: var(--border-soft); border-radius: 999px; position: relative;
  transition: background var(--dur-2); cursor: pointer; border: none;
}
.tweaks-panel .switch::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%;
  background: #fff; transition: transform var(--dur-2);
}
.tweaks-panel .switch.on { background: var(--accent); }
.tweaks-panel .switch.on::after { transform: translateX(18px); }

/* ---- Handwriting font picker ---- */
.tweaks-panel { width: 320px; max-height: calc(100vh - 40px); overflow-y: auto; }
.hand-font-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 4px;
  border: 1px solid var(--border-hair);
  border-radius: var(--r-1);
  padding: 4px;
  background: var(--bg-surface);
}
.hand-font-opt {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  color: inherit;
  cursor: pointer;
  text-align: left;
  transition: background var(--dur-2), border-color var(--dur-2);
}
.hand-font-opt:hover { background: var(--bg-raised); }
.hand-font-opt.active {
  background: var(--bg-page);
  border-color: var(--krew-ink);
  box-shadow: 2px 2px 0 var(--krew-ink);
}
.hfo-sample {
  font-size: 22px;
  line-height: 1;
  color: var(--accent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.hfo-meta {
  display: flex; flex-direction: column; align-items: flex-end; gap: 2px;
  min-width: 0;
}
.hfo-name {
  font-size: 10px; font-weight: 800;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--fg-2);
  white-space: nowrap;
}
.hfo-vibe {
  font-size: 9px;
  color: var(--fg-4);
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.hand-font-opt.active .hfo-name { color: var(--fg-1); }


/* ============================================================
   SMS reply — elegant line-by-line fade-in
   ============================================================ */
.sms-bubble.sms-reply .reply-line {
  opacity: 0;
  transform: translateY(6px);
  animation: replyLine 480ms var(--ease-out) forwards;
}
@keyframes replyLine {
  to { opacity: 1; transform: translateY(0); }
}

/* ============================================================
   TESTIMONIAL — editorial pull-quote
   No card, no tape. Centered serif italic between hairline rules,
   attribution in small-caps mono. Reads as authoritative press,
   not scrapbook. */
.testimonial-section {
  position: relative;
}
.testimonial-pull {
  margin: 0 auto;
  padding: 0;
  max-width: 880px;
  text-align: center;
}
.testimonial-rule {
  width: 56px;
  height: 1px;
  background: var(--accent);
  margin: 0 auto;
}
.testimonial-rule-top { margin-bottom: 36px; }
.testimonial-rule-bot { margin-top: 32px; }

/* Contributor portrait — small circular headshot.
   In the standalone variant, sits centered above the quote.
   In the compact variant, sits inline next to the byline. */
.testimonial-pull-portrait {
  width: 72px;
  height: 72px;
  margin: 0 auto 24px;
  border-radius: 50%;
  overflow: hidden;
  border: 1px solid var(--krew-ink);
  box-shadow: 0 0 0 4px var(--bg-page), 0 0 0 5px var(--accent);
  background: var(--krew-grain-warm, var(--bg-raised));
  flex-shrink: 0;
}
.testimonial-pull-portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
@media (max-width: 560px) {
  .testimonial-pull-portrait { width: 60px; height: 60px; margin-bottom: 18px; }
}

.testimonial-pull-quote {
  position: relative;
  margin: 0;
  padding: 0;
  font-family: 'Crimson Pro', 'Crimson Text', 'Source Serif Pro', Georgia, serif;
  font-style: italic;
  font-weight: 500;
  font-size: clamp(28px, 3.6vw, 44px);
  line-height: 1.32;
  color: var(--fg-1);
  letter-spacing: -0.005em;
  text-wrap: balance;
}
.testimonial-pull-mark {
  /* opening quote, slightly oversized for editorial feel */
  font-family: 'Crimson Pro', 'Crimson Text', Georgia, serif;
  font-style: italic;
  color: var(--accent);
  margin-right: 0.05em;
  font-size: 1em;
  line-height: 0;
}

.testimonial-pull-attrib {
  margin-top: 28px;
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  gap: 14px;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: clamp(11px, 1vw, 13px);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.testimonial-pull-byline {
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-align: left;
  line-height: 1.4;
}
.testimonial-pull-name {
  color: var(--fg-1);
  font-weight: 800;
}
.testimonial-pull-sep {
  color: var(--accent);
  font-weight: 700;
  opacity: 0.85;
}
.testimonial-pull-role {
  color: var(--fg-3);
}

@media (max-width: 560px) {
  .testimonial-pull-attrib { gap: 10px; letter-spacing: 0.1em; }
  .testimonial-pull-sep { display: none; }
}

/* Compact inline variant — sits under the demo paragraph in the
   waitlist's left column. Left-aligned, tighter padding, no portrait
   above, no centered rules — just a top hairline as a divider from
   the paragraph above. The portrait sits inline next to the byline.

   On mobile (≤720px) this gets upgraded to a full callout card —
   see the mobile media query block further down in this file. */
.testimonial-pull-compact {
  text-align: left;
  max-width: 640px;
  margin: 32px 0 0;
  padding: 24px 0 0;
  border-top: 1px solid var(--border-soft);
}
.testimonial-pull-compact .testimonial-rule { display: none; }
.testimonial-pull-compact .testimonial-pull-portrait {
  width: 44px;
  height: 44px;
  margin: 0;
  box-shadow: 0 0 0 3px var(--krew-grain-warm, var(--bg-page)), 0 0 0 4px var(--accent);
}
.testimonial-pull-compact .testimonial-pull-quote {
  font-family: var(--font-hand);
  font-style: normal;
  font-size: clamp(19px, 1.8vw, 22px);
  line-height: 1.45;
  font-weight: 400;
  letter-spacing: 0;
  white-space: nowrap;
  max-width: none;
}
@media (max-width: 720px) {
  .testimonial-pull-compact .testimonial-pull-quote {
    white-space: normal;
    text-wrap: balance;
    font-size: clamp(17px, 4.2vw, 20px);
  }
}
.testimonial-pull-compact .testimonial-pull-mark {
  /* hand fonts handle their own quote glyph; hide the styled one */
  display: none;
}
/* Force the second sentence onto its own line — gives the quote a
   deliberate two-beat rhythm instead of an awkward mid-sentence wrap.
   On very narrow screens, let it flow naturally. */
.testimonial-pull-compact .testimonial-pull-break {
  display: block;
}
@media (max-width: 460px) {
  .testimonial-pull-compact .testimonial-pull-break { display: inline; }
}
.testimonial-pull-compact .testimonial-pull-attrib {
  margin-top: 18px;
  display: flex;
  flex-wrap: nowrap;
  justify-content: flex-start;
  align-items: center;
  gap: 12px;
  font-size: 11px;
  letter-spacing: 0.1em;
}

/* ============================================================
   FOUNDERS — annotated yearbook photo with bio callouts below
   One large group polaroid with handwritten arrows pointing from
   each founder's face DOWN to a callout block holding their
   name + role + bio. Three callouts sit side-by-side under the photo.
   ============================================================ */
.founders-annotated {
  margin-top: 16px;
}

/* Outer wrap. Photo lives in the top 0..68% of this height; callouts
   live in the bottom 76..100%. The SVG overlay covers the full wrap so
   arrows can travel from photo down to callouts.

   Both the photo (CSS box) and the callouts (CSS box) and the arrows
   (SVG viewBox) all use percentages of this wrap, so they line up
   regardless of viewport width. */
.founders-annot-wrap {
  position: relative;
  width: min(100%, 920px);
  /* Aspect: photo block (~3:2) + callout block (~140px) + breathing
     space. At 920px wide that's roughly 920 * 0.85 = 780px tall. */
  aspect-ratio: 920 / 760;
  margin: 16px auto 0;
}

/* Polaroid photo frame — occupies x: 12..88, y: 4..68 of the wrap. */
.founders-annot-wrap .founders-photo-frame {
  position: absolute;
  left: 12%;
  right: 12%;
  top: 4%;
  bottom: 32%;
  background: var(--bg-surface);
  border: 1px solid var(--krew-ink);
  box-shadow: 8px 8px 0 var(--krew-ink);
  padding: 14px 14px 44px;
  transform: rotate(-0.6deg);
}
.founders-annot-wrap .founders-photo-inner {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: var(--krew-grain-pale, var(--bg-raised));
}
.founders-annot-wrap .founders-photo-inner img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Placeholder when no photo yet — soft striped fill + three head/body
   silhouettes spaced across the frame to suggest the group. */
.founders-annot-wrap .founders-photo-placeholder {
  position: absolute;
  inset: 0;
  background-image:
    repeating-linear-gradient(
      135deg,
      var(--border-hair) 0 1px,
      transparent 1px 14px
    );
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  padding-bottom: 18px;
}
.founders-annot-wrap .fp-people {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: space-around;
  padding: 0 8% 0;
}
.founders-annot-wrap .fp-silhouette {
  display: flex;
  flex-direction: column;
  align-items: center;
  opacity: 0.45;
}
.founders-annot-wrap .fp-silhouette[style*="--i:0"],
.founders-annot-wrap .fp-silhouette:nth-child(1) { transform: translateY(8px); }
.founders-annot-wrap .fp-silhouette[style*="--i:1"],
.founders-annot-wrap .fp-silhouette:nth-child(2) { transform: translateY(-4px); }
.founders-annot-wrap .fp-silhouette[style*="--i:2"],
.founders-annot-wrap .fp-silhouette:nth-child(3) { transform: translateY(6px); }
.founders-annot-wrap .fp-head {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--krew-ink);
  margin-bottom: 6px;
}
.founders-annot-wrap .fp-body {
  width: 110px;
  height: 90px;
  background: var(--krew-ink);
  border-radius: 60px 60px 0 0;
}
.founders-annot-wrap .fp-label {
  position: relative;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-4);
  background: var(--bg-surface);
  padding: 4px 10px;
  border: 1px dashed var(--border-soft);
}

/* Polaroid caption strip — the white space at the bottom of the frame */
.founders-annot-wrap .founders-photo-frame .photo-caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 12px;
  text-align: center;
  font-family: var(--font-hand);
  font-size: 18px;
  color: var(--fg-2);
  line-height: 1;
  transform: rotate(-0.4deg);
}

/* Tape pieces — high specificity to override any legacy rules */
.founders-annot-wrap .founders-photo-frame .founders-tape.tape {
  position: absolute;
  z-index: 4;
  top: auto;
  left: auto;
  right: auto;
  bottom: auto;
}
.founders-annot-wrap .founders-photo-frame .founders-tape.tape.tl { top: -14px; left: 18%;  transform: rotate(-6deg); }
.founders-annot-wrap .founders-photo-frame .founders-tape.tape.tr { top: -14px; right: 14%; transform: rotate(5deg); }
.founders-annot-wrap .founders-photo-frame .founders-tape.tape.bl { bottom: -10px; left: 22%; transform: rotate(3deg); }

/* Callouts — three columns of name + role + bio sitting BELOW the
   photo. Use a flex row positioned at the bottom of the wrap so each
   block aligns with the corresponding face above. */
.founders-annot-wrap .founders-callouts {
  position: absolute;
  left: 4%;
  right: 4%;
  top: 76%;
  bottom: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  align-items: start;
}
.founders-annot-wrap .founder-callout {
  position: relative;
  padding-top: 12px;
  border-top: 1px solid var(--krew-ink);
  /* Stagger callouts vertically to mirror the slight tilt of the
     polaroid above and feel more handmade. */
  margin-top: calc(var(--i, 0) * 6px);
}
.founders-annot-wrap .founder-callout:nth-child(1) { margin-top: 4px; }
.founders-annot-wrap .founder-callout:nth-child(2) { margin-top: 0; }
.founders-annot-wrap .founder-callout:nth-child(3) { margin-top: 6px; }

.founders-annot-wrap .callout-name {
  font-size: clamp(20px, 1.6vw, 24px);
  font-weight: 800;
  letter-spacing: -0.015em;
  color: var(--fg-1);
  line-height: 1.15;
}
.founders-annot-wrap .callout-role {
  margin-top: 4px;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
}
.founders-annot-wrap .callout-bio {
  margin: 10px 0 0;
  font-size: var(--fs-15, 15px);
  line-height: 1.55;
  color: var(--fg-2);
}

/* Annotation overlay (SVG) covers the WHOLE wrap so arrows can travel
   from photo region down to callout region. */
.founders-annot-wrap .founders-annotations {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 5;
  overflow: visible;
}
.founders-annot-wrap .annot-arrow path {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: annotDraw 900ms var(--ease-out) forwards;
  animation-delay: calc(var(--i, 0) * 220ms + 200ms);
}
@keyframes annotDraw {
  to { stroke-dashoffset: 0; }
}

@media (max-width: 900px) {
  /* On narrow screens, stack the callouts under the photo and hide the
     overlay arrows (they don't make sense in a vertical stack). */
  .founders-annot-wrap {
    aspect-ratio: auto;
    display: flex;
    flex-direction: column;
    gap: 32px;
    max-width: 480px;
  }
  .founders-annot-wrap .founders-photo-frame {
    position: relative;
    left: 0; right: 0; top: 0; bottom: 0;
    aspect-ratio: 4 / 3;
  }
  .founders-annot-wrap .founders-callouts {
    position: relative;
    left: 0; right: 0; top: 0; bottom: 0;
    grid-template-columns: 1fr;
    gap: 24px;
  }
  .founders-annot-wrap .founders-annotations { display: none; }
}

/* ============================================================
   FOUNDERS — legacy three-up portrait card layout (kept for
   backwards-compat in case any code still mounts .founders-grid).
   ============================================================ */
.founders-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 32px;
  margin-top: 8px;
  max-width: 880px;
  margin-left: auto;
  margin-right: auto;
}
@media (max-width: 900px) {
  .founders-grid { grid-template-columns: 1fr; gap: 40px; max-width: 320px; }
}

/* Inline name+role row used inside .founder-meta. On mobile the role
   sits beside the name (right-aligned, baseline-shared). The desktop
   3-up card layout keeps role on its own line by overriding flex
   direction below. */
.founder-name-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.founder-name-row .founder-role {
  margin-top: 0;
}
/* Desktop 3-up cards: stack name above role like before. */
@media (min-width: 721px) {
  .founder-card .founder-name-row {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 6px;
  }
}

.founder-card {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.founder-portrait {
  position: relative;
  width: 100%;
  max-width: 200px;
  aspect-ratio: 1 / 1;
  background: var(--bg-raised);
  border: 1px solid var(--krew-ink);
  box-shadow: 5px 5px 0 var(--krew-ink);
  padding: 8px 8px 10px;
  transform: rotate(var(--tilt, 0deg));
  transition: transform 300ms var(--ease-out), box-shadow 300ms var(--ease-out);
}
.founder-card:hover .founder-portrait {
  transform: rotate(0deg) translate(-2px, -2px);
  box-shadow: 9px 9px 0 var(--krew-ink);
}
.founder-portrait img {
  position: relative;
  z-index: 2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.founder-portrait-fallback {
  position: absolute;
  inset: 10px 10px 12px;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  background-image:
    repeating-linear-gradient(
      135deg,
      var(--border-hair) 0 1px,
      transparent 1px 14px
    );
  background-color: var(--krew-grain-pale, var(--bg-raised));
  color: var(--fg-3);
}
.founder-portrait-initials {
  font-family: var(--font-hand);
  font-size: 56px;
  line-height: 1;
  color: var(--accent);
  letter-spacing: -0.02em;
}
.founder-portrait-label {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-4);
}
.founder-card:nth-child(1) .founders-tape.tape { top: -12px; left: 22px; transform: rotate(-4deg); }
.founder-card:nth-child(2) .founders-tape.tape { top: -12px; right: 22px; left: auto; transform: rotate(5deg); }
.founder-card:nth-child(3) .founders-tape.tape { top: -12px; left: 50%; margin-left: -46px; transform: rotate(-2deg); }
.founders-tape.tape { z-index: 3; }

.founder-meta {
  padding: 0 4px;
}
.founder-name {
  font-size: clamp(20px, 1.6vw, 24px);
  font-weight: 800;
  letter-spacing: -0.015em;
  color: var(--fg-1);
  line-height: 1.1;
}
.founder-role {
  margin-top: 6px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}
.founder-bio {
  margin: 12px 0 0;
  font-size: var(--fs-15, 15px);
  line-height: 1.55;
  color: var(--fg-2);
}

/* ============================================================
   FOOTER — center the Save the Humans graphic and
   distribute the three link columns evenly.
   ============================================================ */
.footer-sth-bleed .container {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.footer-sth-bleed > .footer-sth-img,
.footer-sth-bleed .footer-sth-img {
  width: auto;
  max-width: min(560px, 86%);
  margin: 0 auto 48px;
  display: block;
}
@media (max-width: 760px) {
  .footer-sth-bleed > .footer-sth-img,
  .footer-sth-bleed .footer-sth-img {
    width: auto;
    max-width: 86%;
    margin: 0 auto 32px;
  }
}
.footer-sth-bleed .footer-grid--slim {
  width: 100%;
  max-width: 760px;
  margin: 0 auto;
  grid-template-columns: repeat(3, 1fr);
  gap: 48px;
  justify-items: center;
  text-align: left;
}
.footer-sth-bleed .footer-grid--slim .footer-col {
  width: 100%;
  max-width: 180px;
}
@media (max-width: 760px) {
  .footer-sth-bleed .footer-grid--slim {
    grid-template-columns: repeat(3, auto);
    gap: 28px;
    max-width: none;
  }
}
.footer-sth-bleed .footer-bottom {
  width: 100%;
  max-width: 760px;
  margin: 40px auto 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
}
@media (max-width: 620px) {
  .footer-sth-bleed .footer-bottom {
    flex-direction: column;
    text-align: center;
  }
}

/* ============================================================
   PILLAR ILLUSTRATIONS — looping micro-motion
   Gentle, infinite, cue-free. Animations pause for reduced-motion.
   ============================================================ */

/* 02 Change tracking — reveal loop.
   Timeline (normalized 0→1, 6.4s total):
     0.00 – 0.12 : ONE page centered (BLUE). WHITE hidden directly behind it.
     0.12 – 0.26 : pages separate — BLUE shifts left, WHITE slides right + fades in.
     0.26 – 0.34 : labels animate on.
     0.34 – 0.42 : diff arrow fades + pops in.
     0.42 – 0.58 : highlighter sweep fills the changed row L→R in orange.
     0.58 – 0.74 : hold — everything visible.
     0.74 – 0.82 : labels + arrow fade out; sweep retracts.
     0.82 – 0.94 : pages rejoin — WHITE slides back + fades out, BLUE re-centers.
     0.94 – 1.00 : single page centered again. */
.illus-diff .diff-page {
  animation-duration: 6.4s;
  animation-iteration-count: infinite;
  animation-timing-function: cubic-bezier(.55,.05,.25,1);
}
.illus-diff .diff-page-blue {
  animation-name: diffPageBlueShift;
}
.illus-diff .diff-page-white {
  animation-name: diffPageWhiteEnter;
}
/* BLUE enters from RIGHT: starts behind WHITE (tx=0, opacity=0),
   slides out to the right and fades in. Spread widened to ±52 so
   the arrow has full clearance between the page edges. */
@keyframes diffPageBlueShift {
  0%,   12% { transform: translateX(0);    opacity: 0; }
  26%, 82%  { transform: translateX(52px); opacity: 1; }
  94%, 100% { transform: translateX(0);    opacity: 0; }
}
/* WHITE starts centered, shifts LEFT on reveal, returns to center. */
@keyframes diffPageWhiteEnter {
  0%,   12% { transform: translateX(0); }
  26%, 82%  { transform: translateX(-52px); }
  94%, 100% { transform: translateX(0); }
}
/* Version labels — WHITE is always visible (it's the prior version,
   present from the start). Only BLUE fades in/out with the reveal.
   Appears AFTER the arrow so the overlay reveals in order:
     pages separate → arrow → BLUE label → sweep. */
.illus-diff .diff-page-blue .diff-label {
  opacity: 0;
  animation: diffLabelFade 6.4s cubic-bezier(.55,.05,.25,1) infinite;
}
@keyframes diffLabelFade {
  0%,   18% { opacity: 0; }
  26%, 74%  { opacity: 1; }
  82%, 100% { opacity: 0; }
}
/* Diff arrow — appears slightly BEFORE the BLUE label so the arrow
   "announces" the comparison first. */
.illus-diff .diff-arrow {
  opacity: 0;
  transform-origin: 100px 60px;
  animation: diffArrowReveal 6.4s cubic-bezier(.55,.05,.25,1) infinite;
}
@keyframes diffArrowReveal {
  0%,   18% { opacity: 0; transform: scale(0.7); }
  26%, 74%  { opacity: 1; transform: scale(1); }
  82%, 100% { opacity: 0; transform: scale(0.7); }
}
/* Highlighter sweep — the clipPath's inner rect starts at width 0 and
   grows L→R, revealing the orange overlay row by row. Retracts before
   pages rejoin. The element is a <rect> inside a <clipPath>, so its
   geometry (not transform) drives the reveal. */
.illus-diff .diff-sweep-mask {
  transform-origin: 71px 52px;
  animation: diffSweepGrow 6.4s cubic-bezier(.55,.05,.25,1) infinite;
}
@keyframes diffSweepGrow {
  0%,   42% { transform: scaleX(0); }
  58%, 74%  { transform: scaleX(1); }
  82%, 100% { transform: scaleX(0); }
}

/* 05 Chart — bars rise on loop, trendline draws itself. The moving
   dot is driven by <animateMotion> inline. */
.illus-chart .chart-bar {
  animation: chartBarRise 4.2s ease-in-out infinite;
}
@keyframes chartBarRise {
  0%, 100% { transform: scaleY(1); }
  30%      { transform: scaleY(0.55); }
  55%      { transform: scaleY(1); }
}
.illus-chart .chart-trendline {
  stroke-dasharray: 0.04 0.06;
  stroke-dashoffset: 1;
  animation: chartTrendDraw 6s ease-in-out infinite;
}
@keyframes chartTrendDraw {
  0%       { stroke-dashoffset: 1;   opacity: 0.4; }
  40%      { stroke-dashoffset: 0;   opacity: 1; }
  60%      { stroke-dashoffset: 0;   opacity: 1; }
  100%     { stroke-dashoffset: -1;  opacity: 0.4; }
}

@media (prefers-reduced-motion: reduce) {
  .illus-diff .diff-arrow,
  .illus-diff .diff-sweep-mask,
  .illus-diff .diff-page-white,
  .illus-diff .diff-page-blue,
  .illus-chart .chart-bar,
  .illus-chart .chart-trendline,
  .illus-grid .qa-cell-flag,
  .illus-grid .qa-scan,
  .illus-qa .qa-question,
  .illus-qa .qa-reply,
  .illus-qa .qa-answer-mask,
  .illus-qa .qa-source,
  .illus-qa .qa-typing-caret { animation: none; }
}

/* 03 QA grid — scan line sweeps left→right; flagged cells flip to
   orange in sequence as the scan passes them, then everything resets. */
.illus-grid .qa-scan {
  animation: qaScan 4.8s cubic-bezier(.55,.05,.2,1) infinite;
}
@keyframes qaScan {
  0%   { transform: translateX(0);    opacity: 0; }
  8%   { opacity: 0.8; }
  80%  { transform: translateX(160px); opacity: 0.8; }
  92%  { transform: translateX(160px); opacity: 0; }
  100% { transform: translateX(0);    opacity: 0; }
}
/* Flagged cells — each flips to orange just AFTER the scan line
   passes its right edge. Timings below are calibrated against the
   `qaScan` translateX keyframe (0 → 160px over 0% → 80% of 4.8s with
   cubic-bezier(.55,.05,.2,1) easing — slow start, fast middle). */
.illus-grid .qa-cell-flag {
  animation-duration: 4.8s;
  animation-iteration-count: infinite;
  animation-timing-function: ease-out;
}
/* Left cell (c=1, x=52..78): scan exits the cell around ~28% of loop */
.illus-grid .qa-cell-flag-0 {
  animation-name: qaCellFlagLeft;
}
@keyframes qaCellFlagLeft {
  0%, 28%   { fill: var(--krew-grain-pale); stroke: var(--border-soft); stroke-width: 1; }
  32%       { fill: var(--accent-soft);     stroke: var(--accent);      stroke-width: 1.5; }
  88%       { fill: var(--accent-soft);     stroke: var(--accent);      stroke-width: 1.5; }
  96%, 100% { fill: var(--krew-grain-pale); stroke: var(--border-soft); stroke-width: 1; }
}
/* Right cell (c=3, x=116..142): scan exits around ~48% of loop */
.illus-grid .qa-cell-flag-1 {
  animation-name: qaCellFlagRight;
}
@keyframes qaCellFlagRight {
  0%, 48%   { fill: var(--krew-grain-pale); stroke: var(--border-soft); stroke-width: 1; }
  52%       { fill: var(--accent-soft);     stroke: var(--accent);      stroke-width: 1.5; }
  88%       { fill: var(--accent-soft);     stroke: var(--accent);      stroke-width: 1.5; }
  96%, 100% { fill: var(--krew-grain-pale); stroke: var(--border-soft); stroke-width: 1; }
}

/* ---------- 01 Q&A — conversational answer ----------
   Loop (6.0s):
     0.00 – 0.12 : idle (empty)
     0.12 – 0.22 : user question bubble drops in
     0.22 – 0.32 : KREW avatar appears, typing caret blinks
     0.32 – 0.65 : answer text streams in (clip-path width)
     0.55 – 0.70 : source citation chip fades up
     0.70 – 0.88 : hold
     0.88 – 1.00 : fade out, reset
*/
.illus-qa .qa-question,
.illus-qa .qa-reply,
.illus-qa .qa-answer-mask,
.illus-qa .qa-source,
.illus-qa .qa-typing-caret {
  animation-duration: 6.0s;
  animation-iteration-count: infinite;
  animation-timing-function: cubic-bezier(.55,.05,.2,1);
}

/* Question bubble drops in */
.illus-qa .qa-question {
  animation-name: qaQuestionDrop;
  opacity: 0;
  transform-origin: 90px 19px;
}
@keyframes qaQuestionDrop {
  0%,  8%   { opacity: 0; transform: translateY(-6px) scale(0.96); }
  18%, 85%  { opacity: 1; transform: translateY(0)    scale(1); }
  95%, 100% { opacity: 0; transform: translateY(-6px) scale(0.96); }
}

/* Reply group (avatar + answer container) fades in */
.illus-qa .qa-reply {
  animation-name: qaReplyIn;
  opacity: 0;
}
@keyframes qaReplyIn {
  0%,  22%  { opacity: 0; }
  32%, 85%  { opacity: 1; }
  95%, 100% { opacity: 0; }
}

/* Answer text streams in via clip-path width */
.illus-qa .qa-answer-mask {
  animation-name: qaAnswerStream;
}
@keyframes qaAnswerStream {
  0%,  32%  { width: 0; }
  60%, 85%  { width: 175px; }
  95%, 100% { width: 0; }
}

/* Typing caret blinks during the typing window, then hides */
.illus-qa .qa-typing-caret {
  animation-name: qaTypingCaret;
  opacity: 0;
}
@keyframes qaTypingCaret {
  0%,  28%  { opacity: 0; }
  30%, 58%  { opacity: 1; }
  60%, 100% { opacity: 0; }
}

/* Source chip slides up once the answer has landed */
.illus-qa .qa-source {
  animation-name: qaSourceIn;
  opacity: 0;
  transform-origin: 93px 97px;
}
@keyframes qaSourceIn {
  0%,  58%  { opacity: 0; transform: translateY(4px); }
  70%, 85%  { opacity: 1; transform: translateY(0); }
  95%, 100% { opacity: 0; transform: translateY(4px); }
}

/* ---------- 04 Watchtower — flight alerts across the crew ----------
   Each row holds 4 chips (ON TIME → DELAY → WEATHER → GATE) stacked
   in the same slot; only one is visible at a time. Per-row stagger
   via --i makes alerts cascade down the crew instead of firing in
   unison. */

/* Each row's chip cycle is offset by --i so the alerts cascade
   across the crew instead of all firing in unison. */
.illus-watch .watch-row {
  --cycle: 16s;
  --offset: calc(var(--i) * -2.1s);
}

/* Chips — only one is visible at any moment per row.
   The 4 chips (index 0..3) are stacked in the same slot.
   We fade each in for ~22% of the cycle, with each chip
   offset by 25% of the cycle, so the row reads:
   ON TIME → DELAY → WEATHER → GATE → ON TIME …
   The whole row's clock is shifted by --offset so rows stagger. */
.illus-watch .watch-chip {
  opacity: 0;
  transform: translateX(8px) scale(0.92);
  transform-origin: 31px 5.5px;
  animation: watchChipIn var(--cycle) cubic-bezier(.2,.7,.2,1) infinite;
  animation-delay: var(--offset);
}
.illus-watch .watch-chip-0 { animation-name: watchChip0; }
.illus-watch .watch-chip-1 { animation-name: watchChip1; }
.illus-watch .watch-chip-2 { animation-name: watchChip2; }
.illus-watch .watch-chip-3 { animation-name: watchChip3; }

@keyframes watchChip0 {
  0%   { opacity: 0; transform: translateX(8px) scale(0.92); }
  4%   { opacity: 1; transform: translateX(0)   scale(1); }
  22%  { opacity: 1; transform: translateX(0)   scale(1); }
  26%  { opacity: 0; transform: translateX(-6px) scale(0.96); }
  100% { opacity: 0; transform: translateX(-6px) scale(0.96); }
}
@keyframes watchChip1 {
  0%, 25%  { opacity: 0; transform: translateX(8px) scale(0.92); }
  29%      { opacity: 1; transform: translateX(0)   scale(1.05); }
  33%, 47% { opacity: 1; transform: translateX(0)   scale(1); }
  51%      { opacity: 0; transform: translateX(-6px) scale(0.96); }
  100%     { opacity: 0; transform: translateX(-6px) scale(0.96); }
}
@keyframes watchChip2 {
  0%, 50%  { opacity: 0; transform: translateX(8px) scale(0.92); }
  54%      { opacity: 1; transform: translateX(0)   scale(1.05); }
  58%, 72% { opacity: 1; transform: translateX(0)   scale(1); }
  76%      { opacity: 0; transform: translateX(-6px) scale(0.96); }
  100%     { opacity: 0; transform: translateX(-6px) scale(0.96); }
}
@keyframes watchChip3 {
  0%, 75%  { opacity: 0; transform: translateX(8px) scale(0.92); }
  79%      { opacity: 1; transform: translateX(0)   scale(1.05); }
  83%, 96% { opacity: 1; transform: translateX(0)   scale(1); }
  100%     { opacity: 0; transform: translateX(-6px) scale(0.96); }
}

@media (prefers-reduced-motion: reduce) {
  .illus-watch .watch-chip { animation: none; }
  .illus-watch .watch-chip-0 { opacity: 1; transform: none; }
  .illus-watch .watch-chip-1,
  .illus-watch .watch-chip-2,
  .illus-watch .watch-chip-3 { opacity: 0; }
}

/* ---------- 06 Daily Brief — three roles cycle through one card ----------
   The brief card itself is static; only the role tag and bullet
   set cycle. Three states (RONNIE/PRIYA/JORDAN), each visible for
   ~33% of the loop, with cross-fades. Total cycle: 12s. */

.illus-brief .brief-role,
.illus-brief .brief-set {
  opacity: 0;
  animation: briefFade 12s ease-in-out infinite;
}
.illus-brief .brief-role-1,
.illus-brief .brief-set-1  { animation-delay: 0s; }
.illus-brief .brief-role-2,
.illus-brief .brief-set-2  { animation-delay: -8s; }
.illus-brief .brief-role-3,
.illus-brief .brief-set-3  { animation-delay: -4s; }

@keyframes briefFade {
  0%, 2%   { opacity: 0; }
  6%, 32%  { opacity: 1; }
  36%, 100%{ opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .illus-brief .brief-role,
  .illus-brief .brief-set { animation: none; }
  .illus-brief .brief-role-1,
  .illus-brief .brief-set-1 { opacity: 1; }
}

/* ============================================================
   FLUID HERO — accommodate widths above the Claude preview
   ============================================================
   The hero was tuned to ~1280px wide. At 1440 / 1728 / 1920+ the
   copy column stretched (h1 reflowed huge, lead paragraph too wide)
   while the mock column stayed centered in its own column and drifted
   away from the right edge — leaving the design with two centered
   islands instead of a left-anchored copy + right-anchored mock.

   Fix: above 1240px, give .hero-copy a fixed max-width, let the mock
   column grow, push the mock toward the right edge of the column,
   and grow the gap with viewport width. Mock itself scales modestly
   on big screens via a width-aware factor.

   Scoped to .hero-stage so the rest of the page is untouched.
   ============================================================ */

/* 1) Container: more canvas at wider widths, but never edge-to-edge. */
@media (min-width: 1000px) {
  .container {
    width: min(1440px, 100% - clamp(96px, 8vw, 200px));
  }
  /* Apply hero padding on the STAGE itself (highest level) so it
     can't lose cascade to the existing `.hero-stage .container`
     rule. Belt-and-suspenders: also pad the inner container. */
  .hero-stage {
    padding-inline: clamp(48px, 4vw, 100px);
  }
  .hero-stage .container {
    width: 100%;
    max-width: 1440px;
    margin-inline: auto;
    padding-inline: 0;
  }
}

/* 2) Hero grid breathes — wider gap, copy column flexible, mock anchored right. */
@media (min-width: 1000px) {
  .hero-stage .hero-grid {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: clamp(48px, 5vw, 120px);
    padding-left: 0;
  }

  .hero-stage .hero-grid > .hero-copy {
    justify-self: start;
    max-width: 620px;
    width: 100%;
  }
  .hero-stage .hero-grid > .hero-mock {
    justify-self: end;
    width: auto;
  }
  .hero-stage .hero-mock .mock-stack { margin-inline: 0; }

  /* Headline: keep growing past 1280, but cap a touch lower so it
     doesn't blow out the 560px column. */
  .hero h1 {
    font-size: clamp(48px, 4.4vw, 80px);
  }

  /* Lead paragraph stays comfortable. */
  .hero-lead {
    max-width: 460px;
  }
}

/* 3) Mock scale: grow with viewport WIDTH (not just height) so on a
      1728/1920 screen the email card and SMS phone read at full presence
      instead of looking like postage stamps. The original height-only
      formula is preserved as a floor. */
/* Stacked layout: when the hero collapses to single column at <900px,
   the mock sits centered below the copy — origin should be top center,
   not top right (right-anchor would yank it off the right edge). */
@media (max-width: 900px) {
  .mock-stack { transform-origin: top center; }
}


/* 4) Very wide screens (1600+): hold the layout. Container is already
      capped at 1440px, so additional whitespace flows to the margins —
      that's the desired "tight column on a big monitor" effect.
      We just ease the hero's vertical padding a touch so the section
      doesn't feel cramped against the now-larger surrounding canvas. */
@media (min-width: 1600px) {
  .hero-stage {
    padding-top: clamp(120px, 11vh, 160px);
    padding-bottom: clamp(72px, 8vh, 100px);
  }
}

/* ============================================================
   DAY / NIGHT TOGGLE
   Ghost glyph in the top-right. No background, no border, no shadow —
   just a muted icon that brightens on hover. The visible glyph reflects
   the destination of the toggle (moon when light, sun when dark).
   ============================================================ */
.day-night {
  position: fixed;
  /* Park in the bottom-right of the viewport. Static placement (not
     attached to the nav) so it's always reachable, never moves with
     scroll, and doesn't crowd the top-right where the user's window
     controls / browser chrome already live. */
  bottom: 22px;
  right: 22px;
  z-index: 50;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 0;
  background: transparent;
  color: var(--krew-ink, #1C1A18);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
  opacity: 0.45;
  transition:
    opacity 180ms ease,
    transform 180ms var(--ease-out, cubic-bezier(.2,.8,.2,1)),
    color 200ms ease;
}
.day-night:hover {
  opacity: 1;
  transform: scale(1.08);
}
.day-night:active {
  transform: scale(0.94);
}
.day-night:focus-visible {
  opacity: 1;
  outline: 2px solid var(--krew-spark, #FF5405);
  outline-offset: 4px;
  border-radius: 50%;
}

/* Two glyphs stacked; show the destination glyph (moon when light,
   sun when dark). The other is faded out + slightly rotated so the
   transition reads as a flip rather than a swap. */
.day-night .dn-glyph {
  position: absolute;
  inset: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: opacity 220ms ease, transform 280ms var(--ease-out, cubic-bezier(.2,.8,.2,1));
}
.day-night.is-light .dn-sun {
  opacity: 0;
  transform: rotate(-90deg) scale(0.6);
  pointer-events: none;
}
.day-night.is-light .dn-moon {
  opacity: 1;
  transform: rotate(0deg) scale(1);
}
.day-night.is-dark .dn-sun {
  opacity: 1;
  transform: rotate(0deg) scale(1);
}
.day-night.is-dark .dn-moon {
  opacity: 0;
  transform: rotate(90deg) scale(0.6);
  pointer-events: none;
}

/* In dark mode, swap glyph color so it stays legible on dark surface. */
.day-night.is-dark {
  color: var(--krew-grain, #EDE4D3);
}

@media (prefers-reduced-motion: reduce) {
  .day-night,
  .day-night .dn-glyph {
    transition: none;
  }
}

/* ============================================================
   ============================================================
   MOBILE — single source of truth, last in cascade
   ============================================================
   Everything in this block is gated by max-width media queries.
   Any rule above this block describes desktop; below describes
   the mobile-only overrides. If something looks wrong on desktop
   after a mobile fix, the rule is in the wrong block.

   Breakpoints:
     ≤ 720px : hard mobile (phones, mobile-preview iframe at 390px)
     ≤ 560px : tight phones
   ============================================================
   ============================================================ */

@media (max-width: 720px) {

  /* ---------- NAV ---------- */
  /* On mobile, the nav becomes a floating frosted pill that sits
     BELOW the device notch with a small inset from the screen edges.
     Stays pinned (position: fixed) as the user scrolls. */
  .nav {
    /* Notch geometry inside the mobile-preview iframe:
         notch top: 18px, height: 32px → bottom at 50px
       Sit the pill ~10px below the notch with a touch of breathing
       room. On a real device with safe-area-insets the env() value
       takes over and bumps it down further. */
    top: calc(60px + env(safe-area-inset-top, 0px));
    left: 12px;
    right: 12px;
    /* Frosted material, slightly translucent so the page peeks
       through. The base var keeps it theme-aware (dark mode swap). */
    /* Translucent from the start — the page tone behind should
       always read through. Lower opacity + heavier blur so it
       feels like a frosted glass pill, not a solid panel. */
    background: color-mix(in oklch, var(--bg-raised) 38%, transparent);
    backdrop-filter: blur(24px) saturate(170%);
    -webkit-backdrop-filter: blur(24px) saturate(170%);
    /* Smoothly transition the background when the menu opens — the
       scrim darkens the page beneath, and a low-alpha pill would
       read muddy through it. .is-menu-open bumps opacity slightly. */
    transition: background 220ms var(--ease-out);
    /* Pill shape with a soft hairline + drop shadow so it lifts
       above the page content. */
    border: 1px solid var(--border-hair);
    border-bottom: 1px solid var(--border-hair); /* override the
       full-width bar's variable bottom border */
    border-radius: 18px;
    box-shadow:
      0 8px 24px rgba(28, 26, 24, 0.12),
      0 2px 6px rgba(28, 26, 24, 0.06);
  }
  /* When the sheet is open, the page is darkened by the scrim, and
     the pill's resting 38% alpha would read muddy through it. Bump
     to ~70% with the warm grain tone (NOT white — the grain page
     palette is bone/tan, so blending toward white reads as a stark
     pop-out). The grain tone keeps the pill feeling material-coherent
     with the rest of the page. */
  .nav.is-menu-open {
    background: var(--krew-grain-pale, #EFE7D5);
  }
  /* Body needs top padding so the first section doesn't hide under
     the floating pill. */
  body { padding-top: 0; }
  /* The pill no longer uses .container for its inner row — the row
     fills the pill directly. */
  .nav-inner {
    /* Extra left padding so the wordmark doesn't kiss the rounded
       left edge of the pill. Right side stays tighter against the
       hamburger. */
    padding: 8px 10px 8px 18px;
    gap: 10px;
    width: auto;
  }
  /* The container inside .nav had a max-width and side gutters; on
     mobile the pill itself provides that, so collapse the container's
     own width constraint. */
  .nav > .container.nav-inner {
    width: auto;
    margin: 0;
  }
  .nav-logo img { height: 20px; }
  .nav-links {
    /* Hide desktop link row entirely; the CTA pill + hamburger
       below replace it on mobile. */
    display: none;
  }
  /* Mobile-only nav controls (rendered by Nav component, hidden ≥720) */
  .nav-mobile {
    display: flex;
    align-items: center;
    gap: 8px;
  }
  .nav-mobile .btn.spark {
    /* Compact CTA — keep it tappable but not dominant */
    padding: 8px 12px;
    font-size: 11px;
    letter-spacing: 0.04em;
  }
  .nav-mobile .btn.spark svg { display: none; }
  .nav-burger {
    width: 40px; height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    border-radius: 0;
    color: var(--krew-ink);
    padding: 0;
    box-shadow: none;
    transition: transform 120ms var(--ease-out);
  }
  /* Dark mode: ink-on-dark is invisible — flip the bars to the
     warm grain tone the rest of the dark-mode chrome uses. */
  body.is-dark .nav-burger {
    color: var(--krew-grain, #EDE4D3);
  }
  .nav-burger:active { transform: translate(1px, 1px); }
  .nav-burger .nb-bars {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .nav-burger .nb-bars svg {
    width: 20px;
    height: 14px;
    flex: none;
    display: block;
  }
  .nav-burger .nb-bar {
    transform-box: fill-box;
    transform-origin: center;
    transition: transform 220ms var(--ease-out), opacity 160ms ease;
  }
  .nav-burger.is-open .nb-bar-1 {
    transform: translateY(5px) rotate(45deg);
  }
  .nav-burger.is-open .nb-bar-2 { opacity: 0; }
  .nav-burger.is-open .nb-bar-3 {
    transform: translateY(-5px) rotate(-45deg);
  }

  /* Sheet — a floating rounded panel that unfurls FROM UNDER
     the nav pill. Sits BELOW the pill in z-order so the pill
     visibly covers its top edge. The panel is sized to its
     content (the menu items + CTA), with comfortable padding
     around all edges. Inset matches the pill (12px on each
     side). */
  .nav-sheet {
    position: fixed;
    /* Sit BELOW the pill with a clean ~7px gap. The nav pill's
       bottom edge lands at ~118px (60px top + 58px height), so we
       start the sheet at 125px. */
    top: calc(125px + env(safe-area-inset-top, 0px));
    left: 12px;
    right: 12px;
    bottom: auto;
    height: auto;
    z-index: 49; /* BELOW the pill (50) so the pill covers its top edge. */
    /* FROSTED-GLASS without backdrop-filter — backdrop-filter is
       unreliable inside the mobile-preview iframe (and on some
       real devices), so we fake it with layered translucent
       gradients + an inner highlight + grain texture. The result
       reads as glass against the warm bone page tone.

       Layer stack (top to bottom):
         1. A bright highlight gradient on the upper edge so the
            panel reads as a thick glass slab catching light
         2. A subtle warm tint (tan @ 60%) for body color
         3. A slightly translucent base so the page tone bleeds
            through softly, sustaining the "frosted" feel */
    background:
      linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.32) 0%,
        rgba(255, 255, 255, 0.08) 18%,
        rgba(255, 255, 255, 0) 60%
      ),
      linear-gradient(
        180deg,
        color-mix(in oklch, var(--krew-grain-warm, #DFD2B8) 97%, transparent) 0%,
        color-mix(in oklch, var(--krew-grain-warm, #DFD2B8) 98%, transparent) 100%
      );
    /* Keep backdrop-filter as a progressive enhancement — if the
       browser DOES support it (real iOS Safari often does), great. */
    backdrop-filter: blur(20px) saturate(160%);
    -webkit-backdrop-filter: blur(20px) saturate(160%);
    border: 1px solid rgba(28, 26, 24, 0.08);
    border-top-color: rgba(255, 255, 255, 0.5);
    border-radius: 18px;
    box-shadow:
      0 18px 40px rgba(28, 26, 24, 0.16),
      0 6px 14px rgba(28, 26, 24, 0.08),
      /* Subtle inset highlight along the top edge to sell the
         glass-slab feel */
      inset 0 1px 0 rgba(255, 255, 255, 0.35),
      inset 0 -1px 0 rgba(28, 26, 24, 0.04);
    display: flex;
    flex-direction: column;
    /* Even padding all sides. */
    padding: 18px 22px 22px;
    /* Animate via opacity only on the panel itself — height/max
       and overflow: hidden interfere with backdrop-filter on
       Chromium. The slide effect is handled by an inner wrapper
       (.nav-sheet-inner) so the panel stays geometrically
       stable while backdrop-filter samples the page. */
    transition: opacity 220ms ease;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }
  .nav-sheet.is-open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
  }
  /* Scrim — darkens the rest of the page while the menu is open.
     Sits BELOW the sheet (z 48 < sheet 49 < pill 50) so the nav
     pill and sheet stay bright while everything else dims.
     Tapping anywhere on the scrim closes the menu. */
  .nav-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 48;
    background: rgba(28, 26, 24, 0.3);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 240ms var(--ease-out);
  }
  .nav-scrim.is-open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
  }
  /* No close button needed — burger stays clickable on the pill
     above (z 50 > sheet 49). Hide the sheet's close button if
     present in markup. */
  .nav-sheet-close { display: none; }
  .nav-sheet a {
    display: block;
    padding: 14px 4px;
    border-bottom: 1px dashed var(--border-soft);
    font-size: 17px;
    font-weight: 700;
    letter-spacing: -0.005em;
    color: var(--fg-1);
    text-decoration: none;
  }
  /* First link's top padding is smaller — even visual rhythm. */
  .nav-sheet a:first-of-type { padding-top: 8px; }
  /* The CTA in the sheet stands out. Sits flush at the bottom of
     the sheet (with the sheet's padding around it). */
  .nav-sheet a.is-cta {
    margin-top: 16px;
    padding: 13px 18px;
    border: 1.5px solid var(--krew-ink);
    border-radius: 10px;
    background: var(--accent);
    color: #fff;
    text-align: center;
    box-shadow: 3px 3px 0 var(--krew-ink);
    font-size: 13px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    font-weight: 800;
  }
  .nav-sheet a.is-cta:active {
    transform: translate(1px, 1px);
    box-shadow: 2px 2px 0 var(--krew-ink);
  }
  /* The link directly above the CTA shouldn't have a dashed border
     (the CTA visually separates them). Same for any element
     just before the CTA. */
  .nav-sheet a:nth-last-of-type(2) { border-bottom: 0; }
  .nav-sheet .sheet-foot {
    /* Hidden in this compact sheet — keep markup but don't
       render. The sheet is short and content-sized. */
    display: none;
  }

  /* ---------- HERO ---------- */
  /* The pin and scroll animation stays. We just make it stack
     gracefully in one column. The continuous --p crossfade still
     drives both the text and the mockup transforms. */
  .hero-pin {
    /* Slightly less travel on mobile so the section doesn't feel
       like 1.5 viewports of dead-stop scroll. */
    height: 200vh;
  }
  .hero-stage {
    /* Tighter top — mock-card transforms have small upward tilt that
       still clears the floating nav pill at 120px. */
    padding-top: 120px;
    padding-bottom: 16px;
  }
  .hero-stage .container {
    align-items: stretch;
  }
  .hero-stage .hero-grid {
    /* The element doubles as `.container` and the parent rule
       `.hero-stage .container { display: flex }` wins over our
       `display: grid` declaration in this cascade. So lay out as
       a flex column on mobile instead — same stacking result, no
       overlap. */
    display: flex !important;
    flex-direction: column;
    grid-template-columns: 1fr;
    /* Tight gap so mock sits close to copy. */
    gap: 6px;
    padding-left: 0;
    align-items: stretch;
    /* Center each column horizontally */
    justify-items: center;
  }
  /* Email/SMS toggle and its hint are desktop-only — on mobile the
     copy + mock + CTA must all fit one viewport, and the user
     reads the rotation as ambient animation, not a control. */
  .hero-switcher-row { display: none !important; }
  .hero-stage .hero-grid > .hero-copy {
    text-align: center;
    max-width: 100%;
    width: 100%;
    /* Reorder: mock on top, copy below. The DOM order keeps the
       headline first for a11y/SEO; flex `order` swaps the visual
       arrangement only. */
    order: 2;
  }
  .hero-stage .hero-grid > .hero-copy .hero-flagship {
    margin-inline: auto;
  }
  .hero-stage .hero-grid > .hero-copy .hero-text-stack {
    /* Lock the stacked grid to the column width so the two layered
       text blocks don't stretch beyond the screen. */
    width: 100%;
  }
  .hero h1 {
    /* +15% for mobile legibility */
    font-size: clamp(37px, 10.58vw, 51px);
    line-height: 1.04;
    letter-spacing: -0.02em;
  }
  /* Lead: bumped 15% from 16px → 18.4px */
  .hero-lead {
    font-size: 18.4px;
    line-height: 1.45;
    margin-top: 12px;
    max-width: 32ch;
    margin-inline: auto;
  }
  .hero-ctas {
    margin-top: 14px;
    justify-content: center;
  }
  .hero-ctas .btn { padding: 12px 18px; font-size: 14px; }

  /* MOCK COLUMN — must NOT drift sideways on mobile. The desktop
     drift (translateX(50px * --p)) was a horizontal-layout trick
     and looks broken in a single column. Force it to zero. */
  .hero-mock {
    transform: none !important;
    padding-bottom: 0;
    gap: 0;
    width: 100%;
    /* Don't grab leftover flex space — size to mock-stack so the
       hero-stage (flex parent) doesn't push the mock to fill the
       residual viewport height. */
    flex: 0 0 auto;
    min-height: 0;
    /* Anchor mock to top of its area. With flex:1 + justify:center
       the dead space expanded symmetrically above and below. */
    justify-content: flex-start;
    /* Mock first, copy second (reordered via flex `order`). */
    order: 1;
  }
  .hero-switcher-row {
    /* Counter-drift was paired with hero-mock drift. Both gone. */
    transform: none !important;
    margin-top: 4px;
    flex-direction: column;
    gap: 8px;
  }
  .hero-caption {
    margin-left: 0;
    text-align: center;
    font-size: 16px;
  }

  /* MOCK STACK on mobile.
     We render BOTH the desktop and a simplified mobile mock inside
     each .mock-card; CSS toggles which one shows. The mobile mocks
     are sized to fit inside the stack at NATIVE font sizes (no
     transform: scale shrinking — text stays readable on iPhone).

     Desktop mocks (.email-card, .sms-phone) are display:none here.
     Mobile mocks (.email-card-mobile, .sms-phone-mobile) are
     display:block. The same --p crossfade still drives the parent
     .mock-card transforms, so the email→sms reveal still animates. */
  .mock-stack {
    width: 320px;
    /* Was 360px — the absolutely-centered cards left ~65px of dead
       space below them, opening a visible chasm to the headline.
       315px hugs the cards (~230px tall, centered) and halves the
       perceived gap between mock and copy. */
    height: 315px;
    transform-origin: center center;
    margin-block: 0;
    margin-inline: auto;
    /* Translate right as --p approaches 1 — compensates for the
       ghost email mock pulling the SMS-state composite leftward.
       NOTE: no scale here. Mobile mocks are sized natively. */
    transform: translateX(calc(var(--p, 0) * 24px));
    transition: transform 200ms var(--ease-out);
  }
  /* Hide DESKTOP mock contents on mobile — they have small text that
     becomes unreadable below their natural size. */
  .mock-stack .mock-email > .email-card,
  .mock-stack .mock-sms > .sms-phone { display: none; }
  /* SHOW the mobile mocks. */
  .mock-stack .mock-email > .email-card-mobile,
  .mock-stack .mock-sms > .sms-phone-mobile { display: block; }

  /* Soften the desktop card transforms on mobile — pure crossfade
     with a small horizontal drift, no diagonal splay. Both cards
     anchor at the stack center and translate slightly. The 3D
     rotates are removed — they were authored for a wider viewport
     and read as broken at this scale. */
  .mock-stack .mock-email {
    transform:
      translate(-50%, -50%)
      translate3d(calc(var(--p) * -40px), 0, 0)
      rotate(calc(1deg - var(--p) * 3deg))
      scale(calc(1 + var(--p) * 0.02));
  }
  .mock-stack .mock-sms {
    transform:
      translate(-50%, -50%)
      translate3d(calc(-40px + var(--p) * 40px), 0, 0)
      rotate(calc(-2deg + var(--p) * 2deg))
      scale(calc(0.96 + var(--p) * 0.04));
  }

  /* Hide the heavy ghost schedule card behind the email mock — it
     overlaps the screen edge and adds visual noise on a phone. */
  .ghost-card { display: none; }

  /* ===========================================================
     MOBILE MOCK STYLES
     Native font sizes, fewer elements, no scale shrinking.
     Both mocks are absolutely-positioned inside .mock-card so the
     parent's transform (driven by --p) crossfades them.
     =========================================================== */

  /* --- Email card (mobile variant) --- */
  .email-card-mobile {
    width: 290px;
    background: var(--bg-surface);
    border: 1px solid var(--krew-ink);
    border-radius: 10px;
    box-shadow: 4px 4px 0 var(--krew-ink), var(--shadow-3);
    overflow: hidden;
    font-family: var(--font-body, inherit);
  }
  /* Email window chrome — three traffic-light dots + label. Makes
     the card read instantly as an email/desktop window. */
  .emc-header {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 14px;
    border-bottom: 1px solid var(--border-hair);
    background: var(--krew-grain-pale);
    font-size: 10px;
    color: var(--fg-3);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }
  .emc-header .emc-dots { display: flex; gap: 5px; }
  .emc-header .emc-dots i {
    width: 9px; height: 9px; border-radius: 50%;
    background: var(--border-soft);
    display: inline-block;
  }
  .emc-header .emc-dots i:nth-child(1) { background: #E06C5E; }
  .emc-header .emc-dots i:nth-child(2) { background: #E8B13C; }
  .emc-header .emc-dots i:nth-child(3) { background: #7FB071; }
  .emc-body-wrap {
    padding: 14px 16px 16px;
  }
  .emc-meta {
    display: flex; align-items: center; gap: 10px;
    margin-bottom: 10px;
  }
  .emc-avatar { width: 30px; height: 30px; }
  .emc-who { display: flex; flex-direction: column; line-height: 1.2; }
  .emc-who strong {
    font-size: 13px; font-weight: 800; color: var(--fg-1);
  }
  .emc-who span {
    font-size: 11px; color: var(--fg-3);
  }
  .emc-subject {
    font-size: 16px;
    font-weight: 800;
    line-height: 1.25;
    letter-spacing: -0.01em;
    color: var(--fg-1);
    margin-bottom: 6px;
  }
  .emc-tag {
    display: inline-block;
    padding: 3px 8px;
    background: var(--krew-alert);
    color: #fff;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    border-radius: var(--r-pill);
    margin-bottom: 10px;
  }
  .emc-body {
    font-size: 13.5px;
    line-height: 1.45;
    color: var(--fg-2);
  }
  .emc-body strong { color: var(--fg-1); font-weight: 700; }

  /* --- SMS phone (mobile variant) ---
     Compact: 320px tall instead of 400. Header + thread + footer
     all tightened so the input sits at the bottom edge of the
     phone (not floating mid-screen). The thread NO LONGER takes
     `flex: 1` to grow — it sizes to its bubbles, with the footer
     directly beneath. The total height of all three pieces is
     content-driven; the phone collapses to fit. */
  .sms-phone-mobile {
    width: 280px;
    background: var(--bg-surface);
    border: 2px solid var(--krew-ink);
    border-radius: 28px;
    box-shadow: 4px 4px 0 var(--krew-ink), var(--shadow-3);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    font-family: var(--font-body, inherit);
  }
  .smsm-header {
    display: flex; align-items: center; gap: 8px;
    padding: 12px 16px 10px;
    border-bottom: 1px solid var(--border-hair);
    background: var(--krew-grain-pale);
    font-size: 13px;
    font-weight: 700;
    color: var(--fg-2);
  }
  .smsm-back { font-size: 22px; line-height: 1; color: var(--accent); font-weight: 800; }
  .smsm-info { margin-left: auto; color: var(--fg-3); font-size: 14px; }
  .smsm-who {
    display: flex; align-items: center; gap: 8px;
    flex: 1; justify-content: center;
  }
  .smsm-avatar {
    width: 24px; height: 24px; border-radius: 50%;
    background: var(--accent);
    border: 1px solid var(--krew-ink);
    overflow: hidden;
    flex-shrink: 0;
  }
  .smsm-avatar img { width: 100%; height: 100%; object-fit: cover; }
  .smsm-thread {
    /* No flex:1 — let the thread size to its content so the footer
       sits directly under the bubbles, not at the bottom of an
       oversized phone. */
    padding: 12px 12px 6px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-height: 100px; /* reserve space so the bubbles don't appear
       to spawn from the input bar; 100px ≈ 2 bubbles */
  }
  .smsm-bubble {
    max-width: 78%;
    padding: 9px 13px;
    border-radius: 16px;
    font-size: 14px;
    line-height: 1.35;
    border: 1px solid var(--krew-ink);
    animation: bubbleRise 360ms var(--ease-out) both;
    white-space: pre-line;
  }
  .smsm-bubble.smsm-out {
    align-self: flex-end;
    background: var(--krew-grain-pale);
    color: var(--fg-1);
    border-bottom-right-radius: 4px;
  }
  .smsm-bubble.smsm-in {
    align-self: flex-start;
    background: var(--krew-grain-warm);
    color: var(--fg-1);
    border-bottom-left-radius: 4px;
    box-shadow: 2px 2px 0 color-mix(in oklch, var(--accent) 30%, transparent);
  }
  .smsm-bubble.smsm-typing { padding: 10px 12px; }
  .smsm-thread.smsm-rewind > .smsm-bubble {
    animation: none;
    transition: opacity 280ms ease;
    opacity: 0.4;
  }
  .smsm-footer {
    padding: 10px 14px 12px;
    border-top: 1px solid var(--border-hair);
    font-size: 13px;
    color: var(--fg-3);
    background: var(--bg-surface);
    margin-top: auto; /* push footer to bottom IF parent has spare
       height (it doesn't, since flex doesn't grow), but keeps it
       glued under the thread when the thread is short */
  }
  .smsm-input {
    display: block;
    padding: 7px 14px;
    background: var(--krew-grain-pale);
    border: 1px solid var(--border-soft);
    border-radius: 999px;
    color: var(--fg-3);
  }

  /* The hero-flagship pill ("Live on a flagship TV series") was
     centered on desktop via `margin-inline: auto`. We already set
     text-align center on the copy block above; the inline-flex pill
     now sits between the centered text. Reset its left margin. */
  .hero-flagship { margin-inline: auto; }


  /* ---------- HOW IT WORKS — vertical, no pin ---------- */
  /* The pinned horizontal doc fan is sized 900x520 and clips at
     390px wide. Replace with a sequential vertical layout where
     each step is its own short section. Captions sit BELOW their
     corresponding mini doc-stack. No sticky, no pin-height math. */
  /* Section padding: was 60/24. With the header now pinned inside
     the stage, the section's own outer padding only frames the pin
     itself. Keep modest top padding so the pin doesn't bump the
     section above; bottom 0 — the pin's last viewport leaves
     natural breathing room. */
  .how-section { padding: 0; }
  /* Hide the desktop-positioned section-head; show the mobile-pinned
     one inside the stage. */
  .how-section-head-desktop { display: none !important; }
  .how-section-head-mobile { display: block; }
  .how-section .section-head { margin-bottom: 0; }
  .how-section .section-head .eyebrow-row { margin-bottom: 8px; }
  .how-section .section-head h2 {
    font-size: clamp(24px, 6.4vw, 32px);
    line-height: 1.1;
    margin: 0 0 8px;
  }
  .how-section .section-head p {
    font-size: 14px;
    line-height: 1.45;
    margin: 0;
  }

  /* MOBILE — keep the desktop pin animation alive, flip the layout
     to vertical (docs stack with translateY instead of translateX,
     overlays slide in from below the doc stack). The JS phase math
     and CSS vars (--fan, --read, --report-in/out, --reply-in,
     --blue-glow) work unchanged. */
  .how-pin {
    /* JS reads getBoundingClientRect on .how-pin to compute scroll
       travel = pinHeight - viewportHeight. Keep the desktop math:
       N steps × 100vh of dwell. */
    /* (no override — desktop's `${steps.length * 100}vh` inline
       style is what we want here too) */
  }
  .how-stage {
    /* Sticky pin clears the floating nav. */
    position: sticky;
    top: 64px;
    height: calc(100vh - 64px);
    min-height: 520px;
    padding: 0;
    overflow: hidden;
  }
  .how-stage-inner {
    display: grid;
    grid-template-rows: auto auto auto;
    grid-template-columns: 1fr;
    height: 100%;
    /* Top padding bumped to 64px so the eyebrow has ~16px clearance
       below the floating nav (nav bottom sits ~117px from page top;
       stage top at 64px + 64px padding = 128px which puts the
       eyebrow comfortably below the nav). */
    padding: 64px 0 12px;
    row-gap: 0;
    align-content: start;
  }
  .how-stage-inner > .how-section-head-mobile {
    grid-row: 1;
    padding: 0 16px;
    margin: 0 0 4px;
    text-align: left;
  }
  .how-stage-inner > .how-visual {
    display: flex;
    grid-row: 2;
    align-items: center;
    justify-content: center;
    min-height: 0;
    /* Generous breathing room above and below the visual block —
       captions still sit close because the visual-stage is sized
       tight to the doc fan. */
    margin: 72px 0 16px;
  }
  .how-stage-inner > .how-captions {
    display: block;
    grid-row: 3;
    /* Compact caption block — tighter than desktop's 132px. */
    height: 110px;
    max-width: 320px;
    /* Zero top margin: the captions hug the visual. The visual
       itself is 360px tall and centered; we want NO extra gap
       between its bottom edge and the step-number eyebrow. */
    margin: 0 auto;
    padding: 0 16px;
  }
  /* Override the desktop .how-captions { margin: 16px auto 0 } and
     center the captions in the available space below the visual.
     Visual block is 380px tall with margin: 56px 0 -8px; captions
     are 110px tall — visually centering them in the residual stage
     height needs a small positive top margin (rather than the prior
     -8px overlap) so the gap above and below the caption text is
     balanced. */
  .how-stage-inner > .how-captions { margin-top: 32px; }

  /* Hide the static fallback list — replaced by the live animation. */
  .how-mobile-steps { display: none !important; }

  /* The doc-fan stage shrinks to phone width AND height. The visible
     doc stack only fills the top ~280px of its stage (docs anchor at
     top:24px and span ~260px tall). Stage height was 380 → cut to
     300 to eliminate the dead space below the docs that pushed the
     captions far away. */
  .how-visual-stage {
    --how-zoom: 1;
    width: 100%;
    max-width: 360px;
    height: 250px;
    max-height: none;
    margin: 0 auto;
    position: relative;
    isolation: isolate;
  }
  /* Step 4 scrim — fades in BEHIND the reply overlay to dim the
     busy doc stack underneath. Same color as the section background
     so it reads as a soft wash rather than a panel. Sits ABOVE
     the docs (z-index ≤10) and BELOW the overlays (z-index 20).
     Generous overshoot so the WHITE doc's lifted title strip is
     fully covered; the section-head above is lifted via z-index
     so the wash never reads onto the paragraph. */
  .how-visual-stage::before {
    content: "";
    position: absolute;
    inset: -160px -40px -40px;
    background: var(--krew-grain-pale);
    /* 0.5 wash — softer dim that lets the docs read faintly behind
       the reply exchange instead of fully washing out. */
    opacity: calc(var(--reply-in, 0) * 0.5);
    pointer-events: none;
    z-index: 15;
    transition: opacity 80ms linear;
  }
  /* Hide the supporting paragraph on mobile — the headline alone
     carries the section, and the saved height lets the visual +
     captions breathe within the pinned stage. */
  .how-stage-inner > .how-section-head-mobile p { display: none; }
  /* Lift the section-head above the scrim's overshoot region so
     the headline is never washed by the step-4 scrim. */
  .how-stage-inner > .how-section-head-mobile {
    position: relative;
    z-index: 30;
  }


  /* DOCS — keep a TIGHT stack on mobile. Each step's overlay layers
     ON TOP of the stack rather than appearing beside it as a separate
     graphic. The fan is intentionally minimal (~4px peek per doc) so
     the BLUE schedule shows just the top edge from behind the white
     ones — enough to read as a multi-doc stack, not a spread.

     The desktop rule fans horizontally; we override:
     - translateY by --offset * tiny-fan instead (vertical peek)
     - kill the report-in shift (overlay covers stack instead of
       displacing it) */
  .how-visual-stage .how-doc {
    width: 220px;
    height: 144px;
    left: calc(50% - 110px);
    /* Anchor stack toward the upper portion of the new shorter
       stage — overlays still fit beneath. */
    top: 24px;
    /* Wider 3D spread so the WHITE schedule's label peeks out
       behind the BLUE on top. Vertical peek is what makes the
       title strips of underlying docs read — ~10px Y per offset
       step lifts the next doc enough that its title row clears
       the doc above (titles sit ~14px from doc top). */
    /* Y peek bumped: 10 + 20*fan per offset. WHITE (--offset:-2)
       lifts up to ~60px above center at fan=1, so its full title
       row clears BLUE's top edge by a comfortable margin. */
    transform:
      translate(
        calc(var(--offset) * (6px + 9px * var(--fan, 0))),
        calc(var(--offset) * (10px + 20px * var(--fan, 0)))
      )
      rotate(calc(var(--offset) * (1deg + 1deg * var(--fan, 0))));
  }
  .how-visual-stage .how-doc.is-blue {
    z-index: calc(2 + 8 * var(--blue-glow, 0));
    /* Nudge BLUE down ~14px so it clearly reads as the NEW doc
       arriving on top of the stack — separated from WHITE peeking
       above it. */
    transform:
      translate(
        calc(var(--offset) * (6px + 9px * var(--fan, 0))),
        calc(
          var(--offset) * (10px + 20px * var(--fan, 0))
          + 14px * var(--fan, 0)
          - 8px * var(--read, 0)
        )
      )
      rotate(calc(var(--offset) * (1deg + 1deg * var(--fan, 0)) - 1deg * var(--read, 0)));
  }
  /* WHITE schedule (doc-0) — extra counter-clockwise tilt on mobile
     so it reads clearly as a discarded prior version peeking out
     from behind the BLUE on top. The base --offset/--fan transform
     is preserved; we add an extra -15deg rotation that fades in
     with --fan. */
  .how-visual-stage .how-doc.how-doc-0 {
    transform:
      translate(
        calc(var(--offset) * (6px + 9px * var(--fan, 0))),
        calc(var(--offset) * (10px + 20px * var(--fan, 0)))
      )
      rotate(calc(
        var(--offset) * (1deg + 1deg * var(--fan, 0))
        - 3deg * var(--fan, 0)
      ));
  }
  /* Read-highlight rails: anchored to the BLUE doc itself (which is
     still tight in the stack on mobile) — tightened widths to fit
     220px doc. */
  .how-visual-stage .how-hit-1 { top: 38px; width: calc(140px * var(--read, 0)); }
  .how-visual-stage .how-hit-2 { top: 60px; width: calc(108px * var(--read, 0)); }
  .how-visual-stage .how-hit-3 { top: 82px; width: calc(72px * var(--read, 0)); }

  /* OVERLAYS — sit ON TOP of the stack, integrated as one composition.
     All three overlays anchor to the SAME vertical region (lower
     portion of the stage), overlapping the lower half of the doc
     stack so the BLUE/WHITE schedules peek out the TOP. The read →
     report → reply transition is a crossfade in place, with small
     Y nudges for distinct beats — not three different positions.

     Doc stack on mobile spans roughly y=140-325 in the 606px stage.
     Overlays start at y~245 — covering the bottom third of the stack
     so the schedules peek out above. */
  .how-visual-stage .how-overlay {
    /* Strong layering: card-on-card needs explicit chrome to read
       cleanly when overlapping the doc stack underneath. */
    z-index: 30;
  }
  .how-visual-stage .how-overlay-read {
    right: auto; left: 50%; top: 105px; bottom: auto;
    width: 290px;
    padding: 12px 14px;
    box-shadow: 4px 4px 0 var(--krew-ink), 0 8px 24px rgba(28,26,24,0.18);
    transform:
      translateX(-50%)
      translateY(calc((1 - var(--read-in, 0)) * 14px));
  }
  .how-visual-stage .how-overlay-read .how-overlay-eyebrow { font-size: 9px; margin-bottom: 6px; }
  .how-visual-stage .how-overlay-read .how-overlay-body { font-size: 11px; gap: 4px; }

  .how-visual-stage .how-overlay-report {
    right: auto; left: 50%; top: 100px; bottom: auto;
    width: 290px;
    transform:
      translateX(-50%)
      rotate(calc(var(--report-in, 0) * 1.5deg))
      translateY(calc((1 - var(--report-in, 0)) * 14px));
  }
  /* Strengthen the email card's elevation so it reads as on-top */
  .how-visual-stage .how-overlay-report .how-email-mini {
    box-shadow: 5px 5px 0 var(--krew-ink), 0 12px 28px rgba(28,26,24,0.22);
  }

  .how-visual-stage .how-overlay-reply {
    /* Reply card stack is ~25px taller than the email card; pull
       it up so its BOTTOM aligns with where the email card bottoms
       out. Keeps the composition's visual baseline consistent
       across the report→reply transition. */
    right: auto; left: 50%; top: 55px; bottom: auto;
    width: 300px;
    transform:
      translateX(-50%)
      translateY(calc((1 - var(--reply-in, 0)) * 14px));
  }
  /* Compact the reply bubbles on mobile */
  .how-visual-stage .how-overlay-reply .how-reply-user,
  .how-visual-stage .how-overlay-reply .how-reply-krew {
    font-size: 11.5px;
    padding: 8px 12px;
  }
  /* Reply card-stack elevation: each bubble feels distinct from the
     stack of docs underneath. */
  .how-visual-stage .how-overlay-reply .how-reply-user {
    box-shadow: 3px 3px 0 var(--krew-ink), 0 6px 18px rgba(28,26,24,0.15);
  }
  .how-visual-stage .how-overlay-reply .how-reply-krew {
    box-shadow: 3px 3px 0 color-mix(in oklch, var(--accent) 50%, transparent), 0 8px 22px rgba(28,26,24,0.18);
  }

  /* Captions: smaller, fixed footer block. Title trimmed for the
     short caption row that sits below the visual. */
  .how-caption-title { font-size: 19px; line-height: 1.18; }
  .how-caption-body { font-size: 13px; line-height: 1.4; }
  .how-caption-step {
    font-size: 10px;
    padding: 4px 8px;
  }
  .how-caption-step-num { font-size: 12px; }

  /* Per-step block: number + title + body + small visual. */
  .how-mobile-steps {
    display: flex;
    flex-direction: column;
    gap: 28px;
    padding-top: 8px;
  }
  .how-mstep {
    display: grid;
    grid-template-columns: 1fr;
    gap: 14px;
    padding: 22px 20px 22px;
    background: var(--bg-raised);
    border: 1px solid var(--krew-ink);
    border-radius: var(--r-3);
    box-shadow: 4px 4px 0 var(--krew-ink);
    position: relative;
  }
  .how-mstep .how-mstep-num {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 11px; font-weight: 700;
    letter-spacing: 0.14em;
    color: var(--fg-3);
    text-transform: uppercase;
  }
  .how-mstep .how-mstep-num strong {
    color: var(--accent);
    font-size: 13px;
    font-weight: 800;
  }
  .how-mstep .how-mstep-title {
    margin: 0;
    font-size: 22px;
    font-weight: 800;
    letter-spacing: -0.015em;
    line-height: 1.2;
    color: var(--fg-1);
  }
  .how-mstep .how-mstep-body {
    margin: 0;
    font-size: 15px;
    line-height: 1.5;
    color: var(--fg-2);
    text-wrap: pretty;
    max-width: 36ch;
  }
  /* Small in-card visual — uses the same vocabulary (mini doc strips,
     mini email card, mini reply bubbles) as desktop but vertical. */
  .how-mstep-visual {
    margin-top: 4px;
    border-top: 1px dashed var(--border-soft);
    padding-top: 14px;
    min-height: 96px;
    position: relative;
  }
  .how-mstep-docs {
    display: flex;
    gap: 6px;
    align-items: stretch;
    height: 88px;
  }
  .how-mstep-docs .md-doc {
    flex: 1;
    min-width: 0;
    background: var(--bg-surface);
    border: 1px solid var(--krew-ink);
    border-radius: 4px;
    padding: 8px 8px 6px;
    position: relative;
    overflow: hidden;
  }
  .how-mstep-docs .md-doc.is-blue { background: #BBD4E8; }
  .how-mstep-docs .md-doc.is-white { background: #FBF7EC; }
  .how-mstep-docs .md-doc.is-warm { background: #FBF7EC; }
  .how-mstep-docs .md-doc h6 {
    margin: 0 0 6px;
    font-size: 8px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: rgba(28, 26, 24, 0.55);
    font-weight: 800;
  }
  .how-mstep-docs .md-doc i {
    display: block;
    height: 4px;
    margin-bottom: 3px;
    background: rgba(28, 26, 24, 0.18);
    border-radius: 1px;
  }
  .how-mstep-docs .md-doc i:nth-child(2) { width: 80%; }
  .how-mstep-docs .md-doc i:nth-child(3) { width: 95%; }
  .how-mstep-docs .md-doc i:nth-child(4) { width: 60%; }
  /* Step 1: just three docs, blue lifted */
  .how-mstep[data-step="0"] .md-doc.is-blue {
    transform: translateY(-6px);
    box-shadow: 3px 3px 0 var(--accent);
  }
  /* Step 2: BLUE doc with diff arrows overlaid */
  .how-mstep[data-step="1"] .md-doc.is-blue { position: relative; }
  .how-mstep[data-step="1"] .md-doc.is-blue::before {
    content: "Δ";
    position: absolute; top: 4px; right: 6px;
    font-weight: 900; font-size: 10px;
    color: var(--accent);
  }
  /* Step 3: mini email card */
  .how-mstep-email {
    background: var(--bg-surface);
    border: 1px solid var(--krew-ink);
    border-radius: 6px;
    padding: 10px 12px;
    box-shadow: 3px 3px 0 var(--krew-ink);
  }
  .how-mstep-email .me-from {
    display: flex; align-items: center; gap: 8px;
    font-size: 11px; font-weight: 800;
    letter-spacing: 0.04em;
    color: var(--fg-1);
    margin-bottom: 6px;
  }
  .how-mstep-email .me-from .me-avatar {
    width: 18px; height: 18px; border-radius: 50%;
    background: var(--accent);
    overflow: hidden;
    border: 1px solid var(--krew-ink);
    flex-shrink: 0;
  }
  .how-mstep-email .me-from .me-avatar img { width: 100%; height: 100%; display: block; }
  .how-mstep-email .me-subj {
    font-size: 12px; font-weight: 800;
    margin-bottom: 4px;
    line-height: 1.3;
  }
  .how-mstep-email .me-snip {
    font-size: 11px;
    color: var(--fg-3);
    line-height: 1.45;
  }
  .how-mstep-email .me-cta {
    margin-top: 6px;
    font-size: 10px;
    font-weight: 800;
    color: var(--accent);
    letter-spacing: 0.06em;
    text-transform: uppercase;
  }
  /* Step 4: tiny SMS exchange */
  .how-mstep-sms {
    display: flex;
    flex-direction: column;
    gap: 6px;
  }
  .how-mstep-sms .ms-bubble {
    max-width: 80%;
    padding: 7px 10px;
    border-radius: 8px;
    font-size: 11.5px;
    line-height: 1.35;
    border: 1px solid var(--krew-ink);
  }
  .how-mstep-sms .ms-bubble.in {
    align-self: flex-start;
    background: var(--accent);
    color: #fff;
    border-bottom-left-radius: 2px;
  }
  .how-mstep-sms .ms-bubble.out {
    align-self: flex-end;
    background: var(--krew-grain-warm);
    color: var(--fg-1);
    border-bottom-right-radius: 2px;
    box-shadow: 2px 2px 0 color-mix(in oklch, var(--accent) 30%, transparent);
    border-color: var(--accent);
  }


  /* ---------- FOUNDERS — mobile: portrait left, bio right ---------- */
  /* On mobile each card becomes a 2-column row: small portrait on the
     left, name/role/bio block on the right. Left-justified to match
     the section headline. The .founders-grid wrapper still drives the
     single-column stack via its own max-width override at 900px. */
  .founders-grid {
    /* Let the cards span the available width on mobile rather than
       being capped at 320px (which made the portrait dominate).
       Roomier row gap so the stacked name + role + bio block has
       breathing room from the next founder card. */
    max-width: none;
    gap: 44px;
  }
  .founder-card {
    display: grid;
    grid-template-columns: 120px 1fr;
    grid-template-rows: auto auto;
    grid-template-areas:
      "portrait meta"
      "role     meta";
    column-gap: 20px;
    row-gap: 8px;
    align-items: start;
    text-align: left;
    padding-left: 10px;
  }
  .founder-portrait { grid-area: portrait; }
  .founder-meta { grid-area: meta; }
  /* The role caption uses the card's own ::before so it can sit in
     its own grid cell directly under the portrait — outside the
     polaroid's rotated box, in the natural document flow. Reads
     like a quick scribble beneath the photo. */
  .founder-card::before {
    content: var(--role-label, "");
    grid-area: role;
    justify-self: center;
    width: 120px;
    text-align: center;
    margin-top: 10px;
    font-family: var(--font-hand);
    font-size: 24px;
    font-weight: 400;
    line-height: 1;
    letter-spacing: 0.01em;
    color: var(--accent);
    /* Slight rotation so it reads as a hand-jotted annotation
       rather than a typeset label. */
    transform: rotate(-3deg);
  }
  .founder-portrait {
    width: 120px;
    margin: 0;
  }
  .founder-meta {
    text-align: left;
    width: auto;
    max-width: none;
    margin: 0;
    padding: 0;
  }
  /* On mobile, the role goes BESIDE the name (not below it), so the
     two share a baseline-aligned row. The role drops to a small mono
     tag flush against the right edge of that row. */
  /* Mobile: hide the inline role badge in the name row — the role
     (CEO / COO / CTO) is rendered as a hand-written annotation
     directly below the portrait via .founder-card::before above. */
  .founder-name-row {
    flex-wrap: nowrap;
    gap: 10px;
  }
  .founder-name-row .founder-name {
    font-size: 18px;
  }
  .founder-name-row .founder-role {
    /* Hidden on mobile — the caption under the portrait carries
       the role instead. Desktop layout still uses this span. */
    display: none;
  }
  .founder-bio {
    margin-top: 8px;
    font-size: 14px;
    line-height: 1.5;
    text-wrap: pretty;
  }


  /* ---------- TESTIMONIAL (compact inline) — center it ---------- */
  /* The compact variant is left-aligned by default for sitting in a
     2-column grid. On mobile it's effectively full-width — center
     the QUOTE for editorial weight, but anchor the attribution row
     (portrait + name + role) to the LEFT so the name lines up flush
     against the portrait edge. */
  .testimonial-pull-compact {
    text-align: center;
    /* Cap width so the card sits inset from the section's side
       padding — gives a bit more visual margin on the left and
       right and helps the card feel like a contained unit rather
       than full-bleed. */
    margin: 24px auto 0;
    max-width: 320px;
    width: 100%;
    /* On mobile only, upgrade from a divider rule to a discrete
       callout card — faint warm-toned bg, 1px hairline border.
       Bottom padding is slightly heavier than top to compensate
       for the optical asymmetry: the quote's cap-height sits high
       in its line-box so it visually hugs the top edge unless the
       bottom is given a touch more room. */
    padding: 24px 16px 28px;
    background: color-mix(in oklch, var(--krew-grain-warm) 55%, var(--bg-page));
    border: 1px solid var(--border-hair);
    border-top: 1px solid var(--border-hair);
    border-radius: var(--r-3);
  }
  /* Strip the inner figure's own first/last-child margins so the
     card's padding isn't being eaten by them — otherwise the quote
     has its blockquote margin pushing it down and the attribution
     has its margin-top pushing it down further. */
  .testimonial-pull-compact > .testimonial-pull-quote:first-child,
  .testimonial-pull-compact > *:first-child {
    margin-top: 0;
  }
  .testimonial-pull-compact > *:last-child {
    margin-bottom: 0;
  }
  /* Re-tone the portrait halo's inner ring to blend with the new
     card bg instead of the page bg. */
  .testimonial-pull-compact .testimonial-pull-portrait {
    box-shadow:
      0 0 0 3px color-mix(in oklch, var(--krew-grain-warm) 55%, var(--bg-page)),
      0 0 0 4px var(--accent);
  }
  .testimonial-pull-compact .testimonial-pull-attrib {
    /* Center the entire attribution block (portrait + byline) under
       the centered quote, but keep the byline TEXT left-justified
       so the name sits flush against the portrait edge. */
    justify-content: center;
    flex-wrap: nowrap;
    width: max-content;
    max-width: 100%;
    margin-left: auto;
    margin-right: auto;
  }
  .testimonial-pull-compact .testimonial-pull-byline {
    text-align: left;
    align-items: flex-start;
  }


  /* ---------- TWEAKS PANEL ---------- */
  /* Slim it down so it doesn't overflow the screen on phones. */
  .tweaks-panel {
    width: calc(100vw - 24px);
    max-width: 320px;
    bottom: 12px;
    right: 12px;
  }


  /* ---------- DAY/NIGHT TOGGLE ---------- */
  /* On mobile, hide the day/night glyph by default — the corner is
     too cramped on a phone for a persistent FAB. Reveal it only
     when the hamburger menu is open, so the toggle rides along
     with the navigation chrome and disappears with it. The toggle
     is a sibling of <nav>; we use the general-sibling combinator
     against `.nav.is-menu-open`. */
  .day-night {
    bottom: 12px;
    right: 12px;
    width: 28px;
    height: 28px;
    opacity: 0;
    transform: scale(0.85);
    pointer-events: none;
    transition: opacity 200ms ease, transform 200ms var(--ease-out, cubic-bezier(.2,.8,.2,1));
  }
  .nav.is-menu-open ~ .day-night {
    opacity: 1;
    transform: scale(1);
    pointer-events: auto;
  }
}

@media (max-width: 560px) {
  /* Tighter container gutters on narrow phones */
  .container { width: min(1240px, 100% - 28px); }

  /* Hero copy padding finer (+15% bump) */
  .hero h1 { font-size: clamp(32px, 9.66vw, 44px); }
  .hero-lead { font-size: 16.1px; }

  /* Section padding tighter */
  .section { padding: 60px 0; }
  .section-head { margin-bottom: 36px; }
  .section-head h2 { font-size: clamp(26px, 7vw, 36px); }
  .section-head p { font-size: 15px; }

  /* Pillars: slim the illustration height a bit */
  .pillar { padding: 22px 18px 20px; }
  .pillar h3 { font-size: 18px; }
  .pillar p { font-size: 14px; }
}

