/* =========================================================
   SurfMix — stylesheet
   Default theme: white elements on a solid pitch-black background.
   ========================================================= */

/* ---------- theme tokens ---------- */
:root,
[data-theme="black"],
[data-theme="neon"] {
  --bg: #000;
  --fg: #fff;
  --fg-2: rgba(255, 255, 255, .72);
  --fg-3: rgba(255, 255, 255, .46);
  --line: rgba(255, 255, 255, .24);
  --line-2: rgba(255, 255, 255, .12);
  --panel: #000;
  --panel-2: #0a0a0a;
  --hover: rgba(255, 255, 255, .08);
  --overlay: rgba(0, 0, 0, .8);
  --shadow: rgba(0, 0, 0, .7);
  --disc: #0b0b0b;
  --groove: rgba(255, 255, 255, .055);
  --tick: rgba(255, 255, 255, .5);
  --wave: #fff;
  --wave-dim: rgba(255, 255, 255, .36);
  --grid: rgba(255, 255, 255, .3);
  --cue: #fff;
  --loop: rgba(255, 255, 255, .15);
  --played: rgba(0, 0, 0, .5);
  --band-low: #3d7bff;
  --band-mid: #ffa63d;
  --band-high: #ffffff;
  --vu: #fff;
  --vu-hot: #fff;
  --vu-off: rgba(255, 255, 255, .12);
  --rec: #ff3b30;
  --deck-accent: var(--fg);
  --on-fg: #000;
  --chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23fff' stroke-width='1.5'/%3E%3C/svg%3E");
  color-scheme: dark;
}

[data-theme="light"] {
  --bg: #fff;
  --fg: #000;
  --fg-2: rgba(0, 0, 0, .72);
  --fg-3: rgba(0, 0, 0, .5);
  --line: rgba(0, 0, 0, .24);
  --line-2: rgba(0, 0, 0, .1);
  --panel: #fff;
  --panel-2: #f4f4f4;
  --hover: rgba(0, 0, 0, .06);
  --overlay: rgba(255, 255, 255, .85);
  --shadow: rgba(0, 0, 0, .18);
  --disc: #ececec;
  --groove: rgba(0, 0, 0, .06);
  --tick: rgba(0, 0, 0, .5);
  --wave: #000;
  --wave-dim: rgba(0, 0, 0, .3);
  --grid: rgba(0, 0, 0, .3);
  --cue: #000;
  --loop: rgba(0, 0, 0, .1);
  --played: rgba(255, 255, 255, .55);
  --band-low: #1f5bff;
  --band-mid: #f08a00;
  --band-high: #000;
  --vu: #000;
  --vu-hot: #000;
  --vu-off: rgba(0, 0, 0, .1);
  --on-fg: #fff;
  --chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23000' stroke-width='1.5'/%3E%3C/svg%3E");
  color-scheme: light;
}

[data-theme="neon"] { --vu-hot: #ff3b5c; }
[data-theme="neon"] [data-index="0"] { --deck-accent: #19e3ff; }
[data-theme="neon"] [data-index="1"] { --deck-accent: #ff3df2; }
[data-theme="neon"] [data-index="2"] { --deck-accent: #b6ff2e; }
[data-theme="neon"] [data-index="3"] { --deck-accent: #ffb02e; }

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  height: 100%;
  background: var(--bg);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  /* the app fills the screen exactly; the page itself never scrolls (see .app / .stage) */
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--fg);
  font: 14px/1.3 system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  overscroll-behavior: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

input, textarea { -webkit-user-select: text; user-select: text; }
button, input, select { font-family: inherit; }
button { -webkit-appearance: none; appearance: none; }
img { -webkit-user-drag: none; }

* { scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-thumb { background: var(--line); border-radius: 4px; }
::-webkit-scrollbar-track { background: transparent; }

:focus { outline: none; }
:focus-visible { outline: 2px solid var(--fg); outline-offset: 2px; }

[hidden] { display: none !important; }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.ico { width: 20px; height: 20px; flex: none; fill: currentColor; }
.ico-xl { width: 56px; height: 56px; color: var(--fg-3); }

.mono, .master-bpm {
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Roboto Mono", monospace;
  font-variant-numeric: tabular-nums;
}

body:not(.ready) .stage { visibility: hidden; }

/* ---------- generic buttons ---------- */
.icon-btn {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--fg);
  display: inline-grid;
  place-items: center;
  cursor: pointer;
  padding: 0;
  flex: none;
}
.icon-btn:hover { background: var(--hover); }
.icon-sm { width: 30px; height: 30px; }
.icon-sm .ico { width: 16px; height: 16px; }

.pill-btn {
  height: 34px;
  padding: 0 12px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--fg);
  font-weight: 700;
  font-size: 12px;
  line-height: 1;
  letter-spacing: .08em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  cursor: pointer;
  white-space: nowrap;
}
.pill-btn .ico { width: 16px; height: 16px; }
.pill-btn:hover { border-color: var(--fg-3); }
.pill-btn:disabled { opacity: .4; cursor: default; }
.pill-solid { background: var(--fg); color: var(--bg); border-color: var(--fg); }
#btn-library[aria-expanded="true"] { background: var(--fg); color: var(--bg); border-color: var(--fg); }

.btn {
  border: 1.5px solid var(--line);
  background: transparent;
  color: var(--fg);
  border-radius: 10px;
  font-weight: 800;
  font-size: 12px;
  line-height: 1;
  letter-spacing: .08em;
  min-height: 42px;
  padding: 0 10px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  touch-action: none;
  transition: background-color .07s, color .07s, border-color .07s, transform .07s;
  text-align: center;
}
.btn:hover { border-color: var(--fg-3); }
.btn.pressed { transform: scale(.96); }
.btn.on { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.btn-sm { min-height: 32px; font-size: 11px; padding: 0 8px; border-radius: 8px; }
.btn-xs { min-height: 30px; width: 28px; padding: 0; font-size: 17px; font-weight: 600; border-radius: 8px; }

.select {
  -webkit-appearance: none;
  appearance: none;
  background: var(--bg) var(--chev) no-repeat right 10px center;
  color: var(--fg);
  border: 1px solid var(--line);
  border-radius: 8px;
  height: 34px;
  padding: 0 28px 0 10px;
  font-weight: 500;
  font-size: 13px;
  line-height: 1;
  max-width: 62%;
  cursor: pointer;
  text-overflow: ellipsis;
}
.select-sm { height: 28px; font-size: 11px; max-width: 120px; }
.select option { background: var(--bg); color: var(--fg); }

/* iOS zooms into inputs smaller than 16px */
@media (pointer: coarse) {
  input[type="search"], input[type="text"], .select { font-size: 16px; }
  .select-sm { font-size: 13px; }
}

/* ---------- app shell ----------
   The app is pinned to the window, so the page itself can never scroll or be dragged around (iOS
   Safari scrolls the document even when it has overflow: hidden). Everything sits in one grid
   (#stage): deck info across the top, waveforms and platters, the control row, the deck
   panels beside the mixer, and the transport with the crossfader at the bottom. ui.js (UI.layout)
   picks the arrangement (data-mode) and sets the row and column sizes (--info-h, --deck-h, …). */
.app {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  overflow: hidden;
  background: var(--bg);
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}
.stage {
  --gap: 6px;
  --pitch-w: 44px;
  --info-h: 76px;
  --info-h2: 35px;
  --deck-h: 200px;
  --deck-h2: 97px;
  --ctrl-h: 48px;
  --trans-h: 64px;
  --wave-h: 56px;
  --mix-w: 240px;
  --hub-h: 40px;
  --xf-h: 40px;
  --ov-h: 20px;
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  display: grid;
  gap: 6px;
  gap: var(--gap);
  padding: 8px;
  overflow: hidden;
}
/* the decks' parts are placed straight into the stage grid */
.deck-col, .deck { display: contents; }

.deck-col-left .deck-info { grid-area: infoA; }
.deck-col-left .pitch-col { grid-area: pitchA; }
.deck-col-left .platter-wrap { grid-area: platA; }
.deck-col-left .deck-wave { grid-area: waveA; }
.deck-col-left .deck-ctrl { grid-area: ctrlA; }
.deck-col-left .deck-pane { grid-area: paneA; }
.deck-col-left .deck-transport { grid-area: transA; }
.deck-col-right .deck-info { grid-area: infoB; }
.deck-col-right .pitch-col { grid-area: pitchB; }
.deck-col-right .platter-wrap { grid-area: platB; }
.deck-col-right .deck-wave { grid-area: waveB; }
.deck-col-right .deck-ctrl { grid-area: ctrlB; }
.deck-col-right .deck-pane { grid-area: paneB; }
.deck-col-right .deck-transport { grid-area: transB; }
.hub { grid-area: hub; }
.views { grid-area: views; }
.hub-bpm { grid-area: bpm; }
.mixer { grid-area: mixer; }
.xfader-wrap { grid-area: xf; }
.library { grid-area: lib; }
.panels { grid-area: lib; }
.tools { grid-area: bpm; }

/* the library view: only there is the library shown; the deck panels, mixer and platters make room */
.stage:not([data-view="lib"]) .library { display: none; }
/* the tools view: a tool panel (AUTOMIX, SAMPLER, TRANSITIONS) in the library's place */
.stage:not([data-view="tool"]) .panels { display: none; }
.stage:not([data-view="mix"]) .deck-pane,
.stage:not([data-view="mix"]) .mixer { display: none; }

/* -- wide: tablets in landscape, laptops and desktops --
   pitch | platter | waveforms (stacked) | platter | pitch, with the mixer between the deck panels */
.stage[data-mode="wide"] {
  grid-template-columns: var(--pitch-w) var(--deck-h) minmax(0, 1fr) var(--mix-w) minmax(0, 1fr) var(--deck-h) var(--pitch-w);
  grid-template-rows: var(--info-h2) var(--info-h2) var(--deck-h2) var(--deck-h2) var(--ctrl-h) minmax(0, 1fr) var(--trans-h);
  grid-template-areas:
    "infoA infoA infoA hub infoB infoB infoB"
    "infoA infoA infoA views infoB infoB infoB"
    "pitchA platA waveA waveA waveA platB pitchB"
    "pitchA platA waveB waveB waveB platB pitchB"
    "ctrlA ctrlA ctrlA bpm ctrlB ctrlB ctrlB"
    "paneA paneA paneA mixer paneB paneB paneB"
    "transA transA transA xf transB transB transB";
}
.stage[data-mode="wide"]:not([data-view="mix"]) {
  grid-template-rows: var(--info-h2) var(--info-h2) var(--deck-h2) var(--deck-h2) var(--ctrl-h) var(--trans-h) minmax(0, 1fr);
  grid-template-areas:
    "infoA infoA infoA hub infoB infoB infoB"
    "infoA infoA infoA views infoB infoB infoB"
    "pitchA platA waveA waveA waveA platB pitchB"
    "pitchA platA waveB waveB waveB platB pitchB"
    "ctrlA ctrlA ctrlA bpm ctrlB ctrlB ctrlB"
    "transA transA transA xf transB transB transB"
    "lib lib lib lib lib lib lib";
}

/* -- tall: tablets in portrait. Waveforms across the top, platters beside a tall mixer -- */
.stage[data-mode="tall"] {
  grid-template-columns: var(--pitch-w) minmax(0, 1fr) minmax(0, 1fr) var(--mix-w) minmax(0, 1fr) minmax(0, 1fr) var(--pitch-w);
  grid-template-rows: var(--info-h2) var(--info-h2) var(--wave-h) var(--wave-h) var(--ctrl-h) var(--deck-h) minmax(0, 1fr) var(--trans-h);
  grid-template-areas:
    "infoA infoA infoA hub infoB infoB infoB"
    "infoA infoA infoA views infoB infoB infoB"
    "waveA waveA waveA waveA waveA waveA waveA"
    "waveB waveB waveB waveB waveB waveB waveB"
    "ctrlA ctrlA ctrlA bpm ctrlB ctrlB ctrlB"
    "pitchA platA platA mixer platB platB pitchB"
    "paneA paneA paneA mixer paneB paneB paneB"
    "transA transA transA xf transB transB transB";
}
.stage[data-mode="tall"]:not([data-view="mix"]) {
  grid-template-rows: var(--info-h2) var(--info-h2) var(--wave-h) var(--wave-h) var(--ctrl-h) var(--trans-h) minmax(0, 1fr);
  grid-template-areas:
    "infoA infoA infoA hub infoB infoB infoB"
    "infoA infoA infoA views infoB infoB infoB"
    "waveA waveA waveA waveA waveA waveA waveA"
    "waveB waveB waveB waveB waveB waveB waveB"
    "ctrlA ctrlA ctrlA bpm ctrlB ctrlB ctrlB"
    "transA transA transA xf transB transB transB"
    "lib lib lib lib lib lib lib";
}

/* -- short: phones in landscape. Waveforms across the top; platters (or, with the pads button, the
   deck panels) beside the mixer; transport, SYNC and the crossfader in one row at the bottom -- */
.stage[data-mode="short"] {
  grid-template-columns: var(--pitch-w) minmax(0, 1fr) minmax(0, 1fr) var(--mix-w) minmax(0, 1fr) minmax(0, 1fr) var(--pitch-w);
  grid-template-rows: var(--info-h) var(--wave-h) var(--wave-h) minmax(0, 1fr) var(--trans-h);
  grid-template-areas:
    "infoA infoA infoA hub infoB infoB infoB"
    "waveA waveA waveA waveA waveA waveA waveA"
    "waveB waveB waveB waveB waveB waveB waveB"
    "pitchA platA platA mixer platB platB pitchB"
    "transA transA ctrlA xf ctrlB transB transB";
}
.stage[data-mode="short"] .deck-col-left .deck-pane { grid-area: platA; }
.stage[data-mode="short"] .deck-col-right .deck-pane { grid-area: platB; }
.stage[data-mode="short"] .deck[data-face="pads"] .platter-wrap,
.stage[data-mode="short"] .deck:not([data-face="pads"]) .deck-pane { display: none; }
.stage[data-mode="short"] .views { grid-area: hub; justify-self: end; }
.stage[data-mode="short"] .hub { justify-self: start; }
.stage[data-mode="short"]:not([data-view="mix"]) {
  grid-template-rows: var(--info-h) minmax(0, 1fr) var(--trans-h);
  grid-template-areas:
    "infoA infoA infoA hub infoB infoB infoB"
    "lib lib lib lib lib lib lib"
    "transA transA ctrlA xf ctrlB transB transB";
}
.stage[data-mode="short"]:not([data-view="mix"]) .deck-wave { display: none; }
/* (a short library: a one-line toolbar, and the column headers give way to the deck banner) */
.stage[data-mode="short"] .lib-toolbar { flex-wrap: nowrap; padding: 4px 6px; gap: 6px; }
.stage[data-mode="short"] .lib-title span,
.stage[data-mode="short"] .lib-toolbar .select,
.stage[data-mode="short"] .lib-toolbar .pill-btn span { display: none; }
.stage[data-mode="short"] .lib-toolbar .pill-btn { width: 34px; padding: 0; }
.stage[data-mode="short"] .lib-search { order: 0; flex: 1 1 auto; height: 32px; }
.stage[data-mode="short"] .lib-close { width: 34px; height: 32px; }
.stage[data-mode="short"] .lib-target { margin: 0 6px 4px; padding: 2px 4px 2px 10px; }
.stage[data-mode="short"] .lib-target .pill-btn { height: 28px; }
.stage[data-mode="short"] .lib-target:not([hidden]) + .lib-head { display: none; }
.stage[data-mode="short"] .trk { height: 46px; }

/* -- narrow: phones in portrait. Deck A above its waveform, deck B below, the platters side by side,
   then one panel at a time (deck A, the mixer or deck B: the A / mixer / B buttons at the top) -- */
.stage[data-mode="narrow"] {
  padding: 6px;
  grid-template-columns: var(--pitch-w) minmax(0, 1fr) minmax(0, 1fr) var(--pitch-w);
  grid-template-rows: var(--hub-h) var(--info-h) var(--wave-h) var(--wave-h) var(--info-h) var(--deck-h) var(--ctrl-h) minmax(0, 1fr) var(--xf-h) var(--trans-h);
  grid-template-areas:
    "hub hub views views"
    "infoA infoA infoA infoA"
    "waveA waveA waveA waveA"
    "waveB waveB waveB waveB"
    "infoB infoB infoB infoB"
    "pitchA platA platB pitchB"
    "ctrlA ctrlA ctrlB ctrlB"
    "pane pane pane pane"
    "xf xf xf xf"
    "transA transA transB transB";
}
.stage[data-mode="narrow"] .deck-col-left .deck-pane,
.stage[data-mode="narrow"] .deck-col-right .deck-pane { grid-area: pane; }
.stage[data-mode="narrow"]:not([data-pane="a"]) .deck-col-left .deck-pane,
.stage[data-mode="narrow"]:not([data-pane="b"]) .deck-col-right .deck-pane,
.stage[data-mode="narrow"]:not([data-pane="mix"]) .mixer { display: none; }
/* the mixer takes the place of the platters, the control row and the panel */
.stage[data-mode="narrow"][data-pane="mix"] {
  grid-template-areas:
    "hub hub views views"
    "infoA infoA infoA infoA"
    "waveA waveA waveA waveA"
    "waveB waveB waveB waveB"
    "infoB infoB infoB infoB"
    "mixer mixer mixer mixer"
    "mixer mixer mixer mixer"
    "mixer mixer mixer mixer"
    "xf xf xf xf"
    "transA transA transB transB";
}
.stage[data-mode="narrow"][data-pane="mix"] .pitch-col,
.stage[data-mode="narrow"][data-pane="mix"] .platter-wrap,
.stage[data-mode="narrow"][data-pane="mix"] .deck-ctrl { display: none; }
.stage[data-mode="narrow"]:not([data-view="mix"]) {
  grid-template-rows: var(--hub-h) var(--info-h) var(--wave-h) var(--wave-h) var(--info-h) minmax(0, 1fr) var(--xf-h) var(--trans-h);
  grid-template-areas:
    "hub hub views views"
    "infoA infoA infoA infoA"
    "waveA waveA waveA waveA"
    "waveB waveB waveB waveB"
    "infoB infoB infoB infoB"
    "lib lib lib lib"
    "xf xf xf xf"
    "transA transA transB transB";
}
/* (in the library view of the small layouts, the platters, pitch faders and control rows make room) */
.stage:not([data-view="mix"]):not([data-mode="wide"]) .pitch-col,
.stage:not([data-view="mix"]):not([data-mode="wide"]) .platter-wrap,
.stage[data-mode="narrow"]:not([data-view="mix"]) .deck-ctrl { display: none; }

/* until ui.js has measured the window (and without JS) a simple stack */
.stage:not([data-mode]) { grid-auto-rows: auto; overflow-y: auto; }

/* ---------- hub: menu, deck count, view switcher, master tempo ---------- */
.hub, .views, .hub-bpm { min-width: 0; min-height: 0; display: flex; align-items: center; justify-content: center; gap: 6px; }
.hub .icon-btn { width: 36px; height: 34px; }
.brand { font-weight: 800; letter-spacing: .24em; font-size: 15px; white-space: nowrap; }
.brand b { font-weight: 300; }
.hub .brand { font-size: 13px; letter-spacing: .2em; overflow: hidden; }
.stage[data-nobrand] .hub .brand,
.stage[data-mode="short"] .hub .brand,
.stage[data-mode="narrow"] .hub .brand { display: none; }
.stage[data-mode="narrow"] .hub { justify-content: flex-start; }
.stage[data-mode="narrow"] .views { justify-content: flex-end; }


/* view switcher: a segmented control */
.views { gap: 0; }
.view-btn {
  height: 32px;
  min-width: 44px;
  padding: 0 10px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--fg-2);
  display: inline-grid;
  place-items: center;
  font-weight: 800;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}
.view-btn + .view-btn { border-left: 0; }
.view-btn:first-child { border-radius: 10px 0 0 10px; }
.view-btn:last-child { border-radius: 0 10px 10px 0; }
.view-btn .ico { width: 20px; height: 20px; }
.view-btn:hover { color: var(--fg); }
.view-btn.on, #btn-library[aria-expanded="true"] { background: var(--fg); color: var(--bg); border-color: var(--fg); }
/* deck panel buttons only on phones in portrait */
.stage:not([data-mode="narrow"]) .view-deck { display: none; }
.stage:not([data-mode="narrow"]) .views [data-view="mix"] { border-radius: 10px 0 0 10px; }
/* landscape phones: the library button alone (the library's own ✕ closes it) */
.stage[data-mode="short"] .views [data-view="mix"] { display: none; }
.stage[data-mode="short"] #btn-library { border-radius: 10px; }
.stage[data-mode="short"] .view-btn, .stage[data-mode="short"] .hub .icon-btn { height: 30px; }
.stage[data-mode="short"] .hub .icon-btn { width: 30px; }
.stage[data-mode="short"] .view-btn { min-width: 38px; padding: 0 6px; }
/* the TOOLS button (phones; tablets and computers have the tool buttons in the control row) */
.view-tools { font-size: 10px; letter-spacing: .08em; }
.view-btn.view-tools.on { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.stage[data-mode="wide"] .view-tools,
.stage[data-mode="tall"] .view-tools { display: none; }
.stage[data-mode="wide"] #btn-library,
.stage[data-mode="tall"] #btn-library { border-radius: 0 10px 10px 0; }
.stage[data-mode="short"] #btn-library { border-radius: 10px 0 0 10px; }
.stage[data-mode="short"] .view-tools { border-radius: 0 10px 10px 0; }
.stage[data-mode="narrow"] .view-btn { min-width: 0; padding: 0 9px; }
.stage[data-mode="narrow"] .view-tools { padding: 0 7px; }

/* tablets and computers: the master tempo moves up beside the view switcher, and the middle of the
   control row holds the tool buttons */
.stage[data-mode="wide"] .views,
.stage[data-mode="tall"] .views { justify-self: start; }
.stage[data-mode="wide"] .hub-bpm,
.stage[data-mode="tall"] .hub-bpm { grid-area: views; justify-self: end; }
.stage[data-mode="tall"] .hub-bpm .master-bpm { font-size: 15px; }
.recording .stage[data-mode="tall"] .master-bpm small { display: none; }
.tools { min-width: 0; min-height: 0; display: flex; align-items: stretch; gap: 6px; }
.stage[data-mode="short"] .tools,
.stage[data-mode="narrow"] .tools { display: none; }
.tool-btn {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0 6px;
  overflow: hidden;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  background: transparent;
  color: var(--fg-2);
  font-weight: 800;
  font-size: 11px;
  line-height: 1;
  letter-spacing: .1em;
  white-space: nowrap;
  text-overflow: clip;
  cursor: pointer;
  touch-action: manipulation;
}
.tool-btn:hover { color: var(--fg); border-color: var(--fg-3); }
.tool-btn.on { background: var(--fg); border-color: var(--fg); color: var(--bg); }
.tool-btn.busy:not(.on) { color: var(--fg); border-color: var(--fg); }
.stage[data-mode="tall"] .tool-btn { font-size: 10px; letter-spacing: .03em; padding: 0 3px; }

.master-bpm { display: flex; align-items: baseline; gap: 4px; font-size: 17px; font-weight: 700; }
.master-bpm small { font: 700 9px/1 system-ui, sans-serif; letter-spacing: .14em; color: var(--fg-3); }
.stage[data-mode="short"] .hub-bpm { display: none; }
/* phones in portrait: the master tempo at the right of the menu row */
.stage[data-mode="narrow"] .hub { justify-self: start; }
.stage[data-mode="narrow"] .hub-bpm { grid-area: hub; justify-self: end; padding-right: 4px; }
.stage[data-mode="narrow"] .master-bpm { font-size: 15px; }
/* (where the master tempo has no place, recording shows as a red dot on the menu button) */
.recording .stage[data-mode="short"] #btn-menu,
.recording .stage[data-mode="narrow"] #btn-menu { position: relative; }
.recording .stage[data-mode="short"] #btn-menu::after,
.recording .stage[data-mode="narrow"] #btn-menu::after {
  content: "";
  position: absolute;
  top: 4px;
  right: 4px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--rec);
  animation: blink 1s steps(2, start) infinite;
}

.rec-indicator {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 28px;
  padding: 0 10px 0 6px;
  border-radius: 999px;
  border: 1px solid var(--rec);
  background: transparent;
  color: var(--fg);
  font: 700 12px/1 ui-monospace, Menlo, monospace;
  cursor: pointer;
}
.rec-indicator .ico { width: 16px; height: 16px; color: var(--rec); animation: blink 1s steps(2, start) infinite; }

@keyframes blink { 50% { opacity: .15; } }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- deck info strip: artwork, title, key and time left, track overview ---------- */
.deck-info {
  min-width: 0;
  min-height: 0;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  grid-template-rows: minmax(0, 1fr) var(--ov-h);
  grid-template-areas: "art name flags stats" "art ov ov ov";
  column-gap: 10px;
  row-gap: 4px;
  align-items: center;
  padding: 4px 8px 4px 4px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
  overflow: hidden;
}
.deck-art-btn {
  grid-area: art;
  width: calc(var(--info-h) - 10px);
  height: calc(var(--info-h) - 10px);
  padding: 0;
  border-radius: 8px;
  border: 1px solid var(--line);
  overflow: hidden;
  background: var(--panel-2);
  color: var(--fg-3);
  display: grid;
  place-items: center;
  cursor: pointer;
}
.deck-art { width: 100%; height: 100%; object-fit: cover; display: block; }
.deck-art-ph { width: 50%; height: 50%; max-width: 28px; max-height: 28px; }
.deck-name {
  grid-area: name;
  align-self: stretch;
  min-width: 0;
  background: none;
  border: 0;
  padding: 0;
  color: inherit;
  text-align: left;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  font: inherit;
}
.deck-title-row { display: flex; align-items: center; gap: 6px; min-width: 0; }
.deck-letter {
  flex: none;
  width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
  border: 1.5px solid var(--deck-accent);
  color: var(--deck-accent);
  border-radius: 6px;
  font-weight: 800;
  font-size: 12px;
  line-height: 1;
}
.deck-title, .deck-artist { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; min-width: 0; }
.deck-title { font-weight: 700; font-size: 15px; }
.deck-artist { color: var(--fg-2); font-size: 12px; }
.deck.empty .deck-title { color: var(--fg-2); font-weight: 600; }
.t-flags { grid-area: flags; display: flex; gap: 4px; flex-wrap: wrap; justify-content: flex-end; max-width: 120px; }
.flag {
  display: none;
  font: 800 9px/1 system-ui, sans-serif;
  letter-spacing: .1em;
  padding: 3px 5px;
  border-radius: 4px;
  background: var(--deck-accent);
  color: var(--on-fg);
}
.flag.on { display: inline-block; }
.deck-stats { grid-area: stats; display: flex; gap: 12px; text-align: right; }
.deck-stats .v { display: block; font-size: 18px; font-weight: 700; line-height: 1; white-space: nowrap; }
.deck-stats small { display: block; margin-bottom: 3px; font-size: 9px; letter-spacing: .14em; color: var(--fg-3); font-weight: 700; }
.deck-key .v { min-width: 2ch; }
.deck-left .v, .deck-key .v {
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Roboto Mono", monospace;
  font-variant-numeric: tabular-nums;
}
.wave-overview {
  grid-area: ov;
  display: block;
  width: 100%;
  height: 100%;
  min-width: 0;
  min-height: 0;
  border-radius: 5px;
  background: var(--panel-2);
  touch-action: none;
  cursor: pointer;
}
.deck.ending .wave-overview { animation: endwarn 1s steps(2, start) infinite; }
@keyframes endwarn { 50% { box-shadow: inset 0 0 0 2px var(--fg); } }
/* slim info rows (phones): one line (the artwork, title and time left) over a slim overview */
.stage[data-mode="short"] .deck-info,
.stage[data-mode="narrow"] .deck-info { padding: 3px 6px 3px 3px; column-gap: 8px; row-gap: 2px; border-radius: 10px; }
.stage[data-mode="short"] .deck-art-btn,
.stage[data-mode="narrow"] .deck-art-btn { width: calc(var(--info-h) - 8px); height: calc(var(--info-h) - 8px); border-radius: 6px; }
.stage[data-mode="short"] .deck-artist,
.stage[data-mode="narrow"] .deck-artist,
.stage[data-mode="short"] .deck-stats small,
.stage[data-mode="narrow"] .deck-stats small,
.stage[data-mode="short"] .t-flags,
.stage[data-mode="short"] .deck-key { display: none; }
.stage[data-mode="short"] .deck-title,
.stage[data-mode="narrow"] .deck-title { font-size: 13px; }
.stage[data-mode="short"] .deck-stats .v,
.stage[data-mode="narrow"] .deck-stats .v { font-size: 14px; }
.stage[data-mode="short"] .deck-letter,
.stage[data-mode="narrow"] .deck-letter { width: 18px; height: 18px; font-size: 11px; }
.stage[data-mode="narrow"] .t-flags { max-width: 90px; }
/* portrait tablets: narrower strips, so the key stays in the library and the title gets the room */
.stage[data-mode="tall"] .deck-key { display: none; }
.stage[data-mode="tall"] .deck-title { font-size: 14px; }
/* deck B in portrait: the overview sits above its title, next to its waveform */
.stage[data-mode="narrow"] .deck-col-right .deck-info { grid-template-rows: var(--ov-h) minmax(0, 1fr); grid-template-areas: "art ov ov ov" "art name flags stats"; }

/* ---------- waveform ---------- */
.deck-wave { position: relative; min-width: 0; min-height: 0; }
.wave-zoom {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border-radius: 8px;
  background: var(--panel-2);
  touch-action: none;
  cursor: grab;
}
.deck-loading {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 0 12px;
  background: var(--overlay);
  border-radius: 8px;
  font-size: 12px;
  font-weight: 600;
  text-align: center;
  overflow: hidden;
}
.spinner {
  width: 18px;
  height: 18px;
  flex: none;
  border: 2px solid var(--line);
  border-top-color: var(--fg);
  border-radius: 50%;
  animation: spin .8s linear infinite;
}
.deck.drop-hover .deck-info,
.deck.drop-hover .deck-wave,
.deck.drop-hover .platter-wrap { outline: 2px dashed var(--fg); outline-offset: -2px; }

/* ---------- platter ----------
   ui.js sizes it to the largest circle that fits its cell (--ps is its size). The tempo, BPM and
   times sit in its middle; the record turns underneath. */
.platter-wrap { display: flex; align-items: center; justify-content: center; min-width: 0; min-height: 0; overflow: hidden; }
.platter {
  --ps: 200px;
  flex: none;
  position: relative;
  width: 100%;
  max-width: 300px;
  border-radius: 50%;
  touch-action: none;
  cursor: grab;
}
.platter::before { content: ""; display: block; padding-top: 100%; }
.platter-ring {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  border-radius: 50%;
  border: 1.5px solid var(--line);
  background: repeating-conic-gradient(var(--tick) 0deg .8deg, transparent .8deg 7.5deg);
  -webkit-mask: radial-gradient(circle, transparent 0 89%, #000 89.5%);
  mask: radial-gradient(circle, transparent 0 89%, #000 89.5%);
  transition: border-color .1s;
}
.platter-disc {
  position: absolute;
  top: 6%;
  right: 6%;
  bottom: 6%;
  left: 6%;
  border-radius: 50%;
  background: var(--disc);
  box-shadow: inset 0 0 0 1px var(--line), 0 6px 18px var(--shadow);
  overflow: hidden;
  will-change: transform;
}
.platter-grooves {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  border-radius: 50%;
  background: repeating-radial-gradient(circle at center, var(--groove) 0 1px, transparent 1px 4px);
}
/* the record label: only the artwork (dimmed, under the readout), when artwork on platters is on */
.platter-label {
  position: absolute;
  top: 14%;
  right: 14%;
  bottom: 14%;
  left: 14%;
  border-radius: 50%;
  overflow: hidden;
  display: none;
  opacity: .32;
  box-shadow: 0 0 0 2px var(--line);
}
.deck.has-art .platter-label { display: block; }
.platter-label-text { display: none; }
.platter-art { position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%; object-fit: cover; }
.platter-marker {
  position: absolute;
  left: 50%;
  top: 2.5%;
  width: 4px;
  height: 13%;
  margin-left: -2px;
  border-radius: 2px;
  background: var(--deck-accent);
  box-shadow: 0 0 0 1px var(--bg);
}
.platter-read {
  position: absolute;
  top: 20%;
  right: 16%;
  bottom: 20%;
  left: 16%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: calc(var(--ps) * .012);
  pointer-events: none;
  text-align: center;
  line-height: 1;
  white-space: nowrap;
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Roboto Mono", monospace;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 4px var(--bg), 0 0 2px var(--bg);
}
.platter-read .pitch-val { font-size: calc(var(--ps) * .068); font-weight: 700; color: var(--fg-2); }
.platter-read .deck-bpm .v { display: block; font-size: calc(var(--ps) * .15); font-weight: 800; color: var(--fg); letter-spacing: -.02em; }
.platter-read .t-elapsed { font-size: calc(var(--ps) * .074); font-weight: 600; color: var(--fg); }
.platter-read .t-remain { font-size: calc(var(--ps) * .062); font-weight: 600; color: var(--fg-2); }
.platter.touched .platter-ring, .deck.scratching .platter-ring { border-color: var(--fg); }
.platter.touched .platter-disc { box-shadow: inset 0 0 0 2px var(--fg), 0 6px 18px var(--shadow); }
.deck.empty .platter { cursor: default; opacity: .7; }

/* ---------- pitch fader (beside the platter, on the outside) ---------- */
.pitch-col { display: flex; flex-direction: column; align-items: stretch; gap: 4px; min-width: 0; min-height: 0; }
.pitch-fader { flex: 1 1 0%; min-height: 0; width: 100%; }
.pitch-col .fader-v { width: 100%; }
.pitch-col .fader-v .fader-cap { width: calc(var(--pitch-w) - 6px); margin-left: calc((var(--pitch-w) - 6px) / -2); }
.pitch-col .fader-v .fader-ticks { left: 3px; }
/* bend buttons stacked (+ on top) */
.pitch-btns { flex: none; display: flex; flex-direction: column-reverse; gap: 4px; }
.pitch-btns .btn-xs { width: 100%; min-height: 30px; }
/* (without room for them the bend buttons are in the deck menu: BEND − / +) */
.stage[data-nobend] .pitch-btns { display: none; }

/* ---------- control row: SYNC, tempo, loop ---------- */
.deck-ctrl { display: flex; align-items: stretch; gap: 6px; min-width: 0; min-height: 0; }
.deck-ctrl .btn { min-height: 0; padding: 0 6px; }
.btn-sync { flex: 1 1 0%; max-width: 120px; font-size: 13px; }
.deck-bpm-btn {
  flex: 1.3 1 0%;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0 8px;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  background: transparent;
  color: var(--fg);
  cursor: pointer;
  font: 700 18px/1 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
}
.deck-bpm-btn small { font: 800 9px/1 system-ui, sans-serif; letter-spacing: .14em; color: var(--fg-3); }
.deck-bpm-btn:hover { border-color: var(--fg-3); }
.loop-ctl { flex: 1.6 1 0%; min-width: 0; display: flex; border: 1.5px solid var(--line); border-radius: 10px; overflow: hidden; }
.loop-ctl .btn { flex: 1 1 0%; min-width: 0; border: 0; border-radius: 0; font-size: 17px; font-weight: 700; padding: 0; }
.loop-ctl .loop-len { flex: 1.3 1 0%; font-size: 15px; font-weight: 800; border-left: 1px solid var(--line); border-right: 1px solid var(--line); }
.loop-ctl .loop-len::before { content: "LOOP"; display: block; margin-right: 6px; font-size: 9px; letter-spacing: .12em; color: var(--fg-3); }
.loop-ctl .loop-len.on::before { color: inherit; opacity: .7; }
.btn-flip { display: none; flex: none; }
.btn-flip .ico { width: 20px; height: 20px; }
/* the right deck mirrors the left: SYNC sits on the outside */
.deck-col-right .deck-ctrl { flex-direction: row-reverse; }
/* phones: SYNC and the loop (the tempo is on the platter); landscape phones swap SYNC and pads */
.stage[data-mode="narrow"] .deck-bpm-btn,
.stage[data-mode="short"] .deck-bpm-btn,
.stage[data-mode="short"] .loop-ctl { display: none; }
.stage[data-mode="short"] .btn-flip { display: inline-flex; flex: 1 1 0%; }
.stage[data-mode="short"] .btn-sync { max-width: none; }
.stage[data-mode="narrow"] .loop-ctl .loop-len::before,
.stage[data-mode="tall"] .loop-ctl .loop-len::before { display: none; }
.stage[data-mode="narrow"] .btn-sync { font-size: 12px; }

/* ---------- transport ---------- */
.deck-transport { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, .7fr); gap: 6px; min-width: 0; min-height: 0; }
.deck-col-right .deck-transport { grid-template-columns: minmax(0, .7fr) minmax(0, 1fr) minmax(0, 1fr); }
.deck-col-right .btn-keylock { order: -1; }
.deck-col-right .btn-play { order: 1; }
.deck-transport .btn { min-width: 0; min-height: 0; overflow: hidden; }
.btn-cue, .btn-play { font-size: 15px; border-radius: 12px; border-width: 2px; }
.btn-play .ico { width: 26px; height: 26px; }
.btn-play .i-pause, .btn-play.on .i-play { display: none; }
.btn-play.on .i-pause { display: block; }
.btn-keylock { font-size: 10px; line-height: 1.15; }
.stage[data-mode="short"] .btn-keylock, .stage[data-mode="narrow"] .btn-keylock { font-size: 9px; letter-spacing: .02em; padding: 0 2px; }
.stage[data-mode="short"] .btn-play .ico, .stage[data-mode="narrow"] .btn-play .ico { width: 22px; height: 22px; }

.deck .btn.on, .deck .pad.on, .deck-tabs button.on, .ch .btn.on {
  background: var(--deck-accent);
  border-color: var(--deck-accent);
  color: var(--on-fg);
}

/* ---------- deck panel: CUES / LOOP / FX / PAD tabs ---------- */
.deck-pane {
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
}
.deck-panels {
  position: relative;
  flex: 1 1 0%;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
}
/* every panel shares one place; switching slides the new one in */
.deck-panel {
  grid-area: 1 / 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  overflow: hidden;
  transition: opacity .16s ease, transform .16s ease, visibility 0s;
}
.deck-panel.tab-off {
  visibility: hidden;
  pointer-events: none;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .16s ease, transform .16s ease, visibility 0s linear .16s;
}
.deck-tabs { flex: none; display: flex; gap: 4px; min-height: 32px; }
.deck-tabs button {
  flex: 1 1 0%;
  min-width: 0;
  height: 32px;
  padding: 0 2px;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: transparent;
  color: var(--fg-2);
  font-weight: 800;
  font-size: 11px;
  line-height: 1;
  letter-spacing: .12em;
  cursor: pointer;
  touch-action: manipulation;
}
.deck-tabs button:hover { color: var(--fg); border-color: var(--fg-3); }
.deck-tabs .deck-menu-btn { flex: 0 0 40px; display: grid; place-items: center; padding: 0; }
.deck-menu-btn .ico { width: 18px; height: 18px; }
.no-pad-btn .deck-pad-btn { display: none; }
.stage[data-pw] .deck-tabs button { letter-spacing: .04em; font-size: 10px; }
.stage[data-tight] .deck-tabs button[data-pg]::after {
  content: attr(data-pg);
  margin-left: 4px;
  font-size: 9px;
  letter-spacing: 0;
  opacity: .75;
}

.pads { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-rows: minmax(0, 1fr); gap: 6px; flex: 1 1 auto; min-height: 0; max-height: 320px; }
.pad {
  min-height: 0;
  min-width: 0;
  padding: 4px 0;
  border-radius: 9px;
  border: 1.5px solid var(--line);
  background: transparent;
  color: var(--fg-2);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  font-weight: 800;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  touch-action: none;
  transition: background-color .07s, transform .07s;
}
.pad.pressed { transform: scale(.95); }
.pad-t { font: 600 9px/1 ui-monospace, Menlo, monospace; color: var(--fg-3); min-height: 9px; letter-spacing: .04em; }
.pad.on .pad-t { color: inherit; opacity: .7; }
.del-mode .pads-hot .pad.on { background: transparent; color: var(--fg); border-style: dashed; border-color: var(--fg); }
.pad-tools { flex: none; display: flex; gap: 6px; }
.pad-tools .btn { flex: 1 1 0%; min-width: 0; padding: 0 4px; }
.roll-mode .pads-loop .pad { border-style: dashed; }
.stage[data-pw] .loop-tools .btn { font-size: 10px; letter-spacing: 0; }

/* FX: three effect slots, like a DJ mixer's FX unit: the ON switch at the top, the effect under it,
   then its knobs. ui.js picks the arrangement (data-fx = cols | rows | page) and sizes the knobs to
   fill the slots (--fxk, data-fxstack when they fit better one above the other) */
.deck-panel[data-panel="fx"] { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-rows: minmax(0, 1fr); gap: 6px; }
.fx-slot {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto auto minmax(0, 1fr);
  grid-template-areas: "on" "type" "knobs";
  gap: 6px;
  min-width: 0;
  min-height: 0;
  padding: 6px;
  border: 1px solid var(--line-2);
  border-radius: 10px;
  overflow: hidden;
}
.fx-slot.active { border-color: var(--deck-accent); }
.fx-slot .fx-on { grid-area: on; width: 100%; min-width: 0; min-height: 32px; padding: 0 4px; }
.fx-slot .fx-type { grid-area: type; width: 100%; min-width: 0; max-width: none; height: 32px; font-size: 12px; }
.fx-knobs { grid-area: knobs; display: flex; align-items: center; justify-content: space-evenly; gap: 4px; min-width: 0; min-height: 0; }
.fx-knobs .knob { width: auto; min-width: 40px; }
.fx-knobs .knob-dial { width: 44px; height: 44px; width: var(--fxk, 44px); height: var(--fxk, 44px); }
.stage[data-fxstack] .fx-knobs { flex-direction: column; justify-content: space-evenly; }
/* narrow panels: the slots one under the other, ON beside the effect */
.stage[data-fx="rows"] .deck-panel[data-panel="fx"] { grid-template-columns: minmax(0, 1fr); grid-template-rows: repeat(3, minmax(0, 1fr)); }
.stage[data-fx="rows"] .fx-slot { grid-template-columns: auto minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); grid-template-areas: "on type" "knobs knobs"; }
.stage[data-fx="rows"] .fx-slot .fx-on { width: 52px; }
/* short panels: one slot at a time on one line (tap the open FX tab for the next: 1/3, 2/3, 3/3) */
.stage[data-fx="page"] .deck-panel[data-panel="fx"] { grid-template-columns: minmax(0, 1fr); }
.stage[data-fx="page"] .fx-slot {
  grid-area: 1 / 1;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-rows: minmax(0, 1fr);
  grid-template-areas: "on type knobs";
  align-items: center;
  padding: 3px 6px;
}
.stage[data-fx="page"] .fx-slot .fx-on { width: 48px; }
.stage[data-fx="page"] .deck[data-page="1"] .fx-slot[data-slot="0"],
.stage[data-fx="page"] .deck[data-page="2"] .fx-slot[data-slot="0"],
.stage[data-fx="page"] .deck:not([data-page="1"]) .fx-slot[data-slot="1"],
.stage[data-fx="page"] .deck:not([data-page="2"]) .fx-slot[data-slot="2"] { display: none; }
.stage[data-fxnolabel] .fx-knobs .knob-label { display: none; }

/* short panels: one (data-tight="1") or two (="2") rows of pads at a time; tapping the open tab
   again pages through the rest (the tab shows 1/2, 2/2…) */
.stage[data-tight] .pad-tools { flex: 1 1 0%; max-height: 52px; }
.stage[data-tight] .pad-tools .btn { min-height: 0; }
.stage[data-tight="1"] .loop-tools .btn:nth-child(n+4) { display: none; }
.stage[data-tight="1"] .deck[data-page="0"] .pads .pad:nth-child(n+5),
.stage[data-tight="1"] .deck[data-page="1"] .pads .pad:nth-child(-n+4),
.stage[data-tight="1"] .deck[data-page="2"] .pads,
.stage[data-tight="1"] .deck[data-page="3"] .pads,
.stage[data-tight="1"] .deck[data-page="0"] .loop-tools,
.stage[data-tight="1"] .deck[data-page="1"] .loop-tools,
.stage[data-tight="2"] .deck[data-page="1"] .pads-loop,
.stage[data-tight="2"] .deck:not([data-page="1"]) .loop-tools { display: none; }
.stage[data-tight="1"] .deck[data-page="3"] .loop-tools .btn:nth-child(n+4) { display: inline-flex; }
.stage[data-tight="1"] .deck[data-page="3"] .loop-tools .btn:nth-child(-n+3) { display: none; }
.stage[data-tight="2"] .loop-tools { flex-wrap: wrap; max-height: none; }
.stage[data-tight="2"] .loop-tools .btn { flex: 1 1 30%; }
/* (hot cue delete mode is also in the deck's ⋯ menu, so short panels give the pads the room) */
.stage[data-tight] [data-panel="cues"] .pad-tools { display: none; }

/* ---------- knobs ---------- */
.knob { display: flex; flex-direction: column; align-items: center; gap: 2px; width: 54px; touch-action: none; }
.knob-dial { width: 44px; height: 44px; border-radius: 50%; cursor: ns-resize; touch-action: none; }
.knob svg { display: block; width: 100%; height: 100%; overflow: visible; }
.knob-track { fill: none; stroke: var(--line); stroke-width: 3; stroke-linecap: round; }
.knob-val { fill: none; stroke: var(--deck-accent); stroke-width: 3; stroke-linecap: round; }
.knob-cap { fill: var(--panel-2); stroke: var(--fg-3); stroke-width: 1; }
.knob-ptr { stroke: var(--fg); stroke-width: 2.6; stroke-linecap: round; }
.knob.active .knob-cap { stroke: var(--fg); }
.knob-label {
  font-weight: 800;
  font-size: 9px;
  line-height: 1;
  letter-spacing: .1em;
  color: var(--fg-2);
  white-space: nowrap;
  max-width: 64px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.knob.active .knob-label { color: var(--fg); }
.knob-sm { width: 46px; }
.knob-sm .knob-dial { width: 36px; height: 36px; }

/* ---------- faders ---------- */
.fader { position: relative; touch-action: none; cursor: pointer; --cap-h: 30px; --cap-w: 36px; }
.fader-v { width: 46px; }
.fader-h { height: 44px; }
.fader-track { position: absolute; background: var(--line); border-radius: 2px; }
.fader-v .fader-track { left: 50%; top: calc(var(--cap-h) / 2); bottom: calc(var(--cap-h) / 2); width: 4px; margin-left: -2px; }
.fader-h .fader-track { top: 50%; left: calc(var(--cap-w) / 2); right: calc(var(--cap-w) / 2); height: 4px; margin-top: -2px; }
.fader-fill { position: absolute; background: var(--fg-3); border-radius: 2px; }
.fader-v .fader-fill { left: 0; right: 0; }
.fader-h .fader-fill { top: 0; bottom: 0; }
.fader-center { position: absolute; background: var(--fg-2); }
.fader-v .fader-center { left: -10px; right: -10px; top: 50%; height: 1px; }
.fader-h .fader-center { top: -10px; bottom: -10px; left: 50%; width: 1px; }
.fader-ticks { position: absolute; pointer-events: none; }
.fader-v .fader-ticks {
  top: 0; bottom: 0; left: 10px; width: 6px;
  background: repeating-linear-gradient(to bottom, var(--line) 0 1px, transparent 1px 10%);
}
.fader-h .fader-ticks {
  left: 0; right: 0; top: 8px; height: 5px;
  background: repeating-linear-gradient(to right, var(--line) 0 1px, transparent 1px 10%);
}
.fader-cap {
  position: absolute;
  border-radius: 6px;
  background: var(--fg);
  box-shadow: 0 2px 8px var(--shadow);
  cursor: grab;
}
.fader-v .fader-cap { left: 50%; width: 40px; height: var(--cap-h); margin-left: -20px; }
.fader-h .fader-cap { top: 50%; width: var(--cap-w); height: 40px; margin-top: -20px; }
.fader-cap::after { content: ""; position: absolute; background: var(--bg); border-radius: 1px; }
.fader-v .fader-cap::after { left: 5px; right: 5px; top: 50%; height: 2px; margin-top: -1px; }
.fader-h .fader-cap::after { top: 5px; bottom: 5px; left: 50%; width: 2px; margin-left: -1px; }
.fader.active .fader-cap { box-shadow: 0 0 0 3px var(--line), 0 2px 8px var(--shadow); }
@media (pointer: coarse) {
  /* touch: fader caps at least 34px in both directions (the whole track is draggable too) */
  .fader { --cap-h: 34px; }
  .xfader-wrap .fader { --cap-w: 34px; }
}

/* ---------- crossfader ---------- */
.xfader-wrap { display: flex; align-items: center; gap: 8px; min-width: 0; min-height: 0; padding: 0 6px; }
.xfader-wrap .fader { flex: 1 1 auto; min-width: 80px; --cap-w: 30px; }
.xf-label { font-weight: 900; font-size: 12px; color: var(--fg-3); }
.stage[data-mode="short"] .xf-label { display: none; }
.stage[data-mode="narrow"] .xfader-wrap { border: 1px solid var(--line); border-radius: 12px; }

/* ---------- mixer ----------
   ui.js tries the layouts in turn and keeps the first that fits (data-mix):
   full    — one tall strip per channel: trim, EQ, filter, cue, fader, crossfader assign
   wide    — the knobs in two columns beside the fader
   compact — FILTER and fader; trim / EQ / cue / assign and master are behind the EQ button */
.mixer {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  min-height: 0;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
  overflow: hidden;
}
.vu { display: block; }
/* MASTER with its meter, and the headphone knobs under it (CUE MIX: CUE ↔ PGM, CUE GAIN) */
.mixer-master {
  flex: none;
  display: grid;
  grid-template-columns: auto auto;
  grid-template-areas: "master vu" "hp hp";
  justify-content: center;
  align-items: center;
  gap: 2px 8px;
}
#k-master { grid-area: master; }
.vu-master { grid-area: vu; width: 14px; height: 52px; }
.hp-controls { grid-area: hp; display: flex; justify-content: center; gap: 10px; padding-top: 4px; border-top: 1px solid var(--line-2); }
.hp-controls .knob { width: 52px; } /* (room for the CUE MIX / CUE GAIN captions) */
.mixer-channels { display: flex; gap: 6px; justify-content: center; flex: 1 1 auto; min-height: 0; }
.ch {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  flex: 1 1 0%;
  min-width: 62px;
  max-width: 120px;
  min-height: 0;
  padding: 6px 3px;
  border: 1px solid var(--line-2);
  border-radius: 10px;
}
.ch-label { font-weight: 900; font-size: 13px; line-height: 1; color: var(--deck-accent); letter-spacing: .1em; }
.ch-cue { width: 54px; }
/* the channel fader takes the strip's spare height */
.ch-fader-row { position: relative; display: flex; align-items: stretch; flex: 1 1 0%; min-height: 96px; padding-left: 13px; }
/* absolutely positioned with an explicit height, so the canvas's pixel buffer can never size the strip */
.ch-fader-row .vu { position: absolute; left: 0; top: 0; width: 7px; height: 100%; }
.ch-fader { width: 42px; }
.xf-assign { display: flex; align-self: stretch; border: 1px solid var(--line); border-radius: 6px; overflow: hidden; flex: none; }
.xf-assign button {
  border: 0;
  background: none;
  color: var(--fg-3);
  font-weight: 800;
  font-size: 9px;
  line-height: 1;
  letter-spacing: .04em;
  flex: 1 1 auto;
  padding: 6px 2px;
  min-height: 26px;
  cursor: pointer;
}
.xf-assign button.on { background: var(--fg); color: var(--bg); }
.knob-filter .knob-val { stroke: var(--fg); }
.mixer-eq-btn { display: none; }

.ch-label { grid-area: label; }
.ch [data-k="trim"] { grid-area: trim; }
.ch [data-k="hi"] { grid-area: hi; }
.ch [data-k="mid"] { grid-area: mid; }
.ch [data-k="low"] { grid-area: low; }
.ch [data-k="filter"] { grid-area: filter; }
.ch-cue { grid-area: cue; }
.ch-fader-row { grid-area: fader; }
.xf-assign { grid-area: xf; }

/* full: slightly smaller knobs, so the strips and the headphone knobs under MASTER fit a tablet in portrait */
.stage[data-mix="full"] .ch { gap: 3px; }
.stage[data-mix="full"] .ch .knob { width: 46px; }
.stage[data-mix="full"] .ch .knob-dial { width: 36px; height: 36px; }
.stage[data-mix="full"] .ch-fader-row { min-height: 84px; }
.stage[data-mix="full"] #k-master .knob-dial { width: 40px; height: 40px; }
.stage[data-mix="full"] .hp-controls .knob-dial { width: 32px; height: 32px; }

/* wide: knobs in two columns beside the fader */
.stage[data-mix="wide"] .ch {
  display: grid;
  flex: none;
  max-width: none;
  grid-template-columns: auto auto auto;
  grid-template-rows: auto auto auto auto auto;
  grid-template-areas: "label label label" "trim hi fader" "mid low fader" "filter cue fader" "xf xf xf";
  justify-items: center;
  align-items: center;
  align-content: space-between;
  gap: 4px 4px;
  padding: 6px 6px 6px;
}
.stage[data-mix="wide"] .ch .knob { width: 44px; }
.stage[data-mix="wide"] .ch .knob-dial { width: 36px; height: 36px; }
.stage[data-mix="wide"] .ch-cue { width: 44px; min-height: 34px; }
.stage[data-mix="wide"] .ch-fader-row { align-self: stretch; min-height: 0; height: 100%; }
.stage[data-mix="wide"] .xf-assign { justify-self: stretch; }

/* compact: FILTER and volume per channel */
.stage[data-mix="compact"] .mixer:not(.eq-open) .mixer-master,
.stage[data-mix="compact"] .mixer:not(.eq-open) .ch [data-k]:not([data-k="filter"]),
.stage[data-mix="compact"] .mixer:not(.eq-open) .ch-cue,
.stage[data-mix="compact"] .mixer:not(.eq-open) .xf-assign { display: none; }
.stage[data-mix="compact"] .mixer-eq-btn { display: inline-flex; flex: none; order: -1; min-height: 28px; align-self: stretch; }
.stage[data-mix="compact"] .ch { padding: 4px 2px 4px; gap: 3px; min-width: 0; }
.stage[data-mix="compact"] .ch .knob { width: 50px; }
.stage[data-mix="compact"] .ch .knob-dial { width: 40px; height: 40px; }
.stage[data-mix="compact"] .ch-fader-row { min-height: 50px; }
/* short rows: the FILTER caption goes so the fader keeps its travel */
.stage[data-mode="short"][data-mix="compact"] .mixer:not(.eq-open) .ch [data-k="filter"] .knob-label { display: none; }
.stage[data-mode="short"][data-mix="compact"] .mixer:not(.eq-open) .ch .knob-dial { width: 34px; height: 34px; }
.stage[data-mode="short"][data-mix="compact"] .mixer:not(.eq-open) .ch-label { display: none; }
/* landscape phones: FILTER beside the fader, so the fader keeps its travel */
.stage[data-mode="short"][data-mix="compact"] .mixer:not(.eq-open) .ch {
  display: grid;
  grid-template-columns: auto auto;
  grid-template-rows: minmax(0, 1fr);
  grid-template-areas: "filter fader";
  align-items: start;
  justify-content: center;
  gap: 2px;
  padding: 4px 1px;
}
.stage[data-mode="short"][data-mix="compact"] .mixer:not(.eq-open) .ch .knob { width: 36px; }
.stage[data-mode="short"][data-mix="compact"] .mixer:not(.eq-open) .ch-fader-row { align-self: stretch; height: 100%; min-height: 0; padding-left: 9px; }
.stage[data-mode="short"][data-mix="compact"] .mixer:not(.eq-open) .ch-fader-row .vu { width: 6px; }
.stage[data-mode="short"][data-mix="compact"] .mixer:not(.eq-open) .ch-fader { width: 34px; }
.stage[data-mode="short"][data-mix="compact"] .mixer:not(.eq-open) .ch-fader .fader-cap { width: 34px; margin-left: -17px; }
.stage[data-mode="short"] .mixer-eq-btn { min-height: 24px; }
/* the EQ page (in place): master, trim / EQ, cue and crossfader assign; it scrolls if it must */
.stage[data-mix="compact"] .mixer.eq-open { overflow-y: auto; overscroll-behavior: contain; }
.stage[data-mix="compact"] .mixer.eq-open .ch-fader-row,
.stage[data-mix="compact"] .mixer.eq-open .ch [data-k="filter"] { display: none; }
.stage[data-mix="compact"] .mixer.eq-open > * { flex-shrink: 0; }
.stage[data-mix="compact"] .mixer.eq-open .mixer-master {
  /* (small mixers: MASTER and the headphone knobs in one row at the top of the EQ page) */
  grid-template-columns: auto auto auto;
  grid-template-areas: "master vu hp";
  gap: 4px 8px;
}
.stage[data-mix="compact"] .mixer.eq-open .hp-controls { padding: 0 0 0 8px; border-top: 0; border-left: 1px solid var(--line-2); gap: 4px; }
.stage[data-mix="compact"] .mixer.eq-open .hp-controls .knob { width: 52px; }
.stage[data-mix="compact"] .mixer.eq-open #k-master .knob-dial { width: 30px; height: 30px; }
.stage[data-mix="compact"] .mixer.eq-open { gap: 4px; padding: 4px 6px; }
.stage[data-mix="compact"] .mixer.eq-open #k-master { width: 44px; }
.stage[data-mix="compact"] .mixer.eq-open .mixer-channels { flex: none; }
.stage[data-mix="compact"] .mixer.eq-open .ch {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, auto));
  grid-template-areas: "label label" "trim hi" "mid low" "cue xf";
  justify-items: center;
  align-items: center;
  align-content: start;
  gap: 2px 4px;
  flex: 1 1 0%;
}
.stage[data-mix="compact"] .mixer.eq-open .ch .knob { width: 40px; }
.stage[data-mix="compact"] .mixer.eq-open .ch .knob-dial { width: 28px; height: 28px; }
.stage[data-mix="compact"] .mixer.eq-open .ch-cue { width: 100%; min-width: 0; min-height: 28px; }
.stage[data-mix="compact"] .mixer.eq-open .xf-assign { justify-self: stretch; }
.stage[data-mix="compact"] .mixer.eq-open .knob-sm { width: 40px; }
.stage[data-mix="compact"] .mixer.eq-open .knob-sm .knob-dial { width: 28px; height: 28px; }
.stage[data-mix="compact"] .mixer.eq-open .vu-master { height: 40px; width: 10px; }
.stage[data-mode="short"][data-mix="compact"] .mixer.eq-open .ch .knob-label { font-size: 8px; }
.stage[data-mode="short"][data-mix="compact"] .mixer.eq-open .ch .knob-dial { width: 28px; height: 28px; }
.stage[data-mode="short"][data-mix="compact"] .mixer.eq-open .ch-label { display: none; }
/* touch screens and narrow strips: one button showing the current assignment; tapping it cycles
   A → THR → B */
@media (pointer: coarse) { .xf-assign button { min-height: 30px; } }
.stage[data-mix="compact"] .xf-assign button { display: none; flex: 1; font-size: 10px; }
.stage[data-mix="compact"] .xf-assign button.on { display: block; }

/* ---------- big screens: controls grow a little with the space ---------- */
@media (min-width: 1800px) and (min-height: 1000px) {
  .deck-title { font-size: 18px; }
  .deck-artist { font-size: 14px; }
  .deck-stats .v { font-size: 22px; }
  .btn-cue, .btn-play { font-size: 17px; }
  .btn-sync { font-size: 15px; }
  .btn-keylock { font-size: 12px; }
  .deck-tabs button { height: 38px; font-size: 12px; }
  .pad { font-size: 16px; }
  .pad-t { font-size: 10px; }
  .btn-sm { min-height: 38px; font-size: 12px; }
  .stage[data-mix="full"] .knob { width: 62px; }
  .stage[data-mix="full"] .knob-dial { width: 52px; height: 52px; }
  .stage[data-mix="full"] .ch-cue { width: 64px; }
  .fader { --cap-h: 34px; --cap-w: 40px; }
  .fader-v .fader-cap { width: 46px; margin-left: -23px; }
  .fader-h .fader-cap { height: 46px; margin-top: -23px; }
}

/* ---------- library (the library view: it takes the place of the deck panels and mixer) ---------- */
.library {
  --lib-cols: 44px minmax(0, 1fr) 58px 44px 50px auto 32px;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg);
  overflow: hidden;
}
.lib-toolbar { flex: none; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 8px 10px; }
.lib-title { display: flex; align-items: center; gap: 6px; font-weight: 800; letter-spacing: .16em; font-size: 13px; }
.lib-count {
  font: 600 11px/1 ui-monospace, Menlo, monospace;
  padding: 3px 7px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--fg-2);
  letter-spacing: 0;
}
.lib-search {
  flex: 1 1 200px;
  display: flex;
  align-items: center;
  gap: 6px;
  height: 36px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--fg-3);
  cursor: text;
}
.lib-search .ico { width: 16px; height: 16px; }
.lib-search input {
  flex: 1;
  min-width: 0;
  height: 100%;
  background: transparent;
  border: 0;
  color: var(--fg);
  font-size: 14px;
  line-height: 1;
  font-family: inherit;
}
.lib-search input::placeholder { color: var(--fg-3); }
.lib-search input::-webkit-search-cancel-button { filter: grayscale(1); }
.lib-toolbar .select { max-width: 160px; }
.lib-target {
  margin: 0 12px 8px;
  padding: 6px 6px 6px 12px;
  border: 1.5px solid var(--fg);
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 13px;
}
.lib-head, .trk { display: grid; grid-template-columns: var(--lib-cols); align-items: center; gap: 8px; padding: 6px 12px; }
.lib-head {
  padding-top: 0;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--line);
  font-weight: 800;
  font-size: 9px;
  line-height: 1;
  letter-spacing: .14em;
  color: var(--fg-3);
}
.lib-list {
  list-style: none;
  margin: 0;
  padding: 0 0 12px;
  overflow-y: auto;
  flex: 1;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
.trk {
  height: 56px;
  border-bottom: 1px solid var(--line-2);
  cursor: pointer;
}
.trk-spacer { list-style: none; margin: 0; padding: 0; border: 0; }
.trk:hover { background: var(--hover); }
.trk.sel { background: var(--hover); box-shadow: inset 3px 0 0 var(--fg); }
.trk.loaded .trk-title::after {
  content: "ON DECK";
  margin-left: 8px;
  font: 800 8px/1 system-ui, sans-serif;
  letter-spacing: .1em;
  padding: 2px 4px;
  border-radius: 3px;
  border: 1px solid var(--fg-3);
  vertical-align: 2px;
}
.trk-art {
  width: 42px;
  height: 42px;
  border-radius: 6px;
  overflow: hidden;
  border: 1px solid var(--line-2);
  display: grid;
  place-items: center;
  color: var(--fg-3);
  background: var(--panel-2);
}
.trk-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.trk-main { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.trk-title, .trk-sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.trk-title { font-weight: 600; }
.trk-sub { color: var(--fg-2); font-size: 12px; }
.trk-bpm, .trk-key, .trk-time {
  font: 500 12px/1 ui-monospace, Menlo, monospace;
  color: var(--fg-2);
  text-align: right;
  white-space: nowrap;
}
.trk-load { display: flex; gap: 4px; }
.trk-btn {
  width: 34px;
  height: 34px;
  border-radius: 8px;
  border: 1.5px solid var(--line);
  background: transparent;
  color: var(--fg);
  font-weight: 900;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
}
.trk-btn:hover { border-color: var(--fg); }
.trk-btn.on { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.trk-del {
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--fg-3);
  display: grid;
  place-items: center;
  cursor: pointer;
  padding: 0;
}
.trk-del:hover { color: var(--fg); background: var(--hover); }
.trk-del .ico { width: 15px; height: 15px; }
.trk-none { padding: 24px 12px; color: var(--fg-3); text-align: center; }
.lib-empty {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 20px;
  gap: 4px;
  color: var(--fg-2);
}
.lib-empty p { margin: 4px 0; max-width: 420px; }
.lib-empty-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 10px; }

/* sortable columns. Columns follow the library's own width (container query), so they stay right
   wherever the library sits. Medium (default): TRACK (+album) | ARTIST | BPM | KEY | TIME */
.library { container-type: inline-size; container-name: lib; }
.lib-head, .trk { grid-template-columns: 44px minmax(0, 1.6fr) minmax(0, 1fr) 58px 44px 50px auto 32px; }
.lh-sort {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  height: 24px;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  white-space: nowrap;
  overflow: hidden;
  cursor: pointer;
}
.lh-sort:hover, .lh-sort.on { color: var(--fg); }
.lh-sort.on::after { content: "\25B2"; font-size: 7px; }
.lh-sort.on.desc::after { content: "\25BC"; }
.lh-num { justify-content: flex-end; }
/* header and rows share one grid: give the LOAD column a fixed width (one button per deck) and keep
   the header clear of the list's scrollbar so the columns line up */
.lh-load, .trk-load { width: calc(var(--load-n, 2) * 38px - 4px); }
.lib-head { padding-right: calc(12px + var(--sbw, 0px)); }
.lh-album, .lh-added, .trk-album, .trk-sub .sub-artist { display: none; }
.trk-artist, .trk-album { min-width: 0; color: var(--fg-2); font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@media (pointer: coarse) { .lh-sort { height: 32px; } }
/* wide: TRACK | ARTIST | ALBUM | BPM | KEY | TIME */
@container lib (min-width: 1000px) {
  .lib-head, .trk { grid-template-columns: 44px minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1fr) 58px 44px 50px auto 32px; }
  .lh-album { display: inline-flex; }
  .trk-album { display: block; }
  .trk-sub .sub-album { display: none; }
}
/* narrow (phones): TRACK (artist · album) | BPM, with the sort options as a row of chips */
@container lib (max-width: 640px) {
  .trk { grid-template-columns: 42px minmax(0, 1fr) 44px auto 28px; gap: 6px; padding: 6px 8px; height: 54px; }
  .trk-artist, .trk-album, .trk-key, .trk-time { display: none; }
  .trk-sub .sub-artist { display: inline; }
  .sub-artist + .sub-album::before { content: " \00B7  "; }
  .lib-head {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    padding: 0 8px 8px;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .lib-head::-webkit-scrollbar { display: none; }
  .lh-art, .lh-load, .lh-del { display: none; }
  .lib-head .lh-sort { display: inline-flex; flex: none; height: 32px; padding: 0 12px; border: 1px solid var(--line); border-radius: 999px; font-size: 10px; }
  .lib-head .lh-sort.on { background: var(--fg); color: var(--bg); border-color: var(--fg); }
}
@supports not (container-type: inline-size) {
  @media (max-width: 640px) {
    .trk { grid-template-columns: 42px minmax(0, 1fr) 44px auto 28px; gap: 6px; padding: 6px 8px; height: 54px; }
    .trk-artist, .trk-album, .trk-key, .trk-time { display: none; }
    .trk-sub .sub-artist { display: inline; }
    .sub-artist + .sub-album::before { content: " \00B7  "; }
    .lib-head { display: flex; overflow-x: auto; padding: 0 8px 8px; }
    .lh-art, .lh-load, .lh-del { display: none; }
    .lib-head .lh-sort { display: inline-flex; flex: none; height: 32px; padding: 0 12px; margin-right: 6px; border: 1px solid var(--line); border-radius: 999px; font-size: 10px; }
    .lib-head .lh-sort.on { background: var(--fg); color: var(--bg); border-color: var(--fg); }
  }
}

@media (max-width: 640px) {
  .trk-btn { width: 32px; height: 36px; }
  .lib-toolbar { gap: 6px; }
  .lib-toolbar .pill-btn span { display: none; }
  .lib-toolbar .pill-btn { width: 36px; padding: 0; }
  .lib-toolbar .select { display: none; } /* the sort chips under the toolbar replace it */
  .lib-search { order: 5; flex-basis: 100%; }
  .lib-title { flex: 1; min-width: 0; }
  .lib-close { width: 36px; height: 36px; }
}

/* ---------- tool panels (AUTOMIX, SAMPLER, TRANSITIONS) ----------
   One panel at a time, in the library's place (the tools view). Each feature fills its own
   .tool-panel; the header shows its name (tablets, computers) or the tool tabs (phones). */
.panels {
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg);
  overflow: hidden;
}
.panel-head { flex: none; display: flex; align-items: center; gap: 8px; padding: 6px 8px 6px 12px; border-bottom: 1px solid var(--line-2); min-width: 0; }
.panel-title { flex: 1 1 auto; margin: 0; min-width: 0; font-weight: 800; font-size: 13px; letter-spacing: .16em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.panel-tabs { flex: 1 1 auto; display: none; gap: 6px; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.panel-tabs::-webkit-scrollbar { display: none; }
.panel-tabs button {
  flex: 1 1 auto;
  min-width: 0;
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--fg-2);
  font-weight: 800;
  font-size: 11px;
  line-height: 1;
  letter-spacing: .08em;
  white-space: nowrap;
  cursor: pointer;
  touch-action: manipulation;
}
.panel-tabs button.on { background: var(--fg); border-color: var(--fg); color: var(--bg); }
.stage[data-mode="narrow"] .panel-title,
.stage[data-mode="short"] .panel-title { display: none; }
.stage[data-mode="narrow"] .panel-tabs,
.stage[data-mode="short"] .panel-tabs { display: flex; }
.stage[data-mode="narrow"] .panel-head { padding-left: 8px; }
.stage[data-mode="short"] .panel-head { padding: 4px 6px; }
.panel-close { flex: none; width: 34px; height: 32px; }
.panel-body { position: relative; flex: 1 1 auto; min-height: 0; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.tool-panel { min-height: 100%; padding: 10px; }
.tool-panel[hidden] { display: none; }
.stage[data-mode="short"] .tool-panel { padding: 6px 8px; }
/* shared bits for the panels' contents */
.tp-sec { margin: 0 0 12px; }
.tp-sec:last-child { margin-bottom: 0; }
.tp-h { margin: 0 0 8px; font-weight: 800; font-size: 11px; letter-spacing: .14em; color: var(--fg-3); }
.tp-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.tp-hint { margin: 6px 0 0; font-size: 12px; line-height: 1.45; color: var(--fg-3); }

/* ---------- drawer (hamburger menu) ---------- */
.scrim {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 50;
  background: rgba(0, 0, 0, .6);
  opacity: 0;
  transition: opacity .22s;
}
.scrim.show { opacity: 1; }
.drawer {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 60;
  width: 380px;
  max-width: 92vw;
  background: var(--bg);
  border-right: 1px solid var(--line);
  transform: translateX(-102%);
  visibility: hidden;
  transition: transform .25s ease, visibility 0s linear .25s;
  display: flex;
  flex-direction: column;
  padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom) env(safe-area-inset-left);
  box-shadow: 12px 0 40px var(--shadow);
}
.drawer.open { transform: none; visibility: visible; transition: transform .25s ease, visibility 0s; }
.drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 52px;
  padding: 0 8px 0 16px;
  border-bottom: 1px solid var(--line-2);
  flex: none;
}
.drawer-body { flex: 1; overflow-y: auto; padding: 6px 14px 30px; overscroll-behavior: contain; }
.menu-group { display: flex; flex-direction: column; padding: 6px 0 10px; border-bottom: 1px solid var(--line-2); }
.menu-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 44px;
  padding: 0 8px;
  border: 0;
  border-radius: 9px;
  background: none;
  color: var(--fg);
  font-weight: 500;
  font-size: 15px;
  line-height: 1.2;
  text-align: left;
  cursor: pointer;
}
.menu-item:hover { background: var(--hover); }
.menu-item:disabled { opacity: .4; cursor: default; }
.menu-item .ico { color: var(--fg-2); }
.menu-item.danger .ico { color: var(--fg); }
.rec-dot { color: var(--rec) !important; }
.menu-item.recording { background: var(--fg); color: var(--bg); }
.menu-item.recording .rec-dot { animation: blink 1s steps(2, start) infinite; }

.menu-sec { padding: 12px 0; border-bottom: 1px solid var(--line-2); }
.menu-sec h3, .menu-sec > summary, .menu-sec h4 {
  margin: 0 0 10px;
  font-weight: 800;
  font-size: 11px;
  line-height: 1;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--fg-2);
}
.menu-sec h4 { margin: 14px 0 6px; display: flex; align-items: center; gap: 8px; }
details.menu-sec > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 30px;
  margin: 0;
}
details.menu-sec > summary::-webkit-details-marker { display: none; }
details.menu-sec > summary::after { content: "+"; font-size: 18px; font-weight: 300; letter-spacing: 0; }
details.menu-sec[open] > summary { margin-bottom: 8px; color: var(--fg); }
details.menu-sec[open] > summary::after { content: "−"; }

.row { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 42px; font-size: 14px; }
.row > span { color: var(--fg-2); }
.row.check { justify-content: flex-start; cursor: pointer; }
.row.check input { width: 20px; height: 20px; margin: 0; flex: none; accent-color: var(--fg); }
.row.check span { color: var(--fg); }
.row input[type="range"] { width: 48%; accent-color: var(--fg); }
.seg { display: flex; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.seg button {
  flex: 1;
  height: 40px;
  border: 0;
  background: none;
  color: var(--fg-2);
  font-weight: 800;
  font-size: 12px;
  line-height: 1;
  letter-spacing: .12em;
  cursor: pointer;
}
.seg button + button { border-left: 1px solid var(--line); }
.seg button.on { background: var(--fg); color: var(--bg); }
.hint { font-size: 12px; color: var(--fg-3); line-height: 1.5; margin: 6px 0; }
.btn-row { display: flex; gap: 8px; flex-wrap: wrap; margin: 8px 0; }
.midi-devices, .midi-maps { list-style: none; margin: 6px 0; padding: 0; }
.midi-devices li { display: flex; align-items: center; gap: 8px; padding: 4px 0; font-size: 13px; }
.dot { width: 8px; height: 8px; border-radius: 50%; border: 1px solid var(--fg-3); flex: none; }
.dot.on { background: var(--fg); border-color: var(--fg); }
.midi-maps li { display: flex; align-items: center; gap: 6px; padding: 6px 0; border-bottom: 1px solid var(--line-2); font-size: 12px; }
.midi-maps li.hint { border: 0; }
.map-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.map-main b { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.map-main small { color: var(--fg-3); font-family: ui-monospace, Menlo, monospace; }
.mini { display: flex; align-items: center; gap: 3px; font-size: 11px; color: var(--fg-2); }
.keys { width: 100%; border-collapse: collapse; font-size: 12px; }
.keys th, .keys td { padding: 5px 4px; text-align: left; border-bottom: 1px solid var(--line-2); }
.keys th { color: var(--fg-3); font-weight: 700; font-size: 10px; letter-spacing: .12em; }
kbd {
  font: 600 11px/1.6 ui-monospace, Menlo, monospace;
  border: 1px solid var(--line);
  border-bottom-width: 2px;
  border-radius: 4px;
  padding: 0 5px;
  white-space: nowrap;
}
/* help: short topics that open one at a time */
.help-intro { margin: 0 0 6px; font-size: 13px; line-height: 1.5; color: var(--fg-2); }
.help-topic { border-top: 1px solid var(--line-2); }
.help-topic > summary {
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 44px;
  padding: 8px 0;
  font-weight: 700;
  font-size: 14px;
  color: var(--fg);
  cursor: pointer;
}
.help-topic > summary::-webkit-details-marker { display: none; }
.help-topic > summary::after { content: "+"; flex: none; font-size: 18px; font-weight: 300; color: var(--fg-3); }
.help-topic[open] > summary::after { content: "−"; }
.help-topic ul, .help-topic ol { margin: 0 0 12px; padding-left: 20px; }
.help-topic li { margin: 6px 0; font-size: 13px; line-height: 1.5; color: var(--fg-2); -webkit-user-select: text; user-select: text; }
.help-topic b { color: var(--fg); font-weight: 700; }
.copyright { color: var(--fg-2); }
.install-steps p { font-size: 13px; color: var(--fg-2); margin: 8px 0; line-height: 1.45; }
#btn-install { margin: 4px 0 8px; }

/* ---------- deck popover ---------- */
.popover {
  position: fixed;
  z-index: 70;
  max-height: calc(100% - 16px);
  overflow-y: auto;
  overscroll-behavior: contain;
  min-width: 250px;
  padding: 6px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 12px 34px var(--shadow);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.popover button {
  min-height: 40px;
  padding: 0 10px;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--fg);
  font-weight: 500;
  font-size: 14px;
  line-height: 1;
  text-align: left;
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
}
.popover button:hover { background: var(--hover); }
.popover button .ico { width: 18px; height: 18px; }
.popover button.toggle::after {
  content: "";
  margin-left: auto;
  width: 32px;
  height: 18px;
  border-radius: 9px;
  border: 1.5px solid var(--fg-3);
  background: radial-gradient(circle at 8px 50%, var(--fg-3) 4px, transparent 4.5px);
}
.popover button.toggle.on::after { background: radial-gradient(circle at 22px 50%, var(--bg) 4px, transparent 4.5px) var(--fg); border-color: var(--fg); }
.popover-row { display: flex; gap: 4px; }
.popover-row button { flex: 1; justify-content: center; padding: 0 4px; border: 1px solid var(--line-2); font-weight: 800; font-size: 12px; letter-spacing: .04em; white-space: nowrap; touch-action: none; }
.popover-row button.pressed { background: var(--fg); color: var(--bg); }

@media (max-height: 520px) {
  #deck-menu { display: grid; grid-template-columns: 1fr 1fr; min-width: 420px; max-width: calc(100vw - 16px); }
  #deck-menu[hidden] { display: none; }
  #deck-menu .popover-row { min-width: 0; }
}

/* ---------- toasts, banners, overlays ---------- */
.toasts {
  position: fixed;
  left: 50%;
  bottom: calc(18px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 90;
  width: 440px;
  max-width: 92vw;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  pointer-events: none;
}
.toast {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: 100%;
  padding: 11px 14px;
  border-radius: 12px;
  background: var(--fg);
  color: var(--bg);
  font-weight: 600;
  font-size: 13px;
  line-height: 1.35;
  box-shadow: 0 10px 30px var(--shadow);
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .2s, transform .2s;
}
.toast.show { opacity: 1; transform: none; }
.toast-error { box-shadow: inset 4px 0 0 var(--rec), 0 10px 30px var(--shadow); }
.toast-btn {
  margin-left: auto;
  border: 1.5px solid var(--bg);
  border-radius: 8px;
  background: none;
  color: var(--bg);
  padding: 6px 10px;
  font-weight: 800;
  font-size: 11px;
  line-height: 1;
  letter-spacing: .08em;
  cursor: pointer;
}

/* MIDI learn panel (floats over the app; ⇅ moves it to the other end of the screen) */
.learn-banner {
  position: fixed;
  top: calc(10px + env(safe-area-inset-top));
  left: 50%;
  transform: translateX(-50%);
  z-index: 80;
  width: 520px;
  max-width: calc(100vw - 16px);
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px 12px;
  border-radius: 14px;
  border: 2px solid var(--fg);
  background: var(--bg);
  color: var(--fg);
  font-size: 13px;
  line-height: 1.35;
  box-shadow: 0 12px 34px var(--shadow);
}
.learn-banner[hidden] { display: none !important; }
.learn-banner.at-bottom { top: auto; bottom: calc(10px + env(safe-area-inset-bottom)); }
.lb-head { display: flex; align-items: center; gap: 8px; min-width: 0; }
.lb-title { font-weight: 800; font-size: 11px; letter-spacing: .16em; }
.lb-step { font: 700 11px/1 ui-monospace, Menlo, monospace; padding: 3px 7px; border-radius: 999px; background: var(--fg); color: var(--bg); }
.lb-activity { flex: 1; min-width: 0; text-align: right; font: 500 11px/1.2 ui-monospace, Menlo, monospace; color: var(--fg-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lb-move { flex: none; font-size: 16px; }
.lb-target { font-weight: 800; font-size: 17px; line-height: 1.2; }
.lb-text { color: var(--fg-2); min-height: 2.7em; }
.lb-row { display: flex; gap: 8px; flex-wrap: wrap; }
.lb-pick { flex: 1 1 auto; max-width: none; width: 100%; }
.lb-btns { justify-content: flex-end; }
.lb-btns .pill-btn { min-width: 64px; }
.midi-activity { font-family: ui-monospace, Menlo, monospace; color: var(--fg-2); }
body.midi-learn [data-ctl] { outline: 1px dashed var(--fg-3); outline-offset: 2px; cursor: crosshair !important; }
body.midi-learn [data-ctl].learn-target { outline: 2px solid var(--fg); outline-offset: 3px; animation: pulse 1s ease-in-out infinite; }
/* (the platter's box clips anything outside it: draw its outlines inside the edge) */
body.midi-learn .platter[data-ctl] { outline-offset: -4px; }
@keyframes pulse { 50% { outline-color: transparent; } }

.drop-overlay {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 85;
  pointer-events: none;
  display: grid;
  place-items: center;
  background: rgba(0, 0, 0, .55);
  border: 3px dashed #fff;
  color: #fff;
  font-size: 18px;
  font-weight: 800;
  letter-spacing: .06em;
}
.drop-overlay div { padding: 14px 20px; background: #000; border-radius: 12px; }

.fatal {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: 24px;
  background: var(--bg);
  text-align: center;
}
.fatal-box { max-width: 440px; }
.fatal-box .brand { font-size: 22px; margin-bottom: 14px; }
.fatal-box p { color: var(--fg-2); line-height: 1.5; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}

/* combined FILTER knob: low-pass to the left, high-pass to the right */
.knob-filter .knob-dial { position: relative; }
.knob-filter .knob-dial::before,
.knob-filter .knob-dial::after {
  position: absolute;
  bottom: -2px;
  font-size: 7px;
  font-weight: 800;
  line-height: 1;
  color: var(--fg-3);
  pointer-events: none;
}
.knob-filter .knob-dial::before { content: "LP"; left: -4px; }
.knob-filter .knob-dial::after { content: "HP"; right: -4px; }
/* headphone CUE MIX: the cued channels to the left, the main mix (program) to the right */
.knob-cuemix .knob-dial { position: relative; }
.knob-cuemix .knob-dial::before,
.knob-cuemix .knob-dial::after {
  position: absolute;
  bottom: -2px;
  font-size: 7px;
  font-weight: 800;
  line-height: 1;
  color: var(--fg-3);
  pointer-events: none;
}
.knob-cuemix .knob-dial::before { content: "CUE"; left: -9px; }
.knob-cuemix .knob-dial::after { content: "PGM"; right: -10px; }

/* ---------- Kaoss-style FX pad ---------- */
.kaoss {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
  min-height: 0;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
}
.kaoss[hidden] { display: none !important; }
.kp-head { display: flex; align-items: center; gap: 8px; flex: none; }
.kp-deck {
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  flex: none;
  border-radius: 7px;
  background: var(--deck-accent);
  color: var(--on-fg);
  font-weight: 900;
  font-size: 14px;
}
.kp-title { flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-weight: 800; font-size: 12px; letter-spacing: .18em; }
.kp-hold { min-width: 0; }
.kp-progs {
  flex: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 6px;
}
.kp-prog {
  height: 34px;
  min-width: 0;
  padding: 0 4px;
  border-radius: 8px;
  border: 1.5px solid var(--line);
  background: transparent;
  color: var(--fg-2);
  font-weight: 800;
  font-size: 10px;
  letter-spacing: .06em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
}
.kp-prog:hover { border-color: var(--fg-3); color: var(--fg); }
.kp-prog.on { background: var(--deck-accent); border-color: var(--deck-accent); color: var(--on-fg); }
.kp-surface-wrap {
  position: relative;
  flex: 1 1 auto;
  min-height: 150px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--panel-2);
  overflow: hidden;
  touch-action: none;
}
.kaoss.active .kp-surface-wrap { border-color: var(--deck-accent); }
.kp-surface {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;
  cursor: crosshair;
  outline-offset: -3px;
}
.kp-axis {
  position: absolute;
  left: 10px;
  max-width: calc(100% - 20px);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  pointer-events: none;
  font: 700 11px/1 ui-monospace, Menlo, monospace;
  letter-spacing: .04em;
  color: var(--fg-2);
}
.kp-axis-y { top: 10px; }
.kp-axis-x { bottom: 10px; }
.kp-hint {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  color: var(--fg-3);
  font-weight: 800;
  font-size: 13px;
  letter-spacing: .24em;
}
.kaoss.active .kp-hint { display: none; }
body.midi-learn .kp-axis { pointer-events: auto; }

/* the pad lives in its deck's PAD panel: programs in a column beside the touch surface, or (narrow
   panels) in one scrolling row above it */
.deck-panel[data-panel="pad"] .kaoss {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: minmax(118px, 30%) minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr);
  grid-template-areas: "head surface" "progs surface";
  gap: 6px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
}
.kp-head { grid-area: head; }
.kp-progs { grid-area: progs; }
.kp-surface-wrap { grid-area: surface; }
.deck-panel[data-panel="pad"] .kp-title { display: none; }
.deck-panel[data-panel="pad"] .kp-hold { flex: 1 1 auto; }
.deck-panel[data-panel="pad"] .kp-close { width: 34px; height: 32px; }
.deck-panel[data-panel="pad"] .kp-progs {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-content: start;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  gap: 4px;
}
.deck-panel[data-panel="pad"] .kp-prog { height: 30px; font-size: 9px; letter-spacing: .02em; }
.deck-panel[data-panel="pad"] .kp-surface-wrap { min-height: 0; }
.stage[data-pw] .deck-panel[data-panel="pad"] .kaoss,
.stage[data-tight] .deck-panel[data-panel="pad"] .kaoss {
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto minmax(0, 1fr);
  grid-template-areas: "progs head" "surface surface";
}
.stage[data-pw] .deck-panel[data-panel="pad"] .kp-deck,
.stage[data-tight] .deck-panel[data-panel="pad"] .kp-deck { display: none; }
.stage[data-pw] .deck-panel[data-panel="pad"] .kp-progs,
.stage[data-tight] .deck-panel[data-panel="pad"] .kp-progs {
  grid-template-columns: none;
  grid-auto-flow: column;
  grid-auto-columns: minmax(64px, max-content);
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.stage[data-pw] .deck-panel[data-panel="pad"] .kp-progs::-webkit-scrollbar,
.stage[data-tight] .deck-panel[data-panel="pad"] .kp-progs::-webkit-scrollbar { display: none; }
.stage[data-pw] .deck-panel[data-panel="pad"] .kp-prog,
.stage[data-tight] .deck-panel[data-panel="pad"] .kp-prog { padding: 0 8px; }
/* short panels: HOLD and one scrolling column of programs beside the touch surface */
.stage[data-tight] .deck-panel[data-panel="pad"] .kaoss {
  grid-template-columns: 84px minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr);
  grid-template-areas: "head surface" "progs surface";
  gap: 4px 6px;
}
.stage[data-tight] .deck-panel[data-panel="pad"] .kp-progs {
  grid-auto-flow: row;
  grid-template-columns: minmax(0, 1fr);
  grid-auto-columns: auto;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  gap: 4px;
}
.stage[data-tight] .deck-panel[data-panel="pad"] .kp-prog { height: 28px; padding: 0 2px; }
.stage[data-tight] .deck-panel[data-panel="pad"] .kp-close { display: none; } /* (the tabs close it) */
.stage[data-tight] .deck-panel[data-panel="pad"] .kp-hold { min-height: 28px; }
.stage[data-tight] .kp-hint { display: none; }
.stage[data-tight] .kp-axis { font-size: 10px; }
.stage[data-tight] .kp-axis-y { top: 6px; }
.stage[data-tight] .kp-axis-x { bottom: 6px; }

/* ---------- fallbacks for browsers without flexbox gap (Safari < 14.1) ---------- */
.no-flexgap .mixer > * + *,
.no-flexgap .deck-pane > * + *,
.no-flexgap .deck-panel > * + * { margin-top: 6px; }
.no-flexgap .hub > * + *,
.no-flexgap .hub-bpm > * + *,
.no-flexgap .deck-ctrl > * + *,
.no-flexgap .deck-tabs > * + *,
.no-flexgap .mixer-channels > * + *,
.no-flexgap .hp-controls > * + *,
.no-flexgap .pad-tools > * + *,
.no-flexgap .kp-head > * + *,
.no-flexgap .lib-toolbar > * + *,
.no-flexgap .trk-load > * + *,
.no-flexgap .deck-stats > * + *,
.no-flexgap .xfader-wrap > * + *,
.no-flexgap .btn-row > * + * { margin-left: 6px; }
.no-flexgap .deck-col-right .deck-ctrl > * + * { margin-left: 0; margin-right: 6px; }
.no-flexgap .ch > * + * { margin-top: 4px; }
.no-flexgap .pitch-btns > * + * { margin-bottom: 4px; }
.no-flexgap .stage[data-mix="wide"] .ch > *,
.no-flexgap .stage[data-mix="compact"] .mixer.eq-open .ch > * { margin: 0; }

/* =====================================================================
   Feature styles. Each feature keeps its rules between its own markers.
   ===================================================================== */

/* ===== feature: pad modes (beat jump, slicer, sampler pads) and the phase meter ===== */
/* the CUES tab's mode row under the pads: CUES | JUMP | SLICER | SAMPLER, then DELETE (hot cues) or
   EDIT (the sampler panel); ui.js sets the mode (data-pm) and hides the other modes' pads */
.pm-tools { min-width: 0; }
.pm-seg {
  flex: 3.4 1 0%;
  min-width: 0;
  display: flex;
  border: 1.5px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
}
.pm-seg button {
  flex: 1 1 0%;
  min-width: 0;
  min-height: 29px;
  padding: 0 2px;
  border: 0;
  background: transparent;
  color: var(--fg-2);
  font-weight: 800;
  font-size: 11px;
  line-height: 1;
  letter-spacing: .08em;
  white-space: nowrap;
  overflow: hidden;
  cursor: pointer;
  touch-action: manipulation;
}
.pm-seg button + button { border-left: 1px solid var(--line); }
.pm-seg button:hover { color: var(--fg); }
.pm-seg button.on { background: var(--deck-accent); color: var(--on-fg); }
.pm-tools .btn { flex: 1 1 0%; }
/* narrow panels: smaller letters, the longer names get more of the row, DELETE / EDIT just what they need */
.stage[data-pw] .pm-seg button { flex: 1 1 auto; padding: 0 2px; font-size: 10px; letter-spacing: .02em; }
.stage[data-pw] .pm-tools .btn { flex: 0 0 auto; padding: 0 8px; font-size: 10px; letter-spacing: .02em; }
.stage[data-pw][data-tight] .pm-seg button { padding: 0 1px; letter-spacing: 0; }
/* … and with height to spare, the mode row on its own row, DELETE / EDIT under it */
.stage[data-pmrows] .pm-tools { flex-wrap: wrap; }
.stage[data-pmrows] .pm-seg,
.stage[data-pmrows] .pm-tools .btn { flex: 1 1 100%; }
.no-flexgap .stage[data-pmrows] .pm-tools > .btn,
.no-flexgap .stage[data-tight="2"] .deck[data-pmpage] .pm-tools > .btn { margin: 6px 0 0; }

/* the CUES tab says which pads it shows (narrow tabs: a little more room for SLICER / SAMPLER) */
.stage[data-pw] .deck-tabs button[data-tab="cues"] { flex-grow: 1.35; }
.stage[data-pw] .deck-tabs button.pm-long { letter-spacing: 0; }
/* paged tabs: a long mode name keeps its page number (1/3) on a second line */
.stage[data-tight] .deck-tabs button.pm-long[data-pg]::after { display: block; margin: 2px 0 0; }
/* narrow and short panels: small tab labels, each tab as wide as its label needs, page numbers under */
.stage[data-pw][data-tight] .deck-tabs button { flex: 1 1 auto; padding: 0 1px; font-size: 9px; letter-spacing: 0; }
.stage[data-pw][data-tight] .deck-tabs button[data-pg]::after { display: block; margin: 2px 0 0; }
.stage[data-pw][data-tight] .deck-tabs .deck-menu-btn { flex: 0 0 30px; padding: 0; }

/* short panels: the mode row is the CUES tab's last page (tap the open tab: 1/2 … 2/2) */
.stage[data-tight] .deck[data-pmpage] [data-panel="cues"] .pads { display: none; }
.stage[data-tight] .deck[data-pmpage] [data-panel="cues"] .pad-tools { display: flex; }
.stage[data-tight="2"] .deck[data-pmpage] .pm-tools { flex-wrap: wrap; max-height: none; }
.stage[data-tight="2"] .deck[data-pmpage] .pm-seg,
.stage[data-tight="2"] .deck[data-pmpage] .pm-tools .btn { flex: 1 1 100%; }
.stage[data-tight="1"][data-pw] .pm-tools .btn { display: none; } /* (DELETE is in the ⋯ menu, EDIT behind TOOLS) */

/* the pads */
.pad-jump .pad-n, .pad-slice .pad-n, .pad-sample .pad-n { white-space: nowrap; }
.pad-jump .pad-t, .pad-slice .pad-t, .pad-sample .pad-t {
  max-width: 100%;
  padding: 0 1px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.stage[data-pw][data-tight] .pad-slice .pad-t { font-size: 8px; letter-spacing: 0; } /* (BAR 12 on the smallest pads) */
.pad-slice.pad-out { opacity: .35; }
.pad-slice.pad-slip { border-style: dashed; border-color: var(--fg); color: var(--fg); } /* (where the song really is) */
.pad-sample .pad-t { text-transform: uppercase; }
.pad-sample.pad-empty { color: var(--fg-3); }
.pads-sample { position: relative; }
.pads-off .pad { opacity: .3; cursor: default; }
.pm-hint {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  max-width: calc(100% - 8px);
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg);
  color: var(--fg-2);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.3;
  text-align: center;
  pointer-events: none;
}
.stage[data-tight] .pm-hint { padding: 2px 8px; font-size: 10px; }

/* the deck's ⋯ menu: PADS  CUES | JUMP | SLICER | SAMPLER */
#deck-menu .dm-label { flex: none; align-self: center; padding: 0 4px 0 8px; font-size: 10px; font-weight: 800; letter-spacing: .12em; color: var(--fg-3); }
#deck-menu .dm-pads button { padding: 0 6px; font-size: 11px; }
#deck-menu .dm-pads button.on { background: var(--fg); color: var(--bg); border-color: var(--fg); }
@media (max-height: 520px) {
  #deck-menu .dm-pads { grid-column: 1 / -1; }
}

/* ===== end: pad modes ===== */


/* ===== feature: sampler panel ===== */
/* The SAMPLER panel: one row of controls, then 8 pads (4 × 2) filling the rest of the panel. The panel
   is pinned to the panel body, so the pads always know their height (it scrolls only if it must). */
.tool-panel.smp:not([hidden]) {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-x: hidden;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.smp-top { flex: none; display: flex; align-items: center; gap: 8px; min-width: 0; margin-bottom: 8px; }
.smp-top .knob { flex: none; }
.smp-top .btn { flex: none; min-height: 36px; padding: 0 12px; white-space: nowrap; }
.smp-cue .ico { width: 16px; height: 16px; fill: currentColor; }
.smp-mode { flex: none; }
.smp-mode button { height: 36px; padding: 0 12px; font-size: 11px; letter-spacing: .08em; white-space: nowrap; }
.smp-top .smp-stop { margin-left: auto; }

.smp-pads {
  flex: 1 1 auto;
  min-height: 120px;
  max-height: 380px;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-template-rows: repeat(2, minmax(56px, 1fr));
  gap: 8px;
}
.smp-cell { position: relative; min-width: 0; min-height: 0; }
.smp-pad {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 14px 6px 8px;
  overflow: hidden;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: transparent;
  color: var(--fg);
  font-weight: 800;
  font-size: 13px;
  line-height: 1.15;
  letter-spacing: .06em;
  text-align: center;
  cursor: pointer;
  touch-action: none;
  transition: background-color .07s, color .07s, border-color .07s, transform .07s;
}
.smp-pad:hover { border-color: var(--fg-3); }
.smp-pad.pressed { transform: scale(.97); }
.smp-pad.on { background: var(--fg); border-color: var(--fg); color: var(--bg); }
.smp-num {
  position: absolute;
  top: 7px;
  left: 9px;
  font: 700 10px/1 ui-monospace, Menlo, monospace;
  letter-spacing: 0;
  color: var(--fg-3);
}
.smp-pad.on .smp-num { color: inherit; opacity: .6; }
/* a dot after the number: your own sound */
.smp-cell.custom .smp-num::after {
  content: "";
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-left: 4px;
  border-radius: 50%;
  background: currentColor;
  vertical-align: 1px;
}
.smp-name {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  max-width: 100%;
  overflow: hidden;
  overflow-wrap: break-word;
  word-break: break-word;
}
.smp-cell.wait .smp-name { opacity: .4; }
.smp-cell.loading .smp-name::after, .smp-cell.loading .smp-ename::after { content: " …"; }
/* how far the sound has played (a CSS animation, started once per tap) */
.smp-bar {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 4px;
  background: currentColor;
  opacity: .45;
  transform: scaleX(0);
  transform-origin: 0 50%;
  visibility: hidden;
}
.smp-pad.on .smp-bar { visibility: visible; }
@keyframes smp-prog-a { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes smp-prog-b { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* EDIT: each pad shows LOAD and RESET instead of playing */
.smp-ebox {
  display: none;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  padding: 5px;
  border: 1.5px dashed var(--fg-3);
  border-radius: 12px;
}
.smp.editing .smp-ebox { display: flex; }
.smp.editing .smp-pad { visibility: hidden; }
.smp-elabel {
  display: block;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  text-align: center;
  font-weight: 800;
  font-size: 11px;
  line-height: 1.1;
  letter-spacing: .05em;
  color: var(--fg-2);
}
.smp-elabel b { margin-right: 5px; font: 700 10px/1 ui-monospace, Menlo, monospace; color: var(--fg-3); }
.smp-ebtns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 5px; }
.smp-ebtns .btn { min-width: 0; min-height: 34px; padding: 0 2px; font-size: 11px; letter-spacing: .05em; }
.smp-ebtns .btn:disabled { opacity: .35; cursor: default; }
.smp-ebtns .btn:disabled:hover { border-color: var(--line); }

.smp-hint { flex: none; margin: 10px 2px 0; }
.stage:not([data-mode="tall"]) .smp-hint { display: none; }

/* tablets in portrait: big square-ish pads */
.stage[data-mode="tall"] .smp-pads { max-height: 360px; gap: 10px; }
.stage[data-mode="tall"] .smp-pad { font-size: 14px; }
.stage[data-mode="tall"] .smp-ebtns .btn,
.stage[data-mode="wide"] .smp-ebtns .btn { min-height: 38px; }

/* phones: one compact row of controls, smaller pads */
.stage[data-mode="narrow"] .tool-panel.smp { padding: 8px; }
.stage[data-mode="narrow"] .smp-top,
.stage[data-mode="short"] .smp-top { gap: 6px; margin-bottom: 6px; }
.stage[data-mode="narrow"] .smp-top { gap: 4px; }
.stage[data-mode="narrow"] .smp-top .btn,
.stage[data-mode="short"] .smp-top .btn { min-height: 34px; padding: 0 8px; font-size: 10px; letter-spacing: .05em; }
.stage[data-mode="narrow"] .smp-mode button,
.stage[data-mode="short"] .smp-mode button { height: 34px; padding: 0 7px; font-size: 10px; letter-spacing: .05em; }
.stage[data-mode="narrow"] .smp-top .btn { padding: 0 7px; letter-spacing: .03em; }
.stage[data-mode="narrow"] .smp-mode button { padding: 0 6px; letter-spacing: .03em; }
.stage[data-mode="narrow"] .smp-cue .ico { display: none; }
.stage[data-mode="narrow"] .smp-pads,
.stage[data-mode="short"] .smp-pads { min-height: 94px; gap: 6px; grid-template-rows: repeat(2, minmax(44px, 1fr)); }
.stage[data-mode="narrow"] .smp-pad,
.stage[data-mode="short"] .smp-pad { padding: 12px 3px 5px; border-radius: 10px; font-size: 11px; letter-spacing: .03em; }
.stage[data-mode="narrow"] .smp-num,
.stage[data-mode="short"] .smp-num { top: 5px; left: 6px; font-size: 9px; }
.stage[data-mode="narrow"] .smp-ebox,
.stage[data-mode="short"] .smp-ebox { gap: 3px; padding: 3px; border-radius: 10px; }
.stage[data-mode="narrow"] .smp-elabel,
.stage[data-mode="short"] .smp-elabel { font-size: 10px; letter-spacing: .02em; }
.stage[data-mode="narrow"] .smp-elabel b,
.stage[data-mode="short"] .smp-elabel b { margin-right: 3px; font-size: 9px; }
.stage[data-mode="narrow"] .smp-ebtns,
.stage[data-mode="short"] .smp-ebtns { gap: 3px; }
.stage[data-mode="narrow"] .smp-ebtns .btn,
.stage[data-mode="short"] .smp-ebtns .btn { min-height: 32px; font-size: 10px; letter-spacing: .02em; border-radius: 7px; }

/* Safari < 14.1 (no flexbox gap) */
.no-flexgap .smp-top > * + * { margin-left: 8px; }
.no-flexgap .smp-top > .smp-stop { margin-left: auto; }
.no-flexgap .smp-ebox > * + * { margin-top: 6px; }
/* ===== end: sampler ===== */


/* ===== feature: library (playlists, history, suggestions, keys, energy) ===== */

/* -- tabs: TRACKS | PLAYLISTS | HISTORY | SUGGESTED, a segmented control in the toolbar.
   Wide screens (iPad landscape, computers) keep one line: the tabs sit after the title. Narrower
   ones give the tabs a row of their own under the toolbar; phones in portrait put them under the
   search, phones in landscape keep everything in one line. The search is what gives way first, so
   the ✕ never ends up on a line of its own. -- */
.lib-search { min-width: 0; }
@media (min-width: 641px) { .stage:not([data-mode="short"]) .lib-search { flex: 1 1 140px; } }
.lib-tabs { flex: none; display: flex; min-width: 0; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.lib-tabs button {
  flex: 1 1 auto;
  min-width: 0;
  height: 32px;
  padding: 0 12px;
  border: 0;
  background: transparent;
  color: var(--fg-2);
  font-weight: 800;
  font-size: 11px;
  line-height: 1;
  letter-spacing: .08em;
  white-space: nowrap;
  cursor: pointer;
  touch-action: manipulation;
}
.lib-tabs button + button { border-left: 1px solid var(--line); }
.lib-tabs button:hover { color: var(--fg); }
.lib-tabs button.on { background: var(--fg); color: var(--bg); }
.lib-tabs button:focus-visible { outline-offset: -3px; }
/* (the folder button keeps only its icon when room is short) */
@media (min-width: 641px) and (max-width: 1239px) {
  .lib-toolbar .lib-folder-btn { width: 36px; padding: 0; }
  .lib-toolbar .lib-folder-btn span { display: none; }
}
@media (max-width: 1119px) {
  .lib-tabs { order: 10; flex: 1 1 100%; }
}
@media (min-width: 641px) and (max-width: 719px) {
  .lib-title > span:not(.lib-count) { display: none; }
}
.stage[data-mode="short"] .lib-tabs { order: 0; flex: none; }
.stage[data-mode="short"] .lib-search { flex: 1 1 0%; }
.stage[data-mode="short"] .lib-toolbar .pill-btn,
.stage[data-mode="short"] .lib-close { flex: none; }
.stage[data-mode="short"] .lib-tabs button { padding: 0 8px; font-size: 10px; letter-spacing: .05em; }
.stage[data-mode="narrow"] .lib-title { display: none; }
.stage[data-mode="narrow"] .lib-search { order: 0; flex: 1 1 0%; }
.stage[data-mode="narrow"] .lib-tabs { order: 10; flex: 1 1 100%; }
.stage[data-mode="narrow"] .lib-tabs button { padding: 0 4px; font-size: 10px; letter-spacing: .05em; }
/* sorting is for TRACKS: the other tabs have their own headers */
.library[data-tab]:not([data-tab="tracks"]) .lib-head { display: none; }

/* -- columns: TRACK | ARTIST | (ALBUM) | BPM | KEY | ENERGY | TIME | LOAD | + | ✕ -- */
.lib-head, .trk { grid-template-columns: 44px minmax(0, 1.6fr) minmax(0, 1fr) 58px 48px 54px 50px auto 32px 32px; }
.trk.trk-pl { grid-template-columns: 44px minmax(0, 1.6fr) minmax(0, 1fr) 58px 48px 54px 50px auto auto; }
.trk.trk-sug { grid-template-columns: 44px minmax(0, 1.6fr) minmax(0, 1fr) 58px 48px 54px 50px auto 32px; }
.lh-main { display: flex; align-items: center; gap: 14px; min-width: 0; }
.lib-head .lh-artist2 { display: none; }
.lh-key { justify-content: center; }
.lh-add { width: 32px; }
.trk .trk-key { text-align: center; }
.trk-nrg { display: flex; justify-content: flex-end; align-items: center; min-width: 0; }
.trk-sub .sub-key, .trk-sub .sub-nrg, .trk-sub .sub-bpm { display: none; }

/* the key: highlighted when it mixes well with the deck that is playing (filled: same or relative key) */
.kpill {
  display: inline-block;
  min-width: 34px;
  padding: 3px 5px;
  border: 1px solid transparent;
  border-radius: 999px;
  text-align: center;
  line-height: 1;
}
.kpill.kmatch { border-color: var(--fg); color: var(--fg); font-weight: 700; }
.kpill.kfull { background: var(--fg); color: var(--bg); }

/* energy: five bars and the number (1–10) */
.nrg { display: inline-flex; align-items: flex-end; gap: 1px; height: 12px; }
.nrg i { display: block; width: 3px; border-radius: 1px; background: var(--line); }
.nrg i:nth-child(1) { height: 4px; }
.nrg i:nth-child(2) { height: 6px; }
.nrg i:nth-child(3) { height: 8px; }
.nrg i:nth-child(4) { height: 10px; }
.nrg i:nth-child(5) { height: 12px; }
.nrg i.on { background: var(--fg-2); }
.nrg-hi i.on { background: var(--fg); }
.nrg b { align-self: center; min-width: 13px; margin-left: 4px; font: 600 11px/1 ui-monospace, Menlo, monospace; color: var(--fg-2); text-align: right; }
.nrg-none { display: inline; height: auto; font: 500 12px/1 ui-monospace, Menlo, monospace; color: var(--fg-2); }

/* + (add to a playlist / the queue) */
.trk-add {
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--fg-2);
  display: grid;
  place-items: center;
  cursor: pointer;
  padding: 0;
}
.trk-add:hover, .trk-add[aria-expanded="true"] { color: var(--fg); background: var(--hover); }
.trk-add .ico { width: 17px; height: 17px; }

/* wide: + ALBUM */
@container lib (min-width: 1000px) {
  .lib-head, .trk { grid-template-columns: 44px minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1fr) 58px 48px 54px 50px auto 32px 32px; }
  .trk.trk-pl { grid-template-columns: 44px minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1fr) 58px 48px 54px 50px auto auto; }
  .trk.trk-sug { grid-template-columns: 44px minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1fr) 58px 48px 54px 50px auto 32px; }
}
/* medium-small (phones in landscape, tablets in portrait): the artist moves under the title */
@container lib (min-width: 641px) and (max-width: 859px) {
  .lib-head, .trk { grid-template-columns: 44px minmax(0, 1fr) 58px 48px 54px 50px auto 32px 32px; }
  .trk.trk-pl { grid-template-columns: 44px minmax(0, 1fr) 58px 48px 54px 50px auto auto; }
  .trk.trk-sug { grid-template-columns: 44px minmax(0, 1fr) 58px 48px 54px 50px auto 32px; }
  .trk-artist, .lib-head .lh-artist { display: none; }
  .lib-head .lh-artist2 { display: inline-flex; }
  .trk-sub .sub-artist { display: inline; }
  .sub-artist + .sub-album::before { content: " \00B7  "; }
}
/* narrow (phones in portrait): TRACK (key · energy · artist) | BPM | LOAD | +; removing is in the + menu */
@container lib (max-width: 640px) {
  .trk { grid-template-columns: 42px minmax(0, 1fr) 44px auto 32px; }
  .trk.trk-pl { grid-template-columns: 42px minmax(0, 1fr) auto auto; }
  .trk.trk-sug { grid-template-columns: 42px minmax(0, 1fr) 44px auto 32px; }
  .trk-nrg, .trk-del[data-del], .lh-add, .trk-pl .trk-bpm { display: none; }
  .trk-sub .sub-key, .trk-sub .sub-nrg { display: inline-block; }
  .trk-pl .trk-sub .sub-bpm { display: inline; }
  .trk-acts { gap: 2px; }
  .trk-acts button { width: 28px; height: 36px; }
  .lib-head .lh-main { flex: none; }
}
@supports not (container-type: inline-size) {
  @media (min-width: 641px) and (max-width: 879px) {
    .lib-head, .trk { grid-template-columns: 44px minmax(0, 1fr) 58px 48px 54px 50px auto 32px 32px; }
    .trk.trk-pl { grid-template-columns: 44px minmax(0, 1fr) 58px 48px 54px 50px auto auto; }
    .trk.trk-sug { grid-template-columns: 44px minmax(0, 1fr) 58px 48px 54px 50px auto 32px; }
    .trk-artist, .lib-head .lh-artist { display: none; }
    .lib-head .lh-artist2 { display: inline-flex; }
    .trk-sub .sub-artist { display: inline; }
    .sub-artist + .sub-album::before { content: " \00B7  "; }
  }
  @media (max-width: 640px) {
    .trk { grid-template-columns: 42px minmax(0, 1fr) 44px auto 32px; }
    .trk.trk-pl { grid-template-columns: 42px minmax(0, 1fr) auto auto; }
    .trk.trk-sug { grid-template-columns: 42px minmax(0, 1fr) 44px auto 32px; }
    .trk-nrg, .trk-del[data-del], .lh-add, .trk-pl .trk-bpm { display: none; }
    .trk-sub .sub-key, .trk-sub .sub-nrg { display: inline-block; }
    .trk-pl .trk-sub .sub-bpm { display: inline; }
    .trk-acts { gap: 2px; }
    .trk-acts button { width: 28px; height: 36px; }
    .lib-head .lh-main { flex: none; }
  }
}
/* (the sub-line's key, energy and BPM) */
.trk-sub .sub-key { min-width: 0; margin-right: 6px; padding: 1px 5px; border-color: var(--line); font: 600 10px/1.2 ui-monospace, Menlo, monospace; vertical-align: 1px; }
.trk-sub .sub-key.kmatch { border-color: var(--fg); }
.sub-nrg { margin-right: 6px; }
.sub-nrg .nrg { vertical-align: -1px; }
.sub-nrg .nrg b { font-size: 10px; min-width: 0; margin-left: 3px; }
.sub-bpm { margin-right: 6px; font: 500 11px/1 ui-monospace, Menlo, monospace; }
.sub-bpm::after { content: " BPM"; }
/* suggestions show their reasons instead */
.trk-sug .trk-sub .sub-key, .trk-sug .trk-sub .sub-nrg, .trk-sug .sub-album { display: none; }

/* -- the + menu -- */
.lib-pop { min-width: 240px; max-width: calc(100vw - 16px); }
.lib-pop-title { padding: 6px 10px 4px; font-size: 12px; color: var(--fg-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 320px; }
.lib-pop button > span { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lib-pop button.in { color: var(--fg-3); cursor: default; }
.lib-pop button.in:hover { background: none; }
.lib-pop .pop-check { flex: none; margin-left: auto; color: var(--fg-2); }
.lib-pop .pop-danger { color: var(--rec); }

/* -- the tab panes -- */
.lib-pane { flex: 1; min-height: 0; overflow-y: auto; padding: 0 0 12px; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
.lp-lists, .lp-tracks, .hs-list { list-style: none; margin: 0; padding: 0; }
.lp-empty { margin: 0; padding: 24px 16px; color: var(--fg-3); text-align: center; font-size: 13px; line-height: 1.5; }
.lp-empty b { color: var(--fg-2); }
.lp-bar {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 8px;
  min-height: 46px;
  padding: 6px 12px;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}
.lp-bar .pill-btn { height: 32px; padding: 0 12px; font-size: 11px; }
.lp-bar-title { flex: 1 1 auto; font-weight: 800; font-size: 11px; letter-spacing: .14em; color: var(--fg-3); }
.lp-bar-name { flex: 1 1 120px; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.lp-bar-name b { font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lp-bar-name small { font-size: 11px; color: var(--fg-3); white-space: nowrap; }
.lp-bar-acts { display: flex; flex-wrap: wrap; gap: 6px; }
.lp-item {
  width: 100%;
  min-height: 54px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 12px;
  border: 0;
  border-bottom: 1px solid var(--line-2);
  background: none;
  color: var(--fg);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.lp-item:hover { background: var(--hover); }
.lp-ico { flex: none; width: 42px; height: 42px; display: grid; place-items: center; border: 1px solid var(--line-2); border-radius: 6px; background: var(--panel-2); color: var(--fg-2); }
.lp-ico .ico { width: 20px; height: 20px; }
.lp-name { flex: 1 1 auto; min-width: 0; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lp-n { flex: none; color: var(--fg-2); font-size: 12px; }
.lp-chev { flex: none; color: var(--fg-3); font-size: 22px; line-height: 1; }
.trk-acts { display: flex; gap: 4px; }
.trk-mv {
  width: 32px;
  height: 34px;
  padding: 0;
  border: 1.5px solid var(--line);
  border-radius: 8px;
  background: transparent;
  color: var(--fg-2);
  font-size: 10px;
  line-height: 1;
  cursor: pointer;
}
.trk-mv:hover:not(:disabled) { border-color: var(--fg); color: var(--fg); }
.trk-mv:disabled { opacity: .3; cursor: default; }
.trk-acts .trk-del { flex: none; }

/* history: one section per set, newest first */
.hs { border-bottom: 1px solid var(--line); }
.hs-head {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px 5px 4px;
  background: var(--bg);
  border-bottom: 1px solid var(--line-2);
}
.hs-head .pill-btn { flex: none; height: 32px; padding: 0 11px; font-size: 11px; }
.hs-toggle {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 42px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 8px;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--fg);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.hs-toggle:hover { background: var(--hover); }
.hs-chev { flex: none; width: 0; height: 0; border-style: solid; border-width: 5px 0 5px 7px; border-color: transparent transparent transparent var(--fg-2); transition: transform .15s; }
.hs-toggle[aria-expanded="true"] .hs-chev { transform: rotate(90deg); }
.hs-txt { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.hs-date { font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hs-n { font-size: 12px; color: var(--fg-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hrow { display: grid; grid-template-columns: 56px 22px minmax(0, 1fr) auto; align-items: center; gap: 8px; min-height: 50px; padding: 4px 12px; border-bottom: 1px solid var(--line-2); }
.hrow:last-child { border-bottom: 0; }
.hrow[data-id] { cursor: pointer; }
.hrow[data-id]:hover { background: var(--hover); }
.hrow.sel { background: var(--hover); box-shadow: inset 3px 0 0 var(--fg); }
.h-time { font: 500 12px/1 ui-monospace, Menlo, monospace; color: var(--fg-2); text-align: right; }
.h-main { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.h-title, .h-sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.h-title { font-weight: 600; }
.h-sub { font-size: 12px; color: var(--fg-2); }
.h-deck { width: 20px; height: 20px; display: grid; place-items: center; border: 1.5px solid var(--fg-3); border-radius: 6px; color: var(--fg-2); font-weight: 800; font-size: 11px; line-height: 1; }
.hs-foot { display: flex; justify-content: center; padding: 16px 12px 4px; }
@container lib (max-width: 640px) {
  .hrow { grid-template-columns: 44px 20px minmax(0, 1fr) auto; gap: 6px; padding: 4px 8px; }
  .hs-head { padding-right: 8px; }
  .hs-head .pill-btn { padding: 0 9px; }
}

/* suggestions: a header line, and the reasons as chips under each title */
.sg-head {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 10px 12px;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  font-size: 13px;
  color: var(--fg-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sg-head b { color: var(--fg); }
.sg-chip {
  display: inline-block;
  margin-right: 4px;
  padding: 1px 6px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font: 600 10px/1.3 ui-monospace, Menlo, monospace;
  color: var(--fg-2);
  vertical-align: 1px;
}
.sg-chip.on { border-color: var(--fg); color: var(--fg); }

/* phones in landscape: the rows are lower */
.stage[data-mode="short"] .lp-item { min-height: 46px; }
.stage[data-mode="short"] .lp-bar, .stage[data-mode="short"] .hs-head { padding-top: 3px; padding-bottom: 3px; min-height: 0; }
.stage[data-mode="short"] .sg-head { padding: 7px 12px; }
.stage[data-mode="short"] .hrow { min-height: 44px; }

/* (Safari before 14.1: no gap in flex layouts) */
.no-flexgap .lp-bar > * + *,
.no-flexgap .lp-bar-acts > * + *,
.no-flexgap .hs-head > * + *,
.no-flexgap .trk-acts > * + * { margin-left: 6px; }
.no-flexgap .lp-item > * + *,
.no-flexgap .hs-toggle > * + * { margin-left: 10px; }
.no-flexgap .lh-main > * + * { margin-left: 14px; }
.no-flexgap .nrg i + i { margin-left: 1px; }

/* ANALYZE (shows only while there are tracks to analyse) */
.lib-analyze .an-count { font: 600 10px/1 ui-monospace, Menlo, monospace; letter-spacing: 0; color: var(--fg-2); }
.lib-analyze.on { background: var(--fg); border-color: var(--fg); color: var(--bg); }
.lib-analyze.on .an-count { color: inherit; opacity: .75; }
@media (max-width: 640px) {
  .lib-toolbar .lib-analyze { width: auto; padding: 0 8px; }
}
.stage[data-mode="short"] .lib-toolbar .lib-analyze { width: auto; padding: 0 6px; }
/* ===== end: library ===== */


/* ===== feature: track analysis ===== */
/* the deck's key: in the deck colour with a dot at its corner when it mixes well with the other deck's key */
.deck-key .v { position: relative; }
.deck-key.key-match .v { color: var(--deck-accent); }
.deck-key.key-match .v::after {
  content: "";
  position: absolute;
  top: 0;
  left: 100%;
  width: 5px;
  height: 5px;
  margin-left: 2px;
  border-radius: 50%;
  background: var(--deck-accent);
}
/* ===== end: track analysis ===== */


/* ===== feature: automix, transitions and EQ kills ===== */
/* EQ kills: the HI / MID / LOW captions under the mixer knobs are buttons. Their tap area is the whole
   width of the knob along the caption's row (a few px more than the text), drawn under the knob (z-index
   inside the knob's own stacking context), so the dial keeps every touch on its circle and nothing moves.
   Lit (and struck through) while the band is cut; the dial dims, since its value comes back with the kill off. */
.ch .knob-host[data-k="hi"], .ch .knob-host[data-k="mid"], .ch .knob-host[data-k="low"] { position: relative; z-index: 0; }
.knob-label.kill-tap { cursor: pointer; border-radius: 3px; }
.knob-label.kill-tap::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 0;
  right: 0;
  bottom: -1px;
  height: calc(1em + 4px);
}
/* (the wide mixer has a little room under the captions; on a phone held upright, plenty) */
.stage[data-mix="wide"] .knob-label.kill-tap::after { bottom: -4px; height: calc(1em + 7px); }
.stage[data-mode="narrow"][data-mix="wide"] .knob-label.kill-tap::after { bottom: -10px; height: calc(1em + 13px); }
.knob-label.kill-tap:hover { color: var(--fg); }
.knob.killed .knob-label {
  background: var(--deck-accent);
  color: var(--on-fg);
  box-shadow: 0 0 0 2px var(--deck-accent);
  text-decoration: line-through;
  text-decoration-thickness: 1.5px;
}
.knob.killed .knob-dial { opacity: .4; }

/* ---------- TRANSITIONS panel: LENGTH, then DECK A and DECK B side by side (stacked on phones) ---------- */
.tx-top { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; min-width: 0; }
.tx-top .tp-h { margin: 0; }
.tx-len { flex: none; }
.tx-len button { width: 46px; height: 34px; font-size: 12px; letter-spacing: .04em; }
.tx-hint { flex: 1 1 auto; min-width: 0; margin: 0 0 0 8px; font-size: 12px; line-height: 1.3; color: var(--fg-3); text-align: right; }
.tx-decks { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px 16px; }
.tx-deck { min-width: 0; }
.tx-head { color: var(--deck-accent); margin-bottom: 6px; }
.tx-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; }
.tx-grid .btn {
  position: relative;
  min-width: 0;
  min-height: 40px;
  padding: 2px 3px;
  overflow: hidden;
  font-size: 11px;
  line-height: 1.1;
  letter-spacing: .05em;
  white-space: normal;
  flex-direction: column;
  gap: 1px;
}
.tx-btn.dim:not(.on) { color: var(--fg-3); border-color: var(--line-2); }
.tx-grid .btn.on { background: var(--deck-accent); border-color: var(--deck-accent); color: var(--on-fg); }
/* how far the running move has got */
.tx-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  background: currentColor;
  opacity: .6;
  transform: scaleX(0);
  transform-origin: 0 50%;
  pointer-events: none;
}
.tx-kill { border-style: dashed; }
.tx-kill small { font-size: 8px; font-weight: 800; letter-spacing: .12em; opacity: .75; }
.tx-grid .tx-kill.on { border-style: solid; }
.stage[data-mode="narrow"] .tx-decks { grid-template-columns: minmax(0, 1fr); }
.stage[data-mode="narrow"] .tx-hint,
.stage[data-mode="short"] .tx-hint { display: none; }
.stage[data-mode="short"] .tx-top { margin-bottom: 6px; }
.stage[data-mode="short"] .tx-decks { gap: 6px 10px; }
.stage[data-mode="short"] .tx-head { margin-bottom: 4px; }
.stage[data-mode="short"] .tx-grid { gap: 5px; }
.stage[data-mode="short"] .tx-grid .btn { min-height: 38px; font-size: 10px; letter-spacing: .03em; }
.stage[data-mode="narrow"] .tx-grid .btn { font-size: 10px; letter-spacing: .03em; }
.stage[data-mode="tall"] .tx-grid .btn { font-size: 10px; letter-spacing: .03em; }

/* ---------- AUTOMIX panel: controls and the queue side by side (stacked on phones in portrait) ---------- */
.tool-panel.am:not([hidden]) {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: 14px;
  overflow: hidden;
}
.am-main, .am-q { min-width: 0; min-height: 0; }
.am-main { display: flex; flex-direction: column; gap: 6px; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; }
.am-q { display: flex; flex-direction: column; }
.am-top { display: flex; gap: 8px; flex: none; }
.am-start { flex: 1 1 auto; min-height: 44px; font-size: 13px; }
.am-skip { flex: none; min-height: 44px; min-width: 76px; }
.am-skip:disabled { opacity: .4; cursor: default; }
.am-now { flex: none; display: flex; flex-direction: column; gap: 5px; }
.am-line { display: flex; align-items: center; gap: 6px; min-width: 0; font-size: 13px; line-height: 1.25; }
.am-cap { flex: none; width: 84px; font-weight: 800; font-size: 10px; letter-spacing: .1em; white-space: nowrap; color: var(--fg-3); }
.am-deck {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 16px;
  height: 16px;
  border: 1.5px solid currentColor;
  border-radius: 5px;
  font-weight: 900;
  font-size: 10px;
  line-height: 1;
}
.am-deck[data-index] { color: var(--deck-accent); }
.am-text { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--fg); }
.am-prog { display: flex; align-items: center; gap: 8px; padding-left: 90px; }
.am-track { position: relative; flex: 1 1 auto; height: 4px; border-radius: 2px; background: var(--line-2); overflow: hidden; }
.am-bar { position: absolute; top: 0; bottom: 0; left: 0; right: 0; background: var(--fg-2); transform: scaleX(0); transform-origin: 0 50%; }
.am-bar.mixing { background: var(--fg); }
.am-when { flex: none; min-width: 84px; text-align: right; font-weight: 700; font-size: 11px; letter-spacing: .06em; color: var(--fg-2); }
.am-set { flex: none; display: flex; flex-direction: column; gap: 5px; }
.am-set2 { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 8px; }
.am-lenwrap { display: flex; align-items: center; gap: 6px; }
.am-h { margin: 0; }
/* segmented buttons that may wrap into two rows (the dividers are the grid's gaps) */
.am-seg {
  display: grid;
  gap: 1px;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  background: var(--line);
}
.am-seg button {
  min-width: 0;
  height: 36px;
  padding: 0 4px;
  border: 0;
  background: var(--bg);
  color: var(--fg-2);
  font-weight: 800;
  font-size: 11px;
  line-height: 1.1;
  letter-spacing: .06em;
  cursor: pointer;
}
.am-seg button.on { background: var(--fg); color: var(--bg); }
.am-style { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.am-len { grid-template-columns: repeat(3, 44px); }
.am-sync, .am-xf { flex: none; min-height: 38px; font-size: 11px; }
.am-lenwrap.off { opacity: .4; }
.am-xftime { flex: 1 1 150px; display: flex; align-items: center; gap: 6px; min-width: 0; }
.am-xfrange { flex: 1 1 auto; min-width: 60px; margin: 0; accent-color: var(--fg); }
.am-xfval { flex: none; min-width: 2.6em; text-align: right; font-weight: 700; font-size: 11px; letter-spacing: .06em; }

.am-qhead { flex: none; display: flex; align-items: center; flex-wrap: wrap; gap: 6px 8px; margin-bottom: 6px; }
.am-qtitle { margin: 0; flex: 1 1 auto; min-width: 90px; }
.am-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.am-acts .pill-btn { height: 32px; padding: 0 10px; font-size: 11px; }
.am-addpl { height: 32px; max-width: 170px; font-size: 11px; font-weight: 700; letter-spacing: .06em; }
.am-list {
  flex: 1 1 auto;
  min-height: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  border-top: 1px solid var(--line-2);
}
.am-row { display: flex; align-items: center; gap: 8px; min-height: 40px; padding: 2px 0; border-bottom: 1px solid var(--line-2); }
.am-row.missing .am-title { color: var(--fg-3); font-style: italic; }
.am-num { flex: none; width: 22px; text-align: right; font-size: 11px; color: var(--fg-3); }
.am-row.next .am-num { color: var(--fg); font-weight: 800; }
.am-main2 { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.am-title, .am-artist { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.am-title { font-size: 13px; line-height: 1.25; }
.am-artist { font-size: 11px; line-height: 1.25; color: var(--fg-3); }
.am-on { font-weight: 800; color: var(--fg-2); }
.am-bpm, .am-key { flex: none; font-size: 11px; color: var(--fg-2); text-align: right; }
.am-bpm { width: 28px; }
.am-key { width: 30px; }
.am-btns { flex: none; display: flex; }
.am-mv { width: 32px; height: 34px; border-radius: 8px; font-size: 12px; color: var(--fg-2); }
.am-mv:disabled { opacity: .25; cursor: default; }
.am-mv:disabled:hover { background: transparent; }
.am-rm { font-size: 20px; font-weight: 300; }
.am-empty { margin: 4px 0 0; }

/* phones in portrait: one column, the whole panel scrolls */
.stage[data-mode="narrow"] .tool-panel.am:not([hidden]) { position: static; display: block; min-height: 100%; overflow: visible; }
.stage[data-mode="narrow"] .am-main { overflow: visible; }
.stage[data-mode="narrow"] .am-q { margin-top: 14px; }
.stage[data-mode="narrow"] .am-list { overflow: visible; }
.stage[data-mode="narrow"] .am-style { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.stage[data-mode="narrow"] .am-bpm, .stage[data-mode="narrow"] .am-key { width: auto; min-width: 22px; }
/* phones on their side: a little tighter */
.stage[data-mode="short"] .tool-panel.am:not([hidden]) { gap: 10px; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.stage[data-mode="short"] .am-main { gap: 4px; }
.stage[data-mode="short"] .am-now { gap: 2px; }
.stage[data-mode="short"] .am-start, .stage[data-mode="short"] .am-skip { min-height: 36px; }
.stage[data-mode="short"] .am-style { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.stage[data-mode="short"] .am-seg button { height: 32px; font-size: 10px; letter-spacing: .03em; }
.stage[data-mode="short"] .am-sync, .stage[data-mode="short"] .am-xf { min-height: 34px; }
.stage[data-mode="short"] .am-line { font-size: 12px; }
.stage[data-mode="short"] .am-key { display: none; }
.stage[data-mode="short"] .am-set:not(.am-set2) > .am-h { display: none; } /* (the style names say it) */
.stage[data-mode="short"] .am-lenwrap .am-h:last-child { display: none; }
.stage[data-mode="short"] .am-len { grid-template-columns: repeat(3, 38px); }
/* tablets on their side with the browser's bars showing (iPad mini in Safari): a little tighter too */
@media (max-height: 680px) {
  .stage[data-mode="wide"] .am-start, .stage[data-mode="wide"] .am-skip { min-height: 38px; }
  .stage[data-mode="wide"] .am-now { gap: 3px; }
}
/* tablets in portrait (narrower columns) */
.stage[data-mode="tall"] .am-style { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* ===== end: automix and transitions ===== */


/* ===== feature: shortcuts, backup, recording, tour ===== */
/* keyboard shortcut editor (Menu → Keyboard shortcuts) */
.sc-list { margin: 4px 0 6px; }
.sc-group + .sc-group { margin-top: 4px; }
.sc-group h4 {
  margin: 14px 0 4px;
  font-weight: 800;
  font-size: 11px;
  line-height: 1;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--fg-3);
}
.sc-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 40px;
  border-bottom: 1px solid var(--line-2);
}
.sc-label { flex: 1; min-width: 0; font-size: 13px; color: var(--fg-2); }
.sc-key {
  flex: none;
  min-width: 48px;
  max-width: 55%;
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-bottom-width: 2px;
  border-radius: 6px;
  background: transparent;
  color: var(--fg);
  font: 600 12px/1 ui-monospace, Menlo, monospace;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
}
.sc-key:hover { border-color: var(--fg-3); }
.sc-key.unset { color: var(--fg-3); }
.sc-key.capturing {
  background: var(--fg);
  border-color: var(--fg);
  color: var(--bg);
  font-family: inherit;
  font-weight: 700;
  animation: sc-blink 1s ease-in-out infinite;
}
@keyframes sc-blink { 50% { opacity: .7; } }
.tour-row { margin: 2px 0 10px; }

/* first-run tour: the dimmed app with a spotlight on one part, and the card */
.tour {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 88;
  opacity: 0;
  transition: opacity .2s;
}
.tour.show { opacity: 1; }
.tour-safe {
  position: absolute;
  top: 0;
  left: 0;
  visibility: hidden;
  pointer-events: none;
  padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
}
.tour-spot {
  position: absolute;
  border-radius: 12px;
  box-shadow: 0 0 0 2px var(--fg), 0 0 0 9999px var(--overlay);
  transition: left .25s ease, top .25s ease, width .25s ease, height .25s ease;
  pointer-events: none;
}
.tour-spot.tour-spot-none { box-shadow: 0 0 0 9999px var(--overlay); }
.tour-card {
  position: absolute;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 14px 12px;
  border: 2px solid var(--fg);
  border-radius: 14px;
  background: var(--bg);
  color: var(--fg);
  box-shadow: 0 12px 34px var(--shadow);
  transition: left .25s ease, top .25s ease;
}
.tour-head { display: flex; align-items: center; gap: 8px; min-width: 0; }
.tour-step { flex: none; font: 700 11px/1 ui-monospace, Menlo, monospace; padding: 3px 7px; border-radius: 999px; background: var(--fg); color: var(--bg); }
.tour-title { min-width: 0; font-weight: 800; font-size: 16px; line-height: 1.2; }
.tour-text { margin: 0; font-size: 13px; line-height: 1.45; color: var(--fg-2); }
.tour-btns { display: flex; align-items: center; gap: 8px; margin-top: 2px; }
.tour-btns .tour-skip { margin-right: auto; border-color: transparent; color: var(--fg-3); padding: 0 6px; }
.tour-btns .tour-next { min-width: 76px; }
@media (max-height: 420px) {
  .tour-card { gap: 6px; padding: 10px 12px; }
  .tour-text { font-size: 12px; line-height: 1.35; }
}
@media (prefers-reduced-motion: reduce) {
  .tour, .tour-spot, .tour-card { transition: none; }
  .sc-key.capturing { animation: none; }
}
.no-flexgap .tour-card > * + * { margin-top: 8px; }
.no-flexgap .tour-head > * + *,
.no-flexgap .tour-btns > * + *,
.no-flexgap .sc-row > * + * { margin-left: 8px; }

/* ===== end: shortcuts, backup, recording, tour ===== */
