/* site/ui/tokens.css — every value the house shares, named once.

   The house is The Broadcast: sage is the paper stock, ink the one printing
   colour, yellow the spot colour. The module is 8px and one printed pixel is
   2px: borders are 2px or 4px, drops 2, 4, 6 or 8px. Values measured from the
   approved version 2 prototype (2026-10-03), so the port looks exactly like it.

   The rule (site/ui/assemble.mjs enforces it): a colour, size, shadow, border,
   spacing or timing is written as a value only in a custom property. The
   house's shared ones live here; a value only one part uses is a custom
   property at the top of that part's .css, named after the part. Everything
   else says var(--...). So any adjustment is one line in a known place:
   this file for the house, the top of the part for the part.

   Screen widths cannot be custom properties inside @media, so they are named
   as custom media (@media (min-width: 768px)), listed at the foot of this file, and
   site/ui/assemble.mjs writes the numbers in. Scripts read the same names
   through ui.mq('md') (site/ui/runtime.js). */

:root {
  /* ---- colour: the ten live tokens, unchanged ---------------------------- */
  --sage: #7d9478; --ink: #1f1f1f; --cream: #f2ead8; --yellow: #f2b52b; --silver: #d6d6d6;
  --paper: #faf6ec; --muted: #5c5342; --tan: #e6d3ae; --leaf: #cfdcc9; --warn: #a8622a;
  --white: #ffffff;
  /* the lights: REC, the display's cyan, and an idle grey */
  --rec: #d0342c; --vfd: #07fafc; --vfd-dim: #8be9ea; --idle: #a8b5a4;
  /* the bevels a printed pixel makes on silver, sage and yellow */
  --silver-hi: #f4f4f4; --silver-lo: #8e8e8e; --sage-hi: #8fa58a; --sage-lo: #6a8165;
  --yellow-hi: #fce063; --yellow-lo: #df9302; --yellow-edge: #c58a06;
  /* the deck's glass, and the backdrop the robot's small face stands on (the deck's key, a who card's fallback) */
  --glass: #0b1313; --robot-bg: #639685;
  /* the shelf, sampled from the studio art: wood, gunmetal shells, steel uprights, a label's green */
  --wood: #a96c41; --wood-hi: #d48547; --wood-lo: #804422; --gun: #3a3e48; --gun-hi: #5b5e68; --gun-lo: #2a2d35;
  --steel: #c5c8d2; --steel-hi: #e1e0e6; --steel-lo: #8a8d98; --dusk: #365d48;

  /* ---- type: the faces ----------------------------------------------------- */
  --sans: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  /* the pixel face (Departure Mono, SIL OFL 1.1), only for machine labels, only at 11, 22, 33 and 44px */
  --pix: 'Departure Mono', 'DM Menlo', 'DM Consolas', 'DM Courier', ui-monospace, monospace;
  --voice: Georgia, 'Times New Roman', serif;
  --code: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --pix-advance: 7px;   /* one pixel-face character at 11px; the deck's display counts in these */

  /* ---- type: the styles the house repeats, by role ------------------------- */
  --t-body: 400 16px/24px var(--sans);
  --t-body-strong: 500 16px/24px var(--sans);
  --t-read: 400 17px/28px var(--sans);            /* standfirsts and reading paragraphs */
  --t-read-strong: 500 17px/28px var(--sans);
  --t-voice: italic 400 17px/28px var(--voice);   /* the footer's colophon */
  --t-ui: 600 14px/20px var(--sans);              /* buttons, nav, small headings */
  --t-ui-medium: 500 14px/20px var(--sans);
  --t-ui-roomy: 600 14px/24px var(--sans);
  --t-ui-small: 600 13px/20px var(--sans);
  --t-key: 700 15px/1 var(--sans);                /* the label on a key */
  --t-h6: 700 16px/20px var(--sans);
  --t-h5: 700 18px/24px var(--sans);
  --t-h4: 700 20px/24px var(--sans);
  --t-h3: 700 22px/28px var(--sans);
  --t-h2: 700 28px/32px var(--sans);
  --t-h2-tight: 700 32px/32px var(--sans);
  --t-h1-panel: 700 40px/40px var(--sans);
  --t-label: 400 11px/16px var(--pix);            /* machine labels: datelines, counts, captions */
  --t-label-tight: 400 11px/12px var(--pix);
  --t-display: 400 22px/24px var(--pix);          /* the deck's counter, big numbers */
  --track-display: -.04em;                        /* the big ink headings: the hero's, a section's */

  /* ---- space: the 8px module, with the 2px pixel and its double ------------ */
  --sp-px: 2px; --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-6: 24px;
  --sp-8: 32px; --sp-10: 40px; --sp-12: 48px; --sp-16: 64px; --sp-20: 80px;
  --target: 44px;       /* the smallest a thing to press may be */
  --target-row: 48px;   /* a row to press: a field, a list's link, a menu's line */
  --vh-box: 1px;        /* a box a screen reader reads and nobody sees (.vh, and a part's own at some widths) */
  --page-max: 1440px;   /* the widest the page grows, before its gutters */
  --gut: 16px;          /* the page's side gutter: 16, 32 from md, 48 from xl (below) */
  --deck-h: 50px;       /* the sticky deck: 48 and its 2px line on a phone, 70 and 2 from deck width */

  /* ---- lines ----------------------------------------------------------------- */
  --line-w: 2px; --line-w-thick: 4px;
  --line: var(--line-w) solid var(--ink);
  --line-thick: var(--line-w-thick) solid var(--ink);

  /* ---- drops, rings and bevels (box-shadow lists) ----------------------------- */
  --drop-1: 2px 2px 0 var(--ink); --drop-2: 4px 4px 0 var(--ink); --drop-3: 6px 6px 0 var(--ink); --drop-4: 8px 8px 0 var(--ink);
  --drop-none: 0 0 0 var(--ink);   /* a drop pressed flat, so a transition has something to run between */
  --ring: 0 0 0 2px var(--ink);
  --bevel-silver: inset 2px 2px 0 var(--silver-hi), inset -2px -2px 0 var(--silver-lo);
  --bevel-silver-in: inset 2px 2px 0 var(--silver-lo), inset -2px -2px 0 var(--silver-hi);
  --bevel-yellow: inset 2px 2px 0 var(--yellow-hi), inset -2px -2px 0 var(--yellow-lo);
  --bevel-sage: inset 0 2px 0 var(--sage-hi), inset 0 -2px 0 var(--sage-lo);
  --bevel-gun: inset 2px 0 0 var(--gun-hi), inset -2px 0 0 var(--gun-lo);

  /* ---- the house's papers: a panel, and a lighter card (site/ui/parts/panel).
     Everything printed on panel paper uses these (the phone menu's sheet, a
     recap's title block on a phone, a picture's frame), so the look is one
     edit here. -------------------------------------------------------------- */
  --panel-fill: var(--paper); --panel-line: var(--line-thick); --panel-drop: var(--drop-4);
  --card-fill: var(--cream); --card-line: var(--line); --card-drop: var(--drop-2);

  /* ---- motion ------------------------------------------------------------------- */
  --press: .06s linear;   /* a key or button going down and coming up */
  --vt-fade: .16s;        /* page to page: the root crossfades in four steps */
  --lift: -2px;           /* how far a pressable thing rises under the pointer */

  /* ---- the dither tiles: ink on clear, one art pixel drawn as 2px, made as the
     prototype's tools/lib.mjs makes them (byte for byte). Draw them pixelated. ---- */
  --tile-d50: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAEUlEQVR42mOQl5f/zwADIA4AFeoCuf9S0GgAAAAASUVORK5CYII=");
  --tile-d50-size: 4px 4px;          /* a 50% checker: the band across a section's head */
  --tile-dots: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAABCAYAAAD0In+KAAAAD0lEQVR42mOQl5f/zwAEAAePAV2H7v1mAAAAAElFTkSuQmCC");
  --tile-dots-size: 4px 2px;         /* a dot every other pixel: the dotted rule */
  --tile-band: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAACgCAYAAAAxQC0IAAAAfElEQVR42u3YQQ6AIAxEUW7S+59SE9bSOIW2QzJujBof3x12DMLDzJ7uNeMNcWn1Jt6y37A64wJDQ5LgfiLU4N5sapjXUAP0sKjhv+BKRQ0SJEiQIEGCBAkSzggM+8m799X7/xefTc0NcYGhgU5gmD/kzWEqJ1t5DVfN5V6nCXQnQ+jBqQAAAABJRU5ErkJggg==");
  --tile-band-size: 16px 320px;      /* clear, up to a 50% screen, hold, back to clear: the stage behind the lead */
  --tile-fade: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAABACAYAAAAnBDaKAAAAdElEQVR42s3SUQpAIQhE0Xbi/ldZX0WYyUxKFUQ8issRXhGRWh4vbcgz4aX+Up83p9kZeMt5ATK4ufgURwbzEjKYJcpAXV4yJBb6/skwf8cMowIb9OYN1jQxA17QBr7gGryfJXEKyrCYYMO2BBus9GtD3oMGviRhgMTcxmMAAAAASUVORK5CYII=");
  --tile-fade-size: 16px 128px;      /* clear to solid ink: the end of the tape, above the footer */
  /* The dotted rule, the one look for every dotted line in the house (lists, the
     account row, the note under a card): a background for a 2px-tall box. */
  --rule-dots: var(--tile-dots) 0 0 / var(--tile-dots-size) repeat-x;
  /* A caret of three pixel rows pointing down: a select's, and a drawer's. Its ink is in the picture. */
  --caret: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 6 4' shape-rendering='crispEdges'%3E%3Cpath fill='%231f1f1f' d='M0 0h6v1H0zM1 1h4v1H1zM2 2h2v1H2z'/%3E%3C/svg%3E");
  --caret-size: 12px 8px;

  /* ---- layers ------------------------------------------------------------------- */
  --z-art: 1; --z-panel: 2; --z-menu: 30; --z-deck: 50; --z-skip: 60;

  /* ---- screen widths, for scripts (ui.mq); CSS uses the custom media below ---- */
  --bp-sm: 480px; --bp-deck: 641px; --bp-md: 768px; --bp-lg: 1024px; --bp-xl: 1280px; --bp-2xl: 1600px;
}
@media (min-width: 641px) { :root { --deck-h: 72px; } }
@media (min-width: 768px) { :root { --gut: 32px; } }
@media (min-width: 1280px) { :root { --gut: 48px; } }

/* ---- custom media: the names parts use in @media, written out by assemble.mjs ----
   The prototype's widths, each kept, so nothing moves in the port. */
/* a window tall enough for something to stay beside you (the shelf's card) */
/* site/ui/base.css — the page itself: the fonts, a reset, links, focus, and
   the few helpers every part may use (.vh, .wrap, .pix). Not a part: these
   are the rules every part is laid on. Values come from tokens.css. */

@font-face { font-family: 'Departure Mono'; src: url(../fonts/DepartureMono-Regular.woff2) format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
/* Stand-ins with the pixel face's own advance (7px a character at 11px), so nothing changes width when the real font arrives. */
@font-face { font-family: 'DM Menlo'; src: local('Menlo'), local('Menlo Regular'); size-adjust: 105.7%; }
@font-face { font-family: 'DM Consolas'; src: local('Consolas'); size-adjust: 115.75%; }
@font-face { font-family: 'DM Courier'; src: local('Courier New'); size-adjust: 106.04%; }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body { margin: 0; background: var(--sage); color: var(--ink); font: var(--t-body); }
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration-thickness: var(--line-w); text-underline-offset: 3px; }
button, input, select { font: inherit; color: inherit; border-radius: 0; }
button { -webkit-appearance: none; appearance: none; cursor: pointer; }
h1, h2, h3, h4, p, ul, ol, figure, blockquote, dl, dd { margin: 0; padding: 0; }
ul, ol { list-style: none; }
:focus-visible { outline: var(--line-w-thick) solid var(--ink); outline-offset: var(--sp-1); }
::selection { background: var(--yellow); color: var(--ink); }
[hidden] { display: none !important; }

/* Read by a screen reader, not seen. */
.vh { position: absolute !important; width: var(--vh-box); height: var(--vh-box); overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
/* The page's width, with its gutter. */
.wrap { width: 100%; max-width: calc(var(--page-max) + 2 * var(--gut)); margin-inline: auto; padding-inline: var(--gut); }
/* A machine label: the pixel face, in capitals. */
.pix { font: var(--t-label); text-transform: uppercase; letter-spacing: 0; }

.skip { position: absolute; left: var(--sp-4); top: -64px; z-index: var(--z-skip); background: var(--yellow); border: var(--line-thick); padding: var(--sp-2) var(--sp-4); font-weight: 700; text-decoration: none; }
.skip:focus { top: var(--sp-2); }

/* The deck is sticky. Everything the page can scroll to, or a keyboard can land
   on, keeps clear of it with its own margin. (Not scroll-padding on html:
   Chrome then treats the deck's own keys as hidden under it and moves the page
   when one takes focus.) */
main [id], main a, main button, main input, main select, main summary, main [tabindex] { scroll-margin-top: calc(var(--deck-h) + var(--sp-4)); }

/* Asked for less motion: nothing animates, nothing glides, the page is complete. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}

/* Page to page, as The Broadcast has it: the root crossfades in four steps,
   the deck is named (in its part) so it stays put, and the lead's headline is
   named so it travels into the recap's title. Nothing else moves. */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--vt-fade); animation-timing-function: steps(4, end); }
::view-transition-group(deck) { animation: none; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
  @view-transition { navigation: none; }
}


/* ---- stat ---- */
/* Stat tiles. Settings first: change these to change every tile on the site. */
.st-row {
  --st-gap: var(--sp-4);
  --st-pad: var(--sp-3) var(--sp-4) 14px;
  --st-value-size: 22px; --st-value-line: 24px;
  --st-label-size: 14px; --st-label-line: 20px;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--st-gap);
}
.st-tile { min-width: 0; background: var(--cream); border: var(--line); padding: var(--st-pad); }
.st-value { display: block; font: 400 var(--st-value-size)/var(--st-value-line) var(--pix); overflow-wrap: anywhere; }
.st-label { display: block; margin-top: var(--sp-1); font: 600 var(--st-label-size)/var(--st-label-line) var(--sans); color: var(--muted); }

/* Home's band of numbers under the lead: only its room above. */
/* It stands in front of a hero's robot (the archive), as the stage does. */
.st-band { --st-band-top: var(--sp-10); position: relative; z-index: var(--z-panel); padding-top: var(--st-band-top); }

/* The widths only change the settings. */
@media (max-width: 359px) { .st-row { --st-gap: var(--sp-2); --st-pad: 10px var(--sp-2) var(--sp-3); } }
@media (min-width: 768px) {
  .st-row { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .st-band { --st-band-top: 56px; }
}
@media (min-width: 1024px) {
  .st-row { --st-pad: var(--sp-4) var(--sp-5) 18px; --st-value-size: 33px; --st-value-line: 32px; }
  .st-row.st-in-column { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1600px) { .st-row { --st-value-size: 44px; --st-value-line: 48px; --st-label-size: 16px; } }


/* ---- icon ---- */
/* Icons. A picture never sits on a text baseline or shrinks in a row of
   controls; its size is in its markup (2px a pixel), so nothing here needs one. */
.ic-pixel, .ic-x { display: block; flex: none; }
.ic-x { fill: currentColor; }


/* ---- press ---- */
/* Press: what every pressable thing in the house does, written once (the
   prototype wrote it eight times: buttons, the deck's keys, REC, both play
   keys, a pill, a host's face, a row, a quote). It stands on a hard drop;
   under the pointer it rises by --lift and the drop grows by as much; pressed,
   it sinks and the drop shrinks. The place to press does not move with it (see
   below). Settings first. */
.pr-lift {
  --pr-drop: var(--sp-1);                           /* at rest: the house's 4px drop */
  --pr-up: calc(var(--pr-drop) - var(--lift));      /* under the pointer: 6px */
  --pr-down: calc(var(--pr-drop) + var(--lift));    /* pressed: 2px */
  --pr-rise: var(--lift);                           /* moved up and left under the pointer */
  --pr-sink: calc(-1 * var(--lift));                /* moved down and right while pressed */
  --pr-at: 0px;                                     /* how far it stands from where it rests, state by state */
  --pr-reach: calc(-2 * var(--lift));               /* its place to press, past its inner edge: its line and a lift */
  --pr-bevel: 0 0 0 0 transparent;                  /* a key's bevel, inside its edge (none here) */
  --pr-bevel-in: var(--pr-bevel);                   /* the bevel while pressed in */
  box-shadow: var(--pr-bevel), var(--pr-drop) var(--pr-drop) 0 var(--ink);
  transition: transform var(--press), box-shadow var(--press);
}
.pr-lift:hover { --pr-at: var(--pr-rise); transform: translate(var(--pr-at), var(--pr-at)); box-shadow: var(--pr-bevel), var(--pr-up) var(--pr-up) 0 var(--ink); }
.pr-lift:active { --pr-at: var(--pr-sink); transform: translate(var(--pr-at), var(--pr-at)); box-shadow: var(--pr-bevel-in), var(--pr-down) var(--pr-down) 0 var(--ink); }
/* The place to press stays put. A thing that rises and sinks would carry it along, out from under a pointer
   that has not moved: on its last pixels a press went down on the thing and came up beside it, which is no
   press at all (one press in eight on a play key, measured), and at its far edge it rose away from the pointer
   and fell back, over and over. So while a link or a button is pointed at or pressed, its place to press is
   held where the thing rests: moved back by as much as the thing has moved, in step with it, and wider all
   round by the lift, so wherever the thing shows, a press on it counts. It lies under the thing's own words
   and pictures, which stay its own. (A row that holds a link holds its link's place still itself: week.) */
a.pr-lift:hover::before, a.pr-lift:active::before, button.pr-lift:hover::before, button.pr-lift:active::before {
  content: ''; position: absolute; z-index: -1; inset: calc(-1 * var(--pr-reach));
  transform: translate(calc(-1 * var(--pr-at)), calc(-1 * var(--pr-at))); transition: transform var(--press);
}
/* A thing that cannot be pressed stays where it is. */
.pr-lift:disabled, .pr-lift[aria-disabled="true"] { --pr-at: 0px; transform: none; box-shadow: var(--pr-bevel), var(--pr-drop) var(--pr-drop) 0 var(--ink); cursor: default; }
a.pr-lift[aria-disabled="true"]::before, button.pr-lift:disabled::before, button.pr-lift[aria-disabled="true"]::before { content: none; }
/* Held all the way down while something happens elsewhere ("Taking you to X…"). */
.pr-lift[data-state~="held"] { --pr-at: var(--pr-drop); transform: translate(var(--pr-at), var(--pr-at)); box-shadow: var(--pr-bevel-in), 0 0 0 var(--ink); cursor: progress; }

/* The silver hardware key (The Deck's keys, REC, the play keys): a cap with
   an ink line; lit (cued or playing) it turns the spot yellow. */
.pr-key { background: var(--silver); border: var(--line); color: var(--ink); }
.pr-key[data-state~="lit"] { background: var(--yellow); }
.pr-key:disabled, .pr-key[aria-disabled="true"] { color: var(--silver-lo); }
/* Its bevel: light above and to the left, shade below and to the right; pressed in, the other way round. */
.pr-bevel { --pr-bevel: var(--bevel-silver); --pr-bevel-in: var(--bevel-silver-in); }
.pr-bevel[data-state~="lit"] { --pr-bevel: var(--bevel-yellow); --pr-bevel-in: var(--bevel-yellow); }

/* The small drop of the deck's slim row on a phone; the house's drop from the deck's width. */
.pr-sm { --pr-drop: var(--sp-px); }
@media (min-width: 641px) { .pr-sm { --pr-drop: var(--sp-1); } }
/* Resting flat on the page (a pill that is a link): it lifts onto a drop under the pointer, and stays lifted while pressed. */
.pr-flat { --pr-drop: 0px; --pr-up: var(--sp-1); --pr-down: var(--pr-up); --pr-sink: var(--pr-rise); }
/* A flat thing with no line of its own (a row of This week): lifted or pressed, the house ring is its edge. */
.pr-ring:hover, .pr-ring:active { --pr-bevel: var(--ring); --pr-bevel-in: var(--ring); }
/* A picture inside a link (a host's face in the grid): pointing anywhere on the link lifts it, as pointing at it does. */
a:hover .pr-follow { transform: translate(var(--pr-rise), var(--pr-rise)); box-shadow: var(--pr-bevel), var(--pr-up) var(--pr-up) 0 var(--ink); }

@media print { .pr-lift { box-shadow: none; } }


/* ---- button ---- */
/* House buttons: cream, go (the spot yellow) and ink, in two sizes, and the
   button that reads as a link. A button stands on the house drop and lifts
   and presses: that is the press part's, which the markup always adds
   (button.mjs). Settings first. */
.bt-button {
  --bt-h: var(--target);
  --bt-pad: var(--sp-4);
  --bt-gap: var(--sp-2);
  --bt-big-h: 56px;
  --bt-big-pad: var(--sp-6);
  --bt-big-size: 17px;
  --bt-line: 1.2;               /* a label too long for its row wraps (one line otherwise, centred as ever) */
  display: inline-flex; align-items: center; justify-content: center; gap: var(--bt-gap);
  max-width: 100%; min-height: var(--bt-h); padding: 0 var(--bt-pad);
  border: var(--line); background: var(--cream); color: var(--ink);
  font: var(--t-key); line-height: var(--bt-line); text-align: center; text-decoration: none;
}
.bt-go { background: var(--yellow); }
.bt-ink { background: var(--ink); color: var(--cream); }
.bt-big { min-height: var(--bt-big-h); padding: 0 var(--bt-big-pad); font-size: var(--bt-big-size); border-width: var(--line-w-thick); }

/* A button that reads as a link: Show everything, Sign out. Its 44px is in its padding. */
.bt-link {
  --bt-link-pad: var(--sp-3);
  --bt-link-font: 700 14px/20px var(--sans);
  --bt-link-offset: 3px;
  background: none; border: 0; padding: var(--bt-link-pad) 0; color: var(--ink);
  font: var(--bt-link-font); text-decoration: underline; text-decoration-thickness: var(--line-w); text-underline-offset: var(--bt-link-offset);
}


/* ---- pill ---- */
/* Small labels. Pills: a fact in a bordered box (who hosted, when, how long),
   coloured by the kind of fact; a pill that is a link lifts (press). Tags: the
   ink chip in the pixel face (Rewind, For hosts, YOUR NUMBERS). Chips: a
   subject on a card. Settings first. */
.pi-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
/* A long row on a phone: the first few, then one line that shows them all. With scripts off, and from
   641px, every pill shows. */
.pi-more { display: none; }
@media (max-width: 640px) {
  .js .pi-fold:not([data-state~="open"]) > .pi-rest { display: none; }
  .js .pi-fold:not([data-state~="open"]) > .pi-more { display: block; flex-basis: 100%; padding-top: var(--sp-2); }
}
.pi-pill {
  --pi-h: 32px;
  --pi-pad: var(--sp-3);
  --pi-font: 700 13px/16px var(--sans);
  --pi-track: .02em;
  --pi-face: 24px;
  display: inline-flex; align-items: center; gap: var(--sp-2); min-height: var(--pi-h); padding: 0 var(--pi-pad);
  max-width: 100%; overflow-wrap: anywhere;   /* words too long for the row (an @handle in a narrow column) wrap inside the pill, never push the page sideways */
  border: var(--line); background: var(--cream); color: var(--ink);
  font: var(--pi-font); text-transform: uppercase; letter-spacing: var(--pi-track); text-decoration: none;
}
a.pi-pill { min-height: var(--target); }
.pi-who { background: var(--tan); }
.pi-when { background: var(--cream); }
.pi-len { background: var(--silver); }
.pi-sub { background: var(--leaf); }
.pi-parts { background: var(--paper); }
.pi-go { background: var(--yellow); }
/* the host's own face, in colour, at the pill's start */
.pi-face { width: var(--pi-face); height: var(--pi-face); border: var(--line); margin-left: calc(-1 * var(--sp-1)); flex: none; }
/* words a phone does without ("hosted by", "aired") */
.pi-wide { display: none; }
@media (min-width: 768px) { .pi-wide { display: inline; } }
/* A row of even pills (a recap's title block): each as tall as the tallest, and on a phone a
   little tighter, so the air time and the length share a line from 360px. */
.pi-even > li { display: flex; }
@media (max-width: 767px) { .pi-even .pi-pill { --pi-pad: 10px; } }

.pi-tag {
  --pi-tag-pad: var(--sp-1) var(--sp-2);
  --pi-tag-lift: 2px;
  display: inline-block; padding: var(--pi-tag-pad); vertical-align: var(--pi-tag-lift);
  background: var(--ink); color: var(--cream); font: var(--t-label); text-transform: uppercase;
}
.pi-tag-go { background: var(--yellow); color: var(--ink); box-shadow: inset 0 0 0 var(--line-w) var(--ink); }
.pi-chip {
  --pi-chip-pad: var(--sp-px) 6px;
  --pi-chip-font: 700 11px/16px var(--sans);
  display: inline-block; padding: var(--pi-chip-pad); border: var(--line); background: var(--white); font: var(--pi-chip-font);
}


/* ---- field ---- */
/* Form fields: a label in the pixel face over a white box with an ink line.
   A select draws the house caret; focused, a box takes a 4px ring and a
   yellow drop. Settings first. */
.fd-field { display: grid; gap: var(--sp-1); min-width: 0; }
.fd-label { font: var(--t-label); text-transform: uppercase; }
.fd-input, .fd-select {
  --fd-h: var(--target-row);
  --fd-pad: var(--sp-3);
  --fd-font: 500 16px/1 var(--sans);
  --fd-placeholder: #6b6557;
  --fd-caret-room: 40px;
  --fd-caret-at: 14px;
  --fd-stamp: .28s steps(4, end);
  width: 100%; min-width: 0; height: var(--fd-h); padding: 0 var(--fd-pad);
  background: var(--white); border: var(--line); color: var(--ink); font: var(--fd-font);
}
.fd-input::placeholder { color: var(--fd-placeholder); opacity: 1; }
.fd-input:focus-visible, .fd-select:focus-visible { outline: var(--line-w-thick) solid var(--ink); outline-offset: 0; box-shadow: var(--sp-1) var(--sp-1) 0 var(--yellow); }
.fd-select {
  -webkit-appearance: none; appearance: none; padding-right: var(--fd-caret-room);
  font-weight: 700; cursor: pointer; text-overflow: ellipsis;
  background: var(--white) var(--caret) no-repeat right var(--fd-caret-at) center / var(--caret-size);
}
/* a choice taken: the box is stamped once (a script adds the word and takes it away) */
.fd-select[data-state~="stamped"] { animation: fd-stamp var(--fd-stamp); }
@keyframes fd-stamp {
  0% { transform: translate(0, 0); background-color: var(--white); }
  40% { transform: translate(2px, 2px); background-color: var(--yellow); }
  100% { transform: translate(0, 0); background-color: var(--white); }
}


/* ---- dropdown ---- */
/* A list that opens under a box: the search panel's subject and host, and the
   subscribe page's hosts. The box is a button with the field part's select
   look; the list stands under it, over what follows, scrolling inside itself,
   never wider than its box (so it can never push a page sideways). A row is a
   choice: a small face, the words (a name over its @handle), a tally at the
   right; rows part on the house's dotted rule, the one pointed at is white,
   the chosen one the spot yellow. Until the script takes over (data-state
   "on") the plain select stands in the button's place, the same size.
   Settings first: on the box and on the list, since a list may stand under
   another part's box (the picker's) with no dropdown around it. */
.dd-drop, .dd-panel {
  --dd-panel-max: 320px;
  --dd-face: 24px;
}
.dd-drop { position: relative; min-width: 0; }
.dd-trigger { display: none; align-items: center; text-align: left; }
.dd-drop[data-state~="on"] .dd-trigger { display: flex; }
.dd-drop[data-state~="on"] .dd-native { display: none; }
.dd-trigger[aria-expanded="true"] { outline: var(--line-w-thick) solid var(--ink); outline-offset: 0; box-shadow: var(--sp-1) var(--sp-1) 0 var(--yellow); }
.dd-cur { display: flex; align-items: center; gap: var(--sp-2); min-width: 0; overflow: hidden; white-space: nowrap; }
.dd-cur .dd-id { flex-direction: row; align-items: baseline; gap: var(--sp-2); }

.dd-panel {
  position: absolute; z-index: var(--z-menu); left: 0; right: 0; top: calc(100% + var(--sp-1));
  max-height: var(--dd-panel-max); overflow-y: auto; overscroll-behavior: contain;
  background: var(--paper); border: var(--line); box-shadow: var(--drop-2);
}
.dd-opt {
  display: flex; align-items: center; gap: var(--sp-3); min-height: var(--target); padding: var(--sp-1) var(--sp-3);
  background-color: var(--paper); font: var(--t-ui); cursor: pointer;
}
.dd-opt + .dd-opt { background-image: var(--tile-dots); background-size: var(--tile-dots-size); background-repeat: repeat-x; image-rendering: pixelated; }
.dd-opt:hover, .dd-opt:focus-visible { background-color: var(--white); }
.dd-opt:focus-visible { outline-offset: calc(-1 * var(--line-w-thick)); }
.dd-opt[aria-selected="true"] { background-color: var(--yellow); }
.dd-lab { display: flex; align-items: center; gap: var(--sp-2); flex: 1; min-width: 0; }
.dd-face { flex: none; width: var(--dd-face); height: var(--dd-face); border: var(--line); object-fit: cover; image-rendering: auto; }
.dd-id { display: flex; flex-direction: column; min-width: 0; }
.dd-name, .dd-hand, .dd-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* a name leads and its @handle is understated; a row with no name keeps its @handle at full strength */
.dd-name + .dd-hand { color: var(--muted); font: var(--t-label); }
.dd-n { flex: none; margin-left: auto; color: var(--muted); font: var(--t-label); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* on the spot yellow the understated words are ink: muted on yellow is too faint to read */
.dd-opt[aria-selected="true"] .dd-hand, .dd-opt[aria-selected="true"] .dd-n { color: var(--ink); }
@media print { .dd-panel { display: none !important; } }


/* ---- timecode ---- */
/* A time code: a moment's place in the room, in the pixel face. One part for
   the prototype's three looks. The house's (tc-chip alone: paper with an ink
   line, the front page's quote card); The Deck's (tc-ink: an ink chip, a
   recap's highlights, quotes and the rail); and the words alone (tc-plain:
   inside something that is itself a link). Settings first. */
.tc-chip {
  --tc-pad: 0 var(--sp-1);
  --tc-ink-pad: var(--sp-px) 6px;
  --tc-reach: -14px -8px;          /* a link's place to press, beyond the chip: 44px tall */
  --tc-ink-reach: -12px -6px;
  --tc-flash: 1.4s steps(2, jump-none) 2;
  display: inline-block; padding: var(--tc-pad);
  background: var(--paper); color: var(--ink); border: var(--line);
  font: var(--t-label); text-decoration: none; white-space: nowrap;
}
a.tc-chip { position: relative; }
a.tc-chip::after { content: ''; position: absolute; inset: var(--tc-reach); }
a.tc-chip:hover { background: var(--yellow); }
.tc-ink { background: var(--ink); color: var(--cream); border: 0; padding: var(--tc-ink-pad); }
a.tc-ink::after { inset: var(--tc-ink-reach); }
a.tc-ink:hover { color: var(--ink); }   /* yellow under the pointer, like the house's, with ink words (the prototype left them cream on yellow) */
.tc-plain { background: none; border: 0; padding: 0; }
/* The moment the deck is reading (the deck puts "cue" in the stop's data-state), and the one a link has just landed on:
   a stop that is the target, a time code that is (a stamp in a sentence carries its own id), or one a page's script
   flashes (data-state "flash": a link that lands on an id the page no longer has goes to the nearest earlier stamp). */
[data-state~="cue"] .tc-ink { background: var(--yellow); color: var(--ink); box-shadow: var(--ring); }
[data-t]:target .tc-ink, .tc-ink:target, .tc-ink[data-state~="flash"] { animation: tc-flash var(--tc-flash); }
@keyframes tc-flash { 0% { background: var(--yellow); color: var(--ink); } 100% { background: var(--ink); color: var(--cream); } }


/* ---- panel ---- */
/* The house's paper, in two weights. A panel: paper, a 4px ink line, an 8px
   drop (the lead, the search panel, the door's card, a recap's title block and
   reading panels, the shelf's label card: the prototype wrote it five times).
   A card: cream, a 2px line, a 4px drop (a quote, a recap's quote, the
   callout, the fuel note: five times again). What sits inside is the
   placing part's; the paper is this one's. Settings first. */
.pn-panel {
  --pn-pad: var(--sp-5) var(--sp-4) var(--sp-6);   /* pn-pad's: the lead's and the door card's */
  background: var(--panel-fill); border: var(--panel-line); box-shadow: var(--panel-drop);
}
.pn-card { background: var(--card-fill); border: var(--card-line); box-shadow: var(--card-drop); }
/* a card on paper rather than cream (a host page's moments) */
.pn-card.pn-paper { background: var(--paper); }
/* keeps its drop inside its column: beside another panel, in a grid, at a column's edge */
.pn-panel.pn-inset { margin-right: var(--sp-2); }
.pn-card.pn-inset { margin-right: var(--sp-1); }
/* the house's padding for a big panel, widening with the page */
.pn-pad { padding: var(--pn-pad); }
@media (min-width: 768px) { .pn-panel { --pn-pad: var(--sp-8); } }
@media (min-width: 1024px) { .pn-panel { --pn-pad: var(--sp-10); } }
@media (min-width: 1600px) { .pn-panel { --pn-pad: 56px; } }


/* ---- plate ---- */
/* A plate: a picture of the studio, framed in ink on the house drop, with the
   printer's crop marks at its corners and a caption in the pixel face. The
   bottom right has no marks: the drop is there. By daylight or at dusk on
   the reader's clock: the page puts data-sky="dusk" on <html> (or a part on a
   box of its own) and the dusk picture and words take over. Settings first. */
.pt-plate {
  --pt-mark-out: 20px;   /* how far beyond the frame the marks reach */
  --pt-mark: 12px;       /* a mark's length */
  --pt-mark-at: 16px;    /* where a mark's line sits, from the outer corner (2px off the frame) */
  --pt-cap-gap: 20px;
  --pt-m: linear-gradient(var(--ink) 0 0);
  position: relative; margin: 0; min-width: 0;
}
.pt-frame { position: relative; border: var(--panel-line); box-shadow: var(--panel-drop); background: var(--ink); }
.pt-frame::before, .pt-frame::after { content: ''; position: absolute; inset: calc(-1 * var(--pt-mark-out)); pointer-events: none; }
.pt-frame::before {
  background:
    var(--pt-m) 0 var(--pt-mark-at) / var(--pt-mark) var(--line-w) no-repeat,
    var(--pt-m) var(--pt-mark-at) 0 / var(--line-w) var(--pt-mark) no-repeat,
    var(--pt-m) 100% var(--pt-mark-at) / var(--pt-mark) var(--line-w) no-repeat,
    var(--pt-m) calc(100% - var(--pt-mark-at)) 0 / var(--line-w) var(--pt-mark) no-repeat;
}
.pt-frame::after {
  background:
    var(--pt-m) 0 calc(100% - var(--pt-mark-at)) / var(--pt-mark) var(--line-w) no-repeat,
    var(--pt-m) var(--pt-mark-at) 100% / var(--line-w) var(--pt-mark) no-repeat;
}
.pt-pic, .pt-img { display: block; }
.pt-img { object-fit: cover; }
/* A plate fills its column, the picture keeping its shape (the desk) ... */
.pt-plate:not(.pt-natural) .pt-pic, .pt-plate:not(.pt-natural) .pt-img { width: 100%; height: auto; }
/* ... or is never enlarged: the picture at the size its markup gives, the frame around it (the window,
   the tape wall). The caption takes the frame's width and never widens the plate. */
.pt-natural { width: max-content; max-width: 100%; }
.pt-natural .pt-cap { contain: inline-size; }
/* No frame: the marks stand at the corners of what the plate holds (the shelf). Smaller, at all four corners. */
.pt-bare { --pt-mark-out: 12px; --pt-mark: var(--sp-2); --pt-mark-at: var(--sp-2); --pt-cap-gap: var(--sp-3); }
.pt-bare .pt-frame { border: 0; box-shadow: none; background: none; }
.pt-bare .pt-frame::after {
  background:
    var(--pt-m) 0 calc(100% - var(--pt-mark-at)) / var(--pt-mark) var(--line-w) no-repeat,
    var(--pt-m) var(--pt-mark-at) 100% / var(--line-w) var(--pt-mark) no-repeat,
    var(--pt-m) 100% calc(100% - var(--pt-mark-at)) / var(--pt-mark) var(--line-w) no-repeat,
    var(--pt-m) calc(100% - var(--pt-mark-at)) 100% / var(--line-w) var(--pt-mark) no-repeat;
}
/* On a phone a bare plate draws no marks: the shelf there is one plank, its uprights at the window's edges. */
@media (max-width: 640px) { .pt-bare .pt-frame::before, .pt-bare .pt-frame::after { content: none; } }
.pt-cap { margin-top: var(--pt-cap-gap); display: flex; justify-content: space-between; gap: var(--sp-4); }
/* one line of caption stands at the right, whole, even past a narrow plate's left edge */
.pt-cap-end { justify-content: flex-end; white-space: nowrap; }
.pt-dusk { display: none; }
[data-sky="dusk"] .pt-day { display: none; }
[data-sky="dusk"] .pt-dusk { display: block; }


/* ---- list ---- */
/* The house list: rows on dotted rules. One part for what the prototype
   wrote as .idx (the archive's columns), .slots (This week's rows: their
   rule) and .si-pillars (the door's pillars), and for the dotted rule
   itself, which it drew five times: a part that needs one adds ls-rule (at
   its foot) or ls-rule-top. Settings first. */
.ls-list {
  --ls-inset: 0px;                 /* how far in from the row's ends the rule stops */
  --ls-row-pad: 6px;
  --ls-reach: var(--sp-2);         /* a link row's paper reaches this far past its ends under the pointer */
  --ls-bar-h: var(--sp-2);
  --ls-sub-font: 600 13px/16px var(--sans);
  --ls-bars-name: 9em; --ls-bars-n: 3.5em;
  --ls-measure: 60ch;           /* an entry's sentence */
  min-width: 0;
}
.ls-item { position: relative; }
.ls-list > .ls-item::after, .ls-rule::after, .ls-rule-top::before {
  content: ''; position: absolute; left: var(--ls-inset, 0); right: var(--ls-inset, 0); bottom: 0; height: var(--line-w);
  background: var(--rule-dots); image-rendering: pixelated; pointer-events: none;
}
.ls-rule, .ls-rule-top { position: relative; }
.ls-rule-top::before { top: 0; bottom: auto; }
/* The guide's rows: the rule stops short of the row's ends (8px, 16px from 768px). */
.ls-inset { --ls-inset: var(--sp-2); }
@media (min-width: 768px) { .ls-inset { --ls-inset: var(--sp-4); } }

/* A row that is a link: the name, a line under it, the count at the right. */
.ls-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 var(--sp-3); align-items: center;
  min-height: var(--target-row); padding: var(--ls-row-pad) 0; text-decoration: none;
}
.ls-row:hover { background: var(--paper); box-shadow: calc(-1 * var(--ls-reach)) 0 0 var(--paper), var(--ls-reach) 0 0 var(--paper); }
.ls-name { font: var(--t-h6); overflow-wrap: anywhere; }
.ls-sub { grid-column: 1; font: var(--ls-sub-font); }
.ls-n { grid-column: 2; grid-row: 1 / span 2; font: var(--t-label); }
/* Bars: each row's share, the biggest lit. */
.ls-bars .ls-row { grid-template-columns: minmax(0, var(--ls-bars-name)) minmax(0, 1fr) var(--ls-bars-n); }
.ls-bars .ls-n { grid-row: auto; grid-column: auto; text-align: right; }
.ls-bar { display: block; height: var(--ls-bar-h); min-width: var(--line-w); width: calc(var(--ls-w) * 1%); background: var(--ink); }
.ls-peak { background: var(--yellow); box-shadow: var(--ring); }

/* A list's heading: the words, and at the right its count (under the words when both will not fit: the hosts grid's on a phone). */
.ls-head {
  --ls-head-track: -.03em;
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--sp-4);
  padding-bottom: var(--sp-2); border-bottom: var(--line-thick); font: var(--t-h2); letter-spacing: var(--ls-head-track);
}
.ls-head-n { font: var(--t-label); text-transform: uppercase; letter-spacing: 0; }
.ls-more { display: inline-flex; align-items: center; min-height: var(--target-row); font-weight: 700; }
.ls-note { --ls-note-font: 500 14px/20px var(--sans); margin-top: var(--sp-4); font: var(--ls-note-font); }

/* Entries with a heading each (the door's pillars): ruled between, under a 4px line. */
.ls-between { border-top: var(--line-thick); }
.ls-between > .ls-item::after { content: none; }
.ls-between > .ls-item + .ls-item::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: var(--line-w);
  background: var(--rule-dots); image-rendering: pixelated;
}
.ls-entry { padding: var(--sp-4) 0; }
.ls-title { --ls-title-track: -.01em; display: flex; align-items: center; gap: var(--sp-3); font: var(--t-h4); letter-spacing: var(--ls-title-track); }
.ls-title > svg { color: var(--ink); }
.ls-text { margin-top: var(--sp-2); font: var(--t-body); max-width: var(--ls-measure); }
/* two across on a tablet; from 1024px the column beside the offer is narrow again */
@media (min-width: 768px) and (max-width: 1023px) {
  .ls-two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--sp-8); }
  .ls-two > .ls-item:nth-child(2)::before { content: none; }
}
@media (min-width: 1024px) { .ls-two > .ls-item:last-child { padding-bottom: 0; } }


/* ---- sec ---- */
/* A section of the house: its room above, then the heading. The heading is
   a 4px rule with a band of dither under it, the section's number and label
   in the pixel face, the big ink word, and a lead. Settings first; the widths
   only change settings. */
.sc-sec { --sc-top: 72px; padding-top: var(--sc-top); }
.sc-head {
  --sc-pad: var(--sp-6);
  --sc-band: var(--sp-2);
  --sc-h-size: 40px; --sc-h-line: 40px;
  --sc-lead-size: 17px; --sc-lead-line: 28px; --sc-lead-measure: 52ch;
  position: relative; display: grid; gap: var(--sp-2) var(--sp-8);
  border-top: var(--line-thick); padding-top: var(--sc-pad);
}
.sc-head::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: var(--sc-band);
  background: var(--tile-d50) 0 0 / var(--tile-d50-size); image-rendering: pixelated;
}
.sc-no { display: flex; gap: var(--sp-3); }
.sc-num { font-weight: 400; background: var(--ink); color: var(--cream); padding: 0 var(--sp-1); }
.sc-h { font: 700 var(--sc-h-size)/var(--sc-h-line) var(--sans); letter-spacing: var(--track-display); }
.sc-lead { font: 500 var(--sc-lead-size)/var(--sc-lead-line) var(--sans); max-width: var(--sc-lead-measure); }
.sc-aside { min-width: 0; }
@media (min-width: 768px) {
  .sc-sec { --sc-top: 96px; }
  .sc-head { --sc-h-size: 64px; --sc-h-line: 64px; --sc-lead-size: 18px; }
}
@media (min-width: 1280px) {
  .sc-sec { --sc-top: 128px; }
  .sc-head { --sc-h-size: 80px; --sc-h-line: 80px; }
}
@media (min-width: 1600px) { .sc-head { --sc-h-size: 104px; --sc-h-line: 104px; --sc-lead-size: 20px; --sc-lead-line: 32px; } }
/* A picture beside the heading from 1024px (This week's window, the archive's tape wall). */
@media (min-width: 1024px) {
  .sc-head-aside { grid-template-columns: minmax(0, 1fr) auto; align-items: end; }
  .sc-head-aside > * { grid-column: 1; }
  .sc-head-aside > .sc-aside { grid-column: 2; grid-row: 1 / span 3; }
}


/* ---- stage ---- */
/* The stage: a band of dither the first panel stands on (the lead on home,
   the card at the door). It reaches up under the hero by --sg-lift, so the
   robot rises out of the band behind the panel; the panel stands in front of
   him. Settings first. */
.sg-stage {
  --sg-lift: var(--sp-8);
  position: relative; margin-top: calc(-1 * var(--sg-lift)); padding: var(--sg-lift) 0 var(--sp-2);
  background: var(--tile-band) 0 0 / var(--tile-band-size) repeat-x; image-rendering: pixelated;
}
/* What stands on the band: in front of the robot, and drawn as pictures normally are. */
.sg-in { position: relative; z-index: var(--z-panel); image-rendering: auto; }
@media (min-width: 768px) { .sg-stage { --sg-lift: var(--sp-10); } }
@media (min-width: 1600px) { .sg-stage { --sg-lift: 56px; } }


/* ---- hero ---- */
/* The hero: the house's big ink heading, the lead under it, and the robot
   rising behind the first panel (the stage part's band and panel follow the
   hero, and the robot stands in front of the band, behind the panel). On a
   phone the lead runs the full width and the robot has a strip of his own,
   the tagline beside him. Settings first; the widths only change settings. */
.hr-hero {
  --hr-pad-top: var(--sp-6); --hr-pad-bottom: 168px;
  --hr-h-size: 40px; --hr-h-line: 40px; --hr-h-max: 9em;
  --hr-lead-gap: var(--sp-4); --hr-lead-size: 16px; --hr-lead-line: 24px; --hr-lead-max: none; --hr-lead-min: 0px;
  --hr-bot: 200px;              /* twice his drawn size on a phone, four times from 1024px */
  --hr-bot-bottom: -40px;       /* how far below the hero he stands, behind the panel */
  --hr-bot-right: 0px;
  --hr-bot-room: 216px;         /* the room he takes beside the words */
  --hr-tag-bottom: 64px;
  --hr-rise: .42s steps(6, end) .1s backwards;   /* once, as the page arrives; nothing holds the end */
  --hr-nod: .6s steps(1, end) infinite;          /* while a quote plays */
  position: relative; padding-block: var(--hr-pad-top) var(--hr-pad-bottom);
}
.hr-h { font: 700 var(--hr-h-size)/var(--hr-h-line) var(--sans); letter-spacing: var(--track-display); text-wrap: balance; max-width: var(--hr-h-max); }
.hr-lead { margin-top: var(--hr-lead-gap); font: 500 var(--hr-lead-size)/var(--hr-lead-line) var(--sans); max-width: var(--hr-lead-max); min-height: var(--hr-lead-min); }
.hr-tag { position: absolute; left: var(--gut); bottom: var(--hr-tag-bottom); max-width: calc(100% - 2 * var(--gut) - var(--hr-bot-room)); }
.hr-bot {
  position: absolute; z-index: var(--z-art); right: var(--hr-bot-right); bottom: var(--hr-bot-bottom);
  width: var(--hr-bot); height: var(--hr-bot); max-width: none; image-rendering: pixelated;
}
@media (min-width: 480px) {
  .hr-hero { --hr-pad-bottom: var(--sp-8); --hr-h-size: 56px; --hr-h-line: 56px; --hr-lead-size: 17px; --hr-lead-line: 28px; --hr-lead-max: min(36ch, calc(100% - var(--hr-bot-room))); --hr-lead-min: 152px; }
  .hr-tag { display: none; }
}
@media (min-width: 768px) { .hr-hero { --hr-pad-top: var(--sp-8); --hr-pad-bottom: var(--sp-10); --hr-h-size: 72px; --hr-h-line: 72px; --hr-lead-size: 18px; --hr-lead-min: 0px; --hr-lead-max: 44ch; } }
@media (min-width: 1024px) { .hr-hero { --hr-h-size: 80px; --hr-h-line: 80px; --hr-lead-size: 20px; --hr-lead-gap: var(--sp-6); --hr-lead-max: 40ch; --hr-bot: 400px; --hr-bot-bottom: -112px; } }
@media (min-width: 1280px) { .hr-hero { --hr-pad-top: var(--sp-6); --hr-h-size: 96px; --hr-h-line: 96px; --hr-lead-max: 44ch; --hr-bot-right: var(--sp-4); } }
@media (min-width: 1600px) { .hr-hero { --hr-pad-top: var(--sp-10); --hr-pad-bottom: 56px; --hr-h-size: 128px; --hr-h-line: 120px; --hr-lead-size: 22px; --hr-lead-line: 32px; --hr-bot-right: var(--sp-12); } }

/* The door's hero (the sign-in pages): a one-line heading with a line under
   it, the robot at three times his size from 1024px (four would stand in the
   dateline). Its settings win over the home hero's at every width. */
.hr-hero.hr-door {
  --hr-pad-bottom: 144px; --hr-h-max: none;
  --hr-lead-gap: var(--sp-3); --hr-lead-size: 17px; --hr-lead-line: 28px; --hr-lead-max: none; --hr-lead-min: 0px;
  --hr-tag-bottom: var(--sp-12); --hr-bot-bottom: -64px;
}
.hr-door .hr-h { overflow-wrap: anywhere; }
@media (min-width: 768px) { .hr-hero.hr-door { --hr-pad-top: var(--sp-8); --hr-pad-bottom: var(--sp-10); --hr-lead-size: 18px; --hr-h-max: calc(100% - var(--hr-bot-room)); --hr-lead-max: calc(100% - var(--hr-bot-room)); --hr-bot-bottom: -40px; } }
@media (min-width: 1024px) { .hr-hero.hr-door { --hr-lead-gap: var(--sp-4); --hr-lead-size: 20px; --hr-lead-line: 32px; --hr-h-max: calc(100% - 332px); --hr-lead-max: calc(100% - 332px); --hr-bot: 300px; --hr-bot-bottom: -112px; } }
@media (min-width: 1280px) { .hr-hero.hr-door { --hr-pad-top: var(--sp-6); } }
@media (min-width: 1600px) { .hr-hero.hr-door { --hr-pad-top: var(--sp-10); --hr-pad-bottom: 56px; --hr-lead-size: 22px; } }
/* The sign-in pages are short until their card is painted: their main fills the window, less the
   deck and the masthead, so the foot does not rise into view and drop away again. */
main:has(> .hr-door) { --hr-page-min: calc(100vh - 160px); min-height: var(--hr-page-min); }
/* No robot (the dashboard, whose card carries the desk): the heading and its line take the width. */
/* Over a band of numbers (the archive, a month): the robot stands on the tiles' top edge, behind them,
   not down among them, where he would show through the gaps between tiles. The band's room above is 40px. */
.hr-hero.hr-door:has(+ .st-band) { --hr-bot-bottom: calc(-1 * var(--sp-10)); }
.hr-hero.hr-door.hr-no-bot { --hr-pad-bottom: var(--sp-8); }
@media (min-width: 768px) { .hr-hero.hr-door.hr-no-bot { --hr-pad-bottom: var(--sp-10); --hr-h-max: none; --hr-lead-max: none; } }
@media (min-width: 1600px) { .hr-hero.hr-door.hr-no-bot { --hr-pad-bottom: 56px; } }

/* A door hero with something in the robot's place (/resound/'s founding pilot's badge): under the lead on a phone
   and a tablet; from 1024px a column of its own at the hero's right, beside the heading and the lead, so the hero
   is as tall as the taller of the two and nothing reaches over the dateline above or the stage below. */
.hr-aside { --hr-aside-gap: var(--sp-6); margin-top: var(--hr-aside-gap); }
@media (min-width: 1024px) {
  .hr-hero.hr-has-aside { --hr-aside-col: var(--sp-10); display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--hr-aside-col); align-items: end; }
  .hr-has-aside > .hr-h, .hr-has-aside > .hr-lead { grid-column: 1; }
  .hr-aside { grid-column: 2; grid-row: 1 / span 2; align-self: center; margin-top: 0; }
}

/* He rises once behind the panel as the page arrives (the page says it runs
   scripts: html.js), and nods while a quote plays (the player says so:
   html[data-audio="playing"]). Reduced motion stops both (base.css). */
@keyframes hr-rise { from { transform: translateY(48px); } to { transform: translateY(0); } }
@keyframes hr-nod { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(2px); } }
.js .hr-bot { animation: hr-rise var(--hr-rise); }
[data-audio="playing"] .hr-bot { animation: hr-nod var(--hr-nod); }
@media print { .hr-bot { display: none !important; } }


/* ---- mast ---- */
/* The masthead: the robot's face and the Re:Cap chip, the main links, the
   phone's menu, Host sign-in and Get recaps. On a phone the two buttons sit
   under the brand, both on the first screen with nothing to open. The
   buttons are the button part's; here only where they stand. Settings first. */
.ms-mast {
  --ms-pad-top: var(--sp-4); --ms-pad-bottom: var(--sp-3);
  --ms-gap: var(--sp-2); --ms-brand-gap: var(--sp-2);
  --ms-face: var(--target);
  --ms-chip-h: var(--target); --ms-chip-pad: 10px; --ms-chip-size: 22px; --ms-chip-line: 36px; --ms-chip-track: -.01em;
  --ms-btn-pad: var(--sp-3);
  --ms-bars-w: 12px; --ms-bars-h: 10px;   /* the menu's three bars, 2px each, 4px apart */
  --ms-bar-2: var(--sp-1); --ms-bar-3: var(--sp-2);
  --ms-signin-line: 39px;          /* one line of words in the sign-in button, where its flex box set them */
  --ms-signin-nudge: .5px;
  --ms-x-drop: -1.5px;
  --ms-x-room: 22px;               /* X's mark and the gap after it: 14px and 8px */
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--ms-gap);
  padding-block: var(--ms-pad-top) var(--ms-pad-bottom);
}
.ms-mast a, .ms-mast summary { scroll-margin-top: calc(var(--deck-h) + var(--sp-4)); }
.ms-brand { display: flex; align-items: center; gap: var(--ms-brand-gap); flex: none; text-decoration: none; }
.ms-face { width: var(--ms-face); height: var(--ms-face); border: var(--line-thick); image-rendering: pixelated; }
.ms-chip {
  display: block; height: var(--ms-chip-h); padding: 0 var(--ms-chip-pad); background: var(--cream); border: var(--line-thick);
  font: 700 var(--ms-chip-size)/var(--ms-chip-line) var(--sans); letter-spacing: var(--ms-chip-track); white-space: nowrap;
}
.ms-nav { display: contents; }
.ms-links { display: none; align-items: center; gap: var(--sp-1); }
.ms-link { display: flex; align-items: center; min-height: var(--target); padding: 0 var(--sp-3); font: var(--t-key); text-decoration: none; }
.ms-link:hover, .ms-link[aria-current] { text-decoration: underline; }
.ms-menu { grid-column: 2; grid-row: 1; justify-self: end; position: static; }
.ms-menu-btn {
  display: flex; align-items: center; justify-content: center; gap: var(--sp-2); min-height: var(--target); min-width: var(--target); padding: 0 var(--sp-3);
  border: var(--line); background: var(--cream); font: var(--t-key); list-style: none; cursor: pointer; user-select: none;
}
.ms-menu-btn::-webkit-details-marker { display: none; }
.ms-menu-btn::before {
  content: ''; width: var(--ms-bars-w); height: var(--ms-bars-h); flex: none;
  background: linear-gradient(var(--ink) 0 0) 0 0 / 100% var(--line-w) no-repeat, linear-gradient(var(--ink) 0 0) 0 var(--ms-bar-2) / 100% var(--line-w) no-repeat, linear-gradient(var(--ink) 0 0) 0 var(--ms-bar-3) / 100% var(--line-w) no-repeat;
}
.ms-menu[open] > .ms-menu-btn { background: var(--yellow); }
.ms-sheet {
  position: absolute; left: var(--gut); right: var(--gut); top: calc(100% - var(--sp-2)); z-index: var(--z-menu);
  display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--sp-2); padding: var(--sp-2);
  background: var(--panel-fill); border: var(--panel-line); box-shadow: var(--panel-drop);
}
.ms-sheet-link { display: flex; align-items: center; min-height: var(--target-row); padding: 0 var(--sp-2); font-weight: 700; text-decoration: none; border-bottom: var(--line-w) solid var(--tan); }
.ms-sheet-link:hover { background: var(--yellow); }
.ms-close { grid-column: 1 / -1; justify-self: end; min-height: var(--target); margin-top: var(--sp-2); padding: 0 var(--sp-4); background: var(--cream); border: var(--line); font: var(--t-key); }
.ms-signin, .ms-get { padding: 0 var(--ms-btn-pad); }
.ms-signin { grid-column: 1; grid-row: 2; }
.ms-get { grid-column: 2; grid-row: 2; flex: none; white-space: nowrap; }   /* never shrinks: a long @handle is cut inside the sign-in button instead */
/* The sign-in button reads "@handle", "Admin" or "My numbers" once a host has signed in. It is one line in a
   block, and a long handle is cut with an ellipsis and never pushes the row out of the window. The cut is the
   words' own (a span as wide as the button less X's mark), not the button's: a button that cut its overflow
   also cut away the place to press that press holds still past its edges, and a press on its last pixels
   was lost. The span is a line box of the button's own height set at its top, so the words stand where
   they stood. */
.ms-signin { display: block; min-width: 0; white-space: nowrap; padding-top: var(--ms-signin-nudge); line-height: var(--ms-signin-line); text-align: center; }
.ms-signin .ic-x { display: inline-block; vertical-align: var(--ms-x-drop); margin-right: var(--sp-2); }
.ms-signin .bt-words { display: inline-block; max-width: calc(100% - var(--ms-x-room)); overflow: hidden; text-overflow: ellipsis; vertical-align: top; }

@media (max-width: 479px) {
  .ms-menu-t { position: absolute; width: var(--vh-box); height: var(--vh-box); overflow: hidden; clip-path: inset(50%); }
  .ms-menu-btn { padding: 0; }
}
@media (min-width: 480px) { .ms-mast { --ms-chip-pad: var(--sp-3); --ms-chip-size: 24px; --ms-btn-pad: var(--sp-4); } }
@media (min-width: 600px) {
  .ms-mast { display: flex; justify-content: space-between; gap: var(--sp-4); --ms-pad-bottom: var(--sp-4); }
  .ms-nav { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; }
}
@media (min-width: 1024px) {
  .ms-links { display: flex; }
  .ms-menu { display: none; }
}
@media (min-width: 1600px) {
  .ms-mast { --ms-pad-top: var(--sp-6); --ms-pad-bottom: var(--sp-6); --ms-face: 80px; --ms-chip-h: 80px; --ms-chip-pad: var(--sp-6); --ms-chip-size: 44px; --ms-chip-line: 72px; --ms-chip-track: -.02em; --ms-brand-gap: var(--sp-4); }
}
@media print { .ms-menu { display: none !important; } }


/* ---- dateline ---- */
/* The dateline: a double rule (4px over, 2px under) with today's date, the
   house's line and the watch list in the pixel face. Three fixed places, so
   the date can change length and nothing beside it moves. Settings first. */
.dl-in {
  --dl-h: 32px;
  --dl-reach: var(--sp-2);   /* the link's 44px reaches past the rules this far */
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--sp-4); min-height: var(--dl-h);
  border-top: var(--line-thick); border-bottom: var(--line);
}
.dl-in > * { white-space: nowrap; }
.dl-in > :last-child { grid-column: 3; justify-self: end; }
.dl-mid { display: none; }
.dl-link { display: inline-flex; align-items: center; min-height: var(--target); margin-block: calc(-1 * var(--dl-reach)); text-decoration: none; scroll-margin-top: calc(var(--deck-h) + var(--sp-4)); }
.dl-link:hover { text-decoration: underline; }
@media (min-width: 768px) { .dl-mid { display: block; } }


/* ---- foot ---- */
/* The foot of every page: the end of the tape. Above it, on the sage, the
   on-air strip (one bar an hour, the busiest lit); then the sage dithers into
   ink and the footer: the colophon, the site's links, the version and the
   house's colours. Settings first; the widths only change settings. */
.ft-foot {
  --ft-top: 336px;          /* the room above, for the strip and the fade */
  --ft-fade-h: 128px;
  --ft-rule: #3d3d3d;       /* the links' rules on ink */
  --ft-ver-pad: 6px;
  --ft-measure: 60ch;
  position: relative; margin-top: var(--ft-top); padding-block: 0 var(--sp-12);
  background: var(--ink); color: var(--cream);
}
.ft-foot::before {
  content: ''; position: absolute; left: 0; right: 0; bottom: 100%; height: var(--ft-fade-h);
  background: var(--tile-fade) 0 0 / var(--tile-fade-size) repeat-x; image-rendering: pixelated;
}
.ft-foot :focus-visible { outline-color: var(--cream); }
.ft-eq { position: absolute; left: 0; right: 0; bottom: calc(100% + var(--ft-fade-h)); pointer-events: none; }
.ft-eq-cap { margin-bottom: var(--sp-2); color: var(--ink); }
.ft-bars {
  --ft-bars-h: 90px;
  --ft-bar-w: var(--sp-px); --ft-bar-gap: var(--sp-px);
  --ft-step: 16px;          /* one room on air (or a fifth of a quote's loudness) */
  --ft-peak-ring: calc(-1 * var(--line-w)) 0 0 var(--ink), var(--line-w) 0 0 var(--ink), 0 calc(-1 * var(--line-w)) 0 var(--ink), calc(-1 * var(--line-w)) calc(-1 * var(--line-w)) 0 var(--ink), var(--line-w) calc(-1 * var(--line-w)) 0 var(--ink);
  display: flex; align-items: flex-end; gap: var(--ft-bar-gap); height: var(--ft-bars-h); overflow: hidden;
  padding-inline: var(--sp-px); border-bottom: var(--line-thick);
}
.ft-bars-end { justify-content: flex-end; }
.ft-bar { flex: none; width: var(--ft-bar-w); height: calc(var(--ft-v) * var(--ft-step) + var(--sp-px)); background: var(--ink); }
.ft-peak { background: var(--yellow); box-shadow: var(--ft-peak-ring); }
.ft-in { display: grid; gap: var(--sp-10); padding-top: var(--sp-12); }
.ft-colophon { display: grid; gap: var(--sp-2); max-width: var(--ft-measure); font: var(--t-voice); }
.ft-nav { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--sp-4); }
.ft-link { display: flex; align-items: center; min-height: var(--target-row); font-weight: 700; text-decoration: none; border-bottom: var(--line-w) solid var(--ft-rule); }
.ft-link:hover { color: var(--yellow); }
.ft-end { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-4); padding-top: var(--sp-4); border-top: var(--line-w-thick) solid var(--cream); }
.ft-ver { display: inline-flex; align-items: center; min-height: var(--target); }
.ft-ver-n { margin-left: var(--sp-2); padding: 0 var(--ft-ver-pad); border: var(--line-w) solid var(--cream); }
.ft-swatches { display: flex; }
.ft-sw { width: var(--sp-4); height: var(--sp-4); background: var(--ft-c); }
@media (min-width: 768px) {
  .ft-bars { --ft-bar-w: 5px; }
  .ft-nav { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .ft-bars { --ft-bar-w: 7px; --ft-bar-gap: 3px; }
  .ft-in { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--sp-16); }
  .ft-end { grid-column: 1 / -1; }
}
@media (min-width: 1280px) { .ft-bars { --ft-bar-w: var(--sp-2); --ft-bar-gap: var(--sp-1); } }
@media (min-width: 1600px) { .ft-bars { --ft-bar-w: 11px; } }
@media print { .ft-eq { display: none !important; } }


/* ---- player ---- */
/* The quote player: a play key, the clip's loudness as bars you can press,
   drag or step with the arrow keys (a slider), and the time. Two looks. The
   house's (the front page's quote card): a flat silver key, short bars on an
   ink line, "0:12/0:38". The Deck's (a recap's quote cards): a bevelled key,
   bars filling the card's foot, the time alone. The key lifts and presses
   (press). With scripts off, the plain audio control under it plays the clip.
   Settings first. */
.pl-player {
  --pl-gap: var(--sp-3);
  --pl-gap-row: var(--sp-2);
  --pl-key: var(--target);
  --pl-wave-h: 32px;
  --pl-bar-w: var(--sp-px);
  --pl-bar-gap: var(--sp-px);
  --pl-bar-max: 28px;            /* the loudest bar, in the house's look; bars step by 2px */
  --pl-reach: var(--sp-2);       /* the wave's place to press reaches past it: 48px tall */
  --pl-on-edge: inset 0 0 0 1px var(--ink);
  --pl-audio-h: 40px;
  --pl-time-w: 28px;
  --pl-spin: 14px;               /* the spinner on the key while a clip is on its way */
  --pl-spin-turn: .8s;           /* one turn of it, in eight steps */
  --pl-spin-after: .4s;          /* how long a clip may take before it shows */
  margin-top: var(--sp-3); display: flex; flex-wrap: wrap; align-items: center; gap: var(--pl-gap-row) var(--pl-gap);
}
.pl-play { display: grid; place-items: center; flex: none; width: var(--pl-key); height: var(--pl-key); padding: 0; }
.pl-play .ic-pause { display: none; }
.pl-play[data-state~="playing"] .ic-play { display: none; }
.pl-play[data-state~="playing"] .ic-pause { display: block; }
/* On its way: asked to play and nothing to hear yet. After a moment the key's sign gives way to a spinner,
   a ring with a gap turning in eight steps, so the press reads as taken by shape and motion, not by colour
   alone; the key stays lit. A clip that comes at once never shows it. With motion turned down it shows at
   once and stands still. Only this part's key has it: today's markup (a ▶ in the key) keeps its sign. */
[data-part="player"] .pl-play > *, [data-part="player"] .pl-play::after { grid-area: 1 / 1; }
[data-part="player"] .pl-play::after {
  content: ''; width: var(--pl-spin); height: var(--pl-spin); box-sizing: border-box;
  border: var(--line); border-right-color: transparent; border-radius: 50%; opacity: 0; transition-property: opacity;
}
[data-part="player"] .pl-play[data-state~="waiting"]::after { opacity: 1; transition-delay: var(--pl-spin-after); animation: pl-spin var(--pl-spin-turn) steps(8) infinite; }
[data-part="player"] .pl-play[data-state~="waiting"] .ic-pause { visibility: hidden; transition-property: visibility; transition-delay: var(--pl-spin-after); }
@keyframes pl-spin { to { transform: rotate(360deg); } }
.pl-wave {
  position: relative; display: flex; align-items: flex-end; gap: var(--pl-bar-gap); flex: none;
  height: var(--pl-wave-h); border-bottom: var(--line); cursor: pointer; touch-action: none;
}
.pl-wave::after { content: ''; position: absolute; inset: calc(-1 * var(--pl-reach)) 0; }
.pl-wave:focus-visible { outline-offset: var(--sp-1); }
.pl-bar { display: block; flex: none; width: var(--pl-bar-w); height: calc(var(--pl-v) * var(--pl-bar-max) / 100); background: var(--idle); }
@supports (height: round(nearest, 3px, 2px)) {
  .pl-bar { height: max(var(--sp-px), round(nearest, calc(var(--pl-v) * var(--pl-bar-max) / 100), var(--sp-px))); }
}
.pl-bar[data-state~="on"] { background: var(--yellow); box-shadow: var(--pl-on-edge); }
.pl-time { font: var(--t-label); white-space: nowrap; color: var(--muted); }
.pl-audio { flex-basis: 100%; width: 100%; height: var(--pl-audio-h); }
/* With scripts on, the key and the wave are the player from the first paint: the plain control is
   not drawn at all, so it can never show for a moment and then go as the script takes over (and
   the cards under it with it). It stays in the page, playing, for the key. */
.js .pl-audio { display: none; }
@media (min-width: 480px) {
  .pl-player { --pl-bar-w: var(--sp-1); }
  .pl-bar[data-state~="on"] { box-shadow: none; }
}

/* The Deck's look: the bars fill the rest of the card's width, as tall as the key. */
.pl-deck { --pl-wave-h: var(--target); --pl-on-edge: inset 0 0 0 1px var(--yellow-edge); margin: 0; gap: 0 var(--pl-gap); min-width: 0; }
.pl-deck .pl-wave { flex: 1; min-width: 0; align-items: center; border-bottom: 0; }
.pl-deck .pl-wave::after { inset: 0; }
.pl-deck .pl-bar { flex: 1; width: auto; height: calc(var(--pl-v) * 1%); min-height: var(--sp-px); }
.pl-deck .pl-bar[data-state~="on"] { box-shadow: var(--pl-on-edge); }
.pl-deck .pl-time { min-width: var(--pl-time-w); text-align: right; color: var(--ink); }
@media print { .pl-player { display: none !important; } }


/* ---- quote ---- */
/* The quote card: the words, who said them and when, and the player at the
   foot. The house's (the front page): the words large. The Deck's (a recap's
   notable quotes): smaller words, the player filling the card's foot, each
   card as tall as its own words. The card's paper is the panel part's
   (pn-card); its time code the timecode part's; its player the player
   part's. Settings first. */
.qt-quote {
  --qt-pad: var(--sp-4);
  --qt-size: 20px; --qt-line: 28px; --qt-track: -.01em;
  min-width: 0; padding: var(--qt-pad);
}
.qt-text { font: 600 var(--qt-size)/var(--qt-line) var(--sans); letter-spacing: var(--qt-track); text-wrap: pretty; }
.qt-text::before { content: '\201C'; }
.qt-text::after { content: '\201D'; }
.qt-by { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1) var(--sp-2); margin-top: var(--sp-2); font: var(--t-ui); color: var(--muted); }
.qt-who { color: var(--ink); font-weight: 700; }
.qt-who a, .qt-by a { color: var(--ink); }
.qt-likely { font-weight: 700; }
@media (min-width: 768px) { .qt-quote { --qt-pad: var(--sp-6); --qt-size: 22px; --qt-line: 32px; } }
/* in the lead at its widest */
@media (min-width: 1600px) { .qt-lead { --qt-size: 28px; --qt-line: 36px; } }

/* The Deck's card. */
.qt-deck {
  --qt-pad: var(--sp-4) var(--sp-4) var(--sp-3);
  --qt-size: 17px; --qt-line: 26px; --qt-track: 0;
  --qt-by-font: 700 13px/20px var(--sans);
  display: grid; gap: var(--sp-2);
}
@media (min-width: 768px) { .qt-deck { --qt-pad: var(--sp-4) var(--sp-4) var(--sp-3); --qt-size: 17px; --qt-line: 26px; } }
.qt-deck .qt-by { display: block; margin-top: 0; font: var(--qt-by-font); }
.qt-deck .qt-by .tc-chip { margin-left: var(--sp-1); }


/* ---- deck ---- */
/* The deck: The Deck's playhead, the sticky row across the top of every page.
   Left to right: the small robot face (the way home once the brand row has
   gone), REW, PLAY and FF as silver keys (press), the bar (an ink track, a
   yellow fill, a silver knob that never leaves the track, the marks and the
   labels under it), the display (the counter, two lines, the state word, a
   meter), REC, and Find (a house button). A phone gets the slim row: PLAY, the
   bar, the counter, REC. The script reads its sizes from the settings here
   (the knob, the label gap, the reading line); --dk-p, how far along the knob
   is (0 to 1), it writes on the deck itself. Settings first. */
.dk-deck {
  --dk-row: 48px;               /* the row inside its line: 48 on a phone, 70 from the deck's width */
  --dk-gap: var(--sp-2);
  --dk-key-h: 40px;
  --dk-key-reach: -4px -2px;    /* a key's place to press beyond its cap: 44px */
  --dk-face: var(--target); --dk-face-img: 36px;
  --dk-scrub-basis: 96px; --dk-scrub-min: 48px; --dk-scrub-top: 0px;
  --dk-track-h: 20px;
  --dk-track-reach: 12px;       /* a taller place to press the bar */
  --dk-knob-w: 16px;            /* the knob; its run is half of this in from each end of the track */
  --dk-knob-h: 32px; --dk-knob-top: -6px;
  --dk-flag: 6px; --dk-flag-top: -10px;
  --dk-scale-h: 12px;
  --dk-label-gap: 6px;          /* labels under the bar keep at least this far apart */
  --dk-gaps-from: 150px;        /* a shorter bar shows a recap's quotes but not its highlights */
  --dk-read-line: 24px;         /* the reading line, this far under the deck */
  --dk-vfd-h: 32px; --dk-vfd-pad: 6px; --dk-vfd-gap: var(--sp-3); --dk-vfd-basis: 276px;
  --dk-glass-edge: #1a2a2a;
  --dk-line-h: 16px;
  --dk-count-w: 4ch; --dk-count-recap: 7ch; --dk-state-w: 4ch;
  --dk-vu-w: var(--sp-1); --dk-vu-h: 10px; --dk-vu-pad: 3px; --dk-vu-off: #1e3232;
  --dk-rec-h: 32px; --dk-rec-pad: 0 var(--sp-2) 0 6px; --dk-rec-gap: 6px; --dk-rec-reach: -8px -2px;
  --dk-rec-dot: var(--sp-3); --dk-rec-font: 700 14px/16px var(--sans);
  --dk-find-pad: var(--sp-3);
  --dk-wind: .24s steps(6, end);      /* the knob steps to a new place */
  --dk-load: .6s steps(12, end);      /* a recap's tape winds back as the page arrives */
  position: sticky; top: 0; z-index: var(--z-deck);
  background: var(--sage); border-bottom: var(--line); box-shadow: var(--bevel-sage);
  view-transition-name: deck;
}
.dk-deck[data-mode="recap"], .dk-deck[data-mode="door"] { --dk-p: 0; }
.dk-in { display: flex; align-items: center; gap: var(--dk-gap); height: var(--dk-row); }

/* the keys (their cap, bevel, lift and press are press's) */
.dk-keys { display: flex; flex: none; gap: var(--sp-2); }
.dk-key { position: relative; display: inline-grid; place-items: center; flex: none; width: var(--target); height: var(--dk-key-h); padding: 0; text-decoration: none; }
.dk-key::after { content: ''; position: absolute; inset: var(--dk-key-reach); }
.dk-play .ic-pause { display: none; }
.dk-play[data-state~="playing"] .ic-play { display: none; }
.dk-play[data-state~="playing"] .ic-pause { display: block; }
.dk-face, .dk-wind { display: none; }
.dk-face { place-items: center; flex: none; width: var(--dk-face); height: var(--dk-face); border: var(--line); background: var(--robot-bg); visibility: hidden; }
.dk-face-img { display: block; width: var(--dk-face-img); height: var(--dk-face-img); image-rendering: pixelated; }
.dk-deck[data-state~="stuck"] .dk-face, html:not(.js) .dk-face { visibility: visible; }

/* the bar: the track is a size container, so 100cqw is its width and the knob stays inside it */
.dk-scrub { display: flex; flex-direction: column; justify-content: center; flex: 1 1 var(--dk-scrub-basis); min-width: var(--dk-scrub-min); padding-top: var(--dk-scrub-top); }
.dk-track { position: relative; height: var(--dk-track-h); background: var(--ink); container-type: inline-size; cursor: pointer; touch-action: none; }
.dk-track::before { content: ''; position: absolute; inset: calc(-1 * var(--dk-track-reach)) 0; }
.dk-track:focus-visible { outline-offset: var(--sp-2); }
.dk-fill { position: absolute; inset: var(--sp-1); background: var(--yellow); transform-origin: 0 50%; transform: scaleX(var(--dk-p, 1)); }
.dk-run { position: absolute; left: 0; top: var(--dk-knob-top); width: var(--dk-knob-w); height: var(--dk-knob-h); transform: translateX(calc(var(--dk-p, 1) * (100cqw - var(--dk-knob-w)))); pointer-events: none; }
.dk-knob { position: absolute; inset: 0; background: var(--silver); border: var(--line); box-shadow: var(--bevel-silver); }
.dk-track:focus-visible .dk-knob { background: var(--yellow); box-shadow: var(--bevel-yellow); }
/* the marks sit on the knob's run, so a mark and the knob's middle agree */
.dk-marks { position: absolute; inset: 0 calc(var(--dk-knob-w) / 2); pointer-events: none; }
.dk-gap { position: absolute; top: 0; bottom: 0; width: var(--line-w); margin-left: calc(var(--line-w) / -2); background: var(--sage); }
.dk-flag { position: absolute; top: var(--dk-flag-top); width: var(--dk-flag); height: var(--dk-flag); margin-left: calc(-1 * (var(--dk-flag) / 2 + var(--line-w))); box-sizing: content-box; background: var(--yellow); border: var(--line); }
.dk-scale { position: relative; display: none; height: var(--dk-scale-h); margin: var(--sp-2) calc(var(--dk-knob-w) / 2) 0; font: var(--t-label-tight); text-transform: uppercase; }
.dk-tick { position: absolute; top: 0; transform: translateX(-50%); white-space: nowrap; }
.dk-tick-first { transform: none; margin-left: calc(var(--dk-knob-w) / -2); }   /* flush with the bar's own end */
.dk-tick-last { transform: translateX(-100%); margin-left: calc(var(--dk-knob-w) / 2); }
.dk-deck[data-mode="recap"] .dk-run, .dk-deck[data-mode="recap"] .dk-fill { transition: transform var(--dk-wind); }
.dk-deck[data-state~="drag"] .dk-run, .dk-deck[data-state~="drag"] .dk-fill { transition: none; }
@keyframes dk-load-run { from { transform: translateX(calc(100cqw - var(--dk-knob-w))); } }
@keyframes dk-load-fill { from { transform: scaleX(1); } }
.js .dk-deck[data-mode="recap"] .dk-run { animation: dk-load-run var(--dk-load); }
.js .dk-deck[data-mode="recap"] .dk-fill { animation: dk-load-fill var(--dk-load); }

/* the display: dark glass, the counter at the pixel face's one crisp large size, two lines, the state word, a meter */
.dk-vfd {
  display: flex; align-items: center; gap: var(--dk-vfd-gap); flex: none; min-width: 0; height: var(--dk-vfd-h); padding: 0 var(--dk-vfd-pad); overflow: hidden;
  background: var(--glass); border: var(--line); box-shadow: inset 0 0 0 var(--line-w) var(--dk-glass-edge);
  color: var(--vfd); font: var(--t-label); text-transform: uppercase;
}
.dk-count { flex: none; min-width: var(--dk-count-w); font: var(--t-display); text-align: center; }
.dk-deck[data-mode="recap"] .dk-count { min-width: var(--dk-count-recap); }
.dk-long { --dk-count-recap: 8ch; }   /* a room of ten hours or more: 10:00:00 */
.dk-vfd[data-state~="lit"] .dk-count { color: var(--yellow); }
.dk-lines, .dk-side { display: none; }
.dk-lines { flex: 1; min-width: 0; }
.dk-l1, .dk-l2 { display: block; height: var(--dk-line-h); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dk-l1 { color: var(--vfd-dim); }
.dk-side { flex: none; gap: var(--sp-px); justify-items: end; }
.dk-state { min-width: var(--dk-state-w); color: var(--yellow); text-align: right; }
.dk-vu { display: flex; gap: var(--sp-px); padding-block: var(--dk-vu-pad); }
.dk-vu-i { width: var(--dk-vu-w); height: var(--dk-vu-h); background: var(--dk-vu-off); }
.dk-vu-i[data-state~="on"] { background: var(--leaf); }
.dk-vu-i:nth-child(n+10)[data-state~="on"] { background: var(--yellow); }

/* REC: a silver plate and a red lamp; it goes to the hosts (press draws the plate). No count since
   2026-10-27: the watch list's size read as the archive shrinking (Dan). */
.dk-rec { position: relative; display: grid; grid-template-columns: auto auto; align-items: center; gap: 0 var(--dk-rec-gap); flex: none; height: var(--dk-rec-h); padding: var(--dk-rec-pad); text-decoration: none; }
.dk-rec::after { content: ''; position: absolute; inset: var(--dk-rec-reach); }
.dk-rec-dot { width: var(--dk-rec-dot); height: var(--dk-rec-dot); border-radius: 50%; background: var(--rec); border: var(--line); }
.dk-rec-t { font: var(--dk-rec-font); }
/* Find: a house button, its word from 1024px, below 768px in the menu instead */
.dk-find { display: none; flex: none; padding: 0 var(--dk-find-pad); }
@media (max-width: 359px) {
  .dk-deck[data-mode="recap"] .dk-rec-t { position: absolute; width: var(--vh-box); height: var(--vh-box); overflow: hidden; clip-path: inset(50%); }
  .dk-deck[data-mode="recap"] { --dk-rec-pad: 0 6px; --dk-rec-gap: 0px; }
}
/* from 641px: the wind keys and the two lines come back, the bar gets its labels */
@media (min-width: 641px) {
  .dk-deck {
    --dk-row: 70px; --dk-gap: var(--sp-3); --dk-key-h: var(--target); --dk-key-reach: 0px;
    --dk-scrub-basis: 88px; --dk-scrub-min: 88px; --dk-scrub-top: 6px;
    --dk-vfd-h: 48px; --dk-vfd-pad: 10px;
    --dk-rec-h: var(--target); --dk-rec-pad: 0 var(--sp-3) 0 10px; --dk-rec-gap: var(--sp-2); --dk-rec-reach: 0px;
  }
  .dk-wind { display: inline-grid; }
  html:not(.js) .dk-wind { display: none; }
  .dk-scale { display: block; }
  .dk-vfd { flex: 0 1 var(--dk-vfd-basis); }   /* the counter, and a first line of 26 characters whole */
  .dk-lines { display: block; }
}
@media (min-width: 641px) and (max-width: 767px) { .dk-deck { --dk-gap: var(--sp-2); } }
@media (min-width: 768px) {
  .dk-find { display: inline-flex; width: var(--target); padding: 0; }
  .dk-find-t { position: absolute; width: var(--vh-box); height: var(--vh-box); overflow: hidden; clip-path: inset(50%); }
}
/* from 900px the small face has its place; from 1024px Find has its word */
@media (min-width: 900px) {
  .dk-face { display: grid; }
  .dk-deck { --dk-vfd-basis: 300px; }
}
@media (min-width: 1024px) {
  .dk-find { width: auto; padding: 0 var(--sp-4); }
  .dk-find-t { position: static; width: auto; height: auto; clip-path: none; }
}
@media (min-width: 1240px) {
  .dk-deck { --dk-vfd-basis: 372px; }
  .dk-side { display: grid; }
}

/* the sign-in pages: no tape. No labels under the empty bar (so it sits on the row's middle), and no meter: its room goes to the words */
.dk-deck[data-mode="door"] .dk-scale, .dk-deck[data-mode="door"] .dk-vu { display: none; }
@media (min-width: 641px) { .dk-deck[data-mode="door"] { --dk-scrub-top: 0px; } }
@media print { .dk-deck { display: none !important; } }


/* ---- rxbars ---- */
/* The room's reactions: a column an emoji, the count over a bar, the emoji on
   a 4px ink rule. Bars in the idle grey, the most in yellow. Settings first. */
.rx-reacts {
  --rx-col-h: 76px;
  --rx-bar-max: 52px;
  --rx-bar-pad: 0 5px;
  --rx-n-type: 700 15px/20px var(--sans);
  --rx-emoji-type: 400 18px/24px var(--sans);
  min-width: 0;
}
.rx-lead { margin-bottom: var(--sp-2); }
.rx-grid { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }
.rx-col { display: grid; grid-template-rows: var(--rx-col-h) auto; min-width: 0; }
.rx-bar { display: flex; flex-direction: column; justify-content: flex-end; align-items: stretch; padding: var(--rx-bar-pad); text-align: center; }
.rx-n { font: var(--rx-n-type); font-variant-numeric: tabular-nums; }
.rx-fill { display: block; height: calc(var(--rx-v) * var(--rx-bar-max)); min-height: var(--sp-px); background: var(--idle); }
.rx-top .rx-fill { background: var(--yellow); }
.rx-emoji { border-top: var(--line-thick); padding-top: var(--sp-1); text-align: center; font: var(--rx-emoji-type); }
@media (min-width: 768px) { .rx-reacts { --rx-col-h: 92px; --rx-bar-max: 64px; } }


/* ---- tapemap ---- */
/* The tape map. An ink strip with the knob's run inset at each end (marks
   and labels sit on that run, so a mark and the knob's middle agree): the
   timeline's rows in grey, worth a full listen in yellow, a sage cut where a
   part begins. Pins above for the highlights, yellow flags below for the
   quotes you can play, the time along the foot, a legend for what is drawn.
   --rm-p (0 to 1) is the knob's place; the script writes it as the deck
   moves. Settings first. */
.rm-map {
  --rm-knob-w: 12px;
  --rm-run-top: -8px; --rm-run-h: 48px;
  --rm-track-h: 32px;
  --rm-pins-h: 10px; --rm-pin-h: 8px;
  --rm-topic-top: 4px; --rm-topic-h: 14px;
  --rm-good-bottom: 4px; --rm-good-h: 8px;
  --rm-cues-h: 16px; --rm-cue-top: 4px; --rm-cue: 8px;
  --rm-row-h: 16px;
  --rm-label-gap: 6px;
  --rm-key-w: 14px; --rm-key-h: 8px; --rm-key-gap: 6px; --rm-key-pin-h: 10px; --rm-key-cue: 4px; --rm-key-worth-h: 4px;
  --rm-key-cut: linear-gradient(90deg, var(--ink) 0 6px, var(--sage) 6px 8px, var(--ink) 8px);
  --rm-wind: .24s steps(6, end);
  position: relative; min-width: 0; padding-top: var(--sp-px);
}
.rm-parts, .rm-pins, .rm-cues, .rm-axis { position: relative; margin-inline: calc(var(--rm-knob-w) / 2); }
.rm-parts { height: var(--rm-row-h); color: var(--muted); }
.rm-part { position: absolute; top: 0; left: calc(var(--rm-x) * 1%); margin-left: calc(var(--line-w) / -2); font: var(--t-label); }
.rm-pins { height: var(--rm-pins-h); }
.rm-pin { position: absolute; bottom: 0; left: calc(var(--rm-x) * 1%); width: var(--line-w); height: var(--rm-pin-h); margin-left: calc(var(--line-w) / -2); background: var(--ink); }

/* the strip: a size container, so 100cqw is its width and the knob stays on it */
.rm-track { position: relative; height: var(--rm-track-h); background: var(--ink); container-type: inline-size; cursor: pointer; touch-action: none; }
.rm-in { position: absolute; inset: 0 calc(var(--rm-knob-w) / 2); }
.rm-topic { position: absolute; top: var(--rm-topic-top); left: calc(var(--rm-x) * 1%); width: calc(var(--rm-w) * 1%); height: var(--rm-topic-h); background: var(--idle); border-right: var(--line); }
.rm-good { position: absolute; bottom: var(--rm-good-bottom); left: calc(var(--rm-x) * 1%); width: calc(var(--rm-w) * 1%); height: var(--rm-good-h); background: var(--yellow); }
.rm-cut { position: absolute; top: 0; bottom: 0; left: calc(var(--rm-x) * 1%); width: var(--line-w); margin-left: calc(var(--line-w) / -2); background: var(--sage); }
.rm-run { position: absolute; left: 0; top: var(--rm-run-top); width: var(--rm-knob-w); height: var(--rm-run-h); transform: translateX(calc(var(--rm-p, 0) * (100cqw - var(--rm-knob-w)))); transition: transform var(--rm-wind); pointer-events: none; }
.rm-map[data-state~="drag"] .rm-run { transition: none; }
.rm-knob { position: absolute; inset: 0; background: var(--silver); border: var(--line); box-shadow: var(--bevel-silver); }

.rm-cues { height: var(--rm-cues-h); }
.rm-cue { position: absolute; top: var(--rm-cue-top); left: calc(var(--rm-x) * 1%); width: var(--rm-cue); height: var(--rm-cue); margin-left: calc(var(--rm-cue) / -2); background: var(--yellow); border: var(--line); }
.rm-axis { height: var(--rm-row-h); margin-top: var(--sp-px); color: var(--muted); }
.rm-tick { position: absolute; top: 0; left: calc(var(--rm-x) * 1%); transform: translateX(-50%); white-space: nowrap; }
.rm-tick-first { transform: none; }

.rm-legend { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4); margin-top: var(--sp-2); color: var(--muted); }
.rm-key { display: flex; align-items: center; gap: var(--rm-key-gap); }
.rm-key::before { content: ''; flex: none; width: var(--rm-key-w); height: var(--rm-key-h); box-sizing: content-box; background: var(--idle); border: var(--line); }
.rm-k-worth::before { height: var(--rm-key-worth-h); background: var(--yellow); }
.rm-k-pin::before { width: var(--line-w); height: var(--rm-key-pin-h); margin-inline: var(--rm-key-gap); border: 0; background: var(--ink); }
.rm-k-cue::before { width: var(--rm-key-cue); height: var(--rm-key-cue); background: var(--yellow); }
.rm-k-cut::before { background: var(--rm-key-cut); }
@media (min-width: 768px) { .rm-map { --rm-cue: 10px; --rm-key-cue: 6px; } }


/* ---- rhead ---- */
/* A recap's title block. One panel (the panel part's paper) from 768px: the
   words at the left, the room's reactions in a 300px column at the right, the
   tape map across the foot. The headline at The Deck's own sizes (24px on a
   phone, 32 from 1024, 38 from 1240, 44 from 1600), and it is where the front
   page's lead headline lands when the page changes (lead-title).

   On a phone the block parts in two, the words and then the meters, each on
   paper of its own, so the page can set the TL;DR between them. The panel's
   paper cannot follow its children there, so this part lays the panel's own
   paper (--panel-fill, --panel-line, --panel-drop in tokens.css) on the two
   halves below 768px: a change to the panel's look reaches them too. Settings first. */
.rh-label {
  --rh-pad: var(--sp-4);
  --rh-gap: var(--sp-4);
  --rh-rx-col: 300px;
  --rh-title-type: 700 24px/28px var(--sans);
  --rh-title-track: -.012em;
  --rh-byline-type: italic 400 15px/24px var(--sans);
  --rh-notes-type: 400 15px/24px var(--sans);
  --rh-measure: 78ch;
  display: grid; gap: var(--rh-gap); padding: var(--rh-pad);
}
.rh-main { display: grid; gap: var(--sp-3); align-content: start; justify-items: start; min-width: 0; }
.rh-kicker { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.rh-title { font: var(--rh-title-type); letter-spacing: var(--rh-title-track); overflow-wrap: anywhere; view-transition-name: lead-title; }
.rh-byline { font: var(--rh-byline-type); color: var(--muted); max-width: var(--rh-measure); }
.rh-byline a, .rh-notes a { color: var(--ink); }
.rh-notes { font: var(--rh-notes-type); color: var(--muted); max-width: var(--rh-measure); }
.rh-notes > * + * { margin-top: var(--sp-2); }
.rh-acts { display: flex; flex-wrap: wrap; gap: var(--sp-4); }
.rh-meters { min-width: 0; }

@media (max-width: 767px) {
  .rh-label { display: contents; }
  .rh-main, .rh-meters { margin-right: var(--sp-2); padding: var(--rh-pad); background: var(--panel-fill); border: var(--panel-line); box-shadow: var(--panel-drop); }
  .rh-meters { display: grid; gap: var(--rh-gap); }
}
@media (min-width: 768px) {
  .rh-label { --rh-pad: var(--sp-6) var(--sp-6) var(--sp-5); grid-template-columns: minmax(0, 1fr) var(--rh-rx-col); gap: var(--sp-5) var(--sp-6); }
  .rh-norx, .rh-bare { grid-template-columns: minmax(0, 1fr); }
  .rh-meters { display: contents; }
  .rh-map { grid-column: 1 / -1; }
}
@media (min-width: 1024px) { .rh-label { --rh-title-type: 700 32px/36px var(--sans); } }
@media (min-width: 1240px) { .rh-label { --rh-title-type: 700 38px/44px var(--sans); } }
@media (min-width: 1600px) { .rh-label { --rh-title-type: 700 44px/48px var(--sans); } }


/* ---- rdoc ---- */
/* The recap as it is read. A reading panel (the panel part's paper) with the
   recap's type: 17px on 28 (18 on 30 at the widest), a measure of 76
   characters. Each section opens on its heading chip, ink words on the spot
   yellow in a 2px line, as The Deck had it. Then the recap's prose as today's
   renderer writes it: square bullets in the TL;DR, a sage rule at the left of
   each line of who said what. A time code inside a sentence (the timecode
   part's ink chip, rd-stamp) sits a pixel up off the baseline; a bracket too
   long to be a time stays as words that wrap. Settings first. */
.rd-panel {
  --rd-pad: var(--sp-5) var(--sp-4) var(--sp-6);
  --rd-type: 400 17px/28px var(--sans);
  --rd-underline: 2px;
  --rd-code-type: 400 14px/20px var(--code);
  --rd-code-pad: 1px var(--sp-1);
  --rd-code-edge: 1px solid #d8d3c4;
  padding: var(--rd-pad); font: var(--rd-type); min-width: 0;
}
@media (min-width: 768px) { .rd-panel { --rd-pad: var(--sp-8) 36px; } }
@media (min-width: 1600px) { .rd-panel { --rd-type: 400 18px/30px var(--sans); } }
.rd-panel a { text-decoration-thickness: var(--line-w); text-underline-offset: var(--rd-underline); }
.rd-panel code { font: var(--rd-code-type); background: var(--cream); border: var(--rd-code-edge); padding: var(--rd-code-pad); }

/* the heading chip, and the tag that may stand beside it */
.rd-h {
  --rd-h-type: 700 19px/24px var(--sans);
  --rd-h-pad: var(--sp-1) var(--sp-3);
  display: inline-block; margin-bottom: var(--sp-4); padding: var(--rd-h-pad);
  background: var(--yellow); border: var(--line); font: var(--rd-h-type);
}
.rd-h-note { --rd-note-lift: 6px; margin-left: var(--sp-2); vertical-align: var(--rd-note-lift); }
.rd-sec + .rd-sec { margin-top: var(--sp-8); }

/* the recap's prose */
.rd-prose { --rd-measure: 76ch; --rd-bullet-in: 22px; min-width: 0; }
.rd-prose > * + * { margin-top: var(--sp-4); }
.rd-prose p, .rd-prose ul, .rd-prose ol { max-width: var(--rd-measure); }
.rd-prose ul, .rd-prose ol { padding-left: var(--rd-bullet-in); }
.rd-prose ul { list-style: square; }
.rd-prose ol { list-style: decimal; }
.rd-prose li { padding-left: var(--sp-px); }
.rd-prose li + li { margin-top: var(--sp-2); }
.rd-prose blockquote { padding-left: var(--sp-3); border-left: var(--line-thick); }
.rd-prose table { border-collapse: collapse; }
.rd-prose th, .rd-prose td { padding: var(--sp-1) var(--sp-3) var(--sp-1) 0; text-align: left; vertical-align: top; border-bottom: var(--line-w) solid var(--tan); }
/* who said what: no bullets, a sage rule at each line's left (a list, or a paragraph a line) */
.rd-who ul { list-style: none; padding-left: 0; display: grid; gap: var(--sp-3); }
.rd-who li + li { margin-top: 0; }
.rd-who li, .rd-who > p { padding-left: var(--sp-3); border-left: var(--line-w-thick) solid var(--sage); }
.rd-who > p + p { margin-top: var(--sp-3); }

/* a time code inside a sentence, and a bracket too long to be one */
.rd-stamp { --rd-stamp-lift: 2px; vertical-align: var(--rd-stamp-lift); }
.rd-stamp-long { overflow-wrap: anywhere; }
/* the star a hedged name carries */
.rd-lk { font-weight: 700; line-height: 0; }

/* the quote cards: one column, two from 768px, each as tall as its own words */
.rd-moments { display: grid; gap: var(--sp-4); align-items: start; }
@media (min-width: 768px) { .rd-moments { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* a line of the quotes read as written, its player under it */
.rd-said { display: grid; gap: var(--sp-2); }

/* the footnote for names marked as likely, and the buttons at the end */
.rd-note { --rd-note-type: 400 14px/20px var(--sans); margin-top: var(--sp-6); font: var(--rd-note-type); color: var(--muted); }
.rd-end { display: flex; flex-wrap: wrap; gap: var(--sp-4); margin-top: var(--sp-6); }


/* ---- rhl ---- */
/* A highlight: the time code, the title, what happened. On a phone the chip
   sits above the title; from 768px it has a column of its own and the words
   run beside it, as The Deck had it. The chip is the timecode part's (the
   deck marks the one it is reading: "cue" in the highlight's data-state).
   Settings first. */
.rhl-list { display: grid; gap: var(--sp-6); }
.rhl-item {
  --rhl-chip-col: 112px;
  --rhl-title-type: 700 17px/24px var(--sans);
  --rhl-measure: 70ch;
  display: grid; gap: var(--sp-1) 0; justify-items: start; min-width: 0;
}
.rhl-at { margin-bottom: var(--sp-px); }
.rhl-title { font: var(--rhl-title-type); }
.rhl-text { max-width: var(--rhl-measure); }
.rhl-text > * + * { margin-top: var(--sp-3); }
@media (min-width: 768px) {
  .rhl-item { grid-template-columns: var(--rhl-chip-col) minmax(0, 1fr); gap: var(--sp-1) var(--sp-2); }
  .rhl-at { grid-row: 1 / span 2; align-self: start; margin-top: var(--sp-1); }
  .rhl-item > .rhl-title, .rhl-item > .rhl-text { grid-column: 2; }
}


/* ---- rtl ---- */
/* The topic timeline: a table that reads as a ruled list. The header in the
   pixel face over a 2px ink line, a tan line under each row, the time column
   as narrow as its chips (the chip is the timecode part's), the topic taking
   the rest and wrapping. Settings first. */
.rtl-table {
  --rtl-type: 400 16px/24px var(--sans);
  --rtl-cell: var(--sp-2) 0;
  width: 100%; border-collapse: collapse; font: var(--rtl-type);
}
.rtl-th { padding: 0 0 var(--sp-2); border-bottom: var(--line); font: var(--t-label); text-transform: uppercase; text-align: left; }
.rtl-table td { padding: var(--rtl-cell); border-bottom: var(--line-w) solid var(--tan); vertical-align: top; }
.rtl-table .rtl-time { width: 1%; padding-right: var(--sp-4); }
.rtl-table .rtl-topic { overflow-wrap: anywhere; }
.rtl-table .rtl-topic + .rtl-topic { padding-left: var(--sp-3); }
.rtl-list { display: grid; gap: var(--sp-2); }
.rtl-list .rtl-row { padding-bottom: var(--sp-2); border-bottom: var(--line-w) solid var(--tan); }


/* ---- rwl ---- */
/* Worth a full listen: a yellow rule at each entry's left, the range's chip
   (the timecode part's) leading the words. Settings first. */
.rwl-list { --rwl-measure: 76ch; display: grid; gap: var(--sp-3); }
.rwl-item { max-width: var(--rwl-measure); padding-left: var(--sp-3); border-left: var(--line-w-thick) solid var(--yellow); }
.rwl-at { --rwl-chip-lift: 2px; margin-right: var(--sp-1); vertical-align: var(--rwl-chip-lift); }


/* ---- rail ---- */
/* "On this tape". Under 1024px a drawer: the summary is a 48px row with the
   house's caret, turned when open. From 1024px the rail beside the recap,
   always open (the summary is only its heading), staying in view under the
   deck, its list scrolling inside it when the window is too short to hold
   it all (the prototype let it go instead, under 800px). A row: the time
   code (the timecode part's) in a column of its own, the words beside it; the
   row the deck is reading wears a yellow rule. Settings first. */
.rl-rail { min-width: 0; }
.rl-index {
  --rl-sum-pad: 0 var(--sp-4);
  --rl-h-type: 700 18px/24px var(--sans);
  --rl-nav-pad: 0 var(--sp-3) var(--sp-3) var(--sp-4);
  --rl-row-type: 600 14px/20px var(--sans);
  --rl-chip-col: calc(var(--rl-chars, 5) * var(--pix-advance) + var(--rl-chip-pad) + var(--rl-chip-air));   /* the longest time code's width (the rail writes --rl-chars) */
  --rl-chip-pad: 12px;
  --rl-chip-air: 11px;
  --rl-row-pad: 10px 6px;
  --rl-row-pull: -10px;
  --rl-chip-drop: 2px;
  --rl-k-gap: var(--sp-2) 0 6px;
  padding: 0;
}
.rl-sum { display: flex; align-items: center; justify-content: space-between; min-height: var(--target-row); padding: var(--rl-sum-pad); cursor: pointer; list-style: none; }
.rl-sum::-webkit-details-marker { display: none; }
.rl-sum::after { content: ''; flex: none; width: var(--sp-3); height: var(--sp-2); background: var(--caret) no-repeat; background-size: var(--caret-size); }
.rl-index[open] > .rl-sum::after { transform: rotate(180deg); }
.rl-h { font: var(--rl-h-type); }
.rl-nav { padding: var(--rl-nav-pad); }
.rl-k { margin: var(--rl-k-gap); color: var(--muted); }
.rl-link {
  display: grid; grid-template-columns: var(--rl-chip-col) minmax(0, 1fr); gap: var(--sp-2); align-items: start;
  min-height: var(--target); padding: var(--rl-row-pad); margin-left: var(--rl-row-pull); border-left: var(--line-w-thick) solid transparent;
  font: var(--rl-row-type); text-decoration: none;
}
.rl-link .tc-chip { justify-self: start; margin-top: var(--rl-chip-drop); }
.rl-link:hover { background: var(--white); }
.rl-link[data-state~="cue"] { background: var(--white); border-left-color: var(--yellow); }
.rl-words { overflow-wrap: anywhere; }
/* shut before the first paint under 1024px, until rail.js shuts the drawer itself */
[data-rl~="shut"] .rl-nav { display: none; }
[data-rl~="shut"] .rl-index[open] > .rl-sum::after { transform: none; }
@media (min-width: 1024px) {
  .rl-rail { position: sticky; top: calc(var(--deck-h) + var(--sp-4)); }
  .rl-index { --rl-row-type: 600 13.5px/18px var(--sans); --rl-row-pad: 5px 6px; --rl-chip-drop: 0px; --rl-k-gap: var(--sp-2) 0 var(--sp-1); --rl-fit: calc(100vh - var(--deck-h) - 96px); }
  .rl-nav { max-height: var(--rl-fit); overflow-y: auto; overscroll-behavior: contain; }
  .rl-sum { min-height: 0; padding: var(--sp-4) var(--sp-4) 0; pointer-events: none; }
  .rl-sum::after { content: none; }
  .rl-link { min-height: 0; }
}


/* ---- rsg ---- */
/* The soundtrack: the re:gen records songs played in the room. A panel (the
   panel part's paper) with an ink band on top carrying the label's name in
   the pixel face, then the songs as a tracklist of cream cards, one a row:
   the cover in an ink frame with a hard drop, the time chip and the debut
   tag, the title, who it is for, and the yellow button to the song. Six
   show; the rest fold under a summary. Settings first. */
.rsg-sec {
  --rsg-pad: var(--sp-5) var(--sp-4) var(--sp-6);
  --rsg-band-pad: var(--sp-2) var(--sp-4);
  --rsg-art: 96px;
  --rsg-card-pad: var(--sp-4);
  --rsg-lead-type: 500 15px/24px var(--sans);
  padding: 0; min-width: 0; overflow: hidden;
}
@media (min-width: 768px) { .rsg-sec { --rsg-pad: var(--sp-6) 36px var(--sp-8); --rsg-band-pad: var(--sp-3) 36px; --rsg-art: 120px; --rsg-card-pad: var(--sp-5); } }
.rsg-band { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); padding: var(--rsg-band-pad); background: var(--ink); color: var(--cream); border-bottom: var(--line-thick); }
.rsg-label { font: var(--t-display); letter-spacing: var(--track-display); color: var(--yellow); }
.rsg-count { font: var(--t-label); text-transform: uppercase; color: var(--cream); }
.rsg-inner { padding: var(--rsg-pad); }
.rsg-h { font: var(--t-h2); letter-spacing: var(--track-display); }
.rsg-lead { margin: var(--sp-2) 0 var(--sp-5); font: var(--rsg-lead-type); color: var(--muted); max-width: 60ch; }
.rsg-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-5); }
.rsg-item { display: flex; min-width: 0; }
.rsg-card { display: grid; grid-template-columns: var(--rsg-art) minmax(0, 1fr); grid-template-areas: "art body" "go go"; column-gap: var(--sp-4); row-gap: var(--sp-4); width: 100%; padding: var(--rsg-card-pad); align-items: center; }
@media (min-width: 768px) { .rsg-card { grid-template-columns: var(--rsg-art) minmax(0, 1fr) auto; grid-template-areas: "art body go"; column-gap: var(--sp-6); } }
.rsg-art { grid-area: art; display: block; width: var(--rsg-art); aspect-ratio: 1; border: var(--line); box-shadow: var(--drop-2); background: var(--sage); }
.rsg-art img, .rsg-blank { display: block; width: 100%; height: 100%; object-fit: cover; }
.rsg-body { grid-area: body; display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-2); min-width: 0; }
.rsg-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.rsg-meta > * { white-space: nowrap; }
.rsg-times { font: var(--t-label); text-transform: uppercase; color: var(--muted); }
.rsg-title { font: var(--t-h4); overflow-wrap: anywhere; }
.rsg-title a { color: inherit; text-decoration: none; }
.rsg-title a:hover { text-decoration: underline; text-decoration-thickness: var(--line-w); }
.rsg-sub { font: var(--t-ui-medium); color: var(--muted); overflow-wrap: anywhere; }
.rsg-go { grid-area: go; justify-self: start; white-space: nowrap; }
@media (min-width: 768px) { .rsg-go { justify-self: end; } }
.rsg-more { margin-top: var(--sp-4); }
.rsg-more > .rsg-grid { margin-top: var(--sp-4); }
.rsg-show { display: inline-block; font: var(--t-ui); text-decoration: underline; text-decoration-thickness: var(--line-w); cursor: pointer; }
.rsg-show:hover { background: var(--yellow); }
.rsg-end { margin-top: var(--sp-6); }


/* ---- rpn ---- */
/* Pinned in the room: a panel (the panel part's paper) holding a strip of
   cards (the panel part's cream card) that scrolls sideways inside it and
   snaps to each card. A card: who pinned it and when (the timecode part's
   chip), the post's words, and the way to it on X. Settings first. */
.rpn-sec {
  --rpn-pad: var(--sp-5) var(--sp-4) var(--sp-6);
  --rpn-card-w: min(260px, 82%);
  --rpn-card-pad: var(--sp-3) var(--sp-4);
  --rpn-text-type: 400 15px/22px var(--sans);
  --rpn-lead-type: 500 15px/24px var(--sans);
  padding: var(--rpn-pad); min-width: 0;
}
@media (min-width: 768px) { .rpn-sec { --rpn-pad: var(--sp-8) 36px; } }
.rpn-lead { margin-bottom: var(--sp-4); font: var(--rpn-lead-type); color: var(--muted); }
.rpn-scroll { overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; padding: 0 var(--sp-2) var(--sp-3) 0; }
.rpn-strip { display: grid; grid-auto-flow: column; grid-auto-columns: var(--rpn-card-w); gap: var(--sp-4); }
.rpn-item { display: flex; scroll-snap-align: start; min-width: 0; }
.rpn-card { display: flex; flex-direction: column; gap: var(--sp-2); width: 100%; padding: var(--rpn-card-pad); text-decoration: none; }
.rpn-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); }
.rpn-who { font: var(--t-ui); overflow-wrap: anywhere; }
.rpn-text { flex: 1; font: var(--rpn-text-type); overflow-wrap: anywhere; }
.rpn-none { color: var(--muted); }
.rpn-go { font: var(--t-ui-small); text-decoration: underline; text-decoration-thickness: var(--line-w); }
.rpn-card:hover .rpn-go { background: var(--yellow); }


/* ---- rsu ---- */
/* Recaps by email: a panel (the panel part's paper) in two halves from
   768px, the words at the left and the Sunday art filling the right behind a
   4px ink rule. The button is the button part's, big and yellow. Settings
   first. */
.rsu-box {
  --rsu-pad: var(--sp-5) var(--sp-4) var(--sp-6);
  --rsu-h-type: 700 32px/32px var(--sans);
  --rsu-h-track: -.035em;
  --rsu-measure: 40ch;
  display: grid; min-width: 0;
}
.rsu-body { display: grid; gap: var(--sp-3); align-content: center; justify-items: start; padding: var(--rsu-pad); }
.rsu-h { font: var(--rsu-h-type); letter-spacing: var(--rsu-h-track); }
.rsu-text { font: var(--t-read); max-width: var(--rsu-measure); }
.rsu-body > .bt-button { margin-top: var(--sp-1); }
.rsu-art { display: none; border-left: var(--line-thick); background: var(--ink); }
.rsu-img { display: block; width: 100%; height: 100%; object-fit: cover; }
@media (min-width: 768px) {
  .rsu-box { --rsu-pad: var(--sp-8); --rsu-h-type: 700 40px/40px var(--sans); grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rsu-art { display: block; }
}


/* ---- rmo ---- */
/* More from this room: panels (the panel part's paper) of rows (the list
   part's), two across from 768px; then the fuel note on a cream card (the
   panel part's). A link inside a sentence reaches 44px tall without moving
   the line. Settings first. */
.rmo-more { display: grid; gap: var(--sp-6); min-width: 0; }
@media (min-width: 768px) { .rmo-two { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.rmo-panel {
  --rmo-pad: var(--sp-5) var(--sp-4);
  --rmo-h-type: 700 21px/28px var(--sans);
  --rmo-h-track: -.01em;
  --rmo-lead-type: 500 15px/24px var(--sans);
  --rmo-measure: 70ch;
  --rmo-reach: 10px;
  padding: var(--rmo-pad); min-width: 0;
}
@media (min-width: 768px) { .rmo-panel { --rmo-pad: var(--sp-6); } }
.rmo-h { margin-bottom: var(--sp-2); font: var(--rmo-h-type); letter-spacing: var(--rmo-h-track); overflow-wrap: anywhere; }
.rmo-lead { margin-bottom: var(--sp-3); font: var(--rmo-lead-type); color: var(--muted); max-width: var(--rmo-measure); }
.rmo-all { display: inline-block; padding-block: var(--rmo-reach); margin-block: calc(-1 * var(--rmo-reach)); color: var(--ink); font-weight: 700; }
.rmo-fuel {
  --rmo-fuel-pad: var(--sp-4);
  --rmo-fuel-type: 600 16px/24px var(--sans);
  --rmo-fuel-reach: 10px;
  margin-right: var(--sp-1); padding: var(--rmo-fuel-pad); font: var(--rmo-fuel-type);
}
.rmo-fuel-go { display: inline-block; padding-block: var(--rmo-fuel-reach); margin-block: calc(-1 * var(--rmo-fuel-reach)); font-weight: 700; }


/* ---- rpage ---- */
/* The recap page's grid. One column; on a phone the blocks take The Deck's
   order (rp-o1 to rp-o9: the title, the TL;DR, the meters, the drawer, the
   recap, pinned posts, recaps by email, more, fuel), the reading column and
   the title block opening up (display: contents) so their blocks can be
   placed. From 1024px the rail (rp-side) stands beside the reading column
   for its whole height (--rp-rows, the column's blocks, written by the
   markup). Settings first. */
.rp-page {
  --rp-gap: var(--sp-6);
  --rp-top: var(--sp-4);
  --rp-end: var(--sp-12);
  --rp-rail-w: 328px;
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--rp-gap); padding-top: var(--rp-top); padding-bottom: var(--rp-end);
}
.rp-read { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--rp-gap); align-items: start; min-width: 0; }
@media (max-width: 767px) {
  .rp-read { display: contents; }
  .rp-o1 { order: 1; } .rp-o2 { order: 2; } .rp-o3 { order: 3; } .rp-o4 { order: 4; } .rp-o5 { order: 5; }
  .rp-o6 { order: 6; } .rp-o7 { order: 7; } .rp-o8 { order: 8; } .rp-o9 { order: 9; }
}
@media (min-width: 768px) { .rp-page { --rp-top: var(--sp-6); } }
@media (min-width: 1024px) {
  .rp-read { grid-template-columns: minmax(0, 1fr) var(--rp-rail-w); }
  .rp-read > * { grid-column: 1; }
  .rp-read > .rp-side { grid-column: 2; grid-row: 1 / span var(--rp-rows, 3); }
}
@media (min-width: 1600px) {
  .rp-page { --rp-rail-w: 400px; }
  .rp-read { column-gap: var(--sp-12); }
}


/* ---- portrait ---- */
/* A printed portrait: a host's face in the house's four tones (ink, muted,
   tan, cream), one art pixel drawn as 2px, inside an ink line, on cream while
   it loads. Where it lifts with its link, the lift is press's. A host with no
   print: the initial, in the pixel face, on tan. In a column narrower than
   the print it shrinks and stays square. Settings first. */
.pp-print {
  --pp-size-48: 100px;           /* 48 art pixels at 2px, and the 2px line each side */
  --pp-size-64: 132px;           /* 64 art pixels at 2px, and the line */
  --pp-size: var(--pp-size-48);
  --pp-initial: 400 44px/44px var(--pix);
  display: block; flex: none; width: var(--pp-size); max-width: 100%; height: auto; aspect-ratio: 1;
  border: var(--line); background: var(--cream); image-rendering: pixelated;
}
.pp-64 { --pp-size: var(--pp-size-64); }
.pp-none { display: grid; place-items: center; background: var(--tan); font: var(--pp-initial); }


/* ---- vcr ---- */
/* A recorder's clock: the display's cyan on the recess's own black, in the
   pixel face. Where it stands inside its picture is the placing part's (the
   shelf's VCR, the tape wall's). Settings first. */
.vc-clock {
  --vc-w: 54px; --vc-h: 14px;
  --vc-recess: #050505;          /* the recess's black, as the art has it: the time reads on its own ground */
  --vc-font: 400 11px/14px var(--pix);
  position: absolute; width: var(--vc-w); height: var(--vc-h);
  background: var(--vc-recess); color: var(--vfd); font: var(--vc-font); text-align: center;
}


/* ---- lead ---- */
/* Home's lead: the kicker, the headline, the standfirst and the way in on the
   left; the quote card and the byline (the printed portrait, the fact pills,
   the room's live reactions) on the right from 1024px, under the words below
   it. The panel's paper and padding are the panel part's, the quote and its
   player the quote part's and the player part's. The headline is named for
   the page-to-page transition: it travels into the recap's title (the recap
   page names its title lead-title too). Settings first; the widths only
   change settings. */
.ld-lead {
  --ld-gap: var(--sp-6);                /* between the words, the side and the foot */
  --ld-col-gap: var(--sp-10);           /* between the two columns, from 1024px */
  --ld-h-size: 28px; --ld-h-line: 32px; --ld-h-track: -.025em;
  --ld-stand-size: 17px; --ld-stand-line: 28px; --ld-stand-measure: 60ch;
  --ld-kicker-font: 600 14px/20px var(--sans);
  --ld-side-gap: var(--sp-5);
  --ld-rx-font: 600 14px/24px var(--sans);
  display: grid; gap: var(--ld-gap);
}
.ld-main, .ld-foot { min-width: 0; }
.ld-kicker { font: var(--ld-kicker-font); color: var(--muted); }
.ld-tag { margin-right: var(--sp-2); }
.ld-h {
  margin-top: var(--sp-3); font: 700 var(--ld-h-size)/var(--ld-h-line) var(--sans); letter-spacing: var(--ld-h-track); text-wrap: balance;
  overflow-wrap: anywhere; view-transition-name: lead-title;
}
.ld-h-a { text-decoration: none; }
.ld-h-a:hover { text-decoration: underline; text-decoration-thickness: var(--line-w-thick); }
/* a press on any other link lets go of the name (lead.js), so the headline never flies into another recap's title */
.ld-h[data-state~="still"] { view-transition-name: none; }
.ld-stand { margin-top: var(--sp-3); font: 400 var(--ld-stand-size)/var(--ld-stand-line) var(--sans); max-width: var(--ld-stand-measure); }
.ld-side { display: grid; gap: var(--ld-side-gap); align-content: start; min-width: 0; }
.ld-byline { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--sp-2) var(--sp-4); align-items: start; }
.ld-face { grid-row: 1 / span 2; }
.ld-rx { grid-column: 2; align-self: end; display: flex; flex-wrap: wrap; gap: 0 var(--sp-3); align-items: baseline; font: var(--ld-rx-font); color: var(--muted); }
.ld-rx-h { flex-basis: 100%; font: var(--t-label); text-transform: uppercase; color: var(--ink); }
.ld-rx-i { white-space: nowrap; }
.ld-inside { font: var(--t-label); text-transform: uppercase; color: var(--muted); }
.ld-go { margin-top: var(--sp-5); display: flex; flex-wrap: wrap; gap: var(--sp-4); align-items: center; }

/* the narrowest phones: the portrait over the pills, so a long name and handle have the panel's width */
@media (max-width: 359px) {
  .ld-byline { grid-template-columns: minmax(0, 1fr); }
  .ld-face { grid-row: auto; }
  .ld-rx { grid-column: 1; }
}
@media (min-width: 768px) { .ld-lead { --ld-h-size: 40px; --ld-h-line: 44px; --ld-stand-size: 18px; } }
@media (min-width: 1024px) {
  .ld-lead { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); grid-template-rows: auto 1fr; column-gap: var(--ld-col-gap); }
  .ld-side { grid-column: 2; grid-row: 1 / span 2; }
  .ld-foot { grid-column: 1; grid-row: 2; align-self: end; }
}
/* the quote card is at its narrowest here: its player's bars go back to 2px, so the wave keeps its line */
@media (min-width: 1024px) and (max-width: 1279px) { .ld-lead .pl-bar { width: var(--sp-px); } }
@media (min-width: 1280px) { .ld-lead { --ld-h-size: 48px; --ld-h-line: 52px; --ld-stand-size: 20px; --ld-stand-line: 32px; } }
@media (min-width: 1600px) { .ld-lead { --ld-gap: var(--sp-8); --ld-col-gap: var(--sp-16); --ld-h-size: 64px; --ld-h-line: 64px; --ld-h-track: -.03em; } }


/* ---- week ---- */
/* This week: a programme guide. Each day is its name and date, a 24-hour
   ruler (a bar a room, overlaps a lane up, NOW on today's) and its rows; from
   1024px the day's name stands in a column of its own and stays in view while
   its rows pass. A row is the time, the length, the title, the host and the
   subjects, and the room's live reactions as a bar (the loudest room's lit).
   A row lifts under the pointer (press's lift, with the ring), stands on the
   house's dotted rule (the list part's ls-rule, inset), and carries the deck's small yellow
   mark while the deck is reading it; its bar on the ruler lights then, and
   while it is pointed at (week.js). Settings first; the widths only change
   settings. */
.wk-week {
  --wk-days-top: var(--sp-12);
  --wk-days-gap: 56px;
  --wk-day-gap: var(--sp-4);
  --wk-head-col: 168px;
  --wk-wd-size: 32px; --wk-wd-line: 32px; --wk-wd-track: -.035em;
  --wk-lane: var(--sp-2);                /* a lane of the ruler */
  --wk-bar-h: 6px; --wk-bar-min: var(--sp-1); --wk-bars-pad: 6px;
  --wk-labs-h: 16px;
  --wk-now-room: var(--sp-6);            /* the newest day keeps room for the NOW flag, so its arrival moves nothing */
  --wk-now-top: -4px; --wk-now-bottom: 20px;
  --wk-flag-top: -18px; --wk-flag-x: calc(-1 * var(--line-w));
  --wk-row-cols: minmax(0, 1fr) auto;
  --wk-row-gap: var(--sp-1) var(--sp-3);
  --wk-row-pad: var(--sp-3) var(--sp-2) 14px;
  --wk-row-out: var(--sp-2);             /* a row reaches this far past the column on each side */
  --wk-row-min: 64px;
  --wk-cue-w: var(--sp-1); --wk-cue-h: 20px; --wk-cue-x: -4px; --wk-cue-y: 14px;
  --wk-time-font: 400 22px/24px var(--pix);
  --wk-ap-size: 11px; --wk-ap-line: 16px;
  --wk-title-size: 18px; --wk-title-line: 24px; --wk-title-track: -.01em;
  --wk-meta-size: 14px;
  --wk-rx-unit: .56px;                   /* a row's reaction bar: the loudest is 120 of these */
  --wk-rx-h: var(--sp-2);
  --wk-a-below: 96px;                    /* a row's link keeps this clear below it when focus scrolls it into view */
  min-width: 0;
}
.wk-days { margin-top: var(--wk-days-top); display: grid; gap: var(--wk-days-gap); }
.wk-day { display: grid; gap: var(--wk-day-gap); min-width: 0; }
/* A folded day (a month's page, past its newest days): its Spaces wait under one line to press. */
.wk-fold { min-width: 0; }
.wk-show {
  display: flex; align-items: center; gap: var(--sp-3); min-height: var(--target-row); padding: 0 var(--sp-4);
  background: var(--cream); border: var(--line); font: var(--t-label); text-transform: uppercase; cursor: pointer; list-style: none;
}
.wk-show::-webkit-details-marker { display: none; }
.wk-show::before { content: '+'; font: var(--t-label); }
.wk-show:hover { background: var(--paper); }
.wk-fold[open] > .wk-show { margin-bottom: var(--wk-day-gap); }
.wk-fold[open] > .wk-show::before { content: '\2212'; }
.wk-show-on, .wk-fold[open] .wk-show-off { display: none; }
.wk-fold[open] .wk-show-on { display: inline; }
.wk-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-4); flex-wrap: wrap; }
.wk-wd { font: 700 var(--wk-wd-size)/var(--wk-wd-line) var(--sans); letter-spacing: var(--wk-wd-track); }
.wk-date { font: var(--t-label); text-transform: uppercase; }
.wk-body { min-width: 0; }

/* the 24-hour ruler: one bar for every room that aired that day */
.wk-ruler { position: relative; margin-bottom: var(--sp-2); }
.wk-day:first-child .wk-ruler { margin-top: var(--wk-now-room); }
.wk-bars { position: relative; height: calc(var(--wk-lanes) * var(--wk-lane) + var(--wk-bars-pad)); border-bottom: var(--line-thick); overflow: hidden; }
.wk-bar {
  position: absolute; left: calc(var(--wk-s) * 1%); bottom: calc(var(--wk-l) * var(--wk-lane) + var(--sp-px));
  width: max(var(--wk-bar-min), calc(var(--wk-d) * 1%)); height: var(--wk-bar-h); background: var(--ink);
}
.wk-bar[data-state~="lit"], .wk-bar[data-state~="cue"] { background: var(--yellow); box-shadow: var(--ring); z-index: 1; }
.wk-ticks { position: relative; height: var(--sp-2); }
.wk-tick { position: absolute; top: 0; left: calc(var(--wk-h) / 24 * (100% - var(--line-w))); width: var(--line-w); height: var(--sp-1); background: var(--ink); }
.wk-major { height: var(--sp-2); }
.wk-labs { position: relative; height: var(--wk-labs-h); font: var(--t-label); text-transform: uppercase; }
.wk-lab { position: absolute; top: 0; left: calc(var(--wk-h) / 24 * (100% - var(--line-w))); white-space: nowrap; }
.wk-lab:last-child { left: auto; right: 0; }
/* NOW, on today's ruler at the reader's own time. Late in the day its flag hangs to the left of the needle
   (40-home.js says so: "flip" from 7:12 PM, and "early" from 2:24 PM, which a phone heeds) */
.wk-now { position: absolute; z-index: 2; top: var(--wk-now-top); bottom: var(--wk-now-bottom); left: calc(var(--wk-n) * (100% - var(--line-w))); width: var(--line-w); background: var(--ink); }
.wk-now::after {
  content: attr(data-t); position: absolute; top: var(--wk-flag-top); left: var(--wk-flag-x); padding: 0 var(--sp-1);
  background: var(--yellow); box-shadow: var(--ring); font: var(--t-label); text-transform: uppercase; white-space: nowrap;
}
.wk-now[data-state~="flip"]::after { left: auto; right: var(--wk-flag-x); }
@media (max-width: 767px) { .wk-now[data-state~="early"]::after { left: auto; right: var(--wk-flag-x); } }

/* a row: one recap, one stop on the deck's tape. The whole row is its link's target. */
.wk-slot {
  display: grid; grid-template-columns: var(--wk-row-cols); gap: var(--wk-row-gap); align-items: center;
  min-height: var(--wk-row-min); padding: var(--wk-row-pad); margin-inline: calc(-1 * var(--wk-row-out));
  scroll-margin-top: calc(var(--deck-h) + var(--sp-4));
}
.wk-slot:focus-within { outline: var(--line-w-thick) solid var(--ink); outline-offset: 0; background: var(--paper); }
.wk-slot[data-state~="cue"]::before {
  content: ''; position: absolute; left: var(--wk-cue-x); top: var(--wk-cue-y); width: var(--wk-cue-w); height: var(--wk-cue-h);
  background: var(--yellow); box-shadow: var(--ring);
}
.wk-time { font: var(--wk-time-font); white-space: nowrap; }
.wk-ap { font-size: var(--wk-ap-size); line-height: var(--wk-ap-line); }
.wk-len { justify-self: end; display: flex; flex-wrap: wrap; gap: var(--sp-1); font: var(--t-label); text-transform: uppercase; white-space: nowrap; }
.wk-chip { padding: 0 var(--sp-1); background: var(--silver); border: var(--line); }
.wk-parts { background: var(--paper); }
.wk-title { grid-column: 1 / -1; font: 700 var(--wk-title-size)/var(--wk-title-line) var(--sans); letter-spacing: var(--wk-title-track); overflow-wrap: anywhere; }
.wk-a { text-decoration: none; scroll-margin-block: calc(var(--deck-h) + var(--sp-10)) var(--wk-a-below); }
/* The whole row is its link's to press, and that place stays where the row rests while the row lifts (press
   says how far it has moved: --pr-at), so a press on the row's last pixels still goes to the recap. */
.wk-a::after {
  content: ''; position: absolute; inset: var(--lift);
  transform: translate(calc(-1 * var(--pr-at, 0px)), calc(-1 * var(--pr-at, 0px))); transition: transform var(--press);
}
.wk-a:focus-visible { outline: 0; }
.wk-meta { min-width: 0; font: 600 var(--wk-meta-size)/var(--sp-5) var(--sans); }
.wk-tags { display: none; font: var(--t-label); text-transform: uppercase; }
.wk-rx { justify-self: end; display: flex; align-items: center; gap: var(--sp-2); font: var(--t-label); white-space: nowrap; }
.wk-rx-bar { display: block; height: var(--wk-rx-h); width: calc(var(--wk-w) * var(--wk-rx-unit)); min-width: var(--line-w); background: var(--ink); }
.wk-peak .wk-rx-bar { background: var(--yellow); box-shadow: var(--ring); }
@media (hover: hover) {
  .wk-slot:hover { background: var(--paper); z-index: 1; }
  .wk-slot:hover::after { display: none; }
}

/* nothing matches the search, or nothing has aired */
.wk-none, .wk-empty { margin-top: var(--sp-8); padding: var(--sp-6); display: grid; gap: var(--sp-2); justify-items: start; }
.wk-none-h { font: var(--t-h3); }
/* the studio's window beside the heading, from 1024px only; below that its holder in the heading goes too (no empty row) */
.wk-window { margin-bottom: var(--sp-2); }
@media (max-width: 1023px) { .wk-window, .sc-aside:has(> .wk-window) { display: none; } }

@media (min-width: 768px) {
  .wk-week {
    --wk-row-cols: 96px minmax(0, 1fr) 72px 104px; --wk-row-gap: var(--sp-px) var(--sp-4); --wk-row-pad: 14px var(--sp-4) var(--sp-4);
    --wk-row-out: var(--sp-4); --wk-row-min: 72px; --wk-cue-x: 0px; --wk-cue-y: var(--sp-4); --wk-title-size: 20px;
  }
  .wk-time { grid-row: 1 / span 2; align-self: start; padding-top: var(--sp-px); }
  .wk-title { grid-column: 2; grid-row: 1; }
  .wk-meta { grid-column: 2; grid-row: 2; display: flex; flex-wrap: wrap; gap: 0 var(--sp-3); align-items: baseline; }
  .wk-tags { display: inline; }
  .wk-len { grid-column: 3; grid-row: 1 / span 2; justify-self: start; align-self: center; }
  .wk-rx { grid-column: 4; grid-row: 1 / span 2; justify-self: stretch; justify-content: flex-end; }
}
@media (min-width: 1024px) {
  .wk-week { --wk-days-gap: 72px; --wk-day-gap: var(--sp-6); --wk-wd-size: 40px; --wk-wd-line: 40px; }
  .wk-day { grid-template-columns: var(--wk-head-col) minmax(0, 1fr); align-items: start; }
  .wk-head { position: sticky; top: calc(var(--deck-h) + var(--sp-6)); display: grid; gap: var(--sp-2); justify-content: start; }
}
@media (min-width: 1280px) { .wk-week { --wk-head-col: 208px; --wk-day-gap: var(--sp-8); --wk-row-cols: 112px minmax(0, 1fr) 80px 168px; --wk-rx-unit: 1px; } }
@media (min-width: 1600px) { .wk-week { --wk-head-col: 320px; --wk-wd-size: 56px; --wk-wd-line: 56px; --wk-title-size: 22px; --wk-title-line: 28px; --wk-meta-size: 15px; } }

/* A run of rows that is not a week (weekRows: a host's, a show's or a subject's every Space). Each row
   says its day in the pixel face where a week's says its time, the subjects show on a phone too, and
   from 1024px the day takes the width of the week's day heads, so the titles stand where home's do. */
.wk-flat { --wk-list-top: var(--sp-2); --wk-dated-top: 6px; }
.wk-list { margin-top: var(--wk-list-top); }
.wk-dated { font: var(--t-label); text-transform: uppercase; }
.wk-flat .wk-tags { display: inline; }
@media (min-width: 768px) {
  .wk-flat { --wk-row-cols: 112px minmax(0, 1fr) 72px 104px; }
  .wk-dated { padding-top: var(--wk-dated-top); }
}
@media (min-width: 1024px) { .wk-flat { --wk-row-cols: 168px minmax(0, 1fr) 72px 104px; } }
@media (min-width: 1280px) { .wk-flat { --wk-row-cols: 208px minmax(0, 1fr) 80px 168px; } }


/* ---- shelf ---- */
/* New on the shelf, The Studio's, standing in the house. The crop marks and
   the caption are the plate part's (bare: no frame, the marks at the shelf's
   corners). From the uprights inward it is The Studio's, on the house grid:
   steel uprights, wooden planks (a 256px row, a 48px gap), tapes standing as
   spines (the host's face on top in colour, the title down the spine, the
   length and five loudness bars at the foot), a thin day spine between days,
   the VCR with the reader's clock, the reel-to-reel whose reels turn while it
   is on screen. Beside it the robot and the label card (the panel part's
   paper); on a tablet the card lies on its side under the shelf; on a phone
   the shelf is one plank you swipe between uprights that stay put, the card
   under it. Settings first; the widths only change settings. */
.sh-shelf {
  --sh-status-font: 600 14px/24px var(--sans);
  --sh-card-col: 296px;
  --sh-row-h: 256px; --sh-row-gap: 48px;   /* a plank every 304px */
  --sh-tape-w: 58px; --sh-tape-h: 232px; --sh-tape-gap: 6px;
  --sh-initial: 400 24px/24px var(--pix);   /* a tape with no face: its host's initial, as the portrait part says it */
  --sh-pad-x: 32px;                        /* the shelf's inside, between the uprights */
  --sh-lift: -16px;                        /* a tape off the shelf */
  /* ...pulled toward the reader as it comes up: a little larger, tipped a little, with a soft shadow that lands
     further off the higher it is (Dan, 2026-10-07: the first shadow was "a bit dark"; "a little more animated with dimension") */
  --sh-lift-to: translateY(var(--sh-lift)) rotate(-2deg) scale(1.05);
  --sh-lift-shade: color-mix(in srgb, var(--ink) 26%, transparent);
  --sh-lift-cast: 8px 14px 0 var(--sh-lift-shade);
  --sh-lift-drop: var(--bevel-gun), var(--sh-lift-cast);
  --sh-rest-drop: var(--bevel-gun), 0 0 0 var(--sh-lift-shade);
  --sh-pull: .24s cubic-bezier(.2, 1.5, .4, 1);   /* up past its place and back: it was .09s in three steps */
  --sh-title-block: 36px; --sh-title-gap: 6px; --sh-title-font: 700 14px/18px var(--sans);
  --sh-lv-w: 6px;
  --sh-div-at: 0 var(--sp-1) 0 6px; --sh-div-h: 152px; --sh-div-gap: 6px;
  --sh-vcr-w: 232px; --sh-vcr-h: 52px; --sh-vcr-gap: 10px;
  --sh-clock-x: 74px; --sh-clock-y: var(--sp-2);       /* the cleared recess in the VCR's display */
  --sh-r2r-w: 170px; --sh-r2r-h: 154px; --sh-r2r-gap: var(--sp-3);
  --sh-reel-l-x: 7px; --sh-reel-l-y: 75px; --sh-reel-l-size: 76px;
  --sh-reel-r-x: 97px; --sh-reel-r-y: 74px; --sh-reel-r-size: 72px;
  --sh-reel-turn: 9.6s steps(24, end);     /* one 15 degree step every 0.4s while on screen */
  --sh-reel-fast: 4.8s;                    /* twice as fast while a quote plays */
  --sh-reel-offset: -.8s;
  --sh-held-top: 136px;                    /* the card's top under the robot on a phone and a tablet */
  --sh-robot-w: 170px; --sh-robot-h: 291px;
  --sh-robot-at: -8px auto -62px;          /* from 1024px: over the card, his hoodie behind its top edge */
  --sh-cap-room: 208px;
  --sh-title-size: 22px; --sh-title-line: 28px; --sh-title-track: -.01em; --sh-title-min: 56px;
  --sh-mini-gap: 6px; --sh-mini-track: var(--sp-2); --sh-mini-knob-y: -4px;
  --sh-mini-font: 700 9px/12px var(--sans); --sh-mini-dot: 6px;
  --sh-lab-top: 14px; --sh-title-top: 6px;
  --sh-chip-gap: 6px; --sh-rx-pad: 0 6px;
  --sh-post: linear-gradient(90deg, var(--ink) 0 2px, var(--steel-hi) 2px 4px, var(--steel) 4px 10px, var(--steel-lo) 10px 12px, var(--ink) 12px 14px);
  --sh-slots: repeating-linear-gradient(transparent 0 8px, var(--gun-hi) 8px 16px, transparent 16px 24px);
  --sh-posts: var(--sh-slots) left 13px top / 4px 24px repeat-y, var(--sh-slots) right 13px top / 4px 24px repeat-y,
    var(--sh-post) left 8px top / 14px 100% no-repeat, var(--sh-post) right 8px top / 14px 100% no-repeat;
  --sh-cast: color-mix(in srgb, var(--ink) 20%, transparent);   /* the plank's hard shadow */
  --sh-planks: repeating-linear-gradient(to bottom, transparent 0 var(--sh-row-h), var(--ink) 0 calc(var(--sh-row-h) + 2px),
    var(--wood-hi) 0 calc(var(--sh-row-h) + 6px), var(--wood) 0 calc(var(--sh-row-h) + 14px), var(--wood-lo) 0 calc(var(--sh-row-h) + 18px),
    var(--ink) 0 calc(var(--sh-row-h) + 20px), var(--sh-cast) 0 calc(var(--sh-row-h) + 28px), transparent 0 calc(var(--sh-row-h) + var(--sh-row-gap)));
  --sh-plank-h: 28px;
  --sh-plank: linear-gradient(var(--ink) 0 2px, var(--wood-hi) 2px 6px, var(--wood) 6px 14px, var(--wood-lo) 14px 18px, var(--ink) 18px 20px, var(--sh-cast) 20px 28px);
  min-width: 0;
}
.sh-status { margin-top: var(--sp-2); min-height: var(--sp-6); font: var(--sh-status-font); }
.sh-clear { padding-block: var(--sp-px); }
.sh-grid { margin-top: var(--sp-8); display: grid; gap: var(--sp-6); align-items: start; }
.sh-plate { min-width: 0; }
.sh-rack { position: relative; }
.sh-posts { display: none; }

/* the shelf: uprights at both ends, a plank under every row */
.sh-tapes {
  position: relative; isolation: isolate; display: flex; flex-wrap: wrap; align-items: flex-end; align-content: flex-start;
  gap: var(--sh-row-gap) var(--sh-tape-gap); padding: 0 var(--sh-pad-x) var(--sh-row-gap); background: var(--sh-posts);
}
.sh-tapes::before { content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none; background: var(--sh-planks); }
.sh-list { display: contents; }
.sh-item, .sh-gear { flex: none; display: flex; align-items: flex-end; height: var(--sh-row-h); }
.sh-item { scroll-margin-top: calc(var(--deck-h) + var(--sp-8)); }
/* a day's thin spine: it travels with that day's first tape left on the shelf, so it never stands alone at a plank's end */
.sh-div { flex: none; margin: var(--sh-div-at); }
.sh-div-in {
  display: block; height: var(--sh-div-h); padding: var(--sp-2) var(--sp-1); writing-mode: vertical-rl;
  background: var(--cream); border: var(--line); border-bottom: 0; font: var(--t-label); text-transform: uppercase; text-align: center; white-space: nowrap;
}
.sh-div-wd { font-weight: 400; margin-bottom: var(--sh-div-gap); padding: var(--sp-1) 0; background: var(--ink); color: var(--cream); }
.sh-gear { position: relative; }
.sh-vcr { margin-right: var(--sh-vcr-gap); }
.sh-vcr-img { width: var(--sh-vcr-w); height: var(--sh-vcr-h); max-width: none; }
.sh-clock { left: var(--sh-clock-x); bottom: var(--sh-clock-y); }
.sh-r2r { margin-left: auto; padding-left: var(--sh-r2r-gap); }
.sh-r2r-img { width: var(--sh-r2r-w); height: var(--sh-r2r-h); max-width: none; }
.sh-reel { position: absolute; max-width: none; border-radius: 50%; }
.sh-reel-l { left: var(--sh-reel-l-x); bottom: var(--sh-reel-l-y); width: var(--sh-reel-l-size); height: var(--sh-reel-l-size); }
.sh-reel-r { left: var(--sh-reel-r-x); bottom: var(--sh-reel-r-y); width: var(--sh-reel-r-size); height: var(--sh-reel-r-size); }
.sh-none { display: flex; align-items: center; justify-content: center; width: 100%; height: var(--sh-row-h); font-weight: 700; }

/* a tape, standing: the host's face, the title down the spine (turned as one piece, so an apostrophe never stands up), the length, the loudness */
.sh-tape {
  position: relative; display: flex; flex-direction: column; flex: none; width: var(--sh-tape-w); height: var(--sh-tape-h);
  padding: var(--sp-1) var(--sp-px) var(--sp-px); background: var(--gun); border: var(--line); box-shadow: var(--sh-rest-drop); transform-origin: 50% 100%;
  color: var(--ink); text-decoration: none; transition: transform var(--sh-pull), box-shadow var(--sh-pull);
}
.sh-label { flex: 1; min-height: 0; display: flex; flex-direction: column; align-items: center; background: var(--paper); border: var(--line); }
.sh-pfp { display: block; width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; border-bottom: var(--line); background: var(--tan); }
.sh-pfp-none { display: grid; place-items: center; font: var(--sh-initial); color: var(--ink); }
.sh-tape-t {
  flex: 1; min-height: 0; inline-size: 100%; block-size: var(--sh-title-block); margin: var(--sh-title-gap) 0; overflow: hidden;
  writing-mode: vertical-rl; text-orientation: sideways; font: var(--sh-title-font); overflow-wrap: anywhere;
}
.sh-dur { align-self: stretch; padding: var(--sp-px) 0; border-top: var(--line); background: var(--silver); font: var(--t-label-tight); text-align: center; white-space: nowrap; }
.sh-bars { display: flex; align-items: flex-end; justify-content: center; gap: var(--sp-px); height: var(--sp-4); padding-top: var(--sp-1); }
.sh-lv { width: var(--sh-lv-w); height: var(--sp-px); background: var(--gun-hi); }
.sh-lv-on { background: var(--idle); }
.sh-lv-on:nth-child(1) { height: calc(2 * var(--sp-px)); }
.sh-lv-on:nth-child(2) { height: calc(3 * var(--sp-px)); }
.sh-lv-on:nth-child(3) { height: calc(4 * var(--sp-px)); }
.sh-lv-on:nth-child(4) { height: calc(5 * var(--sp-px)); }
.sh-lv-on:nth-child(5) { height: calc(6 * var(--sp-px)); }
.sh-peak .sh-lv-on { background: var(--yellow); }
.sh-tape:hover, .sh-tape:focus-visible, .sh-tape[data-state~="held"] { transform: var(--sh-lift-to); z-index: 2; box-shadow: var(--sh-lift-drop); }
.sh-tape:focus-visible { outline: var(--line-w-thick) solid var(--ink); outline-offset: var(--sp-px); box-shadow: var(--bevel-gun), 0 0 0 var(--line-w) var(--yellow), var(--sh-lift-cast); }

/* the robot and the label card: the tape in your hand */
.sh-held { position: relative; min-width: 0; padding-top: var(--sh-held-top); }
.sh-robot { position: absolute; z-index: 0; right: var(--sp-4); top: 0; width: var(--sh-robot-w); height: var(--sh-robot-h); max-width: none; object-fit: contain; object-position: center bottom; }
.sh-cap {
  position: absolute; left: 0; top: 0; display: flex; align-items: flex-end; height: var(--sh-held-top); max-width: calc(100% - var(--sh-cap-room));
  padding-bottom: var(--sp-3); font: var(--t-label); text-transform: uppercase;
}
.sh-cap-touch { display: none; }
@media (hover: none) { .sh-cap-point { display: none; } .sh-cap-touch { display: inline; } }
.sh-card { position: relative; z-index: 1; }
.sh-face { padding: var(--sp-3) var(--sp-4) 0; border-bottom: var(--line-thick); background: var(--dusk); color: var(--cream); }
.sh-mini { display: flex; align-items: center; gap: var(--sh-mini-gap); }
.sh-mini-b { width: var(--sp-4); height: var(--sp-3); background: var(--silver); border: var(--line); }
.sh-mini-t { position: relative; flex: 1; height: var(--sh-mini-track); background: var(--ink); }
.sh-mini-t::before { content: ''; position: absolute; inset: var(--sp-px) 54% var(--sp-px) var(--sp-px); background: var(--yellow); }
.sh-mini-t::after { content: ''; position: absolute; left: 46%; top: var(--sh-mini-knob-y); width: var(--sp-2); height: var(--sp-4); background: var(--silver); border: var(--line); }
.sh-mini-r { display: inline-flex; align-items: center; gap: var(--sp-1); padding: 0 var(--sp-1); background: var(--silver); border: var(--line); color: var(--ink); font: var(--sh-mini-font); }
.sh-mini-dot { width: var(--sh-mini-dot); height: var(--sh-mini-dot); border-radius: 50%; background: var(--rec); }
.sh-lab { display: block; margin-top: var(--sh-lab-top); color: var(--leaf); font: var(--t-label); text-transform: uppercase; }
.sh-title {
  margin: var(--sh-title-top) 0 var(--sp-3); min-height: var(--sh-title-min); font: 700 var(--sh-title-size)/var(--sh-title-line) var(--sans);
  letter-spacing: var(--sh-title-track); text-shadow: var(--drop-1); overflow-wrap: anywhere;
}
.sh-eq { display: flex; align-items: flex-end; gap: var(--sp-px); height: var(--sp-8); border-bottom: var(--line); }
.sh-eq-i { flex: 1; height: calc(var(--sh-v) * 1%); min-height: var(--sp-px); background: var(--idle); }
.sh-eq-i[data-state~="peak"] { background: var(--yellow); }
.sh-body { display: grid; gap: var(--sp-3); padding: var(--sp-4); }
.sh-who { display: flex; align-items: center; gap: var(--sp-3); min-height: var(--sp-10); font: var(--t-ui); color: var(--muted); }
.sh-who-pfp { flex: none; width: var(--sp-10); height: var(--sp-10); border: var(--line); }
.sh-who-at { display: block; color: var(--ink); font-weight: 700; }
.sh-chips { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sh-chip-gap); min-height: var(--sp-8); }
.sh-rx { font: var(--t-ui-small); color: var(--muted); }
.sh-rx-n { display: inline-block; margin-right: var(--sp-2); padding: var(--sh-rx-pad); background: var(--cream); border: var(--line); color: var(--ink); font: var(--t-label); }
.sh-go { width: 100%; }

/* the reels turn in steps while the machine is on screen (shelf.js says "near"), faster while a quote plays */
@keyframes sh-spin { to { transform: rotate(360deg); } }
.js .sh-reel { animation: sh-spin var(--sh-reel-turn) infinite paused; }
.js .sh-reel-r { animation-delay: var(--sh-reel-offset); }
.js .sh-r2r[data-state~="near"] .sh-reel { animation-play-state: running; }
[data-audio="playing"] .sh-reel { animation-duration: var(--sh-reel-fast); }

/* a phone: one plank you swipe, between two uprights that stay put; the card under it, the robot looking over its top edge */
@media (max-width: 640px) {
  .sh-rack { padding-bottom: var(--sh-plank-h); background: var(--sh-plank) left bottom / 100% var(--sh-plank-h) no-repeat; }
  .sh-posts { display: block; position: absolute; inset: 0 0 var(--sh-plank-h); z-index: 3; pointer-events: none; background: var(--sh-posts); }
  .sh-tapes {
    flex-wrap: nowrap; height: var(--sh-row-h); padding: 0 var(--sh-pad-x); gap: 0 var(--sh-tape-gap); background: none;
    overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scroll-snap-type: x proximity; scrollbar-width: none;
  }
  .sh-tapes::-webkit-scrollbar { display: none; }
  .sh-tapes::before { content: none; }
  .sh-item { scroll-snap-align: start; scroll-margin-left: var(--sh-pad-x); }
  .sh-vcr { order: 1; margin: 0 0 0 var(--sp-4); }
  .sh-r2r { order: 2; margin-left: 0; padding-right: var(--sp-2); }
  .sh-none { position: sticky; left: 0; flex: none; width: calc(100vw - 2 * var(--gut) - 2 * var(--sh-pad-x)); }
}
/* a tablet keeps the planks and the card: under the shelf, laid on its side */
@media (min-width: 641px) and (max-width: 1023px) {
  .sh-card { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); }
  .sh-face { display: flex; flex-direction: column; border-bottom: 0; border-right: var(--line-thick); }
  .sh-title { flex: 1; }
}
/* a desktop: the robot stands at the shelf's right, above the card, and on a tall enough window both stay beside you down the shelf */
@media (min-width: 1024px) {
  .sh-grid { grid-template-columns: minmax(0, 1fr) var(--sh-card-col); }
  .sh-held { padding-top: 0; }
  .sh-robot { position: relative; right: auto; display: block; margin: var(--sh-robot-at); }
  .sh-cap { display: none; }
}
@media (min-width: 1024px) and (min-height: 760px) { .sh-held { position: sticky; top: calc(var(--deck-h) + var(--sp-4)); } }
@media (min-width: 1280px) { .sh-shelf { --sh-card-col: 328px; } }
@media print { .sh-grid { display: none !important; } }


/* ---- seek ---- */
/* The search panel: the box and its button, a subject, a host, and a line
   under them (how many recaps are showing, Show everything, and what the
   rows' black bars mean). The subject and the host need scripts, so without
   them they are not shown. What the button finds is listed in a panel of its
   own under this one: a recap a block, its title, its host and day, and up
   to three places in it, each with its time code (the timecode part's ink
   chip) and the words found, marked in the spot yellow. The paper is the
   panel part's, the fields the field part's. Settings first. */
.sk-seek {
  --sk-top: var(--sp-8);
  --sk-pad: var(--sp-4);
  --sk-hit-pad: var(--sp-3) 0 14px;
  --sk-snip-font: 400 15px/22px var(--sans);
  min-width: 0;
}
.sk-form { margin-top: var(--sk-top); padding: var(--sk-pad); display: grid; gap: var(--sp-4); }
.sk-q, .sk-filter { min-width: 0; }
html:not(.js) .sk-filter, html:not(.js) .sk-legend { display: none; }
.sk-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-2); }
.sk-foot { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); align-items: center; justify-content: space-between; font: var(--t-ui); color: var(--muted); }
.sk-foot b { color: var(--ink); }
.sk-go { font-weight: 700; color: var(--ink); }
.sk-state { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0 var(--sp-4); min-height: var(--target); }
.sk-legend { display: inline-flex; align-items: center; gap: var(--sp-2); color: var(--ink); font: var(--t-label); text-transform: uppercase; }
.sk-legend-i { display: block; width: var(--sp-6); height: var(--sp-2); background: var(--ink); }

/* what the button found */
.sk-results { margin-top: var(--sp-4); padding: var(--sk-pad); display: grid; gap: var(--sp-2); }
.sk-res-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0 var(--sp-4); font: var(--t-ui); color: var(--muted); }
.sk-res-head b { color: var(--ink); }
.sk-hit { padding: var(--sk-hit-pad); }
.sk-hit-t { font: var(--t-h5); text-decoration: none; overflow-wrap: anywhere; }
.sk-hit-t:hover { text-decoration: underline; }
.sk-hit-m { margin-top: var(--sp-1); font: var(--t-label); text-transform: uppercase; color: var(--muted); }
.sk-snip { margin-top: var(--sp-2); display: flex; gap: var(--sp-2); align-items: baseline; font: var(--sk-snip-font); }
.sk-snip-t { min-width: 0; overflow-wrap: anywhere; }
.sk-snip mark { background: var(--yellow); color: var(--ink); }

@media (min-width: 768px) {
  .sk-seek { --sk-pad: var(--sp-6); }
  .sk-form { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sk-q, .sk-foot { grid-column: 1 / -1; }
}
@media (min-width: 1024px) {
  .sk-form { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr); }
  .sk-q { grid-column: auto; }
}
@media print { .sk-seek { display: none !important; } }


/* ---- archive ---- */
/* The archive's columns: shows, subjects, then months and the other pages,
   one column on a phone, two from 768px (months and the others side by side
   under them), three from 1280px. The rows and the headings are the list
   part's. And the tape wall's plate beside the section's heading: under the
   words below 1024px, beside them from 1024px, its recorder showing the
   reader's time (the vcr part, placed here). Settings first. */
.ar-cols {
  --ar-top: var(--sp-12);
  --ar-gap: var(--sp-12) var(--sp-8);
  margin-top: var(--ar-top); display: grid; gap: var(--ar-gap);
}
.ar-col, .ar-part { min-width: 0; }
.ar-wide { display: grid; gap: var(--sp-10) var(--sp-8); align-content: start; }
@media (min-width: 768px) { .ar-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 768px) and (max-width: 1279px) { .ar-wide { grid-column: 1 / -1; grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1280px) { .ar-cols { --ar-top: var(--sp-16); --ar-gap: var(--sp-12); grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.ar-plate {
  --ar-clock-x: 104px; --ar-clock-y: 35px;   /* the cleared display of the tape wall's top recorder */
  margin-top: var(--sp-6);
}
.ar-clock { left: var(--ar-clock-x); top: var(--ar-clock-y); }
@media (min-width: 1024px) { .ar-plate { margin: 0 var(--sp-2) 0 0; } }


/* ---- hostgrid ---- */
/* The hosts grid: three across on a phone, then as many 116px columns as fit.
   A host is their printed face (the portrait part; its lift is press's), the
   name in bold and the handle and the numbers in the pixel face, each cut
   with an ellipsis rather than wrapped. The two last tiles are squares the
   face's size: the count of everyone else on cream, and the question mark on
   the spot yellow. Settings first. */
.hg-grid {
  --hg-top: 64px;
  --hg-gap: var(--sp-6) var(--sp-2);
  --hg-col: 116px;                      /* the narrowest a column may be, from 560px */
  --hg-tile: 100px;                     /* the face's size (portrait.css) */
  --hg-under: 6px;                      /* between the face and the name */
  --hg-name-font: 700 15px/20px var(--sans);
  margin-top: var(--hg-top);
}
.hg-sheet { margin-top: var(--sp-6); display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--hg-gap); }
.hg-item { min-width: 0; }
.hg-link { display: grid; gap: var(--sp-px); justify-items: start; min-width: 0; text-decoration: none; }
.hg-face, .hg-tile { margin-bottom: var(--hg-under); }
.hg-name, .hg-at, .hg-n { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hg-name { font: var(--hg-name-font); }
.hg-at, .hg-n { font: var(--t-label); text-transform: uppercase; }
.hg-tile { display: grid; place-items: center; width: var(--hg-tile); max-width: 100%; aspect-ratio: 1; border: var(--line); background: var(--cream); font: var(--t-display); }
.hg-go { background: var(--yellow); }
@media (min-width: 560px) {
  .hg-grid { --hg-gap: var(--sp-8) var(--sp-4); }
  .hg-sheet { grid-template-columns: repeat(auto-fill, minmax(var(--hg-col), 1fr)); }
}


/* ---- doors ---- */
/* Home's two doors: one under the other on a phone and a tablet, side by side
   from 1024px, each a panel with its picture across the top (3:2 on a phone,
   2:1 from 768px, cropped to fill), then the tag, the heading, the words and
   the big button. Settings first; the widths only change settings. */
.dw-doors {
  --dw-top: var(--sp-10);
  --dw-gap: var(--sp-10);
  --dw-art: 3 / 2;
  --dw-pad: var(--sp-5) var(--sp-4) var(--sp-6);
  --dw-h-size: 32px; --dw-h-line: 32px; --dw-h-track: -.035em;
  --dw-measure: 48ch;
  margin-top: var(--dw-top); display: grid; gap: var(--dw-gap);
}
.dw-door { display: grid; grid-template-rows: auto 1fr; min-width: 0; }
.dw-art { aspect-ratio: var(--dw-art); overflow: hidden; border-bottom: var(--line-thick); background: var(--ink); }
.dw-pic, .dw-img { display: block; width: 100%; height: 100%; }
.dw-img { object-fit: cover; }
.dw-body { display: grid; gap: var(--sp-3); align-content: start; justify-items: start; padding: var(--dw-pad); min-width: 0; }
.dw-h { font: 700 var(--dw-h-size)/var(--dw-h-line) var(--sans); letter-spacing: var(--dw-h-track); }
.dw-p { font: var(--t-read); max-width: var(--dw-measure); }
.dw-fine { font: var(--t-ui-medium); color: var(--muted); }
.dw-go { margin-top: var(--sp-2); }
@media (min-width: 768px) { .dw-doors { --dw-art: 2 / 1; --dw-pad: var(--sp-8); --dw-h-size: 40px; --dw-h-line: 40px; } }
@media (min-width: 1024px) { .dw-doors { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1600px) { .dw-doors { --dw-gap: var(--sp-16); --dw-pad: var(--sp-10); } }


/* ---- crumbs ---- */
/* The crumbs: steps in the pixel face, a slash between, each link a 44px
   place to press without looking like a button. Settings first. */
.cb-crumbs { --cb-top: var(--sp-2); --cb-gap: var(--sp-2); padding-top: var(--cb-top); }
.cb-list { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--cb-gap); font: var(--t-label); text-transform: uppercase; }
.cb-item { display: flex; align-items: center; gap: 0 var(--cb-gap); min-width: 0; }
.cb-link { display: inline-flex; align-items: center; min-height: var(--target); min-width: var(--target); text-decoration: none; }
.cb-link:hover { text-decoration: underline; }
.cb-here { display: inline-flex; align-items: center; min-height: var(--target); overflow-wrap: anywhere; }


/* ---- hosthead ---- */
/* The head of a host's page, a show's and a subject's, in the fireside's shape (Dan,
   2026-10-24): the printed portrait beside the name, which sits on the portrait's foot; then
   the seats on the home page's dither band: the paragraph about the room in the house's card,
   and a dark panel with the room's numbers under their pixel icons and what a reader can do.
   Stacked, the numbers run in one row; from 1080px the card and the panel stand side by side,
   as tall as each other, the numbers down the panel. Settings first; the widths only change
   settings. The plain head of the index pages is the top row and a paragraph. */
.hh-head {
  --hh-pad: var(--sp-6) 0 var(--sp-6);
  --hh-face: 132px;
  --hh-h-size: 34px; --hh-h-line: 36px; --hh-h-track: -.035em;
  --hh-blurb-size: 17px; --hh-blurb-line: 28px; --hh-measure: 68ch;
  display: grid; gap: var(--sp-5); padding: var(--hh-pad); min-width: 0;
}
.hh-top { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--sp-4) var(--sp-6); align-items: end; }
/* the house prints a face it shows large: its pixels drawn square, on cream */
.hh-face { width: var(--hh-face); height: var(--hh-face); border: var(--line); background: var(--cream); image-rendering: pixelated; box-shadow: var(--drop-2); }
.hh-h { font: 700 var(--hh-h-size)/var(--hh-h-line) var(--sans); letter-spacing: var(--hh-h-track); text-wrap: balance; overflow-wrap: anywhere; }
.hh-kicker { display: block; margin-bottom: var(--sp-3); font: var(--t-label); letter-spacing: 0; text-transform: uppercase; }
.hh-blurb { font: 500 var(--hh-blurb-size)/var(--hh-blurb-line) var(--sans); max-width: var(--hh-measure); }
.hh-note { font: var(--t-ui-medium); max-width: var(--hh-measure); }
.hh-note a { font-weight: 700; }
@media (max-width: 479px) { .hh-head { --hh-face: 96px; } }

/* ---- the seats ----------------------------------------------------------------------------- */
.hh-seats { --hh-about-font: var(--t-read); --hh-about-measure: 68ch; display: grid; gap: var(--sp-6); min-width: 0; }
/* the paragraph in the house's card: as wide as the panel under it on a tablet, its lines kept readable */
.hh-about { display: grid; gap: var(--sp-3); align-content: start; padding: var(--sp-5); min-width: 0; }
.hh-about-tag { line-height: 0; }
.hh-about-text { font: var(--hh-about-font); max-width: var(--hh-about-measure); }
.hh-feature { display: flex; flex-wrap: wrap; gap: var(--sp-3); padding-top: var(--sp-2); }
/* the panel: the fireside's night colour, its numbers each under a pixel icon in the spot yellow */
.hh-panel {
  --hh-night: var(--gun);
  --hh-tile-fill: rgba(242, 234, 216, .07);
  --hh-tile-font: 400 33px/32px var(--pix);
  display: grid; gap: var(--sp-5); align-content: center; padding: var(--sp-6); min-width: 0;
  background: var(--hh-night); color: var(--cream); border: var(--panel-line); box-shadow: var(--panel-drop);
}
.hh-tiles { --hh-cols: 2; display: grid; grid-template-columns: repeat(var(--hh-cols), minmax(0, 1fr)); gap: var(--sp-3); }
.hh-tile { display: grid; gap: var(--sp-1); align-content: start; padding: var(--sp-3); background: var(--hh-tile-fill); border: var(--line-w) solid var(--gun-hi); min-width: 0; }
.hh-tile-ic { color: var(--yellow); line-height: 0; padding-bottom: var(--sp-1); }
.hh-tile-v { font: var(--hh-tile-font); color: var(--cream); white-space: nowrap; }
.hh-tile-l { font: var(--t-ui-small); color: var(--silver); }
.hh-panel-acts { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.hh-tiles[data-n="3"] { --hh-cols: 3; }
/* on a phone the numbers run down the panel, each icon beside its number, so no label outgrows its tile */
@media (max-width: 479px) {
  .hh-panel { --hh-tile-font: 400 22px/24px var(--pix); padding: var(--sp-5); }
  .hh-tiles, .hh-tiles[data-n="3"] { --hh-cols: 1; }
  .hh-tile { grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: var(--sp-3); row-gap: 0; padding: var(--sp-2) var(--sp-3); }
  .hh-tile-ic { grid-row: span 2; padding-bottom: 0; }
}
/* a full-width panel, from a wide phone to a tablet: every number in one row */
@media (min-width: 560px) { .hh-tiles[data-n="4"] { --hh-cols: 4; } }
@media (min-width: 768px) {
  .hh-head { --hh-h-size: 56px; --hh-h-line: 56px; --hh-blurb-size: 18px; }
  .hh-seats { --hh-about-font: 400 20px/32px var(--sans); --hh-about-measure: none; }
  .hh-about { padding: var(--sp-6); }
  .hh-panel { padding: var(--sp-8); }
}
/* from 1080px: the card and the panel side by side and as tall as each other. The card takes a
   little over half, its words a little larger as the screen grows; the panel's numbers run down
   it, each with its icon beside it, unless the page picked a row for a short paragraph
   (.hh-row-lg, .hh-row-xl: hosthead.mjs panelShapes) */
@media (min-width: 1080px) {
  .hh-seats { --hh-about-size: clamp(18px, calc(18px + (100vw - 1080px) * .006), 21px); --hh-about-font: 400 var(--hh-about-size)/1.55 var(--sans); grid-template-columns: minmax(0, 11fr) minmax(0, 9fr); gap: var(--sp-8); align-items: stretch; }
  .hh-solo { grid-template-columns: minmax(0, 1fr); }
  .hh-about { align-content: center; gap: var(--sp-4); }
  /* the tiles take the panel's spare height, their words centred, so the panel has no empty band */
  .hh-panel { padding: var(--sp-6); grid-template-rows: minmax(0, 1fr) auto; align-content: stretch; }
  .hh-tiles { grid-auto-rows: 1fr; }
  .hh-tile { align-content: center; }
}
/* the numbers down the panel, each with its icon beside it: on a laptop unless the page picked a
   row for it (.hh-row-lg), wider unless it picked a row there (.hh-row-xl) */
@media (min-width: 1080px) and (max-width: 1279px) {
  .hh-seats:not(.hh-row-lg) .hh-tiles { --hh-cols: 1; }
  .hh-seats:not(.hh-row-lg) .hh-tile { grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: var(--sp-4); row-gap: 0; padding: var(--sp-2) var(--sp-4); }
  .hh-seats:not(.hh-row-lg) .hh-tile-ic { grid-row: span 2; padding-bottom: 0; }
}
@media (min-width: 1280px) {
  .hh-seats:not(.hh-row-xl) .hh-tiles { --hh-cols: 1; }
  .hh-seats:not(.hh-row-xl) .hh-tile { grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: var(--sp-4); row-gap: 0; padding: var(--sp-2) var(--sp-4); }
  .hh-seats:not(.hh-row-xl) .hh-tile-ic { grid-row: span 2; padding-bottom: 0; }
}
@media (min-width: 1280px) { .hh-head { --hh-h-size: 72px; --hh-h-line: 72px; } .hh-seats { gap: var(--sp-10); } .hh-about { padding: var(--sp-8); } }


/* ---- moments ---- */
/* A host's moments: cards on paper, two across from 768px, each lifting
   under the pointer (the press part's lift and drop). The words large, the
   credit small under them, the time in its chip. A shelf's own heading is a
   4px rule with its line at the right. Settings first. */
.hm-grid {
  --hm-top: var(--sp-8);
  --hm-gap: var(--sp-6);
  display: grid; gap: var(--hm-gap); margin-top: var(--hm-top); min-width: 0;
}
@media (min-width: 768px) { .hm-grid { --hm-gap: var(--sp-8); grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.hm-card {
  --hm-pad: var(--sp-4);
  --hm-q-size: 19px; --hm-q-line: 28px; --hm-q-track: -.01em;
  --hm-quotes: '\201C' '\201D';
  display: grid; gap: var(--sp-3); align-content: start; min-width: 0; padding: var(--hm-pad); text-decoration: none;
}
.hm-q { font: 600 var(--hm-q-size)/var(--hm-q-line) var(--sans); letter-spacing: var(--hm-q-track); quotes: var(--hm-quotes); }
.hm-by { font: var(--t-ui); color: var(--muted); }
.hm-who { color: var(--ink); }
.hm-likely { color: var(--ink); font-weight: 700; }
.hm-by .tc-chip { margin-left: var(--sp-1); }
@media (min-width: 768px) { .hm-card { --hm-pad: var(--sp-6); --hm-q-size: 22px; --hm-q-line: 32px; } }

.hm-head {
  --hm-head-top: var(--sp-16);
  --hm-head-track: -.03em;
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--sp-2) var(--sp-4);
  margin-top: var(--hm-head-top); padding-bottom: var(--sp-2); border-bottom: var(--line-thick);
}
.hm-h { font: var(--t-h2); letter-spacing: var(--hm-head-track); }
.hm-lead { font: var(--t-label); text-transform: uppercase; }


/* ---- sheet ---- */
/* A page of panels: the column they stand in on the stage, two side by side
   from 1024px, and the words a panel holds. The paper is the panel part's
   (pn-panel pn-pad on the same element), a tag the pill part's, a button the
   button part's; here only where they stand, and the type of the words. A
   heading is a step under the hero's, at the size of the door card's on a
   phone. Settings first; the widths only change settings. */
.sf-col {
  --sf-gap: var(--sp-8);
  display: grid; gap: var(--sf-gap); min-width: 0;
}
@media (min-width: 768px) { .sf-col { --sf-gap: var(--sp-10); } }

/* Two side by side (Free and Plus, the support page's doors): one under the other below 1024px,
   one across whatever the width when a script says solo. Even: both as tall as the taller,
   the lead taking the slack so the two buttons stand on one line. */
.sf-pair {
  --sf-pair-gap: var(--sp-8);
  display: grid; gap: var(--sf-pair-gap); align-items: start; min-width: 0;
}
@media (min-width: 1024px) { .sf-pair { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.sf-pair[data-state~="solo"] { grid-template-columns: minmax(0, 1fr); }
.sf-even { align-items: stretch; }
.sf-even .sf-lead { flex-grow: 1; }

/* A panel: its words one under the other, the house's 12px between. Long words (an address,
   a wallet, a handle) break rather than push the page sideways. */
.sf-panel, .sf-stack {
  --sf-in: var(--sp-3);
  display: flex; flex-direction: column; gap: var(--sf-in); min-width: 0; overflow-wrap: anywhere;
}
.sf-tag { line-height: 0; }

.sf-h {
  --sf-h-size: 28px; --sf-h-line: 32px; --sf-h-track: -.025em;
  font: 700 var(--sf-h-size)/var(--sf-h-line) var(--sans); letter-spacing: var(--sf-h-track); text-wrap: balance;
}
.sf-lead {
  --sf-lead-size: 17px; --sf-lead-line: 28px; --sf-measure: 56ch;
  font: 400 var(--sf-lead-size)/var(--sf-lead-line) var(--sans); max-width: var(--sf-measure); text-wrap: pretty;
}
.sf-text { --sf-text-measure: 64ch; font: var(--t-body); max-width: var(--sf-text-measure); }
.sf-fine { --sf-fine-measure: 64ch; font: var(--t-ui-medium); color: var(--muted); max-width: var(--sf-fine-measure); }
.sf-lead a, .sf-text a, .sf-fine a, .sf-say a, .sf-flag a, .sf-point a { color: var(--ink); font-weight: 700; }
.sf-fine code, .sf-text code { --sf-code: 400 13px/20px var(--code); font: var(--sf-code); }
@media (min-width: 768px) {
  .sf-h { --sf-h-size: 32px; --sf-h-line: 36px; }
  .sf-lead { --sf-lead-size: 18px; }
}
@media (min-width: 1280px) {
  .sf-h { --sf-h-size: 40px; --sf-h-line: 44px; --sf-h-track: -.03em; }
  .sf-lead { --sf-lead-size: 20px; --sf-lead-line: 32px; }
}

/* What a tier gives: a printed square at each line's start. */
.sf-points { --sf-bullet: var(--sp-2); --sf-bullet-in: var(--sp-6); --sf-bullet-top: var(--sp-2); --sf-point-measure: 64ch; display: grid; gap: var(--sp-2); font: var(--t-body); }
.sf-point { position: relative; padding-left: var(--sf-bullet-in); max-width: var(--sf-point-measure); }
.sf-point::before { content: ''; position: absolute; left: 0; top: var(--sf-bullet-top); width: var(--sf-bullet); height: var(--sf-bullet); background: var(--ink); }

/* A price: the figure in the pixel face, at one of its four sizes. */
.sf-price { --sf-price: 400 44px/48px var(--pix); font: var(--sf-price); }
.sf-per { margin-left: var(--sp-1); font: var(--t-ui); color: var(--muted); }

/* A row of buttons, clear of the words above by the button's own drop. */
.sf-acts { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3) var(--sp-4); margin-top: var(--sp-1); }

/* The answer a page gives, at reading size. A block, not a grid: the answer is a sentence with
   its bold and its link in it, which a grid would set one piece a row. What a script puts in it
   as blocks (the question, a button, small print) stands one under the other. */
.sf-say { font: var(--t-read); }
.sf-say > * + * { margin-top: var(--sp-3); }

/* A warning: the spot yellow on a card's line and drop, its first line in bold. */
.sf-warn { background: var(--yellow); border: var(--card-line); box-shadow: var(--card-drop); padding: var(--sp-4); }
.sf-warn-h { font: var(--t-h6); }
.sf-warn-t { margin-top: var(--sp-2); font: var(--t-body); }

/* A line between panels on the panel part's card (You're on Listener Plus). */
.sf-flag { padding: var(--sp-3) var(--sp-4); font: var(--t-body-strong); }


/* ---- form ---- */
/* A form's row: the box (the field part's) grows, the button (the button
   part's) keeps its size and stands as tall as the box, the two no wider
   than an address needs. Too narrow for both, the row wraps: the box the
   width, the button under it. The answer line in bold under them. The trap
   for bots, out of sight. Settings first. */
.fm-row { --fm-max: 640px; display: flex; flex-wrap: wrap; align-items: stretch; gap: var(--sp-3); min-width: 0; max-width: var(--fm-max); }
.fm-box { flex: 1 1 220px; }
.fm-row > .bt-button { flex: none; }
.fm-msg { font: var(--t-body-strong); font-weight: 700; overflow-wrap: anywhere; }
.fm-msg a { color: var(--ink); }
/* Where today's page put it, by its own inline style: far off the left edge, a pixel square, clear. */
.fm-trap { --fm-away: -9999px; --fm-dot: 1px; position: absolute; left: var(--fm-away); width: var(--fm-dot); height: var(--fm-dot); opacity: 0; }


/* ---- picker ---- */
/* Choosing hosts and subjects. A pill is a button on white with an ink
   line, 44px tall, that rests flat and lifts under the pointer (the press
   part's); picked, it takes the spot yellow. A host we no longer cover has a
   dashed line and muted words. A group the reader has set aside (everyone is
   picked) is dimmed. The hosts' box is drawn as the field part's select is,
   with the house caret; its list opens under it on panel paper, a dotted rule
   between the hosts. Settings first. */
.pk-label { font: var(--t-label); text-transform: uppercase; }
.pk-pills { display: flex; flex-wrap: wrap; gap: var(--sp-2); min-width: 0; }
.pk-pill {
  --pk-h: var(--target);
  --pk-pad: var(--sp-3);
  display: inline-flex; align-items: center; min-height: var(--pk-h); max-width: 100%; padding: 0 var(--pk-pad);
  border: var(--line); background: var(--white); color: var(--ink); font: var(--t-ui); text-align: left; overflow-wrap: anywhere;
}
.pk-pill[aria-pressed="true"] { background: var(--yellow); }
.pk-pill[data-state~="lapsed"] { border-style: dashed; background: var(--white); color: var(--muted); }   /* white even while still picked, as today */
.pk-pills[data-state~="dim"], .pk-sel[data-state~="dim"] { opacity: .45; }
.pk-count { font: var(--t-ui-medium); color: var(--muted); }

/* The hosts' box. */
.pk-sel { position: relative; min-width: 0; }
.pk-trigger {
  --pk-caret-room: 40px;
  --pk-caret-at: 14px;
  --pk-placeholder: #6b6557;
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); min-height: var(--target-row);
  padding: var(--sp-2) var(--pk-caret-room) var(--sp-2) var(--sp-3);
  background: var(--white) var(--caret) no-repeat right var(--pk-caret-at) center / var(--caret-size);
  border: var(--line); color: var(--ink); font: var(--t-ui-medium); cursor: pointer;
}
.pk-trigger:focus-visible, .pk-trigger[aria-expanded="true"] { outline: var(--line-w-thick) solid var(--ink); outline-offset: 0; box-shadow: var(--sp-1) var(--sp-1) 0 var(--yellow); }
.pk-ph { color: var(--pk-placeholder); }
.pk-chips { display: contents; }
.pk-chip { display: inline-flex; align-items: center; gap: var(--sp-1); padding: var(--sp-px) var(--sp-2); border: var(--line); background: var(--yellow); font: var(--t-ui-small); }
.pk-chip-face { --pk-chip-face: 16px; display: block; width: var(--pk-chip-face); height: var(--pk-chip-face); object-fit: cover; }
.pk-x { padding: 0 var(--sp-1); font-weight: 700; cursor: pointer; }

/* The list of hosts under the box is the dropdown part's (site/ui/parts/dropdown). */


/* ---- copy ---- */
/* Words to copy, and their button. The words stand in a box drawn as the
   field part's is (white, an ink line, a field's height), in the code face,
   breaking anywhere (a wallet is one long word); the button the button
   part's, beside them. Settings first. */
.cp-row {
  --cp-text: 400 14px/20px var(--code);
  --cp-max: 64ch;
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); min-width: 0; max-width: var(--cp-max);
}
.cp-before { display: inline-flex; align-items: center; gap: var(--sp-1); flex: none; }
.cp-before svg { display: block; }
.cp-text {
  flex: 0 1 auto; min-width: 0; min-height: var(--target-row); display: flex; align-items: center;
  padding: var(--sp-2) var(--sp-3); background: var(--white); border: var(--line); font: var(--cp-text); word-break: break-all;
}
.cp-row > .cp-go { flex: none; }
html:not(.js) .cp-go { display: none; }


/* ---- cal ---- */
/* The calendar's pieces. The Spaces coming up: rows on the list part's
   dotted rules, when at the left from 768px and the two buttons at the right
   from 1024px. The legend. A month: its heading (the list part's), the days
   of the week in the pixel face, a day a paper square with an ink line, today
   on the spot yellow, the day's Spaces as faces that lift under the pointer
   (the press part's); one still to come ringed yellow inside its ink line,
   its face softened. Settings first; the widths only change settings. */
.cl-up { --cl-when-w: 136px; }
.cl-row { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-2) var(--sp-4); padding: var(--sp-4) 0; }
.cl-when { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--sp-2); }
.cl-day-t { font: var(--t-h6); }
.cl-time { font: var(--t-label); text-transform: uppercase; color: var(--muted); }
.cl-what { min-width: 0; }
.cl-title { font: var(--t-h5); overflow-wrap: anywhere; }
.cl-host { display: flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-1); font: var(--t-ui); color: var(--muted); overflow-wrap: anywhere; }
.cl-face { --cl-face: 20px; flex: none; width: var(--cl-face); height: var(--cl-face); border: var(--line); object-fit: cover; }
.cl-acts { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
@media (min-width: 768px) {
  .cl-row { grid-template-columns: var(--cl-when-w) minmax(0, 1fr); }
  .cl-when { flex-direction: column; gap: var(--sp-1); }
  .cl-acts { grid-column: 2; }
}
@media (min-width: 1024px) {
  .cl-row { grid-template-columns: var(--cl-when-w) minmax(0, 1fr) auto; align-items: center; }
  .cl-acts { grid-column: auto; }
}

.cl-legend { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-6); margin-top: var(--sp-6); font: var(--t-ui); }
.cl-key { display: inline-flex; align-items: center; gap: var(--sp-2); }
.cl-dot { display: block; width: var(--sp-4); height: var(--sp-4); background: var(--paper); border: var(--line); }
.cl-dot-up { border-color: var(--yellow); box-shadow: var(--ring); }

.cl-month { margin-top: var(--sp-10); }
.cl-grid {
  --cl-gap: var(--sp-1);
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--cl-gap); margin-top: var(--sp-3);
}
.cl-dow { font: var(--t-label); text-align: center; }
.cl-day {
  --cl-day-h: 64px;
  --cl-pad: var(--sp-1);
  --cl-img: 20px;
  display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; min-height: var(--cl-day-h); padding: var(--cl-pad);
  background: var(--paper); border: var(--line);
}
.cl-day[data-state~="today"] { background: var(--yellow); }
.cl-empty { min-height: 0; background: none; border: 0; }
.cl-date { font: var(--t-label-tight); color: var(--muted); }
.cl-day[data-state~="today"] .cl-date { color: var(--ink); }
.cl-marks { display: flex; flex-wrap: wrap; gap: var(--sp-px); }
.cl-mark { display: block; line-height: 0; border: var(--line); }
.cl-img { display: block; width: var(--cl-img); height: var(--cl-img); object-fit: cover; }
.cl-mark-up .cl-img { border: var(--line-w) solid var(--yellow); opacity: .72; }
.cl-mark-up:hover .cl-img { opacity: 1; }
/* From 1024px a day is wide: larger faces, five or six to a row. */
@media (min-width: 1024px) { .cl-day { --cl-img: 24px; } }
/* On a phone a day is narrow: smaller faces, two to a row from 360px. */
@media (max-width: 767px) {
  .cl-day { --cl-day-h: 56px; --cl-pad: var(--sp-px); --cl-img: 14px; }
}
@media (max-width: 359px) { .cl-grid { --cl-gap: var(--sp-px); } }


/* ---- notes ---- */
/* A week of re:lease notes inside the reading panel (the rdoc part's): the
   version and the week, the title on the panel's heading chip, the notes each
   led by a kind chip in the pixel face, the chips in a column as wide as the
   longest word (IMPROVED) so every note's words start on one line (on a phone
   the chip stands over its note), and the thanks under the list part's
   dotted rule. Settings first. */
.nt-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); margin-bottom: var(--sp-3); }
.nt-week { font: var(--t-label); text-transform: uppercase; color: var(--muted); }
.nt-list { display: grid; gap: var(--sp-3); }
.nt-note {
  --nt-kind-w: calc(8 * var(--pix-advance) + 2 * var(--sp-2) + 2 * var(--line-w));
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-1) var(--sp-3); align-items: baseline;
}
/* On a phone the chip stands over its note, so the note keeps the panel's width; beside it from 768px. */
@media (min-width: 768px) { .nt-note { grid-template-columns: var(--nt-kind-w) minmax(0, 1fr); } }
.nt-kind { justify-self: start; padding: 0 var(--sp-2); border: var(--line); background: var(--cream); font: var(--t-label); text-transform: uppercase; white-space: nowrap; }
.nt-kind[data-kind="new"] { background: var(--yellow); }
.nt-kind[data-kind="fixed"] { background: var(--silver); }
.nt-text { --nt-measure: 76ch; min-width: 0; max-width: var(--nt-measure); overflow-wrap: anywhere; }
.nt-thanks { margin-top: var(--sp-6); padding-top: var(--sp-4); font: var(--t-voice); }


/* ---- hub ---- */
/* A hub's columns: one on a phone, two from 768px, three from 1280px (a page
   with two leaves the third empty, as the prototype's host page does). The
   headings and rows are the list part's. Settings first. */
.hb-cols {
  --hb-top: var(--sp-8);
  --hb-gap: var(--sp-12) var(--sp-8);
  margin-top: var(--hb-top); display: grid; gap: var(--hb-gap); min-width: 0;
}
.hb-col { min-width: 0; }
@media (min-width: 768px) { .hb-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1280px) { .hb-cols { --hb-gap: var(--sp-12); grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* An index's one long list, in columns: one on a phone, two from 768px, three from 1280px. A row
   never breaks across two. */
.hb-list { --hb-list-top: var(--sp-8); --hb-list-cols: 1; margin-top: var(--hb-list-top); min-width: 0; }
.hb-list > .ls-list { column-count: var(--hb-list-cols); column-gap: var(--sp-8); }
.hb-list .ls-item { break-inside: avoid; }
@media (min-width: 768px) { .hb-list { --hb-list-cols: 2; } }
@media (min-width: 1280px) { .hb-list { --hb-list-cols: 3; } .hb-list > .ls-list { column-gap: var(--sp-12); } }


/* ---- pulse ---- */
/* The pulse of a room: a panel under the recap, the minutes as pairs of bars
   in a strip that scrolls on its own (a long room is wider than any screen):
   the reactions in sage, the loudest three minutes lit, the people behind
   them in grey beside. Settings first. */
.pu-pulse { --pu-top: var(--sp-10); margin-top: var(--pu-top); }
.pu-panel { display: grid; gap: var(--sp-3); min-width: 0; }
.pu-h { font: var(--t-h2); letter-spacing: var(--track-display); }
.pu-lead { --pu-measure: 60ch; font: var(--t-read); max-width: var(--pu-measure); }
.pu-scroll { --pu-pad: var(--sp-2) var(--sp-2) var(--sp-1); overflow-x: auto; border: var(--line); background: var(--cream); padding: var(--pu-pad); }
.pu-chart {
  --pu-chart-h: 120px; --pu-r-w: 7px; --pu-p-w: var(--sp-1);
  display: flex; align-items: flex-end; gap: var(--sp-px); height: var(--pu-chart-h); min-width: 100%; width: max-content;
}
.pu-col { display: flex; align-items: flex-end; gap: var(--sp-px); height: 100%; flex: none; }
.pu-r, .pu-p { display: block; height: calc(var(--pu-h) * 1%); }
.pu-r { width: var(--pu-r-w); background: var(--sage); }
.pu-hot { background: var(--yellow); box-shadow: var(--ring); }
.pu-p { width: var(--pu-p-w); background: var(--muted); }
.pu-legend { font: var(--t-label); text-transform: uppercase; color: var(--muted); }
.pu-key { --pu-key: 10px; display: inline-block; width: var(--pu-key); height: var(--pu-key); margin-right: var(--sp-1); vertical-align: baseline; }
.pu-key-r { background: var(--sage); }
.pu-key-p { background: var(--muted); }


/* ---- fireside ---- */
/* Jed's Fireside: the hearth (a night panel with its pixel campfire), then the run of firesides,
   newest first, the full width of the page on a line down its left. A fireside is a card with a
   ticket stub (its number in the pixel face on yellow, its date in bold), and a lost one is an
   ember. Each comes on in four steps of dither as it scrolls into view (fireside.js).
   Settings first; the widths only change settings. */

/* ---- the head: the name over the seats (the bio card and the hearth), which stand on the
   home page's dither band (the stage part) ---------------------------------------------------- */
.fs-head {
  --fs-h-size: 34px; --fs-h-line: 36px; --fs-h-track: -.035em;
  --fs-face: 132px;
  padding: var(--sp-6) 0 var(--sp-6); min-width: 0;
}
.fs-head-top { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--sp-4) var(--sp-6); align-items: end; }
/* the house prints a face it shows large: its pixels drawn square, on cream */
.fs-head-face { width: var(--fs-face); height: var(--fs-face); border: var(--line); background: var(--cream); image-rendering: pixelated; box-shadow: var(--drop-2); }
.fs-head-h { font: 700 var(--fs-h-size)/var(--fs-h-line) var(--sans); letter-spacing: var(--fs-h-track); text-wrap: balance; overflow-wrap: anywhere; }
.fs-kicker { display: block; margin-bottom: var(--sp-3); font: var(--t-label); letter-spacing: 0; text-transform: uppercase; }
.fs-seats { --fs-bio-measure: 64ch; --fs-bio-font: var(--t-read); display: grid; gap: var(--sp-6); min-width: 0; }
/* a short bio of the host, in the house's card: as wide as the hearth under it on tablets, the
   line length kept readable */
.fs-bio { display: grid; gap: var(--sp-3); align-content: start; padding: var(--sp-5); }
.fs-bio-tag { line-height: 0; }
.fs-bio-text { font: var(--fs-bio-font); max-width: var(--fs-bio-measure); }
.fs-seats-aside { min-width: 0; display: grid; }
@media (max-width: 479px) { .fs-head { --fs-face: 96px; } }
@media (min-width: 768px) {
  .fs-head { --fs-h-size: 56px; --fs-h-line: 56px; }
  /* stacked on a tablet the bio fills its card, in a larger size so its lines stay a good length */
  .fs-seats { --fs-bio-font: 400 20px/32px var(--sans); --fs-bio-measure: none; }
  .fs-bio { padding: var(--sp-6); }
}
@media (min-width: 900px) { .fs-seats { --fs-bio-font: 400 22px/34px var(--sans); } }
/* from 1080px: the bio and the hearth side by side, as tall as each other, the fire beside its numbers */
@media (min-width: 1080px) {
  /* the hearth's height is set by its two rows of tiles; the bio's by how many lines it runs to. Two
     fifths of the width for the bio and its size growing with the screen (20px at 1080, 24px from
     1600) keep the two cards about as tall as each other at every width (Dan: "balanced so no
     excess negative space") */
  .fs-seats { --fs-bio-size: clamp(20px, calc(20px + (100vw - 1080px) * .008), 24px); --fs-bio-font: 400 var(--fs-bio-size)/1.5 var(--sans); grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: var(--sp-8); align-items: stretch; }
  .fs-seats .fs-hstats { --fs-hstat-cols: 2; }
  .fs-bio { align-content: center; gap: var(--sp-4); padding: var(--sp-6); }
  .fs-seats .fs-hearth { --fs-art: 128px; margin-top: 0; align-content: center; gap: var(--sp-6); padding: var(--sp-6); }
}
@media (min-width: 1280px) {
  .fs-head { --fs-h-size: 72px; --fs-h-line: 72px; }
  .fs-seats { gap: var(--sp-10); }
}

/* ---- the hearth -------------------------------------------------------------------------- */
.fs-hearth {
  --fs-night: var(--gun);
  --fs-art: 112px;
  --fs-cycle: .54s;                 /* one turn of the three flame frames */
  --fs-rise: 2.8s;                  /* a spark from the fire to the top */
  --fs-rise-b: .9s; --fs-rise-c: 1.8s;
  --fs-hearth-font: 700 30px/34px var(--sans);
  --fs-hearth-measure: 52ch;
  display: grid; gap: var(--sp-5); justify-items: start; align-items: center;
  padding: var(--sp-6);
  background: var(--fs-night); color: var(--cream);
  border: var(--panel-line); box-shadow: var(--panel-drop);
}
.fs-art { width: var(--fs-art); justify-self: center; }
.fs-fire { display: block; width: 100%; height: auto; overflow: visible; }
.fs-o { fill: var(--rec); }
.fs-r { fill: var(--warn); }
.fs-y { fill: var(--yellow); }
.fs-h { fill: var(--yellow-hi); }
.fs-w { fill: var(--wood); }
.fs-wh { fill: var(--wood-hi); }
.fs-wl { fill: var(--wood-lo); }
.fs-frame { opacity: 0; animation-duration: var(--fs-cycle); animation-iteration-count: infinite; animation-timing-function: steps(1, end); }
.fs-frame-a { animation-name: fs-a; }
.fs-frame-b { animation-name: fs-b; }
.fs-frame-c { animation-name: fs-c; }
.fs-spark { opacity: 0; animation: fs-rise var(--fs-rise) linear infinite; }
.fs-spark-b { animation-delay: var(--fs-rise-b); }
.fs-spark-c { animation-delay: var(--fs-rise-c); }
@keyframes fs-a { 0% { opacity: 1; } 33.33% { opacity: 0; } 100% { opacity: 0; } }
@keyframes fs-b { 0% { opacity: 0; } 33.33% { opacity: 1; } 66.66% { opacity: 0; } 100% { opacity: 0; } }
@keyframes fs-c { 0% { opacity: 0; } 66.66% { opacity: 1; } 100% { opacity: 1; } }
@keyframes fs-rise { 0% { transform: translateY(10px); opacity: 0; } 20% { opacity: 1; } 100% { transform: translateY(-2px); opacity: 0; } }
.fs-hearth-words { display: grid; gap: var(--sp-3); min-width: 0; justify-self: stretch; }
.fs-tag { line-height: 0; }
.fs-hearth-h { font: var(--fs-hearth-font); letter-spacing: var(--track-display); text-wrap: balance; }
.fs-hearth-lead { font: var(--t-read); max-width: var(--fs-hearth-measure); }
.fs-hearth-lead a { color: var(--yellow-hi); font-weight: 700; }
.fs-hearth-lead b { color: var(--yellow-hi); }
.fs-hearth-go { display: flex; padding-top: var(--sp-1); }
/* the run's numbers, each under its pixel icon in the spot yellow, two across */
.fs-hstats {
  --fs-hstat-fill: rgba(242, 234, 216, .07);
  --fs-hstat-font: 400 33px/32px var(--pix);
  --fs-hstat-cols: 2;
  display: grid; grid-template-columns: repeat(var(--fs-hstat-cols), minmax(0, 1fr)); gap: var(--sp-3); width: 100%; padding-top: var(--sp-1);
}
.fs-hstat { display: grid; gap: var(--sp-1); align-content: start; padding: var(--sp-3); background: var(--fs-hstat-fill); border: var(--line-w) solid var(--gun-hi); min-width: 0; }
.fs-hstat-ic { color: var(--yellow); line-height: 0; padding-bottom: var(--sp-1); }
.fs-hstat-v { font: var(--fs-hstat-font); color: var(--cream); white-space: nowrap; }
/* on a phone the numbers step down a pixel size so a number never splits across two lines */
@media (max-width: 479px) { .fs-hstats { --fs-hstat-font: 400 22px/24px var(--pix); } }
/* a full-width hearth, from a wide phone to a tablet: the four in one row */
@media (min-width: 560px) { .fs-hstats { --fs-hstat-cols: 4; } }
.fs-hstat-l { font: var(--t-ui-small); color: var(--silver); }
@media (min-width: 768px) {
  .fs-hearth { --fs-art: 128px; --fs-hearth-font: 700 40px/44px var(--sans); grid-template-columns: auto minmax(0, 1fr); gap: var(--sp-6); padding: var(--sp-6); }
}
@media (min-width: 900px) {
  .fs-hearth { gap: var(--sp-8); padding: var(--sp-8); }
}

/* ---- the run: full width, on a line down its left ------------------------------------------ */
.fs-list {
  --fs-rail-x: 10px;                /* where the line runs, from the list's left */
  --fs-rail-pad: 32px;              /* the cards' room to its right */
  --fs-dot: 14px;
  --fs-dot-top: 28px;
  /* the dissolve: three dither tiles, 2 by 2 art pixels at 2px each, as masks (black shows) */
  --fs-d25: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='2' height='2' shape-rendering='crispEdges'%3E%3Crect width='1' height='1'/%3E%3C/svg%3E");
  --fs-d50: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='2' height='2' shape-rendering='crispEdges'%3E%3Crect width='1' height='1'/%3E%3Crect x='1' y='1' width='1' height='1'/%3E%3C/svg%3E");
  --fs-d75: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='2' height='2' shape-rendering='crispEdges'%3E%3Crect width='2' height='1'/%3E%3Crect y='1' width='1' height='1'/%3E%3C/svg%3E");
  --fs-tile: 4px 4px;
  --fs-in-time: .42s;               /* the whole entrance: four dither steps and a stepped rise */
  position: relative; display: grid; gap: var(--sp-6);
  margin-top: var(--sp-8); padding-left: var(--fs-rail-pad);
}
.fs-list::before {
  content: ''; position: absolute; top: var(--sp-4); bottom: var(--sp-4); left: var(--fs-rail-x);
  border-left: var(--line-w) dashed var(--ink);
}
.fs-item { position: relative; min-width: 0; }
/* a square ember on the line beside each fireside: lit for a saved one, cold for a lost one */
.fs-item::before {
  content: ''; position: absolute; top: var(--fs-dot-top);
  left: calc(var(--fs-rail-x) - var(--fs-rail-pad) - var(--fs-dot) / 2 + var(--line-w) / 2);
  width: var(--fs-dot); height: var(--fs-dot);
  background: var(--yellow); border: var(--line); box-shadow: var(--drop-1);
}
.fs-item-ember::before { background: var(--sage-lo); box-shadow: none; }
@media (min-width: 768px) { .fs-list { --fs-rail-x: 14px; --fs-rail-pad: 48px; --fs-dot: 16px; --fs-dot-top: 34px; } }

/* ---- the entrance: waiting below the window, then four steps of dither and a stepped rise ---- */
.fs-item[data-state~="wait"] { opacity: 0; }
.fs-item[data-state~="in"] {
  -webkit-mask-size: var(--fs-tile); mask-size: var(--fs-tile);
  -webkit-mask-repeat: repeat; mask-repeat: repeat;
  animation: fs-in var(--fs-in-time) steps(1, end) both;
}
@keyframes fs-in {
  0% { opacity: 0; transform: translateY(24px); }
  12% { opacity: 1; transform: translateY(18px); -webkit-mask-image: var(--fs-d25); mask-image: var(--fs-d25); }
  37% { opacity: 1; transform: translateY(12px); -webkit-mask-image: var(--fs-d50); mask-image: var(--fs-d50); }
  62% { opacity: 1; transform: translateY(6px); -webkit-mask-image: var(--fs-d75); mask-image: var(--fs-d75); }
  87% { opacity: 1; transform: translateY(0); -webkit-mask-image: none; mask-image: none; }
  100% { opacity: 1; transform: none; -webkit-mask-image: none; mask-image: none; }
}
@media (prefers-reduced-motion: reduce) {
  .fs-frame { animation: none; }
  .fs-frame-a { opacity: 1; }
  .fs-spark { animation: none; opacity: 0; }
  .fs-item[data-state~="wait"] { opacity: 1; }
  .fs-item[data-state~="in"] { animation: none; }
}

/* ---- a fireside: the stub, who, the quote, the way on ------------------------------------------ */
.fs-card, .fs-ember {
  --fs-pad: var(--sp-4);
  --fs-measure: 62ch;
  --fs-face-small: 72px;
  --fs-stub-w: 168px;
  display: grid; grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "stub" "main" "quote" "go";
  gap: var(--sp-4) var(--sp-6); padding: var(--fs-pad); min-width: 0;
}
/* the ticket stub: the number in the pixel face on the spot yellow, the date in bold beside it,
   and from 768px a column of its own down the card's left, ruled off from the rest */
.fs-stub {
  --fs-num-font: 400 33px/36px var(--pix);
  --fs-num-pad: var(--sp-1) var(--sp-3) var(--sp-1) var(--sp-2);
  grid-area: stub; display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-4);
}
.fs-num {
  display: inline-flex; align-items: baseline; gap: var(--sp-2);
  font: var(--fs-num-font); padding: var(--fs-num-pad);
  background: var(--yellow); color: var(--ink); border: var(--line); box-shadow: var(--drop-2);
}
.fs-no { font: var(--t-label); text-transform: uppercase; }
.fs-date { display: grid; }
.fs-day { font: var(--t-h2); letter-spacing: var(--track-display); }
.fs-sub { font: var(--t-label); text-transform: uppercase; }
.fs-main { grid-area: main; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--sp-3) var(--sp-4); align-items: start; }
.fs-face { line-height: 0; }
.fs-words { display: grid; gap: var(--sp-1); min-width: 0; }
.fs-badges { display: flex; flex-wrap: wrap; gap: var(--sp-2); line-height: 0; padding-bottom: var(--sp-1); }
.fs-guest { font: var(--t-h3); text-wrap: balance; overflow-wrap: anywhere; }
.fs-with { display: block; font: var(--t-ui-medium); color: var(--muted); }
.fs-handle { font: var(--t-label); }
.fs-handle a { color: inherit; }
.fs-note { font: var(--t-read); max-width: var(--fs-measure); padding-top: var(--sp-1); }
.fs-facts { padding-top: var(--sp-2); }
.fs-quote { grid-area: quote; min-width: 0; }
.fs-go { grid-area: go; display: flex; justify-content: flex-end; align-items: center; }
.fs-soon { font: var(--t-label); color: var(--muted); text-transform: uppercase; }
/* a saved fireside is one link: the cover lies over the whole card, and the things in it a reader
   presses on their own (the handle, the player and its time code, the button) stand above it; the
   card lifts under the pointer as the house's keys do */
.fs-linked { --fs-lift: -2px; position: relative; cursor: pointer; transition: transform var(--press); }
.fs-cover { position: absolute; inset: 0; z-index: 1; }
.fs-linked .fs-handle a, .fs-linked .fs-quote .pl-player, .fs-linked .fs-quote a, .fs-linked .fs-go { position: relative; z-index: 2; }
.fs-linked:hover { transform: translate(var(--fs-lift), var(--fs-lift)); }
.fs-linked:focus-within { outline: var(--line-thick); outline-offset: var(--sp-1); }
@media (prefers-reduced-motion: reduce) { .fs-linked { transition: none; } .fs-linked:hover { transform: none; } }
@media (max-width: 479px) {
  .fs-face .pp-print { width: var(--fs-face-small); height: var(--fs-face-small); }
}
@media (min-width: 768px) {
  .fs-card, .fs-ember {
    --fs-pad: var(--sp-6);
    grid-template-columns: var(--fs-stub-w) minmax(0, 1fr);
    grid-template-areas: "stub main" "stub quote" "stub go";
  }
  .fs-stub {
    --fs-num-font: 400 44px/44px var(--pix);
    flex-direction: column; align-items: flex-start; justify-content: flex-start; align-self: stretch;
    gap: var(--sp-4); padding-right: var(--sp-6); border-right: var(--line);
  }
  .fs-guest { font: var(--t-h2); }
}
/* wide: who on the left, the quote on the right, the way on under it */
@media (min-width: 1080px) {
  .fs-card, .fs-ember {
    --fs-stub-w: 184px;
    grid-template-columns: var(--fs-stub-w) minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas: "stub main quote" "stub main go";
    grid-template-rows: auto 1fr;
    align-items: start;
  }
  .fs-go { align-self: end; }
}

/* ---- an ember: a fireside X no longer has -------------------------------------------------------- */
.fs-ember {
  --fs-ember-fill: rgba(242, 234, 216, .38);
  --fs-ember-num: rgba(242, 234, 216, .6);
  background: var(--fs-ember-fill); border: var(--line-w) dashed var(--ink); color: var(--ink);
}
.fs-ember .fs-num { background: var(--fs-ember-num); box-shadow: none; color: var(--muted); }
.fs-ember .fs-day, .fs-ember .fs-guest { color: var(--muted); }
.fs-ember .pp-print { filter: grayscale(1); }
/* what is gone, said plainly, and the one thing left to press: the post that announced it */
.fs-lost { grid-area: quote; display: grid; gap: var(--sp-3); justify-items: start; align-content: start; padding: var(--sp-4); border: var(--line-w) dashed var(--ink); }
.fs-lost-say { display: flex; align-items: center; gap: var(--sp-2); font: var(--t-h5); }
.fs-lost .fs-go { grid-area: auto; justify-content: flex-start; }

/* ---- after the run ------------------------------------------------------------------------------- */
.fs-after { --fs-after-measure: 62ch; font: var(--t-voice); max-width: var(--fs-after-measure); padding-top: var(--sp-10); }

