.player-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  /* min-height, not height: padding-bottom below adds the safe area as extra
     room rather than eating into the bar's normal content height, so a fixed
     height here would clip play/seek controls upward on notched phones. */
  min-height: var(--player-h);
  z-index: var(--z-player);
  background: var(--surface);
  border-top: 1px solid var(--border);
  display: grid;
  /* The centre column is capped well below the old 640px so the side columns keep
     enough width for the track title — it was being squeezed to ~105px. minmax(0,1fr)
     rather than 1fr lets the sides actually shrink instead of overflowing. */
  grid-template-columns: minmax(0, 1fr) minmax(320px, 520px) minmax(0, 1fr);
  align-items: center;
  padding: 0 calc(var(--space-6) + var(--safe-right)) var(--safe-bottom) calc(var(--space-6) + var(--safe-left));
  gap: var(--space-5);
  transform: translateY(100%);
  transition: transform var(--dur-slow) var(--ease-out);
  box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.35);
}

/* Controls must never be squeezed below their tap target by a long track title. */
.player-bar .icon-btn {
  flex-shrink: 0;
}

.player-bar.is-visible {
  transform: translateY(0);
}

.player-track {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
}

.player-track__art {
  width: 56px;
  height: 56px;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, 0.85);
  overflow: hidden;
  transition: transform var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}

/* The artwork links to the track page; lift it slightly so that is discoverable. */
.player-track__art[href]:hover,
.player-track__art[href]:focus-visible {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.player-track__art .track-row__eq {
  display: none;
  height: 18px;
}

body.is-playing .player-track__art .player-track__note {
  display: none;
}

body.is-playing .player-track__art .track-row__eq {
  display: flex;
}

/* flex: 1 is what makes the title claim the leftover width. Without it the meta
   sized to content and collapsed to nothing once the column got tight. */
.player-track__meta {
  flex: 1;
  min-width: 0;
}

/* Both are anchors — block is required for ellipsis to apply at all. */
.player-track__title,
.player-track__artist {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

.player-track__title {
  font-weight: 600;
  font-size: var(--text-sm);
}

.player-track__artist {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
}

.player-track__title[href]:hover,
.player-track__title[href]:focus-visible,
.player-track__artist[href]:hover,
.player-track__artist[href]:focus-visible {
  text-decoration: underline;
}

.player-track__artist[href]:hover {
  color: var(--text-secondary);
}

.player-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

.player-controls {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.player-controls .icon-btn.play-toggle {
  width: 40px;
  height: 40px;
  background: var(--text-primary);
  color: var(--bg);
}

.player-controls .icon-btn.play-toggle:hover {
  background: var(--accent);
  color: var(--text-on-accent);
}

/* Transport controls stay left-to-right in every locale: elapsed time on the left,
   total on the right, fill growing rightward. This is the universal convention for
   media players, and it also keeps the scrub maths direction-free — see
   _bindScrub() in js/player.js, which relies on these two rules. */
.player-progress {
  direction: ltr;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
}

.player-time {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
  /* min-width, not width: an hour-long podcast reads 1:02:33 and would clip. */
  min-width: 38px;
  flex-shrink: 0;
}

.player-time--end {
  text-align: end;
}

.progress-track {
  position: relative;
  flex: 1;
  /* Taller than the visible bar on purpose: a 4px line is a miserable pointer
     target, so the hit area is 16px while the rail stays thin. */
  height: 16px;
  display: flex;
  align-items: center;
  cursor: pointer;
  touch-action: none;
}

.progress-track__bg {
  position: relative;
  width: 100%;
  height: 4px;
  border-radius: var(--radius-full);
  background: var(--surface-3);
  overflow: visible;
  transition: height var(--dur-fast) var(--ease-out);
}

/* Thicken on interaction — the standard cue that the rail is draggable. */
.progress-track:hover .progress-track__bg,
.progress-track:focus-visible .progress-track__bg,
.progress-track.is-scrubbing .progress-track__bg {
  height: 6px;
}

.progress-track__fill {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: 0%;
  background: var(--accent);
  border-radius: var(--radius-full);
}

.progress-track:hover .progress-track__fill,
.progress-track.is-scrubbing .progress-track__fill {
  background: var(--accent-bright);
}

.progress-track__thumb {
  position: absolute;
  top: 50%;
  inset-inline-start: 0%;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--text-primary);
  transform: translate(-50%, -50%) scale(0);
  transition: transform var(--dur-fast) var(--ease-out);
}

.progress-track:hover .progress-track__thumb,
.progress-track.is-scrubbing .progress-track__thumb {
  transform: translate(-50%, -50%) scale(1);
}

.player-aside {
  direction: ltr;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-4);
}

.volume-group {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 130px;
}

.volume-group .progress-track {
  height: 12px;
}

.volume-group .progress-track__bg {
  height: 4px;
}

/* Tablet: the volume slider costs too much width, but dropping the whole aside
   also removed the only way to mute. Keep the button, drop the rail. */
@media (max-width: 1024px) {
  .player-bar {
    grid-template-columns: minmax(0, 1fr) minmax(280px, 420px) auto;
    gap: var(--space-4);
  }
  .volume-group {
    display: none;
  }
  .player-lyrics-btn {
    display: none;
  }
}

/*
 * Phones: the three-column grid left the track column ~75px wide, which clipped
 * the title to zero and squashed the buttons to 18px. Two columns instead —
 * artwork plus title on the left, transport on the right — and the seek rail
 * moves to a full-bleed hairline along the top edge of the bar.
 */
@media (max-width: 640px) {
  .player-bar {
    grid-template-columns: minmax(0, 1fr) auto;
    /* min-height (not height, see the base rule) plus longhand left/right only:
       padding-bottom must keep flowing from the base rule's --safe-bottom, and
       the shorthand `padding` used here previously would have reset it to 0. */
    min-height: 68px;
    padding-left: calc(var(--space-3) + var(--safe-left));
    padding-right: calc(var(--space-3) + var(--safe-right));
    gap: var(--space-3);
  }

  .player-track__art {
    width: 44px;
    height: 44px;
  }

  .player-progress {
    position: absolute;
    inset-inline: 0;
    top: 0;
  }

  .player-time {
    display: none;
  }

  .progress-track {
    height: 4px;
  }

  .progress-track__bg,
  .progress-track:hover .progress-track__bg,
  .progress-track.is-scrubbing .progress-track__bg {
    height: 4px;
    border-radius: 0;
  }

  /* No hover on touch, and the thumb would sit half off the top edge. */
  .progress-track__thumb {
    display: none;
  }

  .player-center {
    min-width: 0;
  }

  .player-controls {
    gap: var(--space-1);
  }

  /* Shuffle, repeat and like lose to prev/play/next when space is this tight. */
  #shuffleBtn,
  #repeatBtn,
  #playerLike {
    display: none;
  }

  .player-aside {
    display: none;
  }
}
