/* THE TOWER — 99.5 KUSSR as a 1980s silver component stack.
 *
 * D's brief, and the sentence that settles the whole architecture: "you can
 * only hear one audio product at a time, so why separate them?" A real stack
 * has ONE amplifier with ONE output and a row of source buttons. That is not a
 * decoration here, it is the layout expressing the constraint — the tuner, the
 * tape deck and the turntable are INPUTS, and exactly one is selected.
 *
 * Reference is the Pioneer silver line: brushed aluminium faces, thin dark
 * seams between units, fluorescent blue-green readouts, amber tuning, real
 * knurled knobs, and a slim media rack built into the cabinet rather than
 * bolted beside it.
 *
 * SLIMLINE IS A REQUIREMENT, not a taste. Six stacked components on a phone is
 * a very tall page, so every unit collapses to its face and opens on demand —
 * the stack reads as a stack at 375px, and only the selected source is open.
 */
:root {
  /* the metal */
  --tw-face: linear-gradient(180deg, #d8d8d4 0%, #c3c3bd 42%, #b4b4ad 55%, #cfcfc9 100%);
  --tw-face-flat: #c6c6c0;
  --tw-edge: #8e8e86;
  --tw-seam: #1a1a18;
  --tw-cabinet: #14140f;
  --tw-ink: #2a2a26;
  --tw-ink-dim: #5d5d55;
  /* the glass */
  --tw-glass: #0a1512;
  --tw-lit: #6fe3cf;          /* fluorescent readout */
  --tw-lit-dim: #2f8377;
  --tw-amber: #f0a63c;        /* tuning + dial */
  --tw-red: #e2543a;          /* record / peak */
  --tw-blue: #63b8e8;         /* pioneer blue-line accent */
  --tw-mono: ui-monospace, "SF Mono", "Roboto Mono", Menlo, monospace;
  --tw-body: ui-sans-serif, system-ui, -apple-system, "Helvetica Neue", sans-serif;
  --tw-rack-h: 0px;           /* published by the amp, consumed by the page */
}
* { box-sizing: border-box; }
html { color-scheme: dark; }
body {
  margin: 0; background: var(--tw-cabinet); color: #e9e6dd;
  font: 15px/1.5 var(--tw-body); -webkit-font-smoothing: antialiased;
  /* the cabinet the stack sits in */
  background-image:
    radial-gradient(120% 60% at 50% -10%, rgba(99,184,232,.07), transparent 60%),
    repeating-linear-gradient(90deg, rgba(255,255,255,.012) 0 2px, transparent 2px 5px);
  padding-bottom: calc(var(--tw-rack-h) + env(safe-area-inset-bottom));
}
a { color: var(--tw-amber); }

.tw-shell {
  max-width: 860px; margin: 0 auto; padding: clamp(.6rem, 2vw, 1.4rem);
  display: grid; gap: .9rem;
  /* minmax(0,1fr), NOT 1fr. A grid item's min-width defaults to `auto`, so a
   * plain 1fr track grows to its widest CONTENT rather than to its container —
   * the station list and the LCD pushed the whole stack to 611px inside a
   * 338px viewport and the page scrolled sideways. `minmax(0, …)` is what lets
   * a track actually be smaller than what is in it, and the min-width:0 below
   * carries that permission down to the flex children. */
  grid-template-columns: minmax(0, 1fr);
}
.tw-shell > * { min-width: 0; }
.tw-stack, .tw-unit, .tw-body { min-width: 0; }
/* The media rack sits BESIDE the stack on a desk and BELOW it on a phone —
   built into the same cabinet either way, never a separate page. */
@media (min-width: 900px) {
  .tw-shell { grid-template-columns: minmax(0,1fr) 236px; align-items: start; }
  .tw-stack { grid-column: 1; }
  .tw-rack  { grid-column: 2; position: sticky; top: 1rem; }
}

/* ---------- a component ---------------------------------------------------- */
.tw-stack { display: flex; flex-direction: column; gap: 3px; }
.tw-unit {
  background: var(--tw-face); border: 1px solid var(--tw-edge);
  border-radius: 3px; color: var(--tw-ink);
  box-shadow: 0 1px 0 rgba(255,255,255,.5) inset, 0 -1px 0 rgba(0,0,0,.18) inset,
              0 2px 6px rgba(0,0,0,.45);
  overflow: hidden;
}
/* The rack ears — the little bolt-through tabs either side of a real face. */
.tw-unit::before, .tw-unit::after { content: none; }

.tw-face {
  display: flex; align-items: center; gap: .7rem;
  padding: .55rem .75rem; cursor: pointer; user-select: none;
  border-bottom: 1px solid transparent;
}
.tw-unit.open > .tw-face { border-bottom-color: rgba(0,0,0,.18); }
.tw-face:hover { background: rgba(255,255,255,.18); }
.tw-badge {
  font-family: var(--tw-mono); font-size: .58rem; letter-spacing: .22em;
  text-transform: uppercase; color: var(--tw-ink-dim);
  border: 1px solid rgba(0,0,0,.22); border-radius: 2px;
  padding: .18rem .4rem; flex: 0 0 auto; background: rgba(255,255,255,.35);
}
.tw-name {
  font-family: var(--tw-mono); font-size: .74rem; letter-spacing: .1em;
  text-transform: uppercase; font-weight: 700;
  /* a real basis so it is not the first thing squeezed */
  flex: 1 1 8em; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tw-sub {
  font-size: .68rem; color: var(--tw-ink-dim); font-family: var(--tw-mono);
  /* SHRINKS BEFORE THE NAME DOES, and hides outright when the face gets tight.
   * It was `flex: 0 0 auto`, so on a narrow face the subtitle held its full
   * width and the NAME collapsed to a single letter — "Spectrum Analyzer"
   * rendered as "S" beside a full-width "peak hold · VU · correlation". The
   * name is what the component IS; the sub is a gloss on it. */
  flex: 0 1 auto; min-width: 0; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
@media (max-width: 560px) { .tw-sub { display: none; } }
/* The source LED: lit means THIS unit is what the amp is playing. */
.tw-led {
  width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto;
  background: #6a6a62; box-shadow: 0 0 0 1px rgba(0,0,0,.3) inset;
}
.tw-unit.selected .tw-led { background: var(--tw-red); box-shadow: 0 0 7px var(--tw-red); }
.tw-unit.selected { border-color: #6b6b62; }
.tw-unit.selected > .tw-face { background: rgba(255,255,255,.24); }

.tw-body { display: none; padding: .75rem; background: rgba(255,255,255,.16); }
.tw-unit.open > .tw-body { display: block; }

/* ---------- the head unit -------------------------------------------------- */
.tw-head { padding: .8rem .9rem; display: flex; align-items: center; gap: .9rem; }
.tw-wordmark {
  font-family: var(--tw-mono); font-weight: 700; letter-spacing: .16em;
  font-size: clamp(1.1rem, 3.4vw, 1.5rem); margin: 0; color: var(--tw-ink);
}
.tw-wordmark small {
  display: block; font-size: .42em; letter-spacing: .38em; color: var(--tw-ink-dim);
  margin-top: .18rem;
}
.tw-power {
  margin-left: auto; display: flex; align-items: center; gap: .5rem;
  font-family: var(--tw-mono); font-size: .62rem; letter-spacing: .18em;
  color: var(--tw-ink-dim);
}
.tw-power i { width: 9px; height: 9px; border-radius: 50%; background: var(--tw-blue);
  box-shadow: 0 0 8px var(--tw-blue); display: inline-block; }

/* ---------- glass readouts -------------------------------------------------- */
.tw-glass {
  background: var(--tw-glass); border: 1px solid #05100d; border-radius: 3px;
  padding: .5rem .6rem; color: var(--tw-lit); font-family: var(--tw-mono);
  box-shadow: 0 2px 10px rgba(0,0,0,.5) inset;
}

/* ---------- tuner ----------------------------------------------------------- */
.tw-dial { position: relative; height: 58px; margin-top: .1rem; }
.tw-dial-scale {
  position: absolute; inset: 0; border-radius: 2px;
  background: linear-gradient(180deg, #08110f, #0d1a17);
  border: 1px solid #05100d; overflow: hidden;
}
.tw-ticks { position: absolute; inset: 0; }
.tw-tick { position: absolute; top: 8px; width: 1px; background: var(--tw-lit-dim); }
.tw-tick.maj { top: 5px; height: 13px; background: var(--tw-lit); }
.tw-tick.min { height: 7px; }
.tw-tick-l {
  position: absolute; top: 21px; transform: translateX(-50%);
  font-family: var(--tw-mono); font-size: .54rem; color: var(--tw-lit-dim);
}
/* a lit pip = a station that is actually on the air */
.tw-pip {
  position: absolute; bottom: 8px; width: 4px; height: 4px; border-radius: 50%;
  transform: translateX(-50%); background: #2b4b45;
}
.tw-pip.live { background: var(--tw-amber); box-shadow: 0 0 6px var(--tw-amber); }
.tw-needle {
  position: absolute; top: 2px; bottom: 2px; width: 2px; z-index: 3;
  background: var(--tw-red); box-shadow: 0 0 8px var(--tw-red);
  transition: left .28s cubic-bezier(.22,.61,.36,1);
}
.tw-bandsel { display: flex; gap: 3px; }
.tw-bandsel button {
  font-family: var(--tw-mono); font-size: .6rem; letter-spacing: .14em;
  padding: .3rem .6rem; cursor: pointer; color: var(--tw-ink);
  background: var(--tw-face); border: 1px solid var(--tw-edge); border-radius: 2px;
}
.tw-bandsel button[aria-pressed="true"] {
  background: var(--tw-ink); color: var(--tw-lit); border-color: #000;
}

/* the station list under the dial */
.tw-stations { list-style: none; margin: .6rem 0 0; padding: 0; max-height: 46vh; overflow-y: auto; }
.tw-stations li {
  display: flex; align-items: center; gap: .55rem; padding: .4rem .5rem;
  border-bottom: 1px solid rgba(0,0,0,.1); cursor: pointer; font-size: .84rem;
}
.tw-stations li:hover { background: rgba(255,255,255,.3); }
.tw-stations li.on { background: rgba(0,0,0,.14); }
.tw-stations .f {
  font-family: var(--tw-mono); font-weight: 700; font-size: .8rem;
  min-width: 4.2em; text-align: right; color: var(--tw-ink);
}
.tw-stations .n { flex: 1 1 auto; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.tw-stations .n b { font-weight: 600; }
.tw-stations .n span { color: var(--tw-ink-dim); font-size: .76rem; }
.tw-stations .d { font-family: var(--tw-mono); font-size: .58rem; letter-spacing: .1em;
  color: var(--tw-ink-dim); }
.tw-stations li.dark .n b { color: var(--tw-ink-dim); font-weight: 400; }

/* ---------- the media rack (built into the cabinet) ------------------------- */
.tw-rack {
  background: linear-gradient(180deg, #1c1c16, #131310);
  border: 1px solid #2c2c24; border-radius: 4px; padding: .6rem;
  box-shadow: 0 3px 12px rgba(0,0,0,.5);
}
.tw-rack h2 {
  font-family: var(--tw-mono); font-size: .6rem; letter-spacing: .22em;
  text-transform: uppercase; color: #8b8375; margin: 0 0 .5rem;
}
.tw-formats { display: flex; gap: 3px; margin-bottom: .55rem; flex-wrap: wrap; }
.tw-formats button {
  font-family: var(--tw-mono); font-size: .56rem; letter-spacing: .1em;
  background: #22221b; color: #8b8375; border: 1px solid #33332a;
  border-radius: 2px; padding: .26rem .45rem; cursor: pointer;
}
.tw-formats button[aria-pressed="true"] { background: var(--tw-amber); color: #241a10; border-color: var(--tw-amber); }
/* THE SPINES. A rack of media read edge-on, which is what makes it slim. */
.tw-spines { display: flex; flex-direction: column; gap: 2px; max-height: 58vh; overflow-y: auto; }
.tw-spine {
  display: flex; align-items: center; gap: .5rem; cursor: pointer;
  padding: .4rem .5rem; border-radius: 2px; font-size: .78rem;
  background: #1f1f19; border-left: 3px solid var(--tw-amber); color: #ddd6c6;
}
.tw-spine:hover { background: #2a2a22; }
.tw-spine.on { background: #33332a; }
.tw-spine .k {
  font-family: var(--tw-mono); font-size: .52rem; letter-spacing: .1em;
  color: #8b8375; flex: 0 0 auto;
}
.tw-spine .t { flex: 1 1 auto; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
/* each medium gets its own spine color — the rack is readable at a glance */
.tw-spine[data-fmt="tape"]     { border-left-color: var(--tw-amber); }
.tw-spine[data-fmt="vinyl"]    { border-left-color: #c9a227; }
.tw-spine[data-fmt="minidisc"] { border-left-color: var(--tw-blue); }
.tw-spine[data-fmt="reel"]     { border-left-color: #b8b8b0; }
.tw-spine[data-fmt="cd"]       { border-left-color: #d8d8d4; }
.tw-empty { color: #6c6558; font-size: .74rem; padding: .6rem .2rem; font-style: italic; }

/* ---------- the amp: fixed, one output, always there ----------------------- */
.tw-amp {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  background: linear-gradient(180deg, #cfcfc9, #a9a9a2);
  border-top: 1px solid #7d7d75;
  box-shadow: 0 -6px 22px rgba(0,0,0,.55);
  padding: .5rem clamp(.5rem, 2vw, 1rem);
  padding-bottom: calc(.5rem + env(safe-area-inset-bottom));
  color: var(--tw-ink);
  /* the hub launcher is fixed bottom-left; keep its gutter clear */
  padding-left: 190px;
}
@media (max-width: 760px) { .tw-amp { padding-left: clamp(.5rem, 2vw, 1rem); padding-bottom: calc(46px + env(safe-area-inset-bottom)); } }
.tw-amp-row { display: flex; align-items: center; gap: .6rem; max-width: 1100px; margin: 0 auto; }
.tw-src { display: flex; gap: 2px; flex: 0 0 auto; }
.tw-src button {
  font-family: var(--tw-mono); font-size: .56rem; letter-spacing: .1em;
  padding: .34rem .42rem; cursor: pointer; color: var(--tw-ink);
  background: var(--tw-face); border: 1px solid var(--tw-edge); border-radius: 2px;
  min-height: 34px;
}
.tw-src button[aria-pressed="true"] { background: var(--tw-ink); color: var(--tw-lit); border-color: #000; }
.tw-lcd {
  flex: 1 1 auto; min-width: 0; background: var(--tw-glass); border-radius: 3px;
  border: 1px solid #05100d; padding: .3rem .55rem; font-family: var(--tw-mono);
  box-shadow: 0 2px 8px rgba(0,0,0,.5) inset;
}
.tw-lcd b { display: block; color: var(--tw-lit); font-size: .8rem; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tw-lcd span { display: block; color: var(--tw-lit-dim); font-size: .6rem;
  letter-spacing: .1em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tw-transport { display: flex; gap: 3px; flex: 0 0 auto; }
.tw-btn {
  font-family: var(--tw-mono); font-size: .72rem; cursor: pointer; color: var(--tw-ink);
  background: var(--tw-face); border: 1px solid var(--tw-edge); border-radius: 2px;
  min-width: 40px; min-height: 40px;
}
.tw-btn:hover { background: #e2e2dc; }
.tw-btn.play { min-width: 52px; font-weight: 700; }
.tw-btn[disabled] { opacity: .4; cursor: not-allowed; }
/* VU: playback-driven decoration on the clean deck, real analyser under DSP. */
.tw-vu { display: flex; flex-direction: column; gap: 2px; flex: 0 0 74px; }
.tw-vu i { display: block; height: 5px; background: #2a2a24; border-radius: 1px; overflow: hidden; }
.tw-vu i b { display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, var(--tw-lit), var(--tw-amber) 74%, var(--tw-red));
  transition: width .09s linear; }
@media (max-width: 620px) { .tw-vu { display: none; } }
.tw-vol { flex: 0 0 92px; accent-color: var(--tw-amber); }
@media (max-width: 760px) { .tw-vol { display: none; } }

/* ---------- graphic equalizer + spectrum ----------------------------------- */
/* Its own COMPONENT in the stack, not a panel hidden behind a button — on the
 * reference stack the EQ is the unit everybody looks at, and burying it was the
 * mistake the first version of this player made. */
.tw-eq-wrap { display: flex; gap: .75rem; align-items: stretch; flex-wrap: wrap; }
.tw-spectrum {
  flex: 1 1 260px; min-width: 200px; height: 72px; border-radius: 3px;
  background: var(--tw-glass); border: 1px solid #05100d; display: block;
  box-shadow: 0 2px 10px rgba(0,0,0,.5) inset;
}
.tw-faders { display: flex; gap: .35rem; flex: 1 1 300px; align-items: flex-end; }
.tw-fader { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap: .2rem; }
.tw-fader input {
  -webkit-appearance: slider-vertical; appearance: slider-vertical;
  writing-mode: vertical-lr; direction: rtl;
  width: 16px; height: 58px; accent-color: var(--tw-amber); cursor: pointer;
}
.tw-fader label {
  font-family: var(--tw-mono); font-size: .5rem; letter-spacing: .04em;
  color: var(--tw-ink-dim);
}
.tw-eq-head { display: flex; align-items: center; gap: .5rem; margin-bottom: .5rem; flex-wrap: wrap; }
.tw-eq-head .tw-sub { flex: 1 1 auto; }
.tw-toggle {
  font-family: var(--tw-mono); font-size: .56rem; letter-spacing: .12em;
  padding: .3rem .55rem; cursor: pointer; color: var(--tw-ink);
  background: var(--tw-face); border: 1px solid var(--tw-edge); border-radius: 2px;
}
.tw-toggle[aria-pressed="true"] { background: var(--tw-red); color: #fff; border-color: #8f3323; }
.tw-preset {
  font-family: var(--tw-mono); font-size: .56rem; padding: .28rem .4rem;
  background: var(--tw-face); color: var(--tw-ink);
  border: 1px solid var(--tw-edge); border-radius: 2px;
}
.tw-warn { font-size: .64rem; color: #8a4a2a; margin: .4rem 0 0; }

/* ---------- tape / turntable bodies ---------------------------------------- */
.tw-list { list-style: none; margin: 0; padding: 0; max-height: 46vh; overflow-y: auto; }
.tw-list li {
  display: flex; align-items: center; gap: .6rem; padding: .45rem .5rem;
  border-bottom: 1px solid rgba(0,0,0,.1); cursor: pointer; font-size: .85rem;
}
.tw-list li:hover { background: rgba(255,255,255,.3); }
.tw-list li.on { background: rgba(0,0,0,.14); }
.tw-list .art {
  width: 30px; height: 30px; border-radius: 2px; flex: 0 0 auto; object-fit: cover;
  background: #2a2a24;
}
.tw-list .t { flex: 1 1 auto; min-width: 0; }
.tw-list .t b { display: block; font-weight: 600; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.tw-list .t span { color: var(--tw-ink-dim); font-size: .74rem; }
.tw-list .dur { font-family: var(--tw-mono); font-size: .68rem; color: var(--tw-ink-dim); flex: 0 0 auto; }
.tw-note { font-size: .76rem; color: var(--tw-ink-dim); margin: 0 0 .55rem; }
.tw-note a { color: #8a5a1a; }

/* ---------- the reel-to-reel: the crown of the stack ------------------------ */
/* On the reference tower this deck sits ON TOP and it is the only component
 * with moving parts you can read across a room. Everything below is silver and
 * still; this is where the machine looks alive. */
.tw-deck > .tw-reels { padding: .6rem .75rem .4rem; background: rgba(255,255,255,.1); }
.tw-reel-svg { display: block; width: 100%; height: auto; max-height: 190px; }

.tw-plate { fill: #b9b9b2; stroke: #8e8e86; stroke-width: 1; }
.tw-reel-flange { fill: none; stroke: #7e7e76; stroke-width: 1.5; opacity: .85; }
/* The wound tape itself. Its RADIUS is the state — see reelFill() in tower.js. */
.tw-reel-tape { fill: #4a3526; stroke: #2e2018; stroke-width: .5; }
.tw-hub { fill: #d5d5cf; stroke: #8e8e86; stroke-width: 1; }
.tw-spokes rect { fill: #cfcfc9; stroke: #9a9a92; stroke-width: .6; }
.tw-tape { stroke: #3b2a1e; stroke-width: 2.2; fill: none; opacity: .9; }
.tw-heads { fill: #9a9a92; stroke: #6f6f68; stroke-width: 1; }
.tw-head { fill: #cfcfc9; stroke: #7e7e76; stroke-width: .6; }
.tw-capstan { fill: #55554e; stroke: #33332e; stroke-width: 1; }

/* Rotation is applied by JS as an SVG transform attribute carrying its OWN
 * origin — rotate(deg cx cy). Do NOT also set transform-box/transform-origin
 * here: the two compose, the spokes rotate about a point that is not the hub,
 * and they swing outside the flange like a broken fan. The attribute is the
 * single source of the origin. */
.tw-spokes { will-change: transform; }

.tw-counter {
  margin-top: .25rem; display: flex; justify-content: flex-end;
}
.tw-counter span {
  font-family: var(--tw-mono); font-size: .74rem; letter-spacing: .18em;
  background: var(--tw-glass); color: var(--tw-lit);
  border: 1px solid #05100d; border-radius: 2px; padding: .16rem .5rem;
  box-shadow: 0 2px 8px rgba(0,0,0,.5) inset;
}
@media (prefers-reduced-motion: reduce) { .tw-spokes { transition: none !important; } }

/* ---------- the cued tape: sliding scale, preview, full side ---------------- */
/* Ported from the shelf, not reinvented. The scale is the point of this
 * station's commerce — a floor, a suggestion, a ceiling, and you pick. */
.tw-cued {
  margin-top: .7rem; padding: .8rem; border-radius: 4px;
  background: rgba(0,0,0,.16); border: 1px solid rgba(0,0,0,.2);
}
.tw-cued h3 {
  margin: 0 0 .15rem; font-family: var(--tw-body); font-size: 1rem;
  letter-spacing: 0; text-transform: none; color: var(--tw-ink); font-weight: 700;
}
.tw-cued .sub { font-size: .8rem; color: var(--tw-ink-dim); margin: 0 0 .55rem; }
.tw-cued .blurb { font-size: .84rem; margin: 0 0 .7rem; color: #3a3a34; }

.tw-scale-readout {
  font-family: var(--tw-mono); font-size: clamp(1.5rem, 6vw, 2rem);
  color: #2a2a26; line-height: 1; margin: .2rem 0 .1rem;
}
.tw-scale-note { font-size: .74rem; color: var(--tw-ink-dim); margin: 0 0 .5rem; }
.tw-scale input[type=range] { width: 100%; accent-color: var(--tw-amber); }
.tw-scale-ends {
  display: flex; justify-content: space-between; font-family: var(--tw-mono);
  font-size: .64rem; color: var(--tw-ink-dim);
}
.tw-tiers { display: flex; gap: .3rem; flex-wrap: wrap; margin: .5rem 0; }
.tw-tiers button {
  font-family: var(--tw-mono); font-size: .62rem; padding: .3rem .5rem;
  background: var(--tw-face); color: var(--tw-ink);
  border: 1px solid var(--tw-edge); border-radius: 2px; cursor: pointer;
}
.tw-tiers button.on { background: var(--tw-ink); color: var(--tw-lit); border-color: #000; }
.tw-cued-keys { display: flex; gap: .35rem; flex-wrap: wrap; margin-top: .6rem; }
.tw-owned {
  font-family: var(--tw-mono); font-size: .6rem; letter-spacing: .12em;
  color: #2f6b4f; border: 1px solid #2f6b4f; border-radius: 2px;
  padding: .16rem .4rem;
}

/* ---------- the analyzer: 1980s instrument panel --------------------------- */
/* D: "bring back more visualizer tools, vu meters, eq meters, all of it; super
 * 80's high tech." The look is a rack-mount analyser: black glass, fluorescent
 * traces, peak-hold caps that fall slowly, and REAL ballistic needles rather
 * than bars pretending to be needles. */
.tw-scope-grid, .tw-scope-grid2 { display: flex; gap: .5rem; flex-wrap: wrap; }
.tw-scope-grid2 { margin-top: .5rem; }
.tw-spectrum-big, .tw-vumeter, .tw-ladder, .tw-scope {
  background: var(--tw-glass); border: 1px solid #05100d; border-radius: 3px;
  box-shadow: 0 2px 12px rgba(0,0,0,.55) inset; display: block;
}
.tw-spectrum-big { flex: 2 1 340px; width: 100%; height: auto; max-height: 168px; }
.tw-vumeter     { flex: 1 1 220px; width: 100%; height: auto; max-height: 168px; }
.tw-ladder      { flex: 2 1 340px; width: 100%; height: auto; max-height: 54px; }
.tw-scope       { flex: 1 1 220px; width: 100%; height: auto; max-height: 54px; }

/* The pop-out is a desktop affordance: a separate window is not a thing a
   phone browser meaningfully does, and a button that silently fails is worse
   than no button. */
.tw-popout { font-size: .9rem; }
@media (max-width: 760px) { .tw-popout { display: none; } }

/* ---------- presets: the button row off a car radio ------------------------ */
.tw-presets { display: flex; gap: 3px; flex-wrap: wrap; margin: .5rem 0 .1rem; align-items: center; }
.tw-preset-btn {
  font-family: var(--tw-mono); font-size: .6rem; letter-spacing: .06em;
  min-width: 30px; min-height: 30px; cursor: pointer; color: var(--tw-ink);
  background: var(--tw-face); border: 1px solid var(--tw-edge); border-radius: 2px;
  padding: .2rem .35rem;
}
.tw-preset-btn:hover { background: #e2e2dc; }
.tw-preset-btn.on { background: var(--tw-ink); color: var(--tw-lit); border-color: #000; }
.tw-preset-btn.empty { opacity: .45; }
.tw-preset-hint {
  font-family: var(--tw-mono); font-size: .58rem; color: var(--tw-ink-dim);
  margin-left: .2rem;
}
/* the star that curates a row */
.tw-star {
  flex: 0 0 auto; background: none; border: 1px solid var(--tw-edge);
  border-radius: 2px; cursor: pointer; color: var(--tw-ink-dim);
  min-width: 28px; min-height: 28px; font-size: .8rem; line-height: 1;
}
.tw-star.on { color: #8a6a2f; border-color: #8a6a2f; background: rgba(240,166,60,.18); }
.tw-star:hover { border-color: var(--tw-amber); }
