/* AskWhy website v2. One stylesheet, no imports, no fonts, no images from other hosts.
   The look is taken from the app (ios/FocusPact/Views): near-black ground with two slow
   bands of light, clear glass, white as the only accent, and the app's blur-and-fade
   (0.55 s, ease-out cubic, blur 14) between scenes.

   Classes on <html>, set by the scripts:
     js       app.js ran            ready   texts are in place, page may show
     mjs      motion.js ran         anim    motion allowed: hidden start states exist
     reduced  no motion             lite    slow device: no canvas, no blur
     scrolled page left the top     hero-cta  the opening screen's button is in view
     touch    the main pointer is a finger: nothing is pinned, less blur
     pin-a, pin-b, pin-c   that stage is pinned (opening screen, "what for" and demo; steps; rules):
                           a desktop window, a mouse or trackpad, motion allowed, and it fits
   ("sand" is set on a giant word, not on <html>, while its canvas draws it as grains.)
   Without any of them the page is complete, readable and still. */

/* ---------- 1. Tokens (docs/WEBSITE_V2_BRIEF.md section 3) ---------- */

:root {
  --ground: #080808;
  --ink: #fff;
  --ink-2: rgba(255,255,255,.72);
  --ink-3: rgba(255,255,255,.6);
  --on-white: #080808;
  --panel: rgba(255,255,255,.07);
  --hairline: rgba(255,255,255,.08);
  --stroke: rgba(255,255,255,.14);
  --rim: rgba(255,255,255,.40);
  --rim-hi: rgba(255,255,255,.7);
  --rim-lo: rgba(255,255,255,.08);
  --fill-quiet: rgba(255,255,255,.08);
  --tick-minor: rgba(255,255,255,.4);
  --tick-major: rgba(255,255,255,.8);
  --tick-dot: rgba(255,255,255,.24);
  --skeleton: rgba(255,255,255,.12);
  --glass-solid: rgba(25,25,25,.92);
  --glass-lit: rgba(42,42,42,.96);
  --glass-clear: rgba(255,255,255,.05);
  --underlay: rgba(8,8,8,.5);
  --lens-ground: rgba(8,8,8,.6);
  --o-quiet: .6;                 /* the alpha of --ink-3, for text that dims by opacity */

  --r-card: 24px;
  --r-control: 14px;
  --r-bubble: 18px;
  --r-field: 22px;
  --r-tile: 8px;
  --r-pill: 999px;
  --r-round: 50%;
  --r-inner: 16px; --r-head: 20px; --r-sheet: 32px; --r-device: 44px; --r-screen: 36px;
  --r-mark: 4px; --r-dot: 2px;
  --s-1: 4px; --s-2: 8px; --s-3: 16px; --s-4: 24px; --s-5: 32px;
  --w-text: 640px;
  --w-page: 1200px;
  --g: 16px;
  /* Phone in landscape: both sides step back by the wider safe area. */
  --safe-x: max(env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));
  --gut: max(var(--g), var(--safe-x));
  --wrap: min(var(--w-page), 100vw - 2 * var(--gut));
  --blur-glass: 6px;

  --font: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-round: ui-rounded, "SF Pro Rounded", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --ease-screen: cubic-bezier(.215,.61,.355,1);
  --t-screen: 550ms;
  --blur-screen: 8px;
  --t-hold: 120ms;
  --t-reduced: 200ms;
  --ease-exit: cubic-bezier(.55,.055,.675,.19);
  --t-exit: 280ms;
  --hide: opacity var(--t-exit) var(--ease-exit), visibility 0s linear var(--t-exit);
  --ease-sine: cubic-bezier(.37,0,.63,1);
  --t-press: 300ms;
  --t-release: 800ms;
  --t-lens: 450ms;
  --t-bouncy: 600ms;
  --t-turn: 750ms; --t-hg: 8s;
  --t-number: 200ms;
  --t-scene: 600ms;
  --t-move: 350ms;
  --stagger: 90ms;
  --word-gap: 45ms;
  --t-tick: 250ms;
  --t-shimmer: 1.4s;
  --t-sheen: 6s; --d-sheen: 2s;
  --t-intro: 1300ms; --t-draw: 850ms; --t-drop: 550ms; --d-drop: 750ms;
  --t-band-1: 12s; --d-band-1: -6s; --t-band-2: 16.5s; --d-band-2: -19.3s;
  --t-ll-1: 11s; --t-ll-1y: 13.75s; --t-ll-2: 15.7s; --t-ll-2y: 12.2s;
  --t-ll-3: 22s; --t-ll-3y: 10s; --t-ll-4: 18.35s; --t-ll-4y: 8.45s;
  --d-after: 400ms;
  --d-hero: 700ms; --d-hero-late: 850ms;
  --spring-press: cubic-bezier(.34,1.56,.64,1);
  --spring-release: cubic-bezier(.34,1.56,.64,1);
  --spring-lens: cubic-bezier(.34,1.56,.64,1);
  --spring-bouncy: cubic-bezier(.34,1.56,.64,1);
  --spring-turn: cubic-bezier(.34,1.56,.64,1);
}
@supports (transition-timing-function: linear(0, 1)) {
  :root {
    --spring-press: linear(0, .15, .444, .727, .929, 1.041, 1.081, 1.078, 1.056, 1.031, 1.011, .999, .994, .993, .995, 1);
    --spring-release: linear(0, .062, .219, .426, .646, .848, 1.014, 1.133, 1.205, 1.233, 1.225, 1.193, 1.147, 1.096, 1.047, 1.006, .975, .955, .946, .946, .953, .963, .975, .986, .996, 1.004, 1.009, 1.012, 1.013, 1.012, 1.009, 1.007, 1);
    --spring-lens: linear(0, .11, .346, .602, .817, .969, 1.056, 1.091, 1.092, 1.074, 1.05, 1.027, 1.009, .998, .993, .991, .992, .994, 1);
    --spring-bouncy: linear(0, .059, .197, .366, .535, .685, .808, .902, .968, 1.01, 1.034, 1.044, 1.046, 1.041, 1.034, 1.027, 1.019, 1.012, 1.007, 1.003, 1);
    --spring-turn: linear(0, .165, .472, .749, .934, 1.028, 1.058, 1.054, 1.036, 1.019, 1.006, .999, .997, .997, .998, .999, .999, 1, 1, 1, 1);
  }
}
@media (min-width: 640px) { :root { --g: 24px; --blur-screen: 14px; --blur-glass: 8px; } }
@media (min-width: 940px) { :root { --g: 32px; } }
/* Written by motion.js while the page scrolls. Not inherited: a new value restyles one element. */
@property --v { syntax: "<number>"; inherits: false; initial-value: 1; }
@property --e { syntax: "<number>"; inherits: false; initial-value: 1; }
@property --pose { syntax: "<number>"; inherits: false; initial-value: 0; }
@property --w { syntax: "<number>"; inherits: false; initial-value: -1; }

/* ---------- 2. Base ---------- */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-padding-top: 96px; background: var(--ground); }
html.js:not(.ready) body { visibility: hidden; }
body {
  margin: 0; min-height: 100vh; min-height: 100svh;
  background: var(--ground); color: var(--ink);
  font: 400 1.0625rem/1.5 var(--font);
  overflow-wrap: break-word;
  -webkit-font-smoothing: antialiased;
}
main, .foot { position: relative; z-index: 2; overflow-x: clip; }
@supports not (overflow: clip) { html { overflow-x: hidden; } }
h1, h2, h3, p, ul, ol, figure, fieldset { margin: 0; padding: 0; }
ul, ol { list-style: none; }
fieldset { border: 0; min-width: 0; }
h1 { font-size: 2.25rem; line-height: 1.04; font-weight: 700; letter-spacing: -.03em; text-wrap: balance; }
h2 { font-size: clamp(1.75rem, 4vw, 3rem); line-height: 1.1; font-weight: 700; letter-spacing: -.02em; text-wrap: balance; }
h3 { font-size: 1.25rem; line-height: 1.25; font-weight: 600; }
a { color: inherit; }
button, input { font: inherit; color: inherit; }
button { border: 0; background: none; padding: 0; cursor: pointer; -webkit-tap-highlight-color: transparent; }
a, button, input, [tabindex] { -webkit-tap-highlight-color: transparent; }
svg { display: block; }
[hidden] { display: none !important; }
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; box-shadow: 0 0 0 6px rgba(0,0,0,.6); }
section[tabindex="-1"]:focus-visible, div[tabindex="-1"]:focus-visible { outline: none; box-shadow: none; }
::selection { background: var(--ink); color: var(--on-white); }

.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.hp { display: none; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.skip { position: fixed; z-index: 20; left: 12px; top: 12px; padding: 12px 16px; border-radius: var(--r-pill); background: var(--ink); color: var(--on-white); font-weight: 600; text-decoration: none; transform: translate3d(0,-200%,0); }
.skip:focus { transform: none; }

.lead { font-size: 1.125rem; line-height: 1.45; color: var(--ink-2); }
.fine { font-size: .8125rem; line-height: 1.45; color: var(--ink-3); }
.label, .tag { font-size: .8125rem; line-height: 1.4; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3); }
.tag { font-variant-numeric: tabular-nums; }
@media (min-width: 390px) { h1 { font-size: 2.5rem; } .lead { font-size: 1.25rem; } }

/* ---------- 3. The moving ground (AmbientLayers.swift) ---------- */

.ground {
  position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none;
  background-color: var(--ground);
  background-image: radial-gradient(circle 80vh at 50% -8%, rgba(255,255,255,.11) 0, rgba(255,255,255,.093) 25%, rgba(255,255,255,.055) 50%, rgba(255,255,255,.017) 75%, rgba(255,255,255,0) 100%);
}
/* A band is a soft ramp: drawn at a quarter size and scaled up, a sixteenth of the pixels. */
.band {
  position: absolute; left: 50%; top: 50%;
  --d: var(--diag, 120vmax);
  height: calc(var(--d) * .5); margin-top: calc(var(--d) * -.25);
  transform: rotate(-32deg) translate3d(var(--rest, 0px), 0, 0) scale(4);
  transition: opacity var(--t-scene) linear;
}
.band-1 {
  width: calc(var(--d) * .125); margin-left: calc(var(--d) * -.0625); --rest: calc(var(--d) * -.12);
  background: linear-gradient(90deg, rgba(255,255,255,0) 0, rgba(255,255,255,.013) 12.5%, rgba(255,255,255,.043) 25%, rgba(255,255,255,.072) 37.5%, rgba(255,255,255,.085) 50%, rgba(255,255,255,.072) 62.5%, rgba(255,255,255,.043) 75%, rgba(255,255,255,.013) 87.5%, rgba(255,255,255,0) 100%);
}
.band-2 {
  width: calc(var(--d) * .075); margin-left: calc(var(--d) * -.0375); --rest: calc(var(--d) * .2);
  background: linear-gradient(90deg, rgba(255,255,255,0) 0, rgba(255,255,255,.009) 12.5%, rgba(255,255,255,.03) 25%, rgba(255,255,255,.051) 37.5%, rgba(255,255,255,.06) 50%, rgba(255,255,255,.051) 62.5%, rgba(255,255,255,.03) 75%, rgba(255,255,255,.009) 87.5%, rgba(255,255,255,0) 100%);
}
@keyframes band-slide {
  from { transform: rotate(-32deg) translate3d(calc(var(--d) * -.42), 0, 0) scale(4); }
  to { transform: rotate(-32deg) translate3d(calc(var(--d) * .42), 0, 0) scale(4); }
}
html.anim:not(.lite) .band-1 { animation: band-slide var(--t-band-1) var(--ease-sine) var(--d-band-1) infinite alternate; }
html.anim:not(.lite) .band-2 { animation: band-slide var(--t-band-2) var(--ease-sine) var(--d-band-2) infinite alternate; }
html[data-scene="focus"] .band { opacity: .6; }
html[data-scene="lock"] .band { opacity: .5; }

/* Lock-screen lights: only in the last section, at 60 % of the app's brightness. */
.ll { position: absolute; opacity: 0; transition: opacity var(--t-scene) linear; }
.ll::before { content: ""; position: absolute; inset: 0; border-radius: var(--r-round); }
html[data-scene="lock"] .ll { opacity: 1; }
.ll-1 { width: 44vmax; height: 44vmax; left: 28vw; top: 26vh; margin: -22vmax 0 0 -22vmax; --lx: 24vw; --ly: 14vh; }
.ll-2 { width: 38vmax; height: 38vmax; left: 74vw; top: 58vh; margin: -19vmax 0 0 -19vmax; --lx: 20vw; --ly: 18vh; }
.ll-3 { width: 34vmax; height: 34vmax; left: 40vw; top: 86vh; margin: -17vmax 0 0 -17vmax; --lx: 28vw; --ly: 8vh; }
.ll-4 { width: 26vmax; height: 26vmax; left: 60vw; top: 12vh; margin: -13vmax 0 0 -13vmax; --lx: 25vw; --ly: 10vh; }
.ll-1::before { background: radial-gradient(closest-side, rgba(255,255,255,.2), rgba(255,255,255,.1) 45%, rgba(255,255,255,0)); }
.ll-2::before { background: radial-gradient(closest-side, rgba(255,255,255,.16), rgba(255,255,255,.08) 45%, rgba(255,255,255,0)); }
.ll-3::before { background: radial-gradient(closest-side, rgba(255,255,255,.13), rgba(255,255,255,.065) 45%, rgba(255,255,255,0)); }
.ll-4::before { background: radial-gradient(closest-side, rgba(255,255,255,.12), rgba(255,255,255,.06) 45%, rgba(255,255,255,0)); }
@keyframes ll-x { from { transform: translate3d(calc(var(--lx) * -1), 0, 0); } to { transform: translate3d(var(--lx), 0, 0); } }
@keyframes ll-y { from { transform: translate3d(0, calc(var(--ly) * -1), 0); } to { transform: translate3d(0, var(--ly), 0); } }
html.anim:not(.lite) .ll { animation: ll-x var(--t-ll-1) var(--ease-sine) infinite alternate paused; }
html.anim:not(.lite) .ll::before { animation: ll-y var(--t-ll-1y) var(--ease-sine) infinite alternate paused; }
/* Same weight as the rule above, so each light really gets its own period. */
html.anim:not(.lite) .ll-2 { animation-duration: var(--t-ll-2); } html.anim:not(.lite) .ll-2::before { animation-duration: var(--t-ll-2y); }
html.anim:not(.lite) .ll-3 { animation-duration: var(--t-ll-3); } html.anim:not(.lite) .ll-3::before { animation-duration: var(--t-ll-3y); }
html.anim:not(.lite) .ll-4 { animation-duration: var(--t-ll-4); } html.anim:not(.lite) .ll-4::before { animation-duration: var(--t-ll-4y); }
html.anim[data-scene="lock"] .ll, html.anim[data-scene="lock"] .ll::before { animation-play-state: running; }

/* The dither: one still layer of fine noise over the lights, whose ramps have about twenty
   grey steps each and showed as bands. White dots, 0 to 9 of 255 opaque, one per pixel of a
   dense screen. A plain tile, no blend mode, never repainted. */
.grain { position: absolute; inset: 0; background: url(noise.png) 0 0 / 64px 64px; }

/* Giant type: text, and a canvas inside it that draws the same word as grains (motion.js).
   The canvas is part of the word, so it sits and scrolls with it; it is larger than the
   word by 100 px at the sides and 210 px above and below: room for the grains to fall
   and drift in, and for the lens ring (drawn in the same canvas). */
.word {
  position: absolute; z-index: -1; left: 50%; top: 50%; margin: 0;
  font-size: min(34vw, 272px); line-height: 1; font-weight: 800; letter-spacing: -.04em; white-space: nowrap;
  color: rgba(255,255,255,.08); transform: translate3d(-50%,-50%,0); pointer-events: none; user-select: none; -webkit-user-select: none;
}
html[lang="de"] .join .word { font-size: min(23.5vw, 188px); }
/* The name on the opening screen: the same grains, but real text of the h1 and in the flow.
   Its size follows the window's width and its height, so the whole name always lies inside
   the window ("AskWhy" is about 3.7 em wide: 24vw of type is nine tenths of the width, so
   a system font that runs a tenth wider still fits; a short window sets it by 38vh).
   Without the grains (no script, motion off, lite tier) it is pale type lit from above
   (the padding is room for the y). */
.hero-name { position: relative; left: auto; top: auto; display: block; padding: .12em .04em; margin: -.12em -.04em; font-size: var(--name); color: var(--ink-3); transform: none; }
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .hero-name { color: transparent; background: linear-gradient(180deg, var(--ink-3), var(--stroke)); -webkit-background-clip: text; background-clip: text; }
}
.word canvas { display: none; position: absolute; left: -100px; top: -210px; width: calc(100% + 200px); height: calc(100% + 420px); }
.word.sand { color: transparent; background: none; }
.word.sand canvas { display: block; }

/* ---------- 4. Materials and small parts ---------- */

/* A: glass that floats. Clear, never milky; never glass on glass. */
.glass {
  position: relative;
  background: var(--glass-solid);
  border-radius: var(--r-card);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.28), inset 0 0 0 1px rgba(255,255,255,.1), inset 0 -12px 20px -14px rgba(255,255,255,.1), 0 28px 56px -32px rgba(0,0,0,.85);
}
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .glass { background: var(--glass-clear); -webkit-backdrop-filter: blur(var(--blur-glass)) brightness(1.1); backdrop-filter: blur(var(--blur-glass)) brightness(1.1); }
}
/* Inside the device, inside 3D and on slow devices: no backdrop filter. */
.screen .glass, html.lite .glass { background: var(--glass-solid); -webkit-backdrop-filter: none; backdrop-filter: none; }
/* Touch: only the bar and the dock, which text scrolls under, blur what is behind them.
   The cards lie on the soft lights, where a blur shows nothing. */
html.touch .plan, html.touch .join-card { -webkit-backdrop-filter: none; backdrop-filter: none; }
.glass::before, .device::before, .disc::before, .plens::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1px; pointer-events: none; opacity: .55;
  background: linear-gradient(135deg, var(--rim-hi), var(--rim-lo));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); mask-composite: exclude;
  transition: opacity var(--t-press) linear;
}
.glass::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0;
  background: radial-gradient(190px circle at var(--mx, 50%) var(--my, 0%), rgba(255,255,255,.13), rgba(255,255,255,0) 60%);
  transition: opacity var(--t-screen) linear;
}
.glass.lit::after { opacity: 1; transition-duration: var(--t-number); }
.glass.lit::before { opacity: 1; }
.glass > * { position: relative; z-index: 1; }
.underlay { background: var(--underlay); border-radius: var(--r-inner); padding: var(--s-3); }

/* B: plain panel for long text and for anything that carries a lens. */
.panel { background: var(--panel); border-radius: var(--r-card); }

/* C: the wheel's lens, the only glass that may sit on a panel. The magnified ticks are also
   cut by their own clip-path: Safari can drop a rounded overflow while the lens swells. */
.lens {
  border-radius: var(--r-round); overflow: hidden; isolation: isolate; background: var(--lens-ground);
  box-shadow: inset 0 0 0 1px var(--rim), inset 1px 1px 0 rgba(255,255,255,.5), 0 6px 14px -6px rgba(0,0,0,.8);
  transform: scale(var(--sw, 1)); transition: transform var(--t-lens) var(--spring-lens);
}
.lens.swell { --sw: 1.12; }
.lens-copy { position: absolute; inset: 0; clip-path: circle(50%); filter: brightness(1.15); }
.lens-ind { position: absolute; left: 50%; top: 50%; width: 3px; height: 28px; margin: -14px 0 0 -1.5px; border-radius: var(--r-pill); background: var(--ink); }

/* Ruler ticks: minor every 14 px, major every --major. */
.ticks {
  position: absolute; left: 50%; top: 50%; height: 20px; margin-top: -10px; width: 841.5px; --major: 140px;
  background:
    linear-gradient(90deg, var(--tick-major) 0, var(--tick-major) 1.5px, rgba(255,255,255,0) 1.5px) 0 50% / var(--major) 20px repeat-x,
    linear-gradient(90deg, var(--tick-minor) 0, var(--tick-minor) 1.5px, rgba(255,255,255,0) 1.5px) 0 50% / 14px 12px repeat-x;
  transform: translate3d(calc(var(--x, 0) * -1px), 0, 0);
}
.ticks::before, .ticks::after {
  content: ""; position: absolute; top: 50%; height: 2px; margin-top: -1px; width: 70px;
  background: radial-gradient(circle, var(--tick-dot) 1px, rgba(255,255,255,0) 1.2px) 0 50% / 14px 2px repeat-x;
}
.ticks::before { right: 100%; margin-right: 6px; }
.ticks::after { left: 100%; margin-left: 6px; }
.lens-copy .ticks { transform-origin: 0 50%; transform: scale(1.25) translate3d(calc(var(--x, 0) * -1px), 0, 0); }
.ruler { position: relative; flex: 1; min-width: 0; height: 56px; }
.ruler-mask { position: absolute; inset: 0; overflow: hidden; -webkit-mask-image: linear-gradient(90deg, rgba(0,0,0,0) 0, #000 28%, #000 72%, rgba(0,0,0,0) 100%); mask-image: linear-gradient(90deg, rgba(0,0,0,0) 0, #000 28%, #000 72%, rgba(0,0,0,0) 100%); }
.ruler > .lens { position: absolute; left: 50%; top: 50%; width: 48px; height: 48px; margin: -24px 0 0 -24px; }
.wheel-num { font: 600 2.125rem/1 var(--font-round); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* The glass disc with the hourglass (LockScreenView.swift) and the lens under the pointer
   (.plens) are one material: a thick piece of clear glass. Light falls in at the top left
   (a film, the bright side of the rim, a soft arc) and gathers again at the bottom right
   (a paler floor and a small glint); just inside the rim lie a pale band and a shadow, which
   give it depth, and a shadow below lifts it off the name. No blur: it is a lens, and
   motion.js bends the grains behind it and makes them larger and brighter. */
.disc, .plens {
  border-radius: var(--r-round);
  background:
    radial-gradient(closest-side, rgba(255,255,255,0) 66%, rgba(255,255,255,.08) 84%, rgba(255,255,255,.2) 94%, rgba(255,255,255,.04)),
    radial-gradient(90% 90% at 30% 20%, rgba(255,255,255,.2), rgba(255,255,255,0) 60%),
    radial-gradient(80% 70% at 68% 88%, rgba(255,255,255,.12), rgba(255,255,255,0) 68%),
    rgba(255,255,255,.05);
  box-shadow: inset 0 1px 1px rgba(255,255,255,.6), inset 0 0 0 1px rgba(255,255,255,.14), inset -5px -8px 16px -9px rgba(0,0,0,.5), inset 5px 7px 14px -8px rgba(255,255,255,.3), 0 3px 8px rgba(0,0,0,.45), 0 24px 44px -14px rgba(0,0,0,.9);
}
.disc::before, .plens::before { padding: max(1.5px, 1.5%); opacity: 1; background: linear-gradient(135deg, #fff, rgba(255,255,255,.4) 34%, rgba(255,255,255,.08) 66%, rgba(255,255,255,.6)); }
.disc::after, .plens::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: radial-gradient(62% 50% at 26% 19%, rgba(255,255,255,.7), rgba(255,255,255,0) 70%), radial-gradient(22% 16% at 75% 85%, rgba(255,255,255,.5), rgba(255,255,255,0) 70%);
  -webkit-mask: radial-gradient(closest-side, rgba(0,0,0,0) 64%, #000 80%, #000 92%, rgba(0,0,0,0) 97%); mask: radial-gradient(closest-side, rgba(0,0,0,0) 64%, #000 80%, #000 92%, rgba(0,0,0,0) 97%);
}
.disc { position: relative; width: 148px; height: 148px; display: grid; place-items: center; }
/* The hourglass lies above the highlights, on a soft dark seat, so it stays crisp over the
   brighter grains. */
.disc > * { position: relative; z-index: 1; background: radial-gradient(closest-side, rgba(0,0,0,.34), rgba(0,0,0,0)); }
/* The lens under the pointer on the opening screen (mouse and trackpad): clear glass, as it
   was before the fourth pass (owner, 2026-11-14: the filled bubble was "so visible and not
   clear liquid glass like before"). Only a hairline rim, bright at the top left and faint at
   the bottom right; no film, no shadow, no brightening of what lies behind it. motion.js
   moves it by transform and sets its opacity (no transition here: it must be gone in the
   same frame in which it would touch the logo's disc); over the name it magnifies the
   grains in their canvas. The logo's disc keeps the strong glass. */
.plens { position: fixed; z-index: 3; left: -48px; top: -48px; width: 96px; height: 96px; opacity: 0; visibility: hidden; pointer-events: none; will-change: transform, opacity; background: none; box-shadow: none; }
.plens::before { padding: 1px; background: linear-gradient(135deg, rgba(255,255,255,.8), rgba(255,255,255,.22)); }
.plens::after { content: none; }
.plens.on { visibility: visible; }
.disc .hg { width: 132px; height: 132px; }
@media (min-width: 390px) { .disc { width: 164px; height: 164px; } .disc .hg { width: 148px; height: 148px; } }
/* The opening screen: the same disc in front of the name, on its centre and sized by it; the
   grains pass behind it and are magnified (motion.js), as in the last chapter. Out of the
   flow, so the name, the line and the buttons keep their place. */
.hero h1 { position: relative; --name: min(24vw, 38vh, 360px); }
.hero-lens { position: absolute; left: 50%; top: calc(var(--name) / 2); --hd: clamp(48px, var(--name) * .66, 240px); }
.hero .hero-disc { position: absolute; left: calc(var(--hd) / -2); top: calc(var(--hd) / -2); width: var(--hd); height: var(--hd); }
/* Its hourglass runs by itself, in four layers that only turn, scale and fade: the sand
   runs down, the glass turns over (which looks like the start), and so on. Only while the
   opening screen is in view (hero-cta); still with motion off and in the lite tier. */
.hgr { width: 82%; height: 82%; --a: hgr; }
.hgr .hg { position: absolute; left: 0; top: 0; width: 100%; height: 100%; }
.hgr-s { opacity: 0; --a: hgr-s; }
.hgr-u { transform: scale(0); transform-origin: 50% 30.4%; --a: hgr-u; }
.hgr-l { transform-origin: 50% 82.9%; --a: hgr-l; }
@keyframes hgr { 0%, 90% { transform: none; } to { transform: rotate(180deg); } }
@keyframes hgr-s { 0%, 3%, 76%, to { opacity: 0; } 7%, 72% { opacity: .9; } }
@keyframes hgr-u { 0%, 3% { transform: none; } 74%, to { transform: scale(0); } }
@keyframes hgr-l { 0%, 3% { transform: scale(0); } 74%, to { transform: none; } }
html.anim.hero-cta:not(.lite) [class*="hgr"] { animation: var(--a) var(--t-hg) linear infinite; }
html.anim.hero-cta:not(.lite) .hgr { animation-timing-function: var(--spring-turn); }

/* The hourglass mark (HourglassMark.swift). At rest the sand lies below. */
.hg { color: var(--ink); overflow: visible; }
.hg-turn { transform: rotate(var(--hg-rot, 0deg)); transition: transform var(--t-turn) var(--spring-turn); }
.hg-top { transform: scale(var(--hg-up, 0)); }
.hg-bottom { transform: scale(var(--hg-low, 1)); }
.hg-stream { opacity: 0; transition: opacity var(--t-exit) linear; }
.hg.streaming .hg-stream { opacity: .9; }
/* The one animation that is not transform, opacity or filter: the outline of the 28 px
   mark draws itself once on load, as in the app (HourglassMark.swift). */
@keyframes hg-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes hg-pop { from { opacity: .01; transform: scale(.9); } 65% { opacity: 1; transform: scale(1.03); } to { transform: none; } }
@keyframes hg-drop { from { transform: scale(0); } to { transform: scale(1); } }
html.anim .hg-intro { animation: hg-pop var(--t-intro) var(--ease-screen) backwards; }
html.anim .hg-intro .hg-outline { stroke-dasharray: 1; animation: hg-draw var(--t-draw) ease-in-out backwards; }
html.anim .hg-intro .hg-top { animation: hg-drop var(--t-drop) var(--spring-bouncy) var(--d-drop) backwards; }

.status { display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px; border-radius: var(--r-pill); background: var(--stroke); font-size: .9375rem; line-height: 1.3; font-weight: 600; text-align: left; }
.status svg { flex: none; width: 16px; height: 16px; }
.status-quiet { background: var(--fill-quiet); color: var(--ink-2); }
.status-wide { border-radius: var(--r-control); padding: 10px 12px; align-items: flex-start; font-weight: 500; }
.status-wide svg { margin-top: 2px; }

.tile { flex: none; display: grid; place-items: center; width: 30px; height: 30px; border-radius: var(--r-tile); background: var(--stroke); }
.tile svg { width: 15px; height: 15px; }
.shape { display: block; width: 12px; height: 12px; background: var(--ink); }
.shape-c { border-radius: var(--r-round); }
.shape-s { border-radius: var(--r-dot); }
.shape-t { clip-path: polygon(50% 6%, 100% 94%, 0 94%); }

/* Lock glyph whose shackle opens by turning 30 degrees. */
.lock { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.lock .sh { transform-origin: 16px 11px; transition: transform var(--t-release) var(--spring-release); }
.lock.open .sh, .open > .lock .sh, [data-state="open"] .head-lock .sh { transform: rotate(30deg); transition: transform var(--t-press) var(--spring-press); }
.g { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.g-mark { width: 16px; height: 16px; flex: none; color: currentColor; }

/* Buttons: pressing glass swells and wobbles back (Theme.swift, PressableGlass). */
.btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 46px; padding: 0 20px; border-radius: var(--r-pill);
  font-size: .9375rem; line-height: 1.2; font-weight: 500; text-decoration: none; text-align: center; white-space: nowrap;
  transition: transform var(--t-release) var(--spring-release);
}
.btn-white { min-height: 50px; background: var(--ink); color: var(--on-white); font-size: 1.0625rem; font-weight: 600; }
.btn-glass { background: var(--fill-quiet); color: var(--ink); box-shadow: inset 0 0 0 1px var(--rim); }
.btn-lg { min-height: 56px; padding: 0 28px; }
.btn-sm { min-height: 44px; padding: 0 16px; }
.btn[aria-disabled="true"] { opacity: .6; cursor: default; }
/* Pressed (a class set by motion.js; no :active rule): a swell and a brighter fill; radius,
   filter and backdrop filter never change. In the demo phone no glow, so no edge cuts it. */
html.anim .pressed { transform: scale(var(--px, 1.06), var(--py, 1.1)); transition: transform var(--t-press) var(--spring-press); }
html.anim .btn-glass.pressed, html.anim .chip.pressed { background: rgba(255,255,255,.3); box-shadow: inset 0 0 0 1px var(--rim-hi), 0 0 16px rgba(255,255,255,.35); }
html.anim .screen .pressed { box-shadow: inset 0 0 0 1px var(--rim-hi); }

/* ---------- 5. Chrome: top pill and dock ---------- */

.bar {
  position: fixed; z-index: 10; left: max(12px, var(--safe-x)); right: max(12px, var(--safe-x)); top: calc(12px + env(safe-area-inset-top, 0px)); height: 52px;
  display: flex; align-items: center; gap: 8px; padding: 0 4px 0 12px; border-radius: var(--r-pill);
}
.bar-bg { position: absolute; inset: 0; z-index: -1; border-radius: inherit; transition: opacity var(--t-screen) var(--ease-screen); }
html.anim:not(.scrolled) .bar-bg { opacity: 0; visibility: hidden; transition: var(--hide); }
.brand { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; margin-right: auto; font-size: 1.0625rem; font-weight: 700; text-decoration: none; }
.brand .hg { width: 28px; height: 28px; }
.bar-nav { display: none; }
.bar-nav a, .foot nav a { display: inline-flex; white-space: nowrap; align-items: center; min-height: 44px; padding: 0 10px; text-decoration: none; font-size: .8125rem; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-2); }
.bar-nav a:hover, .foot nav a:hover { color: var(--ink); }
.lang { display: flex; }
.lang button, .lang a { display: grid; place-items: center; width: 44px; height: 44px; border-radius: var(--r-round); font-size: .8125rem; font-weight: 600; color: var(--ink-2); text-decoration: none; transition: transform var(--t-release) var(--spring-release); }
.lang [aria-pressed="true"], .lang [aria-current="true"] { color: var(--on-white); background: radial-gradient(circle, var(--ink) 0, var(--ink) 16px, rgba(255,255,255,0) 16.5px); }
.bar-cta { min-height: 44px; padding: 0 16px; font-size: .9375rem; background: none; isolation: isolate; }
.bar-cta::before { content: ""; position: absolute; z-index: -1; inset: 0; border-radius: inherit; background: var(--ink); }
/* The change is a fade of the white fill; on load it is simply there. */
html.ready .bar-cta { transition: transform var(--t-release) var(--spring-release), color 0s linear var(--t-hold); }
html.ready .bar-cta::before { transition: opacity var(--t-exit) linear; }
/* One white button per screen: while the opening screen's own button is in view, the bar's steps back to glass. */
html.hero-cta .bar-cta { color: var(--ink); background: var(--fill-quiet); box-shadow: inset 0 0 0 1px var(--rim); }
html.hero-cta .bar-cta::before { opacity: 0; }
.motion-btn { flex: none; width: 44px; min-height: 44px; height: 44px; padding: 0; border-radius: var(--r-round); }
/* Solid glyphs: two thin strokes did not read as "pause". */
.motion-btn .g { fill: currentColor; stroke: none; }
@media (max-width: 399px) { .bar { gap: 2px; padding-left: 10px; } .brand { gap: 6px; } .bar-cta { padding: 0 10px; } }
.cta-long { display: none; }
@media (max-width: 349px) { .brand-name { display: none; } }
@media (min-width: 640px) {
  .bar { width: max-content; max-width: min(840px, 100% - 24px); margin-inline: auto; gap: 12px; padding-left: 16px; }
  .cta-long { display: inline; } .cta-short { display: none; }
  .brand { margin-right: 8px; }
}
@media (min-width: 940px) { .bar-nav { display: flex; } }

.dock { display: none; }
html.mjs .dock {
  display: block; position: fixed; z-index: 10; left: max(20px, var(--safe-x)); right: max(20px, var(--safe-x)); bottom: calc(12px + env(safe-area-inset-bottom, 0px)); height: 56px;
  border-radius: var(--r-pill); touch-action: pan-y; cursor: grab; user-select: none; -webkit-user-select: none;
  opacity: 0; visibility: hidden;
  transition: var(--hide);
}
/* It only fades: the element with the backdrop filter never moves. */
html.mjs .dock.on { opacity: 1; visibility: visible; transition: opacity var(--t-screen) var(--ease-screen); }
.dock.drag { cursor: grabbing; }
.dock-ruler { position: absolute; inset: 0; overflow: hidden; border-radius: inherit; -webkit-mask-image: linear-gradient(90deg, rgba(0,0,0,0) 30%, #000 43%, #000 57%, rgba(0,0,0,0) var(--end, 70%)); mask-image: linear-gradient(90deg, rgba(0,0,0,0) 30%, #000 43%, #000 57%, rgba(0,0,0,0) var(--end, 70%)); }
/* Eight chapters: seven steps of 140 px (the plain ruler is five, as the demo's five minutes need). */
.dock .ticks { width: 981.5px; }
.dock > .lens { position: absolute; z-index: 1; left: 50%; top: 50%; width: 48px; height: 48px; margin: -24px 0 0 -24px; }
.dock-idx, .dock-name { position: absolute; z-index: 1; top: 0; line-height: 56px; font-size: .8125rem; font-weight: 600; white-space: nowrap; }
.dock-idx { left: 20px; color: var(--ink-3); font-variant-numeric: tabular-nums; letter-spacing: .04em; }
.dock-name { right: 20px; max-width: calc(38% - 20px); overflow: hidden; text-overflow: ellipsis; color: var(--ink-2); }
html.reduced .dock-ruler, html.reduced .dock > .lens { display: none; }
html.reduced .dock { cursor: default; }
html.reduced .wheel .ruler { display: none; }
@media (min-width: 640px) { html.mjs .dock { left: 0; right: 0; width: 420px; margin-inline: auto; } }
/* Phone: the longest chapter name ("Wieder gesperrt", about 103 px) gets the whole half
   beside the lens, and the ticks end before it. */
@media (max-width: 639px) {
  .dock-idx { left: 16px; }
  .dock-name { right: 16px; max-width: calc(50% - 40px); }
  .dock-ruler { --end: 66%; }
}
@media (max-width: 349px) { html.mjs .dock { left: 12px; right: 12px; } }

/* ---------- 6. Sections: shared layout ---------- */

.sec { position: relative; width: var(--wrap); margin-inline: auto; padding-block: 64px; }
.sec-head { max-width: var(--w-text); }
.sec-head > * + *, .rules-copy > * + *, .limits-head > * + * { margin-top: var(--s-3); }
.card { border-radius: var(--r-card); padding: var(--s-3); }

/* Tracks: on phones the steps and the options are cards that snap under a wheel. */
.track { display: grid; gap: var(--s-3); margin-top: var(--s-5); }
.wheel { display: none; }
@media (max-width: 939px) {
  html.mjs .track {
    display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
    margin-inline: calc((100% - 100vw) / 2); padding: 8px max(7vw, (100vw - 420px) / 2); scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  html.mjs .track::-webkit-scrollbar { display: none; }
  html.mjs .track.dragging { scroll-snap-type: none; }
  html.mjs .track > li { flex: 0 0 86vw; max-width: 420px; scroll-snap-align: center; transform: scale(calc(1 - var(--dist, 0) * .06)); opacity: calc(1 - var(--dist, 0) * .2); }
  /* The pager under a swipe row, built like the dock: the lens in the exact middle, the
     ticks sliding under it, the count a small centred line below. */
  html.mjs .wheel { display: block; margin-top: var(--s-3); touch-action: pan-y; cursor: grab; user-select: none; -webkit-user-select: none; }
  .wheel .ruler { border-radius: var(--r-pill); }
  .wheel .ticks { width: 281.5px; }
  .wheel .tag { display: block; margin-top: var(--s-2); text-align: center; }
  .wheel b { display: inline-block; font-weight: inherit; color: var(--ink); }
}

/* ---------- 7. Chapter 1: the opening screen (the name, one line, one button) ---------- */

.hero { position: relative; width: var(--wrap); margin-inline: auto; min-height: 100vh; min-height: 100svh; padding: 88px 0 64px; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }
.hero-copy { display: flex; flex-direction: column; align-items: center; gap: var(--s-5); max-width: 100%; }
.hero h1 { display: flex; flex-direction: column; align-items: center; gap: var(--s-3); max-width: 100%; }
/* The line under the name. One text (hero.title); it wraps and balances by itself, so a
   line of similar or shorter length needs no other change. */
.hero-line { display: block; max-width: 26em; font-size: clamp(1.25rem, 2.1vw, 1.75rem); line-height: 1.25; font-weight: 600; letter-spacing: -.01em; }
.hero-line > span { display: block; }
.actions { display: flex; flex-direction: column; align-items: center; gap: var(--s-1); }
.hero .btn-white { min-width: min(100%, 240px); }
.quiet-link { display: inline-flex; align-items: center; min-height: 44px; padding: 0 12px; white-space: nowrap; font-size: .9375rem; font-weight: 500; color: var(--ink-2); text-decoration: underline; text-decoration-color: var(--rim); text-underline-offset: 4px; }
.quiet-link:hover { color: var(--ink); }
@media (min-width: 640px) { .actions { flex-direction: row; gap: var(--s-3); } }

/* ---------- 7b. Chapter 2: what it is for ---------- */

/* A heading, one paragraph, three quiet panels: side by side on a desktop window, stacked
   below that. Nothing here moves by itself. */
.why-list { display: grid; gap: var(--s-3); margin-top: var(--s-5); }
.why-list p { margin-top: var(--s-2); color: var(--ink-2); }
.why .lead { text-wrap: pretty; }
@media (min-width: 940px) { .why-list { grid-template-columns: repeat(3, 1fr); gap: var(--s-4); } }

/* ---------- 8. Chapter 3: the demo ---------- */

.demo { position: relative; width: var(--wrap); margin-inline: auto; padding: 24px 0 64px; }
.demo-copy { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-3); }
.try-list { display: none; }
.device-wrap { margin: var(--s-4) -8px 0; }
.device { position: relative; height: clamp(520px, 78vh, 640px); height: clamp(520px, 78svh, 640px); max-width: 420px; margin-inline: auto; border-radius: var(--r-sheet); background: var(--ground); box-shadow: 0 28px 56px -32px rgba(0,0,0,.85); }
.device::before { z-index: 4; }
.device[data-state="open"]::before { opacity: 1; transition-delay: var(--d-after); }
.screen { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; background: var(--ground); isolation: isolate; }
.sb { position: absolute; left: 50%; top: -70%; height: 240%; pointer-events: none; transform: rotate(-32deg); }
.sb-1 { width: 90%; margin-left: -45%; background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.043) 25%, rgba(255,255,255,.085) 50%, rgba(255,255,255,.043) 75%, rgba(255,255,255,0)); }
.sb-2 { width: 54%; margin-left: -27%; background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.03) 25%, rgba(255,255,255,.06) 50%, rgba(255,255,255,.03) 75%, rgba(255,255,255,0)); }
@keyframes sb-slide { from { transform: rotate(-32deg) translate3d(-80%,0,0); } to { transform: rotate(-32deg) translate3d(80%,0,0); } }
html.anim:not(.lite) .sb-1 { animation: sb-slide var(--t-band-1) var(--ease-sine) var(--d-band-1) infinite alternate paused; }
html.anim:not(.lite) .sb-2 { animation: sb-slide var(--t-band-2) var(--ease-sine) var(--d-band-2) infinite alternate paused; }
html.anim[data-scene="focus"] .sb { animation-play-state: running; }
.badge { position: absolute; z-index: 3; top: 14px; right: 14px; padding: 4px 10px; border-radius: var(--r-pill); background: var(--stroke); font-size: .8125rem; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-2); }

.scene { position: absolute; inset: 0; z-index: 1; display: flex; flex-direction: column; transition: opacity var(--t-screen) var(--ease-screen) var(--t-hold), filter var(--t-screen) var(--ease-screen) var(--t-hold), visibility 0s linear var(--t-hold); }
.device[data-scene="block"] .scene-chat, .device[data-scene="chat"] .scene-block {
  opacity: 0; visibility: hidden; pointer-events: none; filter: blur(var(--blur-screen));
  transition: opacity var(--t-exit) var(--ease-exit) var(--t-hold), filter var(--t-exit) var(--ease-exit) var(--t-hold), visibility 0s linear calc(var(--t-exit) + var(--t-hold));
}
.scene-block { align-items: center; justify-content: center; text-align: center; gap: 12px; padding: 56px 16px 16px; }
.block-disc { width: 96px; height: 96px; margin-top: auto; }
.block-disc .hg { width: 84px; height: 84px; }
.block-title { font-size: 1.75rem; line-height: 1.1; font-weight: 700; letter-spacing: -.02em; }
.block-sub { font-size: .9375rem; line-height: 1.4; color: var(--ink-2); max-width: 17em; }
.block-app { display: inline-flex; align-items: center; gap: 14px; padding: 8px 16px 8px 8px; border-radius: var(--r-control); background: var(--panel); font-size: .9375rem; font-weight: 600; }
.ask { width: 100%; min-height: 52px; margin-top: auto; font-size: 1.0625rem; font-weight: 600; overflow: hidden; }
.demo-noscript { margin-top: auto; }
html.js .demo-noscript, html.js .demo-note-out { display: none; }
/* "Restart the demo" sits in the phone's top strip beside the badge, once the chat is open. */
.demo-reset { position: absolute; z-index: 3; left: 8px; top: 5px; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 8px; border-radius: var(--r-pill); font-size: .8125rem; font-weight: 600; color: var(--ink-2); transition: opacity var(--t-screen) var(--ease-screen) var(--t-hold); }
.demo-reset:hover { color: var(--ink); }
.demo-reset .g { width: 16px; height: 16px; }
.device[data-scene="block"] .demo-reset { opacity: 0; visibility: hidden; transition: var(--hide); }
/* Until it has been pressed once, a sheen crosses "Ask for time" every 6 s. */
@keyframes sheen { from { transform: translate3d(-140%,0,0) skewX(-20deg); } 15%, to { transform: translate3d(340%,0,0) skewX(-20deg); } }
html.anim:not(.lite) .ask::after { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 40%; pointer-events: none; background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.22), rgba(255,255,255,0)); transform: translate3d(-140%,0,0) skewX(-20deg); animation: sheen var(--t-sheen) var(--ease-screen) var(--d-sheen) infinite paused; }
html.anim[data-scene="focus"] .device:not(.asked) .ask::after { animation-play-state: running; }

.scene-chat { gap: 8px; padding: 48px 8px 8px; }
.chat-head { flex: none; height: 124px; padding: 8px 16px; border-radius: var(--r-head); display: flex; flex-direction: column; }
.head-row { display: flex; align-items: center; gap: 12px; min-height: 44px; }
.head-app { flex: 1; min-width: 0; font-size: .9375rem; line-height: 1.25; font-weight: 600; }
.head-state { display: flex; align-items: center; gap: 6px; font-size: .8125rem; font-weight: 400; color: var(--ink-3); }
.head-state .g-mark { width: 12px; height: 12px; transform: rotate(var(--turn, 0deg)); transition: transform var(--t-turn) var(--spring-turn); }
.counter { display: flex; gap: 4px; }
.counter i { position: relative; width: 16px; height: 4px; border-radius: var(--r-pill); background: var(--stroke); }
/* A used unlock fills white: a white layer fades in (no colour is animated). */
.counter i::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: var(--ink); opacity: 0; transition: opacity var(--t-number) linear; }
.counter i.used::after { opacity: 1; }
.head-two { position: relative; flex: 1; min-height: 0; }
.head-rules, .head-wheel { position: absolute; inset: 0; display: flex; align-items: center; gap: 12px; transition: opacity var(--t-screen) var(--ease-screen) var(--t-exit), visibility 0s linear var(--t-exit); }
[data-state="locked"] .head-wheel, [data-state="open"] .head-rules { opacity: 0; visibility: hidden; transition: var(--hide); }
.head-wheel .wheel-num { min-width: 2.4em; }
.head-wheel .ticks { --major: 168px; transition: transform var(--t-tick) linear; }
.banner { flex: none; display: flex; align-items: flex-start; gap: 8px; padding: 8px 10px; border-radius: var(--r-control); font-size: .8125rem; line-height: 1.4; color: var(--ink-2); }
.banner .g { width: 16px; height: 16px; margin-top: 1px; }
/* Older messages fade out under the card above the log; none is cut by a hard edge. */
.log { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; padding: 8px; scrollbar-width: thin; scrollbar-color: var(--stroke) transparent; border-radius: var(--r-control); -webkit-mask-image: linear-gradient(180deg, rgba(0,0,0,0) 0, #000 24px); mask-image: linear-gradient(180deg, rgba(0,0,0,0) 0, #000 24px); }
.log:focus-visible { outline-offset: -2px; }
.log > :first-child { margin-top: auto; }
.msg { display: flex; flex-direction: column; gap: 6px; max-width: 84%; font-size: .9375rem; line-height: 1.4; }
.msg-ai { align-self: flex-start; align-items: flex-start; }
.msg-user { align-self: flex-end; align-items: flex-end; }
.msg-sys { align-self: center; max-width: 100%; flex-direction: row; align-items: center; gap: 6px; padding: 2px 8px; font-size: .8125rem; color: var(--ink-3); text-align: center; }
.bub { display: block; padding: 12px; border-radius: var(--r-bubble); overflow-wrap: anywhere; }
.msg-ai .bub { background: var(--panel); box-shadow: inset 0 0 0 .5px var(--stroke); }
.msg-user .bub { background: var(--ink); color: var(--on-white); }
.msg .verdict { order: 2; font-size: .8125rem; }
.verdict .lock { width: 14px; height: 14px; }
.w-hide { opacity: 0; }
.typing .bub { display: grid; gap: 8px; width: 150px; }
.typing i { display: block; height: 12px; border-radius: var(--r-pill); background: var(--skeleton); overflow: hidden; position: relative; }
.typing i:nth-child(2) { width: 83%; } .typing i:nth-child(3) { width: 50%; }
@keyframes shimmer { from { transform: translate3d(-100%,0,0); } to { transform: translate3d(170%,0,0); } }
html.anim:not(.lite) .typing i::after { content: ""; position: absolute; inset: 0; width: 60%; background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.2), rgba(255,255,255,0)); animation: shimmer var(--t-shimmer) ease-in-out infinite; }
@keyframes msg-in { from { opacity: .01; transform: translate3d(0,8px,0) scale(.96); } }
html.anim .msg.fresh { animation: msg-in var(--t-screen) var(--ease-screen) backwards; transform-origin: 0 100%; }
html.anim .msg-user.fresh { transform-origin: 100% 100%; }

.chat-actions { flex: none; min-height: 46px; display: flex; }
/* The row scrolls sideways and cuts what leaves it: it spans the screen, with room for a pressed pill. */
.chips { display: flex; gap: 8px; flex: 1; min-width: 0; overflow-x: auto; scrollbar-width: none; margin: -4px -8px; padding: 4px 32px 4px 8px; -webkit-mask-image: linear-gradient(90deg, #000 86%, rgba(0,0,0,0)); mask-image: linear-gradient(90deg, #000 86%, rgba(0,0,0,0)); }
.chips::-webkit-scrollbar { display: none; }
.chip { flex: none; min-height: 44px; padding: 0 14px; border-radius: var(--r-pill); background: var(--fill-quiet); box-shadow: inset 0 0 0 1px var(--rim); font-size: .9375rem; white-space: nowrap; transition: transform var(--t-release) var(--spring-release); }
.chip[aria-disabled="true"] { opacity: .6; }
.lock-now { flex: 1; }
.composer { flex: none; display: flex; align-items: center; gap: 8px; }
.composer input { flex: 1; min-width: 0; min-height: 48px; padding: 12px 16px; border: 0; border-radius: var(--r-field); background: var(--glass-solid); box-shadow: inset 0 0 0 1px var(--rim); font-size: 1rem; }
.composer input::placeholder, .field::placeholder { color: var(--ink-3); opacity: 1; }
.composer input:disabled { opacity: .5; }
.send { flex: none; display: grid; place-items: center; width: 44px; height: 44px; border-radius: var(--r-round); background: var(--ink); color: var(--on-white); opacity: 0; visibility: hidden; transform: scale(.92); transition: opacity var(--t-exit) var(--ease-exit), transform var(--t-exit) var(--ease-exit), visibility 0s linear var(--t-exit); }
.send .g { stroke-width: 2.4; }
.composer.has-text .send { opacity: 1; visibility: visible; transform: none; transition: opacity var(--t-number) linear, transform var(--t-bouncy) var(--spring-bouncy); }
.send[aria-disabled="true"] { opacity: .5; }
.send:focus-visible, .btn-white:focus-visible, .lang [aria-pressed="true"]:focus-visible, .lang [aria-current="true"]:focus-visible { outline-color: var(--ink); box-shadow: 0 0 0 3px var(--ground), 0 0 0 8px rgba(0,0,0,.6); }

/* ---------- 9. Chapter 4: three steps ---------- */

.steps-pin { position: relative; width: var(--wrap); margin-inline: auto; padding-block: 64px; }
/* The five minutes at chapter size: above the head here, behind the stack on a pinned desktop. */
.word-clock { position: relative; left: auto; top: auto; width: max-content; margin: 0 auto var(--s-5); font-size: min(38vw, 240px); font-variant-numeric: tabular-nums; transform: none; }
.steps-head > * + * { margin-top: var(--s-3); }
.step { background: var(--panel); }
.step-txt { display: grid; grid-template-columns: auto 1fr; gap: 4px 16px; align-items: start; }
.step-n { grid-row: span 2; font: 300 3.25rem/1 var(--font-round); font-variant-numeric: tabular-nums; color: var(--ink-3); }
.step-txt p { grid-column: 2; color: var(--ink-2); }
.step-dots { display: none; }
.vis { position: relative; min-height: 140px; margin-bottom: var(--s-3); border-radius: var(--r-inner); background: var(--underlay); box-shadow: inset 0 0 0 1px var(--hairline); overflow: hidden; display: flex; flex-direction: column; justify-content: center; }
.vis-row { display: flex; align-items: center; gap: 14px; padding: 7px 14px; }
.vis-row + .vis-row { box-shadow: inset 0 1px 0 var(--hairline); }
.vis-row .sk { flex: 1; height: 10px; max-width: 120px; border-radius: var(--r-pill); background: var(--skeleton); }
.vis-row .lock { margin-left: auto; color: var(--ink-2); }
.vis-2 { gap: 8px; padding: 12px; }
.vis-2 .msg { font-size: .8125rem; max-width: 88%; }
.vis-2 .bub { padding: 8px 10px; border-radius: var(--r-control); }
.vis-3 { align-items: center; gap: 8px; }
.vis-3 .num { font: 300 3.25rem/1 var(--font-round); font-variant-numeric: tabular-nums; }
.vis-3 .when-done, .vis-3.done .when-run { display: none; }
.vis-3.done .when-done { display: inline; }
/* The little scenes play once when a step becomes the current one. */
html.anim .vis-1 .lock .sh { transform: rotate(30deg); }
html.anim .vis-1.play .lock .sh { transform: none; transition: transform var(--t-press) var(--spring-press); }
html.anim .vis-1.play .vis-row:nth-child(2) .sh { transition-delay: var(--t-hold); }
html.anim .vis-1.play .vis-row:nth-child(3) .sh { transition-delay: calc(2 * var(--t-hold)); }
html.anim .vis-2 .msg { opacity: .01; transform: translate3d(0,8px,0) scale(.96); }
html.anim .vis-2.play .msg { opacity: 1; transform: none; transition: opacity var(--t-screen) var(--ease-screen), transform var(--t-screen) var(--ease-screen); }
html.anim .vis-2.play .msg-user { transition-delay: var(--d-after); }
html.anim .vis-3 .lock .sh { transform: rotate(30deg); }
html.anim .vis-3.done .lock .sh { transform: none; }

/* ---------- 10. Chapter 5: the rules decide ---------- */

.rules-pin { display: grid; gap: var(--s-5); }
.check-list { display: grid; gap: 12px; margin-top: var(--s-4); }
.check-list li { display: flex; align-items: flex-start; gap: 14px; }
.check-list .tile { margin-top: -2px; }
/* "Who does what": four rows of one height (a label line and room for two lines of text)
   beside a ruler with one long tick per row. The lens rests on a row's long tick, level
   with its label; --i is the row it is on (0 to 3). Still, it is on "Rules". */
.flow { padding: var(--s-3); }
.flow-body { position: relative; display: grid; grid-template-columns: 56px 1fr; margin-top: var(--s-3); --row: 98px; --at: 21px; }
.vruler { position: relative; }
.vticks {
  position: absolute; left: 50%; top: 0; width: 20px; height: calc(4 * var(--row)); margin-left: -10px;
  background:
    linear-gradient(180deg, var(--tick-major) 0, var(--tick-major) 1.5px, rgba(255,255,255,0) 1.5px) 50% calc(var(--at) - .75px) / 20px var(--row) repeat-y,
    linear-gradient(180deg, var(--tick-minor) 0, var(--tick-minor) 1.5px, rgba(255,255,255,0) 1.5px) 50% 6.25px / 12px 14px repeat-y;
}
.lens-v { position: absolute; left: 50%; top: var(--at); width: 48px; height: 48px; margin: -24px 0 0 -24px; transform: translate3d(0, calc(var(--i, 2) * var(--row)), 0); transition: transform var(--t-move) var(--ease-screen); }
.lens-v .vticks { top: calc(50% - var(--at)); transform-origin: 50% var(--at); transform: scale(1.25) translate3d(0, calc(var(--i, 2) * var(--row) * -1), 0); transition: transform var(--t-move) var(--ease-screen); }
.node { position: relative; height: var(--row); padding: calc(var(--at) - 10px) 0 0 var(--s-3); opacity: var(--o-quiet); transition: opacity var(--t-move) linear; }
.node-k { display: block; font-size: .8125rem; line-height: 20px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; }
.node-t { display: block; margin-top: 2px; font-size: .9375rem; line-height: 1.4; }
.node::before { content: ""; position: absolute; left: 0; top: var(--at); width: 3px; height: 28px; margin-top: -14px; border-radius: var(--r-pill); background: var(--ink); opacity: 0; transform: scaleY(.2); transition: transform var(--t-move) var(--ease-screen), opacity var(--t-move) linear; }
/* The row the lens is on is the lit one: "Rules" on a still page, the row motion.js names otherwise. */
.flow:not(.live) .node.key, .flow.live .node.on { opacity: 1; }
.flow:not(.live) .node.key::before, .flow.live .node.on::before { opacity: 1; transform: none; }
@media (max-width: 359px) { .flow-body { grid-template-columns: 48px 1fr; } .node { padding-left: 12px; } }

/* ---------- 11. Chapter 6: pricing ---------- */

/* The price note is an eyebrow above the cards, smaller and quieter than body text. */
.plans-prices { max-width: var(--w-text); margin-top: var(--s-5); }
.plans-prices + .track { margin-top: var(--s-3); }
.plan { height: 100%; padding: var(--s-2); }
.plan-in { height: 100%; display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-2); }
.plan-in > p:not(.label):not(.status) { color: var(--ink-2); font-size: .9375rem; line-height: 1.45; }
.plan-in .status { margin-top: auto; }
/* "Free at launch" is the one tag with a bright rim and a lighter fill: more presence, no colour. */
.status-hook { background: rgba(255,255,255,.22); box-shadow: inset 0 0 0 1px var(--rim-hi); }
.plan-in .g { width: 28px; height: 28px; stroke-width: 1.6; margin-bottom: var(--s-2); }
.plan-slot { transition: opacity var(--t-press) linear; }
.plans-note { margin-top: var(--s-4); }

/* ---------- 12. Chapter 7: limits (on purpose almost still) ---------- */

.limits { display: grid; gap: var(--s-5); }
.limits-list { padding: 0 var(--s-3); }
.limits-list li { display: grid; grid-template-columns: 1.5em 1fr; gap: 0 8px; padding: 14px 0; }
.limits-list li + li { box-shadow: inset 0 1px 0 var(--hairline); }
.limits-list .num { font-variant-numeric: tabular-nums; color: var(--ink-3); font-weight: 600; line-height: 1.5625rem; }
.limits-list p { margin-top: 4px; color: var(--ink-2); }

/* FAQ after the limits: native details in a quiet panel, no chapter number. */
.faq { display: grid; gap: var(--s-4); }
.faq-list { padding: 0 var(--s-3); max-width: var(--w-text); }
.faq-list details + details { box-shadow: inset 0 1px 0 var(--hairline); }
.faq-list summary { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); min-height: 44px; padding: 12px 0; font-weight: 600; cursor: pointer; list-style: none; }
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list summary::after { content: ""; flex: none; width: 8px; height: 8px; margin-right: 4px; border: solid var(--ink-3); border-width: 0 2px 2px 0; transform: rotate(45deg); transition: transform var(--t-release) var(--spring-release); }
.faq-list details[open] summary::after { transform: translateY(3px) rotate(-135deg); }
.faq-list details p { padding-bottom: 16px; color: var(--ink-2); }

/* ---------- 13. Chapter 8: locked again, the waitlist ---------- */

.join { position: relative; min-height: 100vh; min-height: 100svh; display: grid; place-items: center; padding: 128px var(--gut) 96px; }
.join-col { position: relative; width: 100%; max-width: 560px; display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--s-3); }
.join-col::before { content: ""; position: absolute; z-index: -1; left: 50%; top: 50%; width: 720px; max-width: 100vw; height: 116%; transform: translate3d(-50%,-50%,0); background: radial-gradient(closest-side, rgba(8,8,8,.55), rgba(8,8,8,0)); pointer-events: none; }
/* The lock lights move behind this chapter and the footer: small print is one step
   brighter here, so it keeps its contrast on the brightest spots. */
.join, body[data-page="home"] .foot { --ink-3: var(--ink-2); }
.join .word { top: 74px; z-index: -2; }
@media (min-width: 390px) { .join .word { top: 82px; } }
.join h2 { font-size: 2.5rem; }
.join-card { width: 100%; margin-top: var(--s-2); padding: var(--s-2); text-align: left; }
.join-card .underlay { display: grid; gap: var(--s-3); }
#wl-fields { display: grid; gap: 12px; }
#wl-fields:disabled > * { opacity: .5; }
#wl-fields label { font-size: .9375rem; font-weight: 600; }
.field { width: 100%; min-height: 50px; padding: 12px 16px; border: 0; border-radius: var(--r-control); background: var(--fill-quiet); box-shadow: inset 0 0 0 1px var(--rim); font-size: 1rem; }
.field[aria-invalid="true"], .check input[aria-invalid="true"] { box-shadow: inset 0 0 0 2px var(--ink); }
.err { font-size: .9375rem; font-weight: 600; color: var(--ink); }
.err:empty { display: none; }
.err::before, .wl-status[data-kind="err"]::before { content: "!"; display: inline-grid; place-items: center; width: 18px; height: 18px; margin-right: 8px; border-radius: var(--r-round); box-shadow: inset 0 0 0 1.5px var(--ink); font-size: .75rem; font-weight: 700; vertical-align: 2px; }
.check { display: grid; grid-template-columns: 44px 1fr; align-items: start; }
.check-hit { display: grid; place-items: center; width: 44px; height: 44px; margin: -10px 0 0 -10px; }
.check input { -webkit-appearance: none; appearance: none; width: 24px; height: 24px; margin: 0; border-radius: var(--r-tile); background: var(--fill-quiet); box-shadow: inset 0 0 0 1px var(--rim); cursor: pointer; display: grid; place-items: center; }
.check input:checked { background: var(--ink); }
.check input:checked::after { content: ""; width: 11px; height: 6px; margin-top: -3px; border-left: 2.5px solid var(--on-white); border-bottom: 2.5px solid var(--on-white); transform: rotate(-45deg); }
.check input:disabled { cursor: default; }
.check label { font-weight: 400 !important; font-size: .9375rem; line-height: 1.45; color: var(--ink-2); }
.check a { display: inline-block; padding: 12px 0; margin: -4px 0 -12px; font-size: .9375rem; color: var(--ink); text-underline-offset: 3px; grid-column: 2; }
#wl-fields .btn { width: 100%; min-height: 52px; }
#wl-fields:disabled .btn { background: var(--fill-quiet); color: var(--ink); box-shadow: inset 0 0 0 1px var(--rim); cursor: default; }
.wl-status:empty { display: none; }
.wl-status { font-weight: 600; }
.wl-status[data-kind="ok"] { display: flex; align-items: flex-start; gap: 8px; padding: 12px 14px; border-radius: var(--r-control); background: var(--stroke); }
.wl-status[data-kind="ok"]::before { content: "\2713"; font-weight: 700; }
html.anim .wl-status[data-kind="ok"] { animation: msg-in var(--t-screen) var(--ease-screen) backwards; }
#join-download .btn { width: 100%; }

/* ---------- 14. Footer ---------- */

.foot { width: var(--wrap); margin-inline: auto; padding: 32px 0 calc(88px + env(safe-area-inset-bottom, 0px)); display: grid; gap: var(--s-3); justify-items: start; box-shadow: inset 0 1px 0 var(--hairline); }
.foot nav { display: flex; flex-wrap: wrap; gap: 0 8px; margin-left: -10px; }
.foot .fine { max-width: var(--w-text); }

/* ---------- 15. Legal pages and the not-found page ---------- */

.legal-main { position: relative; z-index: 2; width: min(var(--w-text) + 2 * var(--gut), 100%); margin-inline: auto; padding: calc(96px + env(safe-area-inset-top, 0px)) var(--gut) 64px; }
.legal { margin-top: var(--s-4); padding: var(--s-3); color: var(--ink-2); font-size: 1.0625rem; line-height: 1.55; overflow-wrap: break-word; }
.legal h1 { font-size: 2.125rem; line-height: 1.15; color: var(--ink); letter-spacing: -.02em; }
.legal h2 { font-size: 1.25rem; line-height: 1.25; font-weight: 600; color: var(--ink); letter-spacing: 0; margin-top: var(--s-5); }
.legal p, .legal ul, .legal address { margin-top: 12px; }
.legal ul { list-style: disc; padding-left: 1.25em; }
.legal li + li { margin-top: 8px; }
.legal strong { color: var(--ink); font-weight: 600; }
.legal a { color: var(--ink); text-underline-offset: 3px; }
.legal address { font-style: normal; }
.legal code { font-family: var(--font-mono); font-size: .9375rem; }
.legal .lang-block + .lang-block { margin-top: 64px; padding-top: var(--s-5); box-shadow: inset 0 1px 0 var(--hairline); }
mark.ph { background: var(--fill-quiet); color: var(--ink); outline: 1px dashed rgba(255,255,255,.6); outline-offset: 1px; border-radius: var(--r-mark); padding: 0 4px; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.draft { display: flex; gap: 10px; align-items: flex-start; margin: 0 0 var(--s-4) !important; padding: 12px 14px; border-radius: var(--r-control); background: var(--fill-quiet); outline: 1px dashed rgba(255,255,255,.6); color: var(--ink); font-weight: 600; font-size: .9375rem; }
.draft::before { content: "!"; flex: none; display: grid; place-items: center; width: 20px; height: 20px; border-radius: var(--r-round); box-shadow: inset 0 0 0 1.5px var(--ink); font-size: .8125rem; }
.mode-when { font-size: .8125rem; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3); margin-top: var(--s-4) !important; }
html[data-mode] .mode-when { display: none; }
html[data-mode="soon"] [data-mode-block]:not([data-mode-block~="soon"]),
html[data-mode="waitlist"] [data-mode-block]:not([data-mode-block~="waitlist"]),
html[data-mode="launched"] [data-mode-block]:not([data-mode-block~="launched"]) { display: none; }

.lockscreen { position: relative; z-index: 2; min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-3); text-align: center; padding: 96px var(--gut) 64px; }
.lockscreen .btn { margin-top: var(--s-3); }

/* ---------- 16. Motion: start states exist only with html.anim ---------- */

html.anim .rv, html.anim .rvb, html.anim .rvo {
  opacity: .01;
  transition: opacity var(--t-screen) var(--ease-screen), transform var(--t-screen) var(--ease-screen), filter var(--t-screen) var(--ease-screen);
  transition-delay: calc(var(--base, 0ms) + var(--n, 0) * var(--stagger));
}
html.anim .rv { transform: translate3d(0,16px,0); }
html.anim .rvb { transform: translate3d(0,16px,0) scale(.92); filter: blur(var(--blur-screen)); }
html.touch .rvb, html.lite .rvb { filter: none; }   /* arrives during the scroll: fade and move only */
html.anim .in .rv, html.anim .in .rvb, html.anim .in .rvo, html.anim .rv.in, html.anim .rvb.in, html.anim .rvo.in { opacity: 1; transform: none; filter: none; }
.d1 { --n: 1; } .d2 { --n: 2; } .d3 { --n: 3; } .d4 { --n: 4; } .d5 { --n: 5; }
/* Headlines arrive word by word (45 ms apart). */
html.anim [data-split] .w { display: inline-block; opacity: .01; transform: translate3d(0,12px,0); transition: opacity var(--t-screen) var(--ease-screen), transform var(--t-screen) var(--ease-screen), filter var(--t-screen) var(--ease-screen); transition-delay: calc(var(--base, 0ms) + var(--w, 0) * var(--word-gap)); }
html.anim [data-split].in .w { opacity: 1; transform: none; filter: none; }
@media (min-width: 640px) { html.anim:not(.lite):not(.touch) [data-split]:not(.in) .w { filter: blur(var(--blur-screen)); } }
.hero-copy { --base: var(--d-hero); }
.hero-go { --base: var(--d-hero-late); }

/* The opening screen leaves by scroll (--out, written by motion.js): line and buttons
   fade; the grains of the name lift away by themselves, the still name fades. No blur. */
html.anim .hero-line, html.anim .hero-go, html.anim .hero-name:not(.sand) { opacity: calc(1 - var(--out, 0)); }
/* The mark goes first: pinned, before chapter 2 begins to show; flowing, by the time
   chapter 2 is the current chapter (its top in the middle of the window). */
html.anim .hero-lens { opacity: calc(1 - var(--k, 3.2) * var(--out, 0)); }
html.pin-a .hero-lens { --k: 1.4; }
/* Not pinned: the sheet arrives by its own scroll; at rest it is no layer of its own. */
html.anim:not(.pin-a) .device-wrap { opacity: var(--e); transform: translate3d(0, calc((1 - var(--e)) * 24px), 0) scale(calc(.94 + .06 * var(--e))); }
html.anim:not(.pin-a) .device-wrap.still { transform: none; }

/* ---------- 17. Desktop ---------- */

@media (min-width: 940px) {
  h1 { font-size: clamp(3rem, 5.2vw, 4.5rem); }
  .sec { padding-block: 96px; }
  .card { padding: var(--s-4); }
  .join .word { font-size: 14vw; }
  html[lang="de"] .join .word { font-size: 10vw; }
  /* Not pinned (short window, or a finger): the five minutes stand beside the heading. */
  .word-clock { position: absolute; right: 0; top: 32px; margin: 0; font-size: min(12vw, 148px); }

  .demo { display: grid; grid-template-columns: 5fr 7fr; align-items: center; gap: var(--s-5); padding-block: 96px; }
  .try-list { display: grid; gap: 4px; }
  .try-list li { font-size: .8125rem; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3); }
  /* Beside the phone there is room for the honesty note; the phone's own banner makes way for the chat. */
  html.js .demo-note-out { display: block; }
  html.js .banner { display: none; }
  .device-wrap { margin: 0; justify-self: center; }
  /* As tall as the window allows between the bar and the dock, never narrower than its top strip needs. */
  .device { --dev-h: clamp(448px, calc(100vh - 164px), 700px); height: var(--dev-h); width: max(calc(var(--dev-h) * .4865), 264px); max-width: none; border-radius: var(--r-device); background: var(--glass-solid); box-shadow: inset 0 1px 0 rgba(255,255,255,.28), 0 40px 80px -40px rgba(0,0,0,.9); }
  .screen { inset: 8px; border-radius: var(--r-screen); }

  .track { grid-template-columns: repeat(3, 1fr); gap: var(--s-4); }
  .rules-pin { grid-template-columns: 7fr 5fr; gap: 48px; align-items: center; }
  .flow { padding: var(--s-4); }
  .flow-body { grid-template-columns: 72px 1fr; }
  .lens-v { width: 64px; height: 64px; margin: -32px 0 0 -32px; }
  .node-t { font-size: 1.0625rem; }
  .limits { grid-template-columns: 5fr 7fr; align-items: start; }
  .limits-head { position: sticky; top: 120px; }
  .limits-list { padding: 0 var(--s-4); }
  .limits-list li { padding: 20px 0; }
  .legal { padding: var(--s-5); }
  .join-card { padding: var(--s-2); }
  .join-card .underlay { padding: var(--s-4); }

  /* The three options stand as a shallow fan and straighten as they arrive. */
  html.anim .plan-slot { perspective: 1600px; }
  html.anim .plan { -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--glass-solid); transform: rotateY(calc(var(--fan, 0) * var(--ry, 0deg) + var(--tly, 0deg))) rotateX(var(--tlx, 0deg)) translate3d(0, 0, calc(var(--fan, 0) * var(--tz, 0px))); transition: transform var(--t-press) var(--ease-screen); }
  html.anim .plan-slot:nth-child(1) .plan { --ry: 6deg; --tz: -24px; }
  html.anim .plan-slot:nth-child(3) .plan { --ry: -6deg; --tz: -24px; }
  html.anim .plan-list.has-focus .plan-slot:not(.focus) { opacity: .8; }
  html.anim .plan-slot.focus .plan::before { opacity: 1; }
}

/* Pinned stages: a desktop window, motion allowed, and only a stage whose composition fits
   between the top bar and the dock (motion.js measures that and sets pin-a, pin-b, pin-c).
   A stage that follows a pinned one starts under it (the negative margin), so one fades
   out and the next fades in on the spot (--v): nothing slides under the bar. */
html.pin-a .stage-a { height: calc(100vh + 330vh); height: calc(100svh + 330vh); }
html.pin-b .steps { height: calc(100vh + 180vh); height: calc(100svh + 180vh); }
html.pin-c .rules { height: calc(100vh + 170vh); height: calc(100svh + 170vh); }
html.pin-a.pin-b .steps, html.pin-b.pin-c .rules { margin-top: -100vh; margin-top: -100svh; }
/* The flowing chapter after the last pinned stage comes up as that stage fades, so no screen stays empty. */
html.pin-c .plans, html.pin-b:not(.pin-c) .rules, html.pin-a:not(.pin-b) .steps { margin-top: -22vh; }
/* Cut above and below only: a blurred headline needs room at the sides. */
html.pin-a .stage-a-pin, html.pin-b .steps-pin, html.pin-c .rules-pin { position: sticky; top: 0; height: 100vh; height: 100svh; overflow: hidden; overflow: visible clip; }
html.pin-a .demo, html.pin-b .steps-pin, html.pin-c .rules-pin { opacity: var(--v); }
.off { pointer-events: none; }

html.pin-a .hero, html.pin-a .why, html.pin-a .demo { position: absolute; inset: 0; width: var(--wrap); min-height: 0; margin-inline: auto; }
html.pin-a .hero-copy { transform: translate3d(0, calc(var(--out, 0) * -24px), 0); }
/* Chapter 2 stands where the name stood: it comes up from below as the name's line has
   faded, holds, and leaves upwards before the phone begins to show. One number from
   motion.js: --w runs from -1 (not yet there) through 0 (there) to 1 (gone). */
html.pin-a .why { padding: 0; pointer-events: none; }
html.pin-a .why-in { position: absolute; left: 0; right: 0; top: 50%; opacity: calc(1 - max(var(--w), -1 * var(--w))); transform: translate3d(0, calc(-50% - var(--w) * 24px), 0); }
html.pin-a .stage-a[data-part="why"] .why-in { pointer-events: auto; }
/* A short window: a tighter setting, so chapter 2 fits wherever the phone of chapter 3 does. */
@media (max-height: 639px) { html.pin-a .why .lead { font-size: 1.125rem; } html.pin-a .why-list { margin-top: var(--s-4); } html.pin-a .why .card { padding: var(--s-3); } }
html.pin-a .demo { padding: 0; display: block; pointer-events: none; }
html.pin-a .demo-copy { position: absolute; left: 0; top: 50%; width: 42%; pointer-events: auto; opacity: var(--in, 0); transform: translate3d(0, calc(-50% + (1 - var(--in, 0)) * 24px), 0); }
/* The phone arrives with chapter 3: it rises, turns upright and comes into focus. */
html.pin-a .device-wrap { position: absolute; left: 72%; top: 50%; margin: 0; pointer-events: auto; opacity: calc(var(--pose) * 3); transform: translate3d(-50%, calc(-50% + (1 - var(--pose)) * 12vh), 0); }
html.pin-a .device { transform: perspective(1400px) rotateY(calc((1 - var(--pose)) * -14deg)) rotateX(calc((1 - var(--pose)) * 6deg)) scale(calc(.9 + var(--pose) * .1)); }
html.pin-a .stage-a:not([data-part="demo"]) .demo-copy, html.pin-a .stage-a:not([data-part="demo"]) .device-wrap, html.pin-a .stage-a:not([data-part="hero"]) .hero-copy, html.pin-a .demo.off .demo-copy, html.pin-a .demo.off .device-wrap { pointer-events: none; }

html.pin-b .word-clock { right: 4%; top: auto; bottom: max(10%, 88px); font-size: min(15vw, 24vh); }
html.pin-b .steps-pin { padding: 76px 0 80px; display: flex; flex-direction: column; justify-content: center; }
html.pin-b .steps-head, html.pin-b .steps-list, html.pin-b .step-dots { width: 42%; }
html.pin-b .steps-list { display: grid; grid-template-columns: 1fr; margin-top: var(--s-4); }
/* All three steps lie in one cell, so the cell is as tall as the longest text: nothing jumps. */
html.pin-b .step { grid-area: 1 / 1; background: none; padding: 0; opacity: 1; filter: none; transform: none; }
/* Between steps the text fades and moves a little. No blur: on the iPad it was cut along a hard line. */
html.pin-b .step-txt { display: block; opacity: 0; transform: translate3d(0,12px,0); pointer-events: none; transition: opacity var(--t-exit) var(--ease-exit), transform var(--t-exit) var(--ease-exit); }
html.pin-b .step.on .step-txt { opacity: 1; pointer-events: auto; transform: none; transition: opacity var(--t-screen) var(--ease-screen) var(--t-exit), transform var(--t-screen) var(--ease-screen) var(--t-exit); }
html.pin-b .step-n { display: block; font-size: clamp(4rem, min(9vw, 15vh), 8rem); color: var(--ink); margin-bottom: var(--s-3); }
html.pin-b .step-txt p { margin-top: var(--s-2); font-size: 1.125rem; }
html.pin-b .step-dots { display: flex; gap: 8px; margin-top: var(--s-4); }
.step-dots i { width: 32px; height: 4px; border-radius: var(--r-pill); background: var(--stroke); position: relative; overflow: hidden; }
.step-dots i::after { content: ""; position: absolute; inset: 0; background: var(--ink); transform: scaleX(0); transform-origin: 0 50%; transition: transform var(--t-press) var(--ease-screen); }
.step-dots i.on::after { transform: none; }
/* The app taken apart: three layers in an isometric stack. One rule for every step: the
   current step's layer is lit (opaque, bright glass, lifted), the two others are the same
   faint outline whichever they are. The lit fill is a layer of its own that fades in. */
html.pin-b .vis {
  position: absolute; left: 74%; top: 58%; width: 320px; height: 208px; margin: -104px 0 0 -160px; border-radius: var(--r-card);
  background: var(--glass-clear); box-shadow: inset 0 0 0 1px var(--rim); isolation: isolate;
  opacity: .26;
  /* The turn follows the scroll (--b) without a transition; the current layer's lift is a
     move of its own (translate) with one. */
  transform: perspective(1400px) rotateX(55deg) rotateZ(calc(-32deg + var(--b, 0) * 12deg)) translate3d(0, 0, var(--z, 0px));
  translate: 0 0;
  transition: opacity var(--t-screen) var(--ease-screen), translate var(--t-screen) var(--ease-screen);
}
html.pin-b .vis::before { content: ""; position: absolute; z-index: -1; inset: 0; border-radius: inherit; background: var(--glass-lit); box-shadow: inset 0 1px 0 rgba(255,255,255,.4), inset 0 0 0 1px var(--rim), 0 40px 60px -30px rgba(0,0,0,.9); opacity: 0; transition: opacity var(--t-screen) var(--ease-screen); }
html.pin-b .vis-2 { --z: 90px; } html.pin-b .vis-3 { --z: 180px; }
html.pin-b .step.on .vis { opacity: 1; translate: 0 -32px; }
html.pin-b .step.on .vis::before { opacity: 1; }
html.pin-b .vis-row { padding: 14px 16px; }
html.pin-b .vis-2 { padding: var(--s-3); }
html.pin-b .vis-2 .msg { font-size: .9375rem; }

html.pin-c .rules-pin { padding-block: 76px 80px; align-content: center; }
/* A short window: the same chapter in a tighter setting, so it still fits and stays pinned. */
@media (max-height: 779px) { html.pin-c .rules .lead { font-size: 1.0625rem; } html.pin-c .check-list { gap: 8px; margin-top: var(--s-3); font-size: .9375rem; } html.pin-c .flow { padding: var(--s-3); } }

/* ---------- 18. Phone only ---------- */

@media (max-width: 639px) {
  .device { max-width: none; }
  .legal h1 { font-size: 1.75rem; }
}
@media (min-width: 640px) and (max-width: 939px) {
  .sec, .steps-pin { max-width: var(--w-text); }
  .rules-pin, .limits { max-width: var(--w-text); }
}

/* ---------- 19. Conditions ---------- */

/* Reduced motion, by the system setting (also without scripts) or by the pause button. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition-duration: var(--t-reduced) !important; transition-delay: 0s !important; transition-timing-function: ease-in-out !important; scroll-behavior: auto !important; }
}
html.reduced *, html.reduced *::before, html.reduced *::after { animation: none !important; transition-duration: var(--t-reduced) !important; transition-delay: 0s !important; transition-timing-function: ease-in-out !important; }
html.reduced, html.lite { --blur-screen: 0px; }
/* While the pause button switches the tier, nothing eases: pinned stages come and go in one step. */
html.switching * { transition-property: none !important; }

@media (prefers-reduced-transparency: reduce) {
  .glass { background: var(--glass-solid); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
@media (prefers-contrast: more) {
  :root { --ink-2: #fff; --ink-3: #fff; --o-quiet: 1; --tick-minor: rgba(255,255,255,.65); --tick-major: #fff; --tick-dot: rgba(255,255,255,.45); --rim: rgba(255,255,255,.45); --stroke: rgba(255,255,255,.45); --hairline: rgba(255,255,255,.45); }
  .glass { background: var(--ground); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
@media (forced-colors: active) {
  .glass, .panel, .btn, .chip, .field, .composer input, .device, .status, .disc { border: 1px solid CanvasText; -webkit-backdrop-filter: none; backdrop-filter: none; }
  .ll, .band, .grain, .word, .hero-lens, .plens, .glass::before, .glass::after { display: none; }
  .word.hero-name { display: block; color: CanvasText; background: none; } .word.hero-name canvas { display: none; }
  .flow .node { opacity: 1 !important; }
}

/* Page changes between the start page and the legal pages. */
@view-transition { navigation: auto; }
@keyframes vt-out { to { opacity: 0; } }
@keyframes vt-in { from { opacity: .01; } }
::view-transition-old(root) { animation: vt-out var(--t-exit) var(--ease-exit) both; }
::view-transition-new(root) { animation: vt-in var(--t-screen) var(--ease-screen) both; }
@media (prefers-reduced-motion: reduce) { ::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--t-reduced); } }

@media print { .ground, .word, .hero-lens, .plens, .bar, .dock { display: none; } .word.hero-name { display: block; color: #000; background: none; } .word.hero-name canvas { display: none; } body { background: #fff; color: #000; } }
