/*
 * Sprout Ventures — shared stylesheet
 *
 * Design system mirrors the HighPERSleep/Sprout RN app:
 *   • Deep navy backdrop (#06091d → #0e1438)
 *   • Gold (#F0C060) primary accent
 *   • Olive (#7EB87A) for success / nature
 *   • Lavender (#bda7e8) for night / circadian
 *   • Soft glass surfaces (translucent white tints)
 *
 * Pages: index (Ventures landing), sprout (app intro),
 *        privacy, terms — all share this stylesheet.
 */

:root {
  --bg:         #06091d;
  --bg-2:       #0a0e1f;
  --sheet:      #0e1438;
  --txt:        #ffffff;
  --txt2:       rgba(255, 255, 255, 0.72);
  --txt3:       rgba(255, 255, 255, 0.45);
  --border:     rgba(255, 255, 255, 0.10);
  --border-2:   rgba(255, 255, 255, 0.18);
  --gold:       #F0C060;
  --gold-2:     #E8B84B;
  --gold-3:     #c9962e;
  --olive:      #7EB87A;
  --olive-2:    #A8D4A4;
  --blue:       #88AAEE;
  --navy:       #3b4878;
  --lavender:   #bda7e8;
  --red:        #e0492a;

  /* Typography */
  --font:       -apple-system, BlinkMacSystemFont, "SF Pro Display",
                "Inter", "Helvetica Neue", system-ui, sans-serif;
}

/* ── Reset + base ────────────────────────────────────────────── */
* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  font-family: var(--font);
  color: var(--txt);
  background: var(--bg);
  min-height: 100vh;
  line-height: 1.5;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }

/* ── Layout helpers ──────────────────────────────────────────── */
.container {
  width: 100%; max-width: 1180px;
  margin: 0 auto;
  padding: 0 28px;
}
.container-narrow {
  width: 100%; max-width: 760px;
  margin: 0 auto;
  padding: 0 28px;
}

/* ── Navigation ──────────────────────────────────────────────── */
.nav {
  position: sticky; top: 0; z-index: 50;
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  background: rgba(6, 9, 29, 0.75);
  border-bottom: 1px solid var(--border);
}
.nav-inner {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 28px;
  max-width: 1180px; margin: 0 auto;
}
.nav-brand {
  display: flex; align-items: center;
  /* Slight fade on hover so the wordmark feels like a tappable target */
  transition: opacity 0.2s ease;
}
.nav-brand:hover { opacity: 0.85; }
/* Horizontal Sprout Ventures wordmark — sized by HEIGHT so it stays
   crisp at every breakpoint. The animated APNG canvas is 1500×540
   (2.78:1), so 60px tall renders ~167px wide. The static last-frame
   PNG shares those dimensions, so the swap is dimensional-identical. */
.nav-logo {
  height: 60px;
  width: auto;
  display: block;
}
.nav-links {
  display: flex; align-items: center; gap: 28px;
}
.nav-links a {
  font-size: 14px; font-weight: 600; color: var(--txt2);
  transition: color 0.2s ease;
}
.nav-links a:hover, .nav-links a.active { color: var(--txt); }
.nav-cta {
  padding: 9px 18px;
  background: var(--gold);
  color: #000;
  border-radius: 999px;
  font-size: 13px; font-weight: 800; letter-spacing: 0.2px;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.nav-cta:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 24px rgba(240, 192, 96, 0.35);
}

/* ── Sky background (matches app's TimeSky) ─────────────────────
   The alpha + position values are CSS vars so JS can subtly shift them
   as the page scrolls. Fallbacks restore the original cosmic look. */
.sky {
  position: fixed; inset: 0; z-index: -1;
  background:
    radial-gradient(ellipse at 20% var(--sky-top-y, 0%),
      rgba(189, 167, 232, var(--sky-lavender, 0.14)), transparent 50%),
    radial-gradient(ellipse at 80% var(--sky-bot-y, 100%),
      rgba(240, 192, 96, var(--sky-gold, 0.10)), transparent 50%),
    radial-gradient(ellipse at 50% 50%,
      rgba(136, 170, 238, var(--sky-blue, 0.06)), transparent 60%),
    var(--bg);
  transition: background 0.3s linear;
}

/* ── Aurora — cursor-driven parallax blobs ─────────────────────────
   Three large radial-gradient blobs that:
     • drift on their own slow keyframe loops (idle motion)
     • translate in response to cursor via --aurora-x / --aurora-y
       (each blob uses a different multiplier so they parallax at
       different rates — that's what sells the "aurora curtain in
       3D space" feeling vs. a flat overlay)
   The composition trick: the `translate` CSS property (cursor offset)
   and `transform: translate(...)` inside the keyframes COMPOSE rather
   than overwrite, so the idle drift and the cursor parallax run
   independently without any JS having to interpolate transforms. */
.aurora {
  position: fixed; inset: -20%; z-index: -1;
  pointer-events: none;
  overflow: hidden;
  /* Heavy blur is what makes blobs read as "light", not "discs". */
  filter: blur(70px);
}
.aurora-blob {
  position: absolute;
  width: 70vw; height: 70vw;
  border-radius: 50%;
  /* mix-blend-mode: screen lifts the underlying .sky into glowing
     colour where the blob overlaps it — same approach Linear / Vercel
     use for hero atmospherics. */
  mix-blend-mode: screen;
  will-change: transform, translate;
  transition: translate 1.1s var(--ease-pro, ease-out);
}
/* Each blob's `translate` combines THREE motion sources:
     1. cursor parallax  — var(--aurora-x|y) ∈ [-1..1]
     2. scroll parallax  — var(--sy)         ∈ [ 0..1]
     3. idle drift       — applied via `transform` in the keyframes
   1 + 2 live on the `translate` property (so they compose with idle).
   The scroll term uses different signs per blob so the layers shear
   apart as the user scrolls — same depth illusion as cursor motion. */
.aurora-blob.a1 {
  background: radial-gradient(circle, rgba(189, 167, 232, 0.65), transparent 65%);
  top: -22%; left: -18%;
  /* Cursor: follows. Scroll: drifts down with the page. */
  translate:
    calc(var(--aurora-x, 0) * 110px)
    calc(var(--aurora-y, 0) *  70px + var(--sy, 0) *  120px);
  animation: aurora-drift-a 28s ease-in-out infinite alternate;
}
.aurora-blob.a2 {
  background: radial-gradient(circle, rgba(240, 192, 96, 0.55), transparent 65%);
  bottom: -25%; right: -18%;
  /* Cursor: counter (depth). Scroll: rises against the page. */
  translate:
    calc(var(--aurora-x, 0) * -80px)
    calc(var(--aurora-y, 0) * -55px + var(--sy, 0) * -90px);
  animation: aurora-drift-b 34s ease-in-out infinite alternate;
}
.aurora-blob.a3 {
  background: radial-gradient(circle, rgba(136, 170, 238, 0.55), transparent 65%);
  top: 22%; left: 32%;
  width: 55vw; height: 55vw;
  /* Cursor: perpendicular. Scroll: pushes hard upward (mid-layer rises). */
  translate:
    calc(var(--aurora-x, 0) * 130px)
    calc(var(--aurora-y, 0) * -90px + var(--sy, 0) * -160px);
  animation: aurora-drift-c 42s ease-in-out infinite alternate;
}

/* Idle drift — slow, organic, looped. The amplitudes (vw/vh) are large
   on purpose; combined with the 70px blur the actual visible motion
   is gentle. ease-in-out + alternate gives the curtain its breathing. */
@keyframes aurora-drift-a {
  0%   { transform: translate(0, 0)     scale(1); }
  100% { transform: translate(14vw, 8vh) scale(1.12); }
}
@keyframes aurora-drift-b {
  0%   { transform: translate(0, 0)       scale(1.1); }
  100% { transform: translate(-12vw, -6vh) scale(0.95); }
}
@keyframes aurora-drift-c {
  0%   { transform: translate(0, 0)      scale(1); }
  100% { transform: translate(-9vw, 11vh) scale(1.18); }
}

/* ── Aurora variant for the product page (sprout.html) ─────────────
   Same physics — new colour palette, new idle paths, slightly tighter
   blur. Pushes olive (Sprout's "growth" colour) to the foreground, with
   a cool lavender counter-light and a deep blue mid-band. The cursor
   parallax multipliers are tweaked so the product page feels just a
   bit more responsive than the studio landing. */
.aurora.aurora-sprout {
  filter: blur(60px);
}
.aurora.aurora-sprout .aurora-blob.a1 {
  background: radial-gradient(circle, rgba(126, 184, 122, 0.55), transparent 65%);
  top: -18%; left: -22%;
  /* Sprout page: scroll pushes the olive layer down hard — feels like
     the canvas is descending with the reader. */
  translate:
    calc(var(--aurora-x, 0) *  90px)
    calc(var(--aurora-y, 0) *  85px + var(--sy, 0) *  140px);
  animation: aurora-drift-sprout-a 32s ease-in-out infinite alternate;
}
.aurora.aurora-sprout .aurora-blob.a2 {
  background: radial-gradient(circle, rgba(189, 167, 232, 0.55), transparent 65%);
  bottom: -22%; right: -22%;
  /* Counter on cursor AND counter on scroll → strong depth feel. */
  translate:
    calc(var(--aurora-x, 0) * -100px)
    calc(var(--aurora-y, 0) *  -60px + var(--sy, 0) * -110px);
  animation: aurora-drift-sprout-b 26s ease-in-out infinite alternate;
}
.aurora.aurora-sprout .aurora-blob.a3 {
  background: radial-gradient(circle, rgba(136, 170, 238, 0.45), transparent 65%);
  top: 35%; left: 28%;
  width: 60vw; height: 60vw;
  /* Mid-layer slides sideways as well as up — turbulence on scroll. */
  translate:
    calc(var(--aurora-x, 0) *  120px
       + var(--sy,       0) *  -70px)
    calc(var(--aurora-y, 0) * -110px
       + var(--sy,       0) * -180px);
  animation: aurora-drift-sprout-c 38s ease-in-out infinite alternate;
}

@keyframes aurora-drift-sprout-a {
  0%   { transform: translate(0, 0)       scale(1); }
  100% { transform: translate(11vw, 13vh) scale(1.10); }
}
@keyframes aurora-drift-sprout-b {
  0%   { transform: translate(0, 0)       scale(1.08); }
  100% { transform: translate(-14vw, -9vh) scale(0.92); }
}
@keyframes aurora-drift-sprout-c {
  0%   { transform: translate(0, 0)       scale(1); }
  100% { transform: translate(-12vw, 14vh) scale(1.20); }
}
/* Twinkling star layer */
.sky::before, .sky::after {
  content: '';
  position: absolute; inset: 0;
  background-image:
    radial-gradient(1.5px 1.5px at 12% 18%, rgba(255,255,255,0.7), transparent 50%),
    radial-gradient(1px   1px   at 28% 30%, rgba(255,255,255,0.6), transparent 50%),
    radial-gradient(1px   1px   at 88% 22%, rgba(255,255,255,0.7), transparent 50%),
    radial-gradient(1px   1px   at 72% 45%, rgba(255,255,255,0.5), transparent 50%),
    radial-gradient(1.5px 1.5px at 16% 70%, rgba(255,255,255,0.6), transparent 50%),
    radial-gradient(1px   1px   at 92% 60%, rgba(255,255,255,0.5), transparent 50%),
    radial-gradient(1.5px 1.5px at 56% 85%, rgba(255,255,255,0.7), transparent 50%),
    radial-gradient(1px   1px   at 38% 88%, rgba(255,255,255,0.5), transparent 50%),
    radial-gradient(1px   1px   at 82% 12%, rgba(255,255,255,0.6), transparent 50%),
    radial-gradient(1px   1px   at 8%  50%, rgba(255,255,255,0.5), transparent 50%);
  animation: twinkle 6s ease-in-out infinite alternate;
}
.sky::after {
  animation-delay: 3s; opacity: 0.6;
}
@keyframes twinkle {
  0%   { opacity: 0.5; }
  100% { opacity: 1; }
}

/* ── Hero shared ─────────────────────────────────────────────── */
.hero {
  padding: 120px 0 80px;
  text-align: center;
}
.kicker {
  display: inline-block;
  padding: 6px 14px;
  background: rgba(240, 192, 96, 0.12);
  border: 1px solid rgba(240, 192, 96, 0.30);
  border-radius: 999px;
  font-size: 11px; font-weight: 800;
  letter-spacing: 1.4px; text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 22px;
}
.hero h1 {
  font-size: clamp(40px, 6vw, 72px);
  font-weight: 900;
  letter-spacing: -2px;
  line-height: 1.05;
  margin-bottom: 22px;
  background: linear-gradient(180deg, #fff 0%, #d8dce8 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.hero h1 .gold {
  /* Golden-hour sunset palette, animated. Same gradient + drift as
     `.always-gold` so every gold accent across the site catches the
     same drifting light. Per-element animation-delay applied in the
     consolidated "GOLDEN-HOUR TREATMENT" block further down. */
  background: var(--golden-hour-grad, linear-gradient(105deg,
    #fff0c2 0%, #ffd56a 14%, #ffaa3b 30%, #e0691f 50%,
    #ffaa3b 70%, #ffd56a 86%, #fff0c2 100%));
  background-size: 250% 100%;
  background-position: 0% 50%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.hero p.lead {
  font-size: clamp(16px, 2vw, 19px);
  color: var(--txt2);
  max-width: 620px; margin: 0 auto 36px;
  line-height: 1.55;
}
.hero-ctas {
  display: flex; gap: 14px; justify-content: center; flex-wrap: wrap;
}

/* ── Buttons ─────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 14px 26px;
  border-radius: 999px;
  font-size: 15px; font-weight: 800;
  letter-spacing: 0.2px;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.btn-primary {
  background: linear-gradient(135deg, var(--gold-2), var(--gold-3));
  color: #000;
  box-shadow: 0 8px 24px rgba(240, 192, 96, 0.30);
}
.btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 32px rgba(240, 192, 96, 0.45);
}
.btn-ghost {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--border-2);
  color: var(--txt);
}
.btn-ghost:hover { background: rgba(255, 255, 255, 0.10); }

/* ── Section base ────────────────────────────────────────────── */
section {
  padding: 80px 0;
  position: relative;
  z-index: 1;
}
.section-head {
  text-align: center;
  margin-bottom: 56px;
}
.section-head .kicker { margin-bottom: 16px; }
.section-head h2 {
  font-size: clamp(28px, 4vw, 44px);
  font-weight: 900;
  letter-spacing: -1px;
  line-height: 1.15;
  max-width: 680px; margin: 0 auto 14px;
}
.section-head p {
  color: var(--txt2);
  font-size: 16px; line-height: 1.55;
  max-width: 560px; margin: 0 auto;
}

/* ── Feature grid ────────────────────────────────────────────── */
.feature-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 20px;
  overflow: visible;
}
/* On narrow viewports, stack cards cleanly */
@media (max-width: 540px) {
  .feature-grid {
    grid-template-columns: 1fr;
  }
}
.feature {
  padding: 28px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--border);
  border-radius: 22px;
  /* transition is set in the reveal-stagger section below for richer animation */
}
.feature:hover {
  border-color: var(--border-2);
  background: rgba(255, 255, 255, 0.05);
}
.feature .icon {
  width: 44px; height: 44px;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px;
  margin-bottom: 18px;
}
.feature.gold   .icon { background: rgba(240,192,96,0.14); border: 1px solid rgba(240,192,96,0.30); }
.feature.olive  .icon { background: rgba(126,184,122,0.14); border: 1px solid rgba(126,184,122,0.30); }
.feature.blue   .icon { background: rgba(136,170,238,0.14); border: 1px solid rgba(136,170,238,0.30); }
.feature.lavender .icon { background: rgba(189,167,232,0.14); border: 1px solid rgba(189,167,232,0.30); }
.feature.red    .icon { background: rgba(224,73,42,0.14); border: 1px solid rgba(224,73,42,0.30); }
.feature h3 {
  font-size: 17px; font-weight: 800;
  letter-spacing: -0.2px; margin-bottom: 8px;
}
.feature p {
  font-size: 14px; color: var(--txt2);
  line-height: 1.55;
}

/* ── Phone mockup ────────────────────────────────────────────── */
.phone {
  width: 100%; max-width: 320px;
  margin: 0 auto;
  aspect-ratio: 9 / 19.5;
  border-radius: 38px;
  background: var(--bg);
  border: 1px solid rgba(255, 255, 255, 0.10);
  box-shadow:
    0 30px 80px rgba(0, 0, 0, 0.55),
    inset 0 0 0 2px rgba(255, 255, 255, 0.04);
  position: relative; overflow: hidden;
}
.phone::before {
  content: ''; position: absolute; top: 12px; left: 50%;
  transform: translateX(-50%);
  width: 110px; height: 30px; border-radius: 18px;
  background: #000; z-index: 50;
}
.phone-inner {
  position: absolute; inset: 0;
  padding: 60px 20px 28px;
  display: flex; flex-direction: column;
  background:
    radial-gradient(ellipse at 50% 0%, rgba(189,167,232,0.20), transparent 60%),
    radial-gradient(ellipse at 30% 100%, rgba(240,192,96,0.15), transparent 70%),
    linear-gradient(180deg, #0a0e1f 0%, #14193a 100%);
}

/* ── Showcase row (phone + text) ─────────────────────────────── */
.showcase {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 60px;
  align-items: center;
  margin-bottom: 80px;
}
.showcase:nth-child(even) .showcase-phone { order: 2; }
.showcase-text h3 {
  font-size: clamp(24px, 3vw, 34px);
  font-weight: 900;
  letter-spacing: -0.8px; margin-bottom: 16px;
  line-height: 1.2;
}
.showcase-text .accent {
  display: inline-block;
  font-size: 11px; font-weight: 800; letter-spacing: 1.4px;
  text-transform: uppercase;
  margin-bottom: 14px;
  color: var(--gold);
}
.showcase.olive    .showcase-text .accent { color: var(--olive); }
.showcase.lavender .showcase-text .accent { color: var(--lavender); }
.showcase.blue     .showcase-text .accent { color: var(--blue); }
.showcase-text p {
  color: var(--txt2); font-size: 16px; line-height: 1.65;
  margin-bottom: 14px;
}
.showcase-text ul {
  margin-top: 18px; list-style: none;
}
.showcase-text li {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 6px 0;
  color: var(--txt2); font-size: 14px;
}
.showcase-text li::before {
  content: ''; flex-shrink: 0;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--gold); margin-top: 8px;
}
@media (max-width: 800px) {
  .showcase { grid-template-columns: 1fr; gap: 30px; }
  .showcase:nth-child(even) .showcase-phone { order: 0; }
}

/* ── CTA section ─────────────────────────────────────────────── */
.cta-block {
  padding: 64px 40px;
  margin-bottom: 20px;
  border-radius: 32px;
  background:
    radial-gradient(ellipse at 30% 30%, rgba(240,192,96,0.18), transparent 60%),
    radial-gradient(ellipse at 70% 70%, rgba(189,167,232,0.16), transparent 60%),
    linear-gradient(135deg, rgba(255,255,255,0.04), rgba(255,255,255,0.02));
  border: 1px solid var(--border-2);
  text-align: center;
  /* No `position: relative; z-index: 0;` here.
     That combo isolated the cta-block in its own stacking context BELOW
     the parent section's z-index:1 — which let the Principles feature
     cards above (and their reveal-transform animations) paint OVER the
     "Meet Sprout" block during scroll. Letting it sit in normal flow at
     the section's own stacking level keeps everything in order. */
}
.cta-block h2 {
  font-size: clamp(28px, 4vw, 42px);
  font-weight: 900;
  letter-spacing: -1px;
  line-height: 1.15;
  margin-bottom: 14px;
}

/* Extra breathing room above the product section specifically — it sits
   right under the Principles feature-grid, and the feature cards' hover
   lift (translateY -6px + 50px box-shadow) was butting too close. */
#products {
  padding-top: 120px;
}

/* Same defensive padding for the sprout.html sections — same root cause:
   .screenshot-frame inside .showcase has a 0 30px 80px black shadow that
   spills ~110px below the frame, and the .feature card hover lifts can
   reach into the next section if its top padding is only 80px. */
#features,
#download {
  padding-top: 120px;
}
/* The "Grounded in research" section between #features and #download is
   the only major one without an id, so target it via :has() (modern
   browsers — all the ones we support). */
.container:has(> .section-head + .feature-grid) {
  padding-top: 120px;
}
.cta-block p {
  color: var(--txt2);
  font-size: 16px; line-height: 1.55;
  max-width: 520px; margin: 0 auto 28px;
}

/* ── Footer ──────────────────────────────────────────────────── */
.footer {
  padding: 56px 0 32px;
  border-top: 1px solid var(--border);
  background: rgba(6, 9, 29, 0.5);
  margin-top: 80px;
}
.footer-inner {
  display: grid;
  grid-template-columns: 1.4fr repeat(3, 1fr);
  gap: 40px;
  padding: 0 28px;
  max-width: 1180px; margin: 0 auto 40px;
}
@media (max-width: 800px) {
  .footer-inner { grid-template-columns: 1fr 1fr; }
}
.footer-brand h4 { font-size: 18px; font-weight: 900; letter-spacing: -0.3px; margin-bottom: 10px; }
.footer-brand p  { font-size: 13px; color: var(--txt3); line-height: 1.55; max-width: 280px; }
.footer-col h5 {
  font-size: 11px; font-weight: 800; letter-spacing: 1.4px;
  color: var(--txt3); text-transform: uppercase;
  margin-bottom: 14px;
}
.footer-col a {
  display: block;
  font-size: 14px; color: var(--txt2);
  padding: 5px 0;
  transition: color 0.2s ease;
}
.footer-col a:hover { color: var(--gold); }
.footer-bottom {
  text-align: center;
  font-size: 12px; color: var(--txt3);
  padding: 20px 28px 0;
  border-top: 1px solid var(--border);
  max-width: 1180px; margin: 0 auto;
}

/* ── Reveal-on-scroll ────────────────────────────────────────── */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.7s ease, transform 0.7s ease;
}
.reveal.in {
  opacity: 1;
  transform: translateY(0);
}

/* ── Staggered reveal — children animate in one by one (Apple-style) ── */
.reveal-stagger .reveal-child {
  opacity: 0;
  transform: translateY(32px);
  transition: opacity 0.65s cubic-bezier(0.22, 1, 0.36, 1),
              transform 0.65s cubic-bezier(0.22, 1, 0.36, 1);
}
.reveal-stagger.in .reveal-child { opacity: 1; transform: translateY(0); }
/* Each child gets a successively longer delay */
.reveal-stagger.in .reveal-child:nth-child(1) { transition-delay: 0.05s; }
.reveal-stagger.in .reveal-child:nth-child(2) { transition-delay: 0.15s; }
.reveal-stagger.in .reveal-child:nth-child(3) { transition-delay: 0.25s; }
.reveal-stagger.in .reveal-child:nth-child(4) { transition-delay: 0.35s; }
.reveal-stagger.in .reveal-child:nth-child(5) { transition-delay: 0.45s; }
.reveal-stagger.in .reveal-child:nth-child(6) { transition-delay: 0.55s; }

/* ── Hero text cascade — each line drops in ────────────────────── */
.hero .kicker, .hero h1, .hero p.lead, .hero .hero-ctas {
  opacity: 0;
  transform: translateY(22px);
  animation: hero-drop 0.8s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
.hero .kicker      { animation-delay: 0.1s; }
.hero h1           { animation-delay: 0.25s; }
.hero p.lead       { animation-delay: 0.4s; }
.hero .hero-ctas   { animation-delay: 0.55s; }
@keyframes hero-drop {
  to { opacity: 1; transform: translateY(0); }
}

/* ── Subtle scale-in for feature cards on hover ────────────────── */
.feature {
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1),
              border-color 0.4s ease, background 0.4s ease,
              box-shadow 0.5s ease;
}
.feature:hover {
  transform: translateY(-6px) scale(1.02);
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3);
}

/* ── Mission statement lines ────────────────────────────────────── */
.mission-statement {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin-top: 40px;
}
.mission-line {
  display: flex;
  gap: 20px;
  align-items: baseline;
  padding: 24px 0;
  border-bottom: 1px solid var(--border);
}
.mission-line:first-child { border-top: 1px solid var(--border); }
.mission-accent {
  flex-shrink: 0;
  font-size: 12px;
  font-weight: 900;
  letter-spacing: 0.5px;
  color: var(--gold);
  opacity: 0.6;
  min-width: 28px;
}
.mission-line p {
  font-size: 16px;
  color: var(--txt2);
  line-height: 1.65;
  margin: 0;
}
.mission-line em {
  color: var(--gold);
  font-style: italic;
}

/* ── Scroll-driven parallax helper ─────────────────────────────── */
.parallax-slow {
  transition: transform 0.1s linear;
  will-change: transform;
}

/* ── Glow pulse on CTA block — contained so it doesn't bleed into neighbors ── */
.cta-block {
  animation: glow-pulse 4s ease-in-out infinite alternate;
}
@keyframes glow-pulse {
  0%   { box-shadow: 0 0 0 rgba(240,192,96,0); }
  100% { box-shadow: 0 0 40px rgba(240,192,96,0.05); }
}

/* ── Floating sprout mascot animation (hero) ─────────────────── */
@keyframes float {
  0%, 100% { transform: translateY(0) rotate(-1deg); }
  50%      { transform: translateY(-14px) rotate(1deg); }
}
.float-sprout {
  animation: float 4s ease-in-out infinite;
}

/* ── Pricing card (privacy / terms anchor) ───────────────────── */
.price-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 18px;
}
.price-card {
  padding: 28px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border-2);
  border-radius: 22px;
  text-align: left;
}
.price-card.featured {
  border-color: var(--gold);
  background:
    radial-gradient(ellipse at 0% 0%, rgba(240,192,96,0.18), transparent 50%),
    rgba(255, 255, 255, 0.04);
}
.price-card h4 { font-size: 14px; font-weight: 800; letter-spacing: 0.4px; color: var(--txt3); text-transform: uppercase; margin-bottom: 10px; }
.price-card .price {
  font-size: 38px; font-weight: 900; letter-spacing: -1.5px;
  margin-bottom: 6px;
}
.price-card .per { font-size: 13px; color: var(--txt3); margin-bottom: 18px; }
.price-card ul { list-style: none; }
.price-card li { padding: 6px 0; font-size: 14px; color: var(--txt2); }
.price-card li::before { content: '✓ '; color: var(--olive); font-weight: 800; }

/* ── Legal pages ─────────────────────────────────────────────── */
.legal {
  padding: 80px 0;
}
.legal h1 {
  font-size: clamp(32px, 5vw, 48px);
  font-weight: 900; letter-spacing: -1px;
  margin-bottom: 8px;
}
.legal .updated {
  font-size: 13px; color: var(--txt3);
  margin-bottom: 40px;
}
.legal h2 {
  font-size: 20px; font-weight: 800;
  margin: 36px 0 14px;
  letter-spacing: -0.3px;
}
.legal p, .legal li {
  font-size: 15px; color: var(--txt2);
  line-height: 1.75;
  margin-bottom: 14px;
}
.legal ul { padding-left: 22px; }
.legal a {
  color: var(--gold);
  border-bottom: 1px dotted rgba(240, 192, 96, 0.4);
}

/* ── Phone-screen mocks ──────────────────────────────────────── */
.mock-greeting {
  font-size: 11px; color: rgba(255,255,255,0.7);
  font-weight: 700;
  margin-bottom: 4px;
}
.mock-name {
  font-size: 22px; font-weight: 900; letter-spacing: -0.4px;
  margin-bottom: 24px;
}
.mock-card {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 18px;
  padding: 14px;
  margin-bottom: 12px;
}
.mock-card .label {
  font-size: 9px; font-weight: 800; letter-spacing: 1.4px;
  color: rgba(255,255,255,0.4);
  text-transform: uppercase;
  margin-bottom: 6px;
}
.mock-card .value {
  font-size: 26px; font-weight: 900; letter-spacing: -1px;
  color: var(--gold);
}
.mock-card .sub {
  font-size: 12px; color: rgba(255,255,255,0.55);
  margin-top: 4px;
}
.mock-ring {
  width: 120px; height: 120px;
  border-radius: 50%;
  border: 8px solid var(--gold);
  border-right-color: rgba(255,255,255,0.10);
  border-bottom-color: rgba(255,255,255,0.10);
  margin: 20px auto;
  display: flex; align-items: center; justify-content: center;
  font-size: 28px; font-weight: 900;
  transform: rotate(-15deg);
}
.mock-ring span { transform: rotate(15deg); }
.mock-bubble {
  display: inline-block;
  padding: 10px 14px;
  border-radius: 16px;
  font-size: 13px;
  margin-bottom: 8px;
  max-width: 85%;
}
.mock-bubble.user {
  background: var(--gold);
  color: #0e1438;
  align-self: flex-end;
  border-bottom-right-radius: 4px;
}
.mock-bubble.assist {
  background: rgba(255,255,255,0.08);
  color: var(--txt);
  border-bottom-left-radius: 4px;
}
.mock-pot {
  width: 60px; height: 36px;
  background: linear-gradient(180deg, #8a4030, #5a2818);
  border-radius: 6px;
  position: relative; margin: 0 auto;
}
.mock-pot::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0;
  height: 7px; background: #1a0d08; border-radius: 6px 6px 0 0;
}
.mock-pot::after {
  content: '🌱'; position: absolute; top: -38px; left: 50%;
  transform: translateX(-50%); font-size: 32px;
}

/* ── Marquee scroll for app screenshots ──────────────────────── */
.phone-row {
  display: flex; gap: 24px; justify-content: center;
  flex-wrap: wrap;
  margin: 50px 0;
}
.phone-row .phone {
  flex: 0 0 280px;
  transform: scale(0.92);
  transition: transform 0.4s ease;
}
.phone-row .phone:hover {
  transform: scale(0.98) translateY(-8px);
}

/* ── 3D phone iframe (used inside showcase-phone) ───────────────────────
   The 3D phones in assets/3d-phones/ are self-contained HTML pages that
   render a CSS-3D iPhone with built-in idle sway, mouse-follow tilt, and
   a slow light swipe across the glass. We embed them via iframe so each
   phone keeps its own scoped JS (--p3d-rx/--p3d-ry vars driven by the
   per-frame mousemove handler). The iframe inherits a transparent
   background from the embedded body{background:transparent}, so it
   blends into the showcase column without any visible frame chrome.

   Sizing: the embedded phone uses --p3d-w: min(62vw, 38vh) of its own
   viewport, so a 480×640 iframe gives a comfortably sized phone with
   air around it for the idle float to read. The iframe's aspect-ratio
   is fixed so the layout never shifts as the phone loads in. */
.phone-3d {
  display: block;
  width: 100%;
  max-width: 480px;
  aspect-ratio: 3 / 4;
  margin: 0 auto;
  border: 0;
  background: transparent;
  /* Subtle cool drop shadow underneath, matching the glass card family,
     so the phone reads as floating above the page rather than pasted on. */
  filter: drop-shadow(0 18px 28px rgba(60, 80, 120, 0.18));
  /* Hover lift mirrors the screenshot frame's old behaviour so the
     interaction language stays consistent across the page. */
  transition: transform 0.4s var(--ease-pro, ease);
  /* Performance: each iframe runs its own 3D CSS transforms + idle-sway
     JS loop. With 5 of them on the page, off-screen iframes can chew
     mobile GPU/CPU for nothing. `content-visibility: auto` tells the
     browser to skip rendering & layout for the iframe when it's
     scrolled out of view (and resume once it scrolls back in).
     `contain-intrinsic-size` reserves a placeholder size so the
     scrollbar/page height doesn't jump as iframes are skipped.
     Desktop browsers ignore content-visibility:auto gracefully when
     the iframe is visible anyway, so this is a pure mobile win. */
  content-visibility: auto;
  contain-intrinsic-size: 480px 640px;
}
.phone-3d:hover {
  transform: translateY(-6px);
}
@media (max-width: 800px) {
  .phone-3d { max-width: 380px; }
}

/* Trio variant — three phones fanned in a single composition.
   Wider iframe so all three read comfortably without each phone
   collapsing too small. Bumped to 760 so the three fanned phones
   feel headline-sized on the Recovery Fuel row. */
.phone-3d-trio {
  max-width: 760px;
  aspect-ratio: 4 / 3;
}
@media (max-width: 800px) {
  .phone-3d-trio { max-width: 460px; }
}

/* Trio-row showcase: give the phone column more of the grid so the
   wider iframe actually has room to render at full size. The Recovery
   Fuel row is the 2nd child of #features, which means it picks up the
   `.showcase:nth-child(even) .showcase-phone { order: 2 }` rule and the
   phone renders on the RIGHT. So the right column needs to be the wide
   one — text on the left at 1fr, phone on the right at 1.55fr. */
@media (min-width: 801px) {
  .showcase.trio-row {
    grid-template-columns: 1fr 1.55fr;
  }
}

/* ── Screenshot frame (used inside showcase-phone) ──────────────────────
   Re-wired around the iPhone 15 mockup PNG. The frame asset is 350×350
   with the visible phone occupying ~150×304 (the rest of the square is
   transparent surround). Measured screen area inside the phone body:
       top  : 8.6%   left : 28.9%
       width: 42.2%  height: 82.8%   (ratio ≈ 0.51, close to iPhone 19.5:9)
   The screenshot images are positioned absolutely into that screen
   rectangle so they fit exactly inside the bezel.

   The phone PNG sits on a ::after layer above the screenshot so the
   bezel, Dynamic Island, and side keys read in front of the content.
*/
.screenshot-frame {
  position: relative;
  width: 100%;
  max-width: 520px;        /* Bumped from 360 → 520 so the visible
                              screen rectangle (42.2% of width = ~220 px)
                              reads as a comfortable phone again,
                              comparable to the pre-bezel screenshot size. */
  aspect-ratio: 1 / 1;     /* matches the 350×350 frame asset */
  margin: 0 auto;
  background: transparent;
  border: none;
  border-radius: 0;
  /* Drop the heavy 0/0 black shadow — the phone frame carries its own
     subtle depth. The screen inset shadow below carries the screen edge. */
  box-shadow: none;
  overflow: hidden;        /* belt-and-braces: clip anything that tries
                              to escape the wrapper box */
  transition: transform 0.4s ease;
  isolation: isolate;      /* keep day-overlay mask scoped to this frame */
}
.screenshot-frame:hover {
  transform: translateY(-8px) scale(1.02);
}

/* ── Sizing maths (referenced by every rule below) ──────────────────────
   iPhone PNG is 350×350 with the visible phone occupying the centre.
   The TRANSPARENT screen aperture in the bezel measures:
       top inset    : 30 / 350 = 8.57 %
       bottom inset : 31 / 350 = 8.86 %
       height       : 290/350 = 82.86 %
       left inset   : 101/350 = 28.86 %
       right inset  : 102/350 = 29.14 %
       width        : 147/350 = 42 %        → aperture ratio 0.51
   But the screenshots themselves are 1179×2556 (iPhone 15 Pro native)
   = ratio 0.4613 — NARROWER than the bezel's aperture. If we stretch
   the screenshot to fill the full aperture (42 % wide), object-fit:cover
   crops the bottom and object-fit:contain leaves vertical letterbox.
   Solution: keep the screenshot at its true 9:19.5 aspect ratio
   (centred inside the aperture) AND paint a black backdrop behind it
   that fills the full aperture. The thin black band on each side then
   reads as the natural inner screen border every iPhone has between
   the glass and the metal frame — looks intentional, not broken. */
.screenshot-frame::before {
  /* BLACK SCREEN BACKDROP — fills the full bezel aperture. */
  content: '';
  position: absolute;
  inset: 8.57% auto auto 28.86%;
  width: 42%;
  height: 82.86%;
  background: #000;
  border-radius: 22px;
  z-index: 0;
}

/* The phone bezel — painted on top of the screenshot so the chrome,
   notch / Dynamic Island, and side buttons read in front of the
   content. z-index above the screenshot and day-overlay so its
   rounded inner corners reliably cover the screenshot's corners. */
.screenshot-frame::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url('assets/iphone-15-mockup-front-view-isolated-illustration-on-transparent-background-smartphone-or-mobile-phone-or-cellphone-cut-out-template-png.webp');
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  pointer-events: none;
  z-index: 3;
}

/* SCREENSHOT — sized to the screenshot's TRUE 9:19.5 ratio so nothing
   is cropped and nothing is letterboxed.
       width  = 38.29 % of frame ≈ 134 px in a 350-frame
       height = 82.86 % of frame ≈ 290 px in a 350-frame
       ratio  = 134/290 = 0.462  →  matches screenshot 0.4613 exactly
   Centred horizontally inside the aperture (left inset 30.86 % puts
   the screenshot 7 px in from the aperture's left edge; the matching
   7 px gap on the right shows the black ::before backdrop). The
   explicit `inset` shorthand here is critical — the legacy
   `.day-overlay { inset: 0 }` rule would otherwise leak right/bottom
   anchors through and over-constrain the box. */
.screenshot-frame > img {
  position: absolute;
  inset: 8.57% auto auto 30.86%;     /* top right bottom left */
  width: 38.29%;
  height: 82.86%;
  object-fit: cover;
  object-position: center;
  border-radius: 18px;
  display: block;
  z-index: 1;
}

/* ── Day-reveal spotlight on feature screenshots ──────────────────────
   Each .screenshot-frame[data-day] gets a second IMG injected by JS,
   stacked on top of the night version with a radial mask centred on
   the cursor. Where the mask is opaque the day image shows; where it
   fades to transparent, the night image bleeds through. The result:
   a soft round lens that "turns it to day" only where you point.

   ── POSITIONING NOTE ──
   The day-overlay is inset to the SAME screen rectangle as the night
   img above (see the maths comment block on .screenshot-frame::before).
   Earlier this rule had `inset: 0; width: 100%; height: 100%;` which
   stretched the day-overlay to the full 520×520 wrapper and leaked the
   day image out from behind the bezel — see the user-reported bug from
   2026-06-09. Merged the inset/width/height into this single rule so
   there's no duplicate-selector cascade hazard. */
.screenshot-frame[data-day] {
  isolation: isolate;       /* keep the mask scoped to this frame */
}
.screenshot-frame .day-overlay {
  position: absolute;
  inset: 8.57% auto auto 30.86%;   /* matches .screenshot-frame > img exactly */
  width: 38.29%;
  height: 82.86%;
  border-radius: 18px;
  z-index: 2;
  object-fit: cover;
  object-position: center;
  display: block;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.45s var(--ease-pro, ease);
  /* Organic-blob reveal — NOT a flashlight.
     The mask is a single SVG blob with a heavily Gaussian-blurred edge,
     drawn as an irregular Bézier path (no circles involved at all).
     JS picks one of three blob shapes randomly per frame and assigns it
     to --blob, so each screenshot reveals through a unique silhouette.
     mask-position keeps the blob centred on the cursor; mask-size sets
     the overall size of the lens. */
  --blob-size: 540px;
  -webkit-mask-image: var(--blob, none);
          mask-image: var(--blob, none);
  -webkit-mask-size: var(--blob-size) var(--blob-size);
          mask-size: var(--blob-size) var(--blob-size);
  -webkit-mask-position:
    calc(var(--rx, 50%) - var(--blob-size) / 2)
    calc(var(--ry, 50%) - var(--blob-size) / 2);
          mask-position:
    calc(var(--rx, 50%) - var(--blob-size) / 2)
    calc(var(--ry, 50%) - var(--blob-size) / 2);
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  will-change: mask-position, opacity;
}
/* Reveal-trigger states — desktop hover + touch class (mobile) */
.screenshot-frame:hover .day-overlay,
.screenshot-frame.touched .day-overlay {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .screenshot-frame .day-overlay { transition: none; }
}

/* ─────────────────────────────────────────────────────────────────────────
   APPLE-INSPIRED LAYER — index.html only (additive, doesn't break sub-pages)
   ─────────────────────────────────────────────────────────────────────────
   Easing curves used throughout:
     • --ease-pro:  cubic-bezier(0.5, 0, 0.1, 1)   — Apple's house curve
     • --ease-out:  cubic-bezier(0.22, 1, 0.36, 1) — softer overshoot for stagger
*/
:root {
  --ease-pro:  cubic-bezier(0.5, 0, 0.1, 1);
  --ease-out:  cubic-bezier(0.22, 1, 0.36, 1);
}

/* ── Scroll-progress rail ─────────────────────────────────────────────── */
/* A 2px gold rail at the very top of the viewport. JS sets --p (0..1)
   based on scroll position; CSS scales the inner span. Pure visual cue —
   adds the "this is a long-form story" feel without being intrusive. */
.scroll-progress {
  position: fixed; top: 0; left: 0; right: 0;
  height: 2px;
  background: rgba(255, 255, 255, 0.04);
  z-index: 100;
  pointer-events: none;
}
.scroll-progress span {
  display: block; height: 100%;
  width: 100%;
  transform-origin: left center;
  transform: scaleX(var(--p, 0));
  background: linear-gradient(90deg, var(--gold-3), var(--gold), var(--gold-2));
  transition: transform 0.08s linear;
}

/* ── Refined nav (used on the new index hero) ─────────────────────────── */
.nav-links a {
  font-size: 13px;
  font-weight: 600;
  color: var(--txt2);
  padding: 8px 14px;
  border-radius: 999px;
  transition: color 0.25s var(--ease-pro);
}
.nav-links a:hover { color: var(--txt); }
.nav-cta {
  background: var(--gold);
  color: #0a0d20 !important;
  font-weight: 800 !important;
  box-shadow: 0 6px 18px rgba(240, 192, 96, 0.22);
  transition: transform 0.25s var(--ease-pro), box-shadow 0.25s var(--ease-pro);
}
.nav-cta:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 24px rgba(240, 192, 96, 0.32);
}

/* ── Hero (Pro variant) ───────────────────────────────────────────────── */
.hero-pro {
  padding: 140px 0 110px;
  text-align: center;
  position: relative;
  isolation: isolate;
}
.hero-pro .hero-kicker { margin-bottom: 28px; }
/* Headline = the cursor lights up nearby words.
   Why this design (and not background-clip: text on a radial gradient):
   the per-word .word spans use `transform` for the entry animation,
   which creates a new stacking context per word. That breaks the
   parent's clipped-gradient paint across word boundaries — words ended
   up showing as either invisible or with no spotlight effect at all,
   depending on the browser. So instead, JS computes each word's centre
   on every frame and interpolates its `color` between cool-white and
   gold based on cursor proximity. Bullet-proof, and the CSS transition
   smooths the JS frame deltas into a buttery follow. */
.hero-pro .hero-title {
  font-size: clamp(44px, 7vw, 88px);
  font-weight: 900;
  letter-spacing: -2.2px;
  line-height: 1.02;
  margin: 0 auto 24px;
  max-width: 980px;
  /* Override the inherited .hero h1 animation — we drive entry per-word. */
  opacity: 1;
  transform: none;
  animation: none;
  /* Kill the inherited background-clip:text gradient from `.hero h1`. */
  background: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  -webkit-text-fill-color: currentColor;
  color: rgb(216, 220, 232); /* cool-white base */
  cursor: default;
}

/* Per-word: override the legacy .word rule's gradient-clip block entirely.
   Each word now has a plain color that JS animates between cool-white
   (#d8dce8) and gold (#F0C060) based on distance to the cursor. The CSS
   color transition smooths JS frame jitter into a soft follow. */
.hero-pro .hero-title .word {
  display: inline-block;
  opacity: 0;
  transform: translateY(38%);
  transition: opacity 0.85s var(--ease-pro),
              transform 0.85s var(--ease-pro),
              color 0.18s linear,
              text-shadow 0.25s linear;
  background: none;
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  -webkit-text-fill-color: currentColor;
  color: rgb(216, 220, 232);
  padding: 0 0.06em;
  text-shadow: none;
}
.hero-pro .hero-title .word.show {
  opacity: 1;
  transform: translateY(0);
}
/* Always-gold accent word ("flourish.") — golden-hour sunset gradient
   on a slow horizontal drift, so the colour reads like late-afternoon
   light moving through the letters. JS skips this word during the
   spotlight paint, so the gradient + animation win uncontested. */
.hero-pro .hero-title .word.always-gold {
  /* Sunset palette: pale dawn-gold → bright gold → warm amber → deep
     burnished-orange at centre → and symmetrically back, so when the
     gradient position drifts the colour walks through every step
     gradually instead of snapping. */
  background: linear-gradient(
    105deg,
    #fff0c2 0%,
    #ffd56a 14%,
    #ffaa3b 30%,
    #e0691f 50%,
    #ffaa3b 70%,
    #ffd56a 86%,
    #fff0c2 100%
  );
  background-size: 250% 100%;
  background-position: 0% 50%;
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  /* Warm halo underneath so the word reads lit-from-within, like the
     setting sun catching the leaf shape of the letterforms. The wider
     orange-red drop-shadow is the "horizon glow" — kept low alpha so
     it never overpowers the type itself. */
  filter:
    drop-shadow(0 0 10px rgba(255, 170, 70, 0.40))
    drop-shadow(0 0 24px rgba(255, 110, 40, 0.18));
  /* The legacy flat-gold text-shadow assumed a solid colour fill. With
     the gradient now transparent, that shadow would render as a halo
     OUTSIDE the letterforms and read wrong — kill it. */
  text-shadow: none;
  /* Slow drift: 14 s out and back. The cubic-bezier (Apple's house
     curve) makes the motion feel like breath rather than a metronome. */
  animation: golden-hour 14s cubic-bezier(0.5, 0, 0.5, 1) infinite;
}

@keyframes golden-hour {
  0%, 100% { background-position: 0%   50%; }
  50%      { background-position: 100% 50%; }
}

@media (prefers-reduced-motion: reduce) {
  .hero-pro .hero-title .word.always-gold {
    animation: none;
    background-position: 50% 50%;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   GOLDEN-HOUR TREATMENT — applied to every brand-gold touchpoint
   ─────────────────────────────────────────────────────────────────────────
   Same sunset palette + slow 14s position drift as the .always-gold
   "flourish." word, reused on all the prominent gold elements so the
   page feels lit from a single drifting light source. Subtle per-element
   `animation-delay` values offset each element a few seconds into the
   cycle — that's the difference between "ambient sunlight" and "every
   element flashing in lockstep".
   ───────────────────────────────────────────────────────────────────── */

:root {
  /* Reusable gradient definition — the same palette as `.always-gold`,
     symmetric so the loop joins seamlessly with no visible jump. */
  --golden-hour-grad: linear-gradient(
    105deg,
    #fff0c2 0%,
    #ffd56a 14%,
    #ffaa3b 30%,
    #e0691f 50%,
    #ffaa3b 70%,
    #ffd56a 86%,
    #fff0c2 100%
  );
  /* Tighter palette for button BACKGROUNDS — the drift is gentler so a
     button never visibly shifts from yellow-gold to red-orange (which
     would read as "the button is glitching"). Still the same hues, just
     less range so the button always reads as "warm gold". */
  --golden-hour-grad-btn: linear-gradient(
    105deg,
    #ffd97a 0%,
    #f0b54a 25%,
    #d08a20 50%,
    #f0b54a 75%,
    #ffd97a 100%
  );
}

/* ── Text-fill variant: gold accent words / stat numbers / featured h4 ── */
.hero h1 .gold,
.stat-num,
.price-card.featured h4 {
  background: var(--golden-hour-grad);
  background-size: 250% 100%;
  background-position: 0% 50%;
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  /* Two-layer warm halo: tight gold inner glow + wider orange "horizon"
     bleed underneath. Keeps it subtle so it doesn't bloom past being
     a hint on a stat number or featured tier label. */
  filter:
    drop-shadow(0 0 8px  rgba(255, 170, 70, 0.32))
    drop-shadow(0 0 18px rgba(255, 110, 40, 0.14));
  animation: golden-hour 14s cubic-bezier(0.5, 0, 0.5, 1) infinite;
}
/* Per-element offsets so the cycle is desynchronised. Each element
   peaks a few seconds apart, like sunlight catching different surfaces
   from slightly different angles. */
.hero h1 .gold       { animation-delay: -2s; }
.stat-num            { animation-delay: -5s; }
.price-card.featured h4 { animation-delay: -8s; }

/* The Premium h4 had an inline `style="color: var(--gold)"` to override
   the column's default colour — that solid colour wins over our gradient
   fill via the `color` property cascade. Force it to transparent so the
   gradient shows through. */
.price-card.featured h4[style*="color"] {
  color: transparent !important;
}

/* ── Background variant: primary CTAs + Get Sprout nav pill ──────────── */
.btn-primary,
.nav-cta {
  background: var(--golden-hour-grad-btn);
  background-size: 250% 100%;
  background-position: 0% 50%;
  animation: golden-hour 14s cubic-bezier(0.5, 0, 0.5, 1) infinite;
}
.btn-primary { animation-delay: -3s; }
.nav-cta     { animation-delay: -6s; }

/* Stat-num counter inherits `.gold` accent on hover via .stat-num — make
   sure the gradient stays clipped to the digits as the counter updates. */
.stat-num { will-change: background-position; }

@media (prefers-reduced-motion: reduce) {
  .hero h1 .gold,
  .stat-num,
  .price-card.featured h4,
  .btn-primary,
  .nav-cta,
  .kicker,
  .hero-pro .hero-title .word.is-lit {
    animation: none;
    background-position: 50% 50%;
  }
}

/* ── Kicker pills — animated gradient text on the gold pill ──────────
   The kicker pill keeps its faint-gold pill backdrop AND gets the
   sunset gradient on the text glyphs, via per-layer background-clip:
       Layer 1 (gradient) → clipped to text   → fills the glyphs only
       Layer 2 (flat gold) → clipped to padding-box → fills the pill
   So the pill stays a pill, but the text inside it breathes with the
   same golden-hour drift as flourish. */
.kicker {
  background-image:
    var(--golden-hour-grad),
    linear-gradient(rgba(240, 192, 96, 0.12), rgba(240, 192, 96, 0.12));
  background-size: 250% 100%, auto;
  background-repeat: no-repeat, no-repeat;
  background-position: 0% 50%, 0 0;
  -webkit-background-clip: text, padding-box;
          background-clip: text, padding-box;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation: golden-hour 14s cubic-bezier(0.5, 0, 0.5, 1) infinite;
  animation-delay: -10s;
  /* Soft warm halo so the kicker text still reads at 11px against
     the light-gold backdrop — without it, the deep-amber end of the
     palette can blend into the pill backdrop and read as muddy. */
  filter: drop-shadow(0 0 6px rgba(255, 170, 70, 0.20));
}

/* ── 3D-phone scroll scene (sprout.html, between hero and features) ──
   The pattern is "tall track + sticky inner viewport": the outer
   .phone-track is taller than the viewport, so the user scrolls through
   it; meanwhile the inner .phone-track-sticky stays pinned for the
   duration, holding the iframe in view. script.js (section 12) maps the
   track's scroll progress to a 0..1 value posted into the iframe via
   postMessage — the scroll story plays as the user reads down.

   Track height was 380vh; pulled back to 220vh so the burst → tilt/zoom
   → fly-up timeline (which is HARDCODED inside the scene file at
   p=0.03/0.10–0.68/0.68–1) compresses into a tighter scroll distance.
   That makes the animation feel like it kicks in right away when the
   user enters the section AND lets the "Five systems" heading land
   immediately after the phone flies up, instead of with dead scroll
   in between.

   pointer-events: none on the iframe means wheel / touch scroll passes
   straight through to the outer document, so the iframe never
   "captures" scroll the way embedded media usually does. */
.phone-track {
  position: relative;
  /* Even tighter: only one extra viewport of scroll to play the full
     timeline. The phone appears almost the moment the user enters the
     section, the choreography wraps up quickly, and "Five systems"
     lands right under the fly-up exit. */
  height: 160vh;
  /* z-index: 2 so the iframe wins in any overlap area. The iframe is
     transparent in its non-phone pixels, so wherever the iframe sits
     on top of OTHER content (hero copy above, "Five systems" heading
     below), only the PHONE itself blocks the view — the rest of the
     iframe lets the underlying content show through. That's what
     makes the page feel like one continuous flow. */
  z-index: 2;
  /* Pull the track up significantly so the "Sprout" title starts
     typewriting in as soon as the user begins to leave the hero —
     the title appears noticeably earlier in the scroll journey. */
  margin-top: -260px;
}
.phone-track-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
.phone-scroll-frame {
  position: relative;
  z-index: 2;             /* above the title pill */
  width: 100%;
  height: 100%;
  max-width: 1180px;
  border: 0;
  background: transparent;
  display: block;
  pointer-events: none;
}

/* Overlap the features section UPWARDS into the bottom of the phone
   track. Because .phone-track sits at z-index: 2 and #features sits
   at z-index: 1, the iframe paints on TOP of the kicker/heading in
   the overlap area — but only in the iframe's opaque pixels (the
   phone itself). Everywhere else the iframe is transparent, so the
   kicker + heading show right through. The visual effect: as the
   phone flies up out of frame, the "What's Inside" kicker and the
   "Five systems" heading rise into the SAME viewport area the phone
   just left — one continuous beat with no scroll gap. */
.phone-track + #features {
  position: relative;
  z-index: 1;
  padding-top: 0;
  margin-top: -260px;
}
.phone-track + #features .section-head {
  margin-bottom: 36px;          /* was 56 px */
}
.phone-track + #features .section-head .kicker {
  margin-bottom: 8px;           /* was 16 px */
}
@media (max-width: 600px) {
  .phone-track { height: 150vh; margin-top: -140px; }
  .phone-track + #features { padding-top: 0; margin-top: -180px; }
  .phone-track + #features .section-head { margin-bottom: 28px; }
}

/* ── Hero title — hovered word lights up with the sunset gradient ──
   The JS in script.js (section 8) now toggles `.is-lit` on the word
   the cursor is over. That's what we hook into here: the gradient +
   animation are applied only while the user's cursor is on the word,
   and removed the instant they leave it.
   The fade between solid slate and gradient-fill is handled by
   `transition: color 0.18s linear` already defined on `.word` — the
   on/off snap is softened into a quick crossfade. */
.hero-pro .hero-title .word.is-lit {
  background: var(--golden-hour-grad);
  background-size: 250% 100%;
  background-position: 0% 50%;
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  filter:
    drop-shadow(0 0 8px  rgba(255, 170, 70, 0.32))
    drop-shadow(0 0 18px rgba(255, 110, 40, 0.14));
  animation: golden-hour 14s cubic-bezier(0.5, 0, 0.5, 1) infinite;
}

/* The new mid-tier subhead between the H1 and the lead. Calls out the
   studio's scope (wellness + convenience) without ballooning the H1. */
.hero-pro .hero-subhead {
  font-size: clamp(15px, 1.4vw, 18px);
  font-weight: 700;
  letter-spacing: 0.2px;
  /* Solid dark slate (matches the visual weight of the H1 gradient
     above). Solid colour because child <span class="subhead-gold">
     accents need to break out and show their own gold gradient — when
     the parent uses background-clip:text, gold children inherit
     transparent fill and render invisibly. */
  color: #182142;
  /* White halo behind the slate type so it lifts off any region of
     the watercolor — light wash, mountain peak, or lake. */
  filter:
    drop-shadow(0 1px 0 rgba(255, 255, 255, 0.55))
    drop-shadow(0 0 6px rgba(255, 255, 255, 0.45));
  text-align: center;
  max-width: 720px;
  margin: 0 auto 32px;
  opacity: 0;
  animation: hero-drop 0.9s var(--ease-pro) 1.05s forwards;
}

/* Word-line wraps tight so per-word reveal feels like one phrase, not a list. */
.word-line {
  display: block;
  /* Each line gets its own clip so words below don't show through above. */
}
.word {
  display: inline-block;
  opacity: 0;
  transform: translateY(38%);
  /* JS adds .show after a short cascade delay (per word). */
  transition: opacity 0.85s var(--ease-pro), transform 0.85s var(--ease-pro);
  background: linear-gradient(180deg, #fff 0%, #d8dce8 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  padding: 0 0.06em; /* breathing room so descenders/diacritics don't clip */
}
.word.show { opacity: 1; transform: translateY(0); }

/* The headline's accent word — animated gold sweep on top of the reveal. */
.word.gold-sweep {
  background: linear-gradient(110deg,
    var(--gold-3) 0%,
    #fff5dc 25%,
    var(--gold) 50%,
    var(--gold-2) 75%,
    var(--gold-3) 100%);
  background-size: 220% 100%;
  background-position: 100% 0;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: gold-sweep 6s ease-in-out 1.3s infinite alternate;
}
@keyframes gold-sweep {
  to { background-position: 0% 0; }
}

/* Same specificity bump as .hero-title — beats the legacy `.hero p.lead`.
   Delays land in cascade order: kicker → words → subhead → lead → CTAs. */
.hero-pro p.hero-lead {
  font-size: clamp(17px, 1.5vw, 21px);
  color: var(--txt2);
  max-width: 640px;
  margin: 0 auto 44px;
  line-height: 1.55;
  opacity: 0;
  animation: hero-drop 0.9s var(--ease-pro) 1.25s forwards;
}
.hero-pro .hero-ctas {
  opacity: 0;
  animation: hero-drop 0.9s var(--ease-pro) 1.5s forwards;
}
.hero-pro .hero-ctas .btn { padding: 16px 28px; font-size: 15px; }

/* Scroll cue under hero — a thin gold line that "drips" down,
   gently asking the eye to keep going. Pure decorative. */
.hero-scroll-cue {
  position: absolute; left: 50%; bottom: 20px;
  transform: translateX(-50%);
  width: 1px; height: 56px;
  opacity: 0;
  animation: hero-drop 1s var(--ease-pro) 1.9s forwards;
  pointer-events: auto;
}
.hero-scroll-cue span {
  position: absolute; left: 0; top: 0;
  width: 1px; height: 100%;
  background: linear-gradient(180deg, transparent 0%, var(--gold) 50%, transparent 100%);
  animation: cue-drip 2.4s ease-in-out infinite;
}
@keyframes cue-drip {
  0%   { transform: translateY(-100%); opacity: 0; }
  40%  { opacity: 1; }
  100% { transform: translateY(100%); opacity: 0; }
}

/* ── Manifesto / scroll-paint text ────────────────────────────────────── */
/* The line lives just below the hero. Each word starts dim and JS sets
   --t (0..1) per word as it crosses the reveal line; CSS interpolates
   color via opacity-on-mask. */
.manifesto {
  padding: 60px 0 140px;
}
.manifesto-line {
  font-size: clamp(22px, 3.2vw, 38px);
  font-weight: 800;
  letter-spacing: -0.8px;
  line-height: 1.3;
  text-align: center;
  color: var(--txt);
}
/* JS wraps each word in <span class="paint-word"> with a CSS var --t. */
.paint-word {
  display: inline-block;
  color: rgba(255, 255, 255, calc(0.15 + var(--t, 0) * 0.85));
  transition: color 0.2s linear;
  padding: 0 0.06em;
}

/* ── Chapter sections (01 / 02 / 03) ──────────────────────────────────── */
.chapter {
  padding: 120px 0 90px;
}
.chapter-head {
  display: flex; align-items: center; gap: 18px;
  margin-bottom: 32px;
}
.chapter-no {
  font-family: -apple-system, "SF Pro Display", system-ui, sans-serif;
  font-size: 13px;
  font-weight: 900;
  letter-spacing: 0.6px;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}
/* The animated rule between the number and the kicker — draws itself in
   when the chapter enters view (handled via .reveal.in below). */
.chapter-rule {
  flex: 0 0 64px;
  height: 1px;
  background: linear-gradient(90deg, var(--gold), transparent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.9s var(--ease-pro) 0.15s;
}
.reveal.in .chapter-rule,
.chapter-head.reveal.in .chapter-rule { transform: scaleX(1); }

.chapter-head .kicker {
  margin: 0;
  background: transparent;
  border: none;
  padding: 0;
  color: var(--txt3);
}

.chapter-title {
  font-size: clamp(32px, 5vw, 58px);
  font-weight: 900;
  letter-spacing: -1.4px;
  line-height: 1.08;
  margin-bottom: 56px;
  max-width: 880px;
  background: linear-gradient(180deg, #fff 0%, #b8becf 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* Two-column long-form layout inside a chapter — lead on the left,
   body on the right. Stacks on small screens. */
.chapter-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 60px;
  align-items: start;
}
.chapter-lead {
  font-size: clamp(17px, 1.4vw, 20px);
  color: var(--txt);
  line-height: 1.55;
  font-weight: 500;
}
.chapter-body {
  font-size: 16px;
  color: var(--txt2);
  line-height: 1.7;
}
@media (max-width: 760px) {
  .chapter { padding: 80px 0 60px; }
  .chapter-grid { grid-template-columns: 1fr; gap: 24px; }
  .chapter-title { margin-bottom: 36px; }
}

/* ── Mission lines — upgraded with a heading per line ─────────────────── */
.mission-line {
  align-items: flex-start;
  padding: 28px 0;
}
.mission-line > div { flex: 1; }
.mission-line h4 {
  font-size: 18px;
  font-weight: 800;
  letter-spacing: -0.3px;
  margin-bottom: 8px;
  color: var(--txt);
}

/* ── Stats / counters ─────────────────────────────────────────────────── */
.stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 28px;
  padding: 60px 0 100px;
}
@media (max-width: 800px) {
  .stats { grid-template-columns: 1fr; }
}
.stat {
  padding: 36px 28px;
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid var(--border);
  border-radius: 22px;
  text-align: left;
  transition: border-color 0.5s var(--ease-pro), background 0.5s var(--ease-pro);
}
.stat:hover {
  border-color: rgba(240, 192, 96, 0.32);
  background: rgba(255, 255, 255, 0.04);
}
.stat-num {
  font-size: clamp(48px, 6vw, 68px);
  font-weight: 900;
  letter-spacing: -2.2px;
  line-height: 1;
  margin-bottom: 14px;
  /* Golden-hour sunset gradient (animated). Same palette as the
     consolidated treatment so all gold accents catch the same drift.
     Background-size: 250% gives the animation room to walk the colour
     across the digits instead of just stretching the fill. */
  background: var(--golden-hour-grad, linear-gradient(105deg,
    #fff0c2 0%, #ffd56a 14%, #ffaa3b 30%, #e0691f 50%,
    #ffaa3b 70%, #ffd56a 86%, #fff0c2 100%));
  background-size: 250% 100%;
  background-position: 0% 50%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  font-variant-numeric: tabular-nums;
}
.stat-label {
  font-size: 15px;
  font-weight: 800;
  letter-spacing: -0.1px;
  color: var(--txt);
  margin-bottom: 6px;
}
.stat-sub {
  font-size: 13px;
  color: var(--txt3);
  line-height: 1.5;
}

/* ── Magnetic CTA — JS-driven micro-translate toward cursor ───────────── */
.btn.magnetic {
  will-change: transform;
  transition: transform 0.4s var(--ease-pro), box-shadow 0.4s var(--ease-pro);
}

/* ── CTA block — refined visual ───────────────────────────────────────── */
.cta-icon {
  width: 84px; height: 84px;
  border-radius: 22px;
  margin: 0 auto 18px;
  box-shadow: 0 16px 38px rgba(0, 0, 0, 0.5);
}

/* ── Reveal — upgrade to the pro easing curve ────────────────────────── */
.reveal {
  transition: opacity 0.9s var(--ease-pro), transform 0.9s var(--ease-pro);
  transform: translateY(34px);
}
.reveal-stagger .reveal-child {
  transition: opacity 0.85s var(--ease-pro),
              transform 0.85s var(--ease-pro);
  transform: translateY(40px);
}

/* ── Respect reduced-motion ──────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .word { opacity: 1; transform: none; transition: none; }
  .hero-lead, .hero-pro .hero-ctas, .hero-pro .hero-subhead,
  .hero-scroll-cue {
    opacity: 1; animation: none;
  }
  .reveal, .reveal-stagger .reveal-child { opacity: 1; transform: none; }
  .paint-word { color: var(--txt) !important; }
  .scroll-progress { display: none; }
  /* No JS-driven spotlight either — hold the gradient at its default centre. */
  .hero-pro .hero-title { transition: none; }
  /* Freeze the aurora and the sky gradient. */
  .aurora-blob { animation: none; translate: 0 0; }
  .sky { transition: none; }
}

/* ─────────────────────────────────────────────────────────────────────────
   LIGHT WATERCOLOR THEME — overrides the cosmic-navy palette with a soft
   cool-grey / off-white wash and a layered watercolor mountain horizon
   pinned to the bottom of the viewport. Goal: a calmer, more editorial
   feel — less "club app", more "Swiss studio".
   ───────────────────────────────────────────────────────────────────── */
:root {
  --bg:       #eef0f4;
  --bg-2:     #e4e7ed;
  --sheet:    #f6f7fa;
  --txt:      #1d2233;
  --txt2:     rgba(29, 34, 51, 0.72);
  --txt3:     rgba(29, 34, 51, 0.50);
  --border:   rgba(29, 34, 51, 0.10);
  --border-2: rgba(29, 34, 51, 0.18);
  /* Cool the lavender → it now reads as a soft slate-grey. */
  --lavender: #b6bccc;
}

body {
  color: var(--txt);
  background: var(--bg);
}

/* ── Soft cool-grey watercolor sky (replaces the cosmic radial gradients) ── */
.sky {
  background:
    radial-gradient(ellipse at 20% var(--sky-top-y, 0%),
      rgba(182, 188, 204, var(--sky-lavender, 0.22)), transparent 55%),
    radial-gradient(ellipse at 80% var(--sky-bot-y, 100%),
      rgba(210, 210, 215, var(--sky-gold, 0.18)), transparent 55%),
    radial-gradient(ellipse at 50% 50%,
      rgba(196, 206, 220, var(--sky-blue, 0.14)), transparent 65%),
    linear-gradient(180deg, #f3f5f8 0%, #e6e9ef 60%, #dde1e8 100%);
}
/* Stars made of white dots disappear on a white background — hide them. */
.sky::before, .sky::after { display: none; }

/* ── Aurora — desaturate to a barely-there grey-blue / sage wash ────── */
.aurora { filter: blur(90px); opacity: 0.55; }
.aurora-blob.a1 {
  background: radial-gradient(circle, rgba(170, 180, 200, 0.45), transparent 65%);
  mix-blend-mode: multiply;
}
.aurora-blob.a2 {
  background: radial-gradient(circle, rgba(190, 200, 195, 0.40), transparent 65%);
  mix-blend-mode: multiply;
}
.aurora-blob.a3 {
  background: radial-gradient(circle, rgba(180, 195, 210, 0.40), transparent 65%);
  mix-blend-mode: multiply;
}
.aurora.aurora-sprout .aurora-blob.a1 {
  background: radial-gradient(circle, rgba(168, 188, 170, 0.42), transparent 65%);
}
.aurora.aurora-sprout .aurora-blob.a2 {
  background: radial-gradient(circle, rgba(180, 188, 205, 0.40), transparent 65%);
}
.aurora.aurora-sprout .aurora-blob.a3 {
  background: radial-gradient(circle, rgba(185, 200, 215, 0.36), transparent 65%);
}

/* ── Watercolor mountain horizon ──────────────────────────────────────
   A hand-painted multi-layer watercolor SVG (assets/watercolor_mountains.svg)
   with per-ridge feTurbulence+feDisplacementMap "wet-bleed" edges,
   atmospheric perspective washes, snow/ochre slope highlights, and a pale
   teal water reflection. Scoped to body.home (= index.html) only — sub-
   pages get the plain light wash so the painting is the studio landing's
   signature, not a global decoration. */
body.home::after {
  content: '';
  position: fixed;
  left: 0; right: 0; bottom: 0;
  height: 70vh;
  z-index: -1;
  pointer-events: none;
  background-image: url("assets/watercolor_mountains.svg");
  background-repeat: no-repeat;
  background-size: cover;
  background-position: bottom center;
  /* The SVG's own feTurbulence/feDisplacementMap carry the watercolor
     character — no additional CSS blur. We do mask the very top so the
     ridge silhouette dissolves into the sky instead of ending in a hard
     rectangle edge; kept at ≤10% so the hero peak stays visible. */
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 10%, #000 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 10%, #000 100%);
}

/* ── Navigation — flip to a light translucent glass ─────────────────── */
.nav {
  background: rgba(246, 247, 250, 0.78);
  border-bottom: 1px solid var(--border);
}
.nav-cta { color: #1d2233 !important; }

/* ── Hero text gradients — dark slate so they read on the light wash ── */
.hero h1 {
  background: linear-gradient(180deg, #0d1224 0%, #3a4258 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.hero-pro .hero-title,
.hero-pro .hero-title .word {
  color: rgb(46, 54, 72);
}
.word {
  background: linear-gradient(180deg, #0d1224 0%, #3a4258 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.chapter-title {
  background: linear-gradient(180deg, #0d1224 0%, #4a536b 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* ── Cards / surfaces — light translucent panels with subtle slate borders ── */
.feature,
.stat,
.price-card {
  background: rgba(255, 255, 255, 0.55);
  border-color: var(--border);
}
.feature:hover,
.stat:hover {
  background: rgba(255, 255, 255, 0.75);
  border-color: var(--border-2);
}
.btn-ghost {
  background: rgba(29, 34, 51, 0.05);
  border-color: var(--border-2);
  color: var(--txt);
}
.btn-ghost:hover { background: rgba(29, 34, 51, 0.09); }

/* ── CTA block — softer wash, no purple ─────────────────────────────── */
.cta-block {
  background:
    radial-gradient(ellipse at 30% 30%, rgba(240, 192, 96, 0.18), transparent 60%),
    radial-gradient(ellipse at 70% 70%, rgba(160, 172, 195, 0.22), transparent 60%),
    linear-gradient(135deg, rgba(255, 255, 255, 0.65), rgba(255, 255, 255, 0.40));
  border-color: var(--border-2);
}

/* ── Mission lines — slate dividers ─────────────────────────────────── */
.mission-line { border-bottom-color: var(--border); }
.mission-line:first-child { border-top-color: var(--border); }

/* ── Footer — light translucent ─────────────────────────────────────── */
.footer {
  background: rgba(246, 247, 250, 0.6);
  border-top-color: var(--border);
}
.footer-bottom { border-top-color: var(--border); }

/* ── Scroll progress rail track — slate on light ─────────────────────── */
.scroll-progress { background: rgba(29, 34, 51, 0.06); }

/* ── Manifesto paint-words — flip from white-fade to slate-fade so they
   actually appear on the light wash. --t (0..1) controls intensity. ── */
.paint-word {
  color: rgba(29, 34, 51, calc(0.18 + var(--t, 0) * 0.78));
}

/* ── Sprout product page — slightly cooler/bluer wash ────────────────
   The product page (body.product = sprout.html) gets a marginally bluer
   base than the studio landing's neutral grey-white, so the page reads
   as a distinct "room" even before the aurora blobs paint over it. */
body.product {
  background: #e6ebf3;
}
body.product .sky {
  /* Only soft RADIAL washes — no opaque linear base — so the watercolor
     clouds painted in body::before show through. The body's #e6ebf3
     base bg provides the wash colour. */
  background:
    radial-gradient(ellipse at 20% var(--sky-top-y, 0%),
      rgba(176, 188, 212, var(--sky-lavender, 0.32)), transparent 55%),
    radial-gradient(ellipse at 80% var(--sky-bot-y, 100%),
      rgba(196, 206, 224, var(--sky-gold, 0.24)), transparent 55%),
    radial-gradient(ellipse at 50% 50%,
      rgba(178, 198, 224, var(--sky-blue, 0.22)), transparent 65%);
}

/* ── Product-page watercolor clouds ───────────────────────────────────
   Sits between the sky gradient (z:-1) and the aurora blobs. Three
   bands of soft blue clouds painted into the SVG; SMIL inside the
   asset drifts them horizontally on different periods so they shear.
   The CSS layer ADDITIONALLY translates the whole asset on scroll —
   the sky slides up and slightly leftward as the user descends, which
   gives the page the feeling of "moving through" the cloud bank.

   --sy is the scroll-progress var (0..1) the site script writes to
   :root inside requestAnimationFrame. Multiplying by negative values
   yields the parallax direction we want without a new scroll handler. */
body.product::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: url("assets/watercolor_clouds.svg");
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
  /* Slow vertical rise + a quiet horizontal slide. Amplitudes are tuned
     so even at scrollY=max the clouds shift by ≤140px — they should
     feel like they're moving WITH you, not slipping out of the frame. */
  transform: translate3d(
    calc(var(--sy, 0) * -36px),
    calc(var(--sy, 0) * -140px),
    0
  );
  will-change: transform;
  /* Soft fade at the top edge so the cloud bank dissolves into the
     sky rather than hitting a hard rectangle horizon. */
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 12%, #000 88%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 12%, #000 88%, transparent 100%);
}
@media (prefers-reduced-motion: reduce) {
  body.product::before { transform: none; }
}

/* ─────────────────────────────────────────────────────────────────────────
   LIQUID GLASS — nav + card surfaces
   ─────────────────────────────────────────────────────────────────────────
   The Apple "liquid glass" material has four parts that must all be present
   for the effect to read:
     1. A strong backdrop-filter (blur + saturation boost) so what's behind
        looks soft and tinted, not just dim.
     2. A semi-transparent fill that lets that filtered backdrop show
        through with a faint white milkiness.
     3. A bright specular highlight on the top edge (inset shadow) — the
        "light catching the bevel" that makes it read as a glass surface.
     4. A diffuse, COLOURED outer shadow (cool slate, not black) so the
        card feels like it's floating in air rather than punched into a
        page. Black shadows kill the glass effect.
   We tune each on the same scale (alpha values stay coherent) so cards,
   nav, and CTA block all read as the same material.
   ───────────────────────────────────────────────────────────────────── */

/* ── Liquid-glass shared mixin (via custom property reference) ────────── */
:root {
  --glass-bg:        rgba(255, 255, 255, 0.40);
  --glass-bg-hover:  rgba(255, 255, 255, 0.55);
  --glass-border:    rgba(255, 255, 255, 0.55);
  --glass-border-hi: rgba(255, 255, 255, 0.75);
  /* Cool slate shadow — NOT black — so the lift reads as atmospheric
     depth rather than a hard punch. */
  --glass-shadow:
    0 8px 28px rgba(60, 80, 120, 0.10),
    0 2px 6px  rgba(60, 80, 120, 0.06),
    inset 0 1px 0 rgba(255, 255, 255, 0.85),
    inset 0 0 0 1px rgba(255, 255, 255, 0.18);
  --glass-shadow-hover:
    0 16px 40px rgba(60, 80, 120, 0.14),
    0 4px 10px  rgba(60, 80, 120, 0.07),
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    inset 0 0 0 1px rgba(255, 255, 255, 0.24);
  --glass-blur: blur(24px) saturate(180%);
}

/* ── Nav — floating liquid-glass bar ──────────────────────────────────
   Detach from the viewport edges with small side / top margins, round
   ALL corners (not just the bottom border that used to demarcate it),
   and override the previous flat translucent fill with the glass stack. */
.nav {
  position: sticky;
  top: 12px;
  margin: 12px 16px 0;
  border-radius: 22px;
  background: var(--glass-bg);
  -webkit-backdrop-filter: var(--glass-blur);
          backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-border);
  /* Override the legacy bottom-only border. */
  border-bottom: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow);
}
.nav-inner {
  /* The inner row was sized to the old edge-to-edge bar — pull it in a
     touch so the glass material has visible breathing room on the sides. */
  padding: 12px 22px;
}
@media (max-width: 600px) {
  .nav {
    margin: 8px 10px 0;
    border-radius: 18px;
  }
}

/* ── Cards: features, stats, price tiers ──────────────────────────────
   Apply the same glass stack and bump the radius from 22 → 24/26 so the
   corners read as "softer". Hover lifts gently and brightens the specular
   highlight (no dark drop shadow — that breaks the glass illusion). */
.feature,
.stat,
.price-card {
  background: var(--glass-bg);
  -webkit-backdrop-filter: var(--glass-blur);
          backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-border);
  border-radius: 26px;
  box-shadow: var(--glass-shadow);
}
.feature:hover,
.stat:hover {
  background: var(--glass-bg-hover);
  border-color: var(--glass-border-hi);
  /* Override the legacy black hover shadow + scale; glass should lift,
     not punch. Keep the small upward translate but kill scale + dark box. */
  transform: translateY(-3px);
  box-shadow: var(--glass-shadow-hover);
}

/* ── Featured price card — keep the gold-tinted glow, restore glass stack ── */
.price-card.featured {
  background:
    radial-gradient(ellipse at 0% 0%, rgba(240,192,96,0.22), transparent 55%),
    var(--glass-bg);
  border-color: rgba(240, 192, 96, 0.55);
  box-shadow:
    var(--glass-shadow),
    0 0 0 1px rgba(240, 192, 96, 0.10);
}

/* ── CTA block — same material, retains its warm radial accents ─────── */
.cta-block {
  background:
    radial-gradient(ellipse at 30% 30%, rgba(240, 192, 96, 0.20), transparent 60%),
    radial-gradient(ellipse at 70% 70%, rgba(160, 172, 195, 0.22), transparent 60%),
    var(--glass-bg);
  -webkit-backdrop-filter: var(--glass-blur);
          backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow);
}

/* ── Safari / mobile fallback ─────────────────────────────────────────
   If the browser doesn't support backdrop-filter, the cards would
   become near-transparent and unreadable. Fall back to a higher-alpha
   white fill so text contrast survives. */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .nav,
  .feature,
  .stat,
  .price-card,
  .cta-block,
  .contact-form {
    background: rgba(255, 255, 255, 0.85);
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   CONTACT FORM
   ─────────────────────────────────────────────────────────────────────────
   Sits on the home page just above the footer. Wrapped in the same
   liquid-glass material as the feature/stat cards so it reads as part
   of the same family. Inputs use the standard form-control pattern:
   floating label above field, soft translucent fill, focus-state lift
   with a gold ring (matches the primary CTA accent). */

.contact-form {
  max-width: 720px;
  margin: 0 auto;
  padding: 40px;
  border-radius: 26px;
  background: var(--glass-bg);
  -webkit-backdrop-filter: var(--glass-blur);
          backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow);
}
@media (max-width: 600px) {
  .contact-form { padding: 24px; border-radius: 22px; }
}

.contact-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
  margin-bottom: 18px;
}
@media (max-width: 600px) {
  .contact-row { grid-template-columns: 1fr; gap: 14px; margin-bottom: 14px; }
}

/* Each field = a label that wraps the visible <span> caption and the
   input. The whole label is clickable, which keeps the form
   accessible (proper for+id wiring not needed when the input is a
   child). */
.contact-field {
  display: block;
  margin-bottom: 18px;
}
.contact-field:last-of-type { margin-bottom: 24px; }
.contact-field > span {
  display: block;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--txt3);
  margin-bottom: 8px;
}
.contact-field input,
.contact-field textarea {
  width: 100%;
  font-family: var(--font);
  font-size: 15px;
  font-weight: 500;
  color: var(--txt);
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid rgba(29, 34, 51, 0.12);
  border-radius: 14px;
  padding: 13px 16px;
  outline: none;
  transition: border-color 0.2s var(--ease-pro),
              background    0.2s var(--ease-pro),
              box-shadow    0.2s var(--ease-pro);
}
.contact-field textarea {
  resize: vertical;
  min-height: 120px;
  line-height: 1.55;
  font-family: var(--font);    /* textarea inherits monospace otherwise */
}
.contact-field input::placeholder,
.contact-field textarea::placeholder {
  color: rgba(29, 34, 51, 0.35);
}
.contact-field input:hover,
.contact-field textarea:hover {
  background: rgba(255, 255, 255, 0.72);
  border-color: rgba(29, 34, 51, 0.22);
}
.contact-field input:focus,
.contact-field textarea:focus {
  background: rgba(255, 255, 255, 0.88);
  border-color: rgba(240, 192, 96, 0.65);
  /* Soft gold focus ring — same accent the primary CTA uses, so the
     form's interactive state reads as part of the brand. */
  box-shadow: 0 0 0 4px rgba(240, 192, 96, 0.18);
}

.contact-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
}
.contact-actions .btn { padding: 13px 26px; }
.contact-note {
  font-size: 13px;
  color: var(--txt3);
  line-height: 1.5;
}

/* Contact page wrapping section — same top/bottom rhythm as the legal
   pages so contact / privacy / terms read as one family. */
.contact-page {
  padding: 100px 0 80px;
}

/* ── Submit button states — sending + spinner ─────────────────────────
   The button label is wrapped in a <span> so JS can swap it to "Sending…"
   while the AJAX request is in flight. The spinner is a single rotating
   ring that appears next to the label only while the form is submitting.
   Disabled state pulls the button to a slightly washed-out gold so it
   reads as "wait" rather than "broken". */
.contact-submit {
  position: relative;
}
.contact-submit:disabled {
  cursor: progress;
  opacity: 0.82;
  transform: none !important;
}
.contact-submit-spinner {
  display: none;
  width: 14px; height: 14px;
  margin-left: 4px;
  border: 2px solid rgba(0, 0, 0, 0.18);
  border-top-color: rgba(0, 0, 0, 0.75);
  border-radius: 50%;
  animation: contact-spin 0.7s linear infinite;
}
.contact-form.is-submitting .contact-submit-spinner {
  display: inline-block;
}
@keyframes contact-spin {
  to { transform: rotate(360deg); }
}

/* ── Status pill — success / error feedback ───────────────────────────
   The element is empty by default (no border / padding) so it collapses
   to nothing in the layout. JS adds a `data-kind` attribute on
   success/error which styles it as a soft pill so the user sees a clear
   answer without a layout shift mid-flight. */
.contact-status {
  margin: 16px 0 0;
  font-size: 14px;
  line-height: 1.5;
  border-radius: 12px;
  transition: background 0.2s var(--ease-pro), color 0.2s var(--ease-pro);
}
.contact-status:empty { padding: 0; }
.contact-status[data-kind="success"] {
  background: rgba(126, 184, 122, 0.16);
  border: 1px solid rgba(126, 184, 122, 0.45);
  color: #2f5b3a;
  padding: 12px 16px;
}
.contact-status[data-kind="error"] {
  background: rgba(224, 73, 42, 0.10);
  border: 1px solid rgba(224, 73, 42, 0.40);
  color: #832414;
  padding: 12px 16px;
}

/* ── Hero icon (product page) — clean rounded-square mark, no lavender
   shadow (legacy) — soft cool drop shadow that matches the new palette. */
.hero-icon-wrap {
  display: flex;
  justify-content: center;
  margin-bottom: 22px;
}
.hero-icon {
  width: 96px;
  height: 96px;
  border-radius: 24px;
  box-shadow:
    0 18px 40px rgba(74, 92, 130, 0.20),
    0 4px 12px rgba(74, 92, 130, 0.10);
}
@media (max-width: 600px) {
  .hero-icon { width: 80px; height: 80px; border-radius: 20px; }
}

/* ── Mountain horizon — scroll-driven zoom ───────────────────────────
   The painting scales from 1 (page top) up to 1.18 (fully scrolled) so
   the mountains feel like they're approaching as the reader descends.
   Anchored at bottom-centre so the lake stays pinned to the viewport
   floor and only the upper peaks read as "growing larger". --sy is the
   shared scroll-progress var written to :root by script.js. */
body.home::after {
  transform: scale(calc(1 + var(--sy, 0) * 0.18));
  transform-origin: 50% 100%;
  /* No transition: --sy is updated inside rAF on every scroll, so the
     transform reads as buttery without CSS interpolation introducing
     lag. */
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
  body.home::after { transform: none; }
}

/* ── Mobile polish ────────────────────────────────────────────────────
   Fix: `.chapter` and its mobile variant declare `padding: V 0 V` —
   that shorthand zeroes out `.container`'s 28px side padding, so chapter
   titles and bodies bleed to the viewport edge on phones. Restore the
   gutter, dial down the oversized hero/title type, and shrink the nav
   wordmark so it doesn't dominate small screens. */
.chapter {
  padding-left: 28px;
  padding-right: 28px;
}
@media (max-width: 760px) {
  .chapter { padding: 80px 28px 60px; }
}
@media (max-width: 600px) {
  .nav-logo { height: 42px; }
  .nav-inner { padding: 12px 20px; }
  .container,
  .container-narrow,
  .chapter { padding-left: 20px; padding-right: 20px; }
  .hero, .hero-pro { padding: 90px 0 60px; }
  .hero-pro .hero-title { font-size: clamp(36px, 9vw, 56px); letter-spacing: -1.4px; }
  .chapter-title { font-size: clamp(26px, 7vw, 40px); letter-spacing: -1px; }
  .manifesto-line { font-size: clamp(18px, 5vw, 28px); letter-spacing: -0.4px; }
  .manifesto { padding: 40px 0 80px; }
  .section-head h2 { font-size: clamp(24px, 6vw, 36px); }
  .cta-block { padding: 44px 22px; }
  .cta-block h2 { font-size: clamp(24px, 6vw, 34px); }
  .stat { padding: 28px 22px; }
  .stat-num { font-size: clamp(40px, 12vw, 56px); }
  /* The scroll cue can sit on top of the CTA buttons in short hero on phones. */
  .hero-scroll-cue { display: none; }
  /* Mountain horizon: fixed 62vh on a portrait viewport is huge — pull it back. */
  /* iOS Safari fix: 100vh is calculated against the LARGEST viewport
     (address bar collapsed), but position:fixed/bottom:0 anchors to the
     CURRENT visible viewport — so the bottom of the watercolor lands
     behind the URL bar and looks "cut off". `dvh` adapts dynamically
     to the visible area, so the painting always reaches the actual
     bottom of what the user sees. Older Safari versions ignore the
     `dvh` line and fall back to the `vh` value. */
  body.home::after {
    height: 56vh;
    height: 56dvh;
  }
}


