/* ──────────────────────────────────────────────────────────────────────────
   Boba, Landing Page
   Uses design-system/colors_and_type.css as the source of truth for every
   color, radius, shadow, and type scale. No magic numbers here that aren't
   either a DS variable or a layout tweak specifically for web.
   ────────────────────────────────────────────────────────────────────── */

* { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

/* ── Custom cursor, a tiny iridescent Boba pearl ─────────────────────
   SVG is inline-encoded so there's no extra network fetch. Hotspot is
   centered (`12 12` for the default, `16 16` for the pointer). The
   `auto` / `pointer` fallback at the end keeps the system cursor
   working if the browser can't render the data URL. */
body {
  background: var(--bg-app);
  color: var(--fg-2);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-normal);
  overflow-x: hidden;
  /* Cursor rules consolidated at the END of this stylesheet (final
     cascade pass). They need to come after the many `cursor: pointer`
     declarations on .btn / .feature-card / etc. to win source-order. */
}

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

/* ── Gradient text helper ─────────────────────────────────────────────── */
/* "Pearl iridescent", mirrors the actual mascot's color stops:
   blossom-pink → lilac → primary → sky-blue. The same word "Boba"
   should always read this way wherever it appears (hero, nav, etc).
   Tones are slightly deeper than the SVG pearl so the text stays
   legible at heading sizes. */
.grad-text {
  background: linear-gradient(135deg,
    #F6C8E4 0%,      /* boba-blossom (top-left highlight)  */
    #B9AEF0 32%,     /* primary-soft (lilac)               */
    var(--brand-primary) 65%,                              /* #8A7CE0 */
    #9BB4E8 100%     /* deep sky-blue (cool bottom)        */
  );
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* ── Buttons ──────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 28px;
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 16px;
  letter-spacing: -0.01em;
  text-decoration: none;
  transition: transform var(--dur-fast) var(--ease-soft),
              box-shadow var(--dur-med) var(--ease-soft),
              background var(--dur-med) var(--ease-soft);
  cursor: pointer;
  border: none;
}
.btn-primary {
  background: linear-gradient(135deg, var(--brand-primary) 0%, var(--brand-primary-deep) 100%);
  color: var(--white);
  box-shadow: var(--shadow-md);
}
.btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg), 0 0 24px rgba(138,124,224,0.35);
}
.btn-primary:active { transform: translateY(0); }

.btn-ghost {
  background: transparent;
  color: var(--brand-primary-deep);
  padding: 14px 20px;
}
.btn-ghost:hover { color: var(--fg-1); }

/* ── Ambient floating bubbles, alive, never static ────────────────────
   Emil: "constant motion → linear/ease-in-out, not ease-out." Each bubble
   drifts on its own cubic-bezier curve so the motion reads as organic
   weather rather than synced choreography. Cycle shortened from 24s → 14s
   and travel widened to ~80px so the motion is actually PERCEIVABLE, a
   dead-looking background makes the page feel frozen.

   The `.bubble-pulse` overlay pulses opacity on a different cycle from the
   drift, so brightness and position are decoupled, more alive, less loopy. */
.ambient {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  overflow: hidden;
}
.bubble {
  position: absolute;
  border-radius: 50%;
  filter: blur(40px);
  opacity: 0.85;
  animation:
    drift 14s cubic-bezier(0.45, 0, 0.55, 1) infinite,
    breathe 6s ease-in-out infinite;
  will-change: transform, opacity;
}
/* b1 + b3 swapped colors so the upper-left atmosphere reads BLUE (clear
   contrast against the lilac wordmark + lilac eyebrow chip + lilac primary
   button + violet display gradient that all live in this corner) and the
   lower-left grounds the page in lilac warmth. */
.b1 { width: 440px; height: 440px; top: -100px; left: -80px;  background: var(--boba-sky);          animation-delay: 0s,    0s; }
.b2 { width: 360px; height: 360px; top: 14%;    right: -100px; background: var(--boba-blossom);     animation-delay: -4s,  -2s; animation-duration: 16s, 7s; }
.b3 { width: 400px; height: 400px; bottom: 4%;  left: 4%;     background: var(--boba-lilac);        animation-delay: -9s,  -4s; animation-duration: 18s, 8s; }
.b4 { width: 280px; height: 280px; top: 44%;    left: 32%;    background: var(--boba-pearl);        animation-delay: -13s, -1s; animation-duration: 12s, 5s; opacity: 0.95; }
.b5 { width: 320px; height: 320px; bottom: -80px; right: 20%; background: var(--brand-primary-soft); animation-delay: -2s,  -3s; animation-duration: 15s, 6.5s; opacity: 0.78; }

@keyframes drift {
  0%   { transform: translate(0, 0) scale(1) rotate(0deg); }
  25%  { transform: translate(70px, -50px) scale(1.12) rotate(3deg); }
  50%  { transform: translate(-40px, -90px) scale(0.92) rotate(-4deg); }
  75%  { transform: translate(-80px, 40px) scale(1.08) rotate(2deg); }
  100% { transform: translate(0, 0) scale(1) rotate(0deg); }
}
@keyframes breathe {
  0%, 100% { opacity: var(--bub-min, 0.6); }
  50%      { opacity: var(--bub-max, 0.95); }
}

/* ── Nav ──────────────────────────────────────────────────────────────── */
/* Nav element spans the FULL viewport width so the translucent background
   never leaves a visible panel-edge partway across the page. The content
   inside is centered at 1280px via .nav-inner. */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  width: 100%;
  background: transparent;
}
.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 40px;
  max-width: 1280px;
  margin: 0 auto;
}
.nav-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 22px;
  text-decoration: none;
  letter-spacing: -0.02em;
}
/* The "Boba" wordmark uses the SAME pearl-iridescent gradient as the
   hero `.grad-text` (and as the mascot character itself) so the brand
   name reads identically everywhere, nav, hero, footer. Falls back
   to a deep purple if the browser doesn't support background-clip. */
.nav-logo span {
  color: var(--brand-primary-deep);                            /* fallback */
  background: linear-gradient(135deg,
    #F6C8E4 0%,
    #B9AEF0 32%,
    var(--brand-primary) 65%,
    #9BB4E8 100%
  );
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
/* Inline SVG logo, explicit sizing + no possibility of an inherited border,
   background, or outline drawing a visible rectangle around the pearl. */
.nav-mascot {
  width: 36px;
  height: 36px;
  background: transparent;
  overflow: visible;
}
.nav-logo,
.foot-brand a { outline: none; }
.nav-logo:focus-visible,
.foot-brand a:focus-visible {
  outline: 2px solid var(--brand-primary);
  outline-offset: 3px;
  border-radius: 6px;
}
.nav-links {
  display: flex;
  align-items: center;
  gap: 32px;
}
.nav-links a {
  color: var(--fg-2);
  text-decoration: none;
  font-weight: 500;
  font-size: 15px;
  transition: color var(--dur-fast);
}
.nav-links a:hover { color: var(--brand-primary-deep); }
.nav-cta {
  padding: 10px 20px;
  background: var(--brand-primary);
  color: var(--white) !important;
  border-radius: var(--radius-pill);
  font-weight: 700;
}
.nav-cta:hover {
  background: var(--brand-primary-deep);
  transform: translateY(-1px);
}

@media (max-width: 700px) {
  .nav-inner { padding: 14px 20px; }
  .nav-links a:not(.nav-cta) { display: none; }
}

/* ── Hero ─────────────────────────────────────────────────────────────── */
.hero {
  position: relative;
  z-index: 1;
  max-width: 1200px;
  margin: 0 auto;
  padding: 80px 40px 120px;
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  align-items: center;
  gap: 60px;
}
.hero-eyebrow {
  display: inline-block;
  padding: 8px 16px;
  border-radius: var(--radius-pill);
  background: var(--brand-primary-soft);
  color: var(--brand-primary-deep);
  font-size: var(--fs-caption);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 24px;
}
.hero h1 {
  font-family: var(--font-display);
  font-size: clamp(40px, 5.5vw, 68px);
  line-height: 1.05;
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--fg-1);
  margin-bottom: 20px;
}
.hero-sub {
  font-size: clamp(16px, 1.4vw, 18px);
  line-height: 1.55;
  color: var(--fg-2);
  margin-bottom: 32px;
  max-width: 480px;
}
.hero-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-bottom: 32px;
}
/* ── Mascot stage ──────────────────────────────────────────────────────
   Emil: "animations must have a clear purpose." Purposes here:
   - bob     = gently breathing character, never statue-still
   - lean    = subtle rotation so the whole body has a personality
   - blink   = "this thing is alive and aware"
   - breathe = body scales like a chest inhaling
   - sparkle = delight. Rare. Off-beat so it feels incidental.

   Custom easing (cubic-bezier(0.45, 0, 0.55, 1)) is a slow sinusoidal float ,
   better than ease-in-out for constant motion because it doesn't loiter at
   the midpoint. */
.hero-mascot {
  position: relative;
  height: 460px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.mascot-stage {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  animation:
    bob  5s cubic-bezier(0.45, 0, 0.55, 1) infinite,
    lean 8s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}
.boba {
  width: 380px;
  height: auto;
  filter: drop-shadow(0 24px 56px rgba(122,107,201,0.32));
  position: relative;
  z-index: 2;
  overflow: visible;
}
.mascot-glow {
  position: absolute;
  width: 500px;
  height: 500px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(199,184,255,0.55) 0%, rgba(246,200,228,0.32) 40%, transparent 70%);
  filter: blur(24px);
  z-index: 1;
  animation: pulse 3.4s ease-in-out infinite;
}

/* "squish me!" hint — hand-drawn-feeling label hovering above-right of Boba.
   Tilts gently, bobs on its own beat (different from Boba's bob), and is
   click-through so it doesn't steal taps from the mascot's own click handlers.
   Hidden via .hidden once the user has interacted with Boba. */
.mascot-hint {
  position: absolute;
  z-index: 5;
  top: 6%;
  right: 12%;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  transform: rotate(-7deg);
  animation: mascot-hint-bob 3.6s ease-in-out infinite;
  transition: opacity 320ms ease-out, transform 320ms ease-out;
}
.mascot-hint-text {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 22px;
  color: var(--brand-primary-deep);
  letter-spacing: 0.01em;
  background: rgba(255, 255, 255, 0.85);
  padding: 6px 14px;
  border-radius: 999px;
  box-shadow: 0 6px 18px rgba(122, 107, 201, 0.18);
  white-space: nowrap;
}
.mascot-hint-arrow {
  width: 56px;
  height: 42px;
  color: var(--brand-primary);
  margin-left: -28px;       /* curve points down-left toward the mascot */
  margin-top: 2px;
  transform: rotate(8deg);  /* pre-rotate so the arrow tip aims at Boba's body */
  opacity: 0.8;
}
.mascot-hint.hidden {
  opacity: 0;
  transform: rotate(-7deg) translateY(-6px) scale(0.95);
}
@keyframes mascot-hint-bob {
  0%, 100% { transform: rotate(-7deg) translateY(0); }
  50%      { transform: rotate(-5deg) translateY(-4px); }
}
/* On smaller screens (where the mascot stage shrinks), tuck the hint in. */
@media (max-width: 720px) {
  .mascot-hint { top: 0; right: 4%; }
  .mascot-hint-text { font-size: 18px; padding: 5px 11px; }
  .mascot-hint-arrow { width: 44px; height: 32px; }
}
@media (prefers-reduced-motion: reduce) {
  .mascot-hint { animation: none; }
}

/* Bob, vertical float, the main "alive" signal */
@keyframes bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-14px); }
}
/* Lean, slight side-to-side rotation, NOT synced to bob so Boba feels
   unpredictable. Tiny amount (~2.5°), any more and it looks drunk. */
@keyframes lean {
  0%, 100% { rotate: -2.5deg; }
  50%      { rotate:  2.5deg; }
}
/* Glow pulse, warms the backdrop when Boba's at his "up" peak */
@keyframes pulse {
  0%, 100% { opacity: 0.55; transform: scale(0.98); }
  50%      { opacity: 1;    transform: scale(1.1); }
}

/* ── Boba internals ────────────────────────────────────────────────────
   Body breathes on a 3.8s cycle (faster than bob, chest moves faster
   than whole-body drift, like real breathing). */
.boba-body {
  transform-origin: 50% 98%;
  transform-box: fill-box;
  animation: boba-breathe 3.8s ease-in-out infinite;
}
@keyframes boba-breathe {
  0%, 100% { transform: scaleY(1)     scaleX(1); }
  50%      { transform: scaleY(1.025) scaleX(0.99); }
}

/* Shadow sways slightly in the opposite direction, sells the weight */
.boba-shadow { animation: boba-shadow 5s cubic-bezier(0.45, 0, 0.55, 1) infinite; }
@keyframes boba-shadow {
  0%, 100% { transform: scaleX(1)    translateX(0);    opacity: 0.55; }
  50%      { transform: scaleX(1.08) translateX(-2px); opacity: 0.75; }
}

/* Eye blink, uses two keyframes very close together so the eyelid-snap
   feels real. ~140ms closed, 6s between blinks (random feel comes from
   the two eyes having tiny delay offsets). */
.boba-eyes .eye {
  transform-origin: center;
  transform-box: fill-box;
  animation: boba-blink 6.2s infinite;
}
.boba-eyes .eye-r { animation-delay: 0.06s; } /* the other eye a hair behind, natural */

@keyframes boba-blink {
  0%, 92%, 100% { transform: scaleY(1); }
  94%           { transform: scaleY(0.08); }
  96%           { transform: scaleY(1); }
}

/* Sparkles, twinkle in and out at different phases. Scale from 0.6
   (not 0) + opacity 0 so they don't pop from nothing (Emil rule).
   Different durations + delays so they feel incidental, not a sequence. */
.boba-sparkles .spark {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
}
.boba-sparkles .s1 { animation: boba-sparkle 4.2s ease-in-out 0.8s infinite; }
.boba-sparkles .s2 { animation: boba-sparkle 5.6s ease-in-out 2.3s infinite; }
.boba-sparkles .s3 { animation: boba-sparkle 3.8s ease-in-out 1.4s infinite; }

@keyframes boba-sparkle {
  0%, 100%    { opacity: 0;    transform: scale(0.6) rotate(0deg); }
  25%         { opacity: 0.9;  transform: scale(1)   rotate(8deg); }
  50%         { opacity: 0.6;  transform: scale(1.1) rotate(-4deg); }
  75%         { opacity: 0;    transform: scale(0.75) rotate(0deg); }
}

/* Canvas floats, emoji bubbles that Boba "shows" */
.canvas-float {
  position: absolute;
  font-size: 38px;
  padding: 16px;
  width: 72px;
  height: 72px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  animation: float 5s ease-in-out infinite;
  z-index: 3;
  font-family: var(--font-display);
  font-weight: 800;
  color: var(--brand-primary-deep);
}
.cf1 { top: 20px;    left: -10px;  animation-delay: 0s; }
.cf2 { top: 60px;    right: 10px;  animation-delay: -1.5s; }
.cf3 { bottom: 80px; left: 20px;   animation-delay: -3s; }
.cf4 { bottom: 40px; right: -10px; animation-delay: -4.5s; }
@keyframes float {
  0%, 100% { transform: translateY(0) rotate(-3deg); }
  50%      { transform: translateY(-14px) rotate(3deg); }
}

@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; padding: 40px 20px 60px; text-align: center; }
  .hero-sub { margin-left: auto; margin-right: auto; }
  .hero-cta { justify-content: center; }
  .hero-badges { justify-content: center; }
  .hero-mascot { height: 360px; margin-top: 20px; }
  .mascot-stage img { width: 280px; }
  .mascot-glow { width: 360px; height: 360px; }
  .canvas-float { font-size: 30px; width: 60px; height: 60px; }
}

/* ── Sections ─────────────────────────────────────────────────────────── */
.section-title {
  font-family: var(--font-display);
  font-size: clamp(32px, 4.5vw, 52px);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.025em;
  color: var(--fg-1);
  text-align: center;
  margin-bottom: 20px;
}
.section-sub {
  font-size: clamp(16px, 1.4vw, 18px);
  color: var(--fg-2);
  line-height: var(--lh-loose);
  text-align: center;
  max-width: 620px;
  margin: 0 auto 60px;
}
.section-eyebrow {
  display: inline-block;
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  background: var(--brand-accent-soft);
  color: var(--brand-primary-deep);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-bottom: 16px;
}

/* ── Features ─────────────────────────────────────────────────────────── */
.features {
  position: relative;
  z-index: 1;
  max-width: 1200px;
  margin: 0 auto;
  padding: 80px 40px;
}
.feature-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}
.feature-card {
  background: var(--white);
  border-radius: var(--radius-xl);
  padding: 36px 28px;
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--border-1);
  transition: transform var(--dur-med) var(--ease-soft), box-shadow var(--dur-med);
}
.feature-card:hover {
  transform: translateY(-6px);
  box-shadow: var(--shadow-lg);
}
.feature-icon {
  width: 68px;
  height: 68px;
  border-radius: var(--radius-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 34px;
  margin-bottom: 20px;
}
.feat-voice  { background: var(--brand-accent-soft); }
.feat-canvas { background: linear-gradient(135deg, var(--boba-sky), var(--boba-pearl)); }
.feat-memory { background: linear-gradient(135deg, var(--boba-lilac), var(--brand-accent-soft)); }

/* ── Feature card mini-demos ──────────────────────────────────────────
   Each card has a small live scene above the heading showing the
   feature in action. Emil: every animation must have a PURPOSE, here
   the purposes are (1) proof, (2) delight, (3) "I'd try that." */
.feat-demo {
  position: relative;
  width: 100%;
  height: 150px;
  border-radius: var(--radius-lg);
  margin-bottom: 22px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 18px;
}

/* 1. Voice demo, mic with concentric pulses + waveform + chat chip */
.feat-demo-voice {
  background: linear-gradient(135deg, var(--brand-accent-soft) 0%, #FFE5C2 100%);
}
.fd-mic {
  position: relative;
  width: 58px;
  height: 58px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.fd-mic-pulse {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--brand-primary);
  opacity: 0.25;
  animation: fd-ripple 2s ease-out infinite;
}
.fd-mic-pulse-2 {
  animation-delay: 1s;
}
@keyframes fd-ripple {
  0%   { transform: scale(0.6); opacity: 0.35; }
  100% { transform: scale(1.7); opacity: 0; }
}
.fd-mic-icon {
  position: relative;
  z-index: 2;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  box-shadow: var(--shadow-sm);
}
.fd-wave {
  display: flex;
  align-items: center;
  gap: 3px;
  height: 22px;
}
.fd-wave span {
  display: block;
  width: 3px;
  background: var(--brand-primary);
  border-radius: 2px;
  animation: fd-wave 0.9s ease-in-out infinite;
}
.fd-wave span:nth-child(1) { animation-delay: -0.8s; }
.fd-wave span:nth-child(2) { animation-delay: -0.7s; }
.fd-wave span:nth-child(3) { animation-delay: -0.6s; }
.fd-wave span:nth-child(4) { animation-delay: -0.5s; }
.fd-wave span:nth-child(5) { animation-delay: -0.4s; }
.fd-wave span:nth-child(6) { animation-delay: -0.3s; }
.fd-wave span:nth-child(7) { animation-delay: -0.2s; }
.fd-wave span:nth-child(8) { animation-delay: -0.1s; }
@keyframes fd-wave {
  0%, 100% { height: 4px; opacity: 0.5; }
  50%      { height: 20px; opacity: 1; }
}
.fd-caption {
  display: flex;
  justify-content: center;
  width: 100%;
}
.fd-chip {
  padding: 6px 12px;
  border-radius: var(--radius-pill);
  font-size: 12px;
  font-weight: 600;
  background: var(--white);
  color: var(--fg-1);
  box-shadow: var(--shadow-xs);
  animation: fd-chip-pop 4s ease-in-out infinite;
}
.fd-chip-child { color: var(--brand-primary-deep); }
.fd-chip-boba  { color: var(--brand-primary-deep); }
@keyframes fd-chip-pop {
  0%, 100% { opacity: 0; transform: translateY(6px) scale(0.95); }
  15%      { opacity: 1; transform: translateY(0)   scale(1); }
  80%      { opacity: 1; transform: translateY(0)   scale(1); }
  95%      { opacity: 0; transform: translateY(-6px) scale(0.95); }
}

/* 2. Canvas demo, 4 visuals cycling, one at a time, each pops + rotates */
.feat-demo-canvas {
  background: linear-gradient(135deg, var(--boba-sky) 0%, var(--boba-pearl) 100%);
}
.fd-canvas-slot {
  position: relative;
  width: 80px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.fd-visual {
  position: absolute;
  width: 80px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 48px;
  font-family: var(--font-display);
  font-weight: 800;
  color: var(--brand-primary-deep);
  background: var(--white);
  border-radius: 20px;
  box-shadow: var(--shadow-md);
  opacity: 0;
  transform: scale(0.6) rotate(-8deg);
  animation: fd-visual-cycle 8s cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
}
/* 4 visuals, each visible for 25% of the 8s cycle, offset by 2s each */
.fv1 { animation-delay: 0s;   }
.fv2 { animation-delay: -6s;  }
.fv3 { animation-delay: -4s;  }
.fv4 { animation-delay: -2s;  }
@keyframes fd-visual-cycle {
  0%     { opacity: 0; transform: scale(0.6) rotate(-8deg); }
  5%     { opacity: 1; transform: scale(1.12) rotate(4deg); }
  12%    { opacity: 1; transform: scale(1) rotate(0deg); }
  22%    { opacity: 1; transform: scale(1) rotate(0deg); }
  30%    { opacity: 0; transform: scale(0.85) rotate(8deg); }
  100%   { opacity: 0; transform: scale(0.6) rotate(-8deg); }
}

/* 3. Memory demo, three session rows, stacked, TODAY one pulses */
.feat-demo-memory {
  background: linear-gradient(135deg, var(--boba-lilac) 0%, var(--brand-accent-soft) 100%);
  align-items: stretch;
  justify-content: flex-start;
  gap: 8px;
  padding: 16px 18px;
}
.fd-mem {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 12px;
  background: rgba(255,255,255,0.9);
  border-radius: 14px;
  box-shadow: var(--shadow-xs);
  opacity: 0;
  transform: translateX(-10px);
  animation: fd-mem-in 4.5s ease-out infinite;
}
.mem1 { animation-delay: 0.2s; }
.mem2 { animation-delay: 0.6s; }
.mem3 { animation-delay: 1s; }
@keyframes fd-mem-in {
  0%, 5%   { opacity: 0; transform: translateX(-10px); }
  12%      { opacity: 1; transform: translateX(0); }
  85%      { opacity: 1; transform: translateX(0); }
  100%     { opacity: 0; transform: translateX(6px); }
}
.fd-mem-date {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--brand-primary-deep);
  min-width: 42px;
}
.fd-mem-text {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 12px;
  color: var(--fg-1);
  flex: 1;
}
.fd-mem-text strong { color: var(--brand-primary-deep); }
.fd-mem-check {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--mint);
  color: #0b5a3e;
  font-size: 12px;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
}
.fd-mem-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--brand-primary);
  box-shadow: 0 0 0 0 rgba(138,124,224,0.7);
  animation: mic-pulse 1.6s ease-out infinite;
}
.mem3 {
  background: linear-gradient(135deg, var(--white) 0%, #FBD6EE 100%);
  border: 1.5px solid var(--brand-accent);
}
.feature-card h3 {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 700;
  color: var(--fg-1);
  margin-bottom: 10px;
  letter-spacing: -0.01em;
}
.feature-card p {
  color: var(--fg-2);
  font-size: 15px;
  line-height: var(--lh-normal);
}
@media (max-width: 900px) {
  .feature-grid { grid-template-columns: 1fr; gap: 16px; }
  .features { padding: 60px 20px; }
}

/* ── How it works ─────────────────────────────────────────────────────── */
.how-it-works {
  position: relative;
  z-index: 1;
  max-width: 1200px;
  margin: 0 auto;
  padding: 80px 40px;
}
.steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  margin-top: 40px;
}
.step {
  background: var(--bg-1);
  border-radius: var(--radius-xl);
  padding: 36px 28px;
  position: relative;
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: transform var(--dur-med) var(--ease-soft), box-shadow var(--dur-med);
}
.step:hover {
  transform: translateY(-6px);
  box-shadow: var(--shadow-lg);
}
.step:hover .step-num {
  transform: scale(1.12) rotate(-6deg);
}
.step-num {
  position: absolute;
  top: -20px;
  left: 28px;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--grad-sunrise);
  color: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 22px;
  box-shadow: var(--shadow-md);
  text-shadow: 0 1px 2px rgba(0,0,0,0.15);
  transition: transform 320ms cubic-bezier(0.34, 1.56, 0.64, 1);
  z-index: 2;
}

/* Connecting dotted line between consecutive step cards (desktop only).
   Drawn as a pseudo-element on the right edge of steps 1 and 2, visual
   "1 → 2 → 3" flow. Animated dash so it feels alive. */
.steps {
  position: relative;
}
.step:not(:last-child)::after {
  content: '';
  position: absolute;
  top: 50%;
  right: -22px;
  width: 24px;
  height: 4px;
  background-image: linear-gradient(90deg, var(--brand-primary) 50%, transparent 50%);
  background-size: 8px 4px;
  background-repeat: repeat-x;
  opacity: 0.45;
  z-index: 1;
  animation: step-flow 2s linear infinite;
}
@keyframes step-flow {
  0%   { background-position: 0 0; }
  100% { background-position: 16px 0; }
}
@media (max-width: 900px) {
  .step:not(:last-child)::after { display: none; }
}

/* ── Step mini-demos ──────────────────────────────────────────────────
   Each step card now opens with a tiny live demo that visualises the
   step. Keeps the section in motion and gives the eye something to
   land on at each card. */
.step-demo {
  position: relative;
  width: 100%;
  height: 130px;
  border-radius: var(--radius-lg);
  margin: 14px 0 22px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}

/* Step 1, fake form card with auto-typing name + age + avatar */
.step-demo-form {
  background: linear-gradient(135deg, #FFF6E6 0%, #FBD9EC 100%);
  flex-direction: column;
  gap: 8px;
  align-items: stretch;
  padding: 18px 20px;
}
.sd-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 10px;
  background: rgba(255,255,255,0.85);
  border-radius: 10px;
  font-family: var(--font-body);
  font-size: 12px;
  box-shadow: var(--shadow-xs);
  opacity: 0;
  transform: translateY(6px);
  animation: sd-row-in 6s ease-out infinite;
}
.sd-row:nth-child(1) { animation-delay: 0.2s; }
.sd-row:nth-child(2) { animation-delay: 1.4s; }
.sd-row:nth-child(3) { animation-delay: 2.6s; }
@keyframes sd-row-in {
  0%, 5%   { opacity: 0; transform: translateY(6px); }
  12%      { opacity: 1; transform: translateY(0); }
  82%      { opacity: 1; transform: translateY(0); }
  100%     { opacity: 0; transform: translateY(-4px); }
}
.sd-label {
  font-weight: 700;
  color: var(--fg-3);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 9px;
  min-width: 44px;
}
.sd-value {
  color: var(--fg-1);
  font-weight: 600;
  flex: 1;
}
/* Auto-typing name, uses ::before with content + steps() to type "Sam" */
.sd-typed::before {
  content: '';
  display: inline-block;
  color: var(--brand-primary-deep);
  font-weight: 700;
  animation: sd-type 6s steps(1, end) infinite;
}
@keyframes sd-type {
  0%, 18%  { content: ''; }
  22%      { content: 'S'; }
  26%      { content: 'Sa'; }
  30%      { content: 'Sam'; }
  82%      { content: 'Sam'; }
  100%     { content: ''; }
}
.sd-caret {
  display: inline-block;
  width: 1.5px;
  height: 12px;
  background: var(--brand-primary);
  animation: sd-caret 0.9s steps(2, end) infinite;
}
@keyframes sd-caret { 50% { opacity: 0; } }
.sd-age {
  color: var(--brand-primary-deep);
  font-weight: 800;
}
.sd-avatar {
  font-size: 18px;
  margin-left: auto;
  animation: sd-avatar-pop 6s ease-out infinite;
  animation-delay: 2.8s;
}
@keyframes sd-avatar-pop {
  0%, 40%  { transform: scale(0.6); opacity: 0; }
  46%      { transform: scale(1.25); opacity: 1; }
  52%      { transform: scale(1); opacity: 1; }
  82%      { transform: scale(1); opacity: 1; }
  100%     { transform: scale(0.9); opacity: 0; }
}

/* Step 2, tap-the-device with mic ripple + finger pointer */
.step-demo-tap {
  background: linear-gradient(135deg, #B8D4FF 0%, #C7B8FF 100%);
  position: relative;
}
.sd-tap-device {
  position: relative;
  width: 86px;
  height: 86px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.sd-tap-mic {
  position: relative;
  z-index: 2;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  box-shadow: var(--shadow-md);
}
.sd-tap-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: rgba(138,124,224,0.35);
  animation: sd-tap-ripple 2.4s cubic-bezier(0.4, 0, 1, 1) infinite;
}
.sd-tap-ring-2 { animation-delay: 1.2s; }
@keyframes sd-tap-ripple {
  0%   { transform: scale(0.55); opacity: 0.55; }
  100% { transform: scale(1.6);  opacity: 0; }
}
.sd-tap-hand {
  position: absolute;
  bottom: 14px;
  right: 28%;
  font-size: 28px;
  animation: sd-tap-hand 2.4s ease-out infinite;
}
@keyframes sd-tap-hand {
  0%   { transform: translateY(-22px) scale(1); opacity: 0; }
  10%  { transform: translateY(-10px) scale(1); opacity: 1; }
  20%  { transform: translateY(0)     scale(0.92); opacity: 1; }
  30%  { transform: translateY(-10px) scale(1); opacity: 1; }
  60%  { transform: translateY(-22px) scale(1); opacity: 0; }
  100% { transform: translateY(-22px) scale(1); opacity: 0; }
}

/* Step 3, growth bars + star counter ticking up */
.step-demo-grow {
  background: linear-gradient(135deg, #E8F8F1 0%, #EAF0FF 100%);
  flex-direction: column;
  gap: 10px;
}
.sd-bars {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 60px;
}
.sd-bar {
  width: 16px;
  border-radius: 6px 6px 2px 2px;
  background: linear-gradient(180deg, var(--brand-primary) 0%, var(--brand-accent) 100%);
  height: 8px;
  animation: sd-grow 4s cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
  box-shadow: 0 2px 8px rgba(138,124,224,0.25);
}
.sb1 { animation-delay: 0s;   --h: 18px; }
.sb2 { animation-delay: 0.2s; --h: 32px; }
.sb3 { animation-delay: 0.4s; --h: 26px; }
.sb4 { animation-delay: 0.6s; --h: 50px; }
.sb5 { animation-delay: 0.8s; --h: 60px; }
@keyframes sd-grow {
  0%   { height: 6px; }
  35%  { height: var(--h); }
  85%  { height: var(--h); }
  100% { height: 6px; }
}
.sd-grow-stars {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: var(--white);
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 13px;
  color: var(--brand-primary-deep);
  box-shadow: var(--shadow-xs);
}
.sd-grow-num {
  animation: sd-grow-num 4s steps(1, end) infinite;
}
@keyframes sd-grow-num {
  0%, 30%   { content: '+0'; }
  35%       { content: '+3'; }
  50%       { content: '+7'; }
  65%       { content: '+10'; }
  80%, 100% { content: '+12'; }
}
/* The keyframe `content` change above only works on pseudo-elements,
   so we apply it via ::before instead and hide the original text. */
.sd-grow-num { color: var(--brand-primary-deep); position: relative; }
.sd-grow-num::before {
  content: '+0';
  animation: sd-grow-num 4s steps(1, end) infinite;
}
.sd-grow-num { font-size: 0; }
.sd-grow-num::before { font-size: 13px; }
.step h3 {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 700;
  color: var(--fg-1);
  margin: 8px 0 10px;
  letter-spacing: -0.01em;
}
.step p { color: var(--fg-2); font-size: 15px; line-height: var(--lh-normal); }
@media (max-width: 900px) {
  .steps { grid-template-columns: 1fr; gap: 30px; }
  .how-it-works { padding: 60px 20px; }
}

/* ── For Parents ──────────────────────────────────────────────────────── */
.parents {
  position: relative;
  z-index: 1;
  max-width: 1200px;
  margin: 80px auto;
  padding: 80px 40px;
  background: var(--grad-boba-blush);
  border-radius: var(--radius-2xl);
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 60px;
  align-items: center;
}
.parents h2 {
  font-family: var(--font-display);
  font-size: clamp(32px, 4vw, 48px);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--fg-1);
  margin-bottom: 28px;
}
.parents-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.parents-list li {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  color: var(--fg-2);
  font-size: 15px;
  line-height: var(--lh-normal);
}
.parents-list strong { color: var(--fg-1); }
.bullet {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--brand-primary);
  color: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 800;
  margin-top: 1px;
}

/* Preview card (faux dashboard) */
.parents-preview { display: flex; justify-content: center; }
.preview-card {
  background: var(--white);
  border-radius: var(--radius-xl);
  padding: 28px 24px;
  box-shadow: var(--shadow-lg);
  width: 100%;
  max-width: 360px;
  transform: rotate(-2deg);
  transition: transform var(--dur-med) var(--ease-soft);
}
.preview-card:hover { transform: rotate(0) scale(1.02); }
.preview-header {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 14px;
}
.preview-avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--brand-primary-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
}
.preview-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 17px;
  color: var(--fg-1);
}
.preview-sub { font-size: 12px; color: var(--fg-3); }
.preview-stars { font-size: 16px; letter-spacing: 2px; margin-bottom: 18px; }
.preview-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-3);
  margin-top: 14px;
  margin-bottom: 8px;
}
.preview-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.pill {
  padding: 6px 12px;
  border-radius: var(--radius-pill);
  font-size: 13px;
  font-weight: 600;
}
.pill-mastered { background: rgba(255,217,138,0.35); color: #8a5f00; }
.pill-progress { background: rgba(168,230,207,0.45); color: #1e6b4a; }

@media (max-width: 900px) {
  .parents {
    grid-template-columns: 1fr;
    padding: 50px 24px;
    margin: 40px 16px;
    gap: 40px;
  }
  .preview-card { transform: rotate(0); }
}

/* ── Research / Pedagogy ─────────────────────────────────────────────── */
.research {
  position: relative;
  z-index: 1;
  max-width: 1200px;
  margin: 0 auto;
  padding: 80px 40px;
  text-align: center;
}
.research .section-eyebrow { margin-bottom: 12px; }
.research-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  margin-top: 48px;
  text-align: left;
}
.research-card {
  background: var(--white);
  border-radius: var(--radius-xl);
  padding: 32px 26px;
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--border-1);
  transition: transform var(--dur-med) var(--ease-soft), box-shadow var(--dur-med);
}
.research-card {
  cursor: pointer;
}
.research-card:hover {
  transform: translateY(-6px);
  box-shadow: var(--shadow-lg);
}
.research-card:active {
  transform: translateY(-2px) scale(0.99);
  transition: transform 100ms ease-out;
}

/* Click-to-bubble, when you tap a research card, the icon's emoji
   spawns as a glassy bubble at that point, expands with a springy
   pop, then releases and floats up + fades. Pure delight; no purpose
   beyond "this is alive". JS positions + animates it; this is just
   the resting visual style. */
.research-bubble {
  position: fixed;
  z-index: 100;
  width: 96px;
  height: 96px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 44px;
  pointer-events: none;
  background:
    radial-gradient(circle at 30% 25%, rgba(255,255,255,0.95) 0%, rgba(255,255,255,0.75) 40%, rgba(255,255,255,0.4) 100%);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow:
    inset 0 4px 14px rgba(255,255,255,0.7),
    inset 0 -8px 18px rgba(122,107,201,0.12),
    0 12px 32px rgba(122,107,201,0.28);
  transform: translate(-50%, -50%) scale(0.4);
  opacity: 0;
  will-change: transform, opacity;
  /* Subtle white "shine" highlight via outline so it reads as a soap bubble */
  border: 1.5px solid rgba(255,255,255,0.6);
}
.research-icon {
  width: 56px;
  height: 56px;
  border-radius: var(--radius-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  margin-bottom: 18px;
}
.research-card h3 {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  color: var(--fg-1);
  margin-bottom: 10px;
  letter-spacing: -0.01em;
  line-height: 1.25;
  /* Equal min-height keeps card titles aligned across the row even
     when one heading is longer than another. */
  min-height: 2.5em;
}
.research-card p {
  color: var(--fg-2);
  font-size: 15px;
  line-height: 1.55;
}
@media (max-width: 900px) {
  .research-grid { grid-template-columns: 1fr; gap: 14px; }
  .research { padding: 60px 20px; }
}
@media (min-width: 901px) and (max-width: 1080px) {
  .research-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ── Ages band ────────────────────────────────────────────────────────── */
.ages {
  position: relative;
  z-index: 1;
  max-width: 1200px;
  margin: 0 auto;
  padding: 80px 40px;
  text-align: center;
}
.age-band {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 16px;
  margin-top: 40px;
}
.age-bubble {
  background: var(--white);
  border-radius: var(--radius-xl);
  padding: 28px 16px;
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur-med) var(--ease-bounce);
  text-align: center;
}
.age-bubble:hover { transform: translateY(-6px) scale(1.04); }
.age-bubble span {
  display: block;
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 800;
  background: linear-gradient(135deg, var(--brand-primary) 0%, var(--brand-accent) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  line-height: 1;
  margin-bottom: 10px;
  letter-spacing: -0.02em;
}

/* Coming-soon bubbles, faded so they read as "future state" without
   disappearing. Hover lifts them back so content stays scannable. */
.age-bubble-soon {
  opacity: 0.55;
  position: relative;
  filter: saturate(0.85);
}
.age-bubble-soon:hover { opacity: 0.95; filter: saturate(1); }

/* "Coming soon" pill, sky-blue gradient. Selectors are MORE specific than
   `.age-bubble span` (above) so the gradient-text rule there doesn't kill
   the badge's solid color or sky background. */
.age-bubble .age-soon-badge {
  position: absolute;
  top: -12px;
  left: 50%;
  transform: translateX(-50%);
  display: inline-block;
  padding: 5px 12px;
  background: linear-gradient(135deg, #B8D4FF 0%, #C7E0FF 50%, #D8E8FF 100%);
  color: #2C4A82;
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  border-radius: var(--radius-pill);
  box-shadow:
    0 2px 10px rgba(96, 140, 220, 0.45),
    0 0 0 1px rgba(184, 212, 255, 0.4);
  white-space: nowrap;
  margin-bottom: 0;
  line-height: 1.4;
  -webkit-text-fill-color: #2C4A82;
  -webkit-background-clip: border-box;
  background-clip: border-box;
}
.age-bubble p {
  font-size: 13px;
  color: var(--fg-3);
  font-weight: 600;
  line-height: 1.35;
}
@media (max-width: 900px) {
  .age-band { grid-template-columns: repeat(2, 1fr); }
  .ages { padding: 50px 20px; }
}
@media (max-width: 500px) {
  .age-band { grid-template-columns: 1fr; }
}

/* ── Trust cards ──────────────────────────────────────────────────────── */
.trust {
  position: relative;
  z-index: 1;
  max-width: 1200px;
  margin: 0 auto;
  padding: 40px 40px 80px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}
.trust-card {
  background: var(--white);
  border-radius: var(--radius-xl);
  padding: 28px;
  border: 1.5px solid var(--border-1);
  cursor: pointer;
  transition: transform var(--dur-med) var(--ease-soft), box-shadow var(--dur-med);
}
.trust-card:hover {
  transform: translateY(-6px);
  box-shadow: var(--shadow-lg);
}
.trust-card:active {
  transform: translateY(-2px) scale(0.99);
  transition: transform 100ms ease-out;
}

/* ── Trust card mini-demos ─────────────────────────────────────────────
   Same pattern as feature cards: a small live scene above the heading
   that visualises the promise. Each demo loops a short narrative:
   1. Privacy promises tick in
   2. Three font samples cross-fade
   3. Session lengths cycle through "5 min ... as long as they like" */
.trust-demo {
  position: relative;
  width: 100%;
  height: 110px;
  border-radius: var(--radius-lg);
  margin-bottom: 18px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 1. Child-safe, padlock + 3 ticking privacy badges */
.trust-demo-safe {
  background: linear-gradient(135deg, #E8F8F1 0%, #EAF0FF 100%);
}
.ts-shield {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  box-shadow: var(--shadow-sm);
  animation: ts-shield-pulse 4s ease-in-out infinite;
  z-index: 2;
}
@keyframes ts-shield-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.06); }
}
.ts-pill {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 10px;
  background: var(--white);
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 700;
  color: var(--fg-1);
  box-shadow: var(--shadow-xs);
  opacity: 0;
  animation: ts-pill-in 4s ease-out infinite;
}
.ts-pill-1 { top: 14px;   left: 18px;   animation-delay: 0.4s; }
.ts-pill-2 { top: 50%;    right: 16px;  transform: translateY(-50%); animation-delay: 1.0s; }
.ts-pill-3 { bottom: 14px; left: 30px;  animation-delay: 1.6s; }
@keyframes ts-pill-in {
  0%, 8%   { opacity: 0; transform: translate(0, 6px) scale(0.85); }
  18%      { opacity: 1; transform: translate(0, 0)    scale(1.05); }
  25%      { opacity: 1; transform: translate(0, 0)    scale(1); }
  78%      { opacity: 1; transform: translate(0, 0)    scale(1); }
  100%     { opacity: 0; transform: translate(0, -4px) scale(0.95); }
}
.ts-pill-2 {
  /* Custom keyframe needed because this pill is centered with translate */
  animation: ts-pill-in-2 4s ease-out infinite;
  animation-delay: 1.0s;
}
@keyframes ts-pill-in-2 {
  0%, 8%   { opacity: 0; transform: translateY(-50%) translateX(6px) scale(0.85); }
  18%      { opacity: 1; transform: translateY(-50%) translateX(0)   scale(1.05); }
  25%      { opacity: 1; transform: translateY(-50%) translateX(0)   scale(1); }
  78%      { opacity: 1; transform: translateY(-50%) translateX(0)   scale(1); }
  100%     { opacity: 0; transform: translateY(-50%) translateX(-4px) scale(0.95); }
}
.ts-tick {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--mint);
  color: #0b5a3e;
  font-size: 10px;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 2. Research-backed, three "Aa" cards fade between three font families */
.trust-demo-research {
  background: linear-gradient(135deg, #FBD9EC 0%, #F1EEFB 100%);
}
.ts-aa {
  position: absolute;
  width: 64px;
  height: 64px;
  border-radius: 16px;
  background: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32px;
  font-weight: 700;
  color: var(--brand-primary-deep);
  box-shadow: var(--shadow-sm);
  opacity: 0;
  animation: ts-aa-cycle 6s ease-in-out infinite;
  letter-spacing: -0.02em;
}
.ts-aa-1 { font-family: var(--font-display); animation-delay: 0s;   left: calc(50% - 90px); top: 18px; transform: rotate(-6deg); }
.ts-aa-2 { font-family: var(--font-body);    animation-delay: -4s;  left: calc(50% - 32px); top: 18px; }
.ts-aa-3 { font-family: var(--font-kid);     animation-delay: -2s;  left: calc(50% + 26px); top: 18px; transform: rotate(6deg); }
@keyframes ts-aa-cycle {
  0%   { opacity: 0; }
  10%  { opacity: 1; }
  60%  { opacity: 1; }
  75%  { opacity: 0; }
  100% { opacity: 0; }
}
.ts-aa-label {
  position: absolute;
  bottom: 12px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand-primary-deep);
  opacity: 0;
  animation: ts-aa-cycle 6s ease-in-out infinite;
}
.ts-aa-label-1 { left: calc(50% - 90px); width: 64px; text-align: center; animation-delay: 0s; }
.ts-aa-label-2 { left: calc(50% - 32px); width: 64px; text-align: center; animation-delay: -4s; }
.ts-aa-label-3 { left: calc(50% + 26px); width: 64px; text-align: center; animation-delay: -2s; }

/* 3. Screen-time, clock + cycling time labels */
.trust-demo-time {
  background: linear-gradient(135deg, #FFF6E6 0%, #FBD6EE 100%);
  gap: 14px;
}
.ts-clock-icon {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  box-shadow: var(--shadow-sm);
  animation: ts-clock-tick 4s linear infinite;
}
@keyframes ts-clock-tick {
  0%, 24%   { transform: rotate(0deg); }
  25%, 49%  { transform: rotate(90deg); }
  50%, 74%  { transform: rotate(180deg); }
  75%, 99%  { transform: rotate(270deg); }
  100%      { transform: rotate(360deg); }
}
.ts-time-stack {
  position: relative;
  height: 44px;
  width: 180px;
  display: flex;
  align-items: center;
  justify-content: flex-start;
}
.ts-time {
  position: absolute;
  left: 0;
  padding: 8px 16px;
  background: var(--white);
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 14px;
  color: var(--brand-primary-deep);
  white-space: nowrap;
  box-shadow: var(--shadow-xs);
  opacity: 0;
  animation: ts-time-cycle 8s ease-in-out infinite;
  letter-spacing: -0.01em;
}
.tt1 { animation-delay: 0s; }
.tt2 { animation-delay: 2s; }
.tt3 { animation-delay: 4s; }
.tt4 { animation-delay: 6s; }
@keyframes ts-time-cycle {
  0%   { opacity: 0; transform: translateY(8px) scale(0.92); }
  4%   { opacity: 1; transform: translateY(0)   scale(1.05); }
  8%   { opacity: 1; transform: translateY(0)   scale(1); }
  22%  { opacity: 1; transform: translateY(0)   scale(1); }
  26%  { opacity: 0; transform: translateY(-8px) scale(0.92); }
  100% { opacity: 0; transform: translateY(-8px) scale(0.92); }
}
.trust-card h3 {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  color: var(--fg-1);
  margin-bottom: 10px;
  letter-spacing: -0.01em;
  line-height: 1.25;
  min-height: 2.5em;
}
.trust-card p { color: var(--fg-2); font-size: 15px; line-height: 1.55; }
@media (max-width: 900px) {
  .trust { grid-template-columns: 1fr; padding: 20px 20px 60px; }
}

/* ── In-app iPad mockup, "See it in action" ──────────────────────────
   Voice-first. Boba BIG in the center. Canvas teaching content scattered
   around him. No tap options as primary UI (voice is primary). Caption
   subtitle shows what Boba just said. Waveform at the bottom shows the
   child is answering. Every color + radius traces back to the DS. */
.demo {
  position: relative;
  z-index: 1;
  max-width: 1200px;
  margin: 0 auto;
  padding: 80px 40px 40px;
  text-align: center;
}
.ipad-wrap {
  position: relative;
  margin: 56px auto 0;
  width: 100%;
  max-width: 620px;
  display: flex;
  justify-content: center;
  padding: 40px 0;
}
/* iPad Pro 11" proportions, 834 × 1194 portrait → scaled to ~440 × 630 */
.ipad {
  position: relative;
  width: 460px;
  height: 640px;
  background: #1a1630;                /* bezel (deep plum-black, DS dark bg) */
  border-radius: 44px;
  padding: 16px;
  box-shadow:
    0 1px 0 rgba(255,255,255,0.08) inset,
    var(--shadow-xl),
    0 70px 140px rgba(122,107,201,0.22);
  transform-style: preserve-3d;
}
/* Tiny camera dot at top-center, like modern iPads */
.ipad-camera {
  position: absolute;
  top: 22px;
  left: 50%;
  transform: translateX(-50%);
  width: 8px;
  height: 8px;
  background: #333;
  border-radius: 50%;
  box-shadow: 0 0 0 2px rgba(0,0,0,0.3);
  z-index: 3;
}
.ipad-home {
  position: absolute;
  bottom: 8px;
  left: 50%;
  transform: translateX(-50%);
  width: 128px;
  height: 4px;
  background: rgba(255,255,255,0.5);
  border-radius: 4px;
  z-index: 2;
}

/* The actual app screen */
.ipad-screen {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 30px;
  overflow: hidden;
  background: linear-gradient(180deg, #F6F1FF 0%, #EFE7FF 55%, #EAF0FF 100%);
  display: flex;
  flex-direction: column;
  padding: 28px 28px 32px;
}

/* Ambient in-screen bubbles */
.demo-ambient {
  position: absolute; inset: 0;
  pointer-events: none;
  overflow: hidden;
}
.demo-bubble {
  position: absolute;
  border-radius: 50%;
  filter: blur(32px);
  opacity: 0.55;
  animation: drift 14s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}
.db1 { width: 180px; height: 180px; top: 10px;  left: -40px;  background: var(--boba-lilac); }
.db2 { width: 140px; height: 140px; top: 220px; right: -30px; background: var(--boba-blossom); animation-delay: -5s; }
.db3 { width: 200px; height: 200px; bottom: -10px; left: 20%; background: var(--boba-sky); animation-delay: -10s; }
.db4 { width: 120px; height: 120px; top: 180px; left: 38%;    background: var(--boba-pearl); animation-delay: -2s; opacity: 0.4; }

/* Top bar, streak badge (left) + stars earned (right) */
.ipad-topbar {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.streak-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: linear-gradient(135deg, #FFE5C2, #FBD6EE);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-xs);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 12px;
  color: #8A4A1C;
  letter-spacing: 0.01em;
}
.streak-flame { font-size: 14px; }
.demo-stars-row {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 6px 12px;
  background: rgba(255,255,255,0.85);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-xs);
  font-size: 13px;
}
.demo-stars-count {
  margin-left: 4px;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 12px;
  color: var(--brand-primary-deep);
  letter-spacing: -0.02em;
}

/* Canvas area, Boba center, scattered stars, caption below */
.ipad-canvas {
  position: relative;
  z-index: 1;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 0;
}

/* Three canvas stars scattered AROUND Boba, not in a row, that's the
   real app: the whole screen is the canvas, Boba sits inside it. */
.canvas-star {
  position: absolute;
  font-size: 44px;
  filter: drop-shadow(0 4px 12px rgba(255,217,138,0.6));
  opacity: 0;
  animation: canvas-star-pop 5s cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
}
.cs1 { top: 18%; left: 18%;  animation-delay: 0.2s; }
.cs2 { top: 22%; right: 16%; animation-delay: 0.9s; }
.cs3 { bottom: 28%; left: 50%; transform: translateX(-50%); animation-delay: 1.6s; }
@keyframes canvas-star-pop {
  0%   { opacity: 0; transform: scale(0.6)  translateY(20px) rotate(-12deg); }
  10%  { opacity: 1; transform: scale(1.2)  translateY(-8px) rotate(6deg); }
  18%  { opacity: 1; transform: scale(1)    translateY(0)    rotate(0deg); }
  75%  { opacity: 1; transform: scale(1)    translateY(0)    rotate(0deg); }
  90%  { opacity: 0.6; transform: scale(0.95) translateY(-4px) rotate(-4deg); }
  100% { opacity: 0; transform: scale(0.6)  translateY(20px) rotate(-12deg); }
}
/* For cs3, keep the translateX(-50%) through the animation */
.cs3 {
  animation-name: canvas-star-pop-center;
}
@keyframes canvas-star-pop-center {
  0%   { opacity: 0; transform: translateX(-50%) scale(0.6)  translateY(20px) rotate(-12deg); }
  10%  { opacity: 1; transform: translateX(-50%) scale(1.2)  translateY(-8px) rotate(6deg); }
  18%  { opacity: 1; transform: translateX(-50%) scale(1)    translateY(0)    rotate(0deg); }
  75%  { opacity: 1; transform: translateX(-50%) scale(1)    translateY(0)    rotate(0deg); }
  90%  { opacity: 0.6; transform: translateX(-50%) scale(0.95) translateY(-4px) rotate(-4deg); }
  100% { opacity: 0; transform: translateX(-50%) scale(0.6)  translateY(20px) rotate(-12deg); }
}

/* Boba, big, center, with a soft glow ring */
.ipad-boba {
  position: relative;
  width: 180px;
  height: 180px;
  display: flex;
  align-items: center;
  justify-content: center;
  animation:
    bob   5s cubic-bezier(0.45, 0, 0.55, 1) infinite,
    lean  9s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}
.ipad-boba svg {
  width: 180px;
  height: 180px;
  filter: drop-shadow(0 16px 36px rgba(122,107,201,0.32));
  position: relative;
  z-index: 2;
}
.ipad-boba-glow {
  position: absolute;
  width: 240px;
  height: 240px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(199,184,255,0.5) 0%, rgba(246,200,228,0.25) 45%, transparent 70%);
  filter: blur(18px);
  animation: pulse 3.6s ease-in-out infinite;
}
.ipad-body {
  transform-box: fill-box;
  transform-origin: 50% 98%;
  animation: boba-breathe 3.8s ease-in-out infinite;
}
.ipad-eye {
  transform-box: fill-box;
  transform-origin: center;
  animation: boba-blink 6s infinite;
}

/* Sparkles around Boba, fade in + drift out, staggered */
.ipad-spark {
  position: absolute;
  font-size: 22px;
  opacity: 0;
  z-index: 3;
  animation: ipad-spark 4.8s ease-in-out infinite;
}
.ipad-spark.isp1 { top: 4%;  right: 12%; animation-delay: 0.3s; }
.ipad-spark.isp2 { bottom: 14%; left: 8%;  animation-delay: 1.4s; }
.ipad-spark.isp3 { top: 48%; right: -6%; animation-delay: 2.6s; font-size: 18px; }
@keyframes ipad-spark {
  0%, 100% { opacity: 0; transform: scale(0.6) rotate(0deg); }
  25%      { opacity: 1; transform: scale(1.15) rotate(12deg); }
  60%      { opacity: 0.4; transform: scale(0.95) rotate(-6deg); }
  80%      { opacity: 0; transform: scale(0.7) rotate(8deg); }
}

/* Caption, shows what Boba just said, like a subtle subtitle */
.ipad-caption {
  position: absolute;
  bottom: 14px;
  left: 50%;
  transform: translateX(-50%);
  max-width: 80%;
  padding: 10px 16px;
  background: rgba(255,255,255,0.85);
  backdrop-filter: blur(8px);
  border-radius: 16px;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--fg-1);
  text-align: center;
  line-height: 1.35;
  box-shadow: var(--shadow-xs);
}
.ipad-caption strong {
  color: var(--brand-primary-deep);
  font-weight: 700;
}

/* Voice state at the bottom, waveform + "Listening" label */
.ipad-voice {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding-top: 12px;
}
.voice-wave {
  display: flex;
  align-items: center;
  gap: 4px;
  height: 28px;
}
.voice-wave span {
  display: block;
  width: 4px;
  background: linear-gradient(180deg, var(--brand-primary) 0%, var(--brand-accent) 100%);
  border-radius: 2px;
  animation: wave 1.1s ease-in-out infinite;
}
.voice-wave span:nth-child(1)  { animation-delay: -1.0s; }
.voice-wave span:nth-child(2)  { animation-delay: -0.9s; }
.voice-wave span:nth-child(3)  { animation-delay: -0.8s; }
.voice-wave span:nth-child(4)  { animation-delay: -0.7s; }
.voice-wave span:nth-child(5)  { animation-delay: -0.6s; }
.voice-wave span:nth-child(6)  { animation-delay: -0.5s; }
.voice-wave span:nth-child(7)  { animation-delay: -0.4s; }
.voice-wave span:nth-child(8)  { animation-delay: -0.3s; }
.voice-wave span:nth-child(9)  { animation-delay: -0.2s; }
.voice-wave span:nth-child(10) { animation-delay: -0.1s; }
@keyframes wave {
  0%, 100% { height: 6px; opacity: 0.5; }
  50%      { height: 24px; opacity: 1; }
}
.voice-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  background: rgba(255,255,255,0.8);
  border-radius: var(--radius-pill);
  backdrop-filter: blur(6px);
}
.voice-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--brand-primary);
  box-shadow: 0 0 0 0 rgba(138,124,224,0.7);
  animation: mic-pulse 1.6s ease-out infinite;
}
.voice-text {
  font-size: 12px;
  font-weight: 700;
  color: var(--brand-primary-deep);
  letter-spacing: 0.04em;
}
@keyframes mic-pulse {
  0%   { box-shadow: 0 0 0 0   rgba(138,124,224,0.7); transform: scale(1); }
  70%  { box-shadow: 0 0 0 12px rgba(138,124,224,0);   transform: scale(1.15); }
  100% { box-shadow: 0 0 0 0   rgba(138,124,224,0);   transform: scale(1); }
}

/* Floating canvas examples outside the iPad, letter, animal, color, rainbow */
.ipad-float {
  position: absolute;
  width: 64px;
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 30px;
  font-family: var(--font-display);
  font-weight: 800;
  color: var(--brand-primary-deep);
  background: var(--white);
  border-radius: 20px;
  box-shadow: var(--shadow-md);
  animation: float 5s ease-in-out infinite;
}
.iflo-1 { top: 8%;   left: -10px;  animation-delay: 0s; }
.iflo-2 { top: 32%;  right: -20px; animation-delay: -1.5s; }
.iflo-3 { bottom: 18%; left: -30px; animation-delay: -3s; font-size: 14px; letter-spacing: 0.02em; }
.iflo-4 { bottom: 6%;  right: -5px; animation-delay: -4.2s; }

@media (max-width: 700px) {
  .ipad { width: 360px; height: 520px; border-radius: 36px; padding: 12px; }
  .ipad-screen { padding: 24px 20px 24px; border-radius: 26px; }
  .ipad-boba, .ipad-boba svg { width: 140px; height: 140px; }
  .ipad-boba-glow { width: 190px; height: 190px; }
  .canvas-star { font-size: 36px; }
  .ipad-float { display: none; }
}
@media (max-width: 420px) {
  .ipad { width: 300px; height: 440px; }
  .ipad-boba, .ipad-boba svg { width: 110px; height: 110px; }
  .ipad-boba-glow { width: 150px; height: 150px; }
}

/* ── Final CTA ────────────────────────────────────────────────────────── */
.cta {
  position: relative;
  z-index: 1;
  max-width: 1200px;
  margin: 0 auto;
  padding: 80px 40px;
}
/* Lighter, airier card, the previous --grad-boba bottom-right hit
   #9BB4E8 which made body text fight to be readable. Soft white with
   a delicate top-down lavender wash + corner color blobs keeps the
   brand feel without going dark. */
.cta-card {
  background: linear-gradient(180deg, #FFFFFF 0%, #FAF7FF 50%, #F4EEFF 100%);
  border-radius: var(--radius-2xl);
  padding: 72px 40px 60px;
  text-align: center;
  box-shadow: var(--shadow-xl), 0 0 0 1px rgba(122,107,201,0.06);
  position: relative;
  overflow: hidden;
}
.cta-card::before,
.cta-card::after {
  content: '';
  position: absolute;
  width: 360px;
  height: 360px;
  border-radius: 50%;
  filter: blur(70px);
  opacity: 0.55;
  pointer-events: none;
}
.cta-card::before {
  background: var(--boba-blossom);
  top: -140px;
  left: -120px;
}
.cta-card::after {
  background: var(--boba-sky);
  bottom: -140px;
  right: -120px;
}
.cta-mascot {
  width: 104px;
  height: 104px;
  margin: 0 auto 24px;
  animation: bob 4s ease-in-out infinite;
  filter:
    drop-shadow(0 14px 36px rgba(122,107,201,0.42))
    drop-shadow(0 0 28px rgba(199,184,255,0.5));
  position: relative;
}
.cta-eyebrow {
  position: relative;
  display: inline-block;
  padding: 8px 18px;
  border-radius: var(--radius-pill);
  background: linear-gradient(135deg, var(--brand-primary-soft) 0%, var(--brand-accent-soft) 100%);
  color: var(--brand-primary-deep);
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-bottom: 18px;
  box-shadow: var(--shadow-xs);
}

/* Device chips, replace inline "iPhone, iPad, web" bold text with
   tappable-looking pills. Shows availability at a glance. */
.cta-devices {
  position: relative;
  display: inline-flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin: 18px auto 24px;
}
.cta-device {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  background: var(--white);
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 14px;
  color: var(--fg-1);
  box-shadow: var(--shadow-sm);
  border: 1px solid rgba(122,107,201,0.08);
  transition: transform var(--dur-fast) var(--ease-soft), box-shadow var(--dur-med);
}
.cta-device:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md), 0 0 18px rgba(138,124,224,0.2);
}
.cta-device-emoji { font-size: 18px; line-height: 1; }
.cta-card h2 {
  position: relative;
  font-family: var(--font-display);
  font-size: clamp(30px, 4.5vw, 46px);
  font-weight: 800;
  color: var(--fg-1);
  line-height: 1.1;
  letter-spacing: -0.025em;
  margin: 0 auto;
  max-width: 700px;
}
.cta-card > p.cta-sub {
  position: relative;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 15px;
  color: var(--fg-2);
  margin: 0 auto 24px;
  max-width: 520px;
  line-height: 1.5;
}
.cta-form {
  position: relative;
  display: flex;
  gap: 10px;
  max-width: 460px;
  margin: 0 auto 14px;
  flex-wrap: wrap;
  justify-content: center;
}
.cta-form input {
  flex: 1;
  min-width: 200px;
  padding: 16px 22px;
  border-radius: var(--radius-pill);
  border: 1.5px solid var(--border-1);
  background: var(--white);
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--fg-1);
  outline: none;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
.cta-form input::placeholder { color: var(--fg-4); }
.cta-form input:focus {
  border-color: var(--brand-primary);
  box-shadow: 0 0 0 4px rgba(138,124,224,0.15);
}
.cta-micro {
  position: relative;
  font-size: 12px;
  color: var(--fg-3);
}

/* ── App Store + Google Play badges, "coming soon" state ──────────────
   Dimmed at 0.55 opacity (same convention as the coming-soon age cards
   above). Hover brightens for affordance. The actual links go nowhere
   until the apps ship; for now they smooth-scroll to the waitlist. */
.store-block {
  position: relative;
  margin-top: 28px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.store-soon-badge {
  padding: 5px 14px;
  background: linear-gradient(135deg, #B8D4FF 0%, #C7E0FF 50%, #D8E8FF 100%);
  color: #2C4A82;
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  border-radius: var(--radius-pill);
  box-shadow:
    0 2px 10px rgba(96, 140, 220, 0.45),
    0 0 0 1px rgba(184, 212, 255, 0.4);
}
.store-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  opacity: 0.55;
  filter: saturate(0.9);
  transition: opacity 240ms var(--ease-soft), filter 240ms var(--ease-soft);
}
.store-row:hover { opacity: 0.95; filter: saturate(1); }

/* Light-theme store badges, white pill with the official-style glyph
   + dark text. Standard variant since the page itself is light, the
   dark badges fought the airy CTA card. */
.store-badge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 9px 18px;
  background: #ffffff;
  color: #1a1630;
  text-decoration: none;
  border-radius: 12px;
  border: 1.5px solid rgba(26, 22, 48, 0.18);
  box-shadow: var(--shadow-sm);
  transition: transform 200ms var(--ease-soft), box-shadow 200ms, border-color 200ms;
  min-width: 168px;
}
.store-badge:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
  border-color: rgba(26, 22, 48, 0.35);
}
.store-glyph {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  color: #1a1630;     /* Apple glyph stays solid dark on white */
}
.store-text {
  display: flex;
  flex-direction: column;
  line-height: 1.05;
  text-align: left;
}
.store-line-1 {
  font-family: var(--font-body);
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: rgba(26, 22, 48, 0.7);
  text-transform: none;
}
.store-line-2 {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 700;
  color: #1a1630;
  letter-spacing: -0.01em;
  margin-top: 2px;
}

@media (max-width: 900px) {
  .cta-card { padding: 48px 24px; }
  .cta { padding: 40px 16px 60px; }
}

/* ── Footer ───────────────────────────────────────────────────────────── */
footer {
  max-width: 1200px;
  margin: 0 auto;
  padding: 40px 40px 60px;
  border-top: 1px solid var(--border-1);
}
.foot-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 20px;
  margin-bottom: 24px;
}
.foot-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 20px;
}
.foot-brand img { width: 32px; height: 32px; }
/* Footer wordmark, same pearl-iridescent gradient as the nav + hero */
.foot-brand span {
  color: var(--brand-primary-deep);
  background: linear-gradient(135deg,
    #F6C8E4 0%,
    #B9AEF0 32%,
    var(--brand-primary) 65%,
    #9BB4E8 100%
  );
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.foot-links {
  display: flex;
  gap: 24px;
  flex-wrap: wrap;
}
.foot-links a {
  color: var(--fg-3);
  text-decoration: none;
  font-size: 14px;
  transition: color var(--dur-fast);
}
.foot-links a:hover { color: var(--brand-primary-deep); }
.foot-copy {
  color: var(--fg-4);
  font-size: 13px;
  text-align: center;
}

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

/* ── Interactive microinteractions ─────────────────────────────────────
   Emil: every animation must have a clear purpose.
   - Scroll progress bar       = orient the user in long pages
   - Dashboard card 3D tilt    = invite them to look at the preview
   - Canvas-float wiggle       = playfulness when they hover near Boba
   - Age bubble squish + jiggle = tactile feedback on every device
   - Button press state        = "the button heard me"
   - Boba wants-to-be-touched  = cursor changes so users know to click */

/* Top scroll progress, thin bar in brand gradient, fills as the user
   scrolls. 4px so it's visible but never distracting. */
.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 4px;
  width: 0%;
  background: linear-gradient(90deg, var(--brand-primary) 0%, var(--brand-accent) 50%, var(--boba-sky) 100%);
  z-index: 100;
  transition: width 120ms linear;
  box-shadow: 0 1px 6px rgba(138,124,224,0.4);
  pointer-events: none;
}

/* Boba is clickable, cue that to the user */
.mascot-stage {
  cursor: pointer;
}

/* When the user clicks Boba, his whole body squishes once */
.boba.clicked .boba-body {
  animation: boba-squish 600ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes boba-squish {
  0%   { transform: scale(1); }
  40%  { transform: scaleY(0.88) scaleX(1.06); }
  70%  { transform: scaleY(1.04) scaleX(0.98); }
  100% { transform: scale(1); }
}

/* Eyes follow the cursor, JS writes --eye-x / --eye-y per-eye as small
   translate offsets in pixels. Max travel is 3px so Boba doesn't look
   cross-eyed. Transition is snappy (120ms) so tracking feels live. */
.boba-eyes .eye {
  transition: transform 120ms cubic-bezier(0.23, 1, 0.32, 1);
}
.boba:not(.clicked) .eye-l { transform: translate(var(--eye-x, 0px), var(--eye-y, 0px)); }
.boba:not(.clicked) .eye-r { transform: translate(var(--eye-x, 0px), var(--eye-y, 0px)); }

/* Canvas-float emoji chips, snap-bigger + rotate on hover */
.canvas-float {
  cursor: pointer;
  transition:
    transform 260ms cubic-bezier(0.34, 1.56, 0.64, 1),
    box-shadow var(--dur-med);
}
.canvas-float:hover {
  transform: scale(1.18) rotate(-6deg) translateY(-4px);
  box-shadow: var(--shadow-lg), 0 0 24px rgba(138,124,224,0.3);
}
.canvas-float:active {
  transform: scale(0.96) rotate(4deg);
  transition: transform 100ms ease-out;
}

/* Age bubbles, springy press state on click */
.age-bubble { cursor: pointer; }
.age-bubble:active {
  transform: translateY(-2px) scale(0.97);
  transition: transform 100ms ease-out;
}

/* Buttons, tactile press feedback */
.btn { will-change: transform; }
.btn:active {
  transform: translateY(1px) scale(0.97);
  transition: transform 100ms ease-out;
}

/* Magnetic hover on primary CTAs, JS writes --mag-x / --mag-y */
.btn-primary {
  transform: translate(var(--mag-x, 0px), var(--mag-y, 0px));
  transition:
    transform 200ms cubic-bezier(0.23, 1, 0.32, 1),
    box-shadow var(--dur-med) var(--ease-soft),
    background var(--dur-med) var(--ease-soft);
}
.btn-primary:hover {
  transform: translate(var(--mag-x, 0px), calc(var(--mag-y, 0px) - 2px));
}

/* 3D tilt on the dashboard preview, JS writes --tilt-x / --tilt-y */
.preview-card {
  transition: transform 200ms cubic-bezier(0.23, 1, 0.32, 1), box-shadow var(--dur-med);
  transform-style: preserve-3d;
  transform:
    rotate(var(--preview-rot, -2deg))
    perspective(900px)
    rotateX(var(--tilt-x, 0deg))
    rotateY(var(--tilt-y, 0deg));
}
.preview-card:hover {
  --preview-rot: 0deg;
  box-shadow: var(--shadow-xl);
}

/* Counter on the preview, monospace feel for digit reads */
.preview-num { font-variant-numeric: tabular-nums; }

/* Feature / research cards, smooth hover lift already wired; add a
   subtle icon pop so the card icon feels alive on hover. */
.feature-card:hover .feature-icon,
.research-card:hover .research-icon {
  transform: scale(1.08) rotate(-3deg);
  transition: transform 260ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
.feature-icon, .research-icon {
  transition: transform 260ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Reduced-motion: respect the user's preference. Everything that loops
   continuously gets frozen; the reveal-on-scroll fades become instant.
   Hover/press states stay (they're intentional user-initiated feedback). */
@media (prefers-reduced-motion: reduce) {
  .reveal { transition: none; opacity: 1; transform: none; }
  .bubble,
  .mascot-stage,
  .mascot-glow,
  .canvas-float,
  .cta-mascot,
  .boba-body,
  .boba-shadow,
  .boba-eyes .eye,
  .boba-sparkles .spark { animation: none; }
  .boba-sparkles .spark { opacity: 0.8; } /* keep them visible but static */
  .scroll-progress { transition: none; }
  .btn-primary { transform: none; }
  .preview-card { transform: rotate(-2deg); }
  /* iPad demo, keep the UI visible but stop the loops */
  .demo-bubble,
  .ipad-boba,
  .ipad-body,
  .ipad-eye,
  .ipad-boba-glow,
  .ipad-spark,
  .canvas-star,
  .voice-wave span,
  .voice-dot,
  .ipad-float { animation: none; }
  .canvas-star { opacity: 1; transform: scale(1); }
  .ipad-spark  { opacity: 0.8; transform: scale(1); }
  .cs3 { transform: translateX(-50%) scale(1); }
  .voice-wave span { height: 12px; }
  /* Feature card mini-demos, freeze the animations, keep a static
     composed frame so the UX still reads as "here's the feature" */
  .fd-mic-pulse,
  .fd-wave span,
  .fd-chip,
  .fd-visual,
  .fd-mem,
  .fd-mem-dot { animation: none; }
  .fd-chip  { opacity: 1; transform: none; }
  .fv1      { opacity: 1; transform: scale(1) rotate(0deg); } /* show the first visual static */
  .fd-mem   { opacity: 1; transform: none; }
  .fd-wave span { height: 12px; }
  /* Step demos, freeze them in their "complete" state */
  .sd-row,
  .sd-typed::before,
  .sd-caret,
  .sd-avatar,
  .sd-tap-ring,
  .sd-tap-hand,
  .sd-bar,
  .sd-grow-num::before,
  .step:not(:last-child)::after { animation: none; }
  .sd-row    { opacity: 1; transform: none; }
  .sd-avatar { opacity: 1; transform: scale(1); }
  .sd-typed::before { content: 'Sam'; }
  .sd-grow-num::before { content: '+12'; }
  .sb1 { height: 18px; } .sb2 { height: 32px; } .sb3 { height: 26px; }
  .sb4 { height: 50px; } .sb5 { height: 60px; }
  /* Trust demos, freeze with a clear composed state */
  .ts-shield,
  .ts-pill,
  .ts-aa,
  .ts-aa-label,
  .ts-clock-icon,
  .ts-time { animation: none; }
  .ts-pill   { opacity: 1; transform: translate(0, 0) scale(1); }
  .ts-pill-2 { opacity: 1; transform: translateY(-50%) scale(1); }
  .ts-aa, .ts-aa-label { opacity: 1; }
  .ts-time   { opacity: 0; }
  .tt4       { opacity: 1; }   /* show "as long as they like" static */
}

/* ── Custom translucent pearl cursor (FINAL CASCADE PASS) ──────────────
   Re-applied at the bottom of the stylesheet so it wins over all the
   `cursor: pointer` declarations on .btn / .feature-card / .age-bubble
   / .research-card / .trust-card etc. above. The SVGs have opacity on
   the root so text + UI behind the cursor remain readable. */
body,
.demo-opt {
  cursor:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='26' height='26' viewBox='0 0 26 26' opacity='0.6'><defs><radialGradient id='p' cx='35%25' cy='30%25' r='72%25'><stop offset='0%25' stop-color='%23FFFFFF'/><stop offset='30%25' stop-color='%23F3DCFF'/><stop offset='65%25' stop-color='%23C7B8FF'/><stop offset='100%25' stop-color='%239BB4E8'/></radialGradient><radialGradient id='ps' cx='28%25' cy='22%25' r='42%25'><stop offset='0%25' stop-color='%23FFFFFF' stop-opacity='0.95'/><stop offset='100%25' stop-color='%23FFFFFF' stop-opacity='0'/></radialGradient></defs><circle cx='13' cy='13' r='10' fill='url(%23p)'/><ellipse cx='10' cy='9' rx='4' ry='2.4' fill='url(%23ps)'/></svg>") 13 13,
    auto;
}
a,
button,
.btn,
.canvas-float,
.age-bubble,
.feature-card,
.research-card,
.trust-card,
.preview-card,
.mascot-stage,
.step,
.demo-opt,
.nav-cta,
[role="button"] {
  cursor: pointer;
}
input,
textarea,
[contenteditable] { cursor: text; }
