/*!
 * Lauriva Cosmetics — WooCommerce layer.
 * CDDS child theme of coredigify-base. Loads after assets/lauriva.css.
 *
 * WHY THIS FILE EXISTS
 * --------------------
 * theme.json declares `contentSize: 1440px`, `wideSize: 100%` and
 * `useRootPaddingAwareAlignments: false`. That is deliberate: the landing
 * page's hero, dark bands and CTA are full-bleed and live in unconstrained
 * post_content, and each of their sections brings its own `.lv-container`.
 * WooCommerce's templates have no such container, so on any viewport at or
 * below 1440px they inherit *no constraint at all* — measured on the live
 * site, `main` was 1440px wide with `max-width: none` and the product `<h1>`
 * sat at `left: 0`, flush against the screen edge.
 *
 * The fix must therefore be scoped to shop pages only. Every rule below is
 * qualified with a WooCommerce body class:
 *
 *     body.woocommerce          shop archive, single product
 *     body.woocommerce-page     all five (archive, product, cart,
 *                               checkout, my account)
 *     body.single-product / .woocommerce-cart / .woocommerce-checkout /
 *     body.woocommerce-account  page-specific work
 *
 * The front page carries `woocommerce-js`, `woocommerce-uses-block-theme`
 * and `woocommerce-block-theme-has-button-styles` but NOT the bare
 * `woocommerce` / `woocommerce-page` tokens, so nothing here can reach it.
 * Those are separate class tokens — `.woocommerce` does not match
 * `class="woocommerce-js"`. Verified in the browser before writing a line.
 *
 * WHAT THE MARKUP ACTUALLY IS
 * ---------------------------
 * Not what a classic WooCommerce theme ships. These pages are *block*
 * templates with classic markup nested inside them:
 *
 *   shop archive   `ul.wc-block-product-template` (Product Collection).
 *                  It is `is-layout-flow` — NOT `is-flex-container` — which
 *                  is exactly why it renders as a bare vertical list.
 *   single product `wp-block-columns` for the gallery/summary split, with
 *                  `wp-block-woocommerce-product-details` wrapping a
 *                  genuinely classic `.woocommerce-tabs.wc-tabs-wrapper`,
 *                  and a second Product Collection for related products.
 *                  There is no `.summary`, no `.related.products`, no
 *                  `.product_title` and no `ul.products` on this site.
 *   cart/checkout  the React Cart and Checkout blocks.
 *   my account     genuinely classic (`.woocommerce-MyAccount-navigation`
 *                  + `.woocommerce-MyAccount-content`), and the only shop
 *                  page that already had a container (style.css § 05).
 *
 * LOAD ORDER
 * ----------
 * Measured: woocommerce.css, woocommerce-layout.css, woocommerce-blocktheme.css,
 * product-details.css and global-styles-inline-css all load BEFORE the theme's
 * own stylesheets, and this file is enqueued last of all. Ties on specificity
 * therefore resolve in our favour — but see the specificity notes on the tab
 * block, where WooCommerce reaches (0,4,4) and a tie is not good enough
 * because the same selector also has to beat a `@media` variant.
 *
 * TOKENS
 * ------
 * Colour, shape, type and motion all come from the `--lv-*` custom properties
 * declared in style.css and assets/lauriva.css, which in turn read the
 * theme.json presets with a literal fallback. No fresh hex is introduced here.
 * Motion reads `--lv-dur*`, which assets/lauriva.css already zeroes under
 * `prefers-reduced-motion: reduce`; § 17 adds the belt-and-braces block for
 * the state changes that are not durations.
 */

/* ==========================================================================
   00 · Scope and measure
   ========================================================================== */

/*
 * THE CONTENT MEASURE: `--lv-container-w` capped, `--lv-gutter` padded —
 * i.e. exactly the landing page's `.lv-container`, which measures 1296px of
 * content on a 1440 viewport.
 *
 * This was picked by testing both candidates on the live page, not by
 * assumption. The first attempt used a deliberately narrower 1200px column,
 * on the theory that a shop should feel curated rather than warehouse-wide.
 * Measured against the chrome, that put the shop's `<h1>` at `left: 120px`
 * while the header and footer logos sit at `left: 72px` — a 48px offset per
 * side. Big enough to see, too small to read as intentional: precisely the
 * "looks broken" register the client is complaining about. Screenshotted side
 * by side, the aligned version was plainly the better page.
 *
 * So the shop frame now matches the site frame exactly, and the readability
 * problem is solved where it actually lives rather than by squeezing the
 * whole page:
 *
 * 1. Reading is capped per element, not per page. The real defect was never
 *    the container — it was the summary column, which measured 928px on the
 *    live site (roughly 110 characters at the 18px body size, about double a
 *    comfortable measure). `--lv-prose-w: 68ch` caps the product excerpt, the
 *    tab panel and the account copy independently of how wide the page is, so
 *    prose stays readable while the layout stays aligned. A container width
 *    is a bad instrument for line length; a `ch` cap is the right one.
 *
 * 2. The grid stays generous. 1296 with a 2rem gutter and a 260px minimum
 *    track yields four 300px product cards — the right size for 1:1 cosmetic
 *    photography, and comfortably bigger than the 276px a 1200 column gave.
 *
 * 3. One site, one edge. The breadcrumb, title, toolbar, grid, tabs and
 *    footer all start at the same x as the header logo, which is the single
 *    most visible signal that the shop and the landing page were designed
 *    together.
 *
 * Note that this is still narrower than what the page had: the complaint was
 * content running the full 1440 with `max-width: none` and `left: 0`, i.e. no
 * gutter at all. 1296 with a 72px gutter is the fix.
 *
 * HOW it is applied matters as much as the number. Rather than fight
 * WordPress's layout engine with our own containers, we re-point the two
 * custom properties that engine already reads. WordPress emits:
 *
 *     .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull))
 *         { max-width: var(--wp--style--global--content-size); … }
 *     .is-layout-constrained > .alignwide
 *         { max-width: var(--wp--style--global--wide-size); }
 *
 * Redefining both properties on the shop body makes every WooCommerce block —
 * breadcrumb, title, toolbar, product collection, cart, checkout — snap to the
 * measure through WordPress's own rules, with its own auto margins doing the
 * centring. Nothing needs to be re-specified per block, and the front page is
 * untouched because it never matches these selectors.
 *
 * The properties are declared on `:root` by global-styles-inline-css, which
 * scores (0,1,0); `body.woocommerce-page` scores (0,1,1) and wins.
 */
body.woocommerce,
body.woocommerce-page {
	/* The same container the landing page's sections use, so the shop and the
	   front page share one left edge. Measured: 1296px of content at 1440. */
	--lv-shop-w: var(--lv-container-w);

	/* Prose measure for long-form copy (product description, account text).
	   ch units so it tracks the font, not the viewport. This — not the
	   container — is what keeps line length readable. */
	--lv-prose-w: 68ch;

	/* Product card grid: minimum track, and the gap between cards.
	   260px + a 32px gap resolves to four 300px cards at 1296. */
	--lv-card-min: 260px;
	--lv-card-gap: clamp(1.25rem, 2.4vw, 2rem);
	--lv-card-row-gap: clamp(2rem, 4vw, 3.25rem);

	/* Re-point WordPress's own layout engine at our measure. */
	--wp--style--global--content-size: var(--lv-shop-w);
	--wp--style--global--wide-size: var(--lv-shop-w);
}

/*
 * Gutters. `useRootPaddingAwareAlignments` is false, so WordPress adds no
 * padding of its own and a max-width alone still lets content touch the edge
 * on any viewport below the measure. Padding on `main` supplies it, using the
 * same `--lv-gutter` clamp the landing page's `.lv-container` uses, so the
 * shop and the landing page breathe identically at every width.
 *
 * `.lv-page` is excluded: that is the my-account template, whose `.woocommerce`
 * child already carries `padding-inline: var(--lv-gutter)` from style.css § 05.
 * Padding both would double the gutter.
 */
body.woocommerce main:not(.lv-page),
body.woocommerce-page main:not(.lv-page) {
	padding-inline: var(--lv-gutter);
	padding-block-end: clamp(3.5rem, 7vw, 6rem);
}

/* Vertical rhythm between the major blocks of a shop page. WordPress's
   constrained layout zeroes `margin-block` on every child, so spacing has to
   come from the parent. */
body.woocommerce main:not(.lv-page) > * + *,
body.woocommerce-page main:not(.lv-page) > * + * {
	margin-block-start: clamp(2rem, 4.5vw, 3.5rem);
}

/* Nothing on a shop page may push the viewport sideways. `clip` rather than
   `hidden` so this does not become a scroll container and break the sticky
   header. */
body.woocommerce main,
body.woocommerce-page main {
	max-width: 100%;
	overflow-x: clip;
}

/* Headings on shop pages take the warm near-black, not theme.json's pure
   `contrast` black, so they sit in the same family as the landing page.
   Two classes: WordPress emits `:root :where(h1,h2,…){color:…}`, which scores
   (0,1,0) — the same as one class — and is inlined earlier, so a single-class
   selector would tie and lose on nothing but luck. */
body.woocommerce main :is(h1, h2, h3, h4),
body.woocommerce-page main :is(h1, h2, h3, h4) {
	color: var(--lv-ink);
}

/* ==========================================================================
   01 · Breadcrumb
   ========================================================================== */

body.woocommerce nav.woocommerce-breadcrumb,
body.woocommerce-page nav.woocommerce-breadcrumb {
	font-size: var(--lv-micro-size);
	font-weight: var(--lv-micro-weight);
	letter-spacing: var(--lv-micro-ls);
	text-transform: uppercase;
	line-height: 1.4;
	color: var(--lv-muted);
	margin: 0;
	padding-block: 0.25rem;
}

body.woocommerce nav.woocommerce-breadcrumb a,
body.woocommerce-page nav.woocommerce-breadcrumb a {
	color: var(--lv-muted);
	text-decoration: none;
	transition: color var(--lv-dur-fast) var(--lv-ease);
}

body.woocommerce nav.woocommerce-breadcrumb a:hover,
body.woocommerce nav.woocommerce-breadcrumb a:focus-visible,
body.woocommerce-page nav.woocommerce-breadcrumb a:hover,
body.woocommerce-page nav.woocommerce-breadcrumb a:focus-visible {
	color: var(--lv-accent);
}

/* ==========================================================================
   02 · Archive header — title, result count, ordering
   ========================================================================== */

/* theme.json sets h1 to clamp(2.75rem, 7.2vw, 5.125rem) — 82px at desktop.
   Editorial on a landing hero, absurd over a five-product grid. */
body.woocommerce h1.wp-block-query-title,
body.woocommerce-page h1.wp-block-query-title {
	font-size: clamp(2.25rem, 5vw, 3.5rem);
	font-weight: var(--lv-heading-weight);
	line-height: var(--lv-heading-lh);
	letter-spacing: var(--lv-heading-ls);
	margin: 0;
}

/* The toolbar row: "Showing all 5 results" on the left, the sort <select> on
   the right. WooCommerce ships it as a flex group with no styling of its own. */
/* Qualified with the block wrapper because product-results-count.css ships
   `.woocommerce.wc-block-product-results-count .woocommerce-result-count
   { font-size: inherit }` at (0,3,0), which out-scores a plain
   `body.woocommerce p.woocommerce-result-count` (0,1,2) and left this at the
   18px body size. (0,3,2) settles it — no `!important` needed. */
body.woocommerce .wc-block-product-results-count p.woocommerce-result-count,
body.woocommerce-page .wc-block-product-results-count p.woocommerce-result-count {
	margin: 0;
	font-size: var(--lv-micro-size);
	font-weight: var(--lv-micro-weight);
	letter-spacing: var(--lv-micro-ls);
	text-transform: uppercase;
	color: var(--lv-muted);
	line-height: 1;
}

body.woocommerce form.woocommerce-ordering,
body.woocommerce-page form.woocommerce-ordering {
	margin: 0;
}

/*
 * `appearance: none` plus our own chevron: the native control cannot be given
 * the 11px/750/0.12em micro type the rest of the shop uses. The chevron is an
 * inline SVG data URI in ink — no external request, no new colour.
 *
 * Qualified up to (0,3,3) with `form.woocommerce-ordering`. Not because
 * WooCommerce fights it, but because § 11's shared form-control rule matches
 * this select too (it is a `select` inside `.woocommerce`) at (0,3,2) and was
 * quietly winning on font-size and min-height. Measured: 16px/52px instead of
 * 11px. Height stays 52px deliberately — see the note in § 11 on the two
 * control heights.
 */
body.woocommerce form.woocommerce-ordering select.orderby,
body.woocommerce-page form.woocommerce-ordering select.orderby {
	appearance: none;
	-webkit-appearance: none;
	min-height: 52px;
	padding: 0 3rem 0 1.125rem;
	border: 1px solid var(--lv-rule);
	border-radius: var(--lv-radius);
	background-color: transparent;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23231b1e' stroke-width='1.6'%3E%3Cpath d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 1.125rem center;
	background-size: 12px 8px;
	color: var(--lv-ink);
	font-family: inherit;
	font-size: var(--lv-micro-size);
	font-weight: var(--lv-micro-weight);
	letter-spacing: var(--lv-micro-ls);
	text-transform: uppercase;
	line-height: 1;
	cursor: pointer;
	max-width: 100%;
	transition: border-color var(--lv-dur-fast) var(--lv-ease);
}

body.woocommerce form.woocommerce-ordering select.orderby:hover,
body.woocommerce-page form.woocommerce-ordering select.orderby:hover {
	border-color: var(--lv-rose-300);
}

body.woocommerce form.woocommerce-ordering select.orderby:focus-visible,
body.woocommerce-page form.woocommerce-ordering select.orderby:focus-visible {
	outline: 3px solid var(--lv-focus-color);
	outline-offset: 3px;
	box-shadow: 0 0 0 6px var(--lv-focus-halo);
}

/* Under ~520px the count and the select stop fitting on one line. The group is
   `is-nowrap` by block config, so allow the wrap here rather than let the
   select shrink into illegibility. */
@media (max-width: 560px) {
	body.woocommerce main .wp-block-group.is-nowrap:has(> .wp-block-woocommerce-catalog-sorting),
	body.woocommerce-page main .wp-block-group.is-nowrap:has(> .wp-block-woocommerce-catalog-sorting) {
		flex-wrap: wrap;
		gap: 1rem;
	}
}

/* ==========================================================================
   03 · Product grid — shop archive and related products
   ========================================================================== */

/*
 * The shop archive's `ul.wc-block-product-template` carries `is-layout-flow`
 * and no `is-flex-container`, so WooCommerce gives it no columns at all and it
 * renders as a stack. The related-products list on the single product *does*
 * get `is-flex-container.columns-5`, i.e. a wrapping flexbox.
 *
 * Both become the same CSS grid here. `auto-fill` rather than honouring the
 * `columns-N` class on purpose: `columns-3` on the archive and `columns-5` on
 * related are block defaults nobody chose, and with a five-product catalogue
 * they would produce two different card sizes on two pages of the same shop.
 * One `auto-fill` track definition gives identical cards everywhere and adapts
 * from 360px to 1200px without a single breakpoint.
 *
 * `min(100%, var(--lv-card-min))` guards the narrowest case: without it a
 * 220px minimum inside a 200px container overflows the viewport.
 */
body.woocommerce ul.wc-block-product-template,
body.woocommerce-page ul.wc-block-product-template {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--lv-card-min)), 1fr));
	column-gap: var(--lv-card-gap);
	row-gap: var(--lv-card-row-gap);
	list-style: none;
	margin: 0;
	padding: 0;
	max-width: 100%;
}

/* Card. Flex column so the add-to-cart button can be pushed to a common
   baseline across a row regardless of how many lines the title takes. */
body.woocommerce li.wc-block-product,
body.woocommerce-page li.wc-block-product {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 0.5rem;
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	text-align: left;
	position: relative;
	min-width: 0;
	width: auto;
}

/*
 * Neutralise WooCommerce's `columns-N` sizing, which is written for the
 * flexbox it expects rather than the grid we give it.
 *
 * The related-products list — unlike the shop archive — really does carry
 * `is-flex-container columns-5`, and WooCommerce ships
 *
 *     @media (min-width: 600px) {
 *       .wc-block-product-template.is-flex-container.is-flex-container.columns-5 > li
 *         { width: calc(20% - 1em); }
 *     }
 *
 * (the class is repeated on purpose, to buy specificity — (0,4,1)).
 *
 * A grid item honours `width`, and a percentage width inside a grid item
 * resolves against its TRACK, not the container. So `20%` of a 300px track
 * minus 1em produced 42px cards: four slivers with the titles breaking one
 * character per line. It only showed up on the product page, because the
 * archive's list has no `is-flex-container`.
 *
 * `.wp-block-woocommerce-product-collection` is the wrapper both lists share,
 * and adding it reaches (0,4,3) — beating (0,4,1) on class count without
 * repeating a class or reaching for `!important`.
 */
body.woocommerce .wp-block-woocommerce-product-collection ul.wc-block-product-template > li.wc-block-product,
body.woocommerce-page .wp-block-woocommerce-product-collection ul.wc-block-product-template > li.wc-block-product {
	width: auto;
	max-width: none;
	margin: 0;
}

/* Image plate. The rose tint gives the cut-out product shots a surface to sit
   on instead of floating on white, and covers the placeholder images too. */
body.woocommerce li.wc-block-product .wc-block-components-product-image,
body.woocommerce-page li.wc-block-product .wc-block-components-product-image {
	position: relative;
	margin: 0 0 1.125rem;
	background: var(--lv-rose-100);
	border-radius: var(--lv-radius);
	overflow: hidden;
}

body.woocommerce li.wc-block-product .wc-block-components-product-image img,
body.woocommerce-page li.wc-block-product .wc-block-components-product-image img {
	display: block;
	width: 100%;
	height: auto;
	transition: transform var(--lv-dur) var(--lv-ease);
}

body.woocommerce li.wc-block-product:hover .wc-block-components-product-image img,
body.woocommerce li.wc-block-product:focus-within .wc-block-components-product-image img,
body.woocommerce-page li.wc-block-product:hover .wc-block-components-product-image img,
body.woocommerce-page li.wc-block-product:focus-within .wc-block-components-product-image img {
	transform: scale(1.04);
}

/* Title. Two classes so the block library's `.has-text-align-center` (0,1,0)
   cannot hold the centring. */
body.woocommerce li.wc-block-product .wp-block-post-title,
body.woocommerce-page li.wc-block-product .wp-block-post-title {
	margin: 0;
	font-size: clamp(0.9375rem, 1.2vw, 1.0625rem);
	font-weight: var(--lv-heading-weight);
	letter-spacing: -0.022em;
	line-height: 1.28;
	text-align: left;
	text-wrap: pretty;
}

body.woocommerce li.wc-block-product .wp-block-post-title a,
body.woocommerce-page li.wc-block-product .wp-block-post-title a {
	color: inherit;
	text-decoration: none;
	transition: color var(--lv-dur-fast) var(--lv-ease);
}

body.woocommerce li.wc-block-product:hover .wp-block-post-title a,
body.woocommerce-page li.wc-block-product:hover .wp-block-post-title a {
	color: var(--lv-accent);
}

body.woocommerce li.wc-block-product .wp-block-woocommerce-product-price,
body.woocommerce-page li.wc-block-product .wp-block-woocommerce-product-price {
	text-align: left;
}

/* Size is set on the inner `.wc-block-components-product-price`, not on the
   `.wp-block-woocommerce-product-price` wrapper. The wrapper carries
   `has-small-font-size`, which WordPress emits with `!important`; the inner
   element carries no preset class, so the same result is reached here without
   one. Where that dodge is not available, see the !important block below. */
body.woocommerce li.wc-block-product .wc-block-components-product-price,
body.woocommerce-page li.wc-block-product .wc-block-components-product-price {
	font-size: 1.0625rem;
}

/* Button sits on a common baseline across the row. */
body.woocommerce li.wc-block-product .wc-block-components-product-button,
body.woocommerce-page li.wc-block-product .wc-block-components-product-button {
	margin-top: auto;
	padding-top: 0.875rem;
	text-align: left;
	width: 100%;
}

body.woocommerce li.wc-block-product .wc-block-components-product-button__button,
body.woocommerce-page li.wc-block-product .wc-block-components-product-button__button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: 48px;
	padding: 0 1.5rem;
	border: 1px solid var(--lv-ink);
	border-radius: var(--lv-radius);
	background: transparent;
	color: var(--lv-ink);
	font-family: inherit;
	font-size: var(--lv-micro-size);
	font-weight: var(--lv-micro-weight);
	letter-spacing: var(--lv-micro-ls);
	line-height: 1;
	text-transform: uppercase;
	text-decoration: none;
	cursor: pointer;
	transition:
		background-color var(--lv-dur-fast) var(--lv-ease),
		color var(--lv-dur-fast) var(--lv-ease),
		border-color var(--lv-dur-fast) var(--lv-ease);
}

body.woocommerce li.wc-block-product .wc-block-components-product-button__button:hover,
body.woocommerce li.wc-block-product .wc-block-components-product-button__button:focus-visible,
body.woocommerce-page li.wc-block-product .wc-block-components-product-button__button:hover,
body.woocommerce-page li.wc-block-product .wc-block-components-product-button__button:focus-visible {
	background: var(--lv-accent);
	border-color: var(--lv-accent);
	color: #fff;
}

body.woocommerce li.wc-block-product .wc-block-components-product-button__button:focus-visible,
body.woocommerce-page li.wc-block-product .wc-block-components-product-button__button:focus-visible {
	outline: 3px solid var(--lv-focus-color);
	outline-offset: 3px;
	box-shadow: 0 0 0 6px var(--lv-focus-halo);
}

/* The "View cart" link the AJAX button reveals after a successful add. */
body.woocommerce li.wc-block-product a.added_to_cart,
body.woocommerce-page li.wc-block-product a.added_to_cart {
	display: inline-block;
	margin-top: 0.625rem;
	font-size: var(--lv-micro-size);
	font-weight: var(--lv-micro-weight);
	letter-spacing: var(--lv-micro-ls);
	text-transform: uppercase;
	color: var(--lv-accent);
	text-decoration: none;
	border-bottom: 1px solid currentColor;
}

/* --------------------------------------------------------------------------
   The only `!important` declarations in this file.
   --------------------------------------------------------------------------
   Not WooCommerce this time — WordPress. `global-styles-inline-css` emits the
   font-size preset classes as

       .has-small-font-size  { font-size: var(--wp--preset--font-size--small)  !important; }
       .has-medium-font-size { font-size: var(--wp--preset--font-size--medium) !important; }
       .has-large-font-size  { font-size: var(--wp--preset--font-size--large)  !important; }

   and WooCommerce's block templates put those classes directly on the product
   title, the add-to-cart button and the single product's price. `!important`
   cannot be out-specified, only matched, so these three declarations are the
   only way to size those elements at all.

   Measured on the live page before adding them: the card title computed
   17.51px instead of 17px, the card button 14.88px instead of 11px (its
   letter-spacing had applied, which is what gave the mismatch away), and the
   product price fell back to the `large` preset. Every OTHER property on
   these elements is set without `!important` in the rules above; only
   `font-size` is repeated here, deliberately, so the exception stays as
   narrow as the problem.

   If a future WordPress drops `!important` from the preset classes, this
   block can be deleted and the plain rules above will take over unchanged. */

body.woocommerce li.wc-block-product .wp-block-post-title,
body.woocommerce-page li.wc-block-product .wp-block-post-title {
	font-size: clamp(0.9375rem, 1.2vw, 1.0625rem) !important; /* .has-medium-font-size */
}

body.woocommerce li.wc-block-product .wc-block-components-product-button__button,
body.woocommerce-page li.wc-block-product .wc-block-components-product-button__button {
	font-size: var(--lv-micro-size) !important; /* .has-small-font-size */
}

/* Related-products heading. */
body.single-product .wp-block-woocommerce-product-collection > h2.wp-block-heading {
	font-size: clamp(1.5rem, 2.6vw, 2rem);
	font-weight: var(--lv-heading-weight);
	letter-spacing: -0.03em;
	line-height: 1.1;
	margin: 0 0 clamp(1.5rem, 3vw, 2.5rem);
	padding-top: clamp(2rem, 4vw, 3.5rem);
	border-top: 1px solid var(--lv-rule);
}

/* ==========================================================================
   04 · Sale badge
   ========================================================================== */

/*
 * Two different badges on this site.
 *
 * The grid uses the block badge. woocommerce-blocktheme.css paints it
 * `var(--wp--preset--color--foreground, #958e09)` — and this theme's palette
 * has no `foreground` slug, so the fallback wins and the badge renders in
 * mustard. That is where the off-brand olive pill comes from.
 */
body.woocommerce .wc-block-components-product-sale-badge,
body.woocommerce-page .wc-block-components-product-sale-badge {
	position: absolute;
	top: 0.875rem;
	left: 0.875rem;
	z-index: 2;
	min-width: 0;
	min-height: 0;
	padding: 0.5rem 0.75rem;
	border: 0;
	border-radius: var(--lv-radius);
	background-color: var(--lv-accent);
	color: #fff;
	font-size: var(--lv-micro-size);
	font-weight: var(--lv-micro-weight);
	letter-spacing: var(--lv-micro-ls);
	text-transform: uppercase;
	line-height: 1;
}

/*
 * The single product uses the classic `span.onsale`. WooCommerce gives it a
 * 3.236em circle at `top:-.5em; left:-.5em`, and product-image-gallery.css
 * then pulls it to `left:-1rem` — which is what puts it outside the gallery
 * box and, on a narrow viewport, outside the page.
 *
 * Specificity: product-image-gallery.css uses
 * `.woocommerce .wp-block-woocommerce-product-image-gallery span.onsale` (0,2,1),
 * woocommerce.css uses `.woocommerce span.onsale` (0,1,1). Adding `body` as a
 * qualified class takes this to (0,3,1) and both are beaten without
 * `!important`.
 */
/*
 * `position: relative` so the sale badge below has something to anchor to, and
 * `max-width: none` because product-image-gallery.css ships
 * `.woocommerce .wp-block-woocommerce-product-image-gallery { max-width: 512px }`
 * at (0,2,0) — a hard pixel cap that kept the gallery at 512px inside a 588px
 * column no matter what the gallery itself was told. Measured: the gallery
 * block computed `max-width: 512px` with no inline style in sight. `body` as a
 * qualifier takes this to (0,2,1) and lifts the cap.
 */
body.woocommerce .wp-block-woocommerce-product-image-gallery {
	position: relative;
	max-width: none;
}

body.woocommerce .wp-block-woocommerce-product-image-gallery span.onsale {
	position: absolute;
	top: 1rem;
	left: 1rem;
	right: auto;
	z-index: 3;
	min-width: 0;
	min-height: 0;
	margin: 0;
	padding: 0.5rem 0.875rem;
	border-radius: var(--lv-radius);
	background-color: var(--lv-accent);
	color: #fff;
	font-size: var(--lv-micro-size);
	font-weight: var(--lv-micro-weight);
	letter-spacing: var(--lv-micro-ls);
	text-transform: uppercase;
	line-height: 1;
	text-align: center;
}

/* ==========================================================================
   05 · Price
   ========================================================================== */

/*
 * WooCommerce renders a sale price as `<del>…</del><span class="screen-reader-text">
 * …</span><ins>…</ins><span class="screen-reader-text">…</span>`. With no
 * styling the two prices run together — "132,99 €89,88 €" — which is the
 * run-on the client is seeing.
 *
 * Flex with a gap separates them. The screen-reader spans are
 * `position: absolute` (WordPress core), so they are not flex items and
 * contribute no gap of their own.
 */
body.woocommerce .wc-block-components-product-price,
body.woocommerce-page .wc-block-components-product-price {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.5rem 0.625rem;
	color: var(--lv-ink);
	font-weight: var(--lv-heading-weight);
	letter-spacing: -0.02em;
	line-height: 1.2;
}

body.woocommerce .wc-block-components-product-price del,
body.woocommerce-page .wc-block-components-product-price del {
	order: 2;
	opacity: 1;
	color: var(--lv-muted);
	font-weight: 400;
	text-decoration: line-through;
	font-size: 0.8em;
}

body.woocommerce .wc-block-components-product-price ins,
body.woocommerce-page .wc-block-components-product-price ins {
	order: 1;
	background: none;
	color: var(--lv-accent);
	font-weight: var(--lv-heading-weight);
	text-decoration: none;
}

/* The product page's price is the headline number, not a caption.
   `!important` for the same reason as the block in § 03: this element carries
   `has-large-font-size`, and there is no unclassed inner element to fall back
   on here because the flex layout above is applied to the inner price node. */
body.single-product .wp-block-columns .wp-block-woocommerce-product-price {
	font-size: clamp(1.75rem, 3.2vw, 2.5rem) !important; /* .has-large-font-size */
	margin: 0;
}

/* ==========================================================================
   06 · Single product — the gallery / summary split
   ========================================================================== */

/*
 * WooCommerce's block template puts an INLINE `style="flex-basis:512px"` on the
 * first column. An inline declaration outranks any stylesheet rule short of
 * `!important`, so the 512/928 split cannot be corrected by restyling the flex
 * child.
 *
 * Switching the parent to `display: grid` sidesteps it entirely: `flex-basis`
 * has no effect on a grid item, so the inline style goes inert and
 * `grid-template-columns` takes over — no `!important` required. This is the
 * one place on the page where the fix had to be structural rather than
 * cosmetic, and it is why the split is a grid and not a tuned flexbox.
 *
 * 48/52 rather than 50/50: the summary carries the title, price, excerpt and
 * the buy control, so it earns the slightly wider track, and at the 1200
 * measure it lands near 590px ≈ 68 characters.
 */
body.single-product main .wp-block-columns.alignwide {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: clamp(1.75rem, 4vw, 3.5rem);
	align-items: start;
	margin: 0;
}

@media (min-width: 860px) {
	body.single-product main .wp-block-columns.alignwide {
		grid-template-columns: minmax(0, 48fr) minmax(0, 52fr);
		gap: clamp(2.5rem, 5vw, 4.5rem);
	}
}

body.single-product main .wp-block-columns.alignwide > .wp-block-column {
	min-width: 0;
	margin: 0;
}

/* Summary column: consistent vertical rhythm between title, price, excerpt,
   buy form and meta. The block editor emits no gap for these. */
@media (min-width: 860px) {
	body.single-product main .wp-block-columns.alignwide > .wp-block-column:last-child {
		position: sticky;
		top: calc(var(--lv-header-h, 0px) + 2rem);
	}
}

body.single-product main .wp-block-columns.alignwide > .wp-block-column > * + * {
	margin-block-start: clamp(1rem, 2vw, 1.5rem);
}

/*
 * Gallery. woocommerce-layout.css floats `div.images` left at 48%. Left
 * floated, the gallery is out of flow and its parent's height collapses,
 * which breaks both the badge anchor and the column.
 *
 * That rule is `.woocommerce div.product div.images` = (0,3,2). An earlier
 * draft here used three classes and one element = (0,3,1) and quietly LOST —
 * the float measured `left` even though the override looked right on paper.
 * Adding `.images` makes it (0,4,1), which wins on class count. Worth stating
 * plainly: count the elements too, not just the classes.
 */
body.woocommerce .wp-block-woocommerce-product-image-gallery .woocommerce-product-gallery.images {
	float: none;
	width: 100%;
	margin: 0;
	background: var(--lv-rose-100);
	border-radius: var(--lv-radius);
	overflow: hidden;
}

body.woocommerce .wp-block-woocommerce-product-image-gallery .woocommerce-product-gallery.images img {
	display: block;
	width: 100%;
	height: auto;
}

/*
 * The 🔍 full-screen trigger. WooCommerce's own rule is
 * `.woocommerce div.product div.images .woocommerce-product-gallery__trigger`
 * = (0,4,2). Qualifying with `.images` as well as `body.woocommerce` gives
 * (0,5,1), which beats it on class count.
 */
body.woocommerce .wp-block-woocommerce-product-image-gallery .woocommerce-product-gallery.images .woocommerce-product-gallery__trigger {
	position: absolute;
	top: 1rem;
	right: 1rem;
	left: auto;
	z-index: 3;
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	padding: 0;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.92);
	color: var(--lv-ink);
	font-size: 1rem;
	line-height: 1;
	text-decoration: none;
	box-shadow: none;
	transition: background-color var(--lv-dur-fast) var(--lv-ease);
}

body.woocommerce .wp-block-woocommerce-product-image-gallery .woocommerce-product-gallery.images .woocommerce-product-gallery__trigger:hover {
	background: #fff;
}

/* Product title. theme.json's h1 clamp tops out at 5.125rem; a product name is
   not a hero headline. */
body.single-product main h1.wp-block-post-title {
	font-size: clamp(1.875rem, 3.4vw, 2.75rem);
	font-weight: var(--lv-heading-weight);
	line-height: 1.04;
	letter-spacing: -0.038em;
	margin: 0;
	text-wrap: balance;
}

/* Short description. */
body.single-product main .wp-block-post-excerpt__excerpt {
	margin: 0;
	max-width: var(--lv-prose-w);
	color: var(--lv-muted);
	font-size: 1rem;
	line-height: 1.62;
}

/* ==========================================================================
   07 · Single product — quantity and add to cart
   ========================================================================== */

body.single-product form.cart {
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
	gap: 0.75rem;
	margin: 0;
	padding-block: 0.5rem;
}

body.single-product form.cart .quantity {
	display: flex;
	margin: 0;
	float: none;
}

/* assets/lauriva.css already gives `.qty` the border and radius; this only
   matches its height to the 48px button so the pair reads as one control. */
body.single-product form.cart .quantity input.qty {
	width: 5.5rem;
	min-height: 52px;
	padding: 0 0.5rem;
	text-align: center;
	font-size: 1rem;
	font-variant-numeric: tabular-nums;
	background: transparent;
	color: var(--lv-ink);
}

body.single-product form.cart .quantity input.qty:focus-visible {
	outline: 3px solid var(--lv-focus-color);
	outline-offset: 3px;
	box-shadow: 0 0 0 6px var(--lv-focus-halo);
}

/* The colour of this button is owned by the WooCommerce bridge at the bottom of
   assets/lauriva.css (accent background, white text, with the `!important` it
   documents there). Only geometry is set here, so nothing is fought twice. */
body.single-product form.cart button.single_add_to_cart_button {
	flex: 1 1 14rem;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 52px;
	padding: 0 2.25rem;
	float: none;
}

@media (max-width: 480px) {
	body.single-product form.cart {
		gap: 0.625rem;
	}

	body.single-product form.cart .quantity input.qty {
		width: 4.5rem;
	}

	body.single-product form.cart button.single_add_to_cart_button {
		flex: 1 1 100%;
	}
}

/* ==========================================================================
   08 · Single product — meta / categories
   ========================================================================== */

body.single-product .wp-block-woocommerce-product-meta {
	padding-top: clamp(1rem, 2vw, 1.5rem);
	border-top: 1px solid var(--lv-rule);
	font-size: var(--lv-micro-size);
	font-weight: var(--lv-micro-weight);
	letter-spacing: var(--lv-micro-ls);
	text-transform: uppercase;
	line-height: 1.6;
	color: var(--lv-muted);
}

body.single-product .wp-block-woocommerce-product-meta .wp-block-post-terms {
	color: var(--lv-muted);
}

body.single-product .wp-block-woocommerce-product-meta a {
	color: var(--lv-ink);
	text-decoration: none;
	border-bottom: 1px solid var(--lv-rose-300);
	transition:
		color var(--lv-dur-fast) var(--lv-ease),
		border-color var(--lv-dur-fast) var(--lv-ease);
}

body.single-product .wp-block-woocommerce-product-meta a:hover,
body.single-product .wp-block-woocommerce-product-meta a:focus-visible {
	color: var(--lv-accent);
	border-color: var(--lv-accent);
}

/* ==========================================================================
   09 · Product tabs
   ========================================================================== */

/*
 * These are WooCommerce's own tabs (`ul.tabs.wc-tabs` + `.woocommerce-Tabs-panel`),
 * rendered inside the Product Details block with the `is-style-minimal` style
 * variation. Nothing is renamed and no JavaScript is involved — WooCommerce's
 * own tab script keeps working. The goal is only that they read as `.lv-tabs`.
 *
 * SPECIFICITY. product-details.css ships
 *
 *     html body .wp-block-woocommerce-product-details.is-style-minimal ul.tabs.wc-tabs li
 *
 * which is (0,4,4) — four classes, four element/pseudo parts. This file loads
 * later, so an equal (0,4,4) selector would win on order alone; that is not
 * relied on, because the same stylesheet repeats the rule inside a
 * `@media (max-width: 768px)` block and a tie there is fragile. Qualifying with
 * `body.single-product` instead of `html body` gives
 *
 *     body.single-product .wp-block-woocommerce-product-details.is-style-minimal ul.tabs.wc-tabs li
 *
 * = (0,5,3): five classes beats four outright, in both the base and the media
 * rule, without `!important`. woocommerce.css's own (0,3,3) and (0,3,4) tab
 * rules are beaten by the same margin.
 */

body.single-product .wp-block-woocommerce-product-details.is-style-minimal .woocommerce-tabs {
	padding-top: clamp(2rem, 4vw, 3.5rem);
	border-top: 1px solid var(--lv-rule);
}

/* Tab strip. Scrolls inside its own box on narrow viewports; the page never
   gains a horizontal scrollbar. Mirrors `.lv-tabs__list`. */
body.single-product .wp-block-woocommerce-product-details.is-style-minimal ul.tabs.wc-tabs {
	display: flex;
	gap: clamp(1rem, 3vw, 2.75rem);
	align-items: stretch;
	margin: 0 0 clamp(1.75rem, 3.5vw, 2.75rem);
	padding: 0;
	border: 0;
	border-bottom: 1px solid var(--lv-rule);
	list-style: none;
	overflow-x: auto;
	overflow-y: hidden;
	scrollbar-width: none;
	-ms-overflow-style: none;
	-webkit-overflow-scrolling: touch;
}

body.single-product .wp-block-woocommerce-product-details.is-style-minimal ul.tabs.wc-tabs::-webkit-scrollbar {
	display: none;
}

/* WooCommerce draws the strip's rule and the tabs' rounded shoulders with
   pseudo-elements. The rule now lives on the list itself and the shoulders are
   not part of this design. */
body.single-product .wp-block-woocommerce-product-details.is-style-minimal ul.tabs.wc-tabs::before,
body.single-product .wp-block-woocommerce-product-details.is-style-minimal ul.tabs.wc-tabs::after,
body.single-product .wp-block-woocommerce-product-details.is-style-minimal ul.tabs.wc-tabs li::before,
body.single-product .wp-block-woocommerce-product-details.is-style-minimal ul.tabs.wc-tabs li::after {
	content: none;
}

body.single-product .wp-block-woocommerce-product-details.is-style-minimal ul.tabs.wc-tabs li {
	flex: 0 0 auto;
	display: block;
	float: none;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: none;
	box-shadow: none;
	position: relative;
	white-space: nowrap;
}

body.single-product .wp-block-woocommerce-product-details.is-style-minimal ul.tabs.wc-tabs li a {
	display: block;
	padding: 0.875rem 0.125rem 1.0625rem;
	border-bottom: 2px solid transparent;
	color: var(--lv-muted);
	font-family: inherit;
	font-size: clamp(1rem, 2.2vw, 1.25rem);
	font-weight: var(--lv-heading-weight);
	letter-spacing: -0.028em;
	line-height: 1.1;
	text-decoration: none;
	text-shadow: none;
	transition:
		color var(--lv-dur-fast) var(--lv-ease),
		border-color var(--lv-dur-fast) var(--lv-ease);
}

body.single-product .wp-block-woocommerce-product-details.is-style-minimal ul.tabs.wc-tabs li a:hover {
	color: var(--lv-ink);
}

/*
 * The underline is re-declared as a full shorthand here rather than just a
 * colour, and that is load-bearing. product-details.css also ships
 *
 *     html body …is-style-minimal ul.tabs.wc-tabs li.active a { border: none; }
 *
 * at (0,5,5). The base `li a` rule above is (0,5,4), so for the ACTIVE tab
 * only, WooCommerce's `border: none` outscored it and zeroed the width —
 * measured as `border-bottom-color: rgb(200,68,100)` with
 * `border-bottom-width: 0px`, i.e. an accent underline that was correctly
 * coloured and completely invisible. This selector is (0,6,4) and beats it,
 * so setting width and style here restores the underline.
 */
body.single-product .wp-block-woocommerce-product-details.is-style-minimal ul.tabs.wc-tabs li.active a {
	color: var(--lv-ink);
	border-bottom: 2px solid var(--lv-accent);
}

body.single-product .wp-block-woocommerce-product-details.is-style-minimal ul.tabs.wc-tabs li a:focus-visible {
	outline: 3px solid var(--lv-focus-color);
	outline-offset: 3px;
	box-shadow: 0 0 0 6px var(--lv-focus-halo);
	border-radius: var(--lv-radius);
}

/* product-details.css turns the strip into a vertical stack with a left border
   below 768px. A horizontally scrolling strip keeps the tabs where a shopper
   expects them, and the same (0,5,3) selectors win inside a media query. */
@media (max-width: 768px) {
	body.single-product .wp-block-woocommerce-product-details.is-style-minimal ul.tabs.wc-tabs li {
		display: block;
		margin: 0;
		border-width: 0;
	}
}

/* Panel. */
body.single-product .woocommerce-Tabs-panel {
	max-width: var(--lv-prose-w);
	font-size: 1rem;
	line-height: 1.68;
	color: var(--lv-text);
}

/*
 * WooCommerce injects an `<h2>Apraksts</h2>` at the top of the description
 * panel, repeating the tab label immediately below the tab that says the same
 * word. Visually redundant, but it is still the panel's own heading, so it is
 * hidden from sight rather than removed — screen readers and a no-CSS render
 * keep it. Same technique as `.lv-sr-only`.
 */
body.single-product .woocommerce-Tabs-panel--description > h2:first-child {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

body.single-product .woocommerce-Tabs-panel > * + * {
	margin-block-start: 1rem;
}

/*
 * The imported description contains its own `<h1>` and `<h2>` tags. The `<h1>`s
 * are a content problem (a product page must have exactly one, and it is the
 * product title) — noted for the shop owner, not fixable in CSS. What CSS can
 * do is stop them rendering at hero scale inside a tab panel.
 */
body.single-product .woocommerce-Tabs-panel :is(h1, h2, h3) {
	font-weight: var(--lv-heading-weight);
	letter-spacing: -0.028em;
	line-height: 1.14;
	margin-block: 1.75rem 0.5rem;
}

body.single-product .woocommerce-Tabs-panel :is(h1, h2) {
	font-size: clamp(1.25rem, 2.2vw, 1.5rem);
}

body.single-product .woocommerce-Tabs-panel h3 {
	font-size: clamp(1.0625rem, 1.8vw, 1.25rem);
}

body.single-product .woocommerce-Tabs-panel hr {
	height: 1px;
	margin-block: 1.75rem;
	border: 0;
	background: var(--lv-rule);
}

body.single-product .woocommerce-Tabs-panel p {
	margin: 0;
}

/* Reviews tab. */
body.single-product .woocommerce-Tabs-panel--reviews .woocommerce-noreviews {
	margin: 0;
	color: var(--lv-muted);
}

/* ==========================================================================
   10 · Notices
   ========================================================================== */

/* Classic notices. WooCommerce's own rule is (0,1,0) — a coloured top border
   over #f6f5f8 with an icon-font glyph in a `::before`. */
body.woocommerce .woocommerce-message,
body.woocommerce .woocommerce-info,
body.woocommerce .woocommerce-error,
body.woocommerce-page .woocommerce-message,
body.woocommerce-page .woocommerce-info,
body.woocommerce-page .woocommerce-error {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.75rem 1rem;
	margin: 0 0 1.5rem;
	padding: 1.125rem 1.375rem;
	border: 1px solid var(--lv-rule);
	border-top: 2px solid var(--lv-accent);
	border-radius: var(--lv-radius);
	background-color: var(--lv-cream);
	color: var(--lv-ink);
	font-size: 1rem;
	line-height: 1.5;
	list-style: none;
}

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

body.woocommerce .woocommerce-info,
body.woocommerce-page .woocommerce-info {
	border-top-color: var(--lv-rose-300);
	background-color: var(--lv-rose-100);
}

body.woocommerce .woocommerce-error,
body.woocommerce-page .woocommerce-error {
	border-top-color: #b3261e;
	background-color: #fdf3f2;
}

/* The inline action link ("Apskatīt grozu") pushed to the end of the row. */
body.woocommerce .woocommerce-message .button,
body.woocommerce-page .woocommerce-message .button {
	margin-left: auto;
}

/* Block notices (cart, checkout, the AJAX add-to-cart banner). */
body.woocommerce .wc-block-components-notice-banner,
body.woocommerce-page .wc-block-components-notice-banner {
	margin: 0 0 1.5rem;
	padding: 1rem 1.25rem;
	border: 1px solid var(--lv-rule);
	border-left-width: 2px;
	border-radius: var(--lv-radius);
	background-color: var(--lv-cream);
	color: var(--lv-ink);
	font-size: 1rem;
	line-height: 1.5;
}

body.woocommerce .wc-block-components-notice-banner.is-success,
body.woocommerce-page .wc-block-components-notice-banner.is-success {
	border-left-color: var(--lv-accent);
}

body.woocommerce .wc-block-components-notice-banner.is-info,
body.woocommerce-page .wc-block-components-notice-banner.is-info {
	border-left-color: var(--lv-rose-300);
	background-color: var(--lv-rose-100);
}

body.woocommerce .wc-block-components-notice-banner.is-error,
body.woocommerce-page .wc-block-components-notice-banner.is-error {
	border-left-color: #b3261e;
	background-color: #fdf3f2;
}

body.woocommerce .wc-block-components-notice-banner > svg,
body.woocommerce-page .wc-block-components-notice-banner > svg {
	fill: currentColor;
}

/* ==========================================================================
   11 · Form controls — shared by cart, checkout and account
   ========================================================================== */

/*
 * Two families of control, because the shop has two form systems.
 *
 * CLASSIC (my account, and anything WooCommerce renders server-side). These
 * live inside a `.woocommerce` wrapper, so that is the hook.
 *
 * `:not(.woocommerce-ordering)` excludes the shop's sort control. It is a
 * navigation control rather than a data-entry field and § 02 styles it
 * deliberately at 11px micro type with its own chevron — and without the
 * exclusion the two rules tie at (0,3,3), which this one would win purely by
 * sitting further down the file, silently reverting the sort control to 16px.
 */
body.woocommerce-page .woocommerce form:not(.woocommerce-ordering) :is(
	input[type="text"],
	input[type="email"],
	input[type="tel"],
	input[type="password"],
	input[type="number"],
	textarea,
	select
) {
	min-height: 52px;
	padding: 0.875rem 1rem;
	border: 1px solid var(--lv-rule);
	border-radius: var(--lv-radius);
	background-color: var(--lv-bg);
	color: var(--lv-ink);
	font-family: inherit;
	font-size: 1rem;
	line-height: 1.4;
	box-shadow: none;
	transition: border-color var(--lv-dur-fast) var(--lv-ease);
}

/*
 * BLOCK (cart and checkout, React-rendered). Deliberately NOT folded into the
 * rule above, for two measured reasons:
 *
 * 1. These controls are not inside a `.woocommerce` element at all. The
 *    country `<select>` sits in
 *    `.wc-block-components-address-form > .wc-blocks-components-select`, and
 *    `select.closest('.woocommerce')` returned null on the live page — so a
 *    `.woocommerce form select` selector never matched it and the select kept
 *    WooCommerce's own 4px radius and no min-height.
 *
 * 2. checkout.css styles the text inputs at
 *    `.wc-block-components-form .wc-block-components-text-input input[type="email"]`
 *    = (0,3,1). An `:is()` wrapper takes the specificity of its most specific
 *    argument, so the earlier combined rule scored only (0,2,2) and lost the
 *    border colour while winning height and radius — a half-styled input.
 *    Naming the form wrapper explicitly reaches (0,3,2).
 */
body.woocommerce-page .wc-block-components-form .wc-block-components-text-input input,
body.woocommerce-page .wc-block-components-form .wc-block-components-textarea,
body.woocommerce-page .wc-blocks-components-select .wc-blocks-components-select__select {
	min-height: 52px;
	/* Padding is deliberately NOT set here. These controls carry a floating
	   label positioned inside the box, and WooCommerce's own padding is what
	   reserves room for it. Overriding it with a flat `0.875rem 1rem` made the
	   country select's label sit on top of "Latvija" — visible in testing.
	   Border, radius, colour and height are ours; the label geometry is
	   WooCommerce's, and it should stay that way. (The one exception is the
	   select, below: it ships with no padding at all, so raising its
	   min-height to match the inputs re-centred the value under the floating
	   label. It gets the inputs' own 24/8 split back explicitly.) */
	border: 1px solid var(--lv-rule);
	border-radius: var(--lv-radius);
	background-color: var(--lv-bg);
	color: var(--lv-ink);
	font-family: inherit;
	font-size: 1rem;
	line-height: 1.4;
	box-shadow: none;
	transition: border-color var(--lv-dur-fast) var(--lv-ease);
}

/* The select ships with zero padding and relies on its natural height to keep
   the floating label clear of the value. Once min-height matches the text
   inputs, it needs their padding too. Right padding leaves room for
   WooCommerce's own chevron image, which is absolutely positioned. */
body.woocommerce-page .wc-blocks-components-select .wc-blocks-components-select__select {
	padding: 1.5rem 2.75rem 0.5rem 1rem;
}

body.woocommerce-page .woocommerce form:not(.woocommerce-ordering) :is(input, textarea, select):focus-visible,
body.woocommerce-page .wc-block-components-form .wc-block-components-text-input input:focus-visible,
body.woocommerce-page .wc-blocks-components-select .wc-blocks-components-select__select:focus-visible {
	outline: 3px solid var(--lv-focus-color);
	outline-offset: 2px;
	box-shadow: 0 0 0 5px var(--lv-focus-halo);
	border-color: var(--lv-ink);
}

/* Floating labels sit inside the input box; the extra top padding keeps the
   value clear of the label once it has floated up. */
body.woocommerce-page .wc-block-components-form .wc-block-components-text-input {
	margin-top: 1rem;
}

body.woocommerce-page .wc-block-components-checkout-step__title,
body.woocommerce-page .wc-block-components-title {
	font-family: inherit;
	font-weight: var(--lv-heading-weight);
	letter-spacing: -0.028em;
	color: var(--lv-ink);
}

/* ==========================================================================
   12 · Cart
   ========================================================================== */

body.woocommerce-cart main h1.wp-block-post-title {
	font-size: clamp(2rem, 4vw, 3rem);
	font-weight: var(--lv-heading-weight);
	line-height: var(--lv-heading-lh);
	letter-spacing: var(--lv-heading-ls);
	margin: 0 0 clamp(1.5rem, 3vw, 2.5rem);
}

body.woocommerce-cart .wc-block-cart-items {
	border-collapse: collapse;
	width: 100%;
}

body.woocommerce-cart .wc-block-cart-items__header {
	font-size: var(--lv-micro-size);
	font-weight: var(--lv-micro-weight);
	letter-spacing: var(--lv-micro-ls);
	text-transform: uppercase;
	color: var(--lv-muted);
	border-bottom: 1px solid var(--lv-rule);
}

body.woocommerce-cart .wc-block-cart-items__row {
	border-bottom: 1px solid var(--lv-rule);
}

/* cart.css styles this at
   `table.wc-block-cart-items .wc-block-cart-items__row .wc-block-components-product-name`
   = (0,3,1); a plain two-class selector lost and the name stayed at weight
   500. Qualifying with the table takes this to (0,3,2). */
body.woocommerce-cart table.wc-block-cart-items .wc-block-components-product-name {
	color: var(--lv-ink);
	font-weight: var(--lv-heading-weight);
	letter-spacing: -0.022em;
	text-decoration: none;
}

body.woocommerce-cart table.wc-block-cart-items .wc-block-components-product-name:hover {
	color: var(--lv-accent);
}

body.woocommerce-cart .wc-block-cart-item__image img {
	border-radius: var(--lv-radius);
	background: var(--lv-rose-100);
}

/*
 * Order summary card.
 *
 * Note the compound selector. `wc-block-components-sidebar` and
 * `wc-block-cart__sidebar` are two classes on the SAME element, not a parent
 * and a child — an earlier descendant selector here matched nothing at all
 * and the card silently stayed white. Verified against the live DOM:
 * `div.wc-block-components-sidebar.wc-block-cart__sidebar.wp-block-woocommerce-cart-totals-block`.
 *
 * The tint goes on the order-summary block rather than the whole sidebar, so
 * the checkout button below it stays on the page background and reads as the
 * primary action instead of another row inside the card.
 */
body.woocommerce-cart .wc-block-cart__sidebar {
	--lv-rule: var(--lv-rose-300);
}

body.woocommerce-cart .wc-block-cart__sidebar .wp-block-woocommerce-cart-order-summary-block {
	padding: clamp(1.25rem, 2.5vw, 1.75rem);
	background: var(--lv-rose-100);
	border-radius: var(--lv-radius);
}

body.woocommerce-cart .wc-block-cart__totals-title {
	margin: 0 0 0.75rem;
	font-size: var(--lv-micro-size);
	font-weight: var(--lv-micro-weight);
	letter-spacing: var(--lv-micro-ls);
	text-transform: uppercase;
	color: var(--lv-muted);
}

body.woocommerce-cart .wc-block-components-totals-item__label {
	font-size: var(--lv-micro-size);
	font-weight: var(--lv-micro-weight);
	letter-spacing: var(--lv-micro-ls);
	text-transform: uppercase;
	color: var(--lv-muted);
}

body.woocommerce-cart .wc-block-components-totals-item__value {
	color: var(--lv-ink);
	font-weight: var(--lv-heading-weight);
	font-variant-numeric: tabular-nums;
}

body.woocommerce-cart .wc-block-components-totals-footer-item .wc-block-components-totals-item__value {
	font-size: clamp(1.375rem, 2.4vw, 1.75rem);
	letter-spacing: -0.03em;
}

body.woocommerce-cart .wc-block-cart__submit-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: 52px;
	padding: 0 2rem;
	border: 1px solid transparent;
	border-radius: var(--lv-radius);
	background: var(--lv-accent);
	color: #fff;
	font-family: inherit;
	font-size: var(--lv-micro-size);
	font-weight: var(--lv-micro-weight);
	letter-spacing: var(--lv-micro-ls);
	line-height: 1;
	text-transform: uppercase;
	text-decoration: none;
	transition: background-color var(--lv-dur-fast) var(--lv-ease);
}

body.woocommerce-cart .wc-block-cart__submit-button:hover,
body.woocommerce-cart .wc-block-cart__submit-button:focus-visible {
	background: var(--lv-ink);
	color: #fff;
}

/* WooCommerce Blocks ships its own focus ring on this button — measured as a
   2px `rgb(6,117,196)` box-shadow, i.e. bright blue on a pink CTA. Replaced
   with the ink ring and white halo every other control in the shop uses. */
body.woocommerce-cart .wc-block-cart__submit-button:focus-visible {
	outline: 3px solid var(--lv-focus-color);
	outline-offset: 3px;
	box-shadow: 0 0 0 6px var(--lv-focus-halo);
}

/* Empty-cart state — it also renders a product grid, which § 03 already
   covers; this only settles the headings. */
body.woocommerce-cart .wp-block-woocommerce-empty-cart-block h2 {
	font-size: clamp(1.375rem, 2.6vw, 1.875rem);
	font-weight: var(--lv-heading-weight);
	letter-spacing: -0.032em;
}

/* ==========================================================================
   13 · Checkout
   ========================================================================== */

/* The checkout template swaps the site header for WooCommerce's own minimal
   one, so the page needs its own top breathing room. */
body.woocommerce-checkout main:not(.lv-page) {
	padding-block-start: clamp(1.5rem, 4vw, 3rem);
}

body.woocommerce-checkout .wc-block-components-checkout-step__heading {
	margin-block: 0 0.75rem;
}

body.woocommerce-checkout .wc-block-components-checkout-step__title {
	font-size: clamp(1.125rem, 1.8vw, 1.375rem);
}

body.woocommerce-checkout .wc-block-components-checkout-step__description {
	color: var(--lv-muted);
}

/* Compound, not descendant — see the note on the cart sidebar in § 12. */
body.woocommerce-checkout .wc-block-checkout__sidebar {
	--lv-rule: var(--lv-rose-300);
}

body.woocommerce-checkout .wc-block-checkout__sidebar .wc-block-components-order-summary,
body.woocommerce-checkout .wc-block-checkout__sidebar .wp-block-woocommerce-checkout-order-summary-block {
	padding: clamp(1.25rem, 2.5vw, 1.75rem);
	background: var(--lv-rose-100);
	border-radius: var(--lv-radius);
}

body.woocommerce-checkout .wc-block-components-totals-item__label {
	font-size: var(--lv-micro-size);
	font-weight: var(--lv-micro-weight);
	letter-spacing: var(--lv-micro-ls);
	text-transform: uppercase;
	color: var(--lv-muted);
}

body.woocommerce-checkout .wc-block-components-totals-item__value {
	color: var(--lv-ink);
	font-weight: var(--lv-heading-weight);
	font-variant-numeric: tabular-nums;
}

body.woocommerce-checkout .wc-block-components-checkout-place-order-button {
	min-height: 56px;
	border-radius: var(--lv-radius);
	background: var(--lv-accent);
	color: #fff;
	font-family: inherit;
	font-size: var(--lv-micro-size);
	font-weight: var(--lv-micro-weight);
	letter-spacing: var(--lv-micro-ls);
	text-transform: uppercase;
	transition: background-color var(--lv-dur-fast) var(--lv-ease);
}

body.woocommerce-checkout .wc-block-components-checkout-place-order-button:hover,
body.woocommerce-checkout .wc-block-components-checkout-place-order-button:focus-visible {
	background: var(--lv-ink);
	color: #fff;
}

/* Same blue-ring replacement as the cart's checkout button. */
body.woocommerce-checkout .wc-block-components-checkout-place-order-button:focus-visible {
	outline: 3px solid var(--lv-focus-color);
	outline-offset: 3px;
	box-shadow: 0 0 0 6px var(--lv-focus-halo);
}

body.woocommerce-checkout .wc-block-checkout__terms {
	color: var(--lv-muted);
	font-size: 0.9375rem;
}

/* Payment method rows (Montonio is the live gateway here). */
body.woocommerce-checkout .wc-block-components-radio-control__option {
	border-radius: var(--lv-radius);
}

/* ==========================================================================
   14 · My account
   ========================================================================== */

/*
 * The only genuinely classic page. style.css § 05 already gives
 * `.lv-page .woocommerce` a 1440 container; this narrows it to the shop
 * measure and replaces WooCommerce's 30%/68% float pair with a grid.
 * `body.woocommerce-account .lv-page .woocommerce` is (0,3,0) against
 * style.css's (0,2,0), and the nav's own `float`/`width` come from
 * `.woocommerce-account .woocommerce-MyAccount-navigation` at (0,2,0), which
 * the (0,4,0) selectors below beat. Floats are ignored on grid items; the
 * explicit `width: auto` is what actually undoes the 30%.
 */
body.woocommerce-account .lv-page .woocommerce {
	max-width: var(--lv-shop-w);
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: clamp(1.5rem, 3vw, 2.5rem);
	align-items: start;
}

@media (min-width: 840px) {
	body.woocommerce-account .lv-page .woocommerce {
		grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
		gap: clamp(2rem, 4vw, 4rem);
	}
}

/*
 * Kill WooCommerce's clearfix on this element. `woocommerce.css` ships
 *
 *     .woocommerce::after, .woocommerce::before { content: " "; display: table; }
 *     .woocommerce::after { clear: both; }
 *
 * which is harmless in flow layout and actively wrong in grid: generated
 * content boxes ARE grid items. With them in place the four items laid out as
 * [::before, nav, content, ::after], so the nav landed in column 2 of row 1
 * and the account content was pushed to column 1 of row 2 — the nav rendered
 * 998px wide on the right and the greeting text was squeezed into a 240px
 * column underneath it. Measured on the live page; every placement property
 * on both elements read `auto`, which is exactly why it was invisible from
 * the elements themselves.
 *
 * `.woocommerce::before` is (0,1,1); this is (0,3,2).
 */
body.woocommerce-account .lv-page .woocommerce::before,
body.woocommerce-account .lv-page .woocommerce::after {
	content: none;
	display: none;
}


body.woocommerce-account .lv-page .woocommerce .woocommerce-notices-wrapper {
	grid-column: 1 / -1;
	max-width: none;
	padding-inline: 0;
}

body.woocommerce-account .lv-page .woocommerce .woocommerce-MyAccount-navigation,
body.woocommerce-account .lv-page .woocommerce .woocommerce-MyAccount-content {
	float: none;
	width: auto;
	min-width: 0;
	margin: 0;
}

body.woocommerce-account .woocommerce-MyAccount-navigation ul {
	margin: 0;
	padding: 0;
	list-style: none;
	border-top: 1px solid var(--lv-rule);
}

body.woocommerce-account .woocommerce-MyAccount-navigation li {
	margin: 0;
	border-bottom: 1px solid var(--lv-rule);
}

body.woocommerce-account .woocommerce-MyAccount-navigation li a {
	display: block;
	padding: 0.9375rem 0.125rem;
	color: var(--lv-muted);
	font-size: var(--lv-micro-size);
	font-weight: var(--lv-micro-weight);
	letter-spacing: var(--lv-micro-ls);
	text-transform: uppercase;
	text-decoration: none;
	transition: color var(--lv-dur-fast) var(--lv-ease);
}

body.woocommerce-account .woocommerce-MyAccount-navigation li a:hover,
body.woocommerce-account .woocommerce-MyAccount-navigation li a:focus-visible {
	color: var(--lv-ink);
}

body.woocommerce-account .woocommerce-MyAccount-navigation li.is-active a {
	color: var(--lv-accent);
}

body.woocommerce-account .woocommerce-MyAccount-content {
	max-width: var(--lv-prose-w);
	font-size: 1rem;
	line-height: 1.65;
}

body.woocommerce-account .woocommerce-MyAccount-content p {
	margin-block: 0 1rem;
}

body.woocommerce-account .woocommerce-MyAccount-content a {
	color: var(--lv-ink);
	text-decoration-color: var(--lv-rose-300);
	text-underline-offset: 0.2em;
}

body.woocommerce-account .woocommerce-MyAccount-content a:hover {
	color: var(--lv-accent);
}

/* Login / register form, when logged out. */
body.woocommerce-account .woocommerce-form-login,
body.woocommerce-account .woocommerce-form-register {
	padding: clamp(1.5rem, 3vw, 2.25rem);
	border: 1px solid var(--lv-rule);
	border-radius: var(--lv-radius);
	background: var(--lv-cream);
}

body.woocommerce-account .woocommerce-form-login label,
body.woocommerce-account .woocommerce-form-register label {
	display: block;
	margin-bottom: 0.375rem;
	font-size: var(--lv-micro-size);
	font-weight: var(--lv-micro-weight);
	letter-spacing: var(--lv-micro-ls);
	text-transform: uppercase;
	color: var(--lv-muted);
}

/* Order tables inside the account area scroll rather than push the page. */
body.woocommerce-account .woocommerce-MyAccount-content table.shop_table {
	display: block;
	width: 100%;
	overflow-x: auto;
	border-collapse: collapse;
}

/* ==========================================================================
   15 · Narrow viewports
   ========================================================================== */

/*
 * Nothing above uses a fixed width that could exceed a 360px viewport: every
 * measure is a clamp, a percentage or a `min()`-guarded grid track. These are
 * the remaining places where WooCommerce's own markup can push sideways.
 */
@media (max-width: 600px) {
	/*
	 * The cart row. This one fixes a WooCommerce bug rather than one of ours:
	 * measured with ALL of this theme's CSS removed, at a 360px viewport the
	 * stock `.wc-block-cart-items__row` is 380px wide and its cells reach
	 * x=384 — WooCommerce's own `is-mobile` cart row does not fit a 360px
	 * phone out of the box. Adding a page gutter only made it visible at 390
	 * as well.
	 *
	 * Three things are needed, and all three are load-bearing:
	 *
	 * 1. `display: block` on the table AND on its `thead`/`tbody`. Setting it
	 *    on the table alone is not enough — the row groups re-establish table
	 *    layout, and the table stayed at its 380px min-content width. The rows
	 *    themselves are already `display: grid` in WooCommerce's mobile mode,
	 *    so they lay out correctly once the table box stops being a table.
	 *
	 * 2. `min-width: 0` on the product and total cells, so their auto-sized
	 *    grid tracks are allowed to shrink below min-content.
	 *
	 * 3. `white-space: normal` on the savings badge ("Saglabāt 46,11 €"),
	 *    which is the single widest inflexible item in the row and was
	 *    holding the total column open on its own. Word wrapping is enough —
	 *    `overflow-wrap: anywhere` also works but collapses the column to
	 *    ~40px and breaks the price mid-number.
	 */
	body.woocommerce-cart .wc-block-cart-items,
	body.woocommerce-cart .wc-block-cart-items > thead,
	body.woocommerce-cart .wc-block-cart-items > tbody {
		display: block;
		width: 100%;
	}

	body.woocommerce-cart .wc-block-cart-items__row {
		max-width: 100%;
	}

	body.woocommerce-cart .wc-block-cart-item__product,
	body.woocommerce-cart .wc-block-cart-item__total {
		min-width: 0;
	}

	body.woocommerce-cart .wc-block-cart-item__total .wc-block-components-product-badge {
		white-space: normal;
	}

	/* Long product names with no spaces (SKUs, "SPF 50+ …(20ml)"). */
	body.woocommerce li.wc-block-product .wp-block-post-title,
	body.woocommerce-page li.wc-block-product .wp-block-post-title,
	body.single-product main h1.wp-block-post-title {
		overflow-wrap: anywhere;
	}
}

/* ==========================================================================
   16 · Reduced motion
   ========================================================================== */

/*
 * assets/lauriva.css already zeroes `--lv-dur`, `--lv-dur-fast` and
 * `--lv-dur-slow` under this query, and every transition above reads those
 * tokens, so durations are handled. What is left is the one state change that
 * is a transform rather than a duration: the product card's image zoom.
 */
@media (prefers-reduced-motion: reduce) {
	body.woocommerce li.wc-block-product:hover .wc-block-components-product-image img,
	body.woocommerce li.wc-block-product:focus-within .wc-block-components-product-image img,
	body.woocommerce-page li.wc-block-product:hover .wc-block-components-product-image img,
	body.woocommerce-page li.wc-block-product:focus-within .wc-block-components-product-image img {
		transform: none;
	}

	body.woocommerce main :is(a, button, input, select, .wc-block-components-product-image img),
	body.woocommerce-page main :is(a, button, input, select, .wc-block-components-product-image img) {
		transition-duration: 0.01ms;
	}
}
