/**
 * Amiology Core — WooCommerce component overrides.
 *
 * Loads after woocommerce-general (declared as a stylesheet dependency), so
 * these rules win on source order rather than by escalating specificity or
 * reaching for !important.
 *
 * Scope is deliberate: this restyles WooCommerce's own components — buttons,
 * gallery, quantity, notices, forms — to the brand. Layout stays in
 * amiology-parts.css.
 */

/* ---------------------------------------------------------------------------
 * Buttons
 *
 * Oxygen sets a global button colour that would otherwise win here. These
 * selectors carry a class more than Oxygen's defaults and load later, which is
 * enough without !important.
 * ------------------------------------------------------------------------- */

.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit,
.woocommerce a.button.alt,
.woocommerce button.button.alt,
.woocommerce input.button.alt,
.ami-product .single_add_to_cart_button.button,
.ami-product__summary .button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: var(--ami-tap, 44px);
	padding: var(--ami-space-sm, 0.75rem) var(--ami-space-lg, 1.5rem);
	/* !important for the same reason as the product cards: Oxygen emits its
	   global button styling after ours and the selector it uses shifts with
	   the builder's settings, so matching specificity is unwinnable. Without
	   this the single-product Add to Basket renders in Oxygen's default. */
	background-color: var(--ami-amber, #ffb302) !important;
	color: var(--ami-on-amber, #0b0b0c) !important;
	border: 0 !important;
	border-radius: var(--ami-radius, 0);
	font-family: var(--ami-font-display, sans-serif);
	font-size: var(--ami-text-xs, 0.75rem);
	font-weight: var(--ami-weight-extra, 800);
	letter-spacing: var(--ami-tracking-label, 0.18em);
	text-transform: uppercase;
	text-decoration: none;
	line-height: 1.2;
	cursor: pointer;
	transition: background-color var(--ami-duration-fast, 120ms) var(--ami-ease, ease),
	            color var(--ami-duration-fast, 120ms) var(--ami-ease, ease);
}

.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce #respond input#submit:hover,
.woocommerce a.button.alt:hover,
.woocommerce button.button.alt:hover,
.woocommerce input.button.alt:hover,
.ami-product .single_add_to_cart_button.button:hover,
.ami-product__summary .button:hover {
	background-color: var(--ami-amber-hover, #e89e00) !important;
	color: var(--ami-on-amber, #0b0b0c) !important;
}

.woocommerce a.button:focus-visible,
.woocommerce button.button:focus-visible,
.woocommerce input.button:focus-visible {
	outline: 2px solid var(--ami-ink, #0b0b0c);
	outline-offset: 3px;
}

.woocommerce button.button:disabled,
.woocommerce button.button.disabled,
.woocommerce a.button.disabled {
	background-color: var(--ami-fg-muted, #6e6e6e);
	border-color: var(--ami-fg-muted, #6e6e6e);
	color: var(--ami-white, #fff);
	cursor: not-allowed;
	opacity: 1;
}

/* The add-to-cart button takes whatever the quantity field leaves.
 *
 * A fixed basis here (it was 14rem) forces a wrap on a narrow column, and once
 * wrapped the stacked layout turned that basis into a 224px height. Growing
 * into the remaining space avoids both. */
.ami-product__summary .single_add_to_cart_button.button {
	flex: 1 1 auto;
	min-width: 0;
}

/* ---------------------------------------------------------------------------
 * Quantity
 * ------------------------------------------------------------------------- */

.ami-product__summary .quantity input.qty,
.woocommerce .quantity input.qty {
	width: 4.5rem;
	min-height: var(--ami-tap, 44px);
	padding: var(--ami-space-xs, 0.5rem);
	border: var(--ami-border-width, 1px) solid var(--ami-fg-strong, #0b0b0c);
	border-radius: var(--ami-radius, 0);
	background: var(--ami-bg, #fff);
	font: inherit;
	font-variant-numeric: tabular-nums;
	text-align: center;
	color: inherit;
}

/* ---------------------------------------------------------------------------
 * Product gallery
 *
 * Scoped to .ami-product rather than ".woocommerce div.product", so these
 * rules hold even if the wrapper markup changes again. The wrapper does now
 * carry the "product" class via wc_product_class(), which is what lets
 * WooCommerce's own gallery styling apply too.
 * ------------------------------------------------------------------------- */

.ami-product div.images,
.ami-product .woocommerce-product-gallery {
	position: relative;
	width: 100%;
	margin-block-end: 0;
	float: none;
	opacity: 1 !important; /* Woo sets opacity:0 until its JS runs. If the JS
	                          never runs, that leaves an invisible gallery —
	                          worse than an unslid one. */
}

.ami-product .woocommerce-product-gallery__wrapper {
	margin: 0;
	padding: 0;
	list-style: none;
}

.ami-product .woocommerce-product-gallery__image img,
.ami-product div.images img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: var(--ami-radius, 0);
}

/* Graceful fallback.
 *
 * FlexSlider wraps the gallery in .flex-viewport once it initialises. When it
 * has not — LiteSpeed deferring or combining jQuery is the usual reason — every
 * image renders stacked at full width, which looks broken. This turns that
 * state into a horizontal swipe gallery instead: no JavaScript, and a
 * deliberate-looking result either way.
 */
.ami-product .woocommerce-product-gallery:not(:has(.flex-viewport)) .woocommerce-product-gallery__wrapper {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: 100%;
	gap: var(--ami-space-xs, 0.5rem);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	overscroll-behavior-x: contain;
	scrollbar-width: thin;
}

.ami-product .woocommerce-product-gallery:not(:has(.flex-viewport)) .woocommerce-product-gallery__image {
	scroll-snap-align: start;
	min-width: 0;
}

/* Thumbnails.
 *
 * WooCommerce styles these with `.woocommerce div.product div.images
 * .flex-control-thumbs img` — specificity (0,4,1). An earlier version of this
 * file scoped its rules to `.ami-product .flex-control-thumbs img`, which is
 * (0,2,1) and therefore loses no matter where it sits in the cascade. That is
 * why the images kept rendering at their intrinsic size inside much wider
 * grid cells.
 *
 * !important rather than an even longer selector: WooCommerce's own selectors
 * change between releases, and matching them keeps this brittle in the same
 * way twice.
 *
 * The 1px gap is the separator — the grid's background shows through, so
 * every thumbnail gets a hairline on all sides with no doubling where cells
 * meet.
 */
.ami-product .flex-control-thumbs,
.woocommerce div.product div.images .flex-control-thumbs {
	display: grid !important;
	grid-template-columns: repeat(5, minmax(0, 1fr)) !important;
	gap: 1px !important;
	background: var(--ami-line, #e4e4e7) !important;
	border: 1px solid var(--ami-line, #e4e4e7);
	border-block-start: 0;
	margin: 0 !important;
	padding: 0 !important;
	list-style: none;
	overflow: visible;
}

.ami-product .flex-control-thumbs::after,
.woocommerce div.product div.images .flex-control-thumbs::after {
	content: none !important;
}

.ami-product .flex-control-thumbs li,
.woocommerce div.product div.images .flex-control-thumbs li {
	float: none !important;
	width: auto !important;
	margin: 0 !important;
	padding: 0 !important;
	list-style: none;
	background: var(--ami-white, #fff);
}

.ami-product .flex-control-thumbs img,
.woocommerce div.product div.images .flex-control-thumbs img {
	display: block !important;
	width: 100% !important;
	height: auto !important;
	max-width: none !important;
	aspect-ratio: 1 / 1;
	object-fit: contain;
	background: var(--ami-white, #fff);
	opacity: 0.5;
	cursor: pointer;
	transition: opacity var(--ami-duration-fast, 120ms) var(--ami-ease, ease);
}

.ami-product .flex-control-thumbs img:hover,
.ami-product .flex-control-thumbs img.flex-active,
.woocommerce div.product div.images .flex-control-thumbs img.flex-active {
	opacity: 1 !important;
}

@media (max-width: 600px) {
	.ami-product .flex-control-thumbs,
	.woocommerce div.product div.images .flex-control-thumbs {
		grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
	}
}

/* Zoom affordance sits over the image corner rather than above it. */
.ami-product .woocommerce-product-gallery__trigger {
	position: absolute;
	inset-block-start: var(--ami-space-xs, 0.5rem);
	inset-inline-end: var(--ami-space-xs, 0.5rem);
	inset-inline-start: auto;
	z-index: 5;
}

/* ---------------------------------------------------------------------------
 * Variation form
 * ------------------------------------------------------------------------- */

.ami-product form.cart .variations {
	width: 100%;
	margin-block-end: var(--ami-space-md, 1rem);
	border: 0;
}

.ami-product form.cart .variations th,
.ami-product form.cart .variations td {
	display: block;
	width: 100%;
	padding: 0 0 var(--ami-space-xs, 0.5rem);
	text-align: start;
}

.ami-product form.cart .variations label {
	font-size: var(--ami-text-xs, 0.75rem);
	font-weight: var(--ami-weight-extra, 800);
	letter-spacing: var(--ami-tracking-wide, 0.08em);
	text-transform: uppercase;
}

.ami-product form.cart .variations select,
.woocommerce .woocommerce-ordering select,
.woocommerce form .form-row select {
	width: 100%;
	min-height: var(--ami-tap, 44px);
	padding: var(--ami-space-xs, 0.5rem);
	border: var(--ami-border-width, 1px) solid var(--ami-fg-strong, #0b0b0c);
	border-radius: var(--ami-radius, 0);
	background: var(--ami-bg, #fff);
	font: inherit;
	color: inherit;
}

/* ---------------------------------------------------------------------------
 * Form fields — cart, checkout, account
 * ------------------------------------------------------------------------- */

.woocommerce form .form-row input.input-text,
.woocommerce form .form-row textarea,
.woocommerce-page form .form-row input.input-text {
	min-height: var(--ami-tap, 44px);
	padding: var(--ami-space-xs, 0.5rem) var(--ami-space-sm, 0.75rem);
	border: var(--ami-border-width, 1px) solid var(--ami-border, #e4e4e7);
	border-radius: var(--ami-radius, 0);
	background: var(--ami-bg, #fff);
	font: inherit;
	color: inherit;
}

.woocommerce form .form-row input.input-text:focus,
.woocommerce form .form-row textarea:focus,
.woocommerce form .form-row select:focus {
	outline: 2px solid var(--ami-ink, #0b0b0c);
	outline-offset: 1px;
	border-color: var(--ami-ink, #0b0b0c);
}

.woocommerce form .form-row label {
	font-size: var(--ami-text-xs, 0.75rem);
	letter-spacing: var(--ami-tracking-wide, 0.08em);
	text-transform: uppercase;
	color: var(--ami-fg-muted, #6e6e6e);
}

.woocommerce form .form-row.woocommerce-invalid input.input-text {
	border-color: var(--ami-sale, #d62839);
}

/* ---------------------------------------------------------------------------
 * Notices
 *
 * Meaning is carried by a border weight and a word, not by colour alone —
 * colour-only status indicators fail for colour-blind users.
 * ------------------------------------------------------------------------- */

.woocommerce-message,
.woocommerce-info,
.woocommerce-error {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--ami-space-sm, 0.75rem);
	margin: 0 0 var(--ami-space-lg, 1.5rem);
	padding: var(--ami-space-md, 1rem) var(--ami-space-lg, 1.5rem);
	border: var(--ami-border-width, 1px) solid var(--ami-fg-strong, #0b0b0c);
	border-inline-start-width: 4px;
	border-radius: var(--ami-radius, 0);
	background: var(--ami-surface, #f5f5f6);
	font-size: var(--ami-text-sm, 0.875rem);
	list-style: none;
}

.woocommerce-message::before,
.woocommerce-info::before,
.woocommerce-error::before {
	content: none;
}

.woocommerce-message { border-inline-start-color: var(--ami-trust, #0e6e5c); }
.woocommerce-error { border-inline-start-color: var(--ami-sale, #d62839); }

.woocommerce-message .button,
.woocommerce-error .button,
.woocommerce-info .button {
	margin-inline-start: auto;
}

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

.woocommerce .price,
.ami-product p.price,
.ami-product span.price {
	color: inherit;
	font-variant-numeric: tabular-nums;
}

.ami-product p.price del,
.ami-product span.price del {
	opacity: 0.5;
}

.ami-product p.price ins,
.ami-product span.price ins {
	text-decoration: none;
	font-weight: var(--ami-weight-extra, 800);
}

/* ---------------------------------------------------------------------------
 * Cart, checkout and account tables
 * ------------------------------------------------------------------------- */

.woocommerce table.shop_table {
	border: 0;
	border-collapse: collapse;
	border-radius: var(--ami-radius, 0);
}

.woocommerce table.shop_table th,
.woocommerce table.shop_table td {
	padding: var(--ami-space-md, 1rem);
	border-block-end: var(--ami-border-width, 1px) solid var(--ami-border, #e4e4e7);
}

.woocommerce table.shop_table thead th {
	font-size: var(--ami-text-xs, 0.75rem);
	letter-spacing: var(--ami-tracking-wide, 0.08em);
	text-transform: uppercase;
	border-block-end-color: var(--ami-fg-strong, #0b0b0c);
}

.woocommerce-checkout #payment {
	background: var(--ami-surface, #f5f5f6);
	border-radius: var(--ami-radius, 0);
}

.woocommerce-checkout #payment div.payment_box {
	background: var(--ami-bg, #fff);
	border: var(--ami-border-width, 1px) solid var(--ami-border, #e4e4e7);
	border-radius: var(--ami-radius, 0);
}

.woocommerce-checkout #payment div.payment_box::before {
	content: none;
}

/* ===========================================================================
 * CART
 *
 * WooCommerce's classic cart stacks the totals box below a full-width table.
 * On a wide screen that pushes the checkout button far below the fold — the
 * single most important button on the page, hidden by a long product list.
 * Side by side, with the totals sticky, keeps it permanently in view.
 * ======================================================================== */

.woocommerce-cart .woocommerce {
	display: grid;
	grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
	gap: var(--ami-space-xl, 2.5rem);
	align-items: start;
}

/* Notices and the empty-cart message must span both columns. */
.woocommerce-cart .woocommerce > .woocommerce-notices-wrapper,
.woocommerce-cart .woocommerce > .cart-empty,
.woocommerce-cart .woocommerce > .return-to-shop {
	grid-column: 1 / -1;
}

@media (max-width: 900px) {
	.woocommerce-cart .woocommerce {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--ami-space-lg, 1.5rem);
	}
}

.woocommerce-cart table.shop_table {
	width: 100%;
	margin: 0;
}

.woocommerce-cart table.shop_table img {
	width: 72px;
	height: auto;
	max-width: none;
}

.woocommerce-cart .product-name a {
	font-weight: var(--ami-weight-semi, 600);
	color: var(--ami-fg-strong, #0b0b0c);
	text-decoration: none;
}

.woocommerce-cart .product-price,
.woocommerce-cart .product-subtotal {
	font-variant-numeric: tabular-nums;
	font-weight: var(--ami-weight-bold, 700);
}

.woocommerce-cart .cart-collaterals,
.woocommerce-cart .cart_totals {
	width: 100%;
	float: none;
}

.woocommerce-cart .cart_totals {
	padding: var(--ami-space-lg, 1.5rem);
	background: var(--ami-surface, #f5f5f6);
	border: var(--ami-border-width, 1px) solid var(--ami-line, #e4e4e7);
}

@media (min-width: 901px) {
	.woocommerce-cart .cart-collaterals {
		position: sticky;
		inset-block-start: var(--ami-header-offset, 7rem);
	}
}

.woocommerce-cart .cart_totals h2 {
	margin: 0 0 var(--ami-space-md, 1rem);
	font-family: var(--ami-font-display, sans-serif);
	font-size: var(--ami-text-lg, 1.125rem);
	font-weight: var(--ami-weight-black, 900);
	letter-spacing: var(--ami-tracking-tight, -0.035em);
	text-transform: uppercase;
	color: var(--ami-fg-strong, #0b0b0c);
}

.woocommerce-cart .cart_totals .order-total {
	font-size: var(--ami-text-lg, 1.125rem);
	font-weight: var(--ami-weight-black, 900);
}

.woocommerce-cart .wc-proceed-to-checkout {
	padding: 0;
	margin-block-start: var(--ami-space-md, 1rem);
}

.woocommerce-cart .wc-proceed-to-checkout .button {
	width: 100%;
	font-size: var(--ami-text-sm, 0.875rem);
}

/* ===========================================================================
 * CHECKOUT
 *
 * Order summary beside the form rather than beneath it, so what is being paid
 * for stays visible while the details are entered. Removing that reassurance
 * at the exact moment card details are requested costs completed orders.
 * ======================================================================== */

.woocommerce-checkout form.checkout {
	display: grid;
	grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
	grid-template-areas:
		"details review-head"
		"details review";
	grid-template-rows: auto 1fr;
	gap: var(--ami-space-md, 1rem) var(--ami-space-xl, 2.5rem);
	align-items: start;
}

.woocommerce-checkout form.checkout #customer_details { grid-area: details; }
.woocommerce-checkout form.checkout #order_review_heading { grid-area: review-head; margin: 0; }
.woocommerce-checkout form.checkout #order_review { grid-area: review; }

@media (max-width: 900px) {
	.woocommerce-checkout form.checkout {
		grid-template-columns: minmax(0, 1fr);
		grid-template-areas: "details" "review-head" "review";
	}
}

/* Woo floats the two customer columns; stack them instead — address forms
   read better in a single column, and side-by-side halves cramp UK postcodes
   and county fields. */
.woocommerce-checkout #customer_details .col-1,
.woocommerce-checkout #customer_details .col-2 {
	float: none;
	width: 100%;
}

.woocommerce-checkout #customer_details .col-2 {
	margin-block-start: var(--ami-space-lg, 1.5rem);
}

.woocommerce-checkout h3,
.woocommerce-checkout #order_review_heading {
	font-family: var(--ami-font-display, sans-serif);
	font-size: var(--ami-text-lg, 1.125rem);
	font-weight: var(--ami-weight-black, 900);
	letter-spacing: var(--ami-tracking-tight, -0.035em);
	text-transform: uppercase;
	color: var(--ami-fg-strong, #0b0b0c);
}

.woocommerce-checkout #order_review {
	padding: var(--ami-space-lg, 1.5rem);
	background: var(--ami-surface, #f5f5f6);
	border: var(--ami-border-width, 1px) solid var(--ami-line, #e4e4e7);
}

@media (min-width: 901px) {
	.woocommerce-checkout #order_review { position: sticky; inset-block-start: var(--ami-header-offset, 7rem); }
}

.woocommerce-checkout #order_review table.shop_table { background: transparent; }

.woocommerce-checkout #order_review .order-total {
	font-size: var(--ami-text-lg, 1.125rem);
	font-weight: var(--ami-weight-black, 900);
}

.woocommerce-checkout #place_order {
	width: 100%;
	font-size: var(--ami-text-sm, 0.875rem);
}

/* Full-width fields. Woo's default 47% halves are too narrow for UK
   addresses, and a cramped field invites typos in the one place they cost
   a failed delivery. */
.woocommerce-checkout .form-row-first,
.woocommerce-checkout .form-row-last {
	width: 100%;
	float: none;
}

/* ===========================================================================
 * MY ACCOUNT
 * ======================================================================== */

.woocommerce-account .woocommerce {
	display: grid;
	grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
	gap: var(--ami-space-xl, 2.5rem);
	align-items: start;
}

/* The login form has no navigation to sit beside. */
.woocommerce-account:not(.logged-in) .woocommerce {
	display: block;
	max-width: var(--ami-container-narrow, 48rem);
	margin-inline: auto;
}

@media (max-width: 760px) {
	.woocommerce-account .woocommerce {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--ami-space-lg, 1.5rem);
	}
}

.woocommerce-account .woocommerce-MyAccount-navigation {
	width: 100%;
	float: none;
}

.woocommerce-account .woocommerce-MyAccount-navigation ul {
	margin: 0;
	padding: 0;
	list-style: none;
	border-block-start: 2px solid var(--ami-ink, #0b0b0c);
}

.woocommerce-account .woocommerce-MyAccount-navigation li a {
	display: block;
	padding: var(--ami-space-sm, 0.75rem) 0;
	border-block-end: var(--ami-border-width, 1px) solid var(--ami-line, #e4e4e7);
	font-size: var(--ami-text-xs, 0.8rem);
	font-weight: var(--ami-weight-bold, 700);
	letter-spacing: var(--ami-tracking-wide, 0.08em);
	text-transform: uppercase;
	text-decoration: none;
	color: var(--ami-fg-strong, #0b0b0c);
}

.woocommerce-account .woocommerce-MyAccount-navigation li.is-active a {
	color: var(--ami-sale, #d62839);
}

.woocommerce-account .woocommerce-MyAccount-content {
	width: 100%;
	float: none;
}

/* ===========================================================================
 * WIDTH
 *
 * These wrappers are direct children of the page shell, so the shell's cap and
 * auto margins are what centre them. An earlier version set `max-width: none`
 * and `margin-inline: 0` here — correct under the old breakout model, where
 * the shell escaped its ancestors and these wrappers had to get out of the
 * way. Under the release model it strips off the very rules doing the
 * centring, which is why cart, checkout and account sat hard against the left
 * edge while the header was centred.
 *
 * Clear the floats, leave the width alone.
 * ======================================================================== */

.woocommerce-cart .woocommerce,
.woocommerce-checkout .woocommerce,
.woocommerce-account .woocommerce,
.woocommerce-page .entry-content,
.woocommerce-page .woocommerce-notices-wrapper {
	width: 100%;
	float: none;
}

/* Block-based cart and checkout.
 *
 * The block versions render into their own wrappers, nested deeper than the
 * classic shortcode markup, so the shell's direct-child rule does not reach
 * them. Cap and centre explicitly. */
/* !important is the fallback, not the plan.
 *
 * The stylesheet dependency above should be enough on its own. But WooCommerce
 * Blocks also injects inline styles into the footer, and inline styles beat any
 * external sheet regardless of load order. This is the one rule that has to
 * hold for the page to be usable, so it is worth the escape hatch. */
.wp-block-woocommerce-cart,
.wp-block-woocommerce-checkout,
.wc-block-checkout,
.wc-block-cart {
	max-width: var(--ami-container, 100rem) !important;
	margin-inline: auto !important;
	float: none;
}

/* Woo Blocks marks these alignwide/alignfull, which themes with a theme.json
   would size. This build has no theme.json — Oxygen disables the theme system —
   so the alignment classes resolve to nothing and the blocks fall back to
   whatever width their container gives them. Pin them to the site container so
   checkout lines up with every other template. */
.woocommerce-checkout .alignwide,
.woocommerce-checkout .alignfull,
.woocommerce-cart .alignwide,
.woocommerce-cart .alignfull {
	max-width: var(--ami-container, 100rem) !important;
	margin-inline: auto !important;
	width: auto !important;
}

/* Woo's clearfix pseudo-elements fight the grid layouts defined above. */
.woocommerce-page .woocommerce::after,
.woocommerce-page .woocommerce::before {
	content: none;
}

/* Re-assert the logged-out login form's narrow measure. A lone email and
   password field stretched to full width looks broken, not consistent.
   Declared last so source order settles it. */
.woocommerce-account:not(.logged-in) .woocommerce {
	max-width: var(--ami-container-narrow, 48rem);
	margin-inline: auto;
}

/* ===========================================================================
 * BLOCK CART & CHECKOUT
 *
 * WooCommerce ships two checkouts: the classic shortcode and the newer block
 * version. This store uses the block version, so the classic rules above
 * (form.checkout, #order_review, .col-1/.col-2) never match anything — they
 * are kept for the shortcode path, not dead weight.
 *
 * The blocks bring their own two-column layout and spacing, so this is
 * restricted to brand surface: type, buttons, borders, colour. Rewriting the
 * blocks' structural CSS is a fight that gets re-fought at every WooCommerce
 * release.
 * ======================================================================== */

.wc-block-components-title,
.wp-block-woocommerce-checkout h2,
.wc-block-checkout__main h2 {
	font-family: var(--ami-font-display, sans-serif) !important;
	font-weight: var(--ami-weight-black, 900) !important;
	letter-spacing: var(--ami-tracking-tight, -0.035em);
	text-transform: uppercase;
	color: var(--ami-fg-strong, #0b0b0c);
}

/* Product titles in the order summary inherit the heading treatment from the
   blocks, which makes a long catalogue title shout. Bring it back to body. */
.wc-block-components-product-name {
	font-family: var(--ami-font-body, sans-serif) !important;
	font-size: var(--ami-text-sm, 0.875rem) !important;
	font-weight: var(--ami-weight-semi, 600) !important;
	letter-spacing: 0 !important;
	text-transform: none !important;
	line-height: var(--ami-leading-snug, 1.22);
}

.wc-block-components-order-summary-item__description p {
	font-size: var(--ami-text-xs, 0.8rem);
	color: var(--ami-fg-muted, #6b6b72);
}

/* Fields */
.wc-block-components-text-input input[type="text"],
.wc-block-components-text-input input[type="email"],
.wc-block-components-text-input input[type="tel"],
.wc-block-components-combobox input,
.wc-block-components-select__container {
	border-radius: var(--ami-radius, 0) !important;
	border-color: var(--ami-line, #e4e4e7) !important;
	font-family: var(--ami-font-body, sans-serif) !important;
}

.wc-block-components-text-input input:focus,
.wc-block-components-combobox input:focus {
	outline: 2px solid var(--ami-ink, #0b0b0c) !important;
	outline-offset: 1px;
	box-shadow: none !important;
}

/* Place order — the one button that matters. */
.wc-block-components-checkout-place-order-button,
.wc-block-cart__submit-button,
.wc-block-components-button:not(.is-link) {
	border-radius: var(--ami-radius, 0) !important;
	background-color: var(--ami-amber, #ffb302) !important;
	color: var(--ami-on-amber, #0b0b0c) !important;
	font-family: var(--ami-font-display, sans-serif) !important;
	font-weight: var(--ami-weight-extra, 800) !important;
	letter-spacing: var(--ami-tracking-label, 0.14em);
	text-transform: uppercase;
	min-height: var(--ami-tap, 44px);
}

.wc-block-components-checkout-place-order-button:hover,
.wc-block-cart__submit-button:hover,
.wc-block-components-button:not(.is-link):hover {
	background-color: var(--ami-amber-hover, #e89e00) !important;
}

/* Totals */
.wc-block-components-totals-item__value,
.wc-block-components-totals-footer-item .wc-block-components-totals-item__value {
	font-family: var(--ami-font-display, sans-serif);
	font-weight: var(--ami-weight-black, 900);
	font-variant-numeric: tabular-nums;
	color: var(--ami-fg-strong, #0b0b0c);
}

.wc-block-components-sidebar,
.wc-block-checkout__sidebar {
	border-radius: var(--ami-radius, 0);
}

.wc-block-components-panel,
.wc-block-components-sidebar .wc-block-components-order-summary {
	border-radius: var(--ami-radius, 0) !important;
}

/* ===========================================================================
 * WOOCOMMERCE'S OWN PRODUCT LOOP
 *
 * Related products, upsells, cross-sells and search results render through
 * WooCommerce's `ul.products` markup rather than the Amiology card renderer,
 * so none of the card styling reached them. With woocommerce-layout removed —
 * correctly, it is a float grid — they had no layout at all, which is why
 * related products overlapped into each other.
 *
 * Selectors match WooCommerce's own specificity: `.woocommerce ul.products
 * li.product` is (0,3,1), so anything shorter loses regardless of load order.
 * That was the exact mistake behind the gallery thumbnails.
 * ======================================================================== */

.woocommerce ul.products,
.woocommerce-page ul.products {
	display: grid !important;
	grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
	gap: var(--ami-grid-gap, 0.75rem) !important;
	margin: 0 !important;
	padding: 0 !important;
	list-style: none;
}

.woocommerce ul.products::before,
.woocommerce ul.products::after {
	content: none !important;
}

.woocommerce ul.products li.product,
.woocommerce-page ul.products li.product {
	/* Woo floats these and sets percentage widths; both must go or the grid
	   cells collapse onto one another. */
	float: none !important;
	width: auto !important;
	margin: 0 !important;
	padding: var(--ami-space-sm, 0.75rem) !important;
	display: flex !important;
	flex-direction: column;
	height: 100%;
	background: var(--ami-bg, #fff);
	border: var(--ami-border-width, 1px) solid var(--ami-line, #e4e4e7);
	text-align: start;
}

.woocommerce ul.products li.product a img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: var(--ami-card-ratio, 4 / 3);
	object-fit: contain;
	/* Matches the archive cards. These images are in normal flow rather than
	   absolutely positioned, so a margin is the right lever here where an
	   inset was the right one there. */
	margin: var(--ami-card-image-gap, 10px) 0 var(--ami-space-sm, 0.75rem) !important;
	background: var(--ami-white, #fff);
	box-shadow: none !important;
}

.woocommerce ul.products li.product .woocommerce-loop-product__title {
	padding: 0 !important;
	margin: 0 0 var(--ami-space-xs, 0.5rem) !important;
	font-family: var(--ami-font-body, sans-serif) !important;
	font-size: var(--ami-text-sm, 0.875rem) !important;
	font-weight: var(--ami-weight-medium, 500) !important;
	letter-spacing: 0 !important;
	line-height: var(--ami-leading-snug, 1.22) !important;
	text-transform: none !important;
	color: var(--ami-fg, #2a2a2e);
	/* Reserve three lines so prices and buttons land on one line across the
	   row, matching the archive cards. */
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
	min-height: calc(var(--ami-leading-snug, 1.22) * 3em);
}

.woocommerce ul.products li.product .price {
	display: block;
	margin: auto 0 var(--ami-space-sm, 0.75rem) !important;
	font-family: var(--ami-font-display, sans-serif) !important;
	/* Identical to .ami-product-card__price, so related products and search
	   results match the archive and eBay cards. The fallback differed, which
	   is only visible if the token fails to load — but a fallback that
	   disagrees with its token is exactly the kind of thing that surfaces at
	   the worst moment. */
	font-size: var(--ami-text-price, 1.375rem) !important;
	font-weight: var(--ami-weight-black, 900) !important;
	letter-spacing: var(--ami-tracking-tight, -0.035em);
	line-height: 1;
	color: var(--ami-fg-strong, #0b0b0c) !important;
	font-variant-numeric: tabular-nums;
}

/* Same reason as the archive cards: Woo sizes its own inner price markup. */
.woocommerce ul.products li.product .price .woocommerce-Price-amount,
.woocommerce ul.products li.product .price .amount,
.woocommerce ul.products li.product .price .woocommerce-Price-currencySymbol,
.woocommerce ul.products li.product .price bdi {
	font-size: inherit !important;
	font-family: inherit !important;
	font-weight: inherit;
	color: inherit;
}

.woocommerce ul.products li.product .price del {
	font-size: var(--ami-text-sm, 0.875rem) !important;
	font-weight: var(--ami-weight-medium, 500) !important;
	color: var(--ami-fg-muted, #6b6b72) !important;
}

.woocommerce ul.products li.product .price ins {
	text-decoration: none;
	color: var(--ami-sale, #d62839) !important;
}

.woocommerce ul.products li.product .button,
.woocommerce ul.products li.product .added_to_cart {
	display: flex !important;
	width: 100%;
	margin: 0 !important;
	text-align: center;
}

.woocommerce ul.products li.product .added_to_cart {
	margin-block-start: var(--ami-space-2xs, 0.25rem) !important;
}

/* Star ratings are suppressed elsewhere; hide the empty container too. */
.woocommerce ul.products li.product .star-rating {
	display: none !important;
}

@media (max-width: 1100px) {
	.woocommerce ul.products,
	.woocommerce-page ul.products {
		grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
	}
}

@media (max-width: 760px) {
	.woocommerce ul.products,
	.woocommerce-page ul.products {
		grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
	}
}

/* ---------------------------------------------------------------------------
 * Product gallery video
 * ------------------------------------------------------------------------- */

.ami-video {
	position: relative;
	/* Matches the gallery images, so the slide does not change height when the
	   video is the active one. */
	aspect-ratio: var(--ami-card-ratio, 4 / 3);
	background: var(--ami-ink, #0b0b0c);
	overflow: hidden;
}

.ami-video__play {
	display: block;
	width: 100%;
	height: 100%;
	padding: 0;
	border: 0;
	background: none;
	cursor: pointer;
}

.ami-video__play img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: contain;
}

.ami-video__badge {
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 50%;
	transform: translate(-50%, -50%);
	display: flex;
	align-items: center;
	justify-content: center;
	width: 4.5rem;
	height: 4.5rem;
	border-radius: 50%;
	background: var(--ami-amber, #ffb302);
	color: var(--ami-on-amber, #0b0b0c);
	box-shadow: 0 6px 22px rgba(11, 11, 12, 0.35);
	transition: transform var(--ami-duration-fast, 120ms) var(--ami-ease, ease);
}

.ami-video__badge svg {
	width: 2rem;
	height: 2rem;
	fill: currentColor;
	/* The optical centre of a triangle sits left of its bounding box, so it
	   needs nudging right to look centred in a circle. */
	margin-inline-start: 0.15rem;
}

.ami-video__play:hover .ami-video__badge {
	transform: translate(-50%, -50%) scale(1.08);
}

.ami-video__play:focus-visible {
	outline: 3px solid var(--ami-amber, #ffb302);
	outline-offset: -3px;
}

.ami-video__player {
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
	background: var(--ami-ink, #0b0b0c);
}

/*
 * TikTok is portrait, 9:16. Stretched to fill a 4:3 slide it would be badly
 * distorted, so the player keeps its own ratio and sits centred in the slide
 * with the black surround showing either side.
 *
 * The slide itself grows taller for a TikTok video: a 9:16 player letterboxed
 * into a 4:3 box would be a narrow sliver, too small to watch.
 */
.ami-video[data-type="tiktok"] {
	aspect-ratio: 3 / 4;
}

.ami-video[data-type="tiktok"] .ami-video__player {
	width: auto;
	max-width: 100%;
	aspect-ratio: 9 / 16;
	margin-inline: auto;
}

/* ---------------------------------------------------------------------------
 * Product gallery arrows
 *
 * FlexSlider's own directionNav, enabled through
 * woocommerce_single_product_carousel_options. WooCommerce ships no styling
 * for these because it disables them by default, so all of it is here.
 *
 * WooCommerce's gallery selectors run to (0,4,1), so these need !important to
 * reach — the same specificity problem as the thumbnails.
 * ------------------------------------------------------------------------- */

.woocommerce div.product div.images .flex-direction-nav {
	margin: 0 !important;
	padding: 0 !important;
	list-style: none !important;
}

.woocommerce div.product div.images .flex-direction-nav a {
	position: absolute;
	/* Measured from the top of the image, not centred — see the token. */
	inset-block-start: var(--ami-gallery-nav-top, 200px);
	z-index: 4;
	display: flex;
	align-items: center;
	justify-content: center;
	width: var(--ami-tap, 44px);
	height: var(--ami-tap, 44px);
	/* The arrow is drawn as a border chevron below, so the label has to go —
	   but text-indent rather than display:none keeps it readable to a screen
	   reader. */
	overflow: hidden;
	text-indent: -999em;
	background: var(--ami-bg, #fff);
	border: 2px solid var(--ami-ink, #0b0b0c);
	box-shadow: 0 6px 18px rgba(11, 11, 12, 0.16);
	opacity: 1;
	transition: background var(--ami-duration-fast, 120ms) var(--ami-ease, ease);
}

/* FlexSlider fades its arrows in on hover of the slider. On a touchscreen
   there is no hover, so they would never appear — hence keeping them visible
   and overriding its opacity rules. */
.woocommerce div.product div.images .flex-direction-nav a.flex-prev,
.woocommerce div.product div.images .flex-direction-nav a.flex-next {
	opacity: 1 !important;
}

/* Fixed distance from the top of the image, not centred: gallery images are
   not all the same height, so centred arrows sat at a different height on
   every product and moved as the slider changed image. */
.woocommerce div.product div.images .flex-direction-nav a.flex-prev {
	inset-inline-start: var(--ami-space-sm, 0.75rem);
}

.woocommerce div.product div.images .flex-direction-nav a.flex-next {
	inset-inline-end: var(--ami-space-sm, 0.75rem);
}

.woocommerce div.product div.images .flex-direction-nav a:hover {
	background: var(--ami-amber, #ffb302);
}

.woocommerce div.product div.images .flex-direction-nav a:focus-visible {
	outline: 3px solid var(--ami-amber, #ffb302);
	outline-offset: 2px;
}

/*
 * The chevron: two borders on a rotated square.
 *
 * Rotation is avoided elsewhere in this build because it collapses when a flex
 * context squeezes its box. Here the box is a fixed square inside a fixed
 * button, so there is nothing to squeeze it.
 */
.woocommerce div.product div.images .flex-direction-nav a::before {
	content: "";
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 50%;
	width: 0.6rem;
	height: 0.6rem;
	border-block-start: 2px solid var(--ami-ink, #0b0b0c);
	border-inline-start: 2px solid var(--ami-ink, #0b0b0c);
	font-size: 0;
}

.woocommerce div.product div.images .flex-direction-nav a.flex-prev::before {
	transform: translate(-30%, -50%) rotate(-45deg);
}

.woocommerce div.product div.images .flex-direction-nav a.flex-next::before {
	transform: translate(-70%, -50%) rotate(135deg);
}

/* Disabled at the ends of a non-looping slider. */
.woocommerce div.product div.images .flex-direction-nav a.flex-disabled {
	opacity: 0.3 !important;
	cursor: default;
	box-shadow: none;
}

/* The gallery wrapper must be a positioning context for the arrows, and must
   not clip them. */
.woocommerce div.product div.images .woocommerce-product-gallery__wrapper {
	position: relative;
}

/*
 * The two-column range is where the gallery is narrowest — it holds roughly
 * half the container, so the image is shortest just before the layout goes
 * single-column, and grows again below it.
 */
@media (max-width: 1400px) {
	.woocommerce div.product div.images { --ami-gallery-nav-top: 170px; }
}

@media (max-width: 1100px) {
	.woocommerce div.product div.images { --ami-gallery-nav-top: 140px; }
}

@media (max-width: 860px) {
	.woocommerce div.product div.images { --ami-gallery-nav-top: 200px; }
}

@media (max-width: 600px) {
	.woocommerce div.product div.images { --ami-gallery-nav-top: 130px; }

	.woocommerce div.product div.images .flex-direction-nav a {
		width: 2.5rem;
		height: 2.5rem;
	}

	.woocommerce div.product div.images .flex-direction-nav a.flex-prev { inset-inline-start: 0.35rem; }
	.woocommerce div.product div.images .flex-direction-nav a.flex-next { inset-inline-end: 0.35rem; }

	.woocommerce div.product div.images .flex-direction-nav a::before {
		width: 0.5rem;
		height: 0.5rem;
	}
}

/* Smallest phones: the image is only about 260px tall, where 130px is halfway
   down and the arrows stop reading as a control near the top. */
@media (max-width: 420px) {
	.woocommerce div.product div.images { --ami-gallery-nav-top: 105px; }
}

/* ---------------------------------------------------------------------------
 * Play badge on the video thumbnail
 *
 * Keyed on .ami-video-thumb, which the script adds to the thumbnail belonging
 * to the video slide.
 *
 * Earlier versions tried to identify that thumbnail from CSS alone — by
 * :last-child, then by a body class, then by :has() on the gallery. Each was
 * defensible and none of them worked, because FlexSlider generates the strip
 * and the relationship between a slide and its thumbnail is not expressible as
 * a selector. Marking it in script and styling the class is the honest way
 * round: the script knows which slide is the video, so it should be the thing
 * that says so.
 * ------------------------------------------------------------------------- */

.woocommerce div.product .flex-control-thumbs li {
	position: relative;
}

/* The disc. */
.woocommerce div.product .flex-control-thumbs li.ami-video-thumb::before {
	content: "";
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 50%;
	transform: translate(-50%, -50%);
	z-index: 2;
	width: 2rem;
	height: 2rem;
	border-radius: 50%;
	background: var(--ami-amber, #ffb302);
	box-shadow: 0 2px 8px rgba(11, 11, 12, 0.45);
	pointer-events: none;
}

/* The triangle, built from borders rather than a rotated square — a solid
   shape that cannot collapse whatever the parent does. */
.woocommerce div.product .flex-control-thumbs li.ami-video-thumb::after {
	content: "";
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 50%;
	/* A triangle's optical centre sits left of its bounding box, so it needs
	   nudging right to look centred in a disc. */
	transform: translate(-40%, -50%);
	z-index: 3;
	width: 0;
	height: 0;
	border-block: 0.32em solid transparent;
	border-inline-start: 0.52em solid var(--ami-on-amber, #0b0b0c);
	border-inline-end: 0;
	font-size: 1rem;
	pointer-events: none;
}

/* A slight dim so the badge reads against a bright thumbnail. */
.woocommerce div.product .flex-control-thumbs li.ami-video-thumb img {
	filter: brightness(0.82);
}

@media (max-width: 600px) {
	.woocommerce div.product .flex-control-thumbs li.ami-video-thumb::before {
		width: 1.5rem;
		height: 1.5rem;
	}

	.woocommerce div.product .flex-control-thumbs li.ami-video-thumb::after {
		font-size: 0.75rem;
	}
}

@media (prefers-reduced-motion: reduce) {
	.woocommerce div.product div.images .flex-direction-nav a {
		transition: none;
	}
}
