/* Stanza Lift. Rows of type on hairlines, numbered in mono, and little else: the app's near-black,
   white Outfit, planned numbers in signal orange, the glass rim's colours once.

   The page moves only as you scroll, in CSS (animation-timeline). Everything under MOTION is an
   enhancement: without it (older browsers, reduced motion) each section is laid out at rest. */

@font-face { font-family: Outfit; src: url(/fonts/outfit.woff2) format("woff2"); font-weight: 100 900; font-display: swap; }
@font-face { font-family: "Geist Mono"; src: url(/fonts/geist-mono.woff2) format("woff2"); font-weight: 100 900; font-display: swap; }

:root {
  --bg: #0b0b0b;
  --line: #232323;
  --text: #f2f2f2;
  --text2: #c9c9c9;
  --muted: #7d7d7d;
  --faint: #4a4a4a;
  --cool: #8db4ff;
  --warm: #ffc08a;
  --signal: #f0893c;
  --rim: linear-gradient(100deg, #f2f3ff, var(--cool) 50%, var(--warm));
  --mono: "Geist Mono", ui-monospace, monospace;
  --gutter: 20px;
  --max: 1320px;
  --idx: 40px;
  color-scheme: dark;
}
@media (min-width: 720px) { :root { --gutter: 48px; --idx: 64px; } }
/* the hero's phone (--dw) and 01's rows (--fs) are sized together: zoomed by --zoom about its first
   set's row, the phone's rows land on 01's (rows on the phone are .1357 of its width apart; 01's,
   measured, 1.10 of their type on a wide screen and 1.165 on a phone, whose centre is --rc of the
   type below the row's top). On a wide screen the phone is also kept short enough for 01's four
   rows to end above its caption: they end 142px + 1.84 phone widths down. */
:root { --dw: min(62vw, 300px); --fs: calc(var(--dw) * .175); --zoom: 1.5; --rc: .588; }
@media (min-width: 1000px) { :root { --dw: min(clamp(280px, 24vw, 340px), (100svh - 260px) / 1.84); --fs: calc(var(--dw) * .33); --zoom: 2.675; --rc: .545; } }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: 80px; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body { margin: 0; background: var(--bg); color: var(--text); font: 400 17px/1.5 Outfit, system-ui, sans-serif; -webkit-font-smoothing: antialiased; overflow-x: clip; }
h1, h2, p, ol, ul { margin: 0; }
ol, ul { padding: 0; list-style: none; }
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--cool); outline-offset: 3px; border-radius: 4px; }
::selection { background: rgba(141, 180, 255, .35); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.skip { position: absolute; left: 12px; top: -60px; z-index: 20; padding: 10px 14px; background: var(--text); color: var(--bg); border-radius: 8px; text-decoration: none; }
.skip:focus { top: 12px; }

.idx { font: 400 12px/1 var(--mono); color: var(--muted); letter-spacing: .02em; }
.small { font-size: 14px; color: var(--muted); }
.lede { font-size: clamp(18px, 1.7vw, 22px); line-height: 1.4; color: var(--text2); max-width: 26em; text-wrap: pretty; }
.statement { font-weight: 400; font-size: clamp(34px, 5vw, 68px); line-height: 1; letter-spacing: -.035em; }

/* buttons: one solid, one quiet */
.btn { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; border-radius: 999px; white-space: nowrap; font-size: 16px; transition: background .2s, color .2s, border-color .2s; }
.btn-primary { padding: 14px 22px; background: var(--text); color: var(--bg); font-weight: 500; }
.btn-primary:hover { background: #fff; }
.btn-primary span { transition: transform .2s; }
.btn-primary:hover span { transform: translateX(3px); }
.btn-quiet { padding: 13px 20px; border: 1px solid #333; color: var(--text2); }
.btn-quiet:hover { border-color: var(--muted); color: var(--text); }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.actions .small { flex-basis: 100%; }

/* ---------- the top bar: a name and a link ---------- */
.topbar { position: fixed; inset: 0 0 auto; z-index: 10; display: flex; align-items: center; justify-content: space-between; padding: calc(18px + env(safe-area-inset-top)) var(--gutter) 22px;
  background: linear-gradient(var(--bg) 35%, rgba(11, 11, 11, 0)); }
.brand { display: inline-flex; align-items: center; gap: 9px; text-decoration: none; font-size: 16px; }
.mark { width: 18px; height: 18px; }
.bar-cta { font-size: 15px; text-decoration: none; color: var(--text2); }
.bar-cta:hover { color: var(--text); }


/* ---------- hero: the title on one side of a phone drawn in lines, the way in on the other ---------- */
.hero { position: relative; max-width: var(--max); margin: 0 auto; padding: 100px var(--gutter) 0; overflow: clip; overflow-clip-margin: 0; }
.hero-stage { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 22px; margin-top: 8px; }
.hero-side { display: grid; justify-items: center; gap: 26px; }
.hero h1 { font-weight: 400; font-size: clamp(56px, 16vw, 92px); line-height: .92; letter-spacing: -.055em; }
.ln { display: block; overflow: clip; padding-bottom: .08em; }
.ln > span { display: block; }
.hero .lede { max-width: 21em; font-size: 17px; }
.hero-act { display: grid; justify-items: center; gap: 12px; }
.device { position: relative; width: var(--dw); margin-top: 18px; }
.device > .body { position: relative; }
/* the numbers riding on the phone (site.js puts copies of 01's here, over the blank pills) */
.ride { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.ride > span { position: absolute; white-space: nowrap; }
.device img { position: absolute; left: 3.4%; top: 1.62%; width: 93.2%; height: auto; border-radius: 12.9% / 5.95%; }
/* the screen with its pills blank, over it, once 01's numbers sit in them (site.js) */
.device img.blank { display: none; }
.flight .device img.blank { display: block; }
.device svg { position: relative; display: block; width: 100%; overflow: visible; }
.device .edge { fill: none; stroke: #5a5a5a; stroke-width: 1; vector-effect: non-scaling-stroke; }
.device .inner { stroke: #2c2c2c; }
.device .island { fill: #000; stroke: #333; }
.device .key { fill: #3a3a3a; }
/* the sets' lines, out of the screen to the page's edges */
/* behind the phone, a soft glare of the rim's colours out of its Dynamic Island */
.halo { position: absolute; left: 50%; top: 4.9%; width: 0; height: 0; z-index: -1; pointer-events: none; }
.halo i { position: absolute; left: 0; top: 0; width: var(--w); aspect-ratio: 1.5; border-radius: 50%; translate: -50% -50%; will-change: transform, opacity;
  transform: translate(var(--dx), var(--dy)); opacity: var(--o); }
.h-cool { --w: 44vw; --dx: -15vw; --dy: 22vh; --o: .52; background: radial-gradient(closest-side, rgb(141 180 255 / .8), rgb(141 180 255 / .5) 22%, rgb(141 180 255 / .24) 46%, rgb(141 180 255 / .08) 70%, rgb(141 180 255 / 0) 100%); }
.h-warm { --w: 40vw; --dx: 15vw; --dy: 34vh; --o: .46; background: radial-gradient(closest-side, rgb(255 192 138 / .8), rgb(255 192 138 / .5) 22%, rgb(255 192 138 / .24) 46%, rgb(255 192 138 / .08) 70%, rgb(255 192 138 / 0) 100%); }
.h-white { --w: 22vw; --dx: 0vw; --dy: 8vh; --o: .14; background: radial-gradient(closest-side, rgb(242 243 255 / .8), rgb(242 243 255 / .5) 22%, rgb(242 243 255 / .24) 46%, rgb(242 243 255 / .08) 70%, rgb(242 243 255 / 0) 100%); }

/* wide: the title to the phone's left, the way in to its right */
@media (min-width: 1000px) {
  .hero { --gap: clamp(36px, 4vw, 72px); --side: calc(min(50vw, var(--max) / 2) - var(--dw) / 2 - var(--gap) - var(--gutter)); min-height: 100svh; padding-top: 96px; }
  /* the phone's top stays 142px down (01's zoom is worked out from it: #log --devtop) */
  .hero-stage { display: block; width: var(--dw); margin: 46px auto 0; text-align: left; }
  .hero-stage > :not(.device) { position: absolute; }
  .device { margin: 0; }
  .hero h1 { right: calc(100% + var(--gap)); top: 13%; width: var(--side); font-size: clamp(64px, 6.6vw, 118px); }
  .hero-side { left: calc(100% + var(--gap)); top: 15%; width: var(--side); justify-items: start; }
  .hero .lede { max-width: 15em; font-size: clamp(17px, 1.4vw, 21px); }
  .hero-act { justify-items: start; }
}

/* ---------- scenes ---------- */
.scene { position: relative; }
.pin { max-width: var(--max); margin: 0 auto; padding: 120px var(--gutter); display: flex; flex-direction: column; gap: 40px; }

/* the hero and 01 share a scene: without motion, one after the other */
#log .pin { max-width: none; padding: 0; display: block; }
.log-layer { max-width: var(--max); margin: 0 auto; padding: 120px var(--gutter); display: flex; flex-direction: column; gap: 40px; }
.device { transform-origin: 50% 27.2%; }

/* 01 · the sets, as rows of type */
.sets { display: grid; }
.set { position: relative; display: grid; grid-template-columns: var(--idx) 1fr auto; align-items: baseline; gap: 12px; padding: .1em 0 .14em; border-bottom: 1px solid var(--line); }
.set .w { position: relative; display: flex; gap: .45em; font-size: var(--fs); line-height: 1.06; letter-spacing: -.045em; color: var(--signal); white-space: nowrap; }
.set .w > span, .ink > span { display: inline-block; }
.set .w > .ink { display: inline-flex; gap: .45em; }
.bl { display: inline-block; width: 0; height: 0; }
.set.done .w { color: var(--text); }
.set .meta { position: relative; font: 400 clamp(13px, 1.3vw, 16px)/1 var(--mono); color: var(--muted); text-align: right; min-width: 3em; }
@media (min-width: 720px) { .set .meta { min-width: 5.5em; } }
.tick { opacity: 0; color: var(--text); }
.set.done .tick { opacity: 1; }
.set .timer { position: absolute; right: 0; bottom: 0; opacity: 0; color: var(--text); white-space: nowrap; }
.next .w { --p: 100%; justify-self: start; }
.ink { clip-path: inset(-.1em calc(100% - var(--p)) -.3em 0); }
.caret { position: absolute; top: .16em; bottom: .12em; left: var(--p); width: 2px; margin-left: .06em; background: var(--signal); opacity: 0; }
.by { white-space: nowrap; background: var(--rim); -webkit-background-clip: text; background-clip: text; color: transparent; }
.says { display: grid; gap: 6px; max-width: 34em; }
.says p { font-size: clamp(17px, 1.6vw, 21px); line-height: 1.4; color: var(--text2); text-wrap: pretty; }

/* a finished set's line, lit in the rim's colours (drawn as the set is ticked, then cooling) */
.set::before { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--rim); transform-origin: left; transform: scaleX(0); z-index: 1; }
/* the set Coach planned: its type, its line and a soft wash behind it in the rim's colours */
.next::before { display: none; }
/* Coach's line: a real element, its outer layer peeling into 02's curve, its inner one drawn */
.rimline { position: absolute; left: 0; right: 0; bottom: -2px; height: 3px; z-index: 1; pointer-events: none; }
.rimline i { display: block; height: 100%; background: var(--rim); transform-origin: left; box-shadow: 0 0 18px rgba(255, 192, 138, .45), 0 0 30px rgba(141, 180, 255, .25); }
.next .ink { background: linear-gradient(100deg, #f2f3ff, var(--cool) 45%, var(--warm) 95%); -webkit-background-clip: text; background-clip: text; color: transparent; }
.next .caret { background: var(--warm); box-shadow: 0 0 12px var(--warm); }
@property --wash { syntax: "<number>"; inherits: false; initial-value: 1; }
.set.next { background: linear-gradient(90deg, rgb(141 180 255 / calc(.07 * var(--wash))), rgb(255 192 138 / calc(.1 * var(--wash))) 60%, transparent); }
.by { font-size: 1.05em; }
@media (max-width: 719px) { .by-kg, .by-who { display: none; } }

@property --t { syntax: "<integer>"; inherits: true; initial-value: 87; }
@property --m { syntax: "<integer>"; inherits: true; initial-value: 1; }
@property --s { syntax: "<integer>"; inherits: true; initial-value: 27; }
.timer { --m: round(down, var(--t) / 60, 1); --s: mod(var(--t), 60); counter-reset: m var(--m) s var(--s); }
.timer::after { content: counter(m) ":" counter(s, decimal-leading-zero); }
@media (min-width: 720px) { .timer::after { content: "Rest " counter(m) ":" counter(s, decimal-leading-zero); } }

/* 02 · the curve of twelve weeks, out of Coach's line, and one number rolled along it */
.prog-layer { max-width: var(--max); margin: 0 auto; padding: 120px var(--gutter); display: flex; flex-direction: column; gap: 40px; }
.curve { list-style: none; margin-top: 48px; order: 5; }
/* px per unit of the chart (1200 wide, as wide as the rows); site.js measures it exactly */
#log { --cs: calc((min(100vw, var(--max)) - 2 * var(--gutter)) / 1200); }
.curve svg { display: block; width: 100%; height: auto; overflow: visible; }
.trace { clip-path: inset(-40% calc(100% - var(--rv)) -40% calc(var(--rl) - 2%)); fill: none; stroke: url(#rim-line); stroke-width: 3; stroke-linecap: round; vector-effect: non-scaling-stroke; filter: drop-shadow(0 0 8px rgba(255, 192, 138, .22)); }
.curve .tip { display: none; fill: #fff; stroke: none; filter: drop-shadow(0 0 8px rgba(255, 192, 138, .8)); }
@media (max-width: 719px) { .curve .tip { r: 16px; } }

/* 02 · one number, rolled through twelve weeks */
@property --kg { syntax: "<integer>"; inherits: true; initial-value: 690; }
@property --kga { syntax: "<integer>"; inherits: true; initial-value: 69; }
@property --kgb { syntax: "<integer>"; inherits: true; initial-value: 0; }
.gauge { display: grid; gap: 12px; }
.big { display: flex; align-items: baseline; gap: .1em; font-size: clamp(72px, 13vw, 190px); line-height: .82; letter-spacing: -.06em; margin-left: -.05em; font-variant-numeric: tabular-nums; }
.num { --kga: round(down, var(--kg) / 10, 1); --kgb: mod(var(--kg), 10); counter-reset: a var(--kga) b var(--kgb); }
.num::before { content: counter(a) "." counter(b); }
.unit { font-size: .16em; letter-spacing: 0; color: var(--muted); }
.prog-layer .statement { margin-top: 36px; }

/* 03 · the app on an iPhone in 3D: a front (the glass, with the pages), a back, and twelve slices of
   its outline between them for the titanium edge */
.app-layer { max-width: var(--max); margin: 0 auto; padding: 120px var(--gutter); display: grid; gap: 40px; }
.app-layer { --pw: min(60vw, 300px); --d: calc(var(--pw) * .11); --r: calc(var(--pw) * .17); }
.names li { display: grid; grid-template-columns: var(--idx) 1fr; align-items: baseline; gap: 12px; font-size: clamp(40px, 6.6vw, 92px); line-height: 1.08; letter-spacing: -.045em; border-bottom: 1px solid var(--line); }
.iphone-stage { position: relative; width: var(--pw); height: calc(var(--pw) * 2.06); margin: 0 auto; perspective: 1600px; }
.iphone-stage::after { content: ""; position: absolute; left: 10%; right: 10%; bottom: -9%; height: 8%; border-radius: 50%; background: radial-gradient(closest-side, rgba(0, 0, 0, .9), transparent); filter: blur(10px); z-index: -1; }
.iphone { position: absolute; inset: 0; transform-style: preserve-3d; transform: rotateY(-14deg) rotateX(6deg); }
.iphone .front, .iphone .back, .edge i { position: absolute; inset: 0; border-radius: var(--r); }
.iphone .front { transform: translateZ(calc(var(--d) / 2)); backface-visibility: hidden; padding: 3.2%; background: #050505;
  box-shadow: inset 0 0 0 1.5px #2c2d30, inset 0 0 0 3px #050505, inset 0 0 0 3.6px rgba(255, 255, 255, .06); }
.glass { position: relative; width: 100%; height: 100%; border-radius: calc(var(--r) * .82); overflow: hidden; isolation: isolate; }
.pages { position: absolute; inset: 0; background: var(--bg); }
.page { position: absolute; inset: 0; z-index: var(--z); transform-origin: 50% 50%; }
.page img { width: 100%; height: 100%; object-fit: cover; }
.page + .page { display: none; }
.dyn { position: absolute; z-index: 12; top: 2.1%; left: 50%; width: 31%; height: 4.2%; translate: -50% 0; border-radius: 99px; background: #000; }
.sheen { position: absolute; inset: 0; z-index: 11; pointer-events: none; background: linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, .07) 47%, transparent 60%); background-size: 260% 100%; background-position: 60% 0; }
.edge i { transform: translateZ(calc(var(--d) / 2 - var(--k) * var(--d) / 11 - 1px));
  background: linear-gradient(90deg, #2e2f33, #8e9096 14%, #4a4c51 32%, #5d5f64 50%, #9fa1a6 78%, #2e2f33); }
.iphone .back { transform: rotateY(180deg) translateZ(calc(var(--d) / 2)); backface-visibility: hidden; background: linear-gradient(160deg, #2c2d31, #17181b 60%); box-shadow: inset 0 0 0 1.5px #3a3b3f; }
.plateau { position: absolute; top: 3%; left: 5%; width: 46%; aspect-ratio: 1; border-radius: 24%; background: #222327; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .06); }
.plateau b { position: absolute; width: 36%; aspect-ratio: 1; border-radius: 50%; background: radial-gradient(circle at 40% 40%, #2a3550, #050608 60%); box-shadow: 0 0 0 3px #111; }
.plateau b:nth-child(1) { top: 9%; left: 9%; } .plateau b:nth-child(2) { bottom: 9%; left: 9%; } .plateau b:nth-child(3) { top: 32%; right: 9%; }

/* 04 · the promises, read word by word */
.words { font-weight: 300; font-size: clamp(32px, 5.6vw, 84px); line-height: 1.1; letter-spacing: -.035em; max-width: 19em; margin: 0 auto; text-align: center; text-wrap: balance; }
#why .pin { justify-content: center; }
/* each word its part of the rim (white to blue, blue to peach), so each can light on its own */
.rim-words > span { font-weight: 400; -webkit-background-clip: text; background-clip: text; color: transparent; }
.rim-words > span:first-child { background-image: linear-gradient(100deg, #f2f3ff, var(--cool)); }
.rim-words > span:last-child { background-image: linear-gradient(100deg, var(--cool), var(--warm)); }

/* 05 · the beta */
.block { max-width: var(--max); margin: 0 auto; padding: 120px var(--gutter); display: flex; flex-direction: column; gap: 40px; }
/* the beta, quietly, down the middle of the page: an intro, then a single line through its steps (their
   names to either side, in turn) to the year of Pro, and on to the way in */
.join { display: grid; justify-items: center; text-align: center; padding-top: 140px; padding-bottom: 140px; }
.join-title { font-weight: 400; font-size: clamp(44px, 6.4vw, 92px); line-height: .98; letter-spacing: -.045em; }
.beta-status { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 22px; font: 400 12px/1 var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.beta-status i { width: 7px; height: 7px; border-radius: 50%; background: var(--faint); }
.is-beta .beta-status i { background: #7ad8a0; box-shadow: 0 0 10px #7ad8a0; }
.beta-h { font-weight: 300; font-size: clamp(30px, 3.2vw, 46px); line-height: 1; letter-spacing: -.035em; }
.beta-lede { margin: 14px auto 0; max-width: 22em; color: var(--muted); }
/* the path: a hairline down the middle, filling as you pass */
.beta-path { --gt: clamp(22px, 2.4vw, 32px); position: relative; width: min(100%, 760px); display: grid; gap: 44px; margin-top: 56px; padding-top: 44px; }
/* it ends on the year of Pro's point, its words clear below */
.beta-path::before, .beta-path::after { content: ""; position: absolute; left: 50%; top: 0; bottom: calc(var(--gt) * 1.2 + 14px + 16px); width: 1px; margin-left: -.5px; background: #2a2a2a; }
.beta-path::after { background: var(--text2); transform-origin: top; }
.beta-path li { position: relative; display: grid; grid-template-columns: 1fr 32px 1fr; align-items: center; column-gap: clamp(16px, 3vw, 32px);
  font-size: clamp(17px, 1.7vw, 23px); letter-spacing: -.015em; line-height: 1.2; color: var(--text); }
.beta-path .node { grid-column: 2; grid-row: 1; position: relative; z-index: 1; width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; background: var(--bg); box-shadow: inset 0 0 0 1.5px #3c3c3c; }
.beta-path .t { grid-row: 1; grid-column: 3; text-align: left; }
.beta-path li:nth-child(even) .t { grid-column: 1; text-align: right; }
.beta-path .node b { font: 400 13px/1 var(--mono); color: var(--muted); opacity: 0; }
.beta-path .node::before { content: ""; position: absolute; inset: 0; border-radius: 50%; background: var(--text); }
.beta-path .node svg { position: absolute; inset: 3px; fill: none; stroke: var(--bg); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
/* the year of Pro: the section's one touch of the rim, centred under the path's last point */
.beta-path .gift { grid-template-columns: 1fr; justify-items: center; row-gap: 14px; margin-top: 8px; }
.beta-path .gift .node { grid-column: 1; background: var(--bg); box-shadow: none; }
.beta-path .gift .node::before { inset: 11px; background: var(--text); }
.beta-path .gift .t { grid-column: 1; grid-row: 2; text-align: center; font-size: var(--gt); letter-spacing: -.025em;
  background: linear-gradient(100deg, #f2f3ff, var(--cool) 45%, var(--warm)); -webkit-background-clip: text; background-clip: text; color: transparent; }
.beta-act { position: relative; z-index: 1; margin-top: 44px; padding-top: 0; background: var(--bg); }
.fine a { color: var(--text2); text-underline-offset: 3px; text-decoration-color: var(--faint); }

/* 06 · questions */
.qa details { border-bottom: 1px solid var(--line); }
.qa summary { list-style: none; cursor: pointer; display: grid; grid-template-columns: var(--idx) 1fr auto; align-items: baseline; gap: 12px; padding: 18px 0; font-size: clamp(22px, 2.6vw, 34px); letter-spacing: -.025em; line-height: 1.15; }
.qa summary .idx { font-size: 12px; letter-spacing: .02em; }
.qa summary::-webkit-details-marker { display: none; }
.qa summary::after { content: "+"; font: 300 26px/1 Outfit, sans-serif; color: var(--muted); transition: transform .25s; }
.qa details[open] summary::after { transform: rotate(45deg); }
.qa summary:hover::after { color: var(--text); }
.qa p { padding: 0 0 26px calc(var(--idx) + 12px); color: var(--muted); max-width: 44em; }
@media (max-width: 719px) { .qa p { padding-left: 0; } }
.faq-more { margin-top: 28px; color: var(--muted); font-size: 15px; }
.faq-more a { color: var(--text); text-underline-offset: 3px; text-decoration-color: var(--faint); }

/* ---------- footer: dark, as the rest, lit by soft glares of the rim's colours, which spread out from
   the middle of its top edge as you reach it ---------- */
.foot { position: relative; overflow: hidden; isolation: isolate; margin-top: 40px; padding: clamp(72px, 12vh, 128px) var(--gutter) calc(32px + env(safe-area-inset-bottom)); font-size: 15px; color: var(--muted); background: var(--bg); }
.foot > :not(.glares) { position: relative; max-width: calc(var(--max) - 2 * var(--gutter)); margin-left: auto; margin-right: auto; }
.glares { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.glares i { position: absolute; left: 50%; top: 0; width: var(--w); aspect-ratio: 1.6; border-radius: 50%; filter: blur(28px); mix-blend-mode: screen;
  translate: -50% -50%; transform: translate(var(--dx), var(--dy)); opacity: var(--o); }
.g-cool { --w: 62vw; --dx: -28vw; --dy: 36vh; --o: .62; background: radial-gradient(closest-side, var(--cool), transparent); }
.g-warm { --w: 58vw; --dx: 28vw; --dy: 44vh; --o: .55; background: radial-gradient(closest-side, var(--warm), transparent); }
.g-white { --w: 30vw; --dx: 2vw; --dy: 24vh; --o: .2; background: radial-gradient(closest-side, #f2f3ff, transparent); }
.foot-top { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 48px; }
.foot-line { font-weight: 400; font-size: clamp(40px, 6vw, 88px); line-height: .98; letter-spacing: -.045em; color: var(--text); }
.foot-cols { display: flex; gap: clamp(40px, 8vw, 120px); }
.foot-cols div { display: grid; gap: 10px; align-content: start; }
.foot-cols p { font: 400 12px/1 var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--faint); margin-bottom: 6px; }
.foot a { text-decoration: none; color: var(--text2); font-size: 17px; transition: color .2s; }
.foot a:hover { color: var(--text); }
.foot-small { margin-top: clamp(64px, 12vh, 140px); font-size: 13px; color: var(--muted); }

/* ---------- legal pages ---------- */
.legal { max-width: var(--max); margin: 0 auto; padding: 140px var(--gutter) 100px; }
.legal h1 { font-weight: 400; font-size: clamp(48px, 9vw, 120px); line-height: .95; letter-spacing: -.05em; }
.legal .kicker { font: 400 12px/1 var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin-bottom: 22px; }
.legal-date { margin-top: 20px; color: var(--muted); font: 400 13px/1 var(--mono); }
.short { margin-top: 64px; counter-reset: s; }
.short li { counter-increment: s; display: grid; grid-template-columns: var(--idx) 1fr; gap: 12px; padding: 16px 0; border-bottom: 1px solid var(--line); color: var(--text2); font-size: clamp(18px, 1.8vw, 22px); line-height: 1.35; }
.short li:first-child { border-top: 1px solid var(--line); }
.short li::before { content: "0" counter(s); font: 400 12px/1.9 var(--mono); color: var(--muted); }
.legal-body { display: grid; gap: 40px; margin-top: 88px; }
@media (min-width: 900px) { .legal-body { grid-template-columns: 220px minmax(0, 680px); gap: 80px; } }
.toc { display: none; }
@media (min-width: 900px) {
  .toc { display: grid; align-self: start; position: sticky; top: 100px; }
  .toc a { padding: 7px 0; border-bottom: 1px solid var(--line); color: var(--muted); text-decoration: none; font-size: 14px; }
  .toc a:hover { color: var(--text); }
}
.legal-text section + section { margin-top: 52px; }
.legal-text h2 { font-weight: 400; font-size: 28px; letter-spacing: -.025em; margin-bottom: 14px; }
.legal-text p, .legal-text li { color: var(--text2); }
.legal-text a { color: var(--text); text-underline-offset: 3px; text-decoration-color: var(--faint); }
.legal-text p + p, .legal-text ul + p, .legal-text p + ul { margin-top: 14px; }
.legal-text ul { display: grid; gap: 8px; }
.legal-text li { padding-left: 20px; position: relative; }
.legal-text li::before { content: ""; position: absolute; left: 0; top: .75em; width: 8px; height: 1px; background: var(--muted); }

.lost { min-height: 86svh; max-width: var(--max); margin: 0 auto; padding: 140px var(--gutter) 60px; display: flex; flex-direction: column; justify-content: flex-end; gap: 22px; }
.lost h1 { font-weight: 400; font-size: clamp(64px, 14vw, 200px); line-height: .9; letter-spacing: -.055em; }
.lost .kicker { font: 400 12px/1 var(--mono); color: var(--muted); }
.lost .btn { align-self: flex-start; }

/* ================================ MOTION ================================ */
@media (prefers-reduced-motion: no-preference) {
  /* load: the phone is traced, its screen wiped up into it; then the sets' lines run out of it and
     the title rises onto them */
  /* one overlapping sequence: the outline traced, the screen switched on from the top, its numbers
     settling into their pills; the glare blooming out of the island as the words rise in */
  .device .edge { stroke-dasharray: 1; animation: trace 1.1s .05s cubic-bezier(.65, 0, .35, 1) both; }
  .device .inner { animation-delay: .2s; }
  .device .island { animation-delay: .45s; }
  .device .key { animation: fade .5s .8s ease both; }
  .device img { animation: screen-on .75s .75s cubic-bezier(.4, 0, .2, 1) both; }
  .halo i { animation: bloom 1.8s .8s cubic-bezier(.2, .6, .2, 1) both; }
  .hero .ln > span { animation: up .9s 1s cubic-bezier(.2, .8, .1, 1) both; }
  .hero .ln + .ln > span { animation-delay: 1.1s; }
  .hero-side { animation: fade .8s 1.3s ease both; }
}
@keyframes up { from { transform: translateY(105%); } }
/* the glare starts as a bright point on the island and spreads to its place, softening */
@keyframes bloom { 0% { transform: translate(0, 0) scale(.06); opacity: 0; } 15% { opacity: .9; } 100% { transform: translate(var(--dx), var(--dy)) scale(1); opacity: var(--o); } }
@keyframes trace { from { stroke-dashoffset: 1; } }
@keyframes screen-on { from { clip-path: inset(0 0 100% 0); filter: brightness(1.6); } to { clip-path: inset(0 0 0 0); filter: none; } }
@keyframes num-in { from { opacity: 0; } }
@keyframes fade { from { opacity: 0; } }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* scenes pin for as long as their story takes */
    .scene { view-timeline: --scene block; height: var(--len, 300vh); }
    .pin { position: sticky; top: 0; height: 100svh; padding-top: 84px; padding-bottom: 28px; gap: 0; justify-content: space-between; }

    /* the hero into 01: the title slides off, the way in fades, and the phone zooms into its sets'
       rows; as it fades they become the rows of 01 */
    #log { --len: 1880vh; } /* 01, 02 and 03 one after another: 720vh, 420vh, 640vh (home.mjs PART) */
    #log .pin { padding: 0; max-width: none; display: block; }
    /* not clipped: on iPhone the screen can be taller than 100svh, and the phone runs past its foot */
    #log .hero { position: absolute; inset: 0; overflow: visible; }
    .hero h1 { animation: slide-l cubic-bezier(.5, 0, .7, .4) both; animation-timeline: --scene; animation-range: contain 0.81% contain 4.85%; }
    .hero-side { animation: fade .8s 1.3s ease both, fade-out linear both; animation-timeline: auto, --scene; animation-range: normal, contain 0.4% contain 2.83%; }
    /* where the first set's row is: on the phone (--y0) and in 01 (--yt); the phone travels between */
    #log { --H: calc(var(--dw) * 2.0933); --y0: calc(var(--devtop) + var(--H) * .272);
      /* 01's four rows centred, a little high (its caption is below): the phone rises to them as it zooms */
      --yt: calc(50svh - 2.2 * var(--fs) - 28px + var(--fs) * var(--rc)); }
    #log { --devtop: 142px; }
    @media (max-width: 999px) {
      #log { --devtop: max(58svh, 470px); --yt: calc(150px + var(--fs) * var(--rc)); }
      #log .hero-stage { position: static; }
      #log .device { position: absolute; top: var(--devtop); left: 50%; margin: 0 0 0 calc(var(--dw) / -2); }
    }
    .device { --dy: calc(var(--yt) - var(--y0)); will-change: transform; animation: zoom linear both; animation-timeline: --scene; animation-range: contain 1.62% contain 8.49%; }
    #log .sets { position: absolute; left: var(--gutter); right: var(--gutter); top: calc(var(--yt) - var(--fs) * var(--rc)); }
    .log-layer { position: absolute; inset: 0; padding: 84px var(--gutter) 28px; justify-content: space-between; gap: 0;
      animation: fade linear both; animation-timeline: --scene; animation-range: contain 4.85% contain 6.07%; }

    /* 01: the rows settle; the second and third sets are ticked in turn, the rest counting down
       beside the next; then Coach writes the fourth */
    .set { border-bottom-color: transparent; }
    /* (hidden unless their animations draw them: nothing stray if the scroll's timeline isn't ready) */
    .set::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: var(--line); transform-origin: left; transform: scaleX(0);
      animation: draw cubic-bezier(.3, .7, .1, 1) both; animation-timeline: --scene; }
    #log .set:nth-child(1)::after { animation-range: contain 6.07% contain 8.9%; }
    #log .set:nth-child(2)::after { animation-range: contain 6.68% contain 9.51%; }
    #log .set:nth-child(3)::after { animation-range: contain 7.29% contain 10.12%; }
    .set .idx { animation: on linear both; animation-timeline: --scene; animation-range: contain 6.88% contain 8.49%; }
    .set:not(.first):not(.next) .w { animation: ink linear both; animation-timeline: --scene; }
    #log .set:nth-child(2) .w { animation-range: contain 14.56% contain 15.37%; }
    #log .set:nth-child(3) .w { animation-range: contain 21.03% contain 21.84%; }
    /* the numbers ride on the phone as part of it (copies in .ride, carried by its zoom, so nothing can
       pull them apart), then leave for 01's rows, where they land exactly on 01's own numbers, which
       take over. Without site.js, 01 fades in whole. */
    .device > .body { animation: body-fade linear both; animation-timeline: --scene; animation-range: contain 1.62% contain 8.49%; }
    .ride { animation: num-in .45s 1.08s ease both; }
    .ride > span { animation: ride linear both, hand-out linear both; animation-timeline: --scene, --scene; animation-range: contain 1.62% contain 8.49%, contain 8.49% contain 8.75%; }
    .flight .set [data-set] { animation: hand-in linear both; animation-timeline: --scene; animation-range: contain 8.3% contain 8.49%; }
    .flight .log-layer { animation: none; pointer-events: none; }
    .flight .says { animation: fade linear both; animation-timeline: --scene; animation-range: contain 5.66% contain 7.28%; }
    .flight .set.first .tick { animation: on linear both; animation-timeline: --scene; animation-range: contain 6.88% contain 8.49%; }
    .set:not(.first) .tick { animation: on linear both; animation-timeline: --scene; }
    #log .set:nth-child(2) .tick { animation-range: contain 14.56% contain 15.37%; }
    #log .set:nth-child(3) .tick { animation-range: contain 21.03% contain 21.84%; }
    .set .timer { animation: countdown linear both; animation-timeline: --scene; }
    .next .idx { animation: on linear both; animation-timeline: --scene; animation-range: contain 26.69% contain 27.51%; }
    .next .w { animation: write linear both; animation-timeline: --scene; animation-range: contain 27.1% contain 32.77%; }
    .next .caret { animation: caret linear both; animation-timeline: --scene; animation-range: contain 26.69% contain 33.98%; }
    .next .by { animation: on linear both; animation-timeline: --scene; animation-range: contain 32.77% contain 33.98%; }
    .next::after { animation-range: contain 25.89% contain 27.51%; }
    /* each set's line lights as it's ticked (the first as the rows settle) and cools; Coach's is drawn
       as it writes, and stays lit */
    .set:not(.next)::before { animation: flash linear both; animation-timeline: --scene; }
    #log .set:nth-child(1)::before { animation-range: contain 8.49% contain 12.13%; }
    #log .set:nth-child(2)::before { animation-range: contain 14.56% contain 18.2%; }
    #log .set:nth-child(3)::before { animation-range: contain 21.03% contain 24.67%; }
    .rimline i { animation: write-line linear both; animation-timeline: --scene; animation-range: contain 27.1% contain 32.77%; }
    .set.next { animation: wash linear both; animation-timeline: --scene; animation-range: contain 26.69% contain 33.98%; }
    .says { gap: 0; margin-top: auto; }
    .says p { grid-area: 1 / 1; animation: say linear both; animation-timeline: --scene; }
    .says p:first-child { animation-name: say-first; }
    .says p:last-child { animation-name: say-last; }

    /* 01 into 02: the sets lift away, but for Coach's line, which then peels up into the curve of the
       weeks from its start ("peel", home.mjs): what's left of the line hangs off the curve's head and is
       reeled into it, a dot riding the join, the number rolling */
    .set:not(.next) { animation: row-out linear forwards; animation-timeline: --scene; animation-range: contain 40.45% contain 42.81%; }
    .next .ink, .next .meta { animation: fade-out linear forwards; animation-timeline: --scene; animation-range: contain 40.92% contain 42.81%; }
    .next .idx { animation: on linear both, fade-out linear forwards; animation-timeline: --scene, --scene; animation-range: contain 26.69% contain 27.51%, contain 40.92% contain 42.81%; }
    .set.next { animation: wash linear both, unwash linear forwards; animation-timeline: --scene, --scene; animation-range: contain 26.69% contain 33.98%, contain 40.45% contain 42.81%; }
    .next::after { animation: draw cubic-bezier(.3, .7, .1, 1) both, fade-out linear forwards; animation-timeline: --scene, --scene; animation-range: contain 25.89% contain 27.51%, contain 40.45% contain 41.87%; }
    .rimline { animation: peel linear forwards; animation-timeline: --scene; animation-range: contain 43.28% contain 60.74%; }
    .says { animation: fade-out linear forwards; animation-timeline: --scene; animation-range: contain 40.45% contain 41.87%; }
    .flight .says { animation: fade linear both, fade-out linear forwards; animation-timeline: --scene, --scene; animation-range: contain 5.66% contain 7.28%, contain 40.45% contain 41.87%; }

    #log .prog-layer { position: absolute; inset: 0; padding: 84px var(--gutter) 28px; justify-content: space-between; gap: 0; pointer-events: none; }
    .gauge { position: absolute; left: var(--gutter); top: 140px; animation: roll linear both; animation-timeline: --scene; }
    .gauge .big { animation: fade linear both; animation-timeline: --scene; animation-range: contain 42.81% contain 44.22%; }
    .prog-layer .statement { animation: rise linear both; animation-timeline: --scene; }
    .curve { position: absolute; left: 0; right: 0; bottom: 0; margin: 0; animation: on linear both; animation-timeline: --scene; animation-range: contain 42.34% contain 43.04%; }
    .trace { animation: trace-draw linear both; animation-timeline: --scene; }
    .curve .tip { display: block; animation: along linear both; animation-timeline: --scene; }

    /* 02 into 03: the number and its line lift away; the curve is reeled into the dot at its head,
       which flies to the phone's Dynamic Island (site.js measures where) and becomes it; the phone's
       outline is drawn out of the island both ways, its screen wipes in, its body fills in; then it turns */
    .prog-layer { animation: lift-away cubic-bezier(.5, 0, .7, .4) forwards; animation-timeline: --scene; animation-range: contain 64.4% contain 67.28%; }
    .trace { animation: trace-draw linear both, reel-out cubic-bezier(.5, 0, .5, 1) forwards; animation-timeline: --scene, --scene; animation-range: contain 43.28% contain 60.74%, contain 64.58% contain 67.46%; }
    .curve .tip { animation: along linear both, to-island cubic-bezier(.55, 0, .25, 1) forwards; animation-timeline: --scene, --scene; animation-range: contain 43.28% contain 60.74%, contain 67.46% contain 70.15%; }
    .dyn { opacity: 0; animation: island-in linear forwards; animation-timeline: --scene; animation-range: contain 70.15% contain 73.03%; }
    .outline { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; transform: translateZ(calc(var(--d) / 2 + 1px)); pointer-events: none; }
    .outline path { fill: none; stroke: #8a8a8a; stroke-width: 1; vector-effect: non-scaling-stroke; stroke-dasharray: 1;
      animation: trace-out linear both, fade-out linear forwards; animation-timeline: --scene, --scene; animation-range: contain 70.51% contain 74.11%, contain 74.83% contain 76.26%; }
    .iphone .front { animation: front-in linear both; animation-timeline: --scene; animation-range: contain 72.67% contain 74.11%; }
    .pages { animation: screen-in cubic-bezier(.5, 0, .2, 1) both; animation-timeline: --scene; animation-range: contain 72.67% contain 75.19%; }
    .edge, .iphone .back, .iphone-stage::after { animation: fade linear both; animation-timeline: --scene; animation-range: contain 74.11% contain 75.91%; }
    #log .app-layer { position: absolute; inset: 0; padding: 84px var(--gutter) 28px; display: block; pointer-events: none; max-width: none;
      --pw: clamp(220px, 21vw, 310px); --pcx: 72%; --pcy: 54%; }
    .iphone-stage { position: absolute; left: var(--pcx); top: var(--pcy); margin: calc(var(--pw) * -1.03) 0 0 calc(var(--pw) / -2); }
    .iphone { animation: turn linear both; animation-timeline: --scene; animation-range: contain 75.55% contain 100%; }
    .sheen { animation: sheen linear both; animation-timeline: --scene; animation-range: contain 75.55% contain 100%; }
    .names { position: absolute; left: max(var(--gutter), (100% - var(--max)) / 2 + var(--gutter)); top: 50%; translate: 0 -50%; width: min(44%, 560px); }
    .names { animation: names-in cubic-bezier(.2, .7, .2, 1) both; animation-timeline: --scene; animation-range: contain 67.46% contain 70.15%; }
    .names li { animation: name linear both; animation-timeline: --scene; }
    .names li:first-child { animation-name: name-in; }
    .names li:last-child { animation-name: name-last; }
    .page + .page { display: block; }
    .p-push { animation: push-in linear both; animation-timeline: --scene; }
    .p-sheet { animation: sheet-in linear both; animation-timeline: --scene; }
    .p-dissolve { animation: dissolve-in linear both; animation-timeline: --scene; }
    .p-home { animation: home-in linear both; animation-timeline: --scene; }
    .page:nth-child(1) { animation: push-out linear both; animation-timeline: --scene; animation-range: contain 79.86% contain 82.74%; }
    .page:nth-child(2) { animation: push-in linear both, sheet-under linear forwards; animation-timeline: --scene, --scene; animation-range: contain 79.86% contain 82.74%, contain 85.61% contain 88.49%; }
    .page:nth-child(3) { animation: sheet-in linear both, dissolve-out linear forwards; animation-timeline: --scene, --scene; animation-range: contain 85.61% contain 88.49%, contain 90.65% contain 92.8%; }
    .page:nth-child(4) { animation: dissolve-in linear both, close linear forwards; animation-timeline: --scene, --scene; animation-range: contain 90.65% contain 93.52%, contain 95.68% contain 98.56%; }

    /* 04: the words light as they're read */
    #why { --len: 260vh; }
    #why .pin { justify-content: center; }
    .words span { animation: read linear both; animation-timeline: --scene; }
    /* the answer's last words light straight into the rim's colours as each is read (its range on it) */
    .words .rim-words > span { animation: read linear both, rim-in linear both; animation-timeline: --scene, --scene; }

    /* 05: the line fills down the path as the section goes by, ticking each set as it reaches it; then
       the year of Pro lights, and the way in */
    #join { view-timeline: --beta block; }
    .join-intro { animation: rise linear both; animation-timeline: view(); animation-range: entry 0% entry 70%; }
    .is-beta .beta-status i { animation: pulse 2.4s ease-in-out infinite; }
    .beta-path::after { animation: fill-down linear both; animation-timeline: --beta; animation-range: cover 30% cover 66%; }
    .beta-path li:not(.gift) .node::before, .beta-path li:not(.gift) .node svg { animation: on linear both; animation-timeline: --beta; }
    #join .beta-path li:nth-child(1) .node::before, #join .beta-path li:nth-child(1) .node svg { animation-range: cover 33% cover 35%; }
    #join .beta-path li:nth-child(2) .node::before, #join .beta-path li:nth-child(2) .node svg { animation-range: cover 41% cover 43%; }
    #join .beta-path li:nth-child(3) .node::before, #join .beta-path li:nth-child(3) .node svg { animation-range: cover 49% cover 51%; }
    .beta-path li:not(.gift) .node b { animation: off linear both; animation-timeline: --beta; }
    #join .beta-path li:nth-child(1) .node b { animation-range: cover 33% cover 35%; }
    #join .beta-path li:nth-child(2) .node b { animation-range: cover 41% cover 43%; }
    #join .beta-path li:nth-child(3) .node b { animation-range: cover 49% cover 51%; }
    .beta-path li:not(.gift) .t { animation: set-dim linear both; animation-timeline: --beta; }
    #join .beta-path li:nth-child(1) .t { animation-range: cover 33% cover 36%; }
    #join .beta-path li:nth-child(2) .t { animation-range: cover 41% cover 44%; }
    #join .beta-path li:nth-child(3) .t { animation-range: cover 49% cover 52%; }
    .beta-path .gift .node::before, .beta-path .gift .t { animation: on linear both; animation-timeline: --beta; animation-range: cover 57% cover 61%; }
    .beta-act { animation: rise linear both; animation-timeline: --beta; animation-range: cover 62% cover 68%; }
    .faq .join-title, .qa details { animation: rise linear both; animation-timeline: view(); animation-range: entry 0% entry 90%; }
  }
}
/* the footer's glares spread out from the middle of its top edge; its words rise in */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .glares i { animation: disperse cubic-bezier(.2, .6, .2, 1) both; animation-timeline: view(); animation-range: entry 25% entry 100%; }
    .foot-top, .foot-small { animation: foot-words linear both; animation-timeline: view(); animation-range: entry 55% entry 100%; }
  }
}
/* each glare starts as a small hot point at the middle of the top edge, then spreads to its place and fades to a haze */
@keyframes disperse { 0% { transform: translate(0, 0) scale(.08); opacity: 0; } 12% { opacity: 1; } 100% { transform: translate(var(--dx), var(--dy)) scale(1); opacity: var(--o); } }
@keyframes foot-words { from { opacity: 0; transform: translateY(24px); } }
/* on a phone the hero's words sit above the phone: they lift away as it rises, rather than slide across it */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) and (max-width: 999px) {
    .hero h1 { animation-name: lift-away; animation-timing-function: linear; }
  }
}
/* on a phone the number sits under the curve (which ends where 01's rows did) */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) and (max-width: 999px) {
    .gauge { top: calc(150px + 4.66 * var(--fs) + 36px); }
  }
}
/* on a phone, the scenes show one name at a time and keep inside the screen */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) and (max-width: 899px) {
    #log .app-layer { --pw: min(56vw, (100svh - 300px) / 2.06); --pcx: 50%; --pcy: 58%; }
    .names { display: grid; left: 0; right: 0; width: auto; top: 108px; translate: none; text-align: center; }
    .names li { grid-area: 1 / 1; grid-template-columns: 1fr; border-bottom: 0; font-size: clamp(32px, 9vw, 48px); animation-name: solo; }
    .names li .idx { display: none; }
    .names li:first-child { animation-name: solo-in; }
    .names li:last-child { animation-name: solo-last; }
  }
}

@keyframes draw { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes row-out { to { opacity: 0; transform: translateY(-.25em); } }
@keyframes unwash { to { --wash: 0; } }
@property --rv { syntax: "<percentage>"; inherits: false; initial-value: 100%; }
@keyframes trace-draw { from { --rv: 0%; } to { --rv: 100%; } }
@keyframes flash { 0% { transform: scaleX(0); opacity: 1; } 22% { transform: scaleX(1); opacity: 1; } 100% { transform: scaleX(1); opacity: 0; } }
@keyframes wash { from { --wash: 0; } to { --wash: 1; } }
@keyframes write-line { from { transform: scaleX(0); } to { transform: scaleX(1); } }

@keyframes zoom { 45% { transform: translateY(calc(var(--dy) * .45)) scale(calc(1 + (var(--zoom) - 1) * .45)); } to { transform: translateY(var(--dy)) scale(var(--zoom)); } }
/* the phone's screen and frame fade as it zooms; the numbers riding on it don't */
@keyframes body-fade { 0%, 45% { opacity: 1; } 80%, 100% { opacity: 0; } }
@keyframes hand-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes hand-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes slide-l { to { transform: translateX(-40%); opacity: 0; } }
@keyframes slide-r { to { transform: translateX(40%); opacity: 0; } }
@keyframes fade-out { to { opacity: 0; } }
@keyframes on { from { opacity: 0; } to { opacity: 1; } }
@keyframes off { from { opacity: 1; } to { opacity: 0; } }
@keyframes ink { from { color: var(--signal); } to { color: var(--text); } }
@keyframes countdown { 0% { --t: 120; opacity: 0; } 4% { opacity: 1; } 92% { --t: 0; opacity: 1; } 100% { --t: 0; opacity: 0; } }
@property --p { syntax: "<percentage>"; inherits: true; initial-value: 100%; }
@keyframes write { from { --p: 0%; } to { --p: 100%; } }
@keyframes caret { 0% { opacity: 0; } 4%, 92% { opacity: 1; } 100% { opacity: 0; } }
@keyframes say { 0% { opacity: 0; transform: translateY(12px); } 12%, 88% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(-12px); } }
@keyframes say-first { 0%, 88% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(-12px); } }
@keyframes say-last { 0% { opacity: 0; transform: translateY(12px); } 12%, 100% { opacity: 1; transform: none; } }
@keyframes lit { from { opacity: .16; } to { opacity: 1; } }
@keyframes fill-down { from { transform: scaleY(0); } }
@keyframes pulse { 50% { opacity: .45; } }
@keyframes set-dim { from { color: var(--faint); } }
@keyframes rise { from { opacity: 0; transform: translateY(28px); } }
@keyframes name { 0%, 100% { opacity: .16; } 10%, 90% { opacity: 1; } }
@keyframes name-first { 0%, 90% { opacity: 1; } 100% { opacity: .16; } }
@keyframes name-last { 0% { opacity: .16; } 10%, 100% { opacity: 1; } }
@keyframes solo { 0%, 100% { opacity: 0; transform: translateY(.3em); } 12%, 88% { opacity: 1; transform: none; } }
@keyframes solo-first { 0%, 88% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(-.3em); } }
@keyframes solo-last { 0% { opacity: 0; transform: translateY(.3em); } 12%, 100% { opacity: 1; transform: none; } }
@keyframes lift-away { to { opacity: 0; transform: translateY(-4vh); } }
@property --rl { syntax: "<percentage>"; inherits: false; initial-value: 0%; }
@keyframes reel-out { to { --rl: 104%; } }
@keyframes to-island { from { transform: translate(1200px, 80px) scale(1, var(--tq, 1)); } 99.5% { opacity: 1; } to { transform: translate(var(--ix, 1200px), var(--iy, 80px)) scale(var(--is, 1), calc(var(--is, 1) * var(--tq, 1))); opacity: 0; } }
/* the island takes over from the dot as it lands, looking just like it (white, glowing, its height
   across), cools to black, then stretches into its pill */
@keyframes island-in {
  0% { width: 8.95%; opacity: 1; background-color: #fff; box-shadow: 0 0 8px rgba(255, 192, 138, .8); }
  45% { width: 8.95%; opacity: 1; background-color: #000; box-shadow: 0 0 8px rgba(255, 192, 138, 0); }
  100% { width: 31%; opacity: 1; background-color: #000; box-shadow: 0 0 8px rgba(255, 192, 138, 0); }
}
@keyframes trace-out { 0% { stroke-dashoffset: 1; opacity: 0; } 3% { opacity: 1; } 100% { stroke-dashoffset: 0; opacity: 1; } }
@keyframes front-in { from { background-color: transparent; box-shadow: none; } }
@keyframes screen-in { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes turn {
  0% { transform: rotateY(0) rotateX(0); }
  12% { transform: rotateY(-18deg) rotateX(7deg); }
  30% { transform: rotateY(-20deg) rotateX(6deg); }
  44% { transform: rotateY(16deg) rotateX(4deg); }
  60% { transform: rotateY(-12deg) rotateX(7deg) translateY(-1.5%); }
  76% { transform: rotateY(18deg) rotateX(3deg); }
  100% { transform: rotateY(-8deg) rotateX(5deg) translateY(-1%); }
}
@keyframes names-in { from { opacity: 0; transform: translateY(5vh); } }
@keyframes sheen { from { background-position: 90% 0; } to { background-position: 0% 0; } }
@keyframes name-in { 0% { opacity: 0; } 12%, 90% { opacity: 1; } 100% { opacity: .16; } }
@keyframes solo-in { 0% { opacity: 0; transform: translateY(.3em); } 12%, 88% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(-.3em); } }
@keyframes push-in { from { transform: translateX(100%); box-shadow: -20px 0 40px rgba(0, 0, 0, .6); } to { transform: none; box-shadow: -20px 0 40px rgba(0, 0, 0, 0); } }
@keyframes push-out { to { transform: translateX(-30%); filter: brightness(.45); } }
@keyframes sheet-in { from { transform: translateY(100%); border-radius: 18px 18px 0 0; } to { transform: translateY(0); border-radius: 0; } }
@keyframes sheet-under { to { transform: scale(.92) translateY(-1.5%); filter: brightness(.45); border-radius: 22px; } }
@keyframes dissolve-in { from { opacity: 0; transform: scale(1.06); } to { opacity: 1; transform: none; } }
@keyframes dissolve-out { to { opacity: 0; transform: scale(.97); } }
@keyframes home-in { 0% { opacity: 0; transform: scale(1.12); } 10% { opacity: 1; } 100% { opacity: 1; transform: none; } }
@keyframes close { to { transform: translateY(18%) scale(.16); border-radius: 30%; opacity: 0; } }
@keyframes wipe { from { clip-path: inset(100% 0 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes tilt { from { transform: translateY(6vh) rotate(-3deg); } 30%, 70% { transform: none; } to { transform: translateY(-6vh) rotate(2deg); } }
@keyframes rim-in { from { color: var(--text); } to { color: transparent; } }
@keyframes read { from { opacity: .14; } to { opacity: 1; } }
