/* =========================================================================
   Looper — homepage
   The page opens on the headline with the logo breathing behind it. Then one
   picture: Looper in the middle as a second brain for your golf. What you
   Looper hears goes in; Understand, Practice with purpose and On-course support draw
   on it. Last, a companion: the logo again, the app's own greeting, where to get
   it. Content: docs/CONTENT.md.
   Colours mirror the app (ios/LooperColors.swift), light and dark.
   imprint.html and privacy.html still use styles.css.
   ========================================================================= */

/* MARK: tokens */
:root {
  color-scheme: light;
  --bg: #f6f3ea;
  --ink: #14201a;
  --ink-2: #5b6a63;
  --ink-3: #7e8b85;
  --rule: #e1dccd;
  --card: rgba(0, 0, 0, .035);
  --green: #16a34a;
  --green-ink: #15803d;
  --teal: #0f7c7e;
  --amber: #b45309;
  --amber-ring: rgba(180, 83, 9, .8);
  --pill: #fbfaf6;
  --pill-shadow: 0 1px 2px rgba(10, 36, 24, .07);
  --dash: rgba(20, 32, 26, .28);
  --bubble: rgba(227, 234, 201, .85);
  --band-rgb: 22, 163, 74;
  /* the read band: each stretch in its own colour (ReadStreamView.hue(ofStretch:), 20.10.2026) */
  --rs-reliable: 22, 163, 74;
  --rs-mixed: 245, 158, 11;
  --rs-unpredictable: 220, 38, 38;
  --rs-blind: 126, 139, 133;
  --band-a0: .15;
  --band-a1: .23;
  --miss: #d70015;
  --btn-fg: #faf8f3;
  --btn-bg: #0a2418;
  --btn-bg-hover: #14532d;
  --logo-ink: #0a2418;
  --halo: rgba(250, 248, 243, 1);
  --halo-think: rgba(251, 191, 36, .7);
  --aura-1: rgba(74, 222, 128, .46);
  --aura-2: rgba(74, 222, 128, .25);
  --aura-3: rgba(34, 197, 94, .1);
  --aura-think: rgba(251, 191, 36, .4);
  --stage-bg: radial-gradient(circle at 18% 28%, rgba(74, 222, 128, .08), transparent 50%), radial-gradient(circle at 84% 72%, rgba(251, 191, 36, .10), transparent 50%), linear-gradient(180deg, #f5f1e6, #faf8f3);
  --sel-bg: #0a2418;
  --sel-fg: #faf8f3;
  --sel-ico: rgba(255, 255, 255, .14);
  --good: #1f7a35; --good-soft: rgba(52, 199, 89, .17); --good-solid: #248a3d;
  --medium-solid: #b86e00;
  --bad: #c4001a; --bad-soft: rgba(255, 59, 48, .13); --bad-solid: #d70015;
  --on-solid: #fff;
  --mark-g: rgba(36, 138, 61, .42); --mark-b: rgba(215, 0, 21, .3);

  /* The page speaks in a smooth sans (SF Pro on Apple devices, as in the app's UI);
     the serif is kept for what the app itself sets in serif: Looper's voice, the
     player's sentences, the read. */
  --display: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --serif: "Newsreader", "New York", "Iowan Old Style", Georgia, serif;
  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, system-ui, sans-serif;
  --round: ui-rounded, "SF Pro Rounded", -apple-system, system-ui, sans-serif;
  --measure: 32rem;
  --gut: clamp(16px, 5vw, 48px);
}
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --bg: #0a100d;
    --ink: #e6e9e7;
    --ink-2: #9aa7a0;
    --ink-3: #6c7a73;
    --rule: #1f2a24;
    --card: rgba(255, 255, 255, .04);
    --green: #4ade80;
    --green-ink: #4ade80;
    --teal: #5ad1d3;
    --amber: #fbbf24;
    --amber-ring: rgba(251, 191, 36, .8);
    --pill: #1b2a23;
    --pill-shadow: none;
    --dash: rgba(230, 233, 231, .28);
    --bubble: #152821;
    --band-rgb: 74, 222, 128;
    --rs-reliable: 74, 222, 128;
    --rs-mixed: 251, 191, 36;
    --rs-unpredictable: 248, 113, 113;
    --rs-blind: 154, 167, 160;
    --band-a0: .14;
    --band-a1: .21;
    --miss: #ff6961;
    --btn-fg: #4ade80;
    --btn-bg: rgba(74, 222, 128, .12);
    --btn-bg-hover: rgba(74, 222, 128, .22);
    --logo-ink: #faf8f3;
    --halo: rgba(22, 101, 52, 1);
    --halo-think: rgba(251, 191, 36, .55);
    --aura-1: rgba(34, 197, 94, .42);
    --aura-2: rgba(22, 101, 52, .34);
    --aura-3: rgba(22, 101, 52, .13);
    --aura-think: rgba(251, 191, 36, .34);
    --stage-bg: radial-gradient(circle at 50% 40%, rgba(74, 222, 128, .04), transparent 40%), linear-gradient(#080c0a, #0c0f0d);
    --sel-bg: #4ade80;
    --sel-fg: #0a100d;
    --sel-ico: rgba(10, 16, 13, .14);
    --good: #30d158; --good-solid: #30d158;
    --medium-solid: #ffb340;
    --bad: #ff6961; --bad-solid: #ff6961;
    --on-solid: #0b1410;
    --mark-g: rgba(48, 209, 88, .42); --mark-b: rgba(255, 105, 97, .42);
  }
}

/* MARK: base */
* { box-sizing: border-box; }
/* What the browser shows above the page and past either end (the status bar, the bounce) is the root's
   colour: the script sets data-edge to what is at the top of the screen, the cream of the headline and
   the sheets, or the green the picture stands on */
html { -webkit-text-size-adjust: 100%; background: var(--bg); }
html[data-edge="stage"], html[data-edge="stage"] body { background: var(--stage); }
html[data-edge="sheet"], html[data-edge="sheet"] body { background: var(--sheet-edge); }
body { margin: 0; background: var(--bg); color: var(--ink); font: 17px/1.55 var(--sans); -webkit-font-smoothing: antialiased; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--green); outline-offset: 3px; border-radius: 4px; }
.wrap { max-width: 76rem; margin: 0 auto; padding-inline: var(--gut); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* MARK: nav */
.nav { display: flex; align-items: center; justify-content: space-between; padding-block: 22px; }
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; font-weight: 600; letter-spacing: -.01em; }
.logo { width: 28px; height: 28px; background: var(--green); -webkit-mask: url(looper-mark.png) center / contain no-repeat; mask: url(looper-mark.png) center / contain no-repeat; }

/* MARK: hero — the headline, with the logo breathing behind it */
.hero { position: relative; isolation: isolate; overflow: hidden; min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; background: var(--stage-bg); }
/* its foot runs into the green the picture stands on, so the page scrolls on without an edge */
.hero { background: linear-gradient(transparent 62%, var(--stage)), var(--stage-bg); }
.hero .nav { width: 100%; justify-content: center; }
.hero-body { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 8px var(--gut) 72px; }
.hero-mark { position: relative; margin-bottom: clamp(24px, 4vh, 44px); }
h1 { font-family: var(--display); font-weight: 600; font-size: clamp(2.6rem, 6.4vw, 5.25rem); line-height: 1.04; letter-spacing: -.03em; margin: 0; max-width: 14ch; text-wrap: balance; }
.sub { font-size: clamp(1.05rem, 1.8vw, 1.25rem); line-height: 1.5; color: var(--ink-2); max-width: 34rem; margin: 20px auto 0; text-wrap: balance; }
.scroll-cue { position: absolute; left: 50%; bottom: clamp(16px, 4vh, 36px); transform: translateX(-50%); display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; color: var(--ink-2); box-shadow: inset 0 0 0 1px var(--rule); background: var(--pill); animation: cue 2.6s ease-in-out infinite; }
.scroll-cue svg { width: 18px; height: 18px; }
@keyframes cue { 50% { transform: translate(-50%, 5px); } }

/* The logo, breathing (BreathingLogoView): ±4.5% on a 5.2 s breath, the halo
   swelling on the in-breath only */
.hero-logo { display: block; position: relative; width: clamp(108px, 12vw, 168px); aspect-ratio: 1; }
.hero-logo i { position: absolute; inset: 0; background: var(--logo-ink); -webkit-mask: url(looper-mark-640.png) center / contain no-repeat; mask: url(looper-mark-640.png) center / contain no-repeat; animation: logo-breath 5.2s ease-in-out infinite; }
@keyframes logo-breath { 0%, 50%, 100% { transform: scale(1); } 25% { transform: scale(1.045); } 75% { transform: scale(.955); } }

/* The breath, big and wide: one glow from the logo out across the screen, swelling on the
   in-breath */
.aura { position: absolute; left: 50%; top: 50%; width: 220vmax; height: 220vmax; transform: translate(-50%, -50%); z-index: -1; pointer-events: none; }
.aura::before { content: ""; position: absolute; inset: 0; border-radius: 50%; background: radial-gradient(circle closest-side, var(--aura-1) 0%, var(--aura-2) 10%, var(--aura-3) 28%, transparent 56%); transform: scale(.86); opacity: .6; animation: aura-breath 5.2s ease-in-out infinite; transition: background .6s ease; }
@keyframes aura-breath { 0%, 50%, 100% { transform: scale(.86); opacity: .6; } 25% { transform: scale(1.08); opacity: 1; } }

/* Looper's presence: the logo, breathing (LooperStatusLogoView) */
.orb { display: block; position: relative; flex: none; width: 32px; height: 32px; border-radius: 50%; background: radial-gradient(circle at 50% 40%, #163a28, #0a2418 70%); box-shadow: 0 0 0 1px rgba(74, 222, 128, .18), 0 4px 12px rgba(10, 36, 24, .25); animation: breathe 5.2s ease-in-out infinite; }
.orb i { position: absolute; inset: 6px; background: linear-gradient(120deg, #86efac, #4ade80 45%, #a7f3d0 60%, #4ade80 75%); background-size: 300% 100%; -webkit-mask: url(looper-mark.png) center / contain no-repeat; mask: url(looper-mark.png) center / contain no-repeat; animation: sheen 6s linear infinite; }
@keyframes breathe { 50% { transform: scale(1.05); } }
@keyframes sheen { to { background-position: -300% 0; } }

/* MARK: the headline, then one brain for your game.
   The page scrolls as a page from the headline into the picture; only there do the words scroll over it. */
.stack { position: relative; }
h2 { font-family: var(--display); font-weight: 600; font-size: clamp(2rem, 3.6vw, 3.25rem); line-height: 1.08; letter-spacing: -.022em; margin: 0; text-wrap: balance; }
h3 { font-family: var(--display); font-weight: 600; font-size: clamp(1.5rem, 2.6vw, 2rem); line-height: 1.12; letter-spacing: -.018em; margin: 0; text-wrap: balance; }

/* MARK: one brain for your game — Looper in the middle; what it hears goes in from
   above, what draws on it sits below. The picture stays docked (beside the words on a wide
   screen, on top on a phone) while the words scroll past; the script lights the part being
   read (data-state on the section). */
.brain { background: var(--bg); overflow-x: clip; }
/* The picture fills the screen behind and stays as it is; the words scroll over it on sheets of frosted
   glass, through which it shows, blurred. In the gaps between the sheets it plays what was just read. */
.brain-grid { display: grid; grid-template-columns: minmax(0, 1fr); }
.brain-dock, .brain-flow { grid-area: 1 / 1; }
.brain-dock { position: sticky; top: 0; align-self: start; height: 100vh; height: 100svh; padding: clamp(56px, 12vh, 140px) var(--gut) 0; overflow: clip; isolation: isolate; display: flex; align-items: center; justify-content: center; }
.lens { width: 100%; max-width: 50rem; display: grid; justify-items: center; }
/* once the words come in and the line over it has gone, the picture moves up (--rise from the script):
   15 % of the screen, less on a short one, so a grown name keeps clear of the words above */
.lens { transform: translateY(calc(var(--rise, 0) * -1 * min(15svh, max(0px, (100svh - 560px) * .5)))); will-change: transform; }
.diagram { position: relative; width: 100%; display: grid; justify-items: center; }
/* on a wide screen it steps back as the words come in (--zoom from the script) */
@media (min-width: 861px) {
  .diagram { transform: scale(var(--zoom, 1)); transform-origin: 50% 50%; will-change: transform; }
  /* the names and the words grow back part of the way, so they stay readable when it is smaller */
  .diagram .node { font-size: calc(clamp(15px, 1.25vw, 19px) * var(--lift, 1)); }
  .diagram .node[data-k="listen"] { font-size: calc(clamp(16px, 1.4vw, 20px) * var(--lift, 1)); }
  .diagram .node .lvl { font-size: calc(12px * var(--lift, 1)); }
  .diagram .frag { font-size: calc(clamp(15px, 1.7vw, 19px) * var(--lift, 1)); }
  .diagram .node .note { font-size: calc(13px * var(--lift, 1)); }
}
.core { position: relative; width: clamp(84px, 20vh, 200px); aspect-ratio: 1; }
.core .hero-logo { width: 100%; }
.core-in { position: relative; z-index: 1; }
.core-aura { position: absolute; left: 50%; top: 50%; width: 640%; aspect-ratio: 1; transform: translate(-50%, -50%); z-index: -1; pointer-events: none; }
.core-aura::before { content: ""; position: absolute; inset: 0; border-radius: 50%; background: radial-gradient(circle closest-side, var(--aura-1) 0%, var(--aura-1) 6%, var(--aura-2) 18%, var(--aura-3) 40%, transparent 72%); animation: aura-breath 5.2s ease-in-out infinite; }
/* Looper in the middle; the loop (Practice with purpose over Listen) on the left, what draws on it on the right */
.d-grid { width: 100%; display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); grid-template-areas: "pr core un" "li core co"; column-gap: clamp(8px, 2vw, 32px); row-gap: clamp(120px, 30vh, 300px); align-items: center; }
.d-grid .core { grid-area: core; }
.node[data-k="practice"] { grid-area: pr; } .node[data-k="listen"] { grid-area: li; }
.node[data-k="understand"] { grid-area: un; } .node[data-k="course"] { grid-area: co; }
/* the names stand over the upper dots and under the lower ones, so the picture spreads up and
   down rather than sideways */
.node.left, .node.right { display: flex; align-items: center; justify-content: center; text-align: center; gap: 10px; }
.node.left .dot, .node.right .dot { flex: none; }
.node[data-k="practice"], .node[data-k="course"] { flex-direction: column; }
.node[data-k="listen"], .node[data-k="understand"] { flex-direction: column-reverse; }
.node[data-k="practice"], .node[data-k="understand"] { align-self: end; }
.node[data-k="listen"], .node[data-k="course"] { align-self: start; }

/* the wires, and the pulses that run along them */
.wires { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; z-index: -1; }
.wire { fill: none; stroke: rgba(var(--band-rgb), .24); stroke-width: 2; stroke-linecap: round; transition: stroke .5s ease, stroke-width .8s ease; }
.wire.in, .wire.loop { stroke-dasharray: 2 6; }
/* the stroke of the mark itself: never drawn, only run along */
.wire.mark, .wire.mark.lit { stroke: transparent; filter: none; }
/* above the logo: the pulses, and a short light that runs through the stroke of the mark */
.wires-top { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; z-index: 2; }
.mark-glow { fill: none; stroke: #86efac; stroke-linecap: round; opacity: 0; filter: drop-shadow(0 0 4px rgba(74, 222, 128, .7)); }
/* the first time: the logo first (as the headline left it), then Listen, the three below, the loop */
.diagram.pre .node, .diagram.pre .wire { opacity: 0; }
.diagram.build .node { animation: node-in .7s cubic-bezier(.2, .7, .2, 1) both; }
.diagram.build .node[data-k="practice"] { animation-delay: .15s; }
.diagram.build .node[data-k="listen"] { animation-delay: .9s; }
.diagram.build .node[data-k="understand"] { animation-delay: 1.3s; }
.diagram.build .node[data-k="course"] { animation-delay: 1.4s; }
@keyframes node-in { from { opacity: 0; transform: translateY(8px) scale(.96); } }
.wire.lit { stroke: rgba(var(--band-rgb), .85); stroke-width: 2.5; filter: drop-shadow(0 0 5px rgba(var(--band-rgb), .55)); }
/* and its strand is drawn stronger */
.wire.strong { stroke-width: 4.5; stroke: rgba(var(--band-rgb), 1); }
.pulse { fill: var(--green); filter: drop-shadow(0 0 6px rgba(var(--band-rgb), 1)); }
.pulse.tail { filter: none; }

/* what the picture says, over it, while it is first seen (faded by the script as the words come in) */
/* in the same column, type and alignment as the words that follow */
.dock-head { position: absolute; left: 50%; transform: translateX(-50%); top: clamp(16px, 5vh, 56px); z-index: 3; width: 100%; max-width: calc(40rem + 2 * var(--gut)); padding: 0 var(--gut); text-align: left; pointer-events: none; }
.dock-head h2 { font-size: clamp(2rem, 3.6vw, 3.25rem); }
.dock-head p { margin: 14px 0 0; max-width: 38rem; color: var(--ink-2); font-size: clamp(1.15rem, 1.5vw, 1.32rem); line-height: 1.45; text-wrap: pretty; }
/* under each name, in the first view only, what it is */
.node .note { display: block; max-width: 11em; font: 500 12.5px/1.3 var(--sans); letter-spacing: 0; color: var(--ink-3); text-wrap: balance; transition: opacity .4s ease, translate 1s cubic-bezier(.33, .7, .2, 1); }
/* under Listen, while one of its levels is read, the level takes the place of the line */
.brain[data-state^="listen-"] .node[data-k="listen"] .note { opacity: 0; }

/* the four parts: a label and a dot where the wire meets it */
.node { appearance: none; background: none; border: 0; margin: 0; padding: 6px 4px; display: grid; justify-items: center; align-content: start; gap: 10px; font: 650 clamp(15px, 1.25vw, 19px)/1.25 var(--sans); letter-spacing: -.01em; color: var(--ink-2); text-align: center; text-wrap: balance; cursor: pointer; opacity: .45; transition: opacity .45s ease, color .45s ease, transform 1s cubic-bezier(.33, .7, .2, 1); -webkit-tap-highlight-color: transparent; }
/* the part being read grows around its dot (the script sets the origin there) */
.node { position: relative; --grow: 1.6; }
.node.grow { transform: scale(var(--grow)); }
/* near the edge of the screen its name moves in a little (--nudge from the script) */
.node.grow > span, .node.grow > .note { translate: var(--nudge, 0px) 0; }
.node:hover { opacity: .8; }
.node .dot { width: 14px; height: 14px; border-radius: 50%; background: var(--bg); box-shadow: inset 0 0 0 2px rgba(var(--band-rgb), .75); transition: background .45s, box-shadow .45s; }
/* the part in focus: its name on a soft green chip */
.node span { padding: 4px 9px; border-radius: 12px; transition: background .45s ease, translate 1s cubic-bezier(.33, .7, .2, 1); }
.brain:not([data-state="overview"]) .node.lit span { background: rgba(var(--band-rgb), .16); }
.node.lit { opacity: 1; color: var(--ink); }
.node.lit .dot { background: var(--green); box-shadow: 0 0 0 5px rgba(var(--band-rgb), .2), 0 0 14px rgba(var(--band-rgb), .7); }
.node.ping .dot { animation: ping .8s ease-out; }
@keyframes ping { 0% { box-shadow: 0 0 0 0 rgba(var(--band-rgb), .6); } 100% { box-shadow: 0 0 0 18px rgba(var(--band-rgb), 0); } }
.node[data-k="listen"] { font-size: clamp(16px, 1.4vw, 20px); }
/* a part that has just been lit: its name pops and its dot sends out two rings */
.node span { position: relative; }
.node.pop span { animation: pop .8s cubic-bezier(.2, .9, .3, 1.25); }
@keyframes pop { 0% { transform: scale(.92); } 35% { transform: scale(1.16); } 100% { transform: none; } }
.node.pop .dot { animation: ripple 1.2s ease-out; }
@keyframes ripple { 0% { box-shadow: 0 0 0 0 rgba(var(--band-rgb), .6), 0 0 0 0 rgba(var(--band-rgb), .35); } 100% { box-shadow: 0 0 0 22px rgba(var(--band-rgb), 0), 0 0 0 44px rgba(var(--band-rgb), 0); } }
/* under Listen, the level being read beside its name */
.node .lvl { position: absolute; left: 50%; transform: translateX(-50%); top: calc(100% + 8px); font: 600 12px/1 var(--sans); font-style: normal; letter-spacing: .07em; text-transform: uppercase; white-space: nowrap; color: var(--green-ink); opacity: 0; transition: opacity .4s ease; }
.brain[data-state^="listen-"] .node .lvl { opacity: 1; }

/* the player's words, on their way in */
.flow { position: absolute; inset: 0; pointer-events: none; }
.frag { position: absolute; left: 0; top: 0; width: max-content; max-width: min(18rem, 44%); font: italic 400 clamp(15px, 1.7vw, 19px)/1.3 var(--serif); color: var(--ink); text-align: center; opacity: 0; will-change: transform, opacity; }

/* MARK: the stage and the sheets.
   The picture's part of the page stands on the close's colour: paper with the brand's green-500 glow,
   the green the logo's aura casts on the last page. The words come over it on sheets of the page's own
   ground, and between them the picture shows on the green. In dark mode the same: the night with a
   green glow under the picture, the page's dark for the sheets. Brand palette only. */
/* --stage is paper-2 #f5f1e6 with 9% green-500 #22c55e (dark: the night #0a100d with 10%), written out
   so the browser's own bars can take it too (theme-color, set by the script) */
/* --sheet-edge: what a sheet looks like over the green (the page at 65% over the stage), for the bars */
:root { --page: #f6f3ea; --stage: #e2edda; --sheet-edge: #eff1e4; --glass-line: rgba(255, 255, 255, .7); }
@media (prefers-color-scheme: dark) {
  :root { --page: #0a100d; --stage: #0c2215; --sheet-edge: #0b1610; --glass-line: rgba(255, 255, 255, .07); }
}
.brain { --bg: var(--stage); }
.brain-flow > .chapter { --bg: var(--page); }
/* a sheet: frosted glass the full width of the screen. The page's own ground at 65%, the picture behind
   it blurred and a little brighter, a fine light line along its top and bottom edges. */
.brain-flow > .chapter { position: relative; isolation: isolate; padding-block: clamp(44px, 7vh, 84px); pointer-events: auto; }
.brain-flow > .chapter::before { content: ""; position: absolute; z-index: -1; top: 0; bottom: 0; left: 50%; width: 100vw; transform: translateX(-50%); background: color-mix(in srgb, var(--page) 65%, transparent); -webkit-backdrop-filter: blur(22px) saturate(1.5); backdrop-filter: blur(22px) saturate(1.5); box-shadow: inset 0 1px 0 var(--glass-line), inset 0 -1px 0 var(--glass-line); }

/* MARK: the words beside the picture — one chapter per part, read top to bottom */
.brain-flow { position: relative; z-index: 1; width: 100%; max-width: calc(40rem + 2 * var(--gut)); margin: 0 auto; padding: 160vh var(--gut) 70vh; padding-block: 160svh 70svh; pointer-events: none; }
/* (the first 160svh: "What is Looper?" and the picture hold a while before the first sheet comes over them) */
.brain-flow > .chapter:not(#listen), .listen-head, .level { pointer-events: auto; }
/* between two parts, most of a screen of picture */
.chapter + .chapter { margin-top: 78vh; margin-top: 78svh; }
/* Listen and its three cards are one stretch of words */
.listen-head + .levels { margin-top: clamp(32px, 5vh, 48px); }

.brain-flow h2 { font-size: clamp(2rem, 3.6vw, 3.25rem); }
.brain-flow p { color: var(--ink-2); margin: 14px 0 0; max-width: 38rem; text-wrap: pretty; }
.brain-flow .big { font-size: clamp(1.15rem, 1.5vw, 1.32rem); line-height: 1.45; }
.brain-flow .chapter > h3 { font-size: clamp(1.35rem, 2.1vw, 1.75rem); margin-top: 36px; }

/* Listen: one shot, measured and heard — the ball on one side, the player on the other */
.versus { display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.25fr); margin: 28px 0 6px; padding-block: 18px; border-block: 1px solid var(--rule); }
.versus small { display: block; margin-bottom: 10px; font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
.vs-you small { color: var(--green-ink); }
.vs-ball { padding-right: 18px; }
.vs-ball dl { margin: 0; display: grid; gap: 6px; }
.vs-ball dl div { display: flex; justify-content: space-between; gap: 10px; font: 500 14px/1.5 var(--round); font-variant-numeric: tabular-nums; }
.vs-ball dt { color: var(--ink-3); }
.vs-ball dd { margin: 0; color: var(--ink-2); white-space: nowrap; }
.vs-you { padding-left: 18px; border-left: 1px solid var(--rule); }
.vs-you ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.vs-you li { font: italic 400 clamp(15px, 1.4vw, 17px)/1.35 var(--serif); color: var(--ink); }

/* Listen: three levels, at three distances from the shot, each its own stretch of words */
/* side by side as flat cards, one at a time in the width of the words: swipe or scroll sideways,
   each card snaps into place */
.levels { list-style: none; display: flex; gap: 24px; padding: 0; overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scrollbar-width: none; pointer-events: auto; border-radius: 24px; }
.levels::-webkit-scrollbar { display: none; }
.levels:focus-visible { outline: none; }
.levels:focus-visible .level { box-shadow: inset 0 0 0 2px var(--green); }
.level { position: relative; flex: 0 0 100%; scroll-snap-align: start; scroll-snap-stop: always; padding: clamp(24px, 3vw, 36px); border-radius: 24px; background: color-mix(in srgb, var(--ink) 5%, var(--bg)); }
/* under the cards: dots for the three, arrows on the right */
.level-nav { display: flex; align-items: center; justify-content: space-between; margin-top: 18px; pointer-events: auto; }
.level-dots { display: flex; gap: 8px; padding: 10px 14px; border-radius: 999px; background: color-mix(in srgb, var(--ink) 6%, var(--bg)); }
.level-dots button { width: 8px; height: 8px; padding: 0; border: 0; border-radius: 99px; background: var(--ink-3); opacity: .45; cursor: pointer; transition: width .35s ease, opacity .35s ease; }
.level-dots button[aria-current] { width: 26px; opacity: 1; background: var(--ink); }
.level-arrows { display: flex; gap: 10px; }
.level-arrows button { display: grid; place-items: center; width: 40px; height: 40px; padding: 0; border: 0; border-radius: 50%; color: var(--ink); background: color-mix(in srgb, var(--ink) 7%, var(--bg)); cursor: pointer; transition: opacity .3s ease; }
.level-arrows button:disabled { opacity: .35; cursor: default; }
.level-arrows svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.when { display: block; font-size: 12px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--green-ink); }
.level h3 { margin-top: 8px; font-size: clamp(1.35rem, 2.1vw, 1.75rem); }
.level blockquote { margin: 16px 0 0; padding-left: 14px; border-left: 2px solid rgba(var(--band-rgb), .5); font: italic 400 clamp(1.1rem, 1.6vw, 1.25rem)/1.35 var(--serif); color: var(--ink); }
.brain-flow .level .why { font-size: 15px; line-height: 1.5; margin-top: 16px; }
.why b { color: var(--ink); font-weight: 600; }

/* Practice with purpose: what makes it purposeful, three short lines */
.purpose { list-style: none; margin: 28px 0 0; padding: 0; display: grid; gap: 16px; max-width: 38rem; }
.purpose li { padding-left: 16px; border-left: 2px solid rgba(var(--band-rgb), .5); color: var(--ink-2); line-height: 1.5; }
.purpose b { color: var(--ink); font-weight: 600; }

/* Words rise into place as they come into view (the script adds .rise, then .in) */
.js .rise { opacity: 0; transform: translateY(24px); transition: opacity .9s cubic-bezier(.25, .1, .25, 1), transform .9s cubic-bezier(.25, .1, .25, 1); }
.js .rise.in { opacity: 1; transform: none; }

/* One switch for all the motion, while the picture is on screen */
.motion { position: fixed; right: max(var(--gut), env(safe-area-inset-right)); bottom: max(18px, env(safe-area-inset-bottom)); z-index: 20; display: grid; place-items: center; width: 40px; height: 40px; padding: 0; border: 0; border-radius: 50%; color: var(--ink); background: color-mix(in srgb, var(--pill) 85%, transparent); box-shadow: inset 0 0 0 1px var(--rule), 0 6px 18px -10px rgba(10, 36, 24, .35); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); cursor: pointer; opacity: 0; pointer-events: none; transition: opacity .4s ease; }
.motion.on { opacity: 1; pointer-events: auto; }
.motion svg { width: 14px; height: 14px; fill: currentColor; }
.motion .i-play, .paused .motion .i-pause { display: none; }
.paused .motion .i-play { display: block; }
/* paused: everything that loops stands still (the script stops its own loop too) */
.paused *, .paused *::before, .paused *::after { animation-play-state: paused !important; }

/* MARK: a little of the app in each chapter — the read, the challenges, Looper Live */
.show { margin: 28px 0 4px; position: relative; }

/* Your read (ReadStreamView), small: titles over a band whose thickness is the count,
   strength by reading, dotted dividers; pills move as the read changes. The pill that
   moved gets the app's focus ring and pulses twice. */
.read { display: grid; grid-template-rows: auto clamp(170px, 24vh, 215px) auto; max-width: 38rem; }
.rs-titles, .rs-legend { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.rs-titles span { font: 500 15px/1.3 var(--serif); color: var(--ink); }
.rs-band { position: relative; }
.rs-band canvas { position: absolute; left: 0; pointer-events: none; }
.rs-haze { filter: blur(12px); opacity: .55; }
.rs-body { filter: blur(5px); }
.rs-band > i { position: absolute; top: 12%; bottom: 12%; width: 0; border-left: 1px dotted var(--dash); opacity: .7; }
.rs-band > i:nth-of-type(1) { left: 25%; } .rs-band > i:nth-of-type(2) { left: 50%; } .rs-band > i:nth-of-type(3) { left: 75%; }
.rp { position: absolute; left: 0; top: 0; transition: transform .95s cubic-bezier(.45, 0, .2, 1), opacity .5s ease; }
.rp span { display: block; position: relative; font: 600 13px/16px var(--sans); padding: 5px 10px; border-radius: 999px; background: var(--pill); box-shadow: var(--pill-shadow); color: var(--ink); white-space: nowrap; transition: box-shadow .5s, background .5s, outline-color .5s; }
.rp.hollow span { background: transparent; box-shadow: none; outline: 1px dashed var(--dash); outline-offset: -1px; color: var(--ink-2); }
.rp.untested span { box-shadow: 0 0 0 1.5px var(--amber-ring); }
.rp span::after { content: ""; position: absolute; inset: -4px; border-radius: 999px; border: 2px solid color-mix(in srgb, var(--ink) 50%, transparent); opacity: 0; transition: opacity .4s; }
.rp.focus span::after { opacity: 1; }
.rp.focus span { animation: focus-pulse 1.1s ease-in-out .95s 2; }
@keyframes focus-pulse { 50% { transform: scale(1.12); } }
/* a pill takes in each word that flies into it: a bump and a green ring */
.rp span::before { content: ""; position: absolute; inset: 0; border-radius: 999px; pointer-events: none; opacity: 0; }
.rp.hit span { animation: rp-hit .55s cubic-bezier(.3, 1.5, .5, 1); }
.rp.hit span::before { animation: rp-ring .8s ease-out; }
.rp.focus span, .rp.focus.hit span { animation: focus-pulse 1.1s ease-in-out .95s 2; }
@keyframes rp-hit { 40% { transform: scale(1.22); } }
@keyframes rp-ring { 0% { opacity: 1; box-shadow: 0 0 0 0 rgba(var(--band-rgb), .75); } 100% { opacity: 1; box-shadow: 0 0 0 16px rgba(var(--band-rgb), 0); } }
/* where a pill left from: a dashed outline, for a moment */
.rp.ghost { z-index: 0; }
.rp.ghost span { background: transparent; box-shadow: none; outline: 1.5px dashed rgba(var(--band-rgb), .9); outline-offset: -1px; color: var(--ink-3); animation: none; }
.rp.ghost span::after { opacity: 0; }
.rs-foot { display: grid; margin-top: 10px; min-height: 76px; }
.rs-legend, .rs-voices { grid-area: 1 / 1; transition: opacity .45s ease; }
.rs-legend { min-height: 18px; }
.rs-legend span { grid-column: 1; display: inline-flex; align-items: center; justify-content: center; gap: 5px; font-size: 11px; color: var(--ink-2); transition: opacity .5s; }
.rs-legend i { width: 7px; height: 7px; border-radius: 50%; background: var(--amber); opacity: .85; }
.read:not(.untested) .rs-legend span { opacity: 0; }
/* in "Built from what Looper heard", under the band: the part that moved and where to, then the
   voices that moved it */
.rs-voices { display: grid; justify-items: center; align-content: start; gap: 6px; text-align: center; opacity: 0; }
.brain-flow .rs-move { margin: 0; display: flex; align-items: baseline; justify-content: center; gap: 9px; font: 600 clamp(17px, 1.6vw, 19px)/1.3 var(--sans); letter-spacing: -.01em; color: var(--ink); animation: rs-rise .6s cubic-bezier(.2, .7, .2, 1) .5s both; }
.rs-move i, .rs-move em { font-style: normal; color: var(--green-ink); }
.brain-flow .rs-why { margin: 0; max-width: none; display: grid; justify-items: center; gap: 1px; font-size: 13px; line-height: 1.4; color: var(--ink-2); animation: rs-rise .6s cubic-bezier(.2, .7, .2, 1) .75s both; }
@keyframes rs-rise { from { opacity: 0; transform: translateY(6px); } }
.read.explain.voiced .rs-voices { opacity: 1; }
.read.explain.voiced .rs-legend { opacity: 0; }
/* what was heard, on its way in: the player's words as everywhere else (serif, italic), rising
   under the band and flying into the pill they move */
.rs-heard { position: absolute; left: 0; top: 0; z-index: 3; pointer-events: none; white-space: nowrap; font: italic 400 clamp(18px, 1.9vw, 21px)/1.3 var(--serif); color: var(--ink); opacity: 0; will-change: transform, opacity; }
/* what the words are about, over them, as under Listen ("Heard") */
.rs-tag { position: absolute; left: 0; top: 0; z-index: 3; pointer-events: none; white-space: nowrap; font: 600 11px/1.2 var(--sans); letter-spacing: .08em; text-transform: uppercase; color: var(--green-ink); opacity: 0; }
.read.flying .rs-voices, .read.flying .rs-legend span { opacity: 0 !important; transition: opacity .3s; }
.read + h3 { margin-top: 64px !important; }

/* Challenge cards (ChallengeCardView): title, area · level, the pressure line with its
   orange bar, the rules — the word above, the figure under it */
/* one flat card; the challenges change inside it, one fading into the next */
.drills { display: grid; max-width: 28rem; padding: 16px 18px; border-radius: 18px; background: var(--card); box-shadow: inset 0 0 0 1px var(--rule); }
.drill { grid-area: 1 / 1; align-self: start; display: grid; gap: 8px; text-align: left; opacity: 0; transform: translateY(6px); transition: opacity .45s ease, transform .6s ease; }
/* the next card comes in once the last one has gone */
.drill.on { opacity: 1; transform: none; transition-delay: .35s; }
.drill.off { opacity: 0; transform: translateY(-6px); }
.drill.reset { transition: none; }
.drill h4 { margin: 0; font: 600 16px/1.25 var(--sans); letter-spacing: -.01em; color: var(--ink); }
.badge { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--green-ink); }
.badge svg { width: 13px; height: 13px; flex: none; }
.drill .pressure { margin: 0; border-left: 2px solid var(--amber); padding-left: 10px; font-size: 13.5px; font-style: italic; line-height: 1.4; color: var(--ink-2); max-width: none; }
.drill-rules { display: grid; grid-template-columns: repeat(var(--n), minmax(0, 1fr)); gap: 1px 8px; border-top: 1px solid var(--rule); padding-top: 8px; }
.drill-rules small { display: block; font-size: 10.5px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-2); }
.drill-rules b { font: 600 16px/1.3 var(--round); font-variant-numeric: tabular-nums; color: var(--ink); }

/* Looper Live, small, one look per card: the camera, and what Looper saw beside it (spoken) */
.look-live { display: flex; align-items: center; gap: clamp(14px, 3vw, 24px); height: clamp(190px, 26vh, 240px); margin-top: 20px; text-align: left; }
.cam-box { position: relative; flex: none; height: 100%; aspect-ratio: 4 / 5; }
.cam-box .cam { position: absolute; left: 0; top: 0; width: 240px; transform-origin: 0 0; transform: scale(var(--k, .6)); }
.brain-flow .look .seen { flex: 1; min-width: 0; margin: 0; font: 400 clamp(17px, 1.7vw, 19px)/1.35 var(--serif); color: var(--ink); opacity: 0; transform: translateY(6px); transition: opacity .5s ease, transform .5s ease; }
.brain-flow .look .seen.on { opacity: 1; transform: none; }
.brain-flow .look .look-live + p { margin-top: 20px; }
/* the wind on the line: the phone swings round (--d, degrees off the line, from the script), the
   picture moves with it and the dial turns, as the app's WindIndicator does */
.cam.wind .cam-scene canvas { transform: translateX(calc(var(--d, 0) * -.25%)) scale(1.25); transition: transform 1.1s cubic-bezier(.4, 0, .2, 1); }
.cam-wind { position: absolute; right: 14px; top: 14px; z-index: 2; display: grid; justify-items: center; gap: 2px; padding: 5px 5px 4px; border-radius: 10px; background: rgba(0, 0, 0, .25); color: #fff; font: 600 10px/1.15 var(--sans); font-variant-numeric: tabular-nums; }
.cam-wind small { font-size: 9px; font-weight: 400; opacity: .8; }
.wind-dial { position: relative; width: 40px; height: 40px; border-radius: 50%; background: rgba(0, 0, 0, .45); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .25); display: grid; place-items: center; }
.wind-dial > i { position: absolute; left: 50%; top: 2px; width: 2px; height: 5px; margin-left: -1px; border-radius: 1px; background: rgba(255, 255, 255, .7); }
.wind-arrow { width: 19px; height: 19px; fill: none; stroke: #fff; stroke-width: 3.2; stroke-linecap: round; stroke-linejoin: round; transform: rotate(calc(135deg - var(--d, 0) * 1deg)); transition: transform 1.1s cubic-bezier(.4, 0, .2, 1); }
/* the third look is not the camera: the hole in the golfer's shot tracker, and the screenshot taken of it */
.cam.shot { background: #0b0f0d; }
.shot-screen { position: absolute; inset: 0; overflow: hidden; transition: transform .7s cubic-bezier(.2, .7, .2, 1), border-radius .7s ease, box-shadow .7s ease; }
.shot-screen svg { display: block; width: 100%; height: 100%; }
.cam.shot.snapped .shot-screen { transform: scale(.84) rotate(-2deg); border-radius: 16px; box-shadow: 0 0 0 5px #fff, 0 18px 36px rgba(0, 0, 0, .55); }
/* beside it, what Looper takes from it (taken in, not said) */
.brain-flow .look .seen.taken { display: grid; gap: 4px; font: 500 clamp(15px, 1.4vw, 16px)/1.35 var(--sans); color: var(--ink); }
.seen.taken small { margin-bottom: 4px; font: 600 11px/1.2 var(--sans); letter-spacing: .08em; text-transform: uppercase; color: var(--green-ink); }
/* then the call: spoken, beside the Looper orb; when the brain's pulse lands the orb rings */
.level-nav + h3 { margin-top: clamp(48px, 7vh, 72px) !important; }
.brain-flow .the-call { display: flex; align-items: flex-start; gap: 14px; margin: 18px 0 18px; max-width: 34rem; font: 400 clamp(19px, 2.2vw, 23px)/1.3 var(--serif); letter-spacing: -.01em; color: var(--ink); }
.the-call .orb { width: 32px; height: 32px; margin-top: 1px; }
.the-call .orb::after { content: ""; position: absolute; inset: 0; border-radius: 50%; opacity: 0; pointer-events: none; }
.the-call.ping .orb::after { animation: rp-ring 1s ease-out; }

/* Looper Live — the camera (painted grass, a ball, a watch, a trolley screen) and the
   app's own HUD lines (LooperLiveView) */
.cam { position: relative; width: 100%; aspect-ratio: 4 / 5; border-radius: 24px; overflow: hidden; background: #0b0f0d; box-shadow: 0 30px 60px -20px rgba(10, 36, 24, .45), 0 0 0 1px rgba(10, 36, 24, .08); isolation: isolate; }
.cam-scene { position: absolute; inset: 0; opacity: 0; transition: opacity .7s ease; }
.cam-scene.on { opacity: 1; }
.cam-scene canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.cam-scene .soft { filter: blur(9px) saturate(.9) brightness(.82); transform: scale(1.08); }
.cam-scene .depth { filter: blur(1.2px); }
.cam-flash { position: absolute; inset: 0; background: #fff; opacity: 0; pointer-events: none; z-index: 3; }
.cam-flash.go { animation: flash .5s ease-out; }
.cam-marks { position: absolute; inset: 18px; z-index: 2; pointer-events: none; transition: inset .5s cubic-bezier(.2, .7, .2, 1); }
.cam-marks i { position: absolute; width: 24px; height: 24px; border: 2px solid rgba(255, 255, 255, .75); }
.cam-marks i:nth-child(1) { left: 0; top: 0; border-right: 0; border-bottom: 0; border-top-left-radius: 8px; }
.cam-marks i:nth-child(2) { right: 0; top: 0; border-left: 0; border-bottom: 0; border-top-right-radius: 8px; }
.cam-marks i:nth-child(3) { left: 0; bottom: 0; border-right: 0; border-top: 0; border-bottom-left-radius: 8px; }
.cam-marks i:nth-child(4) { right: 0; bottom: 0; border-left: 0; border-top: 0; border-bottom-right-radius: 8px; }
.cam.holding .cam-marks { inset: 30px; }
.cam-label { position: absolute; left: 22px; top: 20px; z-index: 2; display: flex; align-items: center; gap: 7px; font: 600 12px/1 var(--sans); color: #fff; letter-spacing: .02em; padding: 7px 10px; border-radius: 999px; background: rgba(20, 24, 22, .35); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px); }
.cam-label i { width: 7px; height: 7px; border-radius: 50%; background: #4ade80; box-shadow: 0 0 0 3px rgba(74, 222, 128, .25); }
.cam-hud { position: absolute; left: 0; right: 0; bottom: 78px; z-index: 2; display: flex; justify-content: center; transition: opacity .35s, transform .35s; }
/* Looper's reading of the situation, like a subtitle in the viewfinder */
.hud-pill { display: inline-flex; align-items: center; gap: 8px; font: 500 13px/1 var(--sans); color: #fff; padding: 9px 14px; border-radius: 999px; background: rgba(30, 32, 31, .42); -webkit-backdrop-filter: blur(20px) saturate(1.4); backdrop-filter: blur(20px) saturate(1.4); box-shadow: inset 0 0 0 .5px rgba(255, 255, 255, .14); white-space: nowrap; }
.hud-pill svg { width: 15px; height: 15px; flex: none; }
.hud-pill .ring circle:last-child { stroke-dasharray: 38; stroke-dashoffset: 38; }
.cam.holding .hud-pill .ring circle:last-child { transition: stroke-dashoffset 1.1s linear; stroke-dashoffset: 0; }

/* the watch */
.watch { position: absolute; left: 50%; top: 47%; width: 56%; aspect-ratio: .84; transform: translate(-50%, -50%) rotate(-7deg); }
.watch .band-strap { position: absolute; left: 14%; right: 14%; background: linear-gradient(90deg, #17301f, #24442e 50%, #17301f); }
.watch .band-strap.up { bottom: 92%; height: 80%; border-radius: 14px 14px 0 0; }
.watch .band-strap.down { top: 92%; height: 80%; border-radius: 0 0 14px 14px; }
.watch .band-strap.down::after { content: ""; position: absolute; left: 50%; top: 24%; width: 8px; height: 8px; margin-left: -4px; border-radius: 50%; background: #0f2016; box-shadow: 0 18px 0 #0f2016, 0 36px 0 #0f2016; }
.watch .case { position: absolute; inset: 0; border-radius: 30%/26%; background: linear-gradient(145deg, #5d6360, #2a2e2c 40%, #1a1d1b 70%, #4a504d); box-shadow: 0 18px 30px rgba(0, 0, 0, .45), inset 0 1px 1px rgba(255, 255, 255, .25); }
.watch .crown { position: absolute; right: -5%; top: 26%; width: 7%; height: 15%; border-radius: 4px; background: linear-gradient(90deg, #3c413e, #6a706c); }
.watch .crown + .crown { top: 50%; height: 18%; width: 4.5%; right: -3%; }
.watch .screen { position: absolute; inset: 6.5%; border-radius: 26%/22%; background: #000; color: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; font-family: var(--round); text-align: center; padding: 8%; container-type: inline-size; }
.w-top { font-size: 8cqi; font-weight: 600; color: #8e9692; letter-spacing: .02em; }
.w-big { font-size: 34cqi; font-weight: 700; line-height: .95; letter-spacing: -.03em; margin-top: 4cqi; font-variant-numeric: tabular-nums; }
.w-lab { font-size: 7.5cqi; font-weight: 600; color: #4ade80; text-transform: uppercase; letter-spacing: .08em; }
.w-row { display: flex; gap: 12cqi; margin-top: 6cqi; font-size: 10cqi; font-weight: 600; color: #c9cfcc; font-variant-numeric: tabular-nums; }
.w-row b { color: #8e9692; font-weight: 600; margin-right: 2cqi; }
.w-haz { margin-top: 6cqi; display: inline-flex; align-items: center; gap: 3cqi; font-size: 9cqi; font-weight: 700; color: #64d2ff; background: rgba(100, 210, 255, .14); padding: 2.5cqi 5cqi; border-radius: 999px; }

/* the trolley screen */
.trolley { position: absolute; left: 50%; top: 44%; width: 66%; transform: translate(-50%, -50%) rotate(3deg); }
.trolley .dev { position: relative; aspect-ratio: 3 / 4; border-radius: 18px; background: linear-gradient(160deg, #2b302d, #121513 60%); padding: 6%; box-shadow: 0 24px 40px rgba(0, 0, 0, .5), inset 0 1px 1px rgba(255, 255, 255, .18); }
.trolley .dev svg { display: block; width: 100%; height: 100%; border-radius: 8px; }
.trolley .bar { position: absolute; left: -30%; right: -30%; top: 103%; height: 22px; border-radius: 11px; background: linear-gradient(#8b918e, #3b403d 55%, #222624); box-shadow: 0 10px 20px rgba(0, 0, 0, .4); }
.trolley .clamp { position: absolute; left: 38%; right: 38%; top: 96%; height: 26px; border-radius: 0 0 8px 8px; background: linear-gradient(#1b1e1c, #2c312e); }
@keyframes flash { 20% { opacity: .28; } }

/* MARK: a companion — the close: the logo again, the app's own greeting, where to get it */
/* The close comes up in the picture's place once the last chapter has gone (.closed on the section, from
   the script): the picture fades, the logo, the line, the greeting and the stores rise in one after another,
   on the same ground. */
.close-mark { height: 1px; margin-top: 65vh; margin-top: 65svh; }
.lens { transition: opacity .9s ease; }
.brain.closed .lens { opacity: 0; pointer-events: none; }
/* the pause switch is for the picture; at the close it steps aside too (and off the footer's links) */
.brain.closed .motion { opacity: 0; pointer-events: none; }
.dock-close { position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; pointer-events: none; }
.companion-in { display: grid; justify-items: center; gap: 18px; text-align: center; padding: clamp(56px, 9vh, 96px) var(--gut); }
.dock-close .companion-in > * { opacity: 0; transform: translateY(18px); transition: opacity .9s ease, transform 1.1s cubic-bezier(.2, .7, .2, 1); }
.brain.closed .dock-close .companion-in > * { opacity: 1; transform: none; }
.brain.closed .dock-close .companion-in > :nth-child(1) { transition-delay: .4s; }
.brain.closed .dock-close .companion-in > :nth-child(2) { transition-delay: .65s; }
.brain.closed .dock-close .companion-in > :nth-child(3) { transition-delay: .85s; }
.brain.closed .dock-close .companion-in > :nth-child(4) { transition-delay: 1.05s; }
.dock-close .hero-mark { margin-bottom: clamp(8px, 2vh, 20px); }
.dock-close h2 { font-size: clamp(2.4rem, 5.8vw, 4.6rem); line-height: 1.04; letter-spacing: -.03em; margin: 0; max-width: 14ch; }
.greet { font-family: var(--display); font-weight: 500; font-size: clamp(1.1rem, 2vw, 1.35rem); line-height: 1.4; color: var(--ink-2); margin: 0; text-wrap: balance; }
.stores { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-top: clamp(12px, 2vh, 24px); }
.store { display: grid; gap: 3px; min-width: 9.5rem; padding: 10px 18px; border-radius: 14px; box-shadow: inset 0 0 0 1px var(--rule); background: var(--card); text-align: left; }
.store small { font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
.store b { font-size: 16px; font-weight: 600; color: var(--ink-2); }

/* MARK: footer */
/* the footer stays on the close's green, the full width of the screen */
.footer { background: var(--stage); box-shadow: 0 0 0 100vmax var(--stage); clip-path: inset(0 -100vmax); }
.footer { border-top: 1px solid var(--rule); padding-block: 28px 40px; display: flex; flex-wrap: wrap; gap: 12px 24px; justify-content: space-between; font-size: 13px; color: var(--ink-3); }
.footer nav { display: flex; gap: 18px; flex-wrap: wrap; }
.footer a { text-decoration: none; }
.footer a:hover { color: var(--ink); }

/* MARK: narrow screens — the picture fills the screen behind and the words scroll over it on the
   glass sheets; in the gaps between them it plays. */
@media (max-width: 860px) {
  /* on a phone the picture is smaller */
  .core { width: clamp(80px, 12vh, 108px); }
  .d-grid { column-gap: 6px; row-gap: clamp(120px, 20vh, 190px); }
  .node { padding: 2px 0; font-size: 15px; }
  .node { --grow: 1.45; }
  .node.left, .node.right { gap: 8px; }
  .node[data-k="listen"] { font-size: 16.5px; }
  .node span { padding: 4px 7px; }
  /* the level under Listen's name */
  .node .lvl { font-size: 10.5px; line-height: 1.2; width: 7em; white-space: normal; text-align: center; }
  .frag { max-width: 42%; font-size: 15px; }
  .node .note { font-size: 11.5px; }
  .dock-head p { font-size: 17px; }
}
@media (max-width: 640px) {
  .brain-flow p { font-size: 16px; }
  .brain-flow .big { font-size: 17px; }
  .rs-titles span { font-size: 11.5px; letter-spacing: -.01em; }
  .rs-foot { min-height: 96px; }
  .rs-heard { font-size: 17.5px; }
  .rp span { font-size: 11.5px; line-height: 15px; padding: 4px 8px; }
  .drills { padding: 14px 15px; } .drill { gap: 7px; }
  .look-live { height: 196px; }
  .brain-flow .look .seen { font-size: 16px; }
  .brain-flow .the-call { font-size: 18px; }
  .vs-ball { padding-right: 12px; } .vs-you { padding-left: 12px; }
  .vs-ball dl div { font-size: 13px; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
