/* --- player card: shared between the in-page floating card and the pop-out
   (Document Picture-in-Picture) window (player.js / pip.js build the same
   .player-card markup in two different documents — see pip.js's header
   comment). Sizing here targets the in-page card's fixed ~340px width
   (plain rem units); .player-card--pip below layers fluid clamp(vw/vh)
   overrides on top, since that surface is an arbitrary OS-granted window
   size rather than a fixed-width box on a full page — reusing vw/vh units
   here directly would scale off the whole browser viewport, not the card. */
.player-card[hidden] { display: none; }
.player-card {
  display: flex; flex-direction: column;
  background: var(--bg); color: var(--text);
  overflow: hidden;
}
/* The deck page is the player UI; the card would be a duplicate set of
   controls, but the (turbo-permanent) element and its <audio> stay alive.
   Same idea while the pop-out window (pip.js) is open. */
body:has(.deck) .player-card--floating,
.player--piped .player-card--floating,
body:has(.deck) .player-mini,
.player--piped .player-mini { display: none; }

/* --- minimized strip: cover + "Artist – Title" + transport + expand/close.
   Same corner and width as the floating card it stands in for. --- */
.player-mini {
  position: fixed; right: 1rem; bottom: 1rem; z-index: 50;
  width: min(340px, calc(100vw - 2rem));
  display: flex; align-items: center; gap: 0.2rem;
  padding: 0.45rem 0.55rem;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 -8px 24px var(--shadow);
}
.player-mini[hidden] { display: none; }
.player-mini__cover {
  position: relative; flex: none;
  width: 44px; height: 44px; border-radius: 8px; overflow: hidden;
  background: var(--accent-3); margin-right: 0.4rem;
}
.player-mini__cover img { width: 100%; height: 100%; object-fit: cover; }
.player-mini__cover img[hidden] { display: none; }
.player-mini__cover-empty {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 1.2rem; color: var(--text-dim);
}
.player-mini__cover-empty[hidden] { display: none; }
.player-mini__progress {
  position: absolute; left: 0; bottom: 0; height: 3px; width: 0%;
  background: var(--accent); transition: width 0.2s linear;
}
.player-mini__label {
  flex: 1; min-width: 0;
  font-weight: 600; font-size: 0.88rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.player-mini button {
  background: none; border: none; color: var(--text);
  width: 2rem; height: 2rem; border-radius: 6px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
}
.player-mini button:hover { background: var(--soft); }
.player-mini button svg { width: 18px; height: 18px; fill: currentColor; }
.player-mini svg[hidden] { display: none; }
.player-mini__quiet { color: var(--text-dim); }
.player-mini__quiet:hover { color: var(--text); }

.player-card__header {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.6rem 0.75rem; border-bottom: 1px solid var(--line);
}
.player-card__label { flex: 1; margin: 0; font-size: 0.75rem; font-weight: 700; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.08em; }
.player-card__header-actions { display: flex; align-items: center; gap: 0.125rem; }
.player-card__header-actions button, .player-card__pip-button {
  background: none; border: none; color: var(--text-dim);
  width: 2rem; height: 2rem; border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center;
}
.player-card__header-actions button:hover, .player-card__pip-button:hover { color: var(--text); background: var(--soft); }
.player-card__header-actions button.active { color: var(--accent); }
.player-card__header-actions svg, .player-card__pip-button svg { width: 18px; height: 18px; fill: currentColor; }
.player--piped .player-card__pip-button { color: var(--accent); }

.player-card__cover {
  /* no `display` declared here: flex items are auto-blockified when shown,
     but an explicit `display: block` would have the same specificity as the
     UA stylesheet's `[hidden] { display: none }` and — as the later,
     author-stylesheet rule — win the tie, showing the cover even while
     hidden. */
  width: 100%; height: 50%; flex: 0 0 50%;
  background: var(--accent-3); border-bottom: 1px solid var(--line);
  object-fit: cover;
}
/* albums with no art (docs/DESIGN_PALETTE.md's card__cover--empty convention,
   also used on the album grid/header) — this DOES need `display: flex` (to
   center the glyph), so it must win over `[hidden]` deliberately via source
   order rather than by omission like the plain cover above. */
.player-card__cover--empty { display: flex; align-items: center; justify-content: center; font-size: 2.5rem; color: var(--text-dim); }
.player-card__cover--empty[hidden] { display: none; }
/* the queue takes over the cover's visual slot when opened */
.player-card:has(.player-card__queue:not([hidden])) .player-card__cover { display: none; }

/* title/artist/seek/controls/volume block — always present. flex:1 against
   the cover's fixed 50% (closed queue) or against .player-card__queue's
   flex:3 (open queue) is what yields the 50%/25% splits, no state-specific
   sizing rule needed (see .player-card__queue below). */
.player-card__now-playing {
  flex: 1 1 0; min-height: 0;
  display: flex; flex-direction: column; justify-content: center;
  padding: 0.9rem 0.9rem 0.75rem;
}

.player-card__meta { text-align: center; overflow: hidden; }
.player-card__title { font-weight: 700; font-size: 1.05rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.player-card__artist { color: var(--text-dim); font-size: 0.85rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-bottom: 0.6rem; }
/* queue open: title/artist merge onto one "Title — Artist" row since
   .player-card__now-playing is compacted to 25% height */
.player-card:has(.player-card__queue:not([hidden])) .player-card__meta { display: flex; align-items: baseline; justify-content: center; gap: 0.3rem; }
.player-card:has(.player-card__queue:not([hidden])) .player-card__title,
.player-card:has(.player-card__queue:not([hidden])) .player-card__artist { max-width: 45%; margin-bottom: 0; }
.player-card:has(.player-card__queue:not([hidden])) .player-card__artist:not(:empty)::before { content: "— "; }

.player-card__seek { display: flex; align-items: center; gap: 0.5rem; }
.player-card__seek span { color: var(--text-dim); font-size: 0.75rem; font-variant-numeric: tabular-nums; }
.player-card__seek input[type="range"] { flex: 1; accent-color: var(--accent-2); min-width: 0; }

/* queue open: .player-card__now-playing's own content is taller than its
   25% allocation at default sizing — tighten padding and shrink the center
   transport buttons (edge buttons already reduced, see -edge below) so
   everything fits inside the space actually available. */
.player-card:has(.player-card__queue:not([hidden])) .player-card__now-playing { padding: 0.5rem 0.9rem 0.4rem; }
.player-card:has(.player-card__queue:not([hidden])) .player-card__controls { margin: 0.25rem 0; }
.player-card:has(.player-card__queue:not([hidden])) .player-card__volume { margin-top: 0.1rem; }
.player-card:has(.player-card__queue:not([hidden])) .player-card__controls-center button {
  width: 2rem; height: 2rem;
}
.player-card:has(.player-card__queue:not([hidden])) .player-card__controls-center button svg {
  width: 16px; height: 16px;
}

.player-card__controls { display: flex; align-items: center; justify-content: space-between; margin: 0.5rem 0; }
.player-card__controls-center { display: flex; align-items: center; justify-content: center; gap: 0.25rem; }
/* left group is shuffle + an invisible spacer sized to match the right
   group (repeat) so both edges stay equal width and
   .player-card__controls-center renders truly centered, not skewed toward shuffle. */
.player-card__controls-edge-group { display: flex; align-items: center; gap: 0.125rem; position: relative; }
.player-card__controls button {
  background: none; border: none; color: var(--text);
  width: 2.6rem; height: 2.6rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background 0.15s ease;
}
.player-card__controls button svg { width: 20px; height: 20px; fill: currentColor; }
/* the hidden attribute isn't honoured on SVG elements by UA stylesheets */
.player-card__controls svg[hidden] { display: none; }
/* edge buttons (shuffle/repeat) run smaller than prev/play/next. Specificity
   note: ".player-card__controls-edge" alone (0,1,0) loses to
   ".player-card__controls button" (0,1,1) regardless of source order, so
   this has to be the compound ".player-card__controls .-edge" (0,2,0). */
.player-card__controls .player-card__controls-edge,
.player-card__controls-spacer { width: 2rem; height: 2rem; }
.player-card__controls-spacer { visibility: hidden; }
.player-card__controls .player-card__controls-edge svg { width: 16px; height: 16px; }
.player-card__controls button:hover { background: var(--soft); }
.player-card__controls button.active { color: var(--accent); }
.player-card__play { background: var(--accent-2) !important; color: var(--bg) !important; }
.player-card__play:hover { opacity: 0.85; }
.player-card__repeat { position: relative; }
.player-card__repeat--one::after {
  content: "1"; position: absolute; top: 3px; right: 3px;
  font-size: 0.6rem; font-weight: 700; color: var(--accent);
}

.player-card__volume { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.25rem; }
.player-card__volume button {
  background: none; border: none; color: var(--text-dim);
  width: 1.8rem; height: 1.8rem; border-radius: 6px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
}
.player-card__volume button svg { width: 16px; height: 16px; fill: currentColor; }
.player-card__volume svg[hidden] { display: none; }
.player-card__volume button:hover { color: var(--text); background: var(--soft); }
.player-card__volume-slider { flex: 1; accent-color: var(--accent-2); min-width: 0; }

/* --- queue panel: shared by both surfaces ---------------------------------- */
/* flex:3 vs .player-card__now-playing's flex:1 above yields the 75%/25%
   split of whatever space is left once the header and (if visible) cover
   are laid out; irrelevant while [hidden] removes this from flex layout
   entirely. */
.player-card__queue { flex: 3 1 0; min-height: 0; display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.player-card__queue[hidden] { display: none; }
.player-card__queue header {
  display: flex; align-items: center; gap: 0.5rem; flex: none;
  padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--line);
}
.player-card__queue h2 { flex: 1; margin: 0; font-size: 0.75rem; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.08em; }
.player-card__queue header button:first-of-type {
  background: none; border: 1px solid var(--line); color: var(--text-dim);
  border-radius: 6px; padding: 0.2rem 0.6rem; font-size: 0.8rem;
}
.player-card__queue header button:first-of-type:hover { color: var(--text); border-color: var(--text); }
.player-card__queue header button:last-child {
  background: none; border: none; color: var(--text-dim);
  width: 1.6rem; height: 1.6rem; border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center; flex: none;
}
.player-card__queue header button:last-child svg { width: 14px; height: 14px; fill: currentColor; }
.player-card__queue header button:last-child:hover { color: var(--text); background: var(--soft); }

.player-card__queue ol { list-style: none; margin: 0; padding: 0.25rem 0.5rem; overflow-y: auto; }
.player-card__queue li {
  display: flex; align-items: center; border-top: 2px solid transparent;
  transition: opacity 0.15s ease;
}
.player-card__queue li.dragging { opacity: 0.4; }
.player-card__queue li.drop-target { border-top-color: var(--accent); }
.player-card__queue-handle {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 1.4rem; height: 1.8rem; color: var(--text-dim); cursor: grab;
}
.player-card__queue-handle svg { width: 13px; height: 13px; fill: currentColor; }
.player-card__queue li button:first-of-type {
  flex: 1; text-align: left; background: none; border: none; color: var(--text);
  padding: 0.4rem 0.5rem; border-radius: 6px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.player-card__queue li button:first-of-type:hover { background: var(--soft); }
.player-card__queue li.current button:first-of-type { color: var(--accent); font-weight: 700; }
.player-card__queue li button:last-child {
  background: none; border: none; color: var(--text-dim); border-radius: 6px;
  width: 1.8rem; height: 1.8rem; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
}
.player-card__queue li button:last-child svg { width: 14px; height: 14px; fill: currentColor; }
.player-card__queue li button:last-child:hover { color: var(--danger); }

/* --- in-page floating card (bottom-right) ---------------------------------- */
.player-card--floating {
  position: fixed; right: 1rem; bottom: 1rem; z-index: 50;
  width: min(340px, calc(100vw - 2rem));
  /* a *definite* height, not max-height: the cover/now-playing/queue split
     is percentage-based (see .player-card__cover, .player-card__queue), and
     percentages need something definite to resolve against — with only
     max-height, this is an auto-height flex container, and Chromium
     collapses the flex:1 now-playing child to ~0 height in that case,
     clipping its content invisible against the card's overflow:hidden. */
  height: min(480px, calc(100vh - 2rem));
  border-radius: 10px; border: 1px solid var(--line);
  box-shadow: 0 -8px 24px var(--shadow);
}

/* --- pop-out window (pip.js, built fresh in the Document Picture-in-Picture
   window). Fluid clamp(vw/vh) overrides layered on the shared rules above —
   this surface's viewport IS the card, so vw/vh here scale correctly, unlike
   the fixed-size in-page card. --- */
.player-card--pip { height: 100%; }
.player-card--pip .player-card__label { font-size: clamp(0.75rem, 2.2vw, 0.9rem); }
.player-card--pip .player-card__header-actions button { width: clamp(1.6rem, 4.5vw, 2rem); height: clamp(1.6rem, 4.5vw, 2rem); }
.player-card--pip .player-card__header-actions svg { width: clamp(14px, 4vw, 18px); height: clamp(14px, 4vw, 18px); }
.player-card--pip .player-card__title { font-size: clamp(1rem, 4.2vw, 1.375rem); }
.player-card--pip .player-card__artist { font-size: clamp(0.85rem, 3.4vw, 1.125rem); }
.player-card--pip .player-card__seek span { font-size: clamp(0.75rem, 2.8vw, 0.9rem); }
.player-card--pip .player-card__controls button { width: clamp(2.5rem, 11vw, 3.5rem); height: clamp(2.5rem, 11vw, 3.5rem); }
.player-card--pip .player-card__controls button svg { width: clamp(18px, 7.5vw, 25px); height: clamp(18px, 7.5vw, 25px); }
.player-card--pip .player-card__controls .player-card__controls-edge,
.player-card--pip .player-card__controls-spacer { width: clamp(1.75rem, 8vw, 2.5rem); height: clamp(1.75rem, 8vw, 2.5rem); }
.player-card--pip .player-card__controls .player-card__controls-edge svg { width: clamp(14px, 5.5vw, 18px); height: clamp(14px, 5.5vw, 18px); }
.player-card--pip.player-card:has(.player-card__queue:not([hidden])) .player-card__controls-center button {
  width: clamp(1.75rem, 9vh, 2.75rem); height: clamp(1.75rem, 9vh, 2.75rem);
}
.player-card--pip.player-card:has(.player-card__queue:not([hidden])) .player-card__controls-center button svg {
  width: clamp(14px, 6vh, 20px); height: clamp(14px, 6vh, 20px);
}
