/* GENERATED by tools/b2web/sync_v4.py from dev/bioreactor-hero (shared/hero.css + v4/index.html's inline style).
   Do not edit here: edit the dev files, then re-sync. Loaded after css/style.css and ../css/polish.css (the
   order V4 was built and judged in), before ../css/wiki-align.css. */
/* ==== from dev/bioreactor-hero/shared/hero.css ==== */
/* Bioreactor hero prototypes (dev only).
   The house story styles, taken from hardware/photometer/css/style.css's story block (7 Oct 2026), so the three
   versions read exactly like the photometer and LPA heroes: Oxanium title, mono kicker "01 —— ROLE", body in the
   system sans, act rail on the right, scrim under the captions, the 16vh fade into the record.
   Accent: the bioreactor page's own blue (#5aa9ff); loop colours are the page's lumen orange and shell green.
   Loaded after ../../hardware/bioreactor/css/style.css and ../../hardware/css/polish.css. */
@font-face {
  font-family: "Oxanium Title";
  src: url("../../fonts/oxanium-600-latin.woff") format("woff");
  font-weight: 600; font-style: normal; font-display: block;
  unicode-range: U+0020-007E, U+00B7, U+2013-2014, U+2018-2019, U+201C-201D, U+2026;
}

.story { --accent: #5aa9ff; --lumen: #ffa040; --shell: #3ff0a0; --koh: #a9c9ff; position: relative; z-index: 3; }

.story .story-stage {
  position: sticky; top: 0; height: 100svh; min-height: 520px; overflow: hidden;
  background: radial-gradient(120% 90% at 50% 8%, rgba(120, 140, 170, .05), transparent 60%), var(--bg);
}
.story #gl { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* title */
.story .story-title {
  position: absolute; left: clamp(1.4rem, 9vw, 7.5rem); top: 37%; transform: translateY(-50%);
  text-align: left; z-index: 4; pointer-events: none; width: min(86vw, 28rem);
}
.story .story-title .eyebrow {
  font-family: var(--mono); font-size: .62rem; letter-spacing: .42em; text-transform: uppercase;
  color: var(--accent); margin-bottom: 1.1rem;
}
.story .story-title .line {
  margin: 0; font-family: "Oxanium Title", var(--sans); font-weight: 600; letter-spacing: -.02em; line-height: 1.02;
  font-size: clamp(2.1rem, 6.2vw, 4.4rem); text-shadow: 0 0 64px rgba(0, 0, 0, .85); color: var(--fg);
}
.story .title-rule { display: flex; align-items: center; gap: .8rem; justify-content: flex-start; margin-top: 1.3rem; }
.story .title-rule i { height: 1px; width: clamp(1.6rem, 5vw, 3rem); background: linear-gradient(90deg, var(--accent), transparent); }
.story .title-rule i:last-child { display: none; }
.story .title-rule span { font-family: var(--mono); font-size: .58rem; letter-spacing: .34em; text-transform: uppercase; color: var(--accent); }

/* captions */
.story .hud {
  position: absolute; left: clamp(1.1rem, 4vw, 4.2rem); bottom: clamp(1.6rem, 7vh, 5rem);
  width: min(30rem, 44vw); z-index: 5; pointer-events: none;
}
.story .cap { position: absolute; left: 0; bottom: 0; width: 100%; opacity: 0; visibility: hidden; will-change: opacity, transform; }
.story .cap-tag {
  display: flex; align-items: center; gap: .7rem; font-family: var(--mono); font-size: .6rem; letter-spacing: .26em;
  text-transform: uppercase; color: var(--accent); margin-bottom: .75rem;
}
.story .cap-tag i { height: 1px; width: 1.9rem; background: var(--accent); opacity: .6; display: block; }
.story .cap-name {
  font-family: "Oxanium Title", var(--sans); font-weight: 600; font-size: clamp(1.35rem, 2.5vw, 2.05rem);
  letter-spacing: -.015em; line-height: 1.1; color: var(--fg);
}
.story .cap-rule { height: 1px; width: 3.4rem; background: var(--line); margin: .85rem 0 .8rem; }
.story .cap p { margin: 0; max-width: 34ch; font-size: clamp(.86rem, 1.05vw, .98rem); line-height: 1.62; color: #c3cbd6; text-wrap: pretty; }
.story .cap p b, .story .cap p strong { color: var(--fg); font-weight: 600; }
.story .cap p em { color: var(--accent); font-style: normal; }
.story .cap p .lu { color: var(--lumen); }
.story .cap p .sh { color: var(--shell); }

/* act rail */
.story .rail {
  position: absolute; right: clamp(.9rem, 2.2vw, 2.2rem); top: 50%; transform: translateY(-50%);
  display: flex; flex-direction: column; gap: .62rem; z-index: 5; pointer-events: none;
}
.story .rail i { display: block; width: 14px; height: 2px; background: rgba(255, 255, 255, .16); transition: background .35s var(--ease), width .35s var(--ease); }
.story .rail i.on { background: var(--accent); width: 24px; }

/* loader, cue */
.story .loader {
  position: absolute; inset: 0; display: grid; place-items: center; z-index: 8; background: var(--bg); color: var(--faint);
  font-family: var(--mono); font-size: .62rem; letter-spacing: .3em; text-transform: uppercase; transition: opacity .7s var(--ease);
}
.story .loader.gone { opacity: 0; pointer-events: none; }
.story .scroll-cue {
  position: absolute; left: 50%; bottom: 2.1rem; transform: translateX(-50%); display: flex; flex-direction: column;
  align-items: center; gap: .55rem; font-family: var(--mono); font-size: .56rem; letter-spacing: .38em;
  text-transform: uppercase; color: var(--faint); z-index: 5; pointer-events: none;
}
.story .scroll-cue i { display: block; width: 1px; height: 34px; background: linear-gradient(180deg, var(--faint), transparent); }

/* scrim under the captions */
.story .scrim {
  position: absolute; left: 0; bottom: 0; width: min(30rem, 52vw); height: 62%; z-index: 4; pointer-events: none;
  background: linear-gradient(to right, rgba(3,4,7,.86) 0%, rgba(3,4,7,.64) 48%, rgba(3,4,7,0) 92%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 34%); mask-image: linear-gradient(to bottom, transparent 0%, #000 34%);
}

/* the opening's right-hand column */
.story .title-stats {
  position: absolute; right: clamp(1.4rem, 7vw, 6rem); top: 37%; transform: translateY(-50%); z-index: 4;
  pointer-events: none; list-style: none; margin: 0; padding: 0; text-align: right; opacity: 0; visibility: hidden;
}
.story .title-stats li { margin: 0 0 1.45rem; }
.story .title-stats li:last-child { margin-bottom: 0; }
.story .title-stats b { font-family: var(--mono); font-weight: 600; font-size: clamp(1.1rem, 2.1vw, 1.6rem); color: #eef3f8; letter-spacing: .01em; }
.story .title-stats span { font-family: var(--mono); font-size: .62rem; color: var(--faint); margin-left: .3rem; }
.story .title-stats i { display: block; font-style: normal; font-family: var(--mono); font-size: 11px; letter-spacing: .26em; text-transform: uppercase; color: #8b95a3; margin-top: .3rem; }

/* the closing line */
.story .endline {
  position: absolute; left: clamp(1.1rem, 4vw, 4.2rem); top: 50%; transform: translateY(-50%); z-index: 5; opacity: 0;
  visibility: hidden; pointer-events: none; font-family: "Oxanium Title", var(--sans); font-weight: 600; color: var(--fg);
  font-size: clamp(1.5rem, 3.4vw, 2.6rem); letter-spacing: -.02em; line-height: 1.12; max-width: 22ch; text-shadow: 0 0 50px rgba(0,0,0,.9);
}
.story .endline em { color: var(--accent); font-style: normal; }
.story .endline { max-width: 18em; }

/* the key: what is CAD and what is drawn. Plain mono text, no box. */
.story .b2-key {
  position: absolute; left: clamp(1.1rem, 4vw, 4.2rem); bottom: clamp(1rem, 2.6vh, 1.8rem); z-index: 6; pointer-events: none;
  width: min(25rem, 40vw); text-align: left; font-family: var(--mono); font-size: 11px; line-height: 1.55; letter-spacing: .03em;
  color: #9aa4b1; opacity: 0; visibility: hidden;
}
.story .b2-key b { color: #9aa4b1; font-weight: 500; }

/* landing chrome */
.story .hero-frame { position: absolute; inset: 0; z-index: 4; pointer-events: none; opacity: 0; visibility: hidden; }
.story .hero-frame i { position: absolute; width: 30px; height: 30px; border: 1px solid var(--accent); opacity: .62; }
.story .hero-frame i.hf-tl { left: 26px; top: 92px; border-right: 0; border-bottom: 0; }
.story .hero-frame i.hf-tr { right: 26px; top: 92px; border-left: 0; border-bottom: 0; }
.story .hero-frame i.hf-bl { left: 26px; bottom: 26px; border-right: 0; border-top: 0; }
.story .hero-frame i.hf-br { right: 26px; bottom: 26px; border-left: 0; border-top: 0; }
.story .hero-scan {
  position: absolute; left: 0; right: 0; height: 26vh; top: -30vh;
  background: linear-gradient(to bottom, transparent 0%, color-mix(in srgb, var(--accent) 12%, transparent) 50%, transparent 100%);
  animation: heroScan 9s linear infinite;
}
@keyframes heroScan { 0% { transform: translateY(0); opacity: 0; } 12% { opacity: 1; } 88% { opacity: 1; } 100% { transform: translateY(150vh); opacity: 0; } }

/* the 16vh fade into the record */
.story .story-stage::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: clamp(120px, 16vh, 215px); pointer-events: none; z-index: 4;
  background: linear-gradient(to bottom, rgba(5,6,10,0) 0%, rgba(5,6,10,.30) 42%, rgba(5,6,10,.74) 74%, rgb(5,6,10) 100%);
}

/* in-scene marks placed from 3D anchors each frame (thin rules and mono text; never boxed) */
.story .marks { position: absolute; inset: 0; z-index: 5; pointer-events: none; }
.story .mk {
  position: absolute; left: 0; top: 0; opacity: 0; visibility: hidden; white-space: nowrap; will-change: transform, opacity;
  font-family: var(--mono); font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: #d3dae2;
}
.story .mk b { color: var(--accent); font-weight: 600; margin-right: .55em; letter-spacing: .1em; text-transform: none; }
/* units stay as typed: uppercasing turns the micro sign into a Greek capital Mu, which reads "MM" */
.story .mk .u { text-transform: none; letter-spacing: .08em; }
.story .mk::before { content: ""; position: absolute; top: 50%; height: 1px; width: 26px; background: rgba(255,255,255,.32); }
.story .mk.l::before { right: calc(100% + 8px); }
.story .mk.r { transform-origin: right center; }
.story .mk.r::before { left: calc(100% + 8px); }
.story .mk.n::before { display: none; }

@media (max-width: 860px) {
  .story .hud { width: auto; right: clamp(1.1rem, 4vw, 2rem); bottom: 1.4rem; }
  .story .cap p { max-width: none; font-size: .9rem; }
  .story .cap-name { font-size: 1.3rem; }
  .story .rail { display: none; }
}
@media (max-width: 760px) {
  .story .title-stats { display: none; }
  .story .hero-frame i { width: 18px; height: 18px; }
  .story .hero-frame i.hf-tl, .story .hero-frame i.hf-tr { top: 84px; }
  .story .hero-frame i.hf-bl, .story .hero-frame i.hf-br { bottom: 14px; }
  .story .hero-frame i.hf-tl, .story .hero-frame i.hf-bl { left: 14px; }
  .story .hero-frame i.hf-tr, .story .hero-frame i.hf-br { right: 14px; }
  .story .b2-key { left: 1.1rem; right: 1.1rem; width: auto; max-width: none; text-align: left; font-size: 11px; }
  .story .mk { font-size: 11px; letter-spacing: .14em; }
}
@media (max-width: 760px) and (max-aspect-ratio: 4/5) {
  .story .story-title { top: 61%; }
  .story .b2-key { bottom: 1.2rem; }
  /* the key takes the cue's place on a phone: both at the foot of a 390 px frame collided */
  .story .scroll-cue { display: none; }
  .story .endline { top: auto; bottom: 22%; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .story .cap, .story .story-title { transition: none !important; }
  .story .hero-scan { animation: none; opacity: 0; }
}

/* the record's first lines under the story, so the seam can be judged */
.doc-wrap { --blend-h: clamp(170px, 20vh, 300px); --blend-glow: rgba(90, 169, 255, .12); border-top: 0; padding-top: var(--blend-h); position: relative; }
.story-blend {
  position: absolute; left: 0; right: 0; top: 0; height: var(--blend-h); pointer-events: none; z-index: 0;
  background: radial-gradient(120% 74% at 50% 64%, var(--blend-glow) 0%, transparent 58%),
    linear-gradient(to bottom, rgb(5,6,10) 0%, rgba(5,6,10,.90) 26%, rgba(5,6,10,.58) 50%, rgba(5,6,10,.24) 74%, rgba(5,6,10,0) 100%);
}





/* dev-only switcher */




/* round 1: no frosted band over the story (polish.css's topbar blur read as a hard-edged strip over the model) */
body.hero-pinned .topbar { backdrop-filter: none; -webkit-backdrop-filter: none;
  background: linear-gradient(to bottom, rgba(5,6,10,.55) 0%, rgba(5,6,10,0) 100%); }

/* round 2: the scroll cue sat on the case's base; it now hangs under the title column */
@media (min-width: 761px) {
  .story .scroll-cue { left: clamp(1.4rem, 9vw, 7.5rem); bottom: auto; top: 58%; transform: none; align-items: flex-start; }
}
.story .mk.w b { color: #fff; }

/* marks with a leader to their part (round 3): the rule's length is set per frame */
.story .mk.lead { font-size: 12px; }
.story .mk.lead::before { width: var(--lw, 26px); right: calc(100% + 6px); background: rgba(255,255,255,.28); }
.story .endline em.sh { color: var(--shell); }
.story .mk.w::before { background: rgba(255,255,255,.62); width: 30px; }

/* ==== from dev/bioreactor-hero/v4/index.html, inline <style> 1 ==== */
/* V4 only. Shared hero.css stays as V1-V3 use it. Polish pass (9-10 Oct): every piece of text on one system, the
   labelled rack sheet's (dev/lab-bioreactor/rack-model/renders/rack-a-front-labelled.png): a mono kicker in the loop's
   colour, a name in the site sans or Oxanium, a short role; hairlines with a dark halo; 11 px floor everywhere. */
/* 3400vh (was 2900): rule 7's re-timing gives the camera's remaining motion an even share of the scroll; +17 % keeps the
   stations' dwells near their old length (3250 until the c3 back view and the crane over the top came back, 23:00) */
.story { height: 3400vh; --ink: #f3f6f9; --ink2: #c9d1db; --mute: #93a0af; --halo: 0 1px 2px rgba(0,0,0,.9), 0 0 14px rgba(0,0,0,.75), 0 0 30px rgba(0,0,0,.5); }
.story .scroll-cue::after { display: none; }

/* ---- captions: kicker "01 —— GROWS IT" in the loop's colour, Oxanium name, a short fading hairline, the body */
.story .hud { left: clamp(1.3rem, 4.6vw, 4.8rem); bottom: clamp(1.9rem, 8vh, 5.4rem); width: min(31rem, 44vw); }
.story .cap-tag { font-size: 11px; letter-spacing: .3em; color: var(--lumen); gap: .7rem; margin-bottom: .8rem; font-weight: 500; }
.story .cap-tag b { color: var(--ink); font-weight: 600; letter-spacing: .12em; }
.story .cap-tag i { width: 1.7rem; background: currentColor; opacity: .5; }
.story .cap.g .cap-tag { color: var(--shell); }
.story .cap-name { font-size: clamp(1.6rem, 2.7vw, 2.3rem); letter-spacing: -.014em; line-height: 1.06; }
.story .cap-rule { width: 2.8rem; height: 1px; margin: .85rem 0 .8rem; background: linear-gradient(90deg, rgba(255,255,255,.6), rgba(255,255,255,0)); }
.story .cap p { font-size: clamp(.98rem, 1.12vw, 1.06rem); line-height: 1.55; color: var(--ink2); max-width: 31ch; }
.story .cap-name, .story .cap p, .story .cap-tag { text-shadow: var(--halo); }
.story .scrim { width: min(36rem, 58vw); height: 66%;
  background: linear-gradient(to right, rgba(3,4,7,.84) 0%, rgba(3,4,7,.6) 46%, rgba(3,4,7,0) 94%); }

/* ---- the title card */
.story .story-title .eyebrow { font-size: 11px; letter-spacing: .42em; }
.story .story-title .line { font-size: clamp(2.3rem, 6.4vw, 4.7rem); letter-spacing: -.024em; }
.story .title-rule span { font-size: 11px; letter-spacing: .32em; }
.story .title-rule i { width: clamp(1.8rem, 5vw, 3.2rem); }
/* the stats: kicker above the number (the rack sheet's kicker + name), hairline between, tabular numerals */
.story .title-stats li { margin: 0 0 1.05rem; padding-top: .75rem; min-width: 10.5rem; border-top: 1px solid rgba(255,255,255,.11); }
.story .title-stats li:first-child { border-top-color: rgba(90,169,255,.45); }
.story .title-stats i { margin: 0 0 .38rem; font-size: 11px; letter-spacing: .24em; color: var(--mute); }
.story .title-stats b { display: block; font-size: clamp(1.3rem, 2.25vw, 1.8rem); color: #eef3f8; font-variant-numeric: tabular-nums; letter-spacing: 0; line-height: 1.1; }
.story .title-stats b span { font-size: 12px; font-weight: 500; color: var(--mute); margin-left: .4rem; letter-spacing: .04em; }
.story .title-stats b, .story .title-stats i, .story .story-title { text-shadow: var(--halo); }

/* ---- the end line sits in the title's column, clear of the case (the last frame mirrors the first) */
@media (min-width: 761px) {
  .story .endline { left: clamp(1.4rem, 9vw, 7.5rem); top: 37%; max-width: min(17em, 34vw); font-size: clamp(1.5rem, 2.6vw, 2.25rem); }
}
.story .endline { text-shadow: var(--halo); }
@media (max-width: 760px) { .story .endline br.d { display: none; } }

/* ---- labels in the scene (scene.js: initLabels / labelLayout / applyLabels). Leaders and anchors are svg. */
.story .marks { position: absolute; inset: 0; z-index: 5; pointer-events: none; }
.story svg.leaders { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.story .ld { visibility: hidden; opacity: 0; }
.story .ld .h { fill: none; stroke: rgba(3,5,9,.7); stroke-width: 3.6; stroke-linecap: round; stroke-linejoin: round; }
.story .ld .l { fill: none; stroke: rgba(238,242,247,.88); stroke-width: 1; stroke-linejoin: round; }
.story .ld .rh { fill: rgba(3,5,9,.4); stroke: rgba(3,5,9,.72); stroke-width: 3.4; }
.story .ld .r { fill: none; stroke: #f3f6f9; stroke-width: 1.3; }
.story .ld .d { fill: #fff; }
.story .ld .cv { fill: none; stroke: #f3f6f9; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; opacity: 0; }
.story .ld.a .r, .story .ld.a .cv { stroke: #ffcf98; } .story .ld.a .d { fill: #ffb25a; }
.story .ld.g .r, .story .ld.g .cv { stroke: #a8f6d2; } .story .ld.g .d { fill: #4ff0a8; }
.story .lb { position: absolute; left: 0; top: 0; visibility: hidden; opacity: 0; white-space: nowrap; will-change: transform, opacity; text-shadow: var(--halo); }
/* a soft dark pool behind each label, so it reads on the bright wall too */
.story .lb::before { content: ""; position: absolute; inset: -16px -26px; z-index: -1; pointer-events: none;
  background: radial-gradient(closest-side, rgba(3,5,9,.62), rgba(3,5,9,.35) 55%, rgba(3,5,9,0)); }
.story .lb .k { display: block; font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: .22em; text-transform: uppercase; color: #a9b4c2; margin-bottom: 4px; }
.story .lb .n { display: block; font-family: var(--sans); font-weight: 600; font-size: 17px; line-height: 1.15; letter-spacing: -.006em; color: var(--ink); }
.story .lb .r { display: block; font-family: var(--sans); font-size: 13px; line-height: 1.3; color: #b6c0cb; margin-top: 3px; }
.story .lb.a .k { color: #ffae5c; } .story .lb.g .k { color: var(--shell); }
.story .lb.w .n { font-family: var(--mono); letter-spacing: .02em; }
.story .lb.rt { text-align: right; }
@media (max-width: 760px) { .story .lb .n { font-size: 15px; } .story .lb .r { font-size: 12px; } }

/* ---- the route (ROUTE_UI): ringed stops on a hairline, the visited stretch amber, a dot for the parcel */
.story .route { position: absolute; right: clamp(1.1rem, 2.4vw, 2.4rem); top: 50%; transform: translateY(-50%); z-index: 5; pointer-events: none;
  opacity: 0; visibility: hidden; font-family: var(--mono); }
.story .route::before { content: ""; position: absolute; right: -40px; top: -40px; bottom: -40px; width: 200px; z-index: -1;
  background: radial-gradient(ellipse at right center, rgba(3,4,7,.82), rgba(3,4,7,.5) 45%, rgba(3,4,7,0) 72%); }
.story .route .rt-k { font-size: 11px; letter-spacing: .28em; text-transform: uppercase; color: rgba(150,162,178,.8); text-align: right; padding-right: 28px; margin-bottom: 1.15rem; }
.story .route ol { list-style: none; margin: 0; padding: 0; }
.story .route li { position: relative; padding-right: 28px; text-align: right; font-size: 11px; letter-spacing: .22em; text-transform: uppercase; line-height: 1;
  color: rgba(214,222,232,.58); margin: 0 0 1.1rem; text-shadow: 0 1px 2px rgba(0,0,0,.95), 0 0 10px rgba(0,0,0,.8); }
.story .route li:last-child { margin-bottom: 0; }
.story .route li::after { content: ""; position: absolute; right: 5px; top: 50%; width: 7px; height: 7px; margin-top: -4.7px; border-radius: 50%;
  border: 1.2px solid rgba(214,222,232,.42); background: #06080c; }
.story .route li.done { color: rgba(255,182,112,.82); }
.story .route li.done::after { border-color: #ffa040; background: #ffa040; }
.story .route li.on { color: #fff; }
.story .route li.on::after { border-color: #fff; background: #06080c; box-shadow: 0 0 0 3px rgba(255,160,64,.22); }
.story .route.g li.out.on::after { box-shadow: 0 0 0 3px rgba(63,240,160,.25); }
.story .route .rl, .story .route .rf { position: absolute; right: 9.2px; width: 1px; z-index: -1; top: 0; }
.story .route .rl { background: rgba(255,255,255,.14); }
.story .route .rf { width: 1.4px; right: 9px; background: linear-gradient(to bottom, rgba(255,160,64,.35), #ffa040); }
.story .route .rd { position: absolute; right: 5.4px; top: 0; width: 8.6px; height: 8.6px; margin-top: -4.3px; border-radius: 50%; background: #ffb056;
  box-shadow: 0 0 0 2px rgba(6,8,12,.9), 0 0 12px rgba(255,154,46,.95); }
.story .route.g .rd { background: var(--shell); box-shadow: 0 0 0 2px rgba(6,8,12,.9), 0 0 12px rgba(46,240,154,.9); }
/* round 4b (visual 8, r4 15): no route list (the owner dislikes key boxes): the phone's one line under the top bar, on
   desk too, in the captions' column */
.story .route { display: none; }
.story .route-m { display: block; position: absolute; left: clamp(1.3rem, 4.6vw, 4.8rem); width: min(26rem, 40vw); top: 74px; z-index: 5; pointer-events: none; opacity: 0; visibility: hidden;
  font-family: var(--mono); font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: rgba(214,222,232,.62); text-shadow: 0 1px 2px rgba(0,0,0,.9); }
.story .route-m b { color: #fff; font-weight: 600; }
.story .route-m em { font-style: normal; color: #ffae5c; margin: 0 .55em 0 1.1em; }
.story .route-m.g em { color: var(--shell); }
.story .route-m i { display: block; height: 2px; margin-top: 8px; position: relative;
  background: linear-gradient(90deg, rgba(255,255,255,.4) 1.5px, transparent 1.5px) 0 0 / 20% 100% repeat-x, rgba(255,255,255,.1); }
.story .route-m i s { position: absolute; left: 0; top: 0; bottom: 0; background: #ffa040; box-shadow: 0 0 8px rgba(255,160,64,.7); }
.story .route-m.g i s { background: linear-gradient(90deg, #ffa040 80%, var(--shell) 80%); }
@media (max-width: 860px) {
  .story .route-m { left: 1.1rem; right: 1.1rem; width: auto; top: 66px; }
}

/* ---- the honesty key (round 4b, visual 9 / QA 7 / r4 14): one quiet 11 px line at ~55 % ink, no swatches, no box,
   shown only at the end (scene.js KEY_END_ONLY) */
.story .b2-key { width: min(34rem, 52vw); font-size: 11px; line-height: 1.6; color: rgba(214,222,232,.55); text-shadow: 0 1px 2px rgba(0,0,0,.9); }
.story .b2-key p { margin: 0; }

/* phone: the captions' top line keeps the house 11 px floor and a full-width scrim */
@media (max-width: 860px) {
  .story .hud { left: 1.15rem; right: 1.15rem; width: auto; bottom: 1.5rem; }
  .story .cap-name { font-size: 1.42rem; }
  .story .cap p { font-size: .95rem; max-width: none; }
}
@media (max-width: 760px) {
  .story .scrim { width: 100%; height: 44%; background: linear-gradient(to top, rgba(3,4,7,.92), rgba(3,4,7,.7) 52%, transparent); -webkit-mask-image: none; mask-image: none; }
  .story .story-title .eyebrow { color: #8cc4ff; }
  .story .b2-key { left: 1.15rem; right: 1.15rem; width: auto; }
}
@media (max-width: 760px) and (max-aspect-ratio: 4/5) {
  .story .scroll-cue { display: flex; left: 1.1rem; top: calc(61% + 7.2rem); bottom: auto; transform: none; align-items: flex-start; }
}
.story .scroll-cue span { font-size: 11px; }
/* owner, 10 Oct: at top 58% the cue crowded the title rule on shorter windows; it sits at the foot of the title column */
@media (min-width: 761px) {
  .story .scroll-cue { top: auto; bottom: clamp(1.6rem, 5vh, 2.8rem); }
}
.story .rail { display: none; }   /* the route replaces the act rail */
/* no CSS transitions on anything placed per p: a frame must be a pure function of p (captures, clips, scrubbing back) */
.story .route li, .story .route li::after, .story .lb, .story .ld { transition: none !important; }

/* ---- port only (tools/b2web/sync_v4.py; not in the dev page) -------------------------------------------------------
   D3 (PORT-PLAN 3.4): polish.css's full-screen .scanline sweep is not on the dev page V4 was judged on; it would sweep
   over the hero on top of V4's own .hero-scan, at a compositing cost every frame. Hidden while the stage is pinned
   (b2-core / js/hero.js toggle body.hero-pinned); the record keeps it. */
body.hero-pinned .scanline { opacity: 0; }
/* video mode (js/hero.js): the clip frame takes the canvas's place; the labels' layer stays above it */
.hero-video .story .hv-frame { z-index: 0; }
