/*
 * HRD storyboard (homepage). Every scene derives its motion from --p (0..1),
 * set by assets/js/story.js. Sub-ranges are carved out with clamp():
 *   --a: clamp(0, (var(--p) - START) / LENGTH, 1)
 */

/* ---------- Scene scaffold ---------- */
.hrd-story,
.hrd-story > * { margin-block: 0 !important; }

.hrd-scene {
	--p: 0;
	position: relative;
	height: var(--scene-length, 300vh);
	max-width: none !important;
	margin: 0 !important;
	padding: 0 !important;
}
.hrd-stage {
	position: sticky;
	top: 0;
	height: 100vh;
	height: 100svh;
	overflow: hidden;
	max-width: none !important;
	margin: 0 !important;
}
/* Stage layers are absolutely stacked; neutralise block-layout margins. */
.hrd-stage > * {
	position: absolute !important;
	max-width: none !important;
	margin: 0 !important;
}

/* ---------- Homepage header floats over the landing (paper: ink type, the ink mark) ---------- */
.hrd-has-story .wp-site-blocks > header:first-child {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	z-index: 50;
}
.hrd-has-story .wp-site-blocks > header:first-child > .wp-block-group { background: transparent !important; color: var(--wp--preset--color--ink) !important; }
.hrd-has-story .wp-site-blocks > header:first-child .hrd-header__row > .wp-block-navigation > .wp-block-navigation__container > .wp-block-navigation-item > a,
.hrd-has-story .wp-site-blocks > header:first-child .hrd-header__row > .wp-block-navigation > .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .wp-block-navigation-item > :is(a, button),
.hrd-has-story .wp-site-blocks > header:first-child .hrd-header__row > .wp-block-navigation > .wp-block-navigation__responsive-container-open,
.hrd-has-story .wp-site-blocks > header:first-child .hrd-header__icons :is(a, button) { color: var(--wp--preset--color--ink) !important; }

/* On ultrawide stages the cover-cropped strut reaches the header's content frame.
   Give the existing navigation its own paper ground; keep the art and frame intact. */
@media (min-width: 2000px) and (min-aspect-ratio: 2/1) {
	.hrd-has-story .wp-site-blocks > header:first-child:not([data-dock]) > .wp-block-group {
		background: var(--wp--preset--color--paper) !important;
	}
}

/* THE WAY OUT (story.js): past the landing the header docks, fixed and hidden above the top; it slides back
   in whenever you scroll up, on the chapter's own ground (--hdr-bg) in its tone, a hairline under it. */
.hrd-has-story .wp-site-blocks > header:first-child[data-dock] {
	position: fixed;
	transform: translateY(-100%);
	transition: transform 0.32s var(--wp--custom--ease-out), box-shadow 0.32s;
}
.hrd-has-story .wp-site-blocks > header:first-child[data-dock="in"] { transform: none; box-shadow: 0 1px 0 rgb(4 1 29 / 0.1); }
.hrd-has-story .wp-site-blocks > header:first-child[data-dock] > .wp-block-group { background: var(--hdr-bg, var(--wp--preset--color--paper)) !important; }
.hrd-has-story .wp-site-blocks > header:first-child[data-dock][data-tone="dark"] { box-shadow: 0 1px 0 rgb(255 255 255 / 0.12); }
.hrd-has-story .wp-site-blocks > header:first-child[data-dock][data-tone="dark"] > .wp-block-group,
.hrd-has-story .wp-site-blocks > header:first-child[data-dock][data-tone="dark"] .hrd-header__row > .wp-block-navigation > .wp-block-navigation__container > .wp-block-navigation-item > a,
.hrd-has-story .wp-site-blocks > header:first-child[data-dock][data-tone="dark"] .hrd-header__row > .wp-block-navigation > .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .wp-block-navigation-item > :is(a, button),
.hrd-has-story .wp-site-blocks > header:first-child[data-dock][data-tone="dark"] .hrd-header__row > .wp-block-navigation > .wp-block-navigation__responsive-container-open,
.hrd-has-story .wp-site-blocks > header:first-child[data-dock][data-tone="dark"] .hrd-header__icons :is(a, button) { color: var(--wp--preset--color--white) !important; }
/* the white mark over ink (functions.php puts it beside the ink one) */
.hrd-has-story .wp-site-blocks > header:first-child [data-hrd-logo-light],
.hrd-has-story .wp-site-blocks > header:first-child[data-dock][data-tone="dark"] .custom-logo:not([data-hrd-logo-light]) { display: none; }
.hrd-has-story .wp-site-blocks > header:first-child[data-dock][data-tone="dark"] [data-hrd-logo-light] { display: block; }

/* ---------- Viewfinder: fixed corner arrows, folio, slashes progress ---------- */
.hrd-viewfinder {
	--vf-color: var(--wp--preset--color--sky);
	--vf-inset: clamp(16px, 2.2vw, 32px);
	position: fixed;
	inset: 0;
	z-index: 40;
	pointer-events: none;
	color: var(--vf-color);
}
.hrd-viewfinder[data-tone="light"] { --vf-color: var(--wp--preset--color--ink); }
/* Each piece (the arrows, "Shop", the folio) takes its own tone the moment the exit slash's edge crosses it
   (story.js), or as 03's bore fills the corners (data-dark), so it changes with the ground under it, in the same
   frame: no fade (a fade trailed the slash's edge by ~120px). */
.hrd-viewfinder > [data-tone] { color: var(--vf-color); transition: none; }
.hrd-viewfinder > [data-tone="light"] { --vf-color: var(--wp--preset--color--ink); }
.hrd-viewfinder > [data-tone="dark"] { --vf-color: var(--wp--preset--color--sky); }
.hrd-viewfinder { transition: opacity 0.4s var(--wp--custom--ease-out); } /* its pieces change tone in step with the ground: no fade */
.hrd-viewfinder.is-off { opacity: 0; }
.hrd-viewfinder i {
	position: absolute;
	width: var(--hrd-arrow-size);
	height: var(--hrd-arrow-size);
	background: currentColor;
	-webkit-mask: var(--hrd-arrow-svg) center / contain no-repeat;
	mask: var(--hrd-arrow-svg) center / contain no-repeat;
}
/* --vf-top: story.js keeps the top arrows clear of the header until it scrolls away; this default is the
   landing header's height, so the first paint (before the deferred script) already is */
.hrd-has-story .hrd-viewfinder { --vf-top: 84px; }
.hrd-viewfinder i:nth-of-type(1) { top: calc(var(--vf-inset) + var(--vf-top, 0px)); left: var(--vf-inset); }
.hrd-viewfinder i:nth-of-type(2) { top: calc(var(--vf-inset) + var(--vf-top, 0px)); right: var(--vf-inset); transform: rotate(90deg); }
.hrd-viewfinder i:nth-of-type(3) { bottom: var(--vf-inset); left: var(--vf-inset); transform: rotate(-90deg); }
.hrd-viewfinder i:nth-of-type(4) { bottom: var(--vf-inset); right: var(--vf-inset); transform: rotate(180deg); }
/* The way out: "SHOP ↗" centred at the top, between the corner arrows, the site's arrow link (hrd.css
   .hrd-arrow-link: the "Explore drivetrain ↗" style) 2px up from micro and underlined, so it reads as a button.
   Its type hangs from the arrows' top edge; the tap area is 45px tall. It shows while the header doesn't (the
   header has its own Shop); Esc goes there too (story.js), with no keycap shown (the user, 2026-11-08). */
.hrd-viewfinder .hrd-viewfinder__shop { /* (beats hrd.css a.hrd-arrow-link's size) */
	position: absolute;
	top: calc(var(--vf-inset) + var(--vf-top, 0px) - 16px);
	left: 50%;
	transform: translateX(-50%);
	padding: 16px;
	font-size: calc(var(--wp--preset--font-size--micro) + 2px);
	line-height: 1;
	white-space: nowrap;
	color: var(--vf-color); /* its own tone (story.js) */
	text-decoration: underline;
	text-decoration-thickness: 1.5px;
	text-underline-offset: 4px;
	pointer-events: auto;
	transition: opacity 0.3s, visibility 0.3s;
}
.hrd-viewfinder[data-header] .hrd-viewfinder__shop,
.hrd-viewfinder.is-off .hrd-viewfinder__shop { opacity: 0; visibility: hidden; }
.hrd-viewfinder__shop:focus-visible { outline: 1.5px solid currentColor; outline-offset: -6px; border-radius: 2px; }
@media (prefers-reduced-motion: reduce) {
	.hrd-has-story .wp-site-blocks > header:first-child[data-dock],
	.hrd-viewfinder__shop { transition: none; }
}

.hrd-viewfinder__folio {
	position: absolute;
	bottom: calc(var(--vf-inset) + 0.6em);
	left: 50%;
	transform: translateX(-50%);
	display: flex;
	align-items: center;
	gap: 14px;
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 700;
	letter-spacing: var(--wp--custom--track--micro);
	text-transform: uppercase;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}
/* Slashes that fill left→right with overall scroll progress */
.hrd-viewfinder__progress {
	--hz: 12px;
	position: relative;
	width: calc(var(--hz) * 9);
	height: var(--hz);
}
.hrd-viewfinder__progress::before,
.hrd-viewfinder__progress::after {
	content: "";
	position: absolute;
	inset: 0;
	background: repeating-linear-gradient(55deg, currentColor 0 calc(var(--hz) * .33), transparent calc(var(--hz) * .33) calc(var(--hz) * .56));
}
.hrd-viewfinder__progress::before { opacity: 0.25; }
.hrd-viewfinder__progress::after { clip-path: inset(0 calc((1 - var(--story-progress, 0)) * 100%) 0 0); }
/* While the film is short of frames (play.js --story-ready, unset once it's all here): the ready stretch, a
   half-tone fill between the played slashes and the rest, as a video's buffer bar */
.hrd-viewfinder__progress {
	background: repeating-linear-gradient(55deg, color-mix(in srgb, currentColor 35%, transparent) 0 calc(var(--hz) * .33), transparent calc(var(--hz) * .33) calc(var(--hz) * .56)) 0 0 / calc(var(--story-ready, 0) * 100%) 100% no-repeat;
}

/* "Play the story" (assets/js/play.js): a play/pause beside the progress slashes,
   in the chrome's own tone; the hit area is larger than the 11px glyph. */
.hrd-viewfinder__play {
	position: absolute; /* out of the folio's flow: the slashes stay centred */
	left: 100%;
	top: 50%;
	pointer-events: auto;
	display: grid;
	place-items: center;
	width: 30px;
	height: 30px;
	margin: -15px 0 0 6px;
	padding: 0;
	border: 0;
	background: none;
	color: inherit;
	cursor: pointer;
}
.hrd-viewfinder__play svg { width: 11px; height: 11px; fill: currentColor; }
.hrd-viewfinder__play .is-pause,
.hrd-viewfinder__play.is-playing .is-play { display: none; }
.hrd-viewfinder__play.is-playing .is-pause { display: inline; }
.hrd-viewfinder__play:focus-visible { outline: 1.5px solid currentColor; outline-offset: 1px; border-radius: 2px; }
.hrd-viewfinder.is-off .hrd-viewfinder__play { visibility: hidden; }

/* The footer's static corner arrows would double up with the viewfinder. */
.hrd-has-story .hrd-corners--bottom::before,
.hrd-has-story .hrd-corners--bottom::after { display: none; }

/* Stacked headline lines (05's statement and bookend, 06's title): each line rises from its own clip on --r.
   FIDELITY: fully invisible until the reveal begins (no bleed past the clip). */
.hrd-line { display: block; overflow: hidden; padding-bottom: 0.04em; }
.hrd-line > span {
	display: inline-block;
	/* one shared ease on every rise (smoothstep: it leaves and lands at rest; on the linear --r a line ran at one
	   speed and stopped dead, most visibly in Play, where --p runs at a constant speed) */
	--re: calc(var(--r) * var(--r) * (3 - 2 * var(--r)));
	transform: translateY(calc((1 - var(--re)) * 105%));
	opacity: clamp(0, var(--r) * 4, 1);
}

/* ======================================================================
   CHAPTERS (01 Dampers, 02 Drivetrain, …), one template, scroll in place
   - The giant category word drifts sideways the whole chapter (type is the image)
   - A cut-out product rises into place IN FRONT of the word
   - Numbered details stack in; the current one is ink, earlier ones gray
   - Products change by slash wipe (clip-path), never crossfade
   - Exit: a giant 55° slash sweeps to the next tone, hazard stripes on its edge
   FIDELITY: products move by translate only (no scale); clip-paths are vector.
   TONE: every colour comes from --c-* tokens. Default = paper; .is-ink = ink.
   --c-wipe is the NEXT chapter's ground, so each exit hands off seamlessly.
   ====================================================================== */
.hrd-chapter {
	--c-bg: var(--wp--preset--color--paper);
	--c-fg: var(--wp--preset--color--ink);
	--c-sub: var(--wp--preset--color--gray);
	--c-rule: var(--wp--preset--color--hairline);
	--c-accent: var(--wp--preset--color--ink);
	--c-wipe: var(--wp--preset--color--ink);
	--c-wipe-edge: var(--wp--preset--color--ink);
	--scene-length: 360vh;
	--in:  clamp(0, (var(--p) - 0.00) / 0.16, 1);
	--d1:  clamp(0, (var(--p) - 0.10) / 0.08, 1);
	--d2:  clamp(0, (var(--p) - 0.36) / 0.08, 1);
	--d3:  clamp(0, (var(--p) - 0.58) / 0.08, 1);
	--swap: clamp(0, (var(--p) - 0.34) / 0.10, 1);  /* product a → b, slash wipe */
	--redact: clamp(0, (var(--p) - 0.58) / 0.08, 1);
	--cta: clamp(0, (var(--p) - 0.70) / 0.06, 1);
	--out: clamp(0, (var(--p) - 0.80) / 0.08, 1);
	--wipe: clamp(0, (var(--p) - 0.86) / 0.14, 1);
	--ease-in: calc(1 - (1 - var(--in)) * (1 - var(--in)) * (1 - var(--in)));
	color: var(--c-fg);
}
.hrd-chapter .hrd-stage { background: var(--c-bg); }
.hrd-chapter.is-ink {
	--c-bg: var(--wp--preset--color--ink);
	--c-fg: var(--wp--preset--color--white);
	--c-sub: rgba(255, 255, 255, 0.6);
	--c-rule: rgba(255, 255, 255, 0.16);
	--c-accent: var(--wp--preset--color--sky);
	--c-wipe: var(--wp--preset--color--paper);
	--c-wipe-edge: var(--wp--preset--color--paper);
}

.hrd-chapter__word {
	top: 40%;
	left: 0;
	white-space: nowrap;
	font-size: clamp(7rem, 20vw, 24rem);
	font-weight: 700;
	line-height: 0.8;
	letter-spacing: -0.055em;
	text-transform: uppercase;
	color: var(--c-fg);
	/* drifts right→left across the whole chapter */
	transform: translate(calc(30vw - var(--p) * 75vw), -54%);
	z-index: 1;
}

.hrd-chapter__label {
	top: calc(clamp(16px, 2.2vw, 32px) + 72px);
	left: clamp(24px, 6vw, 112px);
	gap: 14px !important;
	align-items: center;
	opacity: var(--d1);
	z-index: 4;
}
.hrd-chapter__label > * { margin: 0 !important; }
.hrd-chapter__label .wp-block-separator.is-style-slashes { --hz: 11px; color: var(--c-accent); }

/* Products: box = the product's own proportions (--ar, width/height), so
   anything attached to it (the redaction bar) hugs the part itself. */
.hrd-chapter__products {
	--ar: 0.46;
	--h: 82vh;
	top: 9vh;
	height: var(--h);
	left: 58%;
	width: calc(var(--h) * var(--ar));
	transform: translate(-50%, calc((1 - var(--ease-in)) * 70vh - var(--out) * 10vh));
	/* FIDELITY: parts are never see-through; they rise fully opaque from
	   below the stage edge (the stage clips them). */
	opacity: clamp(0, var(--in) * 1000, 1);
	z-index: 2;
}
.hrd-chapter__product {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: contain;
	object-position: 50% 100%;
}
/* Slash wipe a → b (only when a chapter has a second product) */
.hrd-chapter__products:has(.hrd-chapter__product--b) .hrd-chapter__product--a { clip-path: polygon(calc(var(--swap) * 160% - 30%) 0, 130% 0, 130% 100%, calc(var(--swap) * 160% - 60%) 100%); }
.hrd-chapter__product--b { clip-path: polygon(-30% 0, calc(var(--swap) * 160% - 30%) 0, calc(var(--swap) * 160% - 60%) 100%, -30% 100%); }

/* The swap's front carries the material: a hazard-striped slash edge, so the
   hand-over reads as a deliberate cut, not a glitch between two parts. */
.hrd-chapter__swap-edge {
	position: absolute;
	inset: 0;
	--f: calc(var(--swap) * 160% - 30%);
	background: repeating-linear-gradient(55deg, var(--c-fg) 0 calc(var(--edge-hz) * 0.33), transparent calc(var(--edge-hz) * 0.33) calc(var(--edge-hz) * 0.56));
	clip-path: polygon(calc(var(--f) - 11%) 0, var(--f) 0, calc(var(--f) - 30%) 100%, calc(var(--f) - 41%) 100%);
	opacity: clamp(0, min(var(--swap), 1 - var(--swap)) * 30, 1);
	pointer-events: none;
}

/* 03 Top Secret: an ink redaction bar slides across the part */
.hrd-chapter__redact {
	position: absolute;
	left: -8%;
	right: -8%;
	top: 57%;  /* the damper body, below the type band */
	height: 11%;
	background: var(--wp--preset--color--ink);
	clip-path: inset(0 calc((1 - var(--redact)) * 100%) 0 0);
	display: flex;
	align-items: center;
	justify-content: center;
	transform: rotate(-4deg);
}
.hrd-chapter__redact span {
	color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	letter-spacing: var(--wp--custom--track--micro);
	text-transform: uppercase;
	opacity: clamp(0, (var(--redact) - 0.6) * 4, 1);
}

/* Details: numbered, stacked; the current one is ink, earlier ones recede */
.hrd-chapter__details {
	left: clamp(24px, 6vw, 112px);
	bottom: calc(clamp(16px, 2.2vw, 32px) + 72px);
	width: min(30vw, 420px);
	list-style: none;
	padding: 0;
	display: grid;
	gap: 22px;
	z-index: 4;
	opacity: calc(1 - var(--out));
}
.hrd-chapter__details li {
	display: grid;
	grid-template-columns: 2.25rem 1fr;
	row-gap: 4px;
	border-top: 1px solid var(--c-rule);
	padding-top: 14px;
}
.hrd-chapter__details li > span:last-child { grid-column: 2; color: var(--c-sub); font-size: var(--wp--preset--font-size--small); line-height: 1.45; }
.hrd-chapter__details strong { font-size: clamp(1.25rem, 1.8vw, 1.75rem); letter-spacing: -0.04em; line-height: 1.05; }
.hrd-chapter__n { font-size: var(--wp--preset--font-size--micro); font-weight: 700; letter-spacing: var(--wp--custom--track--micro); padding-top: 0.45em; }
.hrd-chapter__details li:nth-child(1) { --r: var(--d1); --next: var(--d2); }
.hrd-chapter__details li:nth-child(2) { --r: var(--d2); --next: var(--d3); }
.hrd-chapter__details li:nth-child(3) { --r: var(--d3); --next: 0; }
.hrd-chapter__details li {
	opacity: calc(clamp(0, var(--r) * 3, 1) * (1 - 0.6 * var(--next)));
	transform: translateY(calc((1 - var(--r) * var(--r) * (3 - 2 * var(--r))) * 18px)); /* the shared ease (.hrd-line) */
}

.hrd-chapter__links {
	right: clamp(24px, 6vw, 112px);
	bottom: calc(clamp(16px, 2.2vw, 32px) + 76px);
	opacity: calc(var(--cta) * (1 - var(--out)));
	z-index: 4;
}
.hrd-chapter__links a { color: var(--c-fg); }

/* Every transition edge wears the brand's own hazard stripe (is-style-slashes:
   55°, stripe 0.33 of the period's 0.56), scaled up so it reads bold, Off-White
   style, at any size: --edge-hz is the stripe scale. */
.hrd-scene { --edge-hz: clamp(22px, 3vw, 46px); }

/* Exit sweep: a giant 55° slash (run = 0.7 × height) to the next tone */
.hrd-chapter__wipe,
.hrd-chapter__wipe-edge { inset: 0; z-index: 6; pointer-events: none; }
.hrd-chapter__wipe {
	--x: calc(var(--wipe) * (100% + 70vh + 9vw));
	background: var(--c-wipe);
	clip-path: polygon(0 0, var(--x) 0, calc(var(--x) - 70vh) 100%, 0 100%);
}
.hrd-chapter__wipe-edge {
	--x: calc(var(--wipe) * (100% + 70vh + 9vw));
	background: repeating-linear-gradient(55deg, var(--c-wipe-edge) 0 calc(var(--edge-hz) * 0.33), transparent calc(var(--edge-hz) * 0.33) calc(var(--edge-hz) * 0.56));
	clip-path: polygon(var(--x) 0, calc(var(--x) + 9vw) 0, calc(var(--x) + 9vw - 70vh) 100%, calc(var(--x) - 70vh) 100%);
	opacity: clamp(0, var(--wipe) * 20, 1);
}

/* 01 Dampers (paper), the page's opening: the landing, then HRD's Street Performance dampers and the Top Secret,
   rendered from the photo-built models (frames and the p -> frame map in patterns/chapter-dampers.php;
   bin/render/dampers_seq.py).
     the landing: the scene's lead-in (data-lead="1", story.js): its first screen of scroll runs --lp 0 -> 1 while
     p holds at 0 (frame 0, the strut standing): the slash turns HRD's line into DAMPERS. Then p runs:
     p is over 1200vh of travel (--scene-length 1400vh = 100vh landing + 1300vh); the beats up to frame 456 keep their scroll positions
     from the 900vh cut (p x 0.75). No segment is denser than 0.71 frames per vh (853 frames per unit p), so a
     notched wheel never jumps 2 frames a rAF.
     I    0.000-0.075 01 the 9th gen Civic Si front stands; the camera arcs round it
          0.075-0.191 02 up onto the top hat, to a plan view: it turns on its thrust bearing until its HRD box
                     reads upright, then slides along its camber slots (callouts: studs, nuts, plate)
          0.191-0.242 03 the 304 stainless pillowball, close: the top hat rocks on it
          0.242-0.300 04 down to the Swift spring, along the wire to Swift's print
          0.300-0.380 05 the perch: the large spanner turns it up, the small one runs the lock ring up behind it
          0.380-0.404 down to the HRD label
     the hand-over 0.408-0.4273: the slash (--swap) wipes the front's label (track a, white on EDP black)
          into the rear's (track b, black on Apex Silver), both on one camera move, labels aligned
     II   0.433-0.467 back from the rear's label to the FRS / BRZ / GR86 rear
          0.467-0.572 06 it strokes, twice slow and small, once fast and big, beside the Dual Duty Digressive
                     curve: an end mill riding the piston speed machines it into a navy billet
          0.572-0.626 07 the front stands beside it: pull back
          0.626-0.688    up onto the front's top hat (Act I's plan view); 08 Top Secret lands, its line redacted
     the declassification 0.702-0.733: the redaction band (--band, frames 506-520) sweeps the frame: under
          it the Street Performance plate (track b) becomes the Top Secret's (track c, its camera b's mapped by
          the similarity that lays one plate on the other), DAMPERS becomes {TOP SECRET} DAMPERS, 08 becomes 09
     III  0.742-0.767 09 the {TOP SECRET} DAMPERS etch reads level
          0.767-0.846    down the canister side: the canister's cap, its hose and knob (callouts)
          0.846-0.913 10 out to the whole Top Secret, a slow turn
          0.88-1.00  the links, out, the sweep to ink (Drivetrain)
   Details stack in seven groups in the copy column (01-02, 03-05, 06, 07, 08, 09, 10), each leaving for the
   next: a list's hidden items still take its height, so 06 to 10 each stand alone. */
.hrd-chapter--dampers {
	--scene-length: 1400vh;
	--lp: 0;
	--d1:   clamp(0, (var(--p) - 0.015) / 0.0225, 1);
	--d2:   clamp(0, (var(--p) - 0.0983) / 0.0225, 1);
	--grpa: clamp(0, (var(--p) - 0.1936) / 0.0095, 1);   /* 01-02 leave as the camera pushes into the centre */
	--d3:   clamp(0, (var(--p) - 0.2046) / 0.0236, 1);
	--d4:   clamp(0, (var(--p) - 0.2687) / 0.0248, 1);
	--d5:   clamp(0, (var(--p) - 0.3143) / 0.0239, 1);
	--grpb: clamp(0, (var(--p) - 0.3827) / 0.0096, 1);   /* 03-05 leave on the way down to the label */
	--veil: max(calc(clamp(0, (var(--p) - 0.192) / 0.009, 1) * (1 - clamp(0, (var(--p) - 0.384) / 0.0105, 1))),   /* close-ups under the copy (frames ~125-284) */
	            calc(clamp(0, (var(--p) - 0.65) / 0.008, 1) * (1 - clamp(0, (var(--p) - 0.696) / 0.008, 1))));      /* the rise: the rear's top hat passes under 08 (frames ~472-498) */
	--swap: clamp(0, (var(--p) - 0.4084) / 0.0189, 1); /* the label slash, frames 304-319.5: done half a frame sooner (2026-11-08) so track a is covered before its first frame not re-timed with the camera ease (frames 318-333, track a ends at 324) */
	--cut:  clamp(0, (var(--swap) - 0.5) * 1000, 1);   /* the caption swaps at the slash's midpoint */
	--plot: calc(clamp(0, (var(--p) - 0.4593) / 0.0072, 1) * (1 - clamp(0, (var(--p) - 0.5715) / 0.009, 1)));  /* the curve's axis labels */
	--zlo:  calc(clamp(0, (var(--p) - 0.4677) * 533, 1) * (1 - clamp(0, (var(--p) - 0.5175) * 533, 1)));   /* the slow strokes (frames 352-394) */
	--zhi:  calc(clamp(0, (var(--p) - 0.5231) * 533, 1) * (1 - clamp(0, (var(--p) - 0.5686) * 533, 1)));   /* the pothole (396-418) */
	--wout: calc(clamp(0, (var(--p) - 0.4515) / 0.012, 1) * (1 - clamp(0, (var(--p) - 0.579) / 0.0135, 1)));   /* the word steps out: the beat gets the frame */
	--d6:   clamp(0, (var(--p) - 0.4617) / 0.0212, 1);
	--grpc: clamp(0, (var(--p) - 0.5817) / 0.0082, 1);   /* 06 leaves as the camera pulls back to the pair */
	--d7:   clamp(0, (var(--p) - 0.5954) / 0.0204, 1);
	--grpd: clamp(0, (var(--p) - 0.6533) / 0.0067, 1);   /* 07 steps out as the camera reaches the front's plate */
	--d8:   clamp(0, (var(--p) - 0.6617) / 0.02, 1);
	--redact: clamp(0, (var(--p) - 0.6833) / 0.0167, 1); /* 08's line, redacted */
	--band: clamp(0, (var(--p) - 0.7017) / 0.0311, 1);   /* the redaction band sweeps the frame, frames 506-520 */
	--d9:   1;                                            /* 09 is set whole: the band uncovers it */
	--grpf: clamp(0, (var(--p) - 0.8367) / 0.0067, 1);   /* 09 steps out for 10 */
	--d10:  clamp(0, (var(--p) - 0.8467) / 0.02, 1);
	--cta:  clamp(0, (var(--p) - 0.88) / 0.02, 1);
	--out:  clamp(0, (var(--p) - 0.915) / 0.03, 1);
	--wipe: clamp(0, (var(--p) - 0.925) / 0.075, 1); /* = the section's data-wipe (story.js: the chrome rides it) */
	/* the caption names the damper on screen: the whole front (01), the rear standing whole (06, 07), the Top
	   Secret standing whole (10); off through the close-ups, and it switches names while off */
	--cap: max(calc(var(--d1) * (1 - clamp(0, (var(--p) - 0.0825) / 0.009, 1))),
	           calc(clamp(0, (var(--p) - 0.4665) / 0.0131, 1) * (1 - clamp(0, (var(--p) - 0.6417) / 0.01, 1))),
	           calc(clamp(0, (var(--p) - 0.8617) / 0.0125, 1) * (1 - var(--out))));
	--cut2: clamp(0, (var(--p) - 0.75) * 1000, 1);
	/* the band: its width, its centre line's x (off the left edge -> off the right); it leans 2 deg (the
	   redaction bar's -2 deg), so its edges run 1.75vh either side of the centre line over the height */
	--bw: 12vw;
	--bx: calc(var(--band) * (100vw + var(--bw) + 4vh) - 0.5 * var(--bw) - 2vh);
	--tl: clamp(24px, 6vw, 112px);   /* the copy column's left edge */
}
/* Full-bleed canvases: each frame set is composed with the part right of the copy column (desktop) or
   above it (mobile); the a/b clip and the striped front are the template's swap (.hrd-chapter__product--a/b).
   The strut stands from the first paint (the landing): no rise. */
.hrd-chapter--dampers .hrd-chapter__products {
	inset: 0;
	width: auto;
	height: auto;
	transform: translateY(calc(var(--out) * -10vh));
	opacity: 1;
}

/* The landing (--lp). HRD's line is the giant type the strut stands in front of, the way every chapter's part
   stands in front of its word; paper under it hides DAMPERS. The first scroll's slash (the exit sweep's 55°
   geometry, its bold hazard on the trailing side) crosses the frame: right of it the landing, left of it the
   chapter, DAMPERS in its place. The strut (z 2) is in front of both, the same pixels before and after.
   FIDELITY: clip-path only; the type is never scaled or moved. */
.hrd-chapter--dampers {
	--lx: calc(clamp(0, (var(--lp) - 0.06) / 0.76, 1) * (100vw + 70vh + 9vw));   /* the slash front: off the left edge -> past the right */
}
.hrd-landing,
.hrd-landing__copy { clip-path: polygon(var(--lx) -10%, 120vw -10%, 120vw 110%, calc(var(--lx) - 70vh) 110%); }
.hrd-landing {
	inset: 0;
	z-index: 1;
	background: var(--c-bg);
	pointer-events: none;
}
.hrd-landing__title {
	position: absolute;
	left: clamp(24px, 6vw, 112px);
	top: 39%;
	transform: translateY(-50%);
	margin: 0;
	font-size: min(12.5vw, 21vh);
	font-weight: 700;
	line-height: 0.9;
	letter-spacing: -0.055em;
	text-transform: uppercase;
	white-space: nowrap;
	color: var(--c-fg);
}
.hrd-landing__title span { display: block; }
.hrd-landing__poster { display: none; }
.hrd-landing__edge {
	inset: 0;
	z-index: 1;
	pointer-events: none;
	background: repeating-linear-gradient(55deg, var(--c-fg) 0 calc(var(--edge-hz) * 0.33), transparent calc(var(--edge-hz) * 0.33) calc(var(--edge-hz) * 0.56));
	clip-path: polygon(calc(var(--lx) - 9vw) 0, var(--lx) 0, calc(var(--lx) - 70vh) 100%, calc(var(--lx) - 9vw - 70vh) 100%);
	opacity: clamp(0, min(var(--lp) - 0.06, 0.82 - var(--lp)) * 60, 1);
}
/* the copy is a full-stage layer (the slash's polygon is in the same coordinates as the type's), above the
   chapter's details (z 4: invisible until their beats, but they would take the button's clicks) */
.hrd-landing__copy {
	inset: 0;
	z-index: 5;
}
.hrd-landing__col {
	position: absolute;
	left: clamp(24px, 6vw, 112px);
	bottom: calc(clamp(16px, 2.2vw, 32px) + 72px);
	width: min(30vw, 420px);
}
/* two short lines with a deliberate break (docs/BRAND.md, subheads): "HRD is for the driver / who wants it all."
   (one line wrapped "all." alone at most widths) */
.hrd-landing__line {
	text-wrap: balance;
	margin: 0 0 18px;
	font-size: clamp(1.25rem, 1.8vw, 1.75rem);
	font-weight: 700;
	letter-spacing: -0.04em;
	line-height: 1.05;
}
.hrd-landing__play {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin: 0 0 0 -10px;
	padding: 8px 10px;
	border: 0;
	background: none;
	color: var(--c-fg);
	cursor: pointer;
}
.hrd-landing__play svg { width: 9px; height: 9px; fill: currentColor; }
.hrd-landing__play .is-pause,
.hrd-landing__play.is-playing .is-play { display: none; }
.hrd-landing__play.is-playing .is-pause { display: inline; }
.hrd-landing__play span { margin: 0; }
.hrd-landing__play:focus-visible { outline: 1.5px solid currentColor; outline-offset: 2px; }
/* the copy is clipped with the landing, and a clip-path clips hit testing too: once the slash has passed, the
   button can't be pressed */
.hrd-landing__copy { pointer-events: none; }
.hrd-landing__play { pointer-events: auto; }
.hrd-chapter--dampers img.hrd-chapter__product { object-fit: cover; object-position: 50% 50%; }
.hrd-chapter--dampers .hrd-chapter__caption { opacity: var(--cap); }
/* the word drifts as every chapter's does, at the 900vh cut's pace (p x 0.75): right of the band's line
   only (the band turns it into {TOP SECRET} DAMPERS) */
.hrd-chapter--dampers .hrd-chapter__word {
	--wx: calc(30vw - var(--p) * 100vw);
	transform: translate(var(--wx), -54%);
	opacity: calc(1 - var(--wout));
	clip-path: polygon(calc(var(--bx) - var(--wx)) -50%, 400vw -50%, 400vw 150%, calc(var(--bx) - var(--wx)) 150%);
}
.hrd-chapter--dampers .hrd-chapter__finish { position: relative; left: auto; top: auto; margin: 0 0 4px; opacity: 1; }

/* Details: seven groups in the copy column, the same place */
.hrd-chapter--dampers .hrd-chapter__details--a { opacity: calc(1 - var(--grpa)); }
.hrd-chapter--dampers .hrd-chapter__details--b { opacity: calc(1 - var(--grpb)); }
.hrd-chapter--dampers .hrd-chapter__details--c { opacity: calc(1 - var(--grpc)); }
.hrd-chapter--dampers .hrd-chapter__details--d { opacity: calc(1 - var(--grpd)); }
/* 08 right of the band's line, 09 left of it: the band turns one into the other as it crosses the column */
.hrd-chapter--dampers .hrd-chapter__details--e { opacity: 1; clip-path: polygon(calc(var(--bx) - var(--tl)) -50%, 200vw -50%, 200vw 150%, calc(var(--bx) - var(--tl)) 150%); }
.hrd-chapter--dampers .hrd-chapter__details--f { opacity: calc(1 - var(--grpf)); clip-path: polygon(-50vw -50%, calc(var(--bx) - var(--tl)) -50%, calc(var(--bx) - var(--tl)) 150%, -50vw 150%); }
.hrd-chapter--dampers .hrd-chapter__details--g { opacity: calc(1 - var(--out)); }
.hrd-chapter--dampers .hrd-chapter__details--a li:nth-child(1) { --r: var(--d1); --next: var(--d2); }
.hrd-chapter--dampers .hrd-chapter__details--a li:nth-child(2) { --r: var(--d2); --next: 0; }
.hrd-chapter--dampers .hrd-chapter__details--b li:nth-child(1) { --r: var(--d3); --next: var(--d4); }
.hrd-chapter--dampers .hrd-chapter__details--b li:nth-child(2) { --r: var(--d4); --next: var(--d5); }
.hrd-chapter--dampers .hrd-chapter__details--b li:nth-child(3) { --r: var(--d5); --next: 0; }
.hrd-chapter--dampers .hrd-chapter__details--c li:nth-child(1) { --r: var(--d6); --next: 0; }
.hrd-chapter--dampers .hrd-chapter__details--d li:nth-child(1) { --r: var(--d7); --next: 0; }
.hrd-chapter--dampers .hrd-chapter__details--e li:nth-child(1) { --r: var(--d8); --next: 0; }
.hrd-chapter--dampers .hrd-chapter__details--f li:nth-child(1) { --r: var(--d9); --next: 0; }
.hrd-chapter--dampers .hrd-chapter__details--g li:nth-child(1) { --r: var(--d10); --next: 0; }

/* While a close-up fills the frame under the copy column (the pillowball, the Swift print, the spanners),
   a paper veil fades the frame's left behind the details: a gradient, not a box, so the render dissolves
   into the paper the type is set on */
.hrd-chapter__veil {
	inset: 0;
	z-index: 3;
	pointer-events: none;
	background: linear-gradient(90deg, var(--c-bg) 0, var(--c-bg) calc(clamp(24px, 6vw, 112px) + min(30vw, 420px) - 2vw), rgb(245 245 247 / 0) calc(clamp(24px, 6vw, 112px) + min(30vw, 420px) + 12vw));
	opacity: var(--veil);
}

/* 08 Top Secret: an ink redaction bar slides over its line, "Classified"; then the band (below) carries the
   same bar across the frame. The bar lives inside the line's own span, so the li keeps the template's
   two-column grid. */
.hrd-chapter__secret > span:last-child { position: relative; }
.hrd-chapter__redact-line {
	position: absolute;
	left: -0.3em;
	right: -0.6em;
	top: 50%;
	height: 2.4em;
	margin-top: -1.2em;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--wp--preset--color--ink);
	clip-path: inset(0 calc((1 - var(--redact)) * 100%) 0 0);
	transform: rotate(-2deg);
	font-style: normal;
}
.hrd-chapter__redact-line span {
	color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 700;
	letter-spacing: var(--wp--custom--track--micro);
	text-transform: uppercase;
	opacity: clamp(0, (var(--redact) - 0.6) * 4, 1);
}

/* The stroke machines its Dual Duty Digressive curve, in the render (bin/render/curve_plate.py): a Midnight
   Navy billet beside the rear, an end mill riding the piston speed, the curve cut where it has been.
   Its axes are page type riding the billet's anchors (cy, clo, chi, cx), frames ~346-426; the zone the
   stroke is in reads in ink: the two slow strokes (frames 352-394) light "Cornering, braking", the pothole
   (396-418) "Bumps, potholes". The giant word steps out for the beat. */
.hrd-plotlab { position: absolute; left: 0; top: 0; pointer-events: none; opacity: var(--plot); }
.hrd-plotlab[data-off] { visibility: hidden; }
.hrd-plotlab b {
	position: absolute;
	top: 0;
	white-space: nowrap;
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 700;
	letter-spacing: var(--wp--custom--track--micro);
	text-transform: uppercase;
	color: var(--c-sub);
	transform: translateY(-50%);
}
.hrd-plotlab--y b { right: 0; transform: translateY(-100%); color: var(--c-fg); } /* ends at the tall end: clear of the damper beside it */
.hrd-plotlab--x b { right: 0; color: var(--c-fg); }
.hrd-plotlab--lo b { left: 0; transform: translate(-30%, -10%); color: color-mix(in srgb, var(--c-fg) calc(var(--zlo) * 100%), var(--c-sub)); }
.hrd-plotlab--hi b { left: 0; transform: translate(-50%, -10%); color: color-mix(in srgb, var(--c-fg) calc(var(--zhi) * 100%), var(--c-sub)); }

/* Callouts ride their parts (anchors.json); each shows while its part is in the light */
.hrd-chapter--dampers .hrd-callout--studs    { --o: calc(clamp(0, (var(--p) - 0.1162) / 0.009, 1) * (1 - clamp(0, (var(--p) - 0.1822) / 0.009, 1))); }
.hrd-chapter--dampers .hrd-callout--nuts     { --o: calc(clamp(0, (var(--p) - 0.1215) / 0.009, 1) * (1 - clamp(0, (var(--p) - 0.1822) / 0.009, 1))); }
.hrd-chapter--dampers .hrd-callout--plate    { --o: calc(clamp(0, (var(--p) - 0.1275) / 0.009, 1) * (1 - clamp(0, (var(--p) - 0.1822) / 0.009, 1))); }
.hrd-chapter--dampers .hrd-callout--ball     { --o: calc(clamp(0, (var(--p) - 0.2109) / 0.0079, 1) * (1 - clamp(0, (var(--p) - 0.2336) / 0.0079, 1))); }
.hrd-chapter--dampers .hrd-callout--collar   { --o: calc(clamp(0, (var(--p) - 0.214) / 0.0079, 1) * (1 - clamp(0, (var(--p) - 0.2336) / 0.0079, 1))); }
.hrd-chapter--dampers .hrd-callout--swift    { --o: calc(clamp(0, (var(--p) - 0.2852) / 0.0049, 1) * (1 - clamp(0, (var(--p) - 0.2984) / 0.0048, 1))); } /* once the print has ridden into frame (202-214) */
.hrd-chapter--dampers .hrd-callout--spanners { --o: calc(clamp(0, (var(--p) - 0.3223) / 0.0095, 1) * (1 - clamp(0, (var(--p) - 0.3684) / 0.008, 1))); }
.hrd-chapter--dampers .hrd-callout--drive    { --o: calc(clamp(0, (var(--p) - 0.3508) / 0.008, 1) * (1 - clamp(0, (var(--p) - 0.3684) / 0.008, 1))); }
.hrd-chapter--dampers .hrd-callout--canister { --o: calc(clamp(0, (var(--p) - 0.801) / 0.01, 1) * (1 - clamp(0, (var(--p) - 0.8417) / 0.008, 1))); } /* frames 566-604 */
.hrd-chapter--dampers .hrd-callout--knob     { --o: calc(clamp(0, (var(--p) - 0.8194) / 0.01, 1) * (1 - clamp(0, (var(--p) - 0.8417) / 0.008, 1))); }

/* The capstone. The redaction band: the 08 line's bar at the frame's scale (ink, leaning 2 deg, "Classified"),
   sweeping left to right; it hides the line where tracks b and c meet (c left of it, b right). */
.hrd-chapter--dampers .hrd-chapter__product--b { clip-path: polygon(calc(var(--bx) - 1.75vh) 0, calc(var(--swap) * 160% - 30%) 0, calc(var(--swap) * 160% - 60%) 100%, calc(var(--bx) + 1.75vh) 100%); }
.hrd-chapter--dampers .hrd-chapter__product--c { clip-path: polygon(-30% 0, calc(var(--bx) - 1.75vh) 0, calc(var(--bx) + 1.75vh) 100%, -30% 100%); }
.hrd-chapter__band {
	inset: 0;
	z-index: 6;
	pointer-events: none;
	background: var(--wp--preset--color--ink);
	clip-path: polygon(calc(var(--bx) - 0.5 * var(--bw) - 1.75vh) 0, calc(var(--bx) + 0.5 * var(--bw) - 1.75vh) 0, calc(var(--bx) + 0.5 * var(--bw) + 1.75vh) 100%, calc(var(--bx) - 0.5 * var(--bw) + 1.75vh) 100%);
	opacity: clamp(0, min(var(--band), 1 - var(--band)) * 1000, 1);
}
.hrd-chapter__band span {
	position: absolute;
	left: var(--bx);
	top: 50%;
	transform: translate(-50%, -50%);
	color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 700;
	letter-spacing: var(--wp--custom--track--micro);
	text-transform: uppercase;
	white-space: nowrap;
}
/* {TOP SECRET} DAMPERS, HRD's own line as its plate is etched, stacked behind the Top Secret: left of the band's
   line only. Line height 1: the braces' tails clear DAMPERS' caps by 0.1em (0.94 and tighter, they touch). */
.hrd-chapter__tsword {
	top: 38%;
	left: var(--tl);
	font-size: min(12.5vw, 21vh);
	font-weight: 700;
	line-height: 1;
	letter-spacing: -0.055em;
	text-transform: uppercase;
	white-space: nowrap;
	color: var(--c-fg);
	z-index: 1;
	transform: translateY(calc(-50% - var(--out) * 6vh));
	opacity: calc(1 - var(--out));
	clip-path: polygon(-50vw -50%, calc(var(--bx) - var(--tl)) -50%, calc(var(--bx) - var(--tl)) 150%, -50vw 150%);
}
.hrd-chapter__tsword span { display: block; }
/* the braces centred on the caps: in Helvetica Now Bold a brace runs 0.747em above the baseline to 0.204em
   below, the caps 0.712em to 0, so its centre sits 0.085em low; raised by that (an offset, not a transform) */
.hrd-chapter__tsword i { font-style: normal; position: relative; top: -0.085em; }
/* the caption: the rear's name hands over to the Top Secret's while it is off */
.hrd-chapter--dampers .hrd-chapter__model-b { opacity: calc(var(--cut) * (1 - var(--cut2))); }
.hrd-chapter--dampers .hrd-chapter__model-c { opacity: var(--cut2); }
.hrd-chapter--dampers .hrd-chapter__finish-b { opacity: calc(clamp(0, (var(--swap) - 0.5) * 1000, 1) * (1 - var(--cut2))); }
.hrd-chapter--dampers .hrd-chapter__finish-c { opacity: var(--cut2); }
.hrd-chapter--dampers .hrd-chapter__links a + a { margin-left: 2rem; }

/* 02 Drivetrain (ink): two acts, one sweep, all CAD renders on full-bleed
   canvases (sequence.js; frame map in patterns/chapter-drivetrain.php).
     I   0.01–0.33  Elantra N assembles (01), turns, Midnight → Apex Silver (02)
         0.33–0.455 dive into its sleeve bore → ink (the cut is inside the dark)
     II  0.46–0.89  out of the GR Corolla's Titan Frost pin (03), over the 50A
                    bushing (04), swing to hero as light runs the alloy arm (05)
   Numbering runs 01–05 across both acts; the giant word drifts the whole way.
   Callouts ride the render (anchors.json: projected 3D points per frame). */
.hrd-chapter--drivetrain {
	--scene-length: 740vh;
	--in:   clamp(0, var(--p) / 0.06, 1);
	--d1:   clamp(0, (var(--p) - 0.04) / 0.05, 1);
	--d2:   clamp(0, (var(--p) - 0.1919) / 0.0531, 1); /* 0.20/0.05 and 0.22/0.06 until the turn's knot moved to its still frame 76 (2026-11-08): the same frames */
	--swap: clamp(0, (var(--p) - 0.2132) / 0.0637, 1);
	--dive: clamp(0, (var(--p) - 0.34) / 0.04, 1);   /* act I copy leaves as the camera dives */
	--cut:  clamp(0, (var(--p) - 0.455) * 1000, 1);   /* 0 → 1 inside the ink: N → GR Corolla */
	--d3:   clamp(0, (var(--p) - 0.50) / 0.04, 1);
	--d4:   clamp(0, (var(--p) - 0.59) / 0.04, 1);
	--d5:   clamp(0, (var(--p) - 0.70) / 0.04, 1);
	--cap2: clamp(0, (var(--p) - 0.66) / 0.04, 1);    /* GR Corolla caption once it's recognisable */
	--cta:  clamp(0, (var(--p) - 0.80) / 0.04, 1);
	--out:  clamp(0, (var(--p) - 0.88) / 0.05, 1);
	--wipe: clamp(0, (var(--p) - 0.90) / 0.10, 1); /* = the section's data-wipe (story.js: the chrome rides it) */
}
/* Full-bleed canvases (the dive fills the screen); each frame set is composed
   with the part right of the copy (desktop) or above it (mobile). */
.hrd-chapter--drivetrain .hrd-chapter__products {
	inset: 0;
	width: auto;
	height: auto;
	transform: translateY(calc((1 - var(--ease-in)) * 70vh - var(--out) * 10vh));
	--f: calc(var(--swap) * 100% + 30%); /* wipe front (top edge); it leans 30% across the height */
}
.hrd-chapter--drivetrain img.hrd-chapter__product { object-fit: cover; object-position: 50% 50%; }
.hrd-chapter--drivetrain .hrd-chapter__products .hrd-chapter__product--a { clip-path: polygon(var(--f) 0, 130% 0, 130% 100%, calc(var(--f) - 30%) 100%); }
.hrd-chapter--drivetrain .hrd-chapter__product--b { clip-path: polygon(-30% 0, var(--f) 0, calc(var(--f) - 30%) 100%, -30% 100%); }
.hrd-chapter--drivetrain .hrd-chapter__swap-edge { --f: calc(var(--swap) * 100% + 30%); }

/* caption, top right (mirrors the label top left): model, then finish */
.hrd-chapter__caption {
	top: calc(clamp(16px, 2.2vw, 32px) + 72px);
	right: clamp(24px, 6vw, 112px);
	text-align: right;
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 700;
	letter-spacing: var(--wp--custom--track--micro);
	text-transform: uppercase;
	white-space: nowrap;
	z-index: 4;
	opacity: max(calc(var(--d1) * (1 - var(--dive))), calc(var(--cap2) * (1 - var(--out))));
}
.hrd-chapter__caption p { position: relative; height: 1.4em; margin: 0 0 4px; }
.hrd-chapter__caption p span { position: absolute; left: auto; right: 0; top: 0; transform: none; }
.hrd-chapter__model { color: var(--c-sub); }
.hrd-chapter__model-a { opacity: calc(1 - var(--cut)); }
.hrd-chapter__model-b { opacity: var(--cut); }
.hrd-chapter--drivetrain .hrd-chapter__finish { position: relative; left: auto; top: auto; margin: 0 0 4px; opacity: 1; }
/* GR Corolla is Midnight Navy: after the cut, "Midnight" again */
.hrd-chapter--drivetrain .hrd-chapter__finish-a { opacity: calc(1 - clamp(0, (var(--swap) - 0.5) * 1000, 1) * (1 - var(--cut))); }
.hrd-chapter--drivetrain .hrd-chapter__finish-b { opacity: calc(clamp(0, (var(--swap) - 0.5) * 1000, 1) * (1 - var(--cut))); }

/* While the render fills the screen (dive, bore, bushing close-ups), an ink
   scrim holds the copy column, the way type sits over full-bleed product film. */
.hrd-chapter__scrim {
	inset: 0;
	z-index: 3;
	pointer-events: none;
	background: linear-gradient(90deg, rgb(4 1 29 / 0.9) 0, rgb(4 1 29 / 0.72) 26vw, rgb(4 1 29 / 0) 46vw);
	opacity: calc(clamp(0, (var(--p) - 0.34) / 0.03, 1) * (1 - clamp(0, (var(--p) - 0.67) / 0.04, 1)));
}

/* details: act I (01–02) hands over to act II (03–05) in the same place */
.hrd-chapter--drivetrain .hrd-chapter__details--a { opacity: calc(1 - var(--dive)); }
.hrd-chapter--drivetrain .hrd-chapter__details--b { opacity: calc(1 - var(--out)); }
.hrd-chapter--drivetrain .hrd-chapter__details--a li:nth-child(1) { --r: var(--d1); --next: var(--d2); }
.hrd-chapter--drivetrain .hrd-chapter__details--a li:nth-child(2) { --r: var(--d2); --next: 0; }
.hrd-chapter--drivetrain .hrd-chapter__details--b li:nth-child(1) { --r: var(--d3); --next: var(--d4); }
.hrd-chapter--drivetrain .hrd-chapter__details--b li:nth-child(2) { --r: var(--d4); --next: var(--d5); }
.hrd-chapter--drivetrain .hrd-chapter__details--b li:nth-child(3) { --r: var(--d5); --next: 0; }

/* Callouts: a ring on the part, a 55° leader (the slash angle), a quoted tag.
   sequence.js moves each to its anchor (translate in whole px: crisp text). */
.hrd-callouts { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.hrd-callout {
	position: absolute;
	left: 0;
	top: 0;
	color: var(--c-accent);
	--o: 0;
	opacity: var(--o);
}
.hrd-callout[data-off] { visibility: hidden; }
.hrd-callout i {
	position: absolute;
	left: -5px;
	top: -5px;
	width: 10px;
	height: 10px;
	border: 1.5px solid currentColor;
	border-radius: 50%;
	box-sizing: border-box;
}
.hrd-callout i::after { /* leader: 52px at 55° up-right from the ring */
	content: "";
	position: absolute;
	left: 8px;
	top: 1px;
	width: 46px;
	height: 1.5px;
	background: currentColor;
	transform-origin: 0 50%;
	transform: rotate(-55deg);
}
.hrd-callout b { /* an ink chip: legible over any frame (bright Ti, black urethane, navy) */
	position: absolute;
	left: 30px;
	top: -62px;
	padding: 4px 7px 3px;
	background: var(--c-bg);
	white-space: nowrap;
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 700;
	letter-spacing: var(--wp--custom--track--micro);
	text-transform: uppercase;
}
.hrd-callout[data-flip] i::after { left: auto; right: 8px; transform-origin: 100% 50%; transform: rotate(55deg); }
.hrd-callout[data-flip] b { left: auto; right: 30px; }
/* sequence.js drops a tag below its ring ([data-drop]) where above it would run into the chapter's label or
   links (while they show) or off the stage's top: the leader turns down, the tag hangs under it */
.hrd-callout[data-drop] i::after { transform: rotate(55deg); top: 7px; }
.hrd-callout[data-drop][data-flip] i::after { transform: rotate(-55deg); }
.hrd-callout[data-drop] b { top: 34px; }
.hrd-nobr { white-space: nowrap; } /* a two-line tag never breaks a hyphenated word ("O- / Rings") */
.hrd-callout--pin  { --o: calc(clamp(0, (var(--p) - 0.515) / 0.015, 1) * (1 - clamp(0, (var(--p) - 0.575) / 0.015, 1))); }
.hrd-callout--bush { --o: calc(clamp(0, (var(--p) - 0.590) / 0.015, 1) * (1 - clamp(0, (var(--p) - 0.660) / 0.015, 1))); }
.hrd-callout--arm  { --o: calc(clamp(0, (var(--p) - 0.705) / 0.015, 1) * (1 - var(--out))); }

/* Render sequences (sequence.js): the <img> posters show until a canvas has a
   frame, then the canvases take over; both carry the same product classes. */
.hrd-seq canvas.hrd-chapter__product { visibility: hidden; }
.hrd-seq.is-live canvas.hrd-chapter__product { visibility: visible; }
.hrd-seq.is-live img.hrd-chapter__product { visibility: hidden; }
.hrd-chapter__finish {
	position: absolute;
	left: 100%;
	top: 16%;
	margin: 0 0 0 clamp(12px, 2vw, 28px);
	white-space: nowrap;
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 700;
	letter-spacing: var(--wp--custom--track--micro);
	text-transform: uppercase;
	color: var(--c-accent);
	opacity: var(--d1);
}
.hrd-chapter__finish span { position: absolute; left: 0; top: 0; }
/* a cut at the wipe's midpoint, never a crossfade */
.hrd-chapter__finish-a { opacity: calc(1 - clamp(0, (var(--swap) - 0.5) * 1000, 1)); }
.hrd-chapter__finish-b { opacity: clamp(0, (var(--swap) - 0.5) * 1000, 1); }

/* 03 Shifting (paper): three acts, one camera move, all CAD renders on full-bleed
   canvases (sequence.js; frame map in patterns/chapter-shifting.php).
     I    0.00-0.21  the lineup travels in from the right, parks on the "CYL" (01, 02);
                     a caption rides under each knob (anchors)
     II   0.21-0.495 the "CYL" lifts out of the row and comes apart on a 55° axis (03, 04),
                     a callout on each part, then goes back together, base to the camera
          0.495-0.555 the dive up its M10x1.5 liner, into the dark (the cut at 0.5555)
     III  0.556-0.895 out of the spacer's bore: the cable bushing comes apart, builds
                     itself, rocks on its spherical joint (05, 06), meets its pair
   Numbering runs 01-06; the giant word drifts the whole way, behind the canvas.
   data-dark on the section (0.526-0.6004: the frames where the bore's dark fills every corner, frames 216-248,
   both sets): the chrome goes light (story.js), in the frame the corners change, and the ink copy steps aside. */
.hrd-chapter--shifting {
	--scene-length: 860vh;
	--d1:   clamp(0, (var(--p) - 0.03) / 0.04, 1);
	--d2:   clamp(0, (var(--p) - 0.11) / 0.04, 1);
	--row:  clamp(0, (var(--p) - 0.215) / 0.03, 1);   /* act I copy + captions leave as it lifts */
	--d3:   clamp(0, (var(--p) - 0.30) / 0.04, 1);
	--d4:   clamp(0, (var(--p) - 0.38) / 0.04, 1);
	--cap1: clamp(0, (var(--p) - 0.30) / 0.04, 1);   /* "CYL" caption once it's apart */
	--dive: clamp(0, (var(--p) - 0.495) / 0.02, 1);  /* act II copy leaves as the camera dives */
	--cut:  clamp(0, (var(--p) - 0.5555) * 1000, 1); /* 0 -> 1 inside the dark: knob -> bushing */
	--cap2: clamp(0, (var(--p) - 0.62) / 0.04, 1);   /* bushing caption once it's out of the bore */
	--d5:   clamp(0, (var(--p) - 0.63) / 0.04, 1);
	--d6:   clamp(0, (var(--p) - 0.72) / 0.04, 1);
	--cta:  clamp(0, (var(--p) - 0.84) / 0.04, 1);
	--out:  clamp(0, (var(--p) - 0.88) / 0.05, 1);
	--wipe: clamp(0, (var(--p) - 0.90) / 0.10, 1); /* = the section's data-wipe (story.js: the chrome rides it) */
	/* the label (ink) steps out for the dark (0.505-0.60) and back after */
	--lab:  calc(1 - clamp(0, (var(--p) - 0.505) / 0.015, 1) * (1 - clamp(0, (var(--p) - 0.60) / 0.03, 1)));
}
/* SHIFTING: at the giant word's -0.055em tracking the T's crossbar overlaps the F's arm by 0.028em (the only
   colliding pair in any chapter word); 0.05em after the F opens a 0.022em gap, as E-T and C-T have */
.hrd-chapter__kern { margin-right: 0.05em; }
.hrd-chapter--shifting .hrd-chapter__word {
	top: 40%;
	transform: translate(calc(-38vw + var(--p) * 56vw), -54%); /* counter-motion to the row */
}
.hrd-chapter--shifting .hrd-chapter__label { opacity: calc(var(--d1) * var(--lab)); }
/* Full-bleed canvases (the dive fills the screen); each frame set is composed
   with the row between label and details, the part right of the copy (desktop)
   or above it (mobile). */
.hrd-chapter--shifting .hrd-chapter__products {
	inset: 0;
	width: auto;
	height: auto;
	transform: translateY(calc(var(--out) * -10vh));
}
.hrd-chapter--shifting img.hrd-chapter__product { object-fit: cover; object-position: 50% 50%; }
.hrd-chapter--shifting .hrd-chapter__caption { opacity: max(calc(var(--cap1) * (1 - var(--dive))), calc(var(--cap2) * (1 - var(--out)))); }
.hrd-chapter--shifting .hrd-chapter__finish { position: relative; left: auto; top: auto; margin: 0 0 4px; opacity: 1; }
.hrd-chapter--shifting .hrd-chapter__finish-a { opacity: calc(1 - var(--cut)); }
.hrd-chapter--shifting .hrd-chapter__finish-b { opacity: var(--cut); }

/* Lineup captions ride under each knob (anchors k1..k6), the old figcaption type.
   The anchor is the point under the knob; the text is centred on it in whole px. */
.hrd-knobcap {
	position: absolute;
	left: 0;
	top: 0;
	/* --inview (sequence.js): fades as its knob nears the stage's edge, where the text would be cut. The names
	   leave just before the lift (0.205-0.217), not with the row (0.215-0.245): on a short landscape screen
	   (1280x720) they sit right over the row, and the lift carried them into it */
	opacity: calc(var(--d1) * (1 - clamp(0, (var(--p) - 0.205) / 0.012, 1)) * var(--inview, 1));
	pointer-events: none;
}
.hrd-knobcap[data-off] { visibility: hidden; }
.hrd-knobcap > * {
	position: absolute;
	left: -110px;
	width: 220px;
	text-align: center;
	white-space: nowrap;
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 700;
	letter-spacing: var(--wp--custom--track--micro);
	text-transform: uppercase;
}
.hrd-knobcap strong { top: 6px; font-size: var(--wp--preset--font-size--small); letter-spacing: var(--wp--custom--track--label); }
.hrd-knobcap span { top: 30px; color: var(--c-sub); }

/* Details: 01-02 as a row under the travelling lineup; 03-04 then 05-06 stack in
   the copy column, the same place, as in Drivetrain. */
.hrd-chapter__details--row {
	right: clamp(24px, 6vw, 112px);
	width: auto;
	max-width: 900px;
	grid-template-columns: repeat(2, 1fr);
	gap: clamp(20px, 3vw, 48px);
}
.hrd-chapter__details--row li { --next: 0 !important; opacity: clamp(0, var(--r) * 3, 1); }
.hrd-chapter--shifting .hrd-chapter__details--row { opacity: calc(1 - var(--row)); }
.hrd-chapter--shifting .hrd-chapter__details--a { opacity: calc(1 - var(--dive)); }
.hrd-chapter--shifting .hrd-chapter__details--b { opacity: calc(1 - var(--out)); }
.hrd-chapter--shifting .hrd-chapter__details--row li:nth-child(1) { --r: var(--d1); }
.hrd-chapter--shifting .hrd-chapter__details--row li:nth-child(2) { --r: var(--d2); }
.hrd-chapter--shifting .hrd-chapter__details--a li:nth-child(1) { --r: var(--d3); --next: var(--d4); }
.hrd-chapter--shifting .hrd-chapter__details--a li:nth-child(2) { --r: var(--d4); --next: 0; }
.hrd-chapter--shifting .hrd-chapter__details--b li:nth-child(1) { --r: var(--d5); --next: var(--d6); }
.hrd-chapter--shifting .hrd-chapter__details--b li:nth-child(2) { --r: var(--d6); --next: 0; }

/* Callouts (shared .hrd-callout: ring, 55° leader, a paper chip on paper).
   The CYL's parts while they hang apart (frames ~150-176), the bushing's while it's
   apart and once it's built (~289-383). */
.hrd-chapter--shifting .hrd-callout--pattern { --o: calc(clamp(0, (var(--p) - 0.330) / 0.012, 1) * (1 - clamp(0, (var(--p) - 0.440) / 0.012, 1))); }
.hrd-chapter--shifting .hrd-callout--body    { --o: calc(clamp(0, (var(--p) - 0.338) / 0.012, 1) * (1 - clamp(0, (var(--p) - 0.442) / 0.012, 1))); }
.hrd-chapter--shifting .hrd-callout--ring    { --o: calc(clamp(0, (var(--p) - 0.346) / 0.012, 1) * (1 - clamp(0, (var(--p) - 0.444) / 0.012, 1))); }
.hrd-chapter--shifting .hrd-callout--slug    { --o: calc(clamp(0, (var(--p) - 0.360) / 0.012, 1) * (1 - clamp(0, (var(--p) - 0.432) / 0.012, 1))); }
.hrd-chapter--shifting .hrd-callout--liner   { --o: calc(clamp(0, (var(--p) - 0.368) / 0.012, 1) * (1 - clamp(0, (var(--p) - 0.436) / 0.012, 1))); }
.hrd-chapter--shifting .hrd-callout--oring   { --o: calc(clamp(0, (var(--p) - 0.690) / 0.012, 1) * (1 - clamp(0, (var(--p) - 0.828) / 0.012, 1))); }
.hrd-chapter--shifting .hrd-callout--ball    { --o: calc(clamp(0, (var(--p) - 0.790) / 0.012, 1) * (1 - clamp(0, (var(--p) - 0.834) / 0.012, 1))); } /* both bow out before the pair */

/* 04 Induction & Electronics (ink): "follow the air", one camera move (frames and
   the p -> frame map in chapter-induction.php). A 55° slash opens the illustrative
   thermal view over the gasket and closes it; the word slash-swaps INDUCTION ->
   ELECTRONICS inside the dark at the cut (p 0.5755); "1000%+" counts up on the
   L15's open thermistor. */
@property --hrd-count {
	syntax: '<integer>';
	inherits: true;
	initial-value: 0;
}
.hrd-chapter--induction {
	--scene-length: 950vh; /* 900 -> 950 with the dive re-timed (2026-11-07): no stretch denser than 0.71 frames per vh */
	--d1:   clamp(0, (var(--p) - 0.035) / 0.03, 1);   /* 01 + the label, as the adapter builds */
	--d2:   clamp(0, (var(--p) - 0.4115) / 0.0315, 1);   /* 02, once the gasket has pulled back (below it) */
	/* white on white: while the PTFE fills the screen (out of port 2, and back into it) the
	   white type steps out */
	--wht: max(calc(clamp(0, (var(--p) - 0.3703) / 0.0077, 1) * (1 - clamp(0, (var(--p) - 0.4103) / 0.0073, 1))),
	           calc(clamp(0, (var(--p) - 0.5493) / 0.0077, 1) * (1 - clamp(0, (var(--p) - 0.5760) / 0.0035, 1))));
	--thi:  clamp(0, (var(--p) - 0.456) / 0.022, 1);  /* the thermal slash opens (frames ~218-226) */
	--tho:  clamp(0, (var(--p) - 0.4953) / 0.022, 1);  /* and closes (~233-241: 4 frames sooner since the camera ease into port 2 (2026-11-08) starts the dive on the still frames 241-245, which the thermal view's own frames (to 246) can't follow) */
	--dive: clamp(0, (var(--p) - 0.5300) / 0.0257, 1);    /* act I copy leaves as the camera dives into port 2 */
	--swap: clamp(0, (var(--p) - 0.5596) / 0.0154, 1);  /* the word, inside the dark */
	--cut:  clamp(0, (var(--p) - 0.5755) * 1000, 1);
	--stat: clamp(0, (var(--p) - 0.5838) / 0.0612, 1);   /* counts up through the thermistor macro */
	--d3:   clamp(0, (var(--p) - 0.5924) / 0.0259, 1);
	--d4:   clamp(0, (var(--p) - 0.765) / 0.03, 1);   /* the harness */
	--cta:  clamp(0, (var(--p) - 0.83) / 0.04, 1);
	--out:  clamp(0, (var(--p) - 0.885) / 0.04, 1);
	--wipe: clamp(0, (var(--p) - 0.905) / 0.07, 1); /* = the section's data-wipe (story.js: the chrome rides it). Done by 0.975, not 1: 05 pins from the raw scroll while this runs on the spring (~0.19 s behind in Play), and pinned on an unfinished wipe it cut the last stripes off in one frame */
	/* the caption names the part on screen: adapter, gasket, sensors, harness */
	--ca: calc(var(--d1) * (1 - clamp(0, (var(--p) - 0.2035) / 0.0081, 1)));   /* out before the fittings' tags rise into it */
	--cg: calc(clamp(0, (var(--p) - 0.4139) / 0.0161, 1) * (1 - var(--dive)));
	--cb: calc(clamp(0, (var(--p) - 0.645) / 0.015, 1) * (1 - clamp(0, (var(--p) - 0.765) / 0.012, 1)));
	--ch: calc(clamp(0, (var(--p) - 0.777) / 0.015, 1) * (1 - var(--out)));
	--kc: calc(clamp(0, (var(--p) - 0.7155) / 0.012, 1) * (1 - clamp(0, (var(--p) - 0.7578) / 0.0102, 1)));  /* the sensors' names: in as they settle, out as they leave (the map's rest at 345-346 between) */
	--c-wipe-edge: var(--wp--preset--color--sky);
}
.hrd-chapter--induction .hrd-chapter__word { top: 45%; font-size: clamp(6rem, 15.5vw, 19rem); }
.hrd-chapter__word--swap { display: grid; }
.hrd-chapter__word--swap > span { grid-area: 1 / 1; }
/* same slash geometry as the product swap, across the word's box; the front wears the stripe */
.hrd-word-a { clip-path: polygon(calc(var(--swap) * 130% - 15%) 0, 120% 0, 120% 100%, calc(var(--swap) * 130% - 25%) 100%); }
.hrd-word-b { clip-path: polygon(-20% 0, calc(var(--swap) * 130% - 15%) 0, calc(var(--swap) * 130% - 25%) 100%, -20% 100%); }
.hrd-word-edge {
	--f: calc(var(--swap) * 130% - 15%);
	background: repeating-linear-gradient(55deg, var(--c-fg) 0 calc(var(--edge-hz) * 0.33), transparent calc(var(--edge-hz) * 0.33) calc(var(--edge-hz) * 0.56));
	clip-path: polygon(var(--f) 0, calc(var(--f) + 6%) 0, calc(var(--f) - 4%) 100%, calc(var(--f) - 10%) 100%);
	opacity: clamp(0, min(var(--swap), 1 - var(--swap)) * 30, 1);
}

/* Full-bleed canvases: each frame set is composed with the part right of the copy
   column (desktop) or above it (mobile); the gasket takes the full width. */
.hrd-chapter--induction .hrd-chapter__products {
	inset: 0;
	width: auto;
	height: auto;
	transform: translateY(calc(var(--out) * -10vh));
}
.hrd-chapter--induction img.hrd-chapter__product { object-fit: cover; object-position: 50% 50%; }

/* The thermal view: the same frames as a thermal camera would see them (track "th",
   opaque), shown between two 55° fronts that cross the screen, each wearing the stripe. */
.hrd-chapter--induction .hrd-thermal {
	--xi: calc(var(--thi) * (100% + 70vh + 9vw));
	--xo: calc(var(--tho) * (100% + 70vh + 9vw));
	clip-path: polygon(var(--xo) 0, var(--xi) 0, calc(var(--xi) - 70vh) 100%, calc(var(--xo) - 70vh) 100%);
}
.hrd-thermal__edge {
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: repeating-linear-gradient(55deg, var(--c-fg) 0 calc(var(--edge-hz) * 0.33), transparent calc(var(--edge-hz) * 0.33) calc(var(--edge-hz) * 0.56));
	clip-path: polygon(var(--x) 0, calc(var(--x) + 9vw) 0, calc(var(--x) + 9vw - 70vh) 100%, calc(var(--x) - 70vh) 100%);
}
.hrd-thermal__edge--in  { --x: calc(var(--thi) * (100% + 70vh + 9vw)); opacity: clamp(0, min(var(--thi), 1 - var(--thi)) * 30, 1); }
.hrd-thermal__edge--out { --x: calc(var(--tho) * (100% + 70vh + 9vw)); opacity: clamp(0, min(var(--tho), 1 - var(--tho)) * 30, 1); }
.hrd-thermal__note {
	right: clamp(24px, 6vw, 112px);
	bottom: calc(clamp(16px, 2.2vw, 32px) + 76px);
	margin: 0;
	z-index: 4;
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 700;
	letter-spacing: var(--wp--custom--track--micro);
	text-transform: uppercase;
	color: var(--c-sub);
	opacity: calc(clamp(0, (var(--thi) - 0.6) * 4, 1) * (1 - clamp(0, var(--tho) * 4, 1)));
}

/* Caption: the part on screen, crossfading in place */
.hrd-chapter--induction .hrd-chapter__finish { position: relative; left: auto; top: auto; margin: 0 0 4px; opacity: 1; }
.hrd-cap-a { opacity: var(--ca); }
.hrd-cap-g { opacity: var(--cg); }
.hrd-cap-b { opacity: var(--cb); }
.hrd-cap-h { opacity: var(--ch); }

/* Details: 01-02 through act I, 03-04 through act II, the same place */
.hrd-chapter--induction .hrd-chapter__label { opacity: calc(var(--d1) * (1 - var(--wht))); }
.hrd-chapter--induction .hrd-chapter__caption { opacity: calc(1 - var(--wht)); }
.hrd-chapter--induction .hrd-chapter__details--a { opacity: calc((1 - var(--dive)) * (1 - var(--wht))); }
/* 01 leaves with the adapter, into the bore (the gasket's full width reaches its line); 02 then stands alone */
.hrd-chapter--induction .hrd-chapter__details--a li:nth-child(1) { opacity: calc(clamp(0, var(--r) * 3, 1) * (1 - clamp(0, (var(--p) - 0.3561) / 0.0129, 1))); }
.hrd-chapter--induction .hrd-chapter__details--b { opacity: calc(1 - var(--out)); }
.hrd-chapter--induction .hrd-chapter__details--a li:nth-child(1) { --r: var(--d1); --next: var(--d2); }
.hrd-chapter--induction .hrd-chapter__details--a li:nth-child(2) { --r: var(--d2); --next: 0; }
.hrd-chapter--induction .hrd-chapter__details--b li:nth-child(1) { --r: var(--d3); --next: var(--d4); }
.hrd-chapter--induction .hrd-chapter__details--b li:nth-child(2) { --r: var(--d4); --next: 0; }

/* Callouts ride their parts (anchors.json); each shows while its part holds still */
.hrd-chapter--induction .hrd-callout--billet  { --o: calc(clamp(0, (var(--p) - 0.040) / 0.012, 1) * (1 - clamp(0, (var(--p) - 0.128) / 0.0151, 1))); }
.hrd-chapter--induction .hrd-callout--oring   { --o: calc(clamp(0, (var(--p) - 0.050) / 0.012, 1) * (1 - clamp(0, (var(--p) - 0.118) / 0.012, 1))); }
.hrd-chapter--induction .hrd-callout--bolts   { --o: calc(clamp(0, (var(--p) - 0.1562) / 0.0157, 1) * (1 - clamp(0, (var(--p) - 0.2092) / 0.0097, 1))); }
.hrd-chapter--induction .hrd-callout--booster { --o: calc(clamp(0, (var(--p) - 0.2124) / 0.0097, 1) * (1 - clamp(0, (var(--p) - 0.2620) / 0.0117, 1))); }
.hrd-chapter--induction .hrd-callout--boost   { --o: calc(clamp(0, (var(--p) - 0.2164) / 0.0097, 1) * (1 - clamp(0, (var(--p) - 0.2620) / 0.0117, 1))); }
.hrd-chapter--induction .hrd-callout--vblock  { --o: calc(clamp(0, (var(--p) - 0.2990) / 0.0085, 1) * (1 - clamp(0, (var(--p) - 0.3273) / 0.0108, 1))); }
.hrd-chapter--induction .hrd-callout--ptfe    { --o: calc(clamp(0, (var(--p) - 0.4018) / 0.0145, 1) * (1 - clamp(0, (var(--p) - 0.4430) / 0.0120, 1))); }
.hrd-chapter--induction .hrd-callout--tip     { --o: calc(clamp(0, (var(--p) - 0.5864) / 0.0104, 1) * (1 - clamp(0, (var(--p) - 0.6158) / 0.0104, 1))); }
.hrd-chapter--induction .hrd-callout--harness { --o: calc(clamp(0, (var(--p) - 0.832) / 0.012, 1) * (1 - var(--out))); }
/* the three sensors' names ride under them while the family holds (knob caption type) */
.hrd-chapter--induction .hrd-knobcap { opacity: calc(var(--kc) * var(--inview, 1)); }

.hrd-stat {
	top: calc(clamp(16px, 2.2vw, 32px) + 112px);
	left: clamp(24px, 6vw, 112px);
	display: flex;
	align-items: flex-end;
	gap: 16px;
	z-index: 4;
	opacity: clamp(0, var(--stat) * 6, 1);
	transform: translateY(calc((1 - clamp(0, var(--stat) * 4, 1)) * 16px - var(--out) * 6vh));
	color: var(--wp--preset--color--sky);
}
.hrd-stat__n {
	/* ease-out count: 0 → 1000 */
	--hrd-count: calc(1000 * (1 - (1 - var(--stat)) * (1 - var(--stat)) * (1 - var(--stat))));
	counter-reset: hrd var(--hrd-count);
	font-size: clamp(3.5rem, 8vw, 9rem);
	font-weight: 700;
	line-height: 0.8;
	letter-spacing: -0.05em;
	font-variant-numeric: tabular-nums;
}
.hrd-stat__n::after { content: counter(hrd) "%+"; }
.hrd-stat__k {
	padding-bottom: 0.6em;
	white-space: nowrap; /* two lines, as set */
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 700;
	letter-spacing: var(--wp--custom--track--micro);
	text-transform: uppercase;
	color: var(--c-sub);
}
.hrd-chapter--induction .hrd-chapter__links a + a { margin-left: 2rem; }

/* Exit into "Who we are": the slash wipes in the camo itself */
.hrd-chapter__wipe--camo {
	background: var(--wp--custom--camo--ground); /* the camo image joins below (.hrd-camo-in) */
}

/* 05 Who we are (camo), the capstone. Its timeline is in SCREENS: --v = p x --L
   (one screen = one viewport of scroll; patterns/chapter-who.php computes --L and
   every beat, and the render map, from the same numbers):
     0.1-0.9  the statement types in: DUAL DUTY ISN'T / JUST A FEATURE. / IT'S THE STANDARD.
     1.45-1.85  the slash turns it in place: DUAL DUTY, / IN THEIR WORDS. (DUAL DUTY stays)
     1.55-1.85  the dark field comes in under it · 1.9-2.52 where "It's the standard." stood, an owner answers
     2.78-3.0  out, as the first part arrives (--vc)
     --vc..--vg0  the constellation: nine stops, each review on its part (.hrd-review)
     --vg0..--vge  the catalogue gathers · --vmk the giant HRD box mark slashes in
     --vwv  the box fills with track footage · --vwe it opens to the whole screen
     --vbk  "Engineering happiness." · --vwp the slash to sky (Find your fit)
   in(start, len) = clamp(0, (var(--v) - start) / len, 1) */
.hrd-who {
	--scene-length: 1800vh;
	--L: 18;
	--v: calc(var(--p) * var(--L));
	--c-bg: var(--wp--custom--camo--ground);
	--c-fg: var(--wp--preset--color--white);
	--c-sub: rgba(255, 255, 255, 0.66);
	--c-rule: rgba(255, 255, 255, 0.16);
	--c-accent: var(--wp--preset--color--sky);
	--c-wipe: var(--wp--preset--color--sky);
	--c-wipe-edge: var(--wp--preset--color--sky);
	--d1: clamp(0, (var(--v) - 0.1) / 0.4, 1);
	/* the statement, the slash, the answer */
	--s1a: clamp(0, (var(--v) - 0.1) / 0.4, 1);
	--s1b: clamp(0, (var(--v) - 0.3) / 0.4, 1);
	--s1c: clamp(0, (var(--v) - 0.5) / 0.4, 1);
	--cs:  clamp(0, (var(--v) - 1.45) / 0.4, 1);
	--ovq: clamp(0, (var(--v) - 1.9) / 0.5, 1);
	--ovc: clamp(0, (var(--v) - 2.4) / 0.12, 1);
	--ovo: clamp(0, (var(--v) - 2.78) / 0.22, 1);
	/* the render box: in under the slash, out once the footage covers it */
	--wo: clamp(0, (var(--v) - 1.55) / 0.3, 1);
	/* the catalogue's mark, count line, the footage window, the bookend, the wipe */
	--mk: clamp(0, (var(--v) - var(--vmk)) / 0.3, 1);
	--ct: clamp(0, (var(--v) - var(--vge)) / 0.12, 1);
	--wv: clamp(0, (var(--v) - var(--vwv)) / 0.15, 1);
	--we: clamp(0, (var(--v) - var(--vwe)) / 0.45, 1);
	--fc: clamp(0, (var(--v) - var(--vwe) - 0.5) / 0.15, 1);
	--bk1: clamp(0, (var(--v) - var(--vbk)) / 0.3, 1);
	--bk2: clamp(0, (var(--v) - var(--vbk) - 0.15) / 0.3, 1);
	--wipe: clamp(0, (var(--v) - var(--vwp)) / 0.5, 1); /* = the section's data-wipe (story.js: the chrome rides it) */
	/* the giant mark: as big as the camo above the catalogue band allows */
	--mw: min(54vw, 96vh);
	--mtop: 7vh;
	color: var(--c-fg);
}
.hrd-who .hrd-stage { background: var(--c-bg); }
/* THE CAMO (149 KB over the wire) is only seen far down the page: 04's exit wipe and 05's ground. As a CSS background of
   elements in the DOM it was requested with the first paint and, starved by the frame packs on a phone, held the load
   event for seconds (about 9 s against 2 s without it, audit 2026-11-09). story.js adds .hrd-camo-in once the page
   has loaded; without JS it applies from the start. Same pixels once it is in. */
.hrd-camo-in .hrd-chapter__wipe--camo { background: var(--wp--custom--camo--ground) url("../images/camo-hero.svg") center / cover; }
.hrd-camo-in .hrd-who .hrd-stage { background: var(--c-bg) url("../images/camo-hero.svg") center / cover; }
@media (scripting: none) {
	.hrd-chapter__wipe--camo { background: var(--wp--custom--camo--ground) url("../images/camo-hero.svg") center / cover; }
	.hrd-who .hrd-stage { background: var(--c-bg) url("../images/camo-hero.svg") center / cover; }
}
/* Pattern continuity: 05 exits by wiping in this exact camo, so 06 overlaps 05
   by one screen and pins the instant 05's wipe completes. At that frame both
   are the identical full camo (06 starts with everything hidden): a
   pixel-identical hand-over, instead of two camo copies scrolling past each
   other (which shows a hard seam where the pattern restarts). */
.hrd-story > .hrd-scene.hrd-who { margin-top: -100vh !important; }
/* ...but while it rises through that overlap it stays invisible (story.js sets [data-pinned] the moment its top
   reaches the viewport's: the same scroll position at which 05's wipe completes). Otherwise its camo panel slides
   up with a flat top edge while 05's slash is still wiping: two moves at once. Behind it, the story's own ground is
   the camo's, so a frame where a compositor-driven scroll beats the attribute shows camo ground, never white. */
.hrd-story-ready .hrd-who:not([data-pinned]) > .hrd-stage { visibility: hidden; }
.hrd-story { background: var(--wp--custom--camo--ground); }

/* The statement and "in their words": one stack drawn twice in the same place (the old lines right of the 55°
   front, the new left of it), so DUAL DUTY, the same pixels in both, stays while the rest turns over. The front
   runs 0.7 of the stack's height across it (55°); its bold hazard trails it. Ems are the stack's own: 3 lines of
   0.86 + the clip's 0.04 = 2.7em tall. FIDELITY: clip-path and opacity only. */
.hrd-who__dd {
	--fx: calc(var(--cs) * (100% + 3.4em) - 1.2em);
	left: clamp(24px, 6vw, 112px);
	right: clamp(24px, 6vw, 112px);
	top: 50%;
	z-index: 3;
	font-size: clamp(2.75rem, 8.4vw, 10rem);
	transform: translateY(calc(-50% - var(--ovo) * 6vh));
	opacity: calc(1 - var(--ovo));
	pointer-events: none;
}
.hrd-who__stack { position: relative; display: grid; }
.hrd-who__stack > p {
	grid-area: 1 / 1;
	margin: 0;
	color: var(--c-fg);
	font-size: 1em;
	font-weight: 700;
	line-height: 0.86;
	letter-spacing: -0.05em;
	text-transform: uppercase;
	white-space: nowrap;
}
.hrd-who__old { clip-path: polygon(var(--fx) -10%, 200% -10%, 200% 110%, calc(var(--fx) - 1.89em) 110%); }
.hrd-who__new { clip-path: polygon(-10% -10%, var(--fx) -10%, calc(var(--fx) - 1.89em) 110%, -10% 110%); }
.hrd-who__old .hrd-line:nth-child(1) > span { --r: var(--s1a); }
.hrd-who__old .hrd-line:nth-child(2) > span { --r: var(--s1b); }
.hrd-who__old .hrd-line:nth-child(3) > span { --r: var(--s1c); color: var(--wp--preset--color--sky); }
.hrd-who__new .hrd-line > span { --r: 1; }
.hrd-who__new .hrd-line:nth-child(2) > span { color: var(--wp--preset--color--sky); }
.hrd-who__edge {
	position: absolute;
	inset: 0;
	background: repeating-linear-gradient(55deg, var(--wp--preset--color--sky) 0 calc(var(--edge-hz) * 0.33), transparent calc(var(--edge-hz) * 0.33) calc(var(--edge-hz) * 0.56));
	clip-path: polygon(calc(var(--fx) - 0.6em) -10%, var(--fx) -10%, calc(var(--fx) - 1.89em) 110%, calc(var(--fx) - 2.49em) 110%);
	opacity: clamp(0, min(var(--cs), 1 - var(--cs)) * 40, 1);
}
/* the owner's answer, where the third line stood (1.8em down: two lines of 0.9em) */
.hrd-who__answer {
	position: absolute;
	left: 0;
	right: 0;
	top: 1.86em;
	margin: 0;
	--q: var(--ovq);
	--st: var(--ovc);
}
.hrd-who__answer p { margin: 0; max-width: 62rem; color: var(--c-fg); font-size: clamp(1.4rem, 2.6vw, 3rem); font-weight: 700; line-height: 1.08; letter-spacing: -0.03em; }
.hrd-who__aw .w { opacity: clamp(0, (var(--q) * (var(--n) + 2) - var(--i)) / 2, 1); }
.hrd-who__aw .w.is-hl { color: var(--wp--preset--color--sky); }
/* quote marks: the opening one with the first word, the closing one with the last */
.hrd-q { color: var(--wp--preset--color--sky); opacity: clamp(0, var(--q) * 8, 1); }
.hrd-q--close { opacity: clamp(0, (var(--q) - 0.94) * 16, 1); }
/* headings for screen readers only (the visual stack is aria-hidden) */
.hrd-sr { position: absolute !important; width: 1px; height: 1px; margin: -1px !important; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.hrd-stars { display: inline-flex; gap: 3px; color: var(--wp--preset--color--sky); font-size: 0.95rem; letter-spacing: 0; }
.hrd-stars i { font-style: normal; } /* all five, always: they arrive with the cite */
.hrd-stars i:nth-child(1) { --k: 0; } .hrd-stars i:nth-child(2) { --k: 1; } .hrd-stars i:nth-child(3) { --k: 2; }
.hrd-stars i:nth-child(4) { --k: 3; } .hrd-stars i:nth-child(5) { --k: 4; }


/* beats outside their window (story.js BEAT WINDOWS) cost nothing */
.hrd-scene [data-idle] { display: none !important; }

/* ---- "Dual Duty, in their words." -------------------------------------- */
/* the render box (full bleed, frames drawn cover; bin/render/words.py composes the
   part right of the review column on desktop, above it on phones) */
.hrd-who__words { inset: 0; z-index: 2; opacity: calc(var(--wo) * (1 - clamp(0, (var(--we) - 0.9) * 10, 1))); }
.hrd-who__layer { position: absolute; inset: 0; width: 100%; height: 100%; }
.hrd-seq canvas.hrd-who__layer { visibility: hidden; }
.hrd-seq.is-live canvas.hrd-who__layer { visibility: visible; }

/* A review rides its part: the spec callouts' ring and 55° leader, then a shelf
   to the review column, the words typing on in reading order. sequence.js moves
   the figure to the part's anchor (whole px) and gives --ax/--ay, so the column
   stays put across while the leader rides the part; and --hy, the anchor's height at
   the frame the words start, so the words hold still while they're read (the
   smoothness review, 2026-11-08: they hopped 1-3px with every frame of the part's
   drift, up to 19px over a read). Timeline (screens, inline):
   --r0 ring + leader · +0.05 shelf · --rq0..--rq1 words · then the stars · --r1 out */
.hrd-review {
	--rl: clamp(0, (var(--v) - var(--r0)) / 0.05, 1);
	--rs: clamp(0, (var(--v) - var(--r0) - 0.04) / 0.05, 1);
	--q: clamp(0, (var(--v) - var(--rq0)) / (var(--rq1) - var(--rq0)), 1);
	--st: clamp(0, (var(--v) - var(--rq1)) / 0.08, 1);
	--o: clamp(0, (var(--v) - var(--r1)) / 0.05, 1);
	--col-l: clamp(24px, 6vw, 112px);
	--col-w: min(31vw, 33rem);
	--lead: 64px; /* at 55°: ends 36.7px left, 52.4px up */
	/* the words hold still while they're read: sequence.js gives --hy, the anchor's y at the frame the words start;
	   --dh is how far that row is from where the part is now. The leader stretches to meet the held shelf. */
	--dh: calc(var(--hy, var(--ay, 0px)) - var(--ay, 0px));
	--rise: calc(53px - var(--dh));
	position: absolute;
	left: 0;
	top: 0;
	margin: 0;
	color: var(--wp--preset--color--sky);
	opacity: calc(clamp(0, var(--rl) * 4, 1) * (1 - var(--o)));
}
.hrd-review[data-off] { visibility: hidden; }
.hrd-review > i { position: absolute; display: block; } /* ring, leader, shelf (never the stars) */
.hrd-review__ring { left: -5px; top: -5px; width: 10px; height: 10px; border: 1.5px solid currentColor; border-radius: 50%; box-sizing: border-box; }
.hrd-review__lead {
	left: 0;
	top: 0;
	width: max(0px, calc(var(--rise) / 0.8192));
	height: 1.5px;
	background: currentColor;
	transform-origin: 0 50%;
	transform: rotate(-125deg);
	clip-path: inset(0 calc((1 - var(--rl)) * 100%) 0 0);
}
.hrd-review__shelf {
	top: calc(var(--dh) - 53px);
	height: 1.5px;
	left: calc(var(--col-l) + var(--col-w) + 18px - var(--ax, 0px));
	width: max(0px, calc(var(--ax, 0px) - var(--rise) * 0.7002 - var(--col-l) - var(--col-w) - 18px));
	background: currentColor;
	clip-path: inset(0 0 0 calc((1 - var(--rs)) * 100%));
}
.hrd-review__text {
	position: absolute;
	left: calc(var(--col-l) - var(--ax, 0px));
	top: calc(var(--dh) - 53px - 0.62em);
	width: var(--col-w);
	margin: 0;
	color: var(--c-fg);
	font-size: clamp(1.2rem, 1.75vw, 2rem);
}
.hrd-review__text p { margin: 0; font-weight: 700; line-height: 1.14; letter-spacing: -0.025em; }
.hrd-review__words .w { opacity: clamp(0, (var(--q) * (var(--n) + 2) - var(--i)) / 2, 1); }
.hrd-review__words .w.is-hl { color: var(--wp--preset--color--sky); }
.hrd-review cite,
.hrd-who__answer cite {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px 14px;
	margin-top: clamp(12px, 2vh, 22px);
	font-style: normal;
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 700;
	letter-spacing: var(--wp--custom--track--micro);
	text-transform: uppercase;
	color: var(--c-sub);
	opacity: clamp(0, var(--st) * 3, 1);
}

/* The catalogue lands under a giant HRD box mark (the etched box on every part),
   which slashes in at 55°, then fills with track footage and opens to the screen. */
.hrd-who__mark {
	left: 50%;
	top: var(--mtop);
	width: var(--mw);
	height: auto;
	margin-left: calc(var(--mw) / -2) !important;
	z-index: 1;
	clip-path: polygon(-30% 0, calc(var(--mk) * 160% - 30%) 0, calc(var(--mk) * 160% - 60%) 100%, -30% 100%);
	opacity: calc(1 - var(--wv));
}
.hrd-who__count { /* top right, clear of the mark (the label holds the top left) */
	right: clamp(24px, 6vw, 112px);
	top: calc(clamp(16px, 2.2vw, 32px) + 72px);
	display: flex;
	align-items: center;
	gap: 14px;
	margin: 0;
	z-index: 4;
	--st: var(--ct);
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 700;
	letter-spacing: var(--wp--custom--track--micro);
	text-transform: uppercase;
	opacity: calc(clamp(0, var(--ct) * 3, 1) * (1 - var(--wv)));
}
/* The footage window: clipped to the mark's box, then opened to the full screen
   (clip-path inset only: the footage itself is never scaled). */
.hrd-who__film {
	--mh: calc(var(--mw) / 1.916);
	--it: calc(var(--mtop) * (1 - var(--we)));
	--ib: calc((100vh - var(--mtop) - var(--mh)) * (1 - var(--we)));
	--ix: calc((100vw - var(--mw)) / 2 * (1 - var(--we)));
	inset: 0;
	z-index: 5;
	background: var(--c-bg);
	clip-path: inset(var(--it) var(--ix) var(--ib) var(--ix));
	opacity: var(--wv);
	visibility: hidden;
}
.hrd-who__film video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.hrd-who__film::before { /* a soft floor under the caption */
	content: "";
	position: absolute;
	inset: 55% 0 0 0;
	background: linear-gradient(0deg, rgb(4 1 29 / 0.72), rgb(4 1 29 / 0));
	opacity: var(--fc);
	z-index: 1;
}
.hrd-who__film::after { /* a scrim for the bookend's type */
	content: "";
	position: absolute;
	inset: 0;
	background: rgb(4 1 29 / 0.55);
	opacity: var(--bk1);
	z-index: 1;
}
.hrd-who[data-film] .hrd-who__film { visibility: visible; }
.hrd-who__letters { /* the box's letters stay knocked out while the footage fills the box */
	left: 50%;
	top: var(--mtop);
	width: var(--mw);
	height: auto;
	margin-left: calc(var(--mw) / -2) !important;
	z-index: 6;
	fill: var(--c-bg);
	opacity: calc(var(--wv) * (1 - clamp(0, var(--we) * 3, 1)));
	pointer-events: none;
}
.hrd-who__film-cap { /* bottom right: the footage's own telemetry holds the other corners */
	right: clamp(24px, 6vw, 112px);
	bottom: calc(clamp(16px, 2.2vw, 32px) + 64px);
	text-align: right;
	z-index: 7;
	opacity: calc(var(--fc) * (1 - var(--bk1)));
}
.hrd-who__film-cap p { margin: 0 0 6px; font-size: var(--wp--preset--font-size--micro); font-weight: 700; letter-spacing: var(--wp--custom--track--micro); text-transform: uppercase; }
.hrd-who__film-by { color: var(--c-sub); }
.hrd-who__film-cap .is-style-arrow-link { margin-top: 14px; pointer-events: auto; }
.hrd-who__film-cap a { color: var(--c-fg); }
/* The bookend: the opener's line, over the footage */
.hrd-who__bookend {
	left: clamp(24px, 6vw, 112px);
	right: clamp(24px, 6vw, 112px);
	top: 50%;
	transform: translateY(-50%);
	margin: 0;
	z-index: 7;
	color: var(--c-fg);
	font-size: clamp(3rem, 10.5vw, 13rem);
	line-height: 0.84;
	letter-spacing: -0.055em;
	text-transform: uppercase;
	pointer-events: none;
}
.hrd-who__bookend .hrd-line:nth-child(1) > span { --r: var(--bk1); }
.hrd-who__bookend .hrd-line:nth-child(2) > span { --r: var(--bk2); color: var(--wp--preset--color--sky); }
.hrd-who .hrd-chapter__wipe,
.hrd-who .hrd-chapter__wipe-edge { z-index: 8; }

.hrd-chapter__wipe--sky { background: var(--wp--preset--color--sky); }

/* 06 Find your fit (sky): the finale. Interactive, so it pins only briefly. */
.hrd-fit {
	--scene-length: 200vh;
	--c-bg: var(--wp--preset--color--sky);
	--c-fg: var(--wp--preset--color--ink);
	--c-sub: rgba(4, 1, 29, 0.62);
	--c-rule: rgba(4, 1, 29, 0.2);
	--c-accent: var(--wp--preset--color--ink);
	--d1: clamp(0, (var(--p) - 0.0) / 0.12, 1);
	--f1: clamp(0, (var(--p) - 0.04) / 0.14, 1);
	--f2: clamp(0, (var(--p) - 0.12) / 0.14, 1);
	--form: clamp(0, (var(--p) - 0.24) / 0.16, 1);
}
.hrd-fit__body {
	left: clamp(24px, 6vw, 112px);
	right: clamp(24px, 6vw, 112px);
	top: 50%;
	transform: translateY(-50%);
	z-index: 3;
}
.hrd-fit__title {
	margin: 0 0 clamp(28px, 5vh, 56px);
	color: var(--c-fg);
	font-size: clamp(2.75rem, 8.4vw, 10rem);
	line-height: 0.86;
	letter-spacing: -0.05em;
	text-transform: uppercase;
}
.hrd-fit__title .hrd-line:nth-child(1) > span { --r: var(--f1); }
.hrd-fit__title .hrd-line:nth-child(2) > span { --r: var(--f2); }
.hrd-fit__form,
.hrd-fit__note { opacity: clamp(0, var(--form) * 2, 1); transform: translateY(calc((1 - var(--form) * var(--form) * (3 - 2 * var(--form))) * 20px)); } /* the shared ease; Play lands as it ends (play.js END_P) */
.hrd-fit__form {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr)) auto;
	gap: clamp(16px, 2.5vw, 40px);
	align-items: end;
}
.hrd-fit__field { display: grid; gap: 10px; }
.hrd-fit__k {
	font-size: var(--wp--preset--font-size--micro);
	font-weight: 700;
	letter-spacing: var(--wp--custom--track--micro);
	text-transform: uppercase;
}
.hrd-fit__k span { margin-right: 0.6em; color: var(--c-sub); }
.hrd-fit__field select {
	appearance: none;
	width: 100%;
	padding: 0.35em 1.8em 0.35em 0;
	border: 0;
	border-bottom: 2px solid var(--c-fg);
	border-radius: 0;
	background: transparent url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M0 0h12L6 8z' fill='%2304011D'/%3E%3C/svg%3E") right 0.2em center / 0.7em no-repeat;
	color: var(--c-fg);
	font: inherit;
	font-size: clamp(1.25rem, 2vw, 1.9rem);
	font-weight: 700;
	letter-spacing: -0.03em;
	cursor: pointer;
}
.hrd-fit__field select:disabled { opacity: 0.35; cursor: not-allowed; }
.hrd-fit__field select:focus-visible { outline: 2px solid var(--c-fg); outline-offset: 4px; }
.hrd-fit__go { white-space: nowrap; }
.hrd-fit__go:disabled { opacity: 0.35; cursor: not-allowed; }
.hrd-fit__go:not(:disabled):hover { background: var(--wp--preset--color--white); color: var(--wp--preset--color--ink); }
.hrd-fit__note {
	margin: clamp(20px, 3vh, 32px) 0 0;
	font-size: var(--wp--preset--font-size--small);
	color: var(--c-sub);
}
.hrd-fit__note a { color: var(--c-fg); font-weight: 700; }

/* Phones AND any portrait screen (an iPad upright): sequence.js picks each chapter's frame set by the stage's
   aspect (portrait frames compose the part in the upper half, the copy under it), so the layout follows the
   same rule; before, 782 px+ portrait screens got the desktop copy layout over the portrait frames. */
@media (max-width: 781px), (max-aspect-ratio: 1/1) {
	.hrd-chapter__word { font-size: 30vw; top: 30%; }
	.hrd-chapter__products { --h: 46vh; top: 15vh; left: 50%; }
	.hrd-chapter__details { width: auto; right: 24px; gap: 14px; bottom: calc(clamp(16px, 2.2vw, 32px) + 64px); }
	/* one detail at a time, in one slot at the foot: the desktop's stack (earlier ones gray above the current)
	   climbed into the caption and the parts' tags on a phone's short stage (an iPhone's 100svh is ~660 px).
	   The current one leaves before the next rises in (out over the first third of its ramp, in over the
	   second), never two at once. The shifting row (titles only) keeps its two lines. */
	.hrd-chapter__details:not(.hrd-chapter__details--row) { grid-template-areas: "d"; align-items: end; }
	.hrd-chapter__details:not(.hrd-chapter__details--row) li { grid-area: d; opacity: calc(clamp(0, var(--r) * 3 - 1, 1) * (1 - clamp(0, var(--next) * 3, 1))); }
	.hrd-chapter--induction .hrd-chapter__details--a li:nth-child(1) { opacity: calc(clamp(0, var(--r) * 3 - 1, 1) * (1 - clamp(0, var(--next) * 3, 1)) * (1 - clamp(0, (var(--p) - 0.3561) / 0.0129, 1))); }
	/* the label hands its spot to the link when the link arrives */
	.hrd-chapter__links { bottom: auto; top: calc(clamp(16px, 2.2vw, 32px) + 70px); left: clamp(24px, 6vw, 112px); right: auto; }
	/* sequential, never overlapping: label fully out, then link in */
	.hrd-chapter__label { opacity: calc(var(--d1) * (1 - clamp(0, var(--cta) * 2.5, 1))); }
	.hrd-chapter__links { opacity: calc(clamp(0, (var(--cta) - 0.45) / 0.55, 1) * (1 - var(--out))); }
	/* the landing on a phone: the strut stands in the upper half (the mobile set), HRD's line under it, the copy
	   full width at the foot */
	.hrd-landing__title { top: 61%; font-size: 13.2vw; }
	.hrd-landing__col { right: 24px; width: auto; bottom: calc(clamp(16px, 2.2vw, 32px) + 64px); }
	/* 01: the part sits above 0.54 in the mobile set; the caption under it, the curve under that */
	.hrd-chapter--dampers .hrd-chapter__products { inset: 0; left: 0; top: 0; }
	.hrd-chapter--dampers .hrd-chapter__caption { top: 55svh; }
	.hrd-chapter--dampers { --cap: max(calc(var(--d1) * (1 - clamp(0, (var(--p) - 0.0825) / 0.009, 1))), calc(clamp(0, (var(--p) - 0.8617) / 0.0125, 1) * (1 - var(--out)))); } /* phones: the rear's caption would sit on the curve */
	/* tags fit beside their part, flipped or not: tighter tracking, two lines where one won't fit (every chapter:
	   a one-line "Custom Molded O-Rings" or "7000-Series Alloy Vacuum Block" ran off a 390 px stage) */
	.hrd-callout b { letter-spacing: 0.07em; white-space: normal; width: max-content; max-width: 11em; line-height: 1.25; } /* 11em: "Custom Molded / O-Rings" in two, not three */
	/* the label shows over the strut standing, then gives the top band to the close-ups' tags (the top hat, the
	   pillowball, the spring and the spanners climbing through it: 0.11-0.38), back for the curve, and out for the
	   capstone ({TOP SECRET} DAMPERS stands in its band) */
	.hrd-chapter--dampers { --lbl: calc(1 - clamp(0, (var(--p) - 0.104) / 0.008, 1) + clamp(0, (var(--p) - 0.380) / 0.008, 1) * (1 - clamp(0, (var(--p) - 0.692) / 0.008, 1))); }
	.hrd-chapter--dampers .hrd-chapter__label { opacity: calc(var(--d1) * var(--lbl) * (1 - clamp(0, var(--cta) * 2.5, 1))); }
	/* the veil starts with the crane: the strut fills the lower half under 01-02 as the camera climbs */
	.hrd-chapter--dampers { --veil: calc(clamp(0, (var(--p) - 0.0788) / 0.0113, 1) * (1 - clamp(0, (var(--p) - 0.384) / 0.0105, 1))); }
	/* the capstone on a phone: a wider band (its "Classified" fits), the line in three, above the details */
	.hrd-chapter--dampers { --bw: 30vw; }
	.hrd-chapter__tsword { top: 30%; font-size: 19vw; }
	/* the links come in at the top, where "{TOP" stands: the line steps out first, as the label does */
	.hrd-chapter__tsword { opacity: calc((1 - var(--out)) * (1 - clamp(0, var(--cta) * 2.5, 1))); }
	.hrd-chapter__tsword span:first-child { white-space: normal; width: min-content; }
	/* the curve's axis labels on separate rows, clear of the plate's base (the plate is small on a phone), and
	   the force label ending short of the tall end (here it stands right against the spring) */
	.hrd-plotlab--lo b { transform: translate(-6%, 45%); } /* its anchor sits near the screen's left edge */
	.hrd-plotlab--hi b { transform: translate(-50%, 165%); }
	.hrd-plotlab--x b { transform: translateY(240%); }
	.hrd-plotlab--y b { transform: translate(-16px, -100%); }
	/* the pillowball's two tags: the collar's drops down-right, under the ball's */
	.hrd-chapter--dampers .hrd-callout--collar i::after { transform: rotate(55deg); top: 7px; }
	.hrd-chapter--dampers .hrd-callout--collar b { top: 34px; }
	/* phones: the details sit at the bottom, so the veil rises from it */
	.hrd-chapter__veil { background: linear-gradient(0deg, var(--c-bg) 0, var(--c-bg) 40svh, rgb(245 245 247 / 0) 56svh); }
	.hrd-chapter--induction .hrd-chapter__products { inset: 0; left: 0; top: 0; }
	/* the quick connect stands at the label's height while the booster's and the boost reference's tags show
	   (0.207-0.274): the label steps aside for them */
	.hrd-chapter--induction { --tagi: calc(clamp(0, (var(--p) - 0.2027) / 0.0097, 1) * (1 - clamp(0, (var(--p) - 0.2737) / 0.012, 1))); }
	.hrd-chapter--induction .hrd-chapter__label { opacity: calc(var(--d1) * (1 - var(--wht)) * (1 - var(--tagi)) * (1 - clamp(0, var(--cta) * 2.5, 1))); }
	/* phones: every part (and the gasket) sits above 0.52 in the mobile set; the caption under it,
	   stepping aside while the sensors' own names are up; the thermal note under the caption */
	.hrd-chapter--induction .hrd-chapter__caption { top: 54svh; }
	.hrd-chapter--induction .hrd-cap-b { opacity: calc(var(--cb) * (1 - var(--kc))); }
	.hrd-thermal__note { right: auto; left: 50%; bottom: auto; top: calc(54svh + 48px); transform: translateX(-50%); white-space: nowrap; }
	.hrd-chapter--induction .hrd-chapter__finish { bottom: auto; transform: none; } /* the two caption lines together (the phone rule's offset, as Drivetrain) */
	/* the count waits for the L15 to settle in the frame (the macro's zoom-out fills the top) */
	.hrd-chapter--induction { --stat: clamp(0, (var(--p) - 0.64) / 0.06, 1); }
	.hrd-stat { opacity: calc(clamp(0, var(--stat) * 6, 1) * (1 - clamp(0, (var(--p) - 0.765) / 0.015, 1))); } /* the sensors lift out through its band */
	/* the sensors' names fall across the word's band: it steps back while they're up */
	.hrd-chapter--induction .hrd-chapter__word { opacity: calc(1 - 0.88 * var(--kc)); }
	/* the quick connect sits at the frame's top: its tag drops down-right, clear of the label */
	.hrd-chapter--induction .hrd-callout--boost i::after { transform: rotate(55deg); top: 7px; }
	.hrd-chapter--induction .hrd-callout--boost b { top: 34px; }
	.hrd-chapter--drivetrain .hrd-chapter__products { inset: 0; left: 0; top: 0; --f: calc(var(--swap) * 140%); }
	/* the bushing's tag would ride its anchor through the copy (the mobile set holds it at 0.54-1.09 of the height
	   while it shows): detail 04 names it, "Dual Duty Bushings" */
	.hrd-chapter--drivetrain .hrd-callout--bush { display: none; }
	/* the GR Corolla rises through the caption's line until ~frame 243 in the mobile set: its name waits for it */
	.hrd-chapter--drivetrain { --cap2: clamp(0, (var(--p) - 0.725) / 0.025, 1); }
	.hrd-chapter--shifting .hrd-chapter__products { inset: 0; left: 0; top: 0; }
	.hrd-chapter--shifting .hrd-chapter__caption { top: 54svh; } /* the part sits above 0.52 in the mobile set */
	/* phones: the CYL's callouts fill the top half (0.32-0.46), so the label and the
	   caption step aside for them; the label hands its spot to the link at the end */
	.hrd-chapter--shifting { --tags: clamp(0, (var(--p) - 0.318) / 0.012, 1) * (1 - clamp(0, (var(--p) - 0.456) / 0.012, 1)); } /* back once the last tag (the ring's, 0.456) is out */
	/* and from the spherical bushing's close-up on (its tags fill the top band, 0.69-0.846), the links take the
	   label's spot after it */
	.hrd-chapter--shifting .hrd-chapter__label { opacity: calc(var(--d1) * var(--lab) * (1 - var(--tags)) * (1 - clamp(0, (var(--p) - 0.682) / 0.008, 1)) * (1 - clamp(0, var(--cta) * 2.5, 1))); }
	.hrd-chapter--shifting .hrd-chapter__caption { opacity: calc(max(calc(var(--cap1) * (1 - var(--dive))), calc(var(--cap2) * (1 - var(--out)))) * (1 - var(--tags))); }
	/* tags: tighter tracking, and a flipped tag drops down-left, the empty side of
	   the "\" stack (up-left would run along it) */
	.hrd-chapter--shifting .hrd-callout { --sides: fixed; } /* sequence.js: a flipped tag here also drops (below), so it never trades sides */
	/* "7000-Series Alloy Billet" (it was "7075-T6 Billet") leaves 0.006 earlier: as the CYL comes back together its
	   anchor runs right, and at a 375 stage the fading tag's end met the screen's edge (p 0.450) */
	.hrd-chapter--shifting .hrd-callout--body { --o: calc(clamp(0, (var(--p) - 0.338) / 0.012, 1) * (1 - clamp(0, (var(--p) - 0.436) / 0.012, 1))); }
	.hrd-chapter--shifting .hrd-callout b { white-space: nowrap; width: auto; max-width: none; } /* the "\" stack's five tags fit in one line each, and two-line tags stack into each other there */
	.hrd-chapter--shifting .hrd-callout[data-flip] i::after { transform: rotate(-55deg); top: 7px; }
	.hrd-chapter--shifting .hrd-callout[data-flip] b { top: 34px; }
	.hrd-chapter--drivetrain .hrd-chapter__swap-edge { --f: calc(var(--swap) * 140%); }
	.hrd-chapter__scrim { background: linear-gradient(0deg, rgb(4 1 29 / 0.92) 0, rgb(4 1 29 / 0.75) 34svh, rgb(4 1 29 / 0) 56svh); }
	/* caption under the part (mobile frames keep it in the top half) */
	.hrd-chapter__caption { top: 47svh; right: auto; left: 50%; transform: translateX(-50%); text-align: center; }
	.hrd-chapter__caption p span { right: auto; left: 50%; transform: translateX(-50%); }
	.hrd-chapter--drivetrain .hrd-chapter__finish { bottom: auto; transform: none; }
	.hrd-chapter__finish { left: 50%; top: auto; bottom: -26px; margin: 0; transform: translateX(-50%); text-align: center; }
	.hrd-chapter__finish span { left: 50%; transform: translateX(-50%); }
	.hrd-chapter--induction .hrd-chapter__word { top: 46%; font-size: 22vw; }
	/* "1000%+" and its two-line note inside the margins at any phone width (at 3.3rem the note met the edge) */
	.hrd-stat { gap: 12px; }
	.hrd-stat__n { font-size: clamp(2.4rem, (100vw - 196px) / 4.2, 3.3rem); }
	/* the NPT's line in two ("Universal / 1/8th NPT"): in one it ran into the L15's name beside it */
	.hrd-knobcap[data-anchor="c_npt"] span { white-space: normal; width: 8em; left: -4em; line-height: 1.3; }
	.hrd-chapter--induction .hrd-knobcap span { letter-spacing: 0.07em; } /* the part numbers clear each other at 360 */
	.hrd-who__dd { font-size: 9.6vw; } /* "IT'S THE STANDARD." fits 390 between the margins */
	.hrd-who__answer p { font-size: 1.4rem; line-height: 1.1; }
	/* 05 in their words (phones): the part rides the upper half; its review hangs
	   below it on a leader down-left and a shelf to the margin, full width */
	.hrd-who { --mw: 90vw; --mtop: 10svh; }
	.hrd-review { --ly: calc(var(--lead) * 0.8192); --drop: max(0px, calc(var(--ly) + var(--dh))); --lx: calc(var(--drop) * 0.7002); } /* the leader's drop (to the held row) and run */
	.hrd-review__lead { width: calc(var(--drop) / 0.8192); transform: rotate(125deg); }
	.hrd-review__shelf { top: var(--drop); left: calc(24px - var(--ax, 0px)); width: max(0px, calc(var(--ax, 0px) - var(--lx) - 24px)); }
	.hrd-review__text { left: calc(24px - var(--ax, 0px)); top: calc(var(--drop) + 18px); width: calc(100vw - 48px); font-size: 1.15rem; }
	/* the trio's rear mount stands top-left, above the other two: its words would run across them, so its leader
	   drops straight down past them (the mobile set: anchor at 0.29 of the height, the trio's foot at ~0.44) */
	.hrd-review[data-anchor="rear"] { --lead: 133px; --ly: 133px; --lx: 0px; }
	.hrd-review[data-anchor="rear"] .hrd-review__lead { width: var(--drop); transform: rotate(90deg); }
	.hrd-review__text p { line-height: 1.16; }
	.hrd-who__count { left: 0; right: 0; justify-content: center; top: calc(var(--mtop) + var(--mw) / 1.916 + 14px); }
	.hrd-who__film-cap { left: 24px; right: 24px; text-align: left; }
	.hrd-who__film-cap { bottom: calc(clamp(16px, 2.2vw, 32px) + 96px); }
	.hrd-who__bookend { font-size: 12.5vw; }
	/* 06 on a phone: the body hangs under the label, clear of the folio (centred, its title rose through the
	   label and its note ran under the folio on a 660 px stage); Year and Make share a row */
	.hrd-fit__body { top: calc(clamp(16px, 2.2vw, 32px) + 72px + 40px); transform: none; }
	.hrd-fit__title { font-size: 9vw; margin-bottom: 22px; } /* two lines: "Dual Duty starts / with the right fit." */
	.hrd-fit__form { grid-template-columns: 1fr 1fr; gap: 16px 18px; }
	.hrd-fit__field { gap: 6px; }
	.hrd-fit__field--model,
	.hrd-fit__go { grid-column: 1 / -1; }
	.hrd-fit__note { margin-top: 16px; }
	/* a short stage (an iPhone SE's ~550 px): the button beside the model */
	@media (max-height: 600px) {
		.hrd-fit__body { top: calc(clamp(16px, 2.2vw, 32px) + 72px + 30px); }
		.hrd-fit__title { margin-bottom: 18px; }
		.hrd-fit__field--model,
		.hrd-fit__go { grid-column: auto; }
		.hrd-fit__note { margin-top: 12px; }
	}
	.hrd-chapter__details--row { grid-template-columns: 1fr; gap: 10px; }
	.hrd-chapter__details--row li > span:last-child { display: none; } /* titles only on phones */
}

/* Landscape phones: separate the landing's title, manifesto and Play control,
   and keep the raised title clear of the viewfinder's corner arrows. */
@media (orientation: landscape) and (max-height: 450px) {
	.hrd-chapter .hrd-callout[data-float] b { left: var(--tag-x); right: auto; top: var(--tag-y); }
	.hrd-chapter .hrd-callout[data-float] i::after { left: 4px; right: auto; top: 4px; width: var(--leader-length); transform-origin: 0 50%; transform: rotate(var(--leader-angle)); }
	.hrd-chapter .hrd-callout[data-muted-leader] i::after { visibility: hidden; }
	.hrd-chapter .hrd-callout[data-muted-ring] i { border-color: transparent; }
	.hrd-landing__title { top: 39%; font-size: min(12.5vw, 20svh); }
	.hrd-landing__col { bottom: calc(clamp(16px, 2.2vw, 32px) + 24px); }
	.hrd-landing__title,
	.hrd-landing__col { left: max(48px, clamp(24px, 6vw, 112px)); }
}

/* Short landscape stages have room beside the art, not for stacked details.
   Keep one existing detail at a time and place chapter chrome in the top band. */
@media (orientation: landscape) and (max-height: 450px) {
	.hrd-chapter__label { top: 44px; left: 48px; }
	.hrd-chapter .hrd-chapter__caption { top: 44px; left: auto; right: 48px; transform: none; text-align: right; }
	.hrd-chapter .hrd-chapter__caption p span { left: auto; right: 0; transform: none; }
	.hrd-chapter__details { left: 48px; right: auto; bottom: 48px; width: min(42vw, 360px); gap: 10px; }
	.hrd-chapter__details:not(.hrd-chapter__details--row) { grid-template-areas: "d"; align-items: end; }
	.hrd-chapter__details:not(.hrd-chapter__details--row) li { grid-area: d; opacity: calc(clamp(0, var(--r) * 3 - 1, 1) * (1 - clamp(0, var(--next) * 3, 1))); }
	.hrd-chapter--induction .hrd-chapter__details--a li:nth-child(1) { opacity: calc(clamp(0, var(--r) * 3 - 1, 1) * (1 - clamp(0, var(--next) * 3, 1)) * (1 - clamp(0, (var(--p) - 0.3561) / 0.0129, 1))); }
	.hrd-chapter__details li { padding-top: 8px; }
	.hrd-chapter__details strong { font-size: 20px; }
	.hrd-chapter__details li > span:last-child { font-size: 13px; line-height: 1.3; }
	.hrd-chapter__links { top: 44px; bottom: auto; left: 48px; right: auto; }
	.hrd-who__dd { font-size: min(8vw, 15svh); }
	.hrd-fit__body { top: 80px; left: 48px; right: 48px; transform: none; }
	.hrd-fit__title { font-size: min(6vw, 11svh); margin-bottom: 16px; }
	.hrd-fit__form { grid-template-columns: repeat(3, minmax(0, 1fr)) auto; gap: 12px; }
	.hrd-fit__field { gap: 6px; min-width: 0; }
	.hrd-fit__field--model, .hrd-fit__go { grid-column: auto; }
	.hrd-fit__field select { font-size: 16px; min-height: 44px; }
	.hrd-fit__note { margin-top: 12px; font-size: 13px; }
}

@media (orientation: landscape) and (max-height: 450px) {
	.hrd-chapter--shifting .hrd-chapter__details--row { top: 86px; bottom: auto; grid-template-columns: 1fr; grid-template-areas: "d"; width: min(36vw, 280px); }
	.hrd-chapter__details--row li { grid-area: d; opacity: calc(clamp(0, var(--r) * 3 - 1, 1) * (1 - clamp(0, var(--next) * 3, 1))); }
	.hrd-chapter__details--row li:nth-child(1) { --next: var(--d2) !important; }
	.hrd-chapter__details--row li:nth-child(2) { --next: 0; }
	.hrd-chapter__details--row li > span:last-child { display: none; }
	.hrd-chapter__caption { font-size: 9px; }
	.hrd-chapter--dampers .hrd-chapter__label, .hrd-chapter--induction .hrd-chapter__label { gap: 8px !important; }
	.hrd-who__film-cap { bottom: 36px; }
	.hrd-thermal__note { left: auto; right: 48px; top: auto; bottom: 38px; transform: none; }
	.hrd-chapter--induction .hrd-knobcap { margin-top: -42px; }
	.hrd-plotlab--lo b { left: auto; right: calc(var(--ax) - 100vw + 48px); transform: translateY(-10%); }
	.hrd-plotlab b { font-size: 11px; }
	.hrd-plotlab--hi b { top: -12px; }
}

@media (orientation: landscape) and (max-height: 450px) and (max-width: 767px) {
	.hrd-chapter .hrd-chapter__caption { top: 66px; }
	.hrd-review__text { font-size: 16px; left: calc(48px - var(--ax, 0px)); width: calc(100vw - 96px); top: calc(clamp(110px, calc(var(--hy) + var(--lead)), 160px) - var(--ay)); }
	.hrd-review cite { margin-top: 8px; }
	.hrd-who__count { top: auto; bottom: 54px; }
}

/* ---------- Reduced motion: show the settled storyboard ---------- */
@media (prefers-reduced-motion: reduce) {
	[data-hrd-play] { display: none !important; } /* no film mode */
	.hrd-scene { height: auto; }
	.hrd-stage { position: relative; }
	.hrd-story > .hrd-scene.hrd-who { margin-top: 0 !important; }
	.hrd-story-ready .hrd-who > .hrd-stage { visibility: visible; }
	/* Settled chapter: everything in, no wipe */
	.hrd-chapter { --swap: 0; --redact: 0; --out: 0; --wipe: 0; }
	.hrd-chapter--induction { --swap: 1; } /* settled on act II (the harness): ELECTRONICS */
	.hrd-chapter--dampers { --swap: 1; --redact: 1; --band: 1; } /* settled on the Top Secret (track c), declassified */
	/* the landing settles as its own first screen above it (the h1, the line, its own frame-0 poster: the canvas
	   settles on the Top Secret): 01's stage moves down a screen; overflow-x: clip keeps the drifted word from
	   scrolling sideways while the landing shows above the stage */
	.hrd-chapter--dampers .hrd-stage { overflow-x: clip; overflow-y: visible; margin-top: 100vh !important; margin-top: 100svh !important; }
	.hrd-landing { inset: auto 0 100% 0; height: 100vh; height: 100svh; clip-path: none; }
	.hrd-landing__poster { display: block; position: absolute; inset: 0; }
	.hrd-landing__poster img { width: 100%; height: 100%; object-fit: cover; }
	.hrd-landing__copy { clip-path: none; transform: translateY(-100vh); transform: translateY(-100svh); }
	.hrd-landing__edge { display: none; }
	.hrd-word-edge, .hrd-thermal__edge { display: none; }
}

/* Only shown after an unrecoverable media failure; navigation remains available. */
.hrd-story-notice { position: absolute; left: var(--vf-inset); bottom: calc(var(--vf-inset) + 40px); max-width: min(400px, calc(100vw - 2 * var(--vf-inset))); margin: 0; padding: 10px 14px; background: var(--wp--preset--color--paper); color: var(--wp--preset--color--ink); border: 1px solid currentColor; font-size: 14px; line-height: 1.4; }
