:root {
  /* Picture size shared by the comparison rows of 34-39 and backup 45. */
  --row-frame:30.6cqw;
  color-scheme: dark;
  --bg: #12171c; --panel: #1d252d; --ink: #f6f4ed; --muted: #c2cbd2;
  --line: #46515b; --accent: #89edcf; --warm: #ffb59c;
  font-family: "Liberation Sans", Arial, "Helvetica Neue", Helvetica, sans-serif; font-synthesis: none;
}
* { box-sizing: border-box; }
html, body { width: 100%; height: 100%; margin: 0; overflow: hidden; background: #090c0f; color: var(--ink); }
body { display: grid; place-items: center; }
button, input { font: inherit; }
button { color: inherit; cursor: pointer; }
button:focus-visible, a:focus-visible { outline: 3px solid var(--accent); outline-offset: 5px; }
button:disabled { opacity: .3; cursor: default; }
a { color: var(--accent); text-underline-offset: .16em; }
#deck { position: relative; width: min(100vw, 177.77778vh); height: min(100vh, 56.25vw); container-type: size; overflow: hidden; isolation: isolate; background: var(--bg); }
.slide { position: absolute; inset: 0; display: flex; flex-direction: column; gap: 2.1cqw; padding: 3.5cqw 4.5cqw 3.4cqw; opacity: 0; visibility: hidden; pointer-events: none; transition: opacity 220ms ease; font-size:2.8cqw; line-height: 1.28; }
.slide.active { opacity: 1; visibility: visible; pointer-events: auto; }
header { flex: 0 0 auto; }
.eyebrow { margin: 0 0 1cqw; font-size: 1.6cqw; font-weight: 650; color: var(--accent); }
h1, h2, h3, p, figure, ol, ul { margin: 0; }
h1 { font-size: 8.4cqw; font-weight: 650; line-height: .96; letter-spacing: -.055em; }
h2 { font-size: 3.7cqw; font-weight: 600; line-height: 1.1; letter-spacing: -.037em; max-width: 90cqw; text-wrap: balance; }
h3 { font-size:3.45cqw; font-weight: 600; line-height: 1.16; letter-spacing: -.025em; }
p { text-wrap: pretty; }
strong, b { font-weight: 650; }
em { font-style: normal; color: var(--accent); }
sub { font-size: .72em; }
code, .math { font-weight: 600; }
.accent { color: var(--accent); } .muted { color: var(--muted); } .warm { color: var(--warm); }
.content { flex: 1 1 auto; min-height: 0; }
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 4cqw; align-items: center; }
.split.wide-visual { grid-template-columns: .86fr 1.14fr; gap: 3cqw; }
.split > *, .trio > *, .pair > * { min-width: 0; min-height: 0; }
.stack { display: flex; flex-direction: column; gap: 2cqw; } .spaced { gap: 3cqw; }
.large-copy { font-size:3.23cqw; line-height: 1.25; letter-spacing: -.025em; }
.statement { font-size: 3.77cqw; line-height: 1.15; letter-spacing: -.035em; }
.note { font-size:2.8cqw; color: var(--muted); line-height: 1.3; }
.bottom-line { flex: 0 0 auto; font-size:2.8cqw; color: var(--muted); border-top: 2px solid var(--line-strong); padding-top: 1.25cqw; }
.rule-list { list-style: none; padding: 0; display: flex; flex-direction: column; }
.rule-list > li, .rule-row { padding: 1.6cqw 0; border-top: 2px solid var(--line-strong); }
.rule-list > li:last-child { border-bottom: 2px solid var(--line-strong); }
.rule-list h3 { margin-bottom: .65cqw; } .rule-list p { color: var(--muted); }
.label { font-size:2.8cqw; color: var(--muted); }
.pill { display: inline-block; color: var(--accent); border: 2px solid var(--line-strong); padding: .5cqw .9cqw; font-size: 1.65cqw; }
.hero-layout { display: grid; grid-template-columns: 1fr 1fr; gap: 2cqw; align-items: center; height: 100%; }
.hero-copy { display: flex; flex-direction: column; align-items: flex-start; gap: 2.4cqw; }
.hero-copy .eyebrow { margin: 0; } .hero-copy .large-copy { max-width: 39cqw; }
.hero-image { width: 41cqw; height: 41cqw; border-radius: 50%; object-fit: cover; justify-self: end; }
.media-frame, .video-stack { position: relative; background: #080b0e; overflow: hidden; aspect-ratio: 1; border-radius: .45cqw; }
.media-frame > video, .media-frame > img, .video-stack > video { width: 100%; height: 100%; display: block; object-fit: contain; }
.video-stack > video { position: absolute; inset: 0; opacity: 0; z-index: 0; transition: opacity 380ms ease; }
.video-stack > video.active { opacity: 1; z-index: 1; } .video-stack > video.entering { z-index: 2; }
.media-error { position: absolute; inset: 0; display: grid; place-items: center; padding: 2cqw; background: var(--panel); font-size: 2cqw; }
.gallery { display: grid; grid-template-columns: 35cqw 1fr; gap: 4cqw; align-items: center; }
.gallery .video-stack { width: 35cqw; }
.picker { display: flex; flex-direction: column; gap: .6cqw; }
.media-choice { background: transparent; border: 1px solid transparent; text-align: left; display: flex; align-items: center; gap: 1.3cqw; padding: .65cqw 1cqw; border-radius: .35cqw; font-size:2.8cqw; font-weight: 550; }
.media-choice img { width: 4.7cqw; height: 4.7cqw; border-radius: 50%; object-fit: cover; }
.media-choice:hover { background: #ffffff09; }
.media-choice.active { border-color: var(--accent); background: #89edcf0d; color: var(--accent); }
.pair { display: grid; grid-template-columns: 1fr 1fr; gap: 2.5cqw; justify-items: center; min-height: 0; }
.pair figure { display: flex; flex-direction: column; gap: .85cqw; width: 100%; align-items: center; }
.pair .video-stack, .pair .media-frame { width: 31.7cqw; }
figcaption { font-size:2.8cqw; font-weight: 600; text-align: center; }
.pair-footer { display: flex; justify-content: space-between; align-items: center; gap: 2cqw; }
.inline-picker { display: flex; gap: .8cqw; }
.inline-picker .media-choice { padding: .35cqw; }
.inline-picker .media-choice img { width: 3.7cqw; height: 3.7cqw; }
.inline-picker .media-choice span { display: none; }
.trio { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 2cqw; align-items: center; }
.lookup-figure { display: flex; flex-direction: column; gap: 1.4cqw; text-align: center; }
.lookup-figure img { width: 100%; height: 24cqw; object-fit: contain; border-radius: .4cqw; background: var(--panel); }
.lookup-figure.asset img { padding: 2cqw; background: #050607; }
.lookup-figure figcaption { font-size:3.1cqw; }
.scope-column { align-self: stretch; display: flex; flex-direction: column; justify-content: center; gap: 1.5cqw; padding-right: 1cqw; }
.scope-column + .scope-column { border-left: 2px solid var(--line-strong); padding-left: 3cqw; }
.scope-column .label { color: var(--accent); } .scope-column.boundary .label { color: var(--warm); }
.scope-column h3 { font-size: 3.34cqw; } .scope-column p { color: var(--muted); }
.function-block { padding: 2.6cqw 0; border-top: 2px solid var(--line-strong); border-bottom: 2px solid var(--line-strong); display: flex; flex-direction: column; gap: 1.3cqw; }
.function-block .math { font-size:3.02cqw; letter-spacing: -.05em; }
.function-block.focus { border-color: var(--accent); }
.flow { display: grid; grid-template-columns: 1fr auto 1fr auto 1fr; align-items: center; gap: 1.2cqw; }
.flow.four { grid-template-columns: 1fr auto 1fr auto 1fr auto 1fr; }
.flow-node { border-top: 2px solid var(--line); padding-top: 1.5cqw; display: flex; flex-direction: column; gap: 1.2cqw; align-self: center; min-height: 15cqw; justify-content: flex-start; }
.flow-node.focus { border-color: var(--accent); }
.flow-node h3 { font-size:3.45cqw; } .flow-node p { color: var(--muted); font-size:2.8cqw; }
.arrow { color: var(--accent); font-size:3.23cqw; }
.improvement-list { display: grid; grid-template-columns: 1fr 1fr; gap: 2.6cqw 4cqw; align-content: center; }
.improvement-list article { border-top: 2px solid var(--line-strong); padding-top: 1.5cqw; }
.improvement-list h3 { margin-bottom: .8cqw; } .improvement-list p { color: var(--muted); }
.wave-panel { display: flex; flex-direction: column; gap: 1.5cqw; }
.wave-row { display: grid; grid-template-columns: 4cqw 1fr; gap: 1.5cqw; align-items: center; }
.wave-row svg { width: 100%; height: 5.5cqw; overflow: visible; }
.equation { font-size:3.02cqw; line-height: 1.4; color: var(--accent); }
.wireframe { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1.5cqw; border: 2px dashed #7b929f; min-height: 26cqw; padding: 3cqw; background: #182028; text-align: center; }
.wireframe .label { font-weight: 650; color: var(--accent); }
.wireframe h3 { font-size: 2.91cqw; }
.wireframe p { color: var(--muted); font-size: 1.85cqw; }
.wireframe .shot { border-top: 2px solid var(--line-strong); padding-top: 1.4cqw; margin-top: .5cqw; }
.dataset-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1cqw; width: 34cqw; justify-self: end; }
.dataset-grid img { width: 100%; aspect-ratio: 1; object-fit: contain; border-radius: .35cqw; background: #080b0e; }
.sample-image { position: relative; width: 33cqw; justify-self: end; }
.sample-image img { display: block; width: 100%; border-radius: .4cqw; }
.sample-pair { display: grid; grid-template-columns: 1fr auto 1fr; gap: 1.5cqw; align-items: center; }
.sample-pair > div { border-top: 2px solid var(--line); padding-top: 1.6cqw; } .sample-pair h3 { margin-top: 1cqw; }
.architecture { display: grid; grid-template-columns: 1fr auto 1.7fr auto 1fr; gap: 1.5cqw; align-items: center; }
.architecture > div:not(.arrow) { padding: 2cqw 1.5cqw; border: 2px solid var(--line-strong); text-align: center; display: flex; flex-direction: column; gap: 1cqw; }
.architecture .hidden-layers { background: #89edcf0b; border-color: var(--accent) !important; }
.architecture strong { font-size: 3.45cqw; } .architecture p { font-size:2.8cqw; color: var(--muted); }
.training-facts { display: flex; justify-content: space-between; border-top: 2px solid var(--line-strong); padding-top: 1.8cqw; }
.training-facts > div { display: flex; flex-direction: column; gap: .6cqw; }
.data-table { width: 100%; border-collapse: collapse; font-size:2.8cqw; align-self: center; font-variant-numeric: tabular-nums; }
.data-table th { color: var(--muted); font-weight: 500; text-align: right; font-size:2.8cqw; padding: 0 1.1cqw 1.2cqw; border-bottom: 2px solid var(--line-strong); }
.data-table td { padding: 1.25cqw 1.1cqw; text-align: right; border-bottom: 2px solid var(--line-strong); }
.data-table th:first-child, .data-table td:first-child { text-align: left; }
.data-table tr.highlight td { color: var(--accent); background: #89edcf09; }
.table-wrap { display: flex; flex-direction: column; justify-content: center; gap: 2.6cqw; }
.performance .data-table td { padding-top: 1.1cqw; padding-bottom: 1.1cqw; }
.performance .data-table { font-size:2.8cqw; } .performance .data-table th { font-size:2.8cqw; }
.capacity .media-frame { width: 33cqw; }
.ablation-rows { display: flex; flex-direction: column; justify-content: center; gap: 1.2cqw; }
.ablation-row { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 2cqw; border-top: 2px solid var(--line-strong); padding: 1.6cqw 0; align-items: center; }
.ablation-row span { color: var(--muted); } .ablation-row b { font-size:3.1cqw; } .ablation-row em { font-size:2.8cqw; }
.outlook-list li { display: grid; grid-template-columns: 1fr 1.25fr; gap: 4cqw; padding: 2cqw 0; } .outlook-list h3 { margin: 0; }
.demo-summary { display: grid; grid-template-columns: 1fr 34cqw; gap: 4cqw; align-items: center; }
.demo-summary .video-stack { width: 34cqw; }
.demo-summary .inline-picker { justify-content: center; margin-top: 1cqw; gap: .6cqw; }
.demo-summary .inline-picker .media-choice img { width: 3.8cqw; height: 3.8cqw; }
.choice-title { font-size:3.02cqw; font-weight: 600; line-height: 1.16; letter-spacing: -.025em; color: var(--accent); }
.choice-inputs { font-size:2.8cqw; color: var(--muted); min-height: 4.8cqw; }
.final .statement { font-size: 4.2cqw; } .final .media-frame { width: 37cqw; } .final .large-copy { font-size:2.97cqw; }
.source-list { list-style: none; padding: 0; display: flex; flex-direction: column; justify-content: center; gap: 2cqw; }
.source-list li { border-top: 2px solid var(--line-strong); padding-top: 1.5cqw; }
.source-list p { font-size:2.8cqw; color: var(--muted); margin-top: .7cqw; }
.fragment { opacity: 0; transform: translateY(.5cqw); transition: opacity 220ms ease, transform 220ms ease; }
.fragment.visible { opacity: 1; transform: none; }
#progress-track { position: fixed; height: 3px; bottom: 0; left: 0; right: 0; z-index: 50; opacity: .5; }
#progress-bar { height: 100%; background: var(--accent); transition: width 180ms; }
/* The slide number sits in the bottom-left corner like a page number, beside
   the chapter label. Nothing floats over the picture any more. */
#slide-number { position: absolute; z-index: 60; left: 1.7cqw; bottom: 1.3cqw; font-size: 1.35cqw; font-weight: 650; color: var(--dim); }
/* The chapter overview is hidden until P is pressed; one row per chapter. */
#chapters[hidden] { display: none; }
#chapters {
  position: fixed; z-index: 80; left: 50%; bottom: 60px; transform: translateX(-50%);
  display: flex; flex-direction: column; gap: 10px;
  padding: 18px 24px; border: 1px solid var(--line); border-radius: 12px;
  background: #0b1015f5; box-shadow: 0 10px 40px #0009; font-size: 14px;
}
.chapter-row { display: grid; grid-template-columns: 130px auto; align-items: center; gap: 14px; }
.chapter-name { color: var(--muted); }
.chapter-dots { display: flex; align-items: center; gap: 7px; }
.pagination-dot { width: 9px; height: 9px; padding: 0; border: 0; border-radius: 50%; background: #76838e; }
.pagination-dot.active { background: var(--accent); transform: scale(1.5); }
#notes { display: none; position: fixed; inset: auto 5vw 5vh; max-height: 60vh; overflow: auto; z-index: 100; background: #080e14f7; color: var(--ink); border: 1px solid var(--accent); border-radius: 8px; padding: 24px 30px; white-space: pre-wrap; font-size: 20px; line-height: 1.5; box-shadow: 0 10px 60px #000b; }
#notes.visible { display: block; }
/* The speaker's window is the only one with notes, and it is the one that must
   never end up on the projector. A corner label says which is which. */
body.presenter-view::after {
  content: "Presenter"; position: fixed; top: 10px; right: 14px; z-index: 200;
  font-size: 13px; font-weight: 600; letter-spacing: .02em; color: var(--accent);
  border: 1px solid var(--accent); border-radius: 999px; padding: 3px 12px;
  background: #080e14cc; pointer-events: none;
}
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; } }
@media print {
  html, body { height: auto; overflow: visible; background: var(--bg); } body { display: block; }
  #deck { width: 100vw; height: auto; overflow: visible; container-type: inline-size; }
  .slide { position: relative; height: 56.25vw; opacity: 1; visibility: visible; break-after: page; }
  .fragment { opacity: 1; transform: none; } #slide-number, #notes, #chapters, #progress-track { display: none !important; }
}


/* ============================================================================
   V4 — the staged layouts and visual vocabulary of presentation2, rebuilt for
   beamer distance: larger type, softer geometry, 2px rules, calm motion.
   ========================================================================= */

:root {
  --accent:#55e6d2; --lime:#c5f77b; --violet:#bda2ff; --warm:#ffbd9b;
  --ink:#f4f2ec; --muted:#b8c3d0; --dim:#7d8b9b;
  --line:rgba(255,255,255,.13); --line-strong:rgba(255,255,255,.26);
  --panel:#14202c; --panel-soft:#16232fcc; --panel-line:rgba(255,255,255,.16);
  /* One rounding scale keeps every frame, card and chip visually related. */
  --r-xl:1.7cqw; --r-lg:1.15cqw; --r-md:.8cqw; --r-sm:.5cqw;
  --arrow-ink:#9fb0c2;
  --shadow-lift:0 1.6cqw 4cqw rgba(0,0,0,.45);
  --gradient-ink:linear-gradient(110deg,#ff9db4,#ffc45b 46%,#8ef0dd);
}

#deck {
  background:
    radial-gradient(ellipse at 80% 8%,rgba(29,72,86,.55),transparent 52%),
    radial-gradient(ellipse at 6% 92%,rgba(45,32,74,.5),transparent 50%),
    linear-gradient(140deg,#101a25,#070d15 72%);
}
#deck::before {
  content:""; position:absolute; inset:0; pointer-events:none; z-index:-1; opacity:.3;
  background-image:
    linear-gradient(rgba(170,200,224,.04) 1px,transparent 1px),
    linear-gradient(90deg,rgba(170,200,224,.04) 1px,transparent 1px);
  background-size:5cqw 5cqw;
}
.slide { transition:opacity 340ms ease,visibility 340ms; }
.slide:not(.active) *, .slide:not(.active) *::before, .slide:not(.active) *::after { animation-play-state:paused !important; }

.eyebrow { color:var(--accent); font-size:1.5cqw; }
/* The chapter label reads as a footnote, not a second headline above the title.
   It sits inside the bottom padding band, so it costs the content no height at
   all and the freed header space goes to the slide itself. The title slide keeps
   its label in the composition. */
.slide > header > .eyebrow, .slide > header > .header-copy > .eyebrow, .slide > .eyebrow {
  position:absolute; z-index:4; left:9cqw; bottom:1.3cqw; margin:0;
  font-size:1.35cqw; font-weight:650; color:var(--dim);
}
.hero-copy .eyebrow { position:static; font-size:1.7cqw; color:var(--accent); }
h2 { font-size:3.65cqw; }
.bottom-line { border-top-width:2px; border-color:var(--line-strong); }
.pill { border-radius:var(--r-md); }

.fragment { transition:opacity 380ms ease,transform 520ms cubic-bezier(.18,.78,.18,1); transform:translateY(.8cqw); }
.step-marker { position:absolute; width:0; height:0; pointer-events:none; }

/* Every framed picture keeps the same border, rounding and lift. */
.media-frame, .video-stack {
  border:2px solid var(--panel-line); border-radius:var(--r-xl); background:#070b11;
  box-shadow:var(--shadow-lift),0 0 3cqw rgba(85,230,210,.05); overflow:hidden;
}
.media-frame > video, .media-frame > img, .video-stack > video { border-radius:inherit; }
.video-stack > video { transition:opacity 560ms cubic-bezier(.2,.72,.2,1); }
.media-choice { border-radius:var(--r-md); }

/* 1 · Title ---------------------------------------------------------------- */
.v4-hero .hero-image {
  box-shadow:0 0 6cqw rgba(85,230,210,.1),0 2cqw 7cqw rgba(0,0,0,.5);
  animation:hero-breathe 9s ease-in-out infinite;
}
@keyframes hero-breathe { 50% { transform:translateY(-.6cqw); box-shadow:0 0 8cqw rgba(85,230,210,.16),0 2.6cqw 7cqw rgba(0,0,0,.55); } }

/* Chapter dividers: one breath between the main parts. No media, no build step,
   the number carries the page. */
.chapter-slide { justify-content:center; }
.chapter-card { display:flex; flex-direction:column; justify-content:center; gap:1.2cqw; }
.chapter-index {
  font-size:12cqw; font-weight:650; line-height:.9; letter-spacing:-.05em;
  background:var(--gradient-ink); background-clip:text; -webkit-background-clip:text; color:transparent;
}
.chapter-card h2 { font-size:6.4cqw; max-width:none; }
.chapter-line { font-size:3.23cqw; color:var(--muted); }

/* 2 · One sculpt, seven appearances. The look picker sits beside the title like
   every other switcher, so the clip keeps the whole stage. */
.gallery-stage { display:flex; align-items:center; justify-content:center; min-height:0; }
.gallery-stage .video-stack { height:100%; width:auto; max-width:100%; aspect-ratio:1; }

/* Generic building blocks. Slides compose these; slide-specific rules below
   only tune what genuinely differs. */
.cols { display:grid; gap:4cqw; align-items:center; min-height:0; }
.cols > * { min-width:0; min-height:0; }
.panel-card {
  position:relative; display:flex; flex-direction:column; justify-content:center; gap:1.8cqw;
  padding:3.4cqw; overflow:hidden;
  border:2px solid var(--line); border-radius:var(--r-xl);
  background:linear-gradient(150deg,rgba(23,36,50,.7),rgba(10,17,26,.55));
}
.panel-card .label { font-size:2.8cqw; font-weight:650; color:var(--accent); }
.panel-card h3 { font-size:3.34cqw; }
.panel-card > p:not(.label):not(.card-note) { font-size:2.8cqw; line-height:1.32; color:var(--muted); }
/* A closing remark under the card copy: same voice, one step quieter. */
.panel-card > .card-note {
  margin-top:.4cqw; padding-top:1.4cqw; border-top:2px solid var(--line);
  font-size:2.8cqw; line-height:1.3; color:var(--dim);
}
.panel-card.tone-lime { border-color:rgba(197,247,123,.32); }
.panel-card.tone-lime .label { color:var(--lime); }
.panel-card.tone-warm .label { color:var(--warm); }
.panel-card.tone-plain { border:0; background:none; padding:0; }

/* A row that carries more than one line of content. */
.explain-row.tall { flex:2.3; }
/* The shader's input slots, drawn to scale and morphing between two contracts.
   Only the widths change: a signal the second one adds grows out of zero where
   the first has none, and the slots the first leaves free collapse to nothing.
   The build step inside the strip drives all of it. */
.slot-bar { --look-size:9cqw; position:relative; display:flex; margin-top:1.4cqw; }
.slot-bar:has(.slot-look) { padding-left:calc(var(--look-size) + 1.6cqw); }
/* The look a contract belongs to, crossfaded by the same build step as the
   widths. It sits outside the flex flow so the slot percentages keep measuring
   the 128 slots and nothing else. */
.slot-look {
  position:absolute; left:0; top:50%; transform:translateY(-50%);
  width:var(--look-size); height:var(--look-size);
}
.slot-look img {
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  border-radius:50%; border:2px solid var(--line-strong); background:#080b0e;
  transition:opacity 320ms ease;
}
.slot-look .state-b { opacity:0; }
.slot-bar .slot {
  flex:0 0 var(--a); min-width:0; overflow:hidden;
  transition:flex-basis 820ms cubic-bezier(.4,0,.2,1);
}
/* The gap sits inside the clipped box, so a segment at zero slots leaves no
   sliver of padding behind. */
.slot-bar .slot-face { margin-left:.45cqw; }
.slot-bar .slot:first-of-type .slot-face { margin-left:0; }
.slot-face {
  height:100%; display:flex; flex-direction:column; justify-content:center; gap:.3cqw;
  padding:.8cqw; border-radius:var(--r-md);
  background:rgba(85,230,210,.12); border:2px solid rgba(85,230,210,.4);
}
.slot.free .slot-face { background:rgba(255,255,255,.03); border-color:var(--line); }
.slot-face b { position:relative; display:block; font-size:3.02cqw; font-weight:650; color:var(--accent); }
.slot.free .slot-face b { color:var(--dim); }
/* A vector arrow over the symbol; the combining character is missing from too
   many fonts to rely on. Unlike the connectors this one stays a glyph: a drawn
   bar of the same weight reads as a macron, not as an arrow, at this size. */
.vec { position:relative; padding:0 .06em; }
.vec::after {
  content:"→"; position:absolute; left:50%; top:-.62em; transform:translateX(-50%) scaleX(.72);
  font-size:.82em; line-height:1; pointer-events:none;
}
/* Over a display-sized symbol the arrow would float away from its letter. */
.explain-rows .row-key .vec::after { top:-.46em; font-size:.6em; }

/* The description wraps rather than shrinks: a narrow segment keeps its name. */
.slot-face small { font-size:2.8cqw; line-height:1.15; color:var(--muted); }
.slot-face .state-a, .slot-face .state-b { transition:opacity 320ms ease; }
.slot-face .state-b { position:absolute; left:0; top:0; opacity:0; }
.slot-step { position:absolute; width:0; height:0; }
.slot-bar:has(.slot-step.visible) .slot { flex-basis:var(--b); }
.slot-bar:has(.slot-step.visible) .state-a { opacity:0; }
.slot-bar:has(.slot-step.visible) .state-b { opacity:1; }

/* 3 · Keyword rows — permanent keys, progressively revealed explanations ---- */
.explain-rows { --key-width:22cqw; --row-gap:3.4cqw; display:flex; flex-direction:column; flex:1; min-height:0; width:100%; }
.explain-row {
  position:relative; flex:1; display:grid; grid-template-columns:var(--key-width) 1fr; gap:var(--row-gap);
  align-items:center; padding:.8cqw 0; min-height:6.4cqw;
  border-top:2px solid var(--line-strong);
}
.explain-row:last-child { border-bottom:2px solid var(--line-strong); }
.row-key { font-size:3.02cqw; font-weight:650; line-height:1.14; letter-spacing:-.03em; color:var(--accent); }
.row-copy { font-size:2.8cqw; line-height:1.22; max-width:58cqw; }

/* 4 · The classical pipeline keeps the presentation2 stage arrows ----------- */
.pipeline-rows .explain-row { min-height:7.2cqw; }
.pipeline-rows .row-key { justify-self:center; font-size:4.4cqw; letter-spacing:-.05em; }
.pipeline-rows .row-key sub { font-size:.52em; }
.pipeline-rows .explain-row:last-child .row-key {
  background:var(--gradient-ink); background-clip:text; -webkit-background-clip:text; color:transparent;
}
/* The stage arrow sits on the rule, as in presentation2. It is drawn rather than
   set as a ↓ glyph: a font arrow stays hairline-thin at projection distance. */
.pipeline-rows .explain-row:not(:last-child)::before,
.pipeline-rows .explain-row:not(:last-child)::after,
.explain-row.leads-on::before,
.explain-row.leads-on::after {
  content:""; position:absolute; left:var(--arrow-x,calc(var(--key-width) / 2)); bottom:0;
  transform:translate(-50%,50%); pointer-events:none;
}
/* Only the rule is erased, not a patch of background, so no halo appears. */
.pipeline-rows .explain-row:not(:last-child)::before,
.explain-row.leads-on::before {
  z-index:2; width:5cqw; height:.36cqw;
  background:linear-gradient(90deg,rgba(14,23,34,0),#0e1722 24%,#0e1722 76%,rgba(14,23,34,0));
}
.pipeline-rows .explain-row:not(:last-child)::after,
.explain-row.leads-on::after {
  z-index:3; width:2cqw; height:3.6cqw; background:var(--arrow-ink);
  clip-path:polygon(40% 0,60% 0,60% 57%,100% 57%,50% 100%,0 57%,40% 57%);
}
.result-row .row-key { color:var(--lime); }

/* 5 · One sample travelling through the lookup ----------------------------- */
.lookup-stage {
  position:relative; display:grid; grid-template-columns:36.5cqw 36.5cqw;
  justify-content:space-between; align-content:end; padding-top:6.4cqw;
}
.lookup-panel { position:relative; display:flex; flex-direction:column; gap:1.1cqw; min-width:0; }
.lookup-panel figcaption { font-size:3.1cqw; font-weight:600; text-align:left; letter-spacing:-.02em; }
.lookup-result figcaption { text-align:right; color:var(--lime); }
.lookup-canvas {
  position:relative; width:100%; aspect-ratio:38.2 / 31.4; overflow:visible;
  border:2px solid var(--panel-line); border-radius:var(--r-xl); background:#070b11;
  box-shadow:var(--shadow-lift);
}
.lookup-canvas > img { display:block; width:100%; height:100%; object-fit:cover; border-radius:inherit; }
.lookup-matcap { position:absolute; z-index:5; left:50%; top:0; width:20cqw; transform:translateX(-50%); gap:.7cqw; }
.lookup-matcap figcaption { text-align:center; font-size:2.8cqw; color:var(--accent); }
.lookup-matcap .lookup-canvas {
  width:100%; aspect-ratio:1; border:0; border-radius:50%;
  box-shadow:0 0 0 .42cqw #0b121b,0 1.4cqw 3.6cqw rgba(0,0,0,.45),0 0 3cqw rgba(85,230,210,.12);
}
/* Marker: a lime ring with a filled centre, exactly the presentation2 read.
   Slide 23 marks its sampled pixel with the same ring, so the two read alike. */
.lookup-ring, .sample-beacon {
  position:absolute; width:3cqw; aspect-ratio:1;
  border:.17cqw solid var(--lime); border-radius:50%; background:transparent;
  box-shadow:0 0 .7cqw rgba(197,247,123,.5);
}
.lookup-ring { z-index:6; }
.lookup-ring::after, .sample-dot {
  position:absolute; width:.42cqw; aspect-ratio:1; border-radius:50%; background:var(--lime);
  box-shadow:0 0 .4cqw rgba(197,247,123,.75);
}
.lookup-ring::after { content:""; left:50%; top:50%; transform:translate(-50%,-50%); }
.lookup-ring.fragment {
  opacity:0; transform:translate(-50%,-50%) scale(.55);
  transition:opacity 320ms ease,transform 440ms cubic-bezier(.2,.72,.2,1);
}
.lookup-ring.fragment.visible { opacity:1; transform:translate(-50%,-50%) scale(1); }
.lookup-normal .lookup-ring { left:68%; top:37%; }
.lookup-matcap .lookup-ring { left:14%; top:37%; }
.lookup-result .lookup-ring { left:68%; top:37%; }

/* 6 · Side-by-side motion — square pictures, nothing cropped --------------- */
.cinema-slide { gap:1.7cqw; }
.cinema-pair { display:flex; justify-content:center; align-items:stretch; gap:2.6cqw; min-height:0; }
.cinema-pair figure {
  position:relative; flex:0 0 auto; height:100%; aspect-ratio:1; max-width:44cqw; overflow:hidden;
  border:2px solid var(--panel-line); border-radius:var(--r-xl); box-shadow:var(--shadow-lift);
}
.cinema-pair .video-stack { width:100%; height:100%; aspect-ratio:auto; border:0; border-radius:0; box-shadow:none; }
.cinema-pair video { object-fit:contain; border-radius:0; }
.cinema-pair figcaption {
  position:absolute; z-index:3; inset:auto 0 0; padding:3cqw 1.8cqw 1.2cqw; font-size:2.84cqw;
  font-weight:600; text-align:left; background:linear-gradient(transparent,rgba(6,11,18,.94));
}
.cinema-pair .neural { border-color:rgba(85,230,210,.5); }
.cinema-pair .neural figcaption { color:var(--accent); }

/* 7 · Scope — two cards of equal weight. The second card is a build step, so it
   sits in a wrapper; without stretching that wrapper the card would only be as
   tall as its own text and the pair would read as unequal. */
.scope-slide .panel-card { min-height:30cqw; }
.scope-slide .cols > .fragment { display:flex; }
.scope-slide .cols > .fragment > .panel-card { flex:1; }
.scope-symbol { position:absolute; right:2cqw; top:.5cqw; font-size:14cqw; line-height:1; color:rgba(154,188,225,.09); }

/* 8 · Neural texturing → neural MatCaps ----------------------------------- */
.transfer-rows { display:flex; flex-direction:column; justify-content:center; flex:1; min-height:0; }
.transfer-row {
  flex:1; display:grid; grid-template-columns:22cqw 1fr; gap:3.4cqw; align-content:center;
  padding:2.6cqw 0; border-top:2px solid var(--line-strong);
}
.transfer-row:last-child { border-bottom:2px solid var(--line-strong); }
.transfer-row h3 { font-size:3.23cqw; color:var(--violet); }
.transfer-row:last-child h3 { color:var(--lime); }
.transfer-row p { font-size:2.84cqw; }
.mini-flow { display:flex; align-items:center; gap:1.6cqw; margin-top:1.6cqw; font-size:2.84cqw; }
.mini-flow b { width:2.8cqw; height:1.6cqw; }
.mini-network { border:2px solid rgba(189,162,255,.55); background:rgba(189,162,255,.09); border-radius:9cqw; padding:.7cqw 2.6cqw; color:var(--violet); }

/* 9 · The naive first lookup ---------------------------------------------- */
.initial-flow { display:grid; grid-template-columns:1fr auto 1.35fr auto .7fr; align-items:center; gap:2.4cqw; }
.input-pair { display:flex; flex-direction:column; gap:1.4cqw; }
/* Direct children only: the symbol carries a nested span for its arrow. */
.input-pair > span {
  display:flex; align-items:baseline; justify-content:center; gap:.9cqw;
  border:2px solid rgba(85,230,210,.4); background:rgba(85,230,210,.07);
  padding:1.9cqw 1.4cqw; border-radius:var(--r-lg); font-size:2.84cqw; text-align:center;
}
/* The symbol reads the way it does on 20, 21 and 27. */
.input-pair b { color:var(--accent); font-weight:650; }
/* Every connector between things is the pipeline's stage arrow laid on its
   side: same thin stem, same wide head, a quarter turn from the ↓ on 22-26.
   One silhouette for flow and causality, whichever way it points. */
.arrow-to, .flow-arrow, .mini-flow b {
  clip-path:polygon(0 40%,57% 40%,57% 0,100% 50%,57% 100%,57% 60%,0 60%);
  background:var(--arrow-ink);
}
.arrow-to {
  display:inline-block; width:.94em; height:.52em; margin:0 .18em; vertical-align:.06em;
}
.flow-arrow, .mini-flow b { display:block; flex:0 0 auto; font-size:0; color:transparent; }
.flow-arrow { width:3.6cqw; height:2cqw; }
.network-tile {
  border:2px solid rgba(189,162,255,.45); border-radius:var(--r-xl); padding:2.4cqw;
  background:linear-gradient(150deg,rgba(189,162,255,.11),rgba(19,28,41,0));
  display:flex; flex-direction:column; align-items:center; gap:1.6cqw;
}
.network-graph { width:19cqw; height:11cqw; overflow:visible; }
.network-edges { stroke:var(--violet); stroke-width:1; opacity:.22; }
.network-layer { fill:rgba(189,162,255,.4); stroke:var(--violet); stroke-width:1.5; animation:network-pulse 3.6s ease-in-out var(--stage) infinite; }
@keyframes network-pulse { 0%,65%,100% { fill:rgba(189,162,255,.4); } 25%,40% { fill:#d7c7ff; } }
.rgb-output { font-size:4.2cqw; background:var(--gradient-ink); background-clip:text; -webkit-background-clip:text; color:transparent; }

/* 10–18 · Explanation next to its illustration ---------------------------- */
.explanation-layout { display:grid; grid-template-columns:44cqw 1fr; gap:3.5cqw; align-items:center; min-height:0; }
.explanation-copy {
  padding-left:3.4cqw; border-left:2px solid var(--line-strong);
  display:flex; flex-direction:column; justify-content:center; gap:2.3cqw;
}
.explanation-copy h3 { font-size:3.34cqw; }
.explanation-copy p { font-size:2.84cqw; line-height:1.3; }
.formula { color:var(--accent); font-weight:600; font-size:3.02cqw !important; letter-spacing:-.02em; }

.frequency-visual {
  display:flex; flex-direction:column; gap:1.8cqw; padding:2.2cqw;
  border:2px solid var(--line); border-radius:var(--r-xl); background:rgba(13,23,37,.72);
}
.frequency-band { display:flex; align-items:center; gap:1.6cqw; color:var(--accent); }
.frequency-band:nth-child(2) { color:var(--violet); }
.frequency-band:nth-child(3) { color:var(--lime); }
.frequency-band b { font-size:3.02cqw; }
.frequency-band svg { width:100%; height:6.4cqw; }
.frequency-visual figcaption { font-size:2.8cqw; color:var(--muted); text-align:center; }

.angle-visual { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:1.6cqw; }
.direction-disc {
  width:25cqw; height:25cqw; position:relative; border:2px solid rgba(121,151,176,.55); border-radius:50%;
  background:radial-gradient(circle,rgba(24,60,69,.35),rgba(16,32,48,.2));
}
.direction-disc::after { content:""; position:absolute; left:50%; top:50%; width:.9cqw; aspect-ratio:1; border-radius:50%; background:var(--ink); transform:translate(-50%,-50%); }
.seam-line { position:absolute; left:0; right:50%; top:50%; border-top:2px dashed var(--warm); }
.direction-arm { position:absolute; left:50%; top:50%; width:43%; height:.18cqw; background:var(--accent); transform-origin:0 50%; animation:seam-sweep 5s ease-in-out infinite alternate; }
.direction-arm::after { content:""; position:absolute; right:0; top:50%; width:1.1cqw; aspect-ratio:1; border-top:.18cqw solid var(--accent); border-right:.18cqw solid var(--accent); transform:translateY(-50%) rotate(45deg); }
@keyframes seam-sweep { from { transform:rotate(165deg); } to { transform:rotate(195deg); } }
.angle-values { display:flex; justify-content:space-between; width:25cqw; color:var(--warm); font-size:3.02cqw; }
.angle-visual > p { text-align:center; color:var(--muted); font-size:2.8cqw; line-height:1.3; }
.direction-result { display:flex; align-items:center; gap:1.9cqw; }
.direction-result b { font-size:3.8cqw; color:var(--lime); }

/* Planned Blender captures stay visibly schematic, never a fake video. */
.shot-wireframe, .capture-frame {
  position:relative; display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:1.7cqw; text-align:center; padding:3cqw;
  border:2px solid var(--line); border-radius:var(--r-xl);
  background:linear-gradient(150deg,rgba(22,36,53,.6),rgba(11,22,36,.66));
}
.shot-wireframe { min-height:30cqw; }
.shot-wireframe h3 { font-size:3.12cqw; }
.shot-wireframe p, .capture-frame p { font-size:1.9cqw; color:var(--muted); }
.shot-corners, .capture-frame::before {
  content:""; position:absolute; inset:1.2cqw; pointer-events:none;
  border:2px dashed rgba(103,133,153,.28); border-radius:var(--r-lg);
}
.play-outline {
  width:5.6cqw; aspect-ratio:1; display:grid; place-items:center; padding-left:.35cqw;
  border:2px solid rgba(108,145,167,.75); border-radius:50%; color:var(--accent); font-size:2.8cqw; line-height:1;
  box-shadow:0 0 2.4cqw rgba(85,230,210,.1);
}
.capture-label { font-size:1.7cqw; font-weight:650; color:var(--dim); }

/* Recorded pairs and the still-unshot placeholders share one frame geometry, so
   a pair keeps its layout when its clips arrive. */
/* Both frames of a pair have to come out the same size, whatever the captions
   do. As a row of column flexboxes a two-line caption stole the height from its
   own column only, so one video ended up smaller than its partner. Subgrid puts
   every figure on the same two rows instead: the media row is a shared 1fr, the
   caption row is as tall as the tallest caption in the pair. */
.ablation-pair {
  --frame-size:38cqw;
  display:grid; grid-auto-flow:column; grid-auto-columns:var(--frame-size);
  grid-template-rows:minmax(0,1fr) auto;
  justify-content:center; align-items:stretch; gap:1.3cqw 3.2cqw; min-height:0;
}
.ablation-pair figure {
  display:grid; grid-row:span 2; grid-template-rows:subgrid;
  justify-items:center; align-items:center; min-height:0;
}
/* The frame stays square whichever way the room runs out. Height-driven, so it
   never overflows a short slide, and capped at the column width, so a slide with
   spare height (short title, no bottom line) cannot stretch it into a portrait
   box with letterboxed video. */
.ablation-pair .media-frame, .ablation-pair .video-stack, .capture-frame {
  height:100%; min-height:0; width:auto; max-width:100%;
  max-height:var(--frame-size, 100%); aspect-ratio:1; align-self:center;
}
.ablation-pair .neural .media-frame, .ablation-pair .neural .video-stack { border-color:rgba(85,230,210,.5); }
/* 13 · The detail pair keeps a matched close-up of frame 0 in the same box.
   The still is rendered at 3072² and cropped, so the zoom is real resolution
   rather than an upscaled video frame. */
.zoom-frame > .zoom-still {
  position:absolute; inset:0; width:100%; height:100%; object-fit:contain;
  opacity:0; transition:opacity 320ms ease; pointer-events:none;
}
.ablation-slide[data-choice="zoom"] .zoom-frame > .zoom-still { opacity:1; }

/* 34 · The matched still. Every frame holds the same camera, so the switcher can
   scale all the pictures about the same point at once and the audience compares
   the same patch of sphere in each column. The two-frame width stays here for
   any future pair; the three-frame slides override it below, after `.trio`. */
.zoom-pair { --frame-size:34cqw; --zoom:1; --zoom-x:50%; --zoom-y:50%; }
.zoom-pair .media-frame > img {
  transition:transform 420ms cubic-bezier(.4,0,.2,1), transform-origin 420ms cubic-bezier(.4,0,.2,1);
  transform-origin:var(--zoom-x) var(--zoom-y); transform:scale(var(--zoom));
}
/* Three steps, the same two numbers in every column, so the audience always
   compares the same patch of sphere. At 3x the 1536-pixel stills are still being
   scaled down on a 1920 projector; the tele step magnifies past that, equally in
   every column. */
.v4-fidelity[data-choice="zoom"] .zoom-pair { --zoom:3; }
.v4-fidelity[data-choice="tele"] .zoom-pair { --zoom:6; }
/* 35 · The colour-shift trio is read at its highlight rather than at its
   centre: the soft edge of the highlight and the rim band are where the
   reconstruction actually parts from the reference. The tele step moves into
   the lower right of that view, onto the edge itself. */
/* A zoom origin is the point the picture is scaled about, not the centre of
   what ends up on screen: at factor s the visible band is o·(1−1/s) … +1/s, so
   the view centre lands at o·(1−1/s) + 1/(2s). Both steps below were chosen by
   that arithmetic and then checked against the reference PNG. */
.zoom-top-left[data-choice="zoom"] .zoom-pair { --zoom-x:27%; --zoom-y:24%; }
/* The tele step really does sit in the lower right of the highlight view now —
   it used to land almost on top of it. The highlight's soft edge sweeps through
   the upper left corner and gives way to the checkerboard and its crosses,
   which is the transition worth magnifying. */
.zoom-top-left[data-choice="tele"] .zoom-pair { --zoom-x:42%; --zoom-y:40%; }
/* 36 · Blue Sparkle is read at the tall church windows left of centre — their
   mullion grid is the finest structure this look carries, and it is where the
   narrower network gives up first. 'Windows' frames both windows whole; 'Tele'
   drops to their lower halves and the floor beneath, where the grid meets a
   large smooth surface. */
.zoom-windows[data-choice="zoom"] .zoom-pair { --zoom-x:26%; --zoom-y:37%; }
.zoom-windows[data-choice="tele"] .zoom-pair { --zoom-x:31%; --zoom-y:50%; }
/* Backup · Blood Cell is read at the one highlight cluster below the centre.
   The rest of this view is a large soft gradient with nothing to hold on to,
   which is exactly why the narrower network bands there. */
.zoom-dimple[data-choice="zoom"] .zoom-pair { --zoom-x:55%; --zoom-y:62%; }
.zoom-dimple[data-choice="tele"] .zoom-pair { --zoom-x:58%; --zoom-y:66%; }
/* The world-direction slides switch both columns to another orbit at once,
   crossfaded like the look pickers elsewhere. */
.ablation-slide:has(.orbit-dock) { gap:1.4cqw; }
.orbit-dock { display:flex; justify-content:center; align-items:center; gap:1.4cqw; }
.orbit-dock .media-choice {
  padding:.6cqw 2cqw; border:2px solid var(--line); border-radius:9cqw;
  background:rgba(255,255,255,.03); font-size:2.8cqw; font-weight:600;
  transition:border-color 180ms,background 180ms,transform 180ms;
}
.orbit-dock .media-choice:hover { border-color:var(--line-strong); background:rgba(255,255,255,.06); transform:translateY(-.2cqw); }
.orbit-dock .media-choice.active { border-color:var(--accent); background:rgba(85,230,210,.1); color:var(--accent); }
/* Parked beside the title, the switch costs no vertical space at all, so the
   two frames below can use the full height of the slide. */
/* The copy starts at the top of the header, so a title sits exactly where it
   does on a slide without buttons; the taller control is nudged up to centre on
   the title line instead of pushing it down. */
header.with-aside { display:flex; align-items:flex-start; justify-content:space-between; gap:3cqw; }
header.with-aside .header-copy { min-width:0; }
header.with-aside h2 { max-width:none; }
.header-aside { flex:0 0 auto; margin-top:-.5cqw; }
.header-aside .orbit-dock { justify-content:flex-end; gap:1cqw; }
.header-aside .orbit-dock .media-choice { padding:.45cqw 1.3cqw; font-size:2.8cqw; }
.ablation-pair .neural .capture-frame { border-color:rgba(85,230,210,.45); }
/* Three-way variant: the frames are width-driven so a third column fits. */
/* The trio borrows from the side margin so three frames still read large, and
   sits at the bottom of its box so the orbit switch stays close under it.
   The frames keep the height-driven sizing of the pair, capped at the column
   width by --frame-size. Forcing them to the full column width instead turned
   them into wide boxes with bars beside the picture whenever the row was
   shorter than it was wide — a title or a caption that wraps is enough. */
.ablation-pair.trio { --frame-size:var(--row-frame); margin-inline:-2.5cqw;
  /* The row gap is the pair's, not a wider one of its own: it is what is left
     over for the pictures, so a trio with more air under its frames ended up
     with smaller ones than the pair on the next slide. */
  gap:1.3cqw 2cqw; align-items:flex-end; }
.ablation-pair.trio figure { flex:0 0 var(--frame-size); }
.ablation-pair.trio .capture-frame, .ablation-pair.trio .media-frame, .ablation-pair.trio .video-stack { flex:0 0 auto; width:auto; max-width:100%; aspect-ratio:1; }
/* One caption in a trio can wrap where the others do not. Pinning them to the
   top of the shared caption row keeps their first lines on one baseline. */
.ablation-pair.trio figcaption { font-size:2.8cqw; align-self:start; }
.ablation-pair.trio figcaption sub { font-size:.68em; }
/* 34–36 · The matched stills went from two frames to three: reference, narrow
   network, wide network. They deliberately take NO frame size of their own: the
   deck steps straight from these three onto the capacity clips of 37–39, and a
   still that is a hair smaller than the video replacing it reads as a jump. All
   six slides have the same room, so they all sit at the trio's size and the
   pictures stay put across the cut. The zoom steps are unchanged — all three
   columns scale by the same factor about the same point. */
.ablation-pair figcaption { font-size:2.97cqw; font-weight:600; text-align:center; }
/* 37 · One caption there names a look and a width and wraps to two lines.
   Pinning both captions to the top of the caption row keeps their first lines
   on one baseline instead of centring the short one. */
.ablation-pair.capacity figcaption { align-self:start; }
/* 37 and backup 45 hold two frames where 34-36 and 38-39 hold three, but the
   deck runs straight through all of them, so both take the same picture size:
   --row-frame, set once on :root. Left to themselves the pair ran about 11px
   taller than the trio and therefore reached further down the slide, which read
   as the pictures jumping on the cut. The value sits just under the height these
   rows actually have, so it binds on every one of them instead of letting each
   slide find its own; the pair simply keeps the wider side margin. */
.ablation-pair.capacity { --frame-size:var(--row-frame); }
.ablation-pair .neural .ablation-pair .neural figcaption { color:var(--accent); }

/* 13 / 17 · The geometric coordinates, on one board shown twice. The first
   appearance holds the second card back but keeps its space, so the board does
   not shift when it returns filled in. */
.panel-card.pending { visibility:hidden; }
/* The board carries little copy, so the card headline stays a clear step below
   the slide title instead of competing with it. */
.geometry-slide .panel-card { gap:1.1cqw; padding:2.4cqw; }
.geometry-slide .panel-card h3 { font-size:3.45cqw; }
.geometry-slide .panel-card > p:not(.label):not(.card-note) { font-size:2.8cqw; }

/* 15 · Problem over fix, carried by the same stage arrow as the pipelines. */
.direction-slide .explanation-layout { grid-template-columns:31cqw 1fr; gap:4cqw; }
.seam-rows { --key-width:17cqw; --row-gap:2.4cqw; }
.seam-rows .explain-row { min-height:0; }
.seam-rows .row-key { font-size:3.02cqw; letter-spacing:-.02em; }
.seam-rows .explain-row:last-child .row-key { background:none; color:var(--lime); }
.seam-rows .row-copy { font-size:2.8cqw; line-height:1.34; color:var(--muted); max-width:44cqw; }
.seam-rows .row-copy b { display:block; margin-bottom:.5cqw; font-weight:650; color:var(--ink); }
.seam-rows .explain-row:last-child .row-copy b { color:var(--lime); }

/* 18 · Signal families ----------------------------------------------------- */
.signals-overview .row-key { font-size:3.66cqw; justify-self:center; }
.signals-overview .row-key sub { font-size:.62em; }

/* 19 · Camera roll, recorded against the same render rotated afterwards. The
   frames stay the square ones the rest of the deck uses: seeing the right image
   turn inside its frame, corners and all, is the whole point. */
.roll-pair img { transform-origin:50% 50%; will-change:transform; }
.roll-conclusion { flex:0 0 auto; display:flex; flex-direction:column; gap:.35cqw; padding-top:.9cqw;
  border-top:2px solid var(--line-strong); }
.roll-conclusion p { font-size:2.8cqw; line-height:1.18; color:var(--muted); }
.roll-conclusion b { color:var(--fg); font-weight:650; }
.roll-conclusion .accent b { color:var(--accent); }

/* 19 · The fixed card shrinks into a function of selected inputs ----------- */
/* One timing for the whole shrink: the box, the picture inside it and the type
   have to travel on the same curve, or the image drifts out of its frame. */
.function-lab { position:relative; height:100%; --lab-time:820ms; --lab-ease:cubic-bezier(.18,.78,.18,1); }
.texture-origin {
  position:absolute; left:12cqw; top:3.5cqw; width:67cqw; height:29cqw;
  display:flex; align-items:center; justify-content:space-between; gap:2cqw; padding:2.6cqw;
  border:2px solid var(--line-strong); border-radius:var(--r-xl);
  background:linear-gradient(140deg,rgba(36,51,67,.85),rgba(14,25,38,.95));
  box-shadow:var(--shadow-lift);
  transition:width var(--lab-time) var(--lab-ease),height var(--lab-time) var(--lab-ease),
             left var(--lab-time) var(--lab-ease),top var(--lab-time) var(--lab-ease),
             padding var(--lab-time) var(--lab-ease);
}
.texture-origin > div { display:flex; flex-direction:column; gap:1.5cqw; transition:gap var(--lab-time) var(--lab-ease); }
.texture-origin .label { font-size:2.8cqw; font-weight:650; color:var(--accent); transition:font-size var(--lab-time) var(--lab-ease); }
.origin-formula { font-size:3.02cqw; letter-spacing:-.04em; white-space:nowrap; transition:font-size var(--lab-time) var(--lab-ease); }
.texture-origin img { width:23cqw; height:23cqw; border-radius:50%; object-fit:cover; transition:width var(--lab-time) var(--lab-ease),height var(--lab-time) var(--lab-ease); }
.lab-evolution { position:absolute; inset:0; pointer-events:none; transition:opacity 480ms ease 180ms,transform 640ms cubic-bezier(.18,.78,.18,1) 150ms; }
.lab-evolution.visible { pointer-events:auto; }
.function-machine {
  position:absolute; top:12.6cqw; left:0; width:46cqw; display:flex; flex-direction:column; gap:1.3cqw;
  padding:1.9cqw 2.1cqw; border:2px solid rgba(189,162,255,.4); border-radius:var(--r-xl);
  background:linear-gradient(160deg,rgba(189,162,255,.1),rgba(16,25,38,.3));
}
.function-machine > .label { color:var(--lime); font-size:2.8cqw; font-weight:650; }
.function-signature { font-size:3.02cqw; white-space:nowrap; letter-spacing:-.04em; }
.function-signature b { font-weight:500; color:var(--lime); }
.signal-grid { display:grid; grid-template-columns:1fr 1fr; gap:1.1cqw; align-items:start; }
/* Every signal keeps its place. The selection only changes how a box reads:
   the chosen ones light up, the rest stay grey and half transparent, so the
   full vocabulary is on the wall and the card never changes size. */
.signal-input {
  display:flex; min-height:6.6cqw; align-items:center; gap:1.1cqw; padding:1.2cqw 1.4cqw;
  border:2px solid var(--line); border-radius:var(--r-lg); background:rgba(255,255,255,.03);
  opacity:.4; filter:saturate(.15);
  transition:opacity 420ms ease, filter 420ms ease, border-color 420ms ease, background-color 420ms ease;
}
.signal-input.active {
  opacity:1; filter:none;
  border-color:rgba(85,230,210,.45); background:rgba(85,230,210,.07);
}
.signal-input b { color:var(--accent); font-size:3.02cqw; white-space:nowrap; }
.signal-input b sub { font-size:.68em; }
.signal-input span { font-size:2.8cqw; }
.function-machine .choice-title { font-size:3.02cqw; color:var(--ink); }
.lab-demo { position:absolute; right:0; top:0; width:39cqw; }
.lab-demo .video-stack { width:39cqw; height:39cqw; }
.look-dock { display:flex; align-items:center; justify-content:center; gap:.8cqw; }
.look-dock .media-choice {
  padding:.32cqw; border-radius:50%; border:2px solid var(--line); background:#16222f;
  transition:transform 180ms,border-color 180ms,box-shadow 180ms;
}
.look-dock .media-choice img { width:4cqw; height:4cqw; border-radius:50%; }
/* Beside the title the dock carries no caption and no spacing of its own. */
.header-aside .look-dock { justify-content:flex-end; }
.look-dock .media-choice:hover { transform:translateY(-.3cqw); border-color:var(--line-strong); }
.look-dock .media-choice.active { border-color:var(--lime); box-shadow:0 0 0 .2cqw rgba(197,247,123,.16); }
.function-lab-slide:has(.lab-evolution.visible) .texture-origin { top:0; left:0; width:46cqw; height:11cqw; padding:1.4cqw 1.9cqw; }
.function-lab-slide:has(.lab-evolution.visible) .texture-origin img { width:8cqw; height:8cqw; }
.function-lab-slide:has(.lab-evolution.visible) .texture-origin > div { gap:.7cqw; }
.function-lab-slide:has(.lab-evolution.visible) .texture-origin .label { font-size:2.8cqw; }
.function-lab-slide:has(.lab-evolution.visible) .origin-formula { font-size:2.8cqw; }

/* 20 · The implementation pipeline reuses the classical stage rows of slide 4. */

.process-rows .row-key { font-family:inherit; font-size:3.45cqw; letter-spacing:-.03em; }
.process-rows .explain-row:last-child .process-rows .explain-row:last-child .row-key { background:none; color:var(--lime); }

/* 21 · One sphere becomes many views -------------------------------------- */
.training-layout { display:grid; grid-template-columns:1fr 34cqw; gap:3.5cqw; align-items:center; min-height:0; }
.training-copy .explain-rows { --key-width:17cqw; --row-gap:2.2cqw; }
.training-copy .explain-row { min-height:9.5cqw; }
.training-copy .row-key { font-size:3.02cqw; }
.training-copy .row-copy { font-size:2.8cqw; }
.training-visual { width:34cqw; height:34cqw; position:relative; justify-self:end; }
.training-tile {
  position:absolute; width:48.5%; height:48.5%; overflow:hidden;
  border:2px solid var(--panel-line); border-radius:var(--r-lg); box-shadow:0 .9cqw 2.2cqw rgba(0,0,0,.3);
  transition:width 820ms cubic-bezier(.18,.78,.18,1),height 820ms cubic-bezier(.18,.78,.18,1),
             opacity 620ms ease,transform 820ms cubic-bezier(.18,.78,.18,1);
}
.training-tile img { width:100%; height:100%; display:block; object-fit:cover; border-radius:inherit; }
.tile-0 { left:0; top:0; width:100%; height:100%; z-index:3; border-radius:var(--r-xl); }
.tile-1 { right:0; top:0; } .tile-2 { left:0; bottom:0; } .tile-3 { right:0; bottom:0; }
.training-tile:not(.tile-0) { opacity:0; transform:scale(.75); }
.training-views-morph:has(.explain-row:nth-child(2) .visible) .tile-0 { width:48.5%; height:48.5%; border-radius:var(--r-lg); }
.training-views-morph:has(.explain-row:nth-child(2) .visible) .training-tile:not(.tile-0) { opacity:1; transform:none; transition-delay:100ms; }

/* 22 · Two sources, told with the keyword rows the rest of the deck uses.
   The column labels are labels, not a second heading level competing with h2. */
.metadata-layout { display:grid; grid-template-columns:29cqw 1fr; gap:4.5cqw; min-height:0; align-items:stretch; }
.metadata-layout .label { font-size:2.8cqw; font-weight:650; color:var(--accent); }
.metadata-image { display:flex; flex-direction:column; gap:1.4cqw; min-height:0; }
.metadata-image img {
  width:100%; aspect-ratio:1; object-fit:cover;
  border:2px solid var(--panel-line); border-radius:var(--r-xl); box-shadow:var(--shadow-lift);
}
.metadata-image figcaption { text-align:left; font-size:2.8cqw; font-weight:400; line-height:1.3; color:var(--muted); }
.metadata-text {
  display:flex; flex-direction:column; gap:1.4cqw; min-height:0;
  border-left:2px solid var(--line-strong); padding-left:3.6cqw;
}
.metadata-text .label { color:var(--lime); }
/* The right column quotes the metadata file itself, and only the fields the
   trainer reads. Two build steps, one per field group. */
.metadata-excerpt {
  flex:0 1 auto; min-height:0; margin:0; display:flex; flex-direction:column; gap:1.4cqw;
  font-family:inherit; font-size:2.8cqw; line-height:1.28; white-space:pre;
  padding:1.6cqw 2.2cqw; border:2px solid var(--line); border-radius:var(--r-lg);
  background:rgba(8,13,20,.55);
}
.metadata-excerpt b { font-weight:400; color:var(--muted); }
.metadata-excerpt b::first-line { color:var(--lime); font-weight:650; }
.metadata-caption { font-size:2.8cqw; line-height:1.3; color:var(--muted); }

/* 23 · One pixel, one marker, one normal — the sample stays singular. ------ */
.sampling-layout { display:grid; grid-template-columns:37cqw 1fr; gap:4cqw; align-items:center; min-height:0; }
.sample-photo {
  position:relative; width:37cqw; height:37cqw; overflow:hidden;
  border:2px solid var(--panel-line); border-radius:var(--r-xl); box-shadow:var(--shadow-lift);
}
.sample-photo > img { width:100%; height:100%; object-fit:cover; display:block; }
/* This slide carries a far heavier arrow than the donut lookup, so the marker is
   scaled up to hold its own next to it. Depth order: the ring sits behind the
   arrow, the sampled point itself stays in front of it. */
.sample-beacon, .sample-dot {
  left:55%; top:39%; opacity:0; transform:translate(-50%,-50%) scale(.55);
  transition:opacity 300ms ease,transform 440ms cubic-bezier(.2,.72,.2,1);
}
.sample-beacon { z-index:2; width:3.7cqw; border-width:.19cqw; box-shadow:0 0 1cqw rgba(197,247,123,.45); }
/* At least as wide as the arrow base (21 + 2.4 contour units of a 300-unit
   viewBox drawn at 16.5cqw = 1.29cqw), so the shaft grows out of the point. */
.sample-dot { z-index:4; width:1.35cqw; box-shadow:0 0 .7cqw rgba(197,247,123,.8); }
/* The normal starts at the centre of the marker and points out of the sphere.
   The marked pixel sits 0.24 radii from the centre, so the normal is only 14deg
   off the view axis: its projection is short on purpose. It is drawn about
   1.25 sphere radii long in 3D, which foreshortens to under a third of that. */
.sample-normal {
  position:absolute; z-index:3; left:55%; top:39%; width:16.5cqw; height:16.5cqw;
  transform:translate(-50%,-50%) scale(.3); opacity:0; overflow:visible;
  filter:drop-shadow(0 .2cqw .45cqw rgba(4,10,18,.7));
  transition:opacity 280ms ease,transform 500ms cubic-bezier(.2,.72,.2,1);
}
/* Each visual is tied to the row that explains it, not to a step of its own. */
.sample-build-slide:has(.explain-row:nth-child(1) .row-copy.visible) .sample-beacon,
.sample-build-slide:has(.explain-row:nth-child(1) .row-copy.visible) .sample-dot {
  opacity:1; transform:translate(-50%,-50%) scale(1);
}
.sample-build-slide:has(.explain-row:nth-child(2) .row-copy.visible) .sample-normal {
  opacity:1; transform:translate(-50%,-50%) scale(1);
}
.sampling-steps { display:flex; flex-direction:column; min-height:0; }
.sampling-steps .explain-rows { --key-width:13cqw; --row-gap:1.6cqw; --arrow-x:3.6cqw; }
.sampling-steps .explain-row { min-height:9.1cqw; }
.sampling-steps .row-key { font-size:3.02cqw; }
.sampling-steps .row-copy { font-size:2.8cqw; }

/* 24 · Encode, predict, correct ------------------------------------------- */
.learning-input, .rgb-tile { display:flex; flex-direction:column; align-items:center; gap:1.2cqw; }
.feature-bars { display:flex; align-items:end; height:9cqw; gap:.45cqw; padding:1cqw; }
.feature-bars i { width:.65cqw; height:var(--h); border-radius:9cqw; background:var(--accent); transform-origin:bottom; animation:feature-rise 850ms ease var(--delay) both; }
@keyframes feature-rise { from { transform:scaleY(.1); opacity:.2; } to { transform:scaleY(1); opacity:1; } }
.rgb-channels { display:flex; gap:.8cqw; padding:1.6cqw 0; }
.rgb-channels i { width:2.2cqw; height:6.4cqw; border-radius:9cqw; background:#fc7292; }
.rgb-channels i:nth-child(2) { background:var(--lime); }
.rgb-channels i:nth-child(3) { background:#7188ff; }

/* 24 · The forward pass reads top to bottom on the left, with the heading first
   and its picture beside it; how the run is fitted stays in its own column. */
.learning-layout { display:grid; grid-template-columns:1fr 28cqw; gap:3.2cqw; min-height:0; align-items:stretch; }
.learning-rows { --key-width:16cqw; --row-gap:2.2cqw; }
.learning-rows .explain-row { min-height:0; }
.learning-rows .row-key { font-family:inherit; font-size:3.45cqw; letter-spacing:-.03em; }
.learning-rows .explain-row:last-child .row-key { background:none; color:var(--lime); }
/* All three pictures occupy the same box, so the rows line up and the captions
   start at the same x. Each graphic fills that box rather than sitting in it. */
.learning-figure { display:grid; grid-template-columns:15cqw 1fr; align-items:center; gap:2.4cqw; }
.learning-figure p { font-size:2.97cqw; line-height:1.3; color:var(--muted); }
.learning-figure .feature-bars,
.learning-figure .network-graph,
.learning-figure .rgb-channels { width:15cqw; height:8.6cqw; padding:0; margin:0; }
.learning-figure .feature-bars { justify-content:space-between; gap:0; }
.learning-figure .feature-bars i { flex:1 1 0; margin:0 .2cqw; }
.learning-figure .rgb-channels { display:flex; gap:1.2cqw; }
.learning-figure .rgb-channels i { flex:1 1 0; width:auto; height:100%; }
.training-aside {
  display:flex; flex-direction:column; justify-content:center; gap:3cqw;
  padding-left:3.2cqw; border-left:2px solid var(--line-strong);
}
.train-point h3 { font-size:3.45cqw; color:var(--violet); margin-bottom:.9cqw; letter-spacing:-.03em; }
.train-point p { font-size:2.97cqw; line-height:1.3; color:var(--muted); }

/* 25 · The checkpoint contract -------------------------------------------- */
.v4-checkpoint .function-block {
  padding:3cqw; border:2px solid rgba(85,230,210,.45); border-radius:var(--r-xl);
  background:linear-gradient(150deg,rgba(23,39,56,.75),rgba(12,21,32,.6));
}
.v4-checkpoint .function-block .label { color:var(--accent); font-weight:650; font-size:2.8cqw; }
.v4-checkpoint .split { align-items:center; gap:4cqw; }
.v4-checkpoint .function-block { justify-content:center; gap:2.1cqw; padding:3.8cqw 3.4cqw; }
.v4-checkpoint .function-block h3 { font-size:3.55cqw; }
.v4-checkpoint .function-block .muted { font-size:3.04cqw; line-height:1.3; }
.v4-checkpoint .stack { justify-content:center; gap:2.4cqw; }
.v4-checkpoint .statement { font-size:4.4cqw; }
.v4-checkpoint .stack .muted { font-size:3.04cqw; line-height:1.32; }
/* The rows on this slide carry a short line above a full-width strip, so the
   global reading-width cap only forces a pointless break. */
.v4-checkpoint .row-copy { max-width:none; }

/* A size kept for scale, not recommended: one step back, still readable. */
.data-table tr.dim td { color:var(--dim); }

/* 27–28 · Tables ---------------------------------------------------------- */
/* 32 and 33 are the same table twice with different numbers in it, and the deck
   steps straight from one to the other. Left to size themselves, the columns
   follow their own content — "RTX 4060 Laptop" is wider than "Parameters", so
   the middle boundary jumps sideways on the cut and the eye reads a new table
   instead of new values. A fixed geometry, shared by both, holds every column
   edge still; the widest cell either slide has ("Full MLP file size") fits the
   37% column with room to spare. */
.v4-table .data-table { border-collapse:separate; border-spacing:0; table-layout:fixed; }
.v4-table .data-table col.model { width:26%; }
.v4-table .data-table col.value { width:37%; }
.v4-table .data-table th { padding:1.2cqw 1.4cqw; border-bottom:2px solid var(--line-strong); }
.v4-table .data-table td { padding:1.4cqw; border-bottom:2px solid var(--line); }
.v4-table .data-table tbody tr:last-child td { border-bottom:0; }

/* 29 · The selected look and the numbers that belong to it ---------------- */
.model-explorer { display:flex; gap:3.4cqw; align-items:stretch; min-height:0; }
.model-dashboard { flex:1 1 0; min-width:0; display:flex; flex-direction:column; justify-content:center; gap:1.3cqw; }
.model-dashboard .choice-title { font-size:3.23cqw; color:var(--accent); min-height:3.4cqw; letter-spacing:-.03em; }
.model-stats { display:grid; grid-template-columns:1fr 1fr; gap:1.1cqw; }
.model-stats > div {
  display:flex; flex-direction:column; gap:.7cqw; padding:1.5cqw 1.8cqw;
  border:2px solid var(--line); border-radius:var(--r-lg); background:rgba(23,39,55,.62);
}
.model-stats span { font-size:2.8cqw; color:var(--muted); }
.model-stats strong { font-size:3.12cqw; line-height:1.1; font-weight:550; letter-spacing:-.04em; }

.model-preview { flex:0 0 auto; display:flex; flex-direction:column; justify-content:center; min-height:0; }
.model-preview .video-stack { height:94%; width:auto; aspect-ratio:1; align-self:center; }

/* 30 / 32 · Two pictures of equal weight ---------------------------------- */
.pair { display:flex; justify-content:center; align-items:stretch; gap:3.4cqw; min-height:0; }
.pair figure { flex:0 0 34cqw; display:flex; flex-direction:column; align-items:center; gap:1.3cqw; min-height:0; }
.pair .media-frame, .pair .video-stack { flex:1 1 0; min-height:0; width:auto; aspect-ratio:1; }
.pair figcaption { font-size:2.97cqw; font-weight:600; }

/* 34 · Takeaways beside the live demo ------------------------------------- */
.summary-stage { display:grid; grid-template-columns:1fr 39cqw; gap:3.4cqw; align-items:center; min-height:0; }
.summary-copy { display:flex; flex-direction:column; gap:1.8cqw; }
.summary-line { font-size:4cqw; letter-spacing:-.04em; line-height:1.12; }
.summary-copy .choice-title { border-top:2px solid var(--line-strong); padding-top:1.8cqw; margin-top:1.4cqw; font-size:3.02cqw; color:var(--muted); }
.summary-demo .video-stack { width:39cqw; height:39cqw; }

/* 35 · Closing ------------------------------------------------------------ */
.closing-stage { display:grid; grid-template-columns:1fr 37cqw; gap:3.5cqw; align-items:center; min-height:0; }
.closing-thesis { font-size:4.5cqw; line-height:1.05; letter-spacing:-.04em; }
.closing-details { margin-top:2.2cqw; font-size:3.1cqw; color:var(--muted); line-height:1.3; }
.closing-video {
  width:37cqw; height:37cqw; overflow:hidden; border-radius:50%; justify-self:end;
  border:2px solid rgba(197,247,123,.35);
  box-shadow:0 0 6cqw rgba(197,247,123,.1),0 2cqw 5cqw rgba(0,0,0,.45);
}
.closing-video video { width:100%; height:100%; object-fit:cover; }

/* Backups ----------------------------------------------------------------- */
.v4-backup .equation { }
.source-list li { border-top-width:2px; border-color:var(--line-strong); }
/* The source list grew past what one column holds at the deck's minimum type
   size. Two columns give every entry its own line of description instead of
   shrinking the text below what the back row can read. */
.v4-backup .source-list {
  display:grid; grid-template-columns:1fr 1fr; column-gap:4cqw; row-gap:1.2cqw;
  align-content:center;
}
.v4-backup .source-list li { padding-top:1cqw; }
.v4-backup .source-list p { margin-top:.4cqw; }

@media (prefers-reduced-motion:reduce) { *,*::before,*::after { animation:none !important; transition:none !important; } }
