/**
 * Swatch Studio — single product page swatch styling.
 * Sizing/color custom properties (--ss-size, --ss-gap, --ss-radius, etc.)
 * are set inline per-page from the saved Styling settings.
 */

.ss-swatches {
	display: inline-block;
	vertical-align: top;
}

/* WoodMart theme compatibility: WoodMart's own single-product
   variable-add-to-cart template (an override of WooCommerce core's, not a
   hook) always renders its own native swatch preview (.wd-swatches-product)
   for any attribute whose terms carry WoodMart's own color/image/text
   swatch meta — entirely independent of Swatch Studio, and always in the
   very same table cell right before the dropdown Swatch Studio replaces.
   Hide WoodMart's copy whenever ours actually rendered for that cell, so
   shoppers see one swatch row per attribute instead of two stacked. Falls
   back to showing both (today's behavior, not worse) on any browser without
   :has() support. */
td.value:has(> .ss-swatches) > .wd-swatches-product {
	display: none;
}

/* WoodMart theme compatibility: WoodMart's own swatchesVariations.js reads
   the .wd-active state on its (now hidden, but still present) native swatch
   markup and injects its own "<span class="wd-attr-selected">Blue</span>"
   into the label cell — independent of the .wd-swatches-product div above,
   and not stopped by hiding that div since the JS runs regardless of CSS
   visibility. Redundant with Swatch Studio's own .ss-selected-value text
   right next to it; hide WoodMart's copy wherever ours is active.
   !important: some other WoodMart base rule (not one specifically targeting
   .wd-attr-selected — never fully identified among its ~130 stylesheet
   chunks) sets it to display:inline-block with equal-or-later cascade
   weight; confirmed via live devtools testing that only !important wins. */
tr:has(.ss-swatches) .wd-attr-selected {
	display: none !important;
}

/* WoodMart theme compatibility: WoodMart's own table.variations .cell rule
   adds 20px of bottom padding to every attribute row regardless of what
   renders inside it, which reads as a large, uneven gap between attribute
   rows once compact swatches (rather than a tall native <select>) are the
   actual content. Tightened only for rows Swatch Studio actually touched. */
table.variations:has(.ss-swatches) .cell {
	padding-bottom: 10px;
}

/* Native <select> stays in the DOM (WooCommerce's variation-form JS reads/
   writes it) but is visually hidden — not display:none, so its value changes
   and change events keep working normally. */
.ss-native-select {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
}

.ss-swatch-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--ss-gap, 8px);
}

.ss-swatch-overflow-item {
	display: contents;
}

/* !important: same WoodMart bare-<button> reset collision as .ss-swatch
   above — this one has its own deliberate padding, not zero, so it needs
   protecting too rather than just neutralizing. */
.ss-swatch-more {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	height: max(30px, calc(var(--ss-size, 40px) * 0.72));
	padding: 0 10px !important;
	margin: 0 !important;
	border: 1px dashed var(--ss-border-color, #c9cdd2) !important;
	border-radius: var(--ss-radius, 2px);
	background: transparent !important;
	box-shadow: none !important;
	color: inherit;
	font-size: 12.5px;
	font-weight: 600;
	cursor: pointer;
}

/* !important on the box-model/reset properties: this is a bare <button>,
   and WoodMart (like most themes) applies a generic padded button reset to
   every <button> on the page — confirmed live (devtools computed style)
   that it was overriding this rule's plain padding/margin/background/
   border, adding an extra ~5px/20px frame around every swatch (worse on
   button-type swatches, which already have their own text padding on the
   inner .ss-swatch-button-label, stacking on top of WoodMart's). */
.ss-swatch {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0 !important;
	margin: 0 !important;
	background: transparent !important;
	border: 0 !important;
	box-shadow: none !important;
	border-radius: 0;
	cursor: pointer;
	box-sizing: border-box;
	line-height: 0;
}

/* 44x44 minimum tap target regardless of the configured swatch size. */
.ss-swatch::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: max(44px, var(--ss-size, 40px));
	height: max(44px, var(--ss-size, 40px));
	transform: translate(-50%, -50%);
}

/* Not scoped to .ss-type-color/.ss-type-image: a WooCommerce-native
   "wc-visual" attribute can mix color and image swatches within the same
   row (chosen per term), so each swatch's own element decides its look. */
.ss-swatch-color,
.ss-swatch-image {
	display: block;
	width: var(--ss-size, 40px);
	height: var(--ss-size, 40px);
	border-radius: var(--ss-radius, 999px);
	border: var(--ss-border-width, 2px) solid var(--ss-border-color, #c9cdd2);
	box-sizing: border-box;
	object-fit: cover;
	background-size: cover;
	background-position: center;
	transition: border-color 120ms ease;
}

/* Dual-color split (two colors on one term, e.g. "Black/Red") — the two
   halves come from an inline `background: linear-gradient(...)` set per
   swatch in PHP; this class only needs to exist as a hook, no rules of its
   own, since the base .ss-swatch-color rule above already covers size/
   border/radius identically for solid and split swatches alike. */

.ss-swatch-image-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	background: #eee;
	color: #555;
	font-size: 12px;
	font-weight: 600;
	text-transform: uppercase;
}

/* Height is always its own setting (--ss-button-height), independent of the
   shared color/image swatch size. Width defaults to the legacy square-ish
   min-width tied to that shared size (matches long-standing behavior); the
   .swatch-studio-button-auto-width override below is what most stores
   actually want — button width based on the label text, not a fixed floor
   meant for single-glyph color/image swatches. */
.ss-type-button .ss-swatch-button-label {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: max(36px, var(--ss-size, 40px));
	height: var(--ss-button-height, 36px);
	padding: 0 12px;
	border-radius: var(--ss-radius, 2px);
	border: var(--ss-border-width, 2px) solid var(--ss-border-color, #c9cdd2);
	background: var(--ss-btn-bg, #fff);
	color: var(--ss-btn-text, #201e1d);
	font-size: var(--ss-font-size, 13px);
	font-weight: 600;
	box-sizing: border-box;
	max-width: 100%;
	overflow-wrap: break-word;
	text-align: center;
	transition: border-color 120ms ease, background 120ms ease, color 120ms ease;
}

.swatch-studio-button-auto-width .ss-type-button .ss-swatch-button-label {
	width: auto;
	min-width: 0;
}

/* Radio type: a vertical list (not the horizontal compact strip every other
   type shares) — reuses the same <button role="radio"> element/click/
   keyboard/disabled infrastructure as color/image/button, just laid out and
   labeled differently, so none of that logic had to be duplicated. */
.ss-type-radio .ss-swatch-row {
	flex-direction: column;
	align-items: stretch;
}

.ss-type-radio .ss-swatch {
	justify-content: flex-start;
	width: 100%;
	gap: 10px;
	padding: 8px 10px !important;
	border: var(--ss-border-width, 1px) solid var(--ss-border-color, #c9cdd2);
	border-radius: var(--ss-radius, 4px);
	box-sizing: border-box;
}

.ss-swatch-radio-bullet {
	position: relative;
	flex-shrink: 0;
	width: 16px;
	height: 16px;
	border-radius: 50%;
	border: 1.5px solid var(--ss-border-color, #c9cdd2);
	box-sizing: border-box;
}

.ss-swatch.is-selected .ss-swatch-radio-bullet {
	border-color: var(--ss-selected-color, #ec3013);
}

.ss-swatch.is-selected .ss-swatch-radio-bullet::after {
	content: "";
	position: absolute;
	inset: 3px;
	border-radius: 50%;
	background: var(--ss-selected-color, #ec3013);
}

.ss-swatch-radio-image {
	flex-shrink: 0;
	width: 32px;
	height: 32px;
	border-radius: var(--ss-radius, 4px);
	object-fit: cover;
}

.ss-swatch-radio-label {
	font-size: var(--ss-font-size, 13px);
	color: var(--ss-btn-text, #201e1d);
	text-align: left;
}

.ss-type-radio .ss-swatch:hover {
	border-color: var(--ss-hover-color, #787c82);
}

.ss-swatch:hover .ss-swatch-color,
.ss-swatch:hover .ss-swatch-image {
	border-color: var(--ss-hover-color, #787c82);
}

.ss-swatch:hover .ss-swatch-button-label {
	border-color: var(--ss-hover-color, #787c82);
	background: var(--ss-hover-bg, var(--ss-btn-bg, #fff));
	color: var(--ss-hover-text, var(--ss-btn-text, #201e1d));
}

.ss-swatch.is-selected .ss-swatch-color,
.ss-swatch.is-selected .ss-swatch-image {
	border-color: var(--ss-selected-color, #ec3013);
	border-width: max(2px, var(--ss-border-width, 2px));
}

.ss-swatch.is-selected .ss-swatch-button-label {
	border-color: var(--ss-selected-color, #ec3013);
	background: var(--ss-selected-bg, var(--ss-selected-color, #ec3013));
	color: var(--ss-selected-text, #fff);
}

.ss-swatch-check {
	position: absolute;
	top: -4px;
	right: -4px;
	display: none;
	align-items: center;
	justify-content: center;
	width: 16px;
	height: 16px;
	border-radius: 999px;
	background: var(--ss-selected-color, #ec3013);
	color: var(--ss-tick-color, #fff);
	font-size: 10px;
	line-height: 1;
}

.swatch-studio-show-checkmark .ss-swatch.is-selected .ss-swatch-check {
	display: flex;
}

/* Out-of-stock swatches (state kept in sync with the hidden <option>'s
   .disabled by product.js, since availability depends on the *other*
   selected attributes — the same logic WooCommerce's own JS already runs). */
.ss-swatch.is-disabled {
	cursor: not-allowed;
}

/* !important: same WoodMart opacity-reset collision as the blur mode below. */
.swatch-studio-oos-strike .ss-swatch.is-disabled {
	opacity: 0.55 !important;
}

/* A two-bar "X", rather than a single diagonal strike, so the configurable
   Disabled Cross Color reads clearly as a cross rather than a stray line.
   width/height must be set explicitly here — .ss-swatch::after is also used
   elsewhere (the 44x44 minimum tap-target hitbox) and that rule sets its own
   width/height; since this ruleset didn't declare those two properties at
   all, they fell through to that unrelated rule regardless of this
   selector's higher specificity (specificity only arbitrates when both
   rules set the same property) — the ::after cross bar rendered as a
   60x60 box instead of a thin line, invisible except for its border. */
.swatch-studio-oos-strike .ss-swatch.is-disabled::before,
.swatch-studio-oos-strike .ss-swatch.is-disabled::after,
.swatch-studio-blur-cross.swatch-studio-oos-blur .ss-swatch.is-disabled::before,
.swatch-studio-blur-cross.swatch-studio-oos-blur .ss-swatch.is-disabled::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 15%;
	right: 15%;
	width: auto;
	height: 0;
	border-top: 2.5px solid var(--ss-cross-color, #ff0000);
}

.swatch-studio-oos-strike .ss-swatch.is-disabled::before,
.swatch-studio-blur-cross.swatch-studio-oos-blur .ss-swatch.is-disabled::before {
	transform: rotate(45deg);
}

.swatch-studio-oos-strike .ss-swatch.is-disabled::after,
.swatch-studio-blur-cross.swatch-studio-oos-blur .ss-swatch.is-disabled::after {
	transform: rotate(-45deg);
}

/* Button swatches don't share color/image swatches' fixed square aspect
   ratio (auto-width, sized by their text label) — sizing the cross bars off
   the element's own width, like the rule above, stretches a wide button's
   line far past what 45deg rotation can fold into a compact "X", so it
   renders as a long distorted diagonal instead. Buttons do have a fixed
   height (--ss-button-height) regardless of label length, so size off that
   instead and recenter horizontally with left:50% + a matching negative
   margin, since the line's length is no longer a simple side-to-side %. */
.swatch-studio-oos-strike .ss-type-button .ss-swatch.is-disabled::before,
.swatch-studio-oos-strike .ss-type-button .ss-swatch.is-disabled::after,
.swatch-studio-blur-cross.swatch-studio-oos-blur .ss-type-button .ss-swatch.is-disabled::before,
.swatch-studio-blur-cross.swatch-studio-oos-blur .ss-type-button .ss-swatch.is-disabled::after {
	--ss-cross-len: min(70%, calc(var(--ss-button-height, 36px) * 0.7));
	left: 50%;
	right: auto;
	width: var(--ss-cross-len);
	margin-left: calc(var(--ss-cross-len) / -2);
}

/* Despite the name, "Blur" is a fade + cross treatment, not an actual
   gaussian blur — matches the reference plugin exactly (its own "blur"
   mode never applies a CSS blur() filter either, just opacity).
   !important: confirmed live (devtools) that some other WoodMart rule
   wins over a plain opacity here, same as the other WoodMart-collision
   fixes elsewhere in this file. */
.swatch-studio-oos-blur .ss-swatch.is-disabled {
	opacity: 0.6 !important;
}

.swatch-studio-oos-hide .ss-swatch.is-disabled {
	display: none;
}

/* Attribute label / selected value text, and layout. */
.swatch-studio-hide-attr-label .variations .label {
	display: none;
}

.ss-selected-value {
	font-weight: 400;
	opacity: 0.65;
	margin-left: 6px;
	font-size: 0.9em;
}

.ss-stock-notice {
	margin: 10px 0;
}

.ss-stock-notice .ss-stock-low {
	color: var(--ss-selected-color, #ec3013);
	font-weight: 600;
}

.swatch-studio-layout-stacked .variations tr {
	display: block;
	border-top: 1px dashed rgba(0, 0, 0, 0.15);
	padding-top: 10px;
	margin-top: 10px;
}

.swatch-studio-layout-stacked .variations tr:first-child {
	border-top: 0;
	padding-top: 0;
	margin-top: 0;
}

.swatch-studio-layout-stacked .variations td,
.swatch-studio-layout-stacked .variations th {
	display: block;
	width: auto !important;
}

@media (max-width: 480px) {
	.ss-swatch-color,
	.ss-swatch-image {
		/* --ss-mobile-size is only set (see class-frontend-product.php
		   inline_css()) when a site explicitly picked a mobile override;
		   otherwise this falls back to the original auto-clamp. */
		width: var(--ss-mobile-size, max(32px, min(var(--ss-size, 40px), 44px)));
		height: var(--ss-mobile-size, max(32px, min(var(--ss-size, 40px), 44px)));
	}
}

/* Focus (keyboard) — always visible, independent of the selected/checkmark
   styling above, since a focused swatch isn't necessarily the selected one
   while arrow-keying through the group. */
.ss-swatch:focus-visible {
	outline: 2px solid var(--ss-selected-color, #ec3013);
	outline-offset: 2px;
	border-radius: max(4px, var(--ss-radius, 4px));
}

.ss-swatch-more:focus-visible {
	outline: 2px solid var(--ss-selected-color, #ec3013);
	outline-offset: 2px;
}

/* Lightweight custom tooltip (mouse hover + keyboard focus), built in
   product.js from data-ss-tooltip — label text only, styled independently
   of the bare native title="" attribute it replaces. */
.ss-tooltip {
	position: fixed;
	z-index: 100000;
	display: flex;
	align-items: center;
	gap: 6px;
	max-width: 220px;
	padding: 6px 10px;
	background: var(--ss-tooltip-bg, #201e1d);
	color: var(--ss-tooltip-text, #fff);
	font-size: 12px;
	line-height: 1.35;
	border-radius: 4px;
	box-shadow: 0 4px 14px rgba(0, 0, 0, 0.2);
	pointer-events: none;
}

.ss-tooltip-has-image img {
	flex-shrink: 0;
	width: 32px;
	height: 32px;
	border-radius: 3px;
	object-fit: cover;
}

/* Preloader: WooCommerce's own variation-form JS adds/removes `.processing`
   on form.variations_form while it's fetching a matching variation over
   AJAX — this just reacts to that existing state, no separate JS needed. */
.swatch-studio-preloader .variations_form.processing .ss-swatch-row {
	position: relative;
	opacity: 0.5;
	pointer-events: none;
}

.swatch-studio-preloader .variations_form.processing .ss-swatch-row::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 18px;
	height: 18px;
	margin: -9px 0 0 -9px;
	border: 2px solid var(--ss-border-color, #c9cdd2);
	border-top-color: var(--ss-selected-color, #ec3013);
	border-radius: 50%;
	animation: ss-spin 0.6s linear infinite;
}

@keyframes ss-spin {
	to {
		transform: rotate(360deg);
	}
}
