/* ==========================================================================
   961 Music Web Player — Phase 2: Winamp Player UI
   Now Playing full sheet + mini bar wiring + spectrum visualizer + playlist
   ========================================================================== */

/* ---------- Mini bar upgrades ---------- */
/* S1.1 BLOCKER-UI-01 fix: this rule used to also set `position: relative`, which —
   loading after style.css's `.player-bar { position: fixed; ... }` at equal CSS
   specificity — silently WON the cascade and turned the bottom player bar from a
   fixed, out-of-flow element into a real in-flow flex child of .app-shell. That
   let its own content-driven width (which changes as soon as a track is loaded,
   e.g. once Now Playing has something to show) compete with `.main-content`'s
   `flex:1` for space in the same flex row, directly shrinking the track grid's
   real container width — the actual root cause of the reported card collapse.
   `cursor`/`overflow` (the two rules actually needed here) are preserved. */
.player-bar { cursor: pointer; overflow: hidden; }
.player-bar__progress {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--line);
}
.player-bar__progress span {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--accent);
  box-shadow: 0 0 6px var(--accent);
  transition: width .15s linear;
}
.player-bar__art {
  background-size: cover;
  background-position: center;
  background-color: var(--bg-3);
  position: relative;
  overflow: hidden;
}
.player-bar__art.is-playing::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 60%, rgba(57,255,20,.25));
}
.ctrl-btn {
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  min-width: 44px;
  font-size: 20px;
  color: var(--text-0);
  background: none;
  border: none;
  border-radius: 50%;
}
.ctrl-btn--play { width: 50px; height: 50px; min-width: 50px; font-size: 22px; background: var(--accent-soft); color: var(--accent); }
.ctrl-btn:not(:disabled):active { transform: scale(.92); background: var(--bg-3); }
.ctrl-btn--play:not(:disabled):active { background: var(--accent-soft); }

.player-bar__controls { display: flex; align-items: center; gap: 4px; padding-inline-end: 8px; flex-shrink: 0; }

/* ---------- Now Playing sheet ---------- */
.np-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,.6);
  opacity: 0; pointer-events: none;
  transition: opacity .3s ease;
  z-index: 60;
}
.np-overlay.is-open { opacity: 1; pointer-events: auto; }

.np-sheet {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 70;
  max-width: 480px;
  margin-inline: auto;
  height: 100vh;
  height: 100dvh;
  background: linear-gradient(180deg, var(--bg-1) 0%, var(--bg-0) 100%);
  border-top: 1px solid var(--line);
  border-radius: 20px 20px 0 0;
  padding-top: 10px;
  padding-right: calc(22px + var(--safe-right));
  padding-bottom: calc(20px + var(--safe-bottom));
  padding-left: calc(22px + var(--safe-left));
  display: flex;
  flex-direction: column;
  align-items: center;
  transform: translateY(100%);
  transition: transform .35s cubic-bezier(.2,.8,.2,1);
  overflow-y: auto;
  /* W1-02: the sheet is a fixed-width column; nothing inside it should ever
     scroll sideways. This is a guard, not the fix — the cause is handled at
     .np-extra-controls above. */
  overflow-x: hidden;
  scrollbar-width: thin;
  pointer-events: none;
}
.np-sheet.is-open { transform: translateY(0); pointer-events: auto; }

.np-sheet__handle {
  width: 40px; height: 5px;
  border-radius: 3px;
  background: var(--line);
  margin: 6px auto 4px;
  flex-shrink: 0;
}

.np-spectrum {
  width: 100%;
  height: 64px;
  flex-shrink: 0;
  margin: 6px 0 4px;
  opacity: .9;
}

.np-art-wrap {
  width: 100%;
  aspect-ratio: 1;
  max-width: 300px;
  margin: 8px auto 18px;
  display: grid;
  place-items: center;
}
.np-art {
  width: 100%;
  height: 100%;
  border-radius: var(--radius-l);
  background: linear-gradient(160deg, var(--bg-2), var(--bg-3));
  background-size: cover;
  background-position: center;
  border: 1px solid var(--line);
  box-shadow: 0 20px 50px rgba(0,0,0,.5);
  position: relative;
}
.np-art::before {
  content: "♪";
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-size: 44px;
  color: var(--text-2);
}
.np-art[style*="background-image"]::before { display: none; }

.np-meta { text-align: center; width: 100%; margin-bottom: 14px; }
.np-meta__title {
  font-size: 19px; font-weight: 800; margin: 0 0 4px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.np-meta__artist { margin: 0; color: var(--text-1); font-size: 13.5px; }
.np-live-badge {
  display: inline-block;
  margin-top: 8px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .03em;
  color: #ff4d4f;
  background: rgba(255, 77, 79, .12);
  border: 1px solid rgba(255, 77, 79, .35);
  border-radius: 999px;
  padding: 3px 10px;
}

.np-seek { width: 100%; margin-bottom: 6px; }
.np-seek__range,
.np-volume__range {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 4px;
  border-radius: 2px;
  background: linear-gradient(to right, var(--accent) 0%, var(--accent) var(--val, 0%), var(--line) var(--val, 0%), var(--line) 100%);
  outline: none;
}
.np-seek__range::-webkit-slider-thumb,
.np-volume__range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 15px; height: 15px;
  border-radius: 50%;
  background: var(--text-0);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.np-seek__times {
  display: flex; justify-content: space-between;
  font-size: 11px; color: var(--text-2);
  margin-top: 4px;
  font-variant-numeric: tabular-nums;
}

.np-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin: 10px 0 18px;
  width: 100%;
}
.np-btn {
  width: 48px; height: 48px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--text-0);
  display: grid; place-items: center;
}
.np-btn:active { color: var(--accent); }
.np-btn--toggle { color: var(--text-2); width: 44px; height: 44px; }
.np-btn--toggle.is-active { color: var(--accent); }
.np-btn--play {
  width: 66px; height: 66px;
  background: var(--accent);
  color: #05130a;
  box-shadow: 0 8px 24px var(--accent-soft);
}
.np-btn--play:active { transform: scale(.96); }

.np-volume {
  display: flex; align-items: center; gap: 10px;
  width: 100%; max-width: 260px;
  color: var(--text-2);
  margin-bottom: 18px;
}

/* W1-01 overflow fix: this row held six buttons in a nowrap flex line. Share
   carries a text label (~90px), and the speed button widens when the rate is
   not "1x" ("0.75x" is wider than "1x"). Six buttons + five gaps exceeded the
   sheet's 336px content box, so the sheet grew a horizontal scrollbar. Three
   changes: the row may wrap as a last resort, the gap tightens, and Share
   drops to icon-only inside the sheet (its aria-label and title already carry
   the name, so nothing is lost to assistive tech). */
.np-extra-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 14px;
  max-width: 100%;
}
.np-extra-btn--share .np-extra-btn__label { display: none; }
.np-extra-btn--share { padding: 0; }
.np-extra-btn {
  min-width: 44px;
  height: 44px;
  padding: 0 12px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-2);
  color: var(--text-1);
  font-size: 12.5px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
}
.np-extra-btn.is-active { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
.np-extra-btn#npFavorite.is-active { color: #ff4d4f; }
#npSleepTimerLabel:not(:empty)::before { content: " · "; }

.np-playlist-header {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
}
.np-playlist-toggle {
  flex: 1;
  min-width: 0;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 44px;
  background: none;
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
  color: var(--text-1);
  font-size: 13px;
  font-weight: 600;
}
.np-playlist-toggle #npQueueCount {
  background: var(--accent-soft);
  color: var(--accent);
  border-radius: 20px;
  padding: 1px 8px;
  font-size: 11.5px;
}
/* S1.1 BLOCKER-PLAYER-02 fix: the Clear button — new element, styled to match the
   existing .np-extra-btn pill-button convention already used elsewhere in this
   panel (sleep timer / EQ / lyrics), so it doesn't look like a one-off. */
.np-playlist-clear {
  flex-shrink: 0;
  min-height: 44px;
  padding: 0 14px;
  border-radius: var(--radius-m);
  border: 1px solid var(--line);
  background: var(--bg-2);
  color: var(--text-2);
  font-size: 12.5px;
  font-weight: 600;
}
.np-playlist-clear:active { color: var(--text-1); }

.np-playlist {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  width: 100%;
  max-height: 40vh;
  overflow-y: auto;
  /* S1.1 BLOCKER-PLAYER-02 fix: .np-sheet is a flex column with its own overflow-y:auto.
     A flex item that is itself a scroll container (overflow-y:auto here) gets an
     automatic minimum size of ~0 instead of its content size per the flexbox spec —
     so when the sheet's stacked content (art/meta/seek/controls/extra buttons/this
     list) exceeds the sheet's available height, flex-shrink was crushing this panel
     down to a sliver (measured 14px tall on a 390px-wide phone, 91px on desktop —
     both far short of the intended 40vh/360px) instead of showing the queued tracks.
     flex-shrink:0 keeps this panel at its intended size; if the sheet's total content
     doesn't fit, the sheet's own overflow-y:auto (already present) lets the user
     scroll the sheet instead of silently crushing the queue list to invisible. */
  flex-shrink: 0;
}
.np-playlist__item {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 52px;
  padding: 6px 8px;
  border-radius: var(--radius-m);
  cursor: pointer;
}
.np-playlist__item:active { background: var(--bg-2); }
.np-playlist__item.is-active { background: var(--accent-soft); }
.np-playlist__item.is-active .np-playlist__title { color: var(--accent); }
.np-playlist__num {
  width: 22px; text-align: center;
  font-size: 11.5px; color: var(--text-2);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
.np-playlist__item.is-active .np-playlist__num { color: var(--accent); }
.np-playlist__text { flex: 1; min-width: 0; }
.np-playlist__title {
  display: block; font-size: 13.5px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.np-playlist__artist { display: block; font-size: 11.5px; color: var(--text-2); }
.np-playlist__dur { font-size: 11px; color: var(--text-2); flex-shrink: 0; font-variant-numeric: tabular-nums; }
/* S1.1 BLOCKER-PLAYER-02 fix: per-track remove button — new element. */
.np-playlist__remove {
  flex-shrink: 0;
  width: 28px; height: 28px;
  border-radius: 999px;
  border: none;
  background: transparent;
  color: var(--text-2);
  font-size: 13px;
  line-height: 1;
}
.np-playlist__remove:active { background: var(--bg-2); color: var(--text-1); }
/* S1.1 BLOCKER-PLAYER-02 fix: clean empty state instead of a blank <ul>. */
.np-playlist__empty {
  padding: 24px 8px;
  text-align: center;
  color: var(--text-2);
  font-size: 13px;
}

/* ---------- Desktop ---------- */
@media (min-width: 900px) {
  .np-sheet {
    inset-inline-start: auto; inset-inline-end: 24px; bottom: 24px;
    max-width: 380px;
    height: auto;
    max-height: calc(100vh - 48px);
    border-radius: var(--radius-l);
    border: 1px solid var(--line);
    box-shadow: 0 30px 80px rgba(0,0,0,.6);
    transform: translateY(20px) scale(.97);
    opacity: 0;
    transition: transform .25s ease, opacity .25s ease;
  }
  .np-sheet.is-open { transform: translateY(0) scale(1); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .np-sheet, .np-overlay { transition: none; }
}

/* ---------------- Equalizer panel (Phase 9) ---------------- */
.eq-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.55);
  z-index: 70;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease;
}
.eq-overlay.is-open { opacity: 1; pointer-events: auto; }

.eq-panel {
  position: fixed;
  left: 50%;
  bottom: 0;
  transform: translate(-50%, 100%);
  width: min(94vw, 480px);
  max-height: 80vh;
  overflow-y: auto;
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-bottom: none;
  border-radius: var(--radius-l) var(--radius-l) 0 0;
  padding-top: 16px;
  padding-right: calc(18px + var(--safe-right));
  padding-bottom: calc(var(--safe-bottom) + 20px);
  padding-left: calc(18px + var(--safe-left));
  z-index: 71;
  transition: transform .25s ease;
  pointer-events: none;
}
.eq-panel.is-open { transform: translate(-50%, 0); pointer-events: auto; }

.eq-panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}
.eq-panel__title { font-weight: 800; font-size: 15px; }
.eq-panel__close { background: none; border: none; color: var(--text-2); font-size: 16px; padding: 6px; }

.eq-panel__toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}
.eq-btn {
  height: 44px;
  padding: 0 16px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-2);
  color: var(--text-1);
  font-size: 12px;
  font-weight: 800;
}
.eq-btn.is-active { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
.eq-presets {
  flex: 1;
  height: 34px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-2);
  color: var(--text-0);
  padding: 0 10px;
  font-size: 12.5px;
}

.eq-note {
  font-size: 11.5px;
  color: var(--accent-2);
  background: rgba(255,157,47,.1);
  border: 1px solid rgba(255,157,47,.3);
  border-radius: var(--radius-s);
  padding: 8px 10px;
  margin-bottom: 12px;
}

.eq-bands {
  display: flex;
  gap: 10px;
  align-items: stretch;
}
.eq-bands__group {
  flex: 1;
  display: flex;
  justify-content: space-between;
  gap: 4px;
}
.eq-band {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.eq-band--preamp { padding-inline-end: 10px; border-inline-end: 1px solid var(--line); }
.eq-band__slider {
  width: 20px;
  height: 120px;
  writing-mode: vertical-lr;
  direction: rtl;
  accent-color: var(--accent);
}
.eq-band__label { font-size: 9.5px; color: var(--text-2); white-space: nowrap; }
.eq-band__value { font-size: 9px; color: var(--accent); min-height: 11px; }

/* ---------------- Landscape support — IOS-SAFARI-01-R2 ----------------
 * Short iPhone landscape viewports need one clear scroll owner.
 *
 * The previous landscape override kept the portrait sheet's 480px max-width,
 * while also turning the sheet into a two-column grid and leaving BOTH the
 * sheet and Queue as independent vertical scroll containers. On iOS Safari
 * this produces a narrow/split-looking player and brittle nested scrolling:
 * the menu can be unreachable, and the Queue can appear present but refuse
 * to pan normally.
 *
 * R2:
 *  - use the full landscape viewport (respecting safe areas);
 *  - explicitly place player regions instead of relying on implicit grid rows;
 *  - make the Now Playing sheet the ONLY vertical scroll owner in landscape;
 *  - let the Queue expand into that sheet scroll instead of nesting its own
 *    scrolling region;
 *  - retain the portrait layout unchanged.
 */
@media (orientation: landscape) and (max-height: 520px) {
  .np-sheet {
    inset: 0;
    width: 100%;
    max-width: none;
    height: 100vh;
    height: 100dvh;
    max-height: none;
    margin: 0;
    border-radius: 0;
    border-inline: 0;
    padding-top: 6px;
    padding-right: calc(14px + var(--safe-right));
    padding-bottom: calc(14px + var(--safe-bottom));
    padding-left: calc(14px + var(--safe-left));

    display: grid;
    grid-template-columns: minmax(132px, 31vw) minmax(0, 1fr);
    grid-template-rows: auto auto auto auto auto auto auto auto;
    align-content: start;
    align-items: start;
    column-gap: clamp(12px, 3vw, 24px);
    row-gap: 4px;

    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
    touch-action: pan-y;
  }

  .np-sheet__handle {
    grid-column: 1 / -1;
    grid-row: 1;
    margin-block: 2px 4px;
  }

  .np-spectrum {
    grid-column: 1;
    grid-row: 2;
    width: 100%;
    height: 36px;
    margin: 0 0 6px;
  }

  .np-art-wrap {
    grid-column: 1;
    grid-row: 3 / span 5;
    width: min(100%, 180px);
    max-width: 180px;
    margin: 0 auto;
    aspect-ratio: 1;
    align-self: start;
  }

  .np-art {
    width: 100%;
    height: 100%;
    max-width: none;
  }

  .np-meta {
    grid-column: 2;
    grid-row: 2;
    width: 100%;
    margin: 0 0 4px;
    text-align: start;
  }

  .np-meta__title {
    white-space: normal;
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  .np-seek {
    grid-column: 2;
    grid-row: 3;
    width: 100%;
    margin-bottom: 2px;
  }

  .np-controls {
    grid-column: 2;
    grid-row: 4;
    width: 100%;
    margin: 2px 0 4px;
    gap: 4px;
  }

  .np-btn {
    width: 44px;
    height: 44px;
  }

  .np-btn--play {
    width: 54px;
    height: 54px;
  }

  .np-volume {
    grid-column: 2;
    grid-row: 5;
    width: 100%;
    max-width: none;
    margin: 0 0 4px;
  }

  .np-extra-controls {
    grid-column: 2;
    grid-row: 6;
    width: 100%;
    justify-content: flex-start;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 4px;
  }

  .np-playlist-header {
    grid-column: 2;
    grid-row: 7;
    width: 100%;
    margin-top: 2px;
  }

  .np-playlist {
    grid-column: 2;
    grid-row: 8;
    width: 100%;
    max-height: none;
    overflow: visible;
    margin: 6px 0 0;
    padding-bottom: calc(8px + var(--safe-bottom));
    flex-shrink: 0;
  }

  .np-playlist__item {
    min-height: 48px;
  }

  .eq-panel {
    width: 100%;
    max-width: none;
    max-height: 100vh;
    max-height: 100dvh;
    border-radius: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
    touch-action: pan-y;
  }
}

@media (orientation: portrait) {
  /* Portrait remains the tuned default layout. */
}

/* ---------------- Lyrics panel ---------------- */
.lyrics-panel { max-height: 70vh; }
.lyrics-body {
  max-height: 50vh;
  overflow-y: auto;
  font-size: 14px;
  line-height: 1.9;
  color: var(--text-2);
  white-space: pre-wrap;
}
.lyrics-line {
  padding: 4px 0;
  transition: color .15s ease, transform .15s ease;
}
.lyrics-line.is-active {
  color: var(--accent);
  font-weight: 700;
  transform: scale(1.03);
  transform-origin: left center;
}
.lyrics-empty { color: var(--text-2); font-size: 13px; padding: 20px 0; text-align: center; }


/* ==========================================================================
   SKIN-R2 — Now Playing / Queue refinement
   ========================================================================== */
.np-overlay {
  background: rgba(2,4,9,.68);
  backdrop-filter: blur(5px);
}
.np-sheet {
  background:
    radial-gradient(520px 240px at 50% 0%, rgba(88,76,188,.12), transparent 68%),
    rgba(9,12,20,.98);
  border-color: rgba(173,184,214,.14);
}

/* WAVE7 — Apple-style grabber: one clear tactile affordance, no label or arrow. */
.np-sheet__minimize {
  width: 64px;
  height: 28px;
  min-height: 28px;
  padding: 0;
  margin: -2px auto 5px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 999px;
  background: transparent;
  cursor: pointer;
  touch-action: manipulation;
}
.np-sheet__grabber {
  width: 46px;
  height: 5px;
  border-radius: 999px;
  background: linear-gradient(90deg, #8f7cff, #b9adff);
  box-shadow: 0 0 0 1px rgba(255,255,255,.06), 0 3px 16px rgba(230,57,70,.34);
  transition: width .16s ease, filter .16s ease, transform .16s ease;
}
.np-sheet__minimize:hover .np-sheet__grabber,
.np-sheet__minimize:focus-visible .np-sheet__grabber {
  width: 52px;
  filter: brightness(1.15);
}
.np-sheet__minimize:active .np-sheet__grabber {
  transform: scaleX(.92);
}
.np-sheet__minimize:focus-visible {
  outline: 2px solid rgba(143,124,255,.82);
  outline-offset: 2px;
}


/* Spectrum stays a feature, but stops dominating the player as rows of bright dots. */
.np-spectrum {
  height: 26px;
  margin: 2px 0 8px;
  opacity: .22;
  filter: saturate(.55);
  border-radius: 10px;
  overflow: hidden;
}

.np-art-wrap {
  max-width: 320px;
  margin-top: 4px;
  margin-bottom: 16px;
  transition: aspect-ratio .18s ease, max-width .18s ease;
}
.np-art-wrap.is-youtube {
  aspect-ratio: 16 / 9;
  max-width: 360px;
}
.np-art {
  border-radius: 18px;
  border-color: rgba(173,184,214,.14);
  box-shadow: 0 24px 64px rgba(0,0,0,.42);
}
.np-meta__title {
  font-size: clamp(18px, 4vw, 22px);
  white-space: normal;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-height: 1.25;
}
.np-controls {
  gap: 8px;
}
.np-btn {
  transition: background .16s ease, color .16s ease, transform .16s ease;
}
.np-btn:hover { background: rgba(255,255,255,.05); }
.np-btn--play {
  background: var(--accent);
  color: #fff;
  box-shadow: 0 10px 28px rgba(230,57,70,.28);
}

.np-playlist-header {
  border-top-color: rgba(173,184,214,.11);
}
.np-playlist-toggle {
  color: var(--text-0);
}
.np-playlist__item {
  border-radius: 12px;
  transition: background .15s ease;
}
.np-playlist__item:hover { background: rgba(255,255,255,.035); }
.np-playlist__item.is-active {
  background: rgba(230,57,70,.09);
}
.np-playlist__num {
  color: var(--text-2);
}
.np-playlist__item.is-active .np-playlist__num {
  color: #c9c0ff;
}
.np-playlist-clear {
  color: var(--text-2);
}
.np-playlist-clear:hover { color: var(--text-0); }

@media (min-width: 900px) {
  .np-sheet {
    inset-inline-end: 22px;
    bottom: 22px;
    max-width: 420px;
    max-height: calc(100vh - 44px);
    border-radius: 22px;
  }
}
@media (max-width: 520px) {
  .np-sheet__minimize-label { display: inline; }
  .np-art-wrap.is-youtube { max-width: 100%; }
  .np-spectrum { height: 18px; margin-bottom: 6px; }
}
@media (prefers-reduced-motion: reduce) {
  .np-sheet__minimize,
  .np-art-wrap,
  .np-btn { transition: none !important; }
}


/* ==========================================================================
   961 Music — SKIN-08 final player accessibility polish
   ========================================================================== */
.np-sheet__minimize:focus-visible,
.np-btn:focus-visible,
.np-extra-btn:focus-visible,
.np-playlist-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
[dir="rtl"] .np-sheet__minimize-icon {
  transform: translateY(-1px);
}
@media (max-width: 520px) {
  .np-sheet {
    padding-bottom: calc(14px + var(--safe-bottom));
  }
}


/* SHARE-01 — full-player share action */
.np-extra-btn--share {
  gap: 7px;
  padding-inline: 11px;
  color: #d8d1ff;
  background: rgba(230,57,70,.09);
  border: 1px solid rgba(230,57,70,.16);
}
.np-extra-btn--share:hover {
  background: rgba(230,57,70,.15);
  border-color: rgba(230,57,70,.30);
}
.np-extra-btn__label {
  font-size: 11.5px;
  font-weight: 750;
}/* PHASE18-03 — Public Lyrics UX / Accessibility */
.lyrics-panel{width:min(94vw,620px);max-height:min(78dvh,760px);outline:none}
.lyrics-panel:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 70%,transparent)}
.lyrics-close{min-width:44px;min-height:44px}
.lyrics-context{display:flex;align-items:center;justify-content:space-between;gap:14px;margin:0 0 14px;padding:12px 14px;border:1px solid rgba(173,184,214,.12);border-radius:13px;background:rgba(255,255,255,.025)}
.lyrics-context__copy{min-width:0;display:grid;gap:3px}
.lyrics-context__title,.lyrics-context__artist{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lyrics-context__title{color:var(--text-0);font-size:13px;line-height:1.3}
.lyrics-context__artist{color:var(--text-2);font-size:11.5px}
.lyrics-sync-badge{flex:0 0 auto;display:inline-flex;align-items:center;min-height:28px;padding:4px 9px;border:1px solid rgba(230,57,70,.24);border-radius:999px;background:rgba(230,57,70,.10);color:var(--text-1);font-size:10.5px;font-weight:800}
.lyrics-body{overscroll-behavior:contain;scrollbar-gutter:stable;padding-inline:2px}
.lyrics-body:focus-visible{outline:2px solid color-mix(in srgb,var(--accent) 60%,transparent);outline-offset:4px;border-radius:8px}
.lyrics-line{border-radius:8px;padding:6px 8px}
.lyrics-line--plain{unicode-bidi:plaintext}
.lyrics-line.is-active{background:rgba(230,57,70,.08)}
[dir="rtl"] .lyrics-line.is-active{transform-origin:right center}
.lyrics-empty,.lyrics-loading{min-height:112px;display:grid;place-items:center;padding:22px 14px;line-height:1.55}
@media(max-width:600px){
  .lyrics-panel{width:calc(100vw - 20px);max-height:min(84dvh,760px)}
  .lyrics-context{margin-bottom:10px;padding:10px 12px}
  .lyrics-body{max-height:58dvh;font-size:15px;line-height:1.85}
  .lyrics-line{padding:7px 6px}
}
@media(prefers-reduced-motion:reduce){
  .lyrics-line,.lyrics-panel,.eq-overlay{transition:none!important}
  .lyrics-line.is-active{transform:none}
}

/* W4 — full player uses the same stroke-icon family as the mini player. */
.np-btn .ui-icon,
.np-extra-btn .ui-icon {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}


/* WAVE7 — live radio only shows controls that actually apply to live listening. */
.np-sheet--live .np-seek,
.np-sheet--live #npSpeed,
.np-sheet--live #npEqToggle,
.np-sheet--live #npShuffle,
.np-sheet--live #npRepeat {
  display: none !important;
}
.np-sheet--live .np-controls {
  justify-content: center;
  gap: 18px;
  margin-top: 8px;
}
.np-sheet--live .np-extra-controls {
  justify-content: center;
}

/* ---------------- W1-03: short-viewport artwork clamp ---------------- */
/* On desktop the sheet is capped at calc(100vh - 48px). With a 300px artwork
   plus meta, seek, controls, volume, the secondary row and the queue header,
   the stack exceeds that cap on laptop-height screens and the sheet scrolls
   vertically. Shrinking the artwork on short viewports keeps the whole player
   visible without scrolling. Tall screens are unaffected. */
@media (min-width: 900px) and (max-height: 860px) {
  .np-art { max-width: 220px; }
  .np-sheet { padding-top: 8px; }
}
@media (min-width: 900px) and (max-height: 740px) {
  .np-art { max-width: 170px; }
  .np-meta { margin-bottom: 10px; }
}

/* ---------------- W1b: fixed-width speed button ---------------- */
/* The speed button's label changes between "1x", "0.75x", "1.25x" and "2x",
   and its width followed the label — so the secondary row reflowed every time
   the rate changed. Pinning the width removes the variable: every rate now
   occupies the same box, and nothing around it moves. Tabular figures keep the
   digits from shifting inside it. */
.np-extra-btn#npSpeed {
  min-width: 62px;
  width: 62px;
  padding: 0;
  font-variant-numeric: tabular-nums;
}
