/* ═══════════════════════════════════════════════════════════════════
   ABADDON.NFO — layout and components
   One spacing system. Sections never re-declare their own margins.
   ═══════════════════════════════════════════════════════════════════ */

/* ── the document frame ─────────────────────────────────────────────
   The reference is a framed plate with crop marks. Keep it pinned to
   the viewport so the whole site reads as one document.             */
.frame{
  position:fixed;inset:var(--frame-inset);
  border:1px solid var(--line);
  pointer-events:none;z-index:40;
}
.frame span{position:absolute;width:16px;height:16px;border:0 dashed var(--bone)}
.frame span:nth-child(1){top:-1px;left:-1px;border-top-width:1px;border-left-width:1px}
.frame span:nth-child(2){top:-1px;right:-1px;border-top-width:1px;border-right-width:1px}
.frame span:nth-child(3){bottom:-1px;left:-1px;border-bottom-width:1px;border-left-width:1px}
.frame span:nth-child(4){bottom:-1px;right:-1px;border-bottom-width:1px;border-right-width:1px}

/* ── top status rail: a DOS status line, not a nav bar ──────────── */
.bar{
  position:fixed;top:var(--frame-inset);left:var(--frame-inset);right:var(--frame-inset);
  height:var(--bar-h);z-index:50;
  display:flex;align-items:stretch;
  background:var(--void);
  border-bottom:1px solid var(--line);
  font-size:var(--t-micro);
  letter-spacing:var(--track-mid);
}
.bar__id{
  display:flex;align-items:center;gap:.7ch;
  padding:0 var(--s2);flex:0 0 auto;
  border-right:1px solid var(--line);
  font-weight:600;
}
.bar__id i{font-style:normal;color:var(--ash)}
/* The scroller is the safety net for the band just above the menu
   breakpoint, where a fallback mono could run wider than Plex. Its
   scrollbar is left visible on purpose: a hidden one is how four
   sections went missing here in the first place. */
.bar__nav{
  flex:1 1 auto;display:flex;align-items:stretch;min-width:0;
  overflow-x:auto;
}
.bar__nav a{
  display:flex;align-items:center;padding:0 .95rem;
  white-space:nowrap;color:var(--ash);
  border-right:1px solid var(--dust);
}
.bar__nav a[aria-current="true"]{color:var(--void);background:var(--bone)}
.bar__get{
  flex:0 0 auto;display:flex;align-items:center;gap:.6ch;
  padding:0 var(--s2);border-left:1px solid var(--line);
  font-weight:600;
}
/* the disclosure. Hidden until the eight labels stop fitting. */
.bar__menu{
  display:none;flex:0 0 auto;margin-left:auto;
  align-items:center;padding:0 var(--s2);
  border-left:1px solid var(--line);
  font-size:inherit;letter-spacing:inherit;font-weight:600;
}
.bar__scroll{
  position:fixed;top:var(--frame-inset);left:var(--frame-inset);right:var(--frame-inset);
  height:1px;background:var(--bone);z-index:51;
  transform:scaleX(0);transform-origin:0 50%;
}

/* ── the nav below 1040px ───────────────────────────────────────────
   Seven letterspaced labels need about 680px, and the id and the .nfo
   link either side of them take the bar to roughly 975px. Under that
   the old rule kept the labels in a scroller with the scrollbar
   hidden, so half the sections were unreachable on a phone with no
   sign they were there. Here the same list becomes a panel hung off
   the bar. The breakpoint keeps about 10% in hand for a mono that
   measures wider than Plex.                                         */
@media (max-width:1040px){
  .bar__nav{
    position:fixed;
    top:calc(var(--frame-inset) + var(--bar-h));
    left:var(--frame-inset);right:var(--frame-inset);
    display:none;flex-direction:column;
    /* dvh so the panel is not measured against a viewport that the
       mobile url bar is about to take back; vh first for anything
       that does not know the unit */
    max-height:calc(100vh - var(--bar-h) - var(--frame-inset) * 2);
    max-height:calc(100dvh - var(--bar-h) - var(--frame-inset) * 2);
    overflow:hidden auto;overscroll-behavior:contain;
    background:var(--void);
    border:1px solid var(--line);border-top:0;
  }
  .bar__nav[data-open="true"]{display:flex}
  /* in the bar these labels are a passive readout and sit in the
     secondary ink; in the panel they are the navigation itself */
  .bar__nav a{
    border-right:0;border-bottom:1px dotted var(--dust);
    min-height:var(--tap);padding:0 var(--s2);
    color:var(--bone);
  }
  .bar__nav a:last-child{border-bottom:0}
  .bar__menu{display:flex}
  .bar__menu[aria-expanded="true"]{background:var(--bone);color:var(--void)}
}
@media (max-width:820px){ .bar__get span{display:none} }
/* at 320px the bar holds three items; the serial number is the one
   piece of it that carries no function. */
@media (max-width:560px){ .bar__id i{display:none} }

/* ── inversion: the one interaction language on this site ──────────
   steps(2) keeps even the transition 1-bit. Nothing here fades.    */
.hit{transition:background .07s steps(2),color .07s steps(2)}
.hit:hover,.hit:focus-visible{background:var(--bone);color:var(--void);outline:none}
.hit:hover .row__lead,.hit:focus-visible .row__lead{border-bottom-color:var(--void)}
.hit:hover .row__k,.hit:focus-visible .row__k,
.hit:hover .row__v,.hit:focus-visible .row__v,
.hit:hover .idx__n,.hit:focus-visible .idx__n,
.hit:hover .idx__m u,.hit:focus-visible .idx__m u{color:var(--void)}
.hit:hover .idx__t::after,.hit:focus-visible .idx__t::after{border-bottom-color:var(--void)}

/* ── shell: the triptych ───────────────────────────────────────────
   Two engraving rails flanking one scrolling column of panels.     */
.shell{
  max-width:1560px;margin:0 auto;
  padding:calc(var(--bar-h) + var(--s5)) var(--s4) var(--s6);
  display:grid;grid-template-columns:minmax(0,1fr);
  gap:var(--s4);
}
.rail{display:none}
@media (min-width:1240px){
  .shell{grid-template-columns:var(--rail-w) minmax(0,1fr) var(--rail-w)}
  .rail{
    display:flex;flex-direction:column;gap:var(--s2);
    position:sticky;top:calc(var(--bar-h) + var(--s4));
    height:calc(100vh - var(--bar-h) - var(--s6));
  }
  /* The engraved banner, whole. It is 400x3000 — a 1:7.5 strip — and
     the rail box is nearer 1:6, so `cover` was scaling it to the
     width and slicing the ends off: two of the eight initials never
     made it onto the page. `contain` fits it to the height instead,
     so the full strip reads, and the rail is left wider than the art
     rather than the art cropped to the rail.                       */
  .rail__art{
    flex:1 1 auto;width:100%;height:100%;min-height:0;
    object-fit:contain;object-position:50% 50%;
    opacity:.78;
  }
  /* the reference carries taglines here. These are the client words. */
  .rail__cap{
    flex:0 0 auto;text-align:center;
    font-size:var(--t-micro);letter-spacing:var(--track-mid);
    color:var(--ash);line-height:1.5;
  }
}
@media (max-width:560px){ .shell{padding-inline:var(--s2)} }
.col{display:flex;flex-direction:column;gap:var(--s6);min-width:0}

/* ═══ HERO / NFO HEAD ═══════════════════════════════════════════ */
.hero{display:flex;flex-direction:column;gap:var(--s4)}
.hero__top{
  display:grid;grid-template-columns:1fr;
  gap:var(--s3);align-items:center;justify-items:center;
}

.wordmark{text-align:center;line-height:.82;width:100%}
/* the drawn mark, not type. It is white-on-transparent art, so it
   needs no colour treatment — only a ceiling so it never outgrows
   the column it sits in. */
.wordmark__logo{
  display:block;width:min(100%,var(--logo-w));height:auto;
  margin-inline:auto;
}
.wordmark em{
  display:block;font-style:normal;
  font-size:clamp(.7rem,2.3vw,1.15rem);font-weight:700;
  letter-spacing:clamp(.34em,1.5vw,.62em);
  text-indent:clamp(.34em,1.5vw,.62em);
  margin-top:var(--s2);
}
.wordmark small{
  display:block;margin-top:var(--s2);
  font-size:var(--t-micro);letter-spacing:var(--track-mid);
  color:var(--ash);
}

/* the header cartouche from the reference: =[ ... ]= */
.cartouche{
  display:flex;align-items:center;gap:var(--s2);
  font-size:var(--t-micro);letter-spacing:var(--track-wide);
}
.cartouche::before,.cartouche::after{content:"";flex:1;height:5px;background:var(--screen-50)}
.cartouche span{flex:0 1 auto;text-align:center}

/* Separators were &nbsp;-joined, which welded each line into a single
   unbreakable token and pinned the page wider than a phone viewport.
   Real spaces break; the padding keeps the air. */
.sep{padding:0 .3em;color:var(--ash)}

/* ═══ DOTTED-LEADER ROW — the core information device ════════════ */
.row{display:flex;align-items:baseline;gap:.6ch;padding:.28rem .35rem;font-size:var(--t-fine)}
.row__k{
  flex:0 0 auto;color:var(--ash);white-space:nowrap;
  letter-spacing:var(--track-tight);
}
.row__lead{
  flex:1 1 auto;min-width:1.5ch;align-self:center;
  border-bottom:1px dotted var(--dust);position:relative;top:.18em;
}
.row__v{flex:0 0 auto;white-space:nowrap;font-weight:600;letter-spacing:var(--track-tight)}
.row__v.is-off{color:var(--ash);font-weight:400}

/* ═══ PANEL ═════════════════════════════════════════════════════ */
.panel{display:flex;flex-direction:column;gap:var(--s3);scroll-margin-top:calc(var(--bar-h) + var(--s4))}
.panel__head{display:flex;align-items:center;gap:var(--s2)}
.panel__head::before,.panel__head::after{content:"";flex:1;height:5px;background:var(--screen-50)}
.panel__title{
  flex:0 0 auto;font-weight:600;
  font-size:var(--t-head);letter-spacing:var(--track-wide);white-space:nowrap;
}
.panel__title::before{content:"[ ";color:var(--ash)}
.panel__title::after{content:" ]";color:var(--ash)}
@media (max-width:560px){
  .panel__title{font-size:var(--t-small);letter-spacing:var(--track-mid);white-space:normal}
}
.panel__body{
  border:1px solid var(--line);
  box-shadow:inset 0 0 0 3px var(--void),inset 0 0 0 4px var(--line);
  padding:var(--s4);
  display:flex;flex-direction:column;gap:var(--s3);
}
@media (max-width:560px){ .panel__body{padding:var(--s3) var(--s2)} }
.panel__note{
  font-size:var(--t-micro);letter-spacing:var(--track-tight);
  color:var(--ash);
}

.sub{font-family:var(--gothic);font-weight:700;font-size:var(--t-sub);line-height:1.1;letter-spacing:.02em}

/* ═══ MANIFESTO ═════════════════════════════════════════════════ */
.creed{
  font-family:var(--gothic);font-weight:700;
  font-size:clamp(1.6rem,5.2vw,3.1rem);line-height:1.06;
  text-align:center;max-width:26ch;margin-inline:auto;
}
.prose{max-width:var(--measure);margin-inline:auto;display:flex;flex-direction:column;gap:var(--s2)}
.prose p.is-lead{font-size:var(--t-lead);line-height:1.6}
.prose strong{font-weight:600}
.cite{
  font-size:var(--t-micro);letter-spacing:var(--track-mid);
  color:var(--ash);text-align:center;
}
.rule{height:5px;background:var(--screen-50);border:0}

/* ═══ CONSOLE — custom 1-bit transport over the SoundCloud widget ═ */
.console{
  border:1px solid var(--line);
  box-shadow:inset 0 0 0 3px var(--void),inset 0 0 0 4px var(--line);
  display:flex;flex-direction:column;
}
.console__bar{
  display:flex;align-items:center;justify-content:space-between;gap:var(--s2);
  padding:.5rem .8rem;border-bottom:1px solid var(--line);
  background:var(--screen-12);
  font-size:var(--t-micro);letter-spacing:var(--track-mid);
}
.console__bar b{font-weight:600}
.console__state{color:var(--ash)}
.console__state[data-state="playing"]{color:var(--bone)}
.console__state[data-state="offline"]{color:var(--ash)}
.console__body{padding:var(--s3) var(--s3) var(--s4);display:flex;flex-direction:column;gap:var(--s3)}
.console__now{display:flex;flex-direction:column;gap:.2rem;min-height:3.4em}
.console__now b{
  font-family:var(--term);font-size:clamp(1.1rem,3.4vw,1.7rem);
  line-height:1.1;font-weight:400;letter-spacing:var(--track-tight);
}
.console__now i{
  font-style:normal;font-size:var(--t-micro);letter-spacing:var(--track-mid);
  color:var(--ash);
}

/* progress: a halftone track, a solid bone fill. No font dependency. */
.meter{display:flex;align-items:center;gap:var(--s2)}
.meter__t{
  flex:1 1 auto;height:12px;position:relative;cursor:pointer;
  background:var(--screen-50);border:1px solid var(--dust);
}
.meter__f{position:absolute;inset:0 auto 0 0;width:0;background:var(--bone)}
.meter__time{flex:0 0 auto;font-family:var(--term);font-size:1rem;color:var(--ash);letter-spacing:.04em}

.transport{display:flex;flex-wrap:wrap;gap:.5rem}
.btn{
  border:1px solid var(--line);padding:.4rem .9rem;
  font-size:var(--t-micro);letter-spacing:var(--track-mid);font-weight:600;
}
.btn[disabled]{color:var(--mute);border-color:var(--dust);cursor:not-allowed}
.btn[disabled]:hover{background:none;color:var(--mute)}
.sc-frame{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;border:0}

/* ═══ ARCHIVE INDEX ═════════════════════════════════════════════ */
.tabs{display:flex;flex-wrap:wrap;gap:.4rem;align-items:center}
.tabs__sp{flex:1 1 auto}
.tab{
  border:1px solid var(--line);padding:.32rem .8rem;
  font-size:var(--t-micro);letter-spacing:var(--track-mid);color:var(--ash);
}
.tab[aria-selected="true"]{background:var(--bone);color:var(--void);border-color:var(--bone);font-weight:600}

.index{display:flex;flex-direction:column}
.idx{
  display:grid;grid-template-columns:3.2ch minmax(0,1fr) auto;
  align-items:baseline;gap:.6ch;
  padding:.42rem .5rem;
  border-bottom:1px dotted var(--dust);
}
.idx__n{font-family:var(--term);font-size:.95rem;color:var(--ash);text-align:right}
.idx__t{
  display:flex;align-items:baseline;gap:.6ch;min-width:0;
  font-size:var(--t-body);font-weight:500;letter-spacing:var(--track-tight);
}
.idx__t span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.idx__t::after{
  content:"";flex:1 1 auto;min-width:1.5ch;
  border-bottom:1px dotted var(--dust);position:relative;top:-.24em;
}
.idx__m{display:flex;gap:1.2ch;font-family:var(--term);font-size:1rem;white-space:nowrap;letter-spacing:.03em}
.idx__m u{text-decoration:none;color:var(--ash)}
.idx.is-playing{background:var(--bone);color:var(--void)}
.idx.is-playing .idx__n,.idx.is-playing .idx__m u{color:var(--void)}
.idx.is-playing .idx__t::after{border-bottom-color:var(--void)}
@media (max-width:560px){
  .idx{grid-template-columns:2.6ch minmax(0,1fr);row-gap:0}
  .idx__m{grid-column:2;justify-content:flex-start;font-size:.9rem}
  .idx__t::after{display:none}
}

/* ═══ CREW ══════════════════════════════════════════════════════ */
.crew{display:grid;grid-template-columns:minmax(0,1fr);gap:0 var(--s5)}
@media (min-width:680px){ .crew{grid-template-columns:repeat(2,minmax(0,1fr))} }

/* ═══ NETWORK ═══════════════════════════════════════════════════ */
.net{display:grid;grid-template-columns:minmax(0,1fr);gap:.4rem}
@media (min-width:720px){ .net{grid-template-columns:repeat(2,minmax(0,1fr))} }
.net__i{
  display:flex;align-items:baseline;gap:.6ch;
  border:1px solid var(--line);padding:.6rem .8rem;font-size:var(--t-fine);
}
.net__i .row__k{min-width:11ch}
.net__i[data-set="false"]{border-style:dashed;border-color:var(--dust)}
.net__i[data-set="false"]:hover{background:none;color:inherit}

/* ═══ GATHERINGS ════════════════════════════════════════════════ */
.withheld{
  display:flex;flex-direction:column;align-items:center;gap:var(--s2);
  padding:var(--s5) var(--s2);text-align:center;
  background:var(--screen-12);border:1px dashed var(--line);
}
.withheld b{font-family:var(--gothic);font-weight:700;font-size:clamp(1.5rem,5vw,2.6rem);line-height:1.05}
.withheld p{max-width:46ch;font-size:var(--t-fine);color:var(--ash)}

/* ═══ TRANSMISSION (contact) ════════════════════════════════════ */
.form{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s2)}
@media (min-width:680px){
  .form{grid-template-columns:repeat(2,minmax(0,1fr))}
  .f--wide{grid-column:1/-1}
}
.f{display:flex;flex-direction:column;gap:.3rem}
.f label{font-size:var(--t-micro);letter-spacing:var(--track-mid);color:var(--ash)}
.f input,.f textarea,.f select{
  border:1px solid var(--line);background:var(--void);color:var(--bone);
  padding:.55rem .7rem;font-family:var(--mono);font-size:var(--t-body);
}
.f input::placeholder,.f textarea::placeholder{color:var(--ash);opacity:1}
.f input:focus-visible,.f textarea:focus-visible,.f select:focus-visible{
  outline:1px solid var(--bone);outline-offset:0;background:var(--void);color:var(--bone);
}
.f textarea{resize:vertical;min-height:7.5rem}
.form__act{grid-column:1/-1;display:flex;flex-wrap:wrap;gap:var(--s2);align-items:center}
.form__msg{font-size:var(--t-micro);letter-spacing:var(--track-mid);color:var(--ash)}

/* ═══ SUPPORT ═══════════════════════════════════════════════════ */
.fund{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s2)}
@media (min-width:720px){ .fund{grid-template-columns:repeat(3,minmax(0,1fr))} }
.fund__i{border:1px solid var(--line);padding:var(--s2);display:flex;flex-direction:column;gap:.4rem}
.fund__i b{font-family:var(--term);font-size:1.5rem;font-weight:400;line-height:1}
.fund__i span{font-size:var(--t-micro);letter-spacing:var(--track-mid);color:var(--ash)}
.fund__i p{font-size:var(--t-fine)}

/* ═══ FOOTER ════════════════════════════════════════════════════ */
.foot{
  display:flex;flex-wrap:wrap;gap:var(--s2);justify-content:space-between;align-items:flex-end;
  border-top:1px solid var(--line);padding-top:var(--s3);
  font-size:var(--t-micro);letter-spacing:var(--track-mid);color:var(--ash);
}
.foot b{display:block;font-family:var(--gothic);font-size:1.5rem;color:var(--bone);letter-spacing:.02em}

/* ── narrow viewports ──────────────────────────────────────────────
   The remaining offenders are values that must not wrap on a wide
   screen but have to be allowed to on a narrow one.

   The cartouche used to drop its flanking screens here, because the
   old four-genre line could not fit between them on a phone. It reads
   FREE SOUND now, which fits at 320px, so it keeps its rails.       */
@media (max-width:820px){
  /* Anything under 16px makes iOS Safari zoom the whole page the
     moment the field takes focus, and it never zooms back out. */
  .f input,.f textarea,.f select{font-size:16px}
  /* Controls sized for a cursor are not sized for a thumb. */
  .btn,.tab,.mini__b{min-height:var(--tap);display:inline-flex;align-items:center}
  .mini__x{width:var(--tap);height:var(--tap)}
  .bar__get,.bar__id{min-height:var(--tap)}
  .meter__t{height:20px}
  .idx,.row{padding-block:.55rem}
}
@media (max-width:560px){
  .row{flex-wrap:wrap}
  /* once the value wraps to its own line it is no longer held right by
     the leader, so it has to hold itself there */
  .row__v{white-space:normal;margin-left:auto;text-align:right}
  .row__lead{min-width:1ch}
  .net__i{flex-wrap:wrap}
  .net__i .row__k{min-width:0}
}

/* ── reveal on scroll: quantised steps, no easing ────────────────
   Gated on html.anim, which main.js only adds once it has reached the
   point of wiring the observer. No JS, or a throw before that, leaves
   every panel visible. */
.anim .rv{opacity:0;transform:translate3d(0,10px,0)}
.anim .rv.in{opacity:1;transform:none;transition:opacity .28s steps(4),transform .28s steps(4)}
@media (prefers-reduced-motion:reduce){
  .anim .rv{opacity:1;transform:none}
}

/* ═══ MINI TRANSPORT ════════════════════════════════════════════════
   The console in the archive is the interface; this is the same
   controls docked to the foot of the plate for when it has scrolled
   away. Same widget behind both, so the two can never disagree about
   what is playing. It is built like every other plate on the site —
   hairline, inset rules, no fill — and carries the blackletter A so
   the thing that follows you down the page is still the mark.       */
.mini{
  position:fixed;z-index:45;
  left:var(--frame-inset);right:var(--frame-inset);bottom:var(--frame-inset);
  display:flex;align-items:center;gap:var(--s2);
  padding:.6rem .8rem;
  background:var(--void);
  border:1px solid var(--line);
  box-shadow:inset 0 0 0 3px var(--void),inset 0 0 0 4px var(--line);
  font-size:var(--t-micro);letter-spacing:var(--track-mid);
}
.mini[data-on="false"]{display:none}

/* the progress read: a halftone track struck across the top edge */
.mini__bar{position:absolute;left:0;right:0;top:0;height:3px;background:var(--screen-50)}
.mini__fill{height:100%;width:0;background:var(--bone)}

.mini__mark{
  flex:0 0 auto;
  font-family:var(--gothic);font-weight:700;
  font-size:1.85rem;line-height:1;
  padding:.1rem .45rem .25rem;
  border:1px solid var(--line);
  letter-spacing:0;
}

.mini__now{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:.12rem}
.mini__now b{
  font-family:var(--term);font-weight:400;
  font-size:1.15rem;line-height:1.15;letter-spacing:var(--track-tight);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.mini__now i{
  font-style:normal;color:var(--ash);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

.mini__time{
  flex:0 0 auto;font-family:var(--term);font-size:1rem;
  color:var(--ash);letter-spacing:.04em;white-space:nowrap;
}

.mini__ctl{flex:0 0 auto;display:flex;gap:.35rem}
.mini__b{
  border:1px solid var(--line);padding:.35rem .7rem;
  font-size:var(--t-micro);letter-spacing:var(--track-mid);font-weight:600;
}
.mini__b[disabled]{color:var(--mute);border-color:var(--dust);cursor:not-allowed}
.mini__b[disabled]:hover{background:none;color:var(--mute)}
.mini__x{
  flex:0 0 auto;border:1px solid var(--line);
  width:1.9rem;height:1.9rem;
  display:flex;align-items:center;justify-content:center;
  font-size:1rem;line-height:1;letter-spacing:0;color:var(--ash);
}

/* it arrives the way the panels do: quantised, no easing */
.anim .mini[data-on="true"]{animation:dock .24s steps(4) both}
@keyframes dock{from{opacity:0;transform:translate3d(0,14px,0)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){ .anim .mini[data-on="true"]{animation:none} }

/* On a phone the labels go, but the controls do not: PREV and NEXT
   keep working as guillemets, which the site already uses and which
   are inside Latin-1 like everything else here. */
@media (max-width:700px){
  .mini{gap:var(--s1);padding:.5rem .55rem}
  .mini__now i,.mini__time{display:none}
  .mini__mark{font-size:1.5rem}
  #miniPrev,#miniNext{font-size:0;padding:.35rem .5rem}
  #miniPrev::after{content:"\00AB";font-size:.75rem;letter-spacing:0}
  #miniNext::after{content:"\00BB";font-size:.75rem;letter-spacing:0}
}

/* The dock is fixed, so the column has to give back the height it
   covers or it eats the last line of the footer. :has keeps that
   knowledge in CSS rather than making the controller reach out and
   set a padding on something it does not own. */
body:has(.mini[data-on="true"]) .shell{padding-bottom:calc(var(--s6) + 5rem)}

/* ═══ TRACKLISTS ════════════════════════════════════════════════════
   Only sets with an entry in `tracklists` grow this, so most rows in
   the index look exactly as they did. The toggle sits under its row
   and is indented to the same column the titles start in.          */
.idsw{display:flex;flex-direction:column;border-bottom:1px dotted var(--dust)}
.ids__t{
  align-self:flex-start;
  margin:.1rem 0 .35rem 3.8ch;
  padding:.25rem .7rem;
  border:1px solid var(--dust);
  font-size:var(--t-micro);letter-spacing:var(--track-mid);
  color:var(--ash);
}
.ids__t::before{content:"+ ";}
.ids__t[aria-expanded="true"]{color:var(--bone);border-color:var(--line)}
.ids__t[aria-expanded="true"]::before{content:"- ";}

.ids{
  display:flex;flex-direction:column;
  margin:0 0 .5rem 3.8ch;
  border-left:1px solid var(--dust);
}
.ids__i{
  display:flex;align-items:baseline;gap:1.2ch;width:100%;
  padding:.3rem .7rem;text-align:left;
  font-size:var(--t-fine);
}
/* the timestamp is the control, so it reads as the machine's voice */
.ids__i b{
  flex:0 0 auto;font-family:var(--term);font-size:1rem;font-weight:400;
  color:var(--ash);letter-spacing:.04em;min-width:6ch;
}
.ids__i span{flex:1 1 auto;min-width:0;letter-spacing:var(--track-tight)}
.ids__i:hover b,.ids__i:focus-visible b{color:var(--void)}

@media (max-width:560px){
  .ids__t{margin-left:2.6ch}
  .ids{margin-left:2.6ch}
  .ids__i{flex-wrap:wrap;gap:0 1ch}
}
@media (max-width:820px){
  .ids__t,.ids__i{min-height:var(--tap)}
  .ids__i{align-items:center}
}
