/* ==========================================================================
   Interactive paper — the single stylesheet for index.html.
   A small base/typography layer at the top (palette vars + element resets),
   then the immersive design, mostly scoped under .paper.
   ========================================================================== */

:root {
	--purple: #75409C;
	--purple-bright: #b072e0;
	--purple-glow: rgba(160, 100, 230, 0.55);
	--blue: #28679E;
	--ink: #1d1d22;
	--muted: #6b6b76;
	--paper: #fdfdfd;
	--paper-2: #f5f1fa;
	--dark: #0b0b12;
	--dark-2: #12121d;
	--dark-card: #1a1a28;
	--dark-ink: #ecebf2;
	--dark-muted: #9a98ad;
	--ok: #4f8f6b;
	--fail: #c062c6;
	--maxread: 720px;
	--maxwide: 1100px;
	--fs-lead: clamp(1.08rem, 1rem + 0.4vw, 1.28rem);
	--fs-prose: clamp(1.02rem, 0.97rem + 0.3vw, 1.16rem);
	/* vertical rhythm — two roles only: a header/intro and the content it
	   directly introduces (coupled, --gap-head), and the break between two
	   independent blocks within an act (--gap-block). --act-pad is the band
	   top/bottom. Tune the whole site's vertical feel from these three knobs. */
	--act-pad: 96px;
	--gap-block: 64px;
	--gap-head: 48px;
}

/* ----- base typography (ported from the retired template style.css) ------
   These were the only style.css rules still affecting index.html; the rest
   styled the now-deleted static overview page. Kept verbatim so rendering is
   unchanged. The .paper rules below still override these where they differ. */
html {scroll-behavior: smooth;}
body {margin: 0; font-size: 1em;}
h1, h2, h3, h4, h5, a, p, span, body {font-weight: normal; font-family: "Inter", sans-serif;}
h2 {margin-top: 48px; font-weight: bold; color: #75409C;}
a {color: #75409C; text-decoration: none; transition: color 0.15s ease;}
a:hover {color: #9150BE;}
.bold {font-weight: bold;}
.italic {font-style: italic;}
.nobreak {white-space: nowrap;}
.figure-caption {margin: 24px auto; max-width: 100%; font-size: 0.92em; line-height: 1.6; font-style: italic; text-align: left;}
.figure-caption .bold {font-style: normal;}
.bibtexsection {padding: 4px 16px; font-family: "Courier", monospace; font-size: 15px;
	white-space: pre-wrap; word-break: break-word; background-color: #f4f4f4; text-align: left; overflow-x: auto;}
a.btn {display: inline-block; min-width: 70px; background-color: rgb(36, 36, 36); color: white;
	padding: 9px 20px; font-size: 1.05em; font-weight: 500; border-radius: 32px;
	box-shadow: 0 1px 2px rgba(0,0,0,0.06), 0 2px 6px rgba(0,0,0,0.08);
	transition: background-color 0.15s ease, box-shadow 0.15s ease;}
a.btn:hover {background-color: rgb(20, 20, 20); box-shadow: 0 2px 4px rgba(0,0,0,0.08), 0 6px 14px rgba(0,0,0,0.12);}
.hf-ic {width: 1em; height: 1em; fill: currentColor; vertical-align: -0.125em; display: inline-block;}
.hero-cta .hf-ic {width: 1.12em; height: 1.12em; vertical-align: -0.17em;}
.hero-cta .fa-github {font-size: 1.12em;}

/* ----- reset / base overrides ------------------------------------------- */
.paper {color: var(--ink); overflow-x: hidden;}
.paper p {text-align: left; line-height: 1.7;}
.paper h1, .paper h2, .paper h3, .paper h4 {text-align: left;}
body.paper-body {background-color: var(--paper);}

.wrap {max-width: var(--maxread); margin: 0 auto; padding: 0 24px;}
.wrap-wide {max-width: var(--maxwide); margin: 0 auto; padding: 0 24px;}

/* ----- top progress bar --------------------------------------------------- */
.progress {position: fixed; top: 0; left: 0; height: 3px; width: 0%;
	background: linear-gradient(90deg, var(--blue), var(--purple-bright));
	z-index: 200; transition: width 0.08s linear; box-shadow: 0 0 10px var(--purple-glow);}

/* ----- floating top link -------------------------------------------------- */
.topbar {position: fixed; top: 0; left: 0; right: 0; z-index: 150;
	display: flex; justify-content: space-between; align-items: center;
	padding: 14px 24px; pointer-events: none;
	font-size: 0.9em; transition: background 0.3s ease, backdrop-filter 0.3s ease;}
.topbar a {pointer-events: auto; color: var(--dark-ink); opacity: 0.85; transition: opacity 0.2s, color 0.2s;}
.topbar a:hover {opacity: 1; color: var(--purple-bright);}
.topbar.solid {background: rgba(10,10,18,0.62); backdrop-filter: blur(10px) saturate(1.2);
	box-shadow: 0 1px 0 rgba(255,255,255,0.06);}
.topbar .topbar-title {font-weight: 600; letter-spacing: -0.01em; color: rgba(255,255,255,0.92);
	opacity: 0; transition: opacity 0.3s ease;}

/* ----- section dot nav ---------------------------------------------------- */
.dotnav {position: fixed; right: 18px; top: 50%; transform: translateY(-50%);
	z-index: 140; display: flex; flex-direction: column; gap: 16px;}
.dotnav a {position: relative; width: 14px; height: 14px;}
/* the dot lives on ::before so hover scales only the dot, not the label span */
.dotnav a::before {content: ''; position: absolute; inset: 0; border-radius: 50%;
	background: rgba(120,120,140,0.6); transition: background 0.2s, transform 0.2s ease;}
/* light dots on the dark full-bleed sections so the rail stays legible throughout */
.dotnav a.on-dark:not(.active)::before {background: rgba(255,255,255,0.55);}
.dotnav a:hover::before {transform: scale(1.25);}
.dotnav a.active::before {background: var(--purple); box-shadow: 0 0 8px var(--purple-glow);}
.dotnav a span {position: absolute; right: 24px; top: 50%; transform: translateY(-50%) translateX(6px);
	white-space: nowrap; font-size: 0.78em; color: rgba(255,255,255,0.92);
	/* glass label, matching the sticky header (.topbar.solid) — far softer than an
	   opaque white pill over the dark full-bleed sections */
	background: rgba(10,10,18,0.62); backdrop-filter: blur(10px) saturate(1.2);
	border: 1px solid rgba(255,255,255,0.12);
	padding: 3px 9px; border-radius: 6px; box-shadow: 0 2px 10px rgba(0,0,0,0.28);
	opacity: 0; pointer-events: none; transition: opacity 0.18s, transform 0.18s;}
/* labeled rail: the current section's label stays visible at rest so the rail
   reads as navigation; hovering anywhere on it reveals all labels (full TOC). */
.dotnav a.active span, .dotnav:hover a span {opacity: 1; transform: translateY(-50%) translateX(0);}

/* ==========================================================================
   HERO  (full-bleed dark cinematic)
   ========================================================================== */
.hero {position: relative; height: 100vh; height: 100svh; background: var(--dark);
	display: flex; flex-direction: column; justify-content: flex-start; align-items: center;
	text-align: center; overflow: hidden; padding: 17vh 20px 90px;}
.hero-mosaic {position: absolute; inset: 0; display: grid;
	grid-template-columns: repeat(4, 1fr); grid-auto-rows: 1fr; gap: 6px; opacity: 0.5;
	filter: saturate(1.12);}
.hero-mosaic video {width: 100%; height: 100%; object-fit: cover; display: block;}
.hero-veil {position: absolute; inset: 0; z-index: 1;
	background:
		radial-gradient(ellipse 72% 62% at 50% 42%, rgba(11,11,18,0.42) 0%, rgba(11,11,18,0.74) 55%, rgba(11,11,18,0.9) 100%),
		radial-gradient(ellipse 60% 50% at 50% 18%, var(--purple-glow) 0%, transparent 60%);}
.hero-content {position: relative; z-index: 2; max-width: 880px; color: var(--dark-ink);}
.hero .eyebrow {display: inline-flex; align-items: center; gap: 8px;
	font-size: 0.82em; letter-spacing: 0.16em; text-transform: uppercase;
	color: var(--purple-bright); margin-bottom: 22px; font-weight: 600;}
.hero h1 {text-align: center; color: #fff; font-weight: 700;
	font-size: clamp(2rem, 1.2rem + 2.7vw, 3.2rem); line-height: 1.12; letter-spacing: -0.025em;
	margin: 0 0 28px; text-wrap: balance; text-shadow: 0 2px 28px rgba(0,0,0,0.55);}
.hero h1 .accent {background: linear-gradient(90deg, var(--purple-bright), #d9b3ff);
	-webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;}
.hero .hero-authors {color: var(--dark-muted); font-size: 1.2em; margin-bottom: 10px;}
.hero .hero-authors a {color: var(--dark-ink);}
.hero .hero-authors a:hover {color: var(--purple-bright);}
.hero .hero-affil {color: var(--dark-muted); font-size: 1.02em; margin-bottom: 42px;}
.hero-cta {display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-bottom: 12px;}
.hero-cta a.btn {box-shadow: 0 2px 14px rgba(0,0,0,0.35);}
.hero-cta a.btn.ghost {background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.25);
	color: var(--dark-ink); backdrop-filter: blur(4px);}
.hero-cta a.btn.ghost:hover {background: rgba(255,255,255,0.16);}
.scrollcue {position: fixed; bottom: 26px; left: 50%; transform: translateX(-50%); z-index: 120;
	color: var(--dark-muted); font-size: 0.78em; letter-spacing: 0.12em; text-transform: uppercase;
	display: flex; flex-direction: column; align-items: center; gap: 8px;
	pointer-events: none; transition: opacity 0.4s ease;}
.scrollcue.cue-hide {opacity: 0;}
.scrollcue .chev {width: 18px; height: 18px; border-right: 2px solid var(--purple-bright);
	border-bottom: 2px solid var(--purple-bright); transform: rotate(45deg);
	animation: bob 1.8s ease-in-out infinite;}
@keyframes bob {0%,100% {transform: rotate(45deg) translate(0,0); opacity: 0.4;}
	50% {transform: rotate(45deg) translate(3px,3px); opacity: 1;}}

/* ==========================================================================
   ACT / SECTION SYSTEM
   ========================================================================== */
.act {position: relative; padding: var(--act-pad) 0;}
/* vertical rhythm utilities (see token block): .flow separates independent
   blocks; .flow--tight couples an intro/header to the content it introduces. */
.flow {margin-top: var(--gap-block);}
.flow--tight {margin-top: var(--gap-head);}
.act--light {background: var(--paper); color: var(--ink);}
.act--tint {background: linear-gradient(180deg, #faf7fd 0%, #f4eefb 100%);}
.act--dark {background: var(--dark); color: var(--dark-ink);}
.act--dark h2, .act--dark h3 {color: #fff;}
.act--dark p {color: #cfcdda;}
.act h2 {font-size: clamp(1.55rem, 1.1rem + 1.65vw, 2.4rem); line-height: 1.12;
	letter-spacing: -0.02em; font-weight: 700; margin: 0 0 22px; text-wrap: balance;}
.act .lead {font-size: var(--fs-lead); line-height: 1.6; color: var(--ink);}
.act--dark .lead {color: #d7d5e2;}
.prose {font-size: var(--fs-prose);}
.prose p {margin: 0 0 20px;}
.prose p + p {margin-top: -4px;}

.pullquote {font-size: clamp(1.3rem, 1rem + 1.4vw, 2rem); line-height: 1.3; font-weight: 600;
	letter-spacing: -0.015em; max-width: 820px; margin: 0 auto; text-align: center; text-wrap: balance;}
.pullquote .accent {color: var(--purple-bright);}

/* ----- reveal animation --------------------------------------------------- */
.reveal {opacity: 0; transform: translateY(26px); transition: opacity 0.7s cubic-bezier(.2,.7,.3,1), transform 0.7s cubic-bezier(.2,.7,.3,1);}
.reveal.is-visible {opacity: 1; transform: none;}
.reveal.d1 {transition-delay: 0.08s;} .reveal.d2 {transition-delay: 0.16s;}
.reveal.d3 {transition-delay: 0.24s;} .reveal.d4 {transition-delay: 0.32s;}

/* ==========================================================================
   STAT COUNTERS
   ========================================================================== */
.counters {display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; margin: 44px 0 8px;}
.counter {position: relative; text-align: center; padding: 30px 16px 24px; border-radius: 18px;
	background: linear-gradient(180deg, rgba(255,255,255,0.85), rgba(117,64,156,0.05));
	border: 1px solid rgba(117,64,156,0.14);
	box-shadow: 0 6px 22px rgba(117,64,156,0.06), inset 0 1px 0 rgba(255,255,255,0.6);
	overflow: hidden;}
.act--dark .counter {background: linear-gradient(180deg, rgba(255,255,255,0.06), rgba(255,255,255,0.02));
	border-color: rgba(255,255,255,0.09); box-shadow: 0 6px 22px rgba(0,0,0,0.18);}
/* gradient accent strip that wipes in along the top edge */
.counter::before {content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
	background: linear-gradient(90deg, var(--blue), var(--purple-bright));
	transform: scaleX(0); transform-origin: left;
	transition: transform 1.31s cubic-bezier(.2,.8,.25,1);}
.counters.is-visible .counter::before {transform: scaleX(1);}
.counter .num {font-size: clamp(2rem, 1.3rem + 1.9vw, 3.05rem); font-weight: 700; line-height: 1;
	letter-spacing: -0.025em; color: var(--purple);
	background: linear-gradient(135deg, var(--purple) 0%, #9a5fd6 50%, var(--blue) 100%);
	-webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;}
.act--dark .counter .num {color: var(--purple-bright);
	background: linear-gradient(135deg, var(--purple-bright) 0%, #c79bf0 55%, #5b9fd6 100%);
	-webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;}
.counter .lbl {font-size: 0.72em; color: var(--muted); margin-top: 11px; letter-spacing: 0.09em;
	text-transform: uppercase; font-weight: 600;}
.act--dark .counter .lbl {color: var(--dark-muted);}

/* staggered pop-in when the row first scrolls into view (keyed off the
   container's .is-visible from the shared reveal observer). The container
   itself opts out of the generic .reveal block-motion so only the cards move. */
.counters.reveal {opacity: 1; transform: none; transition: none;}
.counters .counter {opacity: 0;}
.counters.is-visible .counter {opacity: 1;
	animation: counterPop 1.18s cubic-bezier(.22,.9,.28,1) backwards;}
.counters.is-visible .counter:nth-child(1) {animation-delay: 0.08s;}
.counters.is-visible .counter:nth-child(2) {animation-delay: 0.24s;}
.counters.is-visible .counter:nth-child(3) {animation-delay: 0.43s;}
.counters.is-visible .counter:nth-child(4) {animation-delay: 0.59s;}
@keyframes counterPop {
	from {opacity: 0; transform: translateY(26px) scale(0.95);}
	60%  {opacity: 1;}
	to   {opacity: 1; transform: none;}
}

/* ==========================================================================
   TASK MOSAIC (full-bleed video band)
   ========================================================================== */
.bleed {width: 100%;}
.band-note {text-align: center; font-size: 0.92em; color: var(--dark-muted); font-style: italic;
	margin-top: 18px;}

/* ----- task belt: a rotating, draggable conveyor of WM rollouts ----------- */
.taskbelt {position: relative; overflow: hidden; cursor: grab; touch-action: pan-y;
	display: flex; flex-direction: column; gap: 12px;
	-webkit-user-select: none; user-select: none;
	-webkit-mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
	mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);}
.taskbelt.grabbing {cursor: grabbing;}
.taskbelt:focus-visible {outline: 2px solid var(--purple-bright); outline-offset: -2px;}
.belt-row {position: relative; height: 138px; flex: none;}
.belt-tile {position: absolute; top: 0; left: 0; height: 138px; width: 138px; border-radius: 8px;
	box-sizing: border-box; overflow: hidden; will-change: transform; background: #11111a;
	box-shadow: 0 6px 18px rgba(0,0,0,0.4); border: 1px solid rgba(255,255,255,0.06);}
.belt-tile video {width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none;}
.belt-cap {position: absolute; left: 0; right: 0; bottom: 0; padding: 16px 8px 7px;
	display: flex; flex-direction: column; gap: 2px; pointer-events: none;
	background: linear-gradient(180deg, transparent, rgba(8,8,14,0.86));
	opacity: 0; transform: translateY(4px); transition: opacity 0.18s ease, transform 0.18s ease;}
.belt-tile:hover .belt-cap {opacity: 1; transform: none;}
.belt-cap b {font-size: 0.72em; font-weight: 600; color: #fff; letter-spacing: 0.01em; line-height: 1.1;}
.belt-cap i {font-size: 0.6em; font-style: normal; font-weight: 600; letter-spacing: 0.04em;
	text-transform: uppercase; color: var(--dc, #b072e0);}
/* Inline cue pointing at an interaction (drag / hover). Bright purple + upright, even inside the italic captions it sits in. */
.hint {color: var(--purple-bright); font-weight: 600; font-style: normal; white-space: nowrap;}
/* soft glow pulse so every hint (arrow or not) reads as interactive in the small caption type */
@media (prefers-reduced-motion: no-preference) {
	.hint {animation: hintGlow 2.6s ease-in-out infinite;}
}
@keyframes hintGlow {0%, 100% {text-shadow: 0 0 0 transparent;} 50% {text-shadow: 0 0 9px var(--purple-glow);}}
.hint--inset {display: inline-block; margin-left: 8px;}  /* trailing hint, set off from the end of a sentence */
/* the ↔ arrow sways gently so the small-print drag cue catches the eye */
.hint-arrow {display: inline-block;}
@media (prefers-reduced-motion: no-preference) {
	.hint-arrow {animation: hintNudge 2.6s ease-in-out infinite;}
}
@keyframes hintNudge {0%, 100% {transform: translateX(-2px);} 50% {transform: translateX(2px);}}

/* ==========================================================================
   PIPELINE DIAGRAM (shared between Act 3 intro and Act 4 sticky)
   ========================================================================== */
.pipeline {width: 100%; max-width: 580px; margin: 0 auto;}
.pipeline svg {width: 100%; height: auto; display: block; overflow: visible;}
.stage-box {transition: filter 0.45s ease, opacity 0.45s ease;}
.stage-box rect {transition: fill 0.45s ease, stroke 0.45s ease;}
.stage-box text {transition: fill 0.45s ease;}
.pipeline.dimmable .stage-box {opacity: 0.34;}
.pipeline.dimmable .stage-box.is-active {opacity: 1; animation: stageGlow 4.4s ease-in-out infinite;}
.pipeline .stage-box rect {fill: rgba(255,255,255,0.05); stroke: rgba(255,255,255,0.22); stroke-width: 1.5;}
.pipeline .stage-box text {fill: #d4d2e0; font-family: "Inter", sans-serif;}
.pipeline .stage-box .stage-sub {fill: #8a899c; font-size: 10px;}
.pipeline.dimmable .stage-box.is-active rect {fill: rgba(117,64,156,0.34); stroke: var(--purple-bright);}
.pipeline.dimmable .stage-box.is-active text {fill: #fff;}
.pipeline.dimmable .stage-box.is-active .stage-sub {fill: #d9b3ff;}
.pipeline .flow-lbl {fill: var(--purple-bright); font-family: "Inter", sans-serif; font-style: italic;}
.pipeline .pipe-arrow {stroke: rgba(176,114,224,0.5); stroke-width: 1.6; fill: none;
	stroke-dasharray: 5 4; animation: pipeflow 0.8s linear infinite;}
/* gentle "live pipeline": data flows along the arrows; the responsible stage breathes */
@keyframes pipeflow {to {stroke-dashoffset: -9;}}
@keyframes stageGlow {0%, 100% {filter: drop-shadow(0 0 4px rgba(160,100,230,0.35));}
	50% {filter: drop-shadow(0 0 24px rgba(160,100,230,0.85));}}
.pipeline.dimmable .stage-box.is-active rect {animation: stageRect 4.4s ease-in-out infinite;}
@keyframes stageRect {0%, 100% {fill: rgba(117,64,156,0.24);} 50% {fill: rgba(117,64,156,0.58);}}

/* ==========================================================================
   SCROLLY ENGINE (sticky viz + bare .step spacers) — now reused only by the
   Act-3 world-model diagram below. (Originally built for an Act-4 scrolly-
   telling layout that was replaced by the three-modes triptych; the carded
   .step-card/.step-idx/.step-roman/.step h3/p styling went with it.)
   ========================================================================== */
.scrolly {position: relative; display: grid; grid-template-columns: 1fr 0.92fr; gap: 40px; align-items: start;}
.scrolly__viz {position: sticky; top: 0; height: 100vh; display: flex; flex-direction: column;
	justify-content: center; gap: 22px;}
.scrolly__steps {padding: 30vh 0;}
.step {min-height: 78vh; display: flex; flex-direction: column; justify-content: center;}

/* ==========================================================================
   WORLD-MODEL DIAGRAM (Act 3) — horizontal paper-style schematic:
   frame → Encoder → z → Dynamics(+action) → ẑ → Decoder → frame′, solid
   blocks + arrows. A text card below swaps with the active stage and is tied
   to its block by a callout line. Reuses the .scrolly engine: bare .step
   spacers drive the active stage; blocks / callouts / caps share data-stage-id.
   ========================================================================== */
.scrolly--arch {display: block;}                 /* full-width figure, not the 2-col layout */
/* Negative margin pulls the (invisible) step spacers up over the lower part of
   the 100vh sticky viz, so the first stage detent is reached ~18vh after the
   diagram pins instead of ~68vh — trims the dead scroll when entering from above
   without moving the centered diagram. No-op on mobile (steps are display:none). */
.scrolly--arch .scrolly__steps {padding: 4vh 0 8vh; margin-top: -50vh;}
.scrolly--arch .step {min-height: 28vh;}         /* short steps; a trailing dec step holds the end */

/* Stage detents: native scroll-snap makes each stage click into the viewport
   center, so you land on a stage instead of hunting for the right scroll amount.
   `proximity` (not `mandatory`) + no `scroll-snap-stop` keeps the rest of the
   page — and the smooth anchor nav that scrolls *through* this act — completely
   free; a fast flick can still skip a stage but always settles cleanly on one.
   Only Act-3 steps are snap targets, so snapping engages only inside this act.
   The trailing dec step gets no detent, acting as release runway out of the act.
   Off under reduced-motion (everything shows statically) and absent on mobile
   (the steps are display:none there). */
@media (prefers-reduced-motion: no-preference) {
	html {scroll-snap-type: y proximity;}
	.scrolly--arch .step:not(:last-child) {scroll-snap-align: center;}
}

.wmd {position: relative; width: 100%; margin: 0 auto; padding-top: 70px;}  /* full width; top room for keys */
.wmd svg {width: 100%; height: auto; display: block; overflow: visible;}

/* action input: animated key-press cluster above the dynamics block */
.wmd-keys {position: absolute; top: 0; left: 50%; transform: translateX(-50%);
	display: flex; flex-direction: column; align-items: center; gap: 5px;}
.wmd-keys-lbl {font-size: 0.66em; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--purple);}
.wmd-keygrid {display: grid; grid-template-columns: repeat(3, 26px); grid-template-rows: repeat(2, 22px);
	gap: 4px; justify-items: center; align-items: center;}
.wmd-key {display: flex; align-items: center; justify-content: center; width: 24px; height: 20px;
	border-radius: 6px; font-size: 12px; line-height: 1; color: var(--purple); background: #fff;
	border: 1px solid rgba(117,64,156,0.35); border-bottom-width: 2px; transform: translateY(-1px);
	animation: wmdKey 3s ease-in-out infinite;}
.wmd-key--up    {grid-column: 2; grid-row: 1; animation-delay: 1.65s;}
.wmd-key--left  {grid-column: 1; grid-row: 2; animation-delay: 0s;}
.wmd-key--down  {grid-column: 2; grid-row: 2; animation-delay: 0.55s;}
.wmd-key--right {grid-column: 3; grid-row: 2; animation-delay: 1.1s;}
@keyframes wmdKey {
	0%, 14%, 100% {transform: translateY(-1px); background: #fff; color: var(--purple);
		border-bottom-width: 2px; box-shadow: none;}
	4%, 10% {transform: translateY(1px); background: var(--purple); color: #fff;
		border-bottom-width: 1px; box-shadow: 0 0 10px var(--purple-glow);}
}

/* looping video frames (input observation / rendered output) */
.wmd-frame-vid {width: 100%; height: 100%; object-fit: cover; border-radius: 8px; display: block; background: #000;}
.wmd-frame-bd {fill: none; stroke: rgba(117,64,156,0.40); stroke-width: 1.5;}

/* solid component blocks; the active one breathes a soft glow */
.wmd-blk rect {fill: #efe7f8; stroke: rgba(117,64,156,0.38); stroke-width: 1.5;
	transition: fill 0.4s ease, stroke 0.4s ease, filter 0.4s ease;}
.wmd-blk text {fill: var(--ink); font-family: "Inter", sans-serif; transition: fill 0.4s ease;}
.wmd-blk .wmd-sub {fill: var(--muted); font-size: 9px;}
.wmd-blk.is-active rect {fill: var(--purple); stroke: var(--purple-bright);
	animation: wmdGlow 2.4s ease-in-out infinite;}
.wmd-blk.is-active text {fill: #fff;}
.wmd-blk.is-active .wmd-sub {fill: #ecd9fb;}
@keyframes wmdGlow {
	0%, 100% {filter: drop-shadow(0 4px 10px rgba(117,64,156,0.30));}
	50%      {filter: drop-shadow(0 5px 22px rgba(160,100,230,0.62));}
}

/* data-flow arrows: continuously marching dashes toward the arrowhead */
.wmd-arrow {stroke: rgba(117,64,156,0.5); stroke-width: 1.6; fill: none;
	stroke-dasharray: 5 4; animation: wmdFlow 0.8s linear infinite;}
@keyframes wmdFlow {to {stroke-dashoffset: -9;}}
.wmd-flowlbl {fill: var(--purple); font-family: "Inter", sans-serif; font-style: italic;}
.wmd-cap-lbl {fill: var(--muted); font-family: "Inter", sans-serif;}

/* action arrow: solid, with a pulse riding down it in time with the key taps */
.wmd-arrow--action {stroke-dasharray: none; animation: none;}
.wmd-action-pulse {fill: var(--purple-bright); opacity: 0;
	animation: wmdActionPulse 0.75s ease-in infinite;}
@keyframes wmdActionPulse {
	0%   {transform: translateY(0); opacity: 0;}
	18%  {opacity: 1;}
	82%  {opacity: 1;}
	100% {transform: translateY(22px); opacity: 0;}
}

/* callout: a vertical line that draws downward from the active block to its card */
.wmd-conn {stroke: var(--purple-bright); stroke-width: 1.5; fill: none;
	stroke-dasharray: 140; stroke-dashoffset: 140; opacity: 0;
	transition: stroke-dashoffset 0.5s ease, opacity 0.3s ease;}
.wmd-conn.is-active {opacity: 0.9; stroke-dashoffset: 0;}

/* text cards — each positioned directly beneath its block; only the active one shows */
.wmd-caps {position: relative; width: 100%; min-height: 150px; margin-top: 6px;}
.wmd-cap {position: absolute; top: 0; width: 340px; max-width: 78vw;
	text-align: left; background: #fff; border: 1px solid #ece4f4; border-radius: 12px;
	padding: 14px 18px; box-shadow: 0 10px 30px rgba(117,64,156,0.12);
	opacity: 0; transform: translate(-50%, 6px); transition: opacity 0.4s ease, transform 0.4s ease;}
.wmd-cap.is-active {opacity: 1; transform: translate(-50%, 0);}
.wmd-cap--enc {left: 23.33%;}     /* centered under the encoder block (x=168/720) */
.wmd-cap--dyn {left: 50%;}        /* under dynamics (x=360/720) */
.wmd-cap--dec {left: 76.67%;}     /* under decoder (x=552/720) */
.wmd-cap .wmd-cap-tag {font-size: 0.82em; font-weight: 700; text-transform: uppercase;
	letter-spacing: 0.08em; color: var(--purple); margin-bottom: 6px;}
.wmd-cap p {margin: 0; font-size: var(--fs-prose); line-height: 1.6; color: #55525f;}
.wmd-cap p .italic {color: var(--purple);}

/* mobile-only vertical reflow of the architecture diagram.
   The wide horizontal SVG above scales to fit width, so on phones its labels shrink to
   ~6px; below the breakpoint (set in the media query) we hide it and show this stacked
   flow instead. Hidden by default; the media query flips it on. */
.wmd-flow-m {display: none; flex-direction: column; align-items: center;
	width: 100%; max-width: 340px; margin: 0 auto;}
.wfm-frame {position: relative; width: 128px; height: 128px; border-radius: 12px; overflow: hidden;
	background: #000; border: 1.5px solid rgba(117,64,156,0.42);
	box-shadow: 0 6px 18px rgba(117,64,156,0.16);}
.wfm-frame .wmd-frame-vid {width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 0;}
.wfm-flabel {position: absolute; left: 8px; bottom: 6px; font-size: 0.66em; font-weight: 600;
	color: #fff; letter-spacing: 0.02em; text-shadow: 0 1px 3px rgba(0,0,0,0.75);}
.wfm-arrow {display: flex; align-items: center; gap: 5px; color: var(--purple);
	font-size: 0.82em; padding: 7px 0; line-height: 1;}
.wfm-z {font-style: italic; font-weight: 600; color: var(--purple-bright); font-size: 1.15em;}
.wfm-stage {position: relative; box-sizing: border-box; width: 100%; text-align: center;
	background: #efe7f8; border: 1.5px solid rgba(117,64,156,0.38); border-radius: 12px;
	padding: 12px 16px; box-shadow: 0 4px 14px rgba(117,64,156,0.10);}
.wfm-stage--dyn {border-color: rgba(117,64,156,0.6);
	box-shadow: 0 6px 20px rgba(117,64,156,0.18);}
.wfm-name {display: block; font-weight: 700; font-size: 1.04em; color: var(--ink); line-height: 1.2;}
.wfm-sub {display: block; font-size: 0.78em; color: var(--muted); margin-top: 3px;}
.wfm-action {display: inline-flex; align-items: center; gap: 8px; margin-bottom: 9px;
	padding: 4px 10px 4px 11px; border-radius: 999px; background: rgba(117,64,156,0.09);}
.wfm-action-lbl {font-size: 0.6em; font-weight: 700; text-transform: uppercase;
	letter-spacing: 0.11em; color: var(--purple);}
.wfm-keys {display: inline-flex; gap: 3px;}
.wfm-key {display: inline-flex; align-items: center; justify-content: center;
	width: 18px; height: 16px; border-radius: 4px; background: #fff;
	border: 1px solid rgba(117,64,156,0.32); color: var(--purple); font-size: 8px;}
@media (prefers-reduced-motion: no-preference) {
	.wfm-key {animation: wfmKey 3s ease-in-out infinite;}
	.wfm-key--up    {animation-delay: 1.65s;}
	.wfm-key--left  {animation-delay: 0s;}
	.wfm-key--down  {animation-delay: 0.55s;}
	.wfm-key--right {animation-delay: 1.1s;}
	@keyframes wfmKey {
		0%, 18%, 100% {background: #fff; color: var(--purple); border-color: rgba(117,64,156,0.32);}
		6%, 12% {background: var(--purple); color: #fff; border-color: var(--purple-bright);}
	}
}

/* Act 4 — three stacked "mode" subsections, each with its own stage-lit pipeline */
#hallucination .wrap-wide {margin-top: var(--gap-head);}  /* intro paragraph → triptych (coupled) */
.mode-block {max-width: var(--maxread); margin: 0 auto;}
.mode-block + .mode-block {margin-top: 48px; padding-top: 48px; border-top: 1px solid rgba(255,255,255,0.10);}
.mode-block__head {display: flex; align-items: center; gap: 14px; margin-bottom: 12px;}
.mode-num {flex: none; width: 36px; height: 36px; border-radius: 50%; display: inline-flex;
	align-items: center; justify-content: center; font-style: italic; font-weight: 700; font-size: 0.95em;
	color: var(--purple-bright); background: rgba(117,64,156,0.18); border: 1px solid var(--purple);}
.mode-block__titles {min-width: 0;}
.mode-block__head .stage-tag {display: block; font-size: 0.72em; letter-spacing: 0.08em;
	text-transform: uppercase; color: #b58fe0; font-weight: 600; margin-bottom: 2px;}
.mode-block__head h3 {font-size: 1.5em; margin: 0; color: #fff; line-height: 1.15;}
.mode-lead {color: #cfcdda; font-size: var(--fs-prose); line-height: 1.6; margin: 0; max-width: var(--maxread);}

/* mode figure panel — card-less, full width (matches the perceptual round-trip) */
.mode-figs {margin-top: 30px;}
.mode-figs .fig-label {text-align: center;}
.fig-row {display: flex; gap: 10px; align-items: stretch;}
.fig-cell {flex: 1; text-align: center;}
.fig-cell img, .fig-cell video {width: 100%; border-radius: 6px; display: block; background: #000;}
.fig-cell.perc .perc-frame {position: relative;}
.fig-cell.perc .perc-frame + .perc-frame {margin-top: 4px;}
.perc-tag {position: absolute; top: 5px; left: 5px; font-size: 0.6em; font-weight: 600;
	text-transform: uppercase; letter-spacing: 0.04em; color: #fff;
	background: rgba(10, 10, 16, 0.72); padding: 2px 6px; border-radius: 4px;}
.perc-tag.wm {color: #e9d4ff;}
.fig-caption {font-size: 0.92em; line-height: 1.4; margin-top: 8px; color: #bdbcca;}
.fig-caption.ok {color: #9fd8b9;}
.fig-caption.fail {color: #e3a6e8; font-weight: 500;}
.fig-verdict {display: inline-block; font-weight: 700; margin-right: 5px;}
.fig-verdict.ok {color: #6cc596;} .fig-verdict.fail {color: var(--fail);}
.fig-label {font-size: 0.7em; text-transform: uppercase; letter-spacing: 0.08em; color: #8a899c; margin-bottom: 6px;}

/* Act 4 step (ii) — action triptych: one task, three actions (real / zeroed / flipped)
   shown side by side so the effect of the action is directly comparable; tabs swap the
   task. Tabs and verdicts reuse the round-trip (.rt-tabs / .rt-verdict) vocabulary. */
.am-panel {margin-top: 30px;}
.am-panel .fig-label {text-align: center;}
.am-flow {display: flex; align-items: flex-start; justify-content: center; gap: 14px;}
.am-cell {flex: 1 1 0; min-width: 0; max-width: 200px; margin: 0;}
/* stacked rollouts: every variant is mounted; the active task's shows */
.am-stage {position: relative; border-radius: 8px; overflow: hidden; background: #000;
	box-shadow: 0 0 0 1.5px rgba(176,114,224,0.5); aspect-ratio: 1 / 1;}
.am-vid {position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
	display: block; opacity: 0; transition: opacity 0.22s ease;}
.am-vid.is-on {opacity: 1;}
.am-tag {position: absolute; top: 7px; left: 7px; z-index: 2; font-size: 0.62em; font-weight: 700;
	letter-spacing: 0.06em; text-transform: uppercase; color: #e9d4ff;
	background: rgba(10,10,16,0.66); backdrop-filter: blur(3px); padding: 2px 8px; border-radius: 999px;
	pointer-events: none;}
.am-cap {margin-top: 9px; text-align: center; line-height: 1.3;}
.am-cap b {display: block; color: #fff; font-size: 0.92em;}
.am-cap span {display: block; font-size: 0.72em; color: #8a899c; margin-top: 2px;}
/* schematic d-pad: which keys are "held" for this action (real = up+left, zeroed = none, flipped = down+right) */
.am-keys {display: grid; grid-template-columns: repeat(3, 18px); grid-template-rows: repeat(2, 16px);
	gap: 3px; justify-content: center; justify-items: center; align-items: center; margin-top: 9px;}
.am-key {display: flex; align-items: center; justify-content: center; width: 18px; height: 16px;
	border-radius: 5px; font-size: 9px; line-height: 1; color: #5f5d72;
	background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.1); border-bottom-width: 2px;}
.am-key.is-held {color: #fff; background: var(--purple);
	border-color: var(--purple-bright); box-shadow: 0 0 10px var(--purple-glow);}
.am-verdicts {margin-top: 20px;}
/* per-task column labels/keys: default (real/zeroed/flipped) vs the directional
   hold-left / none / hold-right framing used by the navigation + manipulation tasks */
.am-cell .is-dir {display: none;}
.am-panel[data-task="parena"] .am-cell .is-default,
.am-panel[data-task="pickplace"] .am-cell .is-default,
.am-panel[data-task="highway"] .am-cell .is-default {display: none;}
.am-panel[data-task="parena"] .am-cap.is-dir,
.am-panel[data-task="pickplace"] .am-cap.is-dir,
.am-panel[data-task="highway"] .am-cap.is-dir {display: block;}
.am-panel[data-task="parena"] .am-keys.is-dir,
.am-panel[data-task="pickplace"] .am-keys.is-dir,
.am-panel[data-task="highway"] .am-keys.is-dir {display: grid;}
.am-panel[data-task="parena"] .am-tag.is-dir,
.am-panel[data-task="pickplace"] .am-tag.is-dir,
.am-panel[data-task="highway"] .am-tag.is-dir {display: block;}
/* Walker: per-frame animated arrow-keys (dims 0-1 of the real action), driven by JS */
.am-cell .am-keys.is-walker {display: none;}
.am-panel[data-task="walker"] .am-keys.is-default,
.am-panel[data-task="mjwalker"] .am-keys.is-default {display: none;}
.am-panel[data-task="walker"] .am-keys.is-walker,
.am-panel[data-task="mjwalker"] .am-keys.is-walker {display: grid;}

/* Act 4 step (i) — interactive tokenizer round-trip: pick a task, watch the
   real frame travel encode → z → decode and compare against the decoded output.
   The frames ARE the pipeline endpoints; the spine reuses the .pipeline styling. */
.rt-panel {margin-top: 30px;}
.rt-panel .fig-label {text-align: center;}
.rt-tabs {display: flex; justify-content: center; gap: 4px; width: fit-content; margin: 18px auto 22px;
	padding: 3px; background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1);
	border-radius: 999px;}
.rt-tab {appearance: none; border: 0; background: transparent; color: #c9c7d6; cursor: pointer;
	font: inherit; font-size: 0.82em; font-weight: 600; padding: 7px 16px; border-radius: 999px;
	transition: background 0.18s ease, color 0.18s ease;}
.rt-tab:hover {color: #fff;}
.rt-tab:focus-visible {outline: 2px solid var(--purple-bright); outline-offset: 2px;}
.rt-tab.is-on {background: var(--purple); color: #fff; box-shadow: 0 0 14px rgba(176,114,224,0.45);}

.rt-flow {display: flex; align-items: center; justify-content: center; gap: 0;}
.rt-frame {position: relative; flex: 1 1 0; min-width: 0; max-width: 188px; aspect-ratio: 1 / 1;
	border-radius: 8px; overflow: hidden; background: #000; box-shadow: 0 0 0 1px rgba(255,255,255,0.14);}
.rt-frame--out {box-shadow: 0 0 0 1.5px rgba(176,114,224,0.5);}  /* the world-model output */
.rt-img {position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block;
	opacity: 0; transition: opacity 0.22s ease;}
.rt-img.is-on {opacity: 1;}
.rt-tag {position: absolute; top: 7px; left: 7px; z-index: 2; font-size: 0.62em; font-weight: 700;
	letter-spacing: 0.06em; text-transform: uppercase; color: #fff;
	background: rgba(10,10,16,0.66); padding: 2px 8px; border-radius: 999px; pointer-events: none;}
.rt-tag.wm {color: #e9d4ff;}
.rt-spine.pipeline {flex: none; width: clamp(220px, 42vw, 300px); max-width: none; margin: 0;}

.rt-verdicts {margin-top: 18px; min-height: 2.6em;}
.rt-verdict {display: none; font-size: 0.95em; line-height: 1.45; text-align: center; color: #bdbcca;}
.rt-verdict.is-on {display: block;}
.rt-verdict.ok {color: #9fd8b9;}
.rt-verdict.fail {color: #e3a6e8; font-weight: 500;}

/* ==========================================================================
   COVERAGE PANELS (Act 5)
   ========================================================================== */
.coverage-strip {display: grid; grid-template-columns: 1fr 1fr; gap: 18px 34px; margin-top: 28px;}
.cov-task {background: var(--paper); border: 1px solid #eadff5; border-radius: 12px; padding: 12px;
	box-shadow: 0 2px 10px rgba(117,64,156,0.05);}
.cov-task .cov-imgs {display: flex; gap: 5px;}
.cov-task .cov-imgs figure {flex: 1; margin: 0; text-align: center;}
.cov-task .cov-imgs img,
.cov-task .cov-imgs video {width: 100%; aspect-ratio: 1 / 1; object-fit: cover; border-radius: 5px; display: block;}
.cov-task .cov-imgs figcaption {font-size: 0.95em; font-weight: 600; color: var(--muted);
	margin-bottom: 6px; letter-spacing: 0.02em;}
.cov-task .cov-imgs figcaption.cl-density {color: var(--blue);}
.cov-task .cov-imgs figcaption.cl-ur {color: var(--purple);}
.cov-task .cov-name {font-size: 1.08em; color: var(--ink); font-weight: 700; margin: 2px 0 10px; text-align: center;}
.cov-task .cov-name .cov-dom {font-weight: 500; color: var(--muted);}
/* colormap gradient legend (endpoint colors sampled from the panels themselves) */
.legend-row .gl-cap {font-weight: 600; margin-right: 2px;}
.legend-row .gl-bar {width: 110px; height: 11px; border-radius: 99px; display: inline-block;
	border: 1px solid #d9d4e2;}
.legend-row .gl-end {font-size: 0.82em; color: var(--muted);}
.legend-row {display: flex; gap: 48px; justify-content: center; flex-wrap: wrap; margin-top: 22px; font-size: 0.95em;}
.legend-row .lg {display: inline-flex; align-items: center; gap: 7px; color: var(--muted);}
.legend-row .sw {width: 14px; height: 14px; border-radius: 3px; display: inline-block;}

/* predictor cards */
.pred-cards {display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin: 30px 0;}
.pred-card {background: var(--paper); border: 1px solid #ece4f4; border-radius: 14px; padding: 22px 20px;
	box-shadow: 0 2px 12px rgba(117,64,156,0.06); position: relative; overflow: hidden;}
.pred-card::before {content: ""; position: absolute; top: 0; left: 0; right: 0; height: 4px;
	background: linear-gradient(90deg, var(--blue), var(--purple-bright));}
.pred-card .pc-sym {font-size: 1.4em; color: var(--purple); font-style: italic; font-weight: 700;}
.pred-card h4 {margin: 6px 0 10px; min-height: 2.5em; font-size: 1.02em; color: var(--ink);}
.pred-card p {font-size: 0.9em; color: var(--muted); line-height: 1.55; margin: 0;}
/* inline equation accent — MathJax CHTML glyphs inherit this color */
.math-purple {color: var(--purple);}

/* ==========================================================================
   DELTA BAR CHART (Act 6) + PERF BAR CHART (Act 7)
   ========================================================================== */
.barchart {max-width: 720px; margin: 30px auto 0;}
.bar-row {display: grid; grid-template-columns: 190px 1fr; align-items: center; gap: 14px; margin: 10px 0;}
.bar-row .bl {font-size: 0.88em; color: var(--ink); text-align: right;}
.bar-row .bl .sub {color: var(--muted); font-size: 0.85em;}
/* group divider + label separating the non-finetuned baselines from the finetuned results */
.bar-group-title {margin: 20px 0 12px; padding-top: 14px; border-top: 1px dashed rgba(120,120,140,0.35);
	font-size: 0.72em; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);}
.bar-group-title .bgt-sub {font-weight: 500; letter-spacing: 0; text-transform: none; opacity: 0.85;}
.act--dark .bar-group-title {border-top-color: rgba(255,255,255,0.18); color: var(--dark-muted);}
.bar-track {position: relative; height: 26px; background: rgba(120,120,140,0.10); border-radius: 6px;}
.bar-track.diverging::before {content: ""; position: absolute; left: 50%; top: -3px; bottom: -3px;
	width: 1px; background: rgba(120,120,140,0.4);}
.bar-fill {position: absolute; top: 0; bottom: 0; border-radius: 5px; width: 0;
	transition: width 1s cubic-bezier(.2,.7,.3,1); display: flex; align-items: center;}
.bar-fill.pos {left: 50%; background: linear-gradient(90deg, #6aa0cf, var(--purple-bright));}
.bar-fill.neg {right: 50%; background: linear-gradient(90deg, #b3b3c0, #8a8a99);}
.bar-fill.solid {left: 0; background: linear-gradient(90deg, var(--blue), var(--purple-bright));}
.bar-fill.solid.muted {background: linear-gradient(90deg, #c9c9d4, #aeaebb);}
.bar-fill.solid.hi {background: linear-gradient(90deg, var(--purple), var(--purple-bright)); box-shadow: 0 0 14px var(--purple-glow);}
/* hatched = categorically different "reference floor" bar (e.g. random policy, no world model) */
.bar-fill.hatched::after {content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
	background-image: repeating-linear-gradient(45deg, rgba(40,40,60,0.42) 0, rgba(40,40,60,0.42) 2px, transparent 2px, transparent 7px);}
.bar-val {position: absolute; font-size: 0.8em; font-weight: 700; color: var(--ink); top: 50%; transform: translateY(-50%);
	opacity: 0; transition: opacity 0.4s ease 0.6s;}
.bar-fill.in .bar-val, .bar-row.in .bar-val {opacity: 1;}
.chart-note {text-align: center; font-size: 0.92em; color: var(--muted); margin-top: 18px; font-style: italic;}
.chart-note .fa {margin-right: 5px; opacity: 0.7;}

/* bar charts on dark acts (Prevention II): light text + visible track */
.act--dark .bar-row .bl {color: var(--dark-ink);}
.act--dark .bar-row .bl .sub {color: var(--dark-muted);}
.act--dark .bar-val {color: #fff;}
.act--dark .bar-track {background: rgba(255,255,255,0.12);}
.act--dark .chart-note {color: var(--dark-muted);}

/* ==========================================================================
   FINETUNE TRIPTYCH (Act 7, dark)
   ========================================================================== */
.triptych {display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; max-width: 760px; margin: 0 auto;}
.tri-cell {text-align: center;}
.tri-cell .tri-label {font-size: 0.72em; text-transform: uppercase; letter-spacing: 0.08em;
	color: var(--dark-muted); margin-bottom: 7px;}
.tri-cell.hi .tri-label {color: var(--purple-bright); font-weight: 700;}
.tri-cell video {width: 100%; border-radius: 8px; display: block; background: #000;}
.tri-cell.hi video {box-shadow: 0 0 0 2px var(--purple), 0 0 26px rgba(160,100,230,0.4);}
/* Act 7 — data coverage by collection policy (5 panels for one task) */
.policy-strip {display: grid; grid-template-columns: repeat(5, 1fr); gap: 14px; max-width: 880px; margin: 0 auto;}
.pol-cell {text-align: center;}
.pol-cell .pol-label {font-size: 0.72em; text-transform: uppercase; letter-spacing: 0.07em;
	color: var(--dark-muted); margin-bottom: 7px;}
.pol-cell.hi .pol-label {color: var(--purple-bright); font-weight: 700;}
.pol-cell img {width: 100%; aspect-ratio: 1 / 1; object-fit: cover; border-radius: 8px;
	display: block; background: #0a0a14;}
.pol-cell.hi img {box-shadow: 0 0 0 2px var(--purple), 0 0 26px rgba(160,100,230,0.4);}
@media (prefers-reduced-motion: no-preference) {
	.pol-cell.hi img {box-shadow: 0 0 0 2px var(--purple); animation: polGlow 3.4s ease-in-out infinite;}
}
@keyframes polGlow {
	0%, 100% {filter: drop-shadow(0 0 13px rgba(160,100,230,0.48));}
	50% {filter: drop-shadow(0 0 22px rgba(160,100,230,0.66));}
}
.policy-legend {display: flex; justify-content: center; align-items: center; gap: 9px;
	margin-top: 20px; font-size: 0.9em; color: var(--dark-muted);}
.policy-legend .pl-bar {width: 130px; height: 11px; border-radius: 99px; display: inline-block;
	background: linear-gradient(90deg, #bcd8f5, #2f5e9e, #1b2438);}
/* "show more" toggle for additional finetune examples */
.ft-more {display: none;}
.ft-more.open {display: block;}
.ft-more .triptych {margin-top: 36px;}
.ft-more-btn {display: flex; align-items: center; gap: 8px; margin: 26px auto 0; padding: 9px 18px;
	background: rgba(160,100,230,0.10); color: var(--purple-bright);
	border: 1px solid rgba(160,100,230,0.38); border-radius: 999px;
	font: inherit; font-size: 0.9em; font-weight: 600; cursor: pointer;
	transition: background 0.15s, border-color 0.15s;}
.ft-more-btn:hover {background: rgba(160,100,230,0.18); border-color: rgba(160,100,230,0.6);}
.ft-more-btn:focus-visible {outline: 2px solid var(--purple-bright); outline-offset: 3px;}
.ft-more-btn .fa {font-size: 0.85em; transition: transform 0.2s;}
.ft-more-btn[aria-expanded="true"] .fa {transform: rotate(180deg);}
.ft-more.open > * {animation: ftFade 0.45s ease both;}
@keyframes ftFade {from {opacity: 0; transform: translateY(8px);} to {opacity: 1; transform: none;}}
@media (prefers-reduced-motion: reduce) {.ft-more.open > * {animation: none;}}

/* ==========================================================================
   RELEASE CARDS + CITATION (Act 8)
   ========================================================================== */
.release-cards {display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin: 30px 0;}
.rcard {position: relative; display: block; padding: 24px; border-radius: 14px; background: var(--paper-2); border: 1px solid #ece4f4;
	color: inherit; text-decoration: none;}
.rcard .ic {font-size: 1.6em; color: var(--purple); margin-bottom: 10px;}
.rcard h4 {margin: 0 0 8px; color: var(--purple); font-size: 1.02em;}
.rcard p {font-size: 0.92em; color: var(--muted); line-height: 1.5; margin: 0;}

/* ==========================================================================
   LIVE DEMO (Act 8) — embedded client for the self-hosted world model.
   States are driven by main.js/initLiveDemo via classes on #liveDemo
   (.is-live) and #demoStage (.ustate-*), plus the overlay's .show.
   ========================================================================== */
/* lead-in act: blends straight out of the hero (also --dark). Start and end on --dark so
   both the hero seam above and the Problem seam below are invisible, with only a faint mid
   lift for depth; no top border line, which would read as a hard rule against the hero. */
.act--demo {background: linear-gradient(180deg, var(--dark) 0%, var(--dark-2) 50%, var(--dark) 100%);}

.demo-shell {--stage-w: 480px; max-width: 516px; margin: 36px auto 0; padding: 18px 18px 16px; border-radius: 18px;
	background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.02));
	border: 1px solid rgba(255,255,255,0.10);
	box-shadow: 0 24px 70px rgba(0,0,0,0.45), 0 0 50px rgba(160,100,230,0.07);}

.demo-head {display: flex; align-items: center; gap: 10px; margin: 0 auto 14px; min-height: 30px;
	max-width: var(--stage-w);}   /* match the WM window width so controls don't overhang the stage */
.demo-led {width: 9px; height: 9px; border-radius: 50%; flex: none;
	background: #5a5a6a; transition: background 0.3s ease, box-shadow 0.3s ease;}
.demo-led.on {background: #4ade80; box-shadow: 0 0 8px rgba(74,222,128,0.8);
	animation: demoLed 2.4s ease-in-out infinite;}
.demo-led.off {background: #6b6b76;}
@keyframes demoLed {0%,100% {opacity: 1;} 50% {opacity: 0.55;}}
.demo-led-lbl {font-size: 0.8em; color: var(--dark-muted); letter-spacing: 0.04em;
	text-transform: uppercase; white-space: nowrap;}
/* session controls live in the header and exist only while a session runs */
.demo-task {display: none; margin-left: auto; font: inherit; font-size: 0.86em; color: var(--dark-ink);
	background: rgba(255,255,255,0.07); border: 1px solid rgba(255,255,255,0.18);
	border-radius: 8px; padding: 4px 8px; max-width: 180px; outline: none;}
.demo-task:focus {border-color: var(--purple-bright);}
.demo-ibtn {display: none; align-items: center; justify-content: center; width: 28px; height: 28px;
	font: inherit; font-size: 0.95em; line-height: 1; color: var(--dark-muted); cursor: pointer;
	background: rgba(255,255,255,0.07); border: 1px solid rgba(255,255,255,0.18); border-radius: 8px;
	transition: color 0.18s ease, background 0.18s ease;}
.demo-ibtn:hover {color: #fff; background: rgba(255,255,255,0.14);}
.demo-shell.is-live .demo-task {display: block;}
.demo-shell.is-live .demo-ibtn {display: inline-flex;}
.demo-shell.is-live .demo-stage {cursor: pointer;}  /* click frame = pause/resume */
.demo-ibtn .fa {font-size: 12px;}

/* in-frame key HUD: the task's bindable keys in their natural grids, lighting
   up on press (same idea as interactive.py's recording overlay). Only keys
   for the task's action dims are shown (driven by status.act_dim). */
.demo-hud {position: absolute; left: 50%; transform: translateX(-50%); bottom: 12px; z-index: 6;
	display: none; align-items: end; gap: 28px;
	/* shrink-wrapped to the key clusters and made click-capturing: this box (keys
	   AND the small gaps between them) swallows clicks so a near-miss doesn't
	   pause, while clicks on the rest of the frame still pause. */
	pointer-events: auto;}
.demo-shell.is-live .demo-hud {display: flex;}
.hud-grid {display: grid; grid-template-columns: repeat(3, 36px); grid-template-rows: repeat(2, 32px);
	gap: 4px; justify-items: center; align-items: center;}
.hud-grid.dim-off {display: none;}
.hud-key {display: flex; align-items: center; justify-content: center; width: 34px; height: 30px;
	border-radius: 7px; font-size: 13px; font-weight: 600; color: rgba(255,255,255,0.88);
	background: rgba(10,10,18,0.42); border: 1px solid rgba(255,255,255,0.32);
	backdrop-filter: blur(2px);
	pointer-events: auto; cursor: pointer; touch-action: none;
	-webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent;
	transition: background 0.1s ease, box-shadow 0.1s ease, transform 0.1s ease;}
.hud-key .fa {font-size: 12px;}
.hud-key.dim-off {visibility: hidden;}
.hud-key.pressed {background: var(--purple); border-color: var(--purple-bright); color: #fff;
	box-shadow: 0 0 12px var(--purple-glow); transform: translateY(1px);}
.demo-pill {font-size: 0.8em; font-weight: 600; color: var(--dark-ink); white-space: nowrap;
	background: rgba(0,0,0,0.45); border: 1px solid rgba(255,255,255,0.16);
	padding: 3px 10px; border-radius: 999px; display: none;}
.demo-pill.warn {color: #fbbf24; border-color: rgba(251,191,36,0.6);}

.demo-stage {position: relative; max-width: var(--stage-w); margin: 0 auto; aspect-ratio: 1 / 1;
	border-radius: 12px; overflow: hidden; background: #000;
	box-shadow: 0 0 0 2px rgba(255,255,255,0.10); transition: box-shadow 0.35s ease;}
.demo-stage img {width: 100%; height: 100%; object-fit: cover; display: block;
	image-rendering: pixelated; -webkit-user-select: none; user-select: none;}
/* uncertainty ring — the paper's thesis, live. Neutral gray = no hallucination
   (calibrating and the low-uncertainty state look identical); amber = elevated;
   red = hallucination. The server still labels the low state "green" — it renders neutral. */
.demo-stage.ustate-calibrating {box-shadow: 0 0 0 2px rgba(180,180,200,0.55);}
.demo-stage.ustate-green  {box-shadow: 0 0 0 2px rgba(180,180,200,0.55);}
.demo-stage.ustate-yellow {box-shadow: 0 0 0 3px rgba(251,191,36,0.85), 0 0 24px rgba(251,191,36,0.35);}
.demo-stage.ustate-red    {box-shadow: 0 0 0 4px rgba(239,68,68,0.9),  0 0 30px rgba(239,68,68,0.45);}

/* verdict label — the same "Drifting"/"Hallucinating" cue as the Act-5 scrubber,
   mirroring the border colour so the state is legible without reading the glow. */
.demo-verdict {position: absolute; top: 10px; left: 10px; z-index: 6;
	font-size: 0.66em; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
	padding: 4px 10px; border-radius: 20px; color: #fff; background: rgba(0,0,0,0.45);
	backdrop-filter: blur(3px); display: flex; align-items: center; gap: 6px;}
.demo-verdict[hidden] {display: none;}
.demo-verdict .vdot {width: 8px; height: 8px; border-radius: 50%; background: #b4b4c8;}
.demo-stage.ustate-yellow .demo-verdict .vdot {background: #fbbf24;}
.demo-stage.ustate-red .demo-verdict .vdot {background: #ef4444;}

.demo-paused {position: absolute; inset: 0; display: none; align-items: center; justify-content: center;
	background: rgba(0,0,0,0.42); z-index: 5;}
.demo-paused.show {display: flex;}
.demo-paused-badge {display: flex; align-items: center; justify-content: center;
	width: 70px; height: 70px; border-radius: 50%;
	background: rgba(10,10,18,0.55); border: 2px solid rgba(255,255,255,0.85);
	backdrop-filter: blur(3px); box-shadow: 0 6px 28px rgba(0,0,0,0.45);}
.demo-paused-badge .fa {font-size: 24px; color: #fff;}
.demo-overlay {position: absolute; inset: 0; z-index: 10; display: none; flex-direction: column;
	align-items: center; justify-content: center; gap: 16px; padding: 26px; text-align: center;
	background: rgba(7,7,13,0.62); backdrop-filter: blur(3px);}
.demo-overlay.show {display: flex;}
.demo-overlay-msg {font-size: 1.02em; line-height: 1.55; color: var(--dark-ink); white-space: pre-line;}

.demo-btn {font: inherit; font-size: 0.9em; font-weight: 600; color: var(--dark-ink);
	background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.22);
	border-radius: 10px; padding: 7px 14px; cursor: pointer;
	transition: background 0.18s ease, border-color 0.18s ease, opacity 0.18s ease;}
.demo-btn:hover:not(:disabled) {background: rgba(255,255,255,0.16);}
.demo-btn:disabled {opacity: 0.35; cursor: default;}
.demo-btn--primary {background: var(--purple); border-color: transparent; color: #fff;
	font-size: 1.02em; padding: 11px 22px; box-shadow: 0 4px 24px var(--purple-glow);}
.demo-btn--primary:hover:not(:disabled) {background: var(--purple-bright);}

.demo-foot {display: flex; justify-content: center; margin: 13px auto 0; max-width: var(--stage-w);}
.demo-touchnote {margin: 0 auto; max-width: 32rem; text-align: center; font-size: 0.8em; line-height: 1.5; color: var(--dark-muted);}
.demo-touchnote[hidden] {display: none;}
.demo-keys {display: flex; align-items: center; justify-content: center; gap: 4px 10px; flex-wrap: wrap;}
.demo-keygroup {display: inline-flex; align-items: center; gap: 4px; white-space: nowrap;}
.demo-keycap {display: inline-flex; align-items: center; justify-content: center; min-width: 20px;
	height: 19px; padding: 0 5px; border-radius: 5px; font-size: 0.72em; font-weight: 600;
	color: var(--dark-ink); background: rgba(255,255,255,0.08);
	border: 1px solid rgba(255,255,255,0.2); border-bottom-width: 2px;}
.demo-keycap--arrows {gap: 3px; padding: 0 6px;}
.demo-keycap--arrows .fa {font-size: 9px;}
.demo-keylbl {font-size: 0.72em; color: var(--dark-muted); margin: 0 7px 0 2px;
	text-transform: uppercase; letter-spacing: 0.06em;}
/* frame-border legend: one colormap bar, same language as the coverage panels.
   Grid (1fr auto 1fr) keeps the bar itself geometrically centered despite the
   unequal label lengths. Hard-stop end colors: solid caps, so the rounded
   ends can't pick up mis-sampled gradient pixels. */
.demo-legend {display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
	gap: 10px; margin: 12px auto 0; max-width: var(--stage-w);}
.dl-end {font-size: 0.8em; color: var(--dark-muted); white-space: nowrap;}
.dl-end:first-child {justify-self: end;}
.dl-end:last-child {justify-self: start;}
.dl-bar {width: 130px; height: 10px; border-radius: 99px;
	background: linear-gradient(90deg,
		#9a9ab0 0 8px, #fbbf24 50%, #ef4444 calc(100% - 8px) 100%);}

@media (max-width: 560px) {
	.demo-head {flex-wrap: wrap;}
}

@media (prefers-reduced-motion: reduce) {
	.demo-led.on {animation: none;}
}

/* "100% open" — oversized, animated gradient centerpiece of the release act */
.open-hero {text-align: center; margin: 32px 0 14px;}
.open-flag-big {display: inline-block; font-weight: 800;
	font-size: clamp(2.6rem, 1.6rem + 3.4vw, 4rem); line-height: 1.05; letter-spacing: -0.02em;
	background: linear-gradient(110deg, var(--purple) 0%, var(--purple-bright) 28%, var(--blue) 50%, var(--purple-bright) 72%, var(--purple) 100%);
	background-size: 250% auto;
	-webkit-background-clip: text; background-clip: text;
	-webkit-text-fill-color: transparent; color: transparent;
	animation: openGradient 7s linear infinite;}
@keyframes openGradient {to {background-position: 250% center;}}

.paper .open-lead {text-align: center; font-size: var(--fs-prose); color: var(--ink); max-width: 620px; margin: 0 auto 4px;}

.references {list-style: none; max-width: 820px; margin: 22px 0 0; padding: 0; counter-reset: ref;}
.references li {position: relative; padding: 9px 0 9px 32px; border-bottom: 1px solid #ece4f4;
	font-size: 0.88em; line-height: 1.55; color: var(--ink);}
.references li::before {counter-increment: ref; content: counter(ref); position: absolute; left: 4px;
	top: 9px; color: var(--purple); font-weight: 700; font-variant-numeric: tabular-nums;}
.references a {color: var(--blue); text-decoration: none;
	border-bottom: 1px solid transparent; transition: color 0.15s ease, border-color 0.15s ease;}
.references a:hover {color: var(--purple); border-bottom-color: var(--purple);}
.references .ref-venue {color: #8a7da0; font-style: italic;}

.cite-block {position: relative; max-width: 760px; margin: 24px auto 0;}
.cite-block .bibtexsection {border-radius: 6px;}
.bib-copy {position: absolute; top: 10px; right: 10px; display: inline-flex; align-items: center;
	gap: 6px; padding: 6px 12px; border-radius: 6px; cursor: pointer; font-size: 13px; font-weight: 600;
	color: var(--purple); background: rgba(255,255,255,0.85); border: 1px solid #e0d4ef;
	transition: color 0.2s ease, background 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;}
.bib-copy:hover {color: #fff; background: var(--purple);
	border-color: var(--purple); box-shadow: 0 0 14px var(--purple-glow);}
.bib-copy.copied {color: #fff; background: var(--purple); border-color: var(--purple);}
.bib-copy.copied .fa::before {content: "\f00c";}

.paper-foot {box-sizing: border-box; background: var(--dark); color: var(--dark-muted); text-align: center; padding: 50px 20px;}
.paper-foot a {color: var(--purple-bright);
	transition: color 0.22s ease, text-shadow 0.3s ease;}
.paper-foot a:hover {color: #d9b3ff;
	text-shadow: 0 0 14px var(--purple-glow), 0 0 30px rgba(160,100,230,0.4);}
.paper-foot .backtop {display: inline-flex; align-items: center; color: #fff;
	padding: 11px 22px; border-radius: 999px; font-weight: 600;
	border: 1px solid rgba(160,100,230,0.4);
	background: rgba(117,64,156,0.18);
	box-shadow: 0 0 18px rgba(160,100,230,0.25);
	transition: color 0.22s ease, border-color 0.22s ease, background 0.22s ease,
		box-shadow 0.3s ease, transform 0.22s ease;}
.paper-foot .backtop .fa {transition: transform 0.22s ease;}
.paper-foot .backtop:hover {color: #fff; transform: translateY(-3px);
	border-color: var(--purple-bright);
	background: rgba(117,64,156,0.32);
	box-shadow: 0 0 22px var(--purple-glow), 0 0 44px rgba(160,100,230,0.4);
	text-shadow: 0 0 14px var(--purple-glow), 0 0 30px rgba(160,100,230,0.45);}
.paper-foot .backtop:hover .fa {transform: translateY(-2px);}

@media (prefers-reduced-motion: no-preference) {
	.paper-foot .backtop .fa {animation: backtop-bob 1.8s ease-in-out infinite;}
	.paper-foot .backtop:hover .fa {animation: none;}
}
@keyframes backtop-bob {
	0%, 100% {transform: translateY(0);}
	50% {transform: translateY(-4px);}
}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */
@media (max-width: 860px) {
	.dotnav {display: none;}
	.counters {grid-template-columns: repeat(2, 1fr);}
	.belt-row, .belt-tile {height: 118px;}
	.hero-mosaic {grid-template-columns: repeat(3, 1fr);}
	.scrolly {grid-template-columns: 1fr; gap: 0;}
	.scrolly__viz {position: sticky; top: 0; height: auto; padding: 16px 0;
		background: rgba(11,11,18,0.92); backdrop-filter: blur(8px); z-index: 5;
		border-bottom: 1px solid rgba(255,255,255,0.08);}
	.scrolly__steps {padding: 8px 0 30vh;}
	.step {min-height: 70vh;}
	/* world-model diagram: drop scroll-stepping; show the diagram + all captions listed */
	.scrolly--arch .scrolly__viz {position: static; height: auto; padding: 0;
		background: none; backdrop-filter: none; border-bottom: 0;}
	.scrolly--arch .scrolly__steps {display: none;}
	.wmd-conn {display: none;}
	.wmd-caps {position: static; min-height: 0; max-width: 540px; margin: 6px auto 0;}
	.wmd-cap, .wmd-cap.is-active {position: static; left: auto; width: auto; max-width: none; transform: none;
		opacity: 1; margin-bottom: 10px;}
	.wmd-blk.is-active rect {fill: #efe7f8; stroke: rgba(117,64,156,0.38); filter: none; animation: none;}
	.wmd-blk.is-active text {fill: var(--ink);}
	.wmd-blk.is-active .wmd-sub {fill: var(--muted);}
	.coverage-strip {grid-template-columns: 1fr;}
	.pred-cards {grid-template-columns: 1fr;}
	.release-cards {grid-template-columns: 1fr;}
	.triptych {grid-template-columns: 1fr; max-width: 360px;}
	.policy-strip {gap: 6px;}
	.pol-cell .pol-label {font-size: 0.6em; letter-spacing: 0.01em;}
	.policy-legend .pl-bar {width: 90px;}
	/* reserve a right-hand gutter so the value labels (positioned just past the
	   bar's end) stay inside the chart instead of spilling past the viewport edge */
	.bar-row {grid-template-columns: 120px 1fr 52px; gap: 8px;}
	.bar-row .bl {font-size: 0.78em;}
}

/* Below ~620px the horizontal SVG diagram's labels shrink to ~6px, so swap it (and the
   floating keypad above it) for the stacked vertical flow. The captions stay as-is. */
@media (max-width: 620px) {
	.wmd {padding-top: 0;}
	.wmd-keys {display: none;}
	.wmd > svg {display: none;}
	.wmd-flow-m {display: flex;}
	.wmd-caps {margin-top: 18px;}
}

/* Hero CTAs: keep "Live demo" + "Read the PDF" on row one, and the three secondary
   CTAs (Code/Dataset/Checkpoints) together on row two once all five no longer fit. */
.cta-break {display: none;}
@media (max-width: 820px) {
	/* Force a clean 2-row split instead of an awkward mid-row wrap. */
	.cta-break {display: block; flex-basis: 100%; height: 0; margin: 0;}
}
@media (max-width: 680px) {
	/* Tighter still: collapse the secondary CTAs to icon-only. */
	.hero-cta a.btn-iconly .btn-label {display: none;}
	.hero-cta a.btn-iconly {min-width: 0; padding: 9px 16px; text-align: center;}
}

@media (max-width: 560px) {
	.hero-mosaic {grid-template-columns: repeat(2, 1fr);}
	.hero-mosaic video:nth-child(n+9) {display: none;}  /* fewer simultaneous decodes on phones */
	.am-flow {gap: 6px;}                                 /* keep the 3 actions side-by-side — the comparison is the point */
	.am-cap span {display: none;}                        /* drop the sub-caption; the action label alone is enough when tight */
	.rt-flow {flex-direction: column; gap: 12px;}        /* stack frames so they stay large on phones */
	.rt-frame {flex: none; width: min(78%, 300px); max-width: 300px;}
	.rt-spine.pipeline {width: min(72%, 260px);}
	.rt-tabs {gap: 3px; max-width: 100%; flex-wrap: wrap;}  /* wrap the 5-tab pill to a 2nd row on the narrowest screens instead of overflowing */
	.rt-tab {padding: 6px 11px; font-size: 0.78em;}
	.duo-stage {gap: 8px;}
	.duo-tag {top: 8px; left: 8px; font-size: 0.55em; padding: 3px 7px;}
	.duo-controls {gap: 9px;}
	.compare-tl-cap {font-size: 0.5em;}
	.belt-row, .belt-tile {height: 96px;}
	.hint--inset {white-space: normal;}  /* let trailing hints wrap instead of forcing page-width overflow */
}

/* ==========================================================================
   DATA CHARTS — per-task frame distribution (Fig.2) + calibration (Fig.5)
   ========================================================================== */
.datachart {margin: 28px auto 0; max-width: 980px;}
.datachart .dc-plot {width: 100%;}
.dc-svg {width: 100%; height: auto; display: block; overflow: visible;}
.dc-svg text {font-family: inherit;}
.dc-grid {stroke: #e6e3ec; stroke-width: 1;}
.dc-axis {stroke: #cbc7d4; stroke-width: 1;}
.dc-ylab, .dc-xlab {fill: var(--muted); font-size: 13px;}
.dc-median {stroke: #4a4a55; stroke-width: 1.1; stroke-dasharray: 4 3;}
.dc-median-lab {fill: #34343e; font-size: 13px; font-weight: 600;}
.dc-bar {transition: transform 0.7s cubic-bezier(0.22, 0.61, 0.36, 1), opacity 0.2s;}
.dc-bar:hover {filter: brightness(1.12);}
.datachart.dc-anim .dc-bar {transform: scaleY(0); transform-box: fill-box; transform-origin: center bottom;}
.datachart.dc-anim.in .dc-bar {transform: scaleY(1);}
.dc-legend {display: flex; flex-wrap: wrap; gap: 7px 11px; justify-content: center; margin-top: 16px; font-size: 0.9em;}
.dc-legend .lg {display: inline-flex; align-items: center; gap: 6px; color: var(--muted); cursor: pointer; -webkit-tap-highlight-color: transparent; transition: opacity 0.15s ease, color 0.15s ease;}
.dc-legend .lgt {display: inline-flex; flex-direction: column;}
/* reserve the bold width up front so highlighting (bold) never reflows the row */
.dc-legend .lgt::after {content: attr(data-label); font-weight: 700; height: 0; overflow: hidden; visibility: hidden; pointer-events: none;}
.dc-legend .lg.hot {color: var(--ink);}
.dc-legend .lg.hot .lgt {font-weight: 700;}
.dc-legend .lg.cool {opacity: 0.38;}
.dc-legend .sw {width: 11px; height: 11px; border-radius: 2px; display: inline-block; transition: transform 0.15s ease, box-shadow 0.15s ease;}
.dc-legend .lg.hot .sw {transform: scale(1.18); box-shadow: 0 0 0 2px rgba(0,0,0,0.16);}

.chart-tip {position: fixed; z-index: 250; pointer-events: none; background: rgba(20,18,28,0.94);
	color: #fff; font-size: 12px; line-height: 1.38; padding: 7px 9px; border-radius: 7px;
	box-shadow: 0 6px 20px rgba(0,0,0,0.28); opacity: 0; transition: opacity 0.12s; max-width: 230px;}
.chart-tip.on {opacity: 1;}
.chart-tip b {color: var(--purple-bright); font-weight: 600;}
.chart-tip .dim {color: #b9b7c8;}

/* predictor-card mechanism glyphs (light variant of the pipeline language) */
.pc-glyph {margin: 10px 0 12px;}
.pc-glyph svg {width: 100%; height: auto; display: block; overflow: visible;}
.pcg-box {fill: #f3edfa; stroke: rgba(117,64,156,0.42); stroke-width: 1.3;}
.pcg-chip {fill: #fff; stroke: rgba(117,64,156,0.5); stroke-width: 1.3;}
.pcg-frame {fill: #fff; stroke: #c9c2d6; stroke-width: 1.3;}
.pcg-lbl {fill: var(--ink); font: 600 12px "Inter", sans-serif;}
.pcg-sym {fill: var(--purple); font: italic 600 13px "Inter", sans-serif;}
.pcg-neq {fill: var(--purple); font: 800 15px "Inter", sans-serif;}
.pcg-arrow {stroke: rgba(117,64,156,0.5); stroke-width: 1.4; fill: none;
	stroke-dasharray: 4 3; animation: pcgflow 0.7s linear infinite;}
.pcg-axis {stroke: #d9d4e2; stroke-width: 1;}
.pcg-line-lo {stroke: #b9b3c6; stroke-width: 1.7;}
.pcg-line-hi {stroke: var(--purple); stroke-width: 1.9;}
.pcg-fan {stroke: rgba(117,64,156,0.55); stroke-width: 1.5;
	stroke-dasharray: 4 3; animation: pcgflow 0.7s linear infinite;}
.pcg-dot {fill: var(--purple);}
/* The predictor-glyph dashes are 4 3 (period 7), so the march must advance a multiple
   of 7 per loop to stay seamless — pipeflow's -9 is for the pipe diagrams' 5 4 dashes. */
@keyframes pcgflow {to {stroke-dashoffset: -7;}}
.pcg-tip {fill: #fff; stroke: var(--purple); stroke-width: 1.6;}
.pcg-bracket {stroke: #9a93a8; stroke-width: 1.2;}
.pcg-end {fill: var(--muted); font: 500 10.5px "Inter", sans-serif;}
.pcg-end.hi {fill: var(--purple); font-weight: 600;}

/* sub-exhibit headers (detection act): signals · spatial · quantitative · run-time */
.subhead {display: flex; align-items: center; gap: 14px; margin: 64px 0 14px;}
.subhead h3 {margin: 0; font-size: 1.3em; font-weight: 700; letter-spacing: -0.015em; color: var(--ink);}
.subhead .rule {flex: 1; height: 1px; background: linear-gradient(90deg, #e0d8ec, rgba(224,216,236,0));}
.sublead {max-width: 800px; font-size: var(--fs-prose); color: var(--ink); margin: 0 0 26px; line-height: 1.6;}

.calib {margin: 18px auto 0; max-width: 1000px;}
.calib-panels {display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px;}
.calib-panel {min-width: 0;}
.cp-head {display: flex; align-items: baseline; justify-content: center; gap: 8px; margin-bottom: 6px;}
.cp-sym {font-style: italic; font-weight: 700; color: var(--purple); font-size: 1.04em;}
.cp-sym sub {font-style: normal; font-weight: 600; font-size: 0.7em;}
.cp-mode {font-size: 0.78em; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;}
.cp-plot {position: relative; width: 100%; height: 234px;}
.calib.calib-anim .cp-plot {opacity: 0; transition: opacity 0.55s ease;}
.calib.calib-anim.in .cp-plot {opacity: 1;}
.cp-plot canvas, .cp-plot svg {position: absolute; inset: 0; width: 100%; height: 100%;}
.cp-plot svg {overflow: visible;}  /* edge labels (ticks, ρ) must never clip */
.cp-svg text {font-family: inherit;}
.cp-xlabel {text-align: center; font-size: 0.82em; color: var(--ink); margin-top: 8px;}
.cp-grid {stroke: #eeedf2; stroke-width: 1;}
.cp-axis {stroke: #cfcbd6; stroke-width: 1;}
.cp-tick {fill: #6b6b76; font-size: 10.5px;}
.cp-thr {stroke: #1f1f1f; stroke-width: 1.3; stroke-dasharray: 4 3; opacity: 0.85;}
.cp-curve-halo {fill: none; stroke: #fff; stroke-width: 3.4; stroke-linecap: round; stroke-linejoin: round;}
.cp-curve {fill: none; stroke: var(--purple); stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round;}
.cp-dot {fill: var(--purple);}
.cp-rho {fill: #141018; font-size: 13px; font-weight: 700;}
.cp-axlabel {fill: var(--muted); font-size: 10.5px;}
/* linked cross-panel brushing */
.cp-plot canvas {transition: opacity 0.18s ease;}
.calib.brushing .cp-plot canvas {opacity: 0.45;}
.cp-hi {pointer-events: none;}
.cp-gy {stroke: var(--purple-bright); stroke-width: 1.5; stroke-dasharray: 5 3;}
.cp-gy.neg {stroke: #cf5a3f;}
.cp-gx {stroke: var(--purple-bright); stroke-width: 1.1; stroke-dasharray: 4 3; opacity: 0.6;}
.cp-ringhalo {fill: #fff;}
.cp-ring {fill: var(--purple); stroke: #fff; stroke-width: 1.5;}
.cp-pill {fill: var(--purple);}
.cp-pill.neg {fill: #c0492f;}
.cp-pilltx {fill: #fff; font-size: 10.5px; font-weight: 700;}
.chart-tip sub {font-size: 0.72em;}
@media (max-width: 720px) {
	.calib-panels {grid-template-columns: 1fr; gap: 22px;}
	.cp-plot {height: 220px;}
}

/* ==========================================================================
   POLISH — focus rings, card hover-lift, hero CTA, soft band seams
   ========================================================================== */
/* Visible keyboard focus (none existed before — keyboard users were lost) */
.paper a:focus-visible,
.paper button:focus-visible,
.paper [tabindex]:focus-visible {outline: 2px solid var(--purple-bright); outline-offset: 3px; border-radius: 6px;}
.act--dark a:focus-visible, .act--dark button:focus-visible, .hero a:focus-visible {outline-color: #fff;}

/* Lift static cards on hover — the biggest 'feels alive vs. dated' win */
.pred-card, .rcard, .cov-task, .counter {
	transition: transform 0.22s cubic-bezier(.2,.7,.3,1), box-shadow 0.22s ease, border-color 0.22s ease;}
.pred-card:hover, .rcard:hover, .cov-task:hover {
	transform: translateY(-4px);
	box-shadow: 0 14px 34px rgba(117,64,156,0.16);
	border-color: rgba(176,114,224,0.5);}
.counter:hover {transform: translateY(-4px);
	box-shadow: 0 16px 38px rgba(117,64,156,0.16), inset 0 1px 0 rgba(255,255,255,0.6);
	border-color: rgba(176,114,224,0.45);}
.act--dark .counter:hover {border-color: rgba(255,255,255,0.22);
	box-shadow: 0 16px 38px rgba(0,0,0,0.28);}
.rcard {box-shadow: 0 2px 12px rgba(117,64,156,0.05);}  /* resting shadow to match its sibling cards */

/* Hero primary CTA in brand purple (was a flat near-black button) */
.hero-cta a.btn:not(.ghost) {background: var(--purple); border: 1px solid transparent;
	box-shadow: 0 4px 20px var(--purple-glow), 0 2px 14px rgba(0,0,0,0.35);}
.hero-cta a.btn:not(.ghost):hover {background: var(--purple-bright);}

/* "Live Demo" hero CTA: anchors down to the demo act; the pulsing dot
   signals it's actually running right now */
.hero-cta a.btn-live {display: inline-flex; align-items: center; gap: 9px;}
.live-dot {width: 9px; height: 9px; border-radius: 50%; flex: none; background: #4ade80;
	box-shadow: 0 0 8px rgba(74,222,128,0.9); animation: demoLed 2.4s ease-in-out infinite;}
@media (prefers-reduced-motion: reduce) {
	.live-dot {animation: none;}
}

/* Soft seam at the top of light/tint acts so dark->light transitions don't hard-cut.
   Sits inside the 96px top padding (over empty space) — never overlaps content. */
.act--light::before, .act--tint::before {content: ""; position: absolute; top: 0; left: 0; right: 0;
	height: 56px; background: linear-gradient(180deg, rgba(11,11,18,0.05), transparent); pointer-events: none;}

/* ----- GT vs. world-model side-by-side comparison (Act 1) ----------------- */
.duo {max-width: 860px; margin: 0 auto;}
.duo-stage {display: flex; gap: 16px; align-items: stretch;}
.duo-cell {position: relative; flex: 1 1 0; min-width: 0; margin: 0; border-radius: 14px; overflow: hidden;
	cursor: pointer; background: #0c0a12; box-shadow: 0 18px 50px rgba(0,0,0,0.45);}
.duo-cell:focus-visible {outline: 2px solid var(--purple-bright); outline-offset: 3px;}
.compare-vid {display: block; width: 100%; height: auto;}
.duo-tag {position: absolute; top: 12px; left: 12px; font-size: 0.7em; font-weight: 600; letter-spacing: 0.06em;
	text-transform: uppercase; color: #fff; background: rgba(10,10,16,0.6); backdrop-filter: blur(4px);
	padding: 4px 10px; border-radius: 999px; pointer-events: none; z-index: 3;}
.duo-tag--r {color: #e9d4ff;}
/* play / pause + scrubbable playback timeline control bar */
.duo-controls {display: flex; align-items: center; gap: 14px; margin-top: 14px;}
.duo-play {flex: none; width: 40px; height: 40px; padding: 0; border-radius: 50%; cursor: pointer; color: #fff;
	border: 1px solid rgba(176,114,224,0.55); background: rgba(30,22,42,0.7);
	display: grid; place-items: center; transition: background 0.15s, border-color 0.15s, transform 0.08s;}
.duo-play:hover {background: rgba(48,34,66,0.9); border-color: var(--purple-bright);}
.duo-play:active {transform: scale(0.93);}
.duo-play:focus-visible {outline: 2px solid var(--purple-bright); outline-offset: 3px;}
.duo-play svg {width: 19px; height: 19px; fill: currentColor; pointer-events: none;}
.duo-play .ic-play {display: none;}
.duo-play.is-paused .ic-pause {display: none;}
.duo-play.is-paused .ic-play {display: block;}
/* playback timeline / scrubber — shows position in the loop (aligned start -> drift) */
.compare-timeline {flex: 1; --t: 0; display: flex; align-items: center; gap: 9px;
	cursor: pointer; touch-action: none;}
.compare-tl-cap {font-size: 0.6em; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
	color: rgba(255,255,255,0.7); white-space: nowrap; pointer-events: none;}
.compare-tl-cap--r {color: #d9b3ff;}
.compare-tl-track {position: relative; flex: 1; height: 4px; border-radius: 99px;
	background: rgba(255,255,255,0.22);}
.compare-tl-fill {position: absolute; left: 0; top: 0; bottom: 0; width: calc(var(--t) * 100%);
	background: linear-gradient(90deg, rgba(255,255,255,0.55), var(--purple-bright)); border-radius: 99px;}
.compare-tl-knob {position: absolute; top: 50%; left: calc(var(--t) * 100%); width: 11px; height: 11px;
	transform: translate(-50%,-50%); border-radius: 50%; background: #fff;
	box-shadow: 0 0 9px var(--purple-glow), 0 1px 3px rgba(0,0,0,0.55);}
.compare-timeline.scrubbing .compare-tl-track {height: 5px;}
.compare-timeline.scrubbing .compare-tl-knob {width: 14px; height: 14px;}

/* ==========================================================================
   REDUCED MOTION — disable scroll-jacking / animation, show everything
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
	html {scroll-behavior: auto;}
	.dc-bar {transition: none;}
	.cp-plot {opacity: 1 !important;}
	.reveal {opacity: 1; transform: none; transition: none;}
	.pred-card, .rcard, .cov-task, .counter {transition: none;}
	.pred-card:hover, .rcard:hover, .cov-task:hover, .counter:hover {transform: none;}
	.counters .counter, .counters.is-visible .counter {opacity: 1; animation: none;}
	.open-flag-big {animation: none;}
	.counter::before {transition: none; transform: scaleX(1);}
	.scrolly__viz {position: static; height: auto;}
	.scrolly__steps {padding: 20px 0;}
	.step {min-height: auto; margin-bottom: 30px;}
	.pipeline.dimmable .stage-box {opacity: 1;}
	.pipeline .pipe-arrow {animation: none; stroke-dasharray: none;}
	.pcg-arrow, .pcg-fan {animation: none;}
	.pipeline.dimmable .stage-box.is-active {animation: none; filter: drop-shadow(0 0 12px var(--purple-glow));}
	.pipeline.dimmable .stage-box.is-active rect {animation: none;}
	.wmd-blk rect, .wmd-blk text, .wmd-conn, .wmd-cap {transition: none;}
	.wmd-key, .wmd-arrow, .wmd-action-pulse {animation: none;}
	.wmd-arrow {stroke-dasharray: none;}
	.wmd-action-pulse {opacity: 0;}
	.wmd-conn {display: none;}
	.wmd-caps {position: static; min-height: 0;}
	.wmd-cap, .wmd-cap.is-active {position: static; left: auto; width: auto; max-width: none; transform: none;
		opacity: 1; margin-bottom: 10px;}
	.wmd-blk.is-active rect {fill: #efe7f8; stroke: rgba(117,64,156,0.38); filter: none; animation: none;}
	.wmd-blk.is-active text {fill: var(--ink);}
	.wmd-blk.is-active .wmd-sub {fill: var(--muted);}
	.scrollcue .chev {animation: none;}
	.bar-fill {transition: none;}
}

/* ==========================================================================
   "Detection in motion" scrubber (Act-5 exhibit 04)
   ========================================================================== */
.scrubber {margin-top: 22px; max-width: 940px; margin-left: auto; margin-right: auto;}

/* clip selector */
.scrub-clips {display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; margin-bottom: 20px;}
.scrub-clip {display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
	padding: 8px 14px; border-radius: 12px; cursor: pointer; text-align: left;
	background: #fff; border: 1.5px solid rgba(117,64,156,0.18);
	font: inherit; color: var(--muted); transition: border-color .18s, box-shadow .18s, transform .18s;}
.scrub-clip:hover {transform: translateY(-1px); border-color: rgba(117,64,156,0.4);}
.scrub-clip:focus-visible {outline: 2px solid var(--purple-bright); outline-offset: 2px;}
.scrub-clip .sc-name {font-weight: 700; color: var(--ink); font-size: 0.92em;}
.scrub-clip .sc-mode {font-size: 0.7em; font-weight: 600; letter-spacing: 0.02em;}
.scrub-clip.is-active {border-color: var(--purple); box-shadow: 0 6px 18px rgba(117,64,156,0.16);}
.scrub-clip.is-active .sc-mode {color: var(--purple);}
/* temporary "overnight candidate" review group: full-width label + dashed chips on a new line */
.scrub-clip-sep {flex-basis: 100%; height: 0; margin: 4px 0 -6px;
	font-size: 0.7em; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
	color: var(--purple); text-align: center;}
.scrub-clip.is-candidate {border-style: dashed; border-color: rgba(117,64,156,0.5); background: var(--paper-2);}

/* two-column body */
.scrub-main {display: grid; grid-template-columns: minmax(0, 330px) minmax(0, 1fr);
	gap: 28px; align-items: start;}

/* left: the rollout stage */
.scrub-stage {position: relative; aspect-ratio: 1/1; border-radius: 16px; overflow: hidden;
	background: #000; box-shadow: 0 10px 30px rgba(20,12,40,0.18); transition: box-shadow .25s ease;}
.scrub-stage video {width: 100%; height: 100%; object-fit: cover; display: block;
	-webkit-user-select: none; user-select: none;}
/* stable / drifting / hallucinating ring — matched to the live demo's #demoStage */
.scrub-stage.ustate-green  {box-shadow: 0 0 0 2px rgba(180,180,200,0.55), 0 10px 30px rgba(20,12,40,0.18);}
.scrub-stage.ustate-yellow {box-shadow: 0 0 0 3px rgba(251,191,36,0.85), 0 0 24px rgba(251,191,36,0.35), 0 10px 30px rgba(20,12,40,0.18);}
.scrub-stage.ustate-red    {box-shadow: 0 0 0 4px rgba(239,68,68,0.9), 0 0 30px rgba(239,68,68,0.45), 0 10px 30px rgba(20,12,40,0.18);}

.scrub-verdict {position: absolute; top: 10px; left: 10px; z-index: 3;
	font-size: 0.66em; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
	padding: 4px 10px; border-radius: 20px; color: #fff; background: rgba(0,0,0,0.45);
	backdrop-filter: blur(3px); display: flex; align-items: center; gap: 6px;}
.scrub-verdict .vdot {width: 8px; height: 8px; border-radius: 50%; background: #b4b4c8;}
.scrub-stage.ustate-yellow .scrub-verdict .vdot {background: #fbbf24;}
.scrub-stage.ustate-red .scrub-verdict .vdot {background: #ef4444;}

.scrub-readout {position: absolute; right: 10px; bottom: 10px; z-index: 3; text-align: right;
	color: #fff; text-shadow: 0 1px 6px rgba(0,0,0,0.6); pointer-events: none;}
.scrub-readout .ro-val {font-size: 1.7em; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums;}
.scrub-readout .ro-lbl {font-size: 0.64em; font-weight: 600; letter-spacing: 0.04em; opacity: 0.85;}
.scrub-readout .ro-val.over {color: #ff8d8d;}

.scrub-play {position: absolute; inset: 0; z-index: 4; display: none; align-items: center; justify-content: center;
	background: rgba(0,0,0,0.28); border: 0; cursor: pointer; color: #fff;}
.scrubber.is-paused .scrub-play {display: flex;}
.scrub-play .pp {width: 58px; height: 58px; border-radius: 50%; background: rgba(255,255,255,0.92);
	display: flex; align-items: center; justify-content: center; color: var(--purple); font-size: 1.3em;
	box-shadow: 0 6px 20px rgba(0,0,0,0.35);}

.scrub-timeline {position: relative; margin-top: 14px; display: flex; align-items: center; gap: 10px; --t: 0;
	touch-action: none; cursor: pointer;}
.scrub-tl-track {position: relative; flex: 1; height: 5px; border-radius: 99px; background: rgba(117,64,156,0.16);}
.scrub-tl-fill {position: absolute; left: 0; top: 0; bottom: 0; width: calc(var(--t) * 100%);
	border-radius: 99px; background: linear-gradient(90deg, var(--blue), var(--purple-bright));}
.scrub-tl-knob {position: absolute; top: 50%; left: calc(var(--t) * 100%); width: 13px; height: 13px;
	border-radius: 50%; background: #fff; border: 2px solid var(--purple); transform: translate(-50%,-50%);
	box-shadow: 0 1px 5px rgba(0,0,0,0.3);}
.scrub-tl-time {font-size: 0.72em; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; min-width: 56px;}

.scrub-caption {margin-top: 12px; font-size: 0.86em; line-height: 1.5; color: var(--muted);}
.scrub-caption b {color: var(--ink);}

/* right: the live signal chart */
.scrub-chart-col {min-width: 0;}
/* signal legend — centered below the plot, sized/styled like the frame-chart legend */
.scrub-legend {display: flex; flex-wrap: wrap; gap: 9px 20px; justify-content: center;
	margin-top: 14px; font-size: 0.92em;}
.scrub-leg {display: inline-flex; align-items: center; gap: 8px; cursor: pointer; color: var(--muted);
	background: none; border: 0; padding: 2px; font: inherit; user-select: none;
	-webkit-tap-highlight-color: transparent; transition: opacity .15s ease, color .15s ease;}
.scrub-leg .lswatch {width: 22px; height: 4px; border-radius: 2px; transition: transform .15s ease;}
.scrub-leg.is-lead {color: var(--ink); font-weight: 700;}
.scrub-leg.is-lead .lswatch {transform: scaleY(1.5);}
.scrub-leg.is-off {opacity: 0.38;}
.scrub-leg:focus-visible {outline: 2px solid var(--purple-bright); outline-offset: 2px; border-radius: 4px;}

.scrub-plot {position: relative; width: 100%; aspect-ratio: 16/9; min-height: 200px;}
.scrub-plot svg {position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible;}
.sp-band {fill: rgba(239,68,68,0.12);}
.sp-thr {stroke: rgba(239,68,68,0.55); stroke-width: 1.2; stroke-dasharray: 5 4;}
.sp-thr-lbl {fill: #d2545a; font-size: 12.5px; font-weight: 700;}
.sp-axis {stroke: rgba(30,29,34,0.35); stroke-width: 1;}
.sp-grid {stroke: rgba(30,29,34,0.08); stroke-width: 1;}
.sp-tick {fill: var(--muted); font-size: 12px;}
.sp-line {fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; transition: opacity .2s;}
.sp-line.dim {opacity: 0.28; stroke-width: 1.6;}
.sp-line.lead {stroke-width: 2.8;}
.sp-line.hidden {display: none;}
.sp-playhead {stroke: rgba(30,29,34,0.5); stroke-width: 1.2;}
.sp-dot {stroke: #fff; stroke-width: 1.5;}

@media (max-width: 820px) {
	.scrub-main {grid-template-columns: 1fr; gap: 22px;}
	.scrub-stage {max-width: 360px; margin: 0 auto;}
	.scrub-timeline, .scrub-caption {max-width: 360px; margin-left: auto; margin-right: auto;}
}
