/* Surf7 Simple Catalog — Frontend styles (minimal scaffolding).
 * Theme overrides via themes/{theme}/simple-catalog/ are preferred.
 * Uses CSS custom properties from WP head (--scat-accent, --scat-cols-*, etc.)
 */

/* Core container & grid ==================================================== */
.scat,
.scat * {
	box-sizing: border-box;
}
/* How wide catalogue content runs. The value comes from Settings > Display >
   Layout > Content width, emitted as --scat-content-width by Assets.php; the
   fallback here is what applies if that block is ever absent. Deliberately NOT
   declared on :root in this file — the inline block must always win, and which
   of two :root declarations wins would depend on the order the stylesheet and
   the inline block happen to be printed in. */
.scat-container {
	max-width: var(--scat-content-width, 1200px);
	margin: 0 auto;
	padding: 0 16px;
}

/* The archive and taxonomy templates never had a container at all: their root
   was .scat-archive / .scat-taxonomy with no max-width and no padding, so the
   catalogue ran edge to edge while the single product page — whose sections DO
   use .scat-container — sat neatly inside. The theme cannot correct this,
   because these templates render outside its row markup. */
.scat-archive,
.scat-taxonomy {
	max-width: var(--scat-content-width, 1200px);
	margin-left: auto;
	margin-right: auto;
	padding-left: 16px;
	padding-right: 16px;
	/* PADDING, not a margin on the header inside. The container has no border or
	   top padding of its own, so a margin on its first child collapses straight
	   through it and out of the box — measurably: root-top to title-top was 0px
	   and the heading still sat flush under the site nav. Padding cannot
	   collapse, so the space is always inside the archive. */
	padding-top: clamp(24px, 4vw, 48px);
	padding-bottom: 32px;
}

/* Archive headers had no styling whatsoever, so the title sat flush against
   whatever the theme put above it. One rule covers the catalogue, category,
   label and brand archives, which all use this markup. */
.scat-archive__header {
	margin: 0 0 24px;
}

.scat-archive__title {
	margin: 0 0 8px;
	line-height: 1.2;
}

.scat-archive__description {
	color: #475569;
	line-height: 1.7;
	max-width: 70ch;
}

.scat-archive__description p:last-child {
	margin-bottom: 0;
}

/* Category archive image, above the category name. Capped rather than full
   bleed: it is an identifying mark, not a hero banner, and a tall portrait
   upload would otherwise push the products below the fold. */
.scat-category-archive__image {
	margin-bottom: 14px;
}

.scat-category-archive__img {
	display: block;
	max-width: 100%;
	max-height: 220px;
	width: auto;
	height: auto;
	border-radius: 12px;
	object-fit: cover;
}

/* Brand archive logo, above the brand name. */
.scat-brand-archive__logo-wrap {
	margin-bottom: 12px;
}

.scat-brand-archive__website {
	margin: 10px 0 0;
	font-size: 14px;
}

.scat-brand-archive__website a {
	color: var(--scat-accent);
	text-decoration: none;
	font-weight: 600;
}

.scat-brand-archive__website a:hover,
.scat-brand-archive__website a:focus-visible {
	text-decoration: underline;
}

/* Marks the link as leaving the site, so it is not mistaken for another
   catalogue page. */
.scat-brand-archive__website a::after {
	content: " ↗";
	font-weight: 400;
}

.scat-brand-archive__logo {
	max-width: 160px;
	max-height: 80px;
	width: auto;
	height: auto;
	object-fit: contain;
}
.scat-grid {
	display: grid;
	gap: 24px;
	grid-template-columns: repeat(var(--scat-cols-mobile, 2), minmax(0, 1fr));
}
@media (min-width: 720px) {
	.scat-grid {
		grid-template-columns: repeat(var(--scat-cols-tablet, 3), minmax(0, 1fr));
	}
}
@media (min-width: 1024px) {
	.scat-grid {
		grid-template-columns: repeat(var(--scat-cols-desktop, 4), minmax(0, 1fr));
	}
}
.scat-cols-1 { --scat-cols-desktop: 1; }
.scat-cols-2 { --scat-cols-desktop: 2; }
.scat-cols-3 { --scat-cols-desktop: 3; }
.scat-cols-4 { --scat-cols-desktop: 4; }
.scat-cols-5 { --scat-cols-desktop: 5; }
.scat-cols-6 { --scat-cols-desktop: 6; }

/* Settings > Display: "Archive layout" ------------------------------------
   The setting has always written .scat-grid--grid / --list / --masonry onto
   the wrapper, and no rule for any of the three existed — so all three
   rendered as the plain grid above and the control did nothing. Grid is that
   default; the other two are defined here.

   LIST: one card per row, image beside the text. */
.scat-grid--list {
	display: flex;
	flex-direction: column;
	gap: 16px;
}
@media (min-width: 720px) {
	.scat-grid--list .scat-card {
		flex-direction: row;
		align-items: stretch;
	}
	.scat-grid--list .scat-card__media {
		flex: 0 0 clamp(160px, 26%, 280px);
		/* The card ratio still applies, but height is driven by the row, so the
		   media must be allowed to fill it rather than impose its own box. */
		aspect-ratio: auto;
		min-height: 100%;
	}
	.scat-grid--list .scat-card__body {
		justify-content: center;
	}
	/* margin-top:auto pushes the price to the bottom of a tall column, which in
	   a row just strands it below the text. */
	.scat-grid--list .scat-card__price {
		margin-top: 4px;
	}
}

/* MASONRY: CSS columns rather than grid, so cards of unequal height stagger
   instead of leaving the gaps a row-aligned grid forces. Cards must not be
   split across a column break. */
.scat-grid--masonry {
	display: block;
	column-count: var(--scat-cols-mobile, 2);
	column-gap: 24px;
}
@media (min-width: 720px) {
	.scat-grid--masonry { column-count: var(--scat-cols-tablet, 3); }
}
@media (min-width: 1024px) {
	.scat-grid--masonry { column-count: var(--scat-cols-desktop, 4); }
}
.scat-grid--masonry .scat-card {
	break-inside: avoid;
	/* Chrome still breaks inside a flex child without this pair. */
	page-break-inside: avoid;
	display: inline-flex;
	width: 100%;
	margin-bottom: 24px;
}

/* Product card ============================================================= */
.scat-card {
	position: relative;
	display: flex;
	flex-direction: column;
	background: #fff;
	border: 1px solid #e5e7eb;
	border-radius: 12px;
	overflow: hidden;
	transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
	color: inherit;
	text-decoration: none;
}
.scat-card:hover {
	transform: translateY(-2px);
	box-shadow: 0 10px 25px rgba(15, 23, 42, .08);
	border-color: #cbd5e1;
}
.scat-card__media {
	position: relative;
	/* Set from the "Card image aspect ratio" setting; see Assets.php. */
	aspect-ratio: var(--scat-card-ratio, 4 / 3);
	background: #f8fafc;
	overflow: hidden;
	display: block;
}
.scat-card__img {
	width: 100%;
	height: 100%;
	object-fit: var(--scat-card-fit, cover);
	transition: transform .25s ease;
}
.scat-card:hover .scat-card__img { transform: scale(1.03); }
.scat-card__placeholder {
	position: absolute; inset: 0;
	display: grid; place-items: center;
	color: #94a3b8; font-size: 14px;
}
.scat-card__badges {
	position: absolute;
	top: 10px; left: 10px;
	display: flex; flex-wrap: wrap; gap: 6px;
}
.scat-badge {
	display: inline-flex; align-items: center;
	padding: 3px 8px; border-radius: 999px;
	font-size: 11px; line-height: 1;
	background: rgba(15,118,110,.95); color: #fff;
}
.scat-badge--featured { background: #f59e0b; color: #111827; }
/* The card emits TWO classes — `scat-badge--avail scat-badge--sold` — but these
   rules used to target a single class named `scat-badge--avail--sold`, which no
   element ever carries. So the three badge colour settings never reached the
   frontend at all and every availability badge fell back to the base teal. */
.scat-badge--sold        { background: var(--scat-sold, #b91c1c); color: #fff; }
.scat-badge--reserved    { background: var(--scat-reserved, #d97706); color: #fff; }
.scat-badge--coming_soon { background: var(--scat-coming, #2563eb); color: #fff; }
.scat-badge--custom { background: var(--scat-accent); color: var(--scat-accent-contrast, #fff); }

.scat-card__body { padding: 14px 16px 16px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.scat-card__code { font-size: 11px; letter-spacing: .05em; color: #64748b; text-transform: uppercase; }
.scat-card__title { margin: 0; font-size: 16px; line-height: 1.3; color: #0f172a; }
.scat-card__price { font-size: 18px; font-weight: 700; color: #0f172a; margin-top: auto; }
.scat-card__price--empty { visibility: hidden; }
.scat-card__price--request { color: var(--scat-accent); font-size: 14px; font-weight: 600; }
.scat-card__price-sep { color: #94a3b8; margin: 0 4px; }
.scat-card__actions { padding: 12px 16px; border-top: 1px solid #f1f5f9; display: flex; gap: 8px; }

.scat-card--sold { opacity: .85; }
/* No strike-through on a sold title. The Sold badge already says it, and
   striking the name reads as "this product is wrong" rather than "unavailable".
   The dimmed card above is the whole treatment. */

/* Labels / chips =========================================================== */
.scat-label-row { display: flex; flex-wrap: wrap; gap: 6px; }
.scat-label-row--sm .scat-label { font-size: 10px; padding: 2px 6px; }
.scat-label {
	--c: var(--scat-accent);
	display: inline-flex; align-items: center;
	border-radius: 999px;
	padding: 3px 9px;
	font-size: 12px; line-height: 1.5;
	color: #fff;
	background: var(--c, #0ea5e9);
}
/* A label pill is a link on the single product page (it points at the label
   archive) and a plain span on the card, where the whole card is already an
   anchor. Themes style links heavily — Divi reaches these with selectors like
   `#main-content a` — so the doubled class raises specificity enough to keep the
   pill looking the same either way. */
a.scat-label,
.scat-label-row a.scat-label.scat-label {
	color: #fff;
	text-decoration: none;
}

.scat-label-row a.scat-label.scat-label:hover {
	color: #fff;
	opacity: .88;
}

.scat-options-badge {
	align-self: flex-start;
	background: #f1f5f9; color: #334155;
	padding: 2px 8px; border-radius: 6px;
	font-size: 11px;
}

/* Buttons ================================================================== */
.scat-btn {
	--bg: #0f172a;
	--fg: #fff;
	display: inline-flex; align-items: center; justify-content: center; gap: 6px;
	padding: 10px 16px; border-radius: 10px;
	background: var(--bg); color: var(--fg);
	text-decoration: none; border: 1px solid transparent;
	/* A <button> does NOT inherit font-family or letter-spacing — it falls back to
	   the UA's default (Arial here) while the sibling <a> elements pick up the
	   theme's face. Email in "form" mode is a real button (it opens the inline
	   form rather than navigating), so without this it was the one odd-looking
	   button in the row. box-sizing is pinned for the same reason: themes that
	   set content-box globally reach the anchors but not the button. */
	font-family: inherit; letter-spacing: inherit; box-sizing: border-box;
	-webkit-appearance: none; appearance: none;
	font-size: 14px; font-weight: 600; line-height: 1.2;
	cursor: pointer; transition: transform .1s ease, background .15s ease, color .15s ease, border-color .15s ease;
}
.scat-btn:hover { opacity: .92; }
.scat-btn:active { transform: translateY(1px); }
.scat-btn--sm { padding: 6px 10px; font-size: 12px; border-radius: 8px; }
.scat-btn--primary { --bg: var(--scat-accent); --fg: var(--scat-accent-contrast, #fff); }
.scat-btn--ghost { --bg: transparent; --fg: var(--scat-accent); border-color: currentColor; }
.scat-btn--wa       { --bg: #25D366; --fg: #fff; }
.scat-btn--email    { --bg: #3b82f6; --fg: #fff; }
.scat-btn--phone    { --bg: #0891b2; --fg: #fff; }
.scat-btn--telegram { --bg: #229ed9; --fg: #fff; }
.scat-btn--enquiry,
.scat-btn--form { --bg: var(--scat-accent); --fg: var(--scat-accent-contrast, #fff); }
.scat-btn--custom { --bg: #0f172a; --fg: #fff; }

/* Two-up, matching the external shop buttons: half width, side by side.
   Unlike .scat-external-shops there is NO inner list element here — the buttons
   and the optional note are all direct children of this container — so the note
   has to be spanned explicitly, otherwise it would be placed in a half-width
   cell beside the last button. */
.scat-enquiry-buttons {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 10px;
	margin: 18px 0;
}
.scat-enquiry-buttons > .scat-enquiry-note { grid-column: 1 / -1; }
/* A lone button — only one channel enabled, or the "no channels configured"
   fallback — spans the full width instead of sitting half width with dead space
   beside it.  :only-child covers the fallback markup in every browser; the
   :has() rule also covers one-button-plus-note where supported, and is simply
   ignored where it is not (leaving that button half width). */
.scat-enquiry-buttons > .scat-btn:only-child { grid-column: 1 / -1; }
.scat-enquiry-buttons:not(:has(.scat-btn ~ .scat-btn)) > .scat-btn { grid-column: 1 / -1; }
/* Inline / icons size to their content, so they restore display:flex — without
   it their flex-direction / flex-wrap would be no-ops against the grid above. */
.scat-enquiry-buttons--inline,
.scat-enquiry-buttons--icons { display: flex; flex-direction: row; flex-wrap: wrap; }
.scat-enquiry-buttons--icons .scat-btn { padding: 10px; min-width: 44px; font-family: monospace; font-weight: 700; }
.scat-enquiry-note { font-size: 12px; color: #64748b; margin: 0; }

/* External Shops buttons ===================================================== */
.scat-external-shops { display: flex; flex-direction: column; gap: 10px; margin: 0 0 18px; }
.scat-external-shops--inline  { flex-direction: row; flex-wrap: wrap; }
.scat-external-shops--icons   { flex-direction: row; flex-wrap: wrap; }
.scat-external-shops--icons .scat-external-shop { padding: 10px; min-width: 44px; justify-content: center; text-align: center; }
.scat-external-shops__label {
	font-size: 12px; font-weight: 600; color: #64748b;
	text-transform: uppercase; letter-spacing: .05em; margin: 4px 0 -4px;
}
/* Stacked (the default style) lays the shop buttons out two-up: each takes half
   the width and pairs sit side by side.  An odd count leaves the last button in
   a half-width cell rather than stretching it.
   minmax(0,1fr) rather than plain 1fr because grid items default to
   min-width:auto, which would let a long shop name push its column past half and
   break the alignment.
   The --inline / --icons variants size to their content, so they restore
   display:flex explicitly — without that they would inherit this grid and their
   flex-direction / flex-wrap declarations would silently do nothing. */
.scat-external-shops__list {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 10px;
}
.scat-external-shops--inline .scat-external-shops__list,
.scat-external-shops--icons  .scat-external-shops__list {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
}
.scat-external-shop {
	background: var(--scat-btn-bg);
	color: var(--scat-btn-fg);
	display: inline-flex;
	align-items: center;
	gap: 8px;
}
.scat-external-shop__icon-img {
	display: inline-block;
	width: auto;
	height: 1.2em;
	max-height: 28px;
	filter: drop-shadow(0 1px 1px rgba(0,0,0,.1));
}
.scat-external-shop__icon-char {
	font-size: 1.1em;
	line-height: 1;
	vertical-align: middle;
}
/* Material Design glyph. Inherits `color` (set inline per shop from the Icon
   Colour setting, falling back to the button's text colour) via fill=currentColor.
   flex-shrink:0 keeps the glyph square when a long shop name wraps the label. */
.scat-external-shop__icon-svg {
	display: block;
	flex-shrink: 0;
	width: 1.25em;
	height: 1.25em;
	color: var(--scat-btn-icon, var(--scat-btn-fg, currentColor));
}
.scat-external-shops--icons .scat-external-shop__label,
.scat-external-shops--icons .scat-btn__label { display: none; }

/* TT5 / block-theme breakout.
   --------------------------------------------------------------------------
   Twenty Twenty-Five (and every modern block theme) wraps post content in
   .wp-block-post-content / .entry-content > .is-layout-constrained which
   applies inline "max-width: 780px; margin-left:auto; margin-right:auto;" on
   EVERY direct child — including our <article class="scat-single">.  That's
   way too narrow to fit gallery (1.3fr) + summary (1fr) side-by-side, so
   even with a 768px 2-col breakpoint the layout would still collapse to 1
   column because the ARTICLE ITSELF was locked to 780px (less than 768px
   minus any browser chrome padding).

   Solution: viewport-edge breakout.  We pull our article OUT of the narrow
   constrained parent back to the full viewport horizontal edges via
   position: relative + left: 50% + margin-left: -50vw — that's how core's
   alignfull works in the block editor.  Then the inner .scat-single__main
   re-centers to 1200px as the visible content.  Safe on mobile (vw < 1200px)
   because width: 100vw simply equals full screen. */
article.scat-single {
	position: relative;
	left: 50%;
	width: 100vw;
	margin-left: calc(-50vw + 0px);
	margin-right: 0;
	max-width: none !important;
	padding: 0;
	box-sizing: border-box;
	overflow-x: hidden; /* prevents horizontal scrollbar on vw breakout */
}
.scat-single__main {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 32px;
	padding: 8px 16px 32px;
	/* Was a hardcoded 1200px, which quietly ignored Settings > Display > Layout >
	   Content width: a site set to anything else got a product page wider than
	   every archive. It showed up the moment the breadcrumb bar — which does read
	   the setting — stopped lining up with the gallery beneath it. */
	max-width: var(--scat-content-width, 1200px);
	margin: 0 auto;
	box-sizing: border-box;
	width: 100%;
}
/* min-width:0 on grid items is the OFFICIAL CSS grid fix for "my child
   content expands my grid track beyond its fr allocation" bug.  When a
   grid track is minmax(0, Nfr), but the child has a wide intrinsic-size
   element inside it (e.g. a 1200px wide Garmin product photo), browsers
   still treat the track's minimum as the intrinsic size unless you
   explicitly set min-width:0 (or min-height) on the grid item itself. */
.scat-single__main > * {
	min-width: 0;
	min-height: 0;
	box-sizing: border-box;
	width: 100%;
	max-width: 100%;
}
/* 2-column layout at 640px, not 768px, not 1024px.
   --------------------------------------------------------------------------
   After the TT5 viewport-edge breakout above, we have >= 100vw real width
   available for the single product layout — even with browser zoom at 125%
   or a narrow laptop viewport (1280×800).  640px breakpoint = an iPad Mini
   in portrait can already fit the summary column next to gallery without
   wrapping.  We dropped this breakpoint TWICE from 1024 → 768 → 640 because
   earlier values were WAY too aggressive for block themes: TT5's
   is-layout-constrained wrapper traps content at ~780px on every desktop,
   meaning a 1024px media query NEVER MATCHED in the earlier builds (hence
   the permanently stacked 1-col layout the user reported on a 1920×1080
   desktop screen).  640px is conservative and guarantees 2 columns even on
   tablets-in-landscape + narrow laptop windows. */
@media (min-width: 640px) {
	.scat-single__main { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: 40px; }
}
.scat-single__title { margin: 8px 0 8px; font-size: 28px; line-height: 1.2; color: #0f172a; }
.scat-single__sku { color: #64748b; font-size: 13px; }
.scat-single__excerpt { color: #475569; line-height: 1.7; margin: 12px 0; }

/* Category line on the product page. Quieter than the label pills beneath it —
   it is a breadcrumb-ish aid, not a badge. */
.scat-single__categories {
	margin: 8px 0 4px;
	font-size: 14px;
	color: #64748b;
}

.scat-single__categories-label {
	font-weight: 600;
	margin-right: 4px;
}

.scat-single__categories a {
	color: var(--scat-accent);
	text-decoration: none;
}

.scat-single__categories a:hover,
.scat-single__categories a:focus-visible {
	text-decoration: underline;
}

/* Product Brands ============================================================= */
.scat-product-brands { display: flex; flex-direction: column; gap: 10px; margin: 0 0 8px; }
.scat-product-brand { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.scat-product-brand__logo { display: inline-block; max-width: 180px; }
.scat-product-brand__logo img {
	display: block;
	width: auto;
	max-width: 180px;
	height: auto;
	max-height: 56px;
	object-fit: contain;
	filter: drop-shadow(0 1px 2px rgba(0,0,0,.05));
}
.scat-product-brand__name {
	display: inline-block;
	font-size: 13px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: .06em;
	color: #475569;
}
.scat-product-brand__name a { color: inherit; text-decoration: none; }
.scat-product-brand__name a:hover { color: #0f172a; text-decoration: underline; }
.scat-product-brand__title { color: inherit; }
/* .scat-product-brand__desc removed with its markup: the brand description now
   appears only on the brand archive, where it is about the page you are on. */

/* Availability pill ======================================================== */
.scat-availability {
	display: inline-flex; align-items: center; gap: 8px;
	padding: 6px 12px; border-radius: 999px;
	font-weight: 600; font-size: 13px;
}
.scat-availability .scat-dot {
	width: 8px; height: 8px; border-radius: 999px;
	display: inline-block; background: currentColor;
}
/* The pill used its own hardcoded palette and ignored the badge colour
   settings entirely, so the same status could be one colour on a card and a
   different one on the product page.

   Each rule is declared twice on purpose. The first pair is the literal
   fallback any browser understands; the second re-states it in terms of the
   configured colour, tinting the background from it rather than switching to a
   solid block, so the pill keeps its light look. A browser without color-mix()
   simply ignores the second pair and keeps the original palette. */
.scat-availability--available   { background: #ecfdf5; color: #047857; }
.scat-availability--reserved    { background: #fffbeb; color: #b45309; }
.scat-availability--sold        { background: #fef2f2; color: #b91c1c; }
.scat-availability--coming_soon { background: #eff6ff; color: #1d4ed8; }

@supports (background: color-mix(in srgb, red 10%, white)) {
	.scat-availability--available {
		color: var(--scat-available, #047857);
		background: color-mix(in srgb, var(--scat-available, #047857) 12%, #fff);
	}
	.scat-availability--reserved {
		color: var(--scat-reserved, #b45309);
		background: color-mix(in srgb, var(--scat-reserved, #b45309) 12%, #fff);
	}
	.scat-availability--sold {
		color: var(--scat-sold, #b91c1c);
		background: color-mix(in srgb, var(--scat-sold, #b91c1c) 12%, #fff);
	}
	.scat-availability--coming_soon {
		color: var(--scat-coming, #1d4ed8);
		background: color-mix(in srgb, var(--scat-coming, #1d4ed8) 12%, #fff);
	}
}
/* Sold date, shown under the Sold badge. Muted so it reads as a footnote to the
   badge rather than competing with it. */
.scat-sold-date {
	margin: 4px 0 0;
	font-size: 12px;
	line-height: 1.4;
	color: #64748b;
}
.scat-stock-note { font-size: 14px; color: #475569; }

/* Gallery ================================================================== */
.scat-gallery { display: flex; flex-direction: column; gap: 12px; width: 100%; max-width: 100%; min-width: 0; }
.scat-gallery__main {
	position: relative;
	background: #fff;
	border-radius: 16px;
	overflow: hidden;
	width: 100%;
	max-width: 100%;
	min-width: 0;
	/* Use the CSS custom property --scat-gallery-ratio set inline on the
	   element by product-gallery.php (pulled from size_single_w /
	   size_single_h settings).  If no inline ratio is set, fall back to 4/3.
	   NO !important on the default value here because we WANT the user's
	   saved setting (aspect-ratio set via inline style) to win. */
	aspect-ratio: var(--scat-gallery-ratio, 4 / 3);
	transition: aspect-ratio .35s ease, background-color .35s ease;
}
/* Video slide active marker.  Main container aspect ratio NO LONGER CHANGES when video active.
   User configured 800x800 saved aspect-ratio (--scat-gallery-ratio) is preserved FOREVER
   when switching between image slides and the video preview slide.  Gallery box size,
   layout, and height stays 100% stable.  No sudden height shrink!  The video preview
   renders INSIDE this fixed-size box (letterboxed inside the available area, 16:9 video
   preview rendered centered in the middle; the space above/below the 16:9 poster area
   uses the same pure #fff white background as the adjacent image slides for a seamless
   white-on-white integration instead of the jarring black bars from earlier. */
.scat-gallery--video-active > .scat-gallery__main { background: var(--scat-gallery-bg, #fff); }

/* Video preview placeholder inside main gallery — replaces the inline iframe we used to
   render.  Fills FULL WIDTH of the saved 1:1 (e.g. 800x800) square container first.  At
   16:9 aspect ratio this means height = width*(9/16), which is SHORTER than the 1:1 box
   height, producing solid-white letterbox area above and below the 16:9 preview panel
   (NOT wasted left/right space!).  Matches the visual style of the photo image slides
   that sit next to it in the gallery.  No max-width/max-height or flex-shrink
   constraints — must touch left/right edges of the 1:1 main area to look consistent. */
.scat-video-preview {
	position: relative;
	flex: 0 0 100%;
	width: 100%;
	min-width: 100%;
	max-width: none;
	aspect-ratio: 16 / 9;
	background: var(--scat-gallery-bg, #fff);
	display: block;
	overflow: hidden;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	cursor: zoom-in;
	background-image: var(--scat-vthumb, var(--scat-vthumb-fb, linear-gradient(135deg, #0f172a 0%, #334155 100%)));
	background-position: center center;
	background-size: cover;
	background-repeat: no-repeat;
}
/* Provider-branded poster gradients — fallback when thumb URLs 404; exactly same triple-render layers as nav thumb button (bg gradient brand gradient). */
.scat-video-preview.is-provider-youtube {
	background-image: var(--scat-vthumb, var(--scat-vthumb-fb, linear-gradient(135deg, #7f1d1d 0%, #ef4444 50%, #0f172a 100%)));
}
.scat-video-preview.is-provider-vimeo {
	background-image: var(--scat-vthumb, var(--scat-vthumb-fb, linear-gradient(135deg, #075985 0%, #229ed9 50%, #0f172a 100%)));
}
/* Fallback child img inside preview (onerror swaps sddefault -> hqdefault).  Z-index 1, so it's drawn ON TOP of the CSS bg gradient, poster cover;  BUT BELOW play ▶ button overlay z 2. */
.scat-video-preview__poster {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	margin: 0;
	padding: 0;
	display: block;
	z-index: 1;
	object-fit: cover;
	background: transparent;
}
/* Big centered PLAY button centered overlay on hover — visual CTA. Click anywhere inside main video preview. */
.scat-video-preview__play {
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%) scale(1);
	z-index: 2;
	width: 92px;
	height: 92px;
	border-radius: 9999px;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(15, 23, 42, 0.55);
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	border: 0;
	padding: 0 0 0 6px;
	color: #fff;
	cursor: zoom-in;
	box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
	transition: transform .2s ease, background-color .2s ease;
}
.scat-video-preview:hover .scat-video-preview__play,
.scat-video-preview:focus-visible .scat-video-preview__play {
	transform: translate(-50%, -50%) scale(1.08);
	background: rgba(15, 23, 42, 0.78);
}
.scat-video-preview__play svg {
	width: 38px;
	height: 38px;
	display: block;
	flex: 0 0 auto;
}
/* Responsive: smaller play icon on < 640px mobile screens. */
@media (max-width: 640px) {
	.scat-video-preview__play { width: 70px; height: 70px; padding-left: 4px; }
	.scat-video-preview__play svg { width: 28px; height: 28px; }
}
/* Anchor wrapper around scat-video-preview — fills entire slide figure (so click in the
   solid-white letterbox top/bottom bars also triggers lightbox).  display:flex with
   column centering; overflow:hidden so any oversized content never bleeds outside the
   1:1 box; background uses the same var(--scat-gallery-bg, #fff) pure white as image
   slides for seamless look when swapping between photo and video previews; absolutely no
   jarring black letterbox bars from earlier versions. */
.scat-video-lightbox-link {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	display: flex;
	flex-direction: column;
	align-items: stretch;
	justify-content: center;
	cursor: zoom-in;
	text-decoration: none;
	outline: none;
	background: var(--scat-gallery-bg, #fff);
	z-index: 2;
	margin: 0;
	padding: 0;
	overflow: hidden;
}

.scat-gallery__slide {
	position: absolute;
	inset: 0;
	width: 100% !important;
	height: 100% !important;
	display: none;
	align-items: center;
	justify-content: center;
	margin: 0 !important;
	padding: 0 !important;
	max-width: none !important;
	min-width: 0 !important;
	min-height: 0 !important;
}
.scat-gallery__slide.is-active { display: flex; }
/* Use CSS var --scat-fit set inline on the gallery main (inherit through
   DOM works because CSS vars cascade) to pick between cover (crop to box
   when user set crop=true) vs contain (show entire Garmin image with soft
   background letterboxing on mismatched ratios when crop=false).
   size_single_crop=false default in the plugin → show whole product photo
   not chopped off watch bezels. */
.scat-gallery__slide img {
	width: 100% !important;
	height: 100% !important;
	max-width: none !important;
	min-width: 0 !important;
	object-fit: var(--scat-fit, contain);
	object-position: center center;
	display: block;
	background: #fff;
}
.scat-gallery__link { display: block; width: 100%; height: 100%; }
.scat-gallery__thumbs {
	display: grid; grid-template-columns: repeat(6, minmax(0,1fr));
	gap: 8px;
}
@media (max-width: 480px) { .scat-gallery__thumbs { grid-template-columns: repeat(4, minmax(0,1fr)); } }
.scat-gallery__thumb {
	padding: 0; border: 2px solid transparent;
	background: transparent;
	border-radius: 10px; overflow: hidden;
	aspect-ratio: 1/1; cursor: pointer;
}
.scat-gallery__thumb.is-active { border-color: var(--scat-accent); }
.scat-gallery__thumb img { width: 100%; height: 100%; object-fit: cover; }
/* Video thumb nav button.  Rendering path #2 — the button itself gets the
   provider thumbnail applied as its background image via --scat-vthumb CSS
   var (set inline on the <button> element).  This is a FULLY INDEPENDENT
   fallback rendering from the <img> element inside.  Scenarios covered:
     • <img> fails to load → this bg still shows (since it loads from CSS)
     • onerror hides the <img> via display:none → this bg still shows
     • stale cached CSS removes the gradient → this bg still shows
     • provider blocks the <img> hotlink (rare) → bg gradients take over
   Rendering priority (top to bottom):
     1. The <img> element (top layer; user sees actual hi-res thumb)
     2. CSS background-image: var(--scat-vthumb) → sddefault.jpg
     3. CSS linear-gradient YouTube/Vimeo branded fallback gradient
*/
.scat-gallery__thumb--video {
	position: relative;
	background-color: #0f172a;
	background-image: var(--scat-vthumb, var(--scat-vthumb-fb, linear-gradient(135deg, #0f172a 0%, #334155 100%)));
	background-position: center center;
	background-size: cover;
	background-repeat: no-repeat;
	overflow: hidden;
}
.scat-gallery__thumb--video-youtube {
	/* Branded gradient if --scat-vthumb is not set AND the inline <img> also
	   failed to load.  YouTube reds: visually recognizable as "video link". */
	background-image: var(--scat-vthumb, var(--scat-vthumb-fb, linear-gradient(135deg, #7f1d1d 0%, #ef4444 50%, #0f172a 100%)));
}
.scat-gallery__thumb--video-vimeo {
	background-image: var(--scat-vthumb, var(--scat-vthumb-fb, linear-gradient(135deg, #075985 0%, #229ed9 50%, #0f172a 100%)));
}
/* If the <img> rendered successfully on top, let the provider's real
   thumbnail dominate (no opacity wash).  The bg-image under it now acts as
   a fast paint so the user never sees pure black between frames. */
.scat-gallery__thumb--video img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	opacity: 1;
	position: relative;
	z-index: 1;
	background: transparent;
}
/* Play-icon overlay on the nav thumbnail.  Renders on top of BOTH the
   background-image layer AND the <img> layer (z-index 2) so the ▶ play
   glyph is always visible regardless of which fallback triggered. */
.scat-gallery__thumb-badge {
	position: absolute;
	inset: 0;
	display: grid;
	place-items: center;
	background: rgba(15, 23, 42, 0.18);
	color: #fff;
	font-size: 20px;
	line-height: 1;
	pointer-events: none;
	text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
	z-index: 2;
}
/* Hide the video slide by default — JS / CSS toggles .is-active on it.
   (Was removed accidentally in a prior thumbnail-bg refactor; restored here.) */
.scat-gallery__slide--video { display: none; }
/* Video slide uses BLOCK display (not flex) so theme CSS targeting flex
   layouts (TT5) cannot interfere with the absolute-positioned iframe chain. */
.scat-gallery__slide--video.is-active {
	display: block !important;
	padding: 0 !important;
	margin: 0 !important;
	position: absolute !important;
	inset: 0 !important;
	width: 100% !important;
	height: 100% !important;
	max-width: none !important;
	aspect-ratio: auto !important;
	border: 0 !important;
	background: #000 !important;
}

/* Video fills the ENTIRE slide (no empty space on sides/top/bottom).
   Every wrapper down to the <iframe> uses position:absolute + inset:0
   with !important on ALL sizing props so block-theme and core embed CSS
   cannot constrain the iframe with padding-based aspect-ratio hacks. */


/* ---- (Legacy) scat-video-embed — used in v1.1.8 and earlier when we
        rendered the actual iframe inline inside the main gallery slide.
        These rules are harmless back-compat legacy for any page cached
        before 1.2.0.  The modern structure above (scat-video-preview) does
        not render an iframe at all — the iframe only loads inside the
        lightbox overlay when clicked.  Keeping these to avoid visual
        breakage if any cached HTML / old DB content still holds an iframe.
        DO NOT REMOVE until a proper DB migration is written. ---- */

.scat-video-embed {
	position: absolute !important;
	inset: 0 !important;
	width: 100% !important;
	height: 100% !important;
	display: block !important;
	background: #000 !important;
	margin: 0 !important;
	padding: 0 !important;
	max-width: none !important;
	min-width: 0 !important;
	min-height: 0 !important;
	aspect-ratio: auto !important;
	border: 0 !important;
	float: none !important;
	clear: none !important;
}
.scat-video-embed__inner {
	position: absolute !important;
	inset: 0 !important;
	width: 100% !important;
	height: 100% !important;
	display: block !important;
	background: #000 !important;
	margin: 0 !important;
	padding: 0 !important;
	max-width: none !important;
	aspect-ratio: auto !important;
}

/* ---- Kill every known WordPress / block-theme embed wrapper. ----
   wp-block-embed, wp-embed-responsive, wp-has-aspect-ratio, and the
   padding-bottom aspect-ratio hack ALL get neutered here.
   Any class core or TT5 could possibly ship with is explicitly overridden
   so the iframe truly fills edge-to-edge inside our 16:9 container. */
.scat-video-embed .wp-block-embed,
.scat-video-embed figure.wp-block-embed,
.scat-video-embed .wp-embed-responsive,
.scat-video-embed .wp-has-aspect-ratio,
.scat-video-embed .wp-embed-aspect-16-9,
.scat-video-embed .wp-embed-aspect-4-3,
.scat-video-embed .wp-block-embed-youtube,
.scat-video-embed .wp-block-embed-vimeo,
.scat-video-embed .wp-block-embed__wrapper,
.scat-video-embed .wp-block-embed iframe,
.scat-video-embed iframe {
	position: absolute !important;
	inset: 0 !important;
	width: 100% !important;
	height: 100% !important;
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	max-width: none !important;
	min-width: 0 !important;
	max-height: none !important;
	min-height: 0 !important;
	aspect-ratio: auto !important;
	display: block !important;
	background: #000 !important;
	float: none !important;
	clear: none !important;
	box-shadow: none !important;
	border-radius: 0 !important;
	overflow: hidden !important;
}
/* Kill the core responsive-embed padding-bottom aspect-ratio hack:
   padding-bottom: 56.25% is the #1 cause of "empty side space" because it
   sizes the wrapper to 16:9 using padding INSIDE a container that's ALREADY
   sized to 16:9 by us, producing letterboxing. */
.scat-video-embed .wp-embed-responsive,
.scat-video-embed [class*="wp-embed-aspect-"] {
	padding-top: 0 !important;
	padding-right: 0 !important;
	padding-bottom: 0 !important;
	padding-left: 0 !important;
	height: 100% !important;
}
/* Extra-deep iframe selectors (covers every nesting depth we've ever seen
   WP's oEmbed handlers produce, including 3+ levels of <figure> + <div>). */
.scat-video-embed iframe,
.scat-video-embed * iframe,
.scat-video-embed__inner iframe,
.scat-video-embed__inner * iframe {
	position: absolute !important;
	top: 0 !important;
	left: 0 !important;
	right: 0 !important;
	bottom: 0 !important;
	width: 100% !important;
	height: 100% !important;
	border: 0 !important;
	display: block !important;
	background: #000 !important;
}
.scat-gallery__thumb--video { position: relative; background: #0f172a; }
.scat-gallery__thumb--video img { width: 100%; height: 100%; object-fit: cover; display: block; opacity: 1; }
/* Play-icon overlay on the nav thumbnail.  Light tint only so thumbnail preview
   underneath is clearly visible (was previously near-black on 45% overlay). */
.scat-gallery__thumb-badge {
	position: absolute;
	inset: 0;
	display: grid;
	place-items: center;
	background: rgba(15, 23, 42, 0.22);
	color: #fff;
	font-size: 20px;
	line-height: 1;
	pointer-events: none;
	text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
}
.scat-video-link {
	display: inline-flex;
	align-items: center;
	gap: 12px;
	padding: 14px 22px;
	border-radius: 999px;
	background: linear-gradient(135deg, #ef4444, #b91c1c);
	color: #fff;
	font-weight: 600;
	text-decoration: none;
	box-shadow: 0 10px 25px rgba(239, 68, 68, 0.25);
}
.scat-video-link:hover { filter: brightness(0.95); color: #fff; }
.scat-video-link__icon {
	width: 32px; height: 32px;
	border-radius: 999px;
	background: rgba(255,255,255,0.2);
	display: grid; place-items: center;
	font-size: 14px;
}

/* Options ================================================================== */
.scat-options { display: flex; flex-direction: column; gap: 16px; margin: 16px 0; }
/* Was ".sat-option__label" — a typo that meant the option group labels were
   never styled at all. */
.scat-option__label { display: block; font-weight: 600; margin: 0 0 6px; font-size: 14px; }
.scat-option__text { width: 100%; box-sizing: border-box; padding: 10px 12px; border: 1px solid #cbd5e1; border-radius: 10px; background: #fff; font-size: 14px; }
/* Option group help text — captured on both the Option Sets screen and the
   product metabox, but never rendered until 1.14.0. */
.scat-option__help { display: block; margin: -2px 0 6px; font-size: 12px; line-height: 1.4; color: #64748b; }

/* Option values that carry an image become fixed-width cards: picture on top,
   radio + name underneath.  `order:-1` with `flex-basis:100%` lifts the image
   onto its own line without reordering the markup, so the input stays first in
   the DOM for screen readers and label/for pairing.
   Override --scat-opt-image-w to resize them. */
/* --scat-opt-image-w  : width of a fixed-width option card carrying a picture.
   --scat-opt-thumb-w  : the picture itself — the card minus its 8px padding and
                         1px border. Package cards reuse it so their left-hand
                         thumbnail matches the images on every other option. */
.scat-options { --scat-opt-image-w: 110px; --scat-opt-thumb-w: 92px; }
/* Doubled class for specificity: these rules sit ABOVE the base .scat-opt-value
   block, and at equal specificity the later rule would win — leaving the base
   `padding: 8px 12px` in force and squeezing the image to 84px inside a 110px
   card. */
.scat-opt-value.scat-opt-value--has-image {
	flex-wrap: wrap;
	justify-content: center;
	text-align: center;
	width: var(--scat-opt-image-w);
	box-sizing: border-box;
	padding: 8px;
	gap: 4px;
}
/* The picture is wrapped in a lightbox link, so the ANCHOR is the flex item and
   carries the ordering; the image just fills it. */
.scat-opt-value--has-image .scat-opt-image-link,
.scat-opt-value--has-image .scat-opt-image {
	order: -1;
	flex-basis: 100%;
	width: 100%;
	display: block;
}
.scat-opt-value--has-image .scat-opt-image {
	height: auto;
	aspect-ratio: 1;
	object-fit: cover;
	border-radius: 8px;
}
/* Hint that the picture opens rather than selects. */
.scat-opt-image-link { cursor: zoom-in; }
.scat-opt-image-link:focus-visible { outline: 2px solid var(--scat-accent); outline-offset: 2px; }

/* Value description — the field both editors have always stored. Muted and on
   its own line; it is what makes a Package card more than a wide pill. */
.scat-opt-desc { flex-basis: 100%; font-size: 13px; line-height: 1.45; color: #64748b; }

/* Package cards ============================================================
   Stacked full-width choices for tiered offerings ("Basic / Standard /
   Premium"): name and price on the top line, description beneath.
   Doubled classes throughout so these win over the base .scat-opt-value and
   the fixed-width --has-image card regardless of source order. */
.scat-option--package .scat-option__group { flex-direction: column; gap: 10px; }
.scat-opt-value.scat-opt-value--package {
	width: 100%;
	/* Required: .scat-opt-value inherits the theme's box-sizing, and under a
	   content-box theme `width:100%` plus this padding and border overflowed the
	   container by 34px. */
	box-sizing: border-box;
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: start;
	gap: 2px 14px;
	text-align: left;
	padding: 14px 16px;
}
.scat-opt-value.scat-opt-value--package .scat-opt-name {
	grid-column: 1;
	font-weight: 700;
	font-size: 15px;
}
.scat-opt-value.scat-opt-value--package .scat-opt-desc { grid-column: 1; }
.scat-opt-value.scat-opt-value--package .scat-opt-adjust {
	grid-column: 2;
	grid-row: 1;
	font-size: 14px;
	white-space: nowrap;
}
/* A package may carry a picture: a square thumbnail on the LEFT, the same size
   as the image on any other option card, with the text beside it.
   Scoped with :has() so a package WITHOUT an image keeps the plain two-column
   text/price grid and gains no empty gutter. Browsers without :has() fall back
   to the rules above, which lay the picture across the top — a reasonable
   degradation rather than a broken card. */
.scat-opt-value.scat-opt-value--package .scat-opt-image-link {
	grid-column: 1 / -1;
	grid-row: 1;
	order: -1;
	flex-basis: auto;
	margin-bottom: 6px;
}
.scat-opt-value.scat-opt-value--package:has(.scat-opt-image-link) {
	grid-template-columns: var(--scat-opt-thumb-w) 1fr auto;
}
.scat-opt-value.scat-opt-value--package:has(.scat-opt-image-link) .scat-opt-image-link {
	grid-column: 1;
	grid-row: 1 / span 2;
	align-self: start;
	width: var(--scat-opt-thumb-w);
	margin-bottom: 0;
}
.scat-opt-value.scat-opt-value--package:has(.scat-opt-image-link) .scat-opt-name,
.scat-opt-value.scat-opt-value--package:has(.scat-opt-image-link) .scat-opt-desc {
	grid-column: 2;
}
.scat-opt-value.scat-opt-value--package:has(.scat-opt-image-link) .scat-opt-adjust {
	grid-column: 3;
	grid-row: 1;
}
/* Square, matching the thumbnail on the fixed-width option cards. */
.scat-opt-value.scat-opt-value--package .scat-opt-image { aspect-ratio: 1; }
.scat-opt-value--has-image .scat-opt-name { flex-basis: 100%; font-size: 13px; line-height: 1.3; }
.scat-option__group { display: flex; flex-wrap: wrap; gap: 8px; }
.scat-opt-value { position: relative; display: inline-flex; align-items: center; gap: 6px; padding: 8px 12px; border: 1px solid #cbd5e1; border-radius: 10px; cursor: pointer; font-size: 14px; }
/* The control itself is hidden — the card IS the button — but it is hidden
   VISUALLY, not with display:none. A display:none input cannot be focused or
   reached by a screen reader, which would make these options keyboard-unusable.
   Kept 1px and transparent so it stays in the tab order and still announces. */
.scat-opt-value input[type="radio"],
.scat-opt-value input[type="checkbox"] {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: 0;
	opacity: 0;
	pointer-events: none;
}
.scat-opt-value:has(input:checked) { border-color: var(--scat-accent); box-shadow: 0 0 0 2px var(--scat-accent); }
/* Fallback indicator for browsers without :has() — without it, hiding the radio
   would leave no sign at all of which option is selected. */
.scat-opt-value input:checked ~ .scat-opt-name { font-weight: 700; color: var(--scat-accent); }
/* The focus ring has to move to the card, since the input no longer shows one. */
.scat-opt-value:has(input:focus-visible) { outline: 2px solid var(--scat-accent); outline-offset: 2px; }
.scat-opt-swatch { display: inline-block; width: 16px; height: 16px; border-radius: 999px; background: var(--c); border: 1px solid rgba(0,0,0,.1); }
.scat-opt-adjust { color: #065f46; font-size: 12px; font-weight: 600; }
.scat-options select { width: 100%; padding: 10px 12px; border: 1px solid #cbd5e1; border-radius: 10px; background: #fff; }

/* Specs ==================================================================== */
.scat-specs__table { width: 100%; border-collapse: collapse; border: 1px solid #e2e8f0; border-radius: 10px; overflow: hidden; }
.scat-specs__table th, .scat-specs__table td { padding: 12px 16px; border-bottom: 1px solid #e2e8f0; text-align: left; font-size: 14px; }
.scat-specs__table th[scope="row"] { background: #f8fafc; width: 35%; font-weight: 600; color: #334155; }
.scat-specs__group th { background: var(--scat-accent); color: var(--scat-accent-contrast); }

/* Downloads ================================================================ */
.scat-files { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.scat-files__link { display: flex; align-items: center; gap: 12px; padding: 14px 16px; border: 1px solid #e2e8f0; border-radius: 10px; text-decoration: none; color: inherit; }
.scat-files__link:hover { background: #f8fafc; }
.scat-files__badge { padding: 4px 8px; font-size: 11px; font-weight: 700; letter-spacing: .04em; border-radius: 6px; background: #0f172a; color: #fff; min-width: 44px; text-align: center; }
.scat-files__name { flex: 1; font-weight: 600; }
.scat-files__size { color: #64748b; font-size: 12px; }
.scat-files__desc { margin: 4px 0 0 72px; font-size: 13px; color: #475569; }

/* Price block ==============================================================
   Only the note was ever styled, so the figure itself rendered at whatever size
   the theme gave a bare <span> — the most important number on the page looked
   like body copy. The wrapper is flex+wrap so a range keeps its two figures on
   one line and the note drops beneath. */
.scat-price {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0 8px;
	margin: 0 0 4px;
}

.scat-price__value {
	font-size: 28px;
	font-weight: 700;
	line-height: 1.2;
	letter-spacing: -0.01em;
	color: #0f172a;
}

/* The range separator should not compete with the figures it joins. */
.scat-price__sep {
	font-size: 20px;
	font-weight: 400;
	color: #94a3b8;
}

/* "Free" and "Price on request" are statements, not amounts — sized to sit in
   the same slot without shouting a number that is not there. */
.scat-price--free,
.scat-price--on-request {
	font-size: 18px;
	font-weight: 600;
	line-height: 1.3;
	color: #475569;
}

.scat-price--on-request {
	padding: 4px 12px;
	border-radius: 999px;
	background: #f1f5f9;
	font-size: 15px;
}

/* A live total updated by the option selectors, so it must not jump around as
   digits change width. */
.scat-price__value {
	font-variant-numeric: tabular-nums;
}

@media (max-width: 600px) {
	.scat-price__value { font-size: 24px; }
	.scat-price__sep { font-size: 17px; }
}

/* Price note — secondary qualifier under the price ("per set", "before SST").
   display:block so it drops onto its own line rather than running on after the
   figure, whatever the theme does with the surrounding inline spans. */
.scat-price__note {
	display: block;
	margin-top: 2px;
	/* flex-basis 100% so it takes its own row inside the flex wrapper above. */
	flex-basis: 100%;
	font-size: 12px;
	font-weight: 400;
	line-height: 1.4;
	color: #64748b;
}

/* Enquiry form ============================================================= */
.scat-enquiry-form {
	padding: 20px; border: 1px solid #e2e8f0; border-radius: 14px;
	background: #fafafa;
	display: flex; flex-direction: column; gap: 14px;
	margin: 12px 0 24px;
}
.scat-enquiry-form.is-hidden { display: none; }
.scat-fields { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 14px; }
@media (max-width: 640px) { .scat-fields { grid-template-columns: 1fr; } }
.scat-field { display: flex; flex-direction: column; gap: 6px; }
.scat-field--message, .scat-field--gdpr { grid-column: 1 / -1; }
.scat-field label { font-size: 13px; font-weight: 600; color: #334155; }
/* box-sizing MUST be declared here.  These fields inherit the theme's value, and
   under a content-box theme (Divi, among others) `width:100%` means 100% of the
   column PLUS 24px padding and 2px border — a 26px overspill that pushed the
   Name field over the Email field in the two-column grid and pushed the message
   textarea past the edge of the form.
   max-width belts-and-braces the same guarantee if a theme forces a width.
   resize:vertical stops a visitor dragging the textarea wider than its
   container and reintroducing the overflow by hand. */
.scat-field input, .scat-field textarea {
	box-sizing: border-box;
	width: 100%; max-width: 100%; padding: 10px 12px;
	border: 1px solid #cbd5e1; border-radius: 10px;
	background: #fff; font-size: 14px;
}
.scat-field textarea { resize: vertical; }

/* Validation errors, shown against the field they belong to. */
.scat-field__error {
	display: block;
	margin-top: 4px;
	font-size: 12px;
	line-height: 1.4;
	color: #b91c1c;
}

.scat-field--invalid input,
.scat-field--invalid textarea {
	border-color: #b91c1c;
}

.scat-field--invalid input:focus,
.scat-field--invalid textarea:focus {
	border-color: #b91c1c;
	box-shadow: 0 0 0 3px rgba(185, 28, 28, .15);
}

/* The consent row is a horizontal flex, so its error needs a full row of its
   own rather than being squeezed beside the text. Allowing wrap alone was not
   enough: the sentence has a wide min-content width, so it wrapped to its own
   line and put the checkbox back above the text. It has to be told to shrink. */
.scat-field--gdpr { flex-wrap: wrap; }

.scat-field--gdpr > span:not(.scat-field__error) {
	flex: 1 1 0;
	min-width: 0;
}

.scat-field--gdpr .scat-field__error { flex-basis: 100%; }

/* Consent row: checkbox beside its text, not above it.
   .scat-field is a column flex with `width: 100%` on its inputs — sensible for
   a labelled text field, but it stretched the consent checkbox into a full-width
   box sitting on top of the sentence it belongs to. */
.scat-field--gdpr {
	flex-direction: row;
	align-items: flex-start;
	gap: 10px;
}

.scat-field--gdpr input[type="checkbox"] {
	width: auto;
	max-width: none;
	flex: 0 0 auto;
	/* Nudged down to sit on the first line of the text rather than its cap. */
	margin-top: 2px;
	padding: 0;
}

/* :not() so these do not also capture the validation error, which is a direct
   child span too — `.scat-field--gdpr > span` outranks `.scat-field__error` on
   specificity, so without this the error rendered in the consent text's grey
   instead of red. */
.scat-field--gdpr > span:not(.scat-field__error) {
	font-size: 13px;
	line-height: 1.5;
	color: #334155;
}
.scat-field input:focus, .scat-field textarea:focus { outline: none; border-color: var(--scat-accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--scat-accent) 18%, transparent); }
.scat-required { color: #dc2626; margin-left: 2px; }
.scat-form__actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.scat-form__status { color: #16a34a; font-weight: 600; font-size: 13px; }
.scat-form__status.is-error { color: #dc2626; }
.scat-captcha { grid-column: 1 / -1; }

/* Tabs ===================================================================== */
.scat-tabs { margin: 20px 0; border: 1px solid #e2e8f0; border-radius: 14px; overflow: hidden; background: #fff; }
.scat-tabs__nav { display: flex; flex-wrap: wrap; border-bottom: 1px solid #e2e8f0; background: #f8fafc; }
.scat-tabs__btn {
	padding: 14px 18px;
	border: 0;
	border-bottom: 2px solid transparent;
	background: transparent;
	color: #475569;
	font-weight: 600; cursor: pointer;
	font-size: 14px;
}
.scat-tabs__btn.is-active { color: var(--scat-accent); border-bottom-color: var(--scat-accent); background: #fff; }
.scat-tabs__panel { padding: 20px; display: none; }
.scat-tabs__panel.is-active { display: block; }

/* Pagination & load-more =================================================== */
.scat-pagination { margin: 32px 0; display: flex; justify-content: center; }
.scat-load-more {
	display: block; margin: 24px auto;
	padding: 12px 20px;
	border-radius: 999px;
	background: #0f172a; color: #fff;
	border: 0; cursor: pointer; font-weight: 600;
}

/* Empty / filters ========================================================== */
.scat-empty { padding: 40px 24px; text-align: center; background: #f8fafc; border-radius: 14px; color: #475569; }
/* Catalog sidebar =========================================================
   Only present when the Catalog Sidebar widget area has something in it, so
   the default archive is untouched and there is never an empty column. */
.scat-archive__body--has-sidebar {
	display: grid;
	grid-template-columns: minmax(0, 240px) minmax(0, 1fr);
	gap: 32px;
	align-items: start;
}

.scat-archive__sidebar {
	display: flex;
	flex-direction: column;
	gap: 24px;
	min-width: 0;
}

.scat-widget__title {
	margin: 0 0 10px;
	font-size: 15px;
	font-weight: 700;
	color: #0f172a;
}

.scat-widget__list,
.scat-widget__list ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

/* The nested list wp_list_categories emits — indented, not bulleted, so the
   depth reads without competing with the product grid beside it. */
.scat-widget__list ul {
	margin-left: 14px;
	border-left: 1px solid #e2e8f0;
	padding-left: 10px;
}

.scat-widget__list li {
	margin: 0;
	padding: 3px 0;
	font-size: 14px;
	line-height: 1.5;
}

.scat-widget__list a {
	color: #334155;
	text-decoration: none;
}

.scat-widget__list a:hover,
.scat-widget__list a:focus-visible {
	color: var(--scat-accent);
	text-decoration: underline;
}

/* wp_list_categories marks the current term; the brand widget sets its own. */
.scat-widget__list .current-cat > a,
.scat-widget__list li.is-current > a {
	color: var(--scat-accent);
	font-weight: 700;
}

.scat-widget__count {
	color: #94a3b8;
	font-size: 12px;
}

@media (max-width: 860px) {
	/* Stack, with the products first: on a phone a visitor came to see the
	   catalogue, not to read a list of category names. */
	.scat-archive__body--has-sidebar {
		grid-template-columns: minmax(0, 1fr);
		gap: 28px;
	}
	.scat-archive__sidebar { order: 2; }
	.scat-archive__results { order: 1; }
}

/* Filter bar ==============================================================
   Every facet used to be a full-width stacked block, so five of them plus the
   buttons ran to roughly 500px of chrome before a visitor saw a single
   product. It is one wrapping row now: each control sizes to its content,
   the chips and price inputs no longer stretch across the page, and the whole
   bar collapses back to a stack below 640px. */
.scat-filters {
	margin: 0 0 24px;
	padding: 14px 16px;
	border: 1px solid #e2e8f0;
	border-radius: 12px;
	background: #fff;
}

.scat-filters--collapsed .scat-filters__form.is-hidden { display: none; }

.scat-filters__toggle {
	width: 100%;
	padding: 10px 12px;
	display: flex;
	justify-content: space-between;
	align-items: center;
	border-radius: 8px;
	border: 1px solid #cbd5e1;
	background: #fff;
	cursor: pointer;
}

.scat-filters__form {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: 12px;
}

/* Also resets the fieldset the price range uses, which brings its own
   border, padding and margin. */
.scat-filters__row {
	margin: 0;
	padding: 0;
	border: 0;
	min-width: 0;
	flex: 1 1 165px;
	display: flex;
	flex-direction: column;
	gap: 5px;
}

.scat-filters__row > label,
.scat-filters__row > legend,
.scat-filters__row-label {
	padding: 0;
	font-weight: 600;
	font-size: 12px;
	color: #64748b;
}

.scat-filters__row select {
	width: 100%;
	height: 38px;
	padding: 0 30px 0 10px;
	border: 1px solid #cbd5e1;
	border-radius: 8px;
	background-color: #fff;
	font-size: 14px;
}

/* Chips and price inputs are as wide as they need to be — stretching them
   across a third of the bar was most of the wasted space. */
.scat-filters__row--avail,
.scat-filters__row--price {
	flex: 0 1 auto;
}

.scat-chip-row { display: flex; flex-wrap: wrap; gap: 5px; }
.scat-chip input { display: none; }
.scat-chip span {
	display: inline-flex;
	align-items: center;
	height: 38px;
	padding: 0 12px;
	border: 1px solid #cbd5e1;
	border-radius: 999px;
	font-size: 13px;
	cursor: pointer;
}
.scat-chip input:checked + span { background: var(--scat-accent); color: var(--scat-accent-contrast); border-color: transparent; }

.scat-filters__price-range { display: flex; align-items: center; gap: 6px; }
.scat-filters__price-range label { display: flex; align-items: center; gap: 5px; margin: 0; }
.scat-filters__price-range label span { font-size: 12px; color: #64748b; }
.scat-filters__price-range input {
	width: 86px;
	height: 38px;
	padding: 0 8px;
	border: 1px solid #cbd5e1;
	border-radius: 8px;
	font-size: 14px;
}

.scat-filters__actions { flex: 0 0 auto; display: flex; gap: 8px; padding: 0; }

/* Match the 38px of every other control on the bar — the shared --sm button
   size is 28px, which left Apply and Reset looking undersized beside the
   selects and chips they sit next to. */
.scat-filters__actions .scat-btn {
	height: 38px;
	padding: 0 18px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

@media (max-width: 640px) {
	.scat-filters__row,
	.scat-filters__actions { flex: 1 1 100%; }
	.scat-filters__actions .scat-btn { flex: 1 1 auto; justify-content: center; }
}

/* Categories grid ========================================================== */
.scat-cat-grid { display: grid; gap: 16px; grid-template-columns: repeat(var(--scat-cols-mobile, 2), minmax(0, 1fr)); }
@media (min-width: 720px)  { .scat-cat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .scat-cat-grid { grid-template-columns: repeat(var(--scat-cols-desktop, 3), minmax(0, 1fr)); } }
.scat-cat-card {
	display: block; padding: 18px;
	border: 1px solid #e2e8f0; border-radius: 14px;
	text-align: center; text-decoration: none; color: inherit;
	background: #fff; transition: all .15s ease;
}
.scat-cat-card:hover { border-color: var(--scat-accent); transform: translateY(-2px); }
.scat-cat-card__img { width: 100%; aspect-ratio: 4/3; object-fit: cover; border-radius: 10px; margin: 0 0 12px; }
.scat-cat-card__title { font-weight: 700; color: #0f172a; }
.scat-cat-card__count { color: #64748b; font-size: 12px; }

/* Breadcrumbs ============================================================== */
/* The nav sits OUTSIDE the max-width wrapper on every template so the bar
   background can span the full width the theme gives it; this inner element is
   what keeps the trail lined up with the content below. It intentionally reads
   the same --scat-content-width as .scat-archive: the trail used to carry its
   own hardcoded 1200px, so a site that had set a different content width got a
   breadcrumb that did not line up with anything under it. */
.scat-breadcrumbs { padding-top: 16px; margin-bottom: 14px; }
.scat-breadcrumbs__inner { max-width: var(--scat-content-width, 1200px); margin: 0 auto; padding: 0 16px; }
.scat-breadcrumbs ol { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; font-size: 13px; line-height: 1.45; color: var(--scat-crumb-fg, #64748b); }
.scat-breadcrumbs li { display: flex; align-items: center; gap: 10px; }
.scat-breadcrumbs li + li::before { content: '/'; opacity: .45; }
/* Links are the SAME colour as the current page, just dimmed. That is what
   keeps one text-colour setting sufficient on any background: picking a
   separate link colour that stays legible on both a light and a dark bar is a
   choice the site owner should not have to make twice. */
.scat-breadcrumbs a { color: inherit; text-decoration: none; opacity: .62; transition: opacity .15s ease; }
.scat-breadcrumbs a:hover, .scat-breadcrumbs a:focus-visible { opacity: 1; text-decoration: underline; }
.scat-breadcrumbs [aria-current="page"] { font-weight: 600; }
/* Bar style — applied only when Settings > Display > Breadcrumbs > Bar
   background holds a colour. Without one the trail stays plain text in the
   flow, which is how it rendered before this existed. */
.scat-breadcrumbs--bar { background: var(--scat-crumb-bg); padding: 18px 0; margin-bottom: 28px; }

/* RTL ====================================================================== */
[dir="rtl"] .scat-card__badges { left: auto; right: 10px; }

/* Image wrap blur-up ======================================================= */
.scat-img-wrap { display: block; position: relative; background-size: cover; background-position: center; }
.scat-img-wrap img { display: block; width: 100%; height: auto; }

/* Search =================================================================== */
.scat-search { display: flex; gap: 8px; max-width: 480px; }
.scat-search input { flex: 1; padding: 10px 14px; border: 1px solid #cbd5e1; border-radius: 999px; font-size: 14px; }
.scat-search button { padding: 10px 20px; background: var(--scat-accent); color: var(--scat-accent-contrast,#fff); border: 0; border-radius: 999px; font-weight: 600; cursor: pointer; }


/* Card category line and excerpt — both are rendered only when their
   Settings > Display toggle is on. */
.scat-card__category {
	font-size: 12px;
	font-weight: 600;
	letter-spacing: .02em;
	text-transform: uppercase;
	color: #64748b;
	margin-bottom: 2px;
}

.scat-card__excerpt {
	font-size: 13px;
	line-height: 1.5;
	color: #475569;
	margin: 4px 0 2px;
}


/* ---- Settings > Display: "Single gallery style" ------------------------
   The default (thumbs below) is the plain .scat-gallery column rule above.
   thumbs-left turns the same DOM sideways: the thumb strip is source-ordered
   AFTER the main image, so it is pulled to the left with order, not markup. */
.scat-gallery--thumbs-left {
	flex-direction: row;
	/* stretch, not flex-start: it is what makes the thumb rail take the main
	   image's height, which is the height the rows below are divided into. */
	align-items: stretch;
	/* The rail is taken OUT OF FLOW below, so the layout is a single flow child
	   (the main image) with a reserved gutter beside it. That is what breaks the
	   circular sizing: as a flex item the rail's own content set the line height,
	   the main image then stretched to match, and a five-image gallery rendered
	   1548px tall instead of 587. Out of flow, the rail contributes nothing to
	   the height and inherits it instead. */
	display: block;
	position: relative;
	padding-left: 92px;
	/* The gallery is a grid item in .scat-single__main and stretches to the full
	   row height — as tall as the product-info column beside it, 1548px here.
	   The rail is positioned against THIS box, so without hugging the content it
	   inherited that height instead of the image's. */
	align-self: start;
}

.scat-gallery--thumbs-left > .scat-gallery__main {
	width: 100%;
	min-width: 0;
}

.scat-gallery--thumbs-left > .scat-gallery__thumbs {
	/* top:0/bottom:0 against the relative parent gives the rail a DEFINITE
	   height equal to the main image, which is what lets the 1fr rows below
	   resolve. It used to be capped at 520px and scrolled. */
	position: absolute;
	left: 0;
	top: 0;
	bottom: 0;
	width: 84px;
	grid-template-columns: minmax(0, 1fr);
	/* Divide that height between however many thumbs there are, so every one
	   stays visible and no scrollbar appears. With only two or three images the
	   thumbs come out taller than they are wide — a deliberate trade for never
	   hiding a thumbnail. */
	grid-auto-rows: minmax(0, 1fr);
	max-height: none;
	overflow: hidden;
}

.scat-gallery--thumbs-left > .scat-gallery__thumbs .scat-gallery__thumb {
	/* The row height decides the box now, not a square ratio. */
	aspect-ratio: auto;
	min-height: 0;
}

/* A 84px rail beside the image is unusable on a phone; fall back to the
   stacked layout, which is what the narrow breakpoint already styles. */
@media (max-width: 640px) {
	.scat-gallery--thumbs-left {
		/* Undo the out-of-flow rail: back to the stacked layout. */
		display: flex;
		flex-direction: column;
		position: static;
		padding-left: 0;
	}
	.scat-gallery--thumbs-left > .scat-gallery__main,
	.scat-gallery--thumbs-left > .scat-gallery__thumbs { order: 0; }
	.scat-gallery--thumbs-left > .scat-gallery__thumbs {
		position: static;
		flex: 1 1 auto;
		width: auto;
		max-height: none;
		grid-auto-rows: auto;
		grid-template-columns: repeat(6, minmax(0, 1fr));
		overflow: visible;
	}
	.scat-gallery--thumbs-left > .scat-gallery__thumbs .scat-gallery__thumb {
		aspect-ratio: 1 / 1;
	}
}

/* ---- Settings > Display: "Enable image zoom on hover" -----------------
   transform-origin is set from the pointer by frontend.js, so the area under
   the cursor is what magnifies. Skipped entirely for touch and for anyone who
   asked for reduced motion. */
.scat-gallery--zoom .scat-gallery__slide.is-active .scat-gallery__link {
	overflow: hidden;
	cursor: zoom-in;
}

.scat-gallery--zoom .scat-gallery__slide.is-active img {
	transition: transform .18s ease-out;
	will-change: transform;
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
	.scat-gallery--zoom .scat-gallery__slide.is-active .scat-gallery__link:hover img {
		transform: scale(var(--scat-zoom-scale, 2));
	}
}

/* The video slide must never magnify — the play button would drift away
   from the pointer. */
.scat-gallery--zoom .scat-gallery__slide--video img { transform: none !important; }


/* Share this ============================================================== */
/* The brand colour arrives per button as --scat-share-c, set inline from the
   hardcoded registry in ShareButtons::services(). */
.scat-share {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 10px 12px;
	margin-top: 20px;
	padding-top: 18px;
	border-top: 1px solid #e2e8f0;
}

.scat-share__label {
	font-size: 13px;
	font-weight: 600;
	color: #475569;
}

.scat-share__list {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.scat-share__btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	border-radius: 50%;
	background: var(--scat-share-c, #64748b);
	color: #fff;
	text-decoration: none;
	transition: transform .15s ease, opacity .15s ease;
}

.scat-share__btn:hover,
.scat-share__btn:focus-visible {
	color: #fff;
	opacity: .88;
	transform: translateY(-2px);
}

.scat-share__btn:focus-visible {
	outline: 2px solid var(--scat-accent);
	outline-offset: 2px;
}

.scat-share__icon {
	width: 18px;
	height: 18px;
	display: block;
}

@media (prefers-reduced-motion: reduce) {
	.scat-share__btn { transition: none; }
	.scat-share__btn:hover, .scat-share__btn:focus-visible { transform: none; }
}

/* Brand listing — [catalog_brands] ======================================== */
.scat-brands__index {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin: 0 0 18px;
}

.scat-brands__index a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 30px;
	padding: 4px 6px;
	border: 1px solid #e2e8f0;
	border-radius: 8px;
	font-size: 13px;
	font-weight: 600;
	text-decoration: none;
	color: #334155;
}

.scat-brands__index a:hover {
	border-color: var(--scat-accent);
	color: var(--scat-accent);
}

.scat-brands__letter {
	margin: 22px 0 10px;
	padding-bottom: 6px;
	border-bottom: 1px solid #e2e8f0;
	font-size: 15px;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: #64748b;
	/* Offset so the letter is not hidden under a sticky header when jumped to. */
	scroll-margin-top: 90px;
}

.scat-brands__grid {
	display: grid;
	grid-template-columns: repeat(var(--scat-brand-cols, 4), minmax(0, 1fr));
	gap: 12px;
}

.scat-brands__grid.scat-cols-1 { --scat-brand-cols: 1; }
.scat-brands__grid.scat-cols-2 { --scat-brand-cols: 2; }
.scat-brands__grid.scat-cols-3 { --scat-brand-cols: 3; }
.scat-brands__grid.scat-cols-4 { --scat-brand-cols: 4; }
.scat-brands__grid.scat-cols-5 { --scat-brand-cols: 5; }
.scat-brands__grid.scat-cols-6 { --scat-brand-cols: 6; }

@media (max-width: 900px) { .scat-brands__grid { --scat-brand-cols: 3; } }
@media (max-width: 600px) { .scat-brands__grid { --scat-brand-cols: 2; } }

.scat-brand-card {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 8px;
	min-height: 96px;
	padding: 14px 10px;
	border: 1px solid #e2e8f0;
	border-radius: 12px;
	background: #fff;
	text-align: center;
	text-decoration: none;
	color: #0f172a;
	transition: border-color .15s ease, transform .1s ease;
}

.scat-brand-card:hover {
	border-color: var(--scat-accent);
	transform: translateY(-1px);
}

.scat-brand-card__logo {
	max-width: 100%;
	max-height: 48px;
	width: auto;
	height: auto;
	object-fit: contain;
}

.scat-brand-card__name {
	font-size: 13px;
	font-weight: 600;
	line-height: 1.3;
}

/* With a logo present the name is a caption, so let the mark lead. */
.scat-brand-card--has-logo .scat-brand-card__name {
	font-weight: 500;
	color: #475569;
}

.scat-brand-card__count {
	font-size: 11px;
	color: #94a3b8;
}
