/**
 * Masculine Volt Quote Cards — public stylesheet.
 *
 * Everything in this file controls DISPLAY SIZE and GRID PLACEMENT
 * only. Nothing here should ever position quote text, author text,
 * the divider, or the logo — those pixels already exist inside the
 * generated <img>. This file's only job is to let that image shrink
 * and grow as one uniformly-scaled unit.
 */

.mv-quotes-widget {
	width: 100%;
}

.mv-quotes-grid {
	--mv-cols: 3;
	--mv-row-gap: 20px;
	--mv-column-gap: 20px;
	--mv-scroll-width: 220px;

	display: grid;
	grid-template-columns: repeat(var(--mv-cols), minmax(0, 1fr));
	row-gap: var(--mv-row-gap);
	column-gap: var(--mv-column-gap);
	/* Grid items (.mv-quote-grid-item, see below) fill their full track
	   width by default (CSS Grid's normal "stretch") rather than
	   shrinking to content — the OLD "justify-items: center" applied
	   when .mv-quote-card itself was the direct grid item; now that
	   the related-article region needs the FULL track width available
	   for its own ellipsis/truncation math, .mv-quote-grid-item stays
	   full-width and centers its OWN children (including a narrower
	   .mv-quote-card, via --mv-card-width) internally instead. */
}

/**
 * Note: the per-breakpoint value of --mv-cols itself is NOT set here.
 * Elementor's add_responsive_control() already generates its own
 * breakpoint-scoped CSS for --mv-cols (desktop/tablet/mobile) at
 * whatever breakpoints the site has configured, targeting this same
 * .mv-quotes-grid selector — duplicating that logic here would fight it.
 */

@media (max-width: 767px) {
	/* Optional per-widget mode: cards line up in a single scrollable
	   row on mobile instead of stacking. flex-shrink:0 plus a fixed
	   basis is what stops flexbox from squashing the aspect ratio. */
	.mv-quotes-grid.mv-quotes-scroll-mobile {
		display: flex;
		grid-template-columns: none;
		overflow-x: auto;
		overflow-y: hidden;
		scroll-snap-type: x proximity;
		-webkit-overflow-scrolling: touch;
		padding-bottom: 4px;
	}

	.mv-quotes-grid.mv-quotes-scroll-mobile .mv-quote-grid-item {
		flex: 0 0 var(--mv-scroll-width);
		width: var(--mv-scroll-width);
		scroll-snap-align: start;
	}
}

/**
 * .mv-quote-grid-item is the actual CSS Grid cell now (one per quote).
 * It always contains BOTH the related-article region and the quote
 * card as siblings — never nested one inside the other — so an outer
 * border on .mv-quote-card can no longer visually enclose the related-
 * article line (a deliberate change: the related article is no longer
 * part of the "card" unit at all, specifically so its extra line never
 * affects where the card itself begins).
 */
.mv-quote-grid-item {
	width: 100%;
	min-width: 0; /* required for the related-article ellipsis below to work inside a grid/flex child */
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	align-items: center; /* centers a narrower .mv-quote-card (--mv-card-width < 100%) same as before */
}

.mv-quote-card {
	container-type: inline-size;
	container-name: mv-quote-card;
	width: var(--mv-card-width, 100%);
	max-width: 100%;
	box-sizing: border-box;
	background: var(--mv-card-bg, transparent);
	border-radius: var(--mv-card-radius, 0);
	padding: var(--mv-card-padding, 0);
	display: flex;
	flex-direction: column;
	align-items: center;
}

/**
 * "Related article" region — ALWAYS rendered (see
 * MV_Quote_Relationship::render_related_article()), even for a
 * standalone quote with nothing to show. That's what guarantees every
 * .mv-quote-card in a mixed grid begins at the same Y position:
 * min-height reserves an identical box whether or not there's a link
 * inside it. The empty variant uses visibility:hidden — NOT
 * display:none — specifically so it keeps occupying that reserved
 * space instead of collapsing to zero height.
 *
 * position: relative anchors the hover tooltip (below) without taking
 * it out of this element's own box for layout purposes.
 */
.mv-quote-related-article {
	position: relative;
	width: 100%;
	min-width: 0;
	box-sizing: border-box;
	font-size: var(--mv-related-font-size, 0.85em);
	line-height: 1.4;
	min-height: 1.4em;
	margin-bottom: var(--mv-related-gap, 8px);
	/* Single line, always — never wraps, regardless of title length or
	   viewport width (this is a hard requirement, not a default that
	   can be overridden by a long title). */
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.mv-quote-related-article--empty {
	visibility: hidden;
}

.mv-quote-related-article a {
	color: inherit;
	font-weight: 600;
	text-decoration: underline;
}

.mv-quote-related-article a:hover,
.mv-quote-related-article a:focus-visible {
	opacity: 0.8;
}

/**
 * Hover tooltip — the full, untruncated title. Pure CSS: an adjacent-
 * sibling selector reveals it on :hover/:focus-visible of the link
 * right before it in the markup. Absolutely positioned and growing
 * upward (bottom: 100%) so it can never add height to this element's
 * own box or push the quote card below it down, and never needs to
 * measure anything with JavaScript.
 */
.mv-quote-related-tooltip {
	position: absolute;
	left: 0;
	bottom: 100%;
	margin-bottom: 6px;
	background: rgba(17, 17, 17, 0.95);
	color: #ffffff;
	padding: 6px 10px;
	border-radius: 4px;
	font-size: 0.85em;
	line-height: 1.3;
	white-space: normal;
	overflow-wrap: break-word;
	width: max-content;
	max-width: min(280px, calc(100vw - 32px)); /* never wider than the viewport, with a small safety margin */
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: opacity 0.15s ease;
	z-index: 10;
}

.mv-quote-related-article a:hover + .mv-quote-related-tooltip,
.mv-quote-related-article a:focus-visible + .mv-quote-related-tooltip {
	opacity: 1;
	visibility: visible;
}

/**
 * Deliberately NO `overflow: hidden` on .mv-quote-card itself
 * (requirement #45/#72). border-radius already clips this element's
 * own background/border regardless of overflow — the only thing
 * overflow:hidden was ever needed for is clipping the IMAGE inside it
 * to match rounded corners, and doing that on the card itself would
 * also clip the action buttons' focus outlines/box-shadows below the
 * image. Instead, only the media wrapper clips, using the same
 * --mv-card-radius value, so the image's corners still visually match
 * the container's rounded corners without touching the buttons at all.
 */
.mv-quote-card-media {
	width: 100%;
	line-height: 0;
	border-radius: var(--mv-card-radius, 0);
	overflow: hidden;
}

/**
 * The width/height attributes on the <img> (set from the card's real
 * pixel dimensions in quote-card-frontend.php) already reserve the
 * correct intrinsic aspect ratio in every modern browser. This rule
 * simply lets that fixed-ratio box scale down to fit its column.
 */
.mv-quote-card-image {
	display: block;
	width: 100%;
	height: auto;
	max-width: 100%;
	transition: opacity 0.15s ease;
}

/* The whole card image is now a link to the quote's native page (1.11.0)
   — same subtle opacity feedback the related-article link already uses,
   applied to the image itself rather than an outline, since an outline
   would get clipped by .mv-quote-card-media's own overflow:hidden. */
.mv-quote-card-link {
	display: block;
}

.mv-quote-card-link:hover .mv-quote-card-image,
.mv-quote-card-link:focus-visible .mv-quote-card-image {
	opacity: 0.92;
}

.mv-quote-card-actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	/* Button-to-button gap (--mv-btn-gap, Action Buttons section) is
	   distinct from the space between the card image and the whole
	   button row (--mv-actions-gap, Card Container section) — see
	   requirement #48. Falls back to the previous clamp() sizing when
	   --mv-btn-gap hasn't been set by Elementor. */
	gap: 8px;
	gap: clamp(4px, 1.5cqw, 8px);
	gap: var(--mv-btn-gap, clamp(4px, 1.5cqw, 8px));
	margin-top: 10px;
	margin-top: var(--mv-actions-gap, 10px);
}

/**
 * The button's visual identity (background/text color/size/radius) is
 * fully driven by CSS custom properties, with sensible pill defaults
 * baked in here as fallbacks. The Elementor widget's "Action Buttons"
 * style section sets these per-instance via {{WRAPPER}} selectors —
 * see register_button_style_controls() in trait-mv-quote-grid-controls.php,
 * used identically by all three button-bearing widgets (Masculine Volt
 * Quotes, Masculine Volt Category Quotes, and Masculine Volt Quote
 * Download) so hover behavior is unified rather than reimplemented
 * per widget.
 *
 * Sizing is proportional to the CARD, not fixed: .mv-quote-card
 * establishes a CSS container (container-type: inline-size) and the
 * font-size below is a clamp() using cqw (container-query width)
 * units, floored at 10px and capped at whatever font size is actually
 * configured in Elementor. That means a card that shrinks — because
 * the grid has more columns, or the viewport narrowed — shrinks its
 * buttons right along with it instead of the buttons staying a fixed
 * pixel size while the card around them gets tiny. Padding is in em,
 * so it scales together with the font-size automatically.
 *
 * Each property is declared twice on purpose: the plain var() line
 * first as a fallback, the clamp()/cqw line second so it wins in
 * browsers that support container query units, and is silently
 * ignored (falling back to the first line) in ones that don't.
 */
.mv-quote-btn {
	appearance: none;
	box-sizing: border-box;
	background: var(--mv-btn-bg, #111111);
	color: var(--mv-btn-text-color, #ffffff);
	font: inherit;
	font-size: var(--mv-btn-font-size, 13px);
	font-size: clamp(10px, 3.5cqw, var(--mv-btn-font-size, 13px));
	letter-spacing: 0.02em;
	padding: 0.6em 1.15em;
	line-height: 1.2;
	border-radius: var(--mv-btn-radius, 999px);
	border: var(--mv-btn-border-width, 0) solid var(--mv-btn-border-color, transparent);
	cursor: pointer;
	text-decoration: none;
	display: inline-flex;
	align-items: center;
	gap: 6px;
	transition: var(--mv-btn-transition, background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease);
}

/**
 * Hover state — deliberately no automatic default effect (no opacity
 * dimming) beyond falling back to each button's own normal-state
 * value when a hover control is left unset in Elementor. This is the
 * "unified hover settings" requirement: appearance on hover is
 * whatever the Style panel says, consistently, for every quote action
 * button in every widget that shares this class — never a hard-coded
 * per-button effect.
 */
.mv-quote-btn:hover,
.mv-quote-btn:focus-visible {
	background: var(--mv-btn-hover-bg, var(--mv-btn-bg, #111111));
	color: var(--mv-btn-hover-text-color, var(--mv-btn-text-color, #ffffff));
	border-color: var(--mv-btn-hover-border-color, var(--mv-btn-border-color, transparent));
	border-width: var(--mv-btn-hover-border-width, var(--mv-btn-border-width, 0));
	border-radius: var(--mv-btn-hover-radius, var(--mv-btn-radius, 999px));
}

.mv-quote-btn[data-copied="true"] {
	opacity: 0.7;
}

/* =====================================================================
 * CATEGORY FILTER (Elementor widget "Show Category Filter" option)
 * Filters cards already present in the DOM — see initCategoryFilters()
 * in public/js/public.js. Not currently exposed as Elementor style
 * controls; kept to sensible, theme-neutral pill defaults.
 * ===================================================================*/

.mv-quotes-category-filter {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 8px;
	margin-bottom: 22px;
}

.mv-quotes-cat-btn {
	appearance: none;
	border: 1px solid rgba(0, 0, 0, 0.15);
	background: rgba(0, 0, 0, 0.04);
	color: inherit;
	font: inherit;
	font-size: 13px;
	padding: 8px 18px;
	border-radius: 999px;
	cursor: pointer;
	transition: opacity 0.15s ease, background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.mv-quotes-cat-btn:hover {
	opacity: 0.8;
}

.mv-quotes-cat-btn.is-active {
	background: #111111;
	border-color: #111111;
	color: #ffffff;
}

/* =====================================================================
 * PAGINATION (Elementor widgets "Enable Pagination" option)
 * Renders paginate_links()'s own <ul class="page-numbers"> markup — the
 * same structure most WordPress themes already style for their own
 * archive pagination — wrapped in a scoped <nav> so a theme's generic
 * .page-numbers rules don't have to be relied on (and can't visually
 * clash with these theme-neutral defaults).
 * ===================================================================*/

.mv-quotes-pagination {
	margin-top: 28px;
	display: flex;
	justify-content: center;
}

.mv-quotes-pagination ul.page-numbers {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 6px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.mv-quotes-pagination .page-numbers li {
	display: block;
}

.mv-quotes-pagination a.page-numbers,
.mv-quotes-pagination span.page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.4em;
	height: 2.4em;
	padding: 0 0.6em;
	border: 1px solid rgba(0, 0, 0, 0.15);
	border-radius: 6px;
	font-size: 13px;
	text-decoration: none;
	color: inherit;
	transition: opacity 0.15s ease, background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.mv-quotes-pagination a.page-numbers:hover,
.mv-quotes-pagination a.page-numbers:focus-visible {
	opacity: 0.8;
}

.mv-quotes-pagination span.page-numbers.current {
	background: #111111;
	border-color: #111111;
	color: #ffffff;
}

.mv-quotes-pagination .page-numbers.dots {
	border: none;
	background: none;
}

/* =====================================================================
 * QUOTE CATEGORY DIRECTORY ("Masculine Volt Quote Categories" widget)
 * Pure navigation — real <a> elements, no card artwork, no JS. Every
 * responsive value ({{VALUE}}) comes from the widget's own Elementor
 * responsive controls; only the neutral fallback defaults live here.
 * ===================================================================*/

.mv-quote-categories-widget {
	width: 100%;
}

.mv-quote-categories-grid {
	--mv-category-cols: 4;
	--mv-category-row-gap: 20px;
	--mv-category-column-gap: 30px;

	display: grid;
	grid-template-columns: repeat(var(--mv-category-cols), minmax(0, 1fr));
	row-gap: var(--mv-category-row-gap);
	column-gap: var(--mv-category-column-gap);
}

.mv-quote-category-item {
	display: block;
	color: inherit;
	text-decoration: none;
	font: inherit;
}

.mv-quote-category-item:hover,
.mv-quote-category-item:focus-visible {
	text-decoration: none; /* Overridden by the widget's own "Underline On Hover" control when enabled. */
}

/* =====================================================================
 * SINGLE QUOTE DOWNLOAD PAGE ("Masculine Volt Quote Download" widget
 * and the plugin's own fallback template)
 * ===================================================================*/

.mv-quote-download-page-inner {
	max-width: 900px;
	margin: 60px auto;
	padding: 0 20px;
}

.mv-quote-download-page-final {
	text-align: center;
	margin-top: 20px;
}

.mv-quote-download-widget-actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 10px;
	gap: var(--mv-btn-gap, 10px);
	margin-top: 20px;
}

/* =====================================================================
 * MOBILE FOOTER BUG FIX — "Masculine Volt Category Quotes" widget only
 * =====================================================================
 * Investigation: .mv-quotes-grid uses a plain CSS Grid with implicit
 * (auto) row tracks and no height/max-height/overflow constraint of
 * its own; .mv-quote-card has no fixed height either, and the shared
 * PHP template's while-loop correctly calls wp_reset_postdata() after
 * iterating the widget's own WP_Query, so global post state is not
 * left dangling. None of that reproduces a mid-grid footer break on
 * its own.
 *
 * The one place height CAN silently get constrained without anything
 * in this plugin's own CSS being at fault is Elementor's per-widget
 * wrapper: every Elementor widget instance is wrapped in
 * `.elementor-widget-{widget-name} > .elementor-widget-container`,
 * and Elementor itself (via a per-instance Advanced-tab "Overflow"
 * setting, a motion-effect/masking option, or certain theme defaults)
 * can apply `overflow: hidden` and/or a height constraint to THAT
 * wrapper — independent of anything this plugin renders inside it.
 * Because this widget can render a large, dynamically-tall grid (many
 * cards, each now potentially taller than before thanks to the
 * related-article line), it's the widget most likely to actually
 * exceed such a constraint, which produces exactly the reported
 * symptom: content visibly continuing past where the page's normal
 * document flow (and therefore the footer) already moved on.
 *
 * Fix: neutralize height/overflow constraints ONLY on this one
 * widget's own Elementor-generated wrapper, using Elementor's own
 * predictable class name for this widget (`elementor-widget-
 * masculine_volt_category_quotes`, from get_name()). This cannot
 * affect any other widget, the footer, or any other part of the page
 * — it is scoped as narrowly as the DOM allows short of an inline
 * style. content determines height here; nothing overrides it with
 * JavaScript.
 * ===================================================================*/
.elementor-widget-masculine_volt_category_quotes,
.elementor-widget-masculine_volt_category_quotes > .elementor-widget-container {
	height: auto !important;
	max-height: none !important;
	overflow: visible !important;
}

@media (max-width: 767px) {
	/* Same reasoning, mobile-specific: some themes apply mobile-only
	   overflow/height rules to widget wrappers that don't show up on
	   desktop, which matches "no desktop regression, mobile only". */
	.elementor-widget-masculine_volt_category_quotes,
	.elementor-widget-masculine_volt_category_quotes > .elementor-widget-container {
		height: auto !important;
		max-height: none !important;
		overflow: visible !important;
	}
}
