/* Frontend player — scoped, CSS-variable driven. No Tailwind (keeps the
   frontend bundle lean). */

.trueplayer-mount {
	--tp-accent: #4f46e5;
	--tp-bg: #000;
	--tp-fg: #fff;
	/* The player's own type stack. Declared as a variable and re-applied to the
	   text-bearing children below: a theme rule on a generic selector beats
	   plain inheritance from the stage, which is why the same video rendered
	   with the theme's font on a page and the player's font in the editor. */
	--tp-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
	width: 100%;
	max-width: 100%;
}

/* Click-to-load poster facade — static HTML shown until the visitor plays, so
   the real player (and its network cost) never loads on page render. */
.tp-facade {
	position: relative;
	display: block;
	width: 100%;
	aspect-ratio: 16 / 9;
	margin: 0;
	padding: 0;
	border: 0;
	cursor: pointer;
	overflow: hidden;
	background: #000;
	border-radius: var( --tp-radius, 10px );
	-moz-appearance: none;
	     appearance: none;
	-webkit-appearance: none;
}
.tp-facade.is-audio {
	aspect-ratio: auto;
	height: 120px;
	background: #111827;
}
/* A poster is a cover image for the frame, so it fills it — the convention
   every video platform uses. `contain` was letterboxing author-uploaded
   posters inside the stage, and it also left YouTube's smaller sizes showing
   the black bars baked into their pixels. Off-ratio art is cropped, centred. */
.tp-facade-poster {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	-o-object-fit: cover;
	   object-fit: cover;
	-o-object-position: center;
	   object-position: center;
	background: #000;
}
.tp-hover-preview {
	-o-object-fit: cover;
	   object-fit: cover;
	animation: tp-preview-in 0.25s ease;
}
@keyframes tp-preview-in {
	from { opacity: 0; }
	to { opacity: 1; }
}
.tp-facade-btn {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate( -50%, -50% );
	width: 68px;
	height: 68px;
	border-radius: 50%;
	background: var( --tp-accent, #4f46e5 );
	color: #fff;
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 2px 14px rgba( 0, 0, 0, 0.35 );
	transition: transform 0.15s ease, filter 0.15s ease;
}
.tp-facade:hover .tp-facade-btn {
	transform: translate( -50%, -50% ) scale( 1.06 );
	filter: brightness( 1.08 );
}
.tp-facade-btn svg {
	width: 30px;
	height: 30px;
	fill: currentColor;
	margin-left: 3px;
}

/* Narrow, centred frame for 9:16 / 1:1 / 4:3 (set by Player.jsx and the facade). */
.tp-facade {
	width: var( --tp-stage-w, 100% );
	margin-inline: auto;
}
.tp-stage:not( .tp-sticky ) {
	width: var( --tp-stage-w, auto );
	margin-inline: auto;
}

.tp-stage {
	position: relative;
	aspect-ratio: 16 / 9;
	background: var(--tp-bg);
	color: var(--tp-fg);
	overflow: hidden;
	border-radius: var(--tp-radius, 10px);
	font-family: var( --tp-font );
	outline: none;
	/* Size container so the control bar can adapt to the player's own width
	   (narrow admin preview panel, small/mobile embeds) instead of the viewport. */
	container-type: inline-size;
}

/* Re-assert the stack on everything that draws text, so a theme's own rules
   can't win over inheritance (see --tp-font). */
.tp-stage .tp-controls,
.tp-stage .tp-time,
.tp-stage .tp-info,
.tp-stage .tp-menu,
.tp-stage .tp-chapter-now,
.tp-stage button,
.tp-stage input,
.tp-stage select {
	font-family: var( --tp-font );
}

/* control-bar style variants */
.tp-bar-solid .tp-controls {
	background: rgba( 0, 0, 0, 0.85 );
}
.tp-bar-minimal .tp-controls {
	background: transparent;
}
.tp-bar-minimal .tp-controls-row {
	background: rgba( 0, 0, 0, 0.45 );
	border-radius: 8px;
	padding: 2px 6px;
}

/* play-button style variants */
.tp-play-square .tp-bigplay {
	border-radius: 8px;
}
.tp-play-soft .tp-bigplay {
	border-radius: 22px;
}

/* sticky (float on scroll) */
/* Reserves the stage's normal footprint once it goes `position: fixed`
   (sticky), and hosts the sentinel the sticky-on-scroll observer watches —
   see the comment in Player.jsx for why this can't be the stage itself. */
.tp-stage-slot {
	position: relative;
	width: 100%;
}
.tp-stage-sentinel {
	position: absolute;
	inset: 0;
	opacity: 0;
	pointer-events: none;
}

/* Shown in the stage's normal spot while it's actually floating in a
   Picture-in-Picture window elsewhere. */
.tp-pip-placeholder {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 10px;
	background: #0b0d12;
	color: rgba( 255, 255, 255, 0.75 );
	font-size: 13px;
	border-radius: var( --tp-radius, 10px );
}
.tp-pip-return {
	background: var( --tp-accent );
	color: #fff;
	border: 0;
	border-radius: 8px;
	padding: 8px 16px;
	font-size: 13px;
	font-weight: 600;
	cursor: pointer;
}

.tp-sticky {
	position: fixed !important;
	z-index: 99999;
	width: 380px;
	max-width: 46vw;
	aspect-ratio: 16 / 9;
	box-shadow: 0 10px 40px rgba( 0, 0, 0, 0.35 );
}
.tp-sticky-bottom-right { right: 20px; bottom: 20px; }
.tp-sticky-bottom-left { left: 20px; bottom: 20px; }
.tp-sticky-top-right { right: 20px; top: 20px; }
.tp-sticky-top-left { left: 20px; top: 20px; }
.tp-sticky-close {
	position: absolute;
	top: 6px;
	left: 6px;
	z-index: 10;
	width: 24px;
	height: 24px;
	border: 0;
	border-radius: 50%;
	background: rgba( 0, 0, 0, 0.6 );
	color: #fff;
	font-size: 16px;
	line-height: 1;
	cursor: pointer;
}
/* Audio: a proper compact player bar, not a short video box. Art tile on the
   left, controls (progress + buttons) fill the rest — no empty picture area. */
.tp-stage.is-audio {
	aspect-ratio: auto;
	height: auto;
	min-height: 72px;
	background: linear-gradient( 180deg, #232838, #171a22 );
	display: flex;
	align-items: center;
	gap: 12px;
	padding-left: 12px;
	overflow: visible; /* let the settings menu pop out of the short bar */
}
.tp-audio-art {
	width: 48px;
	height: 48px;
	flex-shrink: 0;
	border-radius: 8px;
	overflow: hidden;
	background: rgba( 255, 255, 255, 0.08 );
	color: var( --tp-accent );
	display: flex;
	align-items: center;
	justify-content: center;
	z-index: 2;
}
.tp-audio-art img {
	width: 100%;
	height: 100%;
	-o-object-fit: cover;
	   object-fit: cover;
}
.tp-audio-art svg {
	width: 24px;
	height: 24px;
	fill: currentColor;
}
.tp-stage.is-audio .tp-controls {
	position: static;
	background: none;
	flex: 1;
	min-width: 0;
	padding: 8px 14px 8px 0;
}
.tp-audio-title {
	font-size: 12.5px;
	font-weight: 600;
	color: rgba( 255, 255, 255, 0.92 );
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	margin-bottom: 2px;
}
/* Pseudo-waveform progress bar (audio) */
.tp-stage.is-audio .tp-scrubber {
	padding: 4px 0;
}
.tp-wave {
	position: relative;
	display: flex;
	align-items: center;
	gap: 2px;
	height: 26px;
	width: 100%;
}
.tp-wave-bar {
	flex: 1 1 0;
	min-width: 2px;
	min-height: 3px;
	background: rgba( 255, 255, 255, 0.25 );
	border-radius: 1px;
}
.tp-wave-bar.is-played {
	background: var( --tp-accent );
}

.tp-media-container,
.tp-media {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
}
.tp-media {
	-o-object-fit: contain;
	   object-fit: contain;
	background: #000;
}
/* An explicit ratio fills the frame (cropped) instead of leaving black bars. */
.tp-fill .tp-media {
	-o-object-fit: cover;
	   object-fit: cover;
}
.tp-media-container iframe {
	width: 100%;
	height: 100%;
	border: 0;
}

/* Audio mode has no picture. The <audio> element the provider builds is
   invisible on its own, but a player still mounted from before the source was
   switched to audio-only — or a provider that only hands back an iframe —
   would otherwise paint video across the bar, behind the waveform.
   `visibility`, not `display`, so nothing about how the media loads or plays
   changes; the cover art is a sibling and is unaffected. */
.tp-stage.is-audio .tp-media,
.tp-stage.is-audio .tp-media-container iframe {
	visibility: hidden;
}

/* Transparent click-shield over embedded players (YouTube/Vimeo): swallows
   pointer events so their in-frame links can't be clicked, while our own
   controls (z-index 5) and big-play button sit above it and stay usable. */
.tp-shield {
	position: absolute;
	inset: 0;
	z-index: 2;
	cursor: pointer;
	background: transparent;
}

.tp-poster {
	position: absolute;
	inset: 0;
	background-size: cover; /* see .tp-facade-poster — the poster fills the frame */
	background-position: center;
	background-repeat: no-repeat;
	background-color: #000;
	z-index: 3;
}

.tp-logo {
	position: absolute;
	max-height: 34px;
	max-width: 120px;
	opacity: 0.9;
	z-index: 4;
	pointer-events: none;
}
.tp-logo img {
	max-height: 34px;
	max-width: 120px;
	display: block;
}
.tp-logo.is-link {
	pointer-events: auto;
	cursor: pointer;
}
.tp-logo,
.tp-logo-top-right { top: 12px; right: 12px; }
.tp-logo-top-left { top: 12px; left: 12px; right: auto; }
.tp-logo-bottom-right { top: auto; bottom: 52px; right: 12px; }
.tp-logo-bottom-left { top: auto; bottom: 52px; left: 12px; right: auto; }

/* ---- caption cue styling (html5-backed providers) ---- */
.tp-stage video::cue {
	color: var( --tp-cap-color, #fff );
	background-color: var( --tp-cap-bg, rgba( 0, 0, 0, 0.75 ) );
	font-size: calc( 1em * var( --tp-cap-scale, 1 ) );
}

/* ---- skins ----
   Audio layout rules live at the END of this file and are written with a
   three-class prefix (.tp-stage.is-audio.tp-audio-*) so they outrank anything
   here on specificity rather than on source order. A skin rule that needs to
   beat them is a bug — fix it there, don't move this block. */
/* modern: floating-feel solid bar, brighter accents, roomier padding */
.tp-skin-modern .tp-controls {
	background: linear-gradient( transparent, rgba( 10, 12, 20, 0.9 ) );
	padding: 8px 14px 12px;
}
.tp-skin-modern .tp-scrubber-track,
.tp-skin-modern .tp-scrubber-segs {
	height: 6px;
}
.tp-skin-modern .tp-btn {
	border-radius: 8px;
}
.tp-skin-modern .tp-bigplay {
	width: var( --tp-bigplay-size, 84px );
	height: var( --tp-bigplay-size, 84px );
}

/* simple: flat thin bar, no gradient wash */
.tp-skin-simple .tp-controls {
	background: rgba( 0, 0, 0, 0.6 );
	padding: 4px 10px 6px;
}
.tp-skin-simple .tp-scrubber {
	padding: 5px 0;
}
.tp-skin-simple .tp-scrubber-thumb {
	width: 10px;
	height: 10px;
}
.tp-skin-simple .tp-bigplay {
	width: var( --tp-bigplay-size, 64px );
	height: var( --tp-bigplay-size, 64px );
}

/* minimal: scrubber + essentials only; secondary controls hidden */
.tp-skin-minimal .tp-controls {
	background: transparent;
	padding: 4px 10px 8px;
}
.tp-skin-minimal .tp-controls-row {
	background: rgba( 0, 0, 0, 0.5 );
	border-radius: 10px;
	padding: 2px 8px;
}
.tp-skin-minimal .tp-time,
.tp-skin-minimal .tp-volume,
.tp-skin-minimal .tp-chapter-now {
	display: none;
}

/* standard: classic opaque deck, square corners on the bar */
.tp-skin-standard .tp-controls {
	background: rgba( 12, 14, 18, 0.96 );
	padding: 6px 12px 8px;
}
.tp-skin-standard .tp-scrubber-track,
.tp-skin-standard .tp-scrubber-segs,
.tp-skin-standard .tp-scrubber-buffered,
.tp-skin-standard .tp-scrubber-played,
.tp-skin-standard .tp-seg {
	border-radius: 0;
}

/* ---- "In this video" drawer: chapters + transcript ---- */
.tp-info {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 3.4rem;
	width: min( 340px, 42% );
	z-index: 6;
	display: flex;
	flex-direction: column;
	background: rgba( 18, 18, 18, 0.94 );
	backdrop-filter: blur( 6px );
	color: #fff;
	border-top-left-radius: var( --tp-radius, 8px );
	overflow: hidden;
	animation: tp-info-in 0.2s ease;
}
@keyframes tp-info-in {
	from {
		transform: translateX( 16px );
		opacity: 0;
	}
	to {
		transform: none;
		opacity: 1;
	}
}
.tp-info-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 8px 6px 8px 12px;
	border-bottom: 1px solid rgba( 255, 255, 255, 0.1 );
	flex-shrink: 0;
}
.tp-info-tabs {
	display: flex;
	gap: 4px;
}
.tp-info-tab {
	background: transparent;
	border: 0;
	color: rgba( 255, 255, 255, 0.6 );
	font-size: 13px;
	font-weight: 600;
	padding: 6px 10px;
	border-radius: 6px;
	cursor: pointer;
}
.tp-info-tab:hover {
	color: #fff;
}
.tp-info-tab.is-active {
	color: #fff;
	background: rgba( 255, 255, 255, 0.14 );
}
.tp-info-close {
	background: transparent;
	border: 0;
	color: rgba( 255, 255, 255, 0.7 );
	font-size: 22px;
	line-height: 1;
	cursor: pointer;
	width: 30px;
	height: 30px;
	border-radius: 6px;
}
.tp-info-close:hover {
	background: rgba( 255, 255, 255, 0.12 );
	color: #fff;
}
.tp-info-body {
	flex: 1;
	overflow-y: auto;
	padding: 6px;
	scrollbar-width: thin;
}
.tp-info-row {
	display: flex;
	gap: 10px;
	width: 100%;
	text-align: left;
	background: transparent;
	border: 0;
	color: #eaeaea;
	padding: 8px 10px;
	border-radius: 8px;
	cursor: pointer;
	font-size: 13px;
	line-height: 1.4;
	align-items: flex-start;
}
.tp-info-row:hover {
	background: rgba( 255, 255, 255, 0.08 );
}
.tp-info-row.is-active {
	background: rgba( 255, 255, 255, 0.14 );
}
.tp-info-row.is-locked {
	opacity: 0.4;
	cursor: not-allowed;
}
.tp-info-time {
	color: var( --tp-accent );
	font-variant-numeric: tabular-nums;
	font-weight: 600;
	flex-shrink: 0;
	min-width: 44px;
}
.tp-info-cue .tp-info-time {
	color: rgba( 255, 255, 255, 0.45 );
	font-weight: 500;
}
.tp-info-cue.is-active .tp-info-time {
	color: var( --tp-accent );
}
.tp-info-label {
	flex: 1;
}
.tp-info-empty {
	color: rgba( 255, 255, 255, 0.6 );
	font-size: 13px;
	padding: 20px 16px;
	text-align: center;
}
.tp-controls .tp-btn.is-active {
	color: var( --tp-accent );
}
@media ( max-width: 520px ) {
	.tp-info {
		width: 100%;
	}

}

/* ---- controls ---- */
.tp-controls {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	padding: 6px 12px 10px;
	background: linear-gradient( transparent, rgba( 0, 0, 0, 0.72 ) );
	transition: opacity 0.25s ease;
	z-index: 5;
}
.tp-stage.is-idle .tp-controls {
	opacity: 0;
	pointer-events: none;
}
.tp-controls-row {
	display: flex;
	align-items: center;
	gap: 8px;
}
.tp-spacer {
	flex: 1;
}
.tp-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	color: #fff;
	background: transparent;
	border: 0;
	border-radius: 6px;
	cursor: pointer;
	padding: 0;
}
.tp-btn:hover {
	background: var(--tp-hover, rgba( 255, 255, 255, 0.15 ));
}
/* The speed button shows text ("1.5\00d7") where the others show a 20px icon,
   so it needs its own type sizing and room to grow past a fixed 34px square. */
.tp-btn.tp-speed {
	width: auto;
	min-width: 34px;
	padding: 0 7px;
	font-size: 12px;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	line-height: 1;
}
.tp-btn.tp-speed.is-active {
	color: var( --tp-accent );
}
.tp-time {
	font-size: 12px;
	color: #e5e7eb;
	font-variant-numeric: tabular-nums;
}
/* !important: the player is embedded in arbitrary theme/page markup, and a
   generic host-page reset like `input { width: 100% }` (common in form-
   styling frameworks) otherwise wins the cascade on this specific property
   over a single-class selector — accent-color/cursor aren't touched by that
   kind of rule so they apply fine, but width silently loses, and since this
   sits in a flex row (.tp-controls-row) an unconstrained width stretches it
   across the whole bar. flex is pinned too so it can't grow/shrink either. */
.tp-volume,
.tp-volume:hover,
.tp-volume:focus,
.tp-volume:active {
	/* The track and the thumb, named once. The thumb has to be centred on the
	   track by hand in WebKit (see the negative margin below), and that offset
	   is only correct for one pair of sizes — as a bare number it went stale
	   the moment the thumb was resized, which is how it came to sit ~2px above
	   the track. Derived from these, it cannot drift again. */
	--tp-vol-track: 3px;
	--tp-vol-thumb: 10px;
	width: 74px !important;
	flex: 0 0 74px !important;
	height: 16px; /* comfortable click target; the visible track is drawn thin below */
	/* A floor, not just a height: this is an <input>, and a host theme's own
	   `input { height: auto }` (or a CSS reset) outranks a plain `height` on a
	   single-class selector the same way the width note above describes. Below
	   the thumb's own size the indicator gets clipped by the input's box. */
	min-height: 16px;
	cursor: pointer;
	/* Taking manual control of the track/thumb below via the WebKit/Moz
	   pseudo-elements — accent-color only recolors the browser's default
	   chrome (full-size thumb, solid track block), which read as a second,
	   heavier control bar rather than a slim volume slider. */
	-moz-appearance: none;
	     appearance: none;
	-webkit-appearance: none;
    background: transparent;
    background-image: none !important;
    border: 0 !important;
    box-shadow: none !important;
    outline: 0 !important;
}
.tp-volume::-webkit-slider-runnable-track {
	height: var( --tp-vol-track );
	border-radius: 2px;
	background: rgba( 255, 255, 255, 0.4 ) !important;
    box-shadow: none !important;
}
.tp-volume::-webkit-slider-thumb {
	-webkit-appearance: none;
	appearance: none;
	width: var( --tp-vol-thumb );
	height: var( --tp-vol-thumb );
	/* WebKit lays the thumb out from the TOP of the track, so centring it is
	   ours to do: half the difference, pulled upwards. Computed rather than
	   written out, so resizing either variable keeps the indicator centred.
	   Sizes are px for the same reason — a rem thumb against a px offset
	   decentres itself on any page with a non-16px root font size. */
	margin-top: calc( ( var( --tp-vol-track ) - var( --tp-vol-thumb ) ) / 2 );
	border-radius: 50%;
	background: var( --tp-accent );
	cursor: pointer;
}
.tp-volume::-moz-range-track {
	height: var( --tp-vol-track );
	border-radius: 2px;
	background: rgba( 255, 255, 255, 0.4 );
	box-shadow: none !important;
}
/* The filled portion is part of the track and has to match its height —  at
   8px on a 3px track it drew a bar thicker than the groove it was filling. */
.tp-volume::-moz-range-progress {
	height: var( --tp-vol-track );
	border-radius: 2px;
	background: var( --tp-accent );
}
/* Firefox centres the thumb on the track itself, so no margin here — only the
   size, matched to WebKit's so the control looks the same in both. */
.tp-volume::-moz-range-thumb {
	width: var( --tp-vol-thumb ) !important;
	height: var( --tp-vol-thumb ) !important;
	border: 0;
	border-radius: 50%;
	background: var( --tp-accent );
	cursor: pointer;
}

/* Narrow players: shed the widest, least-critical controls so the single-row
   control bar never overflows the (overflow:hidden) stage and gets clipped.
   Keyed to the player's own width via the .tp-stage size container. */
@container (max-width: 480px) {
	.tp-controls-row {
		gap: 4px;
	}
	.tp-volume {
		display: none; /* mute button stays */
	}
	.tp-btn {
		width: 30px;
		height: 30px;
	}
	.tp-time {
		font-size: 11px;
	}

}
@container (max-width: 340px) {
	.tp-btn {
		width: 28px;
		height: 28px;
	}
	.tp-btn svg {
		width: 17px;
		height: 17px;
	}

}

/* ---- scrubber ---- */
.tp-scrubber {
	padding: 8px 0;
	cursor: pointer;
	touch-action: none; /* let a pointer drag scrub instead of scrolling the page */
	-webkit-user-select: none;
	   -moz-user-select: none;
	        user-select: none;
}
.tp-scrubber.is-disabled {
	cursor: not-allowed;
}
.tp-scrubber-track {
	position: relative;
	height: 5px;
	background: rgba( 255, 255, 255, 0.28 );
	border-radius: 4px;
}
.tp-scrubber-buffered {
	position: absolute;
	top: 0;
	left: 0;
	height: 100%;
	background: rgba( 255, 255, 255, 0.4 );
	border-radius: 4px;
}
.tp-scrubber-played {
	position: absolute;
	top: 0;
	left: 0;
	height: 100%;
	background: var(--tp-accent);
	border-radius: 4px;
}
.tp-scrubber-thumb {
	position: absolute;
	top: 50%;
	width: 13px;
	height: 13px;
	background: #fff;
	border-radius: 50%;
	transform: translate( -50%, -50% );
	box-shadow: 0 0 4px rgba( 0, 0, 0, 0.5 );
}
.tp-scrubber-lockline {
	position: absolute;
	top: -3px;
	bottom: -3px;
	width: 2px;
	background: #f59e0b;
	transform: translateX( -1px );
}
.tp-chapter-marker {
	position: absolute;
	top: 50%;
	width: 3px;
	height: 11px;
	background: #fff;
	transform: translate( -50%, -50% );
	border-radius: 1px;
	opacity: 0.85;
}

/* ---- YouTube-style segmented chapters ---- */
.tp-scrubber-segs {
	position: relative;
	height: 5px;
	transition: height 0.1s ease;
}
.tp-scrubber:hover .tp-scrubber-segs {
	height: 7px;
}
.tp-seg {
	position: absolute;
	top: 0;
	height: 100%;
	background: rgba( 255, 255, 255, 0.28 );
	border-radius: 3px;
	overflow: hidden;
}
.tp-seg-buffered {
	position: absolute;
	left: 0;
	top: 0;
	height: 100%;
	background: rgba( 255, 255, 255, 0.4 );
}
.tp-seg-played {
	position: absolute;
	left: 0;
	top: 0;
	height: 100%;
	background: var(--tp-accent);
}
.tp-chapter-tip {
	position: absolute;
	bottom: 22px;
	transform: translateX( -50% );
	background: rgba( 17, 24, 39, 0.95 );
	color: #fff;
	font-size: 12px;
	padding: 4px 9px;
	border-radius: 6px;
	white-space: nowrap;
	pointer-events: none;
	max-width: 240px;
	overflow: hidden;
	text-overflow: ellipsis;
}
.tp-chapter-now {
	font-size: 12px;
	color: #d1d5db;
	max-width: 180px;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* ---- settings menu ---- */
.tp-menu-wrap {
	position: relative;
}
.tp-menu {
	position: absolute;
	bottom: 42px;
	right: 0;
	min-width: 150px;
	max-height: 260px;
	overflow-y: auto;
	background: rgba( 17, 24, 39, 0.97 );
	border-radius: 8px;
	padding: 6px;
	box-shadow: 0 6px 24px rgba( 0, 0, 0, 0.4 );
}
/* The gear menu specifically: a fixed window rather than a popup that resizes
   as sections are opened and closed. Collapsing a group would otherwise make
   the panel jump under the pointer, moving the next row out from under it.
   box-sizing so the rendered box is exactly 312x250 including the padding. */
.tp-menu.is-settings {
	box-sizing: border-box;
	width: 312px;
	height: 250px;
	max-height: none;
}
.tp-menu-section {
	font-size: 10px;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	color: #9ca3af;
	padding: 6px 8px 2px;
}
/* ---- collapsible group header (gear menu) ---- */
.tp-menu-toggle {
	display: flex;
	align-items: center;
	gap: 8px;
	width: 100%;
	text-align: left;
	background: transparent;
	border: 0;
	color: #e5e7eb;
	padding: 9px 8px;
	border-radius: 6px;
	font-size: 13px;
	font-weight: 500;
	cursor: pointer;
}
.tp-menu-toggle:hover {
	background: rgba( 255, 255, 255, 0.1 );
}
/* The current value, so a collapsed group still answers what it is set to. */
.tp-menu-toggle-value {
	margin-left: auto;
	color: #9ca3af;
	font-size: 12px;
	font-weight: 400;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	max-width: 140px;
}
.tp-menu-chevron {
	flex: none;
	width: 16px;
	height: 16px;
	transition: transform 0.15s ease;
}
.tp-menu-toggle[aria-expanded='true'] .tp-menu-chevron {
	transform: rotate( 180deg );
}
/* Indented so an option reads as belonging to the group above it. */
.tp-menu-group .tp-menu-item {
	padding-left: 24px;
}
.tp-menu-item {
	display: flex;
	align-items: center;
	gap: 6px;
	width: 100%;
	text-align: left;
	background: transparent;
	border: 0;
	color: #e5e7eb;
	padding: 7px 8px;
	border-radius: 6px;
	font-size: 13px;
	cursor: pointer;
}
.tp-menu-item:hover {
	background: rgba( 255, 255, 255, 0.1 );
}
.tp-menu-item.is-active {
	color: #fff;
	font-weight: 600;
}
.tp-menu-item.is-active::after {
	/* Masked SVG tick rather than a text glyph, so it renders identically
	   everywhere and still takes the player's accent colour. */
	content: '';
	width: 13px;
	height: 13px;
	margin-left: auto;
	flex: none;
	background-color: var(--tp-accent);
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27%23fff%27 stroke-width=%273%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27%3E%3Cpath d=%27M5 12.5l4.5 4.5L19 7.5%27/%3E%3C/svg%3E") no-repeat center / contain;
	mask: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27%23fff%27 stroke-width=%273%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27%3E%3Cpath d=%27M5 12.5l4.5 4.5L19 7.5%27/%3E%3C/svg%3E") no-repeat center / contain;
}

/* ---- timed text overlays ---- */
.tp-text-overlay {
	position: absolute;
	z-index: 4;
	max-width: 60%;
	padding: 8px 14px;
	border-radius: 8px;
	color: #fff;
	font-size: 14px;
	line-height: 1.45;
	pointer-events: none;
	display: flex;
	flex-direction: column;
	gap: 2px;
	animation: tp-cta-in 0.25s ease;
}
.tp-text-overlay-title {
	font-size: 15px;
	font-weight: 700;
}
.tp-pos-top-left { top: 14px; left: 14px; }
.tp-pos-top-center { top: 14px; left: 50%; transform: translateX( -50% ); text-align: center; }
.tp-pos-top-right { top: 14px; right: 14px; text-align: right; }
.tp-pos-middle-left { top: 50%; left: 14px; transform: translateY( -50% ); }
.tp-pos-middle-center { top: 50%; left: 50%; transform: translate( -50%, -50% ); text-align: center; }
.tp-pos-middle-right { top: 50%; right: 14px; transform: translateY( -50% ); text-align: right; }
.tp-pos-bottom-left { bottom: 64px; left: 14px; }
.tp-pos-bottom-center { bottom: 64px; left: 50%; transform: translateX( -50% ); text-align: center; }
.tp-pos-bottom-right { bottom: 64px; right: 14px; text-align: right; }

/* ---- action bar ---- */
.tp-actionbar {
	position: absolute;
	left: 0;
	right: 0;
	z-index: 5;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 12px;
	padding: 8px 14px;
	background: var( --tp-accent );
	color: #fff;
	font-size: 14px;
	font-weight: 500;
}
.tp-actionbar-top { top: 0; }
.tp-actionbar-bottom { bottom: 0; }
/* When the control bar is visible, lift a bottom action bar above it. */
.tp-stage:not( .is-idle ) .tp-actionbar-bottom {
	bottom: 3.6rem;
}
.tp-stage.is-audio .tp-actionbar {
	display: none; /* the compact audio bar has no room for it */
}
.tp-actionbar-text {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.tp-actionbar-btn {
	flex-shrink: 0;
	background: rgba( 255, 255, 255, 0.18 );
	border: 1px solid rgba( 255, 255, 255, 0.5 );
	color: #fff;
	border-radius: 6px;
	padding: 4px 14px;
	font-size: 13px;
	font-weight: 600;
	text-decoration: none;
	transition: background 0.15s ease;
}
.tp-actionbar-btn:hover {
	background: rgba( 255, 255, 255, 0.3 );
	color: #fff;
}

/* ---- description under the player ---- */
.tp-description {
	margin-top: 12px;
	font-size: 14.5px;
	line-height: 1.6;
	color: inherit;
}

/* ---- layers ---- */
.tp-layers {
	position: absolute;
	inset: 0;
	z-index: 4;
	pointer-events: none;
}
/* Raised over the big play button (z-index 5) while an email form is showing,
   so the form reads as the thing being asked of the viewer rather than sitting
   behind the button. The container still passes pointer events through
   everywhere except the layer itself, so the control bar stays usable. */
.tp-layers.is-blocking {
	z-index: 6;
}
.tp-layer {
	pointer-events: auto;
}
/* ---- email form ----
   One form, one appearance. The mode decides only where it sits and whether it
   blocks: the gate is centred on the dimmed video, the inline panel is placed
   over the picture and lets playback continue. Nothing below is per-mode, so
   switching Mode cannot change how the form looks — and a colour set on the
   Style tab means the same thing either way. */
.tp-emailform {
	display: flex;
	flex-direction: column;
	gap: 10px;
	box-sizing: border-box;
	margin: 0;
	width: 100%;
	max-width: 420px;
	padding: 22px;
	border-radius: 12px;
	background: var( --tp-of-bg, #fff );
	color: #111827;
	text-align: center;
	box-shadow: 0 12px 40px rgba( 0, 0, 0, 0.3 );
}

/* Gate: centred by .tp-overlay. It covers the whole stage, so it has to fit
   inside it — a short player (21:9, or the scaled editor preview) would
   otherwise spill the form past the picture with its button out of reach. */
.tp-emailform-card {
	max-height: 90%;
	overflow-y: auto;
}

/* Inline: placed over the picture by tp-pos-*. */
.tp-emailform-panel {
	position: absolute;
	max-width: min( 420px, 88% );
}

.tp-emailform-title {
	margin: 0;
	font-weight: 700;
	color: var( --tp-of-title, inherit );
}
/* Scoped to the stage on purpose: the admin styles headings inside `.tp-admin`
   and a theme will style them on the front end, either of which outranks a bare
   class — which is why the headline colour looked dead in the preview. */
.tp-stage .tp-emailform-title {
	font-size: 19px;
	margin-bottom: 6px;
}

.tp-emailform-desc {
	margin: 0 0 4px;
	font-size: 14px;
	color: var( --tp-of-muted, #6b7280 );
}

.tp-emailform-input {
	width: 100%;
	min-width: 0;
	box-sizing: border-box;
	font-size: 14px;
	border-radius: 8px;
	padding: 11px 12px;
	background: #f3f4f6;
	border: 1px solid #d1d5db;
	color: #111827;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
/* Hover previews the focus state rather than a grey step towards it — the same
   rule the admin's own fields follow. Both track the button colour, so a
   restyled form gets matching field states. */
.tp-emailform-input:hover,
.tp-emailform-input:focus {
	outline: none;
	border-color: var( --tp-of-btn-bg, var( --tp-accent ) );
}
.tp-emailform-input:focus {
	box-shadow: 0 0 0 3px rgba( 0, 107, 255, 0.15 );
}
.tp-emailform-input::-moz-placeholder {
	color: var( --tp-of-muted, #9ca3af );
	opacity: 0.75;
}
.tp-emailform-input::placeholder {
	color: var( --tp-of-muted, #9ca3af );
	opacity: 0.75;
}

/* Email + submit share a line; a name field, when asked for, stays above it. */
.tp-emailform-row {
	display: flex;
	align-items: stretch;
	gap: 8px;
}
.tp-emailform-submit {
	flex: 0 0 auto;
	background: var( --tp-of-btn-bg, var( --tp-accent, #4f46e5 ) );
	color: var( --tp-of-btn-text, #fff );
	border: 0;
	border-radius: var( --tp-of-btn-radius, 8px );
	padding: 11px 18px;
	font-size: 14px;
	font-weight: 600;
	white-space: nowrap;
	cursor: pointer;
}
.tp-emailform-submit:disabled {
	opacity: 0.5;
	cursor: not-allowed;
}
/* Narrow players can't hold both on one line without squeezing the field to
   nothing, so they stack instead. */
@container (max-width: 420px) {
	.tp-emailform-row {
		flex-direction: column;
	}
	.tp-emailform-submit {
		width: 100%;
	}

}

.tp-emailform-error {
	margin: 0;
	font-size: 13px;
	color: #dc2626;
}

.tp-emailform-thanks {
	margin: 0;
	font-weight: 600;
}

.tp-emailform-skip {
	align-self: center;
	background: none;
	border: 0;
	padding: 0;
	font-size: 13px;
	text-decoration: underline;
	cursor: pointer;
	color: var( --tp-of-muted, #6b7280 );
}

/* ---- overlays ---- */
.tp-overlay {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba( 0, 0, 0, 0.6 );
	z-index: 6;
	padding: 16px;
}

/* ---- popup (lightbox) ---- */
.trueplayer-popup {
	display: inline-block;
}
.trueplayer-popup-trigger {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	background: var( --tp-accent, #008dff );
	color: #fff;
	border: 0;
	border-radius: 8px;
	padding: 10px 18px;
	font-size: 14px;
	font-weight: 600;
	cursor: pointer;
	font-family: inherit;
	transition: filter 0.15s ease;
}
.trueplayer-popup-trigger:hover {
	filter: brightness( 1.08 );
}
.tp-popup-backdrop {
	position: fixed;
	inset: 0;
	z-index: 100000;
	background: rgba( 0, 0, 0, 0.82 );
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px;
	animation: tp-cta-in 0.18s ease;
}
.tp-popup-dialog {
	position: relative;
	width: min( 900px, 92vw );
}
.tp-popup-close {
	position: absolute;
	top: -38px;
	right: 0;
	background: none;
	border: 0;
	color: #fff;
	font-size: 30px;
	line-height: 1;
	cursor: pointer;
	opacity: 0.85;
}
.tp-popup-close:hover {
	opacity: 1;
}
.tp-popup-player {
	width: 100%;
}

/* ---- CTA / end-screen overlay ---- */
.tp-cta-card {
	position: relative;
	background: #fff;
	color: #111827;
	border-radius: 14px;
	padding: 28px 28px 24px;
	max-width: 460px;
	width: 100%;
	text-align: center;
	box-shadow: 0 12px 40px rgba( 0, 0, 0, 0.35 );
	animation: tp-cta-in 0.2s ease;
}
@keyframes tp-cta-in {
	from { transform: translateY( 8px ) scale( 0.98 ); opacity: 0; }
	to { transform: none; opacity: 1; }
}
.tp-cta-close {
	position: absolute;
	top: 8px;
	right: 10px;
	background: none;
	border: 0;
	font-size: 24px;
	line-height: 1;
	color: #9ca3af;
	cursor: pointer;
}
.tp-cta-close:hover { color: #374151; }
.tp-cta-img {
	max-height: 96px;
	max-width: 100%;
	margin: 0 auto 14px;
	border-radius: 10px;
	-o-object-fit: cover;
	   object-fit: cover;
}
.tp-cta-title {
	font-size: 20px;
	font-weight: 700;
	margin: 0 0 6px;
}
.tp-cta-text {
	font-size: 14px;
	line-height: 1.5;
	color: #4b5563;
	margin: 0 0 18px;
}
.tp-cta-actions {
	display: flex;
	gap: 10px;
	justify-content: center;
	flex-wrap: wrap;
}
.tp-cta-btn {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	background: var( --tp-accent );
	color: #fff;
	font-size: 14px;
	font-weight: 600;
	padding: 10px 20px;
	border-radius: 8px;
	border: 0;
	cursor: pointer;
	text-decoration: none;
	transition: filter 0.15s ease;
}
.tp-cta-btn:hover { filter: brightness( 1.08 ); }
.tp-cta-secondary {
	background: #f3f4f6;
	color: #374151;
}
.tp-bigplay {
	position: absolute;
	inset: 0;
	margin: auto;
	/* Size is author-controllable via --tp-bigplay-size; each skin keeps its own
	   fallback when the control is left on "Auto". */
	width: var( --tp-bigplay-size, 78px );
	height: var( --tp-bigplay-size, 78px );
	border-radius: 50%;
	border: 0;
	/* Accent-driven on every skin (matches the poster facade button). Skins may
	   still override size/shape, but the accent color stays. */
	background: var( --tp-accent, #4f46e5 );
	color: #fff;
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	z-index: 5;
}
/* Icon scales with the button so larger sizes stay proportional. */
.tp-bigplay svg {
	width: 48%;
	height: 48%;
}
.tp-bigplay:hover {
	filter: brightness( 1.08 );
}

.tp-lock-card {
	background: #fff;
	color: #111827;
	border-radius: 12px;
	padding: 24px;
	max-width: 480px;
	width: 100%;
	max-height: 90%;
	overflow-y: auto;
	text-align: center;
	box-shadow: 0 12px 40px rgba( 0, 0, 0, 0.3 );
}

/* ---- opt-in / subscribe ---- */
.tp-optin-card {
	background: #fff;
	color: #111827;
	border-radius: 12px;
	padding: 26px;
	max-width: 420px;
	width: 100%;
	text-align: center;
	box-shadow: 0 12px 40px rgba( 0, 0, 0, 0.3 );
}
.tp-optin-title {
	margin: 0 0 8px;
	font-size: 19px;
	font-weight: 700;
}
.tp-optin-desc {
	margin: 0 0 16px;
	color: #6b7280;
	font-size: 14px;
}
.tp-optin-input {
	width: 100%;
	box-sizing: border-box;
	padding: 11px 12px;
	margin-bottom: 10px;
	border: 1px solid #d1d5db;
	border-radius: 8px;
	font-size: 14px;
}
.tp-optin-input:focus {
	outline: none;
	border-color: var(--tp-accent);
}
.tp-optin-error {
	color: #dc2626;
	font-size: 13px;
	margin: 0 0 10px;
}
.tp-optin-skip {
	display: block;
	margin: 12px auto 0;
	background: none;
	border: 0;
	color: #6b7280;
	font-size: 13px;
	text-decoration: underline;
	cursor: pointer;
}

/* ---- spinner ---- */
.tp-spinner {
	position: absolute;
	inset: 0;
	margin: auto;
	width: 44px;
	height: 44px;
	border: 4px solid rgba( 255, 255, 255, 0.25 );
	border-top-color: #fff;
	border-radius: 50%;
	animation: tp-spin 0.8s linear infinite;
	z-index: 5;
}
@keyframes tp-spin {
	to {
		transform: rotate( 360deg );
	}
}

/* ---- playlists ---- */
.trueplayer-playlist {
	--tp-accent: #4f46e5;
	--tp-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
	width: 100%;
	font-family: var( --tp-font );
}
/* Query the playlist's own width, not the viewport — the video must stack the
   list below it whenever the container (not the screen) is narrow, e.g. inside
   a narrow content column, sidebar, or page-builder cell. */
.tp-pl {
	container-type: inline-size;
	width: 100%;
}
.tp-pl-title {
	font-size: 18px;
	font-weight: 600;
	margin-bottom: 12px;
	color: #111827;
}
/* Cap the stage the way the standalone embed does — but as a *max*, not a
   hard width. A fixed width overflows any content column narrower than the cap
   (a theme's column is commonly ~650px), which is what pushed the sidebar list
   out of the row entirely. */
.tp-pl-main {
	width: 100%;
	max-width: min(960px, calc((100vh - 100px) * 16 / 9));
}
.tp-pl-list {
	display: flex;
	flex-direction: column;
	gap: 8px;
}
.tp-pl-sidebar .tp-pl-body {
	display: flex;
	gap: 16px;
	align-items: flex-start;
	justify-content: center;
	width: 100%;
	margin: 0 auto;
}
/* 450px stage. Kept as a shrinkable basis rather than a hard `width` so a
   content column narrower than 450 + gap + list can't be overflowed — that
   fixed width is what broke this layout in the first place. `min-width: 0` is
   required or the video refuses to shrink below its intrinsic size. */
.tp-pl-sidebar .tp-pl-main {
	flex: 0 1 450px;
	max-width: 450px;
	min-width: 0;
}
.tp-pl-sidebar .tp-pl-list {
	/* Basis 0 so the list claims only the room the 450px stage leaves, rather
	   than competing with it for width and shrinking it below 450. The floor
	   makes the stage yield instead of starving the list in a mid-width column;
	   the cap stops a wide container handing the list half the row. */
	flex: 1 1 0;
	min-width: 150px;
	max-width: 300px;
	gap: 6px;
	max-height: 70vh;
	overflow-y: auto;
	padding-right: 4px;
}
.tp-pl-grid .tp-pl-body {
	display: flex;
	flex-direction: column;
	gap: 16px;
}
.tp-pl-grid .tp-pl-list {
	display: grid;
	grid-template-columns: repeat( auto-fill, minmax( 160px, 1fr ) );
	gap: 12px;
}
.tp-pl-item {
	display: flex;
	gap: 10px;
	align-items: center;
	text-align: left;
	background: transparent;
	border: 1px solid transparent;
	border-radius: 8px;
	padding: 6px;
	cursor: pointer;
	color: #1f2937;
	width: 100%;
}
.tp-pl-item:hover {
	background: rgba( 0, 0, 0, 0.04 );
}
/* Clicking an item leaves it focused, and a theme's default button ring on a
   picked row reads as a rendering glitch — drop it. `:focus-visible` then puts
   the ring back for keyboard navigation only, so arrowing/tabbing through the
   list still shows where you are. */
.tp-pl-item:focus {
	outline: none;
}
.tp-pl-item:focus-visible {
	outline: 2px solid var( --tp-accent );
	outline-offset: 2px;
}
.tp-pl-item.is-active {
	background: rgba( 0, 0, 0, 0.06 );
	border-color: var(--tp-accent);
}
/* Compact icon used in the sidebar list (keeps rows slim vs. a poster thumb). */
.tp-pl-icon {
	width: 30px;
	height: 30px;
	flex-shrink: 0;
	border-radius: 6px;
	background: rgba( 0, 0, 0, 0.06 );
	color: #4b5563;
	display: flex;
	align-items: center;
	justify-content: center;
}
.tp-pl-icon svg {
	width: 15px;
	height: 15px;
	fill: currentColor;
}
.tp-pl-item.is-active .tp-pl-icon {
	background: var( --tp-accent );
	color: #fff;
}
.tp-pl-thumb {
	width: 72px;
	height: 44px;
	flex-shrink: 0;
	border-radius: 6px;
	background: #111827 center/cover no-repeat;
	color: #fff;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 12px;
}
.tp-pl-item-title {
	font-size: 13px;
	line-height: 1.3;
}
.tp-pl-grid .tp-pl-item {
	flex-direction: column;
	align-items: stretch;
	gap: 6px;
}
.tp-pl-grid .tp-pl-thumb {
	width: 100%;
	height: 96px;
}
/* ---- sidebar rows ---- */
.tp-pl-sidebar .tp-pl-item {
	gap: 12px;
	padding: 8px 10px;
	border-radius: 10px;
}
.tp-pl-sidebar .tp-pl-item.is-active {
	background: rgba( 0, 0, 0, 0.06 );
	border-color: var( --tp-accent );
}
.tp-pl-sidebar .tp-pl-icon {
	width: 28px;
	height: 28px;
	border-radius: 8px;
	background: rgba( 0, 0, 0, 0.06 );
	color: #111827;
}
.tp-pl-sidebar .tp-pl-icon svg {
	width: 13px;
	height: 13px;
}
.tp-pl-sidebar .tp-pl-item-title {
	font-size: 14px;
	font-weight: 500;
	line-height: 1.35;
	color: #111827;
	/* A long title wraps to two lines instead of stretching the row. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
@container ( max-width: 520px ) {
	.tp-pl-sidebar .tp-pl-body {
		flex-direction: column;
		align-items: stretch; /* full-width video when stacked */
	}
	/* Stacked, the body is a COLUMN flex container — flex-basis maps to
	   HEIGHT, so the row-mode `flex: 1 1 0` collapsed this list to 0px tall
	   (items clipped, area looked empty) and `flex: 0 1 450px` gave the
	   stage a 450px height basis. Reset both to content sizing. */
	.tp-pl-sidebar .tp-pl-main {
		flex: 0 0 auto;
		width: 100%;
		max-width: none;
	}
	.tp-pl-sidebar .tp-pl-list {
		flex: 0 0 auto;
		width: 100%;
		max-width: none;
		min-width: 0;
		flex-direction: row;
		overflow-x: auto;
		max-height: none;
	}
	/* Stacked, the rows scroll sideways — size each to its content instead
	   of letting them share the width and truncate to a few characters. */
	.tp-pl-sidebar .tp-pl-item {
		flex: 0 0 auto;
		width: auto;
		max-width: 220px;
	}
	.tp-pl-sidebar .tp-pl-item-title {
		-webkit-line-clamp: 1;
		white-space: nowrap;
	}

}
/* Fallback for browsers without container queries: stack on a narrow viewport. */
@supports not ( container-type: inline-size ) {
	@media ( max-width: 520px ) {
		.tp-pl-sidebar .tp-pl-body {
			flex-direction: column;
			align-items: stretch;
		}
		/* Stacked, the body is a COLUMN flex container — flex-basis maps to
		   HEIGHT, so the row-mode `flex: 1 1 0` collapsed this list to 0px tall
		   (items clipped, area looked empty) and `flex: 0 1 450px` gave the
		   stage a 450px height basis. Reset both to content sizing. */
		.tp-pl-sidebar .tp-pl-main {
			flex: 0 0 auto;
			width: 100%;
			max-width: none;
		}
		.tp-pl-sidebar .tp-pl-list {
			flex: 0 0 auto;
			width: 100%;
			max-width: none;
			min-width: 0;
			flex-direction: row;
			overflow-x: auto;
			max-height: none;
		}
		/* Stacked, the rows scroll sideways — size each to its content instead
		   of letting them share the width and truncate to a few characters. */
		.tp-pl-sidebar .tp-pl-item {
			flex: 0 0 auto;
			width: auto;
			max-width: 220px;
		}
		.tp-pl-sidebar .tp-pl-item-title {
			-webkit-line-clamp: 1;
			white-space: nowrap;
		}
	
}

}

.tp-stage:fullscreen {
	border-radius: 0;
}
.tp-stage:fullscreen .tp-media,
.tp-stage:fullscreen .tp-media-container {
	-o-object-fit: contain;
	   object-fit: contain;
}

/* ==========================================================================
   Audio layouts — MUST STAY LAST IN THIS FILE.

   Every rule below carries a three-class prefix (.tp-stage.is-audio.tp-audio-*
   = specificity 0-4-0) so it beats the skin rules (.tp-skin-x .tp-y = 0-2-0)
   on specificity, not on source order. The base audio block further up this
   file wins by order alone, which is fragile — anything added between it and
   the skins would silently lose. These do not have that problem.

   Skins were written for a 16:9 picture; the ones whose rules are actively
   wrong inside a short bar are neutralised here by name rather than left to
   cancel out as a side effect of some other rule.
   ========================================================================== */

/* --- skin neutralisers (audio, any layout) --- */

/* `floating` detaches the bar and pins it inset from the stage edges. Those
   offsets only do nothing today because .tp-stage.is-audio .tp-controls sets
   position:static; say so explicitly so a future position change can't
   resurrect a bar floating outside a 72px box. */
.tp-stage.is-audio .tp-controls {
	left: auto;
	right: auto;
	bottom: auto;
}

/* `minimal` paints a translucent pill around the control row — sensible over
   a picture, but inside an audio bar it reads as a stray button group. */
.tp-stage.is-audio .tp-controls-row {
	background: none;
	backdrop-filter: none;
	-webkit-backdrop-filter: none;
	border-radius: 0;
	padding: 0;
}

/* --- compact: the default bar (art tile left, controls right) --- */
.tp-stage.is-audio.tp-audio-compact {
	flex-direction: row;
}
.tp-stage.is-audio.tp-audio-compact .tp-controls {
	min-width: 0;
}

/* --- card: large cover art above a stacked title / scrubber / buttons --- */
.tp-stage.is-audio.tp-audio-card {
	flex-direction: column;
	align-items: stretch;
	gap: 14px;
	min-height: 0;
	padding: 16px;
}
/* A square that is min(stage content width, 260px), centred.
   Capping the WIDTH is what keeps it square: capping max-height instead lets
   the 100% width win and letterboxes the cover art into a wide, short strip. */
.tp-stage.is-audio.tp-audio-card .tp-audio-art {
	width: 100%;
	max-width: 260px;
	height: auto;
	aspect-ratio: 1 / 1;
	align-self: center;
	border-radius: 12px;
}
.tp-stage.is-audio.tp-audio-card .tp-audio-art img {
	-o-object-fit: cover;
	   object-fit: cover;
}
.tp-stage.is-audio.tp-audio-card .tp-audio-art svg {
	width: 38px;
	height: 38px;
}
.tp-stage.is-audio.tp-audio-card .tp-controls {
	padding: 0;
	flex: none;
}
/* Room to breathe once the bar is no longer a single 72px strip. */
.tp-stage.is-audio.tp-audio-card .tp-audio-title {
	font-size: 15px;
	white-space: normal;
	margin-bottom: 6px;
}

/* --- minimal: play button + waveform, nothing else --- */
/* Keeps the base audio background. It must NOT go transparent: every control
   in the bar is white (.tp-btn colour, the waveform's rgba(255,255,255,…)), so
   on any light surface — the editor's preview panel, a light theme — a
   transparent bar renders as an empty white box. "Minimal" here means fewer
   parts (no art, title, time or volume) and a shorter bar, not no surface. */
.tp-stage.is-audio.tp-audio-minimal {
	min-height: 56px;
	padding-left: 0;
	gap: 0;
}
.tp-stage.is-audio.tp-audio-minimal .tp-audio-art,
.tp-stage.is-audio.tp-audio-minimal .tp-audio-title,
.tp-stage.is-audio.tp-audio-minimal .tp-time,
.tp-stage.is-audio.tp-audio-minimal .tp-volume {
	display: none;
}
/* One row: the buttons sit left of the scrubber rather than under it. The
   children are reordered rather than re-rendered, so Controls.jsx stays a
   single tree for every layout. */
.tp-stage.is-audio.tp-audio-minimal .tp-controls {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 8px 12px;
}
.tp-stage.is-audio.tp-audio-minimal .tp-controls-row {
	order: 1;
	width: auto;
	flex: none;
}
.tp-stage.is-audio.tp-audio-minimal .tp-scrubber {
	order: 2;
	flex: 1;
	min-width: 0;
}
/* The spacer exists to push the right-hand button group away from the left
   one; with the row shrunk to its content it would just add dead space. */
.tp-stage.is-audio.tp-audio-minimal .tp-spacer {
	display: none;
}

