/* ============================================================
   X Progress — landing page
   Design language: true black, X Progress blue, Lato, liquid glass,
   squircle cards. Motion language: one easing curve, small distances,
   masked type, and a single pinned hero→tour scene driven by scroll.
   ============================================================ */

/* ---------- Fonts (Lato: 300/400/700 — nothing heavier than bold by design) ---------- */
@font-face {
  font-family: "Lato"; font-weight: 300; font-style: normal; font-display: swap;
  src: url("../assets/fonts/lato-light.woff2") format("woff2");
}
@font-face {
  font-family: "Lato"; font-weight: 400; font-style: normal; font-display: swap;
  src: url("../assets/fonts/lato-regular.woff2") format("woff2");
}
@font-face {
  font-family: "Lato"; font-weight: 700; font-style: normal; font-display: swap;
  src: url("../assets/fonts/lato-bold.woff2") format("woff2");
}

/* ---------- Tokens ---------- */
:root {
  --bg: #000000;
  --bg-elevated: #121215;
  --surface: #17171b;
  --ink: #f5f5f7;
  --ink-dim: rgba(245, 245, 247, 0.62);
  --ink-faint: rgba(245, 245, 247, 0.38);
  --ink-ghost: rgba(245, 245, 247, 0.18);
  --blue: #0aa5f0;
  --blue-deep: #05a0f0;
  --red: #e8544f;
  --hairline: rgba(255, 255, 255, 0.12);
  --hairline-strong: rgba(255, 255, 255, 0.2);
  --glass-fill: rgba(255, 255, 255, 0.06);
  --glass-fill-strong: rgba(255, 255, 255, 0.11);
  --shadow-card: 0 18px 50px -16px rgba(0, 0, 0, 0.7);
  --shadow-float: 0 30px 70px -25px rgba(0, 0, 0, 0.75);
  --r-chip: 10px;
  --r-card: 20px;
  --r-panel: 28px;
  --r-hero-panel: 40px;
  --ai-gradient: conic-gradient(from 140deg,
      #ff5eae, #a24bff, #4b7bff, #19e3ff, #5bffc7, #ffd36b, #ff5eae);
  --max-w: 1120px;
  --max-w-wide: 1280px;
  --nav-h: 72px;

  /* Motion */
  --ease: cubic-bezier(0.22, 0.68, 0.35, 1);        /* the one reveal curve */
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);   /* snappy UI (menus, hovers) */
  --dur: 0.7s;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

/* ---------- Reset-ish ---------- */
* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: "Lato", -apple-system, "Helvetica Neue", Arial, sans-serif;
  font-size: 17px;
  line-height: 1.53;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img, video { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }
button { font: inherit; color: inherit; }
.tabular { font-variant-numeric: tabular-nums; }
.mono {
  font-family: var(--mono);
  font-size: 0.74rem; font-weight: 500;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-faint);
}

h1, h2 { font-weight: 700; letter-spacing: -0.025em; line-height: 1.06; text-wrap: balance; }
h2 { font-size: clamp(2rem, 4.4vw, 3.4rem); }
h3 { font-weight: 700; font-size: 1.06rem; letter-spacing: -0.005em; }
.lead {
  color: var(--ink-dim);
  font-size: clamp(1.06rem, 1.6vw, 1.26rem);
  line-height: 1.55;
  max-width: 40em;
  text-wrap: pretty;
}
section { scroll-margin-top: calc(var(--nav-h) + 8px); }

:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; border-radius: 6px; }

/* ---------- Buttons & chips ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  height: 48px; padding: 0 1.5em; border-radius: 999px;
  font-weight: 700; font-size: 0.96rem; white-space: nowrap;
  transition: transform 0.35s var(--ease-out-expo), background 0.25s ease, box-shadow 0.35s var(--ease-out-expo);
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: scale(0.97); transition-duration: 0.1s; }
.btn-primary { background: var(--blue); color: #fff; box-shadow: 0 8px 24px -10px rgba(10, 165, 240, 0.7); }
.btn-primary:hover { background: #2cb4f4; box-shadow: 0 12px 30px -10px rgba(10, 165, 240, 0.85); }
.btn-glass {
  background: var(--glass-fill);
  border: 1px solid var(--hairline-strong);
  color: var(--ink);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
.btn-glass:hover { background: var(--glass-fill-strong); }

.chip {
  display: inline-block;
  padding: 0.3em 0.85em;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.08em;
}
.chip-ai {
  background: rgba(162, 75, 255, 0.14);
  color: #d9b8ff;
  letter-spacing: 0.02em;
  margin-right: 0.55em;
}

/* ---------- Floating nav ---------- */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  height: var(--nav-h);
  padding: 0 clamp(16px, 2.5vw, 32px);
  display: flex; align-items: center; justify-content: space-between;
  pointer-events: none;
}
.nav > * { pointer-events: auto; }
.nav-logo {
  display: inline-flex; align-items: center;
  height: 46px; padding: 0 0 0 0;
  border-radius: 999px;
  border: 1px solid var(--hairline-strong);
  background: rgba(10, 10, 12, 0.6);
  backdrop-filter: blur(18px) saturate(1.4);
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  overflow: hidden;
  max-width: 46px;
  transition: max-width 0.55s var(--ease-out-expo), background 0.25s ease;
}
.nav-logo:hover, .nav-logo:focus-visible, .nav.is-scrolled .nav-logo { max-width: 200px; background: rgba(20, 20, 24, 0.75); }
.nav-logo-icon {
  flex: none; width: 44px; height: 44px;
  display: grid; place-items: center;
  transition: transform 0.55s var(--ease-out-expo);
}
.nav-logo:hover .nav-logo-icon { transform: rotate(90deg); }
.nav-logo-icon img { width: 24px; height: 24px; border-radius: 7px; }
.nav-logo-word {
  padding: 0 16px 0 2px;
  font-weight: 700; font-size: 0.98rem; letter-spacing: -0.01em; white-space: nowrap;
  opacity: 0; transform: translateX(-10px);
  transition: opacity 0.35s ease 0.08s, transform 0.55s var(--ease-out-expo) 0.08s;
}
.nav-logo:hover .nav-logo-word, .nav-logo:focus-visible .nav-logo-word, .nav.is-scrolled .nav-logo-word { opacity: 1; transform: none; }

.nav-center { position: absolute; left: 50%; top: 13px; transform: translateX(-50%); }
.nav-menu {
  position: relative;
  border-radius: 24px;
  border: 1px solid var(--hairline-strong);
  background: rgba(10, 10, 12, 0.6);
  backdrop-filter: blur(18px) saturate(1.4);
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  padding: 4px;
  transition: border-radius 0.4s var(--ease-out-expo), background 0.25s ease;
}
.nav-menu-toggle {
  display: none; align-items: center; gap: 10px;
  height: 36px; padding: 0 14px 0 12px;
  border: none; background: transparent; border-radius: 999px;
  font-weight: 700; font-size: 0.9rem; cursor: pointer;
}
.nav-burger { position: relative; width: 15px; height: 10px; display: block; }
.nav-burger i {
  position: absolute; left: 0; width: 15px; height: 1.6px; border-radius: 2px;
  background: currentColor;
  transition: transform 0.4s var(--ease-out-expo), top 0.4s var(--ease-out-expo);
}
.nav-burger i:first-child { top: 0; }
.nav-burger i:last-child { top: 8.4px; }
.nav-menu.is-open .nav-burger i:first-child { top: 4.2px; transform: rotate(45deg); }
.nav-menu.is-open .nav-burger i:last-child { top: 4.2px; transform: rotate(-45deg); }
.nav-links { display: flex; align-items: center; gap: 2px; }
.nav-links a {
  display: inline-flex; align-items: center;
  height: 36px; padding: 0 14px; border-radius: 999px;
  font-size: 0.9rem; font-weight: 700; color: var(--ink-dim);
  transition: color 0.25s ease, background 0.25s ease;
}
.nav-links a:hover { color: var(--ink); background: rgba(255, 255, 255, 0.07); }
.nav-links a.is-current { color: var(--ink); }

.nav-cta {
  height: 44px; padding: 0 1.3em; font-size: 0.92rem;
  opacity: 0; transform: translateY(-8px); pointer-events: none;
  transition: opacity 0.45s var(--ease), transform 0.6s var(--ease), background 0.25s ease, box-shadow 0.35s var(--ease-out-expo);
}
.nav.is-scrolled .nav-cta { opacity: 1; transform: none; pointer-events: auto; }
.nav.is-scrolled .nav-cta:hover { transform: translateY(-1px); }

@media (max-width: 760px) {
  .nav-menu-toggle { display: inline-flex; }
  .nav-menu.is-open { background: rgba(14, 14, 17, 0.9); }
  .nav-links {   /* a dropdown panel under the Menu pill */
    position: absolute; top: calc(100% + 8px); left: 50%;
    transform: translateX(-50%) translateY(-6px) scale(0.98);
    transform-origin: top center;
    display: grid; gap: 2px; padding: 6px;
    min-width: 200px;
    border-radius: 22px;
    border: 1px solid var(--hairline-strong);
    background: rgba(14, 14, 17, 0.92);
    backdrop-filter: blur(18px) saturate(1.4);
    -webkit-backdrop-filter: blur(18px) saturate(1.4);
    opacity: 0; visibility: hidden; pointer-events: none;
    transition: opacity 0.3s ease, transform 0.45s var(--ease-out-expo), visibility 0s linear 0.45s;
  }
  .nav-menu.is-open .nav-links {
    opacity: 1; visibility: visible; pointer-events: auto;
    transform: translateX(-50%);
    transition: opacity 0.3s ease, transform 0.45s var(--ease-out-expo), visibility 0s;
  }
  .nav-links a { height: 42px; padding: 0 16px; }
  .nav-cta { display: none; }
  .nav-logo, .nav-logo:hover, .nav.is-scrolled .nav-logo { max-width: 46px; }
  .nav-logo:hover .nav-logo-word, .nav.is-scrolled .nav-logo-word { opacity: 0; }
}

/* ---------- Pinned hero → tour scene ---------- */
.scene-runway {
  position: relative; z-index: 2;
  height: 200svh;   /* page 1 (hook) + page 2 (statement) share the pinned sea */
}
.scene {
  position: sticky; top: 0;
  height: 100svh;
  overflow: hidden;
  background: var(--bg);
}
.scene-wave {
  position: absolute; inset: 0; z-index: 0; background: #000;
}
.scene-wave::before {   /* static dot-field stand-in when the wave video isn't loaded */
  content: "";
  position: absolute; inset: 0;
  background-image: radial-gradient(circle, rgba(10, 165, 240, 0.3) 1px, transparent 1.4px);
  background-size: 24px 24px;
  -webkit-mask-image: radial-gradient(120% 90% at 50% 0%, black 30%, transparent 78%);
  mask-image: radial-gradient(120% 90% at 50% 0%, black 30%, transparent 78%);
}
.scene-wave canvas {
  position: relative; z-index: 1;
  display: block; width: 100%; height: 100%;   /* the sea fills the whole scene, edge to edge */
}
.scene-wave.is-unavailable canvas { display: none; }   /* no WebGL → the CSS dot-field shows */
.scene-inner {
  position: relative; z-index: 3;   /* copy, phone and captions ride above the sea */
  height: 100%;
  max-width: var(--max-w); margin: 0 auto;
  padding: 0 24px;
  display: grid; grid-template-columns: 1fr;
  align-items: center;
}

.hero-copy {
  position: relative; z-index: 3;
  justify-self: center;
  max-width: 760px;
  padding-top: var(--nav-h);
  padding-bottom: 6svh;
  text-align: center;
  will-change: transform, opacity;
}
/* Solid greys (45% / 95% white on black), not alpha — the sea must not show through the type */
.hero-copy h1 { font-size: clamp(2.35rem, 5.2vw, 4.3rem); line-height: 1.18; color: #737373; }
.hero-pct { color: #f2f2f2; }
.hero-pct-sign { color: #f2f2f2; font-weight: 700; }
.hero-sub { margin: 1.4rem auto 2.1rem; color: #737373; font-size: clamp(1.02rem, 1.55vw, 1.22rem); max-width: 34em; text-wrap: pretty; }
.hero-sub br { display: inline; }   /* three deliberate lines; the mobile rule below lets them reflow */

/* TEMP (2026-08-16): review the page without the download badge and the top
   nav. Delete this block to bring them back — nothing else was removed. */
.nav, .hero-ctas { display: none !important; }
.hero-ctas { display: flex; align-items: center; justify-content: center; gap: 1.1rem; flex-wrap: wrap; }
.appstore-badge { display: inline-block; transition: transform 0.35s var(--ease-out-expo); }
.appstore-badge:hover { transform: translateY(-1px) scale(1.02); }

/* Masked line reveal (hero) — lines slide up out of a clipped box on load */
.mask-line { display: block; overflow: hidden; padding-bottom: 0.14em; margin-bottom: -0.14em; }
.mask-line > span {
  display: inline-block;
  transform: translateY(112%);
  transition: transform 1s var(--ease);
}
.mask-line:nth-child(2) > span { transition-delay: 0.08s; }
.is-loaded .mask-line > span { transform: none; }
.hero-sub, .hero-ctas {
  opacity: 0; transform: translateY(16px);
  transition: opacity 0.8s var(--ease), transform 0.9s var(--ease);
}
.is-loaded .hero-sub { opacity: 1; transform: none; transition-delay: 0.3s; }
.is-loaded .hero-ctas { opacity: 1; transform: none; transition-delay: 0.42s; }

/* The tour phone: parked below the fold, rises to centre stage on scroll */
.stage-hint {
  position: absolute; left: 50%; bottom: 6svh;
  transform: translateX(-50%);
  z-index: 4;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid var(--hairline);
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: var(--ink-dim);
  white-space: nowrap;
  transition: opacity 0.4s ease;
}
.iphone-frame.stage-phone {   /* compound: must beat .iphone-frame's own position/margin */
  position: absolute; left: 50%; bottom: 0;
  z-index: 4;
  height: min(76svh, 720px);
  aspect-ratio: 426 / 898;
  width: auto; max-width: none;
  margin: 0;
  transform: translate(-50%, 112%);   /* fully below the fold (glow included) until you scroll */
  will-change: transform, opacity;
}

/* Tour captions beside the phone */
.tour {
  position: absolute; left: 24px; top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  width: min(34%, 380px);
  opacity: 0;
  pointer-events: none;
}
.tour-steps { position: relative; display: grid; }
.tour-step {
  grid-area: 1 / 1;
  opacity: 0; transform: translateY(18px);
  transition: opacity 0.55s var(--ease), transform 0.65s var(--ease);
}
.tour-step.is-active { opacity: 1; transform: none; }
.tour-step.is-past { opacity: 0; transform: translateY(-18px); }
.tour-num { margin-bottom: 1rem; }
.tour-step h2 { font-size: clamp(1.7rem, 3vw, 2.5rem); margin-bottom: 0.8rem; }
.tour-step p:last-child { color: var(--ink-dim); font-size: 1.02rem; max-width: 26em; }
.tour-progress { display: flex; gap: 6px; margin-top: 2rem; }
.tour-progress i {
  display: block; height: 2px; width: 28px; border-radius: 2px;
  background: var(--ink-ghost);
  overflow: hidden; position: relative;
}
.tour-progress i::after {
  content: ""; position: absolute; inset: 0;
  background: var(--blue);
  transform: scaleX(var(--fill, 0)); transform-origin: left;
}

/* ---------- Page 2: the statement (inside the pinned scene; scroll-scrubbed word brightening) ---------- */
.scene-statement {
  position: absolute; inset: 0; z-index: 3;
  display: flex; align-items: center; justify-content: center;
  padding: 0 24px;
  text-align: center;
  opacity: 0; transform: translate3d(0, 24px, 0);
  pointer-events: none;
  will-change: transform, opacity;
}
.scene-statement .statement-text { max-width: 900px; }
.statement-text {
  font-size: clamp(1.7rem, 3.6vw, 2.9rem);
  font-weight: 700; letter-spacing: -0.02em; line-height: 1.525;
  text-wrap: balance;
}
.statement-text .w { color: var(--ink); opacity: var(--lit, 0.16); transition: opacity 0.35s ease; }

/* ---------- Page 3: "See every moment coming." — the pinned tile-wall scene ----------
   The wall fills the stage edge to edge; site.js lands every tile once
   (springboard-style, each with its own delay/duration), then scroll raises
   the title + subtitle at the centre while the wall dims behind them. */
.moments-runway { z-index: 1; height: 200svh; }
.moments-stage { display: block; }
.tile-wall {
  position: absolute; inset: 0;
  overflow: hidden;
  will-change: opacity, transform;
  /* Fades toward the top and bottom edges, like the app's hero */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, black 14%, black 82%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, black 14%, black 82%, transparent 100%);
}
.tile-wall-track {
  position: absolute; left: 0; top: 0;
  display: grid;
  will-change: transform;
}
.tile-wall img {
  display: block; width: 100%; height: 100%;
  aspect-ratio: 1 / 1; object-fit: cover;
  border-radius: 15%;   /* 20pt on a 135pt cell */
  background: var(--surface);
  opacity: 0; transform: scale(0.2);   /* waits for its landing cue */
}
/* Springboard-style landing: scale up from a dot with a soft overshoot, fading
   in on the way. Each tile carries its own --d (delay) and --t (duration),
   set by site.js — a radial stagger from the stage centre plus jitter, so the
   field lands like a home screen rather than a single curtain. */
.tile-wall.is-landed img {
  animation: tile-land var(--t, 0.7s) var(--d, 0s) cubic-bezier(0.2, 0.7, 0.3, 1) both;
}
.tile-wall.is-settled img, .tile-wall.is-static img { animation: none; opacity: 1; transform: none; }
@keyframes tile-land {
  0%   { opacity: 0; transform: scale(0.2); }
  38%  { opacity: 1; }
  58%  { transform: scale(1.065); }
  80%  { transform: scale(0.982); }
  100% { opacity: 1; transform: scale(1); }
}
.tile-wall.is-static .tile-wall-track { transform: none !important; }
.moments-scrim {
  position: absolute; inset: 0; z-index: 1;
  background: radial-gradient(ellipse 62% 58% at 50% 50%, rgba(0, 0, 0, 0.82), rgba(0, 0, 0, 0.5) 55%, rgba(0, 0, 0, 0) 100%);
  opacity: 0; pointer-events: none;
}
.moments-copy {
  position: absolute; inset: 0; z-index: 2;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 0 24px;
  pointer-events: none;
}
.moments-copy h2, .moments-copy .lead { opacity: 0; will-change: opacity, transform; }
.moments-copy h2 { max-width: 760px; margin-bottom: 1rem; }
.moments-copy .lead { max-width: 760px; margin: 0 auto; }

/* ---------- Device frames ---------- */
/* iPhone frame: a continuous-corner (iOS-style smoothed) bezel drawn by an SVG
   (assets/img/iphone-bezel.svg, 426×898 = the 402×874 screen + a 12-unit
   bezel), the screen masked by the matching squircle
   (iphone-screen-mask.svg). The shadow is a drop-shadow filter so it follows
   the smoothed outline instead of a plain rounded box. Both SVGs were
   generated with the Figma corner-smoothing model (smoothing 0.6). */
.iphone-frame {
  position: relative;
  aspect-ratio: 426 / 898;
  width: 100%; max-width: 380px;   /* explicit: the screen is absolutely positioned, so the frame has no intrinsic width of its own */
  margin: 0 auto;
  filter: drop-shadow(0 24px 28px rgba(0, 0, 0, 0.5));
}
.iphone-frame::before {   /* bezel body + highlight ring */
  content: "";
  position: absolute; inset: 0;
  background: url("../assets/img/iphone-bezel.svg") center / 100% 100% no-repeat;
}
.iphone-frame > img, .iphone-frame > video {
  position: absolute; top: 1.336%; left: 2.817%;
  width: 94.366%; height: 97.328%;   /* the screen inside the 12-unit bezel */
  display: block; object-fit: cover;
  background: #000;
  -webkit-mask: url("../assets/img/iphone-screen-mask.svg") center / 100% 100% no-repeat;
  mask: url("../assets/img/iphone-screen-mask.svg") center / 100% 100% no-repeat;
}
.iphone-frame::after {   /* the Dynamic Island pill */
  content: "";
  position: absolute; top: 2.6%; left: 50%; translate: -50% 0;
  width: 27%; height: 2.7%;
  background: #000; border-radius: 999px;
}
.stage-phone.iphone-frame { filter: drop-shadow(0 -10px 40px rgba(10, 165, 240, 0.18)) drop-shadow(0 30px 45px rgba(0, 0, 0, 0.7)); }

.mac-frame, .ipad-frame, .watch-frame { margin: 0; }
.mac-frame img { border-radius: 12px; box-shadow: 0 30px 70px rgba(0, 0, 0, 0.6); }
.ipad-frame {
  border-radius: 26px;
  border: 10px solid #17171a;
  outline: 1px solid rgba(255, 255, 255, 0.16);
  overflow: hidden; background: #000;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
}
.watch-frame {
  border-radius: 34%/30%;
  border: 9px solid #17171a;
  outline: 1px solid rgba(255, 255, 255, 0.18);
  overflow: hidden; background: #000;
  box-shadow: 0 18px 45px rgba(0, 0, 0, 0.55);
}

/* ---------- Sections ---------- */
.section {
  position: relative; z-index: 3;
  min-height: 100svh;                 /* each scene fills the viewport; longer ones just grow */
  display: flex; flex-direction: column; justify-content: center;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: clamp(4rem, 9vh, 6.5rem) 24px;
}
.section > :last-child, .page > :last-child { margin-bottom: 0; }
/* Sections with several ideas split them into viewport-high pages */
.section.has-pages { padding-top: 0; padding-bottom: 0; }
.page {
  min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(4rem, 9vh, 6.5rem) 0;
}
.section-wide { max-width: none; padding-left: 0; padding-right: 0; }
.section-wide .section-head, .section-wide .split { max-width: var(--max-w); margin-left: auto; margin-right: auto; padding-left: 24px; padding-right: 24px; }
.section-head { margin-bottom: clamp(2.2rem, 5vh, 3.6rem); max-width: 720px; }
.section-head h2 { margin: 0.55rem 0 1rem; }
.eyebrow {
  color: var(--blue);
  font-weight: 700; font-size: 0.82rem;
  letter-spacing: 0.14em; text-transform: uppercase;
}
.h2-tight { margin: 0.55rem 0 1rem; }
.lead-tight { margin-bottom: 1.6rem; }

.split {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
  margin-bottom: clamp(3rem, 7vh, 5rem);
}
.split-flip .split-media { order: 2; }
.split-flip .split-copy { order: 1; }
.split-title { font-size: 1.5rem; font-weight: 700; margin-bottom: 0.7rem; letter-spacing: -0.015em; }
.split-copy > p { color: var(--ink-dim); text-wrap: pretty; }
.split-media .iphone-frame { max-width: min(380px, 34svh); transition: transform 0.7s var(--ease), filter 0.7s var(--ease); }   /* keeps a split inside one viewport */
.split-media:hover .iphone-frame { transform: translateY(-4px); filter: drop-shadow(0 34px 40px rgba(0, 0, 0, 0.65)); }

/* ---------- Track: floating event titles → the editor still ----------
   Pinned scene (site.js `updateTrack`). Each title owns its spot (--x/--y,
   anchored left or right so nothing spills off narrow screens), compact spot
   (--xm/--ym; `.wide-only` ones hide there), entry order (--k) and scroll
   drift in px (--d). One typeface and size throughout — only the spots and
   timing vary. */
.track-runway { z-index: 1; height: 240svh; }
.track-stage { display: block; }
.float-titles { position: absolute; inset: 0; margin: 0; padding: 0; list-style: none; }
.float-titles li {
  position: absolute; top: var(--y); left: var(--x);
  max-width: min(62vw, 40ch);
  font-weight: 700; letter-spacing: -0.015em; line-height: 1.15;
  font-size: clamp(1.05rem, 1.45vw, 1.5rem);   /* one size for the whole field */
  color: var(--ink);
  opacity: 0; transform: translate3d(0, 28px, 0);
  will-change: transform, opacity, filter;
  text-wrap: balance;
}
.float-titles li.from-right { left: auto; right: var(--x); text-align: right; }
.track-hero {
  position: absolute; inset: 0; z-index: 2;
  max-width: var(--max-w); margin: 0 auto; padding: 0 24px;
  display: grid; grid-template-columns: 1fr 1fr; align-items: center;
  gap: clamp(2rem, 5vw, 4.5rem);
  pointer-events: none;
}
.track-copy { opacity: 0; transform: translate3d(0, 24px, 0); will-change: transform, opacity; }
.track-copy h2 { margin: 0 0 1rem; }
.track-copy .lead { margin: 0; }
.iphone-frame.track-phone {
  justify-self: end; margin: 0;
  width: 100%; max-width: min(360px, 36svh);   /* ≈ 78svh tall — stays inside the stage */
  opacity: 0; transform: translate3d(0, 14svh, 0) scale(0.96);
  will-change: transform, opacity;
  filter: drop-shadow(0 -10px 40px rgba(10, 165, 240, 0.14)) drop-shadow(0 30px 45px rgba(0, 0, 0, 0.7));
}

.feature-list { display: grid; gap: 1.5rem; }
.feature-list li { display: grid; grid-template-columns: 2.4rem 1fr; gap: 0.6rem; align-items: start; }
.feature-list .row-num { padding-top: 0.35rem; }
.feature-list h3 { margin-bottom: 0.25rem; }
.feature-list p:not(.row-num) { color: var(--ink-dim); font-size: 0.99rem; text-wrap: pretty; }

/* ---------- Numbered hairline rows + hover-follow preview ---------- */
.rows { position: relative; border-top: 1px solid var(--hairline); margin-bottom: clamp(3rem, 7vh, 5rem); }
.row {
  display: grid; grid-template-columns: 3.4rem 1fr auto;
  align-items: center; gap: 1.2rem;
  padding: clamp(1.4rem, 3.4vh, 2.2rem) 0.4rem;
  border-bottom: 1px solid var(--hairline);
  cursor: default;
  transition: background 0.3s ease, padding-left 0.5s var(--ease-out-expo);
}
.row-num { padding-top: 0.15rem; }
.row-body { max-width: min(64%, 640px); }   /* leaves a right gutter for the hover preview */
.row h3 { font-size: 1.22rem; margin-bottom: 0.3rem; transition: color 0.3s ease; }
.row p:not(.row-num) { color: var(--ink-dim); text-wrap: pretty; }
.row-arrow {
  color: var(--ink-faint); font-size: 1.3rem;
  opacity: 0; transform: translateX(-8px);
  transition: opacity 0.35s var(--ease), transform 0.5s var(--ease-out-expo), color 0.3s ease;
}
@media (hover: hover) {
  .row:hover { padding-left: 0.9rem; }
  .row:hover .row-arrow { opacity: 1; transform: none; color: var(--blue); }
  .row:hover .row-num { color: var(--blue); }
}
.row-preview {
  position: absolute; left: 0; top: 0; z-index: 10;
  width: 260px; aspect-ratio: 760 / 582;
  border-radius: 18px; overflow: hidden;
  outline: 1px solid var(--hairline-strong);
  box-shadow: var(--shadow-float);
  background: var(--surface);
  pointer-events: none;
  opacity: 0; transform: translate(0, 0) scale(0.9);
  transition: opacity 0.35s var(--ease);
  display: none;
}
.row-preview img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity 0.4s var(--ease);
}
.row-preview img.is-active { opacity: 1; }
.row-preview.is-visible { opacity: 1; }
@media (hover: hover) and (min-width: 981px) {
  .row-preview { display: block; }
}

/* ---------- Theme queue ----------
   Every theme waits in one line that recedes toward a vanishing point in
   the top trailing corner (straight up on compact layouts, every card on
   one centre line): slot s (0 = the front) draws its card at
   k(s) = 1/(1 + s·depth) scale with its centre at V + (F − V)·k(s) — the
   perspective projection of identical cards spaced evenly down a corridor,
   done as flat 2D transforms (site.js writes one translate + scale per
   drawn card per frame) so the stacking order stays ours: the nearer card
   is always on top. The line flows up continuously: a card comes on at the
   front from the viewer's side (large, fading in as it settles into the
   front slot) and drifts up the corridor into the distance, fading out at
   the back. Wide layouts seat the queue in the trailing column beside the
   heading; compact layouts stack it above the heading. Hover eases the
   line to a halt, pops the card over its neighbours and plays its loop; a
   click — or 3 s of hovering — lifts the card to the centre (FLIP), blurs
   the rest and opens its story. */
.themes-page { position: relative; justify-content: center; padding: 0; }
.theme-queue-stage {
  position: relative; flex: 1;
  min-height: 100svh;
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); align-items: center;
  column-gap: clamp(16px, 3vw, 48px);
  padding: 0 max(clamp(24px, 4vw, 64px), calc((100% - var(--max-w-wide)) / 2 + 24px));
  overflow: hidden;
}
.theme-queue { position: relative; grid-column: 2; grid-row: 1; height: 100svh; min-width: 0; }
.theme-card {
  position: absolute; left: 0; top: 0;
  width: var(--card-w, 300px); height: calc(var(--card-w, 300px) * 0.45);
  margin: 0; padding: 0; border: 0; background: none;
  color: inherit; font: inherit;
  cursor: pointer;
  transform-origin: 50% 50%;
  visibility: hidden;   /* site.js switches on the cards in the drawn slots; the rest wait off-stage, out of the tab order */
  /* The shadow lives here, not on the clipped face: a filter runs before
     clip-path, so a shadow on the face itself would be cut off with it. */
  filter: drop-shadow(0 18px 44px rgba(0, 0, 0, 0.62));
  transition: filter 0.45s var(--ease), opacity 0.35s var(--ease);   /* eases the hover brightening; the per-frame depth writes change too little per frame to notice the lag */
  will-change: transform, opacity;
  -webkit-tap-highlight-color: transparent;
}
.theme-card.is-on { visibility: visible; }
.theme-card.is-hover { filter: drop-shadow(0 28px 70px rgba(0, 0, 0, 0.75)); }
.theme-card:focus-visible { outline: 2px solid var(--blue); outline-offset: 5px; border-radius: 16px; }
/* Continuous (iOS-style) 12px corners: site.js clips the face to a squircle
   path in the card's own layout pixels (the transform scales it with the
   card) and strokes the same path for the hairline rim — a plain
   border-radius can't ease its curvature into the straight edges, and CSS
   corner-shape is missing from WebKit. */
.theme-card .face {
  position: absolute; inset: 0;
  overflow: hidden;
  background: var(--surface);
  transform-origin: 50% 50%;
  transition: transform 0.45s var(--ease), opacity 0.45s var(--ease), filter 0.45s var(--ease);
}
.theme-card.is-hover .face { transform: scale(var(--pop, 1.25)); }   /* --pop grows with depth so a far card pops as big as a near one */
.rim { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.rim path { fill: none; stroke: rgba(255, 255, 255, 0.16); stroke-width: 2px; }   /* the outer half is clipped away: a 1px inner rim */
.theme-card img, .theme-card video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  display: block; object-fit: cover;
}
.theme-card video { opacity: 0; transition: opacity 0.45s var(--ease); }
.theme-card.is-playing video { opacity: 1; }
.theme-card.is-lifted { pointer-events: none; }
.theme-card.is-lifted .face { opacity: 0; }
.theme-queue-stage.is-focused .theme-card { pointer-events: none; }
.theme-queue-stage.is-focused .theme-card:not(.is-lifted) .face { filter: blur(6px); opacity: 0.5; }
.theme-queue-stage .themes-head {
  position: relative; grid-column: 1; grid-row: 1;
  z-index: 1000;   /* above every card (cards stack by depth, up to 999) */
  width: 100%; max-width: 560px;
  margin: 0; padding: 0;
  text-align: left;
  pointer-events: none;   /* a card sliding out under it stays hoverable */
  transition: filter 0.5s var(--ease), opacity 0.5s var(--ease);
}
.themes-head .lead { margin: 0; }
.theme-queue-stage.is-focused .themes-head { filter: blur(8px); opacity: 0.3; }
.theme-queue-hint {
  margin: 1.6rem 0 0; font-size: 0.78rem; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-faint); white-space: nowrap;
  transition: opacity 0.4s ease;
}
.theme-queue-stage.is-focused .theme-queue-hint, .theme-queue-stage.is-hovering .theme-queue-hint { opacity: 0; }
.hint-compact { display: none; }
@media (hover: none), (max-width: 980px) { .hint-wide { display: none; } .hint-compact { display: inline; } }

/* Focus layer: the lifted card at the centre, its story bare beneath it,
   both 15% wider than a card in the queue (--card-w, set on the stage by
   site.js) — a modest lift that keeps the 600px export from stretching
   soft. */
.theme-focus {
  position: absolute; inset: 0; z-index: 1002;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 40px; padding: 24px;
  pointer-events: none;
}
.theme-focus[hidden] { display: none; }
.theme-focus-card {
  position: relative; flex: none;
  width: calc(var(--card-w, 300px) * 1.15); aspect-ratio: 300 / 135;
  filter: drop-shadow(0 40px 90px rgba(0, 0, 0, 0.65));
  transform-origin: 50% 50%;
  transition: transform 0.65s var(--ease), opacity 0.4s var(--ease);
  pointer-events: auto;
}
.theme-focus-card .face { position: absolute; inset: 0; overflow: hidden; background: var(--surface); }   /* squircle clip from site.js */
.theme-focus-card img, .theme-focus-card video { position: absolute; inset: 0; width: 100%; height: 100%; display: block; object-fit: cover; }
.theme-focus-card video { opacity: 0; transition: opacity 0.45s var(--ease); }
.theme-focus-card.is-playing video { opacity: 1; }
.theme-focus.is-leaving .theme-focus-card { transition-duration: 0.5s; }
.theme-info {
  position: relative; flex: none;
  width: calc(var(--card-w, 300px) * 1.15);   /* a caption as wide as the lifted card, sharing its left edge */
  padding: 0 3rem 0 0;
  text-align: left;
  opacity: 0; transform: translate3d(0, 14px, 0);
  transition: opacity 0.45s var(--ease) 0.25s, transform 0.45s var(--ease) 0.25s;
  pointer-events: none;
}
.theme-focus.is-open .theme-info { opacity: 1; transform: none; pointer-events: auto; }
.theme-focus.is-leaving .theme-info { opacity: 0; transform: translate3d(0, 14px, 0); transition-delay: 0s; pointer-events: none; }
.theme-info-title { margin: 0 0 0.3rem; font-size: 1.5rem; font-weight: 700; letter-spacing: -0.015em; }
.theme-info-author { margin: 0 0 0.9rem; font-size: 0.9rem; color: var(--ink-dim); }
.theme-info-author a { color: var(--blue); text-decoration: none; }
.theme-info-author a:hover { text-decoration: underline; }
.theme-info-author:empty { display: none; }
.theme-info-desc { margin: 0; font-size: 1rem; line-height: 1.55; color: var(--ink-dim); white-space: pre-line; }
.theme-info-close {
  position: absolute; top: -2px; right: 0;
  width: 32px; height: 32px; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.14); background: rgba(255, 255, 255, 0.08);
  color: var(--ink); font-family: inherit; font-size: 20px; font-weight: 400; line-height: 1; cursor: pointer;
  display: grid; place-items: center;
  transition: background 0.25s ease;
}
.theme-info-close:hover { background: rgba(255, 255, 255, 0.16); }
/* ---------- Live Sharing hero ----------
   The Participants screen's intro, on the web. The event card flies in
   from above on a spring (1.5 s, damping 0.75, after 0.35 s), settles at 3°
   and floats — an 8 s ±3° sway and a 3 s 5px bob, both ease-in-out. Five
   emoji ride a 54px orbit whose centre sits 32px above the card's bottom
   edge: the orbit scale-spins in with one extra turn over 2 s, then turns
   once per 25 s; each emoji counter-rotates to stay upright and wobbles
   on a 2–3px orbit of its own; every 2 s one pops into another face
   (site.js). Every number is the app's (ParticipantsViewController /
   OnboardingSharingHeroView). The card is glass the way the web can do it
   (no liquid glass): a translucent fill with a backdrop blur, a highlight
   rim, and a soft shade. Its text block is EventDetailCardCell's: 20pt
   side insets, 32pt above and below, 8pt between the title2 title and
   the footnoteBold date.
   Nested wrappers carry the independent transforms (entry / bob / sway on
   the card; entry / steady spin / per-emoji counter-spin / wobble on the
   orbit) since one element can't run two transform animations. */
.share-hero {
  position: relative; width: 100%; max-width: 520px; margin: 0 auto;
  /* Sized by the card, with room below for the orbit's lower half, an
     emoji's wobble and the shade. The clip is for the top edge, where the
     card parks before it flies in — the way the app parks it above the
     screen — so the stage must never be shorter than what hangs below. */
  padding: 24px 0 96px;
  overflow: clip;
  --share-card-w: min(360px, 100% - 80px);
}
.share-stack { position: relative; width: var(--share-card-w); margin: 0 auto; }
.share-card-entry { transform: translateY(calc(-100% - 80px)) scale(0.75); }   /* parked above the stage */
.share-hero.is-live .share-card-entry { animation: share-card-in 1.5s cubic-bezier(0.3, 1.1, 0.5, 1) 0.35s both; }
.share-hero.is-live .share-card-sway {
  animation: share-rotate-in 1.5s cubic-bezier(0.3, 1.1, 0.5, 1) 0.35s both,
             share-sway 8s ease-in-out 1.85s infinite alternate;   /* takes over from the 3° the entry lands on */
}
.share-hero.is-live .share-card-bob { animation: share-bob 3s ease-in-out 1.85s infinite alternate; }
@supports (animation-timing-function: linear(0, 1)) {
  .share-hero.is-live .share-card-entry { animation-timing-function: linear(0, 0.0252, 0.0865, 0.1707, 0.2673, 0.3684, 0.4682, 0.5626, 0.6489, 0.7257, 0.7923, 0.8487, 0.8954, 0.9331, 0.9628, 0.9855, 1.0022, 1.0139, 1.0216, 1.0261, 1.0281, 1.0283, 1.0271, 1.0251, 1.0225, 1.0197, 1.0169, 1.0141, 1.0115, 1.0091, 1.007, 1.0053, 1.0038, 1.0025, 1.0016, 1.0008, 1.0002, 0.9998, 0.9995, 0.9993, 1); }
  .share-hero.is-live .share-card-sway { animation-timing-function: linear(0, 0.0252, 0.0865, 0.1707, 0.2673, 0.3684, 0.4682, 0.5626, 0.6489, 0.7257, 0.7923, 0.8487, 0.8954, 0.9331, 0.9628, 0.9855, 1.0022, 1.0139, 1.0216, 1.0261, 1.0281, 1.0283, 1.0271, 1.0251, 1.0225, 1.0197, 1.0169, 1.0141, 1.0115, 1.0091, 1.007, 1.0053, 1.0038, 1.0025, 1.0016, 1.0008, 1.0002, 0.9998, 0.9995, 0.9993, 1), ease-in-out; }
}
.share-hero.is-still .share-card-entry { transform: none; }
.share-hero.is-still .share-card-sway { transform: rotate(3deg); }
@keyframes share-card-in { from { transform: translateY(calc(-100% - 80px)) scale(0.75); } to { transform: none; } }
@keyframes share-rotate-in { from { transform: rotate(0deg); } to { transform: rotate(3deg); } }
@keyframes share-sway { from { transform: rotate(3deg); } to { transform: rotate(-3deg); } }
@keyframes share-bob { from { transform: translateY(0); } to { transform: translateY(5px); } }
.share-card-body { position: relative; }
/* The shade is a sibling, not an ancestor: a filter on an ancestor would
   make it a backdrop root and blind the card's backdrop blur. Its pseudo
   takes the card's own squircle (--card-clip, from site.js) and the blur
   runs on the shade itself, so the clipped shape is what gets blurred. */
.share-card-shade { position: absolute; inset: 0; transform: translateY(26px) scale(0.98); filter: blur(28px); opacity: 0.55; pointer-events: none; }
.share-card-shade::before { content: ""; position: absolute; inset: 0; background: #000; clip-path: var(--card-clip); }
.share-card {
  position: relative;
  padding: 10px 10px 0;
  background: rgba(255, 255, 255, 0.92);
  -webkit-backdrop-filter: blur(24px) saturate(1.4); backdrop-filter: blur(24px) saturate(1.4);
  color: #111;
  clip-path: var(--card-clip);   /* 18px continuous corners, the detail card's */
}
.share-card .rim path { stroke: rgba(255, 255, 255, 0.95); }
.share-cover { display: block; width: 100%; aspect-ratio: 3 / 2; object-fit: cover; border-radius: 8px; background: #d9d4cc; }
.share-card-text { padding: 32px 10px 32px; }   /* + the card's 10px = the cell's 20pt side insets; 32pt above and below */
.share-card-title { margin: 0; font-size: 22px; line-height: 29px; font-weight: 700; letter-spacing: -0.01em; color: #111; }
.share-card-date { margin: 8px 0 0; font-size: 13px; line-height: 17px; font-weight: 700; color: rgba(60, 60, 67, 0.6); }   /* the date label's .footnoteBold in secondaryLabel */
.share-orbit { position: absolute; left: 50%; bottom: 32px; width: 140px; height: 140px; translate: -50% 50%; pointer-events: none; }
.orbit-entry, .orbit-steady { position: absolute; inset: 0; }
.orbit-entry { transform: scale(0); }
.share-hero.is-live .orbit-entry { animation: orbit-burst 2s cubic-bezier(0.25, 0.8, 0.25, 1) both; }
.share-hero.is-still .orbit-entry { transform: none; }
.share-hero.is-live .orbit-steady { animation: orbit-spin 25s linear infinite; }
.orbit-slot, .orbit-upright, .orbit-counter-burst, .orbit-counter, .orbit-wobble { position: absolute; left: 0; top: 0; width: 0; height: 0; }
.orbit-slot { left: 50%; top: 50%; transform: rotate(var(--a)) translateX(54px); }
.orbit-upright { transform: rotate(calc(-1 * var(--a))); }
.share-hero.is-live .orbit-counter-burst { animation: orbit-counter-burst 2s cubic-bezier(0.25, 0.8, 0.25, 1) both; }
.share-hero.is-live .orbit-counter { animation: orbit-spin-back 25s linear infinite; }
.share-hero.is-live .orbit-wobble { animation: orbit-wobble var(--d) linear infinite var(--dir, normal); }
.orbit-emoji {
  position: absolute; left: -20px; top: -20px; width: 40px; height: 40px;
  max-width: none;   /* the reset's max-width: 100% would clamp it to its 0×0 wrapper */
  filter: drop-shadow(0 6px 12px rgba(0, 0, 0, 0.17));
}
@keyframes orbit-burst { from { transform: scale(0) rotate(0deg); } to { transform: scale(1) rotate(360deg); } }
@keyframes orbit-spin { to { transform: rotate(360deg); } }
@keyframes orbit-counter-burst { from { transform: rotate(0deg); } to { transform: rotate(-360deg); } }
@keyframes orbit-spin-back { to { transform: rotate(-360deg); } }
@keyframes orbit-wobble {
  from { transform: rotate(0deg) translateX(var(--r)) rotate(0deg); }
  to { transform: rotate(360deg) translateX(var(--r)) rotate(-360deg); }
}

/* ---------- Event-type card stack (narrow / touch fallback) ---------- */
.card-stack { display: grid; gap: 18px; max-width: 430px; margin: 0 auto clamp(3rem, 7vh, 5rem); }
.card-stack img {
  border-radius: 20px;
  outline: 1px solid var(--hairline);
  box-shadow: var(--shadow-card);
}
@media (hover: hover) and (min-width: 981px) {
  .card-stack { display: none; }   /* the hover preview shows these instead */
}

/* ---------- Screen-region card (home-screen crop) ---------- */

/* ---------- Device carousel ---------- */
.carousel { max-width: 900px; margin: 0 auto; }
.carousel-track {
  position: relative;
  display: grid;
  align-items: center;
  min-height: min(clamp(320px, 46vw, 560px), 50svh);
}
.carousel-slide {
  grid-area: 1 / 1;
  opacity: 0;
  transform: translateY(14px) scale(0.97);
  transition: opacity 0.6s var(--ease), transform 0.8s var(--ease);
  pointer-events: none;
  display: flex; justify-content: center;
}
.carousel-slide.is-active { opacity: 1; transform: none; pointer-events: auto; }
/* Widths capped in svh too, so the whole scene stays inside one viewport */
.carousel-slide .mac-frame { max-width: min(860px, 70svh); }
.carousel-slide .ipad-frame { max-width: min(420px, 38svh); }
.carousel-slide .iphone-frame { max-width: min(260px, 24svh); }
.carousel-slide .watch-frame { max-width: min(210px, 42svh); }
.carousel-controls {
  display: flex; align-items: center; justify-content: center;
  gap: 1.2rem; margin-top: 1.6rem;
}
.carousel-btn {
  width: 40px; height: 40px;
  border-radius: 999px;
  border: 1px solid var(--hairline-strong);
  background: var(--glass-fill);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: var(--ink);
  font-size: 1.3rem; line-height: 1;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.35s var(--ease-out-expo);
}
.carousel-btn:hover { background: var(--glass-fill-strong); transform: translateY(-1px); }
.carousel-btn:active { transform: scale(0.94); }
.carousel-dots { display: flex; gap: 9px; }
.carousel-dots button {
  width: 8px; height: 8px;
  border-radius: 999px;
  border: none;
  background: rgba(255, 255, 255, 0.22);
  cursor: pointer;
  transition: background 0.3s ease, transform 0.4s var(--ease-out-expo), width 0.4s var(--ease-out-expo);
}
.carousel-dots button.is-active { background: var(--blue); width: 22px; }
.carousel-label { text-align: center; margin-top: 0.9rem; overflow: hidden; height: 1.4em; }
.carousel-label span { display: inline-block; transition: transform 0.5s var(--ease), opacity 0.4s ease; }
.carousel-label.is-swapping span { transform: translateY(110%); opacity: 0; transition: none; }

/* ---------- Smart Create ---------- */
/* ---------- Smart Create scene ----------
   Edge to edge: the conic AI gradient, blurred wide and slowly turning,
   fills the whole section behind a centred split (copy | phone). The two
   ways to create an event are tabs; the phone's screenshot crossfades to
   match the active one (site.js). */
.ai-section { position: relative; overflow: hidden; }
.ai-bg {
  position: absolute; inset: -25%;
  background: var(--ai-gradient);
  filter: blur(140px) saturate(1.1);
  opacity: 0.26;
  pointer-events: none;
  animation: ai-glow 18s ease-in-out infinite alternate;
}
@keyframes ai-glow { from { transform: rotate(0deg) scale(1); } to { transform: rotate(60deg) scale(1.15); } }
.ai-inner {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: 1.1fr 0.9fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
  width: 100%; max-width: var(--max-w);
  margin: 0 auto; padding: 0 24px;
}
.ai-copy { position: relative; }
.ai-copy h2 { margin: 0.55rem 0 1rem; }
.ai-eyebrow {
  background: var(--ai-gradient);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
.ai-copy em { color: var(--ink); font-style: normal; font-weight: 700; }
.typed-wrap { white-space: nowrap; }
.caret {
  display: inline-block; width: 2px; height: 1em; margin-left: 1px;
  background: var(--blue); vertical-align: -0.12em; border-radius: 1px;
  opacity: 0;
}
.is-typing .caret { opacity: 1; animation: blink 1s step-end infinite; }
@keyframes blink { 50% { opacity: 0; } }
/* The two ways, as tabs: the active one sits on a faint panel. */
.ai-ways { margin-top: 1.8rem; display: grid; gap: 0.4rem; }
.ai-way button {
  display: block; width: 100%;
  padding: 0.85rem 1rem 0.95rem 1.1rem;
  border: 0; border-radius: 16px;
  background: none; text-align: left; cursor: pointer;
  position: relative;
  transition: background 0.35s var(--ease);
}
.ai-way.is-active button { background: rgba(255, 255, 255, 0.05); }
.ai-way button:hover { background: rgba(255, 255, 255, 0.07); }
.ai-way button:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.ai-way h3 { font-size: 1.12rem; font-weight: 700; letter-spacing: -0.01em; margin: 0 0 0.3rem; color: var(--ink-dim); transition: color 0.35s var(--ease); }
.ai-way p { margin: 0; color: var(--ink-faint); line-height: 1.5; text-wrap: pretty; transition: color 0.35s var(--ease); }
.ai-way.is-active h3 { color: var(--ink); }
.ai-way.is-active p { color: var(--ink-dim); }
.ai-way.is-active em { color: var(--ink); }
.ai-privacy { margin-top: 1.6rem; color: var(--ink-faint); font-size: 0.95rem; }
.ai-privacy .chip-ai { display: inline-block; margin: 0; }   /* the badge on its own line, the text under it, one left edge */
.ai-privacy-text { display: block; margin-top: 0.6rem; }
.ai-privacy small { display: block; margin-top: 0.5rem; font-size: 0.8rem; color: var(--ink-faint); }
.ai-media { position: relative; z-index: 1; max-width: min(380px, 36svh); }   /* keeps the scene inside one viewport */
.ai-media .ai-shot { opacity: 0; transition: opacity 0.7s var(--ease); }   /* both shots share the screen slot; the active one shows */
.ai-media .ai-shot.is-active { opacity: 1; }

/* ---------- Widgets: the pinned bento scene ----------
   Ten real widget captures, cut frame-exact from an iPhone Home Screen on
   a pure-black wallpaper (so a card's edge is invisible on this page), laid
   on the iPhone's own widget grid: column unit / gap and row unit / gap
   are the device's (228 / 74 and 204 / 122 at 3×), scaled by site.js so
   eight rows fill the stage — a small is 2×2 cells, a medium 4×2, a large
   4×4, and every frame sits on the same lines at the same scale. Wide:
   twelve rows fill the stage and the cards pack column by column in DOM
   order, so the wall is as wide as its content needs (it may run past the
   screen); compact: four columns, packed row by row. Scroll lands the
   cards one by one (the moments scene's tile-land pop) while the wall
   glides to keep the newest in view, then raises the copy over the dimmed
   wall. */
.widgets-runway { z-index: 1; height: 320svh; }
.widgets-stage { display: flex; align-items: center; justify-content: center; }
.widgets-stage.is-wider { justify-content: flex-start; padding-left: 24px; }
.widgets-stage.is-taller { align-items: flex-start; padding-top: 24px; }
.widget-wall {
  --rows: 12;
  flex: none;
  display: grid;
  grid-template-rows: repeat(var(--rows), var(--uy, 45px));
  grid-auto-columns: var(--ux, 51px);
  grid-auto-flow: column dense;
  column-gap: var(--gx, 16px); row-gap: var(--gy, 27px);
  will-change: transform, opacity;
  transition: transform 0.8s var(--ease);
}
.wcard {
  margin: 0; position: relative;
  grid-row: span var(--rs); grid-column: span var(--cs);
  background: #000;
  opacity: 0; transform: scale(0.2);   /* waits for its landing cue */
}
.wcard img { display: block; width: 100%; height: 100%; }
.wcard.is-in { animation: tile-land 0.7s cubic-bezier(0.2, 0.7, 0.3, 1) both; }
.widget-wall.is-static .wcard { animation: none; opacity: 1; transform: none; }
.widgets-scrim {
  position: absolute; inset: 0; z-index: 1;
  background: radial-gradient(ellipse 62% 58% at 50% 50%, rgba(0, 0, 0, 0.84), rgba(0, 0, 0, 0.55) 55%, rgba(0, 0, 0, 0.1) 100%);
  opacity: 0; pointer-events: none;
}
.widgets-copy {
  position: absolute; inset: 0; z-index: 2;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 0 24px;
  pointer-events: none;
}
.widgets-copy .eyebrow, .widgets-copy h2, .widgets-copy .lead { opacity: 0; will-change: opacity, transform; }
.widgets-copy h2 { max-width: 760px; margin: 0.55rem 0 1rem; }
.widgets-copy .lead { max-width: 680px; margin: 0 auto; }
@media (max-width: 980px) {
  .widget-wall { grid-template-rows: none; grid-template-columns: repeat(4, var(--ux, 51px)); grid-auto-rows: var(--uy, 45px); grid-auto-flow: row dense; }   /* four across, packed row by row */
}

/* ---------- Plans ---------- */
.plans {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: clamp(1rem, 2.5vw, 1.8rem);
  align-items: stretch;
}
.plan {
  position: relative;
  padding: 1.8rem 1.6rem;
  border-radius: var(--r-panel);
  border: 1px solid var(--hairline);
  background: var(--glass-fill);
  transition: transform 0.6s var(--ease-out-expo), border-color 0.3s ease, background 0.3s ease;
}
.plan:hover { transform: translateY(-4px); border-color: var(--hairline-strong); background: var(--glass-fill-strong); }
.plan h3 { font-size: 1.02rem; color: var(--ink-dim); font-weight: 700; }
.plan-price { font-size: 2rem; font-weight: 700; margin: 0.4rem 0 1.2rem; letter-spacing: -0.02em; }
.plan ul { display: grid; gap: 0.55rem; color: var(--ink-dim); font-size: 0.96rem; }
.plan ul li::before { content: "✓"; color: var(--blue); font-weight: 700; margin-right: 0.6em; }
.plan-featured {
  background: rgba(10, 165, 240, 0.12);
  border-color: rgba(10, 165, 240, 0.5);
  box-shadow: 0 12px 45px rgba(10, 165, 240, 0.14);
}
.plan-featured:hover { background: rgba(10, 165, 240, 0.16); border-color: rgba(10, 165, 240, 0.7); }
.plan-flag {
  position: absolute; top: -12px; left: 50%; translate: -50% 0;
  padding: 0.28em 1em;
  background: var(--blue); color: #fff;
  border-radius: 999px;
  font-size: 0.74rem; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}
.plans-note { margin-top: 1.6rem; color: var(--ink-faint); font-size: 0.9rem; text-align: center; }

/* ---------- Final CTA panel ---------- */
.cta-panel {
  position: relative; overflow: hidden;
  border-radius: var(--r-hero-panel);
  background: var(--bg-elevated);
  border: 1px solid var(--hairline);
  padding: clamp(3.5rem, 8vh, 6rem) 24px clamp(4rem, 9vh, 6.5rem);
  text-align: center;
}
.cta-wave { position: absolute; inset: 0; z-index: 0; }
.cta-wave video {
  width: 100%; height: 100%; object-fit: cover; opacity: 0.55;
  -webkit-mask-image: linear-gradient(to top, black 40%, transparent 100%);
  mask-image: linear-gradient(to top, black 40%, transparent 100%);
}
/* The app icon (the App Store's rendered artwork, corners already
   transparent) rises into place as the panel reveals. */
.cta-logo {
  position: relative; z-index: 1;
  height: 150px; margin-bottom: 2rem;
  display: grid; place-items: center;
}
.cta-logo img {
  width: 144px; height: 144px;
  filter: drop-shadow(0 18px 40px rgba(0, 0, 0, 0.6));
  opacity: 0;
  transform: translateY(40px) scale(0.9);
  transition: transform 1.1s var(--ease) 0.1s, opacity 0.6s ease 0.1s;
}
.reveal.in .cta-logo img { opacity: 1; transform: none; }
.cta-inner { position: relative; z-index: 2; }
.cta-inner h2 { font-size: clamp(2.4rem, 5.5vw, 4rem); }
.cta-inner .lead { margin: 0.9rem auto 2.2rem; }
.cta-inner .appstore-badge { display: inline-block; }

/* ---------- Footer ---------- */
.footer {
  position: relative; z-index: 3;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  padding: 3rem 24px 3.5rem;
  text-align: center;
  color: var(--ink-faint);
  font-size: 0.92rem;
  display: grid; gap: 0.7rem;
}
.footer .heart { color: var(--red); }
.footer a { color: var(--ink-dim); transition: color 0.25s ease; }
.footer a:hover { color: var(--ink); }
.footer-copy { font-size: 0.8rem; }

/* ---------- Reveal on scroll ---------- */
.reveal {
  opacity: 0; transform: translateY(20px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.reveal.in { opacity: 1; transform: none; }
.reveal-panel { transform: translateY(40px) scale(0.94); transition-duration: 1s; }
.reveal-panel.in { transform: none; }

/* Children of [data-stagger] get --i from JS and enter one after another */
[data-stagger] > :not(.row-preview) {
  opacity: 0; transform: translateY(16px);
  transition: opacity 0.6s var(--ease), transform 0.7s var(--ease);
  transition-delay: calc(var(--i, 0) * 70ms + 0.1s);
}
.reveal.in [data-stagger] > :not(.row-preview), .reveal.in[data-stagger] > :not(.row-preview) { opacity: 1; transform: none; }

/* Masked word reveal for headings (JS splits into .w > .wi) */
.mask-words .w { display: inline-block; overflow: hidden; padding-bottom: 0.13em; margin-bottom: -0.13em; vertical-align: bottom; }
.mask-words .wi {
  display: inline-block;
  transform: translateY(112%);
  transition: transform 0.9s var(--ease);
  transition-delay: calc(var(--i, 0) * 45ms);
}
.reveal.in .mask-words .wi, .reveal.in.mask-words .wi { transform: none; }

/* ---------- Responsive ---------- */
@media (max-width: 980px) {
  .scene-inner { grid-template-columns: 1fr; text-align: center; }
  .hero-copy { padding-top: var(--nav-h); padding-bottom: 8svh; }
  .hero-copy h1 { font-size: clamp(2.2rem, 7.4vw, 3.6rem); }
  .hero-sub { margin-left: auto; margin-right: auto; }
  .hero-sub br { display: none; }
  .hero-ctas { justify-content: center; }
  .iphone-frame.stage-phone { height: min(54svh, 560px); transform: translate(-50%, 112%); }
  .tour { left: 24px; right: 24px; width: auto; top: auto; bottom: 6svh; transform: none; text-align: center; }
  .tour-step p:last-child { margin: 0 auto; }
  .tour-progress { justify-content: center; }
  .split, .split-flip, .ai-inner { grid-template-columns: 1fr; }
  .ai-media { max-width: min(320px, 40svh); margin: 0 auto; }
  .ai-ways { text-align: left; }
  .split-flip .split-media { order: 1; }
  .split-flip .split-copy { order: 2; }
  .float-titles li { max-width: 64vw; font-size: 1.05rem; left: var(--xm, var(--x)); top: var(--ym, var(--y)); }   /* compact spots: one per band, no collisions */
  .float-titles li.wide-only { display: none; }   /* ten titles fit a phone; sixteen would stack */
  .theme-queue-stage {   /* compact: the queue on top, the heading beneath it */
    grid-template-columns: 1fr; grid-template-rows: auto auto; align-content: center;
    row-gap: clamp(0.6rem, 2.5svh, 1.6rem); padding: 0 20px;
  }
  .theme-queue { grid-column: 1; grid-row: 1; height: 54svh; }
  .theme-queue-stage .themes-head { grid-column: 1; grid-row: 2; max-width: 520px; margin: 0 auto; text-align: center; }
  .themes-head .lead { margin: 0 auto; }
  .themes-head h2 { font-size: 1.6rem; }
  .themes-head .lead { font-size: 0.92rem; line-height: 1.45; }
  .themes-head .theme-queue-hint { font-size: 0.68rem; white-space: normal; margin-top: 1rem; }
  .float-titles li.from-right { left: auto; right: var(--xm, var(--x)); }
  .track-hero { grid-template-columns: 1fr; align-content: center; gap: 1.3rem; text-align: center; }
  .track-copy { max-width: 560px; margin: 0 auto; }
  .track-copy h2 { font-size: clamp(1.9rem, 8vw, 2.6rem); }
  .iphone-frame.track-phone { justify-self: center; max-width: min(230px, 24svh); }   /* ≈ 52svh tall, leaves room for the copy above it */
  .split-media .iphone-frame { max-width: min(320px, 40svh); }
  .section-head { text-align: center; margin-left: auto; margin-right: auto; }
  .section-head .lead { margin-left: auto; margin-right: auto; }
  .split-copy { text-align: center; }
  .feature-list { text-align: left; max-width: 470px; margin: 0 auto; }
  .row { grid-template-columns: 2.6rem 1fr; align-items: start; }
  .row-body { max-width: none; }
  .row .row-num { padding-top: 0.45rem; }
  .row-arrow { display: none; }
  .plans { grid-template-columns: 1fr; max-width: 430px; margin: 0 auto; }
  .plan-featured { order: -1; }
  .carousel-track { min-height: clamp(300px, 78vw, 560px); }
  .carousel-slide .ipad-frame { max-width: 340px; }
  .cta-logo { height: 120px; }
  .cta-logo img { width: 112px; height: 112px; }
}
@media (max-width: 560px) {
  body { font-size: 16px; }
  .card-stack { max-width: 340px; }
}
@media (max-height: 640px) and (min-width: 981px) {
  .iphone-frame.stage-phone { height: 60svh; }
}

/* ---------- Reduced motion: unpin the scene, drop autonomous motion ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; }
  .reveal, .reveal .wi, .mask-line > span, .hero-sub, .hero-ctas, [data-stagger] > * { opacity: 1; transform: none; }
  .scene-runway { height: auto; margin-bottom: 0; }
  .scene { position: static; height: auto; overflow: visible; }
  .scene-inner { height: auto; padding-bottom: 3rem; }
  .hero-copy { padding-top: calc(var(--nav-h) + 8vh); padding-bottom: 2rem; }
  .stage-hint { display: none; }
  .iphone-frame.stage-phone { position: relative; left: auto; bottom: auto; transform: none; margin: 1rem auto 0; height: auto; width: min(320px, 80vw); aspect-ratio: auto; grid-column: 1 / -1; }
  .tour { position: relative; left: auto; top: auto; transform: none; opacity: 1; width: auto; grid-column: 1 / -1; margin-top: 2.5rem; text-align: center; }
  .tour-steps { display: grid; gap: 2rem; }
  .tour-step { grid-area: auto; opacity: 1; transform: none; }
  .tour-progress { display: none; }
  .scene-statement { position: relative; inset: auto; opacity: 1; transform: none; grid-column: 1 / -1; padding: 3rem 0 1rem; }
  .moments-stage { position: relative; height: 100svh; overflow: hidden; }
  .track-stage { position: relative; height: 100svh; overflow: hidden; }
  .float-titles li { opacity: calc(var(--o, 0.8) * 0.35); transform: none; }
  .track-copy, .iphone-frame.track-phone { opacity: 1; transform: none; }
  .moments-scrim { opacity: 1; }
  .moments-copy h2, .moments-copy .lead { opacity: 1; }
  .widgets-stage { position: relative; height: 100svh; overflow: hidden; }
  .widgets-scrim { opacity: 1; }
  .widgets-copy .eyebrow, .widgets-copy h2, .widgets-copy .lead { opacity: 1; }
  .statement-text .w { opacity: 1; }
  .cta-logo img { opacity: 1; transform: none; }
  .nav-cta { opacity: 1; transform: none; pointer-events: auto; }
}
