/* site/v5/v5.css — /v5/: the scrolling site's structure in the poster's art direction.
   Plan: docs/superpowers/specs/2026-09-15-v5-hybrid-design.md (the visual system, the sections, the motion).
   The page is the main page's template (site/v5/index.html) restyled: every ground is black or white, the
   headlines are the poster's thin capitals, the marks (a crosshair and a corner bracket) sit only beside a
   statistic, and type on a photograph sits straight on it (round two: no panes). The phone layer is site/v5/mobile.css. */

:root {
  --void: #000; --bone: #fff;
  --gutter: clamp(24px, 4.5vw, 64px);
  --cl: clamp(13px, 0.95vw, 15px);                 /* the mono callout, and the em every mark is drawn in */
  --ease: cubic-bezier(.2, .7, .2, 1);              /* everything that arrives, hovers or leaves */
  --ease-draw: cubic-bezier(.3, .6, .2, 1);         /* the lights only */
  --ease-glide: cubic-bezier(.19, 1, .22, 1);       /* v6 motion piece 0: the patient curve (gsap-setup.js's v5-glide) — the poster's clip out of its door */
  --ease-burst: cubic-bezier(.1, .9, .2, 1);        /* v6 motion piece 3: a ring (gsap-setup.js's v5-burst) — the page lights' touchdown; piece 5: a pressed state's release */
  --ease-gather: cubic-bezier(.6, 0, .8, .35);      /* v6 motion piece 5: every retraction toward its origin (gsap-setup.js's v5-gather) — the poster's clip back into its door */
}
html { overflow-x: clip; }
html, html body { background: var(--void); }

/* ---- grounds: black or white, nothing else --------------------------------------------------------- */
.v5-ground { position: relative; }
.v5-ground[data-ground="black"] { background: var(--void); color: var(--bone); }
.v5-ground[data-ground="white"] { background: var(--bone); color: var(--void); }

/* ---- type: two headline tiers (round two). Display for the campaign questions (the hero, the 58, the ½: 92 at 1440,
   44 at 390); section for the statements (66 / 32). A question is stacked in the top-left quadrant, never a banner. ---- */
.v5-hl { margin: 0; font-weight: 300; font-size: clamp(32px, 4.6vw, 72px); line-height: .96; letter-spacing: -.008em; text-transform: uppercase; max-width: 14em; text-wrap: balance; }
.v5-hl-display { font-size: clamp(44px, 6.4vw, 104px); line-height: .92; letter-spacing: -.012em; }
/* the short line under a number, and a number's marks in the number's own em ÷ 8 (--n is the Counter's size) */
.v5-short { font-size: 20px; line-height: 1.25; font-weight: 400; text-transform: uppercase; letter-spacing: .01em; }
.v5-hl .ln { display: block; margin-left: calc(var(--step-in, 0) * 1em); }   /* V4's stepped left edge, at 700px and up */
@media (max-width: 699px) {   /* v6: the phone's measure sets the breaks; the lines run on and the headline fades in whole */
  .v5-hl .ln { display: inline; margin-left: 0; }
  .v5-hl .ln + .ln::before { content: " "; }
  .v5-hl { text-wrap: balance; max-width: none; }
  .af-hero-hl .ln, .v5-hl[data-revealed] .ln { animation: none !important; }
  .v5-hl[data-revealed] { animation: v5-fade 400ms var(--ease) both; }
}
@media (max-width: 699px) { .v5-hl .ln { margin-left: 0; } }

/* ---- the section rules (v6 motion piece 5, the motion spec §6 "the page's arrival"): the template's five 2px rules (.v5-rule, the
   kicker inside; site/v6/index.html) in the ground's ink at both widths. Under 1024 the rule is the section's first mark — orientation
   before data: a ::before hairline drawn left → right over D.hair .40 on v5-draw from data-revealed (scaleX from 0, transform-origin
   0), its kicker fading D.headline .40 from R.headlineAt × D.hair 240 with the section's words (the reveal observer in index.html
   holds the headline and the block's children on the same clock); the div itself takes no rise. The laptop keeps its 640 rise on the
   whole div (piece 7). The hairline sits in the border's own 2px (border transparent, the ::before at -2px), so nothing moves. Drawn
   at rest (transform none): Reduce Motion shows the rule whole. ---- */
.v5-rule { border-top: 2px solid currentColor; }
@media (max-width: 1023px) {
  .v5-rule { position: relative; border-top-color: transparent; }
  .v5-rule::before { content: ""; position: absolute; left: 0; right: 0; top: -2px; height: 2px; background: currentColor; transform-origin: 0 50%; }
  .v5-rule[data-revealed]::before { animation: v5-rule-draw 400ms var(--ease-draw) both; }   /* D.hair on v5-draw */
  .v5-rule[data-revealed] > .sc-host-x > div { animation: v5-fade 400ms var(--ease) 240ms both; }   /* the kicker: D.headline from R.headlineAt × D.hair */
}
@keyframes v5-rule-draw { from { transform: scaleX(0); } to { transform: none; } }

/* ---- no panes (round two, 2026-09-16: "way too many boxes"): type sits straight on a photograph at the measured
   floor (the block-K reading, scripts/qa/v5-contrast.cjs) or on the ground beneath it. The one filled shape on
   the home page is the primary button. ---- */

/* ---- the marks (v4.css): a crosshair and a corner bracket, hairlines in the ground's ink ------------- */
.mk { position: absolute; pointer-events: none; --o: 1.6em; --arm: 2.6em; --leg: 2.4em; opacity: .9; }
.mk-cross { width: calc(var(--arm) * 2); height: calc(var(--arm) * 2); }
.mk-cross::before, .mk-cross::after { content: ""; position: absolute; background: currentColor; }
.mk-cross::before { left: 0; right: 0; top: 50%; height: 1px; }
.mk-cross::after { top: 0; bottom: 0; left: 50%; width: 1px; }
.mk-cross[data-at="tl"] { left: calc(-1 * (var(--o) + var(--arm))); top: calc(-1 * (var(--o) + var(--arm))); }
.mk-cross[data-at="tr"] { right: calc(-1 * (var(--o) + var(--arm))); top: calc(-1 * (var(--o) + var(--arm))); }
.mk-cross[data-at="bl"] { left: calc(-1 * (var(--o) + var(--arm))); bottom: calc(-1 * (var(--o) + var(--arm))); }
.mk-cross[data-at="br"] { right: calc(-1 * (var(--o) + var(--arm))); bottom: calc(-1 * (var(--o) + var(--arm))); }
.mk-br { width: var(--leg); height: var(--leg); }
.mk-br::before, .mk-br::after { content: ""; position: absolute; background: currentColor; }
.mk-br::before { left: 0; right: 0; height: 1px; } .mk-br::after { top: 0; bottom: 0; width: 1px; }
.mk-br[data-at="tl"] { left: calc(-1 * var(--o)); top: calc(-1 * var(--o)); }
.mk-br[data-at="tr"] { right: calc(-1 * var(--o)); top: calc(-1 * var(--o)); }
.mk-br[data-at="bl"] { left: calc(-1 * var(--o)); bottom: calc(-1 * var(--o)); }
.mk-br[data-at="br"] { right: calc(-1 * var(--o)); bottom: calc(-1 * var(--o)); }
.mk-br[data-at="tl"]::before, .mk-br[data-at="tr"]::before { top: 0; } .mk-br[data-at="bl"]::before, .mk-br[data-at="br"]::before { bottom: 0; }
.mk-br[data-at="tl"]::after, .mk-br[data-at="bl"]::after { left: 0; } .mk-br[data-at="tr"]::after, .mk-br[data-at="br"]::after { right: 0; }
.mk-br[data-at="tl"]::before, .mk-br[data-at="bl"]::before { transform-origin: 0 50%; } .mk-br[data-at="tr"]::before, .mk-br[data-at="br"]::before { transform-origin: 100% 50%; }
.mk-br[data-at="tl"]::after, .mk-br[data-at="tr"]::after { transform-origin: 50% 0; } .mk-br[data-at="bl"]::after, .mk-br[data-at="br"]::after { transform-origin: 50% 100%; }
/* a bracket that draws itself: the across leg, then the down leg. Drawn at rest; the motion system (step 6) holds a
   statistic's bracket undrawn (.is-undrawn) until its number has arrived. */
.mk-br.draws::before, .mk-br.draws::after { transition: transform .16s var(--ease); }
.is-undrawn .mk-br.draws::before { transform: scaleX(0); }
.is-undrawn .mk-br.draws::after { transform: scaleY(0); }
@media (max-width: 699px) { .mk { --o: 1.2em; --arm: 2.2em; --leg: 2em; } }

/* a statistic and its marks. The wrapper's em is the callout's (--cl), so the marks scale with the mono and never
   with the numeral. A pair on a left-set number puts the crosshair to its right and the bracket below-left, so both
   sit in the number's own field; the three lights keep their right-set callouts with the template's own marks. */
.v5-stat { position: relative; display: inline-flex; width: max-content; font-size: calc(var(--n, 106px) / 8); line-height: 1; vertical-align: baseline; }
.v5-stat .mk { --arm: 2.6em; --leg: 1.6em; }
.v5-stat .mk-cross { transition: transform 240ms var(--ease) 80ms; }
.is-undrawn .mk-cross { transform: scale(0); }
.v5-stat[data-marks="pair"] .mk-cross[data-at="tr"] { right: calc(-1 * (1.2em + var(--arm))); top: calc(-1 * var(--arm) + .06em); }   /* centred 1.2em right of the figure, at cap height */
.v5-stat[data-marks="pair"] .mk-br[data-at="bl"], .v5-stat[data-marks="bracket"] .mk-br { --o: .6em; }

/* ---- photographs: film grain on the laptop (the phone derivatives carry their own); no wash, no veil ----- */
.v5-photo { position: relative; isolation: isolate; }
@media (min-width: 1024px) {
  .v5-photo::after { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
    background: url(/v4/grain.png) 0 0 / 128px 128px; mix-blend-mode: overlay; opacity: .22; }
}
.v5-bleed { margin-left: calc(50% - 50vw); margin-right: calc(50% - 50vw); }   /* About's study photograph, edge to edge */

/* ---- icons: line drawings in the ground's ink; no glow, no tint ------------------------------------ */
i.ph-light { color: currentColor !important; }

/* ---- the design system's blush literals, where the bundle hardcodes them --------------------------- */
[style*="rgb(244, 236, 235)"] { color: #fff !important; }                    /* the primary button's text on a ground */
[style*="rgba(92, 51, 64, 0.08)"] { background: rgba(0, 0, 0, .06) !important; }   /* the secondary button's hover on a ground */
[style*="rgb(234, 220, 219)"] { background: transparent !important; }       /* the photograph's placeholder */

/* ---- the hero: the headline on the picture, the paragraph and the buttons straight on the hair ------- */
.af-hero-hl { color: var(--bone); }

/* ---- what gets in the way: the photograph as a band above the rows --------------------------------- */
.af-inway-band { display: grid; }

/* ---- the quiz on black ----------------------------------------------------------------------------- */
.af-arch-hl { color: var(--void); }
/* the quiz varies (Krish, 2026-09-16): the first question of each dimension carries that dimension's photograph as a band of
   40svh (never under 260px) with the name and line icon bottom-left in the picture's ink; the question, the options and the nav
   sit on black beneath. No pane, no rectangle, no type over a busy field. */
.af-quiz-band { background: var(--void); }
.af-quiz-band .af-quiz-band-name i.ph-light { color: currentColor !important; }
/* two headlines stand in a half-width column or on the arch's wall: a size cap keeps them to three lines at 1440 and 1920 */
.af-next-copy { padding-top: 55px; }   /* the paragraph's cap line on the headline's (the kicker's 31 + 24) */

/* ---- the numbers as light (round four): the layers of site/v5/num/, each filling the frame exactly (object-fit: fill;
   the frame's aspect is the file's). Per glyph group i (each digit, then the tail) two layers: g<i>, the glyph as light,
   and s<i>, the same light out of focus; then trail (the far streak of the whole number) and cloud (its glow). g0 is
   opaque, the rest carry alpha, so they composite with no blend mode. THE NUMBER FORMS once its box is a fifth in
   view (data-lit on the panel, set by the page script), the way a long exposure forms: the cloud blooms (0-1400ms),
   the far streak slides down its own line (150-1950); then (v6 motion piece 3, the motion spec §6 "the 58", R12: one
   body, struck once — the per-group schedule and its 14% slide are gone, reversal 24) the soft masses of every glyph
   arrive TOGETHER (s: 600-1800, rising R.light.rise 4% of the frame while scaling R.light.scale 1.12 → .985 about the
   glyph's own centre, --do / --po), the glyph glows land together under them (g: 1200-2000, from 4% up the line, to
   .4), and the WHOLE mass — the glows and the crisp layers — STRIKES as one brightness event (g and c: from 2000 over
   480, opacity R.strike .4 / 1 / .4 / 1 at R.strikeAt's shares 0 / ⅓ / ⅔ / ⅞ — the second dark step shorter, a
   strike-on and not a stutter (piece 3 review 2, a reversal of P7's equal thirds) — then held at 1; on the 31/8 the
   second number's g and c layers carry --sk and strike D.strike + D.strikeGap later, never with the first); a
   touchdown ring rises from the number's baseline centre (.lt-ring, an HTML hairline circle: from 2600 over 800, its
   size r R.ring.light 40px × .4 → --rmax / 40 on --ease-burst, its opacity .6 → 0 LINEAR over the full D.ring — review
   2, item 1: both on the burst read as a flash; the ruled v5-draw fade reads .057 at 50% and .010 at 75%, under the
   ruling's own floors of .1 / .02, so linear: .30 / .15; --rmax, per size from the markup, caps the reach 8px short of
   the nearest type box or another number's crisp box, 72 at most, never under the birth radius 16 — items 3 and 4) —
   the strike ends before the ring starts, and the ring's lowest pixel stays inside the light's box, above the callout
   (the spec's geometry: 89px clear at 390); the
   callout follows with its marks (--cl, unscaled) and only then the breathing and the drift (--rest). Every number
   here is the phone's D.light row ×2, scaled by --fm (.5 on the phone, mobile.css: masses 300-900, glows 600-1000,
   the strike 1000-1240, the ring 1300-1700, the callout 1600). Every g and s layer but g0 is cropped to its glyph's
   box (the markup carries the box per size in hundredths of the frame, --dl --dt --dw --dh and --pl --pt --pw --ph,
   and the origin inside it, --do --po; the ring its centre, --drx --dry / --prx --pry; scripts/v6/light_markup.py
   writes them from the manifest), so the rise is written in hundredths of the frame (--ty) and divided by the box
   (--h). Opacity and transform only, once; at rest the cloud alone breathes and the trail drifts, and only while the
   panel is in view (data-inview; reversal 34). ---- */
.af-light { --cl: 2800ms; --rest: 2900ms; --fm: 1; }   /* --fm scales every forming duration and delay (the phone .5, mobile.css); --cl and --rest are set per width, not scaled */
.af-light-wake { --cl: 3300ms; --rest: 3400ms; }   /* five glyphs: 3, 1, %, 8, % */
.af-light-num img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: fill; opacity: 0; }   /* g0 is opaque, the rest carry alpha: no blend mode */
.af-light-num .lt-cloud { transform-origin: 50% 100%; }
.af-light-num .lt-g, .af-light-num .lt-s, .af-light-num .lt-c { inset: auto; left: calc(var(--dl, 0) * 1%); top: calc(var(--dt, 0) * 1%); width: calc(var(--dw, 100) * 1%); height: calc(var(--dh, 100) * 1%); --w: var(--dw, 100); --h: var(--dh, 100); transform-origin: var(--do, 50% 50%); }
/* v6 motion piece 3: the touchdown ring — one hairline circle per number, 2 × R.ring.light 40px, scaled about the number's baseline centre (the laptop's --drx --dry here; the phone's --prx --pry in the media rule below) */
.af-light-num .lt-ring { position: absolute; left: calc(var(--drx, 50) * 1%); top: calc(var(--dry, 50) * 1%); --rmax: var(--drmax, 72); width: 80px; height: 80px; margin: -40px 0 0 -40px; box-sizing: border-box; border: 1px solid currentColor; border-radius: 50%; opacity: 0; transform: scale(.4); }
@media (max-width: 1023px) { .af-light-num .lt-g, .af-light-num .lt-s, .af-light-num .lt-c { left: calc(var(--pl, 0) * 1%); top: calc(var(--pt, 0) * 1%); width: calc(var(--pw, 100) * 1%); height: calc(var(--ph, 100) * 1%); --w: var(--pw, 100); --h: var(--ph, 100); transform-origin: var(--po, 50% 50%); } .af-light-num .lt-ring { left: calc(var(--prx, 50) * 1%); top: calc(var(--pry, 50) * 1%); --rmax: var(--prmax, 72); } }
.af-light-num .lt-s { --ty: 4; }   /* v6 motion piece 3: the soft mass rises R.light.rise 4% of the frame into its place (review 2, item 5: no dead --tx) */
.af-light-num .lt-g { --tx: -.7; --ty: -4; }
.af-light[data-lit] .lt-cloud { animation: v5-form-cloud calc(1400ms * var(--fm, 1)) var(--ease-draw) both, v5-breathe 5s ease-in-out var(--rest) infinite alternate paused; }
.af-light[data-lit][data-inview] .lt-cloud { animation-play-state: running, running; }
.af-light[data-lit] .lt-trail { animation: v5-form-trail calc(1800ms * var(--fm, 1)) var(--ease-draw) calc(150ms * var(--fm, 1)) both, v5-drift 7s ease-in-out var(--rest) infinite alternate paused; }
.af-light[data-lit][data-inview] .lt-trail { animation-play-state: running, running; }
.af-light[data-lit] .lt-s { animation: v5-form-soft calc(1200ms * var(--fm, 1)) var(--ease-draw) calc(600ms * var(--fm, 1)) both; }   /* v6 motion piece 3: D.light.massesAt .30, masses .60 — every mass together */
.af-light[data-lit] .lt-g { animation: v5-form-glyph calc(800ms * var(--fm, 1)) var(--ease-draw) calc(1200ms * var(--fm, 1)) both, v5-form-strike calc(480ms * var(--fm, 1)) step-end calc((2000ms + var(--sk, 0ms)) * var(--fm, 1)) forwards; }   /* D.light.glyphsAt .60, glyphs .40 — every glow together, landing at R.strike[0] .4; then the glow JOINS the strike (review 2, item 2: with the glows at 1 under the crisp layers the strike was a focus hunt — the edge softened, the digit stayed lit; now the whole mass goes .4 → 1 → .4 → 1) */
.af-light[data-lit] .lt-c { animation: v5-form-strike calc(480ms * var(--fm, 1)) step-end calc((2000ms + var(--sk, 0ms)) * var(--fm, 1)) forwards; }   /* D.light.strikeAt 1.00 over D.strike .24: the crisp layers' arrival IS the strike (push 7's fade → the whole-mass strike, reversal 24); no backwards fill, so the layer is 0 until it strikes; --sk the second number's offset on the 31/8 */
.af-light[data-lit] .lt-ring { animation: v5-light-ring-op calc(800ms * var(--fm, 1)) linear calc((2600ms + var(--sk, 0ms)) * var(--fm, 1)) forwards, v5-light-ring-r calc(800ms * var(--fm, 1)) var(--ease-burst) calc((2600ms + var(--sk, 0ms)) * var(--fm, 1)) forwards; }   /* D.light.ringAt 1.30 over D.ring .40, 60ms after the strike's end: the opacity linear over the whole ring, the size on the burst (review 2, item 1; gsap-setup.js's ring() carries the same split) */
@keyframes v5-form-cloud { from { opacity: 0; transform: scale(1.08); } to { opacity: 1; transform: none; } }
@keyframes v5-form-trail { from { opacity: 0; transform: translate3d(-1.6%, -9%, 0); } to { opacity: 1; transform: none; } }
@keyframes v5-form-soft { 0% { opacity: 0; transform: translate3d(0, calc(var(--ty) * 100% / var(--h)), 0) scale(1.12); } 40% { opacity: .95; } 100% { opacity: 0; transform: scale(.985); } }   /* R.light.rise .04 (--ty 4), R.light.scale 1.12 → .985 */
@keyframes v5-form-glyph { from { opacity: 0; transform: translate3d(calc(var(--tx) * 100% / var(--w)), calc(var(--ty) * 100% / var(--h)), 0); } to { opacity: .4; transform: none; } }   /* to R.strike[0]: the strike takes it from there */
@keyframes v5-form-strike { 0% { opacity: .4; } 33.333% { opacity: 1; } 66.667% { opacity: .4; } 87.5% { opacity: 1; } 100% { opacity: 1; } }   /* R.strike [.4, 1, .4, 1] at R.strikeAt 0 / ⅓ / ⅔ / ⅞ of D.strike (0 / 80 / 160 / 210 of 240): step-end holds each value to the next stop, the last held at 1 (gsap-setup.js's strike(), in CSS; review 2's shape) */
@keyframes v5-light-ring-op { from { opacity: .6; } to { opacity: 0; } }   /* R.ring.from .6 → 0 */
@keyframes v5-light-ring-r { from { transform: scale(.4); } to { transform: scale(calc(var(--rmax, 72) / 40)); } }   /* R.ring.scale[0] .4 → --rmax / R.ring.light 40 (1.8 at the cap 72) */
.af-light .af-cl { opacity: 0; }
.af-light[data-lit] .af-cl { animation: v5-form-cl 300ms var(--ease) var(--cl) both; }
@keyframes v5-form-cl { from { opacity: 0; transform: translate3d(0, 8px, 0); } to { opacity: 1; transform: none; } }
/* the callout's marks arrive with it: the crosshair grows from its centre, the bracket from its corner */
.af-light .af-cl::before { transform: scale(0); transform-origin: 50% 50%; }
.af-light .af-cl::after { transform: scale(0); transform-origin: 100% 100%; }
.af-light .af-cl[data-arr="tr-bl"]::after { transform-origin: 100% 0; }
.af-light[data-lit] .af-cl::before { animation: v5-mark 160ms var(--ease) var(--cl) both; }
.af-light[data-lit] .af-cl::after { animation: v5-mark 160ms var(--ease) calc(var(--cl) + 120ms) both; }
@keyframes v5-mark { from { transform: scale(0); } to { transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .af-light-num .lt-g, .af-light-num .lt-s, .af-light-num .lt-trail, .af-light-num .lt-cloud, .af-light .af-cl { opacity: 1 !important; animation: none !important; transform: none !important; }
  .af-light-num .lt-s { opacity: 0 !important; }   /* the soft layers are the forming's alone */
  .af-light[data-lit] .af-light-num .lt-c { animation: v5-fade 240ms linear both !important; }   /* v6 motion piece 3 (R8, reversal 42): the strike is a plain D.strike fade from data-lit; no steps (!important as every line of this block: the page's global reduced-motion rule sets animation: none on everything) */
  .af-light[data-lit] .af-light-num .lt-ring { animation: none !important; }   /* no ring (R8; review 2, item 5: !important as the block's other lines) */
  .af-light .af-cl::before, .af-light .af-cl::after { animation: none !important; transform: none !important; }
}

/* ---- the 31% / 8% screen: two ends of one measure (Krish, 2026-09-16: "these stats are supposed to be two ends of the
   spectrum of one measure ... think about it from a storytelling perspective"). The head top-left: the kicker, the finding
   as a plain headline, a deck naming the one question. On the floor the light, rebuilt as two ends (the 8% at the left
   gutter, the 31% at the right, one cap: scripts/v5/build_numerals.py GEO wake-d, `ends`), and over it, in the frame's own
   box (--fw, the light's width), the answer each end stands for above its figure (the rows' plain labels), "of them wake
   up energized." under each, and the LINE between the two figures on their foot with the question it stands for written
   above it and the answer that is not shown below it; the crosshair at its left end, the bracket at its right. The
   positions are the manifest's (wake-d: cap top .54, foot .811, the 8%'s right ink .295, the 31%'s left ink .621). The
   labels arrive with the callout's timing (--cl). ---- */
.af-light-wake { --fw: min(100vw, 200svh); --ans-y: 48.6%; --each-y: 84.6%; --ax-y: 81.1%; --ax-l: 32%; --ax-r: 41.5%; }
.af-wake-head { position: relative; z-index: 2; display: flex; flex-direction: column; align-items: flex-start; gap: 20px; max-width: 100%; }
.af-wake-head > * { order: 0; }
.af-wake-head .v5-hl { order: 1; margin: 0; max-width: 20em; }
.af-wake-head .af-wake-deck { order: 2; }
@media (min-width: 1024px) and (max-height: 820px) {   /* a short window: the head sits tighter so the low end's answer clears the deck */
  .af-wake-head { gap: 12px; }
  .af-wake-head .v5-hl { font-size: 56px; }
  .af-wake-deck { font-size: 15px; max-width: 52ch; }
  .af-light-wake { --ans-y: 52%; }
}
.af-wake-deck { margin: 0; font-size: clamp(16px, 1.32vw, 19px); line-height: 1.45; max-width: 46ch; text-wrap: pretty; }
.af-wake-stage { display: contents; }
.af-wake-ends { position: absolute; left: 0; bottom: 0; width: var(--fw); aspect-ratio: 16 / 10; pointer-events: none; font-family: var(--mono); font-weight: 400; font-size: 11px; line-height: 1.5; letter-spacing: .1em; text-transform: uppercase; -webkit-text-stroke: .32px currentColor; }
.af-wake-ans { position: absolute; top: var(--ans-y); }
.af-wake-ans-lo { left: 4.44%; }
.af-wake-ans-hi { right: 4.44%; text-align: right; }
.af-wake-each { position: absolute; top: var(--each-y); max-width: 22ch; font-family: var(--sans); font-weight: 400; font-size: 17px; line-height: 1.4; letter-spacing: 0; text-transform: none; -webkit-text-stroke: 0; }
.af-wake-each-lo { left: 4.44%; }
.af-wake-each-hi { right: 4.44%; text-align: right; }
.af-wake-axis { position: absolute; left: var(--ax-l); right: var(--ax-r); top: var(--ax-y); height: 1px; background: currentColor; }
.af-wake-axis-l { position: absolute; left: 0; right: 0; bottom: 16px; text-align: center; opacity: .85; }
.af-wake-axis-m { position: absolute; left: 0; right: 0; top: 14px; text-align: center; opacity: .6; }
.af-wake-axis .mk { --arm: 1.6em; --leg: 1.4em; }
.af-wake-axis .mk-cross { left: calc(-1 * var(--arm)); top: calc(-1 * var(--arm) + .5px); }
.af-wake-axis .mk-br[data-at="tr"] { right: 0; top: calc(-1 * var(--leg) + .5px); }
.af-wake-foot { position: absolute; left: var(--gutter); bottom: 36px; margin: 0; max-width: 64ch; font-family: var(--sans); font-weight: 400; font-size: 14px; line-height: 1.5; letter-spacing: 0; text-transform: none; -webkit-text-stroke: .32px currentColor; opacity: .7; }
.af-light .af-wake-ends > *, .af-light .af-wake-foot { opacity: 0; }
.af-light[data-lit] .af-wake-ends > * { animation: v5-form-cl 300ms var(--ease) var(--cl) both; }
.af-light[data-lit] .af-wake-foot { animation: v5-form-cl 300ms var(--ease) calc(var(--cl) + 200ms) both; opacity: .7; }
.af-light .af-wake-axis .mk-cross, .af-light .af-wake-axis .mk-br { transform: scale(0); transform-origin: 50% 50%; }
.af-light .af-wake-axis .mk-br { transform-origin: 100% 0; }
.af-light[data-lit] .af-wake-axis .mk-cross { animation: v5-mark 160ms var(--ease) calc(var(--cl) + 120ms) both; }
.af-light[data-lit] .af-wake-axis .mk-br { animation: v5-mark 160ms var(--ease) calc(var(--cl) + 240ms) both; }
@media (prefers-reduced-motion: reduce) {
  .af-light .af-wake-ends > *, .af-light .af-wake-axis .mk-cross, .af-light .af-wake-axis .mk-br { opacity: 1 !important; animation: none !important; transform: none !important; }
  .af-light .af-wake-foot { opacity: .7 !important; animation: none !important; }
}

/* ---- the pages stop (Krish, 2026-09-16: "snap or stop at their intended locations as the scroll happens"). On the home
   view the document snaps to the top of each screen on the laptop (a fine pointer, no reduced motion), as /v3/ locks
   onto its chapters; the phone stays free, as on /v3/ (its screens run taller than the window and iOS momentum fights
   a mandatory snap, measured there). A screen taller than the window is free inside it (the snap area covers the port). The two double screens stop twice (the in-the-way picture and its rows;
   the arch and the 31/8); the footer is the last stop, at its end. ?snap=0 turns it off (the checks that scroll to a
   measured offset use it). The quiz, the results and About are not snapped. ---- */
@media (min-width: 1024px) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  html.v5-snap[data-view="home"] { scroll-snap-type: y mandatory; }
  html.v5-snap[data-view="home"] .v5-stop { scroll-snap-align: start; }
  html.v5-snap[data-view="home"] footer.v5-stop { scroll-snap-align: end; }
}

/* ---- the motion system (step 6). One curve for everything that arrives (--ease), one for the lights (--ease-draw).
   A block arrives once (v5-rise, 640ms, 90ms per sibling on the laptop; 400 / 60 under 1024 and the phone's headline one 400ms fade
   with no inline animation — v6 motion piece 0, the reveal observer in index.html) and stays; a headline exposes from an 8px blur; a pane
   fades over 480ms and its corners draw together from 240ms; a statistic's marks draw 400ms after its number; a
   light draws over 1.1s when 40% in view; at rest only a light's cloud breathes and its trail drifts, and only while
   its panel is on screen. Nothing scales, nothing passes through black, nothing moves with the scroll. ---- */
.v5-hl .ln { --d: 0ms; } .v5-hl .ln:nth-child(2) { --d: 90ms; } .v5-hl .ln:nth-child(3) { --d: 180ms; } .v5-hl .ln:nth-child(4) { --d: 270ms; }
.v5-hl[data-revealed] .ln { animation: v5-expose 640ms var(--ease) var(--d) both; }
.af-hero-hl { opacity: 0; animation: v5-fade 640ms var(--ease) both; }   /* the hero has no observer: its lines expose on load */
.af-hero-hl .ln { animation: v5-expose 640ms var(--ease) var(--d) both; }
@media (max-width: 1023px) { .af-hero-hl { animation-duration: 400ms; } }   /* v6 motion (the review of pieces 0/1, item 10): the phone's title fades D.headline 400 like everything under it, so it lands before or with the block (it landed 240ms after at 640); the laptop unchanged */
@keyframes v5-drift { from { transform: scale(1.03); } to { transform: translate3d(-.1vh, -.6vh, 0) scale(1.03); } }
@keyframes v5-breathe { from { opacity: 1; } to { opacity: .7; } }
@keyframes v5-drift { from { transform: none; } to { transform: translate3d(-.35%, -2%, 0); } }

@media (prefers-reduced-motion: reduce) {
  .af-hero-hl, .af-hero-hl .ln, .v5-hl[data-revealed] .ln { animation: none !important; opacity: 1 !important; }

  .is-undrawn .mk-br.draws::before, .is-undrawn .mk-br.draws::after { transform: none !important; }
}

/* ==== the six doors and their posters (plan step 4) ============================================================
   The row of six photograph squares in #findings (markup in the template, site/v5/index.html) and the poster layer #dims
   that v5.js builds on <body>, outside <x-dc>. Tokens from :root above: --ease, --cl (the em every mark is drawn in),
   --gutter. The marks (.mk, .mk-cross, .mk-br and the .draws legs) are defined above and only sized and placed here.
   No wash, no blur, no pane inside a poster: the type sits straight on the photograph in the poster's ink (data-ink). */
.v5-doors, .dims { --mono: 'Messina Mono', Menlo, monospace; --sans: 'Equinox Sans', Helvetica, Arial, sans-serif; }

/* ---- the row: a list of six. Six across on the laptop (24px, the spread's gutter), three on a tablet, two by three on the phone ---- */
.v5-doors { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 16px; }
.v5-doors > li { margin: 0; padding: 0; min-width: 0; }
@media (max-width: 1023px) { .v5-doors { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; } }
@media (max-width: 699px) { .v5-doors { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; } }

/* a door: a button holding the photograph and the name — no fill, no border, no shadow, nothing lifts */
.door { display: block; width: 100%; margin: 0; padding: 0; border: 0; border-radius: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.door:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }
.door-img { display: block; position: relative; width: 100%; aspect-ratio: 3 / 4; overflow: hidden; background: var(--void); }
.door-img img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 40%; transform: none; opacity: .92;
  transition: transform 240ms var(--ease), opacity 200ms var(--ease); }   /* object-position per door: a rule v5.js writes from CFG.posP; v6 motion piece 5: at rest R.door.photo .92 (a looked-at or pressed door goes to 1); the 200 is D.doorFade, the picture back under a closing poster */
@media (min-width: 1024px) {
  .door-img::after { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: url(/v4/grain.png) 0 0 / 128px 128px; mix-blend-mode: overlay; opacity: .22; }
}
/* the two brackets inside the picture's corners (round three, back on Krish's word): drawn at rest, half-lit until the door is
   looked at. The legs (::before across, ::after down) are the .mk-br's own; the box they sit in is what the hover and the cue move. */
.door .mk-br { z-index: 2; --o: 0; --leg: 1.8em; font-size: var(--cl); opacity: .6;
  transition: opacity 240ms var(--ease), width 240ms var(--ease), height 240ms var(--ease), left 240ms var(--ease), top 240ms var(--ease), right 240ms var(--ease), bottom 240ms var(--ease); }
.door .mk-br[data-at="tl"] { left: .6em; top: .6em; }
.door .mk-br[data-at="br"] { right: .6em; bottom: .6em; }
.door-name { display: block; margin-top: 12px; font-family: var(--mono); font-weight: 400; font-size: 13px; line-height: 1.5; letter-spacing: .08em; text-transform: uppercase;
  opacity: 1; -webkit-text-stroke: .32px currentColor; transition: opacity 240ms var(--ease); }
/* the door's picture gives way while its poster grows out of it (v5.js sets .is-lifted) and returns for the close */
.door.is-lifted .door-img img { opacity: 0 !important; }

/* ---- the hover (laptop only): under the pointer one door brightens and the five others recede — the brackets open (leg 1.8 →
   2.6em, inset .6 → .3em, .6 → 1), the picture settles (scale 1.03 over 640ms, 240 out), the name comes up (.7 → 1), the siblings'
   pictures fall to .55 over 320ms. Nothing lifts, no shadow, no border. :focus-visible is the same state plus the outline above;
   .is-hot is the same state, set by the first-scroll cue (v5.js: door 1, once per visit, for 900ms). ---- */
.door:is(:focus-visible, .is-hot) .mk-br, .door:is(:focus-visible, .is-hot) .door-name { transition-duration: 320ms; }
.door:is(:focus-visible, .is-hot) .mk-br { --leg: 2.6em; opacity: 1; }
.door:is(:focus-visible, .is-hot) .mk-br[data-at="tl"] { left: .3em; top: .3em; }
.door:is(:focus-visible, .is-hot) .mk-br[data-at="br"] { right: .3em; bottom: .3em; }
.door:is(:focus-visible, .is-hot) .door-name { opacity: 1; }
.door:is(:focus-visible, .is-hot) .door-img img { transform: scale(1.03); opacity: 1; transition-duration: 640ms, 200ms; }
.v5-doors:has(.door.is-hot):not(:has(.door:hover)) .door:not(.is-hot) .door-img img { opacity: .5; transition: opacity 320ms var(--ease), transform 240ms var(--ease); }   /* R.door.recede .5 (was .55) */
@media (hover: hover) {
  .door:hover .mk-br, .door:hover .door-name { transition-duration: 320ms; }
  .door:hover .mk-br { --leg: 2.6em; opacity: 1; }
  .door:hover .mk-br[data-at="tl"] { left: .3em; top: .3em; }
  .door:hover .mk-br[data-at="br"] { right: .3em; bottom: .3em; }
  .door:hover .door-name { opacity: 1; }
  .door:hover .door-img img { transform: scale(1.03); opacity: 1; transition-duration: 640ms, 200ms; }
  .v5-doors:has(.door:hover) .door:not(:hover) .door-img img { opacity: .5; transition: opacity 320ms var(--ease), transform 240ms var(--ease); }
}
/* ---- the pressed door (v6 motion piece 5, the motion spec §6 "the doors", P9): on touchstart, within D.tap .12, the tapped door's two
   brackets close (the .is-hot state at 120ms), its photograph goes to 1 from R.door.photo .92 and the other five recede to R.door.recede
   .5 over D.release .24; a ring rises at the finger (V5GSAP.ringAt, R.ring.tap); on touchend everything releases over D.release on the
   burst curve (.is-released for D.release, from v5.js) and the poster opens out of the door; a finger past R.tapPx cancels the same way
   (reversal 41). No running light, no scale on the photograph (P10: it never moves on the phone), no idle life. ---- */
.door.is-pressed .mk-br { --leg: 2.6em; opacity: 1; transition-duration: 120ms; }
.door.is-pressed .mk-br[data-at="tl"] { left: .3em; top: .3em; }
.door.is-pressed .mk-br[data-at="br"] { right: .3em; bottom: .3em; }
.door.is-pressed .door-name { opacity: 1; }
.door.is-pressed .door-img img { opacity: 1; transition-duration: 240ms, 120ms; }
.door.is-released .mk-br, .door.is-released .door-img img { transition-timing-function: var(--ease-burst); }
.v5-doors:has(.door.is-pressed) .door:not(.is-pressed) .door-img img { opacity: .5; transition: opacity 240ms var(--ease), transform 240ms var(--ease); }
.v5-doors:has(.door.is-released) .door:not(.is-released) .door-img img { transition: opacity 240ms var(--ease-burst), transform 240ms var(--ease); }

/* ---- the first-scroll cue (v5.js, once per visit): .is-cueing puts the twelve legs at nothing with no transition; .is-drawing,
   added a layout later, draws them back — the across leg 160ms, the down leg 160ms from 120ms — 90ms per door left to right
   (--i, set on each door by v5.js). Then door 1 takes .is-hot for 900ms. At rest, with no cue running, the legs are drawn. ---- */
.v5-doors.is-cueing .mk-br.draws::before { transform: scaleX(0); transition: none; }
.v5-doors.is-cueing .mk-br.draws::after { transform: scaleY(0); transition: none; }
.v5-doors.is-cueing.is-drawing .mk-br.draws::before { transform: none; transition: transform 160ms var(--ease) calc(var(--i, 0) * 90ms); }
.v5-doors.is-cueing.is-drawing .mk-br.draws::after { transform: none; transition: transform 160ms var(--ease) calc(var(--i, 0) * 90ms + 120ms); }

/* ---- one text-link treatment (v6, the client's notes of 2026-09-18): Messina Mono 12px caps at full ink, a 1px hairline under the
   words AT REST on both grounds, the arrow at the label's own size (→ where it goes somewhere, ← before a way back), 44px tall,
   touch-action manipulation; pressed = .6 for 120ms; on a laptop one hover: the rule thickens and the arrow slides 4px ---- */
.sc-host-x > :is(button, a)[style*="border: 1px solid transparent"] { font-family: var(--mono) !important; font-weight: 400 !important; font-size: 12px !important; letter-spacing: .1em !important; text-transform: uppercase !important; text-decoration: underline !important; text-decoration-thickness: 1px !important; text-underline-offset: .35em !important; gap: 8px !important; min-height: 44px; touch-action: manipulation; transition: opacity 120ms var(--ease), text-decoration-thickness 240ms var(--ease); }
.sc-host-x > :is(button, a)[style*="border: 1px solid transparent"] > span:last-child { display: none !important; }   /* the design system's 6px caret */
.sc-host-x > :is(button, a)[style*="border: 1px solid transparent"]::after { content: "→"; display: inline-block; text-decoration: none; transition: transform 240ms var(--ease); }
.sc-host-x > :is(button, a)[style*="border: 1px solid transparent"]:active { opacity: .6; }
.af-light-foot, .af-back-top, .dim-back, .dim-next, .dim-quiz, header nav > a, .af-footer-nav a, .af-quiz-foot a { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .35em; touch-action: manipulation; transition: opacity 240ms var(--ease-burst), text-decoration-thickness 240ms var(--ease), transform 240ms var(--ease-burst); }   /* v6 motion piece 5: the release D.release on the burst curve (was 120 on --ease); the press-in below stays 120 */
.af-light-foot:active, .af-back-top:active, .dim-back:active, .dim-next:active, .dim-quiz:active, header nav > a:active, .af-footer-nav a:active, .af-quiz-foot a:active,
.af-light-foot.is-pressed, .af-back-top.is-pressed, .dim-back.is-pressed, .dim-next.is-pressed, .dim-quiz.is-pressed, .dv-rail-b.is-pressed, .dv-next.is-pressed { opacity: .6; transition-duration: 120ms, 240ms, 120ms; transition-timing-function: var(--ease); }   /* v6 motion piece 5 (§6 the strips, P9): pressed on touchstart within D.tap .12 — .is-pressed from v5.js, the site's .6 for a text link (R.press.tick); the rail's names too */
.dim-next.is-pressed { transform: translateX(4px); }   /* 'Next →' translates 4px on pressed and returns on v5-burst over D.release */
/* v6 motion piece 5 (§6 the hero, the bottom quiz button; R.press): every design-system button pressed on touchstart — opacity .85 and scale .97
   over D.tap .12, released over D.release .24 on v5-burst, cancelled past R.tapPx (.is-pressed / .is-released from v5.js). Animations, not a
   transition: the bundle's inline opacity: 1 and transition: 180ms would beat a class's declaration, and an animation's value outranks an inline
   one without !important. The text-link variant keeps its .6 above. Under Reduce Motion the page's global rule ends both (no pressed answer). */
.sc-host-x > :is(button, a):not([style*="border: 1px solid transparent"]).is-pressed { animation: v5-press 120ms var(--ease) both; }
.sc-host-x > :is(button, a):not([style*="border: 1px solid transparent"]).is-released { animation: v5-press-release 240ms var(--ease-burst) both; }
.sc-host-x > :is(button, a)[style*="border: 1px solid transparent"].is-pressed { opacity: .6; }
@keyframes v5-press { from { opacity: 1; transform: none; } to { opacity: .85; transform: scale(.97); } }
@keyframes v5-press-release { from { opacity: .85; transform: scale(.97); } to { opacity: 1; transform: none; } }
@media (hover: hover) {
  .sc-host-x > :is(button, a)[style*="border: 1px solid transparent"]:hover, .af-light-foot:hover, .af-back-top:hover, .dim-back:hover, .dim-next:hover, .dim-quiz:hover, header nav > a:hover, .af-footer-nav a:hover, .af-quiz-foot a:hover { text-decoration-thickness: 2px !important; }
  .sc-host-x > :is(button, a)[style*="border: 1px solid transparent"]:hover::after { transform: translateX(4px); }
}
/* safe areas (viewport-fit=cover): the bar and the poster's strips clear the notch and the home indicator */
header { padding-top: max(10px, env(safe-area-inset-top)) !important; }
/* the poster's strips, the column and the picture: at the end of this file, after every padding shorthand (v6 push 5, review 2) */

/* ---- the poster layer: fixed over the page, transparent, with a black scrim that fades 0 → .92 over 320ms (out: 280ms from 160ms);
   the header (z 40) sits under it and is hidden while it is open. The page is locked by html.dim-open. ---- */
.dims { position: fixed; inset: 0; z-index: 50; overflow: hidden; background: transparent; color: var(--bone); touch-action: none; }
.dims[hidden] { display: none; }
.dims::before { content: ""; position: absolute; inset: 0; background: var(--void); opacity: 0; pointer-events: none; transition: opacity 240ms var(--ease) 80ms; }   /* out: D.scrimOut .24 from D.scrimOutDelay .08 — ends at 320 with the door close's hide (the review's item 9; was 280 from 160, cut at the hide) */
.dims.is-open::before { opacity: .92; transition: opacity 320ms var(--ease); }
.v5-sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
html.dim-open { overflow: hidden; }
html.dim-open header { visibility: hidden; }
@media (min-width: 1024px) { .af-sticky-cta { display: none; } }   /* the bottom quiz button is the phone's (v6) */

/* a poster: the photograph, its twin (the pre-blurred eighth-size -b file, upscaled — no CSS blur), the grain, the strips, the column */
.dim { position: absolute; inset: 0; display: none; color: var(--bone); outline: none; }
.dim[data-ink="dark"] { color: var(--void); }
.dim.is-cur { display: block; z-index: 2; }
.dim.is-leaving { display: block; z-index: 1; }
.dim .fr-img, .dim .fr-twin, .dim .fr-p { position: absolute; inset: 0; }
.dim .fr-img img, .dim .fr-twin img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover; object-position: var(--pos-d, 50% 50%); }
.dim .fr-img img:not([src]), .dim .fr-twin img:not([src]) { visibility: hidden; }
.dim .fr-twin { z-index: 1; pointer-events: none; opacity: 0; }
.dim .fr-p { z-index: 1; pointer-events: none; }
@media (min-width: 1024px) {
  .dim .fr-p::after { content: ""; position: absolute; inset: 0; background: url(/v4/grain.png) 0 0 / 128px 128px; mix-blend-mode: overlay; opacity: .22; }
}

/* ---- the open: one choreography from every origin, the resolve (round two: the clip out of a door is cut — captured, it was a
   hard-edged rectangle mid-growth, the boxiest moment on the site). The scrim 0 → .92 over 320ms; the twin, at 1 over the sharp
   picture, fades to 0 over 480ms from 20ms (v6 motion piece 0: the resolve ends with the open at T.open 500 — it was 560 from 120 under a
   680 open), so the picture forms from soft to sharp with no runtime filter and no scale; the name and the question expose from 200ms
   over 400ms; the label rises 400ms from 240ms and the column 60ms after it (piece 0: 400 / 60, the mobile-first spec's rise; was one 480
   from 240); the strips fade in 240ms from 200ms. ---- */
.dim.is-opening .fr-twin { animation: v5-resolve 480ms var(--ease) 20ms both; }
/* from a door (.is-clipping, round three): the picture, its twin and the grain share one clip that runs from the door's rectangle
   (set inline by v5.js) to the whole frame over 400ms on the glide curve (v6 motion piece 0: T.clipOpen 560 → 400, the spec's
   `v5-glide`) while the twin resolves; the close runs it back over 320ms (T.clipClose 440 → 320) and the door's own picture returns
   under it for the last 200ms */
.dim.is-opening.is-clipping .fr-img, .dim.is-opening.is-clipping .fr-twin, .dim.is-opening.is-clipping .fr-p { transition: clip-path 400ms var(--ease-glide); }
/* v6 motion piece 5 — THE POSTER'S BLACK GROUND IN THE CLIP (Krish's answer 3a, 2026-09-19: lifts the motion spec's R4 and his round-three
   restoration of the photograph in the clip): the picture container carries the poster's ground under its photograph (a ::before in --void,
   under the img, invisible at rest), so from the first frame the growing clip's content is black; the photograph and its twin (the twin resolving
   as today over it) fade in from the ground over D.open .5, linear, while the clip grows (T.clipOpen) — the picture never cuts, it appears. The
   close mirrors it: the photograph goes to black over T.clipClose − T.doorFade .12 inside the shrinking clip (T.clipClose on v5-gather: every
   retraction toward its origin), then the ground fades over D.doorFade .20 as the door's own photograph returns beneath (v5.js lifts the door at
   120), so the hide at 320 cuts nothing. */
.dim .fr-img::before { content: ""; position: absolute; inset: 0; background: var(--void); }
.dim.is-opening.is-clipping .fr-img img, .dim.is-opening.is-clipping .fr-twin img { animation: v5-fade 500ms linear both; }
.dim.is-closing.is-clipping { animation: none; }
.dim.is-closing.is-clipping .fr-img, .dim.is-closing.is-clipping .fr-twin, .dim.is-closing.is-clipping .fr-p { transition: clip-path 320ms var(--ease-gather); }   /* v6 motion piece 5: the clip back into the door on v5-gather (was --ease) */
.dim.is-closing.is-clipping .fr-img::before { animation: v5-fade-out 200ms linear 120ms both; }   /* the photograph's own fade to the ground is inline from v5.js closeDim (it starts from wherever the photograph is: a close mid-open fades from its fade-in's value, never a flash to 1) */
.dim.is-closing.is-clipping .fr-twin { animation: none; opacity: 0; }
@keyframes v5-resolve { from { opacity: 1; } to { opacity: 0; } }
@keyframes v5-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes v5-fade-out { from { opacity: 1; } to { opacity: 0; } }
.dim.is-cur .hl .ln { animation: v5-expose 400ms var(--ease) both; animation-delay: calc(200ms + var(--d, 0ms)); }   /* v6 motion piece 0: one headline fade of 400 (D.headline); was 640 */
.dim .hl .ln:nth-child(2) { --d: 90ms; } .dim .hl .ln:nth-child(3) { --d: 180ms; } .dim .hl .ln:nth-child(4) { --d: 270ms; }
@keyframes v5-expose { from { opacity: 0; transform: translate3d(0, 8px, 0); } to { opacity: 1; transform: none; } }   /* no blur on type (round two) */
.dim.is-cur .dim-label { animation: v5-rise-6 400ms var(--ease) 240ms both; }   /* v6 motion piece 0: the rise 400 (D.rise), the column 60 after the label (D.riseStep); was one 480 from 240 */
.dim.is-cur .col { animation: v5-rise-6 400ms var(--ease) 300ms both; }
.dim.is-cur .dim-deck { animation: v5-rise-6 400ms var(--ease) 300ms both; }   /* the review's item 7: the deck rises with the column (it stood at full opacity outside the growing clip from the first frame) */
.dim.is-cur .dim-top, .dim.is-cur .dim-bottom { animation: v5-fade 240ms var(--ease) 200ms both; }   /* v6 push 5: the ticks fade with their strip */
@keyframes v5-rise-6 { from { opacity: 0; transform: translate3d(0, 6px, 0); } to { opacity: 1; transform: none; } }
/* a step to the next poster (.is-stepping over .is-leaving): a 400ms crossfade — the arriving poster fades in over the leaving one,
   which stays whole underneath until it is covered, so nothing passes through black; its twin resolves; the leaving column fades 200ms */
.dim.is-stepping { animation: v5-fade 400ms var(--ease) both; }
.dim.is-stepping .fr-twin { animation: v5-resolve 480ms var(--ease) both; }
.dim.is-leaving .txt, .dim.is-leaving .dim-ticks { opacity: 0; transition: opacity 200ms var(--ease); }
.dim.is-leaving .dim-top, .dim.is-leaving .dim-bottom { animation: v5-fade-out 200ms var(--ease) both; }   /* the review's item 8: the strips' own fade-in (fill both, .is-cur) pinned them at 1 under a transition; a keyframe on the leaving/closing state wins */
/* the close (.is-closing): the column and the strips fade 200ms; the twin returns 0 → 1 over 320ms while the layer fades 320ms
   from 80ms; the scrim goes 280ms from 160ms. The page beneath never moved. */
.dim.is-closing { animation: v5-fade-out 320ms var(--ease) 80ms both; }
.dim.is-closing .fr-twin { animation: v5-unresolve 320ms var(--ease) both; }
@keyframes v5-unresolve { from { opacity: 0; } to { opacity: 1; } }
.dim.is-closing .txt, .dim.is-closing .dim-ticks { opacity: 0; transition: opacity 200ms var(--ease); }
.dim.is-closing .dim-top, .dim.is-closing .dim-bottom { animation: v5-fade-out 200ms var(--ease) both; }   /* (item 8: with the column; the bottom strip's white ground went in one frame at the hide) */

/* ---- the strips (v6 push 5: the top strip is the bar): the way back top-left (its label names where the poster was opened from:
   "← Back to what we found"; '← Back' on the phone with the origin in the aria-label), the quiz link at the strip's right (its words
   from the quiz state, set by v5.js), the six ticks between them (the laptop: after the link at the right, the current one lit, a tap
   steps; the phone: a progress line in the middle, not tappable); the bottom strip on every poster: the way back left (the phone
   only), the next poster right, the quiz link on the sixth. Fixed while the column scrolls; both take the page bar's ground once the
   column has scrolled 8px (.is-scrolled on the article, set by v5.js and dives.js). ---- */
.dim-top { position: absolute; top: 0; left: 0; right: 0; z-index: 3; height: 64px; padding: 0 var(--gutter); display: flex; justify-content: space-between; align-items: center; gap: 16px; pointer-events: none; }   /* v6 push 5 (review 2): the full-width strips pass a swipe or a wheel through to the column; their links take the tap */
.dim-bottom { position: absolute; bottom: 0; left: 0; right: 0; z-index: 3; height: 64px; padding: 0 var(--gutter); display: flex; justify-content: space-between; align-items: center; gap: 16px; pointer-events: none; }
.dim-bottom .dim-back { display: none; }   /* the laptop's bottom strip stays next / quiz only */
.dim-bottom .dim-next, .dim-bottom .dim-quiz { margin-left: auto; }   /* right-anchored while the back is hidden */
.dim-back, .dim-next, .dim-quiz, .dim-tick { position: relative; display: inline-flex; align-items: center; min-height: 44px; margin: 0; padding: 0; border: 0; border-radius: 0; background: none; color: inherit; font: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; pointer-events: auto; }
.dim-back, .dim-next, .dim-quiz { font-family: var(--mono); font-weight: 400; font-size: 12px; line-height: 1.5; letter-spacing: .08em; text-transform: uppercase; -webkit-text-stroke: .32px currentColor; white-space: nowrap; }
.dim-back:focus-visible, .dim-next:focus-visible, .dim-quiz:focus-visible, .dim-tick:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }
.dim-quiz { margin-left: auto; }   /* the laptop: the link at the strip's right, the ticks after it */
.dim-ticks { display: flex; align-items: center; gap: 6px; margin-left: 24px; }   /* static, the last item of the top strip */
.dim-tick { width: 24px; justify-content: center; opacity: .28; transition: opacity 240ms var(--ease-burst); }   /* v6 motion piece 5: the release on the burst curve */
.dim-tick::before { content: ""; display: block; width: 24px; height: 2px; background: currentColor; transform-origin: 0 50%; }
.dim-tick[aria-current="true"] { opacity: 1; }
/* v6 motion piece 5 (§6 the step poster → poster; Opal's segmented rail): the new current tick FILLS scaleX over D.strip .24 on v5 from the side
   the reader came from — transform-origin 0 on a forward step (and an open), 100% on a back step (data-dir on the article, from v5.js) — with
   its strip's own fade (200ms in); a tapped tick (the laptop: the phone's dashes are a progress line, push 5) shows R.press.tick .6 within D.tap */
.dim.is-cur .dim-tick[aria-current="true"]::before { animation: v5-tick-fill 240ms var(--ease) 200ms both; }
.dim.is-cur[data-dir="-1"] .dim-tick[aria-current="true"]::before { transform-origin: 100% 50%; }
@keyframes v5-tick-fill { from { transform: scaleX(0); } to { transform: none; } }
.dim-tick.is-pressed { opacity: .6; transition-duration: 120ms; transition-timing-function: var(--ease); }
/* the ground: chrome takes the page bar's ground (white .92 under the black type of the six posters; black .92 under the white type
   inside a picture) once anything is under it, over 240ms — the top strip once .txt or .dv-in has scrolled 8px (.is-scrolled), the
   bottom strip and the rail while the scroller can still go down (.has-more: at rest an overflowing column already runs under the
   bottom strip; at the very bottom nothing does). Both classes on the article, from v5.js groundFor. Plain rgba: no gradient, no
   backdrop-filter */
.dim-top, .dim-bottom, .dv-rail { background-color: transparent; transition: background-color 240ms var(--ease); }
.dim.is-scrolled .dim-top { background-color: rgba(255, 255, 255, .92); }
.dim.has-more .dim-bottom { background-color: rgba(255, 255, 255, .92); }
.dim.has-dive.is-scrolled .dim-top { background-color: rgba(0, 0, 0, .92); }
.dim.has-dive.has-more .dv-rail { background-color: rgba(0, 0, 0, .92); }

/* ---- inside the poster (round five): the reading order is the name, the question, the deck (the definition and the take, two
   sentences in the sans), then on the floor the FIGURES: the lead figure set big with its sentence and the pair of marks, the
   other figures in a row beside it, each a control ("More detail") that unfolds its drawer — what was measured, the timeframe,
   who was asked, and the comparisons that belong to it, their rows as bars — into the empty middle of the poster, ABOVE the
   row, so the figure the reader pressed never moves. One drawer open at a time. Padding 88 clears the strips; the column
   scrolls inside the poster only if it must (a short window; the phone). ---- */
.dim .txt { position: absolute; inset: 0; z-index: 2; display: flex; flex-direction: column; align-items: flex-start; box-sizing: border-box;
  padding: 88px var(--gutter) 88px; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; touch-action: pan-y; scrollbar-width: none; }
.dim .txt::-webkit-scrollbar { display: none; }
.dim-label { position: relative; margin: 0 0 max(0px, calc(var(--hy, 12vh) - 88px - 1.5em)); font-family: var(--mono); font-weight: 400; font-size: 12px; line-height: 1.5;
  letter-spacing: .1em; text-transform: uppercase; -webkit-text-stroke: .32px currentColor; }   /* the question's top lands at --hy on the laptop */
.dim .hl { position: relative; margin: 0 0 .2em; font-family: var(--sans); font-weight: 300; font-size: calc(clamp(44px, 6.4vw, 104px) * .7); line-height: .94;
  letter-spacing: -.012em; text-transform: uppercase; max-width: 14em; text-wrap: balance; }
.dim .hl .ln { display: block; }
@media (max-width: 1023px) { .dim .hl .ln { display: inline; } .dim .hl .ln + .ln::before { content: " "; } .dim .hl { text-wrap: pretty; } }   /* v6: the phone's measure sets the question's breaks */
.af-inway-line { font-size: clamp(18px, 1.7vw, 24px); font-weight: 400; line-height: 1.4; }
/* the deck: two sentences, the sans, sentence case, under the question */
.dim-deck { position: relative; margin: .9em 0 0; max-width: 46ch; font-family: var(--sans); font-weight: 400; font-size: clamp(16px, 1.32vw, 19px); line-height: 1.45; letter-spacing: 0; text-transform: none; text-wrap: pretty; }
.dim-deck .ln { display: inline; }
/* the block on the floor (the laptop: above the bottom strip, at the right margin where the picture asks for it, data-col="right") */
.dim .col { position: relative; flex: 0 0 auto; margin: 48px 0 0; width: 100%; max-width: 980px; display: flex; flex-direction: column; align-items: flex-start; }   /* under the deck: one column, the question, the deck, the answer */
.dim[data-col="right"] .col { position: absolute; right: var(--gutter); bottom: 88px; margin: 0; width: auto; max-width: 250px; align-items: flex-start; }   /* a narrow column at the right margin, on the floor, where the picture asks for it: every figure stacked, the lead first */
/* the row of figures: the lead first, set big; the others beside it, their feet on its foot */
.dim .fnds { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 28px 40px; width: 100%; }
.dim[data-col="right"] .fnds { justify-content: flex-end; }
.dim .fnd-side { display: contents; }   /* the figures after the lead sit in the row */
.dim[data-stack] .fnds { flex-direction: column; flex-wrap: nowrap; align-items: flex-start; gap: 22px; }   /* one column: the lead at its head, read first */
.dim[data-stack] .fnd, .dim[data-stack] .fnd-lead { flex: 0 0 auto; width: 100%; }
.dim[data-stack] .fnd-lead .fnd-v { font-size: clamp(64px, 6.4vw, 92px); }
.dim[data-stack] .fnd-t, .dim[data-stack] .fnd-lead .fnd-t { max-width: none; }
@media (min-width: 1024px) and (max-height: 820px) {   /* a short window: the right-hand column keeps clear of the top strip */
  .dim[data-stack] .fnds { gap: 14px; }
  .dim[data-stack] .fnd-btn { gap: 8px; }
  .dim[data-stack] .fnd-v { font-size: 40px; }
  .dim[data-stack] .fnd-lead .fnd-v { font-size: 76px; }
}
/* a poster with one finding (Emotions): the other rows of its comparison stand beside the lead as plain figures, the comparison's title under them */
.dim .fnd-side-rows { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px 32px; flex: 0 1 auto; max-width: 40ch; }
.dim .fnd-side-rows .fnd-row { flex: 0 0 auto; display: flex; flex-direction: column; gap: 8px; }
.dim .fnd-side-rows .fnd-row .fnd-v::after { content: none; }
.dim .fnd-side-title { flex: 0 0 100%; font-size: 13px; line-height: 1.4; opacity: .8; max-width: 40ch; }
.dim .fnd { position: relative; margin: 0; flex: 0 1 22ch; min-width: 0; font-family: var(--sans); font-weight: 400; font-size: 17px; line-height: 1.4; letter-spacing: 0; text-transform: none; }
.dim .fnd-lead { flex: 0 1 26ch; font-size: 17px; }
.dim .fnd-btn { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; width: 100%; margin: 0; padding: 0; border: 0; border-radius: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.dim .fnd-btn:focus-visible { outline: 2px solid currentColor; outline-offset: 6px; }
.dim .fnd-v { position: relative; display: inline-flex; width: max-content; font-family: var(--sans); font-weight: 300; font-size: clamp(38px, 3.4vw, 48px); line-height: 1; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.dim .fnd-lead .fnd-v { font-size: clamp(76px, 7.4vw, 112px); letter-spacing: -.025em; }
.dim .fnd-still .fnd-v::after { display: none; }
.dim .fnd-v::after { content: ""; position: absolute; left: 0; right: 0; bottom: -.07em; height: 1px; background: currentColor; transform: scaleX(0); transform-origin: 0 50%; transition: transform 240ms var(--ease); }   /* the hairline that says it opens */
.dim .fnd-t { display: block; max-width: 32ch; text-wrap: pretty; }
.dim .fnd-lead .fnd-t { max-width: 30ch; }
/* the lead figure's pair of marks (the em is the figure's own size, as the main page's statistics): the crosshair at its head on the
   left, the bracket at its head on the right, clear of the sentence under it */
.dim .fnd-lead .fnd-v .mk { --arm: .22em; --leg: .2em; --o: .1em; }   /* the crosshair hangs in the gutter: .22em arms fit it at every laptop width */
.dim .fnd-lead .fnd-v .mk-cross { transition: transform 240ms var(--ease) 80ms; }   /* v6 motion piece 5 (§6 the poster's open): the lead figure's crosshair and bracket (.draws) draw with the page's is-undrawn machinery once the figure has risen — T.marks = D.posterMarks, from v5.js */
.dim .fnd-v.is-set .mk-cross, .dim .fnd-v.is-set .mk-br.draws::before, .dim .fnd-v.is-set .mk-br.draws::after { transition: none; }   /* v5.js drawMarks sets is-undrawn under .is-set (one layout) so the marks start at nothing instead of shrinking there */
.dim .fnd-lead .fnd-v .mk-cross[data-at="tl"] { left: calc(-1 * (var(--o) + var(--arm) * 2 + .04em)); top: calc(-1 * var(--arm) + .04em); }
.dim .fnd-lead .fnd-v .mk-br[data-at="tr"] { right: calc(-1 * (var(--o) + var(--leg))); top: calc(-1 * var(--o)); }
@media (max-width: 1023px) {   /* narrower than a laptop the gutter is too tight for the crosshair: it moves to the figure's right, the bracket to its foot on the left */
  .dim .fnd-lead .fnd-v .mk-cross[data-at="tl"] { left: auto; right: calc(-1 * (var(--o) + var(--arm) * 2 + .04em)); }
  .dim .fnd-lead .fnd-v .mk-br[data-at="tr"] { right: auto; left: 0; top: auto; bottom: calc(-1 * var(--o)); }
  /* Krish, 2026-09-19: the phone puts the lead's bracket at the bottom-left corner, so its legs face that corner too (it read ┐ instead of └) */
  .dim .fnd-lead .fnd-v .mk-br[data-at="tr"]::before { top: auto; bottom: 0; transform-origin: 0 50%; }
  .dim .fnd-lead .fnd-v .mk-br[data-at="tr"]::after { right: auto; left: 0; transform-origin: 50% 100%; }
}
/* "More detail": the word, mono, underlined like a link (round five's drawer control; v6 push 5: the plus and its rules are gone) */
.dim .fnd-more { display: inline-flex; align-items: center; gap: 8px; font-family: var(--mono); font-weight: 400; font-size: 12px; line-height: 1; letter-spacing: .1em; text-transform: uppercase; -webkit-text-stroke: .32px currentColor; opacity: .9; transition: opacity 240ms var(--ease); }
.dim .fnd-more-l { border-bottom: 1px solid currentColor; padding-bottom: 3px; }
.dim .fnd.is-open .fnd-more { opacity: 1; }
@media (hover: hover) {
  .dim .fnd-btn:hover .fnd-v::after, .dim .fnd.is-open .fnd-v::after { transform: none; }
  .dim .fnd-btn:hover .fnd-more { opacity: 1; }
}
.dim .fnd.is-open .fnd-v::after { transform: none; }
/* the detail region: on the laptop it takes the question's place (absolute at the question's top, --hy; the question and the
   deck fade while a drawer is open, so the drawer lands on the one field every poster keeps legible and the row never moves);
   one drawer open at a time. On the phone it follows the figures. */
.dim .fnd-details { position: absolute; left: var(--gutter); top: max(var(--hy, 12vh), 118px); width: min(calc(100% - 2 * var(--gutter)), 720px); }   /* never over the name (88px strip + the label) */
.dim .fnd-drawer { width: 100%; }
.dim .fnd-detail-v { flex: 0 0 auto; width: 100%; font-family: var(--mono); font-weight: 400; font-size: 11px; line-height: 1.5; letter-spacing: .1em; text-transform: uppercase; -webkit-text-stroke: .32px currentColor; }
.dim .fnd-detail { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 18px 48px; padding-bottom: 4px; font-family: var(--sans); font-weight: 300; font-size: 14px; line-height: 1.45; letter-spacing: 0; text-transform: none; }
.dim .fnd-dl { margin: 0; flex: 1 1 36ch; max-width: 46ch; display: flex; flex-direction: column; gap: 6px; }
.dim .fnd-dl-row { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 0 14px; align-items: baseline; }
.dim .fnd-dl dt { font-family: var(--mono); font-weight: 400; font-size: 11px; line-height: 1.6; letter-spacing: .1em; text-transform: uppercase; -webkit-text-stroke: .32px currentColor; opacity: .8; white-space: nowrap; }
.dim .fnd-dl dd { margin: 0; }
/* while a drawer is open the question and the deck give the drawer their place: the reader is in the detail */
.dim .hl, .dim .dim-deck { transition: opacity 240ms var(--ease); }
.dim.has-open .hl, .dim.has-open .dim-deck { opacity: 0; pointer-events: none; }
/* a comparison in the drawer: its title (the data file's), its rows with the figure, the label and a bar the figure's length, its note */
.dim .cmp { position: relative; flex: 1 1 30ch; max-width: 40ch; min-width: 0; margin: 0; }
.dim .cmp .cmp-title { display: block; margin: 0 0 8px; font-size: 13px; line-height: 1.4; opacity: .8; }
.dim .cmp .cmp-row { display: grid; grid-template-columns: max-content minmax(0, 15ch) 160px; column-gap: 12px; align-items: baseline; margin-top: 4px; }   /* one line: the figure, its label, a bar the figure's length on a 160px track */
.dim .cmp .cmp-v { min-width: 3.1ch; font-family: var(--sans); font-weight: 300; font-size: 22px; line-height: 1.2; letter-spacing: -.02em; font-variant-numeric: tabular-nums; text-align: right; }
.dim .cmp .cmp-l { font-size: 13px; line-height: 1.3; }
.dim .cmp .cmp-bar { display: block; height: 3px; width: 0; align-self: center; background: currentColor; transition: width 640ms var(--ease) 120ms; }
.dim .cmp .cmp-note { display: block; margin-top: 10px; font-size: 13px; line-height: 1.4; opacity: .8; max-width: 40ch; }
/* ---- the phone and the tablet (under 1024): the poster opens full-screen the same way; its column runs down the page and scrolls
   inside the poster under the fixed strips; the lead row's crosshair stands at its right, inside the screen ---- */
@media (max-width: 1023px) {
  .dim .fr-img img, .dim .fr-twin img { object-position: var(--pos-p, 50% 50%); }   /* v6 motion piece 5: the twin at the phone's focal point too (it resolved over a picture up to 10% away — Awe's 60% vs 50%) */
  .dim .txt { -webkit-overflow-scrolling: touch; padding: 88px var(--gutter) 128px; }   /* round six: the last figure's marker clears the bottom strip and the ticks */
  .dim-label { margin: 0 0 1.4em; }
  .dim .hl { margin: 0 0 1.4em; max-width: none; }
  .dim-deck { margin: 0 0 1.8em; max-width: 34ch; font-size: 16px; }
  .dim .col, .dim[data-col="right"] .col { position: static; right: auto; bottom: auto; margin: 0; width: 100%; max-width: none; align-self: auto; align-items: flex-start; }
  .dim .fnds, .dim[data-col="right"] .fnds, .dim[data-stack] .fnds { flex-direction: column; align-items: flex-start; justify-content: flex-start; gap: 24px; }
  .dim .fnd-side-rows { max-width: none; gap: 12px 28px; }
  .dim[data-stack] .fnd-lead .fnd-v { font-size: clamp(64px, 19vw, 84px); }
  .dim .fnd, .dim .fnd-lead { flex: 0 0 auto; width: 100%; }
  .dim .fnd-lead .fnd-v { font-size: clamp(64px, 19vw, 84px); }
  .dim .fnd-lead .fnd-v .mk-cross[data-at="tl"] { left: auto; right: calc(-1 * (var(--o) + var(--arm) * 2 + .04em)); }   /* the crosshair at the figure's right, inside the screen */
  .dim .fnd-lead .fnd-v .mk-br[data-at="tr"] { right: auto; left: 0; top: auto; bottom: calc(-1 * var(--o)); }
  /* Krish, 2026-09-19: the phone puts the lead's bracket at the bottom-left corner, so its legs face that corner too (it read ┐ instead of └) */
  .dim .fnd-lead .fnd-v .mk-br[data-at="tr"]::before { top: auto; bottom: 0; transform-origin: 0 50%; }
  .dim .fnd-lead .fnd-v .mk-br[data-at="tr"]::after { right: auto; left: 0; transform-origin: 50% 100%; }
  .dim .fnd-details { position: static; width: 100%; margin-top: 24px; }   /* the drawers follow the figures on the phone */
  .dim[data-stack] .fnd-side { flex: 0 0 auto; width: 100%; gap: 24px; }
  .dim .fnd-dl-row { grid-template-columns: 1fr; gap: 2px; }
  .dim .cmp .cmp-row { grid-template-columns: max-content minmax(0, 1fr); grid-template-rows: auto auto; row-gap: 4px; }
  .dim .cmp .cmp-bar { max-width: 100%; }
  .dim .cmp .cmp-v { grid-row: 1 / 3; align-self: start; }
  .dim.has-open .hl, .dim.has-open .dim-deck { opacity: 1; pointer-events: auto; }   /* the phone scrolls: nothing gives way */
  .dim .fnd-detail { flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 20px; padding: 0 0 8px; justify-content: flex-start; }
  .dim .fnd-dl, .dim .cmp { flex: 0 0 auto; width: 100%; max-width: 40ch; }
  /* v6 push 5: the six dashes fill the middle of the top strip between '← BACK' and the quiz link and shrink before the labels do
     (aria-hidden and tabindex -1 from setStrips); the bottom strip shows its back */
  .dim-ticks { order: 0; flex: 1 1 auto; min-width: 0; justify-content: center; gap: 4px; margin: 0 8px; pointer-events: none; }
  .dim-quiz { order: 1; margin-left: 0; }
  .dim-tick { flex: 0 1 14px; width: auto; min-width: 4px; pointer-events: none; }   /* (pointer-events inherits: the dash itself says none, the strip's other links say auto) */
  .dim-tick::before { width: 100%; }
  .dim-bottom .dim-back { display: inline-flex; }
}

/* ---- growing reveals (round two): "Measured as" and the results' detail grow over 320ms instead of popping; nothing is inserted ---- */
.v5-grow { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 320ms var(--ease); }
.v5-grow.is-open { grid-template-rows: 1fr; }
.v5-grow > * { overflow: hidden; min-height: 0; opacity: 0; transition: opacity 240ms var(--ease) 80ms; }
.v5-grow.is-open > * { opacity: 1; }
/* the way back on the results and About views: top-left, at the same place on both */
.af-sec-results, .af-sec-about { position: relative; }
.af-back-top { position: absolute; top: 66px; left: var(--gutter); display: inline-flex; align-items: center; min-height: 44px; padding: 0; font-family: 'Messina Mono', Menlo, monospace; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; -webkit-text-stroke: .32px currentColor; text-decoration: none; color: inherit; }

/* ---- reduced motion: no cue, no hover scale; a poster opens, steps and closes by a 200ms fade only — no twin, no expose, no rise;
   the reveals at their state. The template's global rule zeroes every animation and transition; these outrank it by specificity.
   v6 motion piece 0: the 200ms fades below STAY — the coordinator's ruling of 2026-09-19 keeps the poster's opacity-only fade under
   Reduce Motion as R8's one recorded exception (the motion spec's cut, reversal 36, is not applied; T.reduced stays 200). ---- */
@media (prefers-reduced-motion: reduce) {
  .door-name { opacity: 1; }
  .door-img img, .door:is(:hover, :focus-visible, .is-hot, .is-pressed) .door-img img { transform: none !important; opacity: 1 !important; }
  .dim-next.is-pressed { transform: none; }   /* v6 motion piece 5 (R8): a tap answers by opacity only */
  .dims::before, .dims.is-open::before { transition: opacity 200ms linear 0ms !important; }
  .dim.is-cur, .dim.is-stepping { animation: v5-fade 200ms linear both !important; }
  .dim.is-closing { animation: v5-fade-out 200ms linear both !important; }
  .dim.is-closing .txt, .dim.is-leaving .txt, .dim.is-closing .dim-top, .dim.is-closing .dim-bottom, .dim.is-leaving .dim-top, .dim.is-leaving .dim-bottom { opacity: 1; transition: none !important; animation: none !important; }
  .dim .fr-twin { display: none; }
  .dim .fr-img, .dim .fr-twin, .dim .fr-p { clip-path: none !important; transition: none !important; }
  .door .mk-br { opacity: 1; }
  .v5-doors.is-cueing .mk-br.draws::before, .v5-doors.is-cueing .mk-br.draws::after { transform: none !important; }
  .dim.is-cur .hl .ln, .dim.is-cur .dim-label, .dim.is-cur .dim-deck, .dim.is-cur .col, .dim.is-cur .dim-top, .dim.is-cur .dim-ticks, .dim.is-cur .dim-bottom { animation: none !important; }
  [data-parallax] { transform: none !important; }
  .v5-grow, .v5-grow > * { transition: none !important; }
}

/* the line under the six (Krish's decision 1): four words Dom can rewrite, in the template */
.v5-doors-cue { margin: 0 0 .3em; text-align: right; font-family: var(--mono, 'Messina Mono', Menlo, monospace); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; opacity: 1; -webkit-text-stroke: .32px currentColor; }

/* ==== round six: the pictures inside a poster (site/v5/dives.js) =================================================
   A tap on a figure takes the poster's viewport: the photograph fades to pure black under a ground of its own, the tapped
   number travels into the picture's head and is drawn as LIGHT (the poster's blurred numeral, tinted with the dimension's
   glow, no filter: a text-shadow twin), the hundred forms in the stage, the annotation lands at the foot, the rail in the
   bottom strip names the dimension's pictures. Light on black; the ink dimensions (Presence, Emotions) keep their
   photographs from their own pushes on. Nothing here carries filter, will-change or clip-path. ---- */
.dive { position: absolute; inset: 0; z-index: 4; color: #fff; }
.dive[hidden] { display: none; }
.dv-ground { position: absolute; inset: 0; background: #000; opacity: 0; }
.dim.has-dive .dim-bottom { visibility: hidden; pointer-events: none; }   /* v6 push 5: visibility, since the strip's fade-in (v5-fade, fill both) holds its opacity at 1 */
.dim.has-dive .dim-top, .dim.has-dive .dim-ticks { z-index: 6; color: #fff; }
.dim.has-dive .txt { pointer-events: none; }
/* v6 pictures push 1: the ink stage (Presence, Emotions) — a white ground, black hairlines, the measure in the tint; the strips' ground
   white; the head figure and the sub-figures in ink with one tinted twin and no glow (data-ground on .dive and on the poster, per kind) */
.dive[data-ground="ink"] { color: #000; }
.dive[data-ground="ink"] .dv-ground { background: #fff; }
.dim.has-dive[data-ground="ink"] .dim-top, .dim.has-dive[data-ground="ink"] .dim-ticks { color: #000; }
.dim.has-dive.is-scrolled[data-ground="ink"] .dim-top { background-color: rgba(255, 255, 255, .92); }
.dim.has-dive.has-more[data-ground="ink"] .dv-rail { background-color: rgba(255, 255, 255, .92); }
.dive[data-ground="ink"] .dv-fig .dv-g { color: #000; }
.dive[data-ground="ink"] .dv-fig .dv-e { opacity: 0; }
.dive[data-ground="ink"] .dv-fig .dv-b { color: rgb(var(--t)); text-shadow: none; opacity: .9; transform: translate(.05em, .05em); }
.dive[data-ground="ink"] .dv-sub .dv-fig-s .dv-b { opacity: 0; }   /* the ink sub-figure is the plain glyph: at 14px the .05em twin is a fringe (review round 2); the head keeps its twin */
/* the laptop: the head beside the stage, the fine print under the head (v6 pictures push 1: .dv-after, so on the phone the form comes
   before the fine print and sits on the first screen) */
.dv-in { position: absolute; inset: 0; display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); grid-template-rows: auto auto; grid-template-areas: "head stage" "after stage"; align-content: center; column-gap: 48px; row-gap: 20px; padding: 88px var(--gutter) 116px; }
.dv-head { grid-area: head; align-self: end; }
.dv-after:empty { display: none; }   /* Krish, 2026-09-19: no fine print on a picture page */
.dv-after { grid-area: after; align-self: start; display: flex; flex-direction: column; gap: 10px; align-items: flex-start; font-family: var(--sans); font-weight: 300; }
.dv-stage { grid-area: stage; align-self: center; }
/* the head: the figure as light, its sentence; after the stage the fine print, the comparison's title and note */
.dv-head { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 18px; font-family: var(--sans); font-weight: 300; }   /* relative: the step's ghosts sit at their offsets (v6 pictures push 1, round 2) */
.dv-head .dv-ghost { position: absolute; margin: 0; pointer-events: none; }   /* v6 pictures push 1, round 2: the step's crossfade — the outgoing figure and sentence cloned in place over the new head, fading as the new ones come in */
.dv-fig { position: relative; display: inline-block; font-family: var(--sans); font-weight: 300; font-size: clamp(76px, 7.4vw, 112px); line-height: .9; letter-spacing: -.025em; font-variant-numeric: tabular-nums; padding: .12em .3em .1em .18em; margin: -.12em 0 0 -.18em; }
.dv-fig > span { display: block; grid-area: 1 / 1; }
.dv-fig { display: inline-grid; }
.dv-fig .dv-b { color: rgb(var(--t, 255,255,255)); text-shadow: 0 0 .06em rgb(var(--t, 255,255,255)), 0 0 .2em rgb(var(--t, 255,255,255)), 0 0 .5em rgba(var(--t, 255,255,255), .6); opacity: .85; }   /* the soft body */
.dv-fig .dv-e { color: #fff; text-shadow: 0 0 .04em #fff; opacity: .6; transform: translate(-.012em, -.02em); }   /* the crisper edge */
.dv-fig .dv-g { color: #fff; }   /* the glyph */
/* the lead figure's pair of marks, placed as the poster's (the em is the figure's own size): the crosshair at its head on the
   left, the bracket at its head on the right, both clear of the glyphs; the crosshair grows from its centre and the bracket's
   legs draw from the corner once the figure has landed (.is-undrawn is lifted from the timeline) */
.dv-fig .mk { --arm: .22em; --leg: .2em; --o: .1em; }
.dv-fig .mk-cross[data-at="tl"] { left: calc(.18em - (var(--o) + var(--arm) * 2 + .04em)); top: calc(.12em - var(--arm) + .04em); transition: transform 240ms var(--ease) 80ms; }
.dv-fig .mk-br[data-at="tr"] { right: calc(.3em - (var(--o) + var(--leg))); top: calc(.12em - var(--o)); }
.dv-fig.is-undrawn .mk-cross { transform: scale(0); }
.dv-fig .mk-br.draws::before, .dv-fig .mk-br.draws::after { transition: transform 200ms var(--ease); }
.dv-fig .mk-br.draws::after { transition-delay: 120ms; }
.dv-fig-s { font-size: clamp(28px, 2.6vw, 40px); padding: .1em .2em .06em .1em; margin: 0; }
.dv-sent { margin: 0; max-width: 22ch; font-size: clamp(18px, 1.55vw, 24px); line-height: 1.35; text-wrap: pretty; }
.dv-foot { margin: 0; display: flex; flex-direction: column; gap: 4px; max-width: 40ch; font-size: 13px; line-height: 1.45; }
.dv-foot > div { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 0 12px; align-items: baseline; }
.dv-foot dt { font-family: var(--mono); font-weight: 400; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; -webkit-text-stroke: .32px currentColor; opacity: .8; white-space: nowrap; }
.dv-foot dd { margin: 0; opacity: 1; }
.dv-title { margin: 8px 0 0; font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; -webkit-text-stroke: .32px currentColor; opacity: .8; }
.dv-note { margin: 0; max-width: 40ch; font-size: 15px; line-height: 1.45; opacity: .85; text-wrap: pretty; }
/* the stage: the hundred and its hairlines in one SVG sized to the picture's own frame; the labels and sub-figures in HTML over it */
.dv-stage { position: relative; width: 100%; max-width: 100%; aspect-ratio: 358 / 300; justify-self: center; }   /* the width is set per picture by dives.js so the box never outgrows the window's height; v6 motion piece 2: every kind is 358x300 (P10), the default the same */
.dv-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.dv-seed-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }   /* v6 pictures push 1: the seed-carry's light over the stage (dives.js seedLayer); motion piece 2: the stage's ONE light (P1), never removed while a picture is up, its comet drawn in currentColor */
.dv-twin, .dv-comet, .dv-ring { pointer-events: none; }   /* v6 motion piece 2: the running light's twin (a 4px clone under the hairline), the comet and a ring never take a tap */
.dive[data-ground="ink"] .dv-seed-svg { color: #000; }   /* v6 motion piece 2: the seed's ink style — the comet and a ring in ink; the disc and its tint twin are set by V5GSAP.seed.style('ink') */
.dv-lbl.dv-ringlbl { text-align: center; }   /* v6 motion piece 2: the rings' labels centred over each ring */
.dv-sub.dv-ringsub { align-items: center; text-align: center; }   /* the rings' sub-figures at the centres (translated -50% / -50% by dives.js) */
.dv-labels { position: absolute; inset: 0; pointer-events: none; }
.dv-lbl { position: absolute; font-family: var(--mono); font-weight: 400; font-size: 12px; line-height: 1.4; letter-spacing: .1em; text-transform: uppercase; -webkit-text-stroke: .32px currentColor; opacity: .85; white-space: nowrap; }
.dv-lbl.dv-mid, .dv-lbl.dv-axis { white-space: normal; opacity: .6; }
.dv-lbl.dv-axis { font-family: var(--sans); font-weight: 300; font-size: 14px; letter-spacing: 0; text-transform: none; -webkit-text-stroke: 0; opacity: .8; }
.dv-sub { position: absolute; display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.dv-sub-l { font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; opacity: .85; }
.dv-sub-line { font-family: var(--sans); font-weight: 300; font-size: 13px; opacity: .8; white-space: nowrap; }
.dv-unit { position: absolute; right: 0; bottom: -22px; font-family: var(--mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; opacity: .5; }
/* v6 pictures push 1: the 358x300 kinds' labels — the ink sub-figure (14px, no padding), the word centred over its stem (the words),
   the mid and end labels of the two-ends axis, the held member's label at full weight, the tap targets, the in-stage unit line */
.dv-sub.dv-ink .dv-fig-s { font-size: 14px; padding: 0; }
.dv-sub.dv-wordsub { width: calc(60 / 358 * 100%); align-items: center; text-align: center; }
.dv-sub.dv-right { align-items: flex-end; text-align: right; }   /* v6 pictures push 1: a sub-figure placed by its right edge (the lamps' high end) */
.dv-lbl.dv-mid { font-size: 11px; }
.dv-lbl.dv-end { white-space: normal; }
.dv-lbl.is-held, .dv-sub.is-held .dv-sub-l { -webkit-text-stroke: .6px currentColor; opacity: 1; }
.dv-hit { cursor: pointer; }
.dv-unit-in { font-family: var(--mono); text-transform: uppercase; }
/* the rail: the dimension's pictures by number and name in the bottom strip, the current one carrying the 2px rule; Next at the right */
.dv-rail { position: absolute; left: 0; right: 0; bottom: 0; z-index: 5; min-height: 64px; padding: 6px var(--gutter) 10px; display: flex; flex-wrap: wrap; align-items: center; gap: 0 24px; }   /* the names wrap onto a second line when a page has many pictures (Energy has six) */
.dv-rail::-webkit-scrollbar { display: none; }
.dv-rail-b, .dv-next { position: relative; display: inline-flex; align-items: center; min-height: 44px; margin: 0; padding: 0; border: 0; background: none; color: inherit; font-family: var(--mono); font-weight: 400; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; -webkit-text-stroke: .32px currentColor; white-space: nowrap; cursor: pointer; opacity: .6; -webkit-tap-highlight-color: transparent; }
.dv-rail-b::after { content: ""; position: absolute; left: 0; right: 0; bottom: 8px; height: 2px; background: currentColor; transform: scaleX(0); transform-origin: 0 50%; transition: transform 240ms var(--ease); }
.dv-rail-b.is-cur { opacity: 1; } .dv-rail-b.is-cur::after { transform: none; }
.dv-next { margin-left: auto; opacity: 1; }
.dv-rail-b:focus-visible, .dv-next:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }
@media (hover: hover) { .dv-rail-b:hover { opacity: 1; } .dv-rail-b:hover::after { transform: none; } }
/* the marker under each figure on the poster (in place of "more detail"): the picture's number and name, mono, with the plus */
.dim .fnd-mark { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; font-family: var(--mono); font-weight: 400; font-size: 12px; line-height: 1; letter-spacing: .1em; text-transform: uppercase; opacity: 1; }   /* v6: the marker is the site's link: the hairline under the words, the arrow at the label's size, no plus */
.dim .fnd-mark-l { border-bottom: 1px solid currentColor; padding-bottom: 3px; }
.dim .fnd-mark::after { content: "\2192"; display: inline-block; transition: transform 240ms var(--ease); }
@media (hover: hover) { .dim .fnd-btn:hover .fnd-mark-l { border-bottom-width: 2px; } .dim .fnd-btn:hover .fnd-mark::after { transform: translateX(4px); } }
/* the phone: the picture as a column under the top strip — the head, the stage sized to the width, the rail as dashes and names */
@media (max-width: 1023px) {
  .dv-in { display: flex; flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 16px; padding: 92px 16px 72px; overflow-y: auto; overflow-x: hidden; touch-action: pan-y; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; scrollbar-width: none; }   /* v6 push 5: the picture scrolls on the phone (the breakdowns overflow); vertical is scroll, never a close. v6 pictures push 1: 16px margins, so a 358-wide stage fills a 390 screen */
  .dv-in::-webkit-scrollbar { display: none; }
  .dv-head { gap: 10px; align-self: auto; }   /* (align-self: end is the laptop grid's) */
  .dv-after { margin-top: 26px; gap: 8px; align-self: auto; }   /* v6 pictures push 1: after the stage, clear of the unit line at bottom -22px */
  .dv-lbl.dv-axis { font-size: 13px; }
  .dv-fig { font-size: clamp(56px, 17vw, 72px); }
  .dv-fig .mk-cross[data-at="tl"] { left: auto; right: calc(.3em - (var(--o) + var(--arm) * 2 + .04em)); }   /* as the poster's: the crosshair at the figure's right, the bracket at its foot on the left */
  .dv-fig .mk-br[data-at="tr"] { right: auto; left: calc(.18em - var(--o)); top: auto; bottom: calc(.1em - var(--o)); }
  .dv-fig .mk-br[data-at="tr"]::before { top: auto; bottom: 0; transform-origin: 0 50%; }
  .dv-fig .mk-br[data-at="tr"]::after { right: auto; left: 0; transform-origin: 50% 100%; }   /* the picture head's bracket faces its bottom-left corner on the phone (Krish, 2026-09-19) */
  .dv-sent { font-size: 17px; max-width: 26ch; }
  .dv-foot { font-size: 12px; max-width: none; } .dv-foot > div { grid-template-columns: 1fr; gap: 0; }
  .dv-note { font-size: 14px; }
  .dv-stage { align-self: center; }
  .dv-lbl { font-size: 10px; } .dv-fig-s { font-size: 26px; } .dv-sub-line { font-size: 11px; }
  .dv-sub.dv-jarsub .dv-fig-s { font-size: 22px; }   /* v6 pictures push 1: the jars' figures sit between a jar and a mark (or the stage's edge): 22px keeps them clear */
  .dv-rail { min-height: 56px; flex-wrap: nowrap; gap: 0 18px; padding: 0 16px 0 var(--gutter); overflow-x: auto; scrollbar-width: none; }   /* the phone's rail scrolls sideways; the current name centred by dives.js (v6 push 5); 16px at the right: the next link is stuck there (pictures push 1, review 2; was a 40px peek) */
  .dv-rail-b { font-size: 12px; opacity: .85; }   /* v6 push 5: the names at the mono floor; the current one stays at 1 */
  /* v6 pictures push 1 (review 2): the next link stays inside the screen at the right margin when a name runs long (at 375 the words' one
     name is 324px and its rail can never fit), the names scrolling under it; its ground is the stage's own, so no box shows. (The sticky
     inset is measured inside the rail's padding, hence right: 0 with the 16px end padding.) */
  .dv-next { position: sticky; right: 0; flex: none; padding-left: 6px; background-color: #000; }   /* 6px: at 390 the clock's rail fits and the stuck link ends exactly at its name's edge */
  .dv-next::before { content: ""; position: absolute; left: -16px; top: 0; bottom: 0; width: 16px; background: linear-gradient(to right, transparent, #000); pointer-events: none; }   /* v6 pictures push 1, round 2: a 16px fade from the names into the stuck link's ground, so a long name fades under it instead of cutting mid-letter (a gradient, no filter) */
  .dive[data-ground="ink"] .dv-next { background-color: #fff; }
  .dive[data-ground="ink"] .dv-next::before { background: linear-gradient(to right, transparent, #fff); }
  .dim.has-dive .dim-ticks { display: none; }   /* the bottom strip is the rail's on the phone */
}
@media (prefers-reduced-motion: reduce) {
  .dv-ground { opacity: 1 !important; }
  .dim.has-dive .fr-img, .dim.has-dive .fr-twin, .dim.has-dive .fr-p, .dim.has-dive .txt { opacity: 0 !important; }
}


/* ---- safe areas (viewport-fit=cover), declared last so no padding shorthand above overrides them (v6 push 5, review 2): the strips grow
   by the insets (content-box: the top strip 64 + inset-top; the bottom strip and the rail + max(10px, inset-bottom)); on the phone the
   column and the picture start under the top strip (88 / 92 + inset-top) and the picture's last lines clear the rail (72 + inset-bottom).
   Headless: the insets are 0, so 88 / 92 / 72 hold. ---- */
.dim-top { padding-top: env(safe-area-inset-top); box-sizing: content-box; }
.dim-bottom, .dv-rail { padding-bottom: max(10px, env(safe-area-inset-bottom)); box-sizing: content-box; }
@media (max-width: 1023px) {
  .dim .txt { padding-top: calc(88px + env(safe-area-inset-top)); }
  .dv-in { padding-top: calc(92px + env(safe-area-inset-top)); padding-bottom: calc(72px + env(safe-area-inset-bottom)); }
}
