/* ============================================================
   DANCY ANTS — CONTROL SURFACE  (v2)
   ============================================================ */

:root{
  --bg:#08080a; --panel:#0d0d10; --panel2:#131317; --panel3:#191920;
  --line:#1d1d23; --line2:#2a2a33; --line3:#3a3a46;
  /* --dim2 sat at 2.4:1 contrast, which made every hintline a squint.
     One step up keeps the hierarchy and makes the small text readable. */
  --txt:#e9e9ee; --dim:#8e8e9c; --dim2:#7e7e8a;
  --live:#ff3b30; --learn:#ffcc00; --ok:#30d158; --cue:#3f8ae0;
  --r:3px;
}
*{box-sizing:border-box;}
html,body{margin:0;height:100%;}
body{
  background:var(--bg); color:var(--txt);
  font:12px/1.4 -apple-system,BlinkMacSystemFont,"Inter","Helvetica Neue",Arial,sans-serif;
  -webkit-font-smoothing:antialiased; overflow:hidden; user-select:none;
}
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;}
.lbl{font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--dim);font-weight:500;}
.spacer{flex:1;}

/* The bottom strip was a hard 172px. Together with the 44px top bar that
   is 216px of fixed chrome, which is a fifth of a 1366x768 laptop's
   viewport once browser chrome is counted — and it does not shrink when
   the window does. clamp() lets it give way on short screens while never
   collapsing below two usable rows of pads. */
/* Rows: the top bar and the dock size to their CONTENT, the centre gives
   way. The old fixed clamp was the root of years of "cut off at the
   bottom" reports — any fixed height is a bet against some laptop. */
#app{display:grid;grid-template-rows:auto minmax(0,1fr) auto;height:100%;
  grid-template-columns:300px minmax(0,1fr) var(--rw,320px);
  grid-template-areas:"top top top" "left center right" "bottom bottom right";}
/* The right panel runs the full height of the window. The effects strip
   used to span under it too, which left the panel about 600px on a laptop
   — now the strip stops at the panel's edge and the panel keeps the rest.
   #main is only a wrapper in the markup; its three columns are laid out
   on #app's grid directly. */
#top{grid-area:top;} #left{grid-area:left;} #center{grid-area:center;} #right{grid-area:right;} #bottom{grid-area:bottom;}

/* ---------- TOPBAR ---------- */
/* ~1450px of controls that can never shrink. On anything narrower —
   small laptops, browser zoom — the bar WRAPS to a second row instead of
   silently forcing the whole grid wider than the window, which is what
   used to shove the right panel off-screen. */
#top{display:flex;align-items:center;flex-wrap:wrap;gap:6px 9px;
  padding:3px 12px;min-height:44px;min-width:0;
  border-bottom:1px solid var(--line);background:var(--panel);}
#brand{font-size:11px;letter-spacing:.34em;font-weight:600;padding-right:12px;
  border-right:1px solid var(--line);display:inline-flex;align-items:center;gap:8px;}

/* The mark in the top bar is not decoration: it steps on the beat the
   engine has actually detected, so it doubles as the smallest possible
   readout of whether the app is hearing anything. Grey while there is no
   audio, KICK red the moment there is — which means a glance at the corner
   answers "is it listening?" without a label saying so.

   14x7 at 11px type: the same optical weight as the letters beside it. */
#brand .pxant{width:14px;height:7px;flex:none;
  transition:opacity .25s ease;opacity:.45;}
#brand .pxant.live{opacity:1;}

/* the ant, drawn in whole pixels — see js/ant.js */
.pxant{display:inline-block;line-height:0;vertical-align:middle}
.pxant svg{display:block;width:100%;height:100%;image-rendering:pixelated}
.pxant .pxa-b{display:none}
.pxant.b .pxa-a{display:none}
.pxant.b .pxa-b{display:block}
/* joints between the top bar's zones: output · signal · tempo · actions */
.tsep{width:1px;height:20px;background:var(--line);flex:none;}
/* The right-hand cluster (undo … help) is one piece: when the bar is too
   narrow for one row it moves down whole, right-aligned, instead of
   leaving Freeze on one row and Blackout under the logo on the next. */
#topLive{display:flex;align-items:center;gap:6px 9px;margin-left:auto;flex-wrap:nowrap;}
/* a long device name ("MacBook Pro Microphone (Built-in)") must not push
   the whole bar onto a second row */
#audioName{max-width:170px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;vertical-align:bottom;}

/* The upgrade nudge. Persistent and legible, never modal — it must not be
   something to dismiss mid-party. Hidden entirely once licensed, so paying
   customers never see a trace of it. */
#btnUpgrade{display:none;align-items:center;gap:7px;white-space:nowrap;
  border-color:#4a3a12;color:var(--learn);background:rgba(255,204,0,.06);}
#btnUpgrade.show{display:inline-flex;}
#btnUpgrade:hover{background:rgba(255,204,0,.13);border-color:var(--learn);}
.updot{width:6px;height:6px;border-radius:50%;background:var(--learn);flex:none;
  animation:updotPulse 2.4s ease-in-out infinite;}
@keyframes updotPulse{0%,100%{opacity:1}50%{opacity:.35}}

button,select,input[type=text],input[type=number]{
  font:inherit;color:var(--txt);background:var(--panel2);
  border:1px solid var(--line2);border-radius:var(--r);
  padding:5px 9px;cursor:pointer;letter-spacing:.03em;
}
button:hover,select:hover{border-color:var(--line3);background:var(--panel3);}
button.on{background:var(--txt);color:#000;border-color:var(--txt);}
/* Blackout reads dangerous at rest, not only once it has already fired */
button.danger{color:var(--live);border-color:#48211f;}
button.danger:hover{border-color:var(--live);background:var(--panel3);}
button.danger.on{background:var(--live);border-color:var(--live);color:#fff;}
button.small{padding:3px 7px;font-size:10px;}

/* ---------- AUTOPILOT: one line while it is off ---------- */
#apSec.apoff .apbody{display:none;}
#apSec:not(.apoff) .apoffnote{display:none;}
#looks[hidden],#looksNone[hidden],#looksHow[hidden],#mediaCtl[hidden]{display:none;}

/* The one action that gets the show onto the wall. */
button.primary{border-color:#3a3a48;background:var(--panel3);font-weight:500;}
button.primary:hover{border-color:var(--txt);}
/* Its fallback, present but clearly secondary. */
button.ghost{color:var(--dim);border-color:transparent;background:transparent;}
button.ghost:hover{color:var(--txt);border-color:var(--line2);background:var(--panel2);}

/* Audio off is the difference between "reacting to your music" and "an
   animation". It should draw the eye until it is dealt with, then stop —
   so the pulse lives only while there is nothing to hear. Kept to a slow
   border breath rather than anything blinking: this sits beside a
   projector feed all night. */
#btnAudio{display:inline-flex;align-items:center;gap:6px;}
#btnAudio.needed{border-color:var(--live);color:var(--txt);}
#btnAudio.needed{animation:audioWait 2.4s ease-in-out infinite;}
@keyframes audioWait{
  0%,100%{box-shadow:0 0 0 0 rgba(255,59,48,0);}
  50%    {box-shadow:0 0 0 2px rgba(255,59,48,.22);}
}
@media (prefers-reduced-motion: reduce){
  #btnAudio.needed{animation:none;box-shadow:0 0 0 2px rgba(255,59,48,.22);}
}

button:disabled{opacity:.35;cursor:default;}
select{padding:4px 6px;max-width:180px;}
input[type=text],input[type=number]{cursor:text;padding:4px 7px;}

.pill{display:inline-flex;align-items:center;gap:6px;padding:4px 9px;
  border:1px solid var(--line2);border-radius:20px;font-size:10px;letter-spacing:.06em;color:var(--dim);white-space:nowrap;}
.dot{width:6px;height:6px;border-radius:50%;background:#55555f;flex:none;}
.dot.live{background:var(--ok);box-shadow:0 0 6px var(--ok);}
.dot.warn{background:var(--learn);}
.dot.err{background:var(--live);}

#beatDot{width:9px;height:9px;border-radius:50%;background:#2a2a33;transition:background .04s;}
#beatDot.hit{background:var(--txt);}
/* Hollow when there is no audio: visibly "not receiving" rather than a
   filled dot that simply happens not to be lit this instant. */
#beatDot.deaf{background:transparent;box-shadow:inset 0 0 0 1px #33333e;}

/* ---------- MAIN ---------- */
/* Side columns were fixed at 300 + 268 = 568px regardless of window size.
   On a 1280-wide laptop that leaves 712px for the monitor; on anything
   narrower the middle — the part you actually watch — is what gets
   crushed. These steps protect the centre by taking width from the
   panels, which are lists and can simply be tighter. */
#main{display:contents;}
/* a grid child's min-content width must never win against the window */
#main > *{min-width:0;min-height:0;}
#center{overflow:hidden;}

@media (max-width:1400px){
  #app{grid-template-columns:264px minmax(0,1fr) var(--rw,300px);}

  #cueWrap{width:172px;}
}
@media (max-width:1200px){
  #app{grid-template-columns:228px minmax(0,1fr) var(--rw,280px);}
  #cueWrap{width:150px;}
  #scenes{grid-template-columns:repeat(2,1fr);}
  #fx{grid-template-columns:repeat(6,1fr);}
}
@media (max-width:1040px){
  #app{grid-template-columns:196px minmax(0,1fr) var(--rw,260px);}
  /* the cue monitor is the first thing to go — Solo mode does not use it
     and Mix can read the deck cards instead */
  #cueWrap{display:none;}
  #fx{grid-template-columns:repeat(4,1fr);}
}

/* Short viewports: the scene grid and the panels can scroll, but the
   monitor cannot be smaller than useless. Tighten padding instead. */
@media (max-height:720px){
  .sec{padding:8px 10px;}
  #mons{padding:8px 8px 0;}
  #deckbar{padding:7px 10px 8px;margin-top:8px;}
}

/* Genuinely too small to operate. Better to say so than to render a
   scrambled surface and let someone conclude the product is broken. */
#tooSmall{position:fixed;inset:0;z-index:95;background:var(--bg);
  display:none;align-items:center;justify-content:center;
  padding:28px 22px;line-height:1.6;color:var(--dim);
  overflow-y:auto;-webkit-overflow-scrolling:touch;}
@media (max-width:820px),(max-height:520px){
  #tooSmall{display:flex;}
}
.tsCard{max-width:380px;width:100%;margin:auto;text-align:left;}
.tsMark{font-size:11px;letter-spacing:.34em;font-weight:600;color:var(--dim);}
.tsAnts{display:flex;gap:7px;margin:20px 0 22px;}
.tsAnts .pxant{width:26px;height:14px;}
.tsHead{font-size:25px;line-height:1.2;font-weight:600;color:var(--txt);
  margin:0 0 12px;letter-spacing:-.02em;}
.tsBody{font-size:15px;margin:0 0 22px;color:var(--dim);}
.tsSteps{border-top:1px solid var(--line);margin-bottom:24px;}
.tsSteps div{display:flex;gap:11px;align-items:baseline;
  padding:11px 0;border-bottom:1px solid var(--line);font-size:14px;}
.tsSteps b{color:var(--live);font-variant-numeric:tabular-nums;font-weight:600;}
.tsUrl{color:var(--txt);font-weight:600;}
/* 48px tall: a tap target on a phone, not a mouse target shrunk down. */
.tsBtn{width:100%;min-height:48px;border:0;border-radius:9px;
  background:var(--live);color:#0d0d10;font-size:15px;font-weight:600;
  cursor:pointer;font-family:inherit;}
.tsBtn:active{filter:brightness(.92);}
.tsBtn.done{background:#1e4d33;color:#7ee0a5;}
.tsAlt{display:block;text-align:center;margin-top:14px;padding:10px;
  color:var(--dim);font-size:14px;text-decoration:none;}
.tsAlt:hover{color:var(--txt);}
.tsFoot{font-size:12.5px;color:var(--dim2);margin:22px 0 0;
  border-top:1px solid var(--line);padding-top:16px;}
.col{overflow:auto;min-height:0;}
/* one scrollbar design everywhere — the monitor strip and dialogs were
   getting the browser default, which reads as a different application */
::-webkit-scrollbar{width:8px;height:8px;}
::-webkit-scrollbar-thumb{background:#22222a;border-radius:4px;}
::-webkit-scrollbar-thumb:hover{background:#2e2e38;}
::-webkit-scrollbar-track{background:transparent;}
::-webkit-scrollbar-corner{background:transparent;}

/* Keyboard focus gets a visible ring; mouse clicks do not. A performance
   surface must be operable blind-ish, and invisible focus makes tabbing
   through it guesswork. */
:focus{outline:none;}
:focus-visible{outline:1px solid var(--line3);outline-offset:1px;}
button:focus-visible,select:focus-visible{outline-color:var(--txt);}

/* Anyone running the OS-level reduced-motion setting gets stillness in the
   chrome. The output canvas is the show; the panels never need to animate. */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{transition-duration:.01ms !important;animation-duration:.01ms !important;}
}
/* Sections collapse, so a tab reads as structure rather than a wall of
   identical sliders. The heading is the control — click it. */
.sec{border-bottom:1px solid var(--line);padding:10px 12px;}
.sec > .lbl{display:block;margin-bottom:8px;}
.sec.fold > .lbl,
.sec.fold > div:first-child > .lbl{cursor:pointer;position:relative;padding-left:11px;}
.sec.fold > .lbl::before,
.sec.fold > div:first-child > .lbl::before{
  content:'';position:absolute;left:0;top:3px;width:0;height:0;
  border-left:4px solid #55555f;border-top:3px solid transparent;
  border-bottom:3px solid transparent;transform:rotate(90deg);
  transform-origin:2px 3px;transition:transform .12s;}
.sec.fold.shut > .lbl::before,
.sec.fold.shut > div:first-child > .lbl::before{transform:rotate(0deg);}
.sec.fold.shut > *:not(.lbl):not(:first-child){display:none;}
.sec.fold.shut > div:first-child ~ *{display:none;}
.sec.fold.shut{padding-bottom:9px;}
.sec.fold > .lbl:hover::before,
.sec.fold > div:first-child > .lbl:hover::before{border-left-color:var(--txt);}

/* the primary section in each tab reads heavier than the rest */
.sec.lead > .lbl,
.sec.lead > div:first-child > .lbl{color:var(--txt);font-size:9.5px;}

/* ---------- SCENES ---------- */
#left{background:var(--panel);border-right:1px solid var(--line);}
#families{margin-bottom:7px;}
#families select{width:100%;}
.fchip{font-size:9px;letter-spacing:.08em;text-transform:uppercase;padding:2px 6px;
  border-radius:20px;border:1px solid var(--line2);color:var(--dim);cursor:pointer;}
.fchip:hover{border-color:var(--line3);color:var(--txt);}
.fchip.on{color:#000;background:var(--txt);border-color:var(--txt);}

#scenes{display:grid;grid-template-columns:repeat(3,1fr);gap:4px;}
.scene{position:relative;aspect-ratio:16/10;border:1px solid var(--line2);border-radius:var(--r);
  background:var(--panel2) center/cover no-repeat;cursor:pointer;overflow:hidden;transition:border-color .1s;}
.scene:hover{border-color:var(--line3);}
.scene .nm{display:none;position:absolute;left:0;right:0;bottom:0;padding:10px 5px 4px;font-size:9.5px;
  letter-spacing:.02em;line-height:1.1;background:linear-gradient(transparent,rgba(0,0,0,.92));z-index:2;
  text-shadow:0 1px 2px rgba(0,0,0,.8);}
.scene .fam{position:absolute;top:0;left:0;width:100%;height:2px;z-index:3;}
.scene .idx{position:absolute;top:3px;right:4px;font-size:9px;color:#b4b4c0;
  font-family:ui-monospace,monospace;z-index:3;text-shadow:0 1px 2px #000;
  background:rgba(0,0,0,.5);padding:0 3px;border-radius:2px;line-height:13px;}
.scene.a{border-color:var(--txt);box-shadow:0 0 0 1px var(--txt);}
.scene.b{border-color:var(--cue);box-shadow:0 0 0 1px var(--cue);}
.scene .tag{position:absolute;top:3px;left:4px;font-size:9px;font-weight:700;z-index:3;text-shadow:0 1px 2px #000;}

/* ---------- CENTER ---------- */
#center{background:var(--bg);display:flex;flex-direction:column;min-height:0;}
#mons{flex:1;min-height:0;display:flex;gap:10px;padding:12px 12px 0;align-items:stretch;}
#progWrap{flex:1;min-width:0;display:flex;flex-direction:column;min-height:0;}
#cueWrap{width:196px;flex:none;}

/* The monitor is sized to FIT, never to fill. A 16:9 canvas at full column
   width used to be taller than the column on wide screens and shoved the
   whole deck bar out of view — the main controls, invisible, with nothing
   even hinting they existed. #progShell gets an explicit width from JS:
   min(column width, available height × 16/9). */
#progBox{flex:1;min-height:0;display:flex;justify-content:center;align-items:flex-start;}
#progShell{position:relative;width:100%;max-width:100%;}

/* SOLO is the default: one screen, showing what is playing. Everything to
   do with mixing two sources is hidden until you ask for it, because most
   of the time there is only one thing on the wall. */
#app.solo #cueWrap{display:none;}
#app.solo .mixonly{display:none !important;}
#app.solo #deckbar{padding-bottom:9px;}
#app.solo #mons{padding-bottom:0;}
.moncap{display:flex;align-items:center;gap:6px;margin-bottom:5px;flex:none;}
canvas.mon{width:100%;aspect-ratio:16/9;background:#000;border:1px solid var(--line2);border-radius:var(--r);display:block;}
#preview{border-color:var(--line3);}
#cue{border-color:#26456e;}

/* Solo | Mix. The old "⇅ Mix" pill was the single most important mode
   switch on the surface, styled like an afterthought. A segment shows both
   states, names them, and marks which one you are in. */
.seg{display:flex;border:1px solid var(--line2);border-radius:var(--r);overflow:hidden;}
.segbtn{border:none;border-radius:0;background:var(--panel2);color:var(--dim);
  font-size:10px;letter-spacing:.08em;text-transform:uppercase;padding:4px 12px;}
.segbtn:hover{background:var(--panel3);color:var(--txt);border:none;}
.segbtn.on,.segbtn.on:hover{background:var(--txt);color:#000;}
.segbtn + .segbtn{border-left:1px solid var(--line2);}

#deckbar{border-top:1px solid var(--line);background:var(--panel);padding:9px 12px 11px;margin-top:12px;}
#deckbar .ctlrow{flex-wrap:wrap;row-gap:6px;}
.deckrow{display:flex;align-items:center;gap:8px;margin-bottom:7px;flex-wrap:wrap;}
.deckrow:last-child{margin-bottom:0;}
/* ---------- MIXER ---------- */
.mixrow{align-items:stretch;gap:10px;}
.deckcard{display:flex;align-items:center;gap:9px;min-width:158px;text-align:left;
  padding:7px 10px;line-height:1.2;}
/* The solo card is a div, so it inherits none of the button chrome. These
   two rules give it the same box and the same lit state without also
   giving it a pointer cursor it cannot honour. */
div.deckcard{background:var(--panel2);border:1px solid var(--line2);
  border-radius:var(--r);cursor:default;}
div.deckcard.on{background:var(--txt);color:#000;border-color:var(--txt);}
.deckcard .dk{font:600 15px/1 ui-monospace,monospace;color:var(--dim);flex:none;}
.deckcard.on .dk{color:#000;}
.deckcard .dinfo{min-width:0;}
.deckcard .dinfo b{display:block;font-size:11px;font-weight:500;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:112px;}
.deckcard .dinfo em{display:block;font-style:normal;font-size:9px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--dim2);margin-top:2px;}
.deckcard.on .dinfo em{color:#444;}
.deckcard.live{box-shadow:0 0 0 1px var(--live) inset;}
.deckcard .dinfo em.video{color:var(--cue);}
.deckcard.on .dinfo em.video{color:#1a4a80;}

.mixmid{flex:1;min-width:180px;display:flex;flex-direction:column;justify-content:center;gap:2px;}
.mixlegend{display:flex;align-items:center;gap:8px;}
.mixlegend .mono{flex:1;text-align:center;font-size:10px;color:var(--dim);}
.mixlegend button{min-width:0;padding:3px 8px;}

input[type=range]{-webkit-appearance:none;appearance:none;width:100%;height:20px;background:transparent;cursor:pointer;margin:0;}
input[type=range]::-webkit-slider-runnable-track{height:3px;background:var(--line2);border-radius:2px;}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:12px;height:12px;border-radius:50%;
  background:var(--txt);margin-top:-4.5px;border:none;}
input[type=range].thin{height:15px;}
input[type=range].thin::-webkit-slider-thumb{width:9px;height:9px;margin-top:-3px;}
input[type=range].modded::-webkit-slider-runnable-track{background:linear-gradient(90deg,#3a5a8a,#2a2a33);}

/* ---------- RIGHT ---------- */
#right{background:var(--panel);border-left:1px solid var(--line);}
#tabs{display:flex;border-bottom:1px solid var(--line);position:sticky;top:0;background:var(--panel);z-index:5;}
.tab{flex:1;text-align:center;padding:11px 1px;font-size:10px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--dim);cursor:pointer;border-bottom:1px solid transparent;
  white-space:nowrap;overflow:hidden;}
.tab:hover{color:var(--txt);}
.tab.on{color:var(--txt);border-bottom-color:var(--txt);}
.tab:focus-visible{outline:1px solid var(--txt);outline-offset:-2px;}
/* Three tabs, by when you reach for them: Play (during the set), Look
   (shaping the picture), Setup (before the party). Six feature tabs did not
   fit the column and had to wrap onto two rows. */

@media (min-width:1201px){
  .pane[data-p=play] .knobs{grid-template-columns:repeat(4,1fr);gap:2px;}
}

/* Setup's headings carry a live status (right-aligned, plain case). */
.stat{float:right;font-size:9.5px;letter-spacing:.02em;text-transform:none;font-weight:400;
  color:var(--dim);max-width:62%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.stat i{display:inline-block;width:6px;height:6px;border-radius:50%;margin-right:5px;vertical-align:0;background:var(--line3);}
.stat i.ok{background:var(--ok);} .stat i.warn{background:var(--learn);} .stat i.rec{background:var(--live);}
.pane{display:none;}
.pane.on{display:block;}

.knobs{display:grid;grid-template-columns:repeat(2,1fr);gap:9px;}
.knob{text-align:center;}
.knob canvas{width:100%;aspect-ratio:1;max-width:70px;cursor:ns-resize;display:block;margin:0 auto;}
.knob .kn{margin-top:2px;font-size:9px;letter-spacing:.08em;text-transform:uppercase;color:var(--dim);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.knob .ksub{font-size:9px;color:var(--dim2);margin-top:1px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.knob .kv{font-size:9px;color:var(--dim2);font-family:ui-monospace,monospace;}
.knob.learning .kn{color:var(--learn);}

/* ---------- VARIANTS + FILMSTRIP ---------- */
#variants{display:grid;grid-template-columns:repeat(2,1fr);gap:4px;}
.variant{aspect-ratio:16/10;border:1px solid var(--line2);border-radius:var(--r);
  background:var(--panel2) center/cover no-repeat;cursor:pointer;transition:border-color .1s;}
.variant:hover{border-color:var(--line3);}
.variant.on{border-color:var(--txt);box-shadow:0 0 0 1px var(--txt);}

#filmstrip{display:none;margin-top:8px;}
#filmstrip.show{display:block;}
.filmcap{font-size:9px;letter-spacing:.06em;color:var(--dim);margin-bottom:4px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.filmrow{display:grid;grid-template-columns:repeat(5,1fr);gap:3px;}
.film{aspect-ratio:16/10;border:1px solid var(--line2);border-radius:2px;
  background:var(--panel2) center/cover no-repeat;cursor:pointer;}
.film:hover{border-color:var(--txt);}

.row{display:flex;align-items:center;gap:7px;margin-bottom:6px;}
.row:last-child{margin-bottom:0;}
/* 60px could not hold "Colour amount", and nothing stopped the overflow —
   the second line ran out of its box and straight over the slider. Wider
   box, tighter tracking, and words break rather than escape. */
.row .lbl{width:78px;flex:0 0 78px;min-width:0;line-height:1.25;
  letter-spacing:.07em;overflow-wrap:anywhere;}
.row>input[type=range],.row>select,.row>button{min-width:0;}
.row .val{width:32px;text-align:right;font-size:9px;color:var(--dim2);font-family:ui-monospace,monospace;flex:none;}

/* ---------- AUDIO SCOPE ---------- */
#spectrum{width:100%;height:92px;display:block;background:#0a0a0d;border:1px solid var(--line2);border-radius:var(--r);}
.meters{display:grid;grid-template-columns:repeat(4,1fr);gap:5px;margin-top:8px;}
.meter{text-align:center;}
.meter .bar{height:52px;background:#111116;border:1px solid var(--line2);border-radius:2px;position:relative;overflow:hidden;}
.meter .fill{position:absolute;bottom:0;left:0;right:0;background:var(--txt);transition:height .04s linear;}
.meter .hit{position:absolute;top:0;left:0;right:0;height:3px;background:var(--live);opacity:0;}
.meter .mn{font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--dim);margin-top:3px;}

.peakbar{flex:1;height:12px;background:#111116;border:1px solid var(--line2);
  border-radius:2px;position:relative;overflow:hidden;}
.peakbar i{position:absolute;left:0;top:0;bottom:0;width:0;
  background:linear-gradient(90deg,#2f855a 0%,#2f855a 62%,#b7791f 82%,#c53030 100%);
  transition:width .05s linear;}
.peakbar b{position:absolute;right:3px;top:0;line-height:12px;font-size:8.5px;
  letter-spacing:.1em;color:var(--live);opacity:0;font-weight:700;}
.peakbar b.on{opacity:1;}

/* ---------- MOD MATRIX ---------- */
/* mute · when · what · depth · % · remove — the row reads left to right
   as the sentence the hint above it promises */
.route{display:grid;grid-template-columns:16px 1fr 1fr 48px 30px 16px;gap:4px;align-items:center;margin-bottom:4px;}
.route select{max-width:none;width:100%;font-size:10px;padding:3px 4px;}
.route input[type=range]{height:14px;}
.route .dv{font-size:9px;color:var(--dim);text-align:right;font-variant-numeric:tabular-nums;}
.route .rmute{padding:0;width:16px;height:16px;line-height:1;font-size:9px;border-radius:50%;
  color:var(--dim2);}
.route .rmute.on{color:var(--ok);border-color:var(--ok);}
.route .x{text-align:center;color:var(--dim2);cursor:pointer;font-size:13px;line-height:1;}
.route .x:hover{color:var(--live);}
.route.off{opacity:.4;}
.lfo{border:1px solid var(--line2);border-radius:var(--r);padding:7px;margin-bottom:6px;}
.lfo .top{display:flex;align-items:center;gap:5px;margin-bottom:5px;}
.lfo .vis{height:16px;background:#0a0a0d;border-radius:2px;position:relative;overflow:hidden;}
.lfo .vis i{position:absolute;top:0;bottom:0;width:2px;background:var(--txt);}

/* ---------- BOTTOM ---------- */
#bottom{border-top:1px solid var(--line);background:var(--panel);
  display:flex;flex-direction:column;min-height:0;min-width:0;max-height:236px;}
/* Pads compress as the viewport shortens: first the description goes,
   then the MIDI binding line, then the padding. Two full rows of pads
   stay visible down to ~560px of viewport — nothing clips, ever. */
@media (max-height:780px){ .fx{padding:4px 6px 2px;} }
@media (max-height:700px){ .bpane{padding:5px 12px;} #fx{gap:3px;} }
#bottomHead{display:flex;align-items:center;gap:2px;padding:0 12px;
  border-bottom:1px solid var(--line);flex:none;}
#bottomHint{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  text-align:right;flex:0 1 auto;}
.btab{font-size:9px;letter-spacing:.13em;text-transform:uppercase;color:var(--dim);
  padding:9px 12px;cursor:pointer;border-bottom:1px solid transparent;}
.btab:hover{color:var(--txt);}
.btab.on{color:var(--txt);border-bottom-color:var(--txt);}
.bpane{display:none;padding:9px 12px;overflow:auto;min-height:0;flex:1;}
.bpane.on{display:block;}

/* ---------- CONTROL MAP ---------- */
#mapWrap{display:flex;flex-direction:column;gap:8px;}
.maprow{display:flex;gap:4px;flex-wrap:wrap;}
.mapkey{border:1px solid var(--line2);border-radius:var(--r);background:var(--panel2);
  padding:4px 7px;min-width:74px;line-height:1.25;}
.mapkey b{display:block;font:600 10px/1 ui-monospace,monospace;color:var(--txt);}
.mapkey span{display:block;font-size:9px;color:var(--dim);margin-top:3px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:110px;}
.mapkey.lit{background:var(--txt);}
.mapkey.lit b,.mapkey.lit span{color:#111;}
.mapsec{font-size:9px;letter-spacing:.13em;text-transform:uppercase;color:var(--dim2);
  margin-bottom:2px;}
#mon{font-family:ui-monospace,monospace;font-size:9.5px;color:var(--dim);
  line-height:1.5;max-height:120px;overflow:auto;}
#fx{display:grid;grid-template-columns:repeat(8,1fr);gap:4px;}
.fx{border:1px solid var(--line2);border-radius:var(--r);background:var(--panel2);
  padding:5px 6px 3px;cursor:pointer;position:relative;}
.fx .fhead{display:flex;align-items:baseline;gap:5px;margin-bottom:1px;}
.fx .fkey{font-family:ui-monospace,monospace;font-size:9px;color:var(--txt);
  border:1px solid var(--line3);border-radius:2px;padding:0 3px;line-height:13px;flex:none;}
.fx .fn{font-size:10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.fx .fdesc{font-size:9px;color:var(--dim2);line-height:1.25;height:22px;overflow:hidden;margin-bottom:2px;}
.fx.on{background:var(--txt);border-color:var(--txt);}
.fx.on .fn,.fx.on .fdesc{color:#111;}
.fx.on .fkey{color:#000;border-color:#666;}
.fx.learning{border-color:var(--learn);}
.fx.modded{box-shadow:inset 0 0 0 1px #3a5a8a;}
.fx .bind{display:none;}
.fx.on .bind{color:#555;opacity:1;}

/* ---------- GROUPED CONTROL ROW ---------- */
.ctlrow{align-items:flex-end;gap:14px;}
.ctlgrp{display:flex;flex-direction:column;gap:3px;min-width:0;flex-shrink:1;}
/* The labels over the stage controls sat at three different heights
   (PLAYING, CHANGE OVER, SPEED, SURPRISE ME), because each group was
   centred on its own control and the Playing card is taller than a select.
   Labels now share one line; each control centres in the space below. */
#soloRow,#deckbar .ctlrow{align-items:stretch;}
#soloRow .ctlgrp > :last-child,#deckbar .ctlrow .ctlgrp > :last-child{margin-top:auto;margin-bottom:auto;}
.ctlgrp .glbl{font-size:9px;letter-spacing:.13em;text-transform:uppercase;color:var(--dim2);
  margin:0;}   /* the plans page's .glbl heading carries margin-bottom:16px, and the shared class name put a 16px hole under every stage label */
.ctlgrp .glbl b{color:var(--dim);font-weight:400;letter-spacing:0;}
.ctlgrp select,.ctlgrp button{min-width:0;max-width:100%;}
.ctlgrp input[type=range]{width:100%;}

/* The slot number on every Move. This is the rack's whole point: the
   number never moves, so a pad and a finger both know where three is. */
.look .lslot{position:absolute;top:3px;right:3px;min-width:13px;height:13px;
  border-radius:3px;background:rgba(8,8,10,.75);color:var(--dim);
  font-family:ui-monospace,monospace;font-size:9px;line-height:13px;
  text-align:center;padding:0 2px;pointer-events:none;}
.look.on .lslot{color:var(--txt);}
/* An empty slot still shows its number and stays a target — a rack with
   holes in it is not a rack. Dashed so "nothing here yet" is obvious
   without a label saying so. */
.look.empty{border-style:dashed;background:transparent;min-height:34px;cursor:pointer;}
.look.empty:hover{border-color:var(--line3);background:var(--panel2);}
.look.empty .lslot{color:var(--dim2);background:transparent;}

#mon{height:100%;overflow:auto;font-family:ui-monospace,monospace;font-size:9.5px;color:var(--dim);line-height:1.5;}
#mon div:first-child{color:var(--txt);}

/* ---------- OVERLAYS ---------- */
#veil{position:fixed;inset:0;background:rgba(4,4,6,.9);backdrop-filter:blur(6px);
  display:none;align-items:center;justify-content:center;z-index:50;}
#veil.show{display:flex;}
.card{width:500px;max-height:82vh;overflow:auto;background:var(--panel);border:1px solid var(--line2);
  border-radius:6px;padding:22px 24px;}
.card h3{margin:0 0 4px;font-size:12px;letter-spacing:.16em;text-transform:uppercase;font-weight:600;}
.card p{margin:0 0 14px;color:var(--dim);font-size:11.5px;line-height:1.65;}
.card .big{font-size:19px;margin:14px 0;}
.card .prog{font-family:ui-monospace,monospace;font-size:10px;color:var(--dim2);}
.card .btns{display:flex;gap:7px;margin-top:14px;}

.learnbadge{position:fixed;bottom:12px;left:50%;transform:translateX(-50%);
  background:var(--learn);color:#000;font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  padding:6px 14px;border-radius:20px;z-index:60;display:none;font-weight:600;}
.learnbadge.show{display:block;}

#boot{position:fixed;inset:0;background:var(--bg);z-index:80;display:flex;
  align-items:center;justify-content:center;flex-direction:column;gap:14px;}
#boot.gone{display:none;}
#boot .bar{width:220px;height:2px;background:var(--line2);border-radius:2px;overflow:hidden;}
#boot .bar i{display:block;height:100%;width:0;background:var(--kick);transition:width .1s;}
/* the colony, waiting for the shaders */
#bootAnts{display:flex;gap:10px;align-items:flex-end;height:18px;}
#bootAnts .pxant{width:26px;height:14px;}

/* ---------- LOOKS + PALETTE ---------- */
#looks{display:grid;grid-template-columns:repeat(2,1fr);gap:4px;}
.look.recipe.on{border-color:var(--ok);box-shadow:inset 0 0 0 1px var(--ok);}
.look.recipe.on b::after{content:' ●';color:var(--ok);}
/* half-applied: some of its rules exist (hand-built or edited) — amber so
   it reads as "in between", and the card copy says how to resolve it */
.look.recipe.half{border-color:var(--learn);border-style:solid;}
.look.recipe.half b::after{content:' ◐';color:var(--learn);}
.look{border:1px solid var(--line2);border-radius:var(--r);background:var(--panel2);
  padding:6px 7px;cursor:pointer;text-align:left;line-height:1.25;}
.look:hover{border-color:var(--line3);background:var(--panel3);}
.look.on{border-color:var(--txt);}
.look b{display:block;font-size:10px;font-weight:500;letter-spacing:.02em;}
.look small{display:block;font-size:9px;color:var(--dim2);margin-top:2px;
  overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;}

/* Palettes as swatches you can see, not names you have to imagine. */
/* three across with a taller ramp: the swatch is the information, so give
   it the pixels — the name is just confirmation underneath */
#palGrid{display:grid;grid-template-columns:repeat(3,1fr);gap:4px;}
.pal{border:1px solid var(--line2);border-radius:var(--r);overflow:hidden;cursor:pointer;}
.pal i{display:block;height:26px;}
.pal span{display:block;font-size:9px;letter-spacing:.06em;color:var(--dim);
  padding:3px 5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.pal:hover{border-color:var(--line3);}
.pal.on{border-color:var(--txt);box-shadow:0 0 0 1px var(--txt);}
.pal.on span{color:var(--txt);}

.brandrow{display:flex;gap:5px;align-items:center;}
.brandrow input[type=color]{width:34px;height:24px;padding:0;
  border:1px solid var(--line2);background:none;cursor:pointer;flex:none;}

.look{position:relative;}
.look .lx{position:absolute;top:3px;left:4px;font-size:12px;line-height:1;
  color:var(--dim2);opacity:0;pointer-events:none;}
/* invisible must mean untouchable: a tap on a phone or tablet (no hover)
   landed on the hidden × and deleted the Move */
.look:hover .lx{opacity:1;pointer-events:auto;}
@media (hover:none){ .look .lx{display:none;} }
.look .lx:hover{color:var(--live);}
.look .lx.armed{opacity:1;pointer-events:auto;color:var(--live);font-size:11px;background:rgba(0,0,0,.7);padding:2px 5px;border-radius:4px;}

/* Recipes are the same object, doing a different job — mark them so a
   glance tells you which shelf you are on. */
.look.recipe{background:var(--panel);border-style:dashed;}
.look.recipe:hover{background:var(--panel3);border-style:solid;}

/* Live source meters. A modulation source is an invisible number; a bar that
   moves with the track is not. */
#srcMeters{display:grid;grid-template-columns:repeat(2,1fr);gap:3px 5px;}
.srcgrp{grid-column:1/-1;font-size:9px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--dim2);margin:5px 0 1px;}
.srcgrp:first-child{margin-top:0;}
.srcm{cursor:pointer;padding:2px 0;}
.srcm span{display:block;font-size:9px;color:var(--dim);letter-spacing:.03em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.srcm b{display:block;height:3px;margin-top:2px;border-radius:2px;
  background:var(--panel3);overflow:hidden;}
.srcm i{display:block;height:100%;background:var(--txt);
  transform:scaleX(0);transform-origin:left;}
.srcm:hover span{color:var(--txt);}
.srcm:hover b{background:var(--line2);}
.srcm.wired span{color:var(--txt);}
.srcm.wired span::after{content:'•';margin-left:4px;color:var(--live);}

/* numbered how-to lists ("howto", not "steps" — .steps is the onboarding
   checklist, and the two colliding once cost this list its numbers) */
.howto{margin:0 0 8px;padding-left:15px;font-size:9.5px;line-height:1.55;
  color:var(--dim);letter-spacing:.01em;}
.howto li{margin-bottom:2px;}
.howto b{color:var(--txt);font-weight:500;}

/* kept: the shader-import panel still uses this row shape */
.savelook{display:flex;gap:5px;margin-bottom:6px;}
.savelook input{flex:1;min-width:0;font:inherit;font-size:10px;
  background:var(--panel2);color:var(--txt);border:1px solid var(--line2);
  border-radius:var(--r);padding:4px 7px;letter-spacing:.02em;}
.savelook input:focus{outline:none;border-color:var(--line3);}
.savelook input::placeholder{color:var(--dim2);}

#swatch{height:22px;border-radius:2px;border:1px solid var(--line2);}
input[type=color]{-webkit-appearance:none;appearance:none;border-radius:2px;}
input[type=color]::-webkit-color-swatch-wrapper{padding:2px;}
input[type=color]::-webkit-color-swatch{border:none;border-radius:1px;}

.hintline{color:var(--dim2);font-size:9.5px;line-height:1.7;}
kbd{font-family:ui-monospace,monospace;border:1px solid var(--line2);padding:1px 4px;border-radius:2px;font-size:9px;color:var(--dim);}
.warn{color:var(--learn);font-size:10px;line-height:1.5;}
.drop{border:1px dashed var(--line3);border-radius:var(--r);padding:11px;text-align:center;
  color:var(--dim);font-size:10px;cursor:pointer;}
.drop.over{border-color:var(--txt);color:var(--txt);}

/* ---------- IMPORT + DIAGNOSTICS ---------- */
textarea{width:100%;height:74px;resize:vertical;background:var(--panel2);color:var(--txt);
  border:1px solid var(--line2);border-radius:var(--r);padding:6px 7px;margin:6px 0;
  font:10px/1.45 ui-monospace,SFMono-Regular,Menlo,monospace;}
textarea:focus{outline:none;border-color:var(--line3);}

/* ---------- shader import ---------- */
.impbox{margin-bottom:6px;}
.implabel{display:flex;align-items:center;gap:6px;margin-bottom:3px;
  font-size:9px;letter-spacing:.13em;text-transform:uppercase;color:var(--dim);}
.impbox textarea,.impmore textarea{margin:0;}
/* live read-out of what the paste was recognised as — the single most
   useful bit of feedback, because it answers "will this work" before Add */
.fmtchip{font-size:9px;letter-spacing:.1em;text-transform:uppercase;
  border:1px solid var(--line2);border-radius:8px;padding:1px 6px;
  color:var(--dim2);white-space:nowrap;}
.fmtchip.ok{color:var(--ok);border-color:#1e4d33;}
.fmtchip.bad{color:var(--learn);border-color:#4d431e;}
.impmore{margin-bottom:6px;}
.impmore summary{font-size:9.5px;color:var(--dim);cursor:pointer;
  padding:4px 0;list-style:none;}
.impmore summary::-webkit-details-marker{display:none;}
.impmore summary::before{content:'+ ';color:var(--dim2);}
.impmore[open] summary::before{content:'– ';}
.impmore summary:hover{color:var(--txt);}

.imp{display:flex;align-items:center;gap:5px;padding:4px 0;border-top:1px solid var(--line);}
.imp .nm{flex:1;font-size:10px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}
.imp .fmt{font-size:8.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--dim2);
  border:1px solid var(--line2);border-radius:8px;padding:1px 5px;}

#health{font-family:ui-monospace,monospace;font-size:9.5px;line-height:1.6;color:var(--dim);}
#health b{color:var(--txt);font-weight:400;}
#health .bad{color:var(--live);}
#health .warnv{color:var(--learn);}

/* ============================================================
   WELCOME GATE
   Sits above everything until the instrument is unlocked. Deliberately
   warmer and larger than the control surface — this is the only screen a
   stranger sees, and the control surface's 9px labels would read as
   "professional software I am not qualified for".
   ============================================================ */
#gate{position:fixed;inset:0;z-index:90;background:var(--bg);
  overflow:auto;display:none;}
#gate.show{display:block;}
#gateInner{max-width:1040px;margin:0 auto;padding:56px 28px 64px;position:relative;}
#gClose{position:absolute;top:18px;right:22px;width:34px;height:34px;border-radius:50%;
  background:var(--panel2);border:1px solid var(--line2);color:var(--dim);
  font-size:14px;line-height:1;z-index:5;}
#gClose:hover{color:var(--txt);border-color:var(--line3);}

.gbrand{font-size:11px;letter-spacing:.34em;font-weight:600;color:var(--dim);
  margin-bottom:26px;}
#gateHero h1{margin:0 0 14px;font-size:44px;line-height:1.05;letter-spacing:-.02em;
  font-weight:600;}
.glead{margin:0 0 26px;max-width:560px;font-size:15px;line-height:1.65;color:var(--dim);}

.gsteps{display:flex;gap:26px;flex-wrap:wrap;margin-bottom:30px;}
.gsteps > div{display:flex;align-items:center;gap:9px;}
.gsteps b{width:22px;height:22px;border-radius:50%;border:1px solid var(--line3);
  display:flex;align-items:center;justify-content:center;
  font-size:10px;font-weight:600;color:var(--dim);flex:none;}
/* an ant counts each step instead of a numbered circle */
.gsteps .gsa{width:20px;height:11px;flex:none;}
.gsteps span{font-size:12.5px;color:var(--dim);}

.grow{display:flex;gap:9px;flex-wrap:wrap;align-items:center;}
.gbig{font-size:14px;padding:11px 22px;background:var(--txt);color:#000;
  border:1px solid var(--txt);border-radius:var(--r);font-weight:500;letter-spacing:.01em;}
.gbig:hover{background:#fff;border-color:#fff;}
.gghost{font-size:13px;padding:11px 18px;}
.gnote{margin-top:16px;font-size:11.5px;color:var(--dim2);}

/* ---------- plans ---------- */
#gatePlans{margin-top:56px;border-top:1px solid var(--line);padding-top:30px;}
.glbl{font-size:9px;letter-spacing:.16em;text-transform:uppercase;color:var(--dim2);
  margin-bottom:16px;}
#planGrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:12px;}
.plan{border:1px solid var(--line2);border-radius:6px;padding:20px 18px;
  display:flex;flex-direction:column;background:var(--panel);}
.plan.featured{border-color:var(--line3);background:var(--panel2);}
.plan .pname{font-size:15px;font-weight:600;margin-bottom:3px;}
.plan .ptag{font-size:11.5px;color:var(--dim);line-height:1.5;margin-bottom:14px;min-height:34px;}
.plan .pprice{font-size:27px;font-weight:600;letter-spacing:-.02em;}
.plan .pprice small{font-size:12px;font-weight:400;color:var(--dim2);letter-spacing:0;}
.plan .pprice s{font-size:15px;font-weight:400;color:var(--dim2);letter-spacing:0;margin-left:5px;}
.plan .pyear{font-size:11px;color:var(--dim2);margin:3px 0 15px;min-height:15px;}
.plan ul{list-style:none;margin:0 0 18px;padding:0;flex:1;}
.plan li{font-size:12px;color:var(--dim);line-height:1.5;padding:4px 0 4px 16px;position:relative;}
.plan li::before{content:'';position:absolute;left:2px;top:10px;width:5px;height:5px;
  border-radius:50%;background:var(--line3);}
.plan.featured li::before{background:var(--ok);}
.plan button{width:100%;}
.plan .badge{font-size:9px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ok);margin-bottom:8px;height:11px;}

/* The plan you hold. Quiet — a settled fact, not a thing to act on. A
   disabled button alone left it ambiguous which card was yours. */
.plan.owned{border-color:var(--ok);}
.plan.owned .badge{color:var(--ok);}
.plan button:disabled{opacity:.45;cursor:default;}

/* The plan row in the account panel, when there is something above you.
   A pill that does something has to look like it does something — this
   one sat inert for long enough that the product had no upgrade path. */
.pill.act{cursor:pointer;border-color:var(--line3);}
.pill.act:hover{border-color:var(--ok);color:var(--fg);}
.pill.act:focus-visible{outline:2px solid var(--ok);outline-offset:2px;}
.pill.act::after{content:'›';margin-left:2px;opacity:.55;font-size:13px;line-height:1;}

/* The line under the plan pill: what this tier actually means on the wall.
   Quiet — it is context, not a pitch. */
.planline{flex:1;font-size:10.5px;color:var(--dim2);line-height:1.45;}
.linky{background:none;border:0;padding:0;margin-left:6px;cursor:pointer;
  font-size:10.5px;color:var(--ok);text-decoration:underline;
  text-underline-offset:2px;white-space:nowrap;}
.linky:hover{color:var(--fg);}
.linky:focus-visible{outline:2px solid var(--ok);outline-offset:2px;border-radius:2px;}
.gfoot{margin-top:16px;font-size:11.5px;color:var(--dim2);line-height:1.7;}
/* The line that answers "why am I looking at this?" — brighter than the
   standing footer copy beneath it, because it is addressed to one person
   about a choice they actually made. */
.gfoot .pnote{color:var(--ok);font-size:12.5px;margin-bottom:8px;}

/* ---------- auth card ---------- */
#gateAuth{position:absolute;inset:0;background:var(--bg);display:none;
  align-items:flex-start;justify-content:center;padding:80px 28px;}
#gateAuth.show{display:flex;}
.gcard{width:100%;max-width:360px;}
.gcard h2{margin:0 0 20px;font-size:24px;font-weight:600;letter-spacing:-.01em;}
.garow{margin-bottom:12px;}
.garow label{display:block;font-size:9px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--dim2);margin-bottom:5px;}
.garow input{width:100%;font-size:14px;padding:9px 11px;background:var(--panel2);
  border:1px solid var(--line2);border-radius:var(--r);color:var(--txt);}
.garow input:focus{outline:none;border-color:var(--line3);}
.gmsg{min-height:16px;margin-bottom:10px;font-size:11.5px;}
.gGoogle{width:100%;display:flex;align-items:center;justify-content:center;gap:9px;}
.gor{display:flex;align-items:center;gap:10px;margin:14px 0;font-size:11px;color:var(--dim2);}
.gor::before,.gor::after{content:"";flex:1;height:1px;background:var(--line2);}
.gswitch{display:flex;justify-content:space-between;margin-top:12px;gap:10px;}
.glink{background:none;border:none;padding:0;color:var(--dim);font-size:11.5px;
  cursor:pointer;text-decoration:underline;text-underline-offset:3px;}
.glink:hover{color:var(--txt);background:none;border:none;}

@media (max-width:640px){
  #gateHero h1{font-size:32px;}
  #gateInner{padding:36px 20px 48px;}
}

/* ---------- FIRST-RUN TOUR ---------- */
/* One spotlight, one card. The hole's giant box-shadow IS the dimmer —
   a single element, no four-panel choreography to keep in sync. */
/* pointer-events:none on the wrap is what makes the tour honest: clicks
   land on the page, and only the shields and the card catch them. */
#tour{position:fixed;inset:0;z-index:88;display:none;pointer-events:none;}
#tour.show{display:block;}
.tourShield{position:absolute;background:rgba(4,4,6,.78);pointer-events:auto;
  transition:all .28s cubic-bezier(.4,0,.2,1);}
#tourHole{position:absolute;border-radius:6px;
  transition:all .28s cubic-bezier(.4,0,.2,1);
  pointer-events:none;
  box-shadow:0 0 0 1px rgba(255,77,61,.55), 0 0 22px rgba(255,77,61,.18);}
/* the spotlight breathes while it waits for you, and settles when you land */
#tour:not(.stepDone) #tourHole{animation:tourBreath 2.2s ease-in-out infinite;}
@keyframes tourBreath{
  0%,100%{box-shadow:0 0 0 1px rgba(255,77,61,.55), 0 0 22px rgba(255,77,61,.18);}
  50%    {box-shadow:0 0 0 2px rgba(255,77,61,.85), 0 0 30px rgba(255,77,61,.30);}
}
#tour.stepDone #tourHole{box-shadow:0 0 0 2px rgba(48,209,88,.8), 0 0 26px rgba(48,209,88,.25);}
@media (prefers-reduced-motion: reduce){ #tour:not(.stepDone) #tourHole{animation:none;} }

#tourAnt{position:absolute;top:14px;right:16px;width:22px;height:12px;opacity:.9;}
#tourTry{margin:10px 0 0;font-size:12px;color:var(--txt);font-weight:500;
  border-left:2px solid var(--live);padding-left:9px;min-height:15px;}
#tourTry:empty{display:none;}
#tourTry.hit{color:var(--ok);border-left-color:var(--ok);}
/* pointer-events restored explicitly — the wrap beneath it is none */
#tourCard{position:absolute;width:300px;background:var(--panel);pointer-events:auto;
  border:1px solid var(--line3);border-radius:6px;padding:16px 18px;
  transition:all .28s cubic-bezier(.4,0,.2,1);
  box-shadow:0 12px 40px rgba(0,0,0,.5);}
#tourStep{font-size:9px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--dim2);margin-bottom:8px;}
#tourCard h4{margin:0 0 6px;font-size:15px;font-weight:600;letter-spacing:-.01em;}
#tourCard p{margin:0 0 14px;font-size:12px;line-height:1.6;color:var(--dim);}
.tourBtns{display:flex;align-items:center;gap:6px;}

/* ---------- ONBOARDING ---------- */
.steps{list-style:none;margin:0;padding:0;}
.steps li{display:flex;align-items:flex-start;gap:9px;padding:9px 0;border-bottom:1px solid var(--line);}
.steps li:last-child{border-bottom:none;}
.steps .tick{width:17px;height:17px;border-radius:50%;border:1px solid var(--line3);flex:none;
  display:flex;align-items:center;justify-content:center;font-size:10px;color:transparent;margin-top:1px;}
.steps li.done .tick{background:var(--ok);border-color:var(--ok);color:#04210d;}
.steps li.done .tt{color:var(--dim);text-decoration:line-through;text-decoration-color:var(--dim2);}
.steps .tt{font-size:12px;color:var(--txt);}
.steps .td{font-size:10.5px;color:var(--dim);margin-top:2px;line-height:1.55;}
/* spans in the markup: without block display the title ran straight into its description */
.steps .tt,.steps .td{display:block;}

/* The preview cannot show a capture (the stream lives in the output
   window), so say so rather than silently showing the underlying scene. */
#capBadge{position:absolute;inset:0;display:none;align-items:center;justify-content:center;
  background:rgba(6,6,8,.82);border-radius:var(--r);color:var(--cue);
  font:11px/1 ui-monospace,monospace;letter-spacing:.14em;pointer-events:none;}
#capBadge.show{display:flex;}

#errBanner{position:fixed;left:50%;transform:translateX(-50%);bottom:44px;z-index:70;
  background:var(--live);color:#fff;font-size:10.5px;padding:7px 13px;border-radius:20px;display:none;}
#errBanner.show{display:block;}

/* A menu that hangs off the control that opened it — used by Enable Audio,
   and built to be reused. */
/* Above the tour (88): the tour's last step opens this very menu, and at
   z 70 it rendered dimmed behind the shields — visible, unclickable,
   on the step the whole walkthrough builds toward. */
.menu{position:fixed;z-index:92;min-width:250px;background:var(--panel);
  border:1px solid var(--line3);border-radius:6px;padding:4px;
  box-shadow:0 12px 34px rgba(0,0,0,.55);}
.menu button{display:block;width:100%;text-align:left;background:none;border:0;
  padding:8px 10px;border-radius:4px;cursor:pointer;color:var(--txt);}
.menu button:hover{background:var(--panel2);}
.menu button b{display:block;font-size:11.5px;font-weight:500;}
.menu button small{display:block;font-size:10px;color:var(--dim2);margin-top:2px;line-height:1.4;}
.scene:focus-visible{outline:2px solid var(--txt);outline-offset:1px;}

/* System tab: "During the show", "Set-up", "Safety net". They had no
   style at all and rendered as bare 12px text flush against the panel
   edge. Group headings, in the panel's own label voice. */
.zonecap{padding:16px 12px 6px;font-size:9px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--dim2);font-weight:600;border-bottom:1px solid var(--line);}
.pane > .zonecap:first-child{padding-top:10px;}

/* =====================================================================
   READABLE PANEL (v7)
   The panel read like a spec sheet: 9–10px grey capitals, paragraphs of
   9.5px explanation, and names that only made sense after you tried the
   control. macOS body text is 13pt and never below 10pt; this follows
   that. One accent (bass blue) means "on / active / changed". Red stays
   for warnings, green for "working".
   ===================================================================== */
:root{
  --acc:#5b8cff; --acc2:#86a8ff;
  --t1:#ececf1; --t2:#b4b4bf; --t3:#8d8d99;
  --trk:#2e2e38; --fill:#74747f; --tick:#d6d6de;
}
@media (min-width:1700px){ #app{grid-template-columns:320px minmax(0,1fr) var(--rw,344px);} }

/* ---- type scale everywhere else ---- */
.lbl{font-size:10.5px;letter-spacing:.13em;}
.hintline{font-size:12px;line-height:1.5;color:var(--t2);}
.pill{font-size:11px;}
.scene .idx{font-size:10.5px;}
.btab{font-size:11px;letter-spacing:.14em;}
.btab.on{border-bottom-color:var(--acc);}
#bottomHint{font-size:11px;letter-spacing:.04em;text-transform:none;color:var(--t3);}
.fmtchip{font-size:10px;}
.scene.a{border-color:var(--acc);box-shadow:0 0 0 1px var(--acc);}

/* ---- resize grip: a sibling over the panel's left edge ---- */
#rightGrip{grid-area:right;justify-self:start;align-self:stretch;width:9px;margin-left:-5px;
  cursor:col-resize;z-index:30;position:relative;}
#rightGrip::after{content:'';position:absolute;left:4px;top:0;bottom:0;width:1px;background:transparent;transition:background .15s;}
#rightGrip:hover::after,#rightGrip.drag::after{background:var(--acc);}
body.resizing, body.resizing *{cursor:col-resize !important;user-select:none !important;}

/* ---- tabs ---- */
#tabs .tab{font-size:11px;letter-spacing:.14em;padding:14px 0 12px;color:var(--t3);border-bottom:2px solid transparent;}
#tabs .tab:hover{color:var(--t1);}
#tabs .tab.on{color:var(--t1);border-bottom-color:var(--acc);}

/* ---- sections ---- */
#right .sec{padding:15px 16px;position:relative;}
#right .sec > .lbl, #right .sechead > .lbl{font-size:11px;letter-spacing:.13em;font-weight:600;color:var(--t1);}
#right .sec > .lbl{display:block;margin-bottom:12px;}
#right .sechead{display:flex;align-items:center;gap:8px;margin-bottom:12px;min-height:22px;}
#right .sechead > .lbl{margin:0;}
#right .sechead .hintline{margin:0;font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
#right .sec.fold.shut{padding-top:13px;padding-bottom:13px;}
#right .sec.fold.shut > .lbl, #right .sec.fold.shut > .sechead{margin-bottom:0;}
#right .sec.lead > .lbl, #right .sec.lead > div:first-child > .lbl{font-size:11px;color:var(--t1);}
#right .zonecap{font-size:10.5px;letter-spacing:.18em;color:var(--t3);padding:20px 16px 6px;border:0;}
#right .stat{font-size:12px;letter-spacing:0;text-transform:none;font-weight:400;color:var(--t2);}
#right .stat i{width:7px;height:7px;}
#right .sub{font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--t3);font-weight:500;margin:18px 0 9px;}
#right .sec > .sub:first-of-type{margin-top:4px;}
#right .hintline{font-size:12.5px;line-height:1.5;margin:0 0 10px;}
#right div.warn:empty, #right div.hintline:empty{display:none;}

/* essentials first; the rest behind "More" */
#right .sec:not(.moreopen) .adv{display:none;}
.linkbtn{background:none;border:0;padding:0;margin:0;color:var(--acc);font:inherit;font-size:12.5px;cursor:pointer;}
.linkbtn:hover{background:none;color:var(--acc2);}
.linkbtn:focus-visible{outline:2px solid var(--acc2);outline-offset:2px;}
#right .more{display:inline-block;margin-top:2px;}
#right #btnByo{margin-top:12px;}
#right .secreset{position:absolute;top:14px;right:16px;}
#right .sec.fold.shut .secreset{top:12px;}

/* ---- rows ---- */
#right .row{display:flex;align-items:center;gap:10px;margin-bottom:10px;}
#right .row > .lbl{font-size:13px;letter-spacing:0;text-transform:none;color:var(--t1);font-weight:400;
  width:auto;flex:1 1 auto;min-width:0;line-height:1.3;overflow-wrap:normal;}
#right .row > select, #right .row > input[type=text], #right .row > input[type=password]{flex:0 0 58%;min-width:0;}
#right select, #right input[type=text], #right input[type=password], #right textarea{font-size:13px;}
#right select{padding:6px 8px;}
#right input[type=text], #right input[type=password]{padding:7px 9px;}
#right input.wide, #right button.wide{width:100%;margin-bottom:10px;display:block;}
#right .row > button.small:not(.tgl){flex:none;}
#right .row > .pill{flex:0 0 58%;justify-content:center;}
#right .btnrow{display:flex;gap:6px;flex-wrap:wrap;margin:2px 0 10px;}
#right .btnrow > button{flex:1 1 auto;}
#right .btnrow > .pill{flex:none;}
#right button.small{font-size:12.5px;padding:6px 11px;}
#right button.small.on:not(.tgl){background:var(--acc);border-color:var(--acc);color:#fff;}
#right .swatchin{flex:0 0 58%;height:28px;padding:0;border:1px solid var(--line2);border-radius:var(--r);background:none;cursor:pointer;}

/* slider rows: name and value on one line, a full-width slider under */
#right .row:has(> input[type=range]){display:grid;grid-template-columns:1fr auto;grid-template-areas:"n v" "s s";
  row-gap:1px;column-gap:10px;align-items:baseline;}
#right .row:has(> input[type=range]) > .lbl{grid-area:n;}
#right .row:has(> input[type=range]) > input[type=range]{grid-area:s;width:100%;}
#right .row:has(> input[type=range]) > .val{grid-area:v;}
#right .row .val{width:auto;flex:none;font:12.5px/1 -apple-system,BlinkMacSystemFont,"Inter",sans-serif;color:var(--t2);
  font-variant-numeric:tabular-nums;text-align:right;}

/* ---- sliders: neutral fill, a tick at the default, a white thumb ---- */
input[type=range]{height:18px;}
input[type=range]::-webkit-slider-runnable-track{height:4px;border-radius:2px;
  background:
    linear-gradient(90deg, transparent calc(var(--d,-9%) - 1px), var(--tick) calc(var(--d,-9%) - 1px),
                    var(--tick) calc(var(--d,-9%) + 1px), transparent calc(var(--d,-9%) + 1px)),
    linear-gradient(90deg, var(--fill) 0 var(--p,0%), var(--trk) var(--p,0%) 100%);}
input[type=range]::-webkit-slider-thumb{width:14px;height:14px;margin-top:-5px;background:#f4f4f7;border:0;
  box-shadow:0 1px 3px rgba(0,0,0,.6);}
input[type=range].thin{height:18px;}
input[type=range].thin::-webkit-slider-thumb{width:14px;height:14px;margin-top:-5px;}
input[type=range]::-moz-range-track{height:4px;border-radius:2px;background:var(--trk);}
input[type=range]::-moz-range-progress{height:4px;border-radius:2px;background:var(--fill);}
input[type=range]::-moz-range-thumb{width:14px;height:14px;border:0;border-radius:50%;background:#f4f4f7;}
/* a rule is moving this one: the fill turns blue */
input[type=range].modded{--fill:#4f74c9;}
input[type=range].modded::-webkit-slider-runnable-track{
  background:
    linear-gradient(90deg, transparent calc(var(--d,-9%) - 1px), var(--tick) calc(var(--d,-9%) - 1px),
                    var(--tick) calc(var(--d,-9%) + 1px), transparent calc(var(--d,-9%) + 1px)),
    linear-gradient(90deg, var(--fill) 0 var(--p,0%), var(--trk) var(--p,0%) 100%);}

/* ---- changed from default: a dot; the section offers Reset ---- */
#right .lbl.chg::after{content:'';display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--acc);
  margin-left:7px;vertical-align:2px;}

/* ---- switches ---- */
button.tgl{font-size:0 !important;color:transparent !important;width:36px;height:21px;flex:0 0 36px;border-radius:11px;
  padding:0 !important;background:#3a3a45;border:0;position:relative;cursor:pointer;margin-left:auto;}
button.tgl::after{content:'';position:absolute;top:3px;left:3px;width:15px;height:15px;border-radius:50%;
  background:#cfcfd6;transition:left .12s,background .12s;}
button.tgl:hover{background:#474753;border:0;}
button.tgl.on{background:var(--acc);border:0;}
button.tgl.on:hover{background:var(--acc2);}
button.tgl.on::after{left:18px;background:#fff;}
button.tgl.half{background:linear-gradient(90deg,var(--acc) 50%,#3a3a45 50%);}
button.tgl:focus-visible{outline:2px solid var(--acc2);outline-offset:2px;}

/* ---- how-tos: one blue line, opens in place ---- */
#right details.howto{margin:12px 0 0;padding:0;font-size:12.5px;}
#right details.howto > summary{color:var(--acc);cursor:pointer;list-style:none;font-size:12.5px;}
#right details.howto > summary::-webkit-details-marker{display:none;}
#right details.howto > summary::after{content:' ›';}
#right details.howto[open] > summary::after{content:' ⌄';}
#right details.howto > div{margin-top:8px;color:var(--t2);line-height:1.55;}
#right details.howto b{color:var(--t1);font-weight:500;}
#right .howtolist{margin:0 0 8px;padding-left:18px;}
#right .howtolist li{margin-bottom:3px;}
#right .impmore > summary{font-size:12.5px;color:var(--t2);}
#right .implabel{font-size:10.5px;}
#right .drop{font-size:12.5px;padding:14px;color:var(--t2);margin-bottom:10px;}
#right textarea{font-size:12px;}

/* ---- macros ---- */
#right .knob .kn{font-size:12.5px;letter-spacing:0;text-transform:none;color:var(--t1);margin-top:5px;}
#right .knob .ksub{display:none;}
#right .knob .kv{font:12px -apple-system,BlinkMacSystemFont,sans-serif;color:var(--t2);font-variant-numeric:tabular-nums;}
#right .knob canvas{max-width:58px;}
#right .filmcap{font-size:11.5px;letter-spacing:0;color:var(--t2);}

/* ---- autopilot: one line off, plain sentence on ---- */
#apSec.apoff .apbody{display:none;}
#apSec:not(.apoff) .apoffnote{display:none;}
#apSec .apoffnote{margin:0;}
#apStatus{margin-top:4px;}
#apStatus .apline{font-size:13.5px;color:var(--t1);line-height:1.45;}
#apStatus .apline b{font-weight:600;}
#apStatus .energy{height:4px;border-radius:2px;background:var(--trk);margin-top:9px;overflow:hidden;}
#apStatus .energy i{display:block;height:100%;background:var(--acc);border-radius:2px;transition:width .4s;}
#apStatus .apsub{font-size:12px;color:var(--t3);margin-top:7px;}
#apStatus .aptouch{font-size:12px;color:var(--acc);margin-top:5px;}

/* ---- saved looks: 2 across, the picture is the label ---- */
.pane[data-p=play] #looks{grid-template-columns:1fr 1fr;gap:8px;margin-bottom:10px;}
.pane[data-p=play] #looks .look{aspect-ratio:16/10;padding:0;display:flex;align-items:flex-end;border-radius:6px;
  background-size:cover;background-position:center;overflow:hidden;min-height:0;}
.pane[data-p=play] #looks .look b{display:block;width:100%;padding:16px 8px 6px;font-size:12.5px;font-weight:500;letter-spacing:0;
  background:linear-gradient(transparent,rgba(0,0,0,.78));text-shadow:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.pane[data-p=play] #looks .look small{display:none;}
.pane[data-p=play] #looks .look .lslot{font:600 11px/1 -apple-system,sans-serif;top:6px;right:6px;left:auto;
  background:rgba(0,0,0,.6);padding:3px 5px;border-radius:4px;color:#fff;min-width:0;height:auto;}
.pane[data-p=play] #looks .look .lx{top:6px;left:7px;right:auto;font-size:14px;color:#fff;text-shadow:0 1px 3px #000;}
.pane[data-p=play] #looks .look.empty{border-style:dashed;background:transparent;align-items:center;justify-content:center;}
.pane[data-p=play] #looks .look.empty .lslot{position:static;background:none;color:var(--t3);font-size:12px;}
.pane[data-p=play] #looks .look.on{border-color:var(--acc);box-shadow:0 0 0 1px var(--acc);}
.pane[data-p=play] #looks[hidden]{display:none;}

/* ---- make it react: a list of switches ---- */
#recipes .recrow{display:flex;align-items:center;gap:10px;padding:9px 0;border-bottom:1px solid var(--line);cursor:pointer;}
#recipes .recrow:first-child{padding-top:0;}
#recipes .recrow .rn{font-size:13px;color:var(--t1);flex:1;min-width:0;}
#recipes .recrow .part{font-size:12px;color:var(--acc);}

/* ---- palette, meters, rules, shapes: readable labels ---- */
.pal span{font-size:11.5px;letter-spacing:0;color:var(--t2);}
.pal.on span{color:var(--t1);}
#right #brandPreview{height:22px;border-radius:3px;border:1px solid var(--line2);margin-top:8px;}
#right #brandPreview[hidden]{display:none;}
#right .brandrow input[type=color]{width:40px;height:30px;}
.meter .mn{font-size:10.5px;color:var(--t2);}
.srcm span{font-size:11.5px;color:var(--t2);letter-spacing:0;}
.srcMeters .grp, #srcMeters .grp{font-size:10.5px;}
.route select{font-size:12px;padding:4px 5px;}
.route .dv{font-size:11px;color:var(--t2);}
.lfo select{font-size:12px;}

/* ---- effect pads: name + key; on is blue ---- */
.fx .fdesc{display:none;}
.fx{padding:9px 10px 6px;}
.fx .fn{font-size:13px;}
.fx .fkey{font-size:11px;}
.fx.on{background:var(--acc);border-color:var(--acc);}
.fx.on .fn{color:#fff;}
.fx.on .fkey{color:#fff;border-color:rgba(255,255,255,.5);}
.fx.on input[type=range]::-webkit-slider-runnable-track{background:linear-gradient(90deg,#fff 0 var(--p,0%),rgba(255,255,255,.3) var(--p,0%) 100%);}

/* ---- hover preview: low · now · high ---- */
#hoverPrev{position:fixed;z-index:60;width:272px;background:#16161b;border:1px solid #33333d;border-radius:8px;
  box-shadow:0 12px 34px rgba(0,0,0,.6);padding:10px;pointer-events:none;display:none;}
#hoverPrev.show{display:block;}
#hoverPrev .pt{font-size:12px;color:var(--t2);margin-bottom:8px;}
#hoverPrev .pr{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;}
#hoverPrev .pr div{text-align:center;font-size:11.5px;color:var(--t2);}
#hoverPrev .pr .img{aspect-ratio:16/10;border-radius:4px;margin-bottom:5px;border:1px solid #2a2a33;
  background-size:cover;background-position:center;position:relative;overflow:hidden;}
#hoverPrev .pr .now .img{border-color:var(--acc);}

/* folding must beat the row layout above (an id selector outranks the
   old class-only fold rule, so shut sections were showing their rows) */
#right .sec.fold.shut > :not(:first-child){display:none !important;}
#right #palGrid{margin-bottom:14px;}

/* rules: two lines each, so the names are never cut off */
#right .route{display:grid;grid-template-columns:40px minmax(0,.8fr) minmax(0,1.25fr) 22px;
  grid-template-areas:"m s d x" ". dep dep dv";column-gap:6px;row-gap:4px;align-items:center;
  margin-bottom:10px;padding-bottom:10px;border-bottom:1px solid var(--line);}
#right .route > :nth-child(1){grid-area:m;}
#right .route > :nth-child(2){grid-area:s;min-width:0;}
#right .route > :nth-child(3){grid-area:d;min-width:0;}
#right .route > :nth-child(4){grid-area:dep;width:100%;}
#right .route > :nth-child(5){grid-area:dv;text-align:right;}
#right .route > :nth-child(6){grid-area:x;font-size:16px;}
#right .route select{padding:5px 6px;}
#right .route.off select{opacity:.5;}
#right .lfo{padding:9px;}
#right .lfo .top .lbl{width:auto !important;white-space:nowrap;font-size:11px;flex:none;}
#right .lfo .top select{min-width:0;}
#right .route .rmute.tgl{width:36px;height:21px;border-radius:11px;line-height:normal;}

/* ============================================================
   TOP BAR (v8): ONE ROW
   It wrapped to two rows on a 13" laptop. The MIDI pill (now in Setup →
   MIDI), "Open in a window" (Send to Screen 2 already falls back to a
   window) and the "locked to audio" words (now the dot's colour, and a
   hover) are gone, and what is left never wraps: on narrower screens the
   least-needed pieces step out in order — fps, then the BPM unit, then
   the wordmark, and the undo arrows only below 1000px (⌘Z still works) —
   rather than the bar growing a second row.
   ============================================================ */
#top{flex-wrap:nowrap;gap:8px;overflow:hidden;}
#top > *{flex:none;}
#top > .spacer{flex:1 1 0;min-width:6px;}
#topLive{flex-wrap:nowrap;gap:8px;}
#tempoGrp{display:inline-flex;align-items:center;gap:6px;}
#beatPill .bpmU{color:var(--dim2);}
#clockSrc{max-width:124px;}
/* tempo locked (audio, tap or MIDI clock): the dot rests green */
#beatPill[data-src="locked"] #beatDot:not(.hit):not(.deaf){background:#1e7a4c;}
#beatPill[data-src="idle"] #beatDot:not(.hit){box-shadow:inset 0 0 0 1px #5a2a27;}
@media (max-width:1320px){ #fps{display:none;} }
@media (max-width:1220px){
  #beatPill .bpmU{display:none;}
  #audioName{max-width:130px;}
}
/* Undo stays on screen on a 13" laptop: ⌘Z is no help on a touchscreen,
   and hiding the arrows at 1220px left nothing to press. They step out
   only where they genuinely cannot fit. */
@media (max-width:1100px){
  #clockSrc{max-width:100px;} #audioName{max-width:90px;}
  #btnScreen2{font-size:0;}
  #btnScreen2::after{content:'⇥ Screen 2';font-size:12px;}
}
@media (max-width:1000px){ #btnUndo, #btnRedo{display:none;} }
@media (max-width:1180px){
  #brand{font-size:0;letter-spacing:0;padding-right:8px;gap:0;}
  #brand .pxant{width:18px;height:9px;}
  #audioName{max-width:100px;}
  #btnUpgrade{font-size:0;gap:0;padding:5px 8px;}
  #btnUpgrade::after{content:'Remove mark';font-size:11px;margin-left:6px;}
}

/* ---------- panel fixes (v8) ---------- */
/* the whole header row of a folding section opens it, and the keyboard
   can reach it */
#right .sec.fold > .foldhead{cursor:pointer;}
#right .sec.fold .lbl[role=button]:focus-visible{outline:2px solid var(--acc, #5b8cff);outline-offset:3px;border-radius:3px;}
/* "Your colours" with none chosen yet points at the pickers */
#right .brandrow.pulse{animation:brandPulse 1.2s ease-out;border-radius:6px;}
@keyframes brandPulse{0%{box-shadow:0 0 0 0 rgba(91,140,255,.0);}30%{box-shadow:0 0 0 3px rgba(91,140,255,.55);}100%{box-shadow:0 0 0 0 rgba(91,140,255,0);}}
#right #routes .apRules{margin:2px 0 8px;}
/* the strobe safety, armed to turn off: the warning is on screen, one more press */
#right button.tgl.armed, #right button.danger.armed{box-shadow:0 0 0 2px var(--live);}
