/*
 * Single product page.
 *
 * Owned by the product-detail workstream.
 *
 * Every value is a token from theme.json — no hardcoded colours, no viewport breakpoints.
 *
 * ON CONTAINER QUERIES AND THE GALLERY
 * ------------------------------------
 * `container-type: inline-size` implies `contain: layout`, which makes the element the
 * containing block for absolutely AND fixed positioned descendants. The gallery is rendered
 * by the WooSwipe plugin and ships a PhotoSwipe overlay inside it, which the library
 * switches to `position: fixed` when the lightbox opens (verified: the single `fixed` in
 * photoswipe.min.js is `position="fixed"`). So a container on `.nv-product`,
 * `.nv-product__hero` or `.nv-product__media` would trap the full-screen lightbox inside the
 * gallery column. The hero therefore responds by INTRINSIC WRAPPING — flex-basis plus
 * `flex-wrap`, which reflows on the space the row actually has and needs no containment and
 * no viewport breakpoint. Container queries are used everywhere they are safe: the summary
 * column and the details region, neither of which contains an overlay.
 */

/* ---------------------------------------------------------------- page frame */

/*
 * Breadcrumbs, store notices, the details region and the related-products collection all
 * carry `alignwide`, so core widens them to `wideSize` (1600px) while the hero sits at
 * `contentSize` (1280px) — three edges at two different widths. One column, one edge.
 */
.nv-product.wp-block-group > .alignwide {
	max-inline-size: var(--wp--style--global--content-size);
	margin-inline: auto;
}

.nv-product .woocommerce-breadcrumb {
	color: var(--wp--preset--color--text-muted);
	margin-block: 0 var(--wp--preset--spacing--sm);
}

/* The 44px floor for breadcrumb links lives in shell.css — see the note there. */
.nv-product .woocommerce-breadcrumb a {
	color: inherit;
	text-decoration: none;
}

.nv-product .woocommerce-breadcrumb a:hover,
.nv-product .woocommerce-breadcrumb a:focus-visible {
	color: var(--wp--preset--color--brand);
	text-decoration: underline;
}

/* --------------------------------------------------------------------- hero */

.nv-product__hero {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--md) var(--wp--preset--spacing--xl);
	align-items: flex-start;
}

/*
 * The image is the hero: it takes the larger basis and is allowed to grow, but is capped so
 * the 600px-wide source is never scaled far past its own resolution. Below roughly 46rem of
 * available row the two bases can no longer both be satisfied and the row wraps to a single
 * column — image first, which is the right order on a phone.
 */
.nv-product__media {
	flex: 1 1 24rem;
	min-inline-size: 0;
	max-inline-size: 40rem;
}

/*
 * A flex column purely so `order` can place the YITH Compare button. YITH injects it
 * immediately after the add-to-cart-form block, which on an OUT-OF-STOCK product drops it
 * between the availability pill and the pre-order button — a secondary control sitting
 * between the fact and the action. `order` moves it below the primary action instead. The
 * cost is that on out-of-stock pages Compare precedes the pre-order button in the tab order
 * while following it visually: one swap between two adjacent controls, taken deliberately so
 * the page has one unmistakable primary action. Nothing moves on in-stock pages.
 */
.nv-product__summary {
	container: nv-summary / inline-size;
	display: flex;
	flex-direction: column;
	align-items: stretch;
	flex: 1 1 21rem;
	min-inline-size: 0;
}

.nv-product__summary .yith-wccp-compare {
	order: 1;
}

.nv-product__summary .nv-share {
	order: 2;
}

.nv-product__summary .wp-block-woocommerce-product-meta {
	order: 3;
}

/* ------------------------------------------------------------------ gallery */

/* The plugin pads the gallery for a caption row this design does not use. */
.nv-product__media #wooswipe {
	margin-block-end: 0;
	padding-block-end: 0;
}

/*
 * A calm, square stage. Measured across the catalogue, every product's main image is square
 * (600x600, two at 500x500), so a square stage wastes no width on letterboxing and shows the
 * photograph as large as the column allows. The image is CONTAINED, never cropped, so all 54
 * products present at the same size — which is most of what makes a gallery feel considered
 * rather than assembled.
 *
 * `#wooswipe` is repeated in these selectors on purpose: the plugin's own rules are ID-based
 * (`#wooswipe .single-product-main-image img { height: auto }`), so a class-only selector
 * loses and the image overflowed the stage and was cropped by it. Verified in the browser.
 */
.nv-product__media #wooswipe .single-product-main-image {
	display: grid;
	place-items: center;
	/* The plugin only sets border-box on #wooswipe itself, so padding + border on the stage
	   pushed it 42px past the column. Measured before fixing. */
	box-sizing: border-box;
	aspect-ratio: 1;
	padding: var(--wp--preset--spacing--sm);
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--lg);
	overflow: hidden;
}

.nv-product__media #wooswipe .single-product-main-image .woocommerce-main-image {
	display: grid;
	place-items: center;
	inline-size: 100%;
	block-size: 100%;
	border-radius: var(--wp--custom--radius--md);
}

.nv-product__media #wooswipe .single-product-main-image img {
	inline-size: 100%;
	block-size: 100%;
	object-fit: contain;
}

.nv-product__media #wooswipe .single-product-main-image a:focus-visible {
	outline: var(--wp--custom--focus--width) solid var(--wp--preset--color--accent);
	outline-offset: var(--wp--custom--focus--offset);
}

/*
 * Thumbnails. The plugin locks the strip to a 100px-tall band of `object-fit: cover` crops;
 * this releases it so the thumbnails match the stage — contained, square, on the same quiet
 * ground. Slick owns the horizontal track and its inline widths, so only the cells are
 * restyled and the track is left alone.
 */
.nv-product__media #wooswipe .thumbnails {
	block-size: auto;
	overflow: visible;
	margin-block: var(--wp--preset--spacing--xs) 0;
}

.nv-product__media #wooswipe .thumbnail-nav .slick-slide {
	padding-inline: 0 var(--wp--preset--spacing--xxs);
}

.nv-product__media #wooswipe .thumbnails .thumb {
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	overflow: hidden;
	cursor: pointer;
	transition: border-color var(--wp--custom--transition--base);
}

.nv-product__media #wooswipe .thumbnails .thumb:hover {
	border-color: var(--wp--preset--color--brand);
}

.nv-product__media #wooswipe .thumbnail-nav .slick-slide img,
.nv-product__media #wooswipe .thumbnails .thumb img {
	inline-size: 100%;
	block-size: auto;
	aspect-ratio: 1;
	max-block-size: none;
	object-fit: contain;
}

/* Slick's arrows are bare SVGs with no hit area; give them the 44px minimum. */
.nv-product__media #wooswipe .thumbnail-nav button.slick-arrow {
	display: grid;
	place-items: center;
	inline-size: 44px;
	block-size: 44px;
	background: var(--wp--preset--color--base);
	border-radius: var(--wp--custom--radius--full);
}

.nv-product__media #wooswipe .thumbnail-nav button.slick-arrow:focus-visible {
	outline: var(--wp--custom--focus--width) solid var(--wp--preset--color--accent);
	outline-offset: var(--wp--custom--focus--offset);
}

/* ------------------------------------------------------------------ summary */

/*
 * Hierarchy: title, then price, then availability, then one primary action. Everything
 * else — rating, meta, share, compare — is deliberately quieter than all four.
 */
.nv-product__summary > .wp-block-post-title {
	margin-block: 0;
	text-wrap: balance;
}

.nv-product__summary .wp-block-woocommerce-product-rating {
	margin-block-start: var(--wp--preset--spacing--xxs);
	font-size: var(--wp--preset--font-size--sm);
}

.nv-product__summary .wc-block-components-product-rating__container {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--xxs);
	align-items: center;
}

.nv-product__summary .wc-block-components-product-rating__reviews_count a {
	color: var(--wp--preset--color--text-muted);
}

/*
 * The price is ink, not brand. Brand blue is reserved for the thing you click; a large
 * confident black number reads as the fact it is, and leaves exactly one blue control on
 * the screen.
 */
.nv-product__summary .wp-block-woocommerce-product-price {
	margin-block-start: var(--wp--preset--spacing--xs);
}

.nv-product__summary .price,
.nv-product__summary .wc-block-components-product-price {
	color: var(--wp--preset--color--contrast);
	font-size: var(--wp--preset--font-size--xxl);
	font-weight: 700;
	line-height: 1.1;
}

.nv-product__summary del,
.nv-product__summary del .amount {
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--lg);
	font-weight: 400;
}

.nv-product__summary ins {
	text-decoration: none;
}

.nv-product__summary .wp-block-post-excerpt {
	margin-block-start: var(--wp--preset--spacing--xs);
}

.nv-product__summary .wp-block-post-excerpt__excerpt {
	max-inline-size: 62ch;
	margin-block: 0;
	color: var(--wp--preset--color--ink-soft);
}

/* --------------------------------------------------------- availability + CTA */

.nv-product__summary .wp-block-add-to-cart-form,
.nv-product__summary .nv-preorder {
	margin-block-start: var(--wp--preset--spacing--sm);
}

/*
 * Out of stock is a status, so it is stated as one — a pill, not a stray red-ish sentence.
 * The pre-order button immediately below is the action that replaces "add to cart", and the
 * two must not read as one blob.
 */
.nv-product__summary .stock.out-of-stock {
	display: inline-block;
	margin-block: 0;
	padding: var(--wp--preset--spacing--xxxs) var(--wp--preset--spacing--xs);
	color: var(--wp--preset--color--ink-soft);
	background: var(--wp--preset--color--surface-muted);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--full);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 700;
}

/*
 * In stock — the question a buyer asks between the price and the button, which until now
 * nothing on this page answered.
 *
 * The cause was not a missing element: WooCommerce SUPPRESSES the availability text for any
 * product that does not manage stock (WC_Product::get_availability() returns an empty
 * `availability` string, and ProductStockIndicator.php:104 returns '' on that). Every one of
 * the 54 published products has `_manage_stock = no` — measured — so the in-stock case was
 * empty for all of them while out-of-stock still rendered. The text is restored by a filter
 * in inc/woocommerce.php (cross-file request A in the task report); this styles it.
 *
 * The WORD carries the state; the dot is decorative and the ink stays at full contrast, so
 * availability is never signalled by colour alone — and the green accent never has to pass a
 * text-contrast bar it would fail at this size.
 */
.nv-product__summary .stock.in-stock {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--xxs);
	margin-block: 0;
	color: var(--wp--preset--color--contrast);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 700;
}

.nv-product__summary .stock.in-stock::before {
	content: "";
	flex: none;
	inline-size: 0.55em;
	block-size: 0.55em;
	background: var(--wp--preset--color--accent);
	border-radius: var(--wp--custom--radius--full);
}

/* The form follows the availability line, not the price, so the two read as one answer. */
.nv-product__summary .stock.in-stock + form.cart {
	margin-block-start: var(--wp--preset--spacing--xs);
}

.nv-product__summary form.cart {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--xs);
	align-items: stretch;
	margin-block: 0;
}

.nv-product__summary form.cart .quantity {
	display: flex;
}

.nv-product__summary form.cart input.qty {
	inline-size: 5rem;
	min-block-size: 52px;
	padding-inline: var(--wp--preset--spacing--xxs);
	color: inherit;
	text-align: center;
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	font: inherit;
	font-size: var(--wp--preset--font-size--md);
}

.nv-product__summary form.cart input.qty:focus-visible,
.nv-product__summary .single_add_to_cart_button:focus-visible,
.nv-product__summary .yith-wccp-compare a:focus-visible,
.nv-product__summary .wp-block-woocommerce-product-meta a:focus-visible {
	outline: var(--wp--custom--focus--width) solid var(--wp--preset--color--accent);
	outline-offset: var(--wp--custom--focus--offset);
}




/*
 * YITH Compare renders a full `.button.wp-element-button`, so out of the box the page has
 * two equally loud buttons and no primary action. Demoted to a quiet secondary control.
 */
.nv-product__summary .yith-wccp-compare {
	margin-block-start: var(--wp--preset--spacing--xs);
	/* The plugin centres its button; here it belongs on the same edge as the CTA above it. */
	text-align: start;
}



/* ------------------------------------------------------------ share and meta */

.nv-product__summary .nv-share {
	margin-block-start: var(--wp--preset--spacing--sm);
	padding-block-start: var(--wp--preset--spacing--xs);
	border-block-start: 1px solid var(--wp--preset--color--border);
}

.nv-product__summary .wp-block-woocommerce-product-meta {
	margin-block-start: var(--wp--preset--spacing--xs);
	color: var(--wp--preset--color--text-muted);
}

.nv-product__summary .wp-block-woocommerce-product-meta a {
	color: inherit;
}

.nv-product__summary .wp-block-woocommerce-product-meta a:hover {
	color: var(--wp--preset--color--brand);
}

/* ------------------------------------------------------- details as sections */

/*
 * TABS, under the hero — one strip, one panel at a time.
 *
 * This region is ~1,900 words on a product like MEGA1200. Unrolled into one column it buried
 * the specification table (what this buyer compares on) and the warranty (what they ask about
 * second) under two screens of description, and the page's own headings were the only
 * navigation. The strip is the navigation.
 *
 * NO THEME SCRIPT RUNS THIS. WooCommerce's `single-product.js` is already on the page and
 * already does clicks, `aria-selected`, roving `tabindex`, arrow keys, Home/End and `#tab-…`
 * deep links; the previous design suppressed it with `display: block !important` (it writes
 * `display: none` inline). Removing that hand it back — this file only dresses the strip.
 *
 * WITHOUT JAVASCRIPT nothing is hidden: the strip is server-rendered markup whose links are
 * real in-page anchors (`href="#tab-description"`), and every panel stays visible because
 * only the script hides them. So the no-JS page is the old stacked column with a table of
 * contents on top — degradation, not breakage.
 */
.nv-product__details {
	container: nv-details / inline-size;
	margin-block-start: var(--wp--preset--spacing--xl);
}

.nv-product__details .woocommerce-tabs > ul.tabs {
	display: flex;
	flex-wrap: wrap;
	gap: 0 var(--wp--preset--spacing--xs);
	margin: 0 0 var(--wp--preset--spacing--lg);
	padding: 0;
	list-style: none;
	border-block-end: 1px solid var(--wp--preset--color--border);
}

.nv-product__details .woocommerce-tabs > ul.tabs > li {
	margin: 0;
}

/*
 * The 44px floor applies here like everywhere else, and the 2px underline is drawn on the
 * item itself with a −1px offset so it sits ON the strip's rule rather than under it.
 */
.nv-product__details .woocommerce-tabs > ul.tabs > li > a {
	display: flex;
	align-items: center;
	min-block-size: 44px;
	padding-inline: var(--wp--preset--spacing--xxs);
	border-block-end: 2px solid transparent;
	margin-block-end: -1px;
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 700;
	text-decoration: none;
	text-transform: uppercase;
	letter-spacing: 0.02em;
}

.nv-product__details .woocommerce-tabs > ul.tabs > li > a:hover {
	color: var(--wp--preset--color--brand);
}

/* `.active` is what the script sets; `[aria-selected]` is what it means. Both are written so
   the visible state and the announced one cannot drift apart. */
.nv-product__details .woocommerce-tabs > ul.tabs > li.active > a,
.nv-product__details .woocommerce-tabs > ul.tabs > li > a[aria-selected="true"] {
	color: var(--wp--preset--color--contrast);
	border-block-end-color: var(--wp--preset--color--brand);
}

.nv-product__details .woocommerce-tabs .wc-tab {
	max-inline-size: none;
	scroll-margin-block-start: var(--wp--preset--spacing--sm);
}

/*
 * The panel's opening heading repeats the tab that is already highlighted above it, so it is
 * hidden — but ONLY once the script has actually taken over, which is what `.nv-tabs--js`
 * (added by the one line in inc/woocommerce.php) records. With no script the panels are
 * stacked and those headings are the only thing separating them.
 */
.nv-product__details .nv-tabs--js .wc-tab > h2:first-child {
	position: absolute;
	inline-size: 1px;
	block-size: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* No script: the panels are sections again, and need the rule between them they had before. */
.nv-product__details .woocommerce-tabs:not(.nv-tabs--js) .wc-tab + .wc-tab {
	margin-block-start: var(--wp--preset--spacing--lg);
	padding-block-start: var(--wp--preset--spacing--lg);
	border-block-start: 1px solid var(--wp--preset--color--border);
}

/*
 * Two heading levels, not one. The Доставка panel's own content is written as further h2s
 * ("Оформление заказа", "Доставка", "Гарантия") and the reviews heading is a nested h2, so
 * on theme.json's scale every heading in this region rendered at 31–43px and the region read
 * as six equal sections. The panel's OPENING heading is the section title; every heading
 * after it is a sub-heading. Levels are untouched — this is size, not semantics.
 */
.nv-product__details .wc-tab h2 {
	margin-block: var(--wp--preset--spacing--md) var(--wp--preset--spacing--xxs);
	font-size: var(--wp--preset--font-size--xl);
}

.nv-product__details .wc-tab > h2:first-child {
	margin-block: 0 var(--wp--preset--spacing--sm);
	font-size: var(--wp--preset--font-size--xxl);
}

.nv-product__details .wc-tab :is(h3, h4) {
	margin-block: var(--wp--preset--spacing--sm) var(--wp--preset--spacing--xxs);
	font-size: var(--wp--preset--font-size--lg);
}

/* Prose gets a readable measure; the specification table and the icon grid inside the
   description are deliberately exempt, which is why only direct children are capped. */
.nv-product__details .wc-tab > :is(p, ul, ol) {
	max-inline-size: 72ch;
}

.nv-product__details .wc-tab > ul,
.nv-product__details .wc-tab > ol {
	padding-inline-start: var(--wp--preset--spacing--sm);
}

.nv-product__details .wc-tab li {
	margin-block-end: var(--wp--preset--spacing--xxxs);
}

.nv-product__details .wc-tab figure {
	margin-inline: 0;
}

.nv-product__details .wc-tab .wp-caption-text {
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--xs);
	line-height: 1.3;
}

/* ---------------------------------------------------- specifications ("Детали") */

/*
 * The specifications, presented as a two-column definition list rather than a table dump:
 * quiet label, confident value, one hairline per row and a generous row rhythm. It stays a
 * real <table> with <th scope="row"> — overriding `display` on table elements strips the
 * table roles out of the accessibility tree in Chrome and Safari, and these nine rows are
 * exactly the content a screen-reader user needs row/column semantics for.
 *
 * The long selectors are deliberate. WooCommerce styles this table from `body.woocommerce`
 * (`.woocommerce table.shop_attributes tr:nth-child(even) th` = four classes), which sets
 * bold labels, ITALIC values, dotted borders and zebra striping. A three-class selector
 * silently loses to it — measured in the browser: font-weight resolved to 700 and
 * font-style to italic while this file said otherwise.
 */
.nv-product__details .woocommerce-tabs .wc-tab table.woocommerce-product-attributes {
	inline-size: 100%;
	max-inline-size: 58rem;
	border-collapse: collapse;
	margin-block: var(--wp--preset--spacing--xs) 0;
}

.nv-product__details .woocommerce-tabs .wc-tab table.woocommerce-product-attributes tr {
	border-block-end: 1px solid var(--wp--preset--color--border);
}

.nv-product__details .woocommerce-tabs .wc-tab table.woocommerce-product-attributes tr:first-child {
	border-block-start: 1px solid var(--wp--preset--color--border);
}

.nv-product__details .woocommerce-tabs .wc-tab table.woocommerce-product-attributes th,
.nv-product__details .woocommerce-tabs .wc-tab table.woocommerce-product-attributes td {
	padding-block: var(--wp--preset--spacing--xs);
	text-align: start;
	vertical-align: baseline;
	background: none;
	border: 0;
	font-style: normal;
	line-height: 1.4;
}

.nv-product__details .woocommerce-tabs .wc-tab table.woocommerce-product-attributes th {
	inline-size: 38%;
	padding-inline: 0 var(--wp--preset--spacing--sm);
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--base);
	font-weight: 400;
}

/*
 * Values are set in TABULAR figures. Eleven of the twenty-four attributes in use are
 * numeric-with-a-unit (размер 300 · вес 0,85 · комбинация расстояний 5 · нагрузка · длина ·
 * ширина · высота · гарантия · утилизация · сила · срок), and this is a catalogue whose
 * buyers choose BY SIZE — they read the same row on three product pages in three tabs and
 * compare the numbers. Proportional digits make that comparison a re-read; tabular digits
 * put the same column of numerals in the same place on every page.
 */
.nv-product__details .woocommerce-tabs .wc-tab table.woocommerce-product-attributes td {
	padding-inline: 0;
	color: var(--wp--preset--color--contrast);
	font-size: var(--wp--preset--font-size--md);
	font-variant-numeric: tabular-nums;
}

.nv-product__details .woocommerce-tabs .wc-tab table.woocommerce-product-attributes td p {
	margin: 0;
	padding: 0;
}

/*
 * A phone has no room for a 38% label column beside a value; the split moves to 50/50 and
 * the rhythm tightens one step so nine rows stay one readable block rather than a screenful
 * of gaps. Queried against the details region, which contains no positioned overlay.
 */
@container nv-details (max-width: 32rem) {
	.nv-product__details .woocommerce-tabs .wc-tab table.woocommerce-product-attributes th,
	.nv-product__details .woocommerce-tabs .wc-tab table.woocommerce-product-attributes td {
		padding-block: var(--wp--preset--spacing--xxs);
		font-size: var(--wp--preset--font-size--sm);
	}

	.nv-product__details .woocommerce-tabs .wc-tab table.woocommerce-product-attributes th {
		inline-size: 50%;
		padding-inline-end: var(--wp--preset--spacing--xs);
	}
}

/*
 * The `.nv-product__todo` placeholder skin is GONE, with the box it dressed: the mounting
 * slot it marked is now the «Установка» tab, written from the product's own attributes.
 * Grepped before deleting — `nv-product__todo` appeared in exactly two files, this one and
 * templates/single-product.html, and no other template used the class.
 */

/* --------------------------------------------------------------------- reviews */

.nv-product__details .commentlist {
	margin: 0;
	padding: 0;
	list-style: none;
}

.nv-product__details .commentlist .comment_container {
	display: flex;
	gap: var(--wp--preset--spacing--xs);
	align-items: flex-start;
	padding-block: var(--wp--preset--spacing--xs);
	border-block-end: 1px solid var(--wp--preset--color--border);
}

.nv-product__details .commentlist img.avatar {
	flex: 0 0 auto;
	border-radius: var(--wp--custom--radius--full);
}

.nv-product__details .commentlist .meta {
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--sm);
}

/* ------------------------------------------------------------ related products */

.nv-product .wp-block-woocommerce-product-collection {
	margin-block-start: var(--wp--preset--spacing--xl);
	padding-block-start: var(--wp--preset--spacing--lg);
	border-block-start: 1px solid var(--wp--preset--color--border);
}

.nv-product .wp-block-woocommerce-product-collection > .wp-block-heading {
	margin-block: 0 var(--wp--preset--spacing--sm);
	font-size: var(--wp--preset--font-size--xxl);
}

/*
 * The collection ships a five-across flex row whose column count is written into the markup.
 * Replaced with a grid that derives its column count from the space available, so the row
 * reflows to four, three, two and one on its own. Tile styling itself is the catalogue
 * stream's, in catalog.css.
 */
.nv-product .wc-block-product-template {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(14rem, 100%), 1fr));
	gap: var(--wp--preset--spacing--sm);
	margin: 0;
	padding: 0;
	list-style: none;
}

/*
 * `.is-flex-container` IS REPEATED ON PURPOSE — this rule has to out-specify WooCommerce.
 *
 * The block prints an inline stylesheet containing
 *   `.wc-block-product-template.is-flex-container.is-flex-container.columns-5 > li
 *    { width: calc(20% - 1em) }`
 * with the class doubled to buy specificity (0,4,1). That width assumes the <ul> is the flex
 * row the block ships; the rule above makes it a GRID, and a percentage on a grid item
 * resolves against its TRACK, not against the row. So 20% stopped meaning "one of five
 * across" and started meaning "a fifth of one column".
 *
 * Measured on /product/sfericheskoe-zerkalo-k300/ at 768px: tracks were 229px wide and every
 * one of the five related tiles was 31px wide — the product photograph rendered 31x31. The
 * previous `inline-size: auto` here was the right intent at (0,3,1) and simply lost the
 * cascade. Doubling the class the same way the block does takes this to (0,5,1) and wins
 * outright rather than by source order.
 */
.nv-product .wc-block-product-template.is-flex-container.is-flex-container > li.product,
.nv-product .wc-block-product-template li.product {
	inline-size: auto;
	max-inline-size: none;
	margin: 0;
}

/* Related tiles are a browse aid, not the subject: their prices stay quiet so the one on
   this page is the only large number on the screen. */
.nv-product .wc-block-product-template .wc-block-components-product-price {
	color: var(--wp--preset--color--contrast);
	font-size: var(--wp--preset--font-size--md);
	font-weight: 700;
}

.nv-product .wc-block-product-template .wp-block-post-title a {
	color: inherit;
	text-decoration: none;
}

.nv-product .wc-block-product-template .wp-block-post-title a:hover {
	color: var(--wp--preset--color--brand);
}


@media (prefers-reduced-motion: reduce) {
	.nv-product__media #wooswipe .thumbnails .thumb,
	.nv-product__summary .single_add_to_cart_button,
	.nv-product__summary .yith-wccp-compare a.button {
		transition: none;
	}
}

/* Button rules removed: components.css maps these selectors onto the three types. Layout-only rules (order, placement) deliberately kept. */
