/* ============================================================================
   O3DC — "READ THE WARNING LABEL"
   A PR-first concept skin. The register is a pharmaceutical package insert:
   the index's 135 hand-written notes are the product, so the whole page is
   built as the thing you read BEFORE you trust a result.

   Three deliberate departures from a conventional benchmark directory:
     1. Dark only. The X creative this echoes is dark only, and committing to one
        look removes an axis nobody is going to decide by looking at both.
     2. State is carried by TEXTURE + WORDS, never by colour. Green vs amber
        measures dE 5.6 under protanopia — below any usable floor — so the
        three shelf states are solid bar / 45-degree hatch / no bar + dashed edge,
        each with its state printed in words. Colour is redundant throughout.
     3. No card grid, no four-up stat strip, no centred hero. Five numbered acts.
   ========================================================================== */

@font-face{
  font-family:"Mona Sans";
  src:url("fonts/mona-sans-variable.woff2") format("woff2-variations");
  font-weight:200 900; font-display:swap;
}

:root{
  /* ground */
  --ground:#07090b;
  --panel:#0e1412;
  --panel2:#111917;
  --rule:#1c2522;
  --rule-hi:#2b3a35;

  /* ink — all measured against --ground and --panel, all clear AA */
  --ink:#eef2ee;      /* 17.6:1 on ground */
  --ink2:#a9b3ad;     /*  9.3:1 */
  --ink3:#7d8880;     /*  5.4:1 — the mono micro-label ink, AA at 12px */
  --neon:#01CE87;     /*  9.7:1 — O3DC brand green, unchanged */
  --neon-hi:#5cf5b3;  /* 14.4:1 — glow / hover only */
  --neon-dim:#0a2e22;
  --stamp:#d9553f;    /*  5.0:1 — the EXPIRED stamp. Redundant with the word. */
  --bone:#cfd6cf;     /* 13.5:1 — the hatch ink */

  --serif:ui-serif,"New York","Iowan Old Style",Palatino,"Palatino Linotype","Book Antiqua",Georgia,serif;
  --sans:"Mona Sans",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --mono:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace;

  /* The reading measure is in REM, not ch: four blocks at four font sizes read
     it, and ch would give each of them a different pixel width. */
  --measure:40rem;
  --pad:clamp(20px,4vw,64px);
  --maxw:1560px;

  /* Symmetric ease. The house cubic-bezier(.16,1,.3,1) spends 83% of the
     distance in the first 25% of the time — wrong for anything a reader tracks. */
  --ease:cubic-bezier(.4,0,.2,1);
}

*{box-sizing:border-box}
[hidden]{display:none!important}
html{background:var(--ground);scroll-behavior:smooth}
body{
  margin:0;background:var(--ground);color:var(--ink);
  font-family:var(--sans);font-weight:400;font-size:15px;line-height:1.55;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%}
a{color:var(--neon);text-decoration-color:color-mix(in oklab,var(--neon) 45%,transparent);text-underline-offset:3px}
a:hover{color:var(--neon-hi)}
:focus-visible{outline:2px solid var(--neon-hi);outline-offset:3px;border-radius:2px}

/* ---- shared type ------------------------------------------------------- */
.mono{font-family:var(--mono);font-size:11.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink3)}
/* Symbols and technical names must escape the uppercasing: a capital rho is a
   Latin P and "Tm" becomes a trademark symbol. */
.nocase{text-transform:none;letter-spacing:.04em}
.serif{font-family:var(--serif);font-weight:400;letter-spacing:-.012em;line-height:1.02}
.num{font-family:var(--mono);font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}

/* ---- the seal: a fixed lot line, the way a blister pack is printed ----- */
.seal{
  position:fixed;inset:0 0 auto 0;z-index:60;height:34px;
  display:flex;align-items:center;gap:18px;padding:0 var(--pad);
  background:color-mix(in oklab,var(--ground) 88%,transparent);
  backdrop-filter:blur(9px);border-bottom:1px solid var(--rule);
  font-family:var(--mono);font-size:10.5px;letter-spacing:.15em;text-transform:uppercase;
  color:var(--ink3);white-space:nowrap;overflow:hidden;
}
.seal b{color:var(--neon);font-weight:400}
.seal .grow{flex:1}
.seal .seal__x{color:var(--ink2)}
@media (max-width:820px){ .seal .opt{display:none} }

/* a live green pulse — the "we are checking" tell, one dot, no spinner */
.pulse{width:6px;height:6px;border-radius:50%;background:var(--neon);flex:none;
  box-shadow:0 0 0 0 color-mix(in oklab,var(--neon) 70%,transparent);animation:pulse 2.4s var(--ease) infinite}
@keyframes pulse{
  0%{box-shadow:0 0 0 0 color-mix(in oklab,var(--neon) 55%,transparent)}
  70%{box-shadow:0 0 0 7px transparent}100%{box-shadow:0 0 0 0 transparent}
}

/* ---- act scaffolding --------------------------------------------------- */
.act{position:relative;padding:88px var(--pad) 96px;max-width:var(--maxw);margin:0 auto}
.act--0{padding-top:calc(34px + 74px);min-height:100svh;display:flex;flex-direction:column;justify-content:center}
.act+.act{border-top:1px solid var(--rule)}
.acthead{display:flex;align-items:baseline;gap:16px;margin:0 0 10px}
.acthead .no{font-family:var(--mono);font-size:12px;letter-spacing:.16em;color:var(--neon);
  border-bottom:1px solid var(--neon);padding-bottom:2px;font-weight:400}
.acthead h2{margin:0;font-family:var(--serif);font-weight:400;font-size:clamp(26px,3.4vw,40px);letter-spacing:-.015em;line-height:1.08}
.actlede{max-width:var(--measure);color:var(--ink2);font-size:14.5px;margin:0 0 34px}
.actlede b{color:var(--ink);font-weight:600}

/* ---- ACT 00 ------------------------------------------------------------ */
.kick{margin:0 0 26px;font-family:var(--mono);font-size:11.5px;letter-spacing:.19em;
  text-transform:uppercase;color:var(--ink3)}
.kick em{color:var(--neon);font-style:normal}

/* The headline sits in a scan band — the same device as the O3DC launch card:
   a horizontal green bloom that sweeps once, then rests. */
/* full-bleed: the glow is a band across the page, not a panel with corners.
   Confined to its column it read as a rectangle someone forgot to fade out. */
.band{position:relative;isolation:isolate;margin:0 0 34px;padding:38px 0}
.band__bleed{position:absolute;top:0;bottom:0;left:calc(50% - 50vw);width:100vw;z-index:-1;
  pointer-events:none;overflow:hidden;
  mask-image:linear-gradient(180deg,transparent,#000 22%,#000 78%,transparent)}
/* both decorative layers are children of the bleed, which is `overflow:hidden`,
   so neither can widen the document. Measured: scrollWidth == clientWidth. */
.band__bleed>*,.band__bleed::before,.band__bleed::after{max-width:100%}
.band__bleed::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(120% 78% at 12% 50%, color-mix(in oklab,var(--neon) 26%,transparent) 0%, transparent 68%),
    radial-gradient(90% 120% at 78% 46%, color-mix(in oklab,#0f6 13%,transparent) 0%, transparent 70%);
  filter:blur(2px);
}
/* concentric arcs, echoing the launch card's rings — pure decoration, flat,
   so it can never be mistaken for a rendered measurement */
.band__bleed::after{
  content:"";position:absolute;inset:-40% -10% -40% 40%;z-index:-1;pointer-events:none;opacity:.5;
  background:repeating-radial-gradient(circle at 84% 50%,
    transparent 0 62px, color-mix(in oklab,var(--neon) 24%,transparent) 62px 63.4px);
  mask-image:linear-gradient(90deg,transparent,#000 55%);
}
.band h1{
  margin:0;font-family:var(--serif);font-weight:400;
  font-size:clamp(46px,8.6vw,116px);line-height:.93;letter-spacing:-.028em;color:#fff;
  text-shadow:0 0 42px color-mix(in oklab,var(--neon) 30%,transparent);
}
.band__bleed .sweep{
  position:absolute;top:0;bottom:0;width:34%;pointer-events:none;z-index:-1;
  background:linear-gradient(90deg,transparent,color-mix(in oklab,var(--neon-hi) 22%,transparent),transparent);
  filter:blur(14px);animation:sweep 3.4s var(--ease) .35s 1 both;
}
@keyframes sweep{from{left:-40%}to{left:110%}}

.open__grid{display:grid;gap:clamp(28px,4vw,62px);grid-template-columns:minmax(0,1fr)}
@media (min-width:1080px){ .open__grid{grid-template-columns:minmax(0,var(--measure)) minmax(0,1fr);align-items:start} }
.open__lede{margin:0 0 26px;max-width:var(--measure);font-size:16.5px;color:var(--ink2);line-height:1.6}
.open__lede b{color:var(--ink);font-weight:600}
.open__lede .hl{color:var(--neon);font-weight:600}

.jump{display:flex;flex-wrap:wrap;gap:10px;margin:0}

/* the standalone live readout. Its width is reserved so ticking digits — which
   change every second — can never reflow the block or the page. */
.tick{margin:30px 0 0;border:1px solid var(--rule);border-left:3px solid var(--stamp);
  border-radius:2px;background:var(--panel);padding:17px 19px 16px}
.tick__v{font-family:var(--mono);font-variant-numeric:tabular-nums;font-weight:500;
  font-size:clamp(24px,3.2vw,40px);line-height:1;color:var(--ink);letter-spacing:-.012em;
  min-width:12ch;display:block}
.tick__v .u{font-size:.46em;color:var(--stamp);letter-spacing:.1em;margin:0 .12em 0 .3em;font-weight:400}
.tick__l{display:block;margin:11px 0 0;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.13em;text-transform:uppercase;color:var(--ink3);line-height:1.5}
.tick__n{display:block;margin:6px 0 0;font-size:12.5px;color:var(--ink2);line-height:1.5}
.tick__n b{color:var(--ink);font-weight:600}
.jbtn{
  font-family:var(--mono);font-size:11.5px;letter-spacing:.13em;text-transform:uppercase;
  padding:11px 17px;border-radius:2px;cursor:pointer;
  border:1px solid var(--rule-hi);background:transparent;color:var(--ink);
  transition:border-color .2s var(--ease),color .2s var(--ease),background .2s var(--ease);
}
.jbtn:hover{border-color:var(--neon);color:var(--neon)}
.jbtn--p{background:var(--neon);border-color:var(--neon);color:#04140d;font-weight:600}
.jbtn--p:hover{background:var(--neon-hi);border-color:var(--neon-hi);color:#04140d}

/* ---- the vitals: live readouts, every one computed from the feed -------- */
.vitals{display:grid;gap:1px;background:var(--rule);border:1px solid var(--rule);border-radius:3px;overflow:hidden}
.vital{background:var(--panel);padding:16px 18px 15px;display:flex;flex-direction:column;gap:5px}
.vital__v{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:clamp(21px,2.5vw,30px);
  font-weight:500;color:var(--ink);letter-spacing:-.01em;line-height:1}
.vital__v .u{font-size:.5em;color:var(--ink3);letter-spacing:.1em;margin:0 .1em 0 .3em;font-weight:400}
.vital__v.is-neon{color:var(--neon)}
.vital__l{font-family:var(--mono);font-size:10.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink3);line-height:1.45}
.vital__n{font-size:12.5px;color:var(--ink2);line-height:1.45}

/* ---- ACT 01 · THE SHELF ------------------------------------------------ */
.shelf{display:grid;gap:9px;grid-template-columns:repeat(auto-fill,minmax(172px,1fr))}
.chip{
  position:relative;display:flex;flex-direction:column;gap:6px;
  padding:11px 12px 11px 15px;border:1px solid var(--rule);border-radius:2px;
  background:var(--panel);text-align:left;cursor:pointer;color:inherit;font:inherit;
  transition:border-color .18s var(--ease),background .18s var(--ease),transform .18s var(--ease);
}
.chip:hover{border-color:var(--rule-hi);background:var(--panel2);transform:translateY(-1px)}
.chip__bar{position:absolute;left:0;top:0;bottom:0;width:4px}
/* channel 1 of 3 — SOLID */
.chip--live .chip__bar{background:var(--neon)}
/* channel 2 of 3 — 45-degree HATCH. Reads as texture with no colour at all. */
.chip--dead .chip__bar{
  background:repeating-linear-gradient(45deg,var(--bone) 0 2px,transparent 2px 4.6px);
}
/* channel 3 of 3 — NO bar, and the edge goes dashed */
.chip--none{border-style:dashed;background:transparent}
.chip--none .chip__bar{display:none}

.chip__name{font-size:12.5px;font-weight:600;line-height:1.3;color:var(--ink);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.chip--none .chip__name{color:var(--ink2);font-weight:500}
.chip__foot{display:flex;align-items:center;gap:7px;font-family:var(--mono);font-size:10px;
  letter-spacing:.09em;text-transform:uppercase;color:var(--ink3);margin-top:auto}
.chip--live .chip__foot .st{color:var(--neon)}
.chip--dead .chip__foot .st{color:var(--bone)}
.chip__foot .yrs{color:var(--stamp)}
.chip.is-cur{border-color:var(--neon);box-shadow:inset 0 0 0 1px var(--neon)}

/* the expiry rule — a full-width divider row inside the grid */
.shelfrule{grid-column:1/-1;display:flex;align-items:center;gap:14px;margin:20px 0 11px}
.shelfrule .ln{flex:1;height:1px;background:linear-gradient(90deg,var(--stamp),var(--rule) 92%)}
.shelfrule .lbl{font-family:var(--mono);font-size:11px;letter-spacing:.15em;text-transform:uppercase;
  color:var(--stamp);white-space:nowrap}
.shelfrule--none .ln{background:linear-gradient(90deg,var(--rule-hi),var(--rule) 92%)}
.shelfrule--none .lbl{color:var(--ink2)}
/* The rule's label is nowrap so it reads as one printed line beside the rule.
   Below ~560px that single line is wider than the viewport (measured: 4px of
   document overflow at 380px), so it is allowed to wrap and the rule drops under
   it. Wrapping is the only lever here — shrinking the type further would put an
   11px mono label under the AA floor. */
@media (max-width:560px){
  .shelfrule{flex-wrap:wrap;gap:8px}
  .shelfrule .lbl{white-space:normal}
  .shelfrule .ln{flex:1 0 100%}
}

/* the shelf sweeps in on scroll: a stagger, not eight separate animations */
.shelf.is-armed .chip{opacity:0;transform:translateY(9px)}
.shelf.is-run .chip{animation:rise .5s var(--ease) both;animation-delay:var(--d,0ms)}
@keyframes rise{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}

.key{display:flex;flex-wrap:wrap;gap:10px 26px;margin:26px 0 0;padding-top:16px;border-top:1px solid var(--rule)}
.key__i{display:flex;align-items:center;gap:9px;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--ink3)}
/* the key's swatches carry the chip's own classes, so the key cannot drift
   from the marks it describes */
.key__sw{width:16px;height:16px;border:1px solid var(--rule);position:relative;flex:none;background:var(--panel)}

/* ---- ACT 02 · the shelves by category --------------------------------- */
.cats{display:grid;gap:1px;background:var(--rule);border:1px solid var(--rule);border-radius:3px}
.catrow{
  display:grid;grid-template-columns:var(--cat-t);align-items:center;gap:18px;
  background:var(--panel);padding:13px 18px;
}
:root{--cat-t:2.6ch minmax(0,20ch) minmax(0,1fr) 8ch}
@media (max-width:820px){ :root{--cat-t:2.6ch minmax(0,1fr)} .catrow .bar,.catrow .pc{display:none} }
.catrow--h{background:var(--ground);padding-top:9px;padding-bottom:9px}
.catrow--h span{font-family:var(--mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink3)}
.catrow .n{font-family:var(--mono);font-size:12px;color:var(--ink3);text-align:right;font-variant-numeric:tabular-nums}
.catrow .nm{font-size:13px;font-weight:600;line-height:1.25}
.catrow .pc{font-family:var(--mono);font-size:12.5px;text-align:right;font-variant-numeric:tabular-nums;color:var(--ink2)}
.catrow.is-worst .pc{color:var(--stamp)}
.bar{display:flex;height:20px;border:1px solid var(--rule);background:var(--ground)}
.seg{position:relative;min-width:0}
.seg--live{background:var(--neon)}
.seg--dead{background:repeating-linear-gradient(45deg,var(--bone) 0 3.4px,transparent 3.4px 7px);
  border-left:1px solid var(--rule);border-right:1px solid var(--rule)}
.seg--none{background:transparent;
  background-image:linear-gradient(var(--rule-hi),var(--rule-hi));
  background-size:100% 1px;background-repeat:no-repeat;background-position:center}
.seg__n{position:absolute;inset:0;display:grid;place-items:center;font-family:var(--mono);
  font-size:10.5px;font-weight:600;color:inherit}
/* an overlay number takes its ground's ink; it may never carry a fixed colour */
.seg--live .seg__n{color:#04140d}
/* The hatch is half transparent, so neither a light nor a dark ink works across
   it (white on the bone stripes measures 1.31:1). The number gets a solid plate
   and is then read against a ground the checker can name. */
.seg--dead .seg__n{color:var(--ink);position:relative;isolation:isolate}
.seg--dead .seg__n::before{content:"";position:absolute;inset:2px -1px;background:var(--panel);z-index:-1}
.seg--none .seg__n{color:var(--ink3)}

/* ---- ACT 03 · THE INSERT ---------------------------------------------- */
.pick{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:0 0 26px}
.pick input{
  width:100%;display:block;min-width:0;background:var(--panel);border:1px solid var(--rule-hi);
  color:var(--ink);border-radius:2px;padding:11px 13px;font:inherit;font-size:14px;
}
.pick input::placeholder{color:var(--ink3)}
.pick input:focus{outline:none;border-color:var(--neon)}
.hits{position:relative;flex:1 1 460px;min-width:0}
.hits__list{
  position:absolute;z-index:40;left:0;right:0;top:calc(100% + 5px);max-height:320px;overflow:auto;
  background:var(--panel2);border:1px solid var(--rule-hi);border-radius:2px;
  box-shadow:0 18px 50px rgba(0,0,0,.6);
}
.hits__i{display:flex;justify-content:space-between;gap:12px;align-items:baseline;width:100%;
  padding:9px 12px;background:none;border:0;border-bottom:1px solid var(--rule);
  color:var(--ink);font:inherit;font-size:13px;text-align:left;cursor:pointer}
.hits__i:hover,.hits__i.is-sel{background:var(--neon-dim)}
.hits__i .s{font-family:var(--mono);font-size:10px;letter-spacing:.09em;text-transform:uppercase;color:var(--ink3);white-space:nowrap}
.hits__none{padding:11px 12px;color:var(--ink3);font-size:13px}

/* THE INSERT SHEET — this is also the share card. Same markup, one class. */
.insert{
  position:relative;border:1px solid var(--rule-hi);border-radius:3px;background:var(--panel);
  overflow:hidden;
}
.insert__top{padding:22px clamp(18px,2.6vw,32px) 20px;border-bottom:1px solid var(--rule);
  background:linear-gradient(180deg,color-mix(in oklab,var(--neon) 7%,var(--panel)),var(--panel))}
.insert__kick{display:flex;flex-wrap:wrap;gap:8px 16px;margin:0 0 13px}
.insert__nm{margin:0;font-family:var(--serif);font-weight:400;font-size:clamp(27px,3.6vw,44px);
  line-height:1.05;letter-spacing:-.018em;color:#fff;max-width:34ch}
.insert__sub{margin:9px 0 0;font-family:var(--mono);font-size:11px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink2)}
.insert__sub .sep{color:var(--rule-hi)}

/* the stamp. Rotated, ink-bled, and it always prints its own state in words. */
.stamp{
  position:absolute;top:18px;right:clamp(14px,2.4vw,28px);
  transform:rotate(-7deg);padding:7px 13px 6px;border:2.5px solid currentColor;border-radius:3px;
  font-family:var(--mono);font-size:clamp(12px,1.5vw,17px);font-weight:700;letter-spacing:.11em;
  text-transform:uppercase;line-height:1.1;text-align:center;opacity:.92;
}
.stamp small{display:block;font-size:.62em;font-weight:400;letter-spacing:.1em;opacity:.85;margin-top:2px}
.stamp--dead{color:var(--stamp)}
.stamp--live{color:var(--neon)}
.stamp--none{color:var(--ink2);border-style:dashed}
.stamp.is-in{animation:thud .42s var(--ease) both}
@keyframes thud{
  0%{transform:rotate(-7deg) scale(1.5);opacity:0}
  60%{transform:rotate(-7deg) scale(.97);opacity:1}
  100%{transform:rotate(-7deg) scale(1);opacity:.92}
}

/* automatic checks — the indisputable half of the label */
.autos{display:flex;flex-wrap:wrap;gap:7px;margin:15px 0 0}
.auto{display:inline-flex;align-items:center;gap:7px;padding:5px 10px;border-radius:2px;
  border:1px solid currentColor;font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;
  text-transform:uppercase;white-space:nowrap}
.auto--warn{color:var(--stamp)}
.auto--ok{color:var(--neon)}
.auto--flat{color:var(--ink2)}
.auto .g{font-size:12px;line-height:1}

.insert__body{display:grid;grid-template-columns:minmax(0,1fr)}
@media (min-width:900px){ .insert__body{grid-template-columns:minmax(0,1.35fr) minmax(0,1fr)} }
.fields{border-right:1px solid var(--rule)}
@media (max-width:899px){ .fields{border-right:0;border-bottom:1px solid var(--rule)} }
.f{display:grid;grid-template-columns:2.4ch minmax(0,1fr);gap:14px;
  padding:15px clamp(18px,2.6vw,32px);border-bottom:1px solid var(--rule)}
.f:last-child{border-bottom:0}
.f__n{font-family:var(--mono);font-size:11px;color:var(--neon);padding-top:2px}
.f__l{font-family:var(--mono);font-size:10.5px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink3);margin:0 0 6px}
.f__v{margin:0;font-size:14px;line-height:1.55;color:var(--ink);max-width:var(--measure)}
.f__v.dim{color:var(--ink2)}
.f__v.mv{font-family:var(--mono);font-size:12.5px;letter-spacing:.02em}
.f__v .none{color:var(--ink3);font-family:var(--mono);font-size:12px;letter-spacing:.1em;text-transform:uppercase}
.pills{display:flex;flex-wrap:wrap;gap:6px;margin:0}
.pill{font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;
  padding:4px 9px;border:1px solid var(--rule-hi);border-radius:2px;color:var(--ink2)}

/* THE NOTE — the biggest block on the sheet, because it is the product. */
.noteside{padding:0}
.note{padding:19px clamp(18px,2.6vw,32px) 22px}
.note__h{display:flex;align-items:baseline;gap:10px;margin:0 0 4px}
.note__h .g{color:var(--stamp);font-size:14px;line-height:1}
.note__h span{font-family:var(--mono);font-size:10.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--stamp)}
.note__d{margin:0 0 14px;font-size:11.5px;line-height:1.5;color:var(--ink3);max-width:44ch}
.note__t{margin:0;font-family:var(--serif);font-size:clamp(17px,2vw,22px);line-height:1.42;
  color:var(--ink);letter-spacing:-.004em}
.note__t.is-plain{font-size:15px;line-height:1.55;font-family:var(--sans)}

.insert__foot{display:flex;flex-wrap:wrap;gap:12px 22px;align-items:center;justify-content:space-between;
  padding:13px clamp(18px,2.6vw,32px);border-top:1px solid var(--rule);background:var(--ground)}
.insert__foot .src{font-family:var(--mono);font-size:10px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink3)}
.insert__foot .mk{display:flex;align-items:center;gap:8px;font-family:var(--mono);font-size:10px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink2)}
.insert__foot .mk b{color:var(--neon);font-weight:400}

.navpair{display:flex;flex-wrap:wrap;gap:9px;margin:18px 0 0}

/* ---- ACT 04 ----------------------------------------------------------- */
.report{display:grid;gap:clamp(22px,3vw,44px);grid-template-columns:minmax(0,1fr)}
@media (min-width:1000px){ .report{grid-template-columns:minmax(0,1fr) minmax(0,1fr)} }
.rbox{border:1px solid var(--rule);border-radius:3px;background:var(--panel);padding:24px}
.rbox h3{margin:0 0 8px;font-family:var(--serif);font-weight:400;font-size:24px;letter-spacing:-.014em;line-height:1.1}
.rbox p{margin:0 0 18px;color:var(--ink2);font-size:14px;max-width:var(--measure)}

footer{border-top:1px solid var(--rule);padding:34px var(--pad) 60px;max-width:var(--maxw);margin:0 auto}
footer p{margin:0 0 10px;max-width:var(--measure);color:var(--ink3);font-size:12px;line-height:1.6}
footer b{color:var(--ink2);font-weight:600}

/* ---- share-card mode -------------------------------------------------- */
/* ?card=1 renders one insert at 1200x675 and nothing else, so the social team
   can screenshot 135 of them without a designer touching any of it. */
body.card-mode{overflow:hidden}
body.card-mode .seal,body.card-mode .act:not(#act-insert),body.card-mode footer,
body.card-mode .pick,body.card-mode .acthead,body.card-mode .actlede,body.card-mode .navpair{display:none!important}
body.card-mode #act-insert{padding:0;max-width:none}
body.card-mode .insert{width:1200px;height:675px;border:0;border-radius:0;display:flex;flex-direction:column}
body.card-mode .insert__body{flex:1;min-height:0}
body.card-mode .insert__nm{font-size:46px}
body.card-mode .note__t{font-size:22px}
body.card-mode .cardmark{display:flex}
/* A card is a fixed 675px, so it must be DESIGNED to fit rather than clipped:
   honesty-critical text may never be cut off. Two things give: the description
   clamps to three lines, and the API-sweep line moves to the footer, where it is
   the same sentence in the same card. Nothing is dropped, only relocated.
   A probe assertion checks no field's box escapes the body's. */
body.card-mode .f{padding-top:11px;padding-bottom:11px}
body.card-mode .f--desc .f__v{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
body.card-mode .f__sub{display:none}
body.card-mode .insert__foot .src--site{display:none}
body.card-mode .insert__foot .src--sweep{display:inline}
.insert__foot .src--sweep{display:none}
.insert__foot .cardmark{display:none}
body.card-mode .insert__foot .cardmark{display:flex}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms!important;animation-delay:0ms!important;transition-duration:.001ms!important}
  .shelf.is-armed .chip{opacity:1;transform:none}
}

/* ============================================================================
   ACT 01 · THE BLISTER PACK — "watch the field go quiet"

   The one animation this feed can honestly carry. The index holds exactly one
   date per repository (its last recorded push), and one date is enough to know
   the exact day that repository crossed a year of silence. Sort those 88 dates,
   sweep a playhead across them, and each capsule darkens on its own real date.

   What it is NOT, and the caption says so on screen: a picture of how much of
   the field was alive in 2019. A capsule still full at an early playhead date
   has simply not had its silence-anniversary yet — the feed holds no commit
   history to say what was happening then. It is a cumulative record of WHEN the
   field went quiet, which is a real series with real dates.

   No geometry is invented. The blister pack is the concept's own metaphor
   (package insert → foil pack) and every capsule is one catalogue entry.
   ========================================================================== */

.pack{border:1px solid var(--rule);border-radius:3px;background:var(--panel);overflow:hidden}

/* ---- the readout. Every value here is reserved-width, because it changes on
        every animation frame and must never reflow the pack below it. -------- */
/* The NUMBERS are the loudest thing in this row, so they are what must line up.
   `align-items: flex-end` aligned the BLOCKS instead, and since the three labels
   run to one, two and three lines, it put the three numerals on three different
   baselines. Aligning to `start` — with the numeral first in each block — makes
   the numerals share one baseline by construction, whatever the labels do. */
.pack__hud{display:flex;flex-wrap:wrap;align-items:start;gap:16px 34px;
  padding:19px clamp(16px,2.2vw,26px) 17px;border-bottom:1px solid var(--rule);
  background:linear-gradient(180deg,color-mix(in oklab,var(--neon) 6%,var(--panel)),var(--panel))}
.hud{display:flex;flex-direction:column;gap:5px}
.hud__v{font-family:var(--mono);font-variant-numeric:tabular-nums;font-weight:500;line-height:1;
  font-size:clamp(26px,3.6vw,46px);color:var(--ink);letter-spacing:-.015em}
.hud__v .u{font-size:.42em;color:var(--ink3);letter-spacing:.11em;margin:0 0 0 .34em;font-weight:400}
.hud--date .hud__v{min-width:9.2ch}          /* "SEP 2026" plus the widest month */
.hud--count .hud__v{min-width:5.6ch;color:var(--stamp)}
.hud--left .hud__v{min-width:5.6ch;color:var(--neon)}
.hud__l{font-family:var(--mono);font-size:10.5px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink3);line-height:1.45;max-width:26ch;min-height:3.05em}
.pack__badge{margin-left:auto;align-self:center;font-family:var(--mono);font-size:10px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--neon);
  border:1px solid color-mix(in oklab,var(--neon) 45%,transparent);border-radius:2px;padding:5px 9px}

/* ---- the foil ---------------------------------------------------------- */
.pack__foil{padding:clamp(14px,1.8vw,22px) clamp(16px,2.2vw,26px) 6px}
/* auto-fill happily leaves a stub last row — 88 across 40 columns is 40/40/8.
   pickCols() sets --cols so the pack looks like a pack. */
.pack__grid{display:grid;gap:7px;
  grid-template-columns:repeat(var(--cols,auto-fill),minmax(0,1fr))}
.cap{
  position:relative;height:clamp(34px,4.4vw,48px);border-radius:999px;border:1px solid;
  background:none;padding:0;cursor:pointer;
  /* symmetric slow-in/slow-out: the point is to TRACK one capsule as it turns,
     and the house --ease spends 83% of the distance in the first 25% of the time */
  transition:background-color .34s cubic-bezier(.36,0,.64,1),
             border-color .34s cubic-bezier(.36,0,.64,1),
             opacity .34s cubic-bezier(.36,0,.64,1);
}
/* full — solid fill */
.cap--full{background-color:var(--neon);border-color:var(--neon);opacity:1}
/* spent — the same 45-degree hatch the shelf and the bars use, so the texture
   means one thing everywhere on this site. State never rests on colour. */
.cap--spent{
  background-color:transparent;border-color:var(--rule-hi);opacity:.85;
  background-image:repeating-linear-gradient(45deg,var(--bone) 0 2.6px,transparent 2.6px 6px);
}
/* never checkable — dashed, empty, and it can never change */
.cap--void{background-color:transparent;border-color:var(--rule-hi);border-style:dashed;opacity:.68}
.cap:hover,.cap:focus-visible{box-shadow:0 0 0 2px var(--ink)}
.cap.is-pop{animation:pop .36s cubic-bezier(.36,0,.64,1) 1}
@keyframes pop{0%{transform:scale(1)}42%{transform:scale(.82)}100%{transform:scale(1)}}
.cap.is-refill{animation:refill .3s cubic-bezier(.36,0,.64,1) both;animation-delay:var(--rd,0ms)}
@keyframes refill{0%{transform:scale(.82);opacity:.4}100%{transform:scale(1);opacity:1}}

/* ---- the year axis. Marks are HTML placed by percentage, not SVG text.
        The class names are namespaced `.pt` / `.ptl` and MUST stay that way:
        `.tick` is already the hero's live-counter block, a bordered padded box,
        and reusing the name rendered every year mark as a 42x35 panel painted
        over the hover line. Nothing errored; only a screenshot showed it.
        The axis is inset by half the playhead's dot on each side, because a mark
        centred on the edge of its box hangs half outside it. */
.pack__axis{position:relative;height:30px;margin:12px calc(clamp(16px,2.2vw,26px) + 5px) 0}
.pack__axis .pt{position:absolute;top:0;bottom:12px;width:1px;background:var(--rule-hi)}
.pack__axis .ptl{position:absolute;bottom:0;transform:translateX(-50%);font-family:var(--mono);
  font-size:9.5px;letter-spacing:.1em;color:var(--ink3);white-space:nowrap}
.pack__axis .head{position:absolute;top:-4px;bottom:12px;width:2px;background:var(--stamp);
  transform:translateX(-50%);
  box-shadow:0 0 9px color-mix(in oklab,var(--stamp) 75%,transparent)}
.pack__axis .head::before{content:"";position:absolute;top:-4px;left:50%;width:8px;height:8px;
  margin-left:-4px;border-radius:50%;background:var(--stamp)}

/* ---- the hover line. Height is RESERVED: a hover-driven element that reflows
        the thing being hovered oscillates forever. ---------------------------- */
.pack__info{height:38px;display:flex;align-items:center;gap:12px;overflow:hidden;
  margin:0 clamp(16px,2.2vw,26px);border-top:1px solid var(--rule);
  font-family:var(--mono);font-size:11px;letter-spacing:.06em;color:var(--ink3);white-space:nowrap}
.pack__info b{color:var(--ink);font-weight:600;letter-spacing:0;
  font-family:var(--sans);font-size:12.5px;overflow:hidden;text-overflow:ellipsis}
.pack__info .st{color:var(--stamp)}
.pack__info .sl{color:var(--neon)}

/* ---- controls ---------------------------------------------------------- */
.pack__ctl{display:flex;flex-wrap:wrap;align-items:center;gap:12px;
  padding:13px clamp(16px,2.2vw,26px);border-top:1px solid var(--rule);background:var(--ground)}
.playbtn{display:inline-flex;align-items:center;gap:9px;padding:9px 15px 9px 12px;border-radius:2px;
  border:1px solid var(--neon);background:var(--neon);color:#04140d;cursor:pointer;
  font-family:var(--mono);font-size:11px;letter-spacing:.13em;text-transform:uppercase;font-weight:600}
.playbtn:hover{background:var(--neon-hi);border-color:var(--neon-hi)}
.playbtn svg{width:11px;height:11px;fill:currentColor;flex:none}
.scrub{flex:1 1 240px;min-width:0;appearance:none;height:24px;background:none;cursor:pointer}
.scrub::-webkit-slider-runnable-track{height:4px;border-radius:2px;
  background:linear-gradient(90deg,var(--stamp) var(--fill,0%),var(--rule-hi) var(--fill,0%))}
.scrub::-webkit-slider-thumb{appearance:none;width:15px;height:15px;border-radius:50%;
  background:var(--ink);margin-top:-5.5px;border:0}
.scrub::-moz-range-track{height:4px;border-radius:2px;background:var(--rule-hi)}
.scrub::-moz-range-thumb{width:15px;height:15px;border-radius:50%;background:var(--ink);border:0}
.scrub:focus-visible{outline:2px solid var(--neon-hi);outline-offset:2px}
.pack__ctl .hint{font-family:var(--mono);font-size:10px;letter-spacing:.11em;
  text-transform:uppercase;color:var(--ink3)}

/* ── .swap: a label that changes text without changing width ──────────────
   Both the button label (Play / Pause / Replay) and the hint (Drag to scrub /
   Today · <date>) sit in a flex row either side of `.scrub`, which is the
   flexible track. Swapping either string for a longer one therefore made the
   TIMELINE jump shorter — on the last frame of the sweep, which is the one frame
   a viewer is looking at. Same family as the hover-reflow oscillation.

   Every alternative is rendered into the SAME grid cell, so the track sizes to
   the longest of them and the box is exact rather than guessed in `ch`. That
   matters because one of these strings contains a date, so any hand-measured
   reservation would rot the first time the copy or the date format changed.
   `visibility:hidden` and not `display:none`: display would collapse the box and
   lose the reservation, and visibility keeps the inactive strings out of the
   accessibility tree too. */
.swap{display:grid;justify-items:start;align-items:center}
.swap>*{grid-area:1/1;visibility:hidden}
.swap>.is-on{visibility:visible}

/* ---- the 47 that were never checkable, kept out of the pack on purpose - */
.pack__void{padding:14px clamp(16px,2.2vw,26px) 17px;border-top:1px solid var(--rule)}
.pack__void .vl{font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink3);margin:0 0 9px}
.pack__void .vrow{display:grid;gap:5px;grid-template-columns:repeat(auto-fill,minmax(14px,1fr))}
.pack__void .cap{height:18px}

.figcap{max-width:var(--measure);margin:18px 0 0;font-size:12.5px;line-height:1.6;color:var(--ink3)}
.figcap b{color:var(--ink2);font-weight:600}

/* the insert deals like a card when it changes — snappy, and it makes 135
   entries feel like a deck rather than a dropdown */
.insert.is-deal{animation:deal .26s cubic-bezier(.36,0,.64,1) both}
@keyframes deal{
  0%{opacity:0;transform:translateY(10px) scale(.994)}
  100%{opacity:1;transform:none}
}

@media (prefers-reduced-motion:reduce){
  .cap{transition:none}
  .cap.is-pop,.cap.is-refill,.insert.is-deal{animation:none}
}

/* ---- ACT 01b · NEXT TO EXPIRE -----------------------------------------
   The forward edge of the pack's timeline. Grouped by REPOSITORY, not by entry:
   LAB-Bench and LAB-Bench 2 share one repository, so an entry-per-row list prints
   the same date twice and reads as a bug. Both counts are stated instead.
   No chart here on purpose — a package insert does not carry bar charts, and a bar
   would have to be scaled against an arbitrary window to show anything at all. */
.queue{margin:26px 0 0;border:1px solid var(--rule);border-left:3px solid var(--stamp);
  border-radius:2px;background:var(--panel);padding:20px clamp(16px,2.2vw,26px) 18px}
.queue__hd{display:flex;flex-wrap:wrap;align-items:baseline;gap:10px 18px;margin:0 0 10px}
.queue__k{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--stamp)}
.queue__k em{font-style:normal;opacity:.6}
.queue__n{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink3);margin-left:auto}
.queue__lede{margin:0 0 16px;max-width:var(--measure);font-size:13.5px;line-height:1.6;color:var(--ink2)}
.queue__lede b{color:var(--ink);font-weight:600}
.queue__lede .hl{color:var(--stamp);font-weight:600}

 /* capped, so the category column sits near the names it belongs to instead of
    being flung to the far edge of a 1500px row with a void in between */
.queue__list{list-style:none;margin:0;padding:0;display:grid;gap:1px;
  background:var(--rule);max-width:58rem}
.qrow{display:grid;grid-template-columns:var(--q-t);align-items:baseline;gap:6px 18px;
  background:var(--panel);padding:10px 0}
:root{--q-t:11ch 8.5ch minmax(0,1fr) minmax(0,19ch)}
@media (max-width:760px){ :root{--q-t:11ch 8ch minmax(0,1fr)} .qrow .qcat{display:none} }
@media (max-width:520px){ :root{--q-t:minmax(0,1fr) 8ch} .qrow .qdate{grid-column:1/-1} }
.qrow--next{background:color-mix(in oklab,var(--stamp) 7%,var(--panel))}
.qdate{font-family:var(--mono);font-size:12px;font-variant-numeric:tabular-nums;color:var(--ink)}
.qin{font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--stamp);font-variant-numeric:tabular-nums}
.qnames{font-size:13.5px;font-weight:600;line-height:1.35;color:var(--ink)}
.qnames button{background:none;border:0;padding:0;font:inherit;color:inherit;cursor:pointer;text-align:left}
.qnames button:hover{color:var(--neon)}
.qnames .plus{font-weight:400;color:var(--ink3)}
.qcat{font-family:var(--mono);font-size:10px;letter-spacing:.09em;text-transform:uppercase;
  color:var(--ink3);line-height:1.45}
.queue__foot{margin:14px 0 0;max-width:var(--measure);font-size:11.5px;line-height:1.55;color:var(--ink3)}
