/* MIX-ED — DJ Studio · DDJ-FLX4 photo-overlay skin (v22)
   ----------------------------------------------------------------------
   The chassis is a single image (images/flx4-top.png, 2000×1132).
   Invisible hotspots are absolutely positioned over it in % coordinates
   (inline styles in simulator-flx4.html — measured off the image pixels).
   This file paints only the MOVING parts: knob pointers, fader caps,
   jog rotor, VU bars, PLAY/CUE/pad glows, BPM + pitch readouts.

   Self-contained: simulator.css is NOT loaded on this page, so the
   handful of engine classes it needs (.status, .fader-cap, .jog-rotor,
   .bpm-label, .bpm-pulse, .dragover) are defined here.

   Alignment debugging: add class "debug-hotspots" to <body> to outline
   every hotspot in magenta.
*/

/* One column for the whole page: the header (logo to the light/dark
   button), the title, the text and the controller all line up at 1240 px
   of content (1288 with the 24 px padding either side) */
.flx4-skin main { max-width: 1288px; }
.flx4-skin .site-header .inner { max-width: 1288px; }

/* ───────────────────────── Screens panel ───────────────────────── */
/* Placeholder styling — Daniel's Serato-style screen replaces this. */

/* The screens and the controller share one box (.flx4-booth), and the
   screens sit in from its sides by the photo's white edge (x 34-1963 of
   2000: 1.7% left, 1.8% right), so they're exactly as wide as the
   controller's body. Plain % margins: Safari dropped the calc(min()) width
   this used to have, and the screens went full width. */
/* The photo has a white edge (clipped off) 1.7% / 1.8% wide, so the booth
   reaches that far past the column on each side: then the controller's
   body and the screens are exactly the column's width */
.flx4-skin .flx4-booth { width: auto; margin: 0 -1.865% 0 -1.762%; }
.flx4-skin .flx4-screens-panel {
  box-sizing: border-box;
  width: auto;
  margin: 0 1.8% 10px 1.7%;
  padding: 12px;
  background: #101014;
  border: 1px solid #26262e;
  border-radius: 14px;
}
/* Top row of the screens: REC, the MIX-ED wordmark, FULL SCREEN */
.flx4-skin .flx4-topbar { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; margin: -4px 0 8px; }
.flx4-skin .flx4-topbar .tb-right { justify-self: end; }
.flx4-skin .rec-btn {
  display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 9px;
  border: 1px solid #4a4a56; border-radius: 6px; background: transparent; color: #e4e4ea;
  font: 800 11px/1 system-ui, sans-serif; letter-spacing: .08em; font-variant-numeric: tabular-nums; cursor: pointer;
}
.flx4-skin .rec-btn i { width: 9px; height: 9px; border-radius: 50%; background: #ef4444; }
.flx4-skin .rec-btn.on { border-color: #ef4444; background: rgba(239,68,68,.16); color: #fff; }
.flx4-skin .rec-btn.on i { border-radius: 2px; animation: rec-blink 1s steps(2, start) infinite; }   /* stop square, blinking */
@keyframes rec-blink { to { visibility: hidden; } }
/* FULL SCREEN: under the controller on the left, as on Classroom's boards
   (58 px, dark, white corner brackets, pink on hover). In full screen it
   stays in the bottom-left corner, out of the way of the controller. */
.flx4-skin .booth-foot { display: flex; margin: 10px 1.8% 0 1.7%; }
.flx4-skin .booth-foot .booth-fs, body > .booth-foot .booth-fs { flex: none; }
.flx4-skin .booth-fs {
  width: 58px; height: 58px; padding: 0; display: grid; place-items: center; cursor: pointer;
  border-radius: 14px; border: 2px solid rgba(255,255,255,.4); background: rgba(10,6,16,.72); color: #fff;
  transition: background-color .15s, transform .15s;
}
.flx4-skin .booth-fs svg { width: 30px; height: 30px; display: block; }
@media (hover: hover) { .flx4-skin .booth-fs:hover { background-color: #e43a6c; transform: scale(1.06); } }
body.booth-full .flx4-booth .booth-foot { position: fixed; left: 16px; bottom: 16px; margin: 0; z-index: 910; }
.flx4-skin .tb-right { display: flex; gap: 6px; }
.flx4-skin .explain-btn {
  display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 8px 0 6px;
  border: 1px solid #4a4a56; border-radius: 6px; background: transparent; color: #e4e4ea;
  font: 800 11px/1 system-ui, sans-serif; letter-spacing: .08em; cursor: pointer;
}
.flx4-skin .explain-btn svg { width: 15px; height: 15px; display: block; }
/* BPM on / off: amber with the eye crossed out while the numbers are hidden */
.flx4-skin .bpm-toggle {
  display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 8px 0 6px;
  border: 1px solid #4a4a56; border-radius: 6px; background: transparent; color: #e4e4ea;
  font: 800 11px/1 system-ui, sans-serif; letter-spacing: .08em; cursor: pointer;
}
.flx4-skin .bpm-toggle svg { width: 15px; height: 15px; display: block; }
.flx4-skin .bpm-toggle .eye-off { display: none; }
.flx4-skin .bpm-toggle.on { background: #f59e0b; border-color: #f59e0b; color: #111; }
.flx4-skin .bpm-toggle.on .eye-off { display: inline; }
.flx4-skin .bpm-toggle.on span { text-decoration: line-through; }
@media (hover: hover) { .flx4-skin .bpm-toggle:not(.on):hover { border-color: #f59e0b; color: #fff; } }
.flx4-skin .explain-btn.on { background: #38bdf8; border-color: #38bdf8; color: #0b0b0e; }
@media (hover: hover) { .flx4-skin .explain-btn:not(.on):hover { border-color: #38bdf8; color: #fff; } }
@media (hover: hover) { .flx4-skin .rec-btn:hover { border-color: #ff914d; color: #fff; } }
/* After REC: "Your mixes", every recording this session (simulator.js
   renderRecList): listen back, download, send to Showcase; a reminder while
   any isn't saved, and a count on REC */
.flx4-skin .rec-result { margin: 0 0 10px; padding: 8px 10px; border: 1px solid #3a2a2a; border-radius: 10px; background: #1a1416; color: #f2f2f6; font: 700 12px/1.3 system-ui, sans-serif; }
.flx4-skin .rec-result[hidden] { display: none; }
.flx4-skin .rec-result .rr-head { display: flex; align-items: center; gap: 8px; }
.flx4-skin .rec-result .rr-sub { color: #a8a8b4; font-weight: 600; }
.flx4-skin .rec-result .rr-x { margin-left: auto; border: 1px solid #4a4a56; border-radius: 5px; background: transparent; color: #c4c4ce; font-size: 12px; line-height: 1; padding: 3px 7px; cursor: pointer; }
.flx4-skin .rec-result .rr-warn { margin: 6px 0 0; padding: 6px 8px; border-radius: 6px; background: rgba(245,158,11,.14); border: 1px solid rgba(245,158,11,.55); color: #fcd34d; font-weight: 700; }
.flx4-skin .rec-result .rr-items { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.flx4-skin .rec-result.collapsed .rr-items { display: none; }
.flx4-skin .rec-result .rr-item { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.flx4-skin .rec-result .rr-name { min-width: 120px; }
.flx4-skin .rec-result .rr-name small { display: block; color: #a8a8b4; font-weight: 600; max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.flx4-skin .rec-result audio { height: 30px; flex: 1 1 200px; min-width: 0; }
.flx4-skin .rec-result .rr-dl, .flx4-skin .rec-result .rr-sc {
  padding: 6px 11px; border-radius: 7px; border: 0; cursor: pointer; text-decoration: none;
  font: 800 12px/1 system-ui, sans-serif; white-space: nowrap;
}
.flx4-skin .rec-result .rr-dl { background: #ef4444; color: #fff; }
.flx4-skin .rec-result .rr-sc { background: #3d5fec; color: #fff; }
.flx4-skin .rec-result .rr-dl.done, .flx4-skin .rec-result .rr-sc.done { background: #16a34a; }
.flx4-skin .rec-result .rr-sc:disabled { cursor: default; opacity: .9; }
.flx4-skin .rec-result .rr-err { flex-basis: 100%; color: #fca5a5; font-weight: 600; }
.flx4-skin .rec-result .rr-msg { margin-right: 8px; }
/* REC shows how many mixes aren't saved yet */
.flx4-skin .rec-btn { position: relative; }
.flx4-skin .rec-btn[data-unsaved]:not([data-unsaved=""])::after {
  content: attr(data-unsaved); position: absolute; top: -7px; right: -7px; min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 8px; background: #f59e0b; color: #111; font: 800 10px/16px system-ui, sans-serif; text-align: center;
}
/* MIX-ED wordmark, top middle — same blue-to-pink as the logo on the jog wheels */
.flx4-skin .flx4-brand {
  width: fit-content;
  margin: 0 auto;
  font: 800 15px/1.1 system-ui, -apple-system, "Segoe UI", sans-serif;
  letter-spacing: .06em;
  background: linear-gradient(90deg, #8c9ff0 0%, #8c9ff0 48%, #b88eec 68%, #e48ed6 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  user-select: none;
}
.flx4-skin .flx4-displays {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);   /* minmax: the screens shrink to the panel, never push out of it */
  gap: 12px;
}
.flx4-skin .flx4-display {
  background: #16161c;
  border: 1px solid #2c2c36;
  border-radius: 10px;
  padding: 10px 12px;
  min-height: 96px;
}
.flx4-skin .flx4-display.dragover {
  border-color: #ff914d;
  box-shadow: 0 0 0 2px rgba(255,145,77,.35);
}
.flx4-skin .deck-screen-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  letter-spacing: .08em;
  color: #c4c4ce;
  margin-bottom: 4px;
}
.flx4-skin .deck-screen-header .hdr-right { display: flex; align-items: center; gap: 8px; }
/* each part keeps to one line; on a narrow screen the parts go onto a second line */
.flx4-skin .deck-screen-header { flex-wrap: wrap; row-gap: 4px; }
.flx4-skin .deck-screen-header > * { flex: none; white-space: nowrap; }
/* MASTER TEMPO toggle: keep the key when the tempo changes (red when on, as in rekordbox) */
.flx4-skin .mt-btn,
.flx4-skin .scr-btn {
  font: 700 9px/1 system-ui, sans-serif;
  letter-spacing: .08em;
  padding: 3px 6px;
  border: 1px solid #6a6a78;
  border-radius: 3px;
  background: transparent;
  color: #d4d4dc;
  cursor: pointer;
}
.flx4-skin .mt-btn.on { background: #e5484d; border-color: #e5484d; color: #fff; }
@media (hover: hover) { .flx4-skin .mt-btn:hover, .flx4-skin .scr-btn:hover { border-color: #ff914d; color: #f2f2f6; } }
/* Under MT: the BPM, then back to the start, play / pause, eject and SYNC */
.flx4-skin .deck-row { display: flex; align-items: flex-start; gap: 10px; }
.flx4-skin .deck-names { flex: 1; min-width: 0; }
.flx4-skin .deck-tools { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.flx4-skin .scr-bpm {
  color: #f2f2f6;
  font: 700 15px/1 system-ui, sans-serif;
  font-variant-numeric: tabular-nums;
}
.flx4-skin .scr-bpm .bpm-label { font-size: 9px; letter-spacing: .08em; color: #c4c4ce; }
.flx4-skin .scr-bpm { cursor: pointer; border-radius: 4px; padding: 1px 3px; margin: -1px -3px; }
@media (hover: hover) { .flx4-skin .scr-bpm:hover { background: rgba(255,145,77,.16); } }
/* Click the BPM: the tempo box */
.flx4-skin .deck-tools { position: relative; }
.flx4-skin .bpm-pop {
  position: absolute; top: 22px; right: 0; z-index: 20; width: 210px; padding: 10px;
  background: #1d1d25; border: 1px solid #ff914d; border-radius: 10px; box-shadow: 0 12px 30px rgba(0,0,0,.5);
  color: #f2f2f6; font: 700 12px/1.2 system-ui, sans-serif; text-align: left;
}
.flx4-skin .bpm-pop[hidden] { display: none; }
.flx4-skin .bp-head { display: flex; justify-content: space-between; align-items: center; font-size: 10px; letter-spacing: .1em; color: #c4c4ce; }
.flx4-skin .bp-x { border: 0; background: transparent; color: #c4c4ce; font-size: 18px; line-height: 1; cursor: pointer; padding: 0 2px; }
.flx4-skin .bp-now { margin: 4px 0 8px; font-size: 11px; color: #c4c4ce; font-variant-numeric: tabular-nums; }
.flx4-skin .bp-now b { font-size: 22px; color: #fff; }
.flx4-skin .bp-steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; }
.flx4-skin .bp-steps button, .flx4-skin .bp-reset {
  padding: 7px 0; border: 1px solid #4a4a56; border-radius: 6px; background: #26262f; color: #f2f2f6;
  font: 800 12px/1 system-ui, sans-serif; font-variant-numeric: tabular-nums; cursor: pointer;
}
.flx4-skin .bp-reset { width: 100%; margin-top: 6px; font-weight: 700; color: #d4d4dc; }
@media (hover: hover) { .flx4-skin .bp-steps button:hover, .flx4-skin .bp-reset:hover { border-color: #ff914d; } }
.flx4-skin .bp-note { margin-top: 6px; font-size: 11px; font-weight: 600; color: #facc15; }
.flx4-skin .bp-note:empty { display: none; }
.flx4-skin .bpm-pop.empty .bp-steps, .flx4-skin .bpm-pop.empty .bp-reset { opacity: .4; pointer-events: none; }
.flx4-skin .deck-tool-row { display: flex; gap: 4px; }
.flx4-skin .scr-btn.icon-btn { display: inline-flex; align-items: center; padding: 3px 5px; }   /* back to the start, eject */
.flx4-skin .scr-btn.icon-btn svg { display: block; }
.flx4-skin .scr-btn.play-btn.on { background: #16a34a; border-color: #4ade80; color: #fff; }   /* playing */
.flx4-skin .scr-btn svg { fill: currentColor; vertical-align: -0.5px; }
.flx4-skin .scr-btn.on { background: #3d5fec; border-color: #3d5fec; color: #fff; }       /* synced */
.flx4-skin .scr-btn.warn { border-color: #facc15; color: #facc15; }                        /* LOAD BOTH / TOO FAR */
/* Beat FX display under the decks: effect, beat length, channel, level, on/off */
.flx4-skin .bfx-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin-top: 10px;
  padding: 7px 12px;
  border: 1px solid #2c2c36;
  border-radius: 10px;
  background: #16161c;
  color: #c8c8d2;
  font: 600 12px/1.2 system-ui, sans-serif;
  font-variant-numeric: tabular-nums;
}
.flx4-skin .bfx-lbl { font-size: 9px; font-weight: 700; letter-spacing: .1em; color: #c4c4ce; }
.flx4-skin .bfx-name { font-weight: 800; font-size: 14px; letter-spacing: .06em; color: #fff; width: 92px; text-align: center; }
/* fixed widths, so nothing on the line shifts when the effect or BEAT changes */
.flx4-skin .bfx-beat { width: 150px; text-align: center; white-space: nowrap; }
.flx4-skin .bfx-chan { display: flex; gap: 3px; }
.flx4-skin .bfx-chan b { padding: 2px 7px; border: 1px solid #3a3a46; border-radius: 4px; font-weight: 700; color: #c8c8d2; white-space: nowrap; }
.flx4-skin .bfx-chan b.sel { background: #ff914d; border-color: #ff914d; color: #111; }   /* the deck(s) the effect is on */
.flx4-skin .bfx-state {
  min-width: 34px; padding: 2px 6px; border: 1px solid #6a6a78; border-radius: 4px;
  text-align: center; font-weight: 800; font-size: 10px; letter-spacing: .08em; color: #d4d4dc;
}
.flx4-skin .bfx-bar.on { border-color: #ff914d; box-shadow: 0 0 0 1px rgba(255,145,77,.35); }
.flx4-skin .bfx-bar.on .bfx-state { background: #ff914d; border-color: #ff914d; color: #111; }
/* Beat FX controls on the controller */
.flx4-skin .fx-bfx { border-radius: 4px; }
.flx4-skin .fx-bfx:active { background: rgba(255,145,77,.2); }
.flx4-skin .fx-bfx-on.active { animation: bfx-blink 1s steps(2, start) infinite; }
@keyframes bfx-blink {
  from { box-shadow: 0 0 0 3px #ffb37a, 0 0 18px 6px rgba(255,145,77,.75); }
  to   { box-shadow: 0 0 0 2px rgba(255,145,77,.5); }
}
.flx4-skin .fx-bfx-ch-ind {
  position: absolute;
  border-radius: 2px;
  background: #ff914d;
  box-shadow: 0 0 6px rgba(255,145,77,.8);
  pointer-events: none;
  transition: left .12s ease, width .12s ease;
}
.flx4-skin .fx-sync.on { box-shadow: 0 0 0 3px #3d5fec, 0 0 16px 4px rgba(61,95,236,.7); }
.flx4-skin .fx-sync.warn { box-shadow: 0 0 0 3px #facc15; }
.flx4-skin .deck-title {
  color: #f2f2f6;
  font-weight: 600;
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.flx4-skin .deck-artist {
  color: #c8c8d2;
  font-size: 12px;
  min-height: 15px;
}
/* Zoomed waveform: the track scrolls past a fixed playhead (simulator.js _drawZoom).
   Like Serato, this is the big one you work on; the whole-track overview is a
   thin strip above it. */
.flx4-skin .wave-zoom {
  position: relative;
  height: 100px;
  margin: 0 0 6px;
  background: #0b0b10;
  border-radius: 4px;
  overflow: hidden;
}
/* − / + : zoom the waveform out and in */
.flx4-skin .zoom-btns { position: absolute; right: 4px; bottom: 4px; z-index: 3; display: flex; gap: 3px; }
.flx4-skin .zoom-btns button {
  width: 20px; height: 20px; padding: 0; border: 1px solid #4a4a56; border-radius: 4px;
  background: rgba(16,16,20,.85); color: #e4e4ea; font: 700 14px/1 system-ui, sans-serif; cursor: pointer;
}
.flx4-skin .zoom-btns button:disabled { opacity: .35; cursor: default; }
@media (hover: hover) { .flx4-skin .zoom-btns button:not(:disabled):hover { border-color: #ff914d; color: #fff; } }
.flx4-skin .wave-zoom canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
.flx4-skin .wave-zoom::after {          /* playhead */
  content: "";
  position: absolute;
  left: 50%; top: 0; bottom: 0;
  width: 2px; margin-left: -1px;
  background: #fff;
  box-shadow: 0 0 6px rgba(255,255,255,.7);
  opacity: .25;
}
.flx4-skin .wave-zoom.has-wave::after { opacity: 1; }
.flx4-skin .wave-zoom.has-wave { cursor: grab; touch-action: none; }   /* click a spot to bring it to the playhead, or drag it like a record */
.flx4-skin .wave-zoom.has-wave.grabbing { cursor: grabbing; }
.flx4-skin .waveform {
  position: relative;
  height: 20px;
  margin: 6px 0 5px;
  background: repeating-linear-gradient(90deg, #23232c 0 3px, #1a1a22 3px 6px);
  border-radius: 4px;
  overflow: hidden;
}
.flx4-skin .waveform { --wave-color: rgba(235,235,245,0.85); }
.flx4-skin .waveform.has-wave { background: #101016; }
.flx4-skin .waveform.seekable { cursor: pointer; touch-action: none; }   /* click/drag to seek */
.flx4-skin .waveform .wave-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
}
.flx4-skin .waveform .progress {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0%;
  background: linear-gradient(90deg, rgba(140,159,240,.35), rgba(244,142,181,.35));
  border-right: 2px solid #ff914d;
  pointer-events: none;
  z-index: 1;
}
.flx4-skin .waveform .cue-marker {
  position: absolute;
  top: 0; bottom: 0;
  width: 2px;
  background: #ff914d;
  pointer-events: none;
  z-index: 2;
}
/* Hot cue markers — engine adds one per saved pad, coloured by --hc-rgb.
   The line sits under the CUE line, so a hot cue saved on the cue point
   still shows the orange CUE; the numbered tab jumps to the cue. */
.flx4-skin .waveform .hotcue-mark {
  position: absolute;
  top: 0; bottom: 0;
  width: 2px;
  background: rgb(var(--hc-rgb));
  pointer-events: none;
  z-index: 1;
}
/* Serato-style triangle on the bottom edge, pointing up at the hot cue */
.flx4-skin .waveform .hotcue-mark::after {
  content: "";
  position: absolute;
  left: 50%; bottom: 0;
  margin-left: -5px;
  border: solid transparent;
  border-width: 0 5px 7px;
  border-bottom-color: rgb(var(--hc-rgb));
  filter: drop-shadow(0 0 1px rgba(0,0,0,.8));
}
.flx4-skin .waveform .hotcue-tab {
  position: absolute;
  top: 0; left: 0;
  min-width: 11px;
  height: 11px;
  padding: 0 2px;
  border: 0;
  border-radius: 0 3px 3px 0;
  background: rgb(var(--hc-rgb));
  color: #101016;
  font: 700 8px/11px system-ui, sans-serif;
  text-align: center;
  cursor: pointer;
  pointer-events: auto;
}
.flx4-skin .waveform .hotcue-mark.flip .hotcue-tab {
  left: auto; right: 0;
  border-radius: 3px 0 0 3px;
}
.flx4-skin .waveform .hotcue-tab:hover,
.flx4-skin .waveform .hotcue-tab:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 0;
}
/* Bottom line: time left (the countdown), time played / length, loop lengths */
.flx4-skin .deck-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.flx4-skin .deck-time {
  font-size: 12px;
  color: #c8c8d2;
  font-variant-numeric: tabular-nums;
}
.flx4-skin .time-left { color: #fff; font-weight: 700; font-size: 15px; margin-right: 4px; }
.flx4-skin .time-left.ending { color: #ff5a5f; }   /* last 30 seconds: time to mix out */
.flx4-skin .loop-sizes { display: flex; align-items: center; gap: 3px; }
.flx4-skin .loop-lbl { font: 700 9px/1 system-ui, sans-serif; letter-spacing: .08em; color: #c4c4ce; margin-right: 3px; }
.flx4-skin .loop-sizes.active .loop-lbl { color: #4ade80; }
.flx4-skin .loop-sizes button {
  min-width: 22px;
  padding: 3px 4px;
  font: 700 10px/1 system-ui, sans-serif;
  font-variant-numeric: tabular-nums;
  border: 1px solid #6a6a78;
  border-radius: 3px;
  background: transparent;
  color: #d4d4dc;
  cursor: pointer;
}
.flx4-skin .loop-sizes button.sel { border-color: #4ade80; color: #4ade80; }                 /* next auto loop */
.flx4-skin .loop-sizes button.on { background: #22a35a; border-color: #4ade80; color: #fff; }  /* looping now */
@media (hover: hover) { .flx4-skin .loop-sizes button:hover { border-color: #ff914d; color: #fff; } }
/* Key: the Camelot code in its wheel colour (simulator.js camelotColour) and
   the key name; a green tick when it mixes well with the other deck, an
   amber arrow when the tempo fader has moved it (MT off) */
.flx4-skin .deck-key { color: #d4d4dc; letter-spacing: .02em; }
.flx4-skin .cam {
  display: inline-block;
  min-width: 26px;
  padding: 1px 4px;
  border-radius: 4px;
  background: var(--cam, #888);
  color: #111;
  font-weight: 800;
  text-align: center;
  letter-spacing: 0;
}
.flx4-skin .key-shift { color: #facc15; font-style: normal; font-weight: 800; margin-left: 2px; }
.flx4-skin .deck-key.match::after { content: " ✓"; color: #4ade80; font-weight: 800; }

/* ───────────────────────── Hint bar ───────────────────────── */

.flx4-skin .flx4-audio-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  max-width: 1240px;
  margin: 0 auto 12px;
  padding: 6px 4px;
  color: #b9b9c4;
  font-size: 12px;
}
.flx4-skin .booth-btn {
  border: 1px solid #3a3a46;
  background: #1d1d25;
  color: #e8e8ee;
  border-radius: 8px;
  padding: 6px 14px;
  font-size: 13px;
  cursor: pointer;
}
.flx4-skin .booth-btn.primary {
  background: linear-gradient(135deg, #3d5fec, #8b3dee);
  border-color: transparent;
}
.flx4-skin .booth-btn.primary:hover { filter: brightness(1.12); }
.flx4-skin .status { font-size: 12px; letter-spacing: .02em; }
.flx4-skin .audio-on  { color: #4ade80; text-shadow: 0 0 8px rgba(74,222,128,.55); }
.flx4-skin .audio-off { color: #facc15; text-shadow: 0 0 6px rgba(250,204,21,.4); }
.flx4-skin .flx4-audio-hint { margin: 0 auto; text-align: center; color: #55555f; }
.flx4-skin .flx4-audio-hint.stuck { color: #d93a2b; font-weight: 700; font-size: 13px; }   /* the browser paused the sound */

/* ───────────────────────── Photo shell ───────────────────────── */

.flx4-skin .flx4-photo-shell {
  position: relative;
  width: 100%;   /* of .flx4-booth */
  margin: 0;
  user-select: none;
  -webkit-user-select: none;
  container-type: inline-size;
  /* Text on the controller is sized from --cq: 1% of this box's width in px,
     set by simulator.js (wireControllerScale). Safari didn't scale cqw units
     the same way, so pad names came out too big for the pads. */
}
.flx4-skin .flx4-photo {
  display: block;
  width: 100%;
  height: auto;
  pointer-events: none;
  /* no white edge: clip the photo to the controller's body (x 34-1963,
     y 21-1091 of 2000 x 1132), which lines up with the screens above */
  clip-path: inset(1.86% 1.8% 3.53% 1.7% round 2.4% / 4.2%);
}
/* Engine-required stems bars: styles.css gives .deck-stem-bar display:flex,
   which overrides the `hidden` attribute and adds two bars of height INSIDE
   the shell — stretching every % coordinate downward. Kill them hard. */
.flx4-skin .flx4-photo-shell .deck-stem-bar { display: none !important; }

/* Every overlay is % positioned against the shell (inline styles). */
.flx4-skin .flx4-photo-shell > .fx-hot,
.flx4-skin .flx4-photo-shell > .fx-knob,
.flx4-skin .flx4-photo-shell > .fx-fader,
.flx4-skin .flx4-photo-shell > .fx-jog,
.flx4-skin .flx4-photo-shell > .fx-bpm,
.flx4-skin .flx4-photo-shell > .fx-pitch-out,
.flx4-skin .flx4-photo-shell > .fx-vu {
  position: absolute;
  box-sizing: border-box;
}

/* ───────────────────────── Hotspot buttons ───────────────────────── */

.flx4-skin .fx-hot {
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* PLAY / CUE — invisible until the engine adds .active */
.flx4-skin .fx-round { border-radius: 50%; }
.flx4-skin .fx-round:active { background: rgba(255,255,255,.07); }
.flx4-skin .fx-play.active {
  outline: 3px solid rgba(74,222,128,.85);
  outline-offset: 3px;
  box-shadow: 0 0 26px 7px rgba(74,222,128,.4);
}
.flx4-skin .fx-cue.active {
  outline: 3px solid rgba(255,145,77,.85);
  outline-offset: 3px;
  box-shadow: 0 0 26px 7px rgba(255,145,77,.4);
}

/* Hot-cue pads — engine writes the number (1-8), toggles .set and, in hot
   cue mode, sets --hc-rgb to the pad's own colour (FX mode stays orange) */
.flx4-skin .fx-pad {
  border-radius: 8%/9%;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  padding: 3px 7px;
  font-size: clamp(8px, calc(var(--cq, 10px) * 0.95), 13px);
  font-weight: 600;
  color: rgba(255,255,255,.35);
  transition: background .08s, box-shadow .08s;
}
.flx4-skin .fx-pad:active { background: rgba(255,145,77,.3); }
.flx4-skin .fx-pad.set {   /* one even fill across the whole pad; the glow sits outside it */
  color: #fff;
  background: rgba(var(--hc-rgb, 255,145,77), .45);
  box-shadow: 0 0 14px 2px rgba(var(--hc-rgb, 255,145,77), .45);
}

/* ───────────────────────── Knobs ─────────────────────────
   The engine rotates the element itself (style.transform), so the box is
   a transparent square whose centre sits exactly on the printed knob.
   ::before = opaque disc covering the printed knob face (hides the static
   pointer line in image v1); ::after = the live pointer. */

.flx4-skin .fx-knob { cursor: ns-resize; }
.flx4-skin .fx-knob::before {
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: #272727;
}
.flx4-skin .fx-knob::after {
  content: "";
  position: absolute;
  left: calc(50% - 1px);
  width: 2px;
  background: #fff;
  border-radius: 1px;
}
/* lg: 74px box, printed knob face ≈ 61px → disc 82%; pointer to disc edge */
.flx4-skin .fx-knob.lg::before { width: 82%; height: 82%; }
.flx4-skin .fx-knob.lg::after  { top: 10%; height: 34%; }
/* sm (TRIM): 52px box, printed face ≈ 26px → disc 52% */
.flx4-skin .fx-knob.sm::before { width: 52%; height: 52%; }
.flx4-skin .fx-knob.sm::after  { top: 25%; height: 22%; width: 2px; }

/* ───────────────────────── Faders ─────────────────────────
   CustomFader positions .fader-cap in px:
   vertical → cap.style.top = top edge, left 50%  (translateX only)
   horizontal → cap.style.left = cap CENTRE, top 50%  (translate both) */

.flx4-skin .fx-fader { cursor: grab; }
.flx4-skin .fx-fader:active { cursor: grabbing; }
.flx4-skin .fader-cap {
  position: absolute;
  pointer-events: none;
  background: linear-gradient(180deg, #34343c, #17171c);
  border: 1px solid #4a4a55;
  border-radius: 3px;
  box-shadow: 0 2px 6px rgba(0,0,0,.6);
}
.flx4-skin .fx-fader.vert .fader-cap {
  left: 50%;
  transform: translateX(-50%);
  width: 96%;
  height: 15px;
}
.flx4-skin .fx-fader.vert .fader-cap::after {
  content: "";
  position: absolute;
  left: 6%; right: 6%;
  top: calc(50% - 1px);
  height: 2px;
  background: #fff;
  border-radius: 1px;
}
.flx4-skin .fx-fader.horz .fader-cap {
  top: 50%;
  transform: translate(-50%, -50%);
  width: 15px;
  height: 92%;
  background: linear-gradient(90deg, #34343c, #17171c);
}
.flx4-skin .fx-fader.horz .fader-cap::after {
  content: "";
  position: absolute;
  top: 6%; bottom: 6%;
  left: calc(50% - 1px);
  width: 2px;
  background: #fff;
  border-radius: 1px;
}

/* ───────────────────────── Jog wheels ─────────────────────────
   Live: drag to spin — nudges tempo while playing, scrubs while paused.
   The rotor is a full-size invisible disc with a glowing dot that shows
   true platter position (rotated from JS). */

.flx4-skin .fx-jog {
  pointer-events: auto;
  border-radius: 50%;
  cursor: grab;
  touch-action: none;
}
.flx4-skin .fx-jog.touched { cursor: grabbing; }
.flx4-skin .jog-rotor {
  position: absolute;
  inset: 0;
  border-radius: 50%;
}
.flx4-skin .jog-rotor::before {
  content: "";
  position: absolute;
  top: 4.2%;
  left: calc(50% - 5px);
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #ff914d;
  box-shadow: 0 0 10px 2px rgba(255,145,77,.65);
  opacity: 0;
  transition: opacity .2s;
}
.flx4-skin .fx-jog.spinning .jog-rotor::before,
.flx4-skin .fx-jog.touched  .jog-rotor::before { opacity: 1; }
/* Rotor rotation is now driven from JS (true platter position) — no CSS spin. */

/* BPM readout in the jog centre (under the MIX-ED mark) */
.flx4-skin .fx-bpm {
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #f2f2f6;
  font-weight: 700;
  font-size: clamp(11px, calc(var(--cq, 10px) * 1.3), 17px);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 8px rgba(0,0,0,.8);
}
.flx4-skin .bpm-label { font-size: .62em; font-weight: 600; color: #8a8a96; letter-spacing: .06em; }
.flx4-skin .bpm-pulse { animation: flx4bpmPulse 1s ease-in-out infinite; }
@keyframes flx4bpmPulse { 0%, 100% { opacity: 1 } 50% { opacity: .35 } }

/* Tempo readout above each pitch fader */
.flx4-skin .fx-pitch-out {
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #ff914d;
  font-size: clamp(9px, calc(var(--cq, 10px) * 1), 13px);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 6px rgba(0,0,0,.7);
}

/* ───────────────────────── VU meters ───────────────────────── */

.flx4-skin .fx-vu {
  background: rgba(0,0,0,.55);
  border: 1px solid rgba(255,255,255,.14);
  border-radius: 3px;
  overflow: hidden;
  pointer-events: none;
}
.flx4-skin .vu-fill {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 0%;
  background: linear-gradient(to top, #22c55e 0%, #22c55e 55%, #eab308 75%, #ef4444 92%);
  transition: height 60ms linear;
}
/* Central channel meters: taller strip, LED-segment texture */
.flx4-skin .fx-vu.ch {
  background: rgba(0,0,0,.62);
}
.flx4-skin .fx-vu.ch .vu-fill {
  background: linear-gradient(to top, #22c55e 0%, #22c55e 60%, #eab308 80%, #ef4444 93%);
}
.flx4-skin .fx-vu.ch::after {
  /* dark separators every few px → segmented-LED look over the fill */
  content: "";
  position: absolute;
  inset: 0;
  /* 5 chunky LEDs like the hardware */
  background: repeating-linear-gradient(to top, transparent 0 14px, rgba(0,0,0,.75) 14px 21px);
  pointer-events: none;
}

/* ───────────────────────── Debug ───────────────────────── */

body.debug-hotspots .fx-hot,
body.debug-hotspots .fx-knob,
body.debug-hotspots .fx-fader,
body.debug-hotspots .fx-jog,
body.debug-hotspots .fx-vu,
body.debug-hotspots .fx-bpm,
body.debug-hotspots .fx-pitch-out {
  outline: 1px solid magenta;
}

/* ───────────────────────── Responsive ───────────────────────── */

@media (max-width: 720px) {
  .flx4-skin .flx4-displays { grid-template-columns: minmax(0, 1fr); }
  .flx4-skin .flx4-audio-bar { display: none; }   /* only holds the hint, which is too long for phones */
  .flx4-skin .flx4-audio-bar:has(.stuck) { display: flex; }   /* except when it says the sound is paused */
}

/* Number only in the jog centre — the engine still emits a "BPM" label span; hidden on this skin */
.flx4-skin .fx-bpm .bpm-label { display: none; }

/* ─────────────── Hover / in-use highlights (TribeXR-style) ───────────────
   Controls glow softly when the pointer is over them, brighter while in
   use. Hover rules are gated behind (hover:hover) so touchscreens don't
   get stuck highlights. */

.flx4-skin .fx-hot,
.flx4-skin .fx-knob,
.flx4-skin .fx-fader,
.flx4-skin .fx-jog {
  transition: box-shadow .12s ease, background-color .12s ease;
}

@media (hover: hover) {
  .flx4-skin .fx-hot:hover {
    outline: 2px solid rgba(255,255,255,.55);
    outline-offset: 3px;
    box-shadow: 0 0 18px 6px rgba(255,145,77,.45);
    background-color: rgba(255,145,77,.10);
  }
  .flx4-skin .fx-pad:hover { background-color: rgba(255,145,77,.16); }
  .flx4-skin .fx-pad.set:hover { background-color: rgba(var(--hc-rgb, 255,145,77), .45); }   /* keep its own colour */
  .flx4-skin .fx-knob:hover {
    border-radius: 50%;
    outline: 2px solid rgba(255,255,255,.55);
    outline-offset: 3px;
    box-shadow: 0 0 16px 3px rgba(255,145,77,.45);
  }
  .flx4-skin .fx-fader:hover {
    border-radius: 6px;
    outline: 2px solid rgba(255,255,255,.5);
    outline-offset: 3px;
    box-shadow: 0 0 14px 2px rgba(255,145,77,.4);
  }
}

/* brighter while actually using the control */
.flx4-skin .fx-knob:active {
  border-radius: 50%;
  outline: 2px solid #ff914d;
  outline-offset: 3px;
  box-shadow: 0 0 22px 5px rgba(255,145,77,.55);
}
.flx4-skin .fx-fader:active {
  border-radius: 6px;
  outline: 2px solid #ff914d;
  outline-offset: 3px;
  box-shadow: 0 0 22px 5px rgba(255,145,77,.55);
}
/* Jog zones highlight independently — the platter (top) and the outer
   ring are separate sections. JS toggles .zone-platter / .zone-ring from
   the pointer's distance to the centre. */
.flx4-skin .fx-jog.zone-platter {
  background: radial-gradient(circle closest-side, rgba(255,145,77,.32) 0 75%, transparent 78%);
}
.flx4-skin .fx-jog.zone-ring {
  background: radial-gradient(circle closest-side, transparent 0 76%, rgba(255,145,77,.20) 79% 98%, transparent 100%);
  box-shadow: 0 0 0 3px rgba(255,145,77,.5), 0 0 30px 6px rgba(255,145,77,.25);
}
.flx4-skin .fx-jog.zone-platter .jog-rotor::after,
.flx4-skin .fx-jog.zone-ring .jog-rotor::after {
  content: "";
  position: absolute;
  inset: 11.5%;
  border-radius: 50%;
  border: 1px dashed rgba(255,255,255,.3);
}
/* brighter while grabbed */
.flx4-skin .fx-jog.touched.zone-platter {
  background: radial-gradient(circle closest-side, rgba(255,145,77,.50) 0 75%, transparent 78%);
}
.flx4-skin .fx-jog.touched.zone-ring {
  background: radial-gradient(circle closest-side, transparent 0 76%, rgba(255,145,77,.38) 79% 98%, transparent 100%);
  box-shadow: 0 0 0 3px #ff914d, 0 0 36px 8px rgba(255,145,77,.4);
}

/* Pitch/tempo faders: the highlight ring spans the printed pitch marks and
   the TEMPO label, not just the fader track. Drawn on a ::before that
   extends past the element; the drag hit-zone itself is unchanged so the
   cap still maps 1:1 to the printed track. */
.flx4-skin #pitch-a::before,
.flx4-skin #pitch-b::before {
  content: "";
  position: absolute;
  inset: -2% -25% -12% -38%;
  border-radius: 8px;
  pointer-events: none;
}
/* deck B's element is centred on its track (deck A's sits 5px left),
   so its ring needs its own left/right reach to hug the same marks */
.flx4-skin #pitch-b::before {
  inset: -2% -13% -12% -47%;
}
@media (hover: hover) {
  .flx4-skin #pitch-a:hover,
  .flx4-skin #pitch-b:hover {
    outline: none;
    box-shadow: none;
  }
  .flx4-skin #pitch-a:hover::before,
  .flx4-skin #pitch-b:hover::before {
    outline: 2px solid rgba(255,255,255,.5);
    box-shadow: 0 0 14px 2px rgba(255,145,77,.4);
    background: rgba(255,145,77,.07);
  }
}
.flx4-skin #pitch-a:active,
.flx4-skin #pitch-b:active {
  outline: none;
  box-shadow: none;
}
.flx4-skin #pitch-a:active::before,
.flx4-skin #pitch-b:active::before {
  outline: 2px solid #ff914d;
  box-shadow: 0 0 22px 5px rgba(255,145,77,.55);
  background: rgba(255,145,77,.10);
}

/* Loop buttons: lit while their state is engaged */
.flx4-skin .fx-loop.active {
  outline: 2px solid #ff914d;
  outline-offset: 3px;
  box-shadow: 0 0 18px 5px rgba(255,145,77,.45);
}
/* Loop region on the deck screen waveform */
.flx4-skin .waveform .loop-band {
  position: absolute;
  top: 0; bottom: 0;
  display: none;
  background: rgba(255,145,77,.22);
  border-left: 2px solid #ff914d;
  border-right: 2px solid #ff914d;
  pointer-events: none;
  z-index: 1;
}

/* Small loop buttons (4 BEAT, 1/2X, 2X): tight ring, small glow — the 3px
   stand-off tuned for CUE/PLAY reads far too loose at this size */
@media (hover: hover) {
  .flx4-skin [id^="loop-auto"]:hover,
  .flx4-skin [id^="loop-half"]:hover,
  .flx4-skin [id^="loop-double"]:hover {
    outline-width: 2px;
    outline-offset: 0px;
    box-shadow: 0 0 8px 2px rgba(255,145,77,.45);
  }
}
.flx4-skin [id^="loop-auto"].active {
  outline-width: 2px;
  outline-offset: 0px;
  box-shadow: 0 0 10px 3px rgba(255,145,77,.5);
}

/* Pad mode buttons (HOT CUE / PAD FX 1): tight rectangular ring when active */
.flx4-skin .fx-mode-btn { border-radius: 5px; }
.flx4-skin .fx-mode-btn.active {
  outline: 2px solid #ff914d;
  outline-offset: 1px;
  box-shadow: 0 0 10px 3px rgba(255,145,77,.45);
  background-color: rgba(255,145,77,.14);
}
@media (hover: hover) {
  .flx4-skin .fx-mode-btn:hover {
    outline-width: 2px;
    outline-offset: 1px;
    box-shadow: 0 0 8px 2px rgba(255,145,77,.45);
  }
}
/* Pads in FX, BEAT LOOP and STEMS modes: centred small labels (two lines
   where needed), tinted in the pad's colour even when off, so the rows can
   be told apart (PAD FX: blue = during the track, red = ends it) */
.flx4-skin .fx-pad.fx-mode {
  align-items: center;
  justify-content: center;
  padding: 0;
  font-size: clamp(6px, calc(var(--cq, 10px) * 0.62), 10px);   /* FLANGER, ONLY DRUMS fit the pad */
  letter-spacing: .02em;
  line-height: 1.15;
  text-align: center;
  color: rgba(var(--hc-rgb, 255,255,255), .85);
  background: rgba(var(--hc-rgb, 255,255,255), .08);
}
.flx4-skin .fx-pad.fx-mode.set { color: #fff; background: rgba(var(--hc-rgb, 255,145,77), .45); }

/* LOAD on a deck with no track yet: a slow bright-blue pulse, so pupils who
   haven't used the controller can find it (blue, not orange, so it doesn't
   blend in with the controller's orange buttons) */
.flx4-skin .fx-load.empty { animation: load-pulse 1.6s ease-in-out infinite; }
@keyframes load-pulse {
  0%, 100% { box-shadow: 0 0 0 2px rgba(56,189,248,.45), 0 0 6px 1px rgba(56,189,248,.3); }
  50%      { box-shadow: 0 0 0 3px rgba(56,189,248,1), 0 0 18px 6px rgba(56,189,248,.65); }
}
/* LOAD buttons (top of the mixer): glow on hover / press */
.flx4-skin .fx-load { border-radius: 4px; }
.flx4-skin .fx-load:active { background: rgba(56,189,248,.2); }
@media (hover: hover) {
  .flx4-skin .fx-load:hover {
    outline: 2px solid #38bdf8;
    outline-offset: 1px;
    box-shadow: 0 0 10px 3px rgba(56,189,248,.5);
  }
}

/* ───────────────────────── Track library ───────────────────────── */
/* LOAD opens it (simulator-flx4.html): laid out like Serato's library, with
   crates on the left and sortable columns. Blue top edge for deck A, pink for B. */
.flx4-browser {
  width: min(1100px, calc(100vw - 32px));
  height: min(720px, calc(100vh - 48px));
  padding: 14px 16px;
  background: #101014;
  color: #f2f2f6;
  border: 1px solid #2c2c36;
  border-top: 3px solid #4f8cff;
  border-radius: 14px;
  box-shadow: 0 24px 60px rgba(0,0,0,.6);
  font: 13px/1.3 system-ui, -apple-system, "Segoe UI", sans-serif;
}
.flx4-browser.deck-b { border-top-color: #ff4f8b; }
.flx4-browser[open] { display: flex; flex-direction: column; gap: 10px; }
.flx4-browser::backdrop { background: rgba(0,0,0,.55); }
.flx4-browser .tb-head { display: flex; align-items: center; gap: 14px; }
.flx4-browser h2 { margin: 0; font-size: 17px; color: #f2f2f6; white-space: nowrap; }
.flx4-browser .tb-close { margin-left: auto; background: none; border: none; color: #8a8a96; font-size: 26px; line-height: 1; cursor: pointer; padding: 0 4px; }
.flx4-browser .tb-close:hover { color: #f2f2f6; }
.flx4-browser input[type="search"] {
  flex: 1; max-width: 420px; box-sizing: border-box; padding: 8px 12px; font-size: 14px;
  background: #16161c; color: #f2f2f6; border: 1px solid #2c2c36; border-radius: 8px;
}
.flx4-browser input[type="search"]:focus { outline: 2px solid #ff914d; outline-offset: 0; }
.flx4-browser .tb-body { flex: 1; min-height: 0; display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 12px; }
/* crates */
.flx4-browser .tb-crates { overflow-y: auto; display: flex; flex-direction: column; gap: 2px; padding-right: 4px; border-right: 1px solid #22222a; }
.flx4-browser .tb-crates h6 { margin: 10px 8px 4px; font: 800 10px/1 system-ui, sans-serif; letter-spacing: .1em; text-transform: uppercase; color: #8a8a96; }
.flx4-browser .tb-crates button {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%;
  padding: 7px 8px; border: 0; border-radius: 6px; background: transparent; color: #d4d4dc;
  font: 600 13px/1.2 system-ui, sans-serif; text-align: left; cursor: pointer;
}
.flx4-browser .tb-crates button small { display: block; margin-top: 2px; font-size: 11px; font-weight: 600; color: #4ade80; }
.flx4-browser .tb-crates button i { font-style: normal; font-size: 11px; color: #8a8a96; }
.flx4-browser .tb-crates button:hover { background: #1d1d25; }
.flx4-browser .tb-crates button.on { background: #26262f; color: #fff; box-shadow: inset 3px 0 0 #4f8cff; }
.flx4-browser.deck-b .tb-crates button.on { box-shadow: inset 3px 0 0 #ff4f8b; }
/* the table */
.flx4-browser .tb-tablewrap { overflow: auto; min-height: 0; border: 1px solid #22222a; border-radius: 8px; }
.flx4-browser .tb-table { width: 100%; min-width: 0; border-collapse: collapse; font-variant-numeric: tabular-nums; }   /* styles.css gives tables a 540 px minimum on phones */
.flx4-browser .tb-table th {
  position: sticky; top: 0; z-index: 1; padding: 8px 10px; background: #1a1a21; color: #8a8a96;
  font: 800 10px/1 system-ui, sans-serif; letter-spacing: .1em; text-transform: uppercase; text-align: left; white-space: nowrap;
  border-bottom: 1px solid #2c2c36;
}
.flx4-browser .tb-table th[data-sort] { cursor: pointer; }
.flx4-browser .tb-table th[data-sort]:hover, .flx4-browser .tb-table th.sorted { color: #f2f2f6; }
.flx4-browser .tb-table td { padding: 7px 10px; border-bottom: 1px solid #1d1d24; white-space: nowrap; }
.flx4-browser .tb-table tbody tr { cursor: pointer; }
.flx4-browser .tb-table tbody tr:nth-child(even) { background: #131318; }
.flx4-browser .tb-table tbody tr:hover, .flx4-browser .tb-table tbody tr:focus { background: #23232c; outline: none; box-shadow: inset 3px 0 0 #ff914d; }
.flx4-browser .c-n { width: 34px; color: #6b6b76; text-align: right; }
.flx4-browser td.c-title { font-weight: 700; color: #fff; }
.flx4-browser td.c-artist, .flx4-browser td.c-genre { color: #b4b4c0; }
.flx4-browser .c-bpm, .flx4-browser .c-len { text-align: right; }
.flx4-browser td.c-bpm { font-weight: 700; color: #ff914d; }
.flx4-browser td.c-bpm.near, .flx4-browser .tb-legend .near { color: #4ade80; }
.flx4-browser .c-stems { text-align: center; color: #4ade80; }
.flx4-browser .tb-key { display: inline-block; min-width: 28px; padding: 1px 4px; border-radius: 4px;
  background: var(--cam, #888); color: #111; font-weight: 800; text-align: center; }
.flx4-browser .tb-keyok { margin-left: 5px; color: #4ade80; font-weight: 800; }
.flx4-browser .tb-on { display: inline-block; margin-left: 8px; padding: 1px 5px; border-radius: 3px; font: 800 9px/1.3 system-ui, sans-serif; color: #fff; vertical-align: 1px; }
.flx4-browser .tb-on.d-a { background: #4f8cff; }
.flx4-browser .tb-on.d-b { background: #ff4f8b; }
.flx4-browser .tb-none td { color: #b4b4c0; padding: 14px 10px; cursor: default; }
/* foot */
.flx4-browser .tb-foot { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.flx4-browser .tb-count { font-weight: 700; color: #d4d4dc; }
.flx4-browser .tb-legend { color: #8a8a96; font-size: 12px; }
.flx4-browser .tb-own {
  margin-left: auto; padding: 8px 14px; font-size: 14px; cursor: pointer;
  background: transparent; color: #f2f2f6; border: 1px solid #2c2c36; border-radius: 8px;
}
.flx4-browser .tb-own:hover { border-color: #ff914d; }
/* narrow screens: crates become a row of chips; fewer columns */
@media (max-width: 760px) {
  .flx4-browser .tb-head { flex-wrap: wrap; }
  .flx4-browser input[type="search"] { order: 3; max-width: none; flex-basis: 100%; }
  .flx4-browser .tb-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  .flx4-browser .tb-crates { flex-direction: row; overflow-x: auto; overflow-y: hidden; border-right: 0; padding: 0 0 4px; }
  .flx4-browser .tb-crates h6 { display: none; }
  .flx4-browser .tb-crates button { width: auto; flex: none; white-space: nowrap; }
  .flx4-browser .tb-crates button small { display: none; }
  .flx4-browser .c-n, .flx4-browser .c-artist, .flx4-browser .c-genre, .flx4-browser .c-stems, .flx4-browser .c-len { display: none; }   /* title, BPM and key */
  .flx4-browser td.c-title { white-space: normal; }
  .flx4-browser .tb-legend { display: none; }
}

/* ───────────────────────── Full screen ───────────────────────── */
/* simulator.js wireBoothFullscreen: the booth is laid out at its desktop
   width (1240 px) and scaled as one (--bs) to fill the screen, centred
   (--bx, --by), so it's as big as it can be whatever the page zoom */
body.booth-full { overflow: hidden; }
body.booth-full::before { content: ""; position: fixed; inset: 0; z-index: 899; background: #0b0b0e; }
body.booth-full .flx4-booth {
  position: fixed; top: 0; left: 0; z-index: 900;
  width: 1240px; margin: 0;
  transform-origin: 0 0;
  transform: translate(var(--bx, 0px), var(--by, 0px)) scale(var(--bs, 1));
}
body.booth-full .flx4-booth .flx4-screens-panel { margin-bottom: 8px; }
/* the button sits in the corner of the screen (moved out of the booth while it's full screen) */
body.booth-full > .booth-foot { position: fixed; left: 16px; bottom: 16px; margin: 0; z-index: 910; }

/* ───────────────────────── EXPLAIN mode ───────────────────────── */
/* simulator.js wireExplain: hover (or tap) a control for its name and job */
.explain-tip {
  position: fixed; z-index: 1100; max-width: 280px; padding: 9px 11px;
  background: #0f172a; color: #e2e8f0; border: 1.5px solid #38bdf8; border-radius: 10px;
  box-shadow: 0 10px 28px rgba(0,0,0,.45); pointer-events: none;
  font: 500 13px/1.35 system-ui, -apple-system, "Segoe UI", sans-serif;
}
.explain-tip[hidden] { display: none; }
.explain-tip b { display: block; margin-bottom: 3px; font-weight: 800; font-size: 13px; letter-spacing: .04em; color: #fff; }
.explain-tip b small { margin-left: 6px; font-size: 10px; font-weight: 700; color: #7dd3fc; letter-spacing: .08em; }
body.explain-on .explain-hover { outline: 2px solid #38bdf8 !important; outline-offset: 2px; border-radius: 6px; }
body.explain-on [data-explain] { cursor: help; }
body.explain-on button[data-explain], body.explain-on .fx-hot[data-explain], body.explain-on .fx-knob[data-explain],
body.explain-on .custom-fader[data-explain], body.explain-on .fx-jog[data-explain] { cursor: pointer; }
.flx4-skin .flx4-photo-shell > .fx-explain-only { position: absolute; pointer-events: none; border-radius: 6px; }
body.explain-on .flx4-photo-shell > .fx-explain-only { pointer-events: auto; }

/* ───────────────────────── STEMS ───────────────────────── */
/* The stems are on the pads (SAMPLER). The deck screen only says while a
   track's stems load or split (simulator.js _renderStems), and the stem
   pads pulse meanwhile */
.flx4-skin .stem-status { font: 700 9px/1 system-ui, sans-serif; letter-spacing: .08em; color: #fff; animation: stem-busy 1s ease-in-out infinite; }
.flx4-skin .fx-pad.stem-busy { animation: stem-busy 1s ease-in-out infinite; }
@keyframes stem-busy { 50% { opacity: .35; } }

/* Trademark small print under the notice */
.flx4-skin .tm-note { margin: 14px 0 0; font-size: 12px; line-height: 1.45; color: var(--text-dim, #6b6b76); }

/* ───────────────────────── Under the title ───────────────────────── */
.flx4-skin .booth-rule { border: 0; height: 1px; background: var(--border, #e3ddd0); margin: 18px 0 14px; }
.flx4-skin .flx4-audio-hint kbd, .flx4-skin .works-card kbd {
  display: inline-block; min-width: 18px; padding: 1px 5px; border: 1px solid #b9b2a5; border-bottom-width: 2px; border-radius: 4px;
  background: #fff; color: #333; font: 700 11px/1.3 system-ui, sans-serif; text-align: center;
}
/* "What works": an expandable card like the FAQ toggles on fillthefloordiscos.co.uk
   (pale panel, bold 18 px question, grey 16 px text, pink round + / - on the right) */
.flx4-skin .works-card { margin: 28px 0 0; padding: 20px; background: #f9f6f5; color: #666; font: 500 16px/1.6 "Open Sans", Arial, sans-serif; }
.flx4-skin .works-card summary {
  position: relative; display: block; list-style: none; cursor: pointer; padding-right: 50px;
  color: #333; font: 700 18px/27px "Open Sans", Arial, sans-serif;
}
.flx4-skin .works-card summary::-webkit-details-marker { display: none; }
.flx4-skin .works-card summary::after {
  content: "+"; position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  width: 18px; height: 18px; border-radius: 50%; background: #ff6a88; color: #fff;
  font: 700 15px/18px Arial, sans-serif; text-align: center;
}
.flx4-skin .works-card[open] summary::after { content: "\2212"; }
.flx4-skin .works-card .works-body { padding-top: 16px; color: #333; font-size: 12px; line-height: 1.6; }   /* the size of the hint above the screens, the colour of the bold words */
.flx4-skin .works-card ul { margin: 0; padding-left: 20px; }
.flx4-skin .works-card li { margin: 0 0 6px; }
.flx4-skin .works-card li b { color: #333; }
:root[data-theme="dark"] .flx4-skin .works-card { background: #1c1c24; color: #c4c4ce; }
:root[data-theme="dark"] .flx4-skin .works-card summary, :root[data-theme="dark"] .flx4-skin .works-card .works-body, :root[data-theme="dark"] .flx4-skin .works-card li b { color: #f2f2f6; }

/* ───────────────────────── SMART CFX / SMART FADER ───────────────────────── */
.flx4-skin .fx-smart.active { outline: 3px solid rgba(255,145,77,.9); outline-offset: 2px; box-shadow: 0 0 18px 5px rgba(255,145,77,.45); }
.flx4-skin .fx-smart.locked { cursor: not-allowed; }
.flx4-skin .fx-smart.nope { outline: 3px solid rgba(239,68,68,.9); outline-offset: 2px; }

/* ───────────────────────── Headphones: CUE and HEADPHONES MIX ─────────────────────────
   They work with 4 outputs (simulator.js HEADPHONES puts .hp-live on the
   body: a DDJ-FLX4 as the sound output). Until then they look printed, like
   the controls the Studio doesn't do, and a CUE press says what it needs. */
.flx4-skin .fx-hpcue { border-radius: 4px; }
.flx4-skin .fx-hpcue.on { outline: 2px solid #ff914d; outline-offset: 1px; box-shadow: 0 0 12px 4px rgba(255,145,77,.6); background-color: rgba(255,145,77,.35); }
.flx4-skin .fx-hpcue.nope { outline: 2px solid rgba(239,68,68,.9); outline-offset: 1px; }
.flx4-skin:not(.hp-live) .fx-hpcue { cursor: default; }
.flx4-skin:not(.hp-live) .fx-hpmix { pointer-events: none; }
.flx4-skin.explain-on:not(.hp-live) .fx-hpmix { pointer-events: auto; }
.flx4-skin:not(.hp-live) .fx-hpmix::before, .flx4-skin:not(.hp-live) .fx-hpmix::after { display: none; }   /* the printed knob, no pointer */
@media (hover: hover) {
  .flx4-skin:not(.hp-live) .fx-hpcue:hover, .flx4-skin:not(.hp-live) .fx-hpmix:hover { outline: none; box-shadow: none; background-color: transparent; }
}
/* a message in the hint bar (a CUE press that can't work says why) */
.flx4-skin .flx4-audio-hint.note { color: #c2410c; font-weight: 700; }
/* which are on, next to REC on the screens */
.flx4-skin .smart-chips { display: inline-flex; gap: 4px; margin-left: 6px; vertical-align: middle; }
.flx4-skin .smart-chips b { padding: 3px 6px; border-radius: 5px; background: rgba(255,145,77,.18); border: 1px solid #ff914d; color: #ffb27d; font: 800 9px/1 system-ui, sans-serif; letter-spacing: .08em; }
.flx4-skin .flx4-topbar .tb-side:first-child { display: flex; align-items: center; }

/* USE FLX4 (flx4-midi.js): a real DDJ-FLX4 over USB. Grey until it's
   connected, green when it is, amber while the browser waits for a click
   before it plays any sound, red if the browser blocks MIDI. Hidden where
   there's no Web MIDI (Safari, iPads), and on phones unless connected. */
.flx4-skin .midi-btn {
  display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 9px; margin-left: 6px;
  border: 1px solid #4a4a56; border-radius: 6px; background: transparent; color: #e4e4ea;
  font: 800 11px/1 system-ui, sans-serif; letter-spacing: .08em; white-space: nowrap; cursor: pointer;
}
.flx4-skin .midi-btn[hidden] { display: none; }
.flx4-skin .midi-btn i { box-sizing: border-box; width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid #8a8a96; }
.flx4-skin .midi-btn[data-state="none"] { color: #a8a8b4; }
.flx4-skin .midi-btn[data-state="on"] { border-color: #22c55e; background: rgba(34,197,94,.14); color: #fff; }
.flx4-skin .midi-btn[data-state="on"] i { border-color: #22c55e; background: #22c55e; box-shadow: 0 0 6px #22c55e; }
.flx4-skin .midi-btn[data-state="sound"] { border-color: #f59e0b; background: #f59e0b; color: #111; }
.flx4-skin .midi-btn[data-state="sound"] i { border-color: #111; background: #111; animation: rec-blink 1s steps(2, start) infinite; }
.flx4-skin .midi-btn[data-state="blocked"] { border-color: #ef4444; color: #fca5a5; }
@media (hover: hover) { .flx4-skin .midi-btn:not([data-state="sound"]):hover { border-color: #22c55e; color: #fff; } }
@media (max-width: 600px) { .flx4-skin .midi-btn:not([data-state="on"]):not([data-state="sound"]) { display: none; } }

/* A control moved on the plugged-in controller is ringed for a moment,
   so pupils can see which one it is on the screen */
.flx4-skin .midi-touch { outline: 2px solid #ff914d; outline-offset: 3px; box-shadow: 0 0 22px 5px rgba(255,145,77,.55); }
.flx4-skin .fx-knob.midi-touch, .flx4-skin .fx-round.midi-touch { border-radius: 50%; }
.flx4-skin .fx-fader.midi-touch, .flx4-skin .fx-bfx.midi-touch, .flx4-skin .fx-load.midi-touch, .flx4-skin .fx-mode-btn.midi-touch, .flx4-skin .fx-pad.midi-touch { border-radius: 6px; }

/* Tempo pick-up: the controller's tempo fader isn't where the Studio's is
   (after SYNC or Smart Fader); the arrow says which way to move it */
.flx4-skin .fx-pitch-out[data-pickup]::after { content: attr(data-pickup); margin-left: .3em; color: #fbbf24; animation: rec-blink 1s steps(2, start) infinite; }
/* BEAT SYNC: the MASTER deck (rekordbox orange); a rounded rectangle, not a pill */
.flx4-skin .master-tag { font: 700 9px/1 system-ui, sans-serif; letter-spacing: .08em; padding: 3px 6px; border-radius: 3px; background: #ff914d; color: #141418; }
