/* ==========================================================================
   Flight Log Video Hub — design tokens
   These map onto the TriKdanG theme's own --tktt-* brand variables (night-
   flight black background, paper-white text, logo red accent) so the plugin
   always matches the site's actual brand instead of an independent dark
   palette. The hex values after each var() are only a fallback for sites
   that don't have the TriKdanG theme active.
   ========================================================================== */
:root {
	--flv-bg: var(--tktt-bg-primary, #121316);
	--flv-surface: var(--tktt-bg-surface, #1b1d22);
	--flv-surface-2: var(--tktt-bg-surface, #232323);
	--flv-border: var(--tktt-border, #3a3a3d);
	--flv-text: var(--tktt-text-primary, #f5f1e6);
	--flv-text-muted: var(--tktt-text-muted, #9a968c);
	--flv-accent: var(--tktt-accent, #e11d2e);
	--flv-radius: 8px;
	--flv-font-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
	--flv-font-body: "Inter", "Helvetica Neue", Arial, sans-serif;
	--flv-font-mono: "IBM Plex Mono", "Courier New", monospace;
}

/* ---------- Base ---------- */
/* No forced background here on purpose — in light mode --tktt-bg-primary
   resolves to a light color, and the plugin painting its own box over that
   was showing as a mismatched white panel. Leaving background unset lets
   these sections inherit whatever the theme/page already has (light or
   dark) on both the archive/video page and the single video page. */
body.flv-video-hub,
.flv-video-hub,
.flv-hero,
.flv-video-grid-section,
.flv-video-player-section,
.flv-video-article,
.flv-subscribe-bar,
.flv-search-bar {
	background: none;
	color: var(--flv-text);
}

/* Guards against any long unbroken string (a pasted URL, a run-on test
   string, etc.) blowing out past the container width instead of wrapping —
   this is what was happening in the article/description areas. */
.flv-video-hub {
	overflow-wrap: break-word;
	word-break: break-word;
}

.flv-eyebrow {
	font-family: var(--flv-font-mono);
	font-size: 13px;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--flv-accent);
	margin-bottom: 18px;
}

/* ---------- Hero ---------- */
.flv-hero {
	padding: 64px 32px 40px;
	max-width: 1100px;
	margin: 0 auto;
}

.flv-hero-headline {
	font-family: var(--flv-font-display);
	font-weight: 800;
	font-size: clamp(40px, 6vw, 80px);
	line-height: 1.02;
	letter-spacing: -0.01em;
	margin: 0 0 28px;
	color: var(--flv-text);
}

.flv-hero-subhead {
	font-family: var(--flv-font-body);
	font-size: clamp(17px, 2vw, 22px);
	line-height: 1.5;
	color: var(--flv-text-muted);
	max-width: 760px;
	margin: 0 0 32px;
}

.flv-hero-buttons {
	display: flex;
	gap: 14px;
	flex-wrap: wrap;
}

/* ---------- Buttons ---------- */
.flv-btn {
	font-family: var(--flv-font-mono);
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	text-decoration: none;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 14px 24px;
	border-radius: var(--flv-radius);
	transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, filter 0.15s ease;
	cursor: pointer;
	white-space: nowrap;
}

.flv-btn-primary {
	background: var(--flv-accent);
	color: #14090d;
	border: 1px solid var(--flv-accent);
}
.flv-btn-primary:hover,
.flv-btn-outline:hover {
	filter: brightness(1.12);
}

.flv-btn-outline {
	background: transparent;
	color: var(--flv-text);
	border: 1px solid var(--flv-border);
}
.flv-btn-outline:hover {
	border-color: var(--flv-text-muted);
}

.flv-btn-small {
	padding: 10px 16px;
	font-size: 11px;
}

/* Standalone CTA button block — block-level so it always drops onto its
   own line below whatever precedes it (e.g. the video player), instead
   of sitting inline to the left of it. */
.flv-cta-button-wrap {
	display: block;
	margin: 24px 0 0;
}

/* ---------- Subscribe bar ---------- */
/* The standalone flv/subscribe-bar block. Its inner .flv-meta-actions /
   .flv-meta-actions-left markup and button classes are the exact same
   ones the video-player block renders automatically (both come from
   FLV_Blocks::render_flight_log_row()) — this wrapper only adds the
   page-level width/centering, it doesn't restyle the buttons. That's
   what keeps the two visually identical wherever either one appears. */
.flv-subscribe-bar {
	max-width: 1100px;
	margin: 0 auto;
	padding: 20px 32px;
}

/* When the Subscribe bar sits directly under the video player (e.g. if
   showFlightLog is turned off on the player and this block is placed
   right after it instead), it's meant to read as one grouped section
   rather than two stacked boxes. */
.flv-video-player-section + .flv-subscribe-bar {
	padding-top: 0;
}

/* ---------- Search bar (redesigned: no flanking blocks) ---------- */
.flv-search-bar {
	max-width: 1100px;
	margin: 32px auto;
	padding: 0 32px;
	position: relative;
}

.flv-search-centered .flv-search-input-wrap {
	max-width: 640px;
	margin: 0 auto;
}

.flv-search-input-wrap {
	position: relative;
	display: flex;
	align-items: center;
	background: var(--flv-surface);
	border: 1px solid var(--flv-border);
	border-radius: 999px;
	padding: 4px 8px 4px 20px;
}

.flv-search-input-wrap:focus-within {
	border-color: var(--flv-accent);
}

.flv-search-icon {
	color: var(--flv-text-muted);
	font-size: 18px;
	margin-right: 12px;
	line-height: 1;
}

.flv-search-input {
	flex: 1;
	background: transparent;
	border: none;
	outline: none;
	color: var(--flv-text);
	font-family: var(--flv-font-body);
	font-size: 16px;
	padding: 14px 4px;
}

.flv-search-input::placeholder {
	color: var(--flv-text-muted);
}

.flv-search-suggestions {
	list-style: none;
	margin: 8px auto 0;
	padding: 8px;
	max-width: 640px;
	background: var(--flv-surface);
	border: 1px solid var(--flv-border);
	border-radius: var(--flv-radius);
	position: absolute;
	left: 32px;
	right: 32px;
	z-index: 20;
}

.flv-search-full .flv-search-suggestions {
	max-width: none;
}

.flv-search-suggestions[hidden] {
	display: none;
}

.flv-search-suggestions li a {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 10px 12px;
	border-radius: 6px;
	color: var(--flv-text);
	text-decoration: none;
	font-family: var(--flv-font-body);
	font-size: 14px;
}

.flv-search-suggestions li a:hover,
.flv-search-suggestions li.is-active a {
	background: var(--flv-surface-2);
}

.flv-search-suggestions li .flv-suggest-tag {
	font-family: var(--flv-font-mono);
	font-size: 10px;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--flv-text-muted);
	margin-left: auto;
}

/* ---------- Filter pills ----------
   Static/wrapped by default — same as before the marquee existed. JS
   (initFilterMarquee in front.js) measures whether the pills actually
   need more than one line at the available width; only then does it add
   .is-scrolling and clone a second copy of the pills for the seamless
   auto-scroll loop. Fewer categories that already fit in the row are left
   completely alone. */
.flv-filter-marquee {
	overflow: visible;
}

.flv-filter-track {
	display: flex;
	width: auto;
}

.flv-filter-pills {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

/* Only applied by JS once it's confirmed the pills don't fit on one line
   at the current width. The track then holds two identical copies of the
   pills back-to-back, animating exactly -50% — since both halves are
   identical, that always lands on a pixel-perfect copy of the start, so
   the loop never visibly "resets". */
.flv-filter-marquee.is-scrolling {
	overflow: hidden;
	-webkit-mask-image: linear-gradient(to right, transparent, #000 24px, #000 calc(100% - 24px), transparent);
	mask-image: linear-gradient(to right, transparent, #000 24px, #000 calc(100% - 24px), transparent);
}

.flv-filter-marquee.is-scrolling .flv-filter-track {
	width: max-content;
	animation: flv-marquee 75s linear infinite;
}

.flv-filter-marquee.is-scrolling .flv-filter-pills {
	flex-wrap: nowrap;
	padding-right: 8px;
}

/* Pause on hover/focus — a constantly-moving target is hard to click. */
.flv-filter-marquee.is-scrolling:hover .flv-filter-track,
.flv-filter-marquee.is-scrolling .flv-filter-track:focus-within {
	animation-play-state: paused;
}

@keyframes flv-marquee {
	from { transform: translateX(0); }
	to { transform: translateX(-50%); }
}

/* Once a visitor taps/clicks a rolling row (initFilterMarqueeStop in
   front.js adds .is-stopped), the animation freezes for good and the row
   becomes a normal horizontally-swipeable strip instead — the cloned
   second copy is hidden since there's nothing left to loop into. The
   native scrollbar is hidden in favor of the prev/next arrow buttons
   (shown/hidden by the same script based on scroll position). */
.flv-filter-marquee.is-stopped {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	-webkit-mask-image: none;
	mask-image: none;
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.flv-filter-marquee.is-stopped::-webkit-scrollbar {
	display: none;
	height: 0;
}

.flv-filter-marquee.is-stopped .flv-filter-track {
	animation: none;
	transform: none;
}

.flv-filter-marquee.is-stopped [aria-hidden="true"] {
	display: none;
}

.flv-filter-marquee-wrap {
	display: flex;
	align-items: center;
	gap: 4px;
	min-width: 0;
}

/* The marquee itself must actively fill whatever space the wrap has
   (not just shrink-to-fit its own content) — initFilterMarquee measures
   this element's clientWidth against the pills' natural width to decide
   whether to roll at all, so if this collapses to content size that
   check always reads as "doesn't fit" and rolls on every screen size. */
.flv-filter-marquee-wrap .flv-filter-marquee {
	flex: 1 1 auto;
	min-width: 0;
}

.flv-marquee-arrow {
	flex-shrink: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	padding: 0;
	background: var(--flv-surface);
	color: var(--flv-text);
	border: 1px solid var(--flv-border);
	border-radius: 999px;
	cursor: pointer;
}

.flv-marquee-arrow[hidden] {
	display: none;
}

.flv-marquee-arrow:hover {
	border-color: var(--flv-accent);
	color: var(--flv-accent);
}

@media (prefers-reduced-motion: reduce) {
	.flv-filter-track {
		animation: none;
	}
}

.flv-pill {
	font-family: var(--flv-font-mono);
	font-size: 12px;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	text-decoration: none;
	color: var(--flv-text-muted);
	background: var(--flv-surface);
	border: 1px solid var(--flv-border);
	border-radius: 999px;
	padding: 8px 16px;
	white-space: nowrap;
	flex-shrink: 0;
	transition: color 0.15s ease, border-color 0.15s ease;
}

.flv-pill:hover {
	color: var(--flv-text);
}

.flv-pill.is-active {
	color: var(--flv-bg);
	background: var(--flv-text);
	border-color: var(--flv-text);
}

/* ---------- Video grid ---------- */
.flv-video-grid-section {
	max-width: 1100px;
	margin: 0 auto;
	padding: 0 32px 0;
}

.flv-section-heading {
	font-family: var(--flv-font-display);
	font-weight: 700;
	font-size: 26px;
	margin: 0;
}

/* Heading and its filter pills (category or tag) share one line, so
   people can jump straight to another build type right from "More
   builds" instead of scrolling to a separate filter row. Wraps to its
   own line on narrow screens. */
.flv-grid-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 12px 20px;
	margin-bottom: 28px;
}

.flv-grid-header .flv-filter-marquee-wrap {
	flex: 1 1 240px;
	min-width: 0;
}

/* "See all" link, next to the heading/filters on any grid that has more
   matching videos loaded on the server than what's actually on screen —
   set in render.php via $has_more, off the same found_posts count the
   query already produces. */
.flv-view-all-link {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	flex-shrink: 0;
	color: var(--flv-text);
	font-family: var(--flv-font-mono);
	font-size: 13px;
	font-weight: 600;
	text-decoration: none;
	white-space: nowrap;
	padding-bottom: 1px;
	border-bottom: 1px solid transparent;
	transition: border-color 0.15s ease, color 0.15s ease;
}

.flv-view-all-link:hover {
	color: var(--flv-accent);
	border-bottom-color: currentColor;
}

.flv-view-all-link svg {
	transition: transform 0.15s ease;
}

.flv-view-all-link:hover svg {
	transform: translateX(2px);
}

/* auto-fit + a computed min-card width (see --flv-min-card, set inline
   per-instance in render.php from the chosen column count) means the grid
   lands on exactly that many columns at the section's own max width, and
   naturally reflows to fewer on narrower screens — instead of a fixed
   media-query breakpoint hard-capping every column count at 2 below
   900px, which is what was silently overriding a 3+ column choice. */
.flv-video-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(var(--flv-min-card, 240px), 1fr));
	gap: 28px 20px;
}

/* Editor preview only (see $is_editor_preview in video-grid/render.php) —
   fixed 2-column layout regardless of the configured column count or the
   canvas's actual pixel width, so this never lands in the cramped
   in-between state a narrower/unpredictable editor width could otherwise
   produce. Concrete colors here too, not just CSS vars, so cards look
   right even where the theme's own variables aren't loaded in the editor. */
.flv-video-grid--editor {
	grid-template-columns: repeat(2, 1fr) !important;
	gap: 20px 16px;
}
.flv-video-grid--editor .flv-video-thumb {
	background: #1b1d22;
}
.flv-video-grid--editor .flv-thumb-placeholder {
	background: #232323;
}
.flv-video-grid--editor .flv-video-title {
	color: #f5f1e6;
}

/* ---------- Video grid carousel ----------
   render.php loads a larger pool of cards ("count") than what's meant
   to be visible at once ("columns" x "rows") whenever enableCarousel is
   on, then this arranges that pool as a horizontally-scrolling,
   snap-aligned CSS grid (grid-auto-flow: column stacks "rows" cards
   into each column before starting the next one, so a rows=1 carousel
   is a single scrolling row and rows=2/3 is a scrolling grid) so the
   left/right arrows (see front.js's initVideoCarousel) step through
   the rest of that pool one "page" at a time.

   The arrows are absolutely positioned over the grid rather than
   sitting beside it in the flow, so they never add to the section's
   width/margin/padding or throw off the card-width math below (which
   assumes the grid gets the full container width) — they're invisible
   until the wrap is hovered/focused, and stay fully hidden at either
   end of the scroll via the [hidden] attribute front.js toggles. */
.flv-video-carousel-wrap {
	position: relative;
}

.flv-video-grid--carousel {
	display: grid;
	grid-auto-flow: column;
	grid-template-columns: none;
	grid-template-rows: repeat( var( --flv-rows, 1 ), 1fr );
	grid-auto-columns: calc((100% - (var(--flv-columns) - 1) * 20px) / var(--flv-columns));
	gap: 28px 20px;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.flv-video-grid--carousel::-webkit-scrollbar {
	display: none;
	height: 0;
}

.flv-video-grid--carousel .flv-video-card {
	scroll-snap-align: start;
	min-width: 160px;
}

@media (max-width: 900px) {
	/* Tablet: exactly 2 cards fit the screen per view, no partial peek. */
	.flv-video-grid--carousel {
		grid-auto-columns: calc((100% - 20px) / 2);
	}
}

@media (max-width: 600px) {
	/* Mobile: exactly 1 card fills the screen per view. */
	.flv-video-grid--carousel {
		grid-auto-columns: 100%;
	}
}

/* top defaults to 50% (centered on the whole wrap) for a multi-row grid
   carousel; a single-row carousel (.flv-video-carousel-wrap--single-row)
   has front.js set --flv-arrow-top to the thumbnail's own vertical
   center in px, so the arrow lines up with the thumbnail instead of the
   card's full height (which includes the title below it). */
.flv-carousel-arrow {
	position: absolute;
	top: var(--flv-arrow-top, 50%);
	transform: translateY(-50%);
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	background: var(--flv-surface);
	color: var(--flv-text);
	border: 1px solid var(--flv-border);
	border-radius: 999px;
	cursor: pointer;
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.flv-video-carousel-wrap:hover .flv-carousel-arrow,
.flv-video-carousel-wrap:focus-within .flv-carousel-arrow {
	opacity: 1;
	pointer-events: auto;
}

.flv-carousel-arrow-prev {
	left: 8px;
}

.flv-carousel-arrow-next {
	right: 8px;
}

.flv-carousel-arrow:hover {
	border-color: var(--flv-accent);
	color: var(--flv-accent);
}

.flv-carousel-arrow[hidden] {
	display: none;
}

@media (max-width: 640px) {
	/* No hover on touch, and there isn't room to spare for an overlay
	   button on a phone screen anyway — swipe still works, the arrows
	   just step back to appearing at 900px and up. */
	.flv-carousel-arrow {
		display: none;
	}
}

.flv-video-card {
	display: flex;
	flex-direction: column;
	gap: 10px;
	text-decoration: none;
	color: var(--flv-text);
}

.flv-video-thumb {
	position: relative;
	display: block;
	aspect-ratio: 16 / 9;
	background: var(--flv-surface);
	border-radius: var(--flv-radius);
	overflow: hidden;
}

.flv-video-thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: transform 0.2s ease;
}

/* The hover-preview iframe/video (see initHoverPreviews in front.js) —
   fills the thumbnail exactly like the static image underneath it, and
   ignores pointer events so a click still lands on the card's own link
   instead of the video-provider iframe. */
.flv-hover-preview {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
	object-fit: cover;
	pointer-events: none;
}

.flv-video-card:hover .flv-video-thumb img {
	transform: scale(1.03);
}

.flv-thumb-placeholder {
	position: absolute;
	inset: 0;
	background: var(--flv-surface-2);
}

.flv-duration {
	position: absolute;
	bottom: 8px;
	right: 8px;
	background: rgba(0, 0, 0, 0.8);
	color: var(--flv-text);
	font-family: var(--flv-font-mono);
	font-size: 11px;
	padding: 3px 6px;
	border-radius: 4px;
}

.flv-video-title {
	font-family: var(--flv-font-body);
	font-weight: 600;
	font-size: 15px;
	line-height: 1.35;
}

/* ---------- Video player page ---------- */
.flv-video-player-section {
	max-width: 1100px;
	margin: 0 auto;
	padding: 0 32px 32px;
}

.flv-player-wrap {
	position: relative;
	width: 100%;
	aspect-ratio: 16 / 9;
	background: #000;
	border-radius: var(--flv-radius);
	overflow: hidden;
	margin-bottom: 24px;
}

.flv-player-embed,
.flv-player-embed iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: none;
}

/* Editor-only static preview (used instead of a live embed inside the
   block editor — see $is_editor_preview in render.php). Concrete colors
   here on purpose, not just CSS vars, so this always looks right in the
   editor even on setups where the theme's own variables aren't loaded
   there. */
.flv-player-preview {
	background: #000;
}

/* On the front end (not the editor) this same markup is a real click-to-
   load control — see data-flv-video-facade in render.php / front.js — so
   it needs to look and behave like one. The editor's own static preview
   isn't clickable, but the extra cursor/outline rules are harmless there
   either way. */
.flv-player-embed[data-flv-video-facade] {
	cursor: pointer;
}

.flv-player-embed[data-flv-video-facade]:focus-visible {
	outline: 3px solid var(--flv-accent, #e11d2e);
	outline-offset: -3px;
}

.flv-player-preview img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.flv-player-preview-play {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 56px;
	height: 56px;
	transform: translate(-50%, -50%);
	background: rgba(0, 0, 0, 0.55);
	border: 2px solid rgba(255, 255, 255, 0.85);
	border-radius: 999px;
}

.flv-player-preview-play::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 56%;
	width: 0;
	height: 0;
	transform: translate(-50%, -50%);
	border-style: solid;
	border-width: 9px 0 9px 15px;
	border-color: transparent transparent transparent rgba(255, 255, 255, 0.9);
}

.flv-player-preview-badge {
	position: absolute;
	left: 12px;
	bottom: 12px;
	max-width: calc(100% - 24px);
	padding: 6px 12px;
	background: rgba(0, 0, 0, 0.75);
	color: #f5f1e6;
	font-family: "IBM Plex Mono", "Courier New", monospace;
	font-size: 11px;
	letter-spacing: 0.03em;
	border-radius: 999px;
}

/* Video runs edge-to-edge on mobile. The 50%/50vw trick breaks the player
   out of the section's own side padding (and its 1100px max-width) without
   needing to know the exact viewport/scrollbar math; the title, Flight
   Log, and CTA below keep a tighter 12px gutter instead of also going
   edge-to-edge. The 32px side padding used on desktop is far too wide on a
   375–414px screen, so every section (hero, grid, player, article,
   search, subscribe bar) gets the same tighter gutter here. */
/* Subscribe/Like/Share/Support (+ CTA/Tutorial if present) collapse to
   icon-only pills starting at tablet width, not just phone width. Below
   ~900px there isn't reliably enough room for four-plus full-text pills
   on one line, and once .flv-meta-actions-left wraps mid-row it reads as
   a layout bug rather than a deliberate two-line design. Collapsing to
   icons earlier keeps the whole row on one line all the way down to the
   640px tier below, where the rest of the mobile layout changes kick in.
   900px matches the tablet breakpoint already used for the video-grid
   carousel elsewhere in this file, so the row's behavior stays consistent
   with the rest of the plugin's responsive tiers. */
@media (max-width: 900px) {
	.flv-meta-actions-left .flv-btn-svg {
		display: inline-flex;
	}
	.flv-meta-actions-left .flv-btn-label {
		display: none;
	}
	.flv-meta-actions-left .flv-btn-support .flv-btn-label {
		display: inline;
	}
	.flv-meta-actions-left .flv-btn {
		padding: 10px;
		min-width: 40px;
	}

	/* CTA + Tutorial collapse to icon-only pills too, same as
	   Subscribe/Like/Share above, whenever an icon has actually been
	   picked for them (CTA sidebar panel) — keeps the pair from
	   dominating the row on a narrower screen. If no icon was chosen for
	   one (.flv-no-icon), it falls back to a shrunk text pill instead of
	   disappearing into a blank button. */
	.flv-cta-group .flv-btn-icon:not(.flv-no-icon) {
		padding: 10px;
		min-width: 40px;
		justify-content: center;
	}
	.flv-cta-group .flv-btn-icon:not(.flv-no-icon) .flv-btn-label {
		display: none;
	}
	.flv-cta-group .flv-btn.flv-no-icon {
		padding: 10px 16px;
		font-size: 11px;
	}
}

@media (max-width: 640px) {
	.flv-hero,
	.flv-video-grid-section,
	.flv-video-player-section,
	.flv-video-article,
	.flv-search-bar,
	.flv-subscribe-bar {
		padding-left: 12px;
		padding-right: 12px;
	}
	.flv-player-wrap {
		width: 100vw;
		max-width: 100vw;
		margin-left: calc(50% - 50vw);
		margin-right: calc(50% - 50vw);
		border-radius: 0;
	}

	/* Below 640px, the icon row (Subscribe/Like/Share/Support) and the
	   CTA/Tutorial group essentially never fit on one line together —
	   CTA/Tutorial labels vary per-video and aren't reliably short enough
	   for that, even icon-only. Rather than let the browser's default
	   flex-wrap decide where the break falls (which lands differently
	   video to video and can leave the CTA group oddly indented instead
	   of flush left), force it onto a deliberate second row every time:
	   icons on row one, CTA/Tutorial on row two, full width. */
	.flv-cta-group {
		flex-basis: 100%;
		width: 100%;
		gap: 10px;
	}

	/* Tutorial and CTA each take an equal half of that second row when
	   both are present, so the pair reads as one balanced full-width
	   control instead of two differently-sized pills bunched to the
	   left. A lone CTA (no Tutorial set) simply fills the full row. */
	.flv-video-tutorial,
	.flv-video-cta,
	.flv-cta-group .flv-btn.flv-no-icon {
		flex: 1 1 0;
		justify-content: center;
	}

	/* Once CTA/Tutorial get their own full-width row, there's no longer
	   a space crunch that requires hiding their label behind icon-only
	   (unlike Subscribe/Like/Share, which stay cramped next to each
	   other above). Undo the ≤900px icon-only collapse from the block
	   above just for this group, and give them back their normal
	   full-size padding now that each has room to breathe. */
	.flv-cta-group .flv-btn-icon:not(.flv-no-icon) {
		padding: 14px 20px;
		min-width: 0;
	}
	.flv-cta-group .flv-btn-icon:not(.flv-no-icon) .flv-btn-label {
		display: inline;
	}

	/* Same "fill the full row instead of clumping to one side" idea as
	   the CTA/Tutorial row above, applied to the Subscribe/Like/Share/
	   Support row — but NOT the same "flex: 1 1 0" equal-width split.
	   That row only works as equal columns because CTA/Tutorial are just
	   two same-shaped buttons. This row has four, and Support keeps its
	   text label even on mobile (see .flv-btn-support .flv-btn-label
	   above) while Subscribe/Like/Share are bare icons — forcing all
	   four into identical zero-basis columns squeezed Support's
	   icon+label (and Like's icon+count) below their own content width,
	   wrapping/overflowing instead of spreading evenly.
	   "flex: 1 1 auto" grows each button from its own natural content
	   width instead, so the row still stretches edge-to-edge with no
	   leftover gap, but Support/Like keep the extra width their content
	   actually needs. */
	.flv-meta-actions-left {
		width: 100%;
	}
	.flv-meta-actions-left .flv-btn {
		flex: 1 1 auto;
		justify-content: center;
	}
}

.flv-video-title-main {
	font-family: var(--flv-font-display);
	font-weight: 700;
	font-size: 28px;
	margin: 0 0 12px;
}

/* Subscribe/Like/Share/CTA sit in their own row directly under the
   title, above the Model Info + excerpt section below. */
.flv-model-info {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
	margin-bottom: 10px;
}

.flv-model-info-label {
	font-family: var(--flv-font-mono);
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.04em;
	color: var(--flv-text-muted);
	white-space: nowrap;
}

/* Smaller than the default .flv-pill used for filter rows elsewhere —
   there can be several of these next to the label, so keep them compact. */
.flv-model-info .flv-pill {
	padding: 5px 12px;
	font-size: 11px;
}

.flv-meta-actions {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 14px 24px;
	margin-bottom: 20px;
}

.flv-meta-actions-left {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 10px;
}

/* Subscribe/Like/Share/CTA all read as one family of same-size pill
   buttons here, instead of the taller rectangular .flv-btn shape used
   elsewhere on the site (hero, standalone CTA block, etc). */
.flv-meta-actions .flv-btn,
.flv-video-cta {
	border-radius: 999px;
}

/* Subscribe/Support/Tutorial/CTA are <a> tags while Like/Share are
   <button> elements. Browsers apply box-sizing: border-box to <button>
   by default but leave <a> at the normal box-sizing: content-box — so
   the exact same "padding: 10px; min-width: 40px;" mobile rule below
   produced two different pill sizes: buttons landed on a true 40px
   circle, while anchors added the 10px padding + border on *top* of
   the 40px, coming out ~22px wider. That's what made Subscribe's icon
   look like it had far more breathing room than Share's on mobile.
   Forcing border-box here for every button in this row keeps them all
   sized identically regardless of the underlying tag. */
.flv-meta-actions .flv-btn {
	box-sizing: border-box;
}

/* Tooltips for the Subscribe/Like/Share/Support row and the Tutorial/CTA
   pair — most useful once those buttons collapse to icon-only on
   mobile, but shown at every width. CSS-only (no JS), triggered by
   hover and keyboard focus so it stays reachable via Tab. */
.flv-meta-actions [data-flv-tooltip] {
	position: relative;
}

.flv-meta-actions [data-flv-tooltip]::after {
	content: attr(data-flv-tooltip);
	position: absolute;
	bottom: calc(100% + 8px);
	left: 50%;
	transform: translateX(-50%);
	background: rgba(0, 0, 0, 0.85);
	color: #f5f1e6;
	font-family: var(--flv-font-mono);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.03em;
	text-transform: none;
	white-space: nowrap;
	padding: 5px 10px;
	border-radius: 999px;
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: opacity 0.15s ease;
	z-index: 20;
}

.flv-meta-actions [data-flv-tooltip]:hover::after,
.flv-meta-actions [data-flv-tooltip]:focus-visible::after {
	opacity: 1;
	visibility: visible;
}

/* Wraps the CTA + Tutorial buttons together so they read as one group on
   the right of the row (flush against .flv-meta-actions-left via the
   parent's space-between), and stay next to each other as a pair on
   narrow screens instead of the CTA getting pushed away from a lone
   Tutorial button. */
.flv-cta-group {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-shrink: 0;
}

.flv-video-cta,
.flv-video-tutorial {
	flex-shrink: 0;
	white-space: nowrap;
}

/* The CTA and Tutorial buttons can each carry an optional icon (chosen in
   the CTA sidebar panel). Unlike Subscribe/Like/Share — whose icons only
   appear once collapsed on mobile — these show at every width whenever
   one's actually been picked, since it's a deliberate part of the button
   rather than a mobile-only fallback for the label. */
.flv-video-cta .flv-btn-svg,
.flv-video-tutorial .flv-btn-svg {
	display: inline-flex;
}

.flv-btn-icon {
	gap: 6px;
}

/* The icon shows on mobile only (see the max-width:640px rules below) —
   on desktop these buttons stay text-only, same as before. */
.flv-btn-svg {
	display: none;
	flex-shrink: 0;
}

/* The Support button keeps its icon *and* its "Support" label at every
   width — Subscribe/Like/Share collapse to icon-only on mobile because
   their icons are self-explanatory, but a plain icon alone reads as
   unclear for "support", so this one never drops the word. */
.flv-btn-support .flv-btn-svg {
	display: inline-flex;
}

/* Like button: filled/accented once liked, and the count stays visible
   even on mobile where the "Like" text label itself is hidden. */
.flv-like-count {
	font-variant-numeric: tabular-nums;
}

[data-flv-like].is-liked {
	color: var(--flv-accent);
	border-color: var(--flv-accent);
}

[data-flv-like].is-liked .flv-btn-svg {
	fill: var(--flv-accent);
}

[data-flv-share].is-copied {
	color: var(--flv-accent);
	border-color: var(--flv-accent);
}

.flv-description-wrap {
	max-width: 760px;
}

.flv-video-description {
	color: var(--flv-text-muted);
	font-family: var(--flv-font-body);
	font-size: 15px;
	line-height: 1.6;
	margin: 0;
}

/* Fully hidden by default — no preview lines — so only "Show more" shows
   until someone actually wants to read the excerpt; clicking it reveals
   the text in full (there's no partial/clamped state anymore). */
.flv-video-description.flv-desc-clamped {
	display: none;
}

.flv-desc-toggle {
	display: block;
	margin-top: 0;
	padding: 0;
	background: none;
	border: none;
	color: var(--flv-accent);
	font-family: var(--flv-font-body);
	font-size: 14px;
	font-weight: 600;
	cursor: pointer;
}

.flv-desc-toggle:hover,
.flv-desc-toggle:focus {
	text-decoration: underline;
}

/* ---------- Editor preview hardening ----------
   Everything above already has hex fallbacks baked into each var()
   (e.g. var(--flv-accent, #e11d2e)), which should carry the whole page —
   but on setups where the block editor doesn't pick up this stylesheet's
   :root variables at all, that fallback chain never gets evaluated either.
   These rules hardcode the essentials with real colors and !important so
   the title, buttons, and pills always look intentional in the editor
   preview specifically, regardless of that. The published page never gets
   this class and is completely unaffected. */
.flv-editor-preview {
	color: #f5f1e6 !important;
}
.flv-editor-preview .flv-video-title-main {
	color: #f5f1e6 !important;
}
.flv-editor-preview .flv-video-description,
.flv-editor-preview .flv-model-info-label {
	color: #9a968c !important;
}
.flv-editor-preview .flv-btn {
	display: inline-flex !important;
	align-items: center !important;
	border-radius: 999px !important;
	font-family: "IBM Plex Mono", "Courier New", monospace !important;
	font-size: 13px !important;
	font-weight: 600 !important;
	letter-spacing: 0.02em !important;
	text-decoration: none !important;
	padding: 14px 24px !important;
	border: 2px solid #3a3a3d !important;
	background: transparent !important;
	color: #f5f1e6 !important;
}
.flv-editor-preview .flv-btn-primary {
	background: #e11d2e !important;
	border-color: #e11d2e !important;
	color: #fff !important;
}
.flv-editor-preview .flv-pill {
	display: inline-flex !important;
	border-radius: 999px !important;
	border: 1px solid #3a3a3d !important;
	background: transparent !important;
	color: #f5f1e6 !important;
	font-family: "IBM Plex Mono", "Courier New", monospace !important;
	text-decoration: none !important;
}

/* ---------- Video article (written content below the player) ---------- */
.flv-video-article {
	max-width: 1100px;
	margin: 0 auto;
	padding: 0 32px 8px;
	color: var(--flv-text);
	font-family: var(--flv-font-body);
	font-size: 16px;
	line-height: 1.7;
}

.flv-video-article h2,
.flv-video-article h3,
.flv-video-article h4 {
	font-family: var(--flv-font-display);
	color: var(--flv-text);
	margin: 1.4em 0 0.6em;
}

.flv-video-article p {
	margin: 0 0 1.1em;
}

.flv-video-article a {
	color: var(--flv-accent);
}

.flv-video-article img {
	max-width: 100%;
	height: auto;
	border-radius: var(--flv-radius);
}

/* ---------- Misc ---------- */
.flv-empty-state {
	color: var(--flv-text-muted);
	font-family: var(--flv-font-body);
	font-style: italic;
	padding: 24px 0;
}

/* Editor-canvas convenience so blocks are legible while editing. */
.flv-editor-block {
	padding: 24px;
	border-radius: var(--flv-radius);
}

/* ---------- "CTA" sidebar panel — Tutorial search field (Document
   settings) ----------
   LinkControl (the searchable-link field used for the Step-by-Step
   Tutorial link) renders its suggestion list inline rather than in a
   popover. The Document sidebar column is only ~280px wide, so without a
   bound here the list can force the whole "CTA" panel wider or taller
   than the sidebar itself. Constrain both axes and let the results
   scroll internally instead. */
.flv-tutorial-link-control,
.flv-tutorial-link-control .block-editor-link-control {
	max-width: 100%;
	box-sizing: border-box;
}

.flv-tutorial-link-control .block-editor-link-control__search-input-wrapper,
.flv-tutorial-link-control input[type="text"] {
	width: 100%;
	max-width: 100%;
	box-sizing: border-box;
}

.flv-tutorial-link-control .block-editor-link-control__search-results-wrapper,
.flv-tutorial-link-control .block-editor-link-control__search-results {
	max-width: 100%;
	max-height: 220px;
	overflow-x: hidden;
	overflow-y: auto;
	box-sizing: border-box;
}

.flv-tutorial-link-control .block-editor-link-control__search-item-title,
.flv-tutorial-link-control .block-editor-link-control__search-item-info {
	overflow-wrap: break-word;
	word-break: break-word;
}

/* ---------- "Video" sidebar panel (Document settings) ---------- */
.flv-video-panel-preview-wrap {
	margin: 8px 0 16px;
}

.flv-video-panel-preview {
	position: relative;
	width: 100%;
	aspect-ratio: 16 / 9;
	background: #000;
	border-radius: 4px;
	overflow: hidden;
}

.flv-video-panel-preview iframe,
.flv-video-panel-preview video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: none;
}

.flv-video-panel-preview-loading {
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(0, 0, 0, 0.05);
}

/* ---------- Support lightbox ----------
   A single modal per single-video page, opened by the Support button
   (initSupportModal in front.js) instead of navigating away. */
.flv-support-modal {
	position: fixed;
	inset: 0;
	z-index: 9999;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px;
}

.flv-support-modal[hidden] {
	display: none;
}

body.flv-modal-open {
	overflow: hidden;
}

.flv-support-modal-backdrop {
	position: absolute;
	inset: 0;
	background: rgba(0, 0, 0, 0.7);
}

.flv-support-modal-dialog {
	position: relative;
	width: 100%;
	max-width: 480px;
	height: min(640px, 85vh);
	display: flex;
	flex-direction: column;
	background: var(--flv-surface);
	border: 1px solid var(--flv-border);
	border-radius: var(--flv-radius);
	overflow: hidden;
	box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}

.flv-support-modal-close {
	position: absolute;
	top: 8px;
	right: 8px;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	padding: 0;
	background: var(--flv-surface);
	color: var(--flv-text);
	border: 1px solid var(--flv-border);
	border-radius: 999px;
	cursor: pointer;
}

.flv-support-modal-frame {
	flex: 1;
	width: 100%;
	border: none;
	background: #fff;
}

.flv-support-modal-fallback {
	display: block;
	text-align: center;
	padding: 10px 12px;
	font-family: var(--flv-font-mono);
	font-size: 11px;
	letter-spacing: 0.03em;
	color: var(--flv-text-muted);
	border-top: 1px solid var(--flv-border);
	text-decoration: none;
}

.flv-support-modal-fallback:hover {
	color: var(--flv-text);
}

@media (max-width: 640px) {
	.flv-support-modal {
		padding: 0;
	}
	.flv-support-modal-dialog {
		max-width: 100%;
		height: 100%;
		border-radius: 0;
	}
}
