/*
 * Flight Log Shorts Hub — front-end + editor styling.
 * Entirely separate from Video Hub's assets/css/style.css. Reuses the
 * same TriKdanG theme brand tokens (via the --tktt- custom properties,
 * with hard-coded fallbacks) so Shorts pages match the rest of the site,
 * without depending on Video Hub's stylesheet being loaded at all.
 */

:root {
	--flvs-bg: var(--tktt-bg-primary, #121316);
	--flvs-surface: var(--tktt-bg-surface, #1b1d22);
	--flvs-border: var(--tktt-border, #3a3a3d);
	--flvs-text: var(--tktt-text-primary, #f5f1e6);
	--flvs-text-muted: var(--tktt-text-muted, #9a968c);
	--flvs-accent: var(--tktt-accent, #e11d2e);
	--flvs-radius: 14px;
	--flvs-font-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
	--flvs-font-body: "Inter", "Helvetica Neue", Arial, sans-serif;
}

/* No forced background here on purpose — same fix Video Hub already
   has. This class isn't just on <main>, it's also added straight onto
   <body> (see flvs_body_class() in the main plugin file), so painting a
   solid color here paints the entire page body. On a site where the
   theme's own background/footer isn't exactly this color, that shows up
   as a mismatched panel with a hard seam right where the real footer
   starts — which is what was reading as a "narrow and messy footer".
   Leaving background unset lets Shorts pages inherit whatever the
   theme/page already has, so the footer sits on the same continuous
   background as everything above it. */
.flvs-shorts-hub {
	background: none;
	color: var(--flvs-text);
}

/* Guards against any long unbroken string (a pasted URL, a run-on title,
   etc.) blowing out past the container width instead of wrapping — same
   fix already applied on Video Hub's .flv-video-hub. Without this, a
   long string on the single Short page can force the whole document
   wider than the viewport, which is what was squeezing the real site
   footer (below this page's content) into a narrow, misaligned strip
   instead of it spanning the page normally. */
.flvs-shorts-hub {
	overflow-wrap: break-word;
	word-break: break-word;
}

/* Video Hub's single/archive pages render at genuine full width because
   the active theme ships its own "Video Watch Page (Full Width)" FSE
   template for flv_video (see FLV_Templates::block_theme_has_template())
   — when that exists, WordPress's real block-template canvas renders the
   page and this plugin's own PHP wrapper never even runs. Shorts has no
   theme-provided equivalent, so templates/single-flv_short.php and
   archive-flv_short.php's fallback <main id="flvs-short-page"> /
   <main id="flvs-archive-page"> is what always renders instead — and it
   was inheriting the theme's default content-width constraint on <main>,
   which is what was reading as a "shrunk" page with the real site footer
   squeezed/broken underneath it. Forcing these two IDs to full width here
   reproduces the same full-bleed result the Full Width template gives
   Video Hub, without needing the theme to define a matching template. */
#flvs-short-page,
#flvs-archive-page {
	width: 100%;
	max-width: none;
	margin-left: 0;
	margin-right: 0;
}

/* ---------- Short Player (single portal page) ---------- */

.flvs-short-player-section {
	max-width: 640px;
	margin: 0 auto;
	padding: 0 20px 24px;
}

.flvs-player-wrap {
	position: relative;
	width: 100%;
	max-width: 380px;
	margin: 0 auto;
	aspect-ratio: 9 / 16;
	background: #000;
	border-radius: var(--flvs-radius);
	overflow: hidden;
}

/* Enforces the strict 9:16 vertical container even in "full-bleed" mode
   — full-bleed only removes the max-width cap so the card can grow to
   fill a wider column, it never allows widescreen distortion. */
.flvs-player-wrap.flvs-layout-full-bleed {
	max-width: 100%;
	border-radius: 0;
}

.flvs-player-embed,
.flvs-player-embed iframe,
.flvs-player-embed video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
	object-fit: cover;
}

.flvs-player-preview {
	background: #000;
}

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

.flvs-thumb-placeholder {
	display: block;
	width: 100%;
	height: 100%;
	background: var(--flvs-surface);
}

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

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

.flvs-player-preview-badge {
	position: absolute;
	left: 10px;
	right: 10px;
	bottom: 10px;
	padding: 6px 10px;
	background: rgba(0, 0, 0, 0.75);
	color: var(--flvs-text);
	font-size: 11px;
	text-align: center;
	border-radius: 999px;
}

.flvs-short-title-main {
	font-family: var(--flvs-font-display);
	font-size: 20px;
	font-weight: 700;
	line-height: 1.35;
	text-align: center;
	max-width: 380px;
	margin: 18px auto 0;
	color: var(--flvs-text);
}

.flvs-short-article {
	max-width: 380px;
	margin: 18px auto 0;
	color: var(--flvs-text-muted);
	font-family: var(--flvs-font-body);
	font-size: 14px;
	line-height: 1.6;
}

/* ---------- Short Grid (More Shorts / archive) ---------- */

.flvs-short-grid-section {
	max-width: 1100px;
	margin: 0 auto;
	padding: 40px 32px 64px;
}

/* FLV Short Grid block only, when "Full width" is picked from its own
   toolbar (adds the standard "alignfull" class to the block wrapper) —
   removes the section's max-width and side padding so the grid runs
   edge-to-edge on the page. Doesn't affect the "More Shorts" row on a
   single Short page or the /shorts/ archive, since neither renders
   through this block. */
.flvs-short-grid-block.alignfull .flvs-short-grid-section {
	max-width: none;
	margin: 0;
	padding-left: 0;
	padding-right: 0;
}

.flvs-grid-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 10px 18px;
	margin-bottom: 18px;
}

.flvs-section-heading {
	font-family: var(--flvs-font-display);
	font-size: 14px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--flvs-text);
	margin: 0;
}

/* "See all" link, next to the heading/filters on any grid that has more
   matching Shorts loaded on the server than what's actually on screen —
   set in class-templates.php's render_shorts_grid() via $has_more, off
   the same found_posts count the query already produces. Ported 1:1
   from Video Hub's .flv-view-all-link. */
.flvs-view-all-link {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	flex-shrink: 0;
	color: var(--flvs-text);
	font-family: var(--flvs-font-body);
	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;
}

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

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

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

/* ---------- Filter pills (category/tag marquee) ----------
   Ported 1:1 from Video Hub's own filter row (see FLV video-grid/
   render.php + front.js's initFilterMarquee/initFilterMarqueeStop) so
   Shorts' category pills look and behave exactly the same — a plain
   row wrapped by default; JS measures whether the pills actually need
   more than one line at the available width, and only then adds
   .is-scrolling and clones a second copy for a seamless auto-scroll
   loop. Fewer categories that already fit are left completely alone. */
.flvs-filter-marquee {
	overflow: visible;
}

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

.flvs-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". */
.flvs-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);
}

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

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

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

@keyframes flvs-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). */
.flvs-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;
}

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

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

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

.flvs-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. */
.flvs-filter-marquee-wrap .flvs-filter-marquee {
	flex: 1 1 auto;
	min-width: 0;
}

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

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

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

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

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

.flvs-pill {
	display: inline-flex;
	padding: 6px 14px;
	border: 1px solid var(--flvs-border);
	border-radius: 999px;
	color: var(--flvs-text-muted);
	background: var(--flvs-surface);
	font-family: var(--flvs-font-body);
	font-size: 12px;
	text-decoration: none;
	white-space: nowrap;
	flex-shrink: 0;
	transition: color 0.15s ease, border-color 0.15s ease;
}

/* Matches Video Hub's .flv-pill:hover exactly — a subtle text-brighten,
   no border/outline color change. (Previously this swapped the border
   to --flvs-accent, which read as a jarring red outline and was the
   one place Shorts' filter pills didn't match Video Hub's.) */
.flvs-pill:hover {
	color: var(--flvs-text);
}

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

/* Same auto-fit + computed min-card technique as Video Hub's "More
   builds" grid (see class-templates.php render_shorts_grid()): the grid
   lands on exactly the configured column count at the section's own max
   width, then reflows to fewer columns on narrower screens on its own —
   instead of the old fixed 900px/560px breakpoints hard-capping every
   column choice at 3 then 2 regardless of what was configured. */
.flvs-short-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(var(--flvs-min-card, 150px), 1fr));
	gap: 20px 16px;
}

/* The Shorts archive (templates/archive-flv_short.php, id="flvs-archive-
   page") is deliberately kept to a single big column on desktop — see
   the 'columns' => 1 passed to render_shorts_grid() there — but on
   mobile that wastes space, so this override switches it to 2 columns
   there instead, fitting more Shorts on screen per scroll. The "More
   Shorts" grid at the bottom of a single Short page (id="flvs-short-
   page") isn't touched, so it keeps its own configured column count. */
@media (max-width: 640px) {
	#flvs-archive-page .flvs-short-grid {
		grid-template-columns: repeat(2, 1fr) !important;
		gap: 14px 10px;
	}
}

@media (max-width: 380px) {
	#flvs-archive-page .flvs-short-grid {
		gap: 12px 8px;
	}
	#flvs-archive-page .flvs-short-title {
		font-size: 12px;
	}
}

/* Editor preview only (mirrors .flv-video-grid--editor in Video Hub) —
   fixed 3-column layout regardless of the configured column count or the
   canvas's actual pixel width, so the editor never lands in a cramped
   in-between state a narrower/unpredictable canvas width could otherwise
   produce. The published page is unaffected. */
.flvs-short-grid--editor {
	grid-template-columns: repeat(3, 1fr) !important;
	gap: 16px 12px;
}

.flvs-short-card {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

/* Positioning context for the end-card overlay, which sits absolutely
   over the thumbnail link as a sibling (not nested inside it) — see
   class-templates.php render_shorts_grid(). */
.flvs-short-thumb-wrap {
	position: relative;
	display: block;
}

.flvs-short-thumb-link {
	display: block;
	text-decoration: none;
	color: var(--flvs-text);
}

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

.flvs-short-thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: transform 0.25s ease;
}

.flvs-short-thumb-link:hover .flvs-short-thumb img {
	transform: scale(1.03);
}

/* Scroll-triggered autoplay preview (see initShortsFeedAutoplay in
   front.js) — whichever card is currently the most-visible one on
   screen gets this class and a live, muted embed layered over its
   poster image, the same "one video plays as you scroll" behavior as a
   TikTok/YouTube Shorts feed. The poster stays underneath so there's no
   flash of empty space while the embed itself loads in. Applied either
   directly to the embed element (Vimeo/file) or to a wrapping element
   around it (YouTube, whose Player API replaces its target element in
   place — see activateFeedCard in front.js), hence the extra child
   selector below. */
.flvs-short-thumb-embed {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
	opacity: 0;
	transition: opacity 0.2s ease;
	pointer-events: none;
}

.flvs-short-thumb-embed > iframe,
.flvs-short-thumb-embed > video {
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
}

.flvs-short-thumb-link.is-flvs-playing .flvs-short-thumb-embed {
	opacity: 1;
}

/* End-card overlay: hidden by default (see [hidden] rule below), shown
   by front.js once a card's muted preview actually finishes playing —
   "like a YouTube end card" rather than a permanent fixture, so it
   doesn't compete with the thumbnail while the preview is still
   playing. Sits above the thumb link but is only interactive while
   visible; while hidden it never blocks clicks through to the Short's
   own page. */
.flvs-short-endcard {
	position: absolute;
	inset: 0;
	z-index: 2;
	display: flex;
	align-items: flex-end;
	justify-content: center;
	padding: 10px 8px;
	border-radius: 10px;
	background: linear-gradient(180deg, rgba(10, 10, 14, 0) 0%, rgba(10, 10, 14, 0.55) 45%, rgba(10, 10, 14, 0.85) 100%);
}

.flvs-short-endcard[hidden] {
	display: none;
}

/* Compact override of the shared Flight Log row (same markup/classes as
   the single-Short player's own row — see FLVS_Blocks::render_flight_log_row())
   so 4–5 icon buttons still fit comfortably inside a narrow grid card. */
.flvs-short-endcard .flvs-meta-actions {
	margin: 0;
	max-width: none;
	gap: 6px;
	flex-wrap: wrap;
}

.flvs-short-endcard .flvs-meta-actions-left {
	gap: 6px;
	flex-wrap: wrap;
	justify-content: center;
}

.flvs-short-endcard .flvs-icon-btn {
	width: 28px;
	height: 28px;
}

.flvs-short-endcard .flvs-icon-btn svg {
	width: 13px;
	height: 13px;
}

.flvs-short-endcard .flvs-like-count {
	min-width: 13px;
	padding: 0 3px;
	font-size: 8px;
	top: -3px;
	right: -3px;
}

.flvs-short-title-link {
	text-decoration: none;
}

.flvs-short-title {
	font-family: var(--flvs-font-body);
	font-size: 13px;
	font-weight: 600;
	line-height: 1.35;
	color: var(--flvs-text);
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.flvs-empty-state {
	color: var(--flvs-text-muted);
	font-style: italic;
	font-family: var(--flvs-font-body);
}

/* ---------- Flight Log row (icon-only) ----------
   Used both by the short-player block's built-in row (auto-added to
   every single Short page) and the standalone flvs/subscribe-bar
   block — both call FLVS_Blocks::render_flight_log_row() so they can
   never visually drift apart. */

.flvs-subscribe-bar-wrap {
	padding: 14px 0;
}

.flvs-meta-actions {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	max-width: 380px;
	margin: 14px auto 0;
}

.flvs-subscribe-bar-wrap .flvs-meta-actions {
	margin-top: 0;
}

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

.flvs-icon-btn {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	border-radius: 999px;
	background: var(--flvs-surface);
	border: 1px solid var(--flvs-border);
	color: var(--flvs-text);
	text-decoration: none;
	cursor: pointer;
	transition: transform 0.15s ease, border-color 0.15s ease;
}

.flvs-icon-btn:hover {
	transform: translateY(-1px);
	border-color: var(--flvs-text);
}

.flvs-icon-btn svg {
	width: 19px;
	height: 19px;
}

.flvs-icon-subscribe {
	background: var(--flvs-accent);
	border-color: var(--flvs-accent);
	color: #ffffff;
}

/* Per-Short CTA color, set inline via --flvs-cta-color on the element. */
.flvs-icon-cta {
	border-color: var(--flvs-cta-color, var(--flvs-accent));
	color: var(--flvs-cta-color, var(--flvs-accent));
}

.flvs-icon-btn--empty {
	opacity: 0.35;
	pointer-events: none;
}

/* Like icon: real count badge in the corner, filled/accented once liked. */
.flvs-like-count {
	position: absolute;
	top: -4px;
	right: -4px;
	min-width: 17px;
	padding: 1px 4px;
	border-radius: 999px;
	background: var(--flvs-accent);
	color: #ffffff;
	font-family: var(--flvs-font-body);
	font-size: 10px;
	font-weight: 700;
	line-height: 1.5;
	text-align: center;
	font-variant-numeric: tabular-nums;
}

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

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

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

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

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

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

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

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

.flvs-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(--flvs-surface);
	color: var(--flvs-text);
	border: 1px solid var(--flvs-border);
	border-radius: 999px;
	cursor: pointer;
}

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

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

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

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

@media (max-width: 480px) {
	.flvs-player-wrap {
		max-width: 100%;
	}
}

/* Same mobile gutter fix as Video Hub's equivalent sections — the 32px
   side padding used on desktop is too wide on a 375–414px screen, so it
   tightens to 12px here instead, matching the wrapper width Video Hub
   uses at this breakpoint. */
@media (max-width: 640px) {
	.flvs-short-player-section,
	.flvs-short-grid-section {
		padding-left: 12px;
		padding-right: 12px;
	}
}
