/* ============================================================
   FH-02 EAR-TRAINING TERMINAL — hardware chassis + inset screen
   Chassis text is PRINTED (no glow). The screen is the only
   luminous element. Light = warm-grey shell / green phosphor.
   Dark = charcoal shell / blue CRT.
   NO shadow/filter on anything that repaints during cursor drags.
   ============================================================ */
:root{
  /* chassis (light: warm grey plastic) */
  --mat:#63666a;                 /* workbench behind the device */
  --mat-line:rgba(255,255,255,0.06);
  --chassis:#c6c8bf;
  --chassis-raised:#d3d5cc;
  --chassis-recess:#b7b9b0;
  --chassis-deep:#9d9f96;
  --ink:#33362f;                 /* printed labels */
  --ink-dim:#63665d;
  --line:#8f9288;                /* engraved separators */
  --line-soft:rgba(0,0,0,0.12);
  --emboss:rgba(255,255,255,0.55);
  --bezel:#22241f;               /* screen surround */
  /* screen (green phosphor LCD/CRT) */
  --screen-bg:#0c120b;
  --phos:#6fdc7f;
  --phos-bright:#b2f7b8;
  --phos-dim:rgba(111,220,127,0.55);
  --grid-minor:rgba(111,220,127,0.10);
  --grid-major:rgba(111,220,127,0.26);
  --amber:var(--phos);               /* legacy names: cursor + tolerance band */
  --amber-dim:rgba(111,220,127,0.16);
  --green:var(--phos-bright);        /* hit / reveal */
  --red:#ffab5e;                     /* miss — warm signal orange on the screen */
  /* accents */
  --accent:#e0762e;
  --accent-deep:#9c4f1c;
  --accent-ink:#26130a;
  --font-mono:'IBM Plex Mono',ui-monospace,'SF Mono',monospace;
  --font-counter:'VT323',var(--font-mono);
  /* backlit green LCD (Game Select detail pane) — stays green in both chassis
     themes, like a real backlit panel; dark ink on lit glass */
  --lcd-lit:#aecb8f; --lcd-edge:#8fae74; --lcd-scan:rgba(30,54,26,0.11);
  --lcd-ink:#213b1c; --lcd-mid:#3a5c30; --lcd-frame:rgba(33,59,28,0.5);
}
:root[data-theme=dark]{
  --mat:#111214;
  --mat-line:rgba(255,255,255,0.035);
  --chassis:#26282b;
  --chassis-raised:#303337;
  --chassis-recess:#1e2023;
  --chassis-deep:#131417;
  --ink:#c9ccc7;
  --ink-dim:#848883;
  --line:#43474b;
  --line-soft:rgba(0,0,0,0.4);
  --emboss:rgba(255,255,255,0.07);
  --bezel:#0c0d0f;
  --screen-bg:#060a12;
  --phos:#6cb8ff;
  --phos-bright:#c2e6ff;
  --phos-dim:rgba(108,184,255,0.55);
  --grid-minor:rgba(108,184,255,0.10);
  --grid-major:rgba(108,184,255,0.26);
  --amber:var(--phos);
  --amber-dim:rgba(108,184,255,0.15);
  --green:var(--phos-bright);
  --red:#ff9a52;
  /* dark chassis: the Game Select detail pane becomes a dark blue CRT with
     bright phosphor text, matching the game screens (vs the light backlit LCD) */
  --lcd-lit:#0e1a2e; --lcd-edge:#070c16; --lcd-scan:rgba(0,0,0,0.28);
  --lcd-ink:#cbe8ff; --lcd-mid:#6cb8ff; --lcd-frame:rgba(108,184,255,0.32);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme=light]){
    --mat:#111214;
    --mat-line:rgba(255,255,255,0.035);
    --chassis:#26282b;
    --chassis-raised:#303337;
    --chassis-recess:#1e2023;
    --chassis-deep:#131417;
    --ink:#c9ccc7;
    --ink-dim:#848883;
    --line:#43474b;
    --line-soft:rgba(0,0,0,0.4);
    --emboss:rgba(255,255,255,0.07);
    --bezel:#0c0d0f;
    --screen-bg:#060a12;
    --phos:#6cb8ff;
    --phos-bright:#c2e6ff;
    --phos-dim:rgba(108,184,255,0.55);
    --grid-minor:rgba(108,184,255,0.10);
    --grid-major:rgba(108,184,255,0.26);
    --amber:var(--phos);
    --amber-dim:rgba(108,184,255,0.15);
    --green:var(--phos-bright);
    --red:#ff9a52;
    --lcd-lit:#0e1a2e; --lcd-edge:#070c16; --lcd-scan:rgba(0,0,0,0.28);
    --lcd-ink:#cbe8ff; --lcd-mid:#6cb8ff; --lcd-frame:rgba(108,184,255,0.32);
  }
}

*{ box-sizing:border-box; }
input,select,textarea{ user-select:text; -webkit-user-select:text; }
body{
  margin:0; color:var(--ink);
  -webkit-tap-highlight-color:transparent; /* the buttons have their own press states */
  background:
    linear-gradient(var(--mat-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--mat-line) 1px, transparent 1px),
    var(--mat);
  background-size:28px 28px, 28px 28px, auto;
  font-family:var(--font-mono);
  display:flex; justify-content:center; padding:28px 14px;
  -webkit-font-smoothing:antialiased;
}
/* main terminal + aux monitor sit side by side; aux only appears when the
   workbench is wide enough to leave real empty space */
.rig{
  display:flex; justify-content:center; align-items:flex-start; gap:18px;
  width:100%; max-width:1500px;
}
/* 960 -> 1220: the scope modes were noticeably smaller than the two full-screen
   ones (user). The scope is a viewBox SVG, so a wider chassis simply scales it. */
.app{
  user-select:none; -webkit-user-select:none;
  width:100%; max-width:1220px;
  background:var(--chassis);
  border:1px solid var(--chassis-deep);
  border-radius:10px;
  position:relative;
  box-shadow:
    inset 0 1px 0 var(--emboss),
    0 18px 50px -18px rgba(0,0,0,0.55);
  overflow:hidden;
}

/* ---- Top strip (printed) ---- */
.term-strip{
  display:flex; justify-content:space-between; align-items:center;
  padding:7px 22px; font-size:10px; letter-spacing:.2em; color:var(--ink-dim);
  border-bottom:1px solid var(--line-soft);
  text-transform:uppercase;
}
.strip-right{ display:flex; align-items:center; gap:14px; }
.theme-btn{
  background:var(--chassis-raised); border:1px solid var(--line); color:var(--ink);
  width:26px; height:20px; border-radius:3px; cursor:pointer; font-size:11px; line-height:1;
  box-shadow:0 1px 0 var(--chassis-deep);
}
.theme-btn:active{ transform:translateY(1px); box-shadow:none; }
.pwr{ display:flex; align-items:center; gap:6px; }
.pwr-lamp{
  width:9px; height:9px; border-radius:50%;
  background:radial-gradient(circle at 35% 30%, #ffc890, var(--accent) 60%, #7a3c12);
  box-shadow:0 0 6px rgba(224,118,46,0.6);
}

/* ---- Header ---- */
.header{
  display:flex; align-items:center; justify-content:space-between;
  padding:14px 22px; border-bottom:1px solid var(--line-soft);
}
.eyebrow{
  font-size:10px; letter-spacing:.18em; text-transform:uppercase;
  color:var(--ink-dim); margin-bottom:3px;
}
.title-block h1{
  font-size:16px; margin:0; font-weight:700; letter-spacing:.1em; text-transform:uppercase;
  color:var(--ink);
}
.stats{ display:flex; align-items:flex-start; gap:22px; }
.stat{ text-align:center; }
.stat .stat-label{ font-size:9px; color:var(--ink-dim); letter-spacing:.18em; text-transform:uppercase; margin-bottom:4px; }
/* mini LCD windows */
.stat .stat-value{
  font-family:var(--font-counter); font-size:22px; line-height:1;
  color:var(--phos); background:var(--screen-bg);
  border:1px solid var(--bezel); border-radius:2px;
  /* 1/3 padding split centers VT323's digits: its baseline sits at 0.82em but
     digit tops only reach 0.64em, so a symmetric box renders them ~2px low */
  padding:1px 8px 3px; min-width:58px;
  box-shadow:inset 0 2px 6px rgba(0,0,0,0.6);
  font-variant-numeric:tabular-nums;
  text-shadow:0 0 5px var(--phos-dim);
}
.level-progress{
  width:74px; height:6px; margin:5px auto 0;
  background:var(--screen-bg); border:1px solid var(--bezel); overflow:hidden;
}
.level-progress-fill{ height:100%; width:0%; background:var(--phos); transition:width .3s ease; }
.level-progress-label{ font-size:9px; color:var(--ink-dim); margin-top:3px; white-space:nowrap; }
/* Fixed 3-column grid, not wrapped rows: a 4th bulb must sit in column 1 of the
   second row — the slot it would occupy at the 5-life cap — never centered under
   the gap. maxLives is 3..5, so the top row is always full and the tracks size. */
.lives{ display:grid; grid-template-columns:repeat(3, auto); gap:5px 7px;
        justify-content:center; margin-top:5px; }
/* jewel indicator lamps */
.life-pip{
  width:13px; height:13px; border-radius:50%;
  background:radial-gradient(circle at 35% 30%, #ffc890, var(--accent) 55%, #7a3c12);
  border:1px solid var(--chassis-deep);
  box-shadow:0 0 6px rgba(224,118,46,0.55), inset 0 1px 1px rgba(255,255,255,0.4);
}
.life-pip.spent{
  background:radial-gradient(circle at 35% 30%, var(--chassis-recess), var(--chassis-deep) 75%);
  box-shadow:inset 0 1px 2px rgba(0,0,0,0.35);
}
/* lives in the term strip next to theme/power — inline SVG cog, not the ⚙ glyph
   (that codepoint renders as emoji or a hairline on several platforms) */
.gear-btn{
  background:var(--chassis-raised); border:1px solid var(--line); color:var(--ink);
  width:28px; height:20px; border-radius:3px; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center;
  box-shadow:0 1px 0 var(--chassis-deep);
}
.gear-btn svg{ display:block; }
.gear-btn:hover{ background:var(--chassis); }
.gear-btn:active{ transform:translateY(1px); box-shadow:none; }

/* ---- Account (login/sync) ---- */
.account-area{ display:flex; align-items:center; }
.acct-btn{
  background:var(--chassis-raised); border:1px solid var(--line); color:var(--ink);
  padding:4px 10px; border-radius:3px; cursor:pointer; font-size:10px; letter-spacing:.1em;
  text-transform:uppercase; font-family:var(--font-mono);
  box-shadow:0 1px 0 var(--chassis-deep);
}
.acct-btn:hover{ background:var(--chassis); }
.acct-btn:active{ transform:translateY(1px); box-shadow:none; }
.acct-signed-in{ display:flex; align-items:center; gap:8px; }
.acct-name{ font-size:10px; color:var(--ink-dim); letter-spacing:.05em; text-transform:none; max-width:140px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.acct-edit{
  background:none; border:none; color:var(--ink-dim); cursor:pointer;
  font-size:11px; line-height:1; padding:2px 4px; border-radius:3px; margin-left:-4px;
}
.acct-edit:hover{ color:var(--ink); background:var(--chassis-raised); }
.gs-account{ display:inline-flex; align-items:center; gap:8px; margin-right:6px; }
.modal-welcome{ font-size:13px; color:var(--ink-dim); line-height:1.55; margin:6px 0 18px; }
.acct-badge{
  font-size:9px; letter-spacing:.12em; color:var(--accent-ink); background:var(--accent);
  border-radius:2px; padding:2px 5px; font-weight:700;
}

/* ---- Auth / username modals ---- */
/* z-index above the Game Select menu (60) and the mobile settings drawer (80) so a
   modal (e.g. the username prompt auto-opening on load) is never hidden behind them. */
.modal-overlay{
  position:fixed; inset:0; background:rgba(10,10,12,0.6);
  display:flex; align-items:center; justify-content:center;
  opacity:0; pointer-events:none; transition:opacity .15s ease; z-index:90;
}
.modal-overlay.show{ opacity:1; pointer-events:all; }
.modal-box{
  position:relative; width:min(340px, 90vw);
  background:var(--chassis); border:1px solid var(--line); border-radius:8px;
  padding:22px 22px 18px; box-shadow:0 18px 50px -18px rgba(0,0,0,0.6);
  display:flex; flex-direction:column; gap:12px;
}
.modal-box h2{ margin:0; font-size:15px; letter-spacing:.08em; text-transform:uppercase; color:var(--ink); }
.modal-close{
  position:absolute; top:10px; right:10px; background:none; border:none; color:var(--ink-dim);
  font-size:18px; line-height:1; cursor:pointer; padding:4px;
}
.modal-close:hover{ color:var(--ink); }
.btn-google{
  background:var(--chassis-raised); border:1px solid var(--line); color:var(--ink);
  width:100%;
}
.modal-divider{
  display:flex; align-items:center; gap:10px; color:var(--ink-dim); font-size:10px;
  letter-spacing:.12em; text-transform:uppercase;
}
.modal-divider::before,.modal-divider::after{ content:''; flex:1; height:1px; background:var(--line-soft); }
.modal-box input[type=email], .modal-box input[type=password]{
  width:100%; background:var(--chassis-raised); border:1px solid var(--line); color:var(--ink);
  padding:8px 10px; border-radius:3px; font-family:var(--font-mono); font-size:12px;
}
.modal-box .btn-primary{ width:100%; }
.modal-error{ margin:0; font-size:11px; color:var(--red, #c65b4a); }
.modal-links{ display:flex; justify-content:space-between; gap:10px; flex-wrap:wrap; }
.modal-note{ margin:0; font-size:10px; color:var(--ink-dim); line-height:1.4; }
.admin-field{
  grid-column:1 / -1; border:1px dashed var(--accent); border-radius:4px; padding:10px 12px;
}

/* ---- Mode selector: folder-index tabs (archive-divider style) ---- */
/* Trapezoid dividers sitting on a shelf line; earlier tabs stack in FRONT of later
   ones (left overlaps right, like a card index); the active tab rises taller.
   flex:1 + min-width:0 means all six always fit — no horizontal overflow, ever. */
.mode-tabs{
  display:flex; align-items:flex-end; padding:12px 22px 0;
  border-bottom:1px solid var(--line);
}
.mode-tab{
  flex:1 1 0; min-width:0;
  position:relative;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px;
  margin-left:-14px;
  padding:8px 14px;
  background:none; border:none;
  color:var(--ink-dim);
  font-family:var(--font-mono); font-size:11px; font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; cursor:pointer;
}
/* the folder shape lives on ::before: perspective-skew makes a true trapezoid that
   KEEPS its 1px border and rounded top corners (clip-path can't do either) */
.mode-tab::before{
  content:''; position:absolute; inset:0; z-index:-1;
  background:linear-gradient(180deg, var(--emboss), rgba(255,255,255,0) 45%), var(--chassis);
  border:1px solid var(--line); border-bottom:none;
  border-radius:8px 8px 0 0;
  transform:perspective(60px) rotateX(5deg);
  transform-origin:bottom;
}
.mode-tab:first-child{ margin-left:0; }
/* card-index stacking: leftmost in front */
.mode-tab:nth-child(1){ z-index:6; }
.mode-tab:nth-child(2){ z-index:5; }
.mode-tab:nth-child(3){ z-index:4; }
.mode-tab:nth-child(4){ z-index:3; }
.mode-tab:nth-child(5){ z-index:2; }
.mode-tab:nth-child(6){ z-index:1; }
.mode-tab:nth-child(7){ z-index:0; }
.mode-tab:hover{ color:var(--ink); }
.mode-tab:hover::before{ background:linear-gradient(180deg, var(--emboss), rgba(255,255,255,0) 45%), var(--chassis-raised); }
.mode-tab.active{
  color:var(--ink);
  padding:11px 14px; /* taller than neighbors, text still vertically centered */
  z-index:10;
}
.mode-tab.active::before{
  background:linear-gradient(180deg, var(--emboss), rgba(255,255,255,0) 45%), var(--chassis-raised);
  bottom:-1px; /* covers the shelf line beneath it — the open folder reads attached */
}
/* focus: no lingering ring after a mouse click (tabs also blur() on click);
   keyboard nav still gets a clear accent outline on the folder shape itself */
.mode-tab:focus{ outline:none; }
.mode-tab:focus-visible::before{ outline:2px solid var(--accent); outline-offset:2px; }
.tab-code{
  display:flex; align-items:center; gap:5px;
  font-size:8px; font-weight:400; letter-spacing:.16em; opacity:.6;
}
.tab-code::before{
  content:''; width:6px; height:6px; border-radius:50%;
  background:var(--chassis-deep); box-shadow:inset 0 1px 1px rgba(0,0,0,0.4);
}
.mode-tab.active .tab-code{ opacity:.8; }
.mode-tab.active .tab-code::before{
  background:radial-gradient(circle at 35% 30%, #ffc890, var(--accent) 60%, #7a3c12);
  box-shadow:0 0 5px rgba(224,118,46,0.7);
}
.tab-name{
  max-width:100%; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}

/* ---- Maintenance panel ---- */
.drawer{
  max-height:0; overflow:hidden; transition:max-height .25s ease;
  background:var(--chassis-recess);
  border-bottom:1px solid var(--line-soft);
  box-shadow:inset 0 3px 6px rgba(0,0,0,0.12);
}
.drawer.open{ max-height:560px; }
.drawer-inner{ padding:14px 22px 16px; display:grid; grid-template-columns:1fr 1fr; gap:16px 24px; }
/* Stable zones across games (user-tuned): the tolerance fader never migrates,
   and rows pack compactly — DOM order alternates left/right so grid auto-
   placement never skips a row (an explicit col-1 item after a col-2 item forces
   the cursor down one row).
   LEFT:  source/upload, hearing safety, boost-cut, instrument, root, pattern, detection
   RIGHT: tolerance fader, freq range, direction, playback, BPM range, reset */
#sourceField,#uploadField,#loudnessField,#bcField,#instrumentField,
#rootField,#grooveField,#detectionField,#funcLabelsField,#funcInstrumentField{ grid-column:1; }
#tolField,#freqRangeField,#directionField,#playStyleField,#bpmRangeField,#resetField,#startLevelField{ grid-column:2; }
.panel-head{
  grid-column:1 / -1; font-size:10px; letter-spacing:.22em; color:var(--ink-dim);
  border-bottom:1px dashed var(--line); padding-bottom:6px; text-transform:uppercase;
  display:flex; justify-content:space-between; align-items:center; gap:12px;
}
/* close control for the mobile settings overlay — hidden on desktop (inline drawer) */
.drawer-close{
  display:none; flex:0 0 auto; font-family:var(--font-mono); font-size:11px; font-weight:600;
  letter-spacing:.1em; color:var(--ink); background:var(--chassis-raised);
  border:1px solid var(--line); border-radius:4px; padding:6px 12px; cursor:pointer;
  box-shadow:0 1px 0 var(--chassis-deep);
}
.drawer-close:active{ transform:translateY(1px); box-shadow:none; }
.serial-plate{
  grid-column:1 / -1; font-size:9px; letter-spacing:.14em; color:var(--ink-dim);
  border:1px solid var(--line); border-radius:2px; padding:5px 8px; text-align:center;
  text-transform:uppercase; background:var(--chassis);
}
.field{ display:flex; flex-direction:column; gap:6px; }
.field label{ font-size:10px; color:var(--ink-dim); letter-spacing:.12em; text-transform:uppercase; }
.field-hint{ text-transform:none; letter-spacing:0; opacity:.65; font-weight:400; }
.field select, .field input[type=file]{
  background:var(--chassis-raised); border:1px solid var(--line); color:var(--ink);
  padding:8px 10px; border-radius:3px; font-family:var(--font-mono); font-size:12px;
}
.field .row{ display:flex; align-items:center; gap:12px; }
.field .val{ font-size:12px; color:var(--ink); min-width:88px; font-weight:600; }
.field input[type=number]{
  width:90px; background:var(--chassis-raised); border:1px solid var(--line); color:var(--ink);
  padding:8px 10px; border-radius:3px; font-family:var(--font-mono); font-size:12px;
}
.range-sep{ color:var(--ink-dim); font-size:12px; }
.toggle-group{ display:flex; gap:6px; }
.toggle-group button{
  flex:1; background:var(--chassis-raised); border:1px solid var(--line); color:var(--ink-dim);
  padding:7px 8px; border-radius:3px; font-size:11px; cursor:pointer; font-family:var(--font-mono);
  text-transform:uppercase; letter-spacing:.05em;
  box-shadow:0 1px 0 var(--chassis-deep);
}
.toggle-group button.active{
  background:var(--chassis-recess); color:var(--ink);
  box-shadow:inset 0 2px 3px rgba(0,0,0,0.22);
  border-color:var(--accent);
}
.checkbox-row{ display:flex; align-items:center; gap:8px; font-size:12px; color:var(--ink); }
.checkbox-row input{ accent-color:var(--accent); }
.checkbox-row label{ text-transform:none; font-size:12px; letter-spacing:0; }
.reset-link{
  background:none; border:none; color:var(--ink-dim); font-size:10px; text-decoration:underline;
  cursor:pointer; padding:0; text-align:left; font-family:var(--font-mono);
}
.reset-link:hover{ color:var(--ink); }

/* ---- Fader slider (tolerance) ---- */
input[type=range].fader{
  -webkit-appearance:none; appearance:none;
  flex:1; height:24px; background:transparent; margin:0;
}
.fader::-webkit-slider-runnable-track{
  height:6px; border-radius:2px;
  background:var(--screen-bg); border:1px solid var(--bezel);
  box-shadow:inset 0 1px 2px rgba(0,0,0,0.5);
}
.fader::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none;
  width:16px; height:22px; margin-top:-9px; border-radius:2px; cursor:ew-resize;
  background:linear-gradient(180deg,#4a4d51,#2b2e31);
  border:1px solid #17181b;
  background-image:linear-gradient(90deg, transparent 6px, #d8dad4 6px, #d8dad4 9px, transparent 9px),
                   linear-gradient(180deg,#4a4d51,#2b2e31);
}
.fader::-moz-range-track{
  height:6px; border-radius:2px;
  background:var(--screen-bg); border:1px solid var(--bezel);
  box-shadow:inset 0 1px 2px rgba(0,0,0,0.5);
}
.fader::-moz-range-thumb{
  width:16px; height:22px; border-radius:2px; cursor:ew-resize;
  background:linear-gradient(90deg, transparent 6px, #d8dad4 6px, #d8dad4 9px, transparent 9px),
             linear-gradient(180deg,#4a4d51,#2b2e31);
  border:1px solid #17181b;
}
/* Volume fader: fixed console width (not the tolerance fader's flex:1 stretch).
   touch-action:none keeps a drag horizontal so it never scrolls/pulls the page —
   the old rotary knob's vertical-drag gesture was what fought the page scroll. */
input[type=range].vol-fader{
  flex:0 0 auto; width:clamp(130px, 42vw, 190px); touch-action:none;
}

/* ---- Rotary knob (volume) — dark plastic on the chassis ---- */
.knob{ position:relative; display:inline-flex; }
.knob-input{
  position:absolute; opacity:0; width:1px; height:1px; overflow:hidden;
  pointer-events:none;
}
.knob-dial{
  width:34px; height:34px; border-radius:50%;
  background:radial-gradient(circle at 50% 42%, #3b3e42, #202225 68%, #131416);
  border:1px solid #0f1012;
  box-shadow:0 2px 3px rgba(0,0,0,0.35), inset 0 1px 1px rgba(255,255,255,0.12);
  position:relative; cursor:ns-resize; touch-action:none;
  --angle:0deg;
}
.knob-pointer{ position:absolute; inset:0; transform:rotate(var(--angle)); }
.knob-pointer::before{
  content:''; position:absolute; left:calc(50% - 1.5px); top:2px;
  width:3px; height:calc(50% - 4px); background:#e4e6e0;
}
.knob-dial::before{
  content:''; position:absolute; left:calc(50% - 3px); top:calc(50% - 3px);
  width:6px; height:6px; border-radius:50%; background:#0d0e10; z-index:1;
}
.knob:focus-within .knob-dial{ outline:2px solid var(--accent); outline-offset:2px; }

/* ---- The screen ---- */
.scope-wrap{ padding:16px 22px 8px; }
.screen{
  position:relative; border-radius:8px;
  background:var(--screen-bg);
  border:4px solid var(--bezel);
  box-shadow:
    inset 0 0 26px rgba(0,0,0,0.55),
    0 1px 0 var(--emboss);
  overflow:hidden;
}
/* CRT glass: scanlines + vignette + one static reflection streak. Screen-scoped only. */
.screen::after{
  content:''; position:absolute; inset:0; pointer-events:none; z-index:5;
  background:
    linear-gradient(115deg, rgba(255,255,255,0.045) 0 10%, transparent 10.5%),
    repeating-linear-gradient(0deg, rgba(0,0,0,0.20) 0px, rgba(0,0,0,0.20) 1px, transparent 1px, transparent 3px),
    radial-gradient(ellipse at center, transparent 58%, rgba(0,0,0,0.4) 100%);
}
svg#scope{ width:100%; height:auto; display:block; touch-action:none; cursor:crosshair; }
.axis-label{ font-family:var(--font-mono); font-size:10px; fill:var(--phos-dim); }
.db-label{ font-family:var(--font-mono); font-size:10px; fill:var(--phos-dim); }
#cursorReadout{ font-family:var(--font-counter); font-size:20px; fill:var(--phos-bright); }
#cursorReadoutBg{ fill:var(--screen-bg); stroke:var(--phos); stroke-width:1; }
#paramReadout{ font-family:var(--font-mono); font-size:12px; fill:var(--phos-dim); }
#feedbackText{ font-family:var(--font-mono); font-size:13px; font-weight:600; letter-spacing:.04em; }
/* backing plate so the centered message stays legible over reveal graphics
   (EQ curve, GR trace, level rails all live mid-screen too) */
#feedbackBg{ fill:var(--screen-bg); stroke:var(--phos-dim); stroke-width:1; }

/* ---- Controls deck (physical keys) ---- */
.deck{ padding:14px 22px 20px; display:flex; flex-direction:column; gap:14px; }
.deck-row{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
.btn{
  font-family:var(--font-mono); font-size:12px; font-weight:600;
  letter-spacing:.07em; text-transform:uppercase;
  padding:10px 16px; cursor:pointer; border-radius:4px;
  border:1px solid var(--line);
  background:var(--chassis-raised); color:var(--ink);
  box-shadow:0 2px 0 var(--chassis-deep), inset 0 1px 0 var(--emboss);
}
.btn:hover{ background:var(--chassis); }
/* scripted press: keyboard/spacebar activation never triggers :active, so a quick
   dip-and-return plays on every click. Unset props at 0%/100% fall back to each
   button's own shadow, so one keyframe serves .btn and .btn-primary alike. */
@keyframes btn-press{
  0%,100%{ transform:none; }
  35%{ transform:translateY(2px); box-shadow:0 0 0 rgba(0,0,0,0), inset 0 1px 2px rgba(0,0,0,0.25); }
}
.btn.pressed{ animation:btn-press .16s ease-out; }
.btn:active{ transform:translateY(1px); box-shadow:0 1px 0 var(--chassis-deep); }
.btn:disabled{
  opacity:.45; cursor:not-allowed; transform:none;
  box-shadow:inset 0 1px 2px rgba(0,0,0,0.15); background:var(--chassis-recess);
}
.btn-primary{
  background:var(--accent); color:var(--accent-ink); border-color:var(--accent-deep);
  box-shadow:0 2px 0 var(--accent-deep), inset 0 1px 0 rgba(255,255,255,0.35);
}
.btn-primary:hover{ background:#ec8842; }
.btn-primary:active{ box-shadow:0 1px 0 var(--accent-deep); }
.btn-ghost{ background:var(--chassis-raised); }
.nudge-btn{
  width:34px; height:36px; border-radius:4px; border:1px solid var(--line);
  background:var(--chassis-raised); color:var(--ink); cursor:pointer; font-size:12px;
  font-family:var(--font-mono);
  box-shadow:0 2px 0 var(--chassis-deep), inset 0 1px 0 var(--emboss);
}
.nudge-btn:hover{ background:var(--chassis); }
.nudge-btn:active{ transform:translateY(1px); box-shadow:0 1px 0 var(--chassis-deep); }
.vol-wrap{ display:flex; align-items:center; gap:10px; }
.vol-wrap .vol-lbl{ font-size:10px; color:var(--ink-dim); letter-spacing:.18em; }
.vol-wrap .vol-val{ font-size:12px; color:var(--ink); min-width:42px; font-weight:600; }
.hotkey-hint{ margin-left:auto; font-size:10px; color:var(--ink-dim); }
.eq-switch{ display:flex; align-items:center; gap:10px; margin-left:auto; }
.eq-switch .lbl{ font-size:11px; color:var(--ink-dim); text-transform:uppercase; letter-spacing:.08em; }
.eq-switch .lbl.on{ color:var(--ink); font-weight:700; }
.switch{
  width:46px; height:22px; border-radius:3px;
  background:var(--screen-bg); border:1px solid var(--bezel);
  box-shadow:inset 0 1px 3px rgba(0,0,0,0.5);
  position:relative; cursor:pointer;
}
.switch .knob-nub{
  position:absolute; top:2px; left:2px; width:18px; height:16px; border-radius:2px;
  background:linear-gradient(180deg,#4a4d51,#2b2e31); border:1px solid #17181b;
  transition:left .12s;
}
.switch.on .knob-nub{ left:24px; background:linear-gradient(180deg,#ffab6a,var(--accent)); border-color:var(--accent-deep); }
.switch.disabled{ opacity:.35; cursor:not-allowed; }
.toggles-left{ font-size:11px; color:var(--ink-dim); }

/* ---- Answer keys (interval trainer) ---- */
.answer-grid{
  display:grid; grid-template-columns:repeat(12, minmax(44px, 1fr)); gap:6px;
  /* min-content (not 0): a crushed grid spills its keys under the buttons after it;
     refusing to shrink makes the deck row wrap instead */
  flex:1; min-width:min-content;
}
.answer-key{
  position:relative;
  display:flex; align-items:center; justify-content:center;
  min-height:46px;
  font-family:var(--font-mono); font-size:12px; font-weight:700;
  padding:8px 2px; border-radius:4px; cursor:pointer;
  border:1px solid var(--line);
  background:var(--chassis-raised); color:var(--ink);
  box-shadow:0 2px 0 var(--chassis-deep), inset 0 1px 0 var(--emboss);
}
.answer-key .key-hint{
  position:absolute; top:2px; left:4px;
  font-size:8px; font-weight:400; color:var(--ink-dim);
}
.answer-key:hover:not(:disabled){ background:var(--chassis); }
.answer-key:active:not(:disabled){ transform:translateY(1px); box-shadow:0 1px 0 var(--chassis-deep); }
.answer-key:disabled{
  opacity:.4; cursor:not-allowed;
  background:var(--chassis-recess); box-shadow:inset 0 1px 2px rgba(0,0,0,0.15);
}
.answer-key.correct{
  opacity:1;
  background:var(--accent); color:var(--accent-ink); border-color:var(--accent-deep);
  box-shadow:0 2px 0 var(--accent-deep);
}
.answer-key.wrong{
  opacity:1;
  background:var(--chassis-deep); color:var(--ink-dim);
  box-shadow:inset 0 2px 3px rgba(0,0,0,0.35);
}
@media (max-width:760px){
  .answer-grid{ grid-template-columns:repeat(6, minmax(44px, 1fr)); }
}

/* ---- FUNC_EAR on-scope piano (phosphor outline keys) ---- */
.fk{ cursor:pointer; }
.fk-white{ fill:rgba(0,0,0,0.25); stroke:var(--phos-dim); stroke-width:1; }
.fk-black{ fill:var(--phos-dim); stroke:var(--phos-dim); stroke-width:1; }
.fk-white:hover{ fill:var(--amber-dim); }
.fk-black:hover{ fill:var(--phos); }
.fk-off{ opacity:0.22; cursor:default; pointer-events:none; }
.fk-locked{ pointer-events:none; }
.fk-correct{ fill:var(--green) !important; stroke:var(--green); opacity:1; }
.fk-wrong{ fill:none; stroke:var(--red); stroke-width:2.5; opacity:1; }
.fk-label{ font-family:var(--font-mono); font-size:11px; fill:var(--phos-dim); pointer-events:none; }
.fk-label-off{ opacity:0.3; }

/* ---- Aux monitor (MR-3000-style side modules) ---- */
.aux{ display:none; flex:0 0 242px; }
@media (min-width:1250px){ .aux{ display:block; } }
.aux-plate{
  background:var(--chassis);
  border:1px solid var(--chassis-deep);
  border-radius:10px;
  padding:10px 10px 8px;
  box-shadow:
    inset 0 1px 0 var(--emboss),
    0 18px 50px -18px rgba(0,0,0,0.55);
}
.aux-screen{
  position:relative; overflow:hidden; border-radius:8px;
  background:var(--screen-bg);
  border:4px solid var(--bezel);
  box-shadow: inset 0 0 26px rgba(0,0,0,0.55), 0 1px 0 var(--emboss);
  padding:10px 10px 12px;
  display:flex; flex-direction:column; gap:10px;
}
/* same CRT glass as the main scope */
.aux-screen::after{
  content:''; position:absolute; inset:0; pointer-events:none; z-index:5;
  background:
    linear-gradient(115deg, rgba(255,255,255,0.045) 0 10%, transparent 10.5%),
    repeating-linear-gradient(0deg, rgba(0,0,0,0.20) 0px, rgba(0,0,0,0.20) 1px, transparent 1px, transparent 3px),
    radial-gradient(ellipse at center, transparent 58%, rgba(0,0,0,0.4) 100%);
}
.aux-strip{
  display:flex; justify-content:space-between; align-items:baseline;
  font-family:var(--font-counter); font-size:16px; letter-spacing:.08em;
  color:var(--phos-bright); text-shadow:0 0 8px var(--phos-dim);
  border-bottom:1px solid var(--phos-dim); padding:0 2px 5px;
}
#auxClock{ background:var(--phos); color:var(--screen-bg); padding:0 6px; text-shadow:none; }
.aux-box{ border:1px solid var(--phos-dim); }
.aux-head{
  font-family:var(--font-counter); font-size:14px; letter-spacing:.14em;
  background:var(--phos); color:var(--screen-bg); padding:2px 7px 1px;
}
.aux-rows{ padding:8px 9px; display:flex; flex-direction:column; gap:6px; }
.aux-row{
  display:flex; justify-content:space-between; align-items:baseline;
  font-size:10px; letter-spacing:.1em; color:var(--phos-dim);
}
.aux-row span:last-child{
  font-family:var(--font-counter); font-size:16px; color:var(--phos-bright);
}
svg#auxTrend{ display:block; width:100%; height:72px; }
.aux-line{ fill:none; stroke:var(--phos); stroke-width:1.5; }
.aux-dot{ fill:var(--phos-bright); }
.aux-ref{ stroke:var(--phos-dim); stroke-dasharray:3 3; stroke-width:1; }
.aux-note{ font-size:9px; letter-spacing:.12em; color:var(--phos-dim); padding:0 9px 8px; }
.aux-label{
  margin-top:7px; text-align:center;
  font-size:9px; letter-spacing:.22em; color:var(--ink-dim); text-transform:uppercase;
}

/* ---- Combo milestone popup (every 5 in a row) ---- */
.combo-pop{
  position:absolute; top:20%; left:50%; transform:translate(-50%,-50%);
  font-family:var(--font-counter); font-size:44px;
  color:var(--phos-bright); text-shadow:0 0 12px var(--phos-dim);
  letter-spacing:.06em; opacity:0; pointer-events:none; z-index:6;
}
.combo-pop.show{ animation:combo-pop 1.1s ease-out forwards; }
@keyframes combo-pop{
  0%   { opacity:0; transform:translate(-50%,-50%) scale(0.5); }
  15%  { opacity:1; transform:translate(-50%,-50%) scale(1.18); }
  30%  { transform:translate(-50%,-50%) scale(1); }
  70%  { opacity:1; }
  100% { opacity:0; transform:translate(-50%,-50%) scale(1); }
}

/* ---- On-screen overlay (game over) ---- */
.overlay{
  position:absolute; inset:0; background:rgba(0,0,0,0.82);
  display:flex; align-items:center; justify-content:center; flex-direction:column; gap:14px;
  opacity:0; pointer-events:none; transition:opacity .2s; z-index:8;
}
.overlay.show{ opacity:1; pointer-events:all; }
.overlay h2{
  margin:0; font-family:var(--font-counter); font-size:36px; font-weight:400;
  color:var(--phos-bright); text-transform:uppercase; letter-spacing:.08em;
  text-shadow:0 0 8px var(--phos-dim);
}
.overlay p{ margin:0; color:var(--phos-dim); font-size:12px; letter-spacing:.06em; }

/* ---- Mobile / touch ---- */
button, select, input, .switch, .knob-dial{ touch-action:manipulation; }

@media (max-width:700px){
  .header{ flex-wrap:wrap; gap:10px; }
  /* top-aligned like desktop — centering lets the taller LEVEL block (progress
     bar) shove the other stats off-line */
  .stats{ flex-wrap:wrap; align-items:flex-start; }
  .stat .stat-value{ font-size:18px; }
  .scope-wrap{ padding:12px 12px 6px; }
  .deck{ padding:12px 14px 16px; gap:12px; }
  .term-strip{ padding-left:14px; padding-right:14px; gap:10px; }
  /* one line: the model name ellipsizes before the strip controls ever wrap */
  .term-strip > span:first-child{ min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  /* Deck, reflowed for thumbs: row 1 = Play + monitor/EQ switch (the two
     controls used every round), row 2 = nudges + a stretched Lock In, then the
     answer keys, then a full-width Next Round. Orders beat source order so the
     switch never strands on its own line with dead space beside it. */
  .deck-row{ gap:10px; }
  #playBtn{ order:0; }
  .eq-switch{ order:1; }
  #nudgeLeft{ order:2; }
  #nudgeRight{ order:3; }
  #submitBtn{ order:4; flex:1 1 auto; }
  #noChangeBtn{ order:5; flex:1 1 auto; }
  /* answer keys take a full row of their own — sharing one with the transport
     buttons squeezes them into a single skinny column. The !important beats the
     per-mode inline column style; 1fr tracks share the full width evenly. */
  .answer-grid{
    order:10;
    flex:1 1 100%;
    /* --key-cols is set per mode by renderAnswerKeys so rows come out even */
    grid-template-columns:repeat(var(--key-cols, 4), 1fr) !important;
  }
  #nextBtn{ order:11; flex:1 1 100%; }

  /* ---- Scope readability: the SVG scales to phone width (~0.4x), so its
     internal text (set in viewBox units) shrinks. Bump it up on mobile. The
     feedback backing box auto-resizes from the text bbox, so this stays safe. */
  .axis-label{ font-size:22px; }
  .db-label{ font-size:19px; }
  #paramReadout{ font-size:22px; }
  #feedbackText{ font-size:22px; }
  #cursorReadout{ font-size:23px; }
  .fk-label{ font-size:20px; }

  /* ---- Settings open as a full-screen overlay OVER the game (no push,
     no clipped columns). Desktop keeps the inline drawer. ---- */
  .drawer.open{
    position:fixed; inset:0; z-index:80; max-height:none; overflow-y:auto;
    background:var(--chassis); border-bottom:none;
    box-shadow:none;
  }
  .drawer.open .drawer-inner{ grid-template-columns:1fr; padding:0 16px 40px; }
  /* !important beats the #id{grid-column:2} rules that otherwise force a 2nd
     column (which then clips against the drawer edge on a phone) */
  .drawer.open .drawer-inner .field{ grid-column:1 / -1 !important; }
  .drawer.open .panel-head{
    position:sticky; top:0; z-index:2; margin:0 -16px 12px; padding:14px 16px;
    background:var(--chassis-raised); border-bottom:1px solid var(--line);
  }
  .drawer-close{ display:inline-flex; align-items:center; }
}

@media (max-width:640px){
  .stats{ gap:12px; }
  .header{ padding:12px 16px; }
}

@media (hover:none) and (pointer:coarse){
  .hotkey-hint{ display:none; } /* no keyboard, no hints */
  /* 16px stops iOS Safari from auto-zooming when a field gets focus (and never
     zooming back out). Must carry the `.field` prefix + [type] attribute so it
     matches the specificity of `.field input[type=number]{font-size:12px}` above
     and wins on source order — a bare `select,input` selector loses to it. */
  .field select,
  .field input[type="number"],
  .field input[type="file"],
  .field input[type="email"],
  .field input[type="password"]{ font-size:16px; }
}

/* ============================================================
   PHONE LANDSCAPE — side-by-side: the scope claims the FULL height on the left,
   the controls stack in a column on the right (two-handed play). This frees the
   whole screen height for the scope, so the piano/graph get much bigger than any
   vertical layout allows. Portrait is untouched. (max-height guard = phones only.)
   ============================================================ */
@media (orientation: landscape) and (max-height: 560px){
  body{ padding:5px 8px; }
  .rig{ height:calc(100dvh - 10px); }
  .app{
    display:grid;
    grid-template-columns: 1fr clamp(148px, 26vw, 220px);
    grid-template-rows: auto auto minmax(0, 1fr);
    grid-template-areas:
      "strip  strip"
      "header header"
      "scope  deck";
    height:100%; max-height:100%; overflow:hidden;
  }
  .term-strip{ grid-area:strip; padding-top:4px; padding-bottom:4px; }
  .header{ grid-area:header; padding:4px 16px; }
  .scope-wrap{ grid-area:scope; }
  .deck{ grid-area:deck; }

  /* slim header */
  .eyebrow{ font-size:9px; margin-bottom:1px; }
  .title-block h1{ font-size:14px; }
  .stats{ gap:14px; align-items:flex-start; }
  .stat .stat-label{ margin-bottom:2px; }
  .stat .stat-value{ font-size:15px; padding:2px 8px; }
  .level-progress, .level-progress-label{ display:none; }

  /* scope fills its whole cell (both dims); preserveAspectRatio letterboxes to fit */
  .scope-wrap{ display:flex; padding:4px 4px 4px 10px; min-height:0; min-width:0; }
  .screen{ flex:1; min-height:0; min-width:0; }
  svg#scope{ width:100%; height:100%; }

  /* scope text bumps — bigger scope now, but still scaled down from 900px native */
  .axis-label{ font-size:18px; }
  .db-label{ font-size:16px; }
  #paramReadout{ font-size:18px; }
  #feedbackText{ font-size:18px; }
  #cursorReadout{ font-size:21px; }
  .fk-label{ font-size:16px; }

  /* controls column on the right — full-width stacked keys, vol at the bottom.
     `safe center` centers sparse decks but never clips the top of a tall one
     (interval's answer grid) when it overflows — it falls back to top-align. */
  .deck{ flex-direction:column; justify-content:safe center; align-items:stretch;
         gap:7px; padding:6px 10px 6px 6px; overflow-y:auto; }
  .deck-row{ flex-wrap:wrap; gap:7px; margin:0; }
  #playBtn, #submitBtn, #nextBtn, #noChangeBtn{ flex:1 1 100%; }
  .nudge-btn{ flex:1 1 40%; height:38px; }
  .eq-switch{ flex:1 1 100%; justify-content:center; margin:0; }
  .vol-wrap{ flex:1 1 100%; }
  input[type=range].vol-fader{ flex:1; width:auto; }
  /* interval answer keys: compact 3-col grid inside the column */
  .answer-grid{ flex:1 1 100%; grid-template-columns:repeat(3, 1fr) !important; gap:5px; }
  .answer-key{ min-height:34px; }

  /* settings open as an overlay here too (the grid has no room for an inline
     drawer, and an unplaced grid child would break the layout) */
  .drawer.open{
    position:fixed; inset:0; z-index:80; max-height:none; overflow-y:auto;
    background:var(--chassis); border-bottom:none; box-shadow:none;
  }
  .drawer.open .drawer-inner{ padding:0 16px 30px; }
  .drawer.open .panel-head{
    position:sticky; top:0; z-index:2; margin:0 -16px 12px; padding:12px 16px;
    background:var(--chassis-raised); border-bottom:1px solid var(--line);
  }
  .drawer-close{ display:inline-flex; align-items:center; }
}

@media (prefers-reduced-motion: reduce){
  *{ transition:none !important; animation:none !important; }
}

/* ============================================================
   GAME SELECT — landing screen (full-screen overlay).
   Left: matte spec-plate list. Right: backlit green LCD detail.
   Mobile: detail pane drops away; cards tap-to-expand inline.
   ============================================================ */
.strip-left{ display:flex; align-items:center; gap:12px; min-width:0; }
.strip-left > span{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Primary nav control — accent-outlined so it stands out against the muted
   grey strip (it's the only way back to Game Select). Fills on hover. */
.menu-btn{
  flex:0 0 auto; font:inherit; font-size:11px; font-weight:600; letter-spacing:.14em;
  text-transform:uppercase; cursor:pointer;
  color:var(--accent); background:var(--chassis-raised); border:1px solid var(--accent-deep);
  border-radius:4px; padding:6px 14px;
  box-shadow:0 1px 0 var(--chassis-deep), inset 0 1px 0 var(--emboss);
}
.menu-btn:hover{ background:var(--accent); color:var(--accent-ink); border-color:var(--accent-deep); }
.menu-btn:active{ transform:translateY(1px); box-shadow:none; }

.game-select{
  position:fixed; inset:0; z-index:60; overflow-y:auto;
  display:flex; justify-content:center; align-items:flex-start; padding:28px 14px;
  background:
    linear-gradient(var(--mat-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--mat-line) 1px, transparent 1px),
    var(--mat);
  background-size:28px 28px, 28px 28px, auto;
}
.game-select[hidden]{ display:none; }
.gs-app{
  user-select:none; -webkit-user-select:none;
  width:100%; max-width:960px; background:var(--chassis);
  border:1px solid var(--chassis-deep); border-radius:10px; overflow:hidden;
  box-shadow: inset 0 1px 0 var(--emboss), 0 18px 50px -18px rgba(0,0,0,0.55);
}

.gs-head{ display:flex; justify-content:space-between; align-items:flex-end; padding:20px 22px 16px; }
.gs-head .gs-eyebrow{ font-size:10px; letter-spacing:.22em; text-transform:uppercase; color:var(--ink-dim); margin-bottom:8px; }
.gs-head h1{ margin:0; font-size:26px; letter-spacing:.06em; font-weight:700; color:var(--ink); }
.gs-count{ font-size:10px; letter-spacing:.16em; color:var(--ink-dim); border:1px solid var(--line); border-radius:5px; padding:5px 10px; white-space:nowrap; }

.gs-body{ display:grid; grid-template-columns:1fr 1fr; gap:16px; padding:0 22px 22px; align-items:start; }

.gs-list{ display:flex; flex-direction:column; gap:8px; }
.game-item{
  text-align:left; font:inherit; cursor:pointer; color:var(--ink);
  background:linear-gradient(var(--chassis-raised), var(--chassis-recess));
  border:1px solid var(--chassis-deep); border-left:3px solid var(--line);
  border-radius:7px; padding:11px 13px 11px 14px; position:relative;
  transition:border-color .12s, transform .05s;
}
.game-item:active{ transform:translateY(1px); }
.game-item .gi-top{ display:flex; justify-content:space-between; align-items:baseline; gap:10px; }
.game-item .gi-code{ font-size:9px; letter-spacing:.16em; color:var(--ink-dim); }
.game-item .gi-name{ font-size:16px; font-weight:700; letter-spacing:.02em; }
.game-item .gi-tag{ font-size:9px; letter-spacing:.14em; color:var(--ink-dim); border:1px solid var(--line); border-radius:4px; padding:2px 6px; white-space:nowrap; }
.game-item .gi-sub{ font-size:11px; color:var(--ink-dim); margin-top:5px; letter-spacing:.03em; }
.game-item .gi-caret{ position:absolute; right:12px; top:50%; transform:translateY(-50%); color:var(--accent); font-size:12px; opacity:0; transition:opacity .12s; }
.game-item.sel{ border-left-color:var(--accent); border-color:var(--accent-deep); background:linear-gradient(var(--chassis-raised), var(--chassis)); }
.game-item.sel .gi-caret{ opacity:1; }
.game-item:focus{ outline:none; }
.game-item:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }

.gs-detail{
  border:1px solid var(--bezel); border-radius:9px; padding:18px 18px 16px;
  position:sticky; top:22px; min-height:340px; display:flex; flex-direction:column;
  overflow:hidden; color:var(--lcd-ink);
  background:radial-gradient(120% 90% at 50% 40%, var(--lcd-lit), var(--lcd-edge));
}
.gs-detail::before{
  content:''; position:absolute; inset:0; pointer-events:none; opacity:.5;
  background:repeating-linear-gradient(0deg, transparent 0 2px, var(--lcd-scan) 2px 3px);
}
.gs-detail > *{ position:relative; }
.gs-dp-strip{ display:flex; justify-content:space-between; font-size:10px; letter-spacing:.18em; color:var(--lcd-mid); border-bottom:1px solid var(--lcd-frame); padding-bottom:8px; margin-bottom:14px; }
.gs-dp-title{ font-family:var(--font-counter); font-size:38px; line-height:.9; color:var(--lcd-ink); letter-spacing:.02em; }
.gs-dp-eyebrow{ font-size:11px; letter-spacing:.14em; color:var(--lcd-mid); margin-top:6px; text-transform:uppercase; }
.gs-dp-pitch{ font-size:13px; line-height:1.5; margin:16px 0; color:var(--lcd-ink); }
.gs-dp-block{ margin-bottom:10px; border:1px solid var(--lcd-frame); border-radius:5px; padding:9px 11px; }
.gs-dp-label{ font-size:10px; letter-spacing:.16em; color:var(--lcd-mid); margin-bottom:5px; }
.gs-dp-prog{ font-size:12px; line-height:1.5; color:var(--lcd-ink); }
.gs-keys{ display:flex; flex-wrap:wrap; gap:6px; }
.gs-key{ font-size:10px; letter-spacing:.06em; border:1px solid var(--lcd-frame); border-radius:4px; padding:3px 7px; color:var(--lcd-ink); }
.gs-dp-foot{ margin-top:auto; display:flex; justify-content:space-between; align-items:center; padding-top:14px; gap:12px; }
.gs-stat{ font-size:11px; letter-spacing:.1em; color:var(--lcd-mid); }
.gs-stat b{ color:var(--lcd-ink); font-weight:700; }
.gs-boot{
  font:inherit; font-weight:700; font-size:12px; letter-spacing:.14em; cursor:pointer;
  color:var(--accent-ink); background:var(--accent); border:1px solid var(--accent-deep);
  border-radius:6px; padding:9px 16px; white-space:nowrap;
}
.gs-boot:active{ transform:translateY(1px); }

.gs-hint{ padding:10px 22px 18px; font-size:10px; letter-spacing:.1em; color:var(--ink-dim); border-top:1px solid var(--line-soft); }

/* per-item accordion detail — mobile only */
.gi-detail{ display:none; }

@media (max-width:720px){
  .gs-body{ grid-template-columns:1fr; }
  .gs-detail{ display:none; }
  .game-item .gi-caret{ display:none; }
  .gs-hint{ display:none; }
  .gs-head h1{ font-size:22px; }
  .gi-detail{ display:none; margin-top:12px; padding-top:12px; border-top:1px solid var(--line); }
  .game-item.open .gi-detail{ display:block; }
  .gi-detail .gid-pitch{ font-size:12px; line-height:1.5; color:var(--ink); margin-bottom:10px; }
  .gi-detail .gid-label{ font-size:9px; letter-spacing:.16em; color:var(--ink-dim); margin-bottom:3px; text-transform:uppercase; }
  .gi-detail .gid-prog{ font-size:11px; line-height:1.5; color:var(--ink); margin-bottom:10px; }
  .gi-detail .gs-keys{ margin-bottom:12px; }
  .gi-detail .gs-key{ color:var(--ink); border-color:var(--line); }
  .gi-detail .gs-boot{ width:100%; padding:11px; }
}

/* ---- THEORY_RUNNER (CODE_007) — chord-invader field + MIDI deck ----
   The field repaints once per rank-step: keep it filter/shadow-free (house
   rule for animating elements). All glow is plain phosphor fills. */
svg#runner{ width:100%; height:auto; display:block; }
/* full-screen game surface: stats header + aux monitor fold away, the app
   column takes the aux's width too, and the HUD lives inside the field
   (score / hearts / level bar, arcade-style) */
.rig.runner-full .header{ display:none; }
.rig.runner-full .aux{ display:none; }
.rig.runner-full .app{ max-width:1220px; }
.rig.runner-full .scope-wrap{ padding:10px 14px 4px; }
/* combo popup rides the HUD band beside the score — its old mid-screen spot
   sat exactly on the spawn rows and hid fresh enemies (user) */
.rig.runner-full .combo-pop{ top:8%; left:69%; font-size:30px; }
#runDanger{ stroke:var(--red); stroke-width:1.5; stroke-dasharray:7 5; opacity:.75; }
.rh-danger-lbl{ font-family:var(--font-mono); font-size:9px; fill:var(--red); opacity:.55; letter-spacing:.2em; }
.rh-lvl{ font-family:var(--font-counter); font-size:26px; fill:var(--phos); }
.rh-seg{ fill:none; stroke:var(--phos-dim); stroke-width:1.5; }
.rh-seg-fill{ fill:var(--phos); stroke:var(--phos); }
.rh-chap{ font-family:var(--font-mono); font-size:11px; fill:var(--phos-dim); letter-spacing:.1em; }
.rh-score{ font-family:var(--font-counter); font-size:36px; fill:var(--phos-bright); }
/* progression strip: the whole shape stays visible, the chord you're on is lit */
.rh-prog{ font-family:var(--font-mono); font-size:13px; fill:var(--phos-dim); letter-spacing:.06em; opacity:.55; }
.rh-prog-now{ fill:var(--phos-bright); opacity:1; font-weight:700; }
/* NEW KEY card: a key you have never played is introduced, not sprung */
.run-newkey-eyebrow{ font-family:var(--font-mono); font-size:11px; letter-spacing:.34em; fill:var(--phos-dim); }
.run-newkey{ font-family:var(--font-counter); font-size:40px; fill:var(--phos-bright); letter-spacing:.06em; }
.run-newkey-notes{ font-family:var(--font-mono); font-size:17px; letter-spacing:.14em; fill:var(--phos-bright); opacity:.9; }
.run-newkey-chords{ font-family:var(--font-mono); font-size:13px; letter-spacing:.1em; fill:var(--phos-dim); }
/* "still calculating" — the archive screen's honest readout of what you're
   still working out rather than recalling */
/* KEY_MATRIX: the key owns the prime HUD slot — it used to be an 11px dim tag on
   the end of a status line, and key changes went by unnoticed */
.rh-key{ font-family:var(--font-mono); font-size:19px; font-weight:700; letter-spacing:.16em; fill:var(--phos-bright); }
.rh-key-notes{ font-family:var(--font-mono); font-size:12px; letter-spacing:.14em; fill:var(--phos-dim); opacity:.85; }
/* A key change is the single most important thing that can happen between waves
   — every numeral on screen means something different afterwards. The banner
   says so for 1.2s and then leaves the HUD looking untouched, so the key line
   itself pulses amber for a beat. Three beats, not one: a single fade reads as a
   render glitch, a repeated pulse reads as a signal. No geometry is animated
   (letter-spacing or transform would shove the notes line around under it). */
@keyframes rhKeyChange{
  0%   { fill:var(--amber); filter:drop-shadow(0 0 7px var(--amber)); }
  16%  { fill:var(--phos-bright); filter:none; }
  32%  { fill:var(--amber); filter:drop-shadow(0 0 7px var(--amber)); }
  48%  { fill:var(--phos-bright); filter:none; }
  64%  { fill:var(--amber); filter:drop-shadow(0 0 5px var(--amber)); }
  100% { fill:var(--phos-bright); filter:none; }
}
.rh-key-new{ animation:rhKeyChange 2s ease-out 1 both; }
@media (prefers-reduced-motion: reduce){
  .rh-key-new{ animation:none; fill:var(--amber); }
}
.run-slow-title{ font-family:var(--font-mono); font-size:10px; letter-spacing:.22em; fill:var(--phos-dim); opacity:.7; }
.run-slow{ font-family:var(--font-mono); font-size:12px; letter-spacing:.06em; fill:var(--amber, var(--phos-bright)); opacity:.9; }
.rh-heart{ fill:var(--red); stroke:none; }
.rh-heart-spent{ fill:none; stroke:var(--red); stroke-width:1.5; opacity:.45; }
.rh-midi{ font-family:var(--font-mono); font-size:10px; fill:var(--phos-dim); letter-spacing:.12em; }
.rh-midi-off{ fill:var(--red); }
.run-instr{ font-family:var(--font-mono); font-size:11px; fill:var(--phos-dim); letter-spacing:.1em; }
/* chapter/wave sharing the KEY's row: context, so it must not compete with the
   key itself for attention */
.rh-chap-inline{ font-size:11px; opacity:.6; }
.run-nudge{ font-family:var(--font-mono); font-size:14px; font-weight:700; fill:var(--amber); letter-spacing:.08em; animation:runFade 1.4s ease-out forwards; }
.run-title{ font-family:var(--font-counter); font-size:52px; fill:var(--phos-bright); letter-spacing:.18em; }
.run-start{ font-family:var(--font-mono); font-size:15px; font-weight:700; fill:var(--phos); letter-spacing:.14em; }
.run-blink{ animation:runBlink 1.2s steps(2, start) infinite; }
@keyframes runBlink{ 50%{ opacity:0.15; } }
#runFeedbackText{ font-family:var(--font-mono); font-size:13px; font-weight:600; letter-spacing:.04em; }
#runFeedbackBg{ fill:var(--screen-bg); stroke:var(--phos-dim); stroke-width:1; }

/* enemies: vector plates carrying the chord name; hostile tint near the line */
.re-body{ fill:rgba(0,0,0,0.35); stroke:var(--phos); stroke-width:1.5; }
.re-ant{ fill:none; stroke:var(--phos-dim); stroke-width:1.5; }
/* FREE MODE piano: sits along the bottom of the scope so the frequency axis and
   the cursor stay readable above it */
.fkf{ cursor:pointer; }
.fkf-white{ fill:var(--phos-dim); opacity:.38; stroke:var(--screen-bg); stroke-width:1; }
/* --ink is the LIGHT text colour on this dark chassis, so using it here rendered
   the black keys pale and the whole keyboard read inverted. No stroke either —
   at ~11px wide an outline made them read as light keys. */
.fkf-black{ fill:#05070b; opacity:1; }
.fkf-white:hover{ opacity:.7; }
.fkf-black:hover{ fill:var(--phos-dim); opacity:.5; }
/* the key you're on — click, drag or an actual MIDI press all light it */
.fkf-on{ fill:var(--amber); opacity:.9; }
.fkf-label{ font-family:var(--font-mono); font-size:9px; fill:var(--phos-dim); pointer-events:none; }
.re-label{ font-family:var(--font-mono); font-size:16px; font-weight:700; fill:var(--phos-bright); }
/* THE NUMERAL MUST WIN. When V6 and Fmaj/A were 16px and 13px at 72% the eye
   went to the chord name every time — it is the half that says what to play, so
   the numeral never got read (user). The numeral is now half again as large,
   full phosphor; the name under it is small, dim and letterspaced tight so it
   reads as an annotation rather than as an alternative prompt. */
.re-label-roman{ font-size:24px; letter-spacing:.04em; fill:var(--phos-bright); }
.re-spell-name{ font-size:10px; font-weight:400; opacity:.42; letter-spacing:.02em; }
.re-danger .re-spell-name{ opacity:.55; }
/* REVEAL — the on-demand scaffold. Amber while held, because it is costing you */
.rh-reveal{ font-family:var(--font-mono); font-size:11px; letter-spacing:.1em; fill:var(--phos-dim); opacity:.75; cursor:pointer; user-select:none; }
.rh-reveal-on{ fill:var(--amber); opacity:1; }
/* Transition card: level / concept / key, the beat the run stops on */
.run-tc-eyebrow{ font-family:var(--font-mono); font-size:13px; letter-spacing:.3em; fill:var(--amber); }
.run-tc-title{ font-family:var(--font-mono); font-size:26px; font-weight:700; letter-spacing:.12em; fill:var(--phos-bright); }
.run-tc-line{ font-family:var(--font-mono); font-size:12px; letter-spacing:.06em; fill:var(--phos-dim); opacity:.9; }
.run-tc-key{ font-family:var(--font-mono); font-size:20px; font-weight:700; letter-spacing:.18em; fill:var(--phos-bright); }
.run-tc-key-new{ fill:var(--amber); animation:rhKeyChange 2s ease-out 1 both; }
.run-tc-notes{ font-family:var(--font-mono); font-size:14px; letter-spacing:.16em; fill:var(--phos-dim); }
.run-tc-chords{ font-family:var(--font-mono); font-size:13px; letter-spacing:.08em; fill:var(--phos-dim); opacity:.85; }
/* how this chapter relates to the OTHER track — shown once, at the chapter's
   opening level, so the shared ground reads as a prerequisite not a repeat */
.run-tc-prereq{ font-family:var(--font-mono); font-size:11px; letter-spacing:.1em; fill:var(--amber); opacity:.7; }
/* spelling scaffold under an UNMASTERED prompt — dimmer than the label it
   serves, and gone entirely once the chord is learned */
.re-spell{ font-family:var(--font-mono); font-size:13px; font-weight:600; letter-spacing:.04em; fill:var(--phos-bright); opacity:.72; }
.re-danger .re-spell{ fill:var(--red); opacity:.85; }
.re-danger .re-body{ stroke:var(--red); }
.re-danger .re-ant{ stroke:var(--red); opacity:.7; }
.re-danger .re-label{ fill:var(--red); }

/* one-shot FX — animate opacity only, self-removed by JS */
.run-burst line{ stroke:var(--phos-bright); stroke-width:2; }
.run-burst{ animation:runFade .45s ease-out forwards; }
.run-burst-pts{ font-family:var(--font-counter); font-size:18px; fill:var(--phos-bright); text-anchor:middle; }
.run-breach text{ font-family:var(--font-mono); font-size:13px; font-weight:700; fill:var(--red); }
.run-breach{ animation:runFade .9s ease-out forwards; }
@keyframes runFade{ 0%{opacity:1;} 70%{opacity:1;} 100%{opacity:0;} }

/* idle overlay: archive index / status copy */
.run-idle-title{ font-family:var(--font-mono); font-size:12px; font-weight:700; fill:var(--phos); letter-spacing:.2em; }
.run-idle-warn{ font-family:var(--font-mono); font-size:14px; font-weight:700; fill:var(--red); letter-spacing:.08em; }
.run-idle-hint{ font-family:var(--font-mono); font-size:11px; fill:var(--phos-dim); letter-spacing:.12em; }
.run-ch{ font-family:var(--font-mono); font-size:12px; fill:var(--phos-dim); letter-spacing:.06em; }
.run-ch-cur{ fill:var(--phos-bright); font-weight:700; }
.run-ch-desc{ font-size:10px; opacity:.75; }
.run-ch-locked{ opacity:.32; }
.run-ch-link{ cursor:pointer; }
.run-ch-link:hover{ fill:var(--phos-bright); }

/* MIDI deck (chassis-side): printed labels + a live held-notes readout */
.midi-deck{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.midi-lbl{ font-size:10px; color:var(--ink-dim); letter-spacing:.12em; text-transform:uppercase; }
.midi-deck select{
  font-family:var(--font-mono); font-size:12px; color:var(--ink);
  background:var(--chassis-raised); border:1px solid var(--line); border-radius:4px; padding:6px 8px;
  max-width:180px;
}
.midi-held{
  font-family:var(--font-counter); font-size:18px; color:var(--ink);
  background:var(--chassis-recess); border:1px solid var(--line); border-radius:4px;
  padding:2px 10px; min-width:130px; min-height:24px; display:inline-block;
}
.midi-held-wrong{ animation:midiWrong .5s ease-out; }
@keyframes midiWrong{ 0%,60%{ color:var(--red); border-color:var(--red); } }

/* ---- THEORY_RUNNER player ship: keyboard-bodied fighter on the danger line.
   Held pitch classes light its keys — no filters, plain phosphor fills. ---- */
.ship-hull{ fill:var(--phos-dim); }
.ship-key{ stroke:var(--phos-dim); stroke-width:1; }
.ship-key-w{ fill:rgba(0,0,0,0.45); }
.ship-key-b{ fill:var(--phos-dim); }
.ship-key.sk-on{ fill:var(--phos-bright); stroke:var(--phos-bright); }
.rh-back{ font-family:var(--font-mono); font-size:10px; fill:var(--phos-dim); letter-spacing:.14em; cursor:pointer; }
.rh-back:hover{ fill:var(--phos-bright); }

/* ---- THEORY_RUNNER boss fights: big plate + HP bar, pulses on the metronome ---- */
.boss-body{ stroke-width:2.5; }
.boss-label{ font-size:26px; }
.boss-hp-frame{ fill:none; stroke:var(--phos-dim); stroke-width:1.5; }
.boss-hp-fill{ fill:var(--red); }
.boss-beat .re-body{ stroke:var(--phos-bright); }
.boss-beat .re-label{ fill:var(--phos-bright); }
/* boss timing lane (guitar-hero strip): plates glide via rAF transform — keep
   every element here filter/shadow-free (house rule) */
.lane-track{ stroke:var(--grid-major); stroke-width:1; }
.lane-strike{ stroke:var(--phos-bright); stroke-width:2; }
.lane-zone{ fill:var(--amber-dim); }
.lane-pip{ fill:none; stroke:var(--phos-dim); stroke-width:1; }
.lane-pip-on{ fill:var(--phos-bright); stroke:var(--phos-bright); }
.lane-plate-body{ fill:rgba(0,0,0,0.35); stroke:var(--phos-dim); stroke-width:1.5; }
.lane-label{ font-family:var(--font-mono); font-size:14px; font-weight:700; fill:var(--phos-dim); }
.lane-current .lane-plate-body{ stroke:var(--phos); stroke-width:2; }
.lane-current .lane-label{ fill:var(--phos); }
/* already answered this bar — slides past marked, no longer takes input */
.lane-hit .lane-plate-body{ fill:rgba(0,0,0,0.15); stroke:var(--phos-dim); stroke-width:1; }
.lane-hit .lane-label{ fill:var(--phos-dim); opacity:.5; }
/* inside the hit window — this chord will actually count now */
.lane-live .lane-plate-body{ stroke:var(--phos-bright); fill:var(--amber-dim); }
.lane-live .lane-label{ fill:var(--phos-bright); }
.run-tier text{ font-family:var(--font-counter); font-size:20px; fill:var(--phos); }
.run-tier{ animation:runFade .8s ease-out forwards; }
.run-tier-perfect text{ font-size:26px; fill:var(--phos-bright); }

/* ---- GROOVE_LAB (CODE_008) — deviation scope + pad map ----
   The scope repaints per frame: opacity/fill transitions only, never
   shadow/filter/blur (house rule for animating surfaces). */
svg#groove{ width:100%; height:auto; display:block; }
.gv-hud{ font-family:var(--font-mono); font-size:12px; fill:var(--phos); letter-spacing:.1em; }
.gv-hud-meta{ font-family:var(--font-mono); font-size:11px; fill:var(--phos-dim); letter-spacing:.09em; }
.gv-hud-lamp{ font-family:var(--font-mono); font-size:10px; fill:var(--phos-dim); letter-spacing:.12em; }
.gv-band{ fill:rgba(255,255,255,0.018); }
.gv-band-miss{ fill:rgba(255,120,90,0.20); }
.gv-band-extra{ fill:rgba(224,118,46,0.14); }
.gv-zone-good{ fill:var(--amber-dim); }
.gv-zone-perfect{ fill:rgba(111,220,127,0.20); }
:root[data-theme=dark] .gv-zone-perfect{ fill:rgba(108,184,255,0.20); }
@media (prefers-color-scheme: dark){ :root:not([data-theme=light]) .gv-zone-perfect{ fill:rgba(108,184,255,0.20); } }
.gv-target{ stroke:var(--phos-bright); stroke-width:2; }
.gv-lane-label{ font-family:var(--font-mono); font-size:10px; fill:var(--phos-dim); letter-spacing:.12em; }
.gv-axis{ font-family:var(--font-mono); font-size:9px; fill:var(--phos-dim); letter-spacing:.16em; opacity:.75; }

/* hit blips — instant, colour-coded, self-fading */
.gv-blip{ animation:gvFade 1.6s ease-out forwards; }
.gv-perfect{ fill:var(--phos-bright); }
.gv-good{ fill:var(--amber); }
.gv-poor, .gv-wrongPad{ fill:var(--red); }
@keyframes gvFade{ 0%{opacity:1;} 55%{opacity:.9;} 100%{opacity:0;} }

/* loop-position strip */
.gv-strip-rail{ stroke:var(--grid-major); stroke-width:1; }
.gv-strip-bar{ stroke:var(--phos-dim); stroke-width:1; }
.gv-tick{ fill:none; stroke:var(--phos-dim); stroke-width:1.2; }
.gv-tick-ghost{ opacity:.5; }
.gv-playhead{ stroke:var(--accent); stroke-width:2; }

/* pad map */
.gv-pad-box{ fill:var(--phos); fill-opacity:.12; stroke:var(--phos-dim); stroke-width:1.2; }
.gv-pad-box.gv-pad-lit{ fill:var(--phos-bright); fill-opacity:.55; stroke:var(--phos-bright); }
.gv-pad-label{ font-family:var(--font-mono); font-size:11px; font-weight:700; fill:var(--phos-bright); letter-spacing:.08em; }
.gv-pad-note{ font-family:var(--font-mono); font-size:9px; fill:var(--phos-dim); letter-spacing:.1em; }

/* overlays: idle, count-in, results */
.gv-title{ font-family:var(--font-counter); font-size:46px; fill:var(--phos-bright); letter-spacing:.16em; }
.gv-idle-warn{ font-family:var(--font-mono); font-size:13px; font-weight:700; fill:var(--red); letter-spacing:.08em; }
.gv-idle-hint{ font-family:var(--font-mono); font-size:11px; fill:var(--phos-dim); letter-spacing:.1em; }
.gv-countin{ font-family:var(--font-counter); font-size:88px; fill:var(--phos-bright); opacity:.85; }
.gv-phase-big{ font-family:var(--font-mono); font-size:26px; font-weight:700; fill:var(--phos-bright); letter-spacing:.22em; }
.gv-phase{ font-family:var(--font-mono); font-size:11px; fill:var(--phos-dim); letter-spacing:.16em; }
.gv-panel{ fill:var(--screen-bg); stroke:var(--phos); stroke-width:1.5; }
.gv-res-title{ font-family:var(--font-mono); font-size:16px; font-weight:700; letter-spacing:.16em; }
.gv-pass{ fill:var(--phos-bright); } .gv-fail{ fill:var(--red); }
.gv-practice{ fill:var(--amber); }
.gv-res-big{ font-family:var(--font-counter); font-size:52px; fill:var(--phos-bright); }
.gv-res-sub{ font-family:var(--font-mono); font-size:10px; fill:var(--phos-dim); letter-spacing:.12em; }
.gv-res-k{ font-family:var(--font-mono); font-size:9px; fill:var(--phos-dim); letter-spacing:.14em; }
.gv-res-v{ font-family:var(--font-counter); font-size:22px; fill:var(--phos); }
.gv-res-feel{ font-family:var(--font-mono); font-size:12px; font-weight:700; fill:var(--amber); letter-spacing:.1em; }
.gv-res-hint{ font-family:var(--font-mono); font-size:10px; fill:var(--phos-dim); letter-spacing:.16em; }
.gv-res-note{ font-family:var(--font-mono); font-size:10px; fill:var(--amber); letter-spacing:.08em; }
.gv-calib-link{ text-decoration:none; }

/* deck */
.groove-deck{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.groove-deck select{
  font-family:var(--font-mono); font-size:12px; color:var(--ink);
  background:var(--chassis-raised); border:1px solid var(--line); border-radius:4px;
  padding:6px 8px; max-width:170px;
}
.gv-learn-row{ display:flex; gap:5px; flex-wrap:wrap; }
.gv-learn-btn{
  display:flex; flex-direction:column; align-items:center; gap:1px;
  font-family:var(--font-mono); font-size:8px; letter-spacing:.06em;
  padding:4px 8px; border-radius:4px; cursor:pointer;
  border:1px solid var(--line); background:var(--chassis-raised); color:var(--ink-dim);
}
.gv-learn-btn b{ font-family:var(--font-counter); font-size:14px; color:var(--ink); }
.gv-learn-btn.listening{ border-color:var(--accent); color:var(--accent); }
.gv-learn-btn.listening b{ color:var(--accent); font-size:9px; font-family:var(--font-mono); }

/* ---- GROOVE_LAB mix: three channels under the deck's master fader ---- */
.mix-rows{ display:flex; flex-direction:column; gap:6px; }
.mix-row{ display:flex; align-items:center; gap:9px; }
.mix-mute{
  flex:0 0 auto; width:24px; height:24px; border-radius:4px; cursor:pointer;
  font-family:var(--font-mono); font-size:10px; font-weight:700;
  border:1px solid var(--line); background:var(--chassis-raised); color:var(--ink-dim);
}
.mix-mute:hover{ background:var(--chassis); }
.mix-mute.muted{ background:var(--red); color:var(--accent-ink); border-color:var(--red); }
.mix-name{
  flex:0 0 62px; font-family:var(--font-mono); font-size:10px;
  color:var(--ink-dim); letter-spacing:.1em; text-transform:uppercase;
}
.mix-fader{ flex:1 1 auto; min-width:80px; }
.mix-val{
  flex:0 0 40px; text-align:right;
  font-family:var(--font-counter); font-size:15px; color:var(--ink);
}
