/* =========================================================================
   WXPN persistent radio player

   The player markup is mounted via .wxpn-player-mount (see header.css). This
   file styles the player's INTERNAL layout: artwork, controls, now-playing
   meta, volume, archive progress bar, and the mobile collapse toggle.

   Layout strategy:
   - Custom properties (--wxpn-player-*) drive size at each breakpoint.
     Override the variables rather than redeclaring every rule.
   - Desktop: art | meta in a 2-column grid; volume + progress are absolutely
     positioned relative to the player section.
   - Mobile: a fixed bottom bar with a collapsed (default) and expanded state
     toggled via [data-wxpn-player-collapsed].
   ========================================================================= */

:root {
	--wxpn-player-art-size: 84px;
	--wxpn-player-toggle-size: 46px;
	--wxpn-player-toggle-size-sm: 36px;
	--wxpn-player-collapsed-height: 72px;
	--wxpn-player-expanded-height: 132px;
	--wxpn-player-color: #fff;
	--wxpn-player-accent: #d96e1b;
}

.wxpn-radio-player {
	position: relative;
	width: 100%;
	height: 100%;
	min-width: 0;
	color: var(--wxpn-player-color);
}

.wxpn-radio-player__backdrop {
	position: absolute;
	inset: 0;
	pointer-events: none;
}

.wxpn-radio-player__audio {
	display: none;
}

/* -------------------------------------------------------------------------
   Inner layout
   -------------------------------------------------------------------------
   Desktop: art | meta (volume floats off the right of the section)
   Mobile collapsed: art | meta | toggle (toggle replaces volume)
   ------------------------------------------------------------------------- */

.wxpn-radio-player__inner {
	position: relative;
	z-index: 1;
	display: grid;
	grid-template-columns: var(--wxpn-player-art-size) minmax(0, 1fr);
	align-items: center;
	gap: 14px;
	height: 100%;
	min-height: 84px;
	padding: 0;
}

/* The markup uses .__secondary for the art column and .__primary for meta. */
.wxpn-radio-player__secondary {
	position: relative;
	width: var(--wxpn-player-art-size);
	height: var(--wxpn-player-art-size);
}

.wxpn-radio-player__primary {
	display: flex;
	align-items: center;
	min-width: 0;
	/* Left padding reserves a blank column for the absolute-positioned volume
	   button AND the slider that expands to its right on hover. The volume
	   button sits at left: art-size + 8px (28px wide) and the revealed slider
	   extends another ~32px past it, so its right edge is at art-size + 68px;
	   the meta column's outer edge is at art-size + gap. 64px clears the
	   slider (68 - 14 gap = 54, + breathing room) so the slider "fills" this
	   gap instead of overlapping the stream/track text.
	   Right padding (24px) keeps a clear gap between the now-playing text and
	   the utility menu so a wrapped 2-line title never butts against it. */
	padding: 12px 24px 12px 64px;
}

.wxpn-radio-player__meta {
	display: flex;
	flex-direction: column;
	justify-content: center;
	min-width: 0;
	width: 100%;
}

/* -------------------------------------------------------------------------
   Album art + play/pause toggle
   ------------------------------------------------------------------------- */

.wxpn-radio-player__art-wrap {
	position: relative;
	width: 100%;
	height: 100%;
	overflow: hidden;
	isolation: isolate;
}

.wxpn-radio-player__art-wrap::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.2));
	pointer-events: none;
}

.wxpn-radio-player__art {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.wxpn-radio-player__toggle {
	position: absolute;
	top: 50%;
	left: 50%;
	z-index: 3;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--wxpn-player-toggle-size);
	height: var(--wxpn-player-toggle-size);
	padding: 0;
	border: 2px solid #fff;
	border-radius: 999px;
	background: rgba(0, 0, 0, 0.42);
	color: #fff;
	cursor: pointer;
	transform: translate(-50%, -50%);
	transition: transform 0.18s ease, color 0.18s ease, background 0.18s ease;
	-webkit-appearance: none;
	appearance: none;
	-webkit-tap-highlight-color: transparent;
}

.wxpn-radio-player__toggle:hover {
	color: #f4a43a;
	transform: translate(-50%, -50%) scale(1.07);
}

.wxpn-radio-player__toggle:focus-visible,
.wxpn-radio-player__stream-button:focus-visible,
.wxpn-radio-player__volume input:focus-visible,
.wxpn-radio-player__volume-toggle:focus-visible,
.wxpn-radio-player__collapse-toggle:focus-visible {
	outline: 2px solid #fff;
	outline-offset: 2px;
}

.wxpn-radio-player__toggle-icon {
	display: none;
	position: relative;
}

.wxpn-radio-player__toggle-icon--play {
	width: 0;
	height: 0;
	margin-left: 3px;
	border-top: 8px solid transparent;
	border-bottom: 8px solid transparent;
	border-left: 13px solid currentColor;
}

.wxpn-radio-player__toggle-icon--pause {
	width: 12px;
	height: 16px;
}

.wxpn-radio-player__toggle-icon--pause::before,
.wxpn-radio-player__toggle-icon--pause::after {
	content: "";
	position: absolute;
	top: 0;
	width: 4px;
	height: 16px;
	border-radius: 3px;
	background: currentColor;
}

.wxpn-radio-player__toggle-icon--pause::before { left: 0; }
.wxpn-radio-player__toggle-icon--pause::after  { right: 0; }

.wxpn-radio-player.is-playing .wxpn-radio-player__toggle-icon--pause,
.wxpn-radio-player:not(.is-playing) .wxpn-radio-player__toggle-icon--play {
	display: inline-block;
}

/* -------------------------------------------------------------------------
   Meta column (eyebrow, stream label, stream switcher, now-playing)
   ------------------------------------------------------------------------- */

.wxpn-radio-player__top-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0 8px;
	min-width: 0;
	margin-bottom: 4px;
}

/* Prod underlines the "ON AIR: WXPN »" row with a thin white rule that hugs the
   text width. Desktop only — the mobile bottom-bar player handles this row
   differently. */
@media (min-width: 1024px) /* --wxpn-bp-lg */ {
	.wxpn-radio-player__top-row {
		align-self: flex-start;
		max-width: 100%;
		padding-bottom: 3px;
		border-bottom: 1px solid rgba(255, 255, 255, 0.85);
		/* Align "ON AIR:" / "WXPN" / "»" on a shared baseline like prod. With
		   align-items:center the larger » centered to a different midline than
		   the 11px text, so the three read as staggered. */
		align-items: baseline;
	}

	/* The » lives in this nav; baseline-align it too (and drop its min-height
	   below) so its glyph baseline — not the flex box bottom — lands on the
	   row's shared baseline. */
	.wxpn-radio-player__top-row .wxpn-radio-player__streams {
		align-items: baseline;
		min-height: 0;
	}
}

/* Prod on-air text: 11px, normal weight, no letter-spacing (not the bold,
   wide-tracked, larger treatment we had). */
.wxpn-radio-player__eyebrow {
	margin: 0;
	color: #fff;
	font-size: 11px;
	font-weight: 400;
	line-height: 1;
	letter-spacing: normal;
	text-transform: uppercase;
}

.wxpn-radio-player__stream {
	margin: 0;
	font-size: 11px;
	line-height: 1;
	font-weight: 400;
	color: #fff;
	text-transform: uppercase;
}

.wxpn-radio-player__streams {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 6px;
	min-height: 18px;
}

.wxpn-radio-player__stream-button {
	display: none;
	align-items: center;
	justify-content: center;
	min-height: 18px;
	padding: 0;
	border: 0;
	background: transparent;
	color: #fff;
	font-size: 12px;
	font-weight: 500;
	line-height: 1;
	cursor: pointer;
	transition: color 0.18s ease, opacity 0.18s ease;
}

.wxpn-radio-player__stream-button:hover       { color: rgba(255, 255, 255, 0.78); }

/* Active stream button (collapsed/desktop): renders ONLY the » toggle
   indicator, not the stream name. The stream name is already shown by the
   adjacent <h2 class="__stream">, so showing it again here would read as
   "WXPN  WXPN »". Hide the text via font-size: 0 and let the ::after carry
   its own size. */
.wxpn-radio-player__stream-button.is-active {
	/* inline-block (not flex) so the button's baseline is its text baseline —
	   i.e. the »'s baseline — which lets the baseline-aligned top-row line the
	   » up with "ON AIR:" and "WXPN". A flex button synthesizes its baseline to
	   the box bottom, which dropped the » out of alignment. */
	display: inline-block;
	vertical-align: baseline;
	min-height: 0;
	font-size: 0;
	letter-spacing: 0;
	line-height: 1;
}

.wxpn-radio-player__stream-button.is-active::after {
	content: "\00BB";
	display: inline;
	margin-left: 0;
	font-size: 16px;
	line-height: 1;
	vertical-align: baseline;
}

/* When the list is open: hide the active button entirely and show ONLY the
   streams the user can switch TO. */
.wxpn-radio-player.is-stream-list-open .wxpn-radio-player__stream-button {
	display: inline-flex;
	opacity: 1;
	font-size: 12px;          /* restore size for the non-active streams */
}

.wxpn-radio-player.is-stream-list-open .wxpn-radio-player__stream-button.is-active {
	display: none;
}

/* While an archive is playing no stream is active (so there's no » trigger to
   open the list). Reveal all three live streams directly so the listener can
   click back to live. */
.wxpn-radio-player.is-archive .wxpn-radio-player__stream-button {
	display: inline-flex;
	opacity: 1;
	font-size: 12px;
}

/* Now-playing = two lines: bold song title on top, normal-weight artist
   beneath (matches prod, all breakpoints). */
.wxpn-radio-player__now-playing {
	margin: 0;
	color: #fff;
	font-size: 14px;
	line-height: 1.3;
	max-width: 100%;
	min-width: 0;
}

.wxpn-radio-player__np-artist {
	display: block;
	max-width: 100%;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Title wraps to two lines before truncating — prod shows long titles in full
   ("One Sweet Day (ft. Boyz II Men)", "I Guess Time Just Makes Fools of Us All")
   over two lines instead of cutting them off with an ellipsis (QA "text is
   truncated" FAIL). */
.wxpn-radio-player__np-title {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	max-width: 100%;
	overflow: hidden;
	font-weight: 700;
}

.wxpn-radio-player__np-artist {
	font-weight: 400;
	color: rgba(255, 255, 255, 0.92);
}

/* No artist line when there isn't one (promos, archives) — keeps it single-line. */
.wxpn-radio-player__np-artist:empty {
	display: none;
}

/* -------------------------------------------------------------------------
   Volume control — hover-reveal slider on desktop, hidden on mobile
   ------------------------------------------------------------------------- */

.wxpn-radio-player__volume {
	position: absolute;
	top: 50%;
	/* Sits just past the right edge of the album art, vertically centered.
	   --wxpn-player-art-size shrinks under sticky-header so this follows
	   automatically (no separate sticky override needed). */
	left: calc(var(--wxpn-player-art-size) + 8px);
	/* Must sit ABOVE .wxpn-radio-player__inner (position:relative; z-index:1).
	   Without this the inner row's stacking context paints __primary over the
	   volume control even though __volume comes later in the DOM, so the mute
	   button was unclickable and the hover-reveal slider never triggered. */
	z-index: 2;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	transform: translateY(-50%);
}

.wxpn-radio-player__volume-toggle {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	padding: 0;
	border: 2px solid #fff;
	border-radius: 999px;
	background: rgba(0, 0, 0, 0.42);
	color: #fff;
	cursor: pointer;
	transition: transform 0.18s ease, color 0.18s ease, background 0.18s ease;
	-webkit-appearance: none;
	appearance: none;
	-webkit-tap-highlight-color: transparent;
}

.wxpn-radio-player__volume-toggle:hover {
	color: #f4a43a;
	transform: scale(1.07);
}

/* Volume "horn" icon — SVG speaker with TWO sound waves (matches prod's
   fa-volume-high), muted variant is the speaker with an X. */
.wxpn-radio-player__volume-icon {
	display: none;
	align-items: center;
	justify-content: center;
	width: 20px;
	height: 20px;
}

.wxpn-radio-player__volume-icon svg {
	display: block;
	width: 20px;
	height: 20px;
}

.wxpn-radio-player:not(.is-muted) .wxpn-radio-player__volume-icon--on,
.wxpn-radio-player.is-muted       .wxpn-radio-player__volume-icon--off {
	display: inline-flex;
}

.wxpn-radio-player__volume-slider {
	position: absolute;
	/* Anchor flush to the button's right edge (left: 100%, not 100% + 8px) and
	   move the visual gap INSIDE the box via padding-left. With a literal 8px
	   transparent gap the pointer left both the button and the popup while
	   travelling between them, dropping :hover and snapping the popup shut
	   before it could be grabbed. Keeping the hit-area contiguous fixes that. */
	left: 100%;
	top: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 96px;
	padding: 10px 0 10px 8px;
	border-radius: 999px;
	background: transparent;
	opacity: 0;
	pointer-events: none;
	transform: translateY(-50%);
	transition: opacity 0.18s ease;
}

.wxpn-radio-player__volume:hover .wxpn-radio-player__volume-slider,
.wxpn-radio-player__volume:focus-within .wxpn-radio-player__volume-slider,
.wxpn-radio-player__volume-slider:hover {
	opacity: 1;
	pointer-events: auto;
}

.wxpn-radio-player__volume input {
	-webkit-appearance: none;
	appearance: none;
	width: 76px;
	/* Taller input = a wider grab target after the -90deg rotation (was 6px,
	   which made the slider almost impossible to grab). The visible bar stays
	   slim because it's drawn by the 6px runnable-track below, not the input's
	   own background (now transparent). */
	height: 20px;
	border-radius: 999px;
	background: transparent;
	outline: none;
	cursor: pointer;
	transform: rotate(-90deg);
	transform-origin: center;
	box-shadow: none;
	filter: none;
}

.wxpn-radio-player__volume input::-webkit-slider-runnable-track {
	-webkit-appearance: none;
	appearance: none;
	height: 6px;
	border: 0;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.86);
	box-shadow: none;
}

.wxpn-radio-player__volume input::-webkit-slider-thumb {
	-webkit-appearance: none;
	appearance: none;
	width: 10px;
	height: 10px;
	margin-top: -2px;
	border: 0;
	border-radius: 50%;
	background: var(--wxpn-player-accent);
	box-shadow: none;
}

.wxpn-radio-player__volume input::-moz-range-track {
	height: 6px;
	border: 0;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.86);
	box-shadow: none;
}

.wxpn-radio-player__volume input::-moz-range-thumb {
	width: 10px;
	height: 10px;
	border: 0;
	border-radius: 50%;
	background: var(--wxpn-player-accent);
	box-shadow: none;
}

/* -------------------------------------------------------------------------
   Archive scrubber — a transport bar (time · seek · time) shown only while an
   external/archive file with a finite duration is loaded; hidden for live
   streams and by default. Two instances share the [data-wxpn-scrubber] hook and
   are driven together by radio-player.js:

   - --header : full-width bar between the header's top band and the nav menu.
     Rendered at the header level (NOT inside the player) so it escapes
     .wxpn-site-header__top's overflow:hidden and spans the full width. In-flow,
     so it pushes the nav down — it appears "between" the two. Wide screens only.
   - --footer : a row inside the EXPANDED mobile bottom player, between the meta
     area and the stream-switcher bar. Narrow screens only.

   Shared: hidden via the [hidden] attribute regardless of variant.
   ------------------------------------------------------------------------- */

.wxpn-radio-player__scrubber {
	align-items: center;
	gap: 14px;
	color: #fff;
}

.wxpn-radio-player__scrubber[hidden] {
	display: none !important;
}

/* Desktop header bar */
.wxpn-radio-player__scrubber--header {
	display: flex;
	width: 100%;
	padding: 9px 24px;
	background: #000;
}

/* Footer (in-player) instance is desktop-hidden; the header bar covers wide. */
.wxpn-radio-player__scrubber--footer {
	display: none;
}

@media (max-width: 1023px) /* --wxpn-bp-lg */ {
	/* The long header bar is a wide-screen feature; hide it on mobile. */
	.wxpn-radio-player__scrubber--header {
		display: none !important;
	}

	/* Show the footer scrubber only in the EXPANDED bottom player. As a flex
	   child of the player column it sits after the meta row (__inner) and above
	   the absolutely-pinned stream bar — i.e. between meta and the switcher. */
	.wxpn-radio-player[data-wxpn-player-collapsed="false"] .wxpn-radio-player__scrubber--footer:not([hidden]) {
		display: flex;
		flex: 0 0 40px;
		width: 100%;
		padding: 0 16px;
	}
}

.wxpn-radio-player__progress-time {
	flex: 0 0 auto;
	color: rgba(255, 255, 255, 0.86);
	font-size: 11px;
	line-height: 1;
}

.wxpn-radio-player__progress-time {
	flex: 0 0 auto;
	color: rgba(255, 255, 255, 0.86);
	font-size: 11px;
	line-height: 1;
}

.wxpn-radio-player__progress-track {
	display: flex;
	flex: 1 1 auto;
	min-width: 0;
}

.wxpn-radio-player__progress-track input {
	-webkit-appearance: none;
	appearance: none;
	width: 100%;
	height: 4px;
	border: 0;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.9);
	outline: none;
	cursor: pointer;
	box-shadow: none;
	filter: none;
}

.wxpn-radio-player__progress-track input::-webkit-slider-runnable-track {
	-webkit-appearance: none;
	appearance: none;
	height: 4px;
	border: 0;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.9);
	box-shadow: none;
}

.wxpn-radio-player__progress-track input::-webkit-slider-thumb {
	-webkit-appearance: none;
	appearance: none;
	width: 10px;
	height: 10px;
	border: 0;
	border-radius: 50%;
	background: var(--wxpn-player-accent);
	box-shadow: none;
}

.wxpn-radio-player__progress-track input::-moz-range-track {
	height: 4px;
	border: 0;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.9);
	box-shadow: none;
}

.wxpn-radio-player__progress-track input::-moz-range-thumb {
	width: 10px;
	height: 10px;
	border: 0;
	border-radius: 50%;
	background: var(--wxpn-player-accent);
	box-shadow: none;
}

/* -------------------------------------------------------------------------
   Collapse toggle — mobile only. Sits in the bottom-bar player and flips
   chevron orientation when [aria-expanded="true"].
   ------------------------------------------------------------------------- */

.wxpn-radio-player__collapse-toggle {
	display: none;
	position: absolute;
	top: 12px;
	right: 12px;
	z-index: 4;
	width: 32px;
	height: 32px;
	padding: 0;
	border: 1.5px solid #fff;
	border-radius: 999px;
	background: transparent;
	color: #fff;
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
	-webkit-tap-highlight-color: transparent;
	transition: transform 0.2s ease;
}

.wxpn-radio-player__collapse-icon {
	display: block;
	width: 8px;
	height: 8px;
	margin: 0 auto;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	/* Collapsed (default): the player is pinned at the bottom of the
	   viewport and a tap expands it upward, so the chevron points UP.
	   Expanded: points DOWN to indicate "tap to collapse back down". */
	transform: rotate(-135deg);
	transition: transform 0.2s ease;
}

.wxpn-radio-player[data-wxpn-player-collapsed="false"] .wxpn-radio-player__collapse-icon {
	transform: rotate(45deg);
}

/* -------------------------------------------------------------------------
   Sticky shrink — kicks in via body.wxpn-header-is-sticky (set in header.js)

   Scoped to desktop because below 1024px the player is its OWN fixed bottom
   bar; the header's sticky state shouldn't shrink the bottom player's art
   and font sizes (the bottom player already has its own collapsed/expanded
   sizing). Without this guard, scrolling on mobile would collapse the
   expanded player content because the sticky rule's higher specificity
   beat the mobile @media defaults.
   ------------------------------------------------------------------------- */

@media (min-width: 1024px) /* --wxpn-bp-lg */ {
	/* Modest sticky shrink (matches prod): art 84→70, keep the full toggle and
	   ALL full-size fonts. The old sticky rules shrank art to 56 and fonts to
	   9–12px, which read far too tiny. */
	body.wxpn-header-is-sticky .wxpn-radio-player {
		--wxpn-player-art-size: 70px;
	}

	/* Inner height matches the sticky mount (85px) so the art doesn't overflow
	   the section's bottom; art (70px) centers with breathing room. */
	body.wxpn-header-is-sticky .wxpn-radio-player__inner { height: 85px; min-height: 85px; }

	/* Sticky is only 85px tall — a 2-line title plus the artist line (3 lines)
	   overflows it and eats all the vertical padding. Keep the title to ONE line
	   here (title + artist = 2 lines) so it stays centered with breathing room.
	   The full-height header keeps the 2-line wrap that fixed the truncation. */
	body.wxpn-header-is-sticky .wxpn-radio-player__np-title {
		-webkit-line-clamp: 1;
	}
}

/* =========================================================================
   Mobile bottom-bar player (<1024px)

   Collapsed (default): art | meta | collapse-toggle, ~64px tall
   Expanded: same row + transport/volume area below, ~200px tall
   ========================================================================= */

@media (max-width: 1023px) /* --wxpn-bp-lg */ {
	.wxpn-radio-player {
		--wxpn-player-art-size: 56px;
		--wxpn-player-toggle-size: var(--wxpn-player-toggle-size-sm);
		overflow: hidden;     /* clip expanded content during the height transition */
	}

	/* Collapsed (default): art | meta | (chevron lives absolutely positioned).
	   Inner is always var(--wxpn-player-collapsed-height); the SECTION grows
	   when expanded, not the inner row. */
	.wxpn-radio-player__inner {
		min-height: var(--wxpn-player-collapsed-height);
		height: var(--wxpn-player-collapsed-height);
		gap: 12px;
		padding: 0 56px 0 16px;    /* right pad reserves chevron; left pad gives art breathing room */
	}

	.wxpn-radio-player__primary {
		/* Left padding reserves room for the always-visible mute horn that sits
		   between the art and the text (see __volume above). Wider than before to
		   open up the play↔volume spacing to match prod. */
		padding: 6px 0 6px 48px;
	}

	/* Prod mobile player shows the now-playing track (not an "ON AIR WXPN"
	   eyebrow) — 14px, up to two lines. Hide the eyebrow + stream label here;
	   the stream identity/switcher lives in the expanded black bar. */
	.wxpn-radio-player__eyebrow,
	.wxpn-radio-player__stream {
		display: none;
	}

	.wxpn-radio-player__now-playing {
		font-size: 14px;
		line-height: 1.3;
		-webkit-line-clamp: 2;
	}

	/* On mobile/tablet the top row shows only the now-playing line. The "ON AIR"
	   eyebrow and the duplicated stream name/» switcher are dropped — the black
	   stream-switcher bar (expanded state) is the single source of stream
	   identity and selection. The .streams container is hidden here (collapsed)
	   and re-shown as the bottom bar by the expanded-state rules below. */
	.wxpn-radio-player__eyebrow,
	.wxpn-radio-player__stream,
	.wxpn-radio-player__streams {
		display: none;
	}

	.wxpn-radio-player__volume {
		/* Always-visible mute control on mobile, parked in the gap between the
		   album art / play button and the meta text (that gap is reserved by
		   __primary's padding-left below). Anchored to the collapsed top row's
		   vertical center — same as the chevron — so it stays put in both the
		   collapsed and expanded states. left = inner padding (16px) + art width
		   + an 8px gap after the art. */
		display: inline-flex;
		position: absolute;
		left: calc(16px + var(--wxpn-player-art-size) + 14px);
		top: calc(var(--wxpn-player-collapsed-height) / 2);
		transform: translateY(-50%);
		width: 28px;
		height: 28px;
		z-index: 3;
	}

	/* Cover art: hidden in the collapsed bar (prod shows just the play button on
	   the maroon bar), revealed in the expanded state. The play toggle stays put
	   either way (it's centered in the art column). */
	.wxpn-radio-player__art {
		display: none;
	}

	.wxpn-radio-player[data-wxpn-player-collapsed="false"] .wxpn-radio-player__art {
		display: block;
	}

	.wxpn-radio-player__collapse-toggle {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		/* Anchor to the TOP row (the always-visible collapsed row), not the
		   whole player section. Otherwise it drifts to the middle of the
		   expanded player. */
		top: calc(var(--wxpn-player-collapsed-height) / 2);
		transform: translateY(-50%);
		right: 16px;
	}

	/* Expanded: the top content row (art / play / meta / chevron) fills the
	   player MINUS the 60px stream-switcher bar pinned to the bottom, so the play
	   toggle centers at (height − 60px)/2. The collapsed anchor above left the
	   chevron ~9px high of the play button (QA "chevron not vertically centered
	   in expanded"). Re-center it on that same content-row midline. */
	.wxpn-radio-player[data-wxpn-player-collapsed="false"] .wxpn-radio-player__collapse-toggle {
		top: calc((100% - 60px) / 2);
	}

	/* -----------------------------------------------------------------------
	   Expanded mobile state
	   The SECTION grows to var(--wxpn-player-expanded-height). The collapsed
	   row stays at the top (art | meta); a separate volume row sits beneath.
	   We don't use grid-template-areas here — keeping the existing inner row
	   as-is and stacking a sibling row is simpler and more robust.
	   ----------------------------------------------------------------------- */

	.wxpn-radio-player[data-wxpn-player-collapsed="false"] {
		display: flex;
		flex-direction: column;
	}

	.wxpn-radio-player[data-wxpn-player-collapsed="false"] .wxpn-radio-player__inner {
		/* Fill the space above the stream bar so the taller expanded player has
		   no empty band (art/meta sit in a roomier, prod-like row). The stream
		   bar is position:absolute (60px, pinned to the section bottom), so it
		   doesn't reserve flow space — reserve it here via padding-bottom so the
		   now-playing text never slips behind it. */
		flex: 1 1 auto;
		padding-bottom: 60px;
	}

	/* No volume SLIDER on mobile — touch devices control volume with the
	   hardware buttons. The horn (.wxpn-radio-player__volume-toggle) stays as a
	   plain mute/unmute toggle. Matches the legacy SGPlayer, which set
	   .sg-volume-holder { display: none } below its small breakpoint and kept
	   only the mute button. */
	.wxpn-radio-player__volume-slider {
		display: none;
	}

	/* ------------------------------------------------------------------
	   Expanded: lift the stream switcher out of the meta row into a
	   dark gray bar pinned to the bottom of the player section, matching
	   xpn.org's ResponsiveStreamSwitch.

	   The streams element lives inside __meta > __top-row in the markup;
	   position:absolute reparents it visually without DOM moves. We also
	   pad the player bottom so the volume row above doesn't underlap.
	   ------------------------------------------------------------------ */

	/* Total expanded section height (132px) is divided into:
	     72px  inner row (art + mute horn + meta + chevron)
	     60px  streams bar (position:absolute at the bottom)
	   The mute horn lives inline in the top row (always visible), so there is
	   no separate volume row anymore. The flex column lays out the 72px inner
	   and the streams bar covers the bottom 60px.

	   __inner is normally position:relative (for its z-index over __backdrop).
	   In expanded mobile we drop that so __streams (which is nested deep inside
	   __inner > __primary > __meta > __top-row) uses .wxpn-radio-player as its
	   positioning context — letting bottom:0 mean the bottom of the section.
	   The play toggle inside __secondary > __art-wrap is unaffected because
	   __art-wrap has its own position:relative. */
	.wxpn-radio-player[data-wxpn-player-collapsed="false"] .wxpn-radio-player__inner {
		position: static;
	}

	.wxpn-radio-player[data-wxpn-player-collapsed="false"] .wxpn-radio-player__streams {
		position: absolute;
		left: 0;
		right: 0;
		bottom: 0;
		z-index: 5;
		display: flex;
		align-items: center;
		justify-content: space-around;
		gap: 0;
		height: 60px;
		margin: 0;
		padding: 0 16px;
		background: #22201d;
	}

	.wxpn-radio-player[data-wxpn-player-collapsed="false"] .wxpn-radio-player__stream-button {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		flex: 1 1 auto;
		min-height: 60px;
		padding: 0 4px;
		opacity: 0.88;
		font-size: 14px;
		border-bottom: 2px solid transparent;
	}

	.wxpn-radio-player[data-wxpn-player-collapsed="false"] .wxpn-radio-player__stream-button.is-active {
		/* Keep the active stream visible in the black bar. The desktop
		   "is-stream-list-open hides the active button" rule must not apply here —
		   the bar always shows all three; the active one is just underlined.
		   This is what fixed "tapping a stream removes it from the black bar". */
		display: inline-flex;
		opacity: 1;
		border-bottom-color: #f29d07;
	}

	.wxpn-radio-player[data-wxpn-player-collapsed="false"] .wxpn-radio-player__stream-button.is-active::after {
		content: "";
		margin-left: 0;
	}
}

/* Mount height + positioning are owned by header.css (see .wxpn-player-mount
   inside its @media (max-width: 1023px) block). Snap (no transition) so the
   JS positionMobilePlayer() reads the final height immediately. */

@media (max-width: 480px) /* --wxpn-bp-sm */ {
	.wxpn-radio-player {
		--wxpn-player-art-size: 48px;
		--wxpn-player-toggle-size: 32px;
	}

	/* Keep the now-playing at 14px even on the smallest screens — prod's mobile
	   now-playing title is 14px (sampled from live xpn.org), and dropping to 13px
	   here made dev's expanded player text read smaller than prod (QA FAIL). */
	.wxpn-radio-player__now-playing    { font-size: 14px; }
}
