/* Embroidery visualizer. Vanilla CSS — no build step, no framework. */

@font-face {
	font-family: "Haft Block";
	src: url("../fonts/haft-block.woff2") format("woff2");
	font-display: swap;
}

@font-face {
	font-family: "Haft Serif";
	src: url("../fonts/haft-serif.woff2") format("woff2");
	font-display: swap;
}

@font-face {
	font-family: "Haft Script";
	src: url("../fonts/haft-script.woff2") format("woff2");
	font-display: swap;
}

.haft-viz {
	display: grid;
	gap: 1.5rem;
	grid-template-columns: 1fr;
	max-width: 56rem;
}

@media (min-width: 40rem) {
	.haft-viz {
		grid-template-columns: 1fr 1fr;
	}
}

.haft-viz__stage {
	position: relative;
	line-height: 0;
}

/*
 * The stage is a gallery. The track scrolls horizontally and snaps slide by
 * slide, which is all the browser needs to page it by touch — no script. The
 * overlay is positioned against its slide, not the stage, so it keeps sitting
 * on the garment image while other slides scroll past.
 */
.haft-viz__frame {
	position: relative;
}

.haft-viz__track {
	display: flex;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
}

.haft-viz__track::-webkit-scrollbar {
	display: none;
}

@media ( prefers-reduced-motion: reduce ) {
	.haft-viz__track {
		scroll-behavior: auto;
	}
}

.haft-viz__slide {
	position: relative;
	flex: 0 0 100%;
	margin: 0;
	scroll-snap-align: start;
	scroll-snap-stop: always;
}

.haft-viz__image {
	display: block;
	width: 100%;
	height: auto;
}

/* The overlay sits exactly on top of the image. Its viewBox is set by JS from
   the image's natural dimensions, so the aspect ratio is preserved and the
   lettering is never stretched. */
.haft-viz__overlay {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
}

/*
 * Arrows are for pointers. On a phone the thumb does the paging, and a button
 * over the photo would only cover it. They stay `hidden` until the script
 * reveals them, because without the script they would do nothing.
 */
.haft-viz__arrow {
	display: none;
	position: absolute;
	top: 50%;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: #ffffff;
	color: #171a21;
	box-shadow: 0 2px 8px rgba( 23, 26, 33, 0.18 );
	transform: translateY( -50% );
	cursor: pointer;
}

@media ( hover: hover ) {
	.haft-viz__arrow:not( [hidden] ) {
		display: grid;
		place-items: center;
	}
}

.haft-viz__arrow--prev {
	left: 12px;
}

.haft-viz__arrow--next {
	right: 12px;
}

.haft-viz__arrow[disabled] {
	opacity: 0.35;
	cursor: default;
}

/* Thumbnails: a row of squares; the current one wears the shop's thread red. */
.haft-viz__thumbs {
	display: flex;
	gap: 8px;
	margin: 12px 0 0;
	padding: 0;
	list-style: none;
}

.haft-viz__thumb {
	display: block;
	border-radius: 2px;
	outline: 2px solid transparent;
	outline-offset: 2px;
}

.haft-viz__thumb img {
	display: block;
	width: 64px;
	height: 64px;
	object-fit: cover;
	border-radius: 2px;
}

.haft-viz__thumb[aria-current] {
	outline-color: #c41e3a;
}

/*
 * The lettering is stitched, not printed: the fill is a thread pattern and the
 * stroke is the same pattern run the other way, as a satin border. The stroke
 * is painted first so only its outer half shows around the fill — a border
 * that adds to the letter instead of eating into it. Round joins, because a
 * needle cannot make a sharp corner.
 */
.haft-viz__overlay text {
	paint-order: stroke fill;
	stroke-linejoin: round;
	stroke-linecap: round;
}

/*
 * Every choice on the product page reads as one row: caption left, control
 * right, on a shared vertical line.
 *
 * Stacked labels gave the column six separate left edges and made a short form
 * look like a long one. The label track is fixed rather than auto-sized so that
 * these fields line up with WooCommerce's own size and colour rows, which are a
 * <table> we cannot put in the same grid — the two only agree if both are told
 * the same width.
 */
/*
 * One grid for the whole form, not one grid per field.
 *
 * Per-field grids only line up if every field resolves its label column to the
 * same pixel, and the thread colour never could: it is a <fieldset>, whose
 * <legend> the browser lifts out of normal flow, so it was floated back into
 * place and landed half a row above everything else. Making each field
 * `display: contents` puts its label and its control into the parent's grid
 * directly — one column definition, one set of rows, nothing to keep in sync.
 */
.haft-viz__controls {
	display: grid;
	grid-template-columns: var( --haft-label-width, 9.5rem ) minmax( 0, 1fr );
	align-items: center;
	column-gap: 1rem;
	row-gap: 0.9rem;
}

.haft-viz__field {
	display: contents;
	margin: 0;
	border: 0;
	padding: 0;
}

.haft-viz__field > label,
.haft-viz__field > .haft-viz__label {
	grid-column: 1;
}

.haft-viz__field > :not( label ):not( .haft-viz__label ) {
	grid-column: 2;
}

/* The counter belongs under its input, not beside the label. */
.haft-viz__field > .haft-viz__counter {
	grid-column: 2;
	justify-self: start;
	margin-top: -0.55rem;
}

/* The price and the error speak about the whole form, so they span it. */
.haft-viz__price,
.haft-viz__error {
	grid-column: 1 / -1;
	margin: 0;
}

/*
 * WooCommerce's size and colour rows, put on the same line as the rest.
 *
 * It ships them as a real <table> — th.label, td.value — which the theme stacks.
 * Unpicking the table display is what lets a row become a grid, and the label
 * track is the same variable the embroidery fields use, so the two blocks share
 * one vertical line rather than nearly sharing one.
 */
form.variations_form table.variations,
form.variations_form table.variations tbody,
form.variations_form table.variations th {
	display: block;
	padding: 0;
	border: 0;
	text-align: left;
}

/*
 * Matching Blocksy's own selector, not out-competing it with a longer one.
 *
 * The theme sets `form.variations_form table.variations tr { display: flex;
 * flex-direction: column }` — that is what stacked the label above the control
 * and centred both. A shorter selector loses to it silently: the grid columns
 * were computed and then ignored, because display was still flex.
 */
form.variations_form table.variations tr {
	display: grid;
	grid-template-columns: var( --haft-label-width, 9.5rem ) minmax( 0, 1fr );
	align-items: center;
	/* Shorthand, because Blocksy sets `gap: 10px` on this rule and a lone
	   column-gap would leave its row-gap in place. */
	gap: 0 1rem;
	margin: 0 0 0.9rem;
}

form.variations_form table.variations tr:not( :last-child ) {
	margin-bottom: 0.9rem;
}

form.variations_form table.variations td {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 10px;
	padding: 0;
	border: 0;
}

form.variations_form table.variations th.label label {
	margin: 0;
}

@media ( max-width: 47.99rem ) {
	.haft-viz__controls,
	form.variations_form table.variations tr {
		grid-template-columns: minmax( 0, 1fr );
	}

	.haft-viz__controls {
		row-gap: 0.35rem;
	}

	.haft-viz__field > label,
	.haft-viz__field > .haft-viz__label,
	.haft-viz__field > :not( label ):not( .haft-viz__label ) {
		grid-column: 1;
	}

	.haft-viz__field > .haft-viz__counter {
		margin-top: 0;
		margin-bottom: 0.55rem;
	}
}

.haft-viz__counter {
	font-size: 0.8125rem;
	opacity: 0.65;
}

.haft-viz__swatches {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}

.haft-viz__swatch input {
	position: absolute;
	opacity: 0;
}

.haft-viz__swatch span:first-of-type {
	display: block;
	width: 2rem;
	height: 2rem;
	border: 2px solid rgba(0, 0, 0, 0.15);
	border-radius: 50%;
	cursor: pointer;
}

.haft-viz__swatch input:checked + span,
.haft-viz__swatch input:focus-visible + span {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}

.haft-viz__price {
	font-weight: 600;
}

.haft-viz__error {
	color: #b3222a;
	min-height: 1.25rem;
}

.haft-viz__error:empty {
	display: none;
}

.haft-viz__field textarea {
	width: 100%;
	padding: 0.6rem 0.75rem;
	border: 1px solid rgba( 23, 26, 33, 0.2 );
	border-radius: 2px;
	font: inherit;
	resize: vertical;
}

.haft-swatches {
	display: flex;
	flex-wrap: wrap;
	gap: 0.55rem;
	margin-bottom: 0.5rem;
}

.haft-swatches__dot {
	width: 34px;
	height: 34px;
	padding: 0;
	border: 2px solid transparent;
	border-radius: 50%;
	box-shadow: 0 0 0 1px rgba( 23, 26, 33, 0.18 );
	cursor: pointer;
}

.haft-swatches__dot[aria-pressed="true"] {
	border-color: #fff;
	box-shadow: 0 0 0 2px #171a21;
}

/*
 * Hidden from sight, not from assistive technology. The select is still the
 * real control — the swatches only drive it — so a keyboard user must be able
 * to reach it.
 */
.haft-swatches__select {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect( 1px, 1px, 1px, 1px );
	white-space: nowrap;
}

/* --- Personalized product page ------------------------------------------------
 * On a product with an embroidery zone the visualizer stage IS the product
 * image, so the theme's gallery is removed (see Haft_Woo::render_stage) and any
 * lingering wrapper hidden. The stage and the summary then sit side by side.
 */
body.haft-personalized .woocommerce-product-gallery {
	display: none;
}

/*
 * A wider column than the rest of the shop, and only here.
 *
 * The site is laid out for 1290px, which is right for prose and for the home
 * page. A personalized product carries two heavy columns side by side — a photo
 * you are meant to inspect and a form you are meant to fill in — and at 1290 the
 * form ends up narrow enough to wrap its own labels. Retuning Blocksy's variable
 * rather than setting max-width keeps the theme's container maths intact.
 */
body.haft-personalized .product-entry-wrapper {
	--theme-block-max-width: 1450px;
}

@media (min-width: 48rem) {
	body.haft-personalized .product-entry-wrapper {
		display: grid;
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
		gap: 3rem;
		align-items: start;
	}

	/*
	 * Blocksy sizes the summary at 50% for its own float layout, where the
	 * percentage is of the whole row. Inside this grid the percentage is of the
	 * track, so the column came out half empty — 311px of a 621px track — and
	 * the product title wrapped onto a second line with 300px of nothing beside
	 * it. A grid item does not need a width; the track already is one.
	 */
	body.haft-personalized .product-entry-wrapper > .summary {
		width: 100%;
		max-width: none;
	}
}

body.haft-personalized .haft-viz__stage {
	max-width: 40rem;
}

/*
 * One column on a phone: the summary follows the stage directly, and the
 * product title was starting on the thumbnails' outline. The gap the grid gives
 * on wider screens is given here as a margin instead.
 */
@media (max-width: 47.99rem) {
	body.haft-personalized .haft-viz__stage {
		margin-bottom: 1.5rem;
	}
}

/* --- Size chart modal --------------------------------------------------------- */
.haft-size-chart__trigger button {
	padding: 0;
	border: 0;
	background: none;
	color: inherit;
	font: inherit;
	text-decoration: underline;
	cursor: pointer;
}

.haft-size-chart {
	max-width: 32rem;
	padding: 1.5rem;
	border: 1px solid rgba( 23, 26, 33, 0.2 );
	border-radius: 2px;
}

.haft-size-chart::backdrop {
	background: rgba( 23, 26, 33, 0.55 );
}

.haft-size-chart__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	margin-bottom: 1rem;
}

.haft-size-chart__body table {
	width: 100%;
	border-collapse: collapse;
}

.haft-size-chart__body th,
.haft-size-chart__body td {
	padding: 0.5rem 0.75rem;
	border-bottom: 1px solid rgba( 23, 26, 33, 0.12 );
	text-align: left;
}
