/**
 * CL archive — NEW styles only (Phase 2, lane [AR]).
 * Everything that pixel-matches legacy comes from the re-enqueued legacy
 * stylesheets (see cl-engine/inventory/frontend.php); this file covers only
 * what is new in the CL build: dual-thumb range controls, chosen-filter
 * badges, SOLD badge, mobile filter drawer, pagination mobile pattern
 * (no :has), and resets for elements that became real <button>s.
 * Safari budget: no :has(), no color-mix(), no overflow:clip anywhere here.
 */

:root {
	--cl-accent: #d02329;        /* overridden inline from brand.color */
	--cl-accent-hover: #b11e23;  /* precomputed in PHP — no color-mix() */
}

/* ── Button-ified legacy elements: neutralize UA button chrome ─────────── */
.cl-inventory button.filter-handle,
.cl-inventory button.filter-close,
.cl-inventory button.filter-reset,
.cl-inventory button.action-reset,
.cl-inventory button.show-all,
.cl-inventory button.show-less,
.cl-inventory button.mvl-actions-popup-button,
.cl-inventory button.stm-share {
	background: none;
	border: 0;
	padding: 0;
	margin: 0;
	font: inherit;
	color: inherit;
	text-align: inherit;
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
}
.cl-inventory button.filter-handle {
	/* Parity round 2 (2026-07-24): the button-chrome reset above zeroed the
	   padding that legacy base.css gives the (div) filter handle, clipping the
	   pill to 62px vs legacy's 116px. Restore the legacy metrics explicitly. */
	display: flex;
	justify-content: center;
	align-items: center;
	gap: 6px;
	padding: 14px 20px;
	font-size: 16px;
	font-weight: 600;
	border-radius: 8px;
	height: 47px;
}

/* ── Loading state ─────────────────────────────────────────────────────── */
.cl-inventory.cl-loading #listings-result {
	opacity: 0.55;
	pointer-events: none;
	transition: opacity 0.15s ease;
}

/* ── Dual-thumb range control (replaces the legacy jQuery-UI slider) ───── */
.cl-range {
	/* Parity round 2 (2026-07-24): the legacy jQuery-UI slider element is a
	   4px track with 10px vertical margins; the dot handles OVERLAP the track
	   without adding height. The previous 28px-tall control made every slider
	   section 24px taller than legacy, shifting the whole sidebar down. The
	   range inputs stay 24px tall (touch/click target) but are absolutely
	   centered over the 4px box, so the layout height matches legacy. */
	position: relative;
	/* Parity round 4 (2026-07-26, re-measured in live legacy DOM): legacy
	   .stm-price-range-unit is a 4px-tall box with margin 10px 0 — 24px of
	   flow. Round 3 had measured it as h0/mb0 (10px of flow), which left every
	   slider group exactly 14px SHORTER than legacy and slid the sidebar and
	   footer up by 28px across the two sliders. Match the measured legacy
	   flow: 4px + 10/10 margins. */
	height: 4px;
	margin: 10px 0;
	/* Slider fix 2026-07-25: the wrapper drives dragging via pointer events
	   (Chrome ignores pointer-events on the thumb pseudo — see cl-inventory.js
	   attachRangePointer). Don't let touch drags scroll the page instead. */
	touch-action: none;
}
/* Expanded hit area: the box is a 4px strip (legacy layout parity) while the
   thumbs/fingers need ~28px. The pseudo hit-tests as part of the wrapper, so
   pointerdown anywhere over the visual control reaches the drag controller —
   no layout change (absolute overlay). Plain ::before, no :has()/clip. */
.cl-range::before {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: -10px;  /* stays inside the control's own 10px margins so it can */
	bottom: -10px; /* never steal clicks from the min/max fields above */
}
.cl-range__track {
	position: absolute;
	left: 0;
	right: 0;
	top: 50%;
	height: 4px;
	margin-top: -2px;
	border-radius: 2px;
	background: #e2e6ea;
}
.cl-range__fill {
	position: absolute;
	top: 0;
	bottom: 0;
	background: var(--cl-accent);
	border-radius: 2px;
}
.cl-range__input {
	position: absolute;
	left: 0;
	right: 0;
	top: 50%;
	transform: translateY(-50%);
	width: 100%;
	margin: 0;
	height: 28px;
	background: transparent;
	-webkit-appearance: none;
	appearance: none;
	pointer-events: none; /* thumbs re-enable below */
	outline: none;
}
/* Thumbs: solid accent dots, the legacy jQuery-UI slider handle look
   (parity fix 2026-07-24 — was a white ring). */
.cl-range__input::-webkit-slider-thumb {
	-webkit-appearance: none;
	appearance: none;
	pointer-events: auto;
	width: 14px;
	height: 14px;
	border-radius: 50%;
	background: var(--cl-accent);
	border: 0;
	box-shadow: 0 1px 3px rgba(17, 24, 39, 0.25);
	cursor: pointer;
}
.cl-range__input::-moz-range-thumb {
	pointer-events: auto;
	width: 14px;
	height: 14px;
	border-radius: 50%;
	background: var(--cl-accent);
	border: 0;
	box-shadow: 0 1px 3px rgba(17, 24, 39, 0.25);
	cursor: pointer;
}
.cl-range__input::-moz-range-track {
	background: transparent;
}
.cl-range__input:focus-visible::-webkit-slider-thumb {
	outline: 2px solid var(--cl-accent);
	outline-offset: 2px;
}
.cl-range__input:focus-visible::-moz-range-thumb {
	outline: 2px solid var(--cl-accent);
	outline-offset: 2px;
}

/* ── Native sort select skinned like the legacy select2 control ─────────
   (parity fix 2026-07-24: the legacy sort was a borderless select2 with a
   chevron; the CL native <select> rendered with UA chrome. Same look now,
   still a native accessible control.) */
.cl-inventory .stm-select-sorting select[data-cl-sort] {
	-webkit-appearance: none;
	appearance: none;
	border: 0;
	background-color: transparent;
	background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23010101' stroke-opacity='0.8' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 10px center;
	/* Parity round 2 (2026-07-24): match the legacy select2 skin exactly —
	   search-results-actions.css sets 13px/400, rgba(1,1,1,.8), 40px line,
	   0 left padding, 32px right gutter for the chevron.
	   Parity round 3 (2026-07-25, live legacy probe): the select2 span
	   INHERITED "Montserrat, sans-serif" — the CL <button>/<select> were
	   picking up the body's Space Grotesk stack instead, so the control
	   rendered in a visibly different face (the child theme master rule
	   body,button,input,select{font-family:var(--cl-font)!important} forces
	   the site font onto form controls but never touched the legacy select2
	   SPANs — hence the !important + scoped specificity here). */
	font-family: var(--cl-font, Montserrat, sans-serif) !important;
	padding: 0 32px 0 0;
	font-size: 13px;
	font-weight: 400;
	color: rgba(1, 1, 1, 0.8);
	cursor: pointer;
	line-height: 40px;
	height: 40px;
}
.cl-inventory .stm-select-sorting select[data-cl-sort]:focus-visible {
	outline: 2px solid var(--cl-accent);
	outline-offset: 2px;
}
@media (max-width: 767px) {
	/* Parity round 2: the mobile sort pill (child inline styles) draws its own
	   ::after chevron — drop this select's background chevron so the control
	   doesn't show two arrows like it did post-cutover. Round 3: same guard
	   for the enhanced button's cl-icons ::after chevron. */
	.cl-inventory .stm-select-sorting select[data-cl-sort] {
		background-image: none;
	}
	.cl-inventory .cl-sortdd__btn::after {
		display: none;
	}
}

/* ── Custom sort dropdown (sort/pills parity round, 2026-07-24) ────────────
   The OS-native open panel of the skinned <select> was rejected — this is the
   select2-look panel the legacy `.select2-container.sort_order` skin drew,
   rebuilt as a dependency-free button+listbox (cl-inventory.js). The native
   select stays in the DOM as the no-JS fallback; it is hidden only when the
   enhanced control is built (.cl-sortdd class added by JS). Values below are
   the exact legacy rules from the copied search-results-actions.css /
   app-select2.css skins (8px radius, 200px panel, 14px options, link-color
   \f00c check on the selected row, super-lowalpha hover). */
.cl-inventory .stm-select-sorting.cl-sortdd {
	position: relative;
	display: inline-block;
}
.cl-inventory .stm-select-sorting.cl-sortdd select[data-cl-sort] {
	display: none;
}
.cl-inventory .cl-sortdd__btn {
	-webkit-appearance: none;
	appearance: none;
	border: 0;
	background-color: transparent;
	position: relative;
	padding: 0 32px 0 0;
	/* Parity round 3 (2026-07-25, live legacy probe): Montserrat like the
	   select2 span inherited (see the native select rule above — same
	   !important reason: the child master font rule targets button). */
	font-family: var(--cl-font, Montserrat, sans-serif) !important;
	font-size: 13px;
	font-weight: 400;
	color: rgba(1, 1, 1, 0.8);
	cursor: pointer;
	line-height: 40px;
	height: 40px;
	white-space: nowrap;
}
/* Parity round 3: the legacy chevron is NOT an svg — it is the cl-icons
   \e9ff glyph at 14px (search-results-actions.css .select2-selection__arrow
   b::before), 15px box roughly centered in the 40px control, ~8px in from
   the right edge (legacy probe: glyph box [562,317,15,15] in a control
   ending at x585). The icon font is already loaded (mirrored icons.css). */
.cl-inventory .cl-sortdd__btn::after {
	content: "\e9ff";
	font-family: "cl-icons";
	font-size: 14px;
	font-weight: 400;
	position: absolute;
	right: 8px;
	/* Legacy probe: 15px glyph box at 12px from the control top ([562,317,15,15]
	   in a control at y305) — fixed offset, not a centered transform. */
	top: 12px;
	height: 15px;
	line-height: 15px;
	color: rgba(1, 1, 1, 0.8);
}
/* Open state: chevron flips, same as the legacy select2 arrow rotate. */
.cl-inventory .cl-sortdd--open .cl-sortdd__btn::after {
	transform: rotate(180deg);
}
.cl-inventory .cl-sortdd__btn:focus-visible {
	outline: 2px solid var(--cl-accent);
	outline-offset: 2px;
}
.cl-inventory .cl-sortdd__list {
	display: none;
	position: absolute;
	top: 100%;
	left: 0;
	z-index: 1051;               /* legacy select2 dropdown z-index */
	width: 200px;                /* .sort_order .select2-dropdown 200px !important */
	margin: 0;
	padding: 0;
	list-style: none;
	background-color: var(--cl-legacy-filter-bg-color, #ffffff);
	border: 1px solid var(--cl-legacy-border-color, rgba(1, 1, 1, 0.15));
	border-radius: 8px;
	max-height: 350px;           /* app-select2 options max-height */
	overflow-x: hidden;
	overflow-y: auto;
	outline: none;
}
.cl-inventory .cl-sortdd--open .cl-sortdd__list {
	display: block;
}
.cl-inventory .cl-sortdd__opt {
	position: relative;
	margin: 0;
	padding: 6px 6px 6px 14px;
	font-size: 14px;
	font-weight: 400;
	line-height: 21px;
	color: var(--cl-legacy-filter-field-text-color, #010101);
	background-color: var(--cl-legacy-filter-field-bg-color, #ffffff);
	cursor: pointer;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.cl-inventory .cl-sortdd__opt:first-child {
	border-radius: 8px 8px 0 0;
}
.cl-inventory .cl-sortdd__opt:last-child {
	border-radius: 0 0 8px 8px;
}
.cl-inventory .cl-sortdd__opt:hover,
.cl-inventory .cl-sortdd__opt.cl-active {
	/* Neutral light gray highlight (2026-07-24 review: no blue anywhere in
	   the panel — was the link-color super-lowalpha blue tint). */
	background-color: #f1f3f5;
}
/* Legacy `[aria-selected=true]` carried !important — the selected row stays
   white even while highlighted/hovered (see sort-panel-legacy captures). */
.cl-inventory .cl-sortdd__opt[aria-selected="true"]:hover,
.cl-inventory .cl-sortdd__opt[aria-selected="true"].cl-active {
	background-color: var(--cl-legacy-filter-field-bg-color, #ffffff);
}
/* Selected row: white with a near-black FA check (2026-07-24 review: the
   check follows the site text color, NOT the blue link color; FA6 face ships
   with the theme; FA5 name kept as fallback for sites still carrying the
   legacy face). */
.cl-inventory .cl-sortdd__opt[aria-selected="true"]::after {
	content: "\f00c";
	font-family: "Font Awesome 6 Free", "Font Awesome 5 Free";
	font-weight: 900;
	font-size: 16px;
	color: var(--cl-legacy-filter-field-text-color, #010101);
	position: absolute;
	right: 10px;
	top: 50%;
	transform: translateY(-50%);
}
@media (max-width: 767px) {
	/* Legacy mobile skin: the closed control becomes a white 6px-radius pill
	   (search-results-actions.css @767 select2 rule); the wrapper pill/chevron
	   come from the child inline styles exactly as for the native select. */
	.cl-inventory .cl-sortdd__btn {
		background-color: var(--cl-legacy-filter-field-bg-color, #ffffff);
		border-radius: 6px;
		background-image: none; /* wrapper draws the chevron on mobile */
		padding: 0 40px 0 32px;  /* legacy mobile rendered padding */
	}
	.cl-inventory .cl-sortdd--open .cl-sortdd__btn {
		background-image: none;
	}
}

/* Per-page select: same treatment (legacy showed a compact borderless "18 ⌄"). */
.cl-inventory .stm-inventory-items-per-page-wrap select,
.cl-inventory .stm_per_page select {
	-webkit-appearance: none;
	appearance: none;
	border: 1px solid #d9dde2;
	border-radius: 4px;
	background-color: #ffffff;
	padding: 2px 18px 2px 8px;
	font-weight: 700;
	color: #332c2b;
}

/* Chips row deleted (final filter directive 2026-07-24): no chosen-filter
   pills ever render above the results — active state is shown by the
   accent-filled option pills in the sidebar (ported legacy base.css
   `input:checked + .option-badge`), and the actions row keeps only the
   right-aligned Reset all link. */

/* ── SOLD badge (settings: inventory.sold_behavior = badge) ────────────── */
/* 2026-08-06 (owner ask): matched to the single listing's title flag. The badge
   fills with the brand color instead of the old near-black, and its label rides
   the Theme Editor "Button text color" setting like the rest of the filled
   controls do. The span carries its own color because the legacy card CSS
   paints label text at higher specificity than the wrapper. */
.cl-sold-label {
	background: var(--cl-red, #DD0000) !important;
	color: #ffffff;
}
.cl-sold-label span {
	color: #ffffff;
	text-transform: uppercase;
	letter-spacing: 0.04em;
}
.mvl-card-skins.cl-is-sold .image img {
	filter: grayscale(35%);
}

/* ── Call for Price ────────────────────────────────────────────────────── */
/* 2026-08-11 (owner: desktop grid — "Call for Price" overhangs the card
   edge): nowrap was fine when this box held "$11,999", but with the
   "Our Price: " label in front this is a five-word sentence, and at grid-card
   widths one forced line ran straight past the card border. The phrase itself
   stays unbreakable (span below); the only allowed break point is after the
   label, so a tight card reads "Our Price:" over "Call for Price" instead of
   overflowing. Wide list cards still fit on one line and look unchanged. */
.cl-call-for-price {
	white-space: normal;
	max-width: 100%;
	min-width: 0;
}
.cl-call-for-price .cl-cfp-text {
	white-space: nowrap;
}

/* ── Show all / hide all (long checkbox lists) ─────────────────────────── */
.cl-filter-form .stm-filter-pro-options-list label.stashed {
	display: none;
}
.cl-filter-form .stm-filter-item.cl-expanded .stm-filter-pro-options-list label.stashed {
	display: flex; /* parity round 2: legacy labels are flex (base.css) */
}
/* Parity round 2 (2026-07-24): typography/margins come from the legacy
   base.css (.stm-inventory-pro-filter-fields .show-all — 14px/500,
   margin 12px 0 2px, 24px plus sign); this block only handles the CL
   expanded-state toggling, using flex to match the legacy display mode. */
/* Parity round 3 (2026-07-25, measured): our show-all/show-less are real
   <button>s, and the button-chrome neutralizer at the top of this file sets
   margin:0 — overriding the legacy 12px/2px margins and making every stashed
   group 12px shorter than legacy (the show-all row then collided with the
   sticky Reset All footer in full-page renders). Restore the legacy margins
   at higher specificity than the reset. */
.cl-inventory .cl-filter-form button.show-all,
.cl-inventory .cl-filter-form button.show-less {
	margin: 12px 0 2px;
}
.cl-filter-form .show-less,
.cl-filter-form .stm-filter-item.cl-expanded .show-all {
	display: none !important;
}
.cl-filter-form .stm-filter-item.cl-expanded .show-less {
	display: flex !important;
}

/* ── Always-expanded groups (owner-approved improvement, 2026-07-24):
   Condition / Power Type / Seating / Location render EVERY option with no
   "Show all" collapse (.cl-always-expanded set in parts/archive-filters.php).
   The copied pro base.css display:none's label.disabled/.stashed — restore
   them here, keeping the greyed disabled look and blocking interaction on
   zero-count options. Spacing/typography untouched (same flex labels). ── */
.cl-filter-form .stm-filter-item.cl-always-expanded .stm-filter-pro-options-list label.disabled,
.cl-filter-form .stm-filter-item.cl-always-expanded .stm-filter-pro-options-list label.stashed {
	display: flex;
}
.cl-filter-form .stm-filter-item.cl-always-expanded .stm-filter-pro-options-list label.disabled {
	opacity: 0.45;
	pointer-events: none;
}

/* ── Year selects (native, styled close to the legacy select2 skin) ────── */
.cl-year-select {
	width: 100%;
	height: 42px;
	padding: 0 30px 0 12px;
	border: 1px solid #d9dde2;
	border-radius: 6px;
	background-color: #ffffff;
	background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23495057' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 12px center;
	font-size: 14px;
	color: #332c2b;
	-webkit-appearance: none;
	appearance: none;
}

/* ── Actions popup: open state without hover (touch / keyboard) ────────── */
.mvl-actions-popup.cl-open .mvl-actions-popup-content {
	display: block;
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
}
.cl-inventory .cl-share.cl-copied::after {
	content: " ✓";
}

/* ── Mobile filter drawer ──────────────────────────────────────────────── */
html.cl-no-scroll,
html.cl-no-scroll body {
	overflow: hidden; /* plain overflow:hidden — no clip */
}
@media (max-width: 1024px) {
	.cl-inventory .stm-inventory-pro-sidebar {
		display: none;
	}
	.cl-inventory.cl-filter-open .stm-inventory-pro-sidebar {
		display: block;
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		z-index: 100000;
		background: #ffffff;
		overflow-y: auto;
		-webkit-overflow-scrolling: touch;
		padding: 0 16px 32px;
	}
	/* Pro CSS parks .stm-inventory-pro-filter off-canvas on mobile waiting for
	   the legacy JS (removed on this page) to slide it in — pin it back. */
	.cl-inventory.cl-filter-open .stm-inventory-pro-filter {
		position: static !important;
		left: auto !important;
		right: auto !important;
		top: auto !important;
		bottom: auto !important;
		transform: none !important;
		width: 100% !important;
		max-width: none !important;
		height: auto !important;
		margin: 0 !important;
		display: block !important;
		visibility: visible !important;
		opacity: 1 !important;
	}
	.cl-inventory.cl-filter-open .stm-inventory-pro-filter-mobile-header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		position: sticky;
		top: 0;
		background: #ffffff;
		z-index: 2;
		padding: 14px 0;
		border-bottom: 1px solid #e2e6ea;
		margin-bottom: 12px;
	}
	/* [LD] 2026-07-31 (QA G-04): this was locked to 24x24, which is the size of
	   the drawn X and not a size a thumb can hit. The button is now 44x44 and
	   the X is drawn at its old 18px across, centred, so the icon looks exactly
	   as it did and only the target grew. The strokes are sized explicitly
	   rather than inset from the edges, because insets tie the icon to the
	   button and that is what made this hard to fix in the first place. */
	.cl-inventory.cl-filter-open .filter-close {
		width: 44px !important;
		min-width: 44px;
		max-width: 44px;
		height: 44px !important;
		flex: 0 0 44px;
		position: relative;
		border: 0 !important;
		background: none !important;
	}
	.cl-inventory.cl-filter-open .filter-close::before,
	.cl-inventory.cl-filter-open .filter-close::after {
		content: "";
		position: absolute;
		left: 50%;
		top: 50%;
		width: 18px;
		margin-left: -9px;
		height: 2px;
		background: #332c2b;
	}
	.cl-inventory.cl-filter-open .filter-close::before {
		transform: rotate(45deg);
	}
	.cl-inventory.cl-filter-open .filter-close::after {
		transform: rotate(-45deg);
	}
	.cl-inventory.cl-filter-open .filter-reset {
		color: var(--cl-accent);
		font-weight: 600;
	}
}

/* ── Pagination: mobile "Page X of Y" without :has() ───────────────────── */
.cl-pagination .mgc-pg-mobile {
	display: none;
}
@media (max-width: 600px) {
	.cl-pagination {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 14px;
	}
	.cl-pagination ul.page-numbers {
		display: contents;
	}
	.cl-pagination ul.page-numbers li {
		display: none;
	}
	.cl-pagination ul.page-numbers li.cl-pg-prev {
		display: block;
		order: 1;
	}
	.cl-pagination ul.page-numbers li.cl-pg-next {
		display: block;
		order: 3;
	}
	.cl-pagination .mgc-pg-mobile {
		display: block;
		order: 2;
		font-size: 15px;
		font-weight: 700;
		color: #332c2b;
		white-space: nowrap;
	}
}

/* ── Empty results icon spacing tweak (component CSS is re-enqueued) ───── */
.cl-inventory .stm-listings-empty {
	padding: 40px 0;
}

/* ── Mobile 4:3 listing-card image ratio (2026-07-24 [ENG2] platform
   consolidation — moved here from mu-plugins/mgc-inventory-image-ratio.php;
   pages without this stylesheet get the same rules inline from
   cl-engine/media/uploads.php). Motors pins card photos to a 200px landscape
   strip on phones, beheading portrait cart photos — this gives the image area
   a 4:3 ratio box that scales with card width instead. ───────────────────── */
@media (max-width: 767px) {
	.stm-directory-grid-loop .image .image-inner,
	.mvl-card-skins .image .image-inner {
		height: auto !important;
		aspect-ratio: 4/3 !important;
	}
	.stm-directory-grid-loop .image .image-inner .interactive-hoverable,
	.stm-directory-grid-loop .image .image-inner .hoverable-wrap,
	.stm-directory-grid-loop .image .image-inner .hoverable-unit,
	.stm-directory-grid-loop .image .image-inner .thumb,
	.stm-directory-grid-loop .image .image-inner > a,
	.mvl-card-skins .image .image-inner .interactive-hoverable,
	.mvl-card-skins .image .image-inner .hoverable-wrap,
	.mvl-card-skins .image .image-inner .hoverable-unit,
	.mvl-card-skins .image .image-inner .thumb,
	.mvl-card-skins .image .image-inner > a {
		height: 100% !important;
	}
	.stm-directory-grid-loop .image .image-inner img,
	.mvl-card-skins .image .image-inner img {
		height: 100% !important;
		width: 100% !important;
		object-fit: cover !important;
	}
}

/* Parity round 2 (2026-07-24): on phones legacy keeps the (emptied) sidebar
   wrapper in flow — its padding leaves a 30px block between the per-page row
   and the footer. The CL drawer removes the sidebar from flow entirely, so
   reproduce that spacing on the per-page row. */
@media (max-width: 1024px) {
	.cl-inventory .stm-inventory-items-per-page-wrap {
		margin-bottom: 30px;
	}
}

/* ── List-card image column: full card height in pure CSS (card-fix,
   2026-07-24). Problem: the ported legacy list skin pins .image-inner at
   260px; when the content column runs taller (long title, sale+savings,
   promo, sold badge) the photo stopped 30-40px short of the card bottom, and
   the child theme's window-load JS (mgc-inventory-resize-fix.js, now
   dequeued on this page — see cl-engine/inventory/frontend.php) re-measured
   the card and wrote inline heights AFTER first paint — the visible "image
   comes down" jump. Fix: the card row already lays out with flexbox
   (loop-list.css); stretch both columns and paint the media ABSOLUTELY
   inside the (position:relative) .image box so the photo can never
   contribute intrinsic height (a width:100% placeholder img would otherwise
   inflate the row beyond the legacy 264px card) and always fills the column
   from the very first paint. No JS, no listeners, CLS 0. The 1/N photo chip
   (absolute bottom-left) and the hoverable progress strip (absolute
   bottom:0) already overlay the image box and simply follow its height.
   Desktop only: below 768px the card stacks and the existing 4:3
   aspect-ratio block above reserves the image box. No :has()/color-mix()/
   overflow:clip. ─────────────────────────────────────────────────────── */
@media (min-width: 768px) {
	/* Reproduce the exact legacy final geometry. Parity round 3 (2026-07-25):
	   steady-state card-pitch measurement against the live legacy render
	   (18 placeholder cards, 1440px) showed EVERY legacy list card lands
	   exactly 2px taller than the round-2 constants — pitch 282/314 vs our
	   280/312 (the legacy JS's border-box-into-content-box overshoot applies
	   one more time than round 2 accounted for). Empirical legacy geometry:
	   card = max(content-height + 6px, 266px). The content column's 4px
	   bottom margin supplies the +4 inside the 1px borders; the floor is
	   266px. With these two constants the per-card pitch matches legacy
	   exactly (282px standard, 314px sale/savings). */
	.cl-inventory .mvl-list-card-skin.skin_1.listing-list-loop {
		min-height: 266px;
	}
	.cl-inventory .mvl-list-card-skin.skin_1 .mvl-list-content {
		margin-bottom: 4px;
	}
	.cl-inventory .mvl-list-card-skin.skin_1 .skin-list-gallery {
		align-self: stretch;
	}
	/* The media column box: full column height, min 260px exactly like the
	   legacy minimum card height; loop-list already sets position:relative. */
	.cl-inventory .mvl-list-card-skin.skin_1 .skin-list-gallery .skin_1.image {
		height: 100%;
		min-height: 260px;
		margin-bottom: 0; /* loop-list's 20px bottom margin would overflow a full-height column */
	}
	/* Absolute fill: the media never adds intrinsic height (no feedback into
	   the row height — the content column alone sets it, as legacy did), and
	   it is full-bleed from first paint. The !important also outranks any
	   stray element.style height a cached copy of the old JS might write. */
	.cl-inventory .mvl-list-card-skin.skin_1 .skin-list-gallery .skin_1.image .image-inner {
		position: absolute;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		height: auto !important;
	}
	.cl-inventory .mvl-list-card-skin.skin_1 .skin-list-gallery .skin_1.image .image-inner .interactive-hoverable {
		height: 100%;
		min-height: 0;
	}
	/* Placeholder (no-photo) card: the bare img fills the same box. */
	.cl-inventory .mvl-list-card-skin.skin_1 .skin-list-gallery .skin_1.image .image-inner > img.img-responsive {
		width: 100%;
		height: 100%;
		object-fit: cover;
	}
}

/* ── Option availability (filters-final2, 2026-07-24) ──────────────────────
   Options with no remaining listings in the current filtered set are hidden
   outright (factory-direct behavior — never greyed placeholders), and a group
   whose every option is hidden collapses entirely, heading included. Applied
   server-side on first paint (unavailable options are not rendered at all)
   and by cl-inventory.js after every AJAX response (labels/groups toggle
   these classes as availability changes). Plain display:none — no :has(). */
.cl-filter-form .stm-filter-pro-options-list label.cl-unavailable {
	display: none !important;
}
.cl-filter-form .stm-filter-item.cl-group-empty {
	display: none !important;
}

/* ═══════════════════════════════════════════════════════════════════
   APPLIED-FILTER CHIP ROW (2026-07-31, owner: "add back the inventory
   filters up at the top with the black pill").

   Supersedes the 2026-07-29 treatment, which pulled this row OUT of flow
   (position:absolute, tags cloud collapsed to nothing) to answer "when I
   use the filters it creates a gap on the top of the listings… I want
   the inventory to remain stationary". That approach is no longer
   available: the row now carries chips, and chips floated over the H1
   would sit on top of the heading text.

   2026-07-31 (owner, second pass): reserving the row's height permanently
   was the wrong trade. With no filters applied it left a tall empty band
   between the "Golf Carts for Sale" heading and the sort bar on every
   single visit, which is what a shopper sees FIRST and almost always
   sees — the owner sent a side by side against the live site, where the
   sort bar sits directly under the heading, and said "it just stays with
   a big gap". Paying that cost on 100% of page views to avoid a one time
   shift on the minority of visits that filter is backwards.

   So the row now collapses to nothing when it is empty and takes its
   natural height when chips are present, exactly like the live site. The
   original stationary complaint was about a gap that opened ABOVE the
   listings and stayed open; a row that grows to hold the chips a shopper
   just chose is different — it is the direct, expected result of their
   own click, and the live reference site behaves the same way.

   Reset all still uses visibility rather than display so it cannot change
   the row's height on its own once the row is showing.
   ═══════════════════════════════════════════════════════════════════ */
.stm-inventory-pro .search-results-actions,
.search-results-actions {
	position: relative;
}
.search-results-actions .search-results-actions-result {
	/* Two classes deep, so this also beats the legacy
	   `@media (max-width:767px) { .search-results-actions-result{display:none} }`
	   without an !important. Keeping the chips on mobile is intentional: the
	   sidebar that shows selected state is a CLOSED DRAWER on a phone, so the
	   chips are the only visible evidence of what is currently applied. */
	display: flex;
	align-items: center;
	gap: 12px;
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	width: auto;
}
/* Empty state: out of the flow entirely, so the sort bar sits directly under
   the heading. min-height:0 was not enough on its own — the hidden Reset all
   link still contributed its own line box and left a 31px band behind.
   cl-has-filters is set server-side on first paint and by cl-inventory.js
   after every AJAX response, so this tracks the real chip count. */
.search-results-actions .search-results-actions-result:not(.cl-has-filters) {
	display: none;
}
.search-results-actions .search-results-actions-result.cl-has-filters {
	min-height: 40px;
	margin-bottom: 12px;
}
.search-results-actions .search-results-actions-result .search-results-actions-tags-cloud {
	flex: 1 1 auto;
	min-width: 0;
}
.search-results-actions .search-results-actions-result .stm-filter-chosen-units {
	margin: 0;
}
.search-results-actions .search-results-actions-result .stm-filter-chosen-units-list {
	/* Wrap rather than overflow: a shopper stacking five makes plus a price
	   band would otherwise push Reset all off the right edge. */
	flex-wrap: wrap;
}
.search-results-actions .search-results-actions-result .search-results-actions-btn-wrapp {
	flex: 0 0 auto;
	visibility: hidden;
}
.search-results-actions .search-results-actions-result.cl-has-filters .search-results-actions-btn-wrapp {
	visibility: visible;
}
.search-results-actions .search-results-actions-result .search-results-actions-reset-all {
	margin: 0 !important;
	padding: 0 !important;
}
/* The chip IS the <li>. The <button> inside it exists only so the × is
   reachable by keyboard and announced to a screen reader, and must not paint
   anything of its own. The legacy pill rules target
   `li .stm-filter-chosen-units-list-value` and `li i` as DESCENDANTS, so they
   still reach through this wrapper untouched. */
.search-results-actions .stm-filter-chosen-units-list li .cl-chosen-badge__btn {
	display: inline-flex;
	align-items: center;
	background: none !important;
	border: 0 !important;
	box-shadow: none !important;
	padding: 0 !important;
	margin: 0 !important;
	min-height: 0;
	height: auto;
	width: auto;
	color: inherit;
	font: inherit;
	line-height: inherit;
	text-transform: none;
	cursor: pointer;
}
.search-results-actions .stm-filter-chosen-units-list li .cl-chosen-badge__btn:focus-visible {
	/* White ring: the pill it sits on is near-black, so the usual dark focus
	   ring would be invisible exactly where it is needed. */
	outline: 2px solid #fff;
	outline-offset: 2px;
}

/* Mobile filter drawer (2026-07-29, owner): the drawer header already has
   its own sticky Reset All (top, .stm-inventory-pro-filter-mobile-header),
   so the legacy sticky bottom footer duplicated it. Hide the bottom one
   below the 1024px drawer breakpoint; desktop sidebar keeps it. */
@media (max-width: 1023px) {
	.stm-inventory-pro-filter .stm-inventory-pro-filter-footer {
		display: none !important;
	}
}

/* Card image off-center fix (2026-07-29, owner: "images are off centered on
   mobile"). The legacy list skin fixes .interactive-hoverable at width:380px
   (the DESKTOP image-column width) and un-caps its img max-width. On mobile
   the card is ~312px wide, so every image painted 380px and clipped 68px off
   its right side — placeholders AND real photos rendered left-shifted. Make
   the hoverable fluid and center-crop the img with object-fit; on desktop
   the column is exactly 380px anyway, so 100% is pixel-identical there. */
.mvl-list-card-skin.skin_1 .skin-list-gallery .skin_1.image .image-inner .interactive-hoverable {
	width: 100%;
	height: 100%;
	min-height: 0;
}
.mvl-list-card-skin.skin_1 .skin-list-gallery .skin_1.image .image-inner .interactive-hoverable .hoverable-wrap,
.mvl-list-card-skin.skin_1 .skin-list-gallery .skin_1.image .image-inner .interactive-hoverable .hoverable-unit,
.mvl-list-card-skin.skin_1 .skin-list-gallery .skin_1.image .image-inner .interactive-hoverable .hoverable-unit .thumb {
	height: 100%;
}
.mvl-list-card-skin.skin_1 .skin-list-gallery .skin_1.image .image-inner .interactive-hoverable img {
	width: 100%;
	height: 100%;
	max-width: 100%;
	object-fit: cover;
}

/* Call Now card CTA (2026-07-29, owner: "for conversions"). Mobile-only:
   under 769px the action row becomes a side-by-side pair — Call Now as the
   outlined secondary, Get My Quote keeping the solid red primary. Desktop
   is unchanged (call paths live in the actions popup there). */
/* Call Now card CTA (2026-07-29, owner: "for conversions"), take 2 after
   the cascade fight: assets/css/mgc-listing-price.css paints every list-card
   action button solid red at 0,5,1 (a.mvl-action-button:link/:visited) with
   min-width:100% !important, and it PRINTS AFTER this sheet — so these rules
   run at 0,6,1 (tripled class) and the red rule itself now carries
   :not(.mgc-card-call). Mobile only: side-by-side pair, Call Now outlined,
   Get My Quote stays the solid red primary. Desktop unchanged (call paths
   live in the actions popup there). */
.mvl-list-card-skin .mvl-action-buttons .mvl-action-buttons-inner a.mgc-card-call.mgc-card-call.mgc-card-call {
	display: none !important;
}
@media (max-width: 768px) {
	/* Stacked (2026-07-29, owner: side-by-side wrapped both labels and "doesn't
	   really look very good — can you stack them instead?"). Get My Quote stays
	   on top as the primary, Call Now full-width beneath it. */
	.mvl-list-card-skin .mvl-action-buttons .mvl-action-buttons-inner {
		display: flex !important;
		flex-direction: column !important;
		gap: 10px;
	}
	/* 0,7,1: the price-css red rule gained a class of specificity from its
	   :not(.mgc-card-call) guard (0,6,1) and prints after this sheet, so the
	   sizing pair sits one level above it. */
	.mvl-list-card-skin .mvl-action-buttons .mvl-action-buttons-inner a.mgc-card-call.mgc-card-call.mgc-card-call.mgc-card-call,
	.mvl-list-card-skin .mvl-action-buttons .mvl-action-buttons-inner a.mgc-quote-link.mgc-quote-link.mgc-quote-link.mgc-quote-link {
		flex: 0 0 auto !important;
		width: 100% !important;
		min-width: 0 !important;
		margin: 0 !important;
	}
	.mvl-list-card-skin .mvl-action-buttons .mvl-action-buttons-inner a.mgc-quote-link.mgc-quote-link.mgc-quote-link.mgc-quote-link {
		order: 1;
	}
	.mvl-list-card-skin .mvl-action-buttons .mvl-action-buttons-inner a.mgc-card-call.mgc-card-call.mgc-card-call.mgc-card-call {
		order: 2;
	}
	.mvl-list-card-skin .mvl-action-buttons .mvl-action-buttons-inner a.mgc-card-call.mgc-card-call.mgc-card-call {
		display: inline-flex !important;
		align-items: center;
		justify-content: center;
		gap: 8px;
		padding: 14px 10px !important;
		background: #fff !important;
		color: var(--cl-red, #DD0000) !important;
		border: 2px solid var(--cl-red, #DD0000) !important;
		border-radius: 4px !important;
		box-shadow: none !important;
		text-decoration: none !important;
		/* Same face as Get My Quote: the theme's font pass puts the SITE
		   display font (var(--cl-font)) on .mgc-quote-link, overriding the
		   price-css Montserrat — so the pair must read --cl-font too
		   (2026-07-29, owner: "the fonts dont match"). */
		font-family: var(--cl-font, 'Montserrat', sans-serif) !important;
		font-weight: 800 !important;
		font-size: 15px !important;
		text-transform: uppercase !important;
		letter-spacing: 0.5px;
	}
	.mvl-list-card-skin .mvl-action-buttons .mvl-action-buttons-inner a.mgc-card-call.mgc-card-call.mgc-card-call:hover {
		background: #fdeaea !important;
		color: var(--cl-red, #DD0000) !important;
	}
	.mvl-list-card-skin .mvl-action-buttons .mvl-action-buttons-inner a.mgc-card-call.mgc-card-call.mgc-card-call .label {
		color: var(--cl-red, #DD0000) !important;
		font-weight: 800 !important;
		/* Match Get My Quote's label: the theme font pass puts the SITE font
		   on the quote label; a Montserrat pass was catching this one
		   (2026-07-29, owner: "the fonts dont match"). */
		font-family: var(--cl-font, 'Montserrat', sans-serif) !important;
	}
	.mvl-list-card-skin .mvl-action-buttons .mvl-action-buttons-inner a.mgc-card-call.mgc-card-call.mgc-card-call svg {
		width: 16px;
		height: 16px;
		flex: 0 0 auto;
	}
}

/* ── GRID-view Call Now (bug fix 2026-07-29) ──────────────────────────────────
   The Call Now setting only ever rendered on LIST cards; grid cards — the
   default view and what mobile visitors see — showed nothing. The grid button
   is a .mvl-view-listing row under Get My Quote. Same contract as the list
   pair: desktop hidden (call paths live in the actions popup there), mobile
   an OUTLINED white/red secondary so the solid red quote stays the primary.
   Specificity: mgc-listing-price.css paints every
   `.mvl-view-listing a.mvl_view_listing_link` solid red at (0,2,1)!important
   and prints AFTER this sheet, so these rules stack .mgc-card-call to (0,5,1)
   to win regardless of order. */
.mvl-view-listing a.mvl_view_listing_link.mgc-card-call.mgc-card-call.mgc-card-call {
	display: none !important;
}
@media (max-width: 768px) {
	.mvl-view-listing a.mvl_view_listing_link.mgc-card-call.mgc-card-call.mgc-card-call {
		display: flex !important;
		align-items: center;
		justify-content: center;
		gap: 8px;
		padding: 14px 10px !important;
		background: #fff !important;
		background-color: #fff !important;
		color: var(--cl-red, #DD0000) !important;
		border: 2px solid var(--cl-red, #DD0000) !important;
		border-radius: 4px !important;
	}
	.mvl-view-listing a.mvl_view_listing_link.mgc-card-call.mgc-card-call.mgc-card-call:hover {
		background: #fdeaea !important;
		background-color: #fdeaea !important;
		color: var(--cl-red, #DD0000) !important;
	}
	.mvl-view-listing a.mvl_view_listing_link.mgc-card-call.mgc-card-call.mgc-card-call .label {
		color: var(--cl-red, #DD0000) !important;
		font-weight: 800 !important;
		/* Same font contract as the list-view button (owner: "the fonts dont
		   match"): the site font variable, never a stray Montserrat pass. */
		font-family: var(--cl-font, 'Montserrat', sans-serif) !important;
	}
	.mvl-view-listing a.mvl_view_listing_link.mgc-card-call.mgc-card-call.mgc-card-call svg {
		width: 16px;
		height: 16px;
		flex: 0 0 auto;
	}
	/* Tighten the stack: quote row directly above gets a small gap. */
	.mgc-card-call-row {
		margin-top: 8px !important;
	}
}

/* ─────────────────────────────────────────────────────────────────────────────
   CARD PHOTO: SWIPE AFFORDANCE (2026-08-14)

   Owner: "I just dont know that people will know to swipe on mobile ... The
   little line is tiny." He is right, and the reason is measurable: the legacy
   indicator is a 3px bar pinned to the bottom edge of the photo. At that size
   it reads as a decorative underline, not as "there are more photos". The
   "1/13" badge already tells a shopper more photos exist; what was missing was
   any hint of how to reach them — and this audience is not one to rely on
   swipe being assumed knowledge.

   Two changes, both owner-specified: thicken the bar rather than replace it
   with dots, and add arrows ONLY where they are needed. A pointer device
   already scrubs the frames on hover, so the arrows are hidden there.
   ──────────────────────────────────────────────────────────────────────────── */

/* 3px -> 5px. The legacy sheet (assets/legacy/.../hoverable-gallery.css) is a
   verbatim vendor copy and is never edited, so the height is overridden here.
   Both the track and each segment have to move or the segments float inside a
   taller track. */
/* Anchored to .interactive-hoverable, NOT to the legacy sheet's
   .stm-hoverable-interactive-galleries wrapper — that class is not in the
   ancestor chain of a v2 card (verified: indicators > interactive-hoverable >
   image-inner > skin_1 image > skin-list-gallery > mvl-card-skins), so copying
   the legacy selector matched nothing. !important because the legacy sheet is
   enqueued after this one and carries one more class. */
body .interactive-hoverable .hoverable-indicators,
body .interactive-hoverable .hoverable-indicators .indicator {
	height: 5px !important;
}

/* Arrows — touch only. */
.cl-card-arrow {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	/* 44px is the accessibility floor for a touch target, and the reason the
	   button is bigger than the circle you see: the visual disc is drawn by the
	   inner span's background, so the tap area stays generous without a heavy
	   blob sitting over the photo. */
	width: 44px;
	height: 44px;
	padding: 0;
	border: 0;
	background: none;
	display: flex;
	align-items: center;
	justify-content: center;
	z-index: 26; /* above .hoverable-indicators (25) */
	cursor: pointer;
	-webkit-tap-highlight-color: transparent;
}
.cl-card-arrow--prev { left: 0; }
.cl-card-arrow--next { right: 0; }
.cl-card-arrow > span {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	border-radius: 50%;
	background: rgba(17, 24, 39, 0.55);
	color: #ffffff;
	font-size: 15px;
	line-height: 1;
	/* The photo behind can be light or dark; the ring keeps the disc readable
	   on both without needing a per-image treatment. */
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
}
.cl-card-arrow:active > span {
	background: rgba(17, 24, 39, 0.75);
}

/* A device with a real pointer scrubs frames on hover and does not need these.
   Same test the card script uses to decide hover vs swipe, so the arrows can
   never appear on a device whose gallery is hover-driven. */
@media (hover: hover) and (pointer: fine) {
	.cl-card-arrow { display: none; }
}
