/* Settl landing — story-driven, parallax, AI-agent narrative */
:root {
  --bg: #FFFFFF;
  --bg-warm: #F4F4F5;
  --surface: #FFFFFF;
  --text: #14140F;
  --text-sec: #66645E;
  --text-ter: #74726B; /* was #98968F (3.0:1); now ≈ 4.6:1 on white → AA */
  --border: rgba(20,20,20,0.10);
  --divider: rgba(20,20,20,0.08);
  --accent: #FF6B35;
  --accent-soft: #FFE6D9;
  --accent-deep: #C24A1F;
  --pos: #1F8F4D;
  --neg: #C8482E;
  --serif: 'Source Serif 4', 'Tiempos Text', Georgia, serif;
  --sans: 'Inter Tight', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, Menlo, monospace;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
html, body { margin: 0; padding: 0; background: var(--bg); color: var(--text); font-family: var(--sans); -webkit-font-smoothing: antialiased; }
body { overflow-x: hidden; }
a { color: inherit; text-decoration: none; }
::selection { background: var(--accent); color: #fff; }

/* ───── NAV ───── */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 28px;
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  background: rgba(255,255,255,0.65);
  border-bottom: 1px solid transparent;
  transition: border-color 200ms, background 200ms;
}
.nav.scrolled { border-bottom-color: var(--divider); background: rgba(255,255,255,0.85); }
.nav-brand { display: flex; align-items: center; gap: 10px; font-family: var(--serif); font-size: 22px; font-weight: 600; letter-spacing: -0.4px; }
/* Wordmark variant — italic 700 "settl" + ember period, matching the
   iOS app icon and the Flutter splash glyph. Single brand mark across
   every surface. */
.nav-brand-wordmark { gap: 8px; }
.brand-wordmark { font-family: var(--serif); font-size: 26px; font-weight: 700; letter-spacing: -1.1px; line-height: 1; color: var(--text); }
.brand-wordmark em { font-style: italic; font-weight: 700; }
.brand-wordmark .brand-dot { color: var(--accent); font-style: normal; font-weight: 700; }
.brand-beta {
  margin-left: 2px;
  padding: 2px 7px 1px;
  border: 1px solid var(--border);
  border-radius: 9999px;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--text-ter);
  line-height: 1;
}
.nav-links { display: flex; gap: 28px; align-items: center; font-size: 14px; color: var(--text-sec); }
.nav-links a { transition: color 150ms; }
.nav-links a:hover { color: var(--text); }
.nav-cta {
  padding: 9px 18px; border-radius: 9999px;
  background: var(--text); color: var(--bg);
  font-weight: 600; font-size: 14px;
  white-space: nowrap;
  transition: transform 200ms;
}
.nav-cta:hover { transform: translateY(-1px); }
@media (max-width: 720px) { .nav-links { display: none; } }

/* ───── ENTRANCE CHOREOGRAPHY ─────
   One signature page-load: the nav drops, then the hero rises in a single
   staggered breath (eyebrow → headline → sub → CTA → mic). Pure transform +
   opacity, ease-out-expo for a confident, decisive settle. `backwards` fill
   holds each element at its start state through its delay so nothing flashes
   visible-then-hidden. The reduced-motion block below zeroes both duration AND
   delay, so these resolve to their end state instantly for those users. */
@keyframes riseIn { from { opacity: 0; transform: translateY(22px); } to { opacity: 1; transform: none; } }
@keyframes riseMic { from { opacity: 0; transform: scale(0.82); } to { opacity: 1; transform: scale(1); } }
@keyframes navDrop { from { opacity: 0; transform: translateY(-12px); } to { opacity: 1; transform: none; } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

.nav            { animation: navDrop 0.6s cubic-bezier(0.16,1,0.3,1) backwards; }
.hero h1        { animation: riseIn 0.8s cubic-bezier(0.16,1,0.3,1) 0.06s backwards; }
.hero-sub       { animation: riseIn 0.7s cubic-bezier(0.16,1,0.3,1) 0.18s backwards; }
.hero-cta       { animation: riseIn 0.7s cubic-bezier(0.16,1,0.3,1) 0.28s backwards; }
.hero .cta-qr   { animation: riseIn 0.7s cubic-bezier(0.16,1,0.3,1) 0.36s backwards; }
/* The demo stage carries the brand's signature object (the mic) — it arrives
   a beat after the headline with a gentle scale-up, so it reads as
   "powering on" rather than sliding in. */
.hero-stage     { animation: riseMic 0.9s cubic-bezier(0.16,1,0.3,1) 0.30s backwards; }
.lang-strip     { animation: fadeIn 0.8s ease 0.55s backwards; }

/* Scroll-triggered reveal for the static lower sections. landing.js adds
   `.reveal-ready` to <html> and `.reveal` to each target, then `.in` once it
   scrolls into view. Initial-hidden state is gated behind `.reveal-ready` so a
   no-JS visitor sees everything; reduced-motion shows it all immediately. */
html.reveal-ready .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s cubic-bezier(0.16,1,0.3,1), transform 0.7s cubic-bezier(0.16,1,0.3,1);
  transition-delay: var(--reveal-delay, 0ms);
}
html.reveal-ready .reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  html.reveal-ready .reveal { opacity: 1; transform: none; transition: none; }
}

/* ───── HERO (asymmetric split: copy left, live voice demo right) ───── */
.hero {
  position: relative; min-height: 100dvh;
  display: flex; align-items: center; justify-content: center;
  /* Bottom padding reserves room for the language ribbon pinned to the
     hero's bottom edge, so it shows at rest in the first viewport. */
  padding: 110px 24px 150px; overflow: hidden;
}
.hero-bg {
  position: absolute; inset: 0; z-index: 0;
  background:
    radial-gradient(ellipse 70% 60% at 72% 42%, rgba(255,107,53,0.10), transparent 62%),
    radial-gradient(ellipse 50% 40% at 10% 88%, rgba(255,160,107,0.07), transparent 60%),
    var(--bg);
}
.hero-grid {
  position: relative; z-index: 2;
  width: 100%; max-width: 1140px;
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(36px, 6vw, 80px); align-items: center;
}
.hero-content { text-align: left; max-width: 560px; }
.hero h1 {
  font-family: var(--serif);
  font-size: clamp(40px, 5.4vw, 68px);
  font-weight: 500;
  line-height: 1.1; /* italic descenders in "splitting expenses." need ≥1.1 to clear */
  letter-spacing: -2px;
  margin: 0 0 22px; padding-bottom: 2px;
}
.hero h1 em { font-style: italic; color: var(--accent-deep); font-size: inherit; line-height: inherit; }
.hero-sub {
  font-size: clamp(16px, 1.5vw, 19px);
  color: var(--text-sec); line-height: 1.55;
  max-width: 46ch; margin: 0 0 30px;
  text-wrap: pretty;
}
.hero-cta { display: flex; gap: 12px; justify-content: flex-start; flex-wrap: wrap; }

/* ─── Demo stage — mic, typed sentence, parsed expense card ───
   The product loop ("say it → it's logged") demonstrated in the first
   viewport, in the app's own card language. */
.hero-stage {
  position: relative; min-height: 470px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 20px;
}
/* Orbital lines — agent "thinking" feel. The div is nested inside
   .hero-mic-wrap, so every dashed circle is concentric with the waveform
   disc (not with the taller stage). */
.hero-orbits { position: absolute; inset: 0; pointer-events: none; display: grid; place-items: center; }
.hero-orbits .ring {
  position: absolute; border-radius: 50%;
  border: 1px dashed rgba(255,107,53,0.16);
  animation: orbit 60s linear infinite;
}
.hero-orbits .ring.r1 { width: 320px; height: 320px; }
.hero-orbits .ring.r2 { width: 470px; height: 470px; animation-direction: reverse; animation-duration: 90s; }
.hero-orbits .ring.r3 { width: 640px; height: 640px; animation-duration: 120s; }
@keyframes orbit { to { transform: rotate(360deg); } }
.hero-bubble {
  position: relative; z-index: 2;
  min-height: 64px; max-width: 350px;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); border: 1px solid var(--border);
  padding: 12px 20px; border-radius: 20px 20px 20px 5px;
  font-family: var(--serif); font-style: italic;
  font-size: 15.5px; line-height: 1.4; text-align: center; color: var(--text);
  box-shadow: 0 10px 30px rgba(20,18,14,0.08);
}
.hero-bubble .caret {
  display: inline-block; width: 1px; height: 1em;
  background: var(--accent-deep); margin-left: 1px;
  vertical-align: -2px;
  animation: caretBlink 0.9s steps(1) infinite;
}
.hero-bubble, .hero-exp-card { transition: opacity 380ms ease, transform 480ms cubic-bezier(.2,.9,.3,1); }
.hero-bubble.out { opacity: 0; }
.hero-exp-card {
  position: relative; z-index: 2;
  width: 300px;
  background: var(--surface); padding: 14px 18px; border-radius: 16px;
  display: flex; align-items: center; gap: 12px;
  border: 1px solid var(--border);
  box-shadow: 0 14px 34px rgba(20,18,14,0.10);
}
.hero-exp-card .icon { width: 34px; height: 34px; border-radius: 10px; background: var(--accent-soft); color: var(--accent-deep); display: grid; place-items: center; flex-shrink: 0; }
.hero-exp-card .meta { flex: 1; min-width: 0; }
.hero-exp-card .meta .t { font-size: 14px; font-weight: 500; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hero-exp-card .meta .s { font-size: 11px; color: var(--text-sec); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hero-exp-card .amt { font-family: var(--serif); font-size: 17px; font-weight: 500; color: var(--accent-deep); }
/* landing.js flags the stage once the demo cycle is live; only then does the
   card hide between examples. No-JS / reduced-motion visitors keep the
   static first example. */
.hero-stage.demo-live .hero-exp-card { opacity: 0; transform: translateY(12px); }
.hero-stage.demo-live .hero-exp-card.show { opacity: 1; transform: none; }

.btn {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 15px 26px; border-radius: 9999px;
  font-family: var(--sans); font-weight: 600; font-size: 15px;
  border: none; cursor: pointer;
  transition: transform 200ms, box-shadow 200ms;
}
/* Deep ember fill so white text clears WCAG AA (#fff on #C24A1F ≈ 4.9:1; the
   bright #FF6B35 was 2.8:1). The ember glow stays for the brand warmth. */
.btn-primary { background: var(--accent-deep); color: #fff; box-shadow: 0 6px 20px rgba(194,74,31,0.38); }
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 10px 28px rgba(255,107,53,0.5); }
.btn-ghost { background: transparent; color: var(--text); border: 1px solid var(--border); }
.btn-ghost:hover { background: rgba(20,18,14,0.04); }

/* Press feedback — a quick dip on tap so the button feels physical. Placed
   after :hover (equal specificity) so the pressed state wins while held;
   the shorter duration makes the press read as snappier than the release. */
.btn:active { transition-duration: 90ms; }
.btn-primary:active { transform: translateY(0) scale(0.97); box-shadow: 0 4px 14px rgba(194,74,31,0.34); }
.btn-ghost:active { transform: scale(0.97); }
.nav-cta:active { transform: translateY(0) scale(0.97); }

/* Keyboard focus — a visible ring on every interactive element (the buttons
   had none). :where() keeps specificity flat; the outline follows each shape. */
:where(.btn, .nav-cta, .nav-links a, .story-skip, .cta-alt, .cta-qr-sub a,
  .footer-col a, .story-progress .step):focus-visible {
  outline: 2px solid var(--accent-deep);
  outline-offset: 3px;
}
/* ─── Device-aware CTA ───────────────────────────────────────────────
   One clear primary per device — main.js sets html[data-device]. On mobile the
   non-matching store button is demoted to a quiet text link; on desktop (can't
   install) the store buttons hide and a "scan to install" QR shows. No JS →
   no data-device → both buttons show + QR hidden (graceful fallback). */
.cta-alt {
  background: transparent; box-shadow: none; border: none;
  color: var(--text-sec); padding: 8px 10px;
  font-weight: 500; font-size: 14px;
}
.cta-alt:hover {
  background: transparent; box-shadow: none; transform: none;
  color: var(--accent-deep);
}

.cta-qr { display: none; }
.cta-qr-img {
  width: 116px; height: 116px; padding: 9px; background: #fff;
  border: 1px solid var(--border); border-radius: 16px; flex: none;
}
.cta-qr-copy { display: flex; flex-direction: column; gap: 3px; text-align: left; }
.cta-qr-title { font-weight: 600; font-size: 15px; color: var(--text); }
.cta-qr-sub { font-size: 13px; color: var(--text-sec); }
.cta-qr-sub a { color: var(--accent-deep); text-decoration: none; font-weight: 600; }

html[data-device="desktop"] [data-testflight] { display: none; }
html[data-device="desktop"] .cta-qr {
  display: inline-flex; align-items: center; gap: 16px; margin-bottom: 14px;
}

/* Hero mic */
.hero-mic-wrap { position: relative; width: 168px; height: 168px; display: grid; place-items: center; }
.hero-mic {
  width: 108px; height: 108px; border-radius: 9999px;
  background: linear-gradient(160deg, var(--accent), var(--accent-deep));
  box-shadow:
    0 28px 70px rgba(255,107,53,0.35),
    0 10px 24px rgba(255,107,53,0.25),
    inset 0 1px 0 rgba(255,255,255,0.4),
    inset 0 -3px 6px rgba(0,0,0,0.12);
  display: grid; place-items: center; position: relative; z-index: 2;
  animation: heroBreathe 3.6s ease-in-out infinite;
}
@keyframes heroBreathe { 0%,100% { transform: scale(1); } 50% { transform: scale(1.04); } }
.hero-mic .shine { position: absolute; inset: 0; border-radius: 9999px; background: radial-gradient(120% 80% at 30% 20%, rgba(255,255,255,0.5), transparent 50%); pointer-events: none; }
.hero-mic-rings { position: absolute; inset: 0; pointer-events: none; }
.hero-mic-rings .r {
  position: absolute; inset: 0; border-radius: 9999px;
  border: 1.5px solid rgba(255,107,53,0.5);
  animation: micRing 3s ease-out infinite;
}
.hero-mic-rings .r:nth-child(2) { animation-delay: 1s; }
.hero-mic-rings .r:nth-child(3) { animation-delay: 2s; }
@keyframes micRing { 0% { transform: scale(0.6); opacity: 0; } 20% { opacity: 1; } 100% { transform: scale(1.7); opacity: 0; } }

/* ───── LANGUAGE STRIP (marquee of utterances Settl parses) ─────
   Lives INSIDE the hero, pinned to its bottom edge — visible at rest in the
   first viewport rather than stranded between viewports. Two identical
   .lang-set children; the track slides -50% (exactly one set) then loops, so
   the band reads as endless. Reduced motion stops the slide and the first
   set simply sits as a static row. */
.lang-strip {
  position: absolute; left: 0; right: 0; bottom: 26px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
}
.lang-track { display: flex; width: max-content; animation: langScroll 56s linear infinite; }
.lang-set { display: flex; gap: 14px; padding-right: 14px; }
.lang-chip {
  flex: none; display: inline-flex; align-items: center; gap: 10px;
  padding: 9px 18px; border: 1px solid var(--border); border-radius: 9999px;
  background: var(--surface);
  font-family: var(--serif); font-style: italic; font-size: 14px; color: var(--text-sec);
}
.lang-chip q { quotes: '\201C' '\201D'; }
.lang-chip .tag { font-family: var(--mono); font-style: normal; font-size: 11.5px; color: var(--accent-deep); }
@keyframes langScroll { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .lang-track { animation: none; } }

/* Hero collapse — single column, copy first, compact stage below. The
   min-height unlock matters: a forced 100dvh hero on a phone would push
   the demo stage into a half-cropped second viewport.
   ORDER MATTERS: these media blocks must come AFTER every hero base rule
   above (.hero-mic-wrap, .hero-mic, .lang-strip, ...) — at equal
   specificity the later rule wins, and an earlier placement let the
   desktop values override the phone ones (the bug that left the ribbon
   absolutely positioned on top of the demo card on real iPhones). */
@media (max-width: 880px) {
  .hero { padding: 96px 20px 40px; min-height: 0; flex-direction: column; }
  .hero-grid { grid-template-columns: 1fr; gap: 36px; }
  .hero-content { max-width: 560px; margin: 0 auto; text-align: center; }
  .hero-sub { margin-left: auto; margin-right: auto; }
  .hero-cta { justify-content: center; }
  .hero-stage { min-height: 0; gap: 16px; }
  .hero-mic-wrap { width: 124px; height: 124px; }
  .hero-mic { width: 84px; height: 84px; }
  .hero-orbits .ring.r2, .hero-orbits .ring.r3 { display: none; }
  /* Content-sized hero on phones — the ribbon rides in normal flow below
     the demo stage (full-bleed via negative margins). */
  .lang-strip { position: static; margin: 34px -20px 0; }
}

/* Short desktop viewports — tighten the stage so headline, CTAs, demo AND
   the ribbon all land inside the first viewport. */
@media (min-width: 881px) and (max-height: 780px) {
  .hero { padding-top: 90px; padding-bottom: 124px; }
  .hero-stage { min-height: 400px; }
  .hero-orbits .ring.r3 { width: 560px; height: 560px; }
}

/* ───── STORY (sticky parallax) ───── */
.story { position: relative; }

.story-pin {
  position: sticky; top: 0;
  height: 100vh;
  display: grid; grid-template-columns: 1fr 420px 1fr;
  align-items: center;
  /* Clear the fixed nav (~64px) so the phone's top edge isn't tucked
     behind the blurred glass bar. align-items still vertically centers
     the phone within the remaining space. */
  padding-top: 80px; padding-bottom: 24px;
  overflow: hidden;
  transition: background 800ms ease;
}
.story-pin .text-side { padding: 0 5vw; max-width: 520px; justify-self: end; }
.story-pin .text-side .eyebrow {
  font-family: var(--mono); font-size: 11px; letter-spacing: 1.5px; text-transform: uppercase;
  color: var(--accent-deep); margin-bottom: 18px;
  display: inline-flex; align-items: center; gap: 8px;
}
.story-pin .text-side .eyebrow::before {
  content: ''; width: 18px; height: 1px; background: var(--accent);
}
.story-pin h2 {
  font-family: var(--serif);
  font-size: clamp(36px, 4.6vw, 56px);
  font-weight: 500; letter-spacing: -1.5px; line-height: 1.05;
  margin: 0 0 18px; text-wrap: balance;
}
.story-pin .text-side p {
  font-size: 17px; color: var(--text-sec); line-height: 1.6;
  margin: 0 0 14px; text-wrap: pretty;
}
.story-pin .text-side .quote {
  font-family: var(--serif); font-style: italic; font-size: 19px; color: var(--text);
  border-left: 2px solid var(--accent); padding-left: 16px; margin-top: 22px;
}

/* layered scenes — only one active */
.story-scene-track {
  position: relative; justify-self: center;
  width: 100%; height: 100%;
  display: grid; place-items: center;
}

.phone {
  position: relative;
  width: 360px; height: 720px;
  border-radius: 54px;
  background: #0E0C0A;
  padding: 10px;
  box-shadow:
    0 30px 80px rgba(20,18,14,0.25),
    0 12px 30px rgba(20,18,14,0.15),
    inset 0 0 0 1.5px rgba(255,255,255,0.07),
    inset 0 1.5px 0 rgba(255,255,255,0.10);
}
.phone-screen { position: relative; width: 100%; height: 100%; border-radius: 44px; overflow: hidden; background: var(--bg); }
/* Dynamic Island — pure black capsule sitting INSIDE the screen, ~12px
   below the screen's top edge (real iPhone proportions). The phone has
   10px bezel padding, so `top: 22px` puts it 12px under the screen
   edge. Soft inset highlight + tiny inner ring sells the depth. */
.phone-notch {
  position: absolute; top: 22px; left: 50%; transform: translateX(-50%);
  width: 118px; height: 34px; border-radius: 9999px;
  background: #000;
  box-shadow:
    inset 0 0 0 1px rgba(255,255,255,0.04),
    0 2px 6px rgba(0,0,0,0.35);
  z-index: 8;
}
.phone-notch::after {
  /* Faint sensor dot, right side, to suggest the camera + Face ID array. */
  content: '';
  position: absolute; top: 50%; right: 11px; transform: translateY(-50%);
  width: 8px; height: 8px; border-radius: 9999px;
  background: radial-gradient(circle at 35% 35%, #2a2a2e 0%, #0b0b0d 70%);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.04);
}

/* Scenes swap in place by pure opacity — no scale, no translate.
   Earlier versions used `scale(0.96) translateY(24px)` which made the
   phone screen visibly slide while the user scrolled the page; that
   read as "the screen is moving" and broke the "phone sits still
   while content swaps" mental model. Pure cross-fade now: the phone
   frame stays anchored, only the content inside fades. */
.scene {
  position: absolute; inset: 0;
  opacity: 0;
  transition: opacity 380ms ease;
  pointer-events: none;
}
.scene.active { opacity: 1; }
.scene-bg { position: absolute; inset: 0; }

/* Scene-specific bgs */
.scene-1 .scene-bg { background: linear-gradient(180deg, #FFFFFF 0%, #F4F4F5 100%); }
.scene-2 .scene-bg { background: linear-gradient(180deg, #FFF0E0 0%, #FFD9B8 60%, #FFC096 100%); }
.scene-3 .scene-bg { background: linear-gradient(180deg, #FFD0A8 0%, #B97A5C 50%, #2D1F1A 100%); }
.scene-4 .scene-bg { background: linear-gradient(180deg, #FFE4D0 0%, #FFCDA8 50%, #FFB57A 100%); }
.scene-5 .scene-bg { background: linear-gradient(180deg, #1B1340 0%, #0E0826 100%); }
.scene-6 .scene-bg { background: #fff; }
/* Scene 6 — actual app screenshot. The PNG already has the iOS status
   bar baked in (Dynamic Island, time, signals), so when this scene is
   active we hide our decorative notch to avoid double-island. */
.scene-6 .app-shot {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: top center;
  display: block;
}
.phone:has(.scene-6.active) .phone-notch { display: none; }

/* Scene 1 — chaos / pre-Settl */
.chaos-receipt {
  position: absolute;
  background: #fff; padding: 12px 16px; border-radius: 6px;
  box-shadow: 0 8px 24px rgba(20,18,14,0.12);
  font-family: var(--mono); font-size: 11px;
  border: 1px dashed rgba(20,18,14,0.15);
  transform-origin: center;
}
.chaos-bubble {
  position: absolute;
  background: #fff; padding: 10px 14px; border-radius: 18px;
  box-shadow: 0 6px 18px rgba(20,18,14,0.08);
  font-size: 12px; color: var(--text-sec);
  max-width: 200px; line-height: 1.4;
}
.chaos-bubble.right { border-bottom-right-radius: 4px; background: var(--accent); color: #fff; }
.chaos-bubble.left  { border-bottom-left-radius: 4px; }

/* Scene 2 — listening */
.scene-mic {
  position: absolute; top: 22%; left: 50%; transform: translateX(-50%);
  width: 92px; height: 92px; border-radius: 9999px;
  background: linear-gradient(160deg, var(--accent), var(--accent-deep));
  box-shadow: 0 14px 40px rgba(255,107,53,0.5), inset 0 1px 0 rgba(255,255,255,0.4);
  display: grid; place-items: center; z-index: 4;
}
.scene-mic .pulse { position: absolute; inset: -18px; border-radius: 9999px; border: 1.5px solid rgba(255,107,53,0.35); animation: micRing 2.2s ease-out infinite; }
.scene-mic .pulse.d2 { animation-delay: 1.1s; }
.bg-circles { position: absolute; inset: 0; pointer-events: none; }
.bg-circles span {
  position: absolute; border-radius: 9999px;
  background: rgba(255,255,255,0.3);
}
.transcript-bubble {
  position: absolute; top: 38%; left: 50%; transform: translateX(-50%);
  background: #fff; padding: 10px 16px; border-radius: 9999px;
  font-family: var(--serif); font-size: 12px; font-weight: 500;
  line-height: 1.2; text-align: center;
  box-shadow: 0 6px 20px rgba(20,18,14,0.1);
  /* Single-line — at 12px the full sentence fits inside the 360px
     phone with margin to spare. Don't wrap; that overlaps the card
     below. */
  white-space: nowrap; z-index: 4;
}
.transcript-bubble .caret {
  display: inline-block; width: 1px; height: 1em;
  background: var(--accent-deep); margin-left: 1px;
  vertical-align: -2px;
  animation: caretBlink 0.9s steps(1) infinite;
}
@keyframes caretBlink { 0%,49% { opacity: 1; } 50%,100% { opacity: 0; }
}
/* Typewriter sequencing — bubble starts empty, types itself in once
   scene 2 first becomes active, then the expense card fades up beneath
   it. Driven from landing.js so subsequent scrolls back into scene 2
   keep the populated state without retriggering. */
.scene-2 .scene-card {
  /* Override the generic .scene-card typeIn animation — scene 2 waits
     for the typewriter to finish before the card slides up. The
     translateX(-50%) keeps the card horizontally centered (its parent
     positions via left:50%); we only animate the Y axis on top. */
  animation: none;
  opacity: 0; transform: translate(-50%, 14px);
  transition: opacity 500ms ease, transform 500ms cubic-bezier(.2,.9,.3,1);
}
.scene-2 .scene-card.appear { opacity: 1; transform: translate(-50%, 0); }
.scene-card {
  position: absolute; top: 47%; left: 50%; transform: translateX(-50%);
  background: #fff; padding: 14px 18px; border-radius: 14px;
  display: flex; align-items: center; gap: 12px;
  box-shadow: 0 8px 24px rgba(20,18,14,0.12);
  width: 280px; z-index: 4;
  animation: typeIn 600ms 250ms ease-out backwards;
}
.scene-card .icon { width: 34px; height: 34px; border-radius: 8px; background: var(--accent-soft); color: var(--accent-deep); display: grid; place-items: center; flex-shrink: 0; }
.scene-card .meta { flex: 1; }
.scene-card .meta .t { font-size: 14px; font-weight: 500; color: var(--text); }
.scene-card .meta .s { font-size: 11px; color: var(--text-sec); margin-top: 2px; }
.scene-card .amt { font-family: var(--serif); font-size: 17px; font-weight: 500; color: var(--accent); }
@keyframes typeIn { from { opacity: 0; transform: translate(-50%, 12px); } to { opacity: 1; transform: translate(-50%, 0); } }

/* Hills under listening scene */
.hill {
  position: absolute; left: -10%; right: -10%; bottom: 0;
  height: 60%;
  background: var(--col, #FFB890);
  -webkit-mask-image: var(--mask);
          mask-image: var(--mask);
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
}

/* Scene 3 — multi-currency travel */
.expense-chip {
  position: absolute;
  display: flex; align-items: center; gap: 8px;
  padding: 8px 14px 8px 8px; border-radius: 9999px;
  background: rgba(255,255,255,0.95);
  box-shadow: 0 8px 22px rgba(20,18,14,0.18);
  font-size: 13px; font-weight: 500; color: var(--text);
  z-index: 4;
}
.expense-chip .e { width: 26px; height: 26px; border-radius: 9999px; display: grid; place-items: center; font-size: 14px; background: var(--accent-soft); }
.expense-chip .num { font-family: var(--serif); font-weight: 500; }
.travel-mountain {
  position: absolute; left: 0; right: 0;
  pointer-events: none;
}
.travel-sun {
  position: absolute; top: 18%; left: 14%;
  width: 60px; height: 60px; border-radius: 9999px;
  background: radial-gradient(closest-side, #FFE9B5, #FFD78A);
  box-shadow: 0 0 60px #FFD78A88;
}

/* Scene 4 — agent reasoning / ledger */
.ledger-card {
  position: absolute; left: 28px; right: 28px; top: 88px;
  background: #fff; border-radius: 18px;
  padding: 18px; box-shadow: 0 12px 30px rgba(20,18,14,0.12);
}
.ledger-card .tlabel { font-family: var(--mono); font-size: 10px; letter-spacing: 1px; color: var(--text-sec); text-transform: uppercase; margin-bottom: 10px; }
.ledger-card .row { display: flex; justify-content: space-between; align-items: center; padding: 8px 0; border-bottom: 1px solid var(--divider); font-size: 13px; }
.ledger-card .row:last-child { border-bottom: none; }
.ledger-card .row .who { display: flex; align-items: center; gap: 8px; }
.ledger-card .row .av {
  width: 22px; height: 22px; border-radius: 9999px; color: #fff; font-weight: 600; font-size: 10px;
  display: grid; place-items: center;
}
.ledger-card .row .amt { font-family: var(--serif); font-weight: 500; }
.thought-bubble {
  position: absolute; top: 45%; left: 50%; transform: translateX(-50%);
  background: var(--text); color: var(--bg);
  padding: 14px 20px; border-radius: 18px; max-width: 260px;
  font-size: 14px; line-height: 1.5; box-shadow: 0 12px 30px rgba(20,18,14,0.3);
}
.thought-bubble::before {
  content: ''; position: absolute; top: -8px; left: 24px;
  width: 14px; height: 14px; background: var(--text); transform: rotate(45deg);
}
.thought-bubble .who { font-family: var(--mono); font-size: 10px; letter-spacing: 1px; text-transform: uppercase; opacity: 0.5; margin-bottom: 6px; }

.optimal-arrow {
  position: absolute; bottom: 110px; left: 28px; right: 28px;
  background: rgba(255,255,255,0.95); border-radius: 14px; padding: 14px 16px;
  display: flex; align-items: center; gap: 12px;
  box-shadow: 0 8px 20px rgba(20,18,14,0.1);
}
.optimal-arrow .from, .optimal-arrow .to {
  width: 32px; height: 32px; border-radius: 9999px;
  background: var(--accent-soft); color: var(--accent-deep);
  display: grid; place-items: center; font-weight: 600; font-size: 12px;
}
.optimal-arrow .arr { color: var(--text-ter); }
.optimal-arrow .label { flex: 1; font-size: 13px; }
.optimal-arrow .label b { color: var(--text); font-weight: 600; }
.optimal-arrow .amt { font-family: var(--serif); font-weight: 500; font-size: 16px; }

/* Scene 5 — settled, night */
.stars { position: absolute; inset: 0; }
.stars span {
  position: absolute; width: 2px; height: 2px;
  background: #fff; border-radius: 9999px;
  animation: twinkle 3s ease-in-out infinite;
}
@keyframes twinkle { 0%,100% { opacity: .3; } 50% { opacity: 1; } }
.moon {
  position: absolute; top: 12%; right: 18%;
  width: 56px; height: 56px; border-radius: 9999px;
  background: radial-gradient(closest-side, #F8E8B8, #E8D08A);
  box-shadow: 0 0 50px rgba(248,232,184,0.5);
}
.city {
  position: absolute; left: -10%; right: -10%; bottom: 0;
  height: 50%;
}
.confetti { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.confetti span {
  position: absolute; width: 8px; height: 8px;
  animation: confettiFall 4s linear infinite;
}
@keyframes confettiFall {
  0%   { transform: translateY(-30px) rotate(0deg); opacity: 1; }
  100% { transform: translateY(800px) rotate(720deg); opacity: 0; }
}
.check-mark-circle {
  position: absolute; top: 28%; left: 50%; transform: translateX(-50%);
  width: 80px; height: 80px; border-radius: 9999px;
  background: #fff; display: grid; place-items: center;
  box-shadow: 0 0 60px rgba(255,255,255,0.5), 0 12px 30px rgba(0,0,0,0.4);
}
.settled-text {
  position: absolute; left: 0; right: 0; top: 46%; text-align: center;
  font-family: var(--serif); color: #fff; font-size: 38px; font-weight: 500; letter-spacing: -1px;
  text-shadow: 0 2px 16px rgba(0,0,0,0.3);
}
.settled-card {
  position: absolute; left: 28px; right: 28px; bottom: 100px;
  background: #fff; border-radius: 22px; padding: 22px 24px;
  box-shadow: 0 16px 40px rgba(0,0,0,0.3);
}
.settled-card h3 { font-family: var(--serif); font-size: 24px; font-weight: 500; margin: 0 0 8px; letter-spacing: -0.4px; }
.settled-card p { margin: 0; font-size: 13px; color: var(--text-sec); }

/* Scene progress (rail to right of phone) */
.story-progress {
  position: absolute; right: 5vw; top: 50%; transform: translateY(-50%);
  display: flex; flex-direction: column; gap: 14px;
  z-index: 6;
}
.story-progress .step {
  display: flex; align-items: center; gap: 12px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 1px; text-transform: uppercase;
  color: var(--text-ter); cursor: pointer;
  transition: color 300ms;
}
.story-progress .step .pip {
  width: 8px; height: 8px; border-radius: 9999px; background: var(--text-ter);
  transition: all 300ms;
}
.story-progress .step.on { color: var(--accent-deep); }
.story-progress .step.on .pip { background: var(--accent); transform: scale(1.5); box-shadow: 0 0 0 4px rgba(255,107,53,0.2); }

/* ─── Story escape hatch + progress scrubber ─────────────────────────
   The story is 600vh of scroll-jacked narrative; give decided/fast users a
   way out and (where the right rail is hidden) a sense of how far they are. */
.story-skip {
  position: absolute; top: 84px; right: 5vw; z-index: 7;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.4px;
  color: var(--text-sec); text-decoration: none;
  padding: 7px 13px; border: 1px solid var(--border); border-radius: 9999px;
  background: rgba(255,255,255,0.72); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  transition: color 200ms, border-color 200ms;
}
.story-skip:hover { color: var(--accent-deep); border-color: var(--accent); }
/* Phones: the sticky iOS/Android bar (≤720px) already gives a persistent
   jump to install, and at phone widths this pill landed on top of the
   centered act labels ("The mess", "In your hand"). Hide it there. */
@media (max-width: 720px) {
  .story-skip { display: none; }
}
.story-scrubber {
  position: absolute; left: 0; right: 0; top: 64px; height: 3px;
  background: rgba(20,20,20,0.06); z-index: 7; display: none;
}
.story-scrubber-fill { height: 100%; width: 0; background: var(--accent-deep); transition: width 120ms linear; }

@media (max-width: 1100px) {
  .story-scrubber { display: block; }
  .story-skip { top: 72px; right: 16px; }
  /* Pin must equal exactly one viewport — if it grows taller (text +
     full-size phone > 100vh) sticky degrades to scroll-past and the
     phone slides half off the bottom. Tighten text, shrink phone,
     drop the quote, drop the side rail. */
  .story-pin {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
    padding: 72px 16px 12px;
    gap: 12px;
    height: 100vh; min-height: 0;
    align-items: start;
    overflow: hidden;
  }
  .story-pin .text-side { justify-self: center; text-align: center; max-width: 540px; padding: 0; }
  .story-pin .text-side .eyebrow { margin-bottom: 10px; }
  .story-pin .text-side .eyebrow::before { display: none; }
  .story-pin h2 { font-size: clamp(24px, 6.4vw, 34px); margin: 0 0 10px; line-height: 1.1; }
  .story-pin .text-side p { font-size: 14px; line-height: 1.5; margin: 0 0 8px; }
  .story-pin .text-side .quote { display: none; }
  .story-progress { display: none; }
  /* Use real width/height (not transform: scale) so the phone's
     layout footprint actually shrinks. On a 6.1" iPhone (844pt tall)
     this leaves ~470px for the phone after text + padding. */
  .phone {
    width: 240px; height: 480px;
    border-radius: 38px; padding: 8px;
  }
  .phone-screen { border-radius: 30px; }
  .phone-notch { top: 16px; width: 84px; height: 24px; }
  .phone-notch::after { right: 8px; width: 6px; height: 6px; }
  /* Scene contents scale with the smaller screen. The 240x480 phone
     leaves ~224x464 of usable screen — every absolutely-positioned
     piece below was tuned for the desktop 360x720 footprint and now
     overlaps / overflows here. */
  .scene-mic { width: 64px; height: 64px; top: 20%; }
  .scene-mic .pulse { inset: -12px; }
  .scene-mic .waveform { height: 20px; }
  /* Bubble: 'I paid 84.40 for sushi with Alice, Maya and Dev' is too
     wide to keep on one line at any readable size on a 224px screen.
     Allow wrapping; push card down to clear it. */
  .transcript-bubble {
    font-size: 11px; padding: 7px 12px; top: 33%;
    white-space: normal; max-width: 86%;
    line-height: 1.32;
  }
  .scene-card { width: 86%; padding: 10px 12px; top: 56%; }
  .scene-card .icon { width: 28px; height: 28px; }
  .scene-card .meta .t { font-size: 12px; }
  .scene-card .meta .s { font-size: 10px; }
  .scene-card .amt { font-size: 14px; }
  .chaos-receipt { font-size: 9px; padding: 8px 10px; }
  .chaos-bubble { font-size: 10px; padding: 8px 10px; max-width: 140px; }
  .expense-chip { font-size: 11px; padding: 5px 9px; }
  /* Scene 4 — ledger / thought / optimal-arrow stack vertically inside
     the phone. Pull them all in tighter so they don't collide. */
  .ledger-card { left: 14px; right: 14px; top: 56px; padding: 12px 14px; border-radius: 14px; }
  .ledger-card .tlabel { font-size: 9px; margin-bottom: 6px; }
  .ledger-card .row { font-size: 11px; padding: 5px 0; }
  .ledger-card .row .av { width: 18px; height: 18px; font-size: 9px; }
  .thought-bubble {
    top: auto; bottom: 116px; left: 14px; right: 14px;
    transform: none; max-width: none;
    font-size: 11px; line-height: 1.4; padding: 10px 14px;
    border-radius: 14px;
  }
  .thought-bubble::before { left: 18px; }
  .thought-bubble .who { font-size: 8px; margin-bottom: 4px; }
  .optimal-arrow {
    bottom: 22px; left: 14px; right: 14px;
    padding: 9px 12px; gap: 8px; border-radius: 12px;
  }
  .optimal-arrow .from, .optimal-arrow .to { width: 24px; height: 24px; font-size: 10px; }
  .optimal-arrow .label { font-size: 10.5px; }
  .optimal-arrow .amt { font-size: 13px; }
  .settled-text { font-size: 28px; }
  .settled-card { left: 14px; right: 14px; bottom: 60px; padding: 12px 14px; border-radius: 14px; }
  .settled-card h3 { font-size: 18px; }
  .settled-card p { font-size: 11px; }
}

/* ───── STATIC SECTIONS ───── */
section.block { padding: 140px 24px; position: relative; }
.block-inner { max-width: 1100px; margin: 0 auto; }
.block-eyebrow {
  font-family: var(--mono); font-size: 11px; letter-spacing: 1.5px; text-transform: uppercase;
  color: var(--accent-deep); margin-bottom: 18px;
  display: inline-flex; align-items: center; gap: 8px;
}
.block-eyebrow::before { content: ''; width: 18px; height: 1px; background: var(--accent); }
.block-title {
  font-family: var(--serif);
  font-size: clamp(36px, 5vw, 64px);
  font-weight: 500; letter-spacing: -1.8px; line-height: 1.02;
  margin: 0 0 20px; text-wrap: balance; max-width: 800px;
}
.block-sub { font-size: 18px; color: var(--text-sec); line-height: 1.55; max-width: 620px; margin: 0 0 56px; }

/* Capability bento — 7/5 then 5/7 column spans so the two rows zig-zag
   instead of stacking four identical tiles; cards 2 and 3 carry ink and
   ember backgrounds for visual variation. */
.cap-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 18px; }
.cap-card:nth-child(1) { grid-column: span 7; }
.cap-card:nth-child(2) { grid-column: span 5; }
.cap-card:nth-child(3) { grid-column: span 5; }
.cap-card:nth-child(4) { grid-column: span 7; }
.cap-card {
  position: relative;
  padding: 32px; border-radius: 24px;
  background: var(--surface); border: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 18px;
  transition: transform 300ms, box-shadow 300ms, border-color 300ms;
  overflow: hidden;
}
.cap-card:hover { transform: translateY(-4px); box-shadow: 0 24px 50px rgba(20,18,14,0.08); border-color: var(--accent); }
.cap-card .quote-mock {
  background: var(--bg-warm); border-radius: 14px; padding: 16px;
  font-family: var(--serif); font-style: italic; font-size: 15px; color: var(--text-sec);
  line-height: 1.4;
}
.cap-card .arrow { font-size: 13px; color: var(--text-ter); display: flex; align-items: center; gap: 6px; }
.cap-card .result {
  background: var(--accent-soft); border-radius: 14px; padding: 14px 16px;
  display: flex; align-items: center; gap: 12px;
}
.cap-card .result .lbl { font-family: var(--mono); font-size: 10px; letter-spacing: 1px; text-transform: uppercase; color: var(--accent-deep); }
.cap-card .result .val { font-family: var(--serif); font-weight: 500; font-size: 16px; color: var(--text); }
.cap-card h3 { font-family: var(--serif); font-size: 26px; font-weight: 500; margin: 0; letter-spacing: -0.4px; }
.cap-card p { margin: 0; color: var(--text-sec); font-size: 14px; line-height: 1.55; }

/* Ink tile — same light page theme, one dark card for bento contrast. */
.cap-card--ink { background: #1D1813; border-color: rgba(255,247,232,0.08); }
.cap-card--ink h3 { color: #FFF7E8; }
.cap-card--ink p { color: rgba(255,247,232,0.62); }
.cap-card--ink .quote-mock { background: rgba(255,247,232,0.07); color: rgba(255,247,232,0.78); }
.cap-card--ink .arrow { color: rgba(255,247,232,0.45); }
.cap-card--ink .result { background: rgba(255,107,53,0.14); }
.cap-card--ink .result .lbl { color: #FFB893; }
.cap-card--ink .result .val { color: #FFF7E8; }
.cap-card--ink:hover { border-color: var(--accent); box-shadow: 0 24px 50px rgba(20,18,14,0.30); }

/* Ember tile — accent-tinted card. */
.cap-card--ember { background: var(--accent-soft); border-color: rgba(194,74,31,0.16); }
.cap-card--ember .quote-mock { background: rgba(255,255,255,0.72); }
.cap-card--ember .result { background: var(--surface); }

@media (max-width: 760px) {
  .cap-grid { grid-template-columns: 1fr; }
  .cap-card { grid-column: auto; }
}

/* Compare table */
.compare {
  display: grid; grid-template-columns: 1.2fr 1fr 1fr 1fr; gap: 0;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 22px; overflow: hidden;
}
.compare-cell { padding: 18px 22px; border-bottom: 1px solid var(--divider); font-size: 14px; }
.compare-cell.head {
  background: var(--bg-warm);
  font-weight: 600; font-family: var(--sans); font-size: 12px; letter-spacing: 0.6px; text-transform: uppercase; color: var(--text-sec);
}
.compare-cell.head.us { color: var(--accent-deep); background: var(--accent-soft); }
.compare-cell.feat { color: var(--text); font-weight: 500; }
.compare-cell.us-cell { background: rgba(255,230,217,0.35); font-weight: 500; }
.compare > .compare-cell:nth-last-child(-n+4) { border-bottom: none; }
/* Mobile compare — drop the Spreadsheet column entirely (least
   informative comparison; the Other-apps vs Settl read is the one
   that converts). Three columns gets every label onto one or two
   lines instead of the previous 4-5. */
@media (max-width: 720px) {
  .compare {
    grid-template-columns: 1.5fr 1fr 1fr;
    font-size: 10.5px;
  }
  .compare > .compare-cell:nth-child(4n+3) { display: none; }
  .compare-cell { padding: 10px 11px; }
  .compare-cell.head { font-size: 10px; letter-spacing: 0.4px; padding: 12px 11px; }
  .compare > .compare-cell:nth-last-child(-n+4) { border-bottom: 1px solid var(--divider); }
  .compare > .compare-cell:nth-last-child(-n+3) { border-bottom: none; }
}

/* Final CTA */
.final {
  position: relative;
  text-align: center; padding: 160px 24px 200px;
  background: linear-gradient(180deg, transparent 0%, var(--bg-warm) 60%, #15130F 100%);
  overflow: hidden; color: var(--text);
}
.final h2 { font-family: var(--serif); font-size: clamp(48px, 8vw, 96px); font-weight: 500; letter-spacing: -2.5px; line-height: 1; margin: 0 0 28px; }
.final h2 em { font-style: italic; color: var(--accent-deep); }
.final p { font-size: 19px; color: var(--text-sec); margin: 0 0 40px; max-width: 540px; margin-left: auto; margin-right: auto; line-height: 1.5; }
/* Asterisk footnote — reads as part of the lead paragraph (pulled up under
   it), centered like every other block in the section. The old inline
   `margin: 0.5rem 0 0` clobbered the auto side margins and pinned the
   540px box to the left edge. */
.final .cta-fineprint {
  font-size: 0.72rem; color: var(--text-ter); opacity: 0.85;
  max-width: 62ch; line-height: 1.5;
  margin: -28px auto 36px;
}
.final .cta-fineprint a { color: inherit; text-decoration: underline; }

footer {
  background: #15130F; color: rgba(255,247,232,0.5);
  padding: 56px 28px 36px;
}
.footer-inner { max-width: 1100px; margin: 0 auto; display: flex; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.footer-brand { font-family: var(--serif); font-size: 20px; color: var(--bg); display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
/* Wordmark on the dark footer: light glyphs, ember period (inherited). */
.footer-brand .brand-wordmark { color: var(--bg); font-size: 24px; }
.footer-brand small { display: block; font-family: var(--sans); font-size: 13px; color: rgba(255,247,232,0.6); margin-top: 4px; max-width: 280px; line-height: 1.5; font-weight: 400; }
.footer-col { display: flex; flex-direction: column; gap: 10px; font-size: 13px; }
.footer-col h5 { font-family: var(--mono); font-size: 11px; letter-spacing: 1px; text-transform: uppercase; color: rgba(255,247,232,0.4); margin: 0 0 4px; font-weight: 500; }
.footer-col a:hover { color: var(--bg); }
.footer-bottom {
  max-width: 1100px; margin: 36px auto 0;
  border-top: 1px solid rgba(255,247,232,0.08);
  padding-top: 24px;
  display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px;
  font-size: 12px; color: rgba(255,247,232,0.35);
}
.made-with-love {
  display: inline-flex; align-items: center; gap: 6px;
  color: rgba(255,247,232,0.5);
}
.made-with-love svg { width: 13px; height: 13px; }

/* Waveform */
.waveform { display: flex; gap: 3px; align-items: center; height: 36px; }
.waveform i {
  width: 5px; background: #fff; border-radius: 3px;
  animation: bar 1.2s ease-in-out infinite;
}
.waveform i:nth-child(1) { animation-delay: 0s;   height: 40%; }
.waveform i:nth-child(2) { animation-delay: 0.1s; height: 70%; }
.waveform i:nth-child(3) { animation-delay: 0.2s; height: 95%; }
.waveform i:nth-child(4) { animation-delay: 0.3s; height: 60%; }
.waveform i:nth-child(5) { animation-delay: 0.4s; height: 85%; }
.waveform i:nth-child(6) { animation-delay: 0.5s; height: 50%; }
.waveform i:nth-child(7) { animation-delay: 0.6s; height: 75%; }
@keyframes bar { 0%, 100% { transform: scaleY(0.4); } 50% { transform: scaleY(1.2); } }

/* ───── Beta-signup modal (shared between www/ and www/g/) ───── */
.beta-modal {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(20,18,14,0.58);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  animation: bm-fade .18s ease-out;
}
.beta-modal[hidden] { display: none; }
@keyframes bm-fade { from { opacity: 0 } to { opacity: 1 } }
.beta-modal__card {
  width: 100%; max-width: 440px; background: #FFFFFF;
  border-radius: 22px; padding: 28px 26px 22px;
  box-shadow: 0 20px 60px rgba(20,18,14,.25);
  position: relative;
  font-family: 'Inter Tight', -apple-system, BlinkMacSystemFont, sans-serif;
  color: #15130F;
}
.beta-modal__close {
  position: absolute; top: 12px; right: 12px;
  width: 32px; height: 32px; border: 0;
  border-radius: 9999px; background: transparent;
  color: #6B6457; font-size: 22px; line-height: 1; cursor: pointer;
}
.beta-modal__close:hover { background: rgba(20,18,14,0.06); color: #15130F; }
.beta-modal__pill {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 11px; font-weight: 700; letter-spacing: 1.2px;
  color: #6B6457; text-transform: uppercase; margin-bottom: 10px;
}
.beta-modal__pill::before {
  content: ""; width: 7px; height: 7px; border-radius: 9999px;
  background: #FF6B35; display: inline-block;
}
.beta-modal__title {
  margin: 0 0 8px;
  font-family: 'Source Serif 4', Georgia, serif;
  font-weight: 500; font-size: 24px; line-height: 1.2; letter-spacing: -.5px;
}
.beta-modal__sub { margin: 0 0 18px; font-size: 14px; line-height: 1.5; color: #6B6457; }
.beta-modal__field { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.beta-modal__field label {
  font-size: 12px; font-weight: 600; letter-spacing: .3px;
  color: #6B6457; text-transform: uppercase;
}
.beta-modal__field input {
  appearance: none; border: 1px solid rgba(20,18,14,.16);
  background: #FFF; border-radius: 12px;
  padding: 12px 14px; font-size: 15px; color: #15130F;
  font-family: inherit; outline: none;
  transition: border-color .12s, box-shadow .12s;
}
.beta-modal__field input:focus {
  border-color: #FF6B35; box-shadow: 0 0 0 3px rgba(255,107,53,.18);
}
.beta-modal__submit {
  width: 100%; border: 0; background: #FF6B35; color: #FFF;
  font-weight: 600; font-size: 15px;
  padding: 13px 16px; border-radius: 9999px;
  cursor: pointer; font-family: inherit; transition: filter .12s;
}
.beta-modal__submit:hover { filter: brightness(1.05); }
.beta-modal__submit:disabled { opacity: .6; cursor: wait; }
.beta-modal__err { margin: 10px 0 0; font-size: 13px; color: #C24A1F; }
.beta-modal__legal {
  margin: 14px 0 0; font-size: 11px; color: #9C9486; line-height: 1.5; text-align: center;
}
.beta-modal__success { text-align: center; }
.beta-modal__success svg {
  width: 42px; height: 42px; color: #3B9D6E; margin-bottom: 8px;
}
.beta-modal__success h3 {
  margin: 0 0 8px; font-family: 'Source Serif 4', Georgia, serif;
  font-weight: 500; font-size: 22px;
}
.beta-modal__success p { margin: 0; font-size: 14px; line-height: 1.55; color: #6B6457; }
.beta-modal__success strong { color: #15130F; }

/* ───── MID-PAGE CTA ─────
 * Sits between the long sticky-parallax story and the feature blocks.
 * Same ember-on-cream language as the hero; centered card with a
 * tighter, single-line headline + two install buttons. */
.mid-cta {
  padding: clamp(56px, 9vw, 96px) 24px;
  display: flex; justify-content: center;
}
.mid-cta-card {
  width: 100%; max-width: 720px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 28px;
  padding: clamp(32px, 5vw, 48px);
  text-align: center;
  box-shadow: 0 12px 36px rgba(20, 15, 8, 0.06);
}
.mid-cta-h {
  margin: 0 0 22px;
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(28px, 4.6vw, 40px);
  line-height: 1.12;
  letter-spacing: -0.5px;
  color: var(--text);
}
.mid-cta-row {
  display: flex; justify-content: center; gap: 12px; flex-wrap: wrap;
}

/* ───── STICKY MOBILE CTA ─────
 * Pinned to the bottom of the viewport on mobile after the user
 * scrolls past the hero. JS toggles `.sticky-cta--visible` once the
 * hero leaves the viewport. The bar is a translucent card with a
 * frosted backdrop so the page content underneath still reads. */
.sticky-cta {
  position: fixed;
  left: 12px; right: 12px;
  bottom: max(12px, env(safe-area-inset-bottom));
  z-index: 90;
  display: none;
  gap: 10px;
  padding: 10px;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid var(--border);
  border-radius: 9999px;
  box-shadow: 0 12px 30px rgba(20, 15, 8, 0.18);
  transform: translateY(140%);
  opacity: 0;
  transition: transform 280ms cubic-bezier(.2,.7,.2,1), opacity 220ms ease-out;
  pointer-events: none;
}
.sticky-cta--visible { transform: translateY(0); opacity: 1; pointer-events: auto; }
.sticky-cta .btn-primary {
  flex: 1;
  justify-content: center;
  font-size: 14px;
  padding: 11px 14px;
  gap: 6px;
}
/* Show only on phones — desktop has the always-visible nav CTA. */
@media (max-width: 720px) {
  .sticky-cta { display: flex; }
}

/* ─── Reduced motion ─────────────────────────────────────────────────
   Honor prefers-reduced-motion: the page runs many decorative loops (orbit,
   breathe, twinkle, confetti, mic pulse/rings, bobble, bars). Kill them and the
   smooth-scroll; the scroll-driven scene swaps remain (they're content, not
   gratuitous motion) and landing.js also skips the typewriter + confetti. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0ms !important; /* else staggered entrances hold invisible (backwards fill) for their full delay before snapping in */
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
}
