/**
 * Variation Layout Studio — frontend.
 *
 * Selectors are deliberately scoped three deep (.vls-attr .vls-swatches
 * .vls-swatch) so they outrank the button rules almost every WooCommerce
 * theme ships. The handful of !important flags are limited to the box model
 * properties that break the layout outright when a theme forces them.
 */

/* ---------------------------------------------------------------------
 * Container
 *
 * WooCommerce lays the selectors out in a table, and a table sizes itself to
 * its content. A product whose only attribute is a swatch grid has a tiny
 * minimum content width, so the table collapses to roughly one tile and the
 * grid has almost nothing to divide up. A product that also has wide text
 * buttons happens to look fine, which makes this look like a caching problem
 * when it is not.
 *
 * WooCommerce core styles this as `.woocommerce div.product form.cart
 * .variations` and themes layer on top of that, so a single class selector
 * here loses. Hence the specificity and the flags.
 * ------------------------------------------------------------------ */

.variations,
form.cart .variations,
.woocommerce div.product form.cart .variations {
	width: 100% !important;
	max-width: 100% !important;
	table-layout: auto;
}

.variations td.value,
.variations td.woocommerce-variation-value,
.variations .value,
form.cart .variations td.value,
.woocommerce div.product form.cart .variations td.value {
	width: 100% !important;
	max-width: 100% !important;
	min-width: 0;
	box-sizing: border-box;
}

.variations th.label,
.variations .label {
	white-space: nowrap;
}

.vls-attr,
.vls-attr .vls-swatches {
	min-width: 0;
}

@media (max-width: 782px) {

	/* Narrow screens read better with the name above its options. */
	.variations,
	.variations tbody,
	.variations tr,
	.variations th.label,
	.variations td.value {
		display: block;
		width: 100%;
	}

	.variations th.label {
		padding-bottom: 4px;
		text-align: left;
		white-space: normal;
	}
}

/* ---------------------------------------------------------------------
 * Block
 * ------------------------------------------------------------------ */

.vls-attr {
	--vls-size: var(--vls-label-height, 40px);
	--vls-ratio: 1;
	display: block;
	width: 100%;
	margin: 0 0 var(--vls-block-gap, 4px);
}

.vls-attr--color {
	--vls-size: var(--vls-color-size, 40px);
	--vls-ratio: 1;
}

.vls-attr--image {
	--vls-size: var(--vls-image-size, 64px);
	--vls-ratio: var(--vls-image-ratio, 1);
}

.vls-attr--label,
.vls-attr--radio,
.vls-attr--select {
	--vls-size: var(--vls-label-height, 40px);
}

.vls-attr__head {
	display: flex;
	align-items: baseline;
	gap: 6px;
	margin-bottom: 8px;
}

.vls-attr__head[hidden] {
	display: none;
}

.vls-attr__name {
	font-weight: 600;
}

.vls-attr__selected,
.vls-selected-chip {
	font-weight: 400;
	opacity: 0.85;
}

.vls-selected-chip:not(:empty)::before {
	content: " ";
}

/* The native select stays in the DOM so WooCommerce keeps driving the form. */
.vls-attr select.vls-native {
	position: absolute !important;
	width: 1px !important;
	height: 1px !important;
	padding: 0 !important;
	margin: -1px !important;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0 !important;
}

/* ---------------------------------------------------------------------
 * Layouts
 * ------------------------------------------------------------------ */

.vls-attr .vls-swatches {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	gap: var(--vls-gap, 8px);
	margin: 0;
	padding: 0;
	list-style: none;
}

.vls-attr.vls-layout--grid .vls-swatches {
	display: grid;
	grid-template-columns: repeat(var(--vls-cols, 6), minmax(0, 1fr));
	align-items: start;
	justify-items: stretch;
}

.vls-attr.vls-layout--list .vls-swatches {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
}

.vls-attr.vls-layout--scroll .vls-swatches {
	flex-wrap: nowrap;
	overflow-x: auto;
	padding-bottom: 6px;
	scroll-snap-type: x proximity;
	scrollbar-width: thin;
}

.vls-attr.vls-layout--scroll .vls-swatches .vls-swatch {
	flex: 0 0 auto;
	scroll-snap-align: start;
}

/* ---------------------------------------------------------------------
 * Option — reset first, then rebuild
 * ------------------------------------------------------------------ */

.vls-attr .vls-swatches .vls-swatch {
	position: relative;
	display: inline-flex !important;
	flex-direction: column;
	align-items: center;
	gap: 4px;
	box-sizing: border-box;
	float: none !important;
	width: auto !important;
	min-width: 0 !important;
	max-width: 100%;
	height: auto !important;
	min-height: 0 !important;
	margin: 0 !important;
	padding: 0 !important;
	border: 0;
	border-radius: 0;
	background: none;
	box-shadow: none;
	color: var(--vls-text, #0f1111);
	font: inherit;
	font-weight: 400;
	letter-spacing: normal;
	line-height: 1.25;
	text-align: center;
	text-decoration: none;
	text-transform: none;
	cursor: pointer;
	appearance: none;
	-webkit-appearance: none;
}

.vls-attr .vls-swatches .vls-swatch:hover,
.vls-attr .vls-swatches .vls-swatch:focus,
.vls-attr .vls-swatches .vls-swatch:active {
	background: none;
	box-shadow: none;
	color: var(--vls-text, #0f1111);
	transform: none;
}

.vls-attr .vls-swatches .vls-swatch[hidden] {
	display: none !important;
}

.vls-attr .vls-swatches .vls-swatch__box {
	position: relative;
	box-sizing: border-box;
	display: flex;
	align-items: center;
	justify-content: center;
	width: var(--vls-size);
	height: var(--vls-size);
	overflow: hidden;
	border: var(--vls-border-width, 1px) solid var(--vls-border-color, #d5d9d9);
	border-radius: var(--vls-radius, 8px);
	background-color: var(--vls-bg, #fff);
	background-repeat: no-repeat;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.vls-attr .vls-swatches .vls-swatch__box img {
	position: absolute;
	inset: 0;
	display: block;
	box-sizing: border-box;
	width: 100% !important;
	height: 100% !important;
	max-width: none !important;
	margin: 0 !important;
	padding: var(--vls-image-padding, 0);
	border-radius: 0;
	object-fit: var(--vls-image-fit, cover);
}

.vls-attr .vls-swatches .vls-swatch__text {
	display: block;
	padding: 0 2px;
	font-size: var(--vls-font-size, 14px);
	font-weight: 500;
	white-space: nowrap;
}

/* Image tiles follow the chosen aspect ratio rather than forcing a square. */
.vls-attr--image .vls-swatches .vls-swatch__box {
	height: auto;
	min-height: 1px;
	aspect-ratio: var(--vls-ratio, 1);
}

/* In a grid the tile fills its column, so the column count sets the size. */
.vls-attr.vls-layout--grid .vls-swatches .vls-swatch {
	width: 100% !important;
}

.vls-attr--image.vls-layout--grid .vls-swatches .vls-swatch__box,
.vls-attr--color.vls-layout--grid .vls-swatches .vls-swatch__box {
	width: 100%;
	height: auto;
	aspect-ratio: var(--vls-ratio, 1);
}

/* Text options size to their content. */
.vls-attr--label .vls-swatches .vls-swatch__box,
.vls-attr--radio .vls-swatches .vls-swatch__box,
.vls-attr--select .vls-swatches .vls-swatch__box {
	width: auto;
	min-width: var(--vls-label-min-width, 56px);
	height: var(--vls-size);
	padding: 0 12px;
	overflow: visible;
	aspect-ratio: auto;
}

/* A text button must never be squeezed narrower than its label. Wrapping to
   another row is always better than cropping the word. */
.vls-attr--label:not(.vls-layout--grid):not(.vls-layout--list) .vls-swatches .vls-swatch,
.vls-attr--radio:not(.vls-layout--grid):not(.vls-layout--list) .vls-swatches .vls-swatch,
.vls-attr--select:not(.vls-layout--grid):not(.vls-layout--list) .vls-swatches .vls-swatch {
	flex: 0 0 auto;
}

.vls-attr--label.vls-layout--grid .vls-swatches .vls-swatch__box,
.vls-attr--radio.vls-layout--grid .vls-swatches .vls-swatch__box {
	width: 100%;
}

/* Radio dot. */
.vls-attr--radio .vls-swatches .vls-swatch__box::before {
	content: "";
	flex: 0 0 auto;
	width: 14px;
	height: 14px;
	margin-right: 8px;
	border: 1px solid var(--vls-border-color, #d5d9d9);
	border-radius: 50%;
	background: var(--vls-bg, #fff);
}

.vls-attr--radio .vls-swatches .vls-swatch.is-selected .vls-swatch__box::before {
	border-color: var(--vls-selected-color, #0f1111);
	box-shadow: inset 0 0 0 3px var(--vls-bg, #fff), inset 0 0 0 14px var(--vls-selected-color, #0f1111);
}

.vls-attr .vls-swatches .vls-swatch__caption {
	display: block;
	max-width: 100%;
	overflow: hidden;
	font-size: var(--vls-caption-size, 12px);
	text-overflow: ellipsis;
	white-space: nowrap;
}

.vls-attr .vls-swatches .vls-swatch__price {
	display: block;
	font-size: var(--vls-caption-size, 12px);
	opacity: 0.75;
}

/* ---------------------------------------------------------------------
 * States
 * ------------------------------------------------------------------ */

.vls-attr .vls-swatches .vls-swatch:hover .vls-swatch__box {
	border-color: var(--vls-hover-color, #007185);
}

.vls-attr .vls-swatches .vls-swatch:focus-visible {
	outline: none;
}

.vls-attr .vls-swatches .vls-swatch:focus-visible .vls-swatch__box {
	outline: 2px solid var(--vls-hover-color, #007185);
	outline-offset: 2px;
}

.vls-attr .vls-swatches .vls-swatch.is-selected .vls-swatch__box {
	border-color: var(--vls-selected-color, #0f1111);
	border-width: var(--vls-selected-width, 2px);
	box-shadow: 0 0 0 var(--vls-ring-width, 3px) var(--vls-ring-color, #c7e0e4);
}

.vls-attr .vls-swatches .vls-swatch.is-selected .vls-swatch__caption {
	font-weight: 600;
}

/* ---------------------------------------------------------------------
 * List rows
 * ------------------------------------------------------------------ */

.vls-attr.vls-layout--list .vls-swatches .vls-swatch {
	flex-direction: row;
	align-items: center;
	gap: 12px;
	width: 100% !important;
	padding: 8px 12px !important;
	border: var(--vls-border-width, 1px) solid var(--vls-border-color, #d5d9d9);
	border-radius: var(--vls-radius, 8px);
	background-color: var(--vls-bg, #fff);
	text-align: left;
}

.vls-attr.vls-layout--list .vls-swatches .vls-swatch:hover {
	border-color: var(--vls-hover-color, #007185);
	background-color: var(--vls-bg, #fff);
}

.vls-attr.vls-layout--list .vls-swatches .vls-swatch.is-selected {
	border-color: var(--vls-selected-color, #0f1111);
	box-shadow: 0 0 0 var(--vls-ring-width, 3px) var(--vls-ring-color, #c7e0e4);
}

.vls-attr.vls-layout--list .vls-swatches .vls-swatch__box {
	flex: 0 0 auto;
	width: calc(var(--vls-size) * 1.4);
	height: auto;
	min-width: 0;
	padding: 0;
	aspect-ratio: var(--vls-ratio, 1);
	box-shadow: none;
}

.vls-attr.vls-layout--list .vls-swatches .vls-swatch.is-selected .vls-swatch__box {
	border-width: var(--vls-border-width, 1px);
	box-shadow: none;
}

.vls-attr--label.vls-layout--list .vls-swatches .vls-swatch__box {
	display: none;
}

.vls-attr--radio.vls-layout--list .vls-swatches .vls-swatch__box {
	width: auto;
	min-width: 0;
	padding: 0;
	border: 0;
	background: none;
	aspect-ratio: auto;
}

.vls-attr--radio.vls-layout--list .vls-swatches .vls-swatch__text {
	display: none;
}

.vls-attr--radio.vls-layout--list .vls-swatches .vls-swatch__box::before {
	margin-right: 0;
}

.vls-attr.vls-layout--list .vls-swatches .vls-swatch__caption {
	flex: 1 1 auto;
	max-width: none;
	font-size: var(--vls-font-size, 14px);
	text-align: left;
}

.vls-attr.vls-layout--list .vls-swatches .vls-swatch__price {
	flex: 0 0 auto;
	margin-left: auto;
	font-size: var(--vls-font-size, 14px);
	opacity: 1;
}

/* ---------------------------------------------------------------------
 * Tooltip
 * ------------------------------------------------------------------ */

.vls-attr .vls-swatch__tip {
	position: absolute;
	bottom: calc(100% + 10px);
	left: 50%;
	z-index: 20;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 4px;
	min-width: 72px;
	padding: 6px;
	border-radius: 6px;
	background: #0f1111;
	color: #fff;
	font-size: 12px;
	opacity: 0;
	pointer-events: none;
	transform: translate(-50%, 4px);
	transition: opacity 0.15s ease, transform 0.15s ease;
}

.vls-attr .vls-swatch__tip img {
	position: static;
	display: block;
	width: 120px !important;
	height: auto !important;
	border-radius: 4px;
	object-fit: cover;
}

.vls-attr .vls-swatch__tip::after {
	content: "";
	position: absolute;
	top: 100%;
	left: 50%;
	border: 5px solid transparent;
	border-top-color: #0f1111;
	transform: translateX(-50%);
}

.vls-attr .vls-swatches .vls-swatch:hover .vls-swatch__tip,
.vls-attr .vls-swatches .vls-swatch:focus-visible .vls-swatch__tip {
	opacity: 1;
	transform: translate(-50%, 0);
}

/* ---------------------------------------------------------------------
 * Show more
 * ------------------------------------------------------------------ */

.vls-attr .vls-more {
	display: inline-block;
	width: auto !important;
	margin: 10px 0 0 !important;
	padding: 0 !important;
	border: 0 !important;
	background: none !important;
	box-shadow: none !important;
	color: var(--vls-hover-color, #007185);
	font: inherit;
	font-size: var(--vls-caption-size, 12px);
	text-transform: none;
	text-decoration: underline;
	cursor: pointer;
	appearance: none;
	-webkit-appearance: none;
}

.vls-attr .vls-more:hover {
	background: none !important;
	opacity: 0.75;
}

/* ---------------------------------------------------------------------
 * Mobile
 * ------------------------------------------------------------------ */

@media (max-width: 600px) {

	/* Colour and image tiles scale down. Text buttons must not: they size to
	   their own label, and a fixed width here would crop or overflow it. */
	.vls-attr--color:not(.vls-layout--grid):not(.vls-layout--list) .vls-swatches .vls-swatch__box {
		width: calc(var(--vls-size) * var(--vls-scale-mobile, 0.9));
		height: calc(var(--vls-size) * var(--vls-scale-mobile, 0.9));
	}

	.vls-attr--image:not(.vls-layout--grid):not(.vls-layout--list) .vls-swatches .vls-swatch__box {
		width: calc(var(--vls-size) * var(--vls-scale-mobile, 0.9));
	}

	.vls-attr--label .vls-swatches .vls-swatch__box,
	.vls-attr--radio .vls-swatches .vls-swatch__box,
	.vls-attr--select .vls-swatches .vls-swatch__box {
		width: auto;
		min-width: calc(var(--vls-label-min-width, 56px) * var(--vls-scale-mobile, 0.9));
		height: auto;
		min-height: calc(var(--vls-size) * var(--vls-scale-mobile, 0.9));
		padding: 6px 10px;
	}

	.vls-attr--label.vls-layout--grid .vls-swatches .vls-swatch__box,
	.vls-attr--radio.vls-layout--grid .vls-swatches .vls-swatch__box {
		width: 100%;
	}

	/* A long label wraps inside its button rather than spilling out of it. */
	.vls-attr .vls-swatches .vls-swatch__text {
		white-space: normal;
	}

	.vls-attr.vls-layout--grid .vls-swatches {
		grid-template-columns: repeat(var(--vls-cols-mobile, 4), minmax(0, 1fr));
	}

	/* In a grid the column count sets the tile size, so the mobile scale had
	   nothing to act on. Scale the tile inside its column and centre it, which
	   keeps the columns even while giving fine control over swatch size. */
	.vls-attr--color.vls-layout--grid .vls-swatches .vls-swatch__box,
	.vls-attr--image.vls-layout--grid .vls-swatches .vls-swatch__box {
		width: calc(100% * var(--vls-scale-mobile, 0.9));
		margin-left: auto;
		margin-right: auto;
	}
}

@media (prefers-reduced-motion: reduce) {

	.vls-attr .vls-swatches .vls-swatch__box,
	.vls-attr .vls-swatch__tip {
		transition: none;
	}
}

/* ---------------------------------------------------------------------
 * Catalog mode
 * ------------------------------------------------------------------ */

.woocommerce-variation-add-to-cart.vls-catalog {
	display: block;
	margin-top: 4px;
}

.woocommerce-variation-add-to-cart.vls-catalog:empty {
	display: none;
	margin: 0;
}

.vls-catalog-note {
	display: inline-block;
	color: var(--vls-text, #0f1111);
	font-size: var(--vls-font-size, 14px);
}

/* ---------------------------------------------------------------------
 * Outstanding choice prompt
 * ------------------------------------------------------------------ */

.vls-attr .vls-prompt {
	display: block;
	margin: 8px 0 0;
	padding: 0;
	color: var(--vls-prompt-color, #b12704);
	font-size: var(--vls-caption-size, 12px);
	line-height: 1.4;
}

.vls-attr .vls-prompt[hidden] {
	display: none;
}

.vls-attr .vls-prompt::before {
	content: "";
	display: inline-block;
	width: 0.55em;
	height: 0.55em;
	margin-right: 0.45em;
	border-radius: 50%;
	background: currentColor;
	vertical-align: middle;
}

/* A quiet nudge on the group that still needs attention. */
.vls-attr.is-pending .vls-swatches {
	position: relative;
}

.vls-attr.is-pending .vls-swatches::after {
	content: "";
	position: absolute;
	inset: -6px;
	border: 1px dashed var(--vls-prompt-color, #b12704);
	border-radius: calc(var(--vls-radius, 8px) + 4px);
	opacity: 0.45;
	pointer-events: none;
}
