/* ============================================================
   A.K. — CATALOGUE
   One publication, four typographic registers.

   The registers shift page to page (archive index → light field →
   risograph appendix → essay) but they are bound together by three
   constants: the mono face carries every functional label on every
   page, the 12-column grid and spacing scale never change, and every
   page is framed as a document *within* one catalogue — a plate, an
   appendix, a colophon. That is what keeps range from reading as
   incoherence.
   ============================================================ */

/* ---------- 1. shared tokens ----------
   Taken off Plate 01, the spacecraft panel this catalogue opens with.
   Three things about that photograph decide the whole palette:

   the ground is enamelled instrument grey, not paper;
   the labels are engraved black laminate with the lettering cut through
   to white, so a label is a physical object with an edge and a face;
   and the orange is structural — it is on the frame members and the
   alignment marks, never on the lettering.

   The site used to have the last one backwards: orange chips carrying
   white type. Orange is now state only — the page you are on, the row
   that is playing — and nothing else. */
:root{
  --paper:    #F2F2F0;          /* a neutral off-white, not a colour from the photo */
  --paper-2:  #E7E7E4;
  --face:     #E7E7E4;
  --laminate: #111214;          /* an inverted cell */
  --ink:      #111214;
  --ink-70:   rgba(17,18,20,.74);
  --ink-45:   rgba(17,18,20,.62);
  --ink-25:   rgba(17,18,20,.30);
  --hair:     rgba(17,18,20,.18);
  --hair-2:   rgba(17,18,20,.10);
  --edge:     rgba(17,18,20,.34);
  --screw:    rgba(17,18,20,.30);
  --seam:     rgba(17,18,20,.24);  /* the only edge in the system */

  /* Sampling the enamel and the oxide straight off Plate 01 was costume, and
     a mid sage grey desaturates everything sitting on it — the 1-bit plates
     worst of all. What is worth taking from that panel is the relationship,
     not the pigment: near-white, near-black, and colour reserved for a state
     that matters. So the site is monochrome, and there is exactly one colour
     in it. It appears when something is playing. */
  --accent:   #111214;
  --accent-d: #111214;
  --accent-l: #F2F2F0;
  --signal:   #C33410;

  --pad:  clamp(1.15rem, 3.6vw, 3.75rem);
  --maxw: 1600px;
  --ease:    cubic-bezier(.16,1,.3,1);
  --ease-io: cubic-bezier(.65,.05,.36,1);

  --mono:  "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --disp:  "Archivo", "Helvetica Neue", Arial, sans-serif;
  --serif: "Instrument Serif", Georgia, "Times New Roman", serif;
}

/* ---------- 2. reset ---------- */
*,*::before,*::after{ box-sizing:border-box }
html{ -webkit-text-size-adjust:100% }
body{
  margin:0; background:var(--paper); color:var(--ink);
  font-family:var(--mono); font-size:15px; line-height:1.55;
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
  overflow-x:clip;
}
img,canvas,video,svg{ display:block; max-width:100% }

/* Enamel is not a flat colour. A fine speckle over the whole document is the
   one thing that stops large areas of the ground reading as printed paper. */
body::after{
  content:""; position:fixed; inset:0; z-index:900; pointer-events:none;
  opacity:0; mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}
a{ color:inherit; text-decoration:none }
button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer }
h1,h2,h3,h4,p,figure,blockquote,dd{ margin:0 }
ul,ol{ margin:0; padding:0; list-style:none }
::selection{ background:var(--ink); color:var(--paper) }
:focus-visible{ outline:2px solid var(--accent); outline-offset:3px }

/* ---------- 3. type ---------- */
.lbl{
  font-family:var(--mono); font-size:.6875rem; font-weight:500;
  text-transform:uppercase; letter-spacing:.16em; color:var(--ink-45);
}
.lbl--a{ color:var(--accent) }
.num{ font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1 }
.disp{
  font-family:var(--disp); font-variation-settings:"wdth" 72,"wght" 800;
  text-transform:uppercase; line-height:.88; letter-spacing:-.012em;
}
.disp--wide{ font-variation-settings:"wdth" 110,"wght" 700 }
.serif{ font-family:var(--serif); font-weight:400; line-height:1.06; letter-spacing:-.015em }
.t-mega{ font-size:clamp(2.9rem, 11.5vw, 11rem) }
.t-xl  { font-size:clamp(2.1rem, 6.2vw, 5.4rem) }
.t-lg  { font-size:clamp(1.6rem, 3.4vw, 2.9rem) }
.t-md  { font-size:clamp(1.1rem, 1.8vw, 1.5rem) }
.lede{ font-size:clamp(.98rem,1.3vw,1.14rem); line-height:1.62; color:var(--ink-70); max-width:62ch }
.prose p{ color:var(--ink-70); max-width:66ch }
.prose p + p{ margin-top:1.1em }
.prose em{ font-style:italic }

/* ---------- 4. layout ---------- */
.wrap{ max-width:var(--maxw); margin-inline:auto; padding-inline:var(--pad) }
.rule{ height:1px; background:var(--hair); border:0; margin:0 }
.rule--a{ background:var(--accent); height:2px }
.sect{ padding-block:clamp(3.4rem,7.5vw,7.5rem) }
.grid{ display:grid; gap:clamp(1rem,2.2vw,2rem) }
.g-12{ grid-template-columns:repeat(12,1fr) }
@media (max-width:880px){
  .g-12{ grid-template-columns:repeat(6,1fr) }
  /* Every grid-column span in the markup is written for the 12-column track list.
     Below this breakpoint the grid is 6 wide, so those spans (1/8, 3/10, 9/13 …)
     run off the end into implicit tracks and squeeze every column — which reads as
     clipped headlines, not as a wrap. The spans are inline styles, so !important is
     what it takes to reset them. Stack full-width instead. */
  .g-12 > *{ grid-column:1 / -1 !important }
}

/* ---------- 5. chrome ---------- */
.nav{
  position:sticky; top:0; z-index:60;
  display:flex; align-items:center; justify-content:space-between; gap:1rem;
  padding:.7rem var(--pad);
  background:var(--paper); border-bottom:1px solid var(--seam);
}
.mark{
  display:flex; align-items:baseline; gap:.5rem;
  font-family:var(--disp); font-variation-settings:"wdth" 96,"wght" 800;
  text-transform:uppercase; font-size:1.05rem; letter-spacing:.01em;
  view-transition-name:mark;
}
.mark small{ font-family:var(--mono); font-size:.625rem; letter-spacing:.16em; color:var(--ink-45) }
.nav__links{ display:flex; gap:clamp(.75rem,1.8vw,1.9rem); align-items:center }
.nav__links a{
  font-family:var(--mono); font-size:.6875rem; font-weight:500;
  text-transform:uppercase; letter-spacing:.13em; color:var(--ink-45);
  padding:.3rem 0; border-bottom:1px solid transparent; transition:color .3s, border-color .3s;
}
.nav__links a:hover{ color:var(--ink); border-color:var(--ink) }
.nav__links a[aria-current="page"]{ color:var(--accent); border-color:var(--accent) }
@media (max-width:760px){ .nav{ padding-inline:1rem } .nav__links a span{ display:none } }

/* The running strip is now the engraved scale that runs along the bottom
   edge of an instrument panel: minor ticks every 8 px, a major every 40. */
.strip{
  position:relative;
  display:flex; align-items:center; justify-content:space-between; gap:1rem;
  padding:.5rem var(--pad); border-bottom:1px solid var(--seam);
  background:var(--paper-2);
}

.strip .lbl{ font-size:.625rem }


/* ---------- 6. chips & buttons ---------- */
/* An engraved placard. Black laminate, lettering cut through to the white
   core, a hard edge and a hairline of light along the top where the bevel
   catches. Every functional label on the site is one of these. */
.chip{
  display:inline-flex; align-items:center; gap:.45rem;
  font-family:var(--mono); font-size:.625rem; font-weight:600;
  text-transform:uppercase; letter-spacing:.16em;
  padding:.42rem .72rem; background:var(--laminate); color:var(--paper);
}
.chip--ghost{ background:none; color:var(--ink-45); box-shadow:inset 0 0 0 1px var(--seam) }
.chip--ghost:hover{ color:var(--ink); box-shadow:inset 0 0 0 1px var(--ink) }
.chip--ghost[aria-pressed="true"]{ background:var(--laminate); color:var(--paper); box-shadow:none }
/* A switch, not a link: a raised face that goes down when you press it. */
/* A control inverts when you use it. It does not pretend to move. */
.btn{
  display:inline-flex; align-items:center; gap:.7rem;
  font-family:var(--mono); font-size:.6875rem; font-weight:500;
  text-transform:uppercase; letter-spacing:.15em;
  padding:.8rem 1.3rem; color:var(--ink); background:var(--face);
  box-shadow:inset 0 0 0 1px var(--seam);
  transition:background .18s linear, color .18s linear;
}
.btn:hover, .btn:focus-visible{ background:var(--laminate); color:var(--paper); box-shadow:none }
.btn--a:hover, .btn--a:focus-visible{ background:var(--accent); color:#F2F3F0 }

/* ---------- 7. halftone plates ----------
   A plate is mounted, not printed: a recessed aperture inside a frame with
   a fastener at each corner. The four screws are one background shorthand
   rather than four elements. */
.plate{ position:relative; overflow:hidden; background:var(--paper-2) }


.plate canvas, .plate img{ width:100%; height:100%; object-fit:cover; display:block }
.plate__cap{
  display:flex; justify-content:space-between; gap:1rem;
  margin-top:.55rem; align-items:baseline;
}
/* the plate number is an inverted legend cell in the corner of the aperture */
.plate__no{
  position:absolute; z-index:4; top:0; left:0;
  background:var(--laminate); color:var(--paper);
  font-family:var(--mono); font-size:.5625rem; font-weight:600;
  letter-spacing:.2em; padding:.3rem .55rem; text-transform:uppercase;
}
figure.fig{ margin:0 }

/* ---------- 8. catalogue table ---------- */
.cat{ border-top:1px solid var(--ink) }
.cat__row{
  display:grid; align-items:baseline; gap:1rem;
  grid-template-columns:4.5rem minmax(0,1fr) 12rem 5.5rem 4.5rem;
  padding-block:.85rem; border-bottom:1px solid var(--hair-2);
  position:relative; transition:background .35s var(--ease), padding-inline .4s var(--ease);
}
/* Selecting a row inverts it, the way selecting a channel does. It does not
   slide: .cue brings its own horizontal hover padding for the player's cue
   list, which made the three playable rows shift while the others stayed put. */
.cat__row:hover, .cat__row:focus-visible{ background:var(--laminate); color:var(--paper) }
.cat__row.cue:hover{ padding-inline:0 }
.cat__row:hover .cat__no{ color:rgba(242,242,240,.62) }
.cat__row:hover .cat__forces, .cat__row:hover .cat__yr, .cat__row:hover .cat__dur{ color:rgba(243,241,238,.66) }

.cat__no{ color:var(--ink-45); font-size:.75rem; font-weight:500; letter-spacing:.08em }
.cat__ttl{
  font-family:var(--disp); font-variation-settings:"wdth" 76,"wght" 700;
  text-transform:uppercase; font-size:clamp(1rem,1.9vw,1.45rem); line-height:1.05;
}
.cat__forces, .cat__yr, .cat__dur{ font-size:.75rem; color:var(--ink-45) }
.cat__dur{ text-align:right }
@media (max-width:900px){
  .cat__row{ grid-template-columns:3.5rem minmax(0,1fr) 4rem; row-gap:.25rem }
  .cat__forces{ grid-column:2 } .cat__yr{ display:none }
}
.cat__row[hidden]{ display:none }

/* ---------- 9. audio cues ---------- */
.cue{
  display:grid; grid-template-columns:2.1rem minmax(0,1fr) auto; align-items:center; gap:1rem;
  width:100%; text-align:left; padding-block:.8rem;
  border-bottom:1px solid var(--hair-2); transition:padding-inline .4s var(--ease);
}
.cue:hover{ padding-inline:.6rem; background:var(--paper-2) }
.cue__ico{
  width:2.1rem; height:2.1rem; border:1px solid var(--hair); border-radius:50%;
  display:grid; place-items:center; transition:border-color .3s, background .3s;
}
.cue__ico svg{ width:9px; height:9px; fill:var(--ink-70) }
.cue:hover .cue__ico{ border-color:var(--accent) }
.cue[data-active="true"] .cue__ico{ background:var(--signal); border-color:var(--signal) }
.cue[data-active="true"] .cue__ico svg{ fill:#fff }
.cue[data-active="true"] .cue__name{ color:var(--signal) }
.cue__name{ font-size:.9375rem; transition:color .3s }
.cue__dur{ font-size:.75rem; color:var(--ink-45) }

/* ---------- 10. player ---------- */
.player{
  position:fixed; z-index:55; inset:auto 0 0 0;
  display:grid; grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center; gap:clamp(.7rem,1.6vw,1.4rem);
  padding:.6rem var(--pad);
  background:var(--ink); color:var(--paper);
  transform:translateY(101%); transition:transform .6s var(--ease);
}
.player[data-open="true"]{ transform:translateY(0) }
.player__btn{
  width:36px; height:36px; display:grid; place-items:center;
  border:1px solid rgba(244,241,234,.3); border-radius:50%; transition:border-color .3s, transform .3s var(--ease);
}
.player__btn:hover{ transform:scale(1.07) }
.player__btn svg{ width:11px; height:11px; fill:var(--paper) }
.player[data-playing="true"] .player__btn{ border-color:var(--signal) }
.player[data-playing="true"] .player__btn svg{ fill:var(--signal) }
.player__mid{ display:grid; gap:.28rem; min-width:0 }
.player__top{ display:flex; align-items:baseline; gap:.6rem; min-width:0 }
.player__ttl{
  font-family:var(--disp); font-variation-settings:"wdth" 80,"wght" 700;
  text-transform:uppercase; font-size:.8125rem;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.player__meta{ color:rgba(244,241,234,.60) !important }
.player__wave{ width:100%; height:24px; display:block }
.player__seek{ position:relative; height:2px; background:rgba(244,241,234,.2); cursor:pointer }
.player__seek i{ position:absolute; inset:0 100% 0 0; background:var(--signal) }
.player__time{ font-size:.6875rem; color:rgba(244,241,234,.55); white-space:nowrap }
.player__x{ color:rgba(244,241,234,.60); padding:.4rem; transition:color .3s }
.player__x:hover{ color:var(--paper) }
@media (max-width:640px){ .player__wave{ display:none } }

/* ---------- 11. cursor ---------- */
.cursor{
  position:fixed; top:0; left:0; z-index:9999; pointer-events:none;
  width:10px; height:10px; margin:-5px 0 0 -5px; border-radius:50%;
  background:var(--accent);
  opacity:0;                       /* revealed on the first pointermove */
  transition:width .35s var(--ease), height .35s var(--ease), margin .35s var(--ease),
             background .3s, opacity .25s, border-radius .35s var(--ease);
}
.cursor[data-ready="true"]{ opacity:1 }
.cursor[data-v="link"]{ width:40px; height:40px; margin:-20px 0 0 -20px; background:rgba(255,59,18,.22) }
.cursor[data-v="media"]{ width:74px; height:74px; margin:-37px 0 0 -37px; background:var(--accent); border-radius:2px }
.cursor[data-v="hidden"]{ opacity:0 }
.cursor__lbl{
  position:absolute; inset:0; display:grid; place-items:center;
  font-family:var(--mono); font-size:.5625rem; letter-spacing:.13em; text-transform:uppercase;
  color:#fff; opacity:0; transition:opacity .3s;
}
.cursor[data-v="media"] .cursor__lbl{ opacity:1 }
@media (hover:none),(pointer:coarse){ .cursor{ display:none } }
html.has-cursor, html.has-cursor *{ cursor:none !important }

/* ---------- 12. reveals (gated on html.js — see STUDIO 01 note) ---------- */
html.js [data-rv]{ opacity:0; transform:translateY(20px); transition:opacity .85s var(--ease), transform .85s var(--ease) }
html.js [data-rv][data-in="true"]{ opacity:1; transform:none }
[data-rv-d="1"]{ transition-delay:.07s } [data-rv-d="2"]{ transition-delay:.14s }
[data-rv-d="3"]{ transition-delay:.21s } [data-rv-d="4"]{ transition-delay:.28s }
[data-rv-d="5"]{ transition-delay:.35s } [data-rv-d="6"]{ transition-delay:.42s }
.rv-line{ display:block; overflow:hidden }
html.js .rv-line > *{ display:block; transform:translateY(105%); transition:transform 1s var(--ease) }
html.js [data-in="true"] .rv-line > *{ transform:none }
.rv-line:nth-child(2) > *{ transition-delay:.08s }
.rv-line:nth-child(3) > *{ transition-delay:.16s }
@media (prefers-reduced-motion:reduce){
  html.js [data-rv], html.js [data-rv][data-in="true"]{ opacity:1; transform:none; transition:none }
  html.js .rv-line > *{ transform:none; transition:none }
}

/* ---------- 13. footer / colophon ---------- */
.foot{ border-top:1px solid var(--ink); padding-block:clamp(2.2rem,4.5vw,4rem) 6.5rem }
.foot__grid{ display:flex; flex-wrap:wrap; gap:1.5rem 3rem; justify-content:space-between; align-items:flex-end }
.marq{ overflow:hidden; border-block:1px solid var(--ink); padding-block:.7rem; white-space:nowrap; background:var(--accent) }
.marq__in{ display:inline-flex; gap:2.6rem; animation:marq 30s linear infinite; will-change:transform }
.marq span{
  font-family:var(--disp); font-variation-settings:"wdth" 74,"wght" 800;
  text-transform:uppercase; font-size:clamp(1.3rem,3.2vw,2.6rem); color:#fff;
}
@keyframes marq{ to{ transform:translateX(-50%) } }
@media (prefers-reduced-motion:reduce){ .marq__in{ animation:none } }

/* ---------- 14. view transitions ---------- */
@view-transition{ navigation:auto }
::view-transition-old(root){ animation:vt-out .3s var(--ease-io) both }
::view-transition-new(root){ animation:vt-in .42s var(--ease) both }
@keyframes vt-out{ to{ opacity:0 } }
@keyframes vt-in { from{ opacity:0 } }
@media (prefers-reduced-motion:reduce){
  ::view-transition-old(root),::view-transition-new(root){ animation:none }
}

/* ---------- 15. halftone plate rendering ---------- */
.plate canvas[data-ht-canvas]{
  width:100%; height:100%; object-fit:cover;
  image-rendering:pixelated; image-rendering:crisp-edges;
}
/* the <img> is the no-JS fallback; hide it only once a canvas has replaced it */
.plate[data-ht="done"] img{ display:none }
.plate img{ width:100%; height:100%; object-fit:cover }

/* ============================================================
   REGISTER 2 — LIGHT FIELD   (dissolving-room.html)
   Near-white, vast negative space, thin serif, the point cloud
   doing the work. Tokens are re-pointed rather than overridden
   piecemeal, so every shared component follows automatically.
   ============================================================ */
.reg-field{
  --paper:#FBFAF8; --paper-2:#F3F1EC;
  --ink:#141A3C; --ink-70:rgba(20,26,60,.70); --ink-45:rgba(20,26,60,.45);
  --ink-25:rgba(20,26,60,.25); --hair:rgba(20,26,60,.14); --hair-2:rgba(20,26,60,.07);
  background:var(--paper); color:var(--ink);
}
.reg-field .nav{ border-bottom-color:var(--hair) }
.field{ position:relative; width:100%; height:100%; }
.field__canvas{ position:absolute; inset:0; width:100%; height:100% }
.field[data-fallback="true"]{
  background:
    radial-gradient(70% 55% at 50% 78%, rgba(255,59,18,.34), transparent 70%),
    radial-gradient(60% 50% at 50% 26%, rgba(20,26,60,.30), transparent 72%);
}
.field-stage{ position:relative }
.field-stage__track{ height:var(--field-h,320vh) }
.field-stage__pin{ position:sticky; top:0; height:100vh; overflow:hidden }
.field-stage__type{
  position:absolute; z-index:2; inset:auto var(--pad) 0 var(--pad); top:0;
  display:grid; align-content:center; justify-items:center; text-align:center;
  gap:1.1rem; pointer-events:none;
}
.field-stage__type h1{ max-width:16ch }
/* Now the field is dense enough to see, it is also dense enough to swallow the
   title. A soft paper scrim behind the type keeps it legible without cutting a
   hard hole in the cloud. */
.field-stage__type::before{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:radial-gradient(44% 26% at 50% 50%,
    var(--paper) 0%, rgba(251,250,248,.88) 42%, rgba(251,250,248,.45) 65%, transparent 82%);
}
.field-stage__type > *{ position:relative }
.field-hud{
  position:absolute; z-index:3; inset:auto var(--pad) clamp(1rem,3vw,2.2rem) var(--pad);
  display:flex; justify-content:space-between; align-items:flex-end; gap:1rem; pointer-events:none;
}
@media (prefers-reduced-motion:reduce){ .field-stage__track{ height:100vh } }

/* ============================================================
   REGISTER 3 — RISOGRAPH   (notes.html)
   Two inks, deliberately out of register. The offset colour is a
   pseudo-element under the real text, multiplied — which is how an
   actual misregistered two-colour print behaves.
   ============================================================ */
.reg-riso{
  --paper:#EFE7D8; --paper-2:#E4D9C6;
  --ink:#1B1A17; --ink-70:rgba(27,26,23,.72); --ink-45:rgba(27,26,23,.46);
  --hair:rgba(27,26,23,.2); --hair-2:rgba(27,26,23,.1);
  --riso-a:#FF4B7D;   /* fluoro pink */
  --riso-b:#2A4BD8;   /* blue */
  --accent:var(--riso-a);
  background:var(--paper); color:var(--ink);
}
/* paper grain */
.reg-riso::after{
  content:""; position:fixed; inset:0; z-index:2; pointer-events:none; opacity:.5;
  mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
}
.misreg{ position:relative; display:inline-block; isolation:isolate }
.misreg::before{
  content:attr(data-t); position:absolute; left:-.055em; top:.045em; z-index:-1;
  color:var(--riso-b); mix-blend-mode:multiply;
}
.misreg::after{
  content:attr(data-t); position:absolute; left:.05em; top:-.035em; z-index:-1;
  color:var(--riso-a); mix-blend-mode:multiply;
}
.tape{
  display:inline-block; padding:.45rem .9rem;
  background:rgba(255,75,125,.32); mix-blend-mode:multiply;
  font-family:var(--mono); font-size:.6875rem; letter-spacing:.14em; text-transform:uppercase;
  box-shadow:0 0 0 1px rgba(27,26,23,.06);
}
.tilt-1{ transform:rotate(-1.6deg) } .tilt-2{ transform:rotate(1.9deg) }
.tilt-3{ transform:rotate(-.9deg) }  .tilt-4{ transform:rotate(2.6deg) }
.marginal{
  font-family:var(--serif); font-style:italic; font-size:1.05rem; line-height:1.35;
  color:var(--riso-b); max-width:24ch;
}
.card-riso{
  background:var(--paper-2); padding:clamp(1.1rem,2.4vw,1.9rem);
  border:1px solid rgba(27,26,23,.16); position:relative;
  box-shadow:5px 5px 0 rgba(42,75,216,.16);
}
.card-riso h3{ margin-bottom:.6rem }
.stamp{
  display:inline-grid; place-items:center; width:5.6rem; height:5.6rem; border-radius:50%;
  border:2px solid var(--riso-b); color:var(--riso-b);
  font-family:var(--mono); font-size:.5625rem; letter-spacing:.13em; text-transform:uppercase;
  text-align:center; line-height:1.3; transform:rotate(-11deg); mix-blend-mode:multiply;
}
.reg-riso .plate{ box-shadow:5px 5px 0 rgba(42,75,216,.2) }
.cut{ border:0; border-top:2px dashed rgba(27,26,23,.3); margin:0 }

/* ============================================================
   REGISTER 4 — ESSAY   (lineage.html)
   ============================================================ */
.chapmark{
  position:sticky; top:0; z-index:50;
  display:flex; align-items:center; gap:1rem;
  padding:.5rem var(--pad); background:var(--paper); border-bottom:1px solid var(--hair);
}
.chapmark__bar{ flex:1; height:2px; background:var(--hair-2); position:relative; overflow:hidden }
.chapmark__bar i{ position:absolute; inset:0 100% 0 0; background:var(--accent); transition:right .15s linear }
.chap{ padding-block:clamp(3rem,7vw,7rem) }
.chap__no{
  font-family:var(--disp); font-variation-settings:"wdth" 110,"wght" 800;
  font-size:clamp(3rem,9vw,7.5rem); line-height:.8; color:var(--accent); letter-spacing:-.02em;
}
.chap__ttl{ font-family:var(--serif); font-size:clamp(1.8rem,4vw,3.4rem); line-height:1.06; letter-spacing:-.015em; max-width:20ch }
.drop::first-letter{
  float:left; font-family:var(--serif); font-size:4.2em; line-height:.78;
  padding:.06em .1em 0 0; color:var(--accent);
}

/* timeline */
.tline{ position:relative; padding-block:2.6rem 1rem }
.tline__rail{ position:relative; height:2px; background:var(--hair) }
.tline__rail i{ position:absolute; inset:0 100% 0 0; background:var(--accent); transition:right .2s linear }
.tline__nodes{ position:relative; height:0 }
.tline__n{
  position:absolute; top:-2px; transform:translateX(-50%);
  display:grid; justify-items:center; gap:.5rem;
}
.tline__n b{
  width:9px; height:9px; border-radius:50%; background:var(--paper);
  border:2px solid var(--hair); transition:background .4s var(--ease), border-color .4s, transform .4s var(--ease);
}
.tline__n[data-on="true"] b{ background:var(--accent); border-color:var(--accent); transform:scale(1.25) }
.tline__n span{ font-family:var(--mono); font-size:.625rem; letter-spacing:.1em; color:var(--ink-45); white-space:nowrap; transition:color .4s }
.tline__n[data-on="true"] span{ color:var(--ink) }
.tline__n em{
  font-family:var(--mono); font-style:normal; font-size:.5625rem; letter-spacing:.08em;
  color:var(--ink-25); white-space:nowrap; max-width:11ch; text-align:center; line-height:1.3;
}
@media (max-width:820px){ .tline__n em{ display:none } .tline__n span{ font-size:.5rem } }

/* node graph */
.graph{ width:100%; height:auto; overflow:visible }
.graph path, .graph line{ fill:none; stroke:var(--ink-25); stroke-width:1 }
.graph .edge--a{ stroke:var(--accent); stroke-width:1.5 }
.graph circle{ fill:var(--paper); stroke:var(--ink); stroke-width:1.5 }
.graph circle.node--a{ fill:var(--accent); stroke:var(--accent) }
.graph text{ font-family:var(--mono); font-size:9px; letter-spacing:.09em; text-transform:uppercase; fill:var(--ink-70) }
.graph text.lab--a{ fill:var(--accent); font-weight:600 }

/* pull quote */
.pull{
  margin:2.4rem 0; padding-left:1.5rem; border-left:3px solid var(--accent);
  font-family:var(--serif); font-size:clamp(1.35rem,2.6vw,2.05rem); line-height:1.22; max-width:30ch;
}
.pull cite{ display:block; margin-top:.9rem; font-family:var(--mono); font-style:normal; font-size:.6875rem;
  letter-spacing:.14em; text-transform:uppercase; color:var(--ink-45) }

/* shared small pieces */
.spec{ display:grid; gap:1.15rem; align-content:start }
.spec dt{ margin-bottom:.25rem }
.spec dd{ font-size:.9375rem }
.kit{ display:grid; gap:.8rem }
.kit li{ padding-left:1.3rem; position:relative; color:var(--ink-70) }
.kit li::before{ content:""; position:absolute; left:0; top:.62em; width:6px; height:1px; background:var(--accent) }
.lic{ border-top:1px solid var(--ink) }
.lic__row{ display:grid; grid-template-columns:minmax(0,1.1fr) minmax(0,1.4fr) 9rem; gap:1.2rem;
  padding-block:.95rem; border-bottom:1px solid var(--hair-2); align-items:baseline }
.lic__row p{ font-size:.875rem; color:var(--ink-70) }
.lic__row code{ font-size:.75rem; color:var(--ink-45) }
@media (max-width:820px){ .lic__row{ grid-template-columns:1fr; gap:.25rem } }

/* ---------- 16. odds and ends ---------- */
.card-link{
  display:block; padding:clamp(1rem,2vw,1.5rem);
  border:1px solid var(--hair); background:var(--paper);
  transition:border-color .35s, background .35s var(--ease), transform .45s var(--ease);
}
.card-link:hover{ border-color:var(--accent); background:var(--paper-2); transform:translateY(-3px) }
.link{ color:var(--accent); border-bottom:1px solid transparent; transition:border-color .3s }
.link:hover{ border-color:currentColor }
.filters .chip{ cursor:pointer }
/* Keep buttons that act as catalogue rows visually identical to the div rows.
   The playable rows carry both .cat__row and .cue, and .cue declares its own
   three-column grid for the player's cue list. Equal specificity, and .cue is
   further down the file, so it was winning: rows 002, 004 and 007 were laid
   out in three columns and wrapping onto two lines. button.cat__row is one
   class more specific, so the catalogue layout is restated here. */
button.cat__row{ width:100%; text-align:left; font:inherit; color:inherit; border:0;
  border-bottom:1px solid var(--hair-2); background:none; cursor:pointer;
  grid-template-columns:4.5rem minmax(0,1fr) 12rem 5.5rem 4.5rem; align-items:baseline;
  padding-block:.85rem; padding-inline:0 }   /* a button carries UA side padding of its
                                                own, which pushed the three playable rows
                                                a few pixels right of every other row */
@media (max-width:900px){
  button.cat__row{ grid-template-columns:3.5rem minmax(0,1fr) 4rem; row-gap:.25rem }
}

button.cat__row[data-active="true"] .cat__ttl{ color:var(--signal) }
button.cat__row[data-active="true"] .cat__no::after{ content:" \25B8" }

/* ============================================================
   17. THE RACK
   The panel in Plate 01 is not a decorated surface, it is an
   assembly: discrete function blocks butted against each other,
   sharing one hairline where they meet, every one of them
   labelled and numbered. None of that is lighting, so none of
   it is drawn with shadows or bevels.

   A rack is a grid with a 1px gap and a dark background: the gap
   IS the seam. Cells never carry their own borders, so two cells
   meeting never produce a 2px line, and the outer edge of the
   assembly is a single stroke on the rack itself.
   ============================================================ */
.fascia{ max-width:1760px; margin-inline:auto; border-inline:1px solid var(--seam); border-top:1px solid var(--seam) }
.rack{
  display:grid; gap:1px; background:var(--seam);
  border-bottom:1px solid var(--seam);
}
.rack--2{ grid-template-columns:repeat(2,1fr) }
.rack--3{ grid-template-columns:repeat(3,1fr) }
.rack--4{ grid-template-columns:repeat(4,1fr) }
.rack--6{ grid-template-columns:repeat(6,1fr) }
@media (max-width:1000px){
  .rack--6{ grid-template-columns:repeat(3,1fr) }
  .rack--4{ grid-template-columns:repeat(2,1fr) }
}
@media (max-width:620px){
  .rack--2,.rack--3,.rack--4,.rack--6{ grid-template-columns:1fr }
  .rack [style*="grid-column"]{ grid-column:1 / -1 !important }
}

.cell{
  position:relative; min-width:0; background:var(--paper);
  padding:clamp(1.1rem,2.2vw,2.1rem);
}
.cell--inv{ background:var(--laminate); color:var(--paper) }
/* There used to be three greys for cells. The seam does that work, so a cell is
   either the field or inverted, and these two names are kept only so the other
   pages' markup does not have to change. */
.cell--rec, .cell--fwd{ background:var(--paper) }
.cell--flush{ padding:0 }
.cell--tall{ padding-block:clamp(1.4rem,3vw,2.6rem) }

/* the legend on a cell, and the value under it */
.k{
  display:block; font-family:var(--mono); font-size:.5625rem; font-weight:500;
  text-transform:uppercase; letter-spacing:.2em; color:var(--ink-45);
}
.cell--inv .k, .cell--ox .k{ color:rgba(243,241,238,.62) }
.v{
  display:block; margin-top:.75rem; font-family:var(--mono); font-weight:400;
  font-variant-numeric:tabular-nums; font-size:clamp(1.05rem,1.9vw,1.55rem); line-height:1;
}
.v small{ font-size:.5em; letter-spacing:.14em; color:var(--ink-45); margin-left:.4em }
.cell--inv .v small{ color:rgba(243,241,238,.55) }



/* the nameplate: an ident plate bolted to the assembly, not a masthead */
.plate-id{
  font-family:var(--disp); font-variation-settings:"wdth" 68,"wght" 800;
  text-transform:uppercase; line-height:.9; letter-spacing:-.005em;
  font-size:clamp(1.85rem,4.6vw,3.7rem); margin-top:1rem;
}

/* a cell that is a link behaves like a control: it inverts */
a.cell{ display:block; color:inherit; transition:background .16s linear, color .16s linear }
a.cell:hover, a.cell:focus-visible{ background:var(--laminate); color:var(--paper) }
a.cell:hover .k, a.cell:focus-visible .k{ color:rgba(243,241,238,.62) }
a.cell:hover .arrow, a.cell:focus-visible .arrow{ color:var(--accent) }


/* a link cell stacks its legend, its name and its note */
a.cell .v{ font-family:var(--disp); font-variation-settings:"wdth" 78,"wght" 700;
  text-transform:uppercase; font-size:clamp(1.05rem,1.7vw,1.4rem); margin-top:.6rem }
.arrow{ color:var(--ink-45); transition:color .16s linear }

/* inside the fascia the strip is a cell like anything else */
.fascia .strip{ padding-inline:clamp(.85rem,1.5vw,1.45rem); border-bottom:1px solid var(--seam) }
/* a flush plate fills its cell exactly, so the seam is the aperture edge */
.cell--flush.plate img, .cell--flush.plate canvas{ width:100%; height:100%; object-fit:cover }

/* a filter is a control cell: pressed means inverted, not "highlighted" */
.filt{ text-align:left; font:inherit; color:inherit; border:0; cursor:pointer;
  transition:background .16s linear, color .16s linear }
.filt:hover{ background:var(--paper) }
.filt[aria-pressed="true"]{ background:var(--laminate); color:var(--paper) }
.filt[aria-pressed="true"] .k{ color:rgba(243,241,238,.62) }

/* the top rail runs out of room at phone widths — the last link was landing
   exactly on the right edge with nothing to spare */
@media (max-width:640px){
  .nav{ padding-inline:.7rem; gap:.55rem }
  .nav__links{ gap:.62rem }
  .nav__links a{ font-size:.5625rem; letter-spacing:.07em }
  .mark small{ display:none }
}
