/* ═══════════════════════════════════════════════════════════
   CHAT · ECCV 2026
   Light, spacious, system-typeface. Colour does one job.
   ═══════════════════════════════════════════════════════════ */

:root{
  --bg:        #ffffff;
  --bg-2:      #f5f5f7;   /* the alternating band */
  --ink:       #1d1d1f;
  --ink-2:     #5f5f65;   /* 6.34:1 on white, 5.82 on the band */
  --ink-3:     #70707a;   /* 4.90:1 on white, 4.51 on the band */
  --hair:      #d2d2d7;
  --hair-soft: #e8e8ed;
  /* Blue is reserved for two jobs: the mark itself, and live values in the
     figures. Controls are ink, so nothing competes with the wordmark and the
     accent still means something where it appears. */
  --blue:      #0071e3;
  --blue-ink:  #0062c4;
  --link:      #0062c4;
  /* Controls take the navy the shield is drawn in, sampled from the mark:
     related to the wordmark without competing with it, and warmer than the
     flat black it replaces. */
  --ctrl:      #0b1a42;
  --ctrl-ink:  #01153c;
  --ctrl-soft: rgba(11,26,66,.16);

  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
          "Helvetica Neue", "Segoe UI", Roboto, system-ui, sans-serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  --w:    1040px;
  --w-wide: 1240px;
  --gut:  clamp(22px, 5vw, 48px);
  --ease: cubic-bezier(.28,.11,.32,1);
}

*,*::before,*::after{ box-sizing:border-box; }

html{ -webkit-text-size-adjust:100%; scroll-behavior:smooth; }
@media (prefers-reduced-motion: reduce){ html{ scroll-behavior:auto; } }

main{ overflow-x:clip; }

body{
  margin:0;
  background:var(--bg);
  color:var(--ink);
  font-family:var(--sans);
  font-size:17px;
  line-height:1.53;
  letter-spacing:-0.011em;
  font-synthesis:none;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
}

img,video{ display:block; max-width:100%; }
/* width/height attributes are presentational hints: an <img> set to width:100%
   keeps the attribute height and stretches. height:auto hands the shape back
   to the file's own aspect ratio. */
img{ height:auto; }
a{ color:var(--link); text-decoration:none; }
a:hover{ text-decoration:underline; }

::selection{ background:#b4d5fe; color:var(--ink); }

.skip{
  position:absolute; left:-9999px; top:0; z-index:200;
  background:#fff; padding:12px 18px; border-radius:0 0 10px 0;
}
.skip:focus{ left:0; }

:focus-visible{ outline:3px solid var(--blue); outline-offset:3px; border-radius:6px; }

/* ─────────── nav: translucent, content passes under ─────────── */
.nav{
  position:sticky; top:0; z-index:100;
  background:rgba(255,255,255,.72);
  -webkit-backdrop-filter:saturate(180%) blur(20px);
  backdrop-filter:saturate(180%) blur(20px);
  border-bottom:1px solid rgba(0,0,0,.06);
}
.nav-in{
  max-width:var(--w-wide); margin-inline:auto;
  padding:0 var(--gut); height:48px;
  display:flex; align-items:center; gap:28px;
}
.nav-brand{
  font-size:18px; font-weight:600; letter-spacing:-0.02em;
  color:var(--ink); text-decoration:none;
  display:inline-flex; align-items:center; gap:9px;
}
.nav-links{ display:flex; gap:28px; margin-left:auto; }
.nav-links a{
  font-size:12px; color:var(--ink); opacity:.82; text-decoration:none;
  transition:opacity .25s var(--ease);
}
.nav-links a:hover{ opacity:1; text-decoration:none; }
.nav-cta{
  font-size:12px; color:#fff; background:var(--ctrl);
  padding:5px 13px; border-radius:980px; text-decoration:none;
  transition:background .25s var(--ease);
}
.nav-cta:hover{ background:var(--ctrl-ink); text-decoration:none; }
@media (max-width:820px){
  .nav-links{ display:none; }
  .nav-cta{ margin-left:auto; }
}

/* ─────────── entrance animation baseline ─────────── */
[data-anim]{ opacity:0; }
[data-anim="up"]{ transform:translate3d(0,26px,0); }
@media (prefers-reduced-motion: reduce){
  [data-anim]{ opacity:1 !important; transform:none !important; }
}

/* ─────────── layout ─────────── */
.section{
  max-width:var(--w-wide); margin-inline:auto;
  padding:clamp(88px,13vh,168px) var(--gut);
}
.section.tight{ padding-top:0; }
/* Full-bleed background, content on the same optical column as .section.
   A grid track does the centring: children set `margin: 0 0 X` shorthand,
   which would wipe out any margin-inline:auto we tried to give them. */
.band{
  max-width:none; background:var(--bg-2);
  padding-inline:0;
  display:grid;
  grid-template-columns:1fr minmax(0, min(var(--w-wide), 100%)) 1fr;
}
/* min-width:0 stops a wide child (a scrollable table) from widening the track,
   which is a grid item's default behaviour and shows up as page-level
   horizontal overflow on a phone. */
.band > *{ grid-column:2; padding-inline:var(--gut); min-width:0; }

.sec-head{ max-width:760px; margin:0 0 clamp(40px,6vh,72px); }
.sec-head.narrow{ max-width:620px; }

.kicker{
  margin:0 0 10px;
  font-size:19px; font-weight:600; letter-spacing:-0.014em;
  color:var(--ink-2);
}
.title{
  margin:0 0 18px;
  font-size:clamp(33px,4.4vw,54px);
  line-height:1.06;
  letter-spacing:-0.025em;
  font-weight:600;
  text-wrap:balance;
}
.sub a{ white-space:nowrap; }
.sub{
  margin:0; max-width:640px;
  font-size:19px; line-height:1.5; letter-spacing:-0.003em;
  color:var(--ink-2); text-wrap:pretty;
}

/* ─────────── hero ─────────── */
.hero{
  max-width:var(--w); margin-inline:auto;
  padding:clamp(60px,10.5vh,112px) var(--gut) clamp(40px,6vh,76px);
  text-align:center;
}
.eyebrow{
  margin:0 0 clamp(14px,2vh,22px);
  font-size:21px; font-weight:600; letter-spacing:-0.014em;
  color:var(--ink-2);
}
/* The wordmark reproduces the paper's own \chat macro: four letters, four
   blues, and the same negative kerning after each one (C -0.3em, then
   -0.35em). Per-letter colour, so no gradient and no fill-colour tricks. */
/* The hero stage holds the ring behind the wordmark; the ring is painted, the
   type sits above it. */
.hero-stage{ position:relative; }
/* Generated identities, orbiting wide of the wordmark. They fade out as they
   pass the poles, so the vertical axis the type occupies is always clear and
   the ring reads as two wings rather than a wheel. */
.hero-faces{
  --tile: clamp(46px, 5.4vw, 78px);
  position:absolute; left:50%; top:50%; translate:-50% -50%;
  width:min(1120px, 96vw); height:min(1120px, 96vw);
  pointer-events:none;
}
.hero-faces i{
  position:absolute; left:50%; top:50%;
  width:var(--tile); height:var(--tile);
  margin:calc(var(--tile) / -2);
  border-radius:calc(var(--tile) * 0.26);
  background-image:url(assets/faces.webp);
  background-size:700% 200%;
  box-shadow:0 1px 2px rgba(0,0,0,.05), 0 10px 28px rgba(0,0,0,.08);
  opacity:0;
  will-change:transform, opacity;
}
@media (max-width:1099px){ .hero-faces{ display:none; } }

.hero-ring{
  position:absolute; left:50%; top:50%; translate:-50% -50%;
  width:min(600px, 88vw); height:min(600px, 88vw);
  pointer-events:none;
}

.wordmark{
  position:relative; z-index:1;
  margin:0;
  font-size:clamp(80px,16vw,188px);
  line-height:.9;
  letter-spacing:0;
  font-weight:700;
}
.wm-face, .wm-reflect{ display:flex; justify-content:center; }
.wordmark span span{ display:inline-block; }
/* The paper and the poster set CHAT over its own reflection. Same idea here:
   a mirrored copy, faded out down the drop. */
.wm-reflect{
  position:absolute; left:0; right:0; top:100%;
  transform:scaleY(-1);
  margin-top:-0.161em;
  opacity:.30;
  /* The mask is resolved in the element's own box, before scaleY(-1) flips it,
     so it runs to top here in order to land opaque against the real letters. */
  -webkit-mask-image:linear-gradient(to top, rgba(0,0,0,.92), transparent 36%);
          mask-image:linear-gradient(to top, rgba(0,0,0,.92), transparent 36%);
  pointer-events:none; user-select:none;
}
/* The paper's kerns (-0.3em, then -0.35em) are set at body size against a bold
   serif; carried literally to a 188px sans they collide. The ratio between them
   is kept and the magnitude scaled to a tight logotype. */
.wordmark .c{ color:#0077E5; margin-right:-0.060em; }
.wordmark .h{ color:#0095D8; margin-right:-0.070em; }
.wordmark .a{ color:#0062E6; margin-right:-0.070em; }
.wordmark .t{ color:#0067BC; }
.hero-sub{
  margin:clamp(50px,6.6vh,88px) auto 0; max-width:16ch;
  font-size:clamp(27px,4vw,48px);
  line-height:1.08; letter-spacing:-0.026em; font-weight:600;
}
.hero-note{
  margin:18px auto 0; max-width:52ch;
  font-size:17px; line-height:1.5; color:var(--ink-2); letter-spacing:0;
}
.hero-cta{
  margin-top:clamp(22px,3.2vh,34px);
  display:flex; gap:14px; justify-content:center; flex-wrap:wrap;
}
.br-m{ display:none; }
@media (min-width:600px){ .br-m{ display:inline; } }

.btn{
  display:inline-flex; align-items:center;
  background:var(--ctrl); color:#fff;
  padding:13px 26px; border-radius:980px;
  font-size:17px; letter-spacing:0; text-decoration:none;
  box-shadow:0 1px 2px rgba(11,26,66,.18), 0 8px 22px rgba(11,26,66,.14);
  transition:background .25s var(--ease), box-shadow .25s var(--ease), transform .18s var(--ease);
}
.btn:hover{ background:var(--ctrl-ink); box-shadow:0 1px 2px rgba(11,26,66,.22), 0 12px 30px rgba(11,26,66,.20); text-decoration:none; }
.btn:active{ transform:scale(.975); }
/* Paper, video, code, conference: hairline pills, ink on white. They sit
   under the one solid button so the page has a single loudest control. */
.hero-links{
  margin:13px auto 0; display:flex; gap:10px;
  justify-content:center; flex-wrap:wrap;
}
.hero-links a{
  display:inline-flex; align-items:center; gap:8px;
  padding:9px 17px; border-radius:980px;
  border:1px solid var(--hair); background:#fff;
  color:var(--ink); font-size:15px; letter-spacing:-0.006em; text-decoration:none;
  transition:background .22s var(--ease), border-color .22s var(--ease), transform .18s var(--ease);
}
.hero-links a:hover{ background:var(--bg-2); border-color:var(--ctrl-soft); text-decoration:none; }
.hero-links a:active{ transform:scale(.98); }
.hero-links svg{
  width:15px; height:15px; flex:none;
  fill:none; stroke:currentColor; stroke-width:1.5;
  stroke-linecap:round; stroke-linejoin:round;
  color:var(--ink-2);
}
.hero-fine{
  margin:11px auto 0; max-width:52ch;
  font-size:13px; line-height:1.5; color:var(--ink-3); letter-spacing:0;
}
@media (prefers-reduced-motion: reduce){ .hero-links a{ transition:none; } }

/* ─────────── teaser reveal ─────────── */
.reveal-stage{
  max-width:min(1360px, calc(100vw - 2 * var(--gut) - 10px));
  margin-inline:auto;
  padding:0 var(--gut) clamp(72px,10vh,128px);
}
.reveal-figure{
  margin:0;
  transform-origin:center top;
}
.reveal-figure img{ width:100%; }

.caption{
  margin:30px auto 0;
  font-size:15px; line-height:1.5; color:var(--ink-3); letter-spacing:0;
}
.caption.wide{ max-width:660px; text-align:center; }

/* ─────────── statement ─────────── */
.statement{
  max-width:var(--w); margin-inline:auto;
  padding:clamp(72px,12vh,150px) var(--gut);
}
.lead{
  margin:0;
  font-size:clamp(29px,4.2vw,52px);
  line-height:1.13; letter-spacing:-0.025em; font-weight:600;
  text-wrap:balance;
}
.lead .dim{ color:var(--ink-3); display:block; }
.lead .word{ display:inline-block; }

/* ─────────── video player ─────────── */
.player-wrap{ margin-bottom:22px; }
.player{
  position:relative; aspect-ratio:2/1;
  border-radius:clamp(14px,1.6vw,22px); overflow:hidden;
  background:#000;
  box-shadow:0 2px 8px rgba(0,0,0,.05), 0 20px 64px rgba(0,0,0,.09);
}
.player video{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  opacity:0; transition:opacity .45s var(--ease);
}
.player video.on{ opacity:1; }
/* the seam between the two speakers is baked into the encode */

.segmented{
  display:inline-flex; padding:2px; gap:2px;
  background:var(--bg-2); border-radius:980px;
  margin-bottom:20px;
}
.segmented button{
  appearance:none; border:0; cursor:pointer;
  background:transparent; color:var(--ink);
  font-family:inherit; font-size:14px; letter-spacing:0;
  padding:8px 18px; border-radius:980px;
  transition:background .25s var(--ease), color .25s var(--ease);
}
.segmented button:hover{ color:#000; }
.segmented button[aria-selected="true"]{
  background:#fff; color:var(--ink);
  box-shadow:0 1px 3px rgba(0,0,0,.10), 0 0 0 .5px rgba(0,0,0,.04);
}
@media (max-width:560px){
  .segmented{ display:flex; width:100%; overflow-x:auto; }
  .segmented button{ flex:0 0 auto; }
}

.clip-note{ position:relative; min-height:3.2em; max-width:640px; }
.clip-note p{
  margin:0; position:absolute; inset:0;
  font-size:15px; line-height:1.5; color:var(--ink-2); letter-spacing:0;
  opacity:0; transition:opacity .35s var(--ease);
}
.clip-note p.on{ opacity:1; position:relative; }

/* ─────────── pinned pipeline ─────────── */
.pin-section{ background:var(--bg-2); }
.pin-inner{
  max-width:var(--w-wide); margin-inline:auto;
  padding:clamp(72px,10vh,120px) var(--gut);
  min-height:100svh;
  display:grid; grid-template-columns:1.05fr .95fr; gap:clamp(30px,5vw,80px);
  align-items:center;
}
.stages{ list-style:none; margin:34px 0 0; padding:0; }
.stages li{
  padding:24px 0; border-top:1px solid var(--hair);
  opacity:.32; transition:opacity .5s var(--ease);
}
.stages li:last-child{ border-bottom:1px solid var(--hair); }
.stages li.active{ opacity:1; }
.stage-n{
  font-family:var(--mono); font-size:12px; color:var(--ink-3);
  letter-spacing:.04em; display:block; margin-bottom:8px;
}
.stages h3{
  margin:0 0 7px; font-size:22px; font-weight:600; letter-spacing:-0.018em;
}
.stages p{ margin:0; font-size:16px; line-height:1.5; color:var(--ink-2); letter-spacing:0; }

.pin-visual{
  position:relative; aspect-ratio:1/1; max-width:420px; width:100%;
  margin-inline:auto;
  display:grid; place-items:center;
}
.orb-field{ position:absolute; inset:0; display:grid; place-items:center; }
.orb{
  position:absolute; border-radius:50%;
  transition:transform .8s var(--ease), opacity .8s var(--ease);
}
.orb.o1{
  width:56%; height:56%;
  background:radial-gradient(circle at 34% 30%, #7fc4ff, #0071e3 62%, #0055b3);
  opacity:.95;
}
.orb.o2{
  width:74%; height:74%;
  border:1px solid rgba(0,113,227,.30);
  background:radial-gradient(circle at 60% 20%, rgba(0,113,227,.10), transparent 62%);
}
.orb.o3{
  width:94%; height:94%;
  border:1px solid rgba(0,113,227,.16);
}
.pin-label{
  position:absolute; bottom:-4px;
  font-family:var(--mono); font-size:12px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-3);
  opacity:0; transition:opacity .5s var(--ease);
}
.pin-label.on{ opacity:1; }

@media (max-width:900px){
  .pin-inner{ grid-template-columns:1fr; min-height:auto; }
  .pin-visual{ display:none; }
  .stages li{ opacity:1; }
}

/* ─────────── figures ─────────── */
/* The artwork keeps the paper's own white ground, at native colour. Every
   figure sits on a white section, so no card is needed to separate it. */
.fig{ margin:0; }
.fig img{ width:100%; }

/* ─────────── prose ─────────── */
.prose{ max-width:660px; }
.prose.center{ margin-inline:auto; text-align:center; }
.prose p{
  margin:0 0 20px; font-size:19px; line-height:1.55;
  color:var(--ink-2); letter-spacing:-0.003em; text-wrap:pretty;
}
.prose p:last-child{ margin-bottom:0; }
.prose b{ color:var(--ink); font-weight:600; }

/* ─────────── tables ─────────── */
.table-card{
  background:#fff; border-radius:18px;
  box-shadow:0 2px 8px rgba(0,0,0,.04), 0 14px 44px rgba(0,0,0,.06);
  /* The tables keep nowrap cells, so the card is the scroll container and must
     never grow past its column, grid item or not. */
  width:100%; max-width:100%; min-width:0;
  overflow-x:auto; overflow-y:hidden;
  -webkit-overflow-scrolling:touch;
}
.band .table-card{ box-shadow:0 2px 8px rgba(0,0,0,.05), 0 14px 44px rgba(0,0,0,.07); }
.table-card.narrow{ max-width:min(860px, 100%); margin-inline:auto; }
.table-card + .two-up, .table-card + .fig{ margin-top:26px; }
.prose + .table-card, .prose + .fig{ margin-top:clamp(40px,6vh,68px); }
.table-card + .fig, .two-up + .fig{ margin-top:clamp(40px,6vh,68px); }
.stats + .prose{ margin-bottom:0; }

.table-card table{
  width:100%; border-collapse:collapse;
  font-variant-numeric:tabular-nums;
}
.table-card caption{
  caption-side:top; text-align:left;
  padding:22px 26px 14px;
  font-size:14px; color:var(--ink-3); letter-spacing:0;
}
.table-card th, .table-card td{ padding:13px 18px; text-align:right; white-space:nowrap; }
.table-card th[scope="row"]{ text-align:left; font-weight:400; }
.table-card thead th{
  font-size:12px; font-weight:500; color:var(--ink-3);
  border-bottom:1px solid var(--hair-soft);
  letter-spacing:0;
}
.table-card thead th i{ font-style:normal; color:var(--ink-3); padding-left:2px; }
.table-card tbody tr + tr{ border-top:1px solid var(--hair-soft); }
.table-card td{ font-size:15px; color:var(--ink-2); }
.table-card .best{ color:var(--ink); font-weight:600; }
.table-card .second{ color:var(--ink); text-decoration:underline; text-underline-offset:3px; text-decoration-color:var(--hair); }
.table-card .na{ color:var(--ink-3); }
.table-card tr.ours{ background:rgba(0,113,227,.045); }
.table-card tr.ours th[scope="row"]{ font-weight:600; color:var(--ink); }
.table-card .foot{
  margin:0; padding:14px 26px 20px;
  font-size:13px; color:var(--ink-3); letter-spacing:0;
}
table.compact th, table.compact td{ padding:11px 14px; font-size:14px; }

.two-up{ display:grid; grid-template-columns:1fr 1fr; gap:26px; margin-top:26px; }
@media (max-width:960px){ .two-up{ grid-template-columns:1fr; } }


/* ─────────── stats ─────────── */
.stats{
  display:grid; grid-template-columns:repeat(4,1fr);
  gap:clamp(20px,3vw,44px);
  margin:0 0 clamp(44px,6vh,72px);
  text-align:center;
}
@media (max-width:760px){ .stats{ grid-template-columns:1fr 1fr; gap:34px 20px; } }
.stat b{
  display:block;
  font-size:clamp(38px,5.2vw,66px);
  line-height:1; letter-spacing:-0.035em; font-weight:600;
  font-variant-numeric:tabular-nums;
  background:linear-gradient(180deg,#1d1d1f,#4a4a50);
  -webkit-background-clip:text; background-clip:text;
  -webkit-text-fill-color:transparent;
}
.stat span{
  display:block; margin-top:10px;
  font-size:15px; color:var(--ink-2); letter-spacing:0;
}

/* ─────────── poster ─────────── */
.poster{
  display:block; position:relative; border-radius:clamp(12px,1.4vw,20px); overflow:hidden;
  background:#fff;
  box-shadow:0 2px 8px rgba(0,0,0,.04), 0 18px 56px rgba(0,0,0,.08);
}
.poster img{ width:100%; transition:transform .9s var(--ease); }
.poster:hover img{ transform:scale(1.014); }


/* ─────────── authors + bibtex ─────────── */
.authors{
  margin:0 0 20px; max-width:800px;
  font-size:18px; line-height:1.78; letter-spacing:-0.004em;
  color:var(--ink);
}
/* Each name and its marker travel together, so no author is split over a line
   break and the commas stay where they belong. */
.authors .au{ white-space:nowrap; }
.authors sup{
  font-size:.6em; font-weight:500; color:var(--ink-3);
  vertical-align:super; line-height:0; margin-left:1px;
}

/* Eight affiliations on a grid, the number hanging in its own column, so the
   institutions line up instead of running together across the measure. */
.affils{
  margin:0 0 clamp(30px,4.4vh,48px); max-width:820px;
  display:grid; grid-template-columns:repeat(2, minmax(0,1fr));
  gap:8px 44px;
  font-size:13.5px; line-height:1.5; color:var(--ink-2); letter-spacing:0;
}
.affils > span{
  display:grid; grid-template-columns:14px 1fr;
  align-items:baseline; column-gap:2px; white-space:normal;
}
.affils sup{
  font-size:1em; vertical-align:baseline; color:var(--ink-3);
  font-variant-numeric:tabular-nums;
}
.affils .corr{ grid-column:1 / -1; color:var(--ink-3); }
@media (max-width:720px){ .affils{ grid-template-columns:1fr; gap:7px; } }

/* ── availability ──
   One label column, three rows. The pills this replaces were three different
   widths carrying three different kinds of thing. */
.avail{
  margin:clamp(30px,4.6vh,50px) 0 0; max-width:780px;
  padding-top:22px; border-top:1px solid var(--hair-soft);
  display:grid; grid-template-columns:max-content 1fr; gap:14px 32px;
}
.avail dt{
  margin:0; font-size:13px; letter-spacing:.02em; color:var(--ink-3);
}
.avail dd{
  margin:0; font-size:15px; line-height:1.55; color:var(--ink-2); letter-spacing:0;
}
.avail dd .sep{ color:var(--ink-3); padding:0 8px; }
@media (max-width:620px){
  .avail{ grid-template-columns:1fr; gap:3px 0; }
  .avail dt{ margin-top:14px; }
  .avail dt:first-of-type{ margin-top:0; }
}

.bib{
  position:relative; background:var(--bg-2);
  border-radius:16px; overflow:hidden;
}
.bib pre{ margin:0; padding:26px; overflow-x:auto; }
.bib code{
  font-family:var(--mono); font-size:13px; line-height:1.75;
  color:var(--ink-2); letter-spacing:0;
}
.bib button{
  position:absolute; top:14px; right:14px;
  appearance:none; cursor:pointer;
  background:#fff; color:var(--ctrl); border:0;
  font-family:inherit; font-size:13px; letter-spacing:0;
  padding:7px 15px; border-radius:980px;
  box-shadow:0 1px 3px rgba(0,0,0,.10);
  transition:transform .18s var(--ease);
}
.bib button:active{ transform:scale(.96); }
.bib button.done{ color:#1d8a3f; }

.pending{ margin:14px 0 0; font-size:14px; color:var(--ink-3); letter-spacing:0; }



/* ─────────── footer ─────────── */
footer{ background:var(--bg-2); border-top:1px solid var(--hair-soft); }
.foot-in{
  max-width:var(--w-wide); margin-inline:auto;
  padding:34px var(--gut) 44px;
}
.foot-in p{ margin:0 0 6px; font-size:13px; color:var(--ink-2); letter-spacing:0; }
.foot-in .dim{ color:var(--ink-3); margin:0; }

/* ─────────── reduced transparency / contrast ─────────── */
@media (prefers-reduced-transparency: reduce){
  .nav{ background:#fff; backdrop-filter:none; -webkit-backdrop-filter:none; }
}
@media (prefers-contrast: more){
  :root{ --ink-2:#3a3a3f; --ink-3:#54545a; --hair:#8e8e93; }
  .nav{ background:#fff; backdrop-filter:none; -webkit-backdrop-filter:none; }
}

/* ─────────── mechanism panels ───────────────────────────────
   Each panel draws the rule the paper states. Scroll scrubs the
   variable the rule is written in: the playhead, the denoising
   step, the blend window. Nothing here is decorative.
   ─────────────────────────────────────────────────────────── */
.mech{
  display:grid; grid-template-columns:minmax(0,.86fr) minmax(0,1.14fr);
  min-width:0;
  gap:clamp(28px,5vw,74px); align-items:center;
  padding:clamp(44px,6vh,76px) 0;
  border-top:1px solid var(--hair);
}
.mech:first-of-type{ border-top:0; padding-top:0; }
.mech.reverse .mech-copy{ order:2; }
.mech.reverse .mech-vis{ order:1; }
@media (max-width:900px){
  .mech{ grid-template-columns:1fr; gap:26px; }
  .mech.reverse .mech-copy{ order:1; }
  .mech.reverse .mech-vis{ order:2; }
}

.mech-n{
  margin:0 0 10px; font-family:var(--mono); font-size:12px;
  letter-spacing:.06em; color:var(--ink-3);
}
.mech-copy{ min-width:0; }
.mech-copy h3{
  margin:0 0 12px; font-size:clamp(23px,2.5vw,30px);
  line-height:1.15; letter-spacing:-0.022em; font-weight:600;
}
.mech-copy p{
  margin:0 0 14px; font-size:17px; line-height:1.52;
  color:var(--ink-2); letter-spacing:-0.003em; max-width:44ch;
}
.mech-formula{
  margin:0 !important; padding:12px 16px; max-width:100%;
  overflow-x:auto;
  background:#fff; border-radius:10px;
  font-family:var(--mono); font-size:13px !important; line-height:1.6 !important;
  color:var(--ink) !important; letter-spacing:0 !important;
  display:inline-block;
}
.mech-formula sub, .mech-formula sup{ font-size:.78em; }

.mech-vis{ width:100%; min-width:0; }
.mech-vis svg{ width:100%; height:auto; overflow:hidden; }

/* shared type inside the diagrams */
.tl-lab, .sc-lab, .bl-lab, .sc-read, .bl-a{
  font-family:var(--mono); font-size:11px; fill:var(--ink-3);
  letter-spacing:.06em;
}
.sc-read, .bl-a{ fill:var(--blue); text-anchor:end; }
.bl-a, .bl-lab{ text-anchor:middle; }
.sc-end{ text-anchor:end; }

/* 1 · timeline */
.tl-grid line{ stroke:var(--hair-soft); stroke-width:1; }
.tl-blocks rect{ rx:4; }
.tl-blocks .say{ fill:#c9ccd2; transition:fill .25s linear; }
.tl-blocks .say.live{ fill:var(--blue); }
.tl-blocks .bc{ fill:#dfe2e7; transition:fill .25s linear; }
.tl-blocks .bc.live{ fill:#8fc3f5; }
.tl-blocks text{
  font-family:var(--mono); font-size:9px; fill:var(--ink-3);
  text-anchor:middle; letter-spacing:.04em;
}
.tl-head{ stroke:var(--ink); stroke-width:1.5; }

/* 2 · scales */
.sc-rows rect{ rx:2.5; fill:#d7dae0; transition:fill .3s linear, opacity .3s linear; }
.sc-rows rect.on{ fill:var(--blue); }
.sc-rows .sc-rowlab{
  font-family:var(--mono); font-size:11px; fill:var(--ink-3);
  letter-spacing:.06em; text-anchor:end;
}
.sc-axis line{ stroke:var(--hair); stroke-width:1; }
.sc-head{ stroke:var(--ink); stroke-width:1.5; }

/* 3 · blend */
.bl-bars rect{ rx:3; }
.bl-seam{ stroke:var(--hair); stroke-width:1; stroke-dasharray:3 3; }
.bl-curve{ fill:rgba(0,113,227,.10); stroke:var(--blue); stroke-width:1.5; }

@media (prefers-reduced-motion: reduce){
  .tl-head, .sc-head{ opacity:.35; }
}

/* ─────────── sound toggle ─────────── */


/* ─────────── project mark ─────────── */
/* The project's own shield. It is detailed for its size, so it gets the whole
   height the 48px bar allows rather than being shrunk to fit beside the type. */
.nav-brand img{
  width:auto; height:28px; display:block;
  transition:transform .25s var(--ease);
}
.nav-brand:hover img{ transform:translateY(-1px) scale(1.05); }
.nav-brand span{
  display:block; font-weight:700; letter-spacing:-0.014em;
}

.hero-mark{
  width:clamp(52px, 6vw, 72px); height:auto;
  display:block; margin:0 auto clamp(18px, 2.4vh, 28px);
}

/* ─────────── volume ─────────── */
/* One control: the button mutes, the slider sets the level. The slider stays
   hidden until the pointer or keyboard is on the control, so a muted player
   shows one affordance rather than two. */
.volume{
  position:absolute; right:14px; bottom:14px; z-index:2;
  display:flex; align-items:center; gap:0;
  padding:0 4px 0 0; border-radius:980px;
  background:rgba(0,0,0,.42);
  -webkit-backdrop-filter:blur(18px) saturate(180%);
          backdrop-filter:blur(18px) saturate(180%);
  border:1px solid rgba(255,255,255,.16);
  transition:background .25s var(--ease);
}
.volume:hover, .volume:focus-within{ background:rgba(0,0,0,.55); }

.vol-btn{
  appearance:none; -webkit-appearance:none;
  display:inline-flex; align-items:center; gap:7px;
  padding:8px 12px; border:0; background:transparent; cursor:pointer;
  color:#fff; font:inherit; font-size:12px; letter-spacing:.01em;
  border-radius:980px;
}
.vol-btn svg{ width:19px; height:19px; fill:none; stroke:#fff; stroke-width:1.5;
  stroke-linecap:round; stroke-linejoin:round; }
.vol-btn .spk{ fill:#fff; stroke:none; }
.vol-btn .waves{ opacity:0; transition:opacity .25s var(--ease); }
.vol-btn .slash{ opacity:1; transition:opacity .25s var(--ease); }
.volume.on .vol-btn .waves{ opacity:1; }
.volume.on .vol-btn .slash{ opacity:0; }
.vol-btn:focus-visible{ outline:2px solid #fff; outline-offset:2px; }

.vol-range{
  appearance:none; -webkit-appearance:none;
  width:0; opacity:0; margin:0; background:transparent; cursor:pointer;
  transition:width .32s var(--ease), opacity .24s var(--ease), margin .32s var(--ease);
}
.volume:hover .vol-range,
.volume:focus-within .vol-range,
.volume.on .vol-range{ width:78px; opacity:1; margin:0 10px 0 2px; }
.vol-range::-webkit-slider-runnable-track{
  height:3px; border-radius:3px;
  background:linear-gradient(to right, #fff 0 var(--fill,70%), rgba(255,255,255,.28) var(--fill,70%) 100%);
}
.vol-range::-moz-range-track{ height:3px; border-radius:3px; background:rgba(255,255,255,.28); }
.vol-range::-moz-range-progress{ height:3px; border-radius:3px; background:#fff; }
.vol-range::-webkit-slider-thumb{
  appearance:none; -webkit-appearance:none;
  width:11px; height:11px; margin-top:-4px; border-radius:50%; background:#fff;
  box-shadow:0 1px 3px rgba(0,0,0,.4);
}
.vol-range::-moz-range-thumb{
  width:11px; height:11px; border:0; border-radius:50%; background:#fff;
  box-shadow:0 1px 3px rgba(0,0,0,.4);
}
.vol-range:focus-visible{ outline:2px solid #fff; outline-offset:4px; }

/* ─────────── wide figures ─────────── */
/* The paper figures carry small type, so they get more width than the text
   column: the artwork is the content here, not an illustration beside it.
   max(100%, ...) keeps them from shrinking below the column on narrow screens. */
.fig-bleed{
  --bleed-w: max(100%, min(1360px, calc(100vw - 2 * var(--gut) - 10px)));
  width:var(--bleed-w);
  margin-inline:calc((100% - var(--bleed-w)) / 2);
}
/* The responsive-block figure is nearly square and reads fine on the text
   column, so it stays there rather than bleeding with the wide ones. */
.fig-bleed.narrow-bleed{ --bleed-w: 100%; }
.fig-open{
  display:block; position:relative; line-height:0;
  border-radius:clamp(8px,1vw,14px); overflow:hidden;
  text-decoration:none;
}
.fig-open img{ width:100%; display:block; }
.fig-zoom{
  position:absolute; right:12px; bottom:12px;
  padding:6px 11px; border-radius:980px;
  font-size:12px; line-height:1.2; letter-spacing:.01em; color:#fff;
  background:rgba(0,0,0,.44);
  -webkit-backdrop-filter:blur(14px) saturate(180%);
          backdrop-filter:blur(14px) saturate(180%);
  opacity:0; transform:translateY(4px);
  transition:opacity .28s var(--ease), transform .28s var(--ease);
}
.fig-open:hover .fig-zoom, .fig-open:focus-visible .fig-zoom{ opacity:1; transform:none; }
/* No hover on touch, and the small type in these figures is exactly where a
   phone reader needs the full-size link, so show it outright. */
@media (hover: none){ .fig-zoom{ opacity:1; transform:none; } }
.fig-open:focus-visible{ outline:2px solid var(--blue); outline-offset:3px; }

/* Guided read of the pipeline figure. The figure already prints its own
   (a) (b) (c) labels, so nothing is added on top: the two stages you are not
   being shown are simply veiled, one after the other, and then all three
   return. The boxes tile the figure exactly, so nothing is veiled twice. */
.fig-marks{ position:absolute; inset:0; pointer-events:none; }
.fig-dim{
  position:absolute;
  left:calc(var(--x) * 100%); top:calc(var(--y) * 100%);
  width:calc(var(--w) * 100%); height:calc(var(--h) * 100%);
  background:#fff; opacity:0;
}

@media (prefers-reduced-motion: reduce){
  .vol-range{ transition:none; }
  .fig-zoom{ transition:none; }
}

/* Provenance note, set under the clip note and on the same optical column. */
.foot.provenance{
  max-width:640px; margin:22px 0 0;
  font-size:13px; line-height:1.55; color:var(--ink-3); letter-spacing:0;
}

/* ─────────── turn-taking timeline ───────────
   The clips' own unit boundaries, drawn on one shared axis. It is here because
   the shared timeline is the claim: a back-channel bar sitting inside the other
   speaker's sentence bar is the thing to see, and it is hard to see in the video
   alone. Timings come from the generated plan, not from anything hand-drawn. */
.turns{
  position:relative;
  margin:0 0 22px; padding:0;
  /* Height is reserved whether or not a clip has a published unit list, so
     switching to one that has none does not shift the tabs under it. The empty
     state is carried by the children, not by opacity on the figure: the figure
     is a reveal target, and GSAP writes opacity there inline. */
  min-height:86px;
}
.turns:not(.ready) .turns-grid{ visibility:hidden; }
/* Sits over the hidden lanes rather than under them, so the tabs below do not
   move when a clip without a unit list is selected. */
.turns-empty{
  position:absolute; left:0; top:30px; margin:0; max-width:56ch;
  font-size:13px; line-height:1.55; color:var(--ink-3); letter-spacing:0;
  display:none;
}
.turns:not(.ready) .turns-empty{ display:block; }
.turns-cap{
  font-size:12px; letter-spacing:.02em; color:var(--ink-3);
  margin:0 0 10px;
}
.turns-grid{
  display:grid; grid-template-columns:auto 1fr; gap:6px 12px; align-items:center;
}
.turns-name{
  font-size:11px; letter-spacing:.03em; color:var(--ink-3);
  text-align:right; white-space:nowrap;
}
.lane{
  position:relative; height:14px; border-radius:7px;
  background:var(--bg-2);
}
.lane span{
  position:absolute; top:0; bottom:0;
  left:calc(var(--a) * 100%); width:calc(var(--w) * 100%);
  border-radius:7px; background:var(--ink);
  opacity:.26; transition:opacity .18s var(--ease), background .18s var(--ease);
}
.lane span.word{ top:3px; bottom:3px; border-radius:4px; }
.lane span.live{ opacity:1; background:var(--blue); }
.turns-axis{
  position:relative; height:12px;
  font-size:10px; color:var(--ink-3); letter-spacing:.03em;
}
.turns-axis i{ position:absolute; top:0; font-style:normal; }
.turns-axis i:nth-child(1){ left:0; }
.turns-axis i:nth-child(2){ left:50%; transform:translateX(-50%); }
.turns-axis i:nth-child(3){ right:0; }
/* One playhead per lane, both driven by --t on the figure, so the two rows
   cannot drift apart. */
.lane::after{
  content:""; position:absolute; top:-3px; bottom:-3px;
  left:calc(var(--t, 0) * 100%); width:1.5px;
  background:var(--blue); opacity:var(--head, 0);
  pointer-events:none;
}
@media (max-width:560px){
  .turns-name{ font-size:10px; }
  .turns-cap{ font-size:11px; }
}

/* ─────────── figure viewer ───────────
   Opening a figure should not leave the page. The dialog dims the site behind
   a blurred scrim, grows the artwork out of the thumbnail it came from, and
   lets a dense figure be zoomed to its own pixels and panned. */
.lb{
  position:fixed; inset:0; z-index:150;   /* above the sticky nav at 100 */
  display:flex; align-items:center; justify-content:center;
}
.lb[hidden]{ display:none; }
.lb-scrim{
  position:absolute; inset:0;
  background:rgba(12,12,14,.72);
  -webkit-backdrop-filter:blur(26px) saturate(150%);
          backdrop-filter:blur(26px) saturate(150%);
  opacity:0;
}
.lb-frame{
  position:relative; z-index:1;
  display:flex; flex-direction:column; align-items:center; gap:16px;
  width:min(1560px, 94vw); max-height:92vh;
}
.lb-stage{
  display:flex; align-items:center; justify-content:center;
  max-width:100%; max-height:calc(92vh - 84px);
  border-radius:clamp(10px,1.1vw,16px);
  overflow:hidden;
  box-shadow:0 30px 90px rgba(0,0,0,.45);
  background:#fff;
}
.lb-stage img{
  display:block; max-width:100%; max-height:calc(92vh - 84px);
  width:auto; height:auto;
  cursor:zoom-in; user-select:none; -webkit-user-drag:none;
}
/* Zoomed: the stage becomes the scroller and the artwork takes its own size. */
.lb-stage.zoom{ overflow:auto; -webkit-overflow-scrolling:touch; cursor:grab; }
.lb-stage.zoom.drag{ cursor:grabbing; }
.lb-stage.zoom img{ max-width:none; max-height:none; cursor:inherit; }

.lb-bar{
  display:flex; align-items:baseline; justify-content:center; gap:18px;
  flex-wrap:wrap; max-width:760px;
}
.lb-cap{
  margin:0; text-align:center;
  font-size:14px; line-height:1.5; letter-spacing:0;
  color:rgba(255,255,255,.78);
}
.lb-orig{
  flex:none; font-size:13px; color:#fff; text-decoration:none;
  padding:7px 14px; border-radius:980px;
  background:rgba(255,255,255,.14);
  border:1px solid rgba(255,255,255,.2);
  transition:background .22s var(--ease);
}
.lb-orig:hover{ background:rgba(255,255,255,.24); text-decoration:none; }
.lb-orig[hidden]{ display:none; }

.lb-btn{
  position:absolute; z-index:2;
  width:42px; height:42px; padding:0;
  display:grid; place-items:center;
  border:1px solid rgba(255,255,255,.18); border-radius:50%;
  background:rgba(255,255,255,.12); color:#fff; cursor:pointer;
  -webkit-backdrop-filter:blur(16px); backdrop-filter:blur(16px);
  transition:background .22s var(--ease), transform .18s var(--ease), opacity .22s var(--ease);
}
.lb-btn svg{ width:22px; height:22px; fill:none; stroke:currentColor; stroke-width:1.7; stroke-linecap:round; }
.lb-btn:hover{ background:rgba(255,255,255,.24); }
.lb-btn:active{ transform:scale(.94); }
.lb-btn:focus-visible{ outline:2px solid #fff; outline-offset:3px; }
.lb-close{ top:clamp(14px,2.4vh,26px); right:clamp(14px,2.4vw,26px); }
.lb-prev{ left:clamp(10px,1.8vw,26px); top:50%; margin-top:-21px; }
.lb-next{ right:clamp(10px,1.8vw,26px); top:50%; margin-top:-21px; }
.lb-hint{
  position:absolute; left:50%; translate:-50% 0; bottom:clamp(10px,2vh,20px);
  margin:0; font-size:12px; letter-spacing:.02em; color:rgba(255,255,255,.5);
  pointer-events:none; transition:opacity .3s var(--ease);
}
@media (max-width:700px){
  .lb-prev, .lb-next{ top:auto; bottom:clamp(10px,2vh,20px); margin-top:0; }
  .lb-hint{ display:none; }
}
body.lb-open{ overflow:hidden; }
@media (prefers-reduced-motion: reduce){
  .lb-btn, .lb-orig, .lb-hint{ transition:none; }
}
