/**
 * com_nbradio - player skin.
 *
 * Deliberately minimal: every colour and size goes through a `--nbradio-*`
 * custom property, so a template can restyle the player without overriding
 * a single rule.
 *
 * The layout is driven by CONTAINER queries, not viewport ones - the player
 * has to fit whatever module position it is dropped into, which has nothing
 * to do with how wide the screen is. The stacked layout is the base case, so
 * a browser without container query support still gets something that fits;
 * the roomier side-by-side layout is the enhancement.
 *
 * @copyright  (C) 2026 Olvedi Hunor. All rights reserved.
 * @license    GNU General Public License version 2 or later
 */

.nbradio {
	--nbradio-bg: #16181d;
	--nbradio-text: #f2f3f5;
	--nbradio-muted: #9aa0aa;
	--nbradio-accent: #4dd0a7;
	--nbradio-border: rgba(255, 255, 255, .12);
	--nbradio-radius: .6rem;
	--nbradio-art: 150px;
	--nbradio-width: 420px;
	--nbradio-gap: .6rem;
	--nbradio-btn: 2rem;
	--nbradio-shadow: 0 .5rem 1.5rem rgba(0, 0, 0, .35);

	container-type: inline-size;
	container-name: nbradio;

	box-sizing: border-box;
	width: 100%;
	max-width: var(--nbradio-width);
	overflow: hidden;
	color: var(--nbradio-text);
	background: var(--nbradio-bg);
	border: 1px solid var(--nbradio-border);
	border-radius: var(--nbradio-radius);
	box-shadow: var(--nbradio-shadow);
	font-size: .8125rem;
	line-height: 1.35;
}

.nbradio *,
.nbradio *::before,
.nbradio *::after {
	box-sizing: inherit;
	min-width: 0;
}

/* The panels below set display, which would otherwise beat [hidden] */
.nbradio [hidden] {
	display: none !important;
}

.nbradio--small {
	--nbradio-width: 340px;
}

.nbradio--large {
	--nbradio-width: 520px;
}

.nbradio--bottom-left,
.nbradio--bottom-right {
	position: fixed;
	bottom: 1rem;
	z-index: 1030;
}

.nbradio--bottom-left {
	left: 1rem;
}

.nbradio--bottom-right {
	right: 1rem;
}

/* -- consent placeholder ------------------------------------------------- */

.nbradio__consent {
	display: flex;
	flex-direction: column;
	gap: .35rem;
	padding: var(--nbradio-gap);
}

.nbradio__consent-button {
	display: flex;
	align-items: center;
	gap: .5rem;
	width: 100%;
	padding: .6rem .7rem;
	color: var(--nbradio-bg);
	background: var(--nbradio-accent);
	border: 0;
	border-radius: calc(var(--nbradio-radius) - .2rem);
	font: inherit;
	font-weight: 600;
	text-align: left;
	cursor: pointer;
}

.nbradio__consent-text {
	overflow: hidden;
	text-overflow: ellipsis;
}

.nbradio__consent-button:hover,
.nbradio__consent-button:focus-visible {
	filter: brightness(1.08);
}

.nbradio__cookie-link {
	align-self: flex-start;
	padding: 0;
	color: var(--nbradio-muted);
	background: none;
	border: 0;
	font: inherit;
	font-size: .75rem;
	text-decoration: underline;
	cursor: pointer;
}

/* -- pop-out strip ------------------------------------------------------- */

.nbradio__remote {
	display: flex;
	align-items: center;
	gap: .5rem;
	padding: var(--nbradio-gap);
}

.nbradio__remote-body {
	flex: 1 1 auto;
}

.nbradio__remote-text,
.nbradio__remote-track {
	display: block;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.nbradio__remote-text {
	color: var(--nbradio-muted);
	font-size: .75rem;
}

.nbradio__remote-track {
	font-weight: 600;
}

/*
 * A labelled action, not an icon button: .nbradio__button is a fixed square
 * sized for a single glyph, which crushes a word or three into a column.
 */
.nbradio__action {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	gap: .35em;
	padding: .3rem .7rem;
	border: 1px solid var(--nbradio-accent);
	border-radius: 100px;
	background: transparent;
	color: var(--nbradio-accent);
	font: inherit;
	font-size: .85em;
	font-weight: 600;
	line-height: 1.3;
	white-space: nowrap;
	cursor: pointer;
	transition: background .15s ease, color .15s ease;
}

.nbradio__action:hover,
.nbradio__action:focus-visible {
	color: var(--nbradio-bg);
	background: var(--nbradio-accent);
}

.nbradio__action-icon {
	font-size: .8em;
}

/* -- player: stacked base layout ----------------------------------------- */

.nbradio__player {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: var(--nbradio-gap);
	padding: var(--nbradio-gap);
}

.nbradio__art {
	flex: 0 0 auto;
	width: 100%;
	aspect-ratio: 16 / 9;
	overflow: hidden;
	background: #000;
	border-radius: calc(var(--nbradio-radius) - .2rem);
}

/* The YouTube frame stays visible - a hidden player is not permitted */
.nbradio__art iframe {
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
}

.nbradio__body {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	gap: .35rem;
}

.nbradio__list {
	margin: 0;
	overflow: hidden;
	color: var(--nbradio-muted);
	font-size: .7rem;
	text-overflow: ellipsis;
	text-transform: uppercase;
	letter-spacing: .04em;
	white-space: nowrap;
}

.nbradio__track {
	display: -webkit-box;
	overflow: hidden;
	margin: 0;
	font-weight: 600;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
}

/* -- progress and volume ------------------------------------------------- */

.nbradio__progress {
	margin-top: auto;
}

.nbradio__times {
	display: flex;
	justify-content: space-between;
	color: var(--nbradio-muted);
	font-size: .7rem;
	font-variant-numeric: tabular-nums;
}

.nbradio__range {
	display: block;
	width: 100%;
	height: 1rem;
	margin: 0;
	accent-color: var(--nbradio-accent);
	cursor: pointer;
}

/* -- controls ------------------------------------------------------------ */

.nbradio__controls {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: .15rem;
}

.nbradio__button {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: var(--nbradio-btn);
	height: var(--nbradio-btn);
	padding: 0;
	color: var(--nbradio-text);
	background: none;
	border: 0;
	border-radius: .3rem;
	font: inherit;
	font-size: calc(var(--nbradio-btn) * .5);
	line-height: 1;
	cursor: pointer;
}

.nbradio__button:hover,
.nbradio__button:focus-visible {
	background: rgba(255, 255, 255, .08);
}

.nbradio__button--play {
	color: var(--nbradio-bg);
	background: var(--nbradio-accent);
}

.nbradio__button--play:hover,
.nbradio__button--play:focus-visible {
	background: var(--nbradio-accent);
	filter: brightness(1.08);
}

.nbradio__button--toggle {
	opacity: .45;
}

.nbradio__button--toggle.is-active {
	opacity: 1;
	color: var(--nbradio-accent);
}

.nbradio__button--toggle.is-one::after {
	content: "1";
	margin-left: .1rem;
	font-size: .6rem;
	vertical-align: super;
}

/*
 * Placed after the toggle rules on purpose: equal specificity, so the later
 * one wins and a disabled shuffle cannot be left looking active.
 */
.nbradio__button:disabled,
.nbradio__button--toggle:disabled {
	opacity: .25;
	cursor: default;
}

.nbradio__button:disabled:hover,
.nbradio__button:disabled:focus-visible {
	background: none;
}

/* The volume slider is the one control allowed to give up its width */
.nbradio__volume {
	display: flex;
	flex: 1 1 55px;
	align-items: center;
	min-width: 45px;
	max-width: 110px;
	height: var(--nbradio-btn);
	padding: 0 .2rem;
}

.nbradio__range--volume {
	height: .9rem;
}

.nbradio__collapse {
	position: absolute;
	top: .15rem;
	right: .15rem;
	width: 1.4rem;
	height: 1.4rem;
	padding: 0;
	color: var(--nbradio-muted);
	background: none;
	border: 0;
	font-size: .75rem;
	line-height: 1;
	cursor: pointer;
}

/* -- variants ------------------------------------------------------------ */

/*
 * "Show video frame = no". The frame is dropped from the layout entirely,
 * which is what makes the player fit a narrow position - note that this
 * departs from YouTube's IFrame API terms, which expect a visible player.
 */
.nbradio--novideo .nbradio__art {
	display: none;
}

/*
 * Without the frame there is no album art to keep square, so the size cap
 * stops being useful: the player takes whatever width its position gives it
 * and turns into a bar once there is room (see the container query below).
 *
 * The fixed corner placements are excluded on purpose. They sit outside the
 * document flow, so no parent is left to bound them and lifting the cap would
 * stretch them across the entire viewport.
 */
.nbradio--novideo:not(.nbradio--bottom-left):not(.nbradio--bottom-right) {
	max-width: none;
}

/* Lets the player claim the free space in a flex position, e.g. the top bar */
.mod-nbradio-player {
	flex: 1 1 auto;
	min-width: 0;
}

/*
 * Collapsed keeps the transport but shrinks the frame to a thumbnail rather
 * than hiding it, so the visible-player expectation still holds.
 */
.nbradio--collapsed .nbradio__progress,
.nbradio--collapsed .nbradio__list {
	display: none;
}

.nbradio--collapsed .nbradio__track {
	-webkit-line-clamp: 1;
}

.nbradio--collapsed .nbradio__player {
	flex-direction: row;
	align-items: center;
}

.nbradio--collapsed .nbradio__art {
	width: 72px;
	max-width: 40%;
}

/*
 * Container queries below.
 *
 * The custom properties are re-declared on the three PANELS, never on
 * `.nbradio` itself: `.nbradio` establishes the container, and an element
 * cannot match a query against the container it establishes - such a rule
 * would silently never apply.
 */

/* -- roomier containers: album art beside the controls ------------------- */

@container nbradio (min-width: 330px) {
	.nbradio__consent,
	.nbradio__remote,
	.nbradio__player {
		font-size: .875rem;
	}

	.nbradio__player {
		flex-direction: row;
	}

	.nbradio__art {
		width: min(var(--nbradio-art), 40%);
		aspect-ratio: 1;
	}

	.nbradio__controls {
		justify-content: flex-start;
		gap: .2rem;
	}
}

@container nbradio (min-width: 460px) {
	.nbradio__consent,
	.nbradio__remote,
	.nbradio__player {
		--nbradio-art: 180px;
		--nbradio-btn: 2.2rem;
	}
}

/* -- tight containers ----------------------------------------------------- */

@container nbradio (max-width: 300px) {
	.nbradio__consent,
	.nbradio__remote,
	.nbradio__player {
		--nbradio-gap: .5rem;
		--nbradio-btn: 1.85rem;

		font-size: .78rem;
	}
}

@container nbradio (max-width: 240px) {
	.nbradio__consent,
	.nbradio__remote,
	.nbradio__player {
		--nbradio-gap: .45rem;
		--nbradio-btn: 1.7rem;

		font-size: .75rem;
	}

	.nbradio__volume {
		flex-basis: 100%;
		max-width: none;
	}

	/* No room for a label beside the strip text - give it its own line */
	.nbradio__remote {
		flex-direction: column;
		align-items: stretch;
		gap: .45rem;
	}

	.nbradio__action {
		justify-content: center;
	}
}

@container nbradio (max-width: 175px) {
	.nbradio__consent,
	.nbradio__remote,
	.nbradio__player {
		--nbradio-btn: 1.55rem;
		--nbradio-gap: .35rem;
	}

	.nbradio__list,
	.nbradio__times {
		display: none;
	}

	.nbradio__track {
		-webkit-line-clamp: 1;
	}
}

/*
 * -- bar layout: no frame, and width to spare -----------------------------
 *
 * Everything on one line - title, then the progress bar taking whatever is
 * left, then the transport - so the whole player is about as tall as a single
 * button. This is what lets it sit in a fixed-height strip such as the
 * template's 38px top bar, where the stacked layout would overflow.
 */
@container nbradio (min-width: 560px) {
	.nbradio--novideo .nbradio__player {
		--nbradio-btn: 1.65rem;

		flex-direction: row;
		align-items: center;
		padding: .25rem .5rem;
	}

	.nbradio--novideo .nbradio__body {
		flex-direction: row;
		align-items: center;
		gap: .6rem;
	}

	/* The list name is the first thing to go: the track title carries more */
	.nbradio--novideo .nbradio__list {
		display: none;
	}

	.nbradio--novideo .nbradio__track {
		display: block;
		flex: 0 1 auto;
		min-width: 80px;
		max-width: 260px;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	/* Progress takes the rest of the row, with the times alongside it */
	.nbradio--novideo .nbradio__progress {
		display: flex;
		flex: 1 1 auto;
		align-items: center;
		gap: .5rem;
		margin-top: 0;
	}

	.nbradio--novideo .nbradio__progress .nbradio__range {
		flex: 1 1 auto;
	}

	/* Side by side the two readouts would run together, so mark the split */
	.nbradio--novideo .nbradio__times {
		flex: 0 0 auto;
		gap: .3rem;
	}

	.nbradio--novideo .nbradio__times [data-nbradio-current]::after {
		content: "/";
		margin-left: .3rem;
		opacity: .55;
	}

	/* Wrapping here would cost a second row, which is the whole point */
	.nbradio--novideo .nbradio__controls {
		flex: 0 0 auto;
		flex-wrap: nowrap;
	}

	.nbradio--novideo .nbradio__volume {
		flex: 0 0 auto;
		max-width: 80px;
	}

	.nbradio--novideo .nbradio__collapse {
		display: none;
	}
}

/*
 * The consent placeholder and the pop-out strip have to clear the same
 * fixed-height strip the bar does, so they go single-row too.
 */
@container nbradio (min-width: 560px) {
	.nbradio--novideo .nbradio__consent,
	.nbradio--novideo .nbradio__remote {
		padding: .25rem .5rem;
	}

	.nbradio--novideo .nbradio__remote-body {
		display: flex;
		align-items: baseline;
		gap: .5rem;
	}

	.nbradio--novideo .nbradio__remote-text {
		flex: 0 0 auto;
	}
}

/* -- pop-out window ------------------------------------------------------ */

.nbradio-popout {
	padding: .5rem;
}

.nbradio-popout .nbradio {
	max-width: none;
	box-shadow: none;
}

/* -- fixed corner placements never outgrow a phone ----------------------- */

@media (max-width: 575.98px) {
	.nbradio--bottom-left,
	.nbradio--bottom-right {
		right: .5rem;
		bottom: .5rem;
		left: .5rem;
		max-width: none;
	}
}
