/*
 * Single product page.
 *
 * The hero (gallery + buy column) follows the client's product-page design:
 * a 55/45 split on a white ground, the product photography in a soft grey
 * frame, and the buy column as a plain stack rather than a bordered card.
 * Local tokens below are the few values that design pins down more tightly
 * than theme.json's global scale.
 */

.product-summary {
	--pdp-radius-media: 18px;
	--pdp-radius-control: 12px;
	--pdp-control-h: 60px;
	--pdp-surface: #f5f5f5;

	margin-block: var(--wp--preset--spacing--8) var(--wp--custom--section--padding-tight);
}

/*
 * Three layouts, on the same breakpoints the gallery uses so the two never
 * disagree: one column below 768px, an even split through the tablet range,
 * and the design's 55/45 from 1024px up.
 *
 * The split is stated here rather than left to the columns block's own width
 * attributes. Core only honours a column's `flex-basis` inline style through
 * `.wp-block-column[style*=flex-basis] { flex-grow: 0 }` inside its own
 * `min-width: 782px` query - and with that query out of the picture both
 * columns just grow equally from a 100% basis, which is a 50/50 split with
 * the design's proportions quietly gone. Naming the two columns is immune to
 * that.
 *
 * Core's own `.wp-block-columns { flex-wrap: nowrap !important }` (active
 * from 782px up) beats a plain override regardless of source order - only
 * another !important can win against it.
 */
@media (max-width: 767px) {
	.product-summary {
		flex-wrap: wrap !important;
	}

	.product-summary > .wp-block-column {
		flex-basis: 100% !important;
		width: 100% !important;
	}
}

@media (min-width: 768px) and (max-width: 1023px) {
	.product-summary > .product-summary__media,
	.product-summary > .product-summary__buybox {
		flex: 0 1 50%;
	}
}

@media (min-width: 1024px) {
	.product-summary > .product-summary__media {
		flex: 0 1 55%;
	}

	.product-summary > .product-summary__buybox {
		flex: 0 1 45%;
	}
}

/*
 * WooCommerce's default sale flash is an olive pill - the one element on the
 * site that escaped the monochrome palette, because it is coloured by core CSS
 * rather than a theme token. The discount is shown by .pdp-flag--sale instead,
 * which says the actual percentage.
 */
.product-summary__media .onsale {
	display: none;
}

/* --- Gallery ------------------------------------------------------------ */

.product-summary__media {
	position: relative;
}

/*
 * Neither column is sticky: the gallery is stretched to the buy column's
 * height further down, so a sticky column would have no travel to make.
 */

/*
 * WooCommerce's own block CSS (product-image-gallery.css) hard-caps
 * `.wp-block-woocommerce-product-image-gallery` at max-width:512px - a
 * generic default meant for a narrower theme layout. It silently capped this
 * gallery at 512px regardless of the media column's own width, so widening
 * that column alone did nothing; this override lets the column's width (see
 * templates/single-product.html) actually govern the gallery's size.
 */
.product-summary__media .wp-block-woocommerce-product-image-gallery {
	max-width: none;
}

/*
 * Thumbs-left, main image right - a grid so DOM order (thumbs render last,
 * WooCommerce's own markup) doesn't have to match visual order.
 *
 * The thumb column is a percentage (clamped) rather than a fixed pixel width
 * so it scales with the main image instead of the two drifting apart.
 */
.product-summary__media .woocommerce-product-gallery {
	position: relative;
	display: grid;
	grid-template-columns: clamp(72px, 13%, 104px) 1fr;
	grid-template-areas: "thumbs main";
	gap: var(--wp--preset--spacing--3);
}

.product-summary__media .woocommerce-product-gallery__wrapper {
	grid-area: main;
	border-radius: var(--pdp-radius-media);
	overflow: hidden;
	background: var(--pdp-surface);
	position: relative;
}

.product-summary__media .flex-viewport {
	grid-area: main;
	border-radius: var(--pdp-radius-media);
	background: var(--pdp-surface);
}

/*
 * A square frame with the product floated inside it, rather than a box that
 * takes whatever shape the source photo has: the catalogue mixes 1:1 product
 * renders with wider lifestyle shots, and letting each set its own height
 * made the gallery jump as the shopper stepped through the slides.
 */
.product-summary__media .woocommerce-product-gallery__image,
.product-summary__media .woocommerce-product-gallery__image > a {
	display: block;
}

/*
 * `:not(.zoomImg)` is load-bearing. With `wc-product-gallery-zoom` support on,
 * jquery.zoom injects a second <img class="zoomImg"> as a sibling inside this
 * same container and drives it with inline width/height/position - it is
 * deliberately much larger than the frame, which is the whole magnification
 * effect. Styling it like the slide (square, contained, padded, opaque
 * background) shrank the magnified copy back to the frame and put a solid
 * panel over the photo on hover, i.e. it quietly disabled zoom.
 */
.product-summary__media .woocommerce-product-gallery__image img:not(.zoomImg) {
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: contain;
	padding: clamp(16px, 4%, 40px);
	box-sizing: border-box;
	border-radius: var(--pdp-radius-media);
	background: var(--pdp-surface);
}

/*
 * Desktop: the grey photo panel runs the full height of the buy column, so
 * the two blocks start and finish on the same line whatever the product is -
 * a longer short description or a missing warranty line changes the buy
 * column's height, and the gallery side follows instead of leaving a ragged
 * gap under itself.
 *
 * The panel is a pseudo-element in the grid's `main` cell rather than a
 * height forced onto flexslider's own boxes. Forcing it there does not just
 * fail, it feeds back: flexslider measures its slides to write an inline
 * pixel height on `.flex-viewport`, so making the slides a percentage of
 * that height makes each measurement larger than the last - the row grew
 * past 3000px on a five-image gallery. Everything flexslider sizes is left
 * exactly as it sizes it, and only the painted panel behind it stretches.
 */
@media (min-width: 1024px) {
	/* The column's own block gap would push the gallery down 24px while the
	   panel still measured the full column, overflowing the bottom by exactly
	   that much. The gallery is the column's only laid-out child - the flags
	   overlay is absolute - so it starts flush with the top. */
	.product-summary__media .wp-block-woocommerce-product-image-gallery {
		margin-block: 0;
		height: 100%;
	}

	.product-summary__media .woocommerce-product-gallery {
		height: 100%;
	}

	.product-summary__media .woocommerce-product-gallery::before {
		content: "";
		grid-area: main;
		align-self: stretch;
		border-radius: var(--pdp-radius-media);
		background: var(--pdp-surface);
	}

	/* The photo keeps its natural square and centres in the taller panel;
	   the thumbnail rail stays at the top where the eye expects it. */
	.product-summary__media .flex-viewport,
	.product-summary__media .woocommerce-product-gallery__wrapper {
		align-self: center;
		background: transparent;
		z-index: 1;
	}

	.product-summary__media .flex-control-thumbs {
		align-self: start;
	}
}

/* --- Gallery overlay controls (assets/js/product-gallery.js) ------------- */

.pdp-gallery-nav {
	/* A child of .flex-viewport (position: relative, set by flexslider itself)
	   - inset: 0 tracks its size automatically, including flexslider's own
	   per-slide height transition. */
	position: absolute;
	inset: 0;
	pointer-events: none;
	z-index: 2;
}

.pdp-gallery-nav__group {
	pointer-events: none;
	position: absolute;
	right: var(--wp--preset--spacing--4);
	bottom: var(--wp--preset--spacing--4);
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--3);
}

.pdp-gallery-nav__btn {
	pointer-events: auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	border: 1px solid var(--wp--custom--border--on-light);
	border-radius: 50%;
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	box-shadow: var(--wp--custom--shadow--sm);
	cursor: pointer;
	transition:
		background var(--wp--custom--duration--fast) var(--wp--custom--ease--out),
		color var(--wp--custom--duration--fast) var(--wp--custom--ease--out),
		transform var(--wp--custom--duration--fast) var(--wp--custom--ease--out);
}

.pdp-gallery-nav__btn:hover {
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
}

.pdp-gallery-nav__btn:active {
	transform: scale(0.94);
}

.pdp-gallery-nav__counter {
	/* Pure text label ("1 / 8") - never a click target. pointer-events here
	   also matters for WooCommerce's zoom.js, which binds hover to
	   .woocommerce-product-gallery__image: a hit-target sitting over the
	   image reads as genuinely leaving it, so zoom would toggle off and on
	   as the cursor crossed the label. */
	pointer-events: none;
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--preset--color--contrast-muted);
	font-variant-numeric: tabular-nums;
}

/*
 * WooCommerce's own PhotoSwipe trigger, restyled and (in product-gallery.js)
 * moved into the overlay so it sits over the image's bottom-left corner
 * rather than the gallery grid's. It keeps its href/role/aria and stays a
 * descendant of .woocommerce-product-gallery, which is what WooCommerce
 * delegates the lightbox click from.
 *
 * The selector is deliberately longer than it looks like it needs to be:
 * woocommerce.css ships `.woocommerce div.product div.images
 * .woocommerce-product-gallery__trigger { top: .5em; font-size: 2em }` at
 * specificity (0,4,2), and the block template really does render inside
 * `.woocommerce`/`div.product` wrappers - so a shorter selector lost, `top:
 * auto` never applied, and the button stayed pinned to the top corner with
 * `bottom` silently ignored. Naming both element types and the gallery's own
 * class clears (0,4,2) outright instead of tying it and relying on load order.
 */
.product-summary div.product-summary__media div.images.woocommerce-product-gallery .woocommerce-product-gallery__trigger {
	pointer-events: auto;
	position: absolute;
	left: var(--wp--preset--spacing--4);
	bottom: var(--wp--preset--spacing--4);
	top: auto;
	right: auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* WooCommerce sizes this anchor in content-box terms; without this it ends
	   up 2px wider than the arrow buttons it sits opposite. */
	box-sizing: border-box;
	width: 38px;
	height: 38px;
	margin: 0;
	padding: 0;
	border: 1px solid var(--wp--custom--border--on-light);
	border-radius: 50%;
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	box-shadow: var(--wp--custom--shadow--sm);
	font-size: 0;
	line-height: 0;
	text-decoration: none;
	transition:
		background var(--wp--custom--duration--fast) var(--wp--custom--ease--out),
		color var(--wp--custom--duration--fast) var(--wp--custom--ease--out);
}

.product-summary div.product-summary__media div.images.woocommerce-product-gallery .woocommerce-product-gallery__trigger:hover {
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
}

/* --- Flags over the gallery ---------------------------------------------- */

.pdp-flags {
	position: absolute;
	top: var(--wp--preset--spacing--4);
	right: var(--wp--preset--spacing--4);
	z-index: 3;
	display: flex;
	flex-wrap: wrap;
	justify-content: flex-end;
	gap: var(--wp--preset--spacing--2);
	pointer-events: none;
}

.pdp-flag {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 7px 12px;
	border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	box-shadow: var(--wp--custom--shadow--sm);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 700;
	line-height: 1.2;
}

.pdp-flag__icon {
	width: 14px;
	height: 14px;
}

.pdp-flag--sale,
.pdp-flag--oos {
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
	font-variant-numeric: tabular-nums;
}

/* Thumbnail rail: vertical, not the default horizontal strip. */
.product-summary__media .flex-control-thumbs {
	grid-area: thumbs;
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--3);
	list-style: none;
	margin: 0;
	padding: 0;
	max-height: 100%;
	overflow-y: auto;
	scrollbar-width: none;
}

.product-summary__media .flex-control-thumbs::-webkit-scrollbar {
	display: none;
}

/*
 * WooCommerce's own core CSS (`.woocommerce div.product div.images
 * .flex-control-thumbs li { width: 25% }`) is written for its default
 * four-per-row horizontal strip and outranks a plain override here on
 * specificity alone - width: 100% below did nothing without !important,
 * silently capping every thumbnail at a quarter of this column's width no
 * matter how wide the column itself was made.
 */
.product-summary__media .flex-control-thumbs li {
	margin: 0;
	width: 100% !important;
	float: none !important;
}

.product-summary__media .flex-control-thumbs img {
	display: block;
	box-sizing: border-box;
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: contain;
	padding: 10%;
	background: var(--pdp-surface);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--pdp-radius-control);
	cursor: pointer;
	transition:
		border-color var(--wp--custom--duration--fast) var(--wp--custom--ease--out),
		transform var(--wp--custom--duration--fast) var(--wp--custom--ease--out);
}

.product-summary__media .flex-control-thumbs img:hover {
	border-color: var(--wp--preset--color--contrast-muted);
	transform: translateY(-1px);
}

.product-summary__media .flex-control-thumbs img.flex-active {
	border-color: var(--wp--preset--color--contrast);
	border-width: 2px;
}

/*
 * Scroll affordance for a rail taller than the main image. It sits over the
 * foot of the thumbnail column - matching that column's own width so it never
 * strays under the photo - and fades the last thumbnail out beneath itself
 * rather than sitting on top of it as an opaque button. product-gallery.js
 * keeps it hidden unless the rail actually overflows.
 */
.pdp-thumbs-more {
	position: absolute;
	left: 0;
	bottom: 0;
	z-index: 2;
	width: clamp(72px, 13%, 104px);
	height: 46px;
	display: flex;
	align-items: flex-end;
	justify-content: center;
	padding-bottom: 4px;
	border: 0;
	background: linear-gradient(to bottom, rgba(255, 255, 255, 0), var(--wp--preset--color--base) 70%);
	color: var(--wp--preset--color--contrast-muted);
	cursor: pointer;
	transition: color var(--wp--custom--duration--fast) var(--wp--custom--ease--out);
}

.pdp-thumbs-more[hidden] {
	display: none;
}

.pdp-thumbs-more:hover {
	color: var(--wp--preset--color--contrast);
}

@media (max-width: 767px) {
	.product-summary__media .woocommerce-product-gallery {
		grid-template-columns: 1fr;
		grid-template-areas: "main" "thumbs";
	}

	/* Horizontal, swipeable strip under the image on phones. */
	.product-summary__media .flex-control-thumbs {
		flex-direction: row;
		flex-wrap: nowrap;
		max-height: none;
		overflow-x: auto;
		padding-bottom: 2px;
	}

	.product-summary__media .flex-control-thumbs li {
		flex: 0 0 auto;
		width: 64px !important;
	}

	.pdp-thumbs-more {
		display: none;
	}
}

/* --- Buy column ---------------------------------------------------------- */

.product-summary__buybox-card {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--5);
}

/* --- Meta row (category pill + share) ------------------------------------ */

.pdp-hero-meta {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--3);
	margin-bottom: calc(var(--wp--preset--spacing--5) * -1 + var(--wp--preset--spacing--1));
}

.pdp-hero-meta__badge {
	display: inline-flex;
	align-items: center;
	padding: 6px 14px;
	border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--base-subtle);
	color: var(--wp--preset--color--contrast);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 600;
	letter-spacing: 0.01em;
	text-decoration: none;
	transition: background var(--wp--custom--duration--fast) var(--wp--custom--ease--out);
}

.pdp-hero-meta__badge:hover {
	background: var(--wp--preset--color--border);
	color: var(--wp--preset--color--contrast);
}

/* --- Title, lead --------------------------------------------------------- */

.product-summary__buybox-card .wp-block-post-title {
	margin: 0;
	font-size: clamp(1.75rem, 3.2vw, 2.625rem);
	font-weight: 700;
	line-height: 1.05;
	letter-spacing: -0.035em;
	text-wrap: balance;
}

.pdp-hero-lead {
	margin: 0;
	color: var(--wp--preset--color--contrast-subtle);
	font-size: var(--wp--preset--font-size--base);
	line-height: 1.55;
}

.pdp-hero-lead p {
	margin: 0;
}

.pdp-hero-lead p + p {
	margin-top: var(--wp--preset--spacing--2);
}

.product-summary__sku {
	margin: 0;
	font-size: var(--wp--preset--font-size--xs);
	color: var(--wp--preset--color--contrast-muted);
}

/* --- Feature cards ------------------------------------------------------- */

.pdp-hero-specs {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: var(--wp--preset--spacing--3);
	list-style: none;
	margin: var(--wp--preset--spacing--1) 0;
	padding: var(--wp--preset--spacing--5) 0;
	border-block: 1px solid var(--wp--preset--color--border);
}

/* Fewer than four facts spread out rather than leaving a ragged gap. */
.pdp-hero-specs[data-count="1"] {
	grid-template-columns: minmax(0, 1fr);
}

.pdp-hero-specs[data-count="2"] {
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

.pdp-hero-specs[data-count="3"] {
	grid-template-columns: repeat(3, minmax(0, 1fr));
}

.pdp-hero-spec {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 6px;
	min-width: 0;
}

.pdp-hero-spec__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	margin-bottom: 2px;
	border-radius: var(--pdp-radius-control);
	background: var(--pdp-surface);
	color: var(--wp--preset--color--contrast);
}

.pdp-hero-spec__icon svg {
	width: 20px;
	height: 20px;
}

.pdp-hero-spec__value {
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 700;
	line-height: 1.25;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--contrast);
	overflow-wrap: anywhere;
}

.pdp-hero-spec__label {
	font-size: var(--wp--preset--font-size--xs);
	line-height: 1.3;
	color: var(--wp--preset--color--contrast-muted);
	overflow-wrap: anywhere;
}

@media (max-width: 479px) {
	.pdp-hero-specs,
	.pdp-hero-specs[data-count="3"] {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--wp--preset--spacing--4);
	}
}

/* --- Price -------------------------------------------------------------- */

.pdp-price {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--2) var(--wp--preset--spacing--3);
	font-variant-numeric: tabular-nums;
}

.pdp-price__now {
	font-size: clamp(1.75rem, 2.6vw, 2.5rem);
	font-weight: 700;
	line-height: 1.05;
	letter-spacing: -0.04em;
	color: var(--wp--preset--color--contrast);
}

.pdp-price__now .woocommerce-Price-amount,
.pdp-price__was .woocommerce-Price-amount {
	font-size: inherit;
	font-weight: inherit;
	color: inherit;
}

.pdp-price__was {
	font-size: var(--wp--preset--font-size--lg);
	color: var(--wp--preset--color--contrast-muted);
	text-decoration-thickness: 1px;
}

.pdp-price__badge {
	align-self: center;
	padding: 5px 10px;
	border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 700;
	line-height: 1.4;
	font-variant-numeric: tabular-nums;
}

/* --- Purchase row -------------------------------------------------------- */

.product-summary__actions {
	align-items: stretch;
	gap: var(--wp--preset--spacing--3);
	flex-wrap: nowrap;
}

/*
 * The add-to-cart-form block is the whole left part of the row: it carries
 * the quantity stepper and the real submit button, and takes all the width
 * the wishlist square leaves. Sizing the block wrapper (rather than only the
 * form inside it) is what keeps the row from collapsing when WooCommerce's
 * Interactivity API re-renders the block's contents.
 */
.product-summary__actions .wp-block-woocommerce-add-to-cart-form {
	flex: 1 1 auto;
	min-width: 0;
}

/*
 * woocommerce.css sets `.woocommerce div.product form.cart { margin-bottom:
 * 2em }` at (0,4,2) - inside this row that margin is dead space that makes
 * the block wrapper taller than the controls in it, so the wishlist square
 * stopped lining up with the quantity stepper and the buy button. The spacing
 * between the row and what follows it belongs to the column's own gap, so the
 * form keeps no margin of its own; the selector is long enough to actually
 * win that rule.
 */
.product-summary div.product-summary__actions .wp-block-woocommerce-add-to-cart-form form.cart:not(.variations_form),
.product-summary__actions .cart:not(.variations_form) {
	display: flex;
	flex-wrap: nowrap;
	align-items: stretch;
	gap: var(--wp--preset--spacing--3);
	margin: 0;
	width: 100%;
}

/*
 * A variable product's form is not a single row: WooCommerce puts the
 * attribute dropdowns in a `.variations` table above, and only the price,
 * quantity and button inside `.woocommerce-variation-add-to-cart` (which it
 * swaps in and out as a variation is chosen). Laying that form out as a flex
 * row would stand the dropdowns beside the button. So the form stays a normal
 * block and the row treatment moves to the part that actually is the row.
 *
 * The catalogue is all simple products today - this keeps the design correct
 * for the first variable one rather than breaking on it.
 */
.product-summary div.product-summary__actions .wp-block-woocommerce-add-to-cart-form form.cart.variations_form,
.product-summary__actions .cart.variations_form {
	display: block;
	margin: 0;
	width: 100%;
}

.product-summary__actions .variations_form .woocommerce-variation-add-to-cart {
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
	gap: var(--wp--preset--spacing--3);
	margin-top: var(--wp--preset--spacing--4);
}

.product-summary__actions .variations_form .variations {
	width: 100%;
	border-collapse: collapse;
}

.product-summary__actions .variations_form .variations th,
.product-summary__actions .variations_form .variations td {
	padding: 0 0 var(--wp--preset--spacing--3);
	text-align: left;
	vertical-align: middle;
}

.product-summary__actions .variations_form .variations select {
	width: 100%;
	min-height: 48px;
	padding: 0 var(--wp--preset--spacing--3);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--pdp-radius-control);
	background: var(--wp--preset--color--base);
	font-size: var(--wp--preset--font-size--sm);
}

/* WooCommerce prints the selected variation's own price here; the headline
   price above already carries that job. */
.product-summary__actions .variations_form .woocommerce-variation-price {
	width: 100%;
	font-size: var(--wp--preset--font-size--lg);
	font-weight: 700;
}

/*
 * Plain number input: the fallback shape when the stepper style is off.
 *
 * The `:not()` matters - WooCommerce gives the stepper BOTH classes
 * (`quantity wc-block-components-quantity-selector`), so without it this rule
 * also claimed the stepper's own input and, being the more specific of the
 * two, blew it up to 88x89px inside a 60px-tall control.
 */
.product-summary__actions .quantity:not(.wc-block-components-quantity-selector) input[type="number"] {
	height: var(--pdp-control-h);
	width: 88px;
	padding: 0 var(--wp--preset--spacing--2);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--pdp-radius-control);
	font-size: var(--wp--preset--font-size--base);
	font-variant-numeric: tabular-nums;
	text-align: center;
}

/* Stepper style (quantitySelectorStyle: "stepper" on the add-to-cart-form block). */
.product-summary__actions .wc-block-components-quantity-selector {
	flex: 0 0 auto;
	display: flex;
	align-items: stretch;
	height: var(--pdp-control-h);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--pdp-radius-control);
	overflow: hidden;
	background: var(--wp--preset--color--base);
}

.product-summary__actions .wc-block-components-quantity-selector__button {
	flex: 0 0 auto;
	width: 40px;
	border: 0;
	background: none;
	color: var(--wp--preset--color--contrast-subtle);
	cursor: pointer;
	font-size: var(--wp--preset--font-size--lg);
	transition:
		background var(--wp--custom--duration--fast) var(--wp--custom--ease--out),
		color var(--wp--custom--duration--fast) var(--wp--custom--ease--out);
}

.product-summary__actions .wc-block-components-quantity-selector__button:hover {
	background: var(--pdp-surface);
	color: var(--wp--preset--color--contrast);
}

/*
 * The stepper's number.
 *
 * padding and font-size carry !important because the add-to-cart-form block
 * inlines `div.wc-block-add-to-cart-form--stepper .wc-block-components-
 * quantity-selector input[type="number"].input-text.qty.text { padding:
 * .9rem 0; font-size: small }` - roughly (0,7,2), which no reasonable
 * selector here beats. Left alone it made the input 87px tall inside a 60px
 * control (the padding is content-box) and dropped the number to 13px, so it
 * sat visibly below the - and + it belongs between.
 */
.product-summary__actions .wc-block-components-quantity-selector input[type="number"] {
	box-sizing: border-box;
	flex: 0 0 auto;
	width: 42px;
	height: 100%;
	min-height: 0;
	padding: 0 !important;
	border: 0;
	background: none;
	text-align: center;
	font-size: var(--wp--preset--font-size--base) !important;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	color: var(--wp--preset--color--contrast);
}

.product-summary__actions .single_add_to_cart_button,
.product-summary__actions .wp-block-woocommerce-add-to-cart-form .wc-block-add-to-cart-form button {
	flex: 1 1 auto;
	min-width: 0;
	height: var(--pdp-control-h);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	padding-inline: var(--wp--preset--spacing--5);
	border: 0;
	border-radius: var(--pdp-radius-control);
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
	font-size: var(--wp--preset--font-size--base);
	font-weight: 600;
	letter-spacing: -0.01em;
	transition:
		background var(--wp--custom--duration--fast) var(--wp--custom--ease--out),
		transform var(--wp--custom--duration--fast) var(--wp--custom--ease--out);
}

.product-summary__actions .single_add_to_cart_button:hover {
	background: var(--wp--preset--color--primary-hover);
	color: var(--wp--preset--color--base);
}

.product-summary__actions .single_add_to_cart_button:active {
	transform: scale(0.99);
}

/*
 * The cart glyph is decorative and belongs to the button's styling, not its
 * label - WooCommerce owns the text ("Додати в кошик", or whatever
 * add_to_cart_text() returns for the product type), so drawing the icon in
 * CSS leaves that string alone.
 */
.product-summary__actions .single_add_to_cart_button::before {
	content: "";
	flex: 0 0 auto;
	width: 20px;
	height: 20px;
	background: currentColor;
	-webkit-mask: var(--pdp-cart-icon) center / contain no-repeat;
	mask: var(--pdp-cart-icon) center / contain no-repeat;
}

.product-summary {
	--pdp-cart-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 4h2l2.4 10.4a2 2 0 0 0 2 1.6h7.5a2 2 0 0 0 2-1.55L20.5 8H6'/%3E%3Ccircle cx='10' cy='20' r='1.4'/%3E%3Ccircle cx='17.5' cy='20' r='1.4'/%3E%3C/svg%3E");
}

@media (max-width: 479px) {
	.product-summary {
		--pdp-control-h: 56px;
	}
}

/*
 * Two widths leave the purchase row about 115px for the buy button once the
 * stepper and the wishlist square have taken theirs: a 375px phone, and the
 * tablet range, where the buy column is only half of an 800px page. That is
 * not enough for the label WooCommerce puts on the button ("Додати в кошик"),
 * which wrapped to three lines inside a fixed-height control. At both widths
 * the button takes a row of its own instead:
 *
 *     [ - 1 + ]   [ heart ]
 *     [   Додати в кошик   ]
 *
 * The button keeps its full size and glyph rather than being shrunk to fit,
 * and the label stays whatever WooCommerce decides it is - a longer one on
 * another product type still has a whole row to sit on.
 */
@media (max-width: 479px), (min-width: 768px) and (max-width: 1023px) {
	/* Both selectors repeat the specificity of the desktop rules they override
	   - those are written long enough to beat woocommerce.css (and carry
	   `:not(.variations_form)`), so a shorter selector here would silently
	   lose to them. */
	.product-summary div.product-summary__actions .wp-block-woocommerce-add-to-cart-form form.cart:not(.variations_form),
	.product-summary__actions .cart:not(.variations_form) {
		flex-wrap: wrap;
	}

	.product-summary__actions .single_add_to_cart_button,
	.product-summary__actions .wp-block-woocommerce-add-to-cart-form .wc-block-add-to-cart-form button {
		flex: 1 1 100%;
	}

	/* The square keeps to the stepper's line instead of stretching down the
	   two-row form beside it. */
	.pdp-icon-btn--wishlist {
		align-self: flex-start;
	}
}

/* --- Icon buttons (wishlist, share) --------------------------------------- */

.pdp-icon-btn {
	appearance: none;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	width: var(--pdp-control-h);
	height: var(--pdp-control-h);
	padding: 0;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--pdp-radius-control);
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast-subtle);
	cursor: pointer;
	transition:
		border-color var(--wp--custom--duration--fast) var(--wp--custom--ease--out),
		color var(--wp--custom--duration--fast) var(--wp--custom--ease--out),
		background var(--wp--custom--duration--fast) var(--wp--custom--ease--out);
}

.pdp-icon-btn svg {
	width: 22px;
	height: 22px;
	fill: none;
	transition: fill var(--wp--custom--duration--fast) var(--wp--custom--ease--out);
}

.pdp-icon-btn:hover {
	border-color: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--contrast);
}

.pdp-icon-btn:active {
	transform: scale(0.97);
}

/* Filled heart is the whole feedback for "saved"; no colour change needed. */
.pdp-icon-btn--wishlist.is-active {
	border-color: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--contrast);
}

.pdp-icon-btn--wishlist.is-active svg {
	fill: currentColor;
}

/* Share sits in the meta row, where a 60px bordered square would shout. */
.pdp-icon-btn--ghost {
	width: 40px;
	height: 40px;
	border-color: transparent;
	color: var(--wp--preset--color--contrast-muted);
}

.pdp-icon-btn--ghost svg {
	width: 18px;
	height: 18px;
}

.pdp-icon-btn--ghost:hover {
	border-color: var(--wp--preset--color--border);
	background: var(--pdp-surface);
}

/* --- Buy now (secondary) --------------------------------------------------- */

/*
 * Kept from the previous layout - it is a real second checkout path (see
 * patterns/product-buy-now.php), not decoration - but demoted to a quiet
 * outline button so the black "add to cart" above stays the single obvious
 * action.
 */
.product-buy-now {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 52px;
	margin-top: calc(var(--wp--preset--spacing--5) * -1 + var(--wp--preset--spacing--2));
	padding: 0 var(--wp--preset--spacing--5);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--pdp-radius-control);
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 600;
	text-decoration: none;
	transition:
		border-color var(--wp--custom--duration--fast) var(--wp--custom--ease--out),
		background var(--wp--custom--duration--fast) var(--wp--custom--ease--out);
}

.product-buy-now:hover {
	border-color: var(--wp--preset--color--contrast);
	background: var(--pdp-surface);
	color: var(--wp--preset--color--contrast);
}

/* --- Benefits ------------------------------------------------------------- */

.pdp-benefits {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--wp--preset--spacing--4);
	list-style: none;
	margin: var(--wp--preset--spacing--1) 0 0;
	padding: var(--wp--preset--spacing--5) 0 0;
	border-top: 1px solid var(--wp--preset--color--border);
}

.pdp-benefits:has(> :nth-child(2):last-child) {
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

.pdp-benefit__inner {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	color: inherit;
	text-decoration: none;
	transition: opacity var(--wp--custom--duration--fast) var(--wp--custom--ease--out);
}

a.pdp-benefit__inner:hover {
	opacity: 0.7;
	color: inherit;
}

.pdp-benefit__icon {
	flex: 0 0 auto;
	display: inline-flex;
	color: var(--wp--preset--color--contrast-subtle);
}

.pdp-benefit__icon svg {
	width: 20px;
	height: 20px;
}

.pdp-benefit__body {
	display: flex;
	flex-direction: column;
	min-width: 0;
}

.pdp-benefit__title {
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 700;
	line-height: 1.3;
	color: var(--wp--preset--color--contrast);
}

.pdp-benefit__text {
	font-size: var(--wp--preset--font-size--xs);
	line-height: 1.3;
	color: var(--wp--preset--color--contrast-muted);
}

/*
 * Three across needs about 450px. A phone does not have it, and neither does
 * the buy column in the tablet range (half of an 800px page), so both read
 * the benefits as a list instead of three cramped two-line stacks.
 */
@media (max-width: 479px), (min-width: 768px) and (max-width: 1023px) {
	.pdp-benefits,
	.pdp-benefits:has(> :nth-child(2):last-child) {
		grid-template-columns: 1fr;
		gap: var(--wp--preset--spacing--3);
	}
}

/* --- Rating ------------------------------------------------------------- */

.product-rating {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--2);
	margin: 0;
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--preset--color--contrast-muted);
}

/*
 * Two star rows stacked: the grey one always shows all five, the dark one is
 * clipped to the average. Any average renders, including 4.3.
 */
.product-rating__stars {
	position: relative;
	display: inline-flex;
	line-height: 0;
	white-space: nowrap;
}

.product-rating__stars-empty,
.product-rating__stars-full {
	display: inline-flex;
	gap: 2px;
}

.product-rating__stars-empty svg,
.product-rating__stars-full svg {
	width: 16px;
	height: 16px;
	flex: 0 0 auto;
}

.product-rating__stars-empty {
	fill: var(--wp--preset--color--border);
}

.product-rating__stars-full {
	position: absolute;
	inset: 0;
	overflow: hidden;
	fill: var(--wp--preset--color--contrast);
}

.product-rating__value {
	font-weight: 700;
	color: var(--wp--preset--color--contrast);
}

.product-rating__count,
.product-rating__none {
	color: var(--wp--preset--color--contrast-muted);
}

.product-rating__count {
	text-decoration: underline;
	text-underline-offset: 3px;
}

.product-rating__count:hover {
	color: var(--wp--preset--color--contrast);
}

/* --- Stock -------------------------------------------------------------- */

.product-stock {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: calc(var(--wp--preset--spacing--5) * -1 + var(--wp--preset--spacing--2)) 0 0;
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 600;
}

.product-stock__dot {
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: currentColor;
	flex: 0 0 auto;
}

.product-stock--in {
	color: var(--wp--preset--color--success);
}

.product-stock--pending {
	color: var(--wp--preset--color--warning);
}

.product-stock--out {
	color: var(--wp--preset--color--contrast-muted);
}

/* --- Add to cart feedback -------------------------------------------------- */

form.cart.is-busy {
	opacity: 0.7;
	pointer-events: none;
}

/*
 * Confirmation on the button itself rather than a toast: it is where the eye
 * already is, and it cannot cover the page.
 */
form.cart.is-added .single_add_to_cart_button {
	background: var(--wp--preset--color--success);
	border-color: var(--wp--preset--color--success);
	color: var(--wp--preset--color--base);
}

form.cart.is-added .single_add_to_cart_button::after {
	content: " ✓";
}

/* --- Комплектація tab ------------------------------------------------------ */

.product-package-contents ul {
	padding-left: 1.2em;
}

.product-package-contents li {
	margin-bottom: var(--wp--preset--spacing--2);
}

/* --- Details tabs --------------------------------------------------------- */

.wp-block-woocommerce-product-details {
	margin-block: var(--wp--custom--section--padding-tight);
}

.wp-block-woocommerce-product-details .wc-tabs {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--6);
	list-style: none;
	margin: 0 0 var(--wp--preset--spacing--8);
	padding: 0 0 var(--wp--preset--spacing--3);
	border-bottom: 1px solid var(--wp--custom--border--on-light);
}

.wp-block-woocommerce-product-details .wc-tabs li a {
	font-size: var(--wp--preset--font-size--lg);
	font-weight: 600;
	letter-spacing: -0.01em;
	text-decoration: none;
	color: var(--wp--preset--color--contrast-muted);
	transition: color var(--wp--custom--duration--fast) var(--wp--custom--ease--out);
}

.wp-block-woocommerce-product-details .wc-tabs li.active a,
.wp-block-woocommerce-product-details .wc-tabs li a:hover {
	color: var(--wp--preset--color--contrast);
}

.wp-block-woocommerce-product-details table.shop_attributes {
	width: 100%;
	border-collapse: collapse;
	max-width: 720px;
}

.wp-block-woocommerce-product-details table.shop_attributes th,
.wp-block-woocommerce-product-details table.shop_attributes td {
	padding: var(--wp--preset--spacing--3) 0;
	border-bottom: 1px solid var(--wp--custom--border--on-light);
	text-align: left;
	vertical-align: top;
}

.wp-block-woocommerce-product-details table.shop_attributes th {
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 500;
	color: var(--wp--preset--color--contrast-subtle);
	width: 40%;
}

.wp-block-woocommerce-product-details table.shop_attributes td p {
	margin: 0;
	font-weight: 600;
}

/* --- Related products ------------------------------------------------------ */

/*
 * The related-products collection is the last thing in <main> and ships no
 * bottom spacing of its own, so its "Додати в кошик" buttons sat flush
 * against the top edge of the dark footer. The gap matches the rhythm the
 * other sections on the page already use.
 *
 * `.wp-site-blocks`'s own padding-bottom further down does not help here -
 * the footer is inside that wrapper, so that padding lands below the footer
 * (it is there to clear the fixed purchase bar).
 */
.wp-block-woocommerce-product-collection {
	margin-block-end: var(--wp--custom--section--padding-tight);
}

/* --- Sticky purchase bar (desktop and mobile) ---------------------------- */

/*
 * The bar is fixed, so the page owes it the height it covers - otherwise it
 * sits on top of the last thing in the footer. Paid once, unconditionally,
 * rather than toggled with the bar: a page whose length changes as you
 * scroll past a threshold jumps under the reader.
 */
.wp-site-blocks {
	padding-bottom: calc(76px + env(safe-area-inset-bottom, 0px));
}

.pdp-sticky {
	display: none;
}

.pdp-sticky:not([hidden]) {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--4);
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 90;
	/*
	 * <main> applies WordPress's "constrained layout" rule to its direct
	 * children (max-width: content-size + margin-inline: auto), which still
	 * applies to a position:fixed element - fixed only changes how top/left/
	 * right/bottom are resolved, not width/margin. Without this override the
	 * bar sits centred at 800px wide instead of spanning the viewport.
	 */
	width: auto;
	max-width: none;
	margin-inline: 0;
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--5);
	/* Clears the home indicator on iOS. */
	padding-bottom: calc(var(--wp--preset--spacing--3) + env(safe-area-inset-bottom, 0px));
	/* Solid black bar per the brief - not the light frosted-glass treatment
	   the rest of the site's fixed surfaces use. */
	background: var(--wp--preset--color--base-dark);
	color: var(--wp--preset--color--base);
}

.pdp-sticky__img {
	flex: 0 0 auto;
	width: 42px;
	height: 42px;
	object-fit: contain;
	border-radius: var(--wp--custom--radius--sm);
	background: var(--wp--preset--color--base);
}

.pdp-sticky__info {
	display: flex;
	flex-direction: column;
	min-width: 0;
	flex: 1 1 auto;
}

.pdp-sticky__name {
	font-size: var(--wp--preset--font-size--xs);
	color: var(--wp--preset--color--on-dark-muted);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.pdp-sticky__price {
	font-size: var(--wp--preset--font-size--lg);
	font-weight: 700;
	letter-spacing: -0.02em;
	font-variant-numeric: tabular-nums;
	color: var(--wp--preset--color--base);
}

.pdp-sticky__price .woocommerce-Price-amount {
	font-size: inherit;
	font-weight: inherit;
	color: inherit;
}

.pdp-sticky__qty {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--1);
	border: 1px solid var(--wp--custom--border--on-dark);
	border-radius: var(--wp--custom--radius--md);
	padding: 4px;
}

.pdp-sticky__qty-btn {
	width: 28px;
	height: 28px;
	border: 0;
	background: none;
	border-radius: var(--wp--custom--radius--sm);
	font-size: var(--wp--preset--font-size--base);
	line-height: 1;
	cursor: pointer;
	color: var(--wp--preset--color--base);
}

.pdp-sticky__qty-btn:hover {
	background: rgba(255, 255, 255, 0.12);
}

.pdp-sticky__qty-value {
	min-width: 20px;
	text-align: center;
	font-size: var(--wp--preset--font-size--sm);
	font-variant-numeric: tabular-nums;
	color: var(--wp--preset--color--base);
}

.pdp-sticky__cta {
	flex-shrink: 0;
	min-height: 48px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0 var(--wp--preset--spacing--6);
	border: 0;
	border-radius: var(--wp--custom--radius--md);
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 600;
	cursor: pointer;
	transition: opacity var(--wp--custom--duration--fast) var(--wp--custom--ease--out);
}

.pdp-sticky__cta:hover {
	opacity: 0.85;
}

@media (max-width: 599px) {
	.pdp-sticky__qty {
		display: none;
	}
}

/* --- Specifications table (now inside the "Характеристики" tab) ----------- */

/* Wide tables scroll inside their own box; the page never scrolls sideways. */
.product-specs-table__scroll {
	overflow-x: auto;
}

.product-specs-table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--wp--preset--font-size--base);
}

.product-specs-table tr {
	border-bottom: 1px solid var(--wp--preset--color--border);
}

.product-specs-table tr:last-child {
	border-bottom: 0;
}

.product-specs-table th,
.product-specs-table td {
	padding: 14px 0;
	text-align: left;
	vertical-align: top;
}

.product-specs-table th {
	width: 38%;
	padding-right: var(--wp--preset--spacing--5);
	font-weight: 400;
	color: var(--wp--preset--color--contrast-muted);
}

.product-specs-table td {
	font-weight: 600;
	color: var(--wp--preset--color--contrast);
}

@media (max-width: 599px) {
	.product-specs-table th {
		width: 50%;
	}
}
