/* Deck (contract Module C): the sticky bottom player.
   Uses only the tokens site.css defines on :root; derived shades are color-mix() of those tokens.
   Layout bands: >= 1200 one hardware strip; 720 to 1199 the lights, pads and volume move into the
   drawer (deck.js reparents them); < 720 a collapsed mini bar that expands into a sheet. */

.deck {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-deck);
  color: var(--ink);
  font-family: var(--f-body);
  -webkit-font-smoothing: antialiased;

  /* Landscape iPhones: clear the notch or Dynamic Island and the rounded corners (the page opts into
     viewport-fit=cover). The insets are 0 in portrait and on Android. */
  --dk-px: max(clamp(16px, 1.6vw, 28px), env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));
  --dk-row: 29px;
  --dk-gap: 14px;
  --dk-mini: var(--deck-h);
  --dk-hi: color-mix(in srgb, var(--ink) 7%, transparent);        /* top-edge highlight on keys */
  --dk-edge: color-mix(in srgb, var(--ink) 9%, transparent);      /* key outline */
  --dk-shadow: color-mix(in srgb, var(--void) 85%, transparent);
  --dk-glow: color-mix(in srgb, var(--lamp) 55%, transparent);
  --dk-track: color-mix(in srgb, var(--ink) 14%, transparent);
  --dk-segs: repeating-linear-gradient(to top, #000 0 calc(10% - 2px), transparent calc(10% - 2px) 10%);
}

.deck *,
.deck *::before,
.deck *::after { box-sizing: border-box; }

.deck [hidden] { display: none !important; }

/* Page-level element styles (p, h2, lists, labels) must not leak in. :where() keeps this at the
   specificity of one class, so every deck rule below still wins. */
.deck :where(p, h2, ol, ul, li, label) {
  max-width: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: none;
}

.deck button {
  font-family: inherit;
  -webkit-tap-highlight-color: transparent;
}

.deck .dk-sr {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.deck :is(button, a, input, canvas):focus-visible {
  outline: 2px solid var(--uv);
  outline-offset: 2px;
}

.deck :is(button, a, input, canvas):focus:not(:focus-visible) { outline: none; }

.dk-ico {
  display: block;
  width: 18px;
  height: 18px;
  flex: none;
}

/* ---- shell ---------------------------------------------------------------------------------- */

.dk-body {
  position: relative;
  background: var(--booth);
  border-top: 1px solid var(--line);
  padding: 12px var(--dk-px) max(12px, env(safe-area-inset-bottom));
}

.dk-scrim,
.dk-progress { display: none; }

/* ---- platter: a Technics 1210 with the track art as the record label -------------------------- */

.dk-platter {
  position: relative;
  width: 64px;
  height: 64px;
  flex: none;
  border-radius: 50%;
  background:
    radial-gradient(circle closest-side, transparent 0 86%, color-mix(in srgb, var(--ink) 14%, var(--booth-2)) 90%, var(--booth-2) 97%),
    var(--booth-2);
  box-shadow: 0 2px 10px var(--dk-shadow), inset 0 0 0 1px var(--dk-edge);
}

/* Strobe dots on the platter rim. Lit orange by the lamp while playing. */
.dk-dots {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: repeating-conic-gradient(var(--dk-dot, color-mix(in srgb, var(--smoke) 45%, transparent)) 0 2.6deg, transparent 2.6deg 7.5deg);
  -webkit-mask: radial-gradient(circle closest-side, transparent 0 calc(100% - 5px), #000 calc(100% - 4.5px) calc(100% - 1.5px), transparent calc(100% - 1px));
  mask: radial-gradient(circle closest-side, transparent 0 calc(100% - 5px), #000 calc(100% - 4.5px) calc(100% - 1.5px), transparent calc(100% - 1px));
  will-change: transform;
}

.deck[data-playing="true"] .dk-dots { --dk-dot: var(--lamp); }

.dk-disc {
  position: absolute;
  inset: 6px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background:
    radial-gradient(circle closest-side, transparent 0 62%, color-mix(in srgb, var(--ink) 7%, transparent) 63% 64%, transparent 65% 92%, color-mix(in srgb, var(--ink) 6%, transparent) 93% 94%, transparent 95%),
    repeating-radial-gradient(circle, var(--void) 0 1px, color-mix(in srgb, var(--booth) 75%, var(--void)) 1px 2px);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--void) 70%, transparent), 0 1px 4px var(--dk-shadow);
  will-change: transform;
}

.dk-labelwrap {
  position: relative;
  width: 58%;
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, var(--uv), color-mix(in srgb, var(--uv) 30%, var(--booth)) 75%);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--void) 55%, transparent);
}

.dk-label {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
}

/* The spindle. */
.dk-labelwrap::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 4px;
  height: 4px;
  margin: -2px 0 0 -2px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--ink) 85%, var(--smoke));
  box-shadow: 0 0 0 1px var(--void);
}

/* A reflection that stays put while the record turns under it. */
.dk-sheen {
  position: absolute;
  inset: 6px;
  border-radius: 50%;
  pointer-events: none;
  background: conic-gradient(from 210deg, transparent 0deg, color-mix(in srgb, var(--ink) 14%, transparent) 22deg, transparent 50deg 180deg, color-mix(in srgb, var(--ink) 9%, transparent) 204deg, transparent 232deg);
  -webkit-mask: radial-gradient(circle closest-side, transparent 0 60%, #000 62%);
  mask: radial-gradient(circle closest-side, transparent 0 60%, #000 62%);
}

/* The pop-up strobe lamp at the front left of the deck. */
.dk-lamp {
  position: absolute;
  left: -3px;
  bottom: -3px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, color-mix(in srgb, var(--ink) 25%, var(--booth-2)), var(--booth-2));
  box-shadow: 0 0 0 2px var(--booth), inset 0 0 0 1px var(--dk-edge);
  transition: background-color .25s ease, box-shadow .25s ease;
}

.deck[data-playing="true"] .dk-lamp {
  background: radial-gradient(circle at 35% 30%, color-mix(in srgb, var(--ink) 55%, var(--lamp)), var(--lamp) 70%);
  box-shadow: 0 0 0 2px var(--booth), 0 0 9px 1px var(--dk-glow);
}

/* ---- title block ------------------------------------------------------------------------------- */

.dk-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.deck .dk-title {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  font: 600 14.5px/1.3 var(--f-body);
  letter-spacing: 0;
  color: var(--ink);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.dk-subline {
  display: flex;
  flex: 1 1 0;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.dk-badge {
  flex: none;
  padding: 4px 6px 3px;
  border: 1px solid var(--line);
  border-radius: 4px;
  font: 700 10px/1 var(--f-body);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--smoke);
  white-space: nowrap;
}

.deck[data-live] .dk-badge {
  border-color: var(--lamp);
  background: var(--lamp);
  color: var(--void);
}

.deck .dk-sub {
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
  font: 500 12.5px/1.3 var(--f-body);
  color: var(--smoke);
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* The one-row desktop strip only has room for a stub of the sub line after a long title
   ("Hardcore ·..."), which reads as broken. Below 1600 px it goes; the phone bar keeps it. */
@media (min-width: 720px) and (max-width: 1599.98px) {
  .deck .dk-sub { display: none; }
}

/* Radio: "Tuning in" and "No signal" are states, not titles, so they sit back in --smoke. */
.deck:is([data-radio="tuning"], [data-radio="nosignal"]) .dk-title { color: var(--smoke); }

/* ---- Track ID: the tune playing now, under the title (v2) -------------------------------------- */

.dk-id {
  min-width: 0;
  font: 500 12px/14px var(--f-body);
  color: var(--smoke);
}

.deck .dk-id-btn {
  appearance: none;
  display: block;
  width: 100%;
  max-width: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
  border: 0;
  border-radius: 3px;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  white-space: nowrap;
  text-overflow: ellipsis;
  cursor: pointer;
}

.deck .dk-id-btn:hover .dk-id-text { color: var(--ink); text-decoration: underline; text-decoration-color: var(--uv); text-underline-offset: 2px; }

.dk-id-label {
  margin-right: 7px;
  font: 700 9.5px/1 var(--f-body);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--lamp);
  vertical-align: 1px;
}

.dk-id-text b {
  font-weight: 600;
  color: var(--ink);
}

/* ---- share (v2): a key beside the title -------------------------------------------------------- */

.deck .dk-share {
  display: grid;
  place-items: center;
  width: var(--dk-row);
  height: var(--dk-row);
  padding: 0;
  border-radius: 7px;
  color: var(--smoke);
}

.deck .dk-share:hover:not(:disabled) { color: var(--ink); }
.deck .dk-share .dk-ico { width: 15px; height: 15px; }

/* ---- waveform slider --------------------------------------------------------------------------- */

.dk-wave {
  position: relative;
  min-width: 0;
  height: var(--dk-row);
}

#deck-wave {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 3px;
  cursor: pointer;
  touch-action: pan-y;
  -webkit-user-select: none;
  user-select: none;
}

#deck-wave:focus-visible { outline-offset: 3px; }

.deck[data-source="radio"] #deck-wave { cursor: default; }

.dk-tip {
  position: absolute;
  bottom: calc(100% + 7px);
  left: 0;
  z-index: 2;
  transform: translateX(-50%);
  padding: 5px 8px;
  border-radius: 6px;
  background: var(--void);
  box-shadow: inset 0 0 0 1px var(--line), 0 6px 16px var(--dk-shadow);
  font: 600 12px/1 var(--f-body);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  white-space: nowrap;
  pointer-events: none;
  max-width: min(360px, 80vw);
  overflow: hidden;
  text-overflow: ellipsis;
}

.dk-tip-t {
  margin-right: 4px;
  color: var(--lamp);
}

/* ---- LCD: CDJ dot-matrix readouts (Doto at 18 px and up only) ------------------------------ */

.dk-lcd {
  display: grid;
  grid-template-columns: auto auto;
  grid-template-areas:
    "time bpm"
    "time foot";
  align-items: center;
  column-gap: 16px;
  row-gap: 3px;
  height: 64px;
  padding: 6px 12px;
  border-radius: 8px;
  background: var(--void);
  box-shadow: inset 0 0 0 1px var(--line), inset 0 2px 8px var(--dk-shadow);
  color: var(--lamp);
  --dk-lcd-big: 22px;
}

.dk-lcd-time { grid-area: time; }

/* A matrix colon drawn to Doto's dot grid (Doto's own glyph reads as a dagger). */
.dk-colon {
  position: relative;
  display: inline-block;
  width: 1ch;
  height: .66em;
  vertical-align: baseline;
}

.dk-colon::before,
.dk-colon::after {
  content: '';
  position: absolute;
  left: 50%;
  width: 2px;
  height: 2px;
  margin-left: -1px;
  background: currentColor;
}

.dk-colon::before { bottom: .43em; }
.dk-colon::after { bottom: .1em; }

#deck-time {
  display: grid;
  justify-items: end;
  gap: 3px;
  font-family: var(--f-lcd);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-shadow: 0 0 10px color-mix(in srgb, var(--lamp) 40%, transparent);
}

.dk-el,
.dk-tot {
  display: block;
  min-width: calc(var(--dk-chars, 7) * 1ch);
  text-align: right;
}

.dk-el { font: 700 var(--dk-lcd-big)/1 var(--f-lcd); }

.dk-tot {
  font: 700 18px/1 var(--f-lcd);
  /* 90%, not less: with the lamp glow behind it this is the floor for 4.5:1 on the booth. */
  color: color-mix(in srgb, var(--lamp) 90%, var(--void));
}

.dk-lcd-bpm {
  grid-area: bpm;
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 5px;
  white-space: nowrap;
}

.dk-bpm {
  min-width: 4ch;
  font: 900 var(--dk-lcd-big)/1 var(--f-lcd);
  font-variant-numeric: tabular-nums;
  text-align: right;
  text-shadow: 0 0 10px color-mix(in srgb, var(--lamp) 40%, transparent);
}

/* The "~" of an estimated BPM, in the body font: Doto draws a tilde as a raised dot ("^165").
   Large enough to read as a tilde at 1x, not a minus sign. Club mode's BPM uses it too. */
.dk-approx {
  font: 700 .85em/1 var(--f-body);
  vertical-align: .08em;
  margin-right: .08em;
}

.dk-unit {
  font: 700 10px/1 var(--f-body);
  letter-spacing: .12em;
  color: var(--smoke);
}

.dk-lcd-foot {
  grid-area: foot;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  height: 18px;
}

.dk-beats {
  display: flex;
  gap: 3px;
}

.dk-beats i {
  width: 9px;
  height: 5px;
  border-radius: 1px;
  background: color-mix(in srgb, var(--lamp) 16%, transparent);
}

.dk-beats[data-b="0"] i:nth-child(1),
.dk-beats[data-b="1"] i:nth-child(2),
.dk-beats[data-b="2"] i:nth-child(3),
.dk-beats[data-b="3"] i:nth-child(4) {
  background: var(--lamp);
  box-shadow: 0 0 6px var(--dk-glow);
}

.deck .dk-tap {
  display: none;
  align-items: center;
  height: 18px;
  margin: 0;
  padding: 0 7px;
  border: 1px solid color-mix(in srgb, var(--lamp) 55%, transparent);
  border-radius: 4px;
  background: transparent;
  color: var(--lamp);
  font: 700 10px/1 var(--f-body);
  letter-spacing: .12em;
  text-transform: uppercase;
  cursor: pointer;
}

.deck .dk-tap:hover { background: color-mix(in srgb, var(--lamp) 14%, transparent); }
.deck .dk-tap:active { background: color-mix(in srgb, var(--lamp) 26%, transparent); }
.deck[data-synthetic] .dk-tap { display: inline-flex; }

/* ---- LED ladders: DJM-style, --uv low, --ink mid, --lamp for the top two ----------------------- */

.dk-meters {
  display: flex;
  gap: 4px;
  height: 64px;
  padding: 1px 0;
}

.dk-meter {
  --v: 0;
  --p: 0;
  position: relative;
  width: 6px;
  height: 100%;
}

.dk-meter::before,
.dk-meter-lit,
.dk-meter-peak {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, var(--uv) 0 50%, var(--ink) 50% 80%, var(--lamp) 80% 100%);
  -webkit-mask: var(--dk-segs);
  mask: var(--dk-segs);
}

.dk-meter::before { opacity: .12; }
.dk-meter-lit { clip-path: inset(calc(100% - var(--v) * 100%) 0 0 0); }
.dk-meter-peak { clip-path: inset(calc(100% - var(--p) * 10%) 0 calc((var(--p) - 1) * 10%) 0); }

/* ---- keys: the shared tactile button ----------------------------------------------------------- */

.deck .dk-key {
  appearance: none;
  margin: 0;
  border: 1px solid var(--dk-edge);
  background: linear-gradient(180deg, var(--dk-hi), transparent 55%), var(--booth-2);
  color: var(--ink);
  box-shadow: inset 0 1px 0 var(--dk-hi), 0 1px 0 var(--dk-shadow), 0 3px 8px color-mix(in srgb, var(--void) 45%, transparent);
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease, transform .08s ease;
}

.deck .dk-key:hover:not(:disabled) { border-color: color-mix(in srgb, var(--uv) 60%, transparent); }

.deck .dk-key:active:not(:disabled) {
  transform: translateY(1px);
  box-shadow: inset 0 2px 5px var(--dk-shadow);
}

.deck .dk-key:disabled {
  opacity: .38;
  cursor: default;
}

/* ---- transport ----------------------------------------------------------------------------------- */

.dk-transport {
  display: flex;
  align-items: center;
  gap: 8px;
}

.deck .dk-round {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border-radius: 50%;
}

.deck .dk-play {
  position: relative;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  margin: 0;
  padding: 0;
  flex: none;
  border: 0;
  border-radius: 50%;
  background: var(--lamp);
  color: var(--void);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--ink) 40%, transparent),
    inset 0 -2px 0 color-mix(in srgb, var(--void) 22%, transparent),
    0 2px 12px color-mix(in srgb, var(--lamp) 28%, transparent);
  cursor: pointer;
  transition: transform .08s ease, box-shadow .2s ease;
}

.deck .dk-play .dk-ico {
  width: 22px;
  height: 22px;
}

.deck .dk-play:hover {
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--ink) 40%, transparent),
    inset 0 -2px 0 color-mix(in srgb, var(--void) 22%, transparent),
    0 2px 18px color-mix(in srgb, var(--lamp) 42%, transparent);
}

.deck .dk-play:active { transform: translateY(1px) scale(.97); }

.deck[data-playing="true"] .dk-ico-play,
.deck:not([data-playing="true"]) .dk-ico-pause { display: none; }

.deck .dk-play:focus-visible { outline-offset: 5px; }

/* Buffering: a lamp-coloured ring chasing round the play key. */
.dk-ring {
  position: absolute;
  inset: -5px;
  border: 2px solid transparent;
  border-radius: 50%;
  border-top-color: var(--lamp);
  border-left-color: color-mix(in srgb, var(--lamp) 35%, transparent);
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease;
}

.deck[data-buffering] .dk-ring {
  opacity: 1;
  animation: dk-spin .8s linear infinite;
}

/* ---- segmented switches: source and lights -------------------------------------------------- */

.dk-seg {
  display: flex;
  align-items: stretch;
  gap: 2px;
  height: var(--dk-row);
  padding: 2px;
  border-radius: 8px;
  background: var(--void);
  box-shadow: inset 0 0 0 1px var(--line);
}

.deck .dk-seg-btn {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin: 0;
  padding: 0 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--smoke);
  font: 600 11px/1 var(--f-body);
  letter-spacing: .08em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition: color .15s ease;
}

.deck .dk-seg-btn:hover { color: var(--ink); }

.deck .dk-seg-btn[aria-pressed="true"] {
  color: var(--ink);
  background: linear-gradient(180deg, var(--dk-hi), transparent 60%), var(--booth-2);
  box-shadow: inset 0 0 0 1px var(--dk-edge), 0 1px 2px var(--dk-shadow);
}

.deck .dk-seg-btn:focus-visible {
  outline-offset: -2px;
}

.dk-led {
  flex: none;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--smoke) 40%, transparent);
  transition: background-color .2s ease, box-shadow .2s ease;
}

[aria-pressed="true"] > .dk-led,
.deck .dk-st[aria-current="true"] > .dk-led {
  background: var(--lamp);
  box-shadow: 0 0 6px var(--dk-glow);
}

.deck[data-source="radio"][data-playing="true"] .dk-led-live { animation: dk-pulse 1.8s ease-in-out infinite; }

.dk-seg-cap {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 4px 0 6px;
  color: var(--smoke);
  font: 700 10px/1 var(--f-body);
  letter-spacing: .12em;
  text-transform: uppercase;
}

.dk-seg-cap .dk-ico {
  width: 15px;
  height: 15px;
}

.dk-cap-text { display: none; }

/* ---- FX pads: MPC-style rubber pads ------------------------------------------------------------ */

.dk-pads {
  display: flex;
  align-items: center;
  gap: 6px;
}

.deck .dk-pad {
  appearance: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: 48px;
  height: 48px;
  margin: 0;
  padding: 0;
  border: 1px solid var(--dk-edge);
  border-radius: 9px;
  background: radial-gradient(120% 90% at 50% 0%, var(--dk-hi), transparent 70%), var(--booth-2);
  color: var(--ink);
  box-shadow:
    inset 0 1px 0 var(--dk-hi),
    inset 0 -3px 0 color-mix(in srgb, var(--void) 35%, transparent),
    0 2px 6px color-mix(in srgb, var(--void) 55%, transparent);
  cursor: pointer;
  transition: box-shadow .25s ease-out, border-color .25s ease-out, transform .08s ease;
}

.deck .dk-pad .dk-ico {
  width: 18px;
  height: 18px;
}

.dk-pad-name {
  font: 700 9.5px/1 var(--f-body);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--smoke);
  transition: color .25s ease-out;
}

.deck .dk-pad:hover:not(:disabled) { border-color: color-mix(in srgb, var(--uv) 60%, transparent); }
.deck .dk-pad:active:not(:disabled) { transform: translateY(1px); }

.deck .dk-pad.is-hit {
  border-color: var(--lamp);
  box-shadow: inset 0 0 14px color-mix(in srgb, var(--lamp) 38%, transparent), 0 0 14px var(--dk-glow);
  transition-duration: 0s;
}

.deck .dk-pad.is-hit .dk-pad-name {
  color: var(--ink);
  transition-duration: 0s;
}

.deck .dk-pad:disabled {
  opacity: .38;
  cursor: default;
}

/* ---- club / queue --------------------------------------------------------------------------- */

.dk-util {
  display: flex;
  gap: 8px;
}

.deck .dk-util-btn {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  gap: 7px;
  height: var(--dk-row);
  padding: 0 11px 0 9px;
  border-radius: 7px;
  font: 600 11px/1 var(--f-body);
  letter-spacing: .08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.deck .dk-util-btn .dk-ico {
  width: 16px;
  height: 16px;
}

.deck #deck-queue[aria-expanded="true"] {
  border-color: color-mix(in srgb, var(--uv) 75%, transparent);
  background: linear-gradient(180deg, var(--dk-hi), transparent 55%), color-mix(in srgb, var(--uv) 20%, var(--booth-2));
}

.deck .dk-expand {
  appearance: none;
  display: none;
  place-items: center;
  width: 44px;
  height: 44px;
  margin: 0;
  padding: 0;
  flex: none;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--smoke);
  cursor: pointer;
}

.deck .dk-expand:hover { color: var(--ink); }

.dk-expand .dk-ico {
  width: 22px;
  height: 22px;
  transition: transform .25s ease;
}

.deck[data-expanded] .dk-expand .dk-ico { transform: rotate(180deg); }

/* ---- volume ------------------------------------------------------------------------------------- */

.dk-vol {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--smoke);
}

.dk-vol .dk-ico {
  width: 16px;
  height: 16px;
}

#deck-volume {
  --vol: 100%;
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  min-width: 0;
  height: 28px;
  margin: 0;
  background: transparent;
  cursor: pointer;
}

#deck-volume::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 2px;
  background: linear-gradient(to right, var(--uv) var(--vol), var(--dk-track) var(--vol));
}

#deck-volume::-moz-range-track {
  height: 4px;
  border-radius: 2px;
  background: var(--dk-track);
}

#deck-volume::-moz-range-progress {
  height: 4px;
  border-radius: 2px;
  background: var(--uv);
}

/* A fader cap: a light key with a dark centre line. */
#deck-volume::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 12px;
  height: 20px;
  margin-top: -8px;
  border: 0;
  border-radius: 3px;
  background: linear-gradient(to right, transparent 5px, var(--void) 5px 7px, transparent 7px), var(--ink);
  box-shadow: 0 1px 3px var(--dk-shadow);
}

#deck-volume::-moz-range-thumb {
  width: 12px;
  height: 20px;
  border: 0;
  border-radius: 3px;
  background: linear-gradient(to right, transparent 5px, var(--void) 5px 7px, transparent 7px), var(--ink);
  box-shadow: 0 1px 3px var(--dk-shadow);
}

/* ---- drawer: "Up next" (and, from 720 to 1199 px, the lights, pads and volume) -------------- */

.dk-drawer {
  display: flex;
  flex-direction: column;
}

.dk-drawer-fx:empty { display: none; }

.dk-drawer-fx {
  margin-bottom: 14px;
  padding: 2px 4px 16px;
  border-bottom: 1px solid var(--line);
}

.dk-drawer-fx .dk-fx {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 12px;
}

.dk-drawer-fx .dk-lights {
  grid-column: 1 / -1;
  height: 40px;
}

.dk-drawer-fx .dk-lights .dk-seg-btn { flex: 1 1 0; }
.dk-drawer-fx .dk-cap-text { display: inline; }
.dk-drawer-fx .dk-pads { gap: 8px; }

.dk-drawer-fx .dk-pad {
  flex: 1 1 0;
  width: auto;
  height: 56px;
}

.dk-drawer-fx .dk-vol {
  height: 56px;
  padding: 0 4px 0 2px;
}

.deck .dk-drawer-head {
  margin: 0 8px 8px;
  padding: 0;
  font: var(--display-weight-head) 11.5px/1.2 var(--f-display);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--smoke);
}

.deck .dk-qlist {
  margin: 0;
  padding: 0;
  list-style: none;
}

.deck .dk-qitem {
  position: relative;   /* contains its visually hidden label inside the scrolling list */
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  margin: 0;
  padding: 8px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color .15s ease;
}

.deck .dk-qitem:hover { background: var(--booth-2); }
.deck .dk-qitem:focus-visible { outline-offset: -2px; }

.dk-qart {
  display: block;
  width: 40px;
  height: 40px;
  overflow: hidden;
  border-radius: 6px;
  background: radial-gradient(circle at 35% 30%, var(--uv), color-mix(in srgb, var(--uv) 25%, var(--booth)) 80%);
}

.dk-qart img {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
}

.dk-qtext {
  display: grid;
  gap: 3px;
  min-width: 0;
}

.dk-qtitle {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  font: 600 13.5px/1.3 var(--f-body);
  overflow-wrap: anywhere;
}

.dk-qmeta,
.dk-qdur {
  font: 500 12px/1.3 var(--f-body);
  color: var(--smoke);
}

.dk-qdur {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.deck .dk-browse {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  margin: 10px 0 2px;
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--ink);
  font: 600 13px/1 var(--f-body);
  text-decoration: none;
  transition: border-color .15s ease;
}

.deck .dk-browse:hover { border-color: var(--uv); }

/* ---- drawer tabs: Up next (Stations on radio) and Tracklist (v2) -------------------------------- */

.dk-tabs {
  display: flex;
  gap: 6px;
  margin: 0 4px 10px;
  border-bottom: 1px solid var(--line);
}

.deck .dk-tab {
  appearance: none;
  min-height: 40px;
  margin: 0 0 -1px;
  padding: 8px 8px 9px;
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 6px 6px 0 0;
  background: none;
  color: var(--smoke);
  font: var(--display-weight-head) 11.5px/1.2 var(--f-display);
  letter-spacing: .16em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease;
}

.deck .dk-tab:hover:not([aria-disabled="true"]) { color: var(--ink); }

.deck .dk-tab[aria-selected="true"] {
  color: var(--ink);
  border-bottom-color: var(--lamp);
}

.deck .dk-tab[aria-disabled="true"] {
  opacity: .38;
  cursor: default;
}

.deck .dk-tab:focus-visible { outline-offset: -2px; }
/* Touch: 40 px to the eye, 44 px to the finger (upwards, into the drawer's top padding). */
@media (pointer: coarse) {
  .deck .dk-tab { position: relative; }
  .deck .dk-tab::after { content: ""; position: absolute; inset: -4px 0 0; }
}

/* ---- stations (radio) ---------------------------------------------------------------------------- */

.deck .dk-stations {
  margin: 0;
  padding: 0;
  list-style: none;
}

.deck .dk-st {
  position: relative;
  display: grid;
  grid-template-columns: 5px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 52px;
  margin: 0;
  padding: 8px 10px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color .15s ease;
}

.deck .dk-st:hover { background: var(--booth-2); }
.deck .dk-st:focus-visible { outline-offset: -2px; }

.deck .dk-st[aria-current="true"] {
  background: var(--booth-2);
  box-shadow: inset 3px 0 0 var(--lamp);
}

.dk-st-text {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.dk-st-name { font: 600 13.5px/1.25 var(--f-body); }

.dk-st-genre {
  font: 500 12px/1.3 var(--f-body);
  color: var(--smoke);
}

.dk-st-state {
  font: 700 10px/1 var(--f-body);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--lamp);
  white-space: nowrap;
}

.dk-st-state[data-state="tuning"],
.dk-st-state[data-state="nosignal"] { color: var(--smoke); }

.dk-st-state[data-state="live"] {
  padding: 4px 6px 3px;
  border-radius: 4px;
  background: var(--lamp);
  color: var(--void);
}

.deck .dk-st-next {
  margin: 10px 10px 0;
  font: 500 12.5px/1.4 var(--f-body);
  color: var(--ink);
  overflow-wrap: anywhere; /* a station's long unbroken text must not widen the page */
}

.deck .dk-st-note {
  margin: 10px 10px 4px;
  font: 500 12px/1.45 var(--f-body);
  color: var(--smoke);
}

.deck .dk-st-site {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--uv);
  text-underline-offset: 2px;
}

.deck .dk-st-site:hover { text-decoration-color: var(--ink); }

/* ---- tracklist (Track ID) ---------------------------------------------------------------------- */

.dk-tl-head {
  display: grid;
  gap: 10px;
  margin: 0 8px 10px;
}

.deck .dk-tl-sum {
  font: 500 12.5px/1.45 var(--f-body);
  color: var(--smoke);
}

.dk-tl-nav {
  display: flex;
  gap: 8px;
}

.deck .dk-tl-step {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 34px;
  padding: 0 12px;
  border-radius: 8px;
  font: 600 11px/1 var(--f-body);
  letter-spacing: .08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.dk-ico-sm {
  width: 13px;
  height: 13px;
}

.deck .dk-tl-notes {
  margin: 0 8px 10px;
  padding: 2px 0 2px 10px;
  list-style: none;
  border-left: 2px solid var(--line);
  font: italic 500 12px/1.45 var(--f-body);
  color: var(--smoke);
}

.deck .dk-tl {
  --dk-tl-time: 56px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.deck .dk-tl[data-timing="approx"] { --dk-tl-time: 86px; }
.deck .dk-tl[data-timing="list"] { --dk-tl-time: 0px; }

.deck .dk-tl-row {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  border-radius: 10px;
  transition: background-color .15s ease;
}

.deck .dk-tl-row:hover { background: var(--booth-2); }

.deck .dk-tl-seek {
  display: grid;
  grid-template-columns: var(--dk-tl-time) minmax(0, 1fr);
  align-items: baseline;
  column-gap: 10px;
  width: 100%;
  min-height: 44px;
  margin: 0;
  padding: 8px 4px 8px 10px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-align: left;
}

.deck .dk-tl[data-timing="list"] .dk-tl-seek { column-gap: 0; }
.deck button.dk-tl-seek { cursor: pointer; }
.deck .dk-tl-seek:focus-visible { outline-offset: -2px; }

.dk-tl-time {
  font: 600 12px/1.35 var(--f-body);
  font-variant-numeric: tabular-nums;
  color: var(--smoke);
  white-space: nowrap;
}

.dk-tl-text {
  min-width: 0;
  font: 500 13px/1.35 var(--f-body);
  overflow-wrap: anywhere;
}

.dk-tl-artist { font-weight: 700; }
/* Artist in white, title a step back, as on the deck's Track ID line and in the dig results, so a
   row parses at a glance. Only titles after an artist: the DJ's raw lines and jingles are untouched.
   (.72 ink on --booth-2, the current row, is about 8:1.) */
.dk-tl-artist ~ .dk-tl-title { color: rgb(var(--ink-rgb) / .72); }

.deck .dk-tl-row[data-kind="jingle"] .dk-tl-text {
  font-style: italic;
  color: var(--smoke);
}

.dk-tl-tags {
  display: inline-flex;
  gap: 4px;
  vertical-align: 1px;
}

.dk-tl-tag {
  padding: 3px 5px 2px;
  border: 1px solid var(--line);
  border-radius: 4px;
  font: 700 9.5px/1 var(--f-body);
  font-style: normal;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--smoke);
  white-space: nowrap;
}

/* The playing tune: a lamp bar and a lit time, like the current row in the crate. */
.deck .dk-tl-row[aria-current="true"] { background: var(--booth-2); }

.deck .dk-tl-row[aria-current="true"]::before {
  content: '';
  position: absolute;
  left: 0;
  top: 9px;
  bottom: 9px;
  width: 3px;
  border-radius: 2px;
  background: var(--lamp);
  box-shadow: 0 0 8px var(--dk-glow);
}

.deck .dk-tl-row[aria-current="true"] .dk-tl-time { color: var(--lamp); }

.deck .dk-tl-share {
  appearance: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin: 0 2px 0 0;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--smoke);
  cursor: pointer;
  transition: color .15s ease, background-color .15s ease;
}

.deck .dk-tl-share .dk-ico { width: 16px; height: 16px; }
.deck .dk-tl-share:hover { color: var(--ink); background: color-mix(in srgb, var(--uv) 16%, transparent); }
.deck .dk-tl-share:focus-visible { outline-offset: -2px; }
/* Touch: the rows are at least 44 px tall, so the share key can be too. */
@media (pointer: coarse) {
  .deck .dk-tl-share { width: 44px; height: 44px; }
}

/* ======================================================================================== */
/* >= 720 px: one hardware strip, two 29 px rows beside a 64 px platter                     */
/* ======================================================================================== */

@media (min-width: 720px) {
  .dk-panel {
    display: grid;
    align-items: center;
    column-gap: var(--dk-gap);
    row-gap: 6px;
    grid-template-rows: var(--dk-row) var(--dk-row);
  }

  .dk-platter { grid-area: platter; }
  .deck .dk-share { grid-area: share; }

  /* The meta row: the kind badge, then the title (and, from 1600 px, the sub line), with the Track
     ID as a second line under the title while a tune is known. Both lines fit the 29 px row. */
  .dk-meta {
    grid-area: meta;
    display: grid;
    grid-template-columns: auto minmax(0, auto) minmax(0, 1fr);
    grid-template-areas:
      "badge title sub"
      "badge id id";
    align-content: center;
    align-items: center;
    align-self: stretch;
    column-gap: 10px;
    row-gap: 0;
  }

  .dk-subline { display: contents; }
  .dk-badge { grid-area: badge; }
  .deck .dk-title { grid-area: title; }
  .deck .dk-sub { grid-area: sub; }
  .dk-id { grid-area: id; }

  .deck:is([data-tune], [data-source="radio"]) .dk-title {
    font-size: 14px;
    line-height: 15px;
  }

  /* On radio the second line names the station and its genre at every width (the title is the
     station's now-playing text, which alone does not say which station it is). */
  .deck[data-source="radio"] .dk-sub {
    display: block;
    grid-area: id;
    font-size: 12px;
    line-height: 14px;
  }

  .dk-wave { grid-area: wave; }
  .dk-lcd { grid-area: lcd; }
  .dk-meters { grid-area: meters; }
  .dk-transport { grid-area: transport; }
  .dk-source { grid-area: source; }

  .dk-drawer {
    position: absolute;
    right: var(--dk-px);
    bottom: calc(100% + 10px);
    z-index: var(--z-drawer);
    width: min(440px, calc(100vw - 2 * var(--dk-px)));
    max-height: min(70vh, 600px);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 16px 10px 10px;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: var(--booth);
    box-shadow: 0 24px 60px color-mix(in srgb, var(--void) 75%, transparent);
    visibility: hidden;
    opacity: 0;
    transform: translateY(8px);
    transition: opacity .18s ease, transform .18s ease, visibility 0s linear .18s;
  }

  .deck[data-drawer] .dk-drawer {
    visibility: visible;
    opacity: 1;
    transform: none;
    transition-delay: 0s;
  }
}

@media (min-width: 1200px) {
  .dk-panel {
    grid-template-columns: 64px minmax(0, 1fr) auto auto auto auto auto auto auto;
    grid-template-areas:
      "platter meta share lcd meters transport source pads vol"
      "platter wave wave lcd meters transport lights util vol";
  }

  .dk-fx { display: contents; }
  .dk-lights { grid-area: lights; }
  .dk-vol { grid-area: vol; }
  .dk-source .dk-seg-btn,
  .dk-lights .dk-seg-btn { flex: 1 1 auto; }
  .dk-lights .dk-seg-btn { padding: 0 8px; gap: 5px; }

  /* Function keys: the three FX pads above Club and Queue, one tidy two-row cluster. */
  .dk-pads {
    grid-area: pads;
    align-self: stretch;
  }

  .deck .dk-pad {
    flex: 1 1 0;
    width: auto;
    height: auto;
    border-radius: 7px;
  }

  .deck .dk-pad .dk-ico {
    width: 16px;
    height: 16px;
  }

  .dk-pad-name { display: none; }

  .dk-util {
    grid-area: util;
    display: flex;
    gap: 6px;
  }

  .deck #deck-club,
  .deck #deck-booth { flex: 1 1 auto; }

  .deck #deck-queue {
    justify-content: center;
    width: 38px;
    padding: 0;
  }

  .dk-q-more { display: none; }

  .dk-q-queue {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* A vertical channel fader. */
  .dk-vol {
    justify-content: center;
    height: 64px;
  }

  .dk-vol .dk-ico { display: none; }

  #deck-volume {
    writing-mode: vertical-lr;
    direction: rtl;
    width: 22px;
    height: 62px;
  }

  #deck-volume::-webkit-slider-runnable-track {
    width: 4px;
    height: auto;
    background: linear-gradient(to top, var(--uv) var(--vol), var(--dk-track) var(--vol));
  }

  #deck-volume::-webkit-slider-thumb {
    width: 20px;
    height: 11px;
    margin: 0 0 0 -8px;
    background: linear-gradient(to bottom, transparent 4.5px, var(--void) 4.5px 6.5px, transparent 6.5px), var(--ink);
  }

  #deck-volume::-moz-range-track { width: 4px; height: auto; }
  #deck-volume::-moz-range-progress { width: 4px; height: auto; }

  #deck-volume::-moz-range-thumb {
    width: 20px;
    height: 11px;
    background: linear-gradient(to bottom, transparent 4.5px, var(--void) 4.5px 6.5px, transparent 6.5px), var(--ink);
  }
}

/* Narrow desktops: give the waveform the room. The pressed key still shows the lights mode. */
@media (min-width: 1200px) and (max-width: 1439.98px) {
  .dk-lights .dk-led { display: none; }
  .dk-lcd { --dk-lcd-big: 20px; }
  /* The tune matters more than the kind badge while one is known. */
  .deck[data-tune] .dk-badge { display: none; }
}

@media (min-width: 720px) and (max-width: 1199.98px) {
  .dk-panel {
    grid-template-columns: 64px minmax(0, 1fr) auto auto auto auto auto auto auto;
    grid-template-areas:
      "platter meta share lcd meters transport source club booth"
      "platter wave wave lcd meters transport source queue queue";
  }

  .dk-q-queue { display: none; }
  .dk-util { display: contents; }
  .deck #deck-club { grid-area: club; }
  .deck #deck-booth { grid-area: booth; }
  .deck #deck-queue { grid-area: queue; }

  /* Crate over Live radio, as a two-position switch. */
  .dk-source {
    flex-direction: column;
    align-self: stretch;
    height: auto;
  }

  .dk-source .dk-seg-btn {
    flex: 1 1 0;
    justify-content: flex-start;
  }

  .deck #deck-club,
  .deck #deck-booth,
  .deck #deck-queue { justify-self: stretch; }

  #deck-volume { height: 44px; }

  /* The title shares its narrow column with the badge (119 to 145 px at 768), so it gets two
     tighter lines in the same 29 px row rather than one that stops at the DJ's own name. */
  .deck .dk-title {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    font-size: 12.5px;
    line-height: 1.15;
    white-space: normal;
  }

  /* With a Track ID the title keeps one line and the tune takes the second; the badge steps aside
     so the tune has the whole column. */
  .deck:is([data-tune], [data-source="radio"]) .dk-title {
    -webkit-line-clamp: 1;
    font-size: 12.5px;
    line-height: 15px;
    overflow-wrap: anywhere;
  }

  .deck[data-tune] .dk-badge { display: none; }
}

/* Touch tablets and phones held landscape: the source, club and queue keys are 40 px tall, so an
   invisible extension takes each hit area to 44 px. 2 px up and down stays within half the gap
   between stacked keys, so neighbouring targets never overlap. */
@media (pointer: coarse) and (min-width: 720px) and (max-width: 1199.98px) {
  .deck .dk-source .dk-seg-btn,
  .deck .dk-util-btn,
  .deck .dk-share { position: relative; }
  .deck .dk-source .dk-seg-btn::after,
  .deck .dk-util-btn::after,
  .deck .dk-share::after {
    content: "";
    position: absolute;
    inset: -2px -3px;
  }
  /* The util keys have a 1 px border, and ::after is placed from inside it. */
  .deck .dk-util-btn::after { inset: -3px -4px; }
}

@media (min-width: 720px) and (max-width: 959.98px) {
  /* The share key joins the club, booth and queue keys (a 2 x 2 cluster at the right end), so the
     title and the Track ID get its column: at 720 px they had a word or less. */
  .dk-panel {
    grid-template-columns: 56px minmax(0, 1fr) auto auto auto auto auto;
    grid-template-areas:
      "platter meta lcd transport source club booth"
      "platter wave lcd transport source share queue";
    column-gap: 12px;
  }
  .deck .dk-share { justify-self: center; }

  .dk-meters { display: none; }
  .dk-platter { width: 56px; height: 56px; }
  .dk-src-live { display: none; }
  .dk-transport { gap: 6px; }
  .deck .dk-round { width: 34px; height: 34px; }

  .dk-lcd {
    --dk-lcd-big: 18px;
    padding: 6px 10px;
    column-gap: 10px;
  }

  .dk-unit { display: none; }

  .deck .dk-util-btn {
    justify-content: center;
    width: 38px;
    padding: 0;
  }

  .deck .dk-util-btn .dk-util-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* Under about 840 px the "Now playing" word itself would push the tune out of the Track ID line:
   a lamp dot stands in for it (the words stay for screen readers, and in the button's title). */
@media (min-width: 720px) and (max-width: 839.98px) {
  .dk-id-label {
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-right: 6px;
    overflow: hidden;
    border-radius: 50%;
    background: var(--lamp);
    color: transparent;
    font-size: 0;
    vertical-align: 1px;
  }
}

/* Touch tablets (and phones held landscape) get this strip layout, so its keys need finger-sized
   targets. With the height to spare: 44 px transport keys, 40 px source, club and queue keys (the
   rows grow and deck.js republishes --deck-h through its ResizeObserver), and a 45 px hit box on
   the waveform from transparent borders, so the drawing itself keeps its size. */
@media (pointer: coarse) and (min-width: 720px) and (max-width: 1199.98px) and (min-height: 600px) {
  .dk-panel { grid-template-rows: minmax(var(--dk-row), auto) minmax(var(--dk-row), auto); }

  .deck #deck-prev,
  .deck #deck-next { width: 44px; height: 44px; }

  .deck #deck-club,
  .deck #deck-booth,
  .deck #deck-queue { height: 40px; }
  .deck .dk-share { width: 40px; height: 40px; }

  .dk-source { min-height: 86px; }

  #deck-wave {
    box-sizing: content-box;
    margin-block: -8px;
    border-block: 8px solid transparent;
  }
}

/* Short landscape phones: the transport keys fit the existing bar at 44 px. The rows here are only
   29 px, so the stacked source, club and queue keys grow their hit areas outward only (the top keys
   up to the deck's top edge, the bottom keys down to its bottom padding), never into each other. */
@media (pointer: coarse) and (min-width: 720px) and (max-width: 1199.98px) and (max-height: 599.98px) {
  .deck #deck-prev,
  .deck #deck-next { width: 44px; height: 44px; }
  #deck-src-crate::after { inset: -12px -3px -1px; }
  #deck-club::after,
  #deck-booth::after { inset: -12px -4px -3px; }
  #deck-src-radio::after { inset: -1px -3px -11px; }
  #deck-queue::after { inset: -3px -4px -11px; }
}
/* The share key sits in the bottom row under 960 px (beside Queue), and in the top row above. */
@media (pointer: coarse) and (min-width: 720px) and (max-width: 959.98px) and (max-height: 599.98px) {
  #deck-share::after { inset: -3px -4px -11px; }
}
@media (pointer: coarse) and (min-width: 960px) and (max-width: 1199.98px) and (max-height: 599.98px) {
  #deck-share::after { inset: -12px -3px -1px; }
}

/* Touch phones: the collapsed bar's Track ID button is 16 px tall under an 18 px title. Padding
   with an equal negative margin grows its hit area to 40 px, up over the title (not a control) and
   down to the bar's bottom padding, never sideways into the expand and play keys. The button clips
   its overflow (the ellipsis), so a pseudo-element could not do this. */
@media (pointer: coarse) and (max-width: 719.98px) {
  .deck .dk-id-btn { padding-block: 14px 10px; margin-block: -14px -10px; }
}

/* ======================================================================================== */
/* < 720 px: a mini bar that expands into a sheet                                            */
/* ======================================================================================== */

@media (max-width: 719.98px) {
  .dk-body { padding: 10px 16px max(10px, env(safe-area-inset-bottom)); }

  .dk-panel {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px 8px;
  }

  .dk-transport,
  .dk-fx,
  .dk-util { display: contents; }

  /* Row 1, always visible: platter, title, expand, play. */
  .dk-platter {
    order: 1;
    width: 44px;
    height: 44px;
  }

  .dk-platter .dk-dots {
    -webkit-mask: radial-gradient(circle closest-side, transparent 0 calc(100% - 4px), #000 calc(100% - 3.5px) calc(100% - 1px), transparent calc(100% - .5px));
    mask: radial-gradient(circle closest-side, transparent 0 calc(100% - 4px), #000 calc(100% - 3.5px) calc(100% - 1px), transparent calc(100% - .5px));
  }

  .dk-platter .dk-disc,
  .dk-platter .dk-sheen { inset: 4px; }

  .dk-lamp {
    width: 8px;
    height: 8px;
  }

  .dk-meta {
    order: 2;
    flex: 1 1 0;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
  }

  .deck .dk-title { font-size: 14px; }
  /* The open sheet has the height for two lines, so the whole label shows ("(studio recording)"
     included). deck.js keeps dates such as 30-8-26 whole. The collapsed bar stays on one line. */
  .deck[data-expanded] .dk-title {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    white-space: normal;
  }
  .dk-subline { flex: none; }
  .dk-badge { padding: 3px 5px 2px; font-size: 9.5px; }
  .deck .dk-sub { font-size: 12px; }

  /* Two lines in the collapsed bar: the title, then the Track ID when a tune is known (otherwise
     the badge and sub line). The open sheet shows all three. */
  .dk-id { font-size: 12.5px; line-height: 16px; }
  .deck[data-tune]:not([data-expanded]) .dk-subline { display: none; }

  /* Share sits beside Queue in the open sheet (the top row has no room for it next to the tune). */
  .deck .dk-share {
    order: 21;
    flex: 0 0 44px;
    width: 44px;
    height: 44px;
    border-radius: 10px;
  }

  .deck .dk-share .dk-ico { width: 18px; height: 18px; }

  .deck .dk-expand {
    order: 3;
    display: grid;
  }

  .deck .dk-play { order: 4; }

  /* The sheet. */
  .dk-wave {
    order: 10;
    flex: 1 1 100%;
    height: 56px;
  }

  .dk-lcd {
    order: 11;
    flex: 1 1 calc(100% - 52px);
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
      "time bpm tap"
      "time foot tap";
  }

  .dk-lcd-foot { display: contents; }
  .dk-beats { grid-area: foot; justify-self: end; }

  .deck .dk-tap {
    grid-area: tap;
    height: 44px;
    padding: 0 12px;
    margin-left: 4px;
    border-radius: 8px;
  }

  .dk-meters {
    order: 12;
    flex: 0 0 44px;
    justify-content: center;
  }

  .deck #deck-prev,
  .deck #deck-next {
    flex: 0 0 52px;
    height: 48px;
    border-radius: 10px;
  }

  .deck #deck-prev { order: 13; }
  .dk-source { order: 14; flex: 1 1 calc(100% - 120px); height: 48px; }
  .deck #deck-next { order: 15; }

  .dk-seg .dk-seg-btn { flex: 1 1 0; padding: 0 6px; }

  .dk-lights {
    order: 16;
    flex: 1 1 100%;
    height: 48px;
  }

  .dk-lcd { --dk-lcd-big: 24px; }

  /* One row of five square keys: the three pads, Club and Booth. */
  .dk-pads {
    order: 17;
    flex: 1 1 calc(60% - 6px);
    min-width: 0;
    gap: 8px;
  }

  .deck .dk-pad {
    flex: 1 1 0;
    width: auto;
    min-width: 0;
    height: 56px;
  }

  .deck #deck-club,
  .deck #deck-booth {
    order: 18;
    flex: 1 1 calc(20% - 6px);
    min-width: 0;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    height: 56px;
    padding: 0;
    border-radius: 9px;
  }

  .deck #deck-booth { order: 19; }

  .deck :is(#deck-club, #deck-booth) .dk-util-label {
    font-size: 9.5px;
    letter-spacing: .06em;
    color: var(--smoke);
  }

  .deck #deck-queue {
    order: 20;
    flex: 1 1 calc(40% - 30px);
    justify-content: center;
    height: 44px;
    border-radius: 10px;
  }

  .dk-q-more { display: none; }

  .dk-vol {
    order: 22;
    flex: 1 1 calc(60% - 30px);
    height: 44px;
    padding: 0 4px 0 8px;
  }

  #deck-volume { height: 44px; }

  .deck:not([data-expanded]) :is(.dk-wave, .dk-lcd, .dk-meters, #deck-prev, #deck-next, .dk-source, .dk-lights, .dk-pads, #deck-club, #deck-booth, #deck-share, #deck-queue, .dk-vol, .dk-drawer) { display: none; }

  /* Collapsed: a hairline of progress along the top edge. */
  .dk-progress {
    position: absolute;
    top: -1px;
    left: 0;
    right: 0;
    display: block;
    height: 2px;
    overflow: hidden;
  }

  .dk-progress i {
    display: block;
    height: 100%;
    background: var(--lamp);
    transform: scaleX(0);
    transform-origin: left center;
  }

  .deck[data-expanded] .dk-progress,
  .deck[data-source="radio"]:not([data-np]) .dk-progress { display: none; }

  /* Expanded. */
  .deck[data-expanded] .dk-body {
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 16px);
    max-height: calc(100dvh - 16px);
    overflow-y: auto;
    overscroll-behavior: contain;
    border-radius: 18px 18px 0 0;
    box-shadow: 0 -20px 60px color-mix(in srgb, var(--void) 70%, transparent);
    animation: dk-sheet-in .3s cubic-bezier(.2, .8, .2, 1);
  }

  /* No grabber pill: the sheet does not drag, and a handle promises that it does. The chevron and
     a tap on the scrim close it. */

  .deck[data-sheet-closing] .dk-body { animation: dk-sheet-out .2s ease-in forwards; }

  .deck[data-expanded] .dk-scrim {
    position: fixed;
    inset: 0;
    display: block;
    background: color-mix(in srgb, var(--void) 72%, transparent);
    touch-action: none;
    animation: dk-fade .3s ease;
  }

  .deck[data-sheet-closing] .dk-scrim { animation: dk-fade-out .2s ease forwards; }

  /* The queue sits under the controls, inside the sheet. */
  .dk-drawer {
    display: none;
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--line);
  }

  .deck[data-expanded][data-drawer] .dk-drawer { display: flex; }

  .dk-panel { flex: none; }

  /* The queue takes the room the sheet has left rather than making the sheet scroll: at 280 px it
     pushed the sheet's own title and play key half out of view on a 360x740 phone. */
  .dk-drawer {
    position: relative;
    flex: 1 1 auto;
    min-height: min(200px, 45vh);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .deck .dk-drawer-head { margin: 0 0 6px; }
  .deck .dk-qitem { padding: 8px 0; }
  .dk-tabs { margin: 0 0 10px; }
  .dk-tl-head { margin: 0 0 10px; }
  .deck .dk-tl-notes { margin: 0 0 10px; }
  .dk-tl-nav .dk-tl-step { flex: 1 1 0; justify-content: center; height: 44px; }
}

/* A 360x740 phone on radio: the Stations button, share and volume wrap to a second row, and a
   200 px queue made the sheet itself scroll, clipping its title. 180 px still shows about two and a
   half station rows. */
@media (max-width: 719.98px) and (max-height: 760px) {
  .deck .dk-drawer { min-height: min(180px, 45vh); }
}

/* ---- motion ------------------------------------------------------------------------------------ */

@keyframes dk-spin { to { transform: rotate(360deg); } }

@keyframes dk-pulse { 50% { opacity: .3; } }

@keyframes dk-fade { from { opacity: 0; } }

@keyframes dk-fade-out { to { opacity: 0; } }

/* The sheet rises from where the mini bar sits, so the bar is the handle it was pulled up by. */
@keyframes dk-sheet-in { from { transform: translateY(calc(100% - var(--dk-mini))); } }

@keyframes dk-sheet-out { to { transform: translateY(calc(100% - var(--dk-mini))); } }

@media (prefers-reduced-motion: reduce) {
  .deck[data-buffering] .dk-ring { animation: dk-pulse 1.6s ease-in-out infinite; }
  .deck[data-source="radio"][data-playing="true"] .dk-led-live { animation: none; }

  .deck[data-expanded] .dk-body,
  .deck[data-sheet-closing] .dk-body { animation: none; }

  .dk-drawer,
  .deck[data-drawer] .dk-drawer { transform: none; }

  .dk-expand .dk-ico { transition: none; }
}

/* ---- iOS Safari 16.0/16.1: no color-mix() ---------------------------------------------------- */
/* The contract targets iOS 16+, and color-mix() arrived in Safari 16.2. There, each color-mix()
   declaration above is dropped and every var(--dk-*) that uses one goes invalid, so pressed keys
   lose their fill and the platter loses its face. Every input is a fixed hex token, so each mix is
   written out here as the literal it computes to (a mix with transparent is rgba(token, p)). */
@supports not (color: color-mix(in srgb, red 50%, blue)) {
  .deck {
    --dk-hi: rgb(var(--ink-rgb) / .07);
    --dk-edge: rgb(var(--ink-rgb) / .09);
    --dk-shadow: rgb(var(--void-rgb) / .85);
    --dk-glow: rgb(var(--lamp-rgb) / .55);
    --dk-track: rgb(var(--ink-rgb) / .14);
  }

  .dk-platter {
    background:
      radial-gradient(circle closest-side, transparent 0 86%, var(--mt-dk-platter) 90%, var(--booth-2) 97%),
      var(--booth-2);
  }

  .dk-dots { background: repeating-conic-gradient(var(--dk-dot) 0 2.6deg, transparent 2.6deg 7.5deg); }

  .dk-disc {
    background:
      radial-gradient(circle closest-side, transparent 0 62%, rgb(var(--ink-rgb) / .07) 63% 64%, transparent 65% 92%, rgb(var(--ink-rgb) / .06) 93% 94%, transparent 95%),
      repeating-radial-gradient(circle, var(--void) 0 1px, var(--mt-dk-disc) 1px 2px);
    box-shadow: 0 0 0 1px rgb(var(--void-rgb) / .7), 0 1px 4px var(--dk-shadow);
  }

  .dk-labelwrap {
    background: radial-gradient(circle at 35% 30%, var(--uv), var(--mt-dk-labelwrap) 75%);
    box-shadow: 0 0 0 1px rgb(var(--void-rgb) / .55);
  }

  .dk-labelwrap::after { background: var(--mt-dk-labelwrap-after); }

  .dk-lamp { background: radial-gradient(circle at 35% 30%, var(--mt-dk-lamp), var(--booth-2)); }
  .deck[data-playing="true"] .dk-lamp { background: radial-gradient(circle at 35% 30%, var(--mt-dk-lamp-2), var(--lamp) 70%); }

  #deck-time { text-shadow: 0 0 10px rgb(var(--lamp-rgb) / .4); }
  .dk-tot { color: var(--mt-dk-tot); }

  .dk-beats i { background: rgb(var(--lamp-rgb) / .16); }
  .dk-led { background: rgb(var(--smoke-rgb) / .4); }

  .deck #deck-queue[aria-expanded="true"] {
    border-color: rgb(var(--uv-rgb) / .75);
    background: linear-gradient(180deg, var(--dk-hi), transparent 55%), var(--mt-deck-queue);
  }

  .dk-qart { background: radial-gradient(circle at 35% 30%, var(--uv), var(--mt-dk-qart) 80%); }

  /* iOS is always synthetic, so TAP always shows there. */
  .deck .dk-tap { border: 1px solid rgb(var(--lamp-rgb) / .55); }
  .dk-ring { border-left-color: rgb(var(--lamp-rgb) / .35); }

  .deck .dk-tl-share:hover { background: rgb(var(--uv-rgb) / .16); }
}

@media (max-width: 719.98px) {
  @supports not (color: color-mix(in srgb, red 50%, blue)) {
    .deck[data-expanded] .dk-scrim { background: rgb(var(--void-rgb) / .72); }
  }
}

/* ---- Windows High Contrast (forced colours) ----------------------------------------------------- */
/* The pressed state of the source and lights keys is all background, box-shadow and the LED's
   background, which forced colours strip, so a high-contrast user could not see which light mode
   (strobe included) is on. The pressed key fills with the system highlight instead, and focus gets
   its own ring, so it stays distinct from pressed. */
@media (forced-colors: active) {
  .deck .dk-seg-btn[aria-pressed="true"] {
    forced-color-adjust: none;
    background: Highlight;
    color: HighlightText;
  }
  .deck .dk-seg-btn:focus-visible { outline: 2px solid CanvasText; outline-offset: 2px; }

  /* v2: the selected tab, the playing tune and the station on the dial keep their marking. */
  .deck :is(.dk-tab[aria-selected="true"], .dk-tl-row[aria-current="true"], .dk-st[aria-current="true"]) {
    forced-color-adjust: none;
    background: Highlight;
    color: HighlightText;
  }

  .deck :is(.dk-tl-row[aria-current="true"], .dk-st[aria-current="true"]) :is(.dk-tl-time, .dk-st-genre, .dk-st-state, .dk-tl-tag) { color: HighlightText; }
}

/* ==== SoundCloud strip, on air, tracklist headings, Listen again (Mark, workflow 2) ==== */

/* ---- SoundCloud strip (widget tracks) --------------------------------------------------------- */

.deck .dk-sc {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  margin: -4px 0 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}

/* SoundCloud's own mini player: never covered, never moved, at least 200 px wide (their terms: the
   player stays visible and attributed). */
.deck .dk-sc-player {
  flex: 1 1 320px;
  min-width: 200px;
  height: 20px;
}

.deck .dk-sc-frame {
  display: block;
  width: 100%;
  height: 20px;
  border: 0;
}

.deck .dk-sc-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex: none;
  padding: 3px 9px 3px 8px;
  border: 1px solid color-mix(in srgb, var(--lamp) 45%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--lamp) 10%, transparent);
  color: var(--ink);
  font: 600 11.5px/1.2 var(--f-body);
  letter-spacing: .02em;
  cursor: pointer;
}

.deck .dk-sc-chip .dk-led {
  background: var(--lamp);
  box-shadow: 0 0 6px var(--dk-glow);
}

.deck .dk-sc-chip[aria-expanded="true"] { background: color-mix(in srgb, var(--lamp) 20%, transparent); }

.deck .dk-sc-open {
  flex: none;
  color: var(--ink);
  font: 600 12px/1.2 var(--f-body);
  text-decoration: underline;
  text-decoration-color: var(--uv);
  text-underline-offset: 2px;
}

.deck .dk-sc-open:hover { text-decoration-color: var(--ink); }

.deck .dk-sc-why {
  flex: 1 1 100%;
  max-width: 68ch;
  color: var(--smoke);
  font: 500 12px/1.45 var(--f-body);
}

/* Safari: our Play cannot start SoundCloud's player; its own play button must be pressed. A steady
   outline (no flashing) marks the strip until the set plays. */
.deck[data-sc-press] .dk-sc-player { outline: 2px solid var(--lamp); outline-offset: 3px; border-radius: 2px; }

/* The tempo is kept, not heard: the TAP key is the way to line the lights up, so it stays lit. */
.deck[data-via="widget"] .dk-tap { border-color: color-mix(in srgb, var(--lamp) 60%, transparent); }

@media (max-width: 719.98px) {
  .deck .dk-sc { margin: -2px 0 8px; padding-bottom: 8px; gap: 6px 10px; }
  .deck .dk-sc-player { flex-basis: 100%; }
}

/* ---- On air (the DJ's own show on the station playing; html[data-onair] is set by sections.js) --- */

/* The ON AIR lamp colour is --onair, used only by the lamp, and it never flashes (contract ruling 5). */
html[data-onair] .deck .dk-led-live,
.deck[data-show] .dk-led-live {
  background: var(--onair);
  box-shadow: 0 0 6px color-mix(in srgb, var(--onair) 55%, transparent);
}

/* A steady lamp, not the pulsing station dot, while the show is on (no flashing red). */
.deck[data-show][data-source="radio"][data-playing="true"] .dk-led-live { animation: none; }

.deck[data-show] .dk-badge {
  background: color-mix(in srgb, var(--onair) 18%, transparent);
  color: var(--ink);
}

/* ---- Tracklist section headings (tracklists.js entry.head, D's flag 32: "Bonus Mix") -------------- */

.deck .dk-tl-row[data-head] .dk-tl-title {
  color: var(--smoke);
  font: 700 10.5px/1.3 var(--f-body);
  letter-spacing: .12em;
  text-transform: uppercase;
}

.deck .dk-tl-row[data-head] { padding-top: 10px; }

/* ---- Listen again (deck Stations tab) ------------------------------------------------------------ */

.deck .dk-la { margin: 12px 10px 0; }

.deck .dk-la-head {
  margin-bottom: 6px;
  color: var(--smoke);
  font: 700 10.5px/1 var(--f-body);
  letter-spacing: .14em;
  text-transform: uppercase;
}

.deck .la-list { display: grid; gap: 2px; list-style: none; }

.deck .la-play {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 7px 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--ink);
  font: 600 13px/1.3 var(--f-body);
  text-align: left;
  cursor: pointer;
}

.deck .la-play:hover { background: color-mix(in srgb, var(--ink) 6%, transparent); }
.deck .la-play[aria-pressed="true"] { box-shadow: inset 3px 0 0 var(--lamp); }
.deck .la-dur { flex: none; color: var(--smoke); font: 500 12px/1 var(--f-lcd); }
