/*
 * Shared components: share row, pre-order dialog, pre-order trigger.
 *
 * Used by several workstreams; treat as shared and coordinate changes.
 *
 * Split out of the former single woo.css so the redesign workstreams own disjoint
 * files. Every value is a token from theme.json — no hardcoded colours, no breakpoints;
 * layout responds with container queries.
 */

/* ------------------------------------------------------------------- share */
/* These rules were an inline <style> block printed into wp_head by the old theme. */

.nv-share {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--xxs);
	align-items: center;
	margin-block: var(--wp--preset--spacing--xs) 0;
}

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

/* 44px hit area. The old row was a 24px icon with no padding — under the minimum for
   touch, and the icons sat flush together once the plugin's CSS was removed. */
.nv-share__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: 44px;
	block-size: 44px;
	color: var(--wp--preset--color--text-muted);
	border-radius: var(--wp--custom--radius--full);
	transition: color var(--wp--custom--transition--base),
		background var(--wp--custom--transition--base);
}

.nv-share__link:hover,
.nv-share__link:focus-visible {
	color: var(--wp--preset--color--base);
	background: var(--wp--preset--color--brand);
}

.nv-share__link:focus-visible {
	outline: var(--wp--custom--focus--width) solid var(--wp--preset--color--accent);
	outline-offset: var(--wp--custom--focus--offset);
}

/* ------------------------------------------------------------------ dialog */

.nv-dialog {
	inline-size: min(32rem, calc(100vw - 2rem));
	padding: var(--wp--preset--spacing--sm);
	color: var(--wp--preset--color--contrast);
	background: var(--wp--preset--color--base);
	border: 0;
	border-radius: var(--wp--custom--radius--lg);
	box-shadow: 0 8px 40px rgb(0 0 0 / 24%);
}

.nv-dialog::backdrop {
	background: rgb(5 26 38 / 55%);
}

.nv-dialog__head {
	display: flex;
	gap: var(--wp--preset--spacing--xs);
	align-items: start;
	justify-content: space-between;
}

.nv-dialog__title {
	margin: 0;
	font-size: var(--wp--preset--font-size--lg);
	line-height: 1.25;
}

.nv-dialog__product {
	display: block;
	color: var(--wp--preset--color--brand);
}

.nv-dialog__close {
	min-inline-size: 44px;
	min-block-size: 44px;
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--xl);
	line-height: 1;
	background: none;
	border: 0;
	border-radius: var(--wp--custom--radius--md);
	cursor: pointer;
}

.nv-dialog__intro {
	margin-block: var(--wp--preset--spacing--xxs) 0;
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--sm);
}

.nv-field {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	margin-block: var(--wp--preset--spacing--xs) 0;
}

.nv-field__label {
	font-size: var(--wp--preset--font-size--sm);
}

.nv-field__required {
	color: var(--wp--preset--color--brand);
}

.nv-field__input {
	min-block-size: 44px;
	padding: 0.5em 0.75em;
	color: inherit;
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	font: inherit;
}

.nv-field__input:focus-visible,
.nv-dialog__close:focus-visible,
.nv-preorder__trigger:focus-visible {
	outline: var(--wp--custom--focus--width) solid var(--wp--preset--color--accent);
	outline-offset: var(--wp--custom--focus--offset);
}

/* Empty until there is something to say, so it takes no space and announces nothing. */
.nv-dialog__status:empty {
	display: none;
}

.nv-dialog__status {
	margin-block: var(--wp--preset--spacing--xs) 0;
	padding: var(--wp--preset--spacing--xxs) var(--wp--preset--spacing--xs);
	border-radius: var(--wp--custom--radius--md);
	font-size: var(--wp--preset--font-size--sm);
}

.nv-dialog__status.is-ok {
	color: var(--wp--preset--color--base);
	background: var(--wp--preset--color--accent);
}

.nv-dialog__status.is-error {
	background: var(--wp--preset--color--surface-muted);
	border: 1px solid var(--wp--preset--color--brand);
}

.nv-dialog__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--xs);
	align-items: center;
	margin-block-start: var(--wp--preset--spacing--sm);
}

.nv-dialog__submit {
	min-block-size: 44px;
	padding-inline: var(--wp--preset--spacing--sm);
	cursor: pointer;
}

.nv-dialog__submit[disabled] {
	opacity: 0.6;
	cursor: progress;
}

.nv-dialog__cancel {
	min-block-size: 44px;
	padding-inline: var(--wp--preset--spacing--xs);
	color: var(--wp--preset--color--text-muted);
	background: none;
	border: 0;
	cursor: pointer;
	text-decoration: underline;
}

/* --------------------------------------------------------------- pre-order */

.nv-preorder__trigger {
	display: inline-block;
	min-block-size: 44px;
	padding: 0.6em 1.2em;
	color: var(--wp--preset--color--base);
	background: var(--wp--preset--color--accent);
	border: 0;
	border-radius: var(--wp--custom--radius--md);
	font: inherit;
	font-weight: 700;
	cursor: pointer;
	transition: background var(--wp--custom--transition--base);
}

.nv-preorder__trigger:hover {
	background: var(--wp--preset--color--brand);
}

@media (prefers-reduced-motion: reduce) {
	.wp-block-woocommerce-product-template li.product,
	.nv-preorder__trigger {
		transition: none;
	}
}

/* ========================================================================== *
 * THE BUTTON SYSTEM — three types, and that is the whole set
 * ========================================================================== *
 *
 * Measured before writing this: 15 distinct button treatments across 7 heights on nine pages.
 * They happened because padding and height were set per file with no shared box, so every
 * stream invented its own. This is the shared box.
 *
 * THE ACTION HIERARCHY, which is the point of the whole thing:
 *
 *     primary    В корзину · Замовити · Оформить заказ     the one thing on the screen
 *     secondary  Контакты · Подробнее о категории          a real action, not the main one
 *     tertiary   Сравнить · Детальніше · share             available, deliberately quiet
 *
 * Each type is the one above with something REMOVED — fill, then border, then weight. A
 * demotion ladder rather than three unrelated designs, so "which is more important" is
 * legible without reading the labels.
 *
 * Every type carries a 1px border in its box model, transparent where it is not drawn, so
 * swapping a button's type never shifts the layout by 2px.
 */

.nv-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--wp--preset--spacing--xxs);
	min-block-size: 44px;
	padding-block: 0.6875rem;
	padding-inline: var(--wp--preset--spacing--sm);
	border: 1px solid transparent;
	border-radius: var(--wp--custom--radius--md);
	font-family: inherit;
	font-size: var(--wp--preset--font-size--base);
	line-height: 1.2;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
	transition: background var(--wp--custom--transition--base),
		border-color var(--wp--custom--transition--base),
		color var(--wp--custom--transition--base);
}

.nv-btn:focus-visible {
	outline: var(--wp--custom--focus--width) solid var(--wp--preset--color--accent);
	outline-offset: var(--wp--custom--focus--offset);
}

/* PRIMARY — the conversion action. Taller than the others on purpose: 48px against 44px is
   the cheapest way to make it read as the destination without shouting in colour. */
.nv-btn--primary {
	min-block-size: 48px;
	background: var(--wp--preset--color--brand);
	border-color: var(--wp--preset--color--brand);
	color: var(--wp--preset--color--base);
	font-weight: 700;
}

.nv-btn--primary:hover { background: var(--wp--preset--color--brand-dark); border-color: var(--wp--preset--color--brand-dark); }
.nv-btn--primary:active { background: var(--wp--preset--color--brand-darker); border-color: var(--wp--preset--color--brand-darker); }

/* SECONDARY — fill removed. Still a box, still 400 weight. */
.nv-btn--secondary {
	background: transparent;
	border-color: var(--wp--preset--color--border);
	color: var(--wp--preset--color--contrast);
	font-weight: 400;
}

.nv-btn--secondary:hover { border-color: var(--wp--preset--color--brand); color: var(--wp--preset--color--brand); }

/* TERTIARY — border removed too. A text action that keeps its 44px hit area. */
.nv-btn--tertiary {
	min-inline-size: 0;
	padding-inline: 0;
	background: none;
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 400;
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.nv-btn--tertiary:hover { color: var(--wp--preset--color--brand); }

.nv-btn[disabled],
.nv-btn[aria-disabled="true"] {
	opacity: 0.55;
	cursor: not-allowed;
}

/* A primary action inside a card fills its column, so buttons align across a row regardless of
   how long the product name is. Outside a card it shrinks to its label. */
.nv-card .nv-btn--primary,
li.product .nv-btn--primary {
	inline-size: 100%;
}

/* ========================================================================== *
 * MIGRATION — every existing control mapped onto one of the three types
 * ========================================================================== *
 *
 * Most buttons on this site are emitted by WooCommerce, WordPress core, Contact Form 7 and
 * YITH. Their markup cannot be given a class from here, so the system is applied by MAPPING
 * their selectors onto it rather than by editing call sites. That is deliberate and is why
 * this block exists instead of a hundred template edits.
 *
 * Measured before: 19 distinct treatments across 78 controls on 12 pages.
 *
 * Rule for anyone adding to this list: a control goes in exactly ONE group. If it seems to
 * need a fourth group, it is either a primary that is scared of itself or a tertiary wearing
 * a box — pick one.
 */

/* ---- PRIMARY: the conversion action. One per screen, ideally. ---- */
.single_add_to_cart_button,
.checkout-button,
#place_order,
.nv-preorder__trigger,
.nv-dialog__submit,
.wpcf7-submit,
.woocommerce-form-login .button,
.nv-btn--primary {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--wp--preset--spacing--xxs);
	min-block-size: 48px;
	padding-block: 0.6875rem;
	padding-inline: var(--wp--preset--spacing--sm);
	background: var(--wp--preset--color--brand);
	border: 1px solid var(--wp--preset--color--brand);
	border-radius: var(--wp--custom--radius--md);
	color: var(--wp--preset--color--base);
	font-family: inherit;
	font-size: var(--wp--preset--font-size--base);
	font-weight: 700;
	line-height: 1.2;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
	transition: background var(--wp--custom--transition--base),
		border-color var(--wp--custom--transition--base);
}

.single_add_to_cart_button:hover,
.checkout-button:hover,
#place_order:hover,
.nv-preorder__trigger:hover,
.nv-dialog__submit:hover,
.wpcf7-submit:hover,
.nv-btn--primary:hover {
	background: var(--wp--preset--color--brand-dark);
	border-color: var(--wp--preset--color--brand-dark);
	color: var(--wp--preset--color--base);
}

/* ---- SECONDARY: a real action, not the main one. Fill removed. ---- */
/* `--quiet` is the homepage's old name for this; kept as an alias so its two call sites in
   inc/home-sections.php keep working without a PHP edit. It was 700 weight — secondary is
   400, or it competes with primary at a glance. */
.nv-btn--secondary,
.nv-btn--quiet,
.woocommerce-cart .actions .button,
.wc-block-components-button:not(.wc-block-components-checkout-place-order-button) {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-block-size: 44px;
	padding-block: 0.6875rem;
	padding-inline: var(--wp--preset--spacing--sm);
	background: transparent;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	color: var(--wp--preset--color--contrast);
	font-size: var(--wp--preset--font-size--base);
	font-weight: 400;
	text-decoration: none;
	cursor: pointer;
}

.nv-btn--secondary:hover,
.nv-btn--quiet:hover,
.woocommerce-cart .actions .button:hover {
	border-color: var(--wp--preset--color--brand);
	color: var(--wp--preset--color--brand);
}

/* ---- TERTIARY: available, deliberately quiet. Border removed too. ---- */
.compare,
.nv-dialog__cancel,
.nv-btn--tertiary,
.woocommerce-info .showcoupon,
.woocommerce-form-login-toggle a {
	display: inline-flex;
	align-items: center;
	min-block-size: 44px;
	padding-inline: 0;
	background: none;
	border: 0;
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 400;
	text-decoration: underline;
	text-underline-offset: 0.2em;
	cursor: pointer;
}

.compare:hover,
.nv-dialog__cancel:hover,
.nv-btn--tertiary:hover {
	background: none;
	color: var(--wp--preset--color--brand);
}

/*
 * WordPress core's search button ships as a 22px browser-default grey box with square
 * corners — the single most out-of-system control on the site, and it appears on the 404 and
 * search pages where a lost visitor most needs the site to look competent.
 */
.wp-block-search__button,
.search-submit {
	min-block-size: 48px;
	padding-inline: var(--wp--preset--spacing--sm);
	background: var(--wp--preset--color--brand);
	border: 1px solid var(--wp--preset--color--brand);
	border-radius: var(--wp--custom--radius--md);
	color: var(--wp--preset--color--base);
	font-size: var(--wp--preset--font-size--base);
	font-weight: 700;
	cursor: pointer;
}

/*
 * Plugin controls that are NOT actions: gallery arrows and the cart's remove "x". They keep
 * their own geometry — they are icons, not buttons — but must not borrow the brand fill, or
 * a gallery arrow reads as loud as "add to cart".
 */
.wooswipe-prev,
.wooswipe-next,
.slick-arrow {
	background: transparent;
	border: 0;
	color: var(--wp--preset--color--text-muted);
	box-shadow: none;
}

/*
 * SIZING GUARD — why a button must never resolve its height against its parent.
 *
 * The pre-order trigger is a bare <button> and therefore a DIRECT flex/grid child. In a
 * container with a definite height (a card stretched to its row) a form control resolves
 * `block-size: auto` against that height, so the button grew to fill the whole card — 573px,
 * measured, overflowing into the row below. The add-to-cart button never did this because
 * WooCommerce wraps it in a div.
 *
 * This lived in catalog.css and was lost when its rule block was removed during the migration
 * to this file. It belongs here: it is a property of the BUTTON, not of the catalogue.
 */
.nv-btn,
.nv-btn--primary,
.nv-preorder__trigger,
.single_add_to_cart_button,
.checkout-button,
#place_order,
.wpcf7-submit,
.nv-dialog__submit {
	flex: 0 0 auto;
	block-size: fit-content;
}

/*
 * Core's button block applies its own padding on top of ours, which produced 91px and 102px
 * buttons in the hero and the closing CTA. The system's padding is the whole padding.
 */
.wp-block-button__link.wp-element-button {
	min-block-size: 48px;
	padding-block: 0.6875rem;
	padding-inline: var(--wp--preset--spacing--sm);
	font-size: var(--wp--preset--font-size--base);
}

/*
 * WooCommerce's `.button.alt` is its "this is the important one" class and ships ACCENT green
 * here. Green is this site's availability/confirmation colour; the purchase action is blue.
 * Two different colours both meaning "most important" is the ambiguity the hierarchy exists
 * to remove.
 */
.button.alt,
.woocommerce .button.alt {
	background: var(--wp--preset--color--brand);
	border-color: var(--wp--preset--color--brand);
	color: var(--wp--preset--color--base);
}

/* ==========================================================================
 * The category tile
 *
 * One card, two pages: the home page's catalogue band and every catalogue archive
 * (/shop/ and each product category) use this object, because on a store that browses by
 * category the tile IS the primary navigation control and it should not look like two
 * different things depending on which page you met it on. The GRID that lays these out is
 * stated per context — home.css and catalog.css own their own column counts.
 *
 * Structure: a media plate, a two-line name, an optional two-line note, and a count pinned
 * to the bottom. Every row is present on every card, which is what levels the grid — the
 * heights match because the CONTENT is consistent, not because a height was forced.
 * ========================================================================== */

.nv-tile {
	container-type: inline-size;
	display: flex;
}

/*
 * The card surface is the LINK, not a wrapper around it: one element carries the box, the
 * hairline and the focus ring, so there is one target, one hit area and one thing to style in
 * every state. `block-size: 100%` is what cashes in `grid-auto-rows: 1fr`.
 */
.nv-tile__link {
	display: grid;
	grid-template-rows: auto 1fr;
	flex: 1;
	gap: var(--wp--preset--spacing--xs);
	padding: var(--wp--preset--spacing--xs);
	block-size: 100%;
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	transition: border-color var(--wp--custom--transition--base);
}

/* The plate. These are white/light mirrors photographed on white — without a tone behind them
   the cutouts float in the page. `surface-muted` has exactly this one job site-wide. */
.nv-tile__media {
	display: block;
	overflow: hidden;
	background: var(--wp--preset--color--surface-muted);
	border-radius: var(--wp--custom--radius--md);
}

/* The RATIO LIVES ON THE IMAGE, not on the box around it. Putting `aspect-ratio` on the
   wrapper and `height: 100%` on the image looks equivalent and is not: the wrapper's height
   is then indefinite as far as the percentage is concerned, `object-fit` never gets a box to
   fit into, and the image is cropped by `overflow: hidden` instead. Measured in the browser
   — a 360x360 photo rendered 333x363 inside a 305x229 frame. */
.nv-tile__image {
	display: block;
	box-sizing: border-box;
	width: 100%;
	height: auto;
	/* 4:3, not square. The photographs are cutouts with air around them, so a square plate
	   spent a third of the card on white — the tiles read as pictures with a caption instead
	   of as a catalogue. The picture is still whole (`contain`), just no longer the tile. */
	aspect-ratio: 4 / 3;
	padding: var(--wp--preset--spacing--xs);
	object-fit: contain;
}

/* A family whose term has no thumbnail. It occupies the plate exactly, so replacing it with a
   photograph does not re-lay out the row. */
.nv-tile__need {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 4 / 3;
	padding: var(--wp--preset--spacing--xs);
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--xs);
	line-height: 1.4;
	text-align: center;
	border: 1px dashed var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
}

.nv-tile__body {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--xxs);
}

/*
 * TWO LINES, ALWAYS. `Купольные зеркала` is one line and `Сферические обзорные зеркала для
 * помещений` is three; Ukrainian is routinely longer again. Clamping at two AND reserving two
 * line-heights is what makes six different names occupy one box — without the `min-block-size`
 * the clamp alone still lets a one-line title sit in a shorter card.
 */
.nv-tile__title {
	margin: 0;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	/* `2.5em` is 2 x 1.25 line-height — the same box, for engines without the `lh` unit.
	   They ignore the second declaration; `grid-auto-rows: 1fr` still levels the row there. */
	min-block-size: 2.5em;
	min-block-size: 2lh;
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 700;
	line-height: 1.25;
	text-wrap: balance;
}

/*
 * The one line saying what the family is FOR. Same two-line treatment as the title: clamped
 * and floor-set, so ten cards with descriptions of different lengths still level up. Muted,
 * because it is support for the name rather than a competitor to it.
 */
.nv-tile__note {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	min-block-size: 2.8em;   /* 2 x 1.4 line-height, for engines without `lh` */
	min-block-size: 2lh;
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--xs);
	line-height: 1.4;
	text-wrap: pretty;
}

/*
 * The count. The ONE fact that makes six interchangeable tiles rankable — and the reason a
 * tile no longer needs to be bigger to say "there is more in here". Pushed to the bottom of
 * the body so it sits on one line across the row regardless of how many lines a name took.
 */
.nv-tile__count {
	margin-block-start: auto;
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--sm);
	line-height: 1.5;
	font-variant-numeric: tabular-nums;
}

/* Hover and focus are a HAIRLINE CHANGE. No shadow (a card does not float — design-system.md
   §8) and no scale (only colour transitions — §11). */
.nv-tile__link:hover {
	border-color: var(--wp--preset--color--brand);
}

.nv-tile__link:hover .nv-tile__title {
	color: var(--wp--preset--color--brand);
}

.nv-tile__link:focus-visible {
	border-color: var(--wp--preset--color--brand);
	outline: var(--wp--custom--focus--width) solid var(--wp--preset--color--accent);
	outline-offset: var(--wp--custom--focus--offset);
}

/*
 * COLOUR. The plate was `surface-muted` — a neutral grey that made a page of ten cut-out
 * photographs read as ten grey squares. It is now a wash of the brand at 5%, which is enough
 * to separate a white mirror from the white page and to tie the catalogue to the rest of the
 * site, and far too little to compete with the photograph standing on it. `color-mix` against
 * the palette tokens rather than a new hex: change `brand` in theme.json and this follows.
 */
.nv-tile__media {
	background: color-mix(in srgb, var(--wp--preset--color--brand) 5%, var(--wp--preset--color--base));
	transition: background var(--wp--custom--transition--base);
}

.nv-tile__link:hover .nv-tile__media,
.nv-tile__link:focus-visible .nv-tile__media {
	background: color-mix(in srgb, var(--wp--preset--color--brand) 11%, var(--wp--preset--color--base));
}

/*
 * The count is the tile's one piece of data, so it is the one place colour carries meaning
 * rather than decoration: brand-coloured, on its own tinted chip, sitting on the bottom edge
 * of the card. Muted grey text said "seventeen products" as quietly as a caption.
 */
.nv-tile__count {
	align-self: start;
	padding: 0.15em 0.6em;
	color: var(--wp--preset--color--brand-dark);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 700;
	background: color-mix(in srgb, var(--wp--preset--color--brand) 9%, var(--wp--preset--color--base));
	border-radius: var(--wp--custom--radius--full);
}

/*
 * The chevron. A drawn box rather than a character, so it is not announced and needs no icon
 * font, and it moves on hover — the one motion cue that says a card is a link to somewhere
 * rather than a picture. It sits AFTER the title's text and inside the clamp, which is what
 * stopped it wrapping onto a line of its own the way the old shop tiles' one did.
 */
.nv-tile__title::after {
	content: "";
	display: inline-block;
	inline-size: 0.34em;
	block-size: 0.34em;
	margin-inline-start: 0.4em;
	vertical-align: middle;
	border-block-start: 2px solid var(--wp--preset--color--brand);
	border-inline-end: 2px solid var(--wp--preset--color--brand);
	transform: rotate(45deg);
	transition: transform var(--wp--custom--transition--base);
}

.nv-tile__link:hover .nv-tile__title::after {
	transform: translateX(0.25em) rotate(45deg);
}

/* The hairline goes brand on hover — plus a brand-tinted ground, so the whole card responds
   and not only its edge. No shadow and no scale: DESIGN.md §8 and §11. */
.nv-tile__link:hover,
.nv-tile__link:focus-visible {
	background: color-mix(in srgb, var(--wp--preset--color--brand) 3%, var(--wp--preset--color--base));
}

/* ==========================================================================
 * The redesign palette — one declaration for every page built to a handoff
 *
 * The approved handoffs (contact 4D, cart 5B, home 6A, info 7A) all specify the SAME palette
 * and the SAME radius scale, and all four disagree with `theme.json` in every hue: blue
 * #1a72b8 against the token's #1576af, green #7ac143 against #72c23a, plus band, panel and
 * on-blue colours the token set does not have at all. The handoffs win — they are the approved
 * design and they say colours are final — but the divergence belongs in ONE place, so that
 * folding it back into theme.json later, if the whole site moves to this palette, is one edit
 * rather than forty.
 *
 * Add `nv-brandpage` to a page's <main> and the variables below are in scope for its
 * stylesheet. Nothing here paints anything by itself.
 *
 * NOTE: assets/css/cart.css (--nv-c-*) and assets/css/home-6a.css (--nv6-*) still carry their
 * own copies of these values under different prefixes. They were written in parallel with this
 * and are not touched here to avoid colliding with work in flight; converging them on this
 * block is a small, separate change. See board/backend/task49.md.
 * ========================================================================== */

.nv-brandpage {
	--c-blue: #1a72b8;
	--c-blue-hover: #155f9b;
	--c-blue-active: #124f81;
	--c-blue-tint: #eef5fb;
	--c-band: #0f4c73;
	--c-panel: #0b3c5c;
	--c-on-band: #c5dcea;
	--c-on-panel: #bcd4e3;
	--c-on-band-faint: #8fb6ce;
	--c-green: #7ac143;
	--c-green-light: #a5db6a;
	--c-ink: #16232c;
	--c-body: #3b4a54;
	--c-body-soft: #4a5761;
	--c-muted: #6b7880;
	--c-muted-soft: #7b8891;
	--c-faint: #9aa6ad;
	--c-line: #e5e9ec;
	--c-line-hover: #c9d6de;
	--c-field-line: #d6dde2;
	--c-field: #f7f9fa;
	--c-error: #e0533a;

	/* Radii, shared by 4D / 5B / 6A / 7A. */
	--c-r-shell: var(--wp--custom--radius--shell);
	--c-r-card: var(--wp--custom--radius--card);
	--c-r-step: var(--wp--custom--radius--inner);
	--c-r-control: var(--wp--custom--radius--control);
	--c-r-pill: var(--wp--custom--radius--pill);

	/* The two shadows the handoffs allow: the overlapping card, and a card on hover. */
	--c-shadow-card: 0 24px 60px rgb(15 44 63 / 18%);
	--c-shadow-hover: 0 8px 22px rgb(15 44 63 / 7%);

	/* The 1280px frame and its gutter. */
	--c-frame: var(--wp--style--global--content-size);
	--c-gutter: 40px;
}

/*
 * ---------------------------------------------------------------- touch floor
 *
 * Mobile handoff rule 2, for the two controls that come from OUTSIDE this theme's own component
 * set: WordPress's block button and YITH's compare link, measured at 44 and 45.8. They are styled
 * here rather than in the plugin so an update cannot revert them.
 */
@media (max-width: 1024px) {
	.wp-block-button__link,
	a.compare.button {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		min-block-size: var(--wp--custom--touch--target);
	}
}
