/* ============================================================
   turtleneck — marketing site styles
   Every color, radius, font, and shadow below is ported from the
   app's design tokens (src/theme/tokens.ts, light palette).
   Brand laws: light mode only, no corporate blue, no red.
   Reveal/entrance styles are gated behind html.js (set inline in
   <head>) so a broken-JS visitor still sees the whole page.
   ============================================================ */

/* ---- brand fonts (the exact three weights the app loads) ---- */
@font-face {
  font-family: "Nunito";
  src: url("fonts/Nunito_600SemiBold.woff2") format("woff2"),
       url("fonts/Nunito_600SemiBold.ttf") format("truetype");
  font-weight: 600;
  font-display: swap;
}
@font-face {
  font-family: "Nunito";
  src: url("fonts/Nunito_700Bold.woff2") format("woff2"),
       url("fonts/Nunito_700Bold.ttf") format("truetype");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "Nunito";
  src: url("fonts/Nunito_800ExtraBold.woff2") format("woff2"),
       url("fonts/Nunito_800ExtraBold.ttf") format("truetype");
  font-weight: 800;
  font-display: swap;
}

/* ---- design tokens ---- */
:root {
  --bg-top: #fdf4e7;      /* cream */
  --bg-bottom: #e7f3ea;   /* soft mint */
  --primary: #3e9b6e;     /* shell green */
  --primary-deep: #2e7352;
  /* coral — celebration moments. NEVER as text on cream/mint (2.35:1, hard
     fail); pair with ink text on a solid coral fill, or use on forest bands */
  --accent: #ff7a5c;
  --sunshine: #ffc94d;    /* milestones, sparkles */
  --ink: #23372e;
  --ink-soft: #55665e;    /* darkened from #5c6f66 for AA headroom on mint */
  --surface: rgba(255, 255, 255, 0.92);
  --shadow: rgba(35, 55, 46, 0.12);
  --skin: #8bd3a5;
  --skin-shade: #63b784;

  /* forest depths — darker steps of the brand green for immersive bands */
  --forest: #2e7352;
  --forest-2: #245c42;
  --forest-3: #1c4a35;
  --mint-text: #dcefe4; /* body copy on forest bands — ≥4.5:1 even on the
                           gradient's lighter top (#2e7352), was 4.33 before */

  --radius-card: 20px;
  --radius-sheet: 28px;
  --radius-pill: 999px;
  --soft-shadow: 0 6px 16px var(--shadow);

  /* signature easing: decisive for ordinary motion… */
  --ease-turtle: cubic-bezier(0.22, 1, 0.36, 1);
  /* …overshoot reserved for celebration only */
  --ease-party: cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* ---- base ---- */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: smooth;
}

body {
  font-family: "Nunito", "Segoe UI", system-ui, sans-serif;
  font-weight: 600;
  color: var(--ink);
  background: var(--bg-top);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img,
svg {
  max-width: 100%;
  display: block;
}

/* the hidden attribute must always win over author display rules */
[hidden] {
  display: none !important;
}

h1,
h2,
h3 {
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.01em;
}

h1 { letter-spacing: -0.02em; }

h2 {
  font-size: clamp(1.9rem, 5.5vw, 3rem);
  line-height: 1.2; /* headings that wrap need more than display-tight 1.12 */
  margin-bottom: 0.7em;
  text-wrap: balance; /* wrapped lines come out evenly weighted */
}

/* keeps a sentence whole — lines break between sentences, never inside */
.nowrap { white-space: nowrap; }

/* the signature flourish: three shell scutes under every section heading */
.kicker + h2::after {
  content: "";
  display: block;
  width: 66px;
  height: 14px;
  margin-top: 16px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='66' height='14' viewBox='0 0 66 14'%3E%3Cg fill='%238BD3A5'%3E%3Cpolygon points='7,1 12.2,4 12.2,10 7,13 1.8,10 1.8,4'/%3E%3Cpolygon points='29,1 34.2,4 34.2,10 29,13 23.8,10 23.8,4' opacity='0.75'/%3E%3Cpolygon points='51,1 56.2,4 56.2,10 51,13 45.8,10 45.8,4' opacity='0.5'/%3E%3C/g%3E%3C/svg%3E") no-repeat;
}

/* two-tone wordmark: turtle + neck */
.wm-neck { color: var(--primary); }
.footer .wm-neck { color: var(--skin); }

/* highlighter sweep on a headline's key word */
.hl {
  font-style: normal;
  padding-inline: 3px;
  border-radius: 4px;
  background-image: linear-gradient(transparent 62%, rgba(255, 201, 77, 0.6) 62%);
}

.hl-coral {
  background-image: linear-gradient(transparent 62%, rgba(255, 122, 92, 0.45) 62%);
}

h3 {
  font-size: 1.2rem;
  font-weight: 700; /* the middle Nunito weight — 800 stays for h1/h2/CTAs */
  line-height: 1.3; /* card headings wrap to two lines */
}

p {
  margin-bottom: 1em;
}

p:last-child {
  margin-bottom: 0;
}

a {
  color: var(--primary-deep);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

button:focus-visible,
input:focus-visible,
a:focus-visible,
summary:focus-visible,
.hero-art:focus-visible,
.gallery:focus-visible {
  /* primary-deep: ~5:1 on mint (shell green sat right at the 3:1 floor) */
  outline: 3px solid var(--primary-deep);
  outline-offset: 3px;
  border-radius: 6px;
}

/* brand-green outlines vanish on the dark bands — go sunshine there */
.forest :focus-visible,
.footer :focus-visible {
  outline-color: var(--sunshine);
}

/* ---- layout ---- */
.wrap {
  max-width: 1080px;
  margin-inline: auto;
  padding-inline: clamp(20px, 5vw, 48px);
}

.narrow {
  max-width: 640px;
}

.band {
  position: relative;
  /* 56px floor: short phones shouldn't spend 20% of a screen on padding */
  padding-block: clamp(56px, 12vw, 132px);
}

/* ambient stars scattered through the sections — always BEHIND content */
.bg-spark {
  position: absolute;
  z-index: 0;
  color: var(--sunshine);
  pointer-events: none;
  animation: float-drift 8s ease-in-out infinite alternate;
}

/* section content rides above the ambient layer */
.band > .wrap {
  position: relative;
  z-index: 1;
}

/* storybook color blocks joined by wave dividers */
.hero       { background: linear-gradient(var(--bg-top), var(--bg-bottom)); }
.solid-mint  { background: var(--bg-bottom); }
.solid-cream { background: var(--bg-top); }

/* deep bands wear a faint turtle-shell scute pattern — the brand's texture */
.forest {
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='58' height='62' viewBox='0 0 58 62'%3E%3Cpolygon points='29,7 49,18 49,42 29,53 9,42 9,18' fill='none' stroke='%23FDF4E7' stroke-opacity='0.055' stroke-width='3' stroke-linejoin='round'/%3E%3C/svg%3E"),
    linear-gradient(var(--forest), var(--forest-2));
  color: var(--bg-top);
}

.footer {
  background-color: var(--forest-3);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='58' height='62' viewBox='0 0 58 62'%3E%3Cpolygon points='29,7 49,18 49,42 29,53 9,42 9,18' fill='none' stroke='%23FDF4E7' stroke-opacity='0.045' stroke-width='3' stroke-linejoin='round'/%3E%3C/svg%3E");
  padding-block: clamp(72px, 10vw, 110px);
}

/* organic wave at a section's top — colored as the PREVIOUS section's floor.
   The path tiles seamlessly, so the whole shoreline drifts, slow as water. */
.wave {
  position: absolute;
  top: -1px;
  left: 0;
  right: 0;
  height: clamp(34px, 6vw, 70px);
  overflow: hidden;
  pointer-events: none;
}

.wave svg {
  width: 200%;
  max-width: none; /* the global svg max-width would cap the tiling at 100% */
  height: 100%;
  display: block;
  animation: wave-drift 30s linear infinite;
}

.wave-mint svg   { animation-duration: 34s; }
.wave-forest svg { animation-duration: 27s; }
.wave-cream svg  { animation-duration: 31s; }

@keyframes wave-drift {
  to { transform: translateX(-50%); }
}

.wave-mint   { color: var(--bg-bottom); }
.wave-cream  { color: var(--bg-top); }
.wave-forest { color: var(--forest-2); }

/* text on the deep bands — but white cards inside keep their ink text */
.forest .kicker {
  background: var(--sunshine);
  color: var(--ink);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.22);
}
.forest h2 { color: var(--bg-top); }
.forest .narrow > p:not(.kicker) { color: var(--mint-text); }
.forest .tier-card,
.forest .feature,
.forest .waitlist-card { color: var(--ink); }
.forest .waitlist-card h2 { color: var(--ink); }
/* a bare CTA sitting directly on a forest band needs sunshine — deep green
   is the literal band color. Use this modifier wherever that happens. */
.pill.solid.on-forest {
  background: var(--sunshine);
  color: var(--ink);
  border-bottom-color: #cc9a2e;
}

.footer .wordmark.small { color: var(--bg-top); }
.footer .footer-line,
.footer .badge-line,
.footer .footer-links,
.footer .fineprint { color: rgba(253, 244, 231, 0.72); }
.footer .footer-links a { color: var(--bg-top); }

.kicker {
  display: inline-block;
  background: var(--surface);
  color: var(--primary-deep);
  font-weight: 800;
  font-size: 0.875rem;
  letter-spacing: 0.04em;
  padding: 6px 16px;
  border-radius: var(--radius-pill);
  box-shadow: var(--soft-shadow);
  margin-bottom: 22px;
}

/* ---- hero ---- */
.hero {
  position: relative;
  overflow: hidden;
  min-height: 88svh;
  display: flex;
  align-items: center;
  padding-bottom: clamp(70px, 11vw, 140px);
}

.hero-grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(20px, 4vw, 64px);
  align-items: center;
  padding-block: clamp(36px, 7vw, 80px);
  width: 100%;
}

/* rolling meadow at the hero's feet — front hill lands exactly on mint */
.hero-hills {
  position: absolute;
  bottom: -1px;
  left: 0;
  width: 100%;
  height: clamp(90px, 16vw, 190px);
  pointer-events: none;
}

/* a soft sun glow behind the turtle, breathing slowly */
.hero-sun {
  position: absolute;
  top: -5%;
  left: 50%;
  transform: translateX(-50%);
  width: min(64vw, 380px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 201, 77, 0.38), rgba(255, 201, 77, 0) 68%);
  pointer-events: none;
  animation: sun-breathe 9s ease-in-out infinite alternate;
}

@keyframes sun-breathe {
  from { opacity: 0.72; transform: translateX(-50%) scale(1); }
  to   { opacity: 1; transform: translateX(-50%) scale(1.08); }
}

/* ---- falling leaves: the meadow air is alive, slow as sunday ---- */
.hero-leaves {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}

.leaf {
  position: absolute;
  top: -30px;
  width: 12px;
  height: 12px;
  background: var(--skin);
  border-radius: 2px 60% 60% 60%;
  opacity: 0;
  animation: leaf-fall 17s linear infinite;
}

.leaf.l1 { left: 8%; }
.leaf.l2 { left: 24%; width: 9px; height: 9px; background: var(--sunshine); animation-duration: 21s; animation-delay: 4s; }
.leaf.l3 { left: 40%; width: 10px; height: 10px; background: var(--skin-shade); animation-duration: 19s; animation-delay: 9s; }
.leaf.l4 { left: 57%; background: #cfe5d6; animation-duration: 23s; animation-delay: 2s; }
.leaf.l5 { left: 73%; width: 9px; height: 9px; animation-duration: 18s; animation-delay: 12s; }
.leaf.l6 { left: 89%; width: 11px; height: 11px; background: var(--sunshine); animation-duration: 25s; animation-delay: 6s; }

@keyframes leaf-fall {
  0%   { transform: translate3d(0, -4vh, 0) rotate(0deg); opacity: 0; }
  8%   { opacity: 0.8; }
  25%  { transform: translate3d(26px, 24vh, 0) rotate(80deg); }
  50%  { transform: translate3d(-16px, 50vh, 0) rotate(160deg); }
  75%  { transform: translate3d(22px, 76vh, 0) rotate(240deg); opacity: 0.8; }
  100% { transform: translate3d(-10px, 104vh, 0) rotate(330deg); opacity: 0; }
}

/* the faraway ridge turtle wanders, glacially */
.ridge-turtle {
  animation: ridge-amble 46s ease-in-out infinite alternate;
}

@keyframes ridge-amble {
  to { transform: translateX(46px); }
}

/* document order on mobile: headline + form FIRST, turtle after —
   the CTA must never be pushed below the first phone screen */
.hero-side {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
}

.hero-art {
  display: flex;
  justify-content: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.2s var(--ease-turtle);
}

/* desktop invitation: the turtle perks up when you point at it.
   scale (not translate) — a moved element can slide out from under the
   cursor and jitter; a grown one can't. */
.hero-art:hover { transform: scale(1.02); }

/* ambient sparkles drifting around the turtle — behind the demo card */
.float-spark {
  position: absolute;
  z-index: 0;
  color: var(--sunshine);
  font-size: 1.2rem;
  pointer-events: none;
  animation: float-drift 8s ease-in-out infinite alternate;
}

.fs1 { top: 6%; left: 6%; }

@keyframes float-drift {
  from { transform: translateY(0); opacity: 0.4; }
  to   { transform: translateY(-16px); opacity: 0.95; }
}

/* ---- mini check-in demo ---- */
.demo-card {
  position: relative;
  z-index: 1;
  background: var(--surface);
  border-radius: var(--radius-card);
  box-shadow: var(--soft-shadow);
  padding: 18px 20px;
  width: min(100%, 340px);
  text-align: center;
}

.demo-q {
  font-weight: 800;
  font-size: 1rem;
  margin-bottom: 12px;
}

.demo-choices {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
}

.demo-btn {
  font-family: inherit;
  font-weight: 800;
  font-size: 0.9375rem;
  letter-spacing: 0.03em;
  border-radius: var(--radius-pill);
  padding: 10px 16px;
  min-height: 44px;
  cursor: pointer;
  border: 2px solid var(--skin);
  background: #fff;
  color: var(--primary-deep);
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.18s var(--ease-turtle), border-color 0.18s var(--ease-turtle);
}

/* mirrors the app: "sitting tall" is the green button, "caught me slouching" the soft one */
.demo-btn.tall {
  background: var(--primary-deep);
  color: #fff;
  border-color: var(--primary-deep);
  border-bottom: 3px solid var(--forest-3);
}

.demo-btn.slouch {
  border-bottom-width: 3px;
}

.demo-btn:hover { transform: translateY(-2px); }
.demo-btn:active { transform: scale(0.96); }

.demo-btn.picked {
  outline: 3px solid var(--sunshine);
  outline-offset: 2px;
}

.demo-btn:disabled {
  opacity: 0.65;
  cursor: default;
  transform: none;
}

.demo-result {
  position: relative;
  color: var(--ink-soft);
  font-size: 0.9375rem;
  min-height: 1.5em; /* reserved so the card doesn't jump when a line appears */
  margin: 12px 0 0;
}


/* replaces the two choice buttons in the same slot, same height */
.demo-done {
  display: inline-block;
  background: var(--primary-deep);
  color: #fff;
  font-weight: 800;
  border-radius: var(--radius-pill);
  padding: 10px 22px;
  min-height: 44px;
  margin: 0;
  animation: msg-pop 0.32s var(--ease-party);
}


/* ---- turtle pose engine ----
   Geometry is driven per-frame by site.js with the app's own spring values
   (poses.ts + AnimatedTurtle.tsx). CSS only supplies the lift wrapper. */
.turtle-lift {
  will-change: transform;
}

/* confetti — brand-colored pieces burst from the turtle on celebration */
.hero-art { position: relative; }

.confetti-bit {
  position: absolute;
  left: 50%;
  top: 42%;
  width: 8px;
  height: 12px;
  border-radius: 2px;
  pointer-events: none;
  animation: confetti-fly 1s var(--ease-turtle) forwards;
}

@keyframes confetti-fly {
  0%   { transform: translate(0, 0) rotate(0); opacity: 1; }
  60%  { opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) rotate(var(--rot)); opacity: 0; }
}

/* hero copy rises in on load (animation, not transition — always ends visible) */
.rise { animation: rise-in 0.7s var(--ease-turtle) backwards; }
.r1 { animation-delay: 0.05s; }
.r2 { animation-delay: 0.15s; }
.r3 { animation-delay: 0.25s; }
.r4 { animation-delay: 0.35s; }
.r5 { animation-delay: 0.45s; }

@keyframes rise-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* the demo card floats gently, offset from the turtle's bob so the two
   drift like things on the same breeze, not a synchronized machine.
   (.demo-card.rise outranks the plain .rise animation shorthand) */
.demo-card.rise {
  animation: rise-in 0.7s var(--ease-turtle) 0.25s backwards,
             card-float 5.5s ease-in-out 1.6s infinite alternate;
}

@keyframes card-float {
  from { transform: translateY(0); }
  to   { transform: translateY(-5px); }
}

.mascot {
  width: min(46vw, 200px);
  overflow: visible; /* the slouch pose swings the head outside the viewBox */
  /* no drop-shadow filter: filtering a constantly-animating svg re-rasterizes
     every frame — the art's painted ground shadow already does this job */
  animation: bob 6s ease-in-out infinite alternate;
}

.spark {
  animation: twinkle 3.2s ease-in-out infinite;
  transform-box: fill-box;
  transform-origin: center;
}
.spark.s2 { animation-delay: 1.1s; }
.spark.s3 { animation-delay: 2.2s; }

/* the turtle blinks */
.eyes {
  animation: blink 5.5s infinite;
  transform-box: fill-box;
  transform-origin: center;
}

/* tap the turtle → happy hop + sparkle burst */
.hero-art.party { animation: hop 0.65s var(--ease-party); }
.hero-art.party .spark { animation: burst 0.65s ease both; }

/* offscreen sections pause their loops (class toggled by JS) */
.off .mascot,
.off .eyes,
.off .spark,
.off .bg-spark,
.off .float-spark,
.off .wave svg,
.off .firefly,
.off .feature-emoji,
.off .ridge-turtle,
.off .hero-sun,
.off .footer-turtle,
.off .cheer-turtle,
.off .egg-rock,
.off .install-cta,
.off .leaf,
.off .demo-card,
.off.drift-divider .drift-walker,
.off.drift-divider .drift-walker svg {
  animation-play-state: paused;
}

@keyframes bob {
  from { transform: translateY(0); }
  to   { transform: translateY(-12px); }
}

@keyframes twinkle {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.25; }
}

@keyframes blink {
  0%, 93%, 100% { transform: scaleY(1); }
  95.5%, 97%    { transform: scaleY(0.08); }
}

@keyframes hop {
  0%   { transform: translateY(0); }
  35%  { transform: translateY(-18px) scale(1.02); }
  65%  { transform: translateY(2px) scale(0.99); }
  100% { transform: translateY(0); }
}

@keyframes burst {
  0%   { opacity: 1; transform: scale(1); }
  55%  { opacity: 1; transform: scale(1.9); }
  100% { opacity: 0.9; transform: scale(1); }
}

.wordmark {
  font-size: clamp(3rem, 11vw, 5.2rem);
  color: var(--primary-deep);
  text-transform: lowercase;
  margin-bottom: 0.1em;
}

.wordmark.small {
  font-size: 2rem;
  margin-bottom: 0.4em;
}


.sub {
  color: var(--ink-soft);
  max-width: 46ch;
  margin-bottom: 1.6em;
}

/* two-beat hero sub — the PROMISE leads big, the mechanics follow small.
   (research: emotional headline > feature list; sizes must descend) */
.sub-big {
  font-size: clamp(1.4rem, 3.8vw, 1.7rem);
  font-weight: 800;
  line-height: 1.25;
  color: var(--ink);
  max-width: 24ch;
  margin-top: 0.5em;
  margin-bottom: 0.25em;
}

.sub-big .tn-green { color: var(--primary-deep); }

.sub-strong {
  font-size: clamp(1rem, 2.4vw, 1.15rem);
  font-weight: 700;
  line-height: 1.45;
  color: var(--ink-soft);
  max-width: 40ch;
  margin-bottom: 1.5em;
}

.stat-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
  margin-block: 4px 14px;
}

.stat-row span {
  background: var(--surface);
  color: var(--primary-deep);
  font-weight: 800;
  font-size: 0.875rem;
  letter-spacing: 0.03em;
  padding: 5px 14px;
  border-radius: var(--radius-pill);
  box-shadow: 0 3px 10px var(--shadow);
}

/* ---- waitlist form ---- */
.waitlist-form {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 14px;
}

.waitlist-form input[type="email"] {
  flex: 1 1 220px;
  min-width: 0;
  font-family: inherit;
  font-weight: 600;
  font-size: 1rem;
  color: var(--ink);
  background: var(--surface);
  border: 2.5px solid var(--skin);
  border-radius: var(--radius-pill);
  padding: 12px 22px;
  outline: none;
  transition: border-color 0.18s var(--ease-turtle);
}

.waitlist-form input[type="email"]::placeholder {
  color: var(--ink-soft);
}

.waitlist-form input[type="email"]:focus {
  border-color: var(--primary);
}

.waitlist-form .pill.solid {
  cursor: pointer;
  transition: transform 0.18s var(--ease-turtle);
}

.waitlist-form .pill.solid:hover {
  transform: translateY(-2px);
}

.waitlist-form .pill.solid:disabled {
  opacity: 0.7;
  cursor: wait;
  transform: none;
}

/* ---- launch-day install CTAs (wired to the store url via store.js) ---- */
.install-row {
  margin-bottom: 14px;
}

.install-cta {
  font-size: 1.05rem;
  padding: 15px 34px;
  cursor: pointer;
}

.install-cta:hover { transform: translateY(-2px); }

/* the primary action breathes, slowly — its shadow swells and settles.
   (on the element's own box-shadow: a pseudo-element's outward glow would
   be clipped by the sheen's overflow:hidden) */
.install-cta {
  animation: cta-breathe 3.4s ease-in-out infinite alternate;
}

@keyframes cta-breathe {
  from { box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.22), var(--soft-shadow); }
  to   { box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.22), 0 12px 28px rgba(35, 55, 46, 0.28); }
}

/* honest note when the store link hasn't been pasted yet */
.store-soon {
  display: block;
  margin-top: 8px;
  font-size: 0.875rem;
  color: var(--ink-soft);
  animation: rise-in 0.3s var(--ease-turtle);
}

.forest .store-soon { color: var(--mint-text); }

.form-note {
  color: var(--ink-soft);
  font-size: 0.875rem;
  margin-bottom: 0.6em;
}

.form-msg a,
.form-note a {
  color: inherit;
  font-weight: 800;
}

/* the post-signup "follow the build" nudge inside the success message */
.follow-line {
  display: inline-block;
  margin-top: 4px;
  font-weight: 600;
  font-size: 0.9375rem;
}

.form-msg {
  position: relative;
  font-weight: 800;
  color: var(--primary-deep);
  margin-bottom: 1em;
  /* errors deserve an entrance too, not just successes */
  animation: rise-in 0.3s var(--ease-turtle);
}

.form-msg.ok {
  animation: msg-pop 0.32s var(--ease-party);
}

@keyframes msg-pop {
  from { transform: scale(0.9); }
  to   { transform: scale(1); }
}

/* celebration particles on successful signup */
.burst-bit {
  position: absolute;
  left: 50%;
  top: 50%;
  pointer-events: none;
  font-size: 1.1rem;
  animation: bit-fly 0.8s var(--ease-turtle) forwards;
}

@keyframes bit-fly {
  from { transform: translate(0, 0) scale(0.6); opacity: 1; }
  to   { transform: translate(var(--dx), var(--dy)) scale(1.2); opacity: 0; }
}

/* post-demo handoff — appears once the check-in sequence settles */
.demo-next {
  font-size: 0.9375rem;
  color: var(--ink-soft);
  margin: 8px 0 0;
  animation: rise-in 0.5s var(--ease-turtle);
}

.demo-next a {
  font-weight: 800;
}

/* mobile companion pill — arrives with a friendly little spring.
   centered via auto margins, NOT left:50% — that trick halves the
   available width and silently crushes the flex children. */
.sticky-cta {
  position: fixed;
  /* clears the iphone home-indicator zone (needs viewport-fit=cover) */
  bottom: max(16px, calc(10px + env(safe-area-inset-bottom)));
  left: 0;
  right: 0;
  margin-inline: auto;
  width: fit-content;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 12px;
  animation: rise-in 0.45s var(--ease-party);
}

.sticky-cta .pill.solid {
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.22), 0 8px 22px rgba(35, 55, 46, 0.3);
}

.sticky-close {
  width: 44px; /* apple hig tap-target minimum */
  height: 44px;
  flex-shrink: 0; /* the tap target never gets squeezed */
  border-radius: 50%;
  border: none;
  background: var(--surface);
  color: var(--ink-soft);
  font-family: inherit;
  font-weight: 800;
  cursor: pointer;
  box-shadow: var(--soft-shadow);
}

@media (min-width: 760px) {
  .sticky-cta { display: none; }
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---- pills / buttons ---- */
.pill {
  display: inline-block;
  border-radius: var(--radius-pill);
  font-weight: 800;
  font-size: 1rem;
  padding: 13px 26px;
  text-decoration: none;
  border: none;
  cursor: default;
  font-family: inherit;
}

/* deep green: 5.7:1 on white text (AA); --primary alone fails at 3.4:1.
   The chunky bottom edge gives buttons a pressable, game-y depth. */
.pill.solid {
  position: relative;
  overflow: hidden;
  background: var(--primary-deep);
  color: #fff;
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.22), var(--soft-shadow);
  border-bottom: 4px solid var(--forest-3);
  transition: transform 0.18s var(--ease-turtle), box-shadow 0.18s var(--ease-turtle);
}

/* a quiet sheen slides across on hover — polish, not fireworks */
.pill.solid::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: -60%;
  width: 45%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.22), transparent);
  transform: skewX(-20deg) translateX(0);
  transition: transform 0.55s ease;
  pointer-events: none;
}

.pill.solid:hover::after {
  transform: skewX(-20deg) translateX(340%);
}

.pill.solid:hover {
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.22), 0 10px 24px rgba(35, 55, 46, 0.24);
}

.pill.solid:active {
  transform: translateY(2px) !important;
  border-bottom-width: 2px;
}

.pill.mini {
  background: var(--surface);
  color: var(--primary-deep);
  border: 2px solid var(--skin);
  font-size: 0.9375rem;
  letter-spacing: 0.03em;
  padding: 8px 18px;
  min-height: 44px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.18s var(--ease-turtle), border-color 0.18s var(--ease-turtle);
  align-self: center;
}

.pill.mini:hover {
  transform: translateY(-2px);
  border-color: var(--primary);
}

.pill.mini:active { transform: scale(0.96); }

/* ---- creed pull-lines ---- */
/* the side bar is a pseudo-element so it can draw itself in on reveal */
.creed,
.founder-creed {
  position: relative;
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--primary-deep);
  padding-left: 23px;
  border-radius: 3px;
}

.creed::before,
.founder-creed::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 5px;
  border-radius: 3px;
  background: var(--skin);
  transform-origin: top;
}

/* ---- how it works steps ---- */
.steps {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(16px, 2.5vw, 24px);
  margin-top: 44px; /* the sitewide "intro block → content block" gap */
}

.step {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  background: var(--surface);
  border-radius: var(--radius-card);
  box-shadow: var(--soft-shadow);
  padding: 18px 20px;
  transition: transform 0.2s var(--ease-turtle), box-shadow 0.2s var(--ease-turtle);
}

.step:hover {
  transform: translateY(-4px);
  box-shadow: 0 10px 22px var(--shadow);
}

.step-num {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  background: var(--bg-top);
  border: 2.5px solid var(--skin);
  border-radius: 50%;
  font-weight: 800;
  color: var(--primary-deep);
}

/* the number waves hello when you visit its card */
.step:hover .step-num {
  animation: wiggle 0.5s var(--ease-party);
  border-color: var(--sunshine);
}

.step p {
  margin: 0;
  color: var(--ink-soft);
}

/* staggered entrance for the three steps */
.js .reveal .step {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.5s var(--ease-turtle), transform 0.5s var(--ease-turtle);
}

.js .reveal .step:nth-child(1) { transition-delay: 0.1s; }
.js .reveal .step:nth-child(2) { transition-delay: 0.25s; }
.js .reveal .step:nth-child(3) { transition-delay: 0.4s; }

.js .reveal.in .step {
  opacity: 1;
  transform: none;
}

/* ---- placeholder chrome (founder photo only) ---- */
.todo-chip {
  display: inline-block;
  background: var(--sunshine);
  color: var(--ink);
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: lowercase;
  padding: 3px 12px;
  border-radius: var(--radius-pill);
}

.drop-slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-align: center;
  background: var(--surface);
  border: 2.5px dashed var(--skin-shade);
  border-radius: var(--radius-sheet);
  color: var(--ink-soft);
  padding: 18px;
}

.drop-slot .slot-emoji { font-size: 2rem; }
.drop-slot .slot-label { font-weight: 800; color: var(--primary-deep); }
.drop-slot .slot-hint  { font-size: 0.8rem; }

.drop-slot.portrait { aspect-ratio: 4 / 5; }

/* ---- voice tiers ---- */
.tiers {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(16px, 2.5vw, 24px);
  margin-block: 44px;
}

.tier-card {
  background: var(--surface);
  border: 1px solid rgba(35, 55, 46, 0.06);
  border-radius: var(--radius-card);
  box-shadow: var(--soft-shadow);
  padding: clamp(20px, 3vw, 28px);
  display: flex;
  flex-direction: column;
  gap: 18px;
  border-top: 6px solid var(--skin);
  cursor: pointer; /* the whole card cycles lines, not just the button */
  transition: transform 0.2s var(--ease-turtle);
}

.tier-card:hover { transform: translateY(-4px); }

.tier-card[data-tier="sweet"] { border-top-color: var(--skin); }
.tier-card[data-tier="mild"]  { border-top-color: var(--sunshine); }
.tier-card[data-tier="spicy"] { border-top-color: var(--accent); }

.tier-card.featured {
  box-shadow: 0 6px 16px var(--shadow), 0 0 0 2.5px var(--accent);
}

/* ink on coral: ~4.9:1, AA (white on coral fails at 2.6:1) */
.fav-chip {
  display: inline-block;
  vertical-align: middle;
  background: var(--accent);
  color: var(--ink);
  font-size: 0.8rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  padding: 3px 12px;
  border-radius: var(--radius-pill);
  margin-left: 8px;
}

.tier-emoji {
  font-size: 1.35rem;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  background: var(--bg-top);
  border: 2.5px solid var(--skin);
  border-radius: 50%;
  margin-bottom: 8px;
}

.tier-card:hover .tier-emoji { animation: wiggle 0.5s var(--ease-party); }

@keyframes wiggle {
  0%   { transform: rotate(0); }
  30%  { transform: rotate(-8deg); }
  60%  { transform: rotate(6deg); }
  100% { transform: rotate(0); }
}

.tier-desc {
  color: var(--ink-soft);
  font-size: 1rem;
  margin: 0;
}

/* notification mock — slides in when the tier row scrolls into view */
.note {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  background: #fff;
  border-radius: 16px;
  padding: 13px 15px;
  box-shadow: 0 3px 10px var(--shadow);
  min-height: 108px;
}

.js .tiers.reveal .note {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.55s var(--ease-turtle), transform 0.55s var(--ease-turtle);
}

.js .tiers .tier-card:nth-child(1) .note { transition-delay: 0.15s; }
.js .tiers .tier-card:nth-child(2) .note { transition-delay: 0.32s; }
.js .tiers .tier-card:nth-child(3) .note { transition-delay: 0.49s; }

.js .tiers.reveal.in .note {
  opacity: 1;
  transform: none;
}

.note-icon {
  border-radius: 9px;
  flex-shrink: 0;
}

.note-icon.nudge {
  animation: icon-nudge 0.35s var(--ease-party);
}

@keyframes icon-nudge {
  0%   { transform: rotate(0) scale(1); }
  40%  { transform: rotate(4deg) scale(1.08); }
  100% { transform: rotate(0) scale(1); }
}

.note-meta {
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  margin-bottom: 3px;
}

.note-body {
  font-size: 1rem;
  line-height: 1.45;
  margin: 0;
  transition: opacity 0.18s ease;
}

.note-body.swap { opacity: 0; }

/* ---- feature grid ---- */
.feature-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(16px, 2.5vw, 24px);
}

.feature {
  background: var(--surface);
  border: 1px solid rgba(35, 55, 46, 0.06);
  border-radius: var(--radius-card);
  box-shadow: var(--soft-shadow);
  padding: clamp(20px, 3vw, 28px);
  transition: transform 0.2s var(--ease-turtle);
}

.feature:hover { transform: translateY(-4px); }

/* staggered entrance for the four cards */
.js .feature-grid.reveal .feature {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.55s var(--ease-turtle), transform 0.55s var(--ease-turtle);
}

.js .feature-grid .feature:nth-child(1) { transition-delay: 0.05s; }
.js .feature-grid .feature:nth-child(2) { transition-delay: 0.15s; }
.js .feature-grid .feature:nth-child(3) { transition-delay: 0.25s; }
.js .feature-grid .feature:nth-child(4) { transition-delay: 0.35s; }

.js .feature-grid.reveal.in .feature {
  opacity: 1;
  transform: none;
}

.feature-emoji {
  font-size: 1.55rem;
  width: 56px;
  height: 56px;
  display: grid;
  place-items: center;
  background: var(--bg-top);
  border: 2.5px solid var(--skin);
  border-radius: 50%;
  margin-bottom: 14px;
  transition: border-color 0.25s var(--ease-turtle);
  animation: emoji-float 4.5s ease-in-out infinite alternate;
}

/* a sunshine halo blooms around the emoji when you visit its card */
.feature-emoji { transition: border-color 0.25s var(--ease-turtle), box-shadow 0.3s var(--ease-turtle); }
.feature:hover .feature-emoji {
  border-color: var(--sunshine);
  box-shadow: 0 0 0 5px rgba(255, 201, 77, 0.28);
}

.feature:nth-child(2) .feature-emoji { animation-delay: 1.1s; }
.feature:nth-child(3) .feature-emoji { animation-delay: 2.2s; }
.feature:nth-child(4) .feature-emoji { animation-delay: 3.3s; }

@keyframes emoji-float {
  from { transform: translateY(0); }
  to   { transform: translateY(-5px); }
}

.feature h3 { margin-bottom: 8px; }
.feature p  { color: var(--ink-soft); margin: 0; }

.mid-cta {
  text-align: center;
  margin-top: 44px;
}

.mid-cta .pill.solid {
  cursor: pointer;
  transition: transform 0.18s var(--ease-turtle);
}

.mid-cta .pill.solid:hover { transform: translateY(-2px); }

/* ---- drift dividers — the mascot ambles across the section seams ---- */
.drift-divider {
  position: relative;
  z-index: 1;
  height: 90px;
  margin-block: -45px; /* rides the existing whitespace, adds none */
  overflow: hidden;
  pointer-events: none;
}

/* the walk restarts whenever its divider scrolls into view (site.js),
   and the turtle begins ON the edge — visible from the very first frame */
.drift-walker {
  position: absolute;
  left: -6px;
  bottom: 8px;
  animation: drift 22s linear infinite;
}

.drift-walker svg {
  width: 54px;
  animation: walk-bob 2.2s ease-in-out infinite alternate;
}

.drift-walker.rtl {
  animation-name: drift-rtl;
}

/* the art faces left natively — flip the left-to-right walker so every
   turtle leads with its head. Both directions START in view at their edge
   and finish fully offscreen on the far side. */
@keyframes drift {
  from { transform: translateX(0) scaleX(-1); }
  to   { transform: translateX(calc(100vw + 80px)) scaleX(-1); }
}

@keyframes drift-rtl {
  from { transform: translateX(calc(100vw - 56px)); }
  to   { transform: translateX(-80px); }
}

@keyframes walk-bob {
  from { transform: translateY(0); }
  to   { transform: translateY(-5px); }
}

/* ---- founder ---- */
.founder-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(32px, 6vw, 64px);
  align-items: start;
}

.founder-photo {
  max-width: 320px;
  width: 100%;
  margin-inline: auto;
}

.founder-photo figcaption {
  text-align: center;
  color: var(--ink-soft);
  font-size: 0.9375rem;
  margin-top: 12px;
}

/* the real founder photo — same chunky-ink treatment as the app shots */
.founder-img {
  display: block;
  width: 100%;
  height: auto; /* the height attribute must not defeat the aspect-ratio */
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border: 2.5px solid var(--ink);
  border-radius: var(--radius-sheet);
  box-shadow: var(--soft-shadow);
}

.founder-bio {
  color: var(--ink-soft);
}

/* ---- screenshot gallery ---- */
.gallery {
  margin-top: 44px;
  display: flex;
  gap: clamp(16px, 2.5vw, 24px);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: clamp(20px, 5vw, 48px);
  padding-bottom: 12px;
  -webkit-overflow-scrolling: touch;
}

.shot {
  flex: 0 0 min(64vw, 250px);
  scroll-snap-align: center;
  transition: transform 0.2s var(--ease-turtle);
}

/* end cards rest flush with the rail edge instead of straining to center */
.shot:first-child { scroll-snap-align: start; }
.shot:last-child  { scroll-snap-align: end; }

/* a playful hand-held tilt, like picking the phone up off a table */
.shot:hover { transform: translateY(-6px) rotate(1.2deg); }
.shot:hover .phone-img {
  box-shadow: 0 14px 30px rgba(35, 55, 46, 0.2);
}

/* staggered entrance for the four shots */
.js .gallery.reveal .shot {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.55s var(--ease-turtle), transform 0.55s var(--ease-turtle);
}

.js .gallery .shot:nth-child(1) { transition-delay: 0.05s; }
.js .gallery .shot:nth-child(2) { transition-delay: 0.15s; }
.js .gallery .shot:nth-child(3) { transition-delay: 0.25s; }
.js .gallery .shot:nth-child(4) { transition-delay: 0.35s; }
.js .gallery .shot:nth-child(5) { transition-delay: 0.45s; }
.js .gallery .shot:nth-child(6) { transition-delay: 0.55s; }
.js .gallery .shot:nth-child(7) { transition-delay: 0.65s; }

.js .gallery.reveal.in .shot {
  opacity: 1;
  transform: none;
}

.phone-img {
  display: block;
  width: 100%;
  height: auto;
  border: 2.5px solid var(--ink);
  border-radius: var(--radius-sheet);
  box-shadow: var(--soft-shadow);
  transition: box-shadow 0.25s var(--ease-turtle);
}

/* the rail scrolls sideways — keep the scrollbar visible but on-brand */
.gallery::-webkit-scrollbar { height: 10px; }
.gallery::-webkit-scrollbar-track { background: transparent; }
.gallery::-webkit-scrollbar-thumb {
  background: var(--skin);
  border-radius: var(--radius-pill);
}
.gallery { scrollbar-color: var(--skin) transparent; }

.shot figcaption {
  text-align: center;
  color: var(--ink-soft);
  font-size: 0.9375rem;
  margin-top: 12px;
}

/* tap any screenshot for a closer look */
.phone-img { cursor: zoom-in; }

.gallery-dots {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-top: 14px;
}

.gallery-dots .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--skin);
  transition: transform 0.2s var(--ease-turtle), background-color 0.2s var(--ease-turtle);
}

.gallery-dots .dot.on {
  background: var(--primary-deep);
  transform: scale(1.3);
}

/* screenshot lightbox — native <dialog> */
.shot-dialog {
  border: none;
  background: transparent;
  padding: 0;
  max-width: min(92vw, 420px);
  margin: auto;
}

.shot-dialog::backdrop {
  background: rgba(35, 55, 46, 0.55);
}

.shot-dialog img {
  width: 100%;
  max-height: 82vh;
  object-fit: contain;
  border: 2.5px solid var(--ink);
  border-radius: var(--radius-sheet);
  background: var(--bg-top);
}

.shot-dialog .dialog-cap {
  text-align: center;
  color: var(--bg-top);
  font-weight: 700;
  margin-top: 12px;
}

.shot-dialog .dialog-close {
  position: absolute;
  top: -14px;
  right: -10px;
  z-index: 1;
  width: 44px;
  height: 44px;
  border: none;
  border-radius: 50%;
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-weight: 800;
  cursor: pointer;
  box-shadow: var(--soft-shadow);
}

/* ---- faq ---- */
.faq-list {
  display: grid;
  gap: 14px;
  margin-top: 44px; /* the sitewide "intro block → content block" gap */
}

.faq-list details {
  background: var(--surface);
  border-radius: var(--radius-card);
  box-shadow: var(--soft-shadow);
  padding: 6px 22px;
}

.faq-list summary {
  cursor: pointer;
  font-weight: 800;
  color: var(--primary-deep);
  padding-block: 14px;
  min-height: 44px;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.faq-list summary:hover { color: var(--ink); } /* darker, never lighter — AA holds */

.faq-list summary::-webkit-details-marker { display: none; }

.faq-list summary::after {
  content: "+";
  font-size: 1.3rem;
  line-height: 1;
  color: var(--skin-shade);
  transition: transform 0.2s var(--ease-turtle);
}

.faq-list details[open] summary::after {
  transform: rotate(45deg);
}

.faq-list details p {
  color: var(--ink-soft);
  padding-bottom: 16px;
  margin: 0;
}

.faq-list details[open] p {
  animation: rise-in 0.35s var(--ease-turtle);
}

/* ---- waitlist band (background comes from .forest) ---- */
.waitlist-band {
  padding-block: clamp(72px, 10vw, 110px);
  padding-bottom: clamp(110px, 14vw, 170px); /* room for the night meadow */
}

.waitlist-band .wrap {
  position: relative;
  z-index: 1;
}

/* the closing scene: darker hills settle in front of the waitlist card */
.band-hills {
  position: absolute;
  bottom: -1px;
  left: 0;
  width: 100%;
  height: clamp(50px, 8vw, 90px);
  pointer-events: none;
}

/* dusk fireflies over the night meadow — they glow AND wander */
.firefly {
  opacity: 0.12;
  animation: firefly-glow 5.5s ease-in-out infinite,
             firefly-drift 12s ease-in-out infinite alternate;
}

.firefly.f2 { animation-delay: 1.8s; animation-duration: 6.5s, 14s; }
.firefly.f3 { animation-delay: 3.4s; animation-duration: 7s, 10s; }

@keyframes firefly-glow {
  0%, 100% { opacity: 0.12; }
  50%      { opacity: 0.85; }
}

@keyframes firefly-drift {
  from { transform: translate(0, 0); }
  to   { transform: translate(9px, -6px); }
}

.waitlist-card {
  position: relative;
  background: var(--surface);
  border-radius: var(--radius-sheet);
  box-shadow: var(--soft-shadow);
  padding: clamp(28px, 5vw, 44px);
  text-align: center;
}

/* the egg peeks up over the card as it scrolls into view */
.peek-turtle {
  position: absolute;
  width: 74px;
  top: -62px;
  left: 50%;
  transform: translateX(-50%);
}

.peek-egg { width: 86px; top: -70px; }

/* the app's idle egg wobble: ±4°, 900ms a swing, ease-in-out */
.egg-rock {
  transform-box: fill-box;
  transform-origin: 50% 85%;
  animation: egg-rock 1.8s ease-in-out infinite;
}

@keyframes egg-rock {
  0%, 100% { transform: rotate(-4deg); }
  50%      { transform: rotate(4deg); }
}

.js .reveal .peek-turtle {
  opacity: 0;
  transform: translateX(-50%) translateY(26px);
  transition: opacity 0.6s var(--ease-turtle) 0.25s, transform 0.6s var(--ease-turtle) 0.25s;
}

.js .reveal.in .peek-turtle {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  animation: peek-bob 4s ease-in-out 1.4s infinite alternate;
}

@keyframes peek-bob {
  from { transform: translateX(-50%) translateY(0); }
  to   { transform: translateX(-50%) translateY(-6px); }
}

.waitlist-card p {
  color: var(--ink-soft);
  max-width: 40ch;
  margin-inline: auto;
  margin-bottom: 1.6em;
}

/* closing card: heading → one line → the button, evenly weighted.
   the intro paragraph provides the gap above; the card's own padding
   closes the space below — no stray margins. */
.waitlist-card .install-row {
  /* auto side margins — the card's 40ch paragraph cap applies to this row
     too, so it must re-center itself, not pin left */
  margin: 2px auto 4px;
}

/* ---- footer ---- */
.footer .wrap {
  text-align: center;
  margin-inline: auto;
}

/* a small turtle says goodnight at the very end of the page */
.footer-turtle {
  width: 62px;
  margin: 0 auto 14px;
  animation: emoji-float 5s ease-in-out 0.8s infinite alternate;
}

.footer-line {
  color: var(--ink-soft);
  margin-bottom: 16px;
}

.badge-line {
  color: var(--ink-soft);
  font-size: 0.9375rem;
  margin-bottom: 32px;
}

.footer-btns {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 14px;
  margin-bottom: 32px;
}

.pill.gold {
  background: var(--sunshine);
  color: var(--ink);
  border-bottom: 4px solid #cc9a2e;
  box-shadow: var(--soft-shadow);
  transition: transform 0.18s var(--ease-turtle);
}

.pill.line {
  background: transparent;
  color: var(--bg-top);
  border: 2.5px solid rgba(253, 244, 231, 0.55);
  transition: transform 0.18s var(--ease-turtle), border-color 0.18s var(--ease-turtle);
}

.pill.gold:hover,
.pill.line:hover { transform: translateY(-2px); }
.pill.gold:hover { box-shadow: 0 10px 22px rgba(0, 0, 0, 0.28); }
.pill.line:hover { border-color: var(--bg-top); }
.pill.gold:active,
.pill.line:active { transform: translateY(1px); }

.footer-links {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 32px;
  color: var(--ink-soft);
}

.footer-links a {
  display: inline-block;
  padding-block: 12px; /* 44px+ tap target */
}

.fineprint {
  font-size: 0.875rem;
  color: var(--ink-soft);
}

/* ---- founder page ---- */
.founder-main {
  min-height: 70svh;
}

.back-link {
  display: inline-block;
  font-weight: 800;
  margin-bottom: 28px;
}

.mini-turtle {
  width: 110px;
  margin-bottom: 18px;
}

.founder-page .founder-photo {
  margin-block: 8px 28px;
}

/* the sendoff line — the story's last word before the ask */
.founder-send {
  font-weight: 800;
  font-size: 1.15rem;
  color: var(--primary-deep);
  margin-top: 28px;
}

.founder-cta {
  margin-top: 16px;
}

.founder-footer {
  padding-block: 40px;
}

/* a cheering turtle leads into the features CTA */
.cheer-turtle {
  width: 54px;
  margin: 0 auto 10px;
  animation: emoji-float 4.2s ease-in-out 0.4s infinite alternate;
}

/* ---- idle posture check — the site does the app's job once ---- */
.idle-toast {
  position: fixed;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 80;
  display: flex;
  gap: 12px;
  align-items: flex-start;
  width: min(92vw, 390px);
  background: var(--surface);
  border-radius: 16px;
  box-shadow: 0 12px 32px rgba(35, 55, 46, 0.28);
  padding: 12px 14px;
  animation: toast-in 0.45s var(--ease-turtle);
}

.idle-toast.bye {
  transition: opacity 0.4s var(--ease-turtle), transform 0.4s var(--ease-turtle);
  opacity: 0;
  transform: translateX(-50%) translateY(-12px);
}

@keyframes toast-in {
  from { opacity: 0; transform: translateX(-50%) translateY(-16px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}

.idle-toast .toast-close {
  border: none;
  background: none;
  color: var(--ink-soft);
  font-family: inherit;
  font-weight: 800;
  font-size: 1rem;
  cursor: pointer;
  padding: 2px 8px;
  margin-left: auto;
  flex-shrink: 0;
}

/* ---- scroll reveal (JS-gated) ---- */
.js .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s var(--ease-turtle), transform 0.7s var(--ease-turtle);
}

.js .reveal.in {
  opacity: 1;
  transform: none;
}

/* ---- reveal choreography: each section arrives like a page turning ---- */

/* the kicker pill pops in first, with a little spring */
.js .reveal .kicker {
  opacity: 0;
  transform: translateY(8px) scale(0.92);
  transition: opacity 0.5s var(--ease-turtle) 0.1s, transform 0.5s var(--ease-party) 0.1s;
}

.js .reveal.in .kicker {
  opacity: 1;
  transform: none;
}

/* the shell-scute underline draws itself in beneath the heading */
.js .reveal .kicker + h2::after {
  width: 0;
  opacity: 0;
}

.js .reveal.in .kicker + h2::after {
  width: 66px;
  opacity: 1;
  transition: width 0.6s var(--ease-turtle) 0.4s, opacity 0.4s ease 0.4s;
}

/* the sunshine highlighter sweeps across its word, like a real marker.
   Keyed on .swept — added by its own observer only when the WORD itself
   is on screen, so the stroke always happens in front of the visitor
   (section reveals fire early and would waste it off-screen). */
.hl {
  background-repeat: no-repeat;
  background-size: 100% 100%;
}

.js .hl {
  background-size: 0% 100%;
  transition: background-size 0.7s var(--ease-turtle) 0.15s;
}

.js .hl.swept {
  background-size: 100% 100%;
}

/* step numbers bounce in after their cards land */
.js .reveal .step-num {
  opacity: 0;
  transform: scale(0.4);
  transition: transform 0.45s var(--ease-party), opacity 0.3s ease;
}

.js .reveal.in .step-num {
  opacity: 1;
  transform: none;
}

.js .reveal .step:nth-child(1) .step-num { transition-delay: 0.3s; }
.js .reveal .step:nth-child(2) .step-num { transition-delay: 0.45s; }
.js .reveal .step:nth-child(3) .step-num { transition-delay: 0.6s; }

/* the why-section builds top-down: heading → prose → creed → cards */
.js #why .reveal > p:not(.kicker):not(.creed) {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.5s var(--ease-turtle) 0.3s, transform 0.5s var(--ease-turtle) 0.3s;
}

.js #why .reveal.in > p:not(.kicker):not(.creed) {
  opacity: 1;
  transform: none;
}

.js #why .reveal .creed {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.5s var(--ease-turtle) 0.55s, transform 0.5s var(--ease-turtle) 0.55s;
}

.js #why .reveal.in .creed {
  opacity: 1;
  transform: none;
}

/* the creed's side bar draws itself, top to bottom */
.js #why .reveal .creed::before {
  transform: scaleY(0);
  transition: transform 0.6s var(--ease-turtle) 0.7s;
}

.js #why .reveal.in .creed::before {
  transform: scaleY(1);
}

/* ---- desktop ---- */
@media (min-width: 760px) {
  .hero-grid { grid-template-columns: 1.15fr 1fr; }
  .mascot { width: min(30vw, 340px); }
  .tiers { grid-template-columns: repeat(3, 1fr); }
  .steps { grid-template-columns: repeat(3, 1fr); }
  .step { flex-direction: column; }
  .feature-grid { grid-template-columns: repeat(2, 1fr); }
  .founder-grid { grid-template-columns: 320px 1fr; }
  /* the rail continues on desktop — wider cards */
  .shot { flex: 0 0 244px; }
}

/* ---- reduced motion ---- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .mascot, .spark, .eyes, .hero-art.party, .hero-art.party .spark { animation: none; }
  .drift-walker, .drift-walker svg { animation: none; } /* parks it offscreen */
  .form-msg.ok, .note-icon.nudge, .burst-bit { animation: none; }
  .burst-bit { display: none; }
  .float-spark, .bg-spark, .feature-emoji, .tier-card:hover .tier-emoji,
  .rise, .demo-done, .faq-list details[open] p,
  .js .reveal.in .peek-turtle { animation: none; }
  .wave svg, .hero-sun, .ridge-turtle, .firefly { animation: none; }
  .form-msg, .idle-toast { animation: none; }
  .footer-turtle, .cheer-turtle, .install-cta, .egg-rock { animation: none; }
  .demo-card.rise { animation: none; }
  .leaf { display: none; }
  .pill.solid::after { transition: none; }
  .js .reveal .kicker, .js .reveal .step-num { opacity: 1; transform: none; transition: none; }
  .js .hl { background-size: 100% 100%; transition: none; }
  .js .reveal .kicker + h2::after { width: 66px; opacity: 1; transition: none; }
  .js #why .reveal > p, .js #why .reveal .creed { opacity: 1; transform: none; transition: none; }
  .js #why .reveal .creed::before { transform: none; transition: none; }
  .step:hover { transform: none; }
  .step:hover .step-num { animation: none; }
  .confetti-bit { display: none; }
  .js .reveal { opacity: 1; transform: none; transition: none; }
  .js .tiers.reveal .note,
  .js .feature-grid.reveal .feature,
  .js .gallery.reveal .shot,
  .js .reveal .step { opacity: 1; transform: none; transition: none; }
  .js .reveal .peek-turtle {
    opacity: 1;
    transform: translateX(-50%);
    transition: none;
  }
  .tier-card:hover, .feature:hover, .shot:hover,
  .pill.mini:hover, .waitlist-form .pill.solid:hover, .mid-cta .pill.solid:hover,
  .demo-btn:hover, .demo-checkin:hover, .hero-art:hover,
  .pill.gold:hover, .pill.line:hover {
    transform: none;
  }
}
