/**
 * Worldwide Pop hero.
 *
 * Every colour/opacity/blur below reads a CSS custom property with a literal
 * fallback, so the Customizer controls can move them live and the hero still
 * renders correctly before anything is saved.
 */

.wwp-hero {
	position: relative;
	width: 100%;
	background: var( --wwp-hero-bg, #000 );
	/* The strip is markup-first (above the stage) so it stays in a sensible
	   reading and tab order; ordering moves it visually without moving it in
	   the DOM. */
	display: flex;
	flex-direction: column;
}
.wwp-hero[data-cue="bottom"] .wwp-hero-cue { order: 3; }
.wwp-hero[data-cue="top"] .wwp-hero-cue { order: 0; }
.wwp-hero .wwp-hero-stage { order: 1; }
.wwp-hero .wwp-hero-meta { order: 2; }

/* --- ambient backdrop --------------------------------------------------
   The playing item's own still, blown up and blurred behind the whole hero,
   so the area around a 16:9 video in a taller frame carries the video's colour
   instead of sitting on flat black. Off unless the hero enables it, and
   enabled separately for pointer and touch devices. */
/*
 * Fixed to the VIEWPORT, not to the hero: this is a page background that
 * happens to be driven by whatever the hero is playing, so it fills the whole
 * window and everything on the page sits on top of it. hero.js moves this
 * element to <body> on init - a fixed element is trapped by any ancestor with
 * a transform or filter, and a theme this large is certain to have one
 * somewhere.
 */
.wwp-hero-ambient {
	position: fixed;
	inset: 0;
	z-index: 0;
	overflow: hidden;
	pointer-events: none;
	/* Above the page's black, below the content. */
	background: transparent;
	display: none;
}
body.has-wwp-ambient .wwp-hero-ambient { display: block; }

/* The theme's own wrapper has to sit above the backdrop, or the backdrop is
   simply invisible behind an opaque page. */
body.has-wwp-ambient .site,
body.has-wwp-ambient #page {
	position: relative;
	z-index: 1;
	background: transparent;
}
/* Sections that paint their own solid background would punch a hole in the
   effect - let the backdrop through and keep their own only as a tint. */
body.has-wwp-ambient .site-content,
body.has-wwp-ambient #content,
body.has-wwp-ambient .king-editorschoice,
body.has-wwp-ambient .king-stories-top {
	background-color: transparent;
}

/*
 * The mobile-overlay mode paints EVERY #content child with a translucent
 * sheet, which on a phone covered the backdrop almost completely - including
 * the hero itself. The two features are solving the same problem in different
 * ways, so when the ambient backdrop is on it wins and the sheet stands down.
 * Specificity deliberately matches the sheet rule; hero.css is enqueued after
 * style.css, so an equal-weight rule here is the later one.
 */
body.has-wwp-ambient.topnav-mobile-overlay #content > *:not( .featured-video ),
body.home.has-wwp-ambient.topnav-mobile-overlay #content > *:not( .featured-video ) {
	background: transparent;
}

/* The hero's own fill would sit on top of the backdrop it is driving. */
body.has-wwp-ambient .wwp-hero { background: transparent; }

/* Vignette: darkens the edges so the title row and the category bar stay
   readable over a busy frame, without flattening the middle. */
.wwp-hero-ambient-vignette {
	position: absolute;
	inset: 0;
	background:
		radial-gradient(
			ellipse at 50% 38%,
			rgba( 0, 0, 0, 0 ) 30%,
			rgba( 0, 0, 0, calc( var( --wwp-ambient-vignette, 0.7 ) * 0.55 ) ) 70%,
			rgba( 0, 0, 0, var( --wwp-ambient-vignette, 0.7 ) ) 100%
		);
}

.wwp-hero-ambient-img {
	position: absolute;
	/* Overscanned: blur samples beyond the element's edges, so an exactly
	   fitted layer shows a pale border all the way round. */
	inset: -8%;
	background-size: cover;
	background-position: center;
	filter: blur( var( --wwp-ambient-blur, 44px ) ) brightness( var( --wwp-ambient-brightness, 0.6 ) );
	transform: scale( 1.08 );
	opacity: 0;
	transition: opacity 0.9s ease;
	will-change: opacity;
}
.wwp-hero-ambient-img.is-on { opacity: var( --wwp-ambient-opacity, 0.55 ); }

/* Within the hero itself these still need to stack above its own layers. */
.wwp-hero-stage,
.wwp-hero-meta { position: relative; z-index: 1; }

/* With a backdrop behind it the stage should letterbox rather than crop, or
   the effect has nothing to fill. */
.wwp-hero.has-ambient .wwp-hero-stage { background: transparent; }
.wwp-hero.has-ambient .wwp-hero-poster { object-fit: contain; }
.wwp-hero.has-ambient .wwp-hero-player iframe,
.wwp-hero.has-ambient .wwp-hero-player video { object-fit: contain; }

@media ( prefers-reduced-motion: reduce ) {
	.wwp-hero-ambient-img { transition: none; }
}

/*
 * A phone viewport is roughly 9:16 while the still is 16:9, so `cover` has to
 * crop hard on the sides. Anchoring to the centre keeps the subject - which is
 * almost always centre-frame in a music video - rather than drifting to an
 * edge, and scaling up a little further hides the softness at the crop.
 */
@media ( max-width: 640px ) {
	.wwp-hero-ambient-img {
		background-position: 50% 50%;
		transform: scale( 1.35 );
	}
}

/* --- play cue ---------------------------------------------------------
   Two modes. Overlaid (the default) it is absolutely positioned inside the
   stage and costs no layout height. In flow it is a sibling of the stage and
   the ordering rules above place it. */
.wwp-hero[data-cue-overlay="1"] .wwp-hero-cue {
	position: absolute;
	left: 0;
	right: 0;
	z-index: 5;
	background: var( --wwp-cue-bg-overlay, linear-gradient( to top, rgba( 0, 0, 0, 0.75 ), rgba( 0, 0, 0, 0 ) ) );
}
.wwp-hero[data-cue-overlay="1"][data-cue="bottom"] .wwp-hero-cue { bottom: 0; }
/* Top sits flush under the site header, which floats over the hero. */
.wwp-hero[data-cue-overlay="1"][data-cue="top"] .wwp-hero-cue {
	top: 0;
	background: var( --wwp-cue-bg-overlay-top, linear-gradient( to bottom, rgba( 0, 0, 0, 0.75 ), rgba( 0, 0, 0, 0 ) ) );
}
/* An overlaid strip must not sit under the header's own floating bar. */
body.home .wwp-hero[data-cue-overlay="1"][data-cue="top"] .wwp-hero-cue {
	padding-top: calc( var( --topnav-h, 70px ) + 10px );
}

/* --- the strip as a vertical column -----------------------------------
   Left or right instead of above or below. Two separate problems:

   IN FLOW, the hero stops being a single column and becomes a grid, so the
   strip can stand beside the stage AND the metadata bar rather than beside
   one of them. Grid areas rather than a wrapper element, because wrapping
   would change the markup the JS and the overlay mode both rely on. The
   ambient backdrop is position:fixed and so takes no cell.

   THE RAIL IS ABSOLUTELY POSITIONED INSIDE ITS OWN GRID AREA, and that is
   load-bearing. A normal grid item spanning both rows contributes its content
   height to them, so a 20-item strip stretched the hero from 1084px to 1387px
   and a 200-item one would run off the page - measured, not theorised, and
   `min-height: 0` does not fix it (that removes the automatic MINIMUM, not the
   content contribution to auto-sized rows). Taken out of flow it contributes
   nothing, the rows follow the video, and `inset: 0` fills the reserved column
   because an absolutely positioned grid child is contained by its grid area.
   The column then needs an explicit width, since nothing is left to measure. */
.wwp-hero[data-cue-overlay="0"][data-cue="left"],
.wwp-hero[data-cue-overlay="0"][data-cue="right"] {
	display: grid;
	/* Thumbnail, its padding either side, and room for a thin scrollbar. */
	--wwp-cue-col: calc( var( --wwp-cue-size, 108px ) + 2 * clamp( 10px, 2vw, 24px ) + 12px );
}
.wwp-hero[data-cue-overlay="0"][data-cue="left"] {
	grid-template-columns: var( --wwp-cue-col ) minmax( 0, 1fr );
	grid-template-areas: "cue stage" "cue meta";
}
.wwp-hero[data-cue-overlay="0"][data-cue="right"] {
	grid-template-columns: minmax( 0, 1fr ) var( --wwp-cue-col );
	grid-template-areas: "stage cue" "meta cue";
}
.wwp-hero[data-cue-overlay="0"][data-cue="left"] .wwp-hero-cue,
.wwp-hero[data-cue-overlay="0"][data-cue="right"] .wwp-hero-cue {
	grid-area: cue;
	position: absolute;
	inset: 0;
}
.wwp-hero[data-cue-overlay="0"][data-cue="left"] .wwp-hero-stage,
.wwp-hero[data-cue-overlay="0"][data-cue="right"] .wwp-hero-stage { grid-area: stage; }
.wwp-hero[data-cue-overlay="0"][data-cue="left"] .wwp-hero-meta,
.wwp-hero[data-cue-overlay="0"][data-cue="right"] .wwp-hero-meta { grid-area: meta; }

/* OVERLAID, it is absolutely positioned inside the stage as before - the base
   rule pins left AND right to 0 for a horizontal bar, which both have to be
   undone before one of them can be re-pinned. */
.wwp-hero[data-cue-overlay="1"][data-cue="left"] .wwp-hero-cue,
.wwp-hero[data-cue-overlay="1"][data-cue="right"] .wwp-hero-cue {
	top: 0;
	bottom: 0;
	left: auto;
	right: auto;
	width: max-content;
}
.wwp-hero[data-cue-overlay="1"][data-cue="left"] .wwp-hero-cue {
	left: 0;
	background: var( --wwp-cue-bg-overlay-left, linear-gradient( to right, rgba( 0, 0, 0, 0.75 ), rgba( 0, 0, 0, 0 ) ) );
}
.wwp-hero[data-cue-overlay="1"][data-cue="right"] .wwp-hero-cue {
	right: 0;
	background: var( --wwp-cue-bg-overlay-right, linear-gradient( to left, rgba( 0, 0, 0, 0.75 ), rgba( 0, 0, 0, 0 ) ) );
}
/* A left rail on the front page still has to clear the floating header. */
body.home .wwp-hero[data-cue-overlay="1"][data-cue="left"] .wwp-hero-cue,
body.home .wwp-hero[data-cue-overlay="1"][data-cue="right"] .wwp-hero-cue {
	padding-top: calc( var( --topnav-h, 70px ) + 10px );
}

/* Shared by both modes: the strip runs down instead of across. */
.wwp-hero[data-cue="left"] .wwp-hero-cue,
.wwp-hero[data-cue="right"] .wwp-hero-cue {
	flex-direction: column;
	overflow-x: hidden;
	overflow-y: auto;
	min-height: 0;
	overscroll-behavior: contain;
}

/* The prev/next arrows and the action buttons must not sit under the rail,
   and the country stamp is pinned to the top LEFT of the stage, which is
   exactly where a left rail lands. --wwp-cue-w is measured from the real
   strip (see hero.js), the same way --wwp-cue-h already is. */
.wwp-hero[data-cue-overlay="1"][data-cue="left"] .wwp-hero-controls { padding-left: var( --wwp-cue-w, 0px ); }
.wwp-hero[data-cue-overlay="1"][data-cue="right"] .wwp-hero-controls { padding-right: var( --wwp-cue-w, 0px ); }
.wwp-hero[data-cue-overlay="1"][data-cue="right"] .wwp-hero-actions {
	right: calc( clamp( 8px, 1.6vw, 20px ) + var( --wwp-cue-w, 0px ) );
}
.wwp-hero[data-cue-overlay="1"][data-cue="left"] { --wwp-stamp-offset-x: var( --wwp-cue-w, 0px ); }

/* A vertical rail on a phone is a rail across a third of the screen, so the
   side settings mean "beside it where there is room, under it where there is
   not". */
@media ( max-width: 782px ) {
	.wwp-hero[data-cue-overlay="0"][data-cue="left"],
	.wwp-hero[data-cue-overlay="0"][data-cue="right"] {
		display: flex;
		flex-direction: column;
	}
	.wwp-hero[data-cue-overlay="0"][data-cue="left"] .wwp-hero-cue,
	.wwp-hero[data-cue-overlay="0"][data-cue="right"] .wwp-hero-cue {
		position: static;
	}
	.wwp-hero[data-cue="left"] .wwp-hero-cue,
	.wwp-hero[data-cue="right"] .wwp-hero-cue {
		flex-direction: row;
		overflow-x: auto;
		overflow-y: hidden;
		order: 3;
		width: auto;
		max-width: none;
		inset: auto 0 0 0;
		padding-top: 10px;
	}
	.wwp-hero[data-cue-overlay="1"][data-cue="left"] .wwp-hero-controls,
	.wwp-hero[data-cue-overlay="1"][data-cue="right"] .wwp-hero-controls { padding-left: 0; padding-right: 0; }
	.wwp-hero[data-cue-overlay="1"][data-cue="right"] .wwp-hero-actions { right: clamp( 8px, 1.6vw, 20px ); }
	.wwp-hero[data-cue-overlay="1"][data-cue="left"] { --wwp-stamp-offset-x: 0px; }
}

.wwp-hero-cue {
	display: flex;
	gap: 8px;
	padding: 10px clamp( 10px, 2vw, 24px );
	overflow-x: auto;
	scrollbar-width: thin;
	background: var( --wwp-cue-bg, rgba( 16, 16, 20, 0.85 ) );
	backdrop-filter: blur( var( --wwp-cue-blur, 0px ) );
	-webkit-backdrop-filter: blur( var( --wwp-cue-blur, 0px ) );
	/* Set per hero. Applied to the strip as a whole rather than to its
	   background alone, so the thumbnails dim with it. */
	opacity: var( --wwp-cue-opacity, 0.85 );
	transition: opacity 0.2s ease;
}
/* Never leave it faded while someone is actually using it. */
.wwp-hero-cue:hover,
.wwp-hero-cue:focus-within { opacity: 1; }
.wwp-hero-cue-item {
	position: relative;
	flex: 0 0 auto;
	width: var( --wwp-cue-size, 108px );
	aspect-ratio: 16 / 9;
	padding: 0;
	border: 0;
	border-radius: 6px;
	overflow: hidden;
	cursor: pointer;
	background: #111;
	opacity: 0.55;
	transition: opacity 0.18s ease, outline-color 0.18s ease;
	outline: 2px solid transparent;
	outline-offset: 2px;
}
.wwp-hero-cue-item img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.wwp-hero-cue-item:hover,
.wwp-hero-cue-item:focus-visible {
	opacity: 0.9;
}
.wwp-hero-cue-item.is-active {
	opacity: 1;
	outline-color: var( --wwp-accent, #e5133b );
}
.wwp-hero-cue-n {
	position: absolute;
	top: 3px;
	left: 4px;
	padding: 0 5px;
	border-radius: 3px;
	font: 600 11px/1.6 monospace;
	color: #fff;
	background: rgba( 0, 0, 0, 0.7 );
}

/* --- stage ------------------------------------------------------------ */
.wwp-hero-stage {
	position: relative;
	width: 100%;
	aspect-ratio: var( --wwp-hero-ratio, 16 / 9 );
	overflow: hidden;
	background: #000;
}
.wwp-hero-track,
.wwp-hero-player {
	position: absolute;
	inset: 0;
}
.wwp-hero-slide {
	position: absolute;
	inset: 0;
	opacity: 0;
	visibility: hidden;
}
.wwp-hero-slide.is-active {
	opacity: 1;
	visibility: visible;
}
.wwp-hero-poster {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/* Transitions. The engine re-adds .is-entering on every advance, so these
   run from the start each time rather than only once. */
.wwp-hero[data-transition="fade"] .wwp-hero-slide.is-active { animation: wwp-fade 0.6s ease both; }
.wwp-hero[data-transition="slide-left"] .wwp-hero-slide.is-active { animation: wwp-slide-left 0.6s cubic-bezier( 0.22, 0.61, 0.36, 1 ) both; }
.wwp-hero[data-transition="slide-right"] .wwp-hero-slide.is-active { animation: wwp-slide-right 0.6s cubic-bezier( 0.22, 0.61, 0.36, 1 ) both; }

@keyframes wwp-fade { from { opacity: 0 } to { opacity: 1 } }
@keyframes wwp-slide-left { from { opacity: 0; transform: translateX( 6% ) } to { opacity: 1; transform: none } }
@keyframes wwp-slide-right { from { opacity: 0; transform: translateX( -6% ) } to { opacity: 1; transform: none } }

@media ( prefers-reduced-motion: reduce ) {
	.wwp-hero .wwp-hero-slide.is-active { animation: wwp-fade 0.2s linear both; }
}

/* The YouTube iframe never takes a tap: YouTube's overlay links out of the
   site (owner, 2026-10-15). Taps land on the stage instead - pause / carry on -
   and a full play gets WWP's own bar below. */
.wwp-hero-player iframe { pointer-events: none; }

/* WWP's control bar for a full play: bright, always visible while it plays. */
.wwp-hero-ctl {
	position: absolute;
	left: 12px;
	right: 12px;
	bottom: calc( 12px + var( --wwp-hero-ctl-lift, 0px ) );
	z-index: 6;
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 8px 12px;
	border-radius: 14px;
	background: rgba( 4, 10, 12, 0.72 );
	-webkit-backdrop-filter: blur( 8px );
	backdrop-filter: blur( 8px );
	box-shadow: 0 0 0 1px rgba( 246, 210, 122, 0.25 ), 0 8px 24px rgba( 0, 0, 0, 0.45 );
	color: #fff;
	font: 700 12px/1 system-ui, sans-serif;
	font-variant-numeric: tabular-nums;
}
.wwp-hero-ctl-play {
	all: unset;
	cursor: pointer;
	flex: 0 0 34px;
	height: 34px;
	border-radius: 50%;
	display: grid;
	place-items: center;
	font-size: 13px;
	color: #2a1a00;
	background: linear-gradient( 180deg, #fff2c4, #f6d27a 45%, #d4a84b );
}
.wwp-hero-ctl-play:focus-visible,
.wwp-hero-ctl-rail:focus-visible { outline: 2px solid #2ec4b6; outline-offset: 3px; }
.wwp-hero-ctl-time { flex: 0 0 auto; opacity: 0.9; }
.wwp-hero-ctl-rail {
	position: relative;
	flex: 1;
	height: 28px; /* a thumb-sized target around a slim track */
	cursor: pointer;
	touch-action: none;
}
.wwp-hero-ctl-rail::before,
.wwp-hero-ctl-fill {
	content: "";
	position: absolute;
	left: 0;
	top: 50%;
	height: 6px;
	margin-top: -3px;
	border-radius: 3px;
}
.wwp-hero-ctl-rail::before { right: 0; background: rgba( 255, 255, 255, 0.28 ); }
.wwp-hero-ctl-fill { background: linear-gradient( 90deg, #2ec4b6, #f6d27a ); box-shadow: 0 0 10px rgba( 246, 210, 122, 0.6 ); }
.wwp-hero-ctl-knob {
	position: absolute;
	top: 50%;
	width: 16px;
	height: 16px;
	margin: -8px 0 0 -8px;
	border-radius: 50%;
	background: #f6d27a;
	box-shadow: 0 0 0 3px rgba( 0, 0, 0, 0.35 ), 0 0 12px rgba( 246, 210, 122, 0.8 );
}

/* The YouTube iframe / <video> fills the stage once playback starts. */
.wwp-hero-player { opacity: 0; transition: opacity 0.35s ease; }
.wwp-hero.is-live .wwp-hero-player { opacity: 1; }
.wwp-hero-player iframe,
.wwp-hero-player video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
	object-fit: cover;
}

/* --- overlay ---------------------------------------------------------- */
/* The whole layer is click-through; only real controls opt back in, or the
   video underneath becomes unclickable. */
.wwp-hero-overlay {
	position: absolute;
	inset: 0;
	/* Above the overlaid film strip (z-index 5), or the sound and bookmark
	   buttons end up behind it. */
	z-index: 6;
	pointer-events: none;
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: clamp( 8px, 1.6vw, 20px );
}
.wwp-hero-overlay > * { pointer-events: auto; }
.wwp-hero-actions {
	position: absolute;
	right: clamp( 8px, 1.6vw, 20px );
	/* --wwp-cue-h is measured from the real strip (see hero.js) rather than
	   assumed, because its height follows the configurable thumbnail size. */
	bottom: calc( clamp( 8px, 1.6vw, 20px ) + var( --wwp-cue-clear-bottom, 0px ) );
	display: flex;
	gap: 8px;
	transition: bottom 0.2s ease;
}
.wwp-hero[data-cue-overlay="1"][data-cue="bottom"] {
	--wwp-cue-clear-bottom: var( --wwp-cue-h, 0px );
}
/* With the strip on top, the prev/next arrows are what needs the clearance. */
.wwp-hero[data-cue-overlay="1"][data-cue="top"] .wwp-hero-controls {
	margin-top: var( --wwp-cue-h, 0px );
}
.wwp-hero-controls {
	display: flex;
	justify-content: space-between;
	width: 100%;
	/*
	 * .wwp-hero-controls (prev/next) is vertically centered across the WHOLE
	 * overlay by the parent's align-items:center. .wwp-hero-actions (sound /
	 * bookmark / expand) is independently pinned bottom-right to clear the
	 * play-cue filmstrip. On a short stage those two anchors land on top of
	 * each other - measured at 430px wide, "next" and "expand" shared the
	 * same right-edge column with a 20px vertical overlap.
	 *
	 * Reserved as bottom margin rather than repositioning either element:
	 * margin participates in flexbox centering, so an asymmetric margin-bottom
	 * shifts the CENTERED content up, away from the corner, without breaking
	 * true centering when the stage is tall enough that no collision exists.
	 * The reserved amount is the actions cluster's own fixed footprint - its
	 * buttons are always 44px regardless of how many are visible, so this is
	 * a real constant, not a guess (unlike the play-cue height, which IS user
	 * configurable and is measured in hero.js rather than hardcoded here).
	 */
	margin-bottom: calc( 2 * ( 44px + clamp( 8px, 1.6vw, 20px ) + 10px ) );
}
.wwp-hero-btn {
	width: 44px;
	height: 44px;
	display: flex;
	align-items: center;
	justify-content: center;
	border: 0;
	border-radius: 50%;
	cursor: pointer;
	font-size: 20px;
	line-height: 1;
	color: #fff;
	background: var( --wwp-btn-bg, rgba( 28, 28, 31, 0.4 ) );
	backdrop-filter: blur( var( --wwp-btn-blur, 16px ) );
	-webkit-backdrop-filter: blur( var( --wwp-btn-blur, 16px ) );
	opacity: 0;
	transition: opacity 0.2s ease, background 0.2s ease;
}
.wwp-hero-btn:hover { background: rgba( 28, 28, 31, 0.75 ); }

/*
 * Revealing controls on hover works on a mouse and fails completely on a
 * touchscreen, where there is no hover state at all - the sound and bookmark
 * buttons were simply invisible on a phone. Split the two cases: pointer
 * devices keep hover-to-reveal, touch devices show the controls and let the
 * idle timer take them away instead.
 */
@media ( hover: hover ) {
	.wwp-hero:hover .wwp-hero-btn,
	.wwp-hero:focus-within .wwp-hero-btn { opacity: 1; }
}
@media ( hover: none ) {
	.wwp-hero-btn { opacity: 1; }
}

/*
 * Idle: hand the frame back to the video. Everything chrome-like fades
 * together so it reads as one gesture, and stops taking taps while hidden so
 * an invisible control cannot be hit by accident.
 */
.wwp-hero-cue,
.wwp-hero-stamp,
.wwp-hero-btn {
	transition: opacity 0.45s ease;
}
.wwp-hero.is-idle .wwp-hero-btn,
.wwp-hero.is-idle .wwp-hero-cue,
.wwp-hero.is-idle .wwp-hero-stamp {
	opacity: 0;
	pointer-events: none;
}
/* The metadata bar is content, not chrome - it stays. */

.wwp-hero-sound .wwp-i-sound,
.wwp-hero-sound[data-muted="1"] .wwp-i-muted { display: inline; }
.wwp-hero-sound .wwp-i-muted,
.wwp-hero-sound[data-muted="1"] .wwp-i-sound { display: none; }

/* --- country stamp ----------------------------------------------------
   A mark on the work rather than a caption, so it sits on the video itself.
   Deliberately restrained: a slight rotation and a rule, not a novelty rubber
   stamp, because it appears on every slide. */
.wwp-hero-stamp {
	position: absolute;
	/* On the front page the site header floats OVER the hero, so a stamp
	   pinned to the top of the stage lands on the logo. The offset stacks:
	   header height, plus the film strip when that is mounted on top too. */
	top: calc( var( --wwp-stamp-offset, 0px ) + clamp( 10px, 2vw, 22px ) );
	left: calc( var( --wwp-stamp-offset-x, 0px ) + clamp( 10px, 2vw, 22px ) );
	z-index: 7;
	display: flex;
	flex-direction: column;
	gap: clamp( 1px, 0.3vw, 3px );
	/* Fluid rather than stepped: the stamp sits over video at every width, so
	   it should shrink continuously with the frame instead of holding desktop
	   proportions until a breakpoint rescues it. At 390px it lands around
	   half its desktop size. */
	padding: clamp( 5px, 1.1vw, 9px ) clamp( 8px, 1.6vw, 14px );
	border: clamp( 1px, 0.14vw, 1.5px ) solid var( --wwp-stamp-border, rgba( 255, 255, 255, 0.55 ) );
	border-radius: clamp( 3px, 0.4vw, 5px );
	background: var( --wwp-stamp-bg, rgba( 0, 0, 0, 0.32 ) );
	backdrop-filter: blur( var( --wwp-stamp-blur, 6px ) );
	-webkit-backdrop-filter: blur( var( --wwp-stamp-blur, 6px ) );
	color: var( --wwp-stamp-fg, #fff );
	/* Scaled rather than re-typing every clamp() above: one factor takes the
	   whole mark down together - type, padding, border weight and corner
	   radius stay in proportion, which re-tuning six clamps by hand would not
	   guarantee. Scaling from the top-left keeps it anchored to its corner. */
	transform: rotate( var( --wwp-stamp-rotate, -3deg ) ) scale( var( --wwp-stamp-scale, 0.7 ) );
	transform-origin: top left;
	pointer-events: auto;
	/* Never more than a bit over half the frame, and never wider than it needs
	   to be on a large screen. */
	max-width: min( 56%, 340px );
}
.wwp-hero-stamp[hidden] { display: none; }
.wwp-hero-stamp-made {
	font-size: var( --wwp-stamp-size, clamp( 10px, 2.3vw, 15px ) );
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	line-height: 1.2;
}
/* Not 1.5em: tying the flag to the label meant it grew fastest exactly where
   there was least room. */
.wwp-hero-stamp-flag { font-size: clamp( 13px, 3vw, 21px ); line-height: 1; }
.wwp-hero-stamp-link {
	font-size: clamp( 9px, 1.7vw, 11px );
	line-height: 1.3;
	color: inherit;
	opacity: 0.82;
	text-decoration: underline;
}
.wwp-hero-stamp-link[hidden] { display: none; }
.wwp-hero-stamp-link:hover { opacity: 1; }

/* Out of the way while the video is actually playing. */
.wwp-hero.is-live .wwp-hero-stamp {
	opacity: 0.35;
	transition: opacity 0.3s ease;
}
.wwp-hero.is-live .wwp-hero-stamp:hover { opacity: 1; }

@media ( prefers-reduced-motion: reduce ) {
	/* Drops the tilt, keeps the size - the scale is layout, not motion. */
	.wwp-hero-stamp { transform: scale( var( --wwp-stamp-scale, 0.7 ) ); }
}

/* On a phone the stamp shares the frame with the film strip and the controls,
   so it tucks in tighter. It keeps the tilt: an earlier version dropped it
   here on the theory that it read as clutter at small sizes, but the mark is
   more legible as a stamp with it than without, and it is the same mark on
   both viewports. */
@media ( max-width: 640px ) {
	.wwp-hero-stamp {
		gap: 0;
		max-width: 62%;
	}
	/*
	 * The sub-label is unreadable at this size and only makes the stamp
	 * taller, so the whole stamp becomes the tap target instead - which is
	 * also a far better one than a 9px line of text.
	 */
	.wwp-hero-stamp-link {
		position: absolute;
		inset: 0;
		font-size: 0;
		text-decoration: none;
		border-radius: inherit;
	}
	.wwp-hero-stamp-link:focus-visible {
		outline: 2px solid var( --wwp-accent, #e5133b );
		outline-offset: 2px;
	}
	/* A hint that it goes somewhere, without spending a line on it. */
	.wwp-hero-stamp:has( .wwp-hero-stamp-link:not( [hidden] ) ) .wwp-hero-stamp-made::after {
		content: " ›";
		opacity: 0.7;
	}
}

/* Clear the floating site header. */
body.home .wwp-hero { --wwp-stamp-offset: var( --topnav-h, 70px ); }
/* Clear a top-mounted film strip. */
.wwp-hero[data-cue-overlay="1"][data-cue="top"] { --wwp-stamp-offset: var( --wwp-cue-h, 0px ); }
/* Clear both, when both are in play. */
body.home .wwp-hero[data-cue-overlay="1"][data-cue="top"] {
	--wwp-stamp-offset: calc( var( --topnav-h, 70px ) + var( --wwp-cue-h, 0px ) );
}

/* --- metadata bar, under the video ------------------------------------ */
.wwp-hero-meta {
	position: relative;
	display: flex;
	align-items: center;
	gap: 12px;
	padding: var( --wwp-meta-pad, 12px clamp( 12px, 2vw, 24px ) );
	color: var( --wwp-meta-fg, #fff );
	background: var( --wwp-meta-bg, rgba( 16, 16, 20, 0.92 ) );
	backdrop-filter: blur( var( --wwp-meta-blur, 0px ) );
	-webkit-backdrop-filter: blur( var( --wwp-meta-blur, 0px ) );
	font-family: var( --wwp-meta-font, inherit );
}
.wwp-hero-meta-text { flex: 1 1 auto; min-width: 0; }
.wwp-hero-title {
	display: block;
	font-size: var( --wwp-meta-title-size, 17px );
	font-weight: var( --wwp-meta-title-weight, 700 );
	line-height: 1.25;
	color: inherit;
	text-decoration: none;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.wwp-hero-title:hover { text-decoration: underline; }
.wwp-hero-sub {
	display: flex;
	gap: 8px;
	margin-top: 2px;
	font-size: var( --wwp-meta-sub-size, 13px );
	opacity: var( --wwp-meta-sub-opacity, 0.72 );
}
.wwp-hero-pos::before { content: "· "; }
.wwp-hero-genre::before { content: "· "; }
.wwp-hero-genre[hidden] { display: none; }

/* Country of origin, right-aligned in the bar. */
.wwp-hero-country {
	display: flex;
	align-items: center;
	gap: 6px;
	flex: 0 0 auto;
	font-size: var( --wwp-meta-country-size, 13px );
	opacity: var( --wwp-meta-country-opacity, 0.8 );
	white-space: nowrap;
}
.wwp-hero-country[hidden] { display: none; }
.wwp-hero-flag { font-size: 1.15em; line-height: 1; }

.wwp-hero-meta-layer { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.wwp-hero-meta-layer[data-slot="over"] {
	position: absolute;
	inset: 0;
	justify-content: center;
	pointer-events: none;
}
.wwp-hero-meta-layer[data-slot="over"] > * { pointer-events: auto; }
.wwp-hero-meta-layer:empty { display: none; }
.wwp-hero-layer { max-height: 40px; width: auto; display: block; }

/* Dwell progress. Animation duration is set from the hero's own setting. */
.wwp-hero-progress {
	position: absolute;
	left: 0;
	right: 0;
	top: 0;
	height: 2px;
	background: rgba( 255, 255, 255, 0.12 );
}
.wwp-hero-progress > span {
	display: block;
	height: 100%;
	width: 0;
	background: var( --wwp-accent, #e5133b );
}
.wwp-hero:not( .is-held ) .wwp-hero-progress > span {
	animation: wwp-progress var( --wwp-dwell, 5s ) linear both;
}
@keyframes wwp-progress { from { width: 0 } to { width: 100% } }

@media ( max-width: 640px ) {
	.wwp-hero-cue-item { width: var( --wwp-cue-size-mobile, 84px ); }
	.wwp-hero-title { font-size: var( --wwp-meta-title-size-mobile, 15px ); }
}

/* Embed fallback: no film strip or metadata bar, so the stage is the hero. */
.wwp-hero-fallback .wwp-hero-stage { aspect-ratio: var( --wwp-hero-ratio, 16 / 9 ); }

/* --- immersive view --------------------------------------------------------
   Expands the hero to fill the viewport in place. "In place" is the whole
   trick: moving the player into a modal container would tear the iframe out of
   the document and reload it, restarting the video. Nothing is reparented -
   only the hero's own position changes, so playback continues untouched.

   Not the native Fullscreen API, because iPhone Safari does not implement
   requestFullscreen() on arbitrary elements, and the video-element fallback
   hands the frame to the platform player, losing the film strip, the country
   stamp and the metadata bar. */
/* Specificity note: the ambient backdrop sets position and z-index through
   `body.has-wwp-ambient .wwp-hero` (0,2,1), which outranks a bare
   `.wwp-hero.is-immersive` (0,2,0) and silently kept the hero relative. The
   leading `body` matches that weight, and being later in the file wins. */
body .wwp-hero.is-immersive,
body.has-wwp-ambient .wwp-hero.is-immersive {
	position: fixed;
	inset: 0;
	z-index: 99999;
	width: 100%;
	/* dvh tracks the mobile browser's collapsing chrome; vh is the fallback
	   for anything that does not know dvh, and would otherwise leave the
	   bottom of the frame under the address bar. */
	height: 100vh;
	height: 100dvh;
	max-height: none;
	margin: 0;
	border-radius: 0;
	/* !important because the ambient backdrop deliberately makes .wwp-hero
	   transparent so the fixed blurred layer shows through it. That is right
	   for the hero in the page and wrong for a full-viewport layer, where a
	   transparent hero simply shows the stories and Pick Hits rails through
	   the video. The two states are mutually exclusive, so this overrides
	   rather than out-specifies. */
	background: #000 !important;
	display: flex;
	flex-direction: column;
}

/* The header floats over the hero on the front page and the stamp is offset to
   clear it. Nothing floats over an immersive hero. */
body .wwp-hero.is-immersive {
	--wwp-stamp-offset: 0px;
}

/* The stage takes the room the meta bar and film strip do not. */
.wwp-hero.is-immersive .wwp-hero-stage {
	flex: 1 1 auto;
	min-height: 0;
	height: auto;
}

.wwp-hero.is-immersive .wwp-hero-meta {
	flex: 0 0 auto;
}

/* Nothing behind the layer should scroll or be reachable. */
body.wwp-immersive-open {
	overflow: hidden;
	touch-action: none;
}

/* The button swaps meaning, so it swaps glyph. */
.wwp-hero-expand .wwp-i-collapse,
.wwp-hero.is-immersive .wwp-hero-expand .wwp-i-expand {
	display: none;
}

.wwp-hero.is-immersive .wwp-hero-expand .wwp-i-collapse {
	display: inline;
}

/* In immersive view the exit control is the one thing that must be findable
   without hunting, so it leaves the action cluster and takes the corner where
   a close button is expected - clear of the film strip at either position. */
.wwp-hero.is-immersive .wwp-hero-expand {
	position: fixed;
	top: max( 12px, env( safe-area-inset-top ) );
	right: max( 12px, env( safe-area-inset-right ) );
	z-index: 12;
}

/* The idle timer fades every .wwp-hero-btn and stops it taking taps, which is
   right for the sound and bookmark buttons and wrong for this one: fading the
   only visible way out of a full-screen layer strands the reader. Escape and
   the back gesture still work, but neither is discoverable. Unconditional -
   not inside a hover media query, which is how this first shipped and why the
   button was invisible on a touch device. */
body .wwp-hero.is-immersive .wwp-hero-expand,
body .wwp-hero.is-immersive.is-idle .wwp-hero-expand {
	opacity: 1 !important;
	visibility: visible !important;
	pointer-events: auto !important;
}


/* --- immersive: filling the frame ------------------------------------------
   A 16:9 music video in a 9:16 phone viewport is letterboxed, which is
   correct - cropping it would throw away most of the picture. But a portrait
   video in a portrait viewport should go edge to edge, and by default the
   embed still letterboxes it inside its own player.

   hero.js sets --wwp-item-aspect from the item and adds .is-fill only when the
   item is portrait, so the crop is opt-in per item rather than blanket. */
body .wwp-hero.is-immersive .wwp-hero-stage {
	position: relative;
	overflow: hidden;
}

/* The stage's two media children: .wwp-hero-track holds the poster slides,
   .wwp-hero-player holds the embed. Scoped to direct children because the
   film strip also lives in the stage and must not be scaled with them. */
body .wwp-hero.is-immersive.is-fill > .wwp-hero-stage > .wwp-hero-track,
body .wwp-hero.is-immersive.is-fill > .wwp-hero-stage > .wwp-hero-player {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate( -50%, -50% );
	/* Whichever dimension would leave a gap is grown past 100% instead, and
	   the overflow is cropped by the stage. */
	/* To cover, the dimension that would leave a gap grows past 100% and the
	   stage crops the overflow. A frame wider than its box (item aspect >
	   stage aspect) grows in width; a taller one grows in height. Getting
	   these two the wrong way round scales the frame off-screen entirely. */
	width: max( 100%, calc( 100% * var( --wwp-item-aspect, 1.778 ) / var( --wwp-stage-aspect, 1 ) ) );
	height: max( 100%, calc( 100% * var( --wwp-stage-aspect, 1 ) / var( --wwp-item-aspect, 1.778 ) ) );
	max-width: none;
	object-fit: cover;
}


/* The letterbox carries the blurred still, not flat black. A 16:9 video in a
   9:16 frame will always leave bars - this is the same treatment the page
   ambient backdrop uses, reusing its tuning variables so the two read as one
   idea rather than two. Black stays underneath as the base, so nothing behind
   the layer can ever show through. */
body .wwp-hero.is-immersive::before {
	content: "";
	position: absolute;
	/* Overscanned so the blur's soft edge never reaches the frame edge. */
	inset: -8%;
	background-image: var( --wwp-immersive-still, none );
	background-size: cover;
	background-position: center;
	filter: blur( var( --wwp-ambient-blur, 44px ) )
		brightness( var( --wwp-ambient-brightness, 0.6 ) );
	opacity: var( --wwp-ambient-opacity, 0.55 );
	z-index: 0;
	pointer-events: none;
}

/* Everything that is not the backdrop sits above it. */
body .wwp-hero.is-immersive > .wwp-hero-stage,
body .wwp-hero.is-immersive > .wwp-hero-meta {
	position: relative;
	z-index: 1;
}

/* --- prev/next arrows on touch ---------------------------------------------
   Hidden where there is no pointer, because swipe replaces them there and they
   were causing a real problem: the arrows are vertically centred in the
   overlay, and on a phone the hero is short enough (306px vs ~787px on
   desktop) that centring puts them 11px underneath the floating header, over
   the hamburger and the account avatar.

   Both halves matter - swiping is the better gesture anyway, and removing the
   arrows on touch is what resolves the collision. Pointer devices keep them,
   where the hero is tall enough that they sit nowhere near the header.

   Trade-off worth knowing: a first-time visitor on a phone has no visible
   affordance saying the hero can be swiped. The film strip underneath is the
   thing carrying that signal - it shows there are more items and is tappable
   in its own right. */
@media ( hover: none ) {
	.wwp-hero-prev,
	.wwp-hero-next {
		display: none;
	}
}

/* --- play the whole playlist -------------------------------------------
   The primary action in the cluster. It used to carry the accent red, which
   the owner found off-key against the rest of the site (2026-09-12) - so it
   is now a white ring with a solid glyph, the classic player mark.

   A RING rather than a filled disc, which is the harder thing to keep
   legible: there is no solid field behind the glyph, and the hero plays
   video, so the button can land on a white frame. The drop-shadow is what
   keeps the ring and the triangle readable there - without it this design
   disappears entirely on bright footage, which is exactly the case a still
   mockup never shows. */
.wwp-hero-playall {
	background: transparent;
	color: #fff;
	border: 2px solid #fff;
	/* The frosted disc belonged to the filled treatment; behind a ring it
	   reads as a smudged circle rather than an outline. */
	backdrop-filter: none;
	-webkit-backdrop-filter: none;
	filter: drop-shadow( 0 1px 3px rgba( 0, 0, 0, 0.75 ) );
}
/* The glyph is a triangle, which is optically left-heavy inside a circle -
   its visual centre sits behind its leading edge. A hair to the right makes
   it look centred, which geometric centring does not. */
.wwp-hero-playall .wwp-i-playall {
	transform: translateX( 1px );
}
.wwp-hero-playall:hover,
.wwp-hero-playall:focus-visible {
	background: rgba( 255, 255, 255, 0.18 );
	border-color: #fff;
	filter: drop-shadow( 0 1px 3px rgba( 0, 0, 0, 0.75 ) );
}
.wwp-hero-playall .wwp-i-stopall,
.wwp-hero-playall[aria-pressed="true"] .wwp-i-playall { display: none; }
.wwp-hero-playall[aria-pressed="true"] .wwp-i-stopall { display: inline; }

/* While the list is playing the strip is a queue rather than a shop window,
   so the item being played is worth more than a thin outline. */
.wwp-hero.is-playall .wwp-hero-cue-item.is-active {
	outline-width: 3px;
	opacity: 1;
}
/* Everything before the playhead reads as already heard. */
.wwp-hero.is-playall .wwp-hero-cue-item { opacity: 0.45; }
.wwp-hero.is-playall .wwp-hero-cue-item:hover,
.wwp-hero.is-playall .wwp-hero-cue-item:focus-visible { opacity: 0.9; }

/* ---------------------------------------------------------------------------
   The film strip dips away during playback.

   Transform, not display or height: the strip keeps its box, so the stage does
   not resize underneath the video every seven seconds - a layout that reflows
   while you are watching is worse than chrome that stays. Pointer events go
   with it so a hidden strip cannot swallow a tap meant for the video.

   Only ever applied while playing, by the script. An idle hero keeps its strip.
   --------------------------------------------------------------------------- */
.wwp-hero .wwp-hero-cue {
	transition: transform .32s ease, opacity .32s ease;
	will-change: transform;
}

.wwp-hero.is-cue-away[data-cue="bottom"] .wwp-hero-cue { transform: translateY( 105% ); }
.wwp-hero.is-cue-away[data-cue="top"]    .wwp-hero-cue { transform: translateY( -105% ); }
.wwp-hero.is-cue-away[data-cue="left"]   .wwp-hero-cue { transform: translateX( -105% ); }
.wwp-hero.is-cue-away[data-cue="right"]  .wwp-hero-cue { transform: translateX( 105% ); }

.wwp-hero.is-cue-away .wwp-hero-cue {
	opacity: 0;
	pointer-events: none;
}

/* In flow rather than overlaid, sliding it away would leave a hole the size of
   the strip. Collapse it instead, and keep the same duration so the two
   arrangements feel like one behaviour. */
.wwp-hero:not([data-cue-overlay="1"]).is-cue-away .wwp-hero-cue {
	transform: none;
	max-height: 0;
	margin: 0;
	overflow: hidden;
	transition: max-height .32s ease, opacity .32s ease, margin .32s ease;
}

/* Somebody who has asked for less motion gets the same behaviour without the
   slide - the strip is still out of the way, it just stops animating there. */
@media ( prefers-reduced-motion: reduce ) {
	.wwp-hero .wwp-hero-cue { transition: opacity .01s linear; }
	.wwp-hero.is-cue-away .wwp-hero-cue { transform: none; }
}

/* --- the strip's second content: stations (Rule 14a) ------------------- */

/* Rule 14b: a cell here shows a NAME, not a number. The name is the cell's
   whole point, so it sits over the whole face rather than in a corner badge
   the way a track number does — and it stays legible whether or not the
   station has artwork behind it. */
.wwp-hero-cue-station .wwp-hero-cue-name {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0 6px;
	font: 700 clamp( 11px, 1.4vw, 14px )/1.2 inherit;
	letter-spacing: 0.02em;
	text-align: center;
	color: #fff;
	text-shadow: 0 1px 3px rgba( 0, 0, 0, 0.9 );
	/* A station with no artwork still needs a readable face, and one WITH
	   artwork still needs the name to win over it. */
	background: linear-gradient( rgba( 0, 0, 0, 0.25 ), rgba( 0, 0, 0, 0.65 ) );
	overflow: hidden;
}

/* The station holding the hero. Same accent as the track cue's playhead, so
   "this is the one you are on" reads identically in both contents. */
.wwp-hero-cue-station.is-active {
	opacity: 1;
	outline-color: var( --wwp-accent, #e5133b );
}

/* The toggle. Sized to the other action buttons so the cluster stays a row of
   equals rather than one odd control. */
.wwp-hero-stations-icon {
	width: 1.15em;
	height: 1.15em;
	display: block;
	object-fit: contain;
	/* The site icon is the default mark and may be a light square; a subtle
	   ring keeps it from reading as a blank tile on a dark bar. */
	border-radius: 50%;
}
.wwp-hero.is-stations .wwp-hero-stations {
	outline: 2px solid var( --wwp-accent, #e5133b );
	outline-offset: 2px;
}

/* Fetching a station's tracks. Deliberately only on the strip: the video
   behind it is still playing the previous station and must not be dimmed as
   though it had stopped. */
.wwp-hero.is-station-loading .wwp-hero-cue {
	opacity: 0.6;
	pointer-events: none;
}
.wwp-hero.has-station-error .wwp-hero-cue {
	outline: 2px solid rgba( 229, 19, 59, 0.9 );
	outline-offset: 2px;
}

@media ( prefers-reduced-motion: reduce ) {
	.wwp-hero-cue-item { transition: none; }
}

/* --- control pad skins -------------------------------------------------
   The owner's name for the cluster of round buttons over the video. These
   change the FINISH only: size, spacing and hit targets are untouched, so a
   skin can never make a control harder to press, and nothing here touches the
   video, the film strip or the metadata bar. Selected in
   Customizer > Top Nav > Hero > "Control pad style". */

/* --- Jukebox: 1950s chrome and amber ---------------------------------- */
.wwp-hero[data-pad="jukebox"] .wwp-hero-btn {
	color: #fff3d6;
	/* Chrome is a GRADIENT, not a colour - a flat grey disc reads as plastic.
	   The hard stop at the middle is the horizon line every chrome bezel has. */
	background:
		linear-gradient( #2a2118 0%, #120d09 100% ) padding-box,
		linear-gradient( #ffffff 0%, #c8ccd2 42%, #6d7078 52%, #f2f4f7 100% ) border-box;
	border: 2px solid transparent;
	backdrop-filter: none;
	-webkit-backdrop-filter: none;
	box-shadow:
		0 0 10px rgba( 255, 176, 0, 0.35 ),
		inset 0 1px 2px rgba( 255, 226, 168, 0.45 ),
		inset 0 -2px 4px rgba( 0, 0, 0, 0.55 );
	text-shadow: 0 0 6px rgba( 255, 176, 0, 0.8 );
}
.wwp-hero[data-pad="jukebox"] .wwp-hero-btn:hover,
.wwp-hero[data-pad="jukebox"] .wwp-hero-btn:focus-visible {
	box-shadow:
		0 0 16px rgba( 255, 176, 0, 0.75 ),
		inset 0 1px 2px rgba( 255, 232, 184, 0.6 ),
		inset 0 -2px 4px rgba( 0, 0, 0, 0.5 );
}
/* The play button keeps its ring, but the ring goes warm rather than white. */
.wwp-hero[data-pad="jukebox"] .wwp-hero-playall {
	border-color: #ffd27a;
	background: transparent;
}

/* --- Bakelite: the classic radio set ---------------------------------- */
.wwp-hero[data-pad="bakelite"] .wwp-hero-btn {
	color: #f4e4c1;
	/* Phenolic resin is translucent and swirled, so the highlight sits OFF
	   centre - a centred radial reads as a plastic bubble instead. */
	background:
		radial-gradient( circle at 34% 28%, #96603a 0%, #6b3f22 45%, #3d2312 100% );
	border: 2px solid #c9a227;
	backdrop-filter: none;
	-webkit-backdrop-filter: none;
	box-shadow:
		0 2px 5px rgba( 0, 0, 0, 0.5 ),
		inset 0 2px 5px rgba( 255, 214, 150, 0.28 ),
		inset 0 -3px 6px rgba( 0, 0, 0, 0.5 );
	text-shadow: 0 1px 1px rgba( 0, 0, 0, 0.6 );
}
.wwp-hero[data-pad="bakelite"] .wwp-hero-btn:hover,
.wwp-hero[data-pad="bakelite"] .wwp-hero-btn:focus-visible {
	border-color: #e3bf4a;
	background:
		radial-gradient( circle at 34% 28%, #a86c42 0%, #7a4828 45%, #46280f 100% );
}
.wwp-hero[data-pad="bakelite"] .wwp-hero-playall {
	border-color: #e3bf4a;
	background: radial-gradient( circle at 34% 28%, #96603a 0%, #6b3f22 45%, #3d2312 100% );
}

/* Both skins are heavy finishes; honour a request for less motion by
   dropping their transitions, not their look. */
@media ( prefers-reduced-motion: reduce ) {
	.wwp-hero[data-pad="jukebox"] .wwp-hero-btn,
	.wwp-hero[data-pad="bakelite"] .wwp-hero-btn { transition: none; }
}

/* One playlist control at a time, and never two.

   Below 770px the Now Playing bar's second hamburger IS the playlist selector
   (assets/js/strip-toggle.js repurposes it in place), so the hero's own globe
   would be a duplicate of it - which is exactly what the owner objected to.
   Above 770px that hamburger is hidden by the theme and the pill does not
   exist, so the hero's button is the only one there is.

   Scoped to the hero deliberately: the Now Playing bar's layout is
   load-bearing and is not touched by this. */
@media screen and ( max-width: 769px ) {
	.wwp-hero-stations { display: none !important; }
}

/* --- "Now Playing", desktop only ---------------------------------------
   The Now Playing bar carries this badge on a phone, but its pill is hidden
   above 770px, so on desktop nothing named the mark. It sits to the LEFT of
   the country flag in the metadata row (owner, 2026-09-12).

   Matched to the bar's own .wwp-rail-tag-now so the two read as the same
   badge at different widths: same radius, tracking, weight and accent. */
.wwp-hero-nowtag {
	display: none;
	flex: 0 0 auto;
	margin-left: auto;
	margin-right: 10px;
	padding: 2px 7px;
	border-radius: 3px;
	background: var( --wwp-accent, #da1b1b );
	color: #fff;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	line-height: 1.5;
	white-space: nowrap;
}
@media screen and ( min-width: 770px ) {
	.wwp-hero-nowtag { display: inline-block; }
	/* The country box was carrying the push to the right edge on its own.
	   With the badge in front of it, the badge takes that job and the two
	   travel together as a pair. */
	.wwp-hero-nowtag + .wwp-hero-country { margin-left: 0; }
}
/* Nothing is playing yet, so neither is the claim. */
.wwp-hero:not( .is-playing ) .wwp-hero-nowtag { visibility: hidden; }


/* --- desktop height ----------------------------------------------------------
   Owner, 2026-09-28: on a desktop the 16:9 stage filled the screen (877px of a
   900px window, pinned), leaving no room for the page. Capped at a share of
   the screen height (Customizer -> Hero Video, --wwp-hero-vh, default 65),
   and kept EDGE TO EDGE - no side bars: the embed keeps its own 16:9 box at
   full width and is centred vertically, the stage cropping top and bottom.
   The poster slides are cover-sized already. Phones keep the full 16:9, and
   the immersive view has its own sizing. */
@media ( min-width: 770px ) {
	body .wwp-hero:not( .is-immersive ) {
		container-type: inline-size;
	}

	body .wwp-hero:not( .is-immersive ) > .wwp-hero-stage {
		aspect-ratio: auto;
		height: min( calc( 100cqw / ( var( --wwp-hero-ratio, 16 / 9 ) ) ), calc( var( --wwp-hero-vh, 65 ) * 1vh ) );
	}

	/* Posters too: they are 16:9 thumbnails, so filling the wider stage
	   trims them top and bottom instead of leaving side bars. */
	body .wwp-hero:not( .is-immersive ) > .wwp-hero-stage .wwp-hero-slide img {
		object-fit: cover;
	}

	body .wwp-hero:not( .is-immersive ) > .wwp-hero-stage > .wwp-hero-player {
		inset: auto 0;
		top: 50%;
		width: 100%;
		height: auto;
		aspect-ratio: var( --wwp-hero-ratio, 16 / 9 );
		transform: translateY( -50% );
	}
}


/* --- pin / scroll-away toggle (title bar, left of NOW PLAYING) -------------- */
.wwp-hero-pin {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	margin: 0 8px 0 0;
	padding: 0;
	color: #9a9aa3;
	font-size: 15px;
	background: rgba( 255, 255, 255, 0.06 );
	border: 1px solid rgba( 255, 255, 255, 0.12 );
	border-radius: 50%;
	cursor: pointer;
	transition: color 0.2s ease, background 0.2s ease, transform 0.2s ease;
}

/* Unpinned: the pin lies tilted, as if pulled out. */
.wwp-hero-pin i {
	transform: rotate( 45deg );
	transition: transform 0.2s ease;
}

.wwp-hero-pin:hover {
	color: #fff;
	background: rgba( 255, 255, 255, 0.12 );
}

/* Pinned: upright, in WorldWidePop gold. */
.wwp-hero-pin[aria-pressed="true"] {
	color: #e0b451;
	border-color: rgba( 224, 180, 81, 0.55 );
	background: rgba( 224, 180, 81, 0.12 );
}

.wwp-hero-pin[aria-pressed="true"] i {
	transform: none;
}

.wwp-hero-pin:focus-visible {
	outline: 2px solid #e0b451;
	outline-offset: 2px;
}

/* Pause / carry on (owner, 2026-10-17). Shows pause while the stage plays, play when it is paused or still. */
.wwp-hero-pause .wwp-i-resume { display: none; }
.wwp-hero.is-stage-paused .wwp-hero-pause .wwp-i-pause { display: none; }
.wwp-hero.is-stage-paused .wwp-hero-pause .wwp-i-resume { display: inline; }
.wwp-hero-pause span { display: inline-grid; place-items: center; line-height: 0; }
.wwp-hero.is-stage-paused .wwp-hero-pause .wwp-i-resume { display: inline-grid; }
