/**
 * Single product page
 */

/*
 * Flexbox, not CSS Grid: confirmed live on shop.cncgc.ru that
 * grid-template-columns: 1.15fr 0.85fr computes an absurd (millions of px)
 * track width for this column — a real browser bug/edge case triggered by
 * the third-party woo-product-gallery-slider plugin's gallery markup inside
 * the grid item, independent of any single corrupted image file. That
 * plugin's output is now overridden by the launch plugin cncgc-launch
 * (includes/class-cncgc-launch-workarounds.php; doc/launch-checklist.md,
 * section 1). The native gallery below has not been confirmed to hit this
 * bug, but flexbox with equivalent flex-grow ratios lays out identically
 * either way — do not switch this back to `display: grid` with `fr`
 * columns without re-testing the gallery on a real product page first.
 */
.cncgc-product__top {
	display: flex;
	flex-direction: column;
	gap: 28px;
	padding: 8px 0 40px;
}

/* stylelint-disable-next-line media-feature-range-notation -- `min-width` kept deliberately: the modern `width >=` range syntax isn't supported before Safari 16.4 (March 2023), and this project's own cross-browser rule (CLAUDE.md) treats any layout-affecting CSS change as unconfirmed without real Safari testing. */
@media (min-width: 992px) {
	.cncgc-product__top {
		flex-direction: row;
		gap: 48px;
		align-items: flex-start;
	}

	.cncgc-product__gallery {
		flex: 1.15 1.15 0;
		min-width: 0;
	}

	.cncgc-product__summary {
		flex: 0.85 0.85 0;
		min-width: 0;
	}
}

.cncgc-product__gallery .woocommerce-product-gallery {
	width: 100% !important;
	float: none !important;
	opacity: 1 !important;

	/*
	 * Positioning context for .cncgc-gallery-expand below: that span is a
	 * plain sibling of the gallery's own children (not nested inside
	 * .flex-viewport), so without `position: relative` here its
	 * `position: absolute; top/right` resolved against the page's own
	 * initial containing block instead — confirmed live, it landed pinned to
	 * the browser viewport's top-right corner rather than the image's.
	 */
	position: relative;
}

.cncgc-product__gallery .flex-viewport {
	background: var(--cncgc-bg-soft);
}

/*
 * WooCommerce's own zoom plugin (assets/js/zoom/jquery.zoom.min.js,
 * `wc-product-gallery-zoom` theme support) appends `img.zoomImg` as a
 * SIBLING of the slide's `<a>` (both children of
 * `.woocommerce-product-gallery__image`), absolutely positioned to cover
 * the entire image at all times — not just while actively zooming. It's
 * only visually hidden via `opacity: 0` when inactive, which does not
 * remove it from hit-testing. Confirmed live via `elementFromPoint()` at
 * the image's own center: with no fix, `.zoomImg` — not the `<a>` — was the
 * topmost element there, at every point in time, so a real mouse click
 * (unlike a JS-dispatched `.click()`, which bypasses hit-testing entirely)
 * never reached the link meant to open the PhotoSwipe lightbox. Since
 * `.zoomImg` is a pure rendering target — WC's own hover/mousemove tracking
 * for the zoom lens is bound to the `<a>`/wrapper, not to `.zoomImg` itself,
 * confirmed live: the lens still follows the cursor correctly with this
 * rule in place — making it click-transparent fixes the lightbox without
 * touching the zoom effect at all.
 */
.cncgc-product__gallery .zoomImg {
	pointer-events: none;
}

.cncgc-product__gallery .woocommerce-product-gallery__image img {
	margin: 0 auto;
}

/*
 * Native WooCommerce product gallery (FlexSlider + zoom + PhotoSwipe, all
 * enabled via the wc-product-gallery-* theme supports in inc/setup.php).
 * The third-party "Woo Product Gallery Slider" plugin that used to override
 * this markup is neutralised in inc/woocommerce.php — these rules target
 * FlexSlider's own generated class names instead of a third-party plugin's
 * markup.
 *
 * CORRECTION to a claim this comment used to make ("WooCommerce's own
 * woocommerce.css already supplies FlexSlider's baseline") — confirmed live
 * at 320px that it doesn't: WC's bundled flexslider CSS scopes its
 * thumbnail-grid and arrow styling under a `.flexslider` ancestor class,
 * and — as the BUG FIX note below already explains for the thumbnail-rail
 * selector — this WooCommerce version's FlexSlider init never adds that
 * class here, at any width. So below 992px, before this fix, thumbnails had
 * no width rule at all (each `<li>` rendered block-level at the full
 * container width — 14 thumbnails stacked into ~1400px of dead vertical
 * space) and the prev/next arrows had no positioning at all
 * (`position: static`, bare "Previous"/"Next" text sitting inline right
 * after the image). The rules below are this theme's own full replacement
 * for both, not a >=992px-only repositioning of an otherwise-working
 * default: a horizontally scrollable thumbnail strip + circular arrow
 * buttons at every width, with >=992px switching the strip to the design
 * concept's left-hand rail.
 *
 * The arrow rules are unscoped from any media query (not just >=992px
 * responsibility) because they no longer depend on the two-column layout at
 * all: product-gallery.js's relocateDirectionNav() moves FlexSlider's
 * `.flex-direction-nav` (appended as a sibling of `.flex-viewport` by
 * default) to be an actual DOM child of `.flex-viewport` instead, which is
 * `position: relative` at every width via WooCommerce's own FlexSlider CSS.
 *
 * BUG FIX (thumbnail-rail selector): this used to key the flex container
 * off `.woocommerce-product-gallery.flexslider`, assuming FlexSlider's init
 * adds a `flexslider` class to that element the way older FlexSlider/WC
 * versions did. Checked live: it doesn't, in this WooCommerce version —
 * `.flex-viewport` and `.flex-control-nav` land as plain siblings inside
 * `.cncgc-product-gallery` with no such class ever appearing anywhere, so
 * that selector never matched. Keying off our own `.cncgc-product-gallery`
 * class instead — guaranteed present, since we add it ourselves in
 * product-image.php — fixes this regardless of whether a given
 * FlexSlider/WooCommerce version happens to add its own marker class.
 */
.cncgc-product__gallery .flex-control-nav.flex-control-thumbs {
	display: flex;
	flex-wrap: nowrap;
	overflow-x: auto;
	gap: 8px;
	margin: 12px 0 0;
	padding: 0 0 4px;
	list-style: none;
}

.cncgc-product__gallery .flex-control-thumbs li {
	flex: 0 0 72px;
	width: 72px;
}

.cncgc-product__gallery .flex-control-thumbs img {
	display: block;
	width: 100%;
	height: 72px;
	object-fit: cover;
	border: 1px solid var(--cncgc-border);
	border-radius: var(--cncgc-radius);
	cursor: pointer;
	opacity: 0.6;
}

.cncgc-product__gallery .flex-control-thumbs img.flex-active {
	opacity: 1;
	border-color: var(--cncgc-black);
	border-width: 2px;
}

/* Touch target 44x44 (this project's own adaptive-design minimum), not the 40x40 an earlier version of this rule used. */
.cncgc-product__gallery .flex-direction-nav a {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	width: 44px;
	height: 44px;
	margin: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--cncgc-bg);
	border-radius: 50%;
	box-shadow: var(--cncgc-shadow);

	/* Hide «Previous/Next»: text-indent alone fails inside a flex box in iOS 18 Safari. */
	font-size: 0;
	color: transparent;
	text-indent: -9999px;
	overflow: hidden;
	opacity: 1;
	z-index: 5;
}

.cncgc-product__gallery .flex-direction-nav a::before {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	width: 8px;
	height: 8px;
	border-right: 2px solid var(--cncgc-black);
	border-bottom: 2px solid var(--cncgc-black);
}

.cncgc-product__gallery .flex-direction-nav .flex-prev {
	left: 12px;
}

.cncgc-product__gallery .flex-direction-nav .flex-prev::before {
	margin: -6px 0 0 -3px;
	transform: rotate(135deg);
}

.cncgc-product__gallery .flex-direction-nav .flex-next {
	right: 12px;
}

.cncgc-product__gallery .flex-direction-nav .flex-next::before {
	margin: -6px 0 0 -6px;
	transform: rotate(-45deg);
}

.cncgc-product__gallery .flex-direction-nav .flex-disabled {
	opacity: 0.25;
	pointer-events: none;
}

/* stylelint-disable-next-line media-feature-range-notation -- see .cncgc-product__top above for why `min-width` is kept here. */
@media (min-width: 992px) {
	.cncgc-product__gallery .cncgc-product-gallery {
		display: flex;
		align-items: flex-start;
		gap: 16px;
	}

	.cncgc-product__gallery .flex-viewport {
		order: 1;
		flex: 1 1 auto;
		min-width: 0;
		border-radius: var(--cncgc-radius);
	}

	.cncgc-product__gallery .flex-control-nav.flex-control-thumbs {
		order: 0;
		flex: 0 0 96px;
		width: 96px;
		flex-direction: column;
		gap: 12px;
		margin: 0;
		padding: 0;
		max-height: 640px;
		overflow: visible auto;
	}

	.cncgc-product__gallery .flex-control-thumbs li {
		flex: 0 0 auto;
		width: 100%;
	}

	.cncgc-product__gallery .flex-control-thumbs img {
		height: 96px;
	}

	.cncgc-product__gallery .flex-direction-nav .flex-prev {
		left: 16px;
	}

	.cncgc-product__gallery .flex-direction-nav .flex-next {
		right: 16px;
	}
}

/* Decorative "expand" hint on the main slide — injected by product-gallery.js.
   The whole slide is already a fancybox trigger (plugin's own lightBox()),
   this only surfaces that affordance visually per the design concept. */
.cncgc-gallery-expand {
	position: absolute;
	top: 16px;
	right: 16px;
	width: 36px;
	height: 36px;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--cncgc-bg);
	border-radius: 50%;
	box-shadow: var(--cncgc-shadow);
	pointer-events: none;
	z-index: 6;
}

/*
 * WooCommerce's own zoom JS (single-product.js) additionally appends its
 * own "open fullscreen gallery" trigger button (top-left by WC core's
 * default styling, magnifying-glass emoji) — not part of any theme
 * template, confirmed absent from this theme's PHP (grepped the repo).
 * It opens the exact same PhotoSwipe dialog as `.cncgc-gallery-expand`
 * above and a click on the image itself already do, so it's a redundant
 * second icon rather than an extra feature — confirmed live, both icons
 * shown at once. Hidden, not the zoom theme support disabled: that would
 * also remove the working hover-to-magnify lens, which is unrelated.
 */
.cncgc-product__gallery .woocommerce-product-gallery__trigger {
	display: none;
}

.cncgc-product__summary {
	width: 100% !important;
	float: none !important;
}

.cncgc-product-summary__cat {
	margin: 0 0 8px;
	font-size: 0.8rem;
	color: var(--cncgc-text-muted);
	text-transform: uppercase;
	letter-spacing: 0.06em;
}

.cncgc-product__summary .product_title {
	font-size: clamp(1.5rem, 2.8vw, 2rem);
	margin-bottom: 8px;
}

.cncgc-product__summary .woocommerce-product-details__short-description {
	color: var(--cncgc-text-muted);
	font-size: 0.95rem;
	margin-bottom: 20px;
}

.cncgc-product__summary .price {
	font-size: 1.75rem;
	font-weight: 700;
	margin: 16px 0 10px;
}

/*
 * On sale, WooCommerce wraps the old price in <del> and the new one in
 * <ins>. The new price still inherits the 1.75rem from .price above; the
 * old one is deliberately smaller (1.1rem) so it reads as secondary next
 * to it.
 */
.cncgc-product__summary .price del {
	color: #767d83;
	font-size: 1.1rem;
}

.cncgc-product__summary .price ins {
	color: #ce0019;
	font-weight: bold;
	text-decoration: none;
}

.cncgc-product__summary .stock {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: 0.875rem;
	margin-bottom: 8px;
}

.cncgc-product__summary .stock.in-stock {
	color: var(--cncgc-success);
}

.cncgc-product__summary .stock.out-of-production {
	padding: 6px 12px;
	background: var(--cncgc-bg-muted);
	color: var(--cncgc-charcoal);
	font-weight: 600;
	border-radius: var(--cncgc-radius);
}

.cncgc-product-summary__stock-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 16px;
	margin-bottom: 16px;
	font-size: 0.875rem;
}

.cncgc-product-summary__stock-row .stock {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin: 0;
}

.cncgc-product__summary .sku_wrapper,
.cncgc-product__summary .product_meta {
	font-size: 0.8rem;
	color: var(--cncgc-text-muted);
	margin-bottom: 16px;
}

/*
 * Overrides the rule above specifically inside the stock/SKU row: that rule's
 * own margin-bottom (needed when .sku_wrapper stood alone) was inflating only
 * this item's flex-item box on one side, throwing off `align-items: center`
 * against the sibling `.stock` (which has no such margin) — confirmed live,
 * an 8px vertical offset between "В наличии" and "Артикул: …". Matching
 * font-size too so both read as one line, not two different sizes.
 */
.cncgc-product-summary__stock-row .sku_wrapper {
	font-size: 0.875rem;
	margin-bottom: 0;
}

/*
 * Statuses other than "В наличии" in the stock/SKU row are badges, in the
 * catalog badge style (woocommerce.css, .out_of_stock-badge), so they stand
 * out from the muted SKU. WooCommerce's own message for these statuses is
 * dropped (cncgc_hide_duplicate_stock_html(), inc/woocommerce.php).
 */
.cncgc-product-summary__stock-row .stock.out-of-stock,
.cncgc-product-summary__stock-row .stock.available-on-backorder,
.cncgc-product-summary__stock-row .stock.out-of-production {
	min-height: 32px;
	margin: 0;
	padding: 0 12px;
	border: 1px solid transparent;
	border-radius: var(--cncgc-radius);
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.03em;
	text-transform: uppercase;
}

.cncgc-product-summary__stock-row .stock.out-of-stock {
	border-color: var(--cncgc-red);
	color: var(--cncgc-red);
}

.cncgc-product-summary__stock-row .stock.available-on-backorder {
	background: var(--cncgc-charcoal);
	color: #fff;
}

.cncgc-product__summary form.cart {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	align-items: center;
	margin-bottom: 20px;
}

.cncgc-product__summary form.cart .single_add_to_cart_button {
	flex: 1 1 220px;
	min-height: 52px;
}

/*
 * Variable products only: `form.cart` here is WooCommerce's own
 * `.variations_form`, whose direct children are `table.variations` and
 * `.single_variation_wrap` — NOT the quantity/button/wishlist row itself,
 * which sits one level deeper inside `.single_variation_wrap
 * > .woocommerce-variation-add-to-cart`. The flex rule above only ever
 * reaches direct children, so for a variable product it flexed the wrong
 * two boxes (the variations table and the whole variation wrap) while the
 * actual quantity input, button and wishlist toggle inside were left with
 * no flex layout at all and stacked as plain block elements. Simple
 * products have no `.variations_form` wrapper, so the rule above still
 * governs their layout exactly as before — this only re-targets the
 * variable-product case one level down.
 */
.cncgc-product__summary form.variations_form.cart {
	display: block;
}

.cncgc-product__summary .single_variation_wrap {
	display: block;
	width: 100%;
}

.cncgc-product__summary .woocommerce-variation.single_variation:not(:empty) {
	margin-bottom: 12px;
}

.cncgc-product__summary .woocommerce-variation-add-to-cart {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	align-items: center;
	margin-bottom: 20px;
}

.cncgc-product__summary .woocommerce-variation-add-to-cart .single_add_to_cart_button {
	flex: 1 1 220px;
	min-height: 52px;
}

/*
 * Native WooCommerce "Clear" (reset_variations) link — relocated by
 * product-swatches.js from its default spot inside the now visually-hidden
 * `table.variations` (redundant once our color swatches already show the
 * label/picker) to right between the quantity field and the Add to cart
 * button. Sized/styled to match `.cncgc-wishlist-toggle` for a single,
 * consistent icon-button language in this row.
 */
.cncgc-reset-variations {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 52px;
	min-height: 52px;
	background: var(--cncgc-bg);
	border: 1px solid var(--cncgc-border-strong);
	border-radius: var(--cncgc-radius);
	color: var(--cncgc-black);
	flex: 0 0 auto;
}

@media (hover: hover) and (pointer: fine) {
	.cncgc-reset-variations:hover {
		border-color: var(--cncgc-red);
		color: var(--cncgc-red);
	}
}

/*
 * `table.variations` rows for attributes with no swatch equivalent (e.g.
 * Применяемость/Модель/Калибр on a multi-select variable product) — these
 * rows are left in place by product-swatches.js (only color-swatch rows get
 * hidden), so they need their own themed look instead of native browser
 * <table>/<select> chrome. See doc/known-issues.md, раздел 7.
 *
 * The table is de-tabled into a simple vertical stack — one themed dropdown
 * per attribute, label above value, matching the label style already used
 * for `.cncgc-color-swatches__label` above.
 */
.cncgc-product__summary table.variations {
	display: block;
	width: 100%;
	margin: 0 0 16px;
	border: 0;
}

.cncgc-product__summary table.variations tbody {
	display: grid;
	gap: 14px;
}

.cncgc-product__summary table.variations tr {
	display: block;
}

.cncgc-product__summary table.variations th.label {
	display: block;
	padding: 0 0 8px;
	font-size: 0.8rem;
	font-weight: 400;
	color: var(--cncgc-text-muted);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	text-align: left;
}

.cncgc-product__summary table.variations td.value {
	display: block;
}

/*
 * appearance: none replaces the native dropdown arrow with our own chevron
 * (inline SVG, since a data: URI can't reference --cncgc-black — the fill
 * below is that variable's literal value and must be kept in sync with it),
 * for a consistent look across browsers/OSes; the element is still a real
 * <select> underneath — full keyboard/native mobile picker support.
 */
.cncgc-product__summary table.variations select {
	width: 100%;
	min-height: 48px;
	padding: 12px 40px 12px 14px;
	border: 1px solid var(--cncgc-border-strong);
	border-radius: var(--cncgc-radius);
	background-color: var(--cncgc-bg);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23111111' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 14px center;
	background-size: 12px;
	appearance: none;
	cursor: pointer;
	transition: border-color var(--cncgc-transition);
}

.cncgc-product__summary table.variations select:focus-visible {
	outline: none;
	border-color: var(--cncgc-black);
}

.cncgc-product__summary table.variations select:disabled {
	opacity: 0.5;
	cursor: not-allowed;
}

.cncgc-trust-badges {
	display: grid;
	grid-template-columns: 1fr;
	gap: 10px;
	margin: 8px 0 0;
	padding: 0;
	list-style: none;
}

/* stylelint-disable-next-line media-feature-range-notation -- see .cncgc-product__top above for why `min-width` is kept here. */
@media (min-width: 576px) {
	.cncgc-trust-badges {
		/* Колонки по числу пунктов: без «Гарантии» — 50/50, с ней — по трети. */
		grid-auto-columns: minmax(0, 1fr);
		grid-auto-flow: column;
		grid-template-columns: none;
	}
}

.cncgc-trust-badges__item {
	display: flex;
	gap: 10px;
	align-items: flex-start;
	padding: 14px;
	background: var(--cncgc-bg-soft);
	border: 1px solid var(--cncgc-border);
	font-size: 0.8rem;
}

.cncgc-trust-badges__text {
	display: grid;
	gap: 2px;
}

.cncgc-trust-badges__text strong {
	font-size: 0.8rem;
}

.cncgc-trust-badges__text small {
	color: #000;
}

.cncgc-product-manual {
	margin: 12px 0 0;
}

.cncgc-product-manual__link {
	display: flex;
	align-items: center;
	gap: 8px;
	width: 100%;
	padding: 10px 14px;
	background: var(--cncgc-bg-soft);
	border: 1px solid var(--cncgc-border);
	color: var(--cncgc-text);
	font-size: 0.85rem;
	font-weight: 600;
	text-decoration: none;
	transition: border-color var(--cncgc-transition), background-color var(--cncgc-transition);
}

.cncgc-product-manual__link .cncgc-icon {
	flex-shrink: 0;
	color: var(--cncgc-red);
}

@media (hover: hover) and (pointer: fine) {
	.cncgc-product-manual__link:hover {
		background: var(--cncgc-bg-muted);
		border-color: var(--cncgc-border-strong);
	}
}

.cncgc-licensed-notice {
	padding: 20px 24px;
	background: var(--cncgc-red);
	color: #fff;
}

.cncgc-licensed-notice p {
	margin: 0 0 8px;
	font-size: 0.9rem;
	line-height: 1.6;
}

.cncgc-licensed-notice p:last-child {
	margin-bottom: 0;
}

/* stylelint-disable-next-line media-feature-range-notation -- see .cncgc-product__top above for why `min-width` is kept here. */
@media (min-width: 768px) {
	.cncgc-licensed-notice {
		padding: 24px 48px;
	}

	.cncgc-licensed-notice p {
		font-size: 0.95rem;
	}
}

.cncgc-product__tabs {
	padding: 16px 0 64px;
	border-top: 1px solid var(--cncgc-border);
}

.cncgc-product__tabs .woocommerce-tabs ul.tabs {
	display: flex;
	flex-wrap: wrap;
	gap: 0;
	padding: 0;
	margin: 0 0 28px;
	border-bottom: 1px solid var(--cncgc-border);
	list-style: none;
}

.cncgc-product__tabs .woocommerce-tabs ul.tabs::before {
	display: none;
}

.cncgc-product__tabs .woocommerce-tabs ul.tabs li {
	border: 0 !important;
	background: transparent !important;
	margin: 0;
	padding: 0;
	border-radius: 0 !important;
}

.cncgc-product__tabs .woocommerce-tabs ul.tabs li a {
	display: block;
	padding: 14px 16px;
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--cncgc-text-muted);
	border-bottom: 2px solid transparent;
}

.cncgc-product__tabs .woocommerce-tabs ul.tabs li.active a {
	color: var(--cncgc-black);
	border-bottom-color: var(--cncgc-black);
}

.cncgc-product__tabs .woocommerce-Tabs-panel {
	padding: 0;
	border: 0;
}

.cncgc-product__tabs .woocommerce-Tabs-panel h2 {
	font-size: 1.15rem;
}

/*
 * Reviews tab: the review form is a card (same look as «Характеристики»),
 * so with no reviews yet it doesn't melt into the "no reviews" text.
 */
.woocommerce #review_form_wrapper {
	margin-top: 24px;
	padding: 20px;
	background: var(--cncgc-bg-soft);
	border: 1px solid var(--cncgc-border);
}

@media (min-width: 768px) {
	.woocommerce #review_form_wrapper {
		padding: 28px;
	}
}

.woocommerce #review_form #respond .comment-reply-title {
	display: block;
	margin-bottom: 16px;
	font-size: 1rem;
	font-weight: 700;
	line-height: 1.4;
}

.woocommerce #review_form #respond textarea {
	width: 100%;
	padding: 12px 14px;
	background: var(--cncgc-bg);
	border: 1px solid var(--cncgc-border-strong);
	border-radius: var(--cncgc-radius);
	font: inherit;
}

/* Shown instead of the fields once the customer has reviewed (cncgc_review_form_once()). */
.woocommerce #review_form #respond .cncgc-review-done {
	margin: 0;
	color: var(--cncgc-text-muted);
}

/* Rating stars — marketplace yellow instead of the text color. */
.woocommerce #review_form #respond p.stars a,
.woocommerce-Tabs-panel--reviews .star-rating {
	color: #ffb800;
}

/* «Отправить» = «Получить код» (.cncgc-auth__btn, auth.css): disabled until
   rating + 10 chars, toggled by assets/js/product-reviews.js. */
.woocommerce #review_form #respond input#submit {
	width: 100%;
	min-height: 52px;
	padding: 0 18px;
	border: 1px solid var(--cncgc-black) !important;
	background: var(--cncgc-black) !important;
	font: 700 13px/1 var(--cncgc-font);
	letter-spacing: 0.04em;
	text-transform: uppercase;
	cursor: pointer;
	transition: background var(--cncgc-transition), color var(--cncgc-transition);
}

@media (min-width: 576px) {
	.woocommerce #review_form #respond input#submit {
		width: auto;
		min-width: 240px;
	}
}

.woocommerce #review_form #respond input#submit:disabled {
	border-color: var(--cncgc-border) !important;
	background: var(--cncgc-border) !important;
	color: #8f8f8f !important;
	cursor: not-allowed;
}

@media (hover: hover) and (pointer: fine) {
	.woocommerce #review_form #respond input#submit:not(:disabled):hover {
		background: #000 !important;
	}
}

/*
 * Restore normal list styling (bullets/numbers, indent) inside product
 * content — description body, "Комплектация" and any other custom tab.
 * The site-wide `ul, ol { list-style: none; padding: 0 }` reset (main.css,
 * written for component lists — nav, footer, product grids) was also
 * stripping bullets/numbers from genuine content lists here: confirmed
 * live, a real `<ul><li>` list (correctly parsed HTML, not escaped text —
 * checked) rendered as unstyled run-together lines, unreadable as a list.
 * Excludes the reviews panel deliberately: that one is WooCommerce's own
 * comment list (`ol.commentlist`), a component list like nav/footer, not
 * user-authored content — it should keep the site-wide reset, not gain
 * bullets.
 */
.cncgc-product__tabs .woocommerce-Tabs-panel:not(.woocommerce-Tabs-panel--reviews) ul {
	list-style: disc;
	padding-left: 1.25em;
	margin: 0 0 1em;
}

.cncgc-product__tabs .woocommerce-Tabs-panel:not(.woocommerce-Tabs-panel--reviews) ol {
	list-style: decimal;
	padding-left: 1.25em;
	margin: 0 0 1em;
}

.cncgc-product__tabs .woocommerce-Tabs-panel:not(.woocommerce-Tabs-panel--reviews) li {
	margin-bottom: 0.4em;
}

.cncgc-product__tabs table.shop_attributes {
	width: 100%;
	max-width: 520px;
}

.cncgc-product__tabs table.shop_attributes th,
.cncgc-product__tabs table.shop_attributes td {
	border-bottom: 1px solid var(--cncgc-border);
	padding: 10px 0;
	font-size: 0.9rem;
	font-weight: 600;
	color: var(--cncgc-text);
}

.cncgc-product__tabs table.shop_attributes th {
	width: 45%;
	color: var(--cncgc-text-muted);
	font-weight: 600;
}

/*
 * Some attribute values are authored as links (e.g. a compatibility spec
 * pointing at a related product/page) — the base `a { text-decoration:
 * none }` (main.css) leaves them visually identical to plain text, so
 * nothing signals they're clickable. Dashed underline matches the
 * production theme's existing convention for in-copy links.
 */
.cncgc-product__tabs table.shop_attributes td a {
	border-bottom: 1px dashed currentcolor;
}

@media (hover: hover) and (pointer: fine) {
	.cncgc-product__tabs table.shop_attributes td a:hover {
		border-bottom-style: solid;
	}
}

/*
 * "Схема размеров" tab: dimension blueprint image. Centered, capped so an
 * oversized source image doesn't dwarf the other tab panels; bordered card
 * to match the engineering-diagram content (see cncgc_product_blueprint_tab()
 * in inc/woocommerce.php).
 */
.cncgc-blueprint-tab {
	display: flex;
	justify-content: center;
	padding: 16px;
	background: var(--cncgc-bg-soft);
	border: 1px solid var(--cncgc-border);
}

.cncgc-blueprint-tab__image {
	display: block;
	max-width: 100%;
	height: auto;
}

/*
 * WooCommerce core's own `tr:nth-child(even)` shading on this table
 * (`.shop_attributes tr:nth-child(even) th/td`) sits only a couple of grey
 * units off `.cncgc-spec-card`'s `--cncgc-bg-soft` background — the two wash
 * together on screen. Overriding with a darker, explicit tint (rather than
 * tweaking the card's own background, which would also shift the odd rows)
 * restores visible zebra striping without touching card/odd-row color.
 */
.cncgc-spec-card table.shop_attributes tr:nth-child(even) th,
.cncgc-spec-card table.shop_attributes tr:nth-child(even) td {
	background-color: rgb(17 17 17 / 6%);
}

/* Spec chips */
.cncgc-spec-chips {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 12px;
	margin: 0 0 16px;
	padding: 14px 0;
	list-style: none;
	border-top: 1px solid var(--cncgc-border);
	border-bottom: 1px solid var(--cncgc-border);
}

/* stylelint-disable-next-line media-feature-range-notation -- see .cncgc-product__top above for why `min-width` is kept here. */
@media (min-width: 576px) {
	.cncgc-spec-chips {
		grid-template-columns: repeat(4, 1fr);
	}
}

.cncgc-spec-chips__item {
	display: flex;
	gap: 8px;
	align-items: flex-start;
}

.cncgc-spec-chips__text {
	display: grid;
	gap: 2px;
	font-size: 0.8rem;
}

.cncgc-spec-chips__text strong {
	font-size: 0.85rem;
}

.cncgc-spec-chips__text small {
	color: var(--cncgc-text-muted);
}

/*
 * Brand logo chip: pinned to the last grid column so it always sits at the
 * right edge of the row, whatever column count is active (2 on mobile, 4 at
 * >=576px) and however many of the other (optional) spec chips render
 * before it.
 *
 * `grid-column-end: -1` only, not the `grid-column: -1` shorthand: the
 * shorthand also sets grid-column-start to -1, and since -1 IS the grid's
 * last line, that pairs -1 (start) with the default auto (end), which asks
 * for one track *after* the last line — creating a genuine new 5th column
 * instead of placing the item in the existing last one. Confirmed live:
 * with the shorthand, `.cncgc-spec-chips` grew an extra 0-content column
 * and every existing chip narrowed to make room for it.
 */
.cncgc-spec-chips__item--brand {
	grid-column-end: -1;
	place-self: start end;
}

.cncgc-spec-chips__brand-link {
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 4px;
}

/* Same type treatment as the other chips' own value (e.g. "6.960 kg"), not their muted label underneath — matches `.cncgc-spec-chips__text strong`. */
.cncgc-spec-chips__brand-label {
	font-size: 0.85rem;
	font-weight: 700;
	color: var(--cncgc-text);
}

.cncgc-spec-chips__brand-logo {
	width: 64px;
	height: 64px;
	object-fit: contain;
}

.cncgc-spec-chips__brand-name {
	font-size: 0.85rem;
	font-weight: 700;
	text-align: right;
}

/* Color swatches */
.cncgc-color-swatches {
	margin: 0 0 16px;
}

.cncgc-color-swatches__label {
	margin: 0 0 8px;
	font-size: 0.8rem;
	color: var(--cncgc-text-muted);
	text-transform: uppercase;
	letter-spacing: 0.06em;
}

.cncgc-color-swatches__list {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

.cncgc-color-swatches__item {
	width: 32px;
	height: 32px;
	min-width: 44px;
	min-height: 44px;
	padding: 0;
	background-color: var(--cncgc-bg-muted);
	border: 2px solid var(--cncgc-border);
	border-radius: 50%;
	cursor: pointer;
}

.cncgc-color-swatches__item.is-active {
	border-color: var(--cncgc-black);
}

.cncgc-color-swatches__item--unmapped {
	background-image: linear-gradient(45deg, var(--cncgc-border) 25%, transparent 25%, transparent 75%, var(--cncgc-border) 75%);
	background-size: 8px 8px;
}

/* Wishlist toggle */
.cncgc-wishlist-toggle {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 52px;
	min-height: 52px;
	background: var(--cncgc-bg);
	border: 1px solid var(--cncgc-border-strong);
	border-radius: var(--cncgc-radius);
	color: var(--cncgc-black);
}

.cncgc-wishlist-toggle.is-active {
	color: var(--cncgc-red);
	border-color: var(--cncgc-red);
}

@media (hover: hover) and (pointer: fine) {
	.cncgc-wishlist-toggle:hover {
		border-color: var(--cncgc-black);
	}
}

/*
 * Tabs widget + "Характеристики" card, side by side: the spec card is
 * always visible here regardless of which tab is active (moved out of the
 * "Описание" tab's own panel — see cncgc_single_product_spec_card() in
 * inc/woocommerce.php — where it used to disappear whenever a different
 * tab, e.g. "Отзывы", was selected).
 *
 * The column ratio and gap here are deliberately kept identical to
 * `.cncgc-product__top` above (1.15:0.85 split, 48px gap) — both rows sit
 * at the same container width, so matching them makes `.cncgc-spec-card`
 * compute to exactly the same width as `.cncgc-product__summary`
 * (confirmed live via getBoundingClientRect() before this fix: the two
 * rows previously used different ratios — 1.1fr/0.9fr here vs 1.15/0.85
 * flex-grow there — and a different gap, 40px vs 48px, which is what made
 * the spec card visibly wider than the summary column above it).
 */
.cncgc-product__tabs-row {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 24px;
	margin-bottom: 32px;
}

/*
 * Embeds pasted into the description (VK/YouTube iframes) come with fixed
 * width attributes (e.g. width="635px"). Without a ceiling they stretch the
 * grid track above and the whole page on phones: the layout viewport grows
 * wider than the screen and the fixed bottom tab bar (inc/mobile-nav.php)
 * slides out of view, so «Меню» stops responding.
 */
.cncgc-description-tab__text iframe,
.cncgc-description-tab__text video,
.cncgc-description-tab__text embed,
.cncgc-description-tab__text object {
	max-width: 100%;
}

/* Same text and h2 as news and information pages (.cncgc-prose, prose.css). */
.cncgc-description-tab__text {
	line-height: 1.7;
	color: var(--cncgc-text);
	hyphens: auto;
	hyphenate-limit-chars: 6 3 3;
}

.cncgc-product__tabs .cncgc-description-tab__text h2 {
	font-size: clamp(1.3rem, 1.1rem + 0.8vw, 1.625rem);
	font-weight: 600;
	line-height: 1.3;
	color: var(--cncgc-black);
	hyphens: manual;
}

/* stylelint-disable-next-line media-feature-range-notation -- see .cncgc-product__top above for why `min-width` is kept here. */
@media (min-width: 992px) {
	.cncgc-product__tabs-row {
		grid-template-columns: 1.15fr 0.85fr;
		gap: 48px;
	}

	.cncgc-product__tabs-row > .woocommerce-tabs {
		min-width: 0;
	}
}

.cncgc-spec-card {
	padding: 24px;
	background: var(--cncgc-bg-soft);
	border: 1px solid var(--cncgc-border);
}

.cncgc-spec-card h3 {
	margin-bottom: 16px;
	font-size: 1rem;
}

/*
 * `.cncgc-product__tabs table.shop_attributes` (below) caps the table at
 * max-width: 520px — that rule dates from when this table rendered directly
 * in the full-width standalone "Характеристики" tab (removed, see
 * cncgc_product_tabs() in inc/woocommerce.php) and was meant to keep it from
 * stretching too wide there. Now it only ever renders inside this narrower
 * spec-card column, where 520px can still exceed the card's own content
 * width on wide viewports — confirmed live, leaving the table narrower than
 * the h3 heading above it. The card is the width constraint now; the table
 * should just fill it.
 */
.cncgc-spec-card table.shop_attributes {
	max-width: none;
}

/* Hides the native variation <select> once product-swatches.js has wired up
   the swatch buttons as its visual proxy; kept in the DOM for a11y/no-JS. */
.cncgc-visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}
