/* What only this talk's slides use; the deck's look is ../deck.css. Rules are scoped by slide id. The content area is
   1152 × 628 px under a one-line title; nothing goes below the footer band (676 px). */

.reveal figure { margin: 0; }
/* Talk-wide colors beyond the page's glimpse, canvas and policy: neuro-AI models (#timeline). */
.reveal { --neuro-ai: #c026d3; }
.reveal figure img { display: block; }
/* A slide's closing statement: centered, bold, one line where it can. */
.reveal .claim { margin-top: 26px; font-size: 32px; font-weight: 750; letter-spacing: -.015em; text-align: center; }
/* The title (the speakers) and the paper (its authors, NeurIPS, a QR code to arXiv) share portraits and logos. */
/* The title's background is the section's data-background-gradient, which reveal.js paints over the whole window so
   no page white shows at any window shape. Its colors are --glimpse and --canvas, written out because the attribute
   is applied outside the slide. */
#title .layout { position: absolute; inset: 0; display: grid; grid-template-columns: 1fr 440px; grid-template-rows: 100%; color: #fff; }
#title .name { display: flex; flex-direction: column; justify-content: center; gap: 44px; padding: 0 48px 0 var(--slide-pad-x); }
#title h1 { font-size: 60px; color: #fff; text-shadow: 0 2px 28px rgb(3 6 14 / .35); }
#title .name .authors, #title .name .logos { justify-content: start; }
/* The affiliations in their own colors, on the gradient, under a hairline. */
#title .logos { width: max-content; gap: 40px; padding-top: 30px; border-top: 1px solid rgb(255 255 255 / .25); }
/* Portrait frames: the brand's blue to red, top to bottom as the background runs, at full saturation. */
#title .authors img { padding: 6px; background: linear-gradient(to bottom, hsl(212 100% 69%), hsl(2 100% 69%)); }
#title .authors figcaption { color: rgb(255 255 255 / .92); text-shadow: 0 1px 14px rgb(3 6 14 / .35); }
#title .logos .wordlogo { display: flex; align-items: center; gap: 12px; font-size: 28px; font-weight: 800; letter-spacing: -.02em; color: #fff; white-space: nowrap; }
#title .logos .wordlogo img { height: 42px; width: 42px; }
/* Lamarck Labs' name as its site sets it: Open Sans Bold, uppercase, tracked (assets/fonts). */
@font-face { font-family: "Open Sans"; font-weight: 700; font-display: block; src: url("assets/fonts/open-sans-700-latin.woff2") format("woff2"); }
#title .logos .wordlogo.lamarck { font-family: "Open Sans", var(--sans); font-size: 22px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; }
#title .teaser-panel { display: grid; place-items: center; }
/* The teaser (title-teaser.js): the scene with the viewpoint gliding and each glimpse taken with a flash, the canvas
   below crossfading to its state after each glimpse. */
#title title-teaser { display: grid; gap: 16px; transition: opacity .6s ease; }
#title title-teaser.faded { opacity: 0; }
#title title-teaser figure { position: relative; width: 300px; height: 300px; margin: 0; border-radius: 10px; overflow: hidden; }
#title title-teaser .scene img { display: block; width: 100%; height: 100%; }
#title title-teaser :is(.box, .trace) { position: absolute; box-sizing: border-box; }
#title title-teaser .trace { border: 1.5px solid rgb(255 255 255 / .55); }
#title title-teaser .box { border: 3px solid var(--glimpse); box-shadow: 0 0 0 1px rgb(255 255 255 / .6); transition: opacity .4s ease; }
#title title-teaser .box.gliding { transition: top 1.1s ease-in-out, left 1.1s ease-in-out, width 1.1s ease-in-out, height 1.1s ease-in-out, opacity .4s ease; }
#title title-teaser .box.hidden { opacity: 0; }
#title title-teaser .box.taken { animation: teaser-take .5s ease-out; }
#title title-teaser .flash { position: absolute; inset: 0; background: #fff; opacity: 0; }
#title title-teaser .box.taken .flash { animation: teaser-flash .5s ease-out; }
@keyframes teaser-take { 0% { border-width: 3px; } 30% { border-width: 7px; } 100% { border-width: 3px; } }
@keyframes teaser-flash { 0% { opacity: .75; } 100% { opacity: 0; } }
#title title-teaser .canvas { background: rgb(255 255 255 / .06); box-shadow: 0 0 0 3px var(--canvas); }
#title title-teaser .canvas canvas { position: absolute; inset: 0; width: 100%; height: 100%; image-rendering: pixelated; }
#title title-teaser .canvas .front { opacity: 0; }
#title title-teaser .canvas .front.shown { animation: teaser-write .6s ease forwards; }
@keyframes teaser-write { to { opacity: 1; } }
:is(#title, #paper) .authors { display: grid; grid-auto-flow: column; grid-auto-columns: 250px; }
:is(#title, #paper) .authors figure { display: flex; flex-direction: column; align-items: center; }
:is(#title, #paper) .authors img { width: 150px; height: 150px; border-radius: 50%; object-fit: cover; }
:is(#title, #paper) .authors figcaption { margin-top: 16px; font-size: 22px; font-weight: 650; white-space: nowrap; }
:is(#title, #paper) .logos { display: flex; align-items: center; justify-content: center; gap: 40px; font-size: 21px; }
:is(#title, #paper) .logos img { height: 40px; width: auto; }
/* The name and NeurIPS side by side, the team across the slide under both. */
#paper .layout { display: grid; grid-template-columns: auto auto; grid-template-rows: auto auto; justify-content: center;
                 align-items: center; align-content: space-evenly; column-gap: 90px; height: 100%; }
#paper .body { display: contents; }
#paper .name { grid-column: 1; grid-row: 1; text-align: center; }
#paper .venue { grid-column: 2; grid-row: 1; }
#paper .team { grid-column: 1 / 3; grid-row: 2; justify-self: center; display: grid; gap: 34px; }
#paper .wordmark { display: block; width: 440px; height: auto; margin: 0 auto; }
#paper .expansion { margin-top: 0; font-size: 36px; font-weight: 700; color: var(--ink); }
#paper .title { margin-top: 16px; font-size: 29px; color: var(--ink); }
#paper .authors { grid-auto-columns: 280px; }
#paper .authors img { width: 160px; height: 160px; }
#paper .authors figcaption { margin-top: 12px; font-size: 25px; }
#paper .logos { gap: 48px; font-size: 25px; }
#paper .logos img { height: 48px; }
/* NeurIPS, where the QR code was: the conference's logo over its name and year. */
#paper .venue { display: flex; flex-direction: column; align-items: center; gap: 18px; color: var(--ink); }
#paper .venue img { height: 120px; width: auto; }
#paper .venue b { font-size: 46px; font-weight: 800; letter-spacing: -.01em; }
/* The slide number on the title's dark gradient. */
.reveal:has(#title.present) .slide-number { color: #fff; }
/* The title slide names the talk itself. */
.reveal:has(#title.present) .footer { display: none; }

/* Yamins et al. 2014's panel beside Zhuang et al. 2021's. The Yamins crop leaves out its x-axis title, shared with
   panel B in the paper; it is restated under the panel. */
#tradition .two-figures { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: end; margin-top: 30px; }
#tradition .two-figures img { display: block; height: 400px; width: auto; max-width: 100%; margin: 0 auto; object-fit: contain; }
#tradition .two-figures .yamins img { height: 376px; }
#tradition .two-figures .zhuang img { height: 330px; margin: 0 0 46px; }
/* Zhuang's y-axis title, shared with another panel in the paper, restated beside the cropped panel. */
#tradition .zhuang .plot { display: flex; align-items: center; justify-content: center; gap: 6px; }
#tradition .zhuang .axis.y { writing-mode: vertical-rl; transform: rotate(180deg); margin-bottom: 46px; }
#tradition .axis { margin: 0; font-size: 18px; line-height: 24px; color: var(--ink); text-align: center; }
#tradition figcaption { margin-top: 12px; text-align: center; font-size: 21px; line-height: 1.3; }
#tradition figcaption b, #tradition figcaption .cite { display: block; }
/* The training regime, the slide's distinction, large under each figure. */
#tradition figcaption .regime { font-size: 34px; font-weight: 800; white-space: nowrap; color: var(--ink); letter-spacing: -.01em; }
/* Yamins alone first, centered and enlarged; it fades out for Brain-Score and returns at its place on the left
   (no transform transition, so it never slides while hidden). */
#tradition .stage { position: relative; }
#tradition .yamins { transform-origin: 50% 25%; transition: opacity .5s ease; }
#tradition:not(.shows-back) .yamins { transform: translateX(calc(50% + 24px)) scale(1.12); }
#tradition.shows-brain-score:not(.shows-back) .yamins { opacity: 0; }
#tradition .zhuang { transition: opacity .5s ease; }
#tradition:not(.shows-self-supervised) .zhuang { opacity: 0; }
/* Brain-Score's Fig. 1, 1600 x 729 px: the scatter spans x < 55.6%; its box on the models above 70% top-1 is centered
   at (51%, 12%); the zoomed panel and its connectors lie right of 55.4%. */
#tradition .brain-score { position: absolute; top: 4px; left: 0; right: 0; width: 1040px; margin: 0 auto;
                          opacity: 0; visibility: hidden; transition: opacity .5s ease, visibility .5s; }
#tradition.shows-brain-score:not(.shows-back) .brain-score { opacity: 1; visibility: visible; }
#tradition .brain-score .frame { position: relative; transform: translateX(229px); transition: transform .8s ease; }
#tradition.shows-zoom .brain-score .frame { transform: none; }
#tradition .brain-score img { display: block; width: 100%; height: auto; }
#tradition .brain-score .all { clip-path: inset(0 44.6% 0 0); }
#tradition .brain-score .zoom { position: absolute; inset: 0; clip-path: inset(0 0 0 55.4%); transform-origin: 51% 12%;
                                transform: scale(.1); opacity: 0; transition: transform .9s ease, opacity .4s ease; }
#tradition.shows-zoom .brain-score .zoom { transform: none; opacity: 1; }
#tradition .brain-score figcaption { margin-top: 10px; text-align: center; }

/* The world against what a system can take in at once, as a scale: level at first, tipped on "tip". Each side sits within
   its half of the beam. */
#bandwidth .scale { position: absolute; left: 80px; width: 1120px; top: 120px; height: 520px; }
#bandwidth .arm { position: absolute; left: 0; right: 0; top: 270px; height: 0; transform-origin: 50% 50%;
                  transition: transform 1.2s cubic-bezier(.3, 1.4, .5, 1); }
#bandwidth.shows-tip .arm { transform: rotate(-10deg); }
#bandwidth .bar { position: absolute; left: 0; right: 0; top: -3px; height: 6px; border-radius: 3px; background: var(--ink); }
#bandwidth .world, #bandwidth .limits { position: absolute; bottom: 10px; transform: translateX(-50%); white-space: nowrap; color: var(--ink); }
#bandwidth .world { left: 26%; font-size: 124px; font-weight: 900; letter-spacing: -.04em; line-height: .9; }
#bandwidth .limits { left: 82%; display: flex; flex-direction: column; align-items: center; }
#bandwidth .limits b { font-size: 40px; font-weight: 750; line-height: 1.2; }
#bandwidth .pivot { position: absolute; left: 50%; top: 270px; transform: translateX(-50%); border-left: 34px solid transparent;
                    border-right: 34px solid transparent; border-bottom: 58px solid var(--ink); }

/* The foveated street (foveate.js), alone and centered. */
#human-vision .views { position: relative; }
/* The animation alone, as large as the slide allows. */
#human-vision .foveation { position: absolute; left: 50%; top: 10px; width: 620px; transform: translateX(-50%); }

foveated-scene { position: relative; display: block; aspect-ratio: 1; overflow: hidden; border-radius: 10px;
  container-type: inline-size; transition: --fx 70ms ease-in-out, --fy 70ms ease-in-out; }
foveated-scene img { position: absolute; inset: 0; width: 100%; height: 100%; filter: blur(calc(var(--blur) * 100cqw)); }
/* Blurring spreads the image past its edges; the scale keeps the blurred layers' borders outside the frame. */
foveated-scene img:first-child { transform: scale(1.06); }
foveated-scene img.masked {
  mask-image: radial-gradient(circle at var(--fx) var(--fy), #000 calc(var(--inner) * var(--fovea) * 100cqw),
                              transparent calc(var(--outer) * var(--fovea) * 100cqw)); }
/* Stopped, the sharp top layer is unmasked and covers the others: the photograph at full resolution. */
foveated-scene:not(.playing) img:last-of-type { mask-image: none; }
foveated-scene .fixation { position: absolute; left: var(--fx); top: var(--fy); width: 30px; height: 30px; margin: -15px 0 0 -15px;
  background: linear-gradient(#fff, #fff) center / 100% 4px no-repeat, linear-gradient(#fff, #fff) center / 4px 100% no-repeat;
  filter: drop-shadow(0 0 1.5px rgb(0 0 0 / .8)); }

/* Each glimpse's answer is the map clipped to its box (--top, --left, --size from table.js); it appears over its glimpse
   on the photograph, one figure width and gap to the left, then flies to its place in the map. */
:is(#integrating-information-across-viewpoints, #table-callback) .table-demo { --side: 490px; --gap: 44px; display: flex; justify-content: center; gap: var(--gap); }
:is(#integrating-information-across-viewpoints, #table-callback) figure { position: relative; width: var(--side); }
:is(#integrating-information-across-viewpoints, #table-callback) figure > img, :is(#integrating-information-across-viewpoints, #table-callback) .blank { display: block; width: var(--side); height: var(--side); border-radius: 10px; }
:is(#integrating-information-across-viewpoints, #table-callback) .photo .over { position: absolute; inset: 0; opacity: 0; transition: opacity .4s ease; }
#integrating-information-across-viewpoints.shows-glimpses .photo .over { opacity: 1; }
:is(#integrating-information-across-viewpoints, #table-callback) .blank { background: #ebebf0; opacity: 0; transition: opacity .5s ease .5s; }
:is(#integrating-information-across-viewpoints, #table-callback) .map > img.answer { position: absolute; left: 0; top: 0;
  clip-path: inset(calc(var(--top) * 100%) calc((1 - var(--left) - var(--size)) * 100%)
                   calc((1 - var(--top) - var(--size)) * 100%) calc(var(--left) * 100%));
  opacity: 0; transform: translateX(calc(-1 * (var(--side) + var(--gap))));
  transition: opacity .35s ease, transform 1s cubic-bezier(.45, 0, .2, 1) .55s; }
/* Both glimpses' answers on one click, the near one a beat after the far one. */
#integrating-information-across-viewpoints.shows-answers .map > img.answer { opacity: 1; transform: none; }
/* The photo centered while it is alone, then at its place as the map arrives; the answers wait for it to land. */
#integrating-information-across-viewpoints .photo { transition: transform .8s ease; }
#integrating-information-across-viewpoints:not(.shows-answers) .photo { transform: translateX(calc((var(--side) + var(--gap)) / 2)); }
#integrating-information-across-viewpoints .map > img.answer { transition-delay: .8s, 1.35s; }
#integrating-information-across-viewpoints .map > img.answer:nth-of-type(2) { transition-delay: 1.1s, 1.65s; }
#integrating-information-across-viewpoints.shows-answers .blank { opacity: 1; }
:is(#integrating-information-across-viewpoints, #table-callback) .map .scale { opacity: 0; transition: opacity .5s ease .5s; }
#integrating-information-across-viewpoints.shows-answers .map .scale { opacity: 1; }
:is(#integrating-information-across-viewpoints, #table-callback) .marks { height: var(--side); opacity: 0; transition: opacity .5s ease; }
#integrating-information-across-viewpoints.shows-gap .marks { opacity: 1; }
:is(#integrating-information-across-viewpoints, #table-callback) .marks .ring { stroke: var(--ink); }
:is(#integrating-information-across-viewpoints, #table-callback) .marks .halo { stroke: var(--bg); }
:is(#integrating-information-across-viewpoints, #table-callback) .marks .query { fill: var(--ink); font-size: 44px; font-weight: 800; }
:is(#integrating-information-across-viewpoints, #table-callback) .scale { display: flex; align-items: center; gap: 8px; margin-top: 12px; font-size: 17px; color: var(--ink); }
:is(#integrating-information-across-viewpoints, #table-callback) .scale i { width: 160px; height: 12px; border-radius: 3px;
  background: linear-gradient(90deg, #000004, #420a68, #932667, #dd513a, #fca50a, #fcffa4); }
:is(#integrating-information-across-viewpoints, #table-callback) .scale b { margin-left: 8px; font-weight: 650; color: var(--text); }

/* #foundation: the photo; then the feature map beside it; then the feature map small, with arrows to the
   linear probe's probability maps. Positions per state, so the images glide between them. */
#foundation .stage { position: relative; height: 556px; }
#foundation .stage img { display: block; border-radius: 8px; }
#foundation .photo, #foundation .features { position: absolute; transition: left .8s ease, top .8s ease, width .8s ease, opacity .6s ease; }
#foundation .photo { left: 0; top: 40px; width: 552px; }
#foundation .features { left: 600px; top: 40px; width: 552px; }
#foundation.shows-decode .photo { opacity: 0; }
#foundation.shows-decode .features { left: 0; top: 126px; width: 456px; }
#foundation .arrows { position: absolute; inset: 0; overflow: visible; pointer-events: none; }
#foundation .arrows path { stroke: var(--ink); stroke-width: 3; }
#foundation .arrows text { font: 700 22px var(--sans); fill: var(--ink); opacity: 0; transition: opacity .2s ease; }
#foundation.shows-decode .arrows .draw { stroke-dashoffset: 0; transition-duration: .45s; transition-delay: .25s; }
#foundation.shows-decode .arrows text { opacity: 1; transition: opacity .25s ease .35s; }
#foundation .prob { position: absolute; left: 788px; top: calc(var(--row) * 188px); width: 270px; margin: 0;
                    display: grid; grid-template-columns: 270px auto; gap: 14px; align-items: center;
                    opacity: 0; transition: opacity .35s ease calc(.5s + var(--row) * .12s); }
#foundation .prob img { width: 270px; grid-column: 1; grid-row: 1; }
#foundation .prob figcaption { grid-column: 2; grid-row: 1; font-size: 22px; font-weight: 750; white-space: nowrap; }
#foundation.shows-decode .prob { opacity: 1; }
#foundation > .cite { position: absolute; left: var(--slide-pad-x); bottom: 50px; }
/* Other tasks (foundation-tasks.js): the decode state fades and the two task panels appear side by side, each naming its
   backbone and head; the citation names the family rather than ViT-B/16. */
#foundation .task { position: absolute; top: 40px; width: 564px; margin: 0; opacity: 0; transition: opacity .35s ease .2s; }
#foundation .task.objects { left: 0; }
#foundation .task.depth { left: 588px; }
#foundation.shows-tasks .task { opacity: 1; }
#foundation .task .view { position: relative; }
#foundation .task img { display: block; width: 100%; border-radius: 8px; }
#foundation .task figcaption { margin-top: 10px; text-align: center; font-size: 22px; font-weight: 750; color: var(--ink); }
#foundation svg.detections { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
#foundation svg.detections .box { fill: none; stroke: var(--box); stroke-width: 10; }
#foundation svg.detections .tag { fill: var(--box); }
#foundation svg.detections text { font-family: var(--sans); font-weight: 800; fill: #111827; }
#foundation.shows-tasks :is(.photo, .features, .pca-label, .prob, .arrows) { opacity: 0; transition: opacity .3s ease; }
#foundation > .cite { transition: opacity .3s ease; }
#foundation > .cite.tasks-cite, #foundation.shows-tasks > .cite:not(.tasks-cite) { opacity: 0; }
#foundation.shows-tasks > .cite.tasks-cite { opacity: 1; }

/* A stage: a positioned area for a slide's elements (#foundation). */
.reveal .stage { position: relative; height: 556px; }

/* The project page's "What's in an active-vision model?", at slide size. */
:is(#active-vision-model, #how-to-see-first, #choosing-where-to-look) .axes { display: grid; grid-template-columns: 2fr 1fr; gap: 20px; margin-top: 10px; }
:is(#active-vision-model, #how-to-see-first, #choosing-where-to-look) .group { position: relative; display: flex; flex-direction: column; padding: 16px; border-radius: 20px; }
:is(#active-vision-model, #how-to-see-first, #choosing-where-to-look) .group.observer { background: var(--soft); }
:is(#active-vision-model, #how-to-see-first, #choosing-where-to-look) .group.policy { border: 2px dashed #cbd5e1; }
:is(#active-vision-model, #how-to-see-first, #choosing-where-to-look) .does { margin-bottom: 12px; font-size: 22px; font-weight: 700; color: var(--ink); text-align: center; }
:is(#active-vision-model, #how-to-see-first, #choosing-where-to-look) .jobs { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 14px; }
:is(#active-vision-model, #how-to-see-first, #choosing-where-to-look) .job { padding: 16px 18px; border: 1px solid var(--rule); border-top: 5px solid var(--accent); border-radius: 14px; background: var(--bg); }
:is(#active-vision-model, #how-to-see-first, #choosing-where-to-look) .job h3 { color: var(--accent); font-size: 28px; white-space: nowrap; text-align: center; }
:is(#active-vision-model, #how-to-see-first, #choosing-where-to-look) .role { margin-top: 16px; font-size: 30px; font-weight: 800; text-align: center; }
/* After the claim, a contour around action selection, the focus of most prior active vision work, in its color. */
#active-vision-model .job { transition: box-shadow .6s ease; }
#active-vision-model.shows-active-focus .job.action { box-shadow: 0 0 0 5px var(--accent); }
/* The diagram spread out over the slide, the claim below it. */
#active-vision-model .axes { margin-top: 80px; }
#active-vision-model .bottom { display: grid; gap: 6px; margin-top: 90px; }
#active-vision-model .bottom > * { opacity: 0; transition: opacity .6s ease; }
#active-vision-model.shows-claim .claim { opacity: 1; }
#active-vision-model .claim { margin-top: 18px; font-size: 34px; }
#active-vision-model .claim span { display: block; }

/* Spatial coverage and perception of detail: scene, the model's 128 px input, p(class), then DINOv3's p(class) from the
   whole scene at 128 px; the input zooms into the zoomed glimpse's box (--zoom-*, detail.js), then the zoomed glimpse
   replaces it at the same framing. */
#detail .detail-row { display: grid; grid-template-columns: repeat(4, 270px); gap: 24px; justify-content: center; margin-top: 120px; }
#detail figure { margin: 0; }
#detail figcaption { min-height: 2.5em; margin-bottom: 8px; font-size: 19px; font-weight: 750; line-height: 1.25; white-space: pre-line; }
#detail .frame { position: relative; width: 270px; height: 270px; overflow: hidden; border-radius: 8px; }
#detail .frame img { position: absolute; inset: 0; width: 100%; height: 100%; transition: opacity .6s ease; }
#detail .scene .boxed { opacity: 0; }
#detail.shows-loupe .scene .boxed { opacity: 1; }
#detail.shows-full .scene .frame { outline: 4px solid var(--glimpse); outline-offset: -4px; }
#detail.shows-loupe .scene .frame { outline: none; }
/* The model's answer follows its input on the same click, a moment later (the delay only on the way in). */
#detail .input, #detail .prob, #detail .passive { opacity: 0; transition: opacity .6s ease; }
#detail.shows-passive .passive { opacity: 1; }
#detail.shows-full .input { opacity: 1; }
#detail.shows-full .prob { opacity: 1; transition-delay: .8s; }
#detail .input .full { transform-origin: 0 0; transition: transform 1.4s ease, opacity .6s ease; }
#detail.shows-loupe .input .full {
  transform: translate(calc(-100% * var(--zoom-left) / var(--zoom-side)), calc(-100% * var(--zoom-top) / var(--zoom-side)))
             scale(calc(1 / var(--zoom-side))); }
#detail .input .zoomed, #detail .prob .fz { opacity: 0; }
#detail.shows-zoom .input .zoomed { opacity: 1; }
#detail.shows-zoom .prob .fz { opacity: 1; transition-delay: .8s; }
#detail .object-ring { position: absolute; box-sizing: border-box; border: 3px solid #fff; border-radius: 50%;
                       box-shadow: 0 0 0 3px rgba(0, 0, 0, .35); opacity: 0; transition: opacity .4s ease;
                       top: calc(100% * (var(--object-top) - .03)); left: calc(100% * (var(--object-left) - .03));
                       height: calc(100% * (var(--object-height) + .06)); width: calc(100% * (var(--object-width) + .06)); }
#detail.shows-full:not(.shows-loupe) .object-ring { opacity: 1; transition-delay: 1.6s; }

/* The paper's architecture figure, revealed left to right by a mask over what is not yet shown, in fractions of the
   figure's width: the first glimpse's backbone and canvas end at .275; the second glimpse's at .66; the third fills the
   rest, with the legend. What is shown stays centered: the figure glides left as each part is revealed. */
/* The figure is centered at the slide's full height, its legend row cropped and the footer hidden. */
.reveal:has(#architecture.present) :is(.footer, .slide-number) { visibility: hidden; }
#architecture .arch-reveal { clip-path: inset(0 0 4.4% 0); }
#architecture .arch-reveal { --w: 800px; position: absolute; top: 10px; left: 50%; width: var(--w); margin: 0 0 0 calc(var(--w) / -2); }
#architecture .arch-reveal img { display: block; width: 100%; height: auto; }
#architecture .arch-reveal .mask { position: absolute; top: 0; right: -2px; bottom: 0; left: 27.5%;
                                   background: color-mix(in srgb, var(--bg) 84%, transparent);
                                   transition: left .8s ease; }
#architecture.shows-next .arch-reveal .mask { left: 66%; }
#architecture.shows-more .arch-reveal .mask { left: 101%; }
#architecture .relabel { position: absolute; inset: 0; width: 100%; height: 100%; }
#architecture .relabel rect { fill: #fff; }
#architecture .relabel text { text-anchor: middle; fill: var(--ink); font-family: var(--sans, Inter, sans-serif); }
#architecture .relabel .viewpoint { font-size: 25px; font-variant-numeric: tabular-nums; }
#architecture .relabel .glimpse-count { font-size: 42px; font-weight: 700; }

/* Panel A centered, then the cost charts in its place across the slide (shows-payoff); C beside B unless hide-c. */
#canvas-attention .stage { position: static; display: grid; place-items: center; height: 620px; margin-top: -19px; }
#canvas-attention .stage > * { grid-area: 1 / 1; transition: opacity .6s ease; }
/* Panel A as tall as the slide allows above the footer band. */
#canvas-attention svg.figure { display: block; position: absolute; top: 20px; left: 50%; height: 652px; width: auto; transform: translateX(-50%); }
#canvas-attention .cost { display: flex; gap: 12px; opacity: 0; }
#canvas-attention .b-only .flops-chart.total { width: 1100px; }
#canvas-attention .with-c .flops-chart.total { width: 640px; }
#canvas-attention .with-c .flops-chart.ratio { width: 500px; }
#canvas-attention.hide-c .cost.with-c, #canvas-attention:not(.hide-c) .cost.b-only { display: none; }
#canvas-attention.shows-payoff svg.figure { opacity: 0; }
#canvas-attention.shows-payoff .cost { opacity: 1; transition-delay: .3s; }
#canvas-attention .rings ellipse { fill: none; stroke: var(--glimpse); stroke-width: 1.4; }
#canvas-attention .vit-blocks { fill: none; stroke: var(--glimpse); stroke-width: 1.6; }
#canvas-attention .canvas-side { fill: none; stroke: var(--canvas); stroke-width: 1.4; stroke-dasharray: 4 2.5; }

/* A training step unrolled in time: one column per glimpse (1, 2, 3, then 21 after an ellipsis), one row per role;
   the target repeats in every column. Each column appears on its click, its rows in order, input to output. */
#distillation .unrolled { --col: 176px; --gap: 22px; --ellipsis: 34px; --img: 128px; --logo: 104px;
  display: grid; grid-template-columns: 190px repeat(3, var(--col)) var(--ellipsis) var(--col);
  grid-template-rows: 22px var(--img) 22px 20px 24px 20px var(--img) 30px var(--img); column-gap: var(--gap);
  row-gap: 3px; justify-content: center; align-items: center; justify-items: center;
  translate: -36px 0; /* the row labels' column is wider than its labels: centers the last state's ink */ }
#distillation .unrolled > * { margin: 0; }
#distillation .t0 { grid-column: 2; } #distillation .t1 { grid-column: 3; }
#distillation .t2 { grid-column: 4; } #distillation .t20 { grid-column: 6; }
#distillation .head { grid-row: 1; font-size: 18px; font-weight: 700; color: var(--glimpse); }
#distillation .glimpse { grid-row: 2; outline: 3px solid var(--glimpse); outline-offset: -3px; }
#distillation .viewpoint { grid-row: 3; font: 500 14px var(--mono); color: var(--text); white-space: nowrap; }
#distillation .in { grid-row: 4; }
#distillation :is(.model, .carry) { grid-row: 5; }
#distillation .out { grid-row: 6; }
#distillation .prediction { grid-row: 7; }
#distillation .score { grid-row: 8; padding: 1px 10px; border: 2px solid currentColor; border-radius: 7px;
  background: color-mix(in srgb, currentColor 10%, white); font: 700 17px var(--mono); }
#distillation .target { grid-row: 9; }
#distillation :is(.glimpse, .prediction, .target) { width: var(--img); height: var(--img); border-radius: 6px; }
#distillation .model { width: var(--logo); height: auto; }
#distillation .row-label { grid-column: 1; justify-self: end; text-align: right; font-size: 19px; font-weight: 700;
  line-height: 1.2; }
#distillation .of-input { grid-row: 2 / span 2; } #distillation .of-prediction { grid-row: 7; }
#distillation .of-score { grid-row: 8; } #distillation .of-target { grid-row: 9; }
#distillation .ellipsis { grid-column: 5; grid-row: 1; font-size: 22px; font-weight: 700; color: var(--glimpse); }
/* Straight connectors: glimpse to model to prediction (ink), the canvas carried from one model to the next (canvas
   red). */
/* Every CSS arrow's shaft ends 2px inside its head's base, where the head is far wider than the shaft, so that no
   rounding of either lets the shaft show beside the head; each head is centered on its shaft. */
#distillation .down { position: relative; width: 3px; height: calc(100% - 4px); align-self: start; background: var(--ink); }
#distillation .down::after { content: ""; position: absolute; left: -5px; bottom: -6px;
  border: 6.5px solid transparent; border-top: 8px solid var(--ink); border-bottom: 0; }
#distillation .carry { position: relative; justify-self: start; height: 3px; background: var(--canvas);
  width: calc(var(--gap) + var(--col) - var(--logo) - 8px); margin-left: calc(var(--logo) / 2 - var(--col) / 2 - var(--gap)); }
#distillation .carry.skip { width: calc(2 * var(--gap) + var(--ellipsis) + var(--col) - var(--logo) - 8px);
  margin-left: calc(var(--logo) / 2 - var(--col) / 2 - 2 * var(--gap) - var(--ellipsis));
  background: repeating-linear-gradient(90deg, var(--canvas) 0 8px, transparent 8px 14px); }
#distillation .carry::after { content: ""; position: absolute; right: -8px; top: -5px;
  border: 6.5px solid transparent; border-left: 9px solid var(--canvas); border-right: 0; }
#distillation .carry.t1::before { content: "canvas"; position: absolute; left: 50%; bottom: 6px; translate: -50% 0;
  font-size: 17px; font-weight: 700; color: var(--canvas); }
/* Visibility: the first column without its target, then the target and the error, then one column per click. */
#distillation .unrolled > :not(.of-input, .of-prediction) { opacity: 0; transition: opacity .5s ease; }
#distillation .unrolled > .t0:not(.score, .target) { opacity: 1; }
/* Who produces the target, under the row label, which alone did not make it clear. */
#distillation .row-label small { display: block; font-size: 17px; font-weight: 600; color: var(--ink); }
#distillation.shows-score .unrolled > :is(.t0, .row-label) { opacity: 1; }
#distillation.shows-second .unrolled > .t1, #distillation.shows-third .unrolled > .t2,
#distillation.shows-last .unrolled > :is(.t20, .ellipsis) { opacity: 1; }
#distillation :is(.head, .glimpse, .viewpoint) { --delay: 0s; } #distillation :is(.in, .model, .carry) { --delay: .35s; }
#distillation :is(.out, .prediction) { --delay: .7s; } #distillation :is(.score, .target) { --delay: 1.05s; }
#distillation:is(.shows-second, .shows-third, .shows-last) .unrolled > :not(.t0, .row-label) { transition-delay: var(--delay); }

#rollout .episode { width: 1060px; margin: 0 auto; padding: 14px 20px; transform-origin: 0 50%;
  transition: transform .8s ease; }
#rollout canvit-episode { font-size: 15px; }
/* The component's own controls (scene tabs, readout choices, play) are for the project page, not the slide. */
#rollout canvit-episode::part(controls) { display: none; }

#extrapolation .extrapolation { display: grid; grid-template-columns: 110px repeat(4, 235px); gap: 10px 14px;
                                align-items: center; justify-content: center; }
#extrapolation img { width: 235px; height: 235px; border-radius: 8px; }
#extrapolation .col-label { font-size: 17px; font-weight: 700; text-align: center; }
#extrapolation .row-label { font-size: 18px; font-weight: 700; color: var(--ink); }
#extrapolation .class-legend { display: grid; gap: 4px; margin-top: 10px; font-size: 17px; font-weight: 650; color: var(--text); }

/* A class legend (index.html fills it from a legend.json): each class name after a chip of its color. */
.reveal .class-legend span::before { content: ""; display: inline-block; width: .8em; height: .8em; margin-right: .4em;
                                     border-radius: 3px; background: var(--chip); vertical-align: -.05em; }

#frontier .chart { width: 1040px; margin: 0 auto; padding: 14px 20px 10px; font-size: 14px; }

#links .layout { display: flex; flex-direction: column; justify-content: space-between; height: 100%; padding-top: 4px; }
#links .qr { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
#links .qr a { display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 18px 12px 20px; border-radius: 18px;
               background: var(--soft); color: var(--ink); text-decoration: none; }
#links .qr .head { display: flex; align-items: center; gap: 12px; height: 44px; font-size: 28px; font-weight: 750; }
#links .qr .logo { height: 40px; width: auto; }
#links .qr .code { width: 270px; height: 270px; padding: 12px; border-radius: 12px; background: #fff; }
#links .homepage { text-align: center; font-size: 26px; font-weight: 650; }
#links .homepage a { color: var(--glimpse); text-decoration: none; }
#links .start { display: flex; justify-content: center; align-items: center; gap: 18px; font-size: 26px; }
#links .start code { padding: 10px 24px; border-radius: 12px; background: var(--ink); color: #fff; font-size: 26px; }
#links .funders { display: flex; justify-content: space-between; align-items: center; gap: 14px; padding-top: 18px;
                  border-top: 1px solid var(--rule); }
#links .funders img { height: 40px; width: auto; max-width: 128px; object-fit: contain; }
#links .funders img.tall { height: 64px; }

/* C2F and F2C side by side, playing together, each labeled in its color. */
#c2f-and-f2c .stages { display: grid; gap: 30px; margin-top: 22px; }
#c2f-and-f2c .stage-row { display: grid; grid-template-columns: 110px repeat(2, 220px 60px) 220px; align-items: center; justify-content: center; }
#c2f-and-f2c .label { margin: 0; font-size: 34px; font-weight: 800; color: var(--policy-color); }
#c2f-and-f2c figure { margin: 0; display: grid; gap: 6px; justify-items: center; }
#c2f-and-f2c .frame { position: relative; width: 220px; height: 220px; }
#c2f-and-f2c .frame img, #c2f-and-f2c .frame svg { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 8px; }
#c2f-and-f2c .frame svg { overflow: visible; }
#c2f-and-f2c rect { fill: none; vector-effect: non-scaling-stroke; }
#c2f-and-f2c rect.halo { stroke: #fff; stroke-width: calc((var(--stroke) + 2.5) * 1px); }
#c2f-and-f2c rect.box { stroke: var(--policy-color); stroke-width: calc(var(--stroke) * 1px); }
#c2f-and-f2c figcaption { font-size: 18px; font-weight: 700; color: var(--policy-color); }
#c2f-and-f2c .arrow { justify-self: center; translate: -3px 0; width: 28px; height: 4px; margin-bottom: 30px; background: var(--muted); position: relative; }
#c2f-and-f2c .arrow::after { content: ""; position: absolute; right: -10px; top: -7px; border: 9px solid transparent; border-left: 12px solid var(--muted); border-right: 0; }

/* Accuracy by viewing policy: ImageNet-1k, then ADE20K beside it. */
#policy-accuracy .charts { display: grid; grid-template-columns: repeat(2, 540px); gap: 48px; justify-content: center; }
#policy-accuracy figure { margin: 0; transition: opacity .6s ease, transform .8s ease; }
/* ImageNet-1k centered while it is alone, then at its place as ADE20K joins it (half a column and the gap). */
#policy-accuracy:not(.shows-ade20k) .in1k { transform: translateX(294px); }
/* Charts sized for the room: taller, larger text (policy-curves.js reads these). */
canvit-policy-curves, canvit-frontier { --canvit-chart-tick: 17px; --canvit-chart-title: 18px; --canvit-chart-label: 19px;
                                         --canvit-chart-callout: 20px;
                                         --canvit-muted: var(--ink); }
#policy-accuracy canvit-policy-curves { --canvit-chart-aspect: .9; }
/* Once the second set joins (fine-tuned beside frozen, the 64² canvas beside 32²), the first, dashed, recedes. */
#policy-accuracy canvit-policy-curves[show="both"]::part(dashed) { opacity: .35; animation: policy-recede .6s ease; }
@keyframes policy-recede { from { opacity: 1; } }
#policy-accuracy figcaption { margin-bottom: 6px; font-size: 22px; font-weight: 750; }
#policy-accuracy .ade20k { opacity: 0; }

#policy-accuracy.shows-ade20k .ade20k { opacity: 1; }

/* Quickstart: the install line alone and large, then small above the code; the code walked through block by block,
   the street and the segmentation each model call returns beside it, the map a moment after its glimpse's box. */
#quickstart .install { position: absolute; left: 0; right: 0; top: 346px; text-align: center; transition: top .7s ease, font-size .7s ease;
                       font-size: 44px; }
#quickstart .install code { padding: .3em .7em; border-radius: .3em; background: var(--ink); color: #fff; font-size: 1em; }
#quickstart.shows-code .install { top: 104px; font-size: 20px; }
#quickstart pre { position: absolute; left: var(--slide-pad-x); top: 156px; width: 800px; box-sizing: border-box;
                  padding: 14px 22px; font-size: 13.5px; line-height: 1.42; }
#quickstart pre::before { top: calc(14px + (var(--line-from, 1) - 1) * 1lh); }
#quickstart .result { position: absolute; right: var(--slide-pad-x); top: 136px; width: 226px; display: grid; gap: 8px; }
#quickstart .result figure { margin: 0; opacity: 0; transition: opacity .5s ease; }
#quickstart.shows-code .result .scene, #quickstart.shows-first .result .map { opacity: 1; }
#quickstart.code-only .result { display: none; }
#quickstart.code-only pre { left: 50%; transform: translateX(-50%); width: 960px; font-size: 15px; }
#quickstart.shows-first .result .map { transition-delay: .8s; }
#quickstart .result figcaption { margin-bottom: 4px; font-size: 16px; }
#quickstart .result .frame { position: relative; width: 226px; height: 226px; }
#quickstart .result .frame > * { position: absolute; inset: 0; width: 100%; height: 100%; transition: opacity .5s ease; }
#quickstart .result .frame img { border-radius: 6px; }
#quickstart .result :is(.first, .second) { opacity: 0; }
#quickstart.shows-first .result .first { opacity: 1; }
#quickstart.shows-second .result .first { opacity: 0; }
#quickstart.shows-second .result .second { opacity: 1; }
#quickstart.shows-second .result .map .second { transition-delay: .8s; }
#quickstart .names span { position: absolute; transform: translate(-50%, -50%); white-space: nowrap; color: #fff;
                          font-size: 16px; font-weight: 750; text-shadow: 0 0 3px #000, 0 0 6px rgba(0, 0, 0, .6); }

/* The deep active vision timeline (timeline.js): active models in amber, neuro-AI models in --neuro-ai. */
#timeline .timeline svg { display: block; width: 100%; height: auto; overflow: visible; }
#timeline .axis { fill: none; stroke: var(--ink); stroke-width: 3; stroke-linejoin: round; }
#timeline .tick { stroke: var(--ink); stroke-width: 1.5; }
#timeline .year { font: 600 18px var(--sans); fill: var(--ink); paint-order: stroke; stroke: var(--bg); stroke-width: 8px; }
#timeline .marker { fill: #d97706; stroke: var(--bg); stroke-width: 2.5; }
#timeline .leader { stroke: var(--muted); stroke-width: 1.5; stroke-dasharray: 4 5; }
#timeline .name { font: 800 24px var(--sans); fill: var(--ink); }
#timeline .cite { font: italic 400 15px var(--sans); fill: var(--ink); }
#timeline .neuro { opacity: 0; transition: opacity .6s ease; }
#timeline.shows-neuro .neuro { opacity: 1; }
#timeline .marker.neuro { fill: var(--neuro-ai); }
#timeline .neuro .name { fill: var(--neuro-ai); }

/* EG-C2F's choice in one frame (uncertainty.js): the scene with two canvas patches outlined at their true size, each
   linked by a leader line to its class probabilities; the scene crossfades into the entropy map (shows-map) with its
   quadrants and their means (shows-quadrants), then back to the scene with the second glimpse (shows-next). Geometry in
   px, shared with uncertainty.js's leader lines: the frame FRAME wide at the layout's left, the panels at PANEL_X. */
#eg-c2f .layout { --frame: 480px; position: relative; width: 1000px; height: 530px; margin: 8px auto 0; }
#eg-c2f .frame { position: absolute; left: 0; top: 0; width: var(--frame); transition: transform .8s ease; }
/* The scene centered while it is alone, then at its place as the patches' probabilities arrive beside it. */
#eg-c2f:not(.shows-certain) .frame { transform: translateX(calc((1000px - var(--frame)) / 2)); }
#eg-c2f .frame canvit-scene, #eg-c2f .frame canvit-map { display: block; width: var(--frame); }
#eg-c2f .frame .map { position: absolute; left: 0; top: 0; width: var(--frame); opacity: 0; transition: opacity .7s ease; }
#eg-c2f.shows-map:not(.shows-next) .frame .map { opacity: 1; }
#eg-c2f .frame :is(.patches, .quadrants) { position: absolute; left: 0; top: 0; width: var(--frame); height: var(--frame); pointer-events: none; }
#eg-c2f .patches :is(rect, circle) { fill: none; vector-effect: non-scaling-stroke; opacity: 0; transition: opacity .4s ease; }
#eg-c2f .patches .halo { stroke: #fff; stroke-width: 6; }
#eg-c2f .patches .outline { stroke: var(--ink); stroke-width: 2.5; }
#eg-c2f .patches .ring.outline { stroke-width: 2; }
#eg-c2f .patch { position: absolute; left: 590px; width: 410px; opacity: 0; transition: opacity .5s ease; }
#eg-c2f .patch.certain { top: 10px; }
#eg-c2f .patch.uncertain { top: 270px; }
#eg-c2f.shows-certain :is(.patch.certain, .certain-mark), #eg-c2f.shows-uncertain :is(.patch.uncertain, .uncertain-mark) { opacity: 1; }
#eg-c2f .patch .head { margin: 0 0 8px; font-size: 20px; font-weight: 700; color: var(--ink); }
#eg-c2f .patch .row { display: grid; grid-template-columns: 110px 190px 60px; align-items: center; gap: 10px; font-size: 19px; }
#eg-c2f .patch .name { text-align: right; color: var(--text); }
#eg-c2f .patch .bar { height: 18px; width: calc(var(--p) * 190px); border-radius: 3px; background: var(--ink); }
#eg-c2f .patch .p { color: var(--ink); font-variant-numeric: tabular-nums; }
#eg-c2f .patch .entropy { margin: 10px 0 0; font-size: 22px; font-weight: 800; color: var(--ink); }
#eg-c2f .leaders { position: absolute; left: 0; top: 0; width: 1000px; height: 500px; overflow: visible; pointer-events: none; }
#eg-c2f .leaders path { fill: none; stroke: var(--ink); stroke-width: 2; opacity: 0; transition: opacity .4s ease; }
#eg-c2f .quadrants span { position: absolute; box-sizing: border-box; display: flex; align-items: center; justify-content: center;
                          border: 2px dashed rgba(255, 255, 255, .85); color: #fff; font-size: 26px; font-weight: 800;
                          text-shadow: 0 0 4px #000; opacity: 0; transition: opacity .4s ease; }
#eg-c2f .quadrants small { margin-left: 6px; font-size: 18px; font-weight: 650; }
#eg-c2f.shows-quadrants .quadrants span { opacity: 1; }
#eg-c2f.shows-next .quadrants span { border-color: transparent; }
/* The quadrants' rank by mean entropy, in place of the values, then each visited in turn: the one being visited ringed,
   those already visited set back. */
#eg-c2f .quadrants .bits, #eg-c2f .quadrants .rank { position: absolute; transition: opacity .4s ease; }
#eg-c2f .quadrants .bits { font-style: normal; }
#eg-c2f .quadrants .rank { display: grid; place-items: center; width: 74px; height: 74px; border-radius: 50%;
                           background: rgb(255 255 255 / .92); color: var(--ink); font-size: 44px; font-weight: 800;
                           text-shadow: none; box-shadow: 0 0 0 4px var(--ink); opacity: 0; }
#eg-c2f.shows-rank .quadrants .bits { opacity: 0; }
#eg-c2f.shows-rank .quadrants .rank { opacity: 1; }
#eg-c2f.shows-next .quadrants .rank-1 .rank,
#eg-c2f.shows-visit-2 .quadrants .rank-2 .rank,
#eg-c2f.shows-visit-3 .quadrants .rank-3 .rank,
#eg-c2f.shows-visit-4 .quadrants .rank-4 .rank { box-shadow: 0 0 0 6px var(--canvit-glimpse); }
#eg-c2f.shows-visit-2 .quadrants .rank-1 .rank,
#eg-c2f.shows-visit-3 .quadrants :is(.rank-1, .rank-2) .rank,
#eg-c2f.shows-visit-4 .quadrants :is(.rank-1, .rank-2, .rank-3) .rank { opacity: .35; box-shadow: 0 0 0 4px var(--ink); }

/* The divider before the appendix's slides. */
#appendix .divider { display: grid; place-items: center; height: 100%; margin: 0; font-size: 96px; font-weight: 800;
                   letter-spacing: -.03em; color: var(--ink); }

/* The chart, then the budget below it: the chart shrinks and the glimpses of pretraining and of learning where to
   look appear to scale. */
#learned-policy .learned-layout { width: 900px; margin: 18px auto 0; transition: width .7s ease; }
#learned-policy canvit-policy-curves { --canvit-chart-aspect: .6; }
#learned-policy canvit-policy-curves::part(added) { transition: opacity .6s ease; }
#learned-policy:not(.shows-learned) canvit-policy-curves::part(added) { opacity: 0; }
#learned-policy.shows-budget .learned-layout { width: 600px; margin-top: 0; }
/* Its own transition keeps the rescale's, which this rule would otherwise replace. */
#learned-policy .budget { margin-top: 14px; opacity: 0; transition: opacity .6s ease .4s, --log-max 2s cubic-bezier(.3, 0, .3, 1); }
#learned-policy.shows-budget .budget { opacity: 1; }
#learned-policy .rescale { --who: 300px; --label: 220px; --log-max: 5.84510; /* 700K */ }
#learned-policy.shows-pretraining .rescale { --log-max: 9; /* 1B */ }
#learned-policy .row.policy .bar { background: var(--policy); }
#learned-policy .row.pretraining .bar { background: var(--brand); }

#links .funders .wordlogo { display: flex; align-items: center; gap: 8px; font-size: 19px; font-weight: 800; letter-spacing: -.01em; color: var(--ink); white-space: nowrap; }
#links .funders .wordlogo img { height: 34px; width: 34px; }

/* The gap: the segmentation task, then the bars (gap.js). */
#gap .gap-layout { display: grid; grid-template-columns: 340px 1fr; gap: 24px; align-items: center; margin-top: 84px; }
#gap .examples { display: grid; gap: 14px; }
/* The example alone, large and centered over the slide, until the bars come in: then it shrinks into its column.
   406 px moves the column's center (170 px) to the content area's (576 px). */
#gap .examples { transform: translate(406px, -62px) scale(1.38); transform-origin: center top; transition: transform .9s ease; }
#gap.shows-bars .examples { transform: none; }
#gap .example figcaption small { display: block; font-size: 15px; font-weight: 500; color: var(--ink); }
#gap .example .frame { position: relative; height: 340px; border-radius: 12px; overflow: hidden; }
#gap .example .frame img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
#gap .example figcaption { margin-top: 6px; text-align: center; font-size: 18px; font-weight: 700; }
#gap.shows-map .wipe { clip-path: inset(0); }
#gap .bar-chart { opacity: 0; transition: opacity .6s ease; }
#gap.shows-bars .bar-chart { opacity: 1; }
/* An arrow between the steps of a pipeline drawn left to right (#vit-on-a-glimpse, #canvas-updates): a line and an open
   head, stroked like #next's arrow. */
.flow-arrow { width: 44px; height: 20px; overflow: visible; }
.flow-arrow path { fill: none; stroke: var(--muted); stroke-width: 3.5; stroke-linecap: round; stroke-linejoin: round; }
.bar-chart .axis-title { font-size: 22px; font-weight: 700; fill: var(--ink); }
.bar-chart :is(.spine, .tick-mark) { stroke: var(--ink); stroke-width: 2px; }
.bar-chart svg { display: block; width: 100%; height: auto; font-family: var(--sans); }
.bar-chart .grid { stroke: var(--rule); }
.bar-chart .tick { font-size: 18px; fill: var(--ink); }
.bar-chart .name { font-size: 26px; font-weight: 800; fill: var(--ink); }
.bar-chart .value { font-size: 26px; font-weight: 800; fill: var(--ink); }
/* Each kind's color fills its bars and draws a frozen bar's outline; CanViT's bars take the brand's gradient instead
   (bar-rows.js sets it on them), whose stops are colored here. */
.bar-chart .passive { color: var(--ink); }
.bar-chart .active { color: #d97706; }
.bar-chart .canvit { color: var(--canvas); }
.bar-chart .bar { fill: currentColor; }
.bar-chart .bar.outline { fill: none; stroke: currentColor; stroke-width: 2px; vector-effect: non-scaling-stroke; }
.bar-chart .brand stop:first-child { stop-color: var(--canvas); }
.bar-chart .brand stop:last-child { stop-color: var(--glimpse); }
.bar-chart .section-label { font-size: 21px; font-weight: 800; fill: var(--ink); }
.bar-chart .bracket { stroke: var(--ink); stroke-width: 3px; stroke-linecap: round; }

/* The cost charts of #canvas-attention (flops-chart.js), in the bar charts' text sizes. */
.flops-chart svg { display: block; width: 100%; height: auto; font-family: var(--sans); overflow: visible; }
.flops-chart .grid line { stroke: var(--rule); }
.flops-chart :is(.spine, .tick-mark) { stroke: var(--ink); stroke-width: 2px; }
.flops-chart .tick { font-size: 24px; fill: var(--ink); }
.flops-chart .axis-title { font-size: 24px; font-weight: 700; fill: var(--ink); }
.flops-chart .curve { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.flops-chart .curve.dinov3 { stroke: var(--ink); stroke-dasharray: 14 9; }
.flops-chart .curve.thick { stroke-width: 7px; }
.flops-chart .curve.thin { stroke-width: 3px; }
.flops-chart .end-label { font-size: 24px; font-weight: 800; fill: var(--ink); }
.flops-chart .key-title { font-size: 22px; font-weight: 750; fill: var(--ink); }
.flops-chart .brand stop:first-child { stop-color: var(--canvas); }
.flops-chart .brand stop:last-child { stop-color: var(--glimpse); }
.flops-chart .ratio .curve { stroke: currentColor; stroke-width: 4px; }
.flops-chart .ratio circle { fill: currentColor; }
.flops-chart .ratio.end-label { fill: currentColor; }
.flops-chart .shade-0 { color: var(--glimpse); }
.flops-chart .shade-1 { color: color-mix(in oklab, var(--glimpse) 62%, var(--bg)); }
.flops-chart .shade-2 { color: color-mix(in oklab, var(--glimpse) 35%, var(--bg)); }

/* Yes/no comparison: the families of models against what an active-vision foundation model needs. */
.compare-wrap { display: flex; justify-content: center; margin-top: 40px; }
table.compare { border-collapse: separate; border-spacing: 0; font-size: 28px; }
table.compare th, table.compare td { padding: 16px 30px; text-align: center; border-bottom: 1px solid var(--rule); }
table.compare thead th { font-size: 24px; font-weight: 750; color: var(--ink); vertical-align: bottom; max-width: 210px; line-height: 1.25; }
table.compare tbody th { text-align: left; font-weight: 650; color: var(--ink); white-space: nowrap; }
table.compare .yes { color: #15803d; font-weight: 800; font-size: 36px; }
table.compare .no { color: #b91c1c; font-weight: 800; font-size: 36px; }
table.compare .some { color: #b45309; font-weight: 700; }
table.compare .na { color: var(--ink); }
/* The goal column in the brand's colors: a light canvas-red-to-glimpse-blue band, the same in every row. */
table.compare .goal { background: linear-gradient(90deg, color-mix(in srgb, var(--canvas) 10%, transparent),
                                                        color-mix(in srgb, var(--glimpse) 10%, transparent)); }
table.compare thead .goal { color: var(--ink); }
/* Passive and prior active models side by side, then the goal column. */
#compare td.goal, #compare th.goal { opacity: 0; transition: opacity .5s ease; }
#compare.shows-goal td.goal, #compare.shows-goal th.goal { opacity: 1; }
#compare table.compare thead th { white-space: nowrap; max-width: none; }

/* Yarbus's records: the painting, then every record at once, free examination and the six tasks; each in a cell of its own. */
#task-dependent-scanpaths .yarbus { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px 18px; margin-top: 8px; }
#task-dependent-scanpaths figure { display: flex; flex-direction: column; align-items: center; }
#task-dependent-scanpaths figure img { width: 100%; height: 196px; object-fit: contain; border-radius: 6px; }
#task-dependent-scanpaths figcaption { margin-top: 8px; font-size: 18px; font-weight: 650; line-height: 1.25; text-align: center; text-wrap: balance; }
#task-dependent-scanpaths figure:not(.painting) { opacity: 0; transition: opacity .5s ease; }
/* The painting opens large in the middle of the slide, then moves into its cell when the records arrive. */
#task-dependent-scanpaths figure.painting { transform: translate(430px, 132px) scale(2.1); transition: transform .8s ease; }
#task-dependent-scanpaths.shows-tasks figure.painting { transform: none; }
#task-dependent-scanpaths.shows-tasks figure { opacity: 1; }
#task-dependent-scanpaths figcaption .cite { display: block; margin-top: 2px; font-weight: 400; }

/* A Vision Transformer on a glimpse: scene, glimpse, backbone, tokens, left to right, each on its own click. The three
   pictures and the backbone share one height and one grid whose rows every figure shares (subgrid): pictures, box and
   arrows centered on one line, the captions on one baseline right below, the token view's label under its caption. */
#vit-on-a-glimpse { --picture: 270px; }
#vit-on-a-glimpse .vit-flow { display: grid; grid-template-columns: repeat(3, auto 36px) auto; grid-template-rows: auto auto auto;
                              justify-content: center; align-items: center; column-gap: 14px; margin-top: 130px; }
#vit-on-a-glimpse :is(.flow-arrow, .vit) { grid-row: 1; }
#vit-on-a-glimpse figure { display: grid; grid-row: 1 / span 3; grid-template-rows: subgrid; place-items: center; }
#vit-on-a-glimpse figcaption { grid-row: 2; align-self: start; margin-top: 12px; font-size: 22px; font-weight: 750; }
#vit-on-a-glimpse :is(.pca-label, .pca-player) { grid-row: 3; align-self: start; }
#vit-on-a-glimpse .scene .frame { position: relative; width: var(--picture); height: var(--picture); }
#vit-on-a-glimpse .scene img { display: block; width: 100%; height: 100%; border-radius: 10px; }
#vit-on-a-glimpse .box { position: absolute; box-sizing: border-box; border: 3px solid var(--glimpse); border-radius: 3px; opacity: 0; transition: opacity .4s ease; }
#vit-on-a-glimpse .glimpse img, #vit-on-a-glimpse .tokens img { width: var(--picture); height: var(--picture); border-radius: 8px; }
#vit-on-a-glimpse .glimpse img { box-shadow: 0 0 0 3px var(--glimpse); }
#vit-on-a-glimpse .pca-label { margin: 4px 0 0; font-size: 17px; font-weight: 600; color: var(--ink); white-space: nowrap; }
#vit-on-a-glimpse .glimpse figcaption { color: var(--glimpse); }
#vit-on-a-glimpse .vit { display: grid; place-items: center; width: 140px; height: var(--picture); box-sizing: border-box; border-radius: 14px;
                         background: #d8b4e2; border: 2px solid #a879b8; color: #5b2a73; font-size: 20px; font-weight: 800; text-align: center; }
#vit-on-a-glimpse :is(.to-glimpse, .glimpse, .to-vit, .vit, .to-tokens, .tokens) { opacity: 0; transition: opacity .5s ease; }
#vit-on-a-glimpse.shows-glimpse :is(.box, .to-glimpse, .glimpse) { opacity: 1; }
#vit-on-a-glimpse.shows-vit :is(.to-vit, .vit) { opacity: 1; }
#vit-on-a-glimpse.shows-tokens :is(.to-tokens, .tokens) { opacity: 1; }

/* Signposting slides: a statement alone, large and centered, or Part II's outline with the current part highlighted. */
.reveal section.signpost .statement { display: flex; flex-direction: column; justify-content: center; align-items: center; height: 560px; margin: 0; font-size: 56px; font-weight: 800;
                                      letter-spacing: -.02em; line-height: 1.2; text-align: center; color: var(--ink); text-wrap: balance; }
.reveal section.signpost .outline { display: flex; justify-content: center; align-items: center; gap: 44px; height: 560px; }
.reveal section.signpost .outline p { margin: 0; padding: 26px 38px; border-radius: 22px; font-size: 48px; font-weight: 800;
                                      color: var(--ink); background: var(--soft); transition: opacity .5s ease, box-shadow .5s ease; }
#outline-architecture.shows-architecture .outline p:not(.architecture), .outline.on-pretraining p:not(.pretraining),
.outline.on-experiments p:not(.experiments) { opacity: .25; }
#outline-architecture.shows-architecture .architecture, .outline.on-pretraining .pretraining, .outline.on-experiments .experiments {
  box-shadow: inset 0 0 0 4px var(--ink); }

.reveal section.signpost .statement small { display: block; margin-top: 18px; font-size: 30px; font-weight: 600; color: var(--ink); letter-spacing: 0; }

/* Why DINOv3's scale matters: Raugel et al.'s ICLR Fig. 4E, as large as the slide allows. */
#dinov3-and-the-brain .scaling { width: 840px; top: 116px; margin: 0 auto; text-align: center; }
#dinov3-and-the-brain .scaling img { width: 100%; height: auto; }
#dinov3-and-the-brain .scaling figcaption { margin-top: 10px; }

/* The label of the feature view shown (pca-cycle.js), under the feature map, following it when it moves aside. */
#foundation .pca-label { position: absolute; left: 600px; top: 418px; width: 552px; margin: 0; text-align: center;
                         font-size: 20px; font-weight: 700; color: var(--ink);
                         transition: left .8s ease, top .8s ease, width .8s ease; }
#foundation.shows-decode .pca-label { left: 0; top: 440px; width: 456px; font-size: 17px; }

/* "Where to look" in the policy's color, "how to see" in CanViT's gradient, underlined in it, on every signpost. */
.reveal section.signpost .look { color: var(--policy); }
/* #how-to-see-first: the statement over Part I's diagram, the observer ringed and the policy set back. */
#how-to-see-first .statement { height: auto; margin-top: 70px; }
#how-to-see-first .axes { width: 1060px; margin: 64px auto 0; }
#how-to-see-first .group.observer { box-shadow: 0 0 0 4px var(--ink); }
#how-to-see-first .group.policy { opacity: .35; }
/* #choosing-where-to-look: the same diagram alone and centered, the policy ringed and the observer set back. */
#choosing-where-to-look .axes { position: absolute; top: 50%; left: 50%; width: 1100px; margin: 0; transform: translate(-50%, -50%); }
#choosing-where-to-look .group.policy { box-shadow: 0 0 0 4px var(--ink); border-color: transparent; }
#choosing-where-to-look .group.observer { opacity: .35; }
.reveal section.signpost .see { background: var(--brand); -webkit-background-clip: text; background-clip: text; color: transparent;
                                box-shadow: none; position: relative; }
.reveal section.signpost .see::after { content: ""; position: absolute; left: 0; right: 0; bottom: -.06em; height: .09em;
                                       border-radius: .05em; background: var(--brand); }

/* RAM, which the field traces back to: a larger name and a ring around its marker. */
#timeline .pioneer .name { font-size: 40px; }

/* The slide opens on RAM alone, its paper's figures on the right; on rest they fade, the axis grows to its full length
   and the later models arrive in turn (timeline.js). */
#timeline .grows { transform: translateX(var(--grow-dx)); transition: transform 1s ease; }
#timeline .axis-line { transform-origin: 40px 0; transform: scaleX(var(--axis-k)); transition: transform 1s ease; }
#timeline .axis-head { transform: translateX(var(--head-dx)); transition: transform 1s ease; }
#timeline.shows-rest :is(.grows, .axis-line, .axis-head) { transform: none; }
#timeline .later, #timeline .later-model { opacity: 0; transition: opacity .5s ease; }
#timeline.shows-rest .later { opacity: 1; transition-delay: .6s; }
#timeline.shows-rest .later-model { opacity: 1; transition-delay: calc(1s + var(--i) * .7s); }
#timeline .ram { position: absolute; right: var(--slide-pad-x); top: 120px; width: 600px; display: flex; flex-direction: column;
                 align-items: center; gap: 14px; transition: opacity .5s ease; }
#timeline.shows-rest .ram { opacity: 0; }
#timeline .ram .sensor { width: 560px; }
#timeline .ram .path { margin: 0; display: flex; align-items: center; gap: 16px; }
#timeline .ram .path img { width: 210px; }
#timeline .ram .path figcaption { font-size: 22px; font-weight: 700; }
#timeline .pioneer-ring { fill: none; stroke: var(--ink); stroke-width: 3; }

/* The gap chart's rows (gap.js): the core rows bunched at first, then every row at its place in the full chart. */
#gap .bar-chart .row { transform: translateY(var(--y-core)); transition: transform .8s ease, opacity .6s ease; }
/* The zoomed axis (gap.js): bars stretched from the origin, values and ticks shifted with them, ticks beyond hidden. */
#gap .bar-chart :is(.bar, .value, .tick-group) { transform: var(--zoom); transition: transform .9s ease, opacity .6s ease; }
#gap .bar-chart .bar { transform-box: fill-box; transform-origin: left center; }
#gap .bar-chart .tick-group.beyond { opacity: 0; }
#gap.shows-more .bar-chart :is(.bar, .value, .tick-group) { transform: none; opacity: 1; }
#gap .bar-chart .row:not(.core) { opacity: 0; }
#gap.shows-more .bar-chart .row { transform: translateY(var(--y-all)); opacity: 1; }
/* Before the passive models arrive, the plot closes around the active rows, centered in the chart's height: the rows drop
   by --core-drop, the bottom axis rises by as much, the vertical lines shrink about their center (bar-rows.js). */
#gap .bar-chart .row { --y-core-centered: calc(var(--y-core) + var(--core-drop)); }
#gap:not(.shows-more) .bar-chart .row { transform: translateY(var(--y-core-centered)); }
#gap .bar-chart :is(.tick-mark, .tick, .spine.x, .axis-title) { transition: transform .8s ease; }
#gap:not(.shows-more) .bar-chart :is(.tick-mark, .tick, .spine.x, .axis-title) { transform: translateY(calc(-1 * var(--core-drop))); }
#gap .bar-chart :is(.grid, .spine.y) { transform-box: fill-box; transform-origin: center; transition: transform .8s ease; }
#gap:not(.shows-more) .bar-chart :is(.grid, .spine.y) { transform: scaleY(var(--core-squeeze)); }
#gap .bar-chart .name { font-size: 22px; }
#gap .bar-chart .value { font-size: 26px; }
#gap .bar-chart .tick { font-size: 24px; }

/* Toward CanViT 2: CanViT's column centered, then it shifts left, the arrow draws and CanViT 2's column appears. CanViT's
   limits in red, CanViT 2's in green. */
#next .versions { position: relative; height: 560px; margin-top: 6px; }
#next .version { position: absolute; top: 50%; width: 460px; padding: 24px 30px 28px; border-radius: 22px; background: var(--soft);
                 text-align: center; transition: left .8s ease, transform .8s ease, opacity .6s ease; }
#next .version p { margin: 0; }
#next .name { margin-bottom: 14px !important; font-size: 44px; font-weight: 800; color: var(--ink); }
#next .item { margin-top: 12px !important; padding: 12px 14px; border-radius: 12px; font-size: 27px; font-weight: 750; }
#next .now .item { color: #b91c1c; background: color-mix(in srgb, #dc2626 10%, white); }
#next .next .item { color: #15803d; background: color-mix(in srgb, #16a34a 11%, white); }
#next .now { left: 50%; transform: translate(-50%, -50%); }
#next.shows-next .now { left: 0; transform: translate(0, -50%); }
#next .next { right: 0; transform: translate(40px, -50%); opacity: 0; }
#next.shows-next .next { transform: translate(0, -50%); opacity: 1; transition-delay: .9s; }
#next .next-arrow { position: absolute; left: 50%; top: 50%; width: 92px; transform: translate(-50%, -50%); overflow: visible; }
/* What each model perceives at a moment, atop its column, unseen regions black (glimpse-tour.js, canvit2-glimpses.js). */
#next .perceived { position: relative; margin: 0 auto 18px; background: #000; border-radius: 10px; overflow: hidden; }
#next .now .perceived { width: 260px; height: 260px; }
#next .next .perceived { width: 460px; height: 260px; }
#next .perceived canvas { display: block; width: 100%; height: 100%; }
/* CanViT: the glimpse at its own resolution in its box, with its 8 x 8 patches. */
#next glimpse-tour { position: absolute; inset: 0; }
#next glimpse-tour .box { position: absolute; box-sizing: border-box; transition: top .6s ease, left .6s ease, width .6s ease, height .6s ease; }
#next glimpse-tour .box.snap { transition: none; }
#next glimpse-tour .box img { position: absolute; inset: 0; width: 100%; height: 100%; image-rendering: pixelated;
                             transition: opacity .2s ease; }
#next glimpse-tour .box.empty img, #next glimpse-tour .box.empty .patches { opacity: 0; }
#next glimpse-tour .box .patches { position: absolute; inset: 0;
  background: linear-gradient(to right, rgb(255 255 255 / .75) 1px, transparent 1px) 0 0 / calc(100% / 8) 100%,
              linear-gradient(to bottom, rgb(255 255 255 / .75) 1px, transparent 1px) 0 0 / 100% calc(100% / 8); }
#next glimpse-tour .box::after { content: ""; position: absolute; inset: -2px; border: 2px solid var(--glimpse); }
#next .next-arrow path { fill: none; stroke: var(--ink); stroke-width: 5; stroke-linecap: round; stroke-linejoin: round; }
#next.shows-next .next-arrow .draw { stroke-dashoffset: 0; transition-duration: .9s; transition-delay: .6s; }

/* The gap slide's annotation names its classes as the map wipes in (labeled-map.js). */
#gap .names { position: absolute; inset: 0; }
#gap .names span { position: absolute; transform: translate(-50%, -50%); white-space: nowrap; color: #fff; font-size: 16px;
                   font-weight: 750; padding: 0 5px; border-radius: 4px; background: rgba(15, 23, 42, .72); opacity: 0;
                   transition: opacity .4s ease; }
#gap.shows-map .names span { opacity: 1; transition-delay: calc(.9s + var(--i) * 70ms); }
#dinov3-and-the-brain .scaling .takeaway { margin: 0 0 14px; font-size: 32px; font-weight: 800; color: var(--ink); }

/* Pretraining policies, static: a row per policy, the scene with numbered boxes, then the glimpses numbered. */
#pretraining-policies .pretraining-grid { display: grid; gap: 34px; margin-top: 36px; }
#pretraining-policies .grid-row { display: grid; grid-template-columns: 180px 230px 1fr; gap: 26px; align-items: center; }
#pretraining-policies .label { margin: 0; display: grid; gap: 2px; text-align: right; }
#pretraining-policies .label b { font-size: 34px; font-weight: 800; color: var(--policy-color); }
#pretraining-policies .label span { font-size: 18px; color: var(--ink); white-space: nowrap; }
#pretraining-policies .label em { font-style: normal; font-size: 22px; font-weight: 800; color: var(--policy-color); }
#pretraining-policies .scene { position: relative; width: 230px; height: 230px; }
#pretraining-policies .scene img, #pretraining-policies .scene svg { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 8px; }
#pretraining-policies .scene svg { overflow: visible; }
#pretraining-policies .scene rect { fill: none; stroke: var(--policy-color); stroke-width: .02; }
#pretraining-policies .scene rect.halo { stroke: #fff; stroke-width: .045; }
#pretraining-policies .scene text { font: 800 .13px var(--sans); fill: var(--policy-color); paint-order: stroke; stroke: #fff; stroke-width: .04; }
#pretraining-policies .glimpses { display: flex; gap: 14px; }
#pretraining-policies .glimpses figure { margin: 0; display: grid; gap: 6px; justify-items: center; }
#pretraining-policies .glimpses img { width: 102px; height: 102px; border-radius: 6px; box-shadow: 0 0 0 3px var(--policy-color); }
#pretraining-policies .glimpses figcaption { font-size: 18px; font-weight: 800; color: var(--policy-color); }

/* SR-RoPE: the glimpse's 8 x 8 patches in its own frame (left) and at their scene positions (right), each patch a cell
   with a dot at its center, the position RoPE uses; the canvas's 32 x 32 patches on their fixed grid. The cells and
   dots glide when the glimpse changes to the smaller one (shows-zoom); dots scale with the cells. */
#sr-rope .rope-layout { display: grid; grid-template-columns: 300px 70px 420px; grid-template-rows: auto auto;
                        justify-content: center; align-items: center; column-gap: 40px; margin-top: 56px; }
#sr-rope figure { margin: 0; display: flex; flex-direction: column; align-items: center; }
#sr-rope figcaption { margin-top: 10px; font-size: 22px; font-weight: 750; text-align: center; }
#sr-rope .glimpse figcaption { color: var(--glimpse); }
#sr-rope .frame { position: relative; }
#sr-rope .glimpse .frame { --cell: calc(300px / var(--grid)); width: 300px; height: 300px; }
#sr-rope .scene .frame { --cell: calc(420px * var(--size) / var(--grid)); width: 420px; height: 420px; }
#sr-rope .scene img { display: block; width: 100%; height: 100%; border-radius: 8px; }
#sr-rope .crop { position: absolute; inset: 0; border-radius: 6px; box-shadow: 0 0 0 3px var(--glimpse); overflow: hidden; }
#sr-rope .crop canvas { position: absolute; inset: 0; width: 100%; height: 100%; image-rendering: pixelated; }
/* A grid of n x n cells over an element: a line at the left and top of each cell; the element's border closes it. */
#sr-rope .patch-cells { background: linear-gradient(to right, var(--line) 1.5px, transparent 1.5px) 0 0 / calc(100% / var(--n)) 100%,
                                    linear-gradient(to bottom, var(--line) 1.5px, transparent 1.5px) 0 0 / 100% calc(100% / var(--n)); }
#sr-rope .glimpse .grid, #sr-rope .scene .box .grid { position: absolute; inset: 0; --n: var(--grid); --line: rgb(255 255 255 / .8); }
#sr-rope .dots { position: absolute; inset: 0; pointer-events: none; }
#sr-rope .dots span { --dot: min(9px, calc(var(--cell) * .34)); position: absolute; width: var(--dot); height: var(--dot);
                      margin: calc(var(--dot) / -2) 0 0 calc(var(--dot) / -2); border-radius: 50%; background: var(--glimpse);
                      box-shadow: 0 0 0 1.5px #fff; }
#sr-rope .glimpse .dots span { left: calc(100% * (var(--col) + .5) / var(--grid)); top: calc(100% * (var(--row) + .5) / var(--grid)); }
#sr-rope .scene .dots span { left: calc(100% * (var(--left) + var(--size) * (var(--col) + .5) / var(--grid)));
                             top: calc(100% * (var(--top) + var(--size) * (var(--row) + .5) / var(--grid))); }
#sr-rope .box { position: absolute; box-sizing: border-box;
                left: calc(100% * var(--left)); top: calc(100% * var(--top)); width: calc(100% * var(--size)); height: calc(100% * var(--size)); }
#sr-rope .box::after { content: ""; position: absolute; inset: 0; border: 3px solid var(--glimpse); border-radius: 3px; }
/* The canvas's 32 x 32 patches: their cells, and a dot at the center of each. */
#sr-rope .canvas-cells { position: absolute; inset: 0; border-radius: 8px; --n: 32; --line: rgb(224 72 62 / .25); }
#sr-rope .canvas-cells::after { content: ""; position: absolute; inset: 0;
                                background: radial-gradient(circle, var(--canvas) 1.7px, transparent 2.3px) 0 0 / calc(100% / 32) calc(100% / 32); }
#sr-rope .arrow { height: 3px; background: var(--muted); position: relative; margin: 0 36px 40px 0; }
#sr-rope .arrow::after { content: ""; position: absolute; right: -8px; top: -5.5px; border: 7px solid transparent; border-left: 10px solid var(--muted); border-right: 0; }
#sr-rope .legend { grid-column: 3; display: flex; justify-content: center; gap: 26px; margin: 8px 0 0; font-size: 19px; font-weight: 650; }
#sr-rope .legend span::before { content: ""; display: inline-block; width: 10px; height: 10px; margin-right: 8px; border-radius: 50%; vertical-align: 1px; }
#sr-rope .glimpse-key { color: var(--glimpse); }
#sr-rope .glimpse-key::before { background: var(--glimpse); }
#sr-rope .canvas-key { color: var(--canvas); }
#sr-rope .canvas-key::before { background: var(--canvas); }

/* A new active-vision state of the art: #gap's chart as it ended, at the same sizes, then on "canvit" every row glides to
   make room and CanViT-B's bar grows between the active and passive models, in the brand's gradient (gap.js). On "in1k" the
   ImageNet-1k chart takes the same place, and on "in1k-canvit" its rows make room for CanViT-B's two bars. */
#state-of-the-art .charts { display: grid; width: 1100px; margin: 40px auto 0; }
#state-of-the-art .charts > .bar-chart { grid-area: 2 / 1; transition: opacity .6s ease; }
#state-of-the-art .training-key { grid-area: 1 / 1; justify-self: end; display: flex; gap: 26px; margin: 0 0 -26px;
                                  padding: 0 0 0 10px; background: var(--bg); position: relative; z-index: 1;
                                  font-size: 18px; font-weight: 700; }
:is(#gap, #state-of-the-art) .training-key span { display: flex; align-items: center; gap: 9px; }
:is(#gap, #state-of-the-art) .training-key span::before { content: ""; width: 30px; height: 18px; border-radius: 4px;
                                               border: 2px solid var(--ink); box-sizing: border-box; }
:is(#gap, #state-of-the-art) .training-key .trained::before { background: var(--ink); }
:is(#gap, #state-of-the-art) .training-key .frozen::before { background: repeating-linear-gradient(-45deg, var(--ink) 0 3.5px,
                                                                                         transparent 3.5px 8.5px); }
#state-of-the-art .bracket { transform-box: fill-box; transform-origin: top; transform: scaleY(var(--bracket-core));
                             transition: transform .8s ease; }
#state-of-the-art.shows-canvit .ade20k .bracket, #state-of-the-art.shows-in1k-canvit .in1k .bracket { transform: none; }
#state-of-the-art .bar-chart.in1k, #state-of-the-art.shows-in1k .bar-chart.ade20k { opacity: 0; }
#state-of-the-art.shows-in1k .bar-chart.in1k { opacity: 1; }
#state-of-the-art .bar-chart .row { transform: translateY(var(--y-core)); transition: transform .8s ease, opacity .6s ease; }
#state-of-the-art .bar-chart .row:not(.core) { opacity: 0; }
#state-of-the-art.shows-canvit .ade20k .row, #state-of-the-art.shows-in1k-canvit .in1k .row {
  transform: translateY(var(--y-all)); opacity: 1; }
#state-of-the-art .bar-chart .canvit .bar { transform: scaleX(0); transform-box: fill-box; transform-origin: left center;
                                            transition: transform .9s ease .4s; }
#state-of-the-art.shows-canvit .ade20k .canvit .bar, #state-of-the-art.shows-in1k-canvit .in1k .canvit .bar { transform: none; }
#state-of-the-art .in1k .row:not(.core) { transition: transform .8s ease, opacity .6s ease .4s; }
#state-of-the-art .bar-chart .name { font-size: 22px; }
#state-of-the-art .bar-chart .value { font-size: 26px; }
#state-of-the-art .bar-chart .tick { font-size: 24px; }
/* The viewpoint, under the glimpse it produced: what the box shows, not what SR-RoPE encodes. */
#sr-rope .viewpoint { display: block; margin-top: 6px; font-size: 20px; font-weight: 600; color: var(--ink); text-align: center;
                      font-variant-numeric: tabular-nums; }
#sr-rope .viewpoint span { display: block; line-height: 1.35; }
#sr-rope .axes { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
/* One glimpse patch singled out, ringed in both panels, and the canvas patch under it, each with its scene coordinates. */
#sr-rope .pick { position: absolute; z-index: 2; width: 24px; height: 24px; transform: translate(-50%, -50%); border-radius: 50%;
                 box-shadow: 0 0 0 3px var(--glimpse), 0 0 0 5px #fff; pointer-events: none; }
#sr-rope .glimpse-pick { width: clamp(12px, calc(var(--cell) * .7), 24px); height: clamp(12px, calc(var(--cell) * .7), 24px); }
#sr-rope .canvas-pick { width: calc(420px / var(--canvas-grid)); height: calc(420px / var(--canvas-grid)); border-radius: 2px;
                        box-shadow: 0 0 0 3px var(--canvas), 0 0 0 5px #fff; }
#sr-rope .coord { position: absolute; top: 50%; padding: 1px 6px; border-radius: 4px; color: #fff; font-size: 17px;
                  font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; transform: translateY(-50%); }
#sr-rope .glimpse-pick .coord { right: calc(100% + 10px); background: var(--glimpse); }
#sr-rope .canvas-pick .coord { left: calc(100% + 12px); background: var(--canvas); }
#sr-rope .axes path { fill: none; stroke: var(--ink); stroke-width: 2; }
#sr-rope .axes text { fill: var(--ink); font-size: 18px; font-weight: 600; }
#sr-rope .axes .name { fill: var(--ink); font-size: 17px; font-weight: 750; font-style: italic; }

/* The table again, after pretraining (#table-callback): the table slide's last state, then CanViT's p(table) after
   both glimpses fading in over the passive answers, and the question mark gone. */
#table-callback .photo .over, #table-callback .map > img.answer, #table-callback .blank, #table-callback .map .scale,
#table-callback .marks { opacity: 1; transform: none; }
#table-callback .map > img.canvit { position: absolute; left: 0; top: 0; width: var(--side); height: var(--side); border-radius: 10px;
                                    opacity: 0; transition: opacity .8s ease; }
#table-callback.shows-canvit .map > img.canvit { opacity: 1; }
#table-callback.shows-canvit .marks { opacity: 0; }

/* Pretraining CanViT-B: the run as three stats, then its compute beside DINOv3 7B's, to scale, centered on the slide. */
#pretraining .run { display: flex; flex-direction: column; justify-content: center; gap: 80px; height: 560px; }
#pretraining .stats { display: grid; grid-template-columns: repeat(3, 280px); justify-content: center; gap: 32px; }
#pretraining .stats p { margin: 0; padding: 22px 16px; border-radius: 16px; background: var(--soft); text-align: center;
                       font-size: 24px; font-weight: 500; color: var(--ink); }
#pretraining .stats b { display: block; margin-bottom: 4px; font-size: 44px; font-weight: 750; line-height: 1.1; }
#pretraining .rescale { --who: 190px; --label: 340px; --log-max: 2.30103; /* 200 */ margin: 0 40px; }
#pretraining.shows-teacher .rescale { --log-max: 4.78845; /* 61,440 */ }
#pretraining .rescale .who { font-size: 30px; }
#pretraining .rescale .plot { height: 52px; }
#pretraining .rescale .n { font-size: 28px; }
#pretraining .row.canvit .bar { background: var(--brand); }
#pretraining .row.teacher .bar { background: var(--ink); }

/* DINOv3 and the brain: the study's design first, then (shows-scaling) Fig. 4E in its place. */
#dinov3-and-the-brain figure { position: absolute; left: 0; right: 0; top: 130px; opacity: 0; transition: opacity .6s ease; }
#dinov3-and-the-brain .method { width: 800px; top: 116px; margin: 0 auto; text-align: center; opacity: 1; }
#dinov3-and-the-brain .method img { display: block; width: 100%; height: auto; }
#dinov3-and-the-brain .method .header { margin-bottom: 12px; }
#dinov3-and-the-brain .method figcaption { margin-top: 8px; }
#dinov3-and-the-brain.shows-scaling .method { opacity: 0; }
#dinov3-and-the-brain.shows-scaling .scaling { opacity: 1; }

/* The paper's fig:example-canvit-rollout at the full content width, a stage per glimpse, each over the last. */
#canvit-rollout .stages { position: relative; width: 1152px; aspect-ratio: 396 / 178.58; margin: 42px auto 0; }
/* The scene alone, centered and as large as the slide allows; it settles at its place as the first glimpse arrives. */
#canvit-rollout .stages { transform-origin: 241px 284px; transition: transform .8s ease; }
#canvit-rollout:not(.shows-g1) .stages { transform: translate(341px, -20px) scale(1.38); }
#canvit-rollout .stage { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; transition: opacity .5s ease; }
#canvit-rollout .s0, #canvit-rollout.shows-g1 .s1, #canvit-rollout.shows-g2 .s2, #canvit-rollout.shows-g3 .s3,
#canvit-rollout.shows-g4 .s4 { opacity: 1; }

/* Canvas updates within a glimpse, in one row: the scene, the glimpse, then what each of the glimpse's three Canvas
   Attention Writes adds to the canvas (its residual), large, each on its click, the arrow and the label with the first.
   As on #vit-on-a-glimpse, every figure shares the grid's rows (subgrid): pictures centered on one line, captions on one
   baseline (canvas-updates.js). */
#canvas-updates { --picture: 190px; --map: 222px; }
#canvas-updates .updates { display: grid; grid-template-columns: auto auto 44px repeat(3, auto);
                           grid-template-rows: auto var(--map) auto; column-gap: 12px; justify-content: center;
                           margin-top: 70px; }
#canvas-updates figure { display: grid; grid-row: 2 / span 2; grid-template-rows: subgrid; place-items: center; margin: 0; }
#canvas-updates figcaption { align-self: start; margin-top: 12px; font-size: 22px; font-weight: 750; }
#canvas-updates .writes-label { grid-area: 1 / 4 / 2 / 7; justify-self: center; margin: 0 0 12px; font-size: 22px;
                                font-weight: 750; }
#canvas-updates .glimpse figcaption { color: var(--glimpse); }
#canvas-updates .flow-arrow { grid-area: 2 / 3; align-self: center; }
#canvas-updates .frame { position: relative; width: var(--picture); height: var(--picture); }
#canvas-updates .write .frame { width: var(--map); height: var(--map); }
#canvas-updates .frame img { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 8px; }
#canvas-updates .glimpse img { display: block; width: var(--picture); height: var(--picture); border-radius: 8px;
                               box-shadow: 0 0 0 3px var(--glimpse); }
#canvas-updates .box { position: absolute; box-sizing: border-box; border: 3px solid var(--glimpse); border-radius: 3px; }
#canvas-updates :is(.flow-arrow, .writes-label, .write) { opacity: 0; transition: opacity .5s ease; }
#canvas-updates.shows-write-1 :is(.flow-arrow, .writes-label, [data-write="1"]), #canvas-updates.shows-write-2 [data-write="2"],
#canvas-updates.shows-write-3 [data-write="3"] { opacity: 1; }


/* Bars on a linear axis that rescales (#pretraining, #learned-policy): each bar is --v / --max of its plot, and --max
   changes on a click. What animates is its base-10 logarithm, --log-max: bars scale as 1 / --max, so a linear glide of
   --max would shrink them almost entirely in its first instants, while a glide of the logarithm zooms out steadily.
   Labels sit just past each bar's end, in room kept at the right. */
@property --log-max { syntax: "<number>"; inherits: true; initial-value: 0; }
.rescale { display: grid; --max: pow(10, var(--log-max)); transition: --log-max 2s cubic-bezier(.3, 0, .3, 1); }
/* Space between rows as margins, not a gap, so a collapsed row takes none. */
.rescale > * + * { margin-top: 22px; }
.rescale .row, .rescale .axis { display: grid; grid-template-columns: var(--who) 1fr var(--label); column-gap: 20px; align-items: center; }
.rescale .who { margin: 0; font-size: 22px; font-weight: 750; color: var(--ink); text-align: right; }
.rescale .plot { position: relative; height: 30px; }
.rescale .bar { position: absolute; left: 0; top: 0; bottom: 0; width: clamp(1.5px, calc(100% * var(--v) / var(--max)), 100%); border-radius: 4px; }
.rescale .n { position: absolute; top: 50%; left: calc(100% * min(1, var(--v) / var(--max)) + 14px); transform: translateY(-50%);
              margin: 0; font-size: 20px; font-weight: 700; color: var(--ink); white-space: nowrap; }
/* The second row takes no room until it arrives, so the axis sits right under the first bar; then it opens. */
.rescale .row:nth-of-type(2) { max-height: 0; margin-top: 0; overflow: hidden; opacity: 0;
                               transition: max-height .5s ease, margin-top .5s ease, opacity .5s ease .3s; }
/* Ticks beyond the axis's end while it zooms out stay hidden; the margin keeps the last tick's label whole. */
.rescale .axis .scale { grid-column: 2; position: relative; height: 34px; border-top: 2px solid var(--ink);
                        overflow: clip; overflow-clip-margin: 40px; }
.rescale .axis span { position: absolute; top: 10px; left: calc(100% * var(--t) / var(--max)); transform: translateX(-50%);
                      font-size: 20px; color: var(--ink); font-variant-numeric: tabular-nums; transition: opacity .4s ease; }
.rescale .axis span::before { content: ""; position: absolute; left: 50%; top: -10px; height: 6px; border-left: 1.5px solid var(--ink); }
.rescale .axis .after { opacity: 0; }
.rescale .unit { grid-column: 2; grid-row: 2; margin: 8px 0 0; text-align: center; font-size: 20px; font-weight: 700; color: var(--ink); }
#pretraining.shows-teacher .rescale .row.teacher, #learned-policy.shows-pretraining .rescale .row.pretraining { max-height: 120px; margin-top: 22px; opacity: 1; }
#pretraining.shows-teacher .rescale .axis .before, #learned-policy.shows-pretraining .rescale .axis .before { opacity: 0; }
#pretraining.shows-teacher .rescale .axis .after, #learned-policy.shows-pretraining .rescale .axis .after { opacity: 1; transition-delay: .9s; }

/* #gap's key, as #state-of-the-art's, at the chart's top right; it comes with the passive models, the first frozen rows. */
#gap .bar-chart .training-key { display: flex; justify-content: flex-end; gap: 26px; margin: 0 0 4px; font-size: 18px; font-weight: 700;
                                opacity: 0; transition: opacity .5s ease .4s; }
#gap.shows-more .bar-chart .training-key { opacity: 1; }

#canvas-attention .panel-letter { fill: var(--bg); }
