/**
 * Catalog shell — meta bar, header, page head, section heads, chip, footer.
 *
 * Marker classes: .nou-catalog-topbar  .nou-catalog-header  .nou-catalog-home
 *                 .nou-catalog-footer
 * Companion files: assets/css/catalog-home.css  (product grid + cards)
 *                  assets/js/catalog-nav.js     (Menu button, hover grace)
 *
 * Ported from design-lab/css/wf-c-base.css + wf-c-light.css, LIGHT MODE ONLY.
 * The lab file carried a dark palette plus a light override layer; here only
 * the resolved light values remain, and every colour/radius/easing now reads a
 * real theme.json token instead of the lab's `--nou-*` placeholders:
 *
 *     lab                     theme.json
 *     --nou-line          ->  --wp--custom--line--soft      (neutral 150)
 *     --nou-line-strong   ->  --wp--custom--line--strong    (neutral 300)
 *     --nou-accent        ->  --wp--custom--accent--strong   (= primary)
 *     --nou-accent-strong ->  --wp--custom--accent--stronger (= secondary)
 *     --nou-n-*           ->  --wp--custom--neutral--*
 *     --nou-radius-*      ->  --wp--custom--radius--*
 *     --nou-track-*       ->  --wp--custom--tracking--*
 *     --nou-ease*         ->  --wp--custom--easing--*
 *     --nou-font-mono     ->  --wp--preset--font-family--mono
 *
 * TEXT COLOUR FLOOR. Every label and meta line here sits at neutral 600 or
 * darker. Measured on #ffffff with the WCAG 2.1 formula: 400 = 2.04:1,
 * 500 = 3.30:1, 600 = 4.83:1. So 600 is the lightest step allowed to carry
 * text; 500 and below are for rules and borders only. Label hierarchy is
 * expressed with size, mono and uppercase, not with lightness — white leaves
 * no room for a second grey text step.
 *
 * TWO DELIBERATE EXCEPTIONS at neutral 400, both CSS-generated separators
 * where the real structure lives in the markup: the `/` of a path row and the
 * `·` between footer column items. WCAG 1.4.3 does not apply to those.
 *
 * WIDTH IS OWNED HERE, NOT BY BLOCK LAYOUT. `.nou-catalog-shell` is
 * max-width 1200px *including* its 40px gutters, so the content column is
 * 1120px. WordPress constrained layout would give 1200px of content plus 40px
 * of padding — 80px wider than the design that was measured at all seven
 * breakpoints. Rather than re-tune the design to WP's arithmetic, the shell
 * keeps the verified numbers and the wrapper groups use `layout: default`.
 */

/* ================================================================== *
 * SHELL + PAGE SURFACE
 * ================================================================== */

/*
 * style.css paints `.wp-site-blocks` with two radial tints and a vertical
 * gradient. The catalog design is measured flat white: `muted` and `accent`
 * both land on 4.83:1 against #ffffff, so any tinted backdrop pushes them
 * under AA. Flatten it. This file only loads on catalog pages, so the
 * gradient survives everywhere else.
 */
.wp-site-blocks {
	background: var(--wp--custom--surface--page);
}

.nou-catalog-shell {
	width: 100%;
	max-width: var(--wp--style--global--wide-size, 1200px);
	margin-inline: auto;
	padding-inline: var(--wp--custom--spacing--gap, 40px);
}

@media (max-width: 600px) {
	.nou-catalog-shell {
		padding-inline: 20px;
	}
}

/*
 * Flow layout gives every child after the first a block-gap margin. The
 * containers below are flex or grid rows owned by this file, where a stray top
 * margin on the second child pushes it out of the row instead of being
 * absorbed. Neutralised once here rather than per rule.
 *
 * EVERY SELECTOR IS PREFIXED WITH `:root`, and that is a fix, not a habit.
 *
 * An earlier version of this block noted that core's rule has "specificity 0".
 * That is no longer true and was the cause of a real bug. WordPress emits:
 *
 *     :root :where(.is-layout-flow) > * { margin-block-start: … }
 *
 * `:where()` adds nothing, but the leading `:root` scores (0,1,0) — exactly
 * what a bare `.nou-catalog-header__row > *` scores. A tie is settled by source
 * order, and the order of this file against that inline block is not constant:
 * it depends on which catalog stylesheets a template enqueues and what they
 * declare as dependencies.
 *
 * Measured, not assumed. On the single-product template core won the tie, so
 * every header child after the first took a 24px top margin: the wordmark
 * stayed put, the navigation and the account icons dropped below it, and the
 * header grew from 67px to 147px on markup that is byte-for-byte identical to
 * the category template's. `:root` here lifts these to (0,2,0) so the outcome
 * no longer depends on load order.
 */
:root .nou-catalog-shell > *,
:root .nou-catalog-home > *,
:root .nou-catalog-header > *,
:root .nou-catalog-header__row > *,
:root .nou-catalog-nav-wrap > *,
:root .nou-catalog-topbar > *,
:root .nou-catalog-topbar__row > *,
:root .nou-catalog-pagehead > *,
:root .nou-catalog-secthead > *,
:root .nou-catalog-footer > *,
:root .nou-catalog-footer__cols > *,
:root .nou-catalog-footer__cols > * > *,
:root .nou-catalog-footer__base > * {
	margin-block: 0;
}

/* ================================================================== *
 * META BAR — parts/topbar.html
 *
 * A sibling template part, not part of the header, so it scrolls away while
 * the navigation row below stays pinned. assets/css/sticky.css pins
 * `header.wp-block-template-part`, and a sticky element can never leave its
 * own containing block — as long as this bar lived inside the header part it
 * pinned too. See patterns/topbar-catalog.php.
 * ================================================================== */

.nou-catalog-topbar {
	border-bottom: 1px solid var(--wp--custom--line--soft);
	font-family: var(--wp--preset--font-family--mono);
	font-size: 11px;
	letter-spacing: 0.04em;
	color: var(--wp--custom--neutral--600);
}

.nou-catalog-topbar__row {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: 10px;
	padding-block: 9px;
}

.nou-catalog-topbar p {
	margin: 0;
	font-size: inherit;
	line-height: inherit;
	letter-spacing: inherit;
	color: inherit;
}

/* Status pip — the same accent dot the theme uses on `.nou-page-eyebrow`. */
.nou-catalog-topbar__scope::before {
	content: "";
	display: inline-block;
	width: 6px;
	height: 6px;
	margin-right: 8px;
	border-radius: 50%;
	background: var(--wp--custom--accent--strong);
	vertical-align: 1px;
}

.nou-catalog-topbar__links {
	display: flex;
	gap: 18px;
}

.nou-catalog-topbar a {
	color: inherit;
	text-decoration: none;
	transition: color 160ms var(--wp--custom--easing--base);
}

.nou-catalog-topbar a:hover {
	color: var(--wp--custom--neutral--900);
}

/* ================================================================== *
 * HEADER — the row that pins
 * ================================================================== */

/*
 * `position: relative` is load-bearing: the mobile menu panel is absolutely
 * positioned and has to span the full header width, so this element must be
 * the panel's containing block.
 */
.nou-catalog-header {
	position: relative;
	border-bottom: 1px solid var(--wp--custom--line--soft);
	background: color-mix(in srgb, var(--wp--custom--surface--page) 88%, transparent);
	backdrop-filter: blur(12px);
	-webkit-backdrop-filter: blur(12px);
}

.nou-catalog-header__row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--x-small, 20px);
	padding-block: 15px;
}

/* --- Wordmark ---------------------------------------------------- */

/*
 * The site title carries the wordmark. The trailing terminal caret is drawn
 * with `::after` rather than typed into the title, so it works for any site
 * name and cannot be lost when the title is edited in the site editor.
 * First of three places the caret motif appears — see also the page title and
 * the card name in catalog-home.css.
 */
/*
 * `:root` PREFIX IS LOAD-BEARING — it is not decoration, and removing it
 * breaks the header on some templates but not others.
 *
 * WordPress prints its global styles as `:root :where(.wp-block-site-title)
 * { font-size: var(--wp--preset--font-size--large) }`. `:where()` contributes
 * nothing to specificity, so that selector scores (0,1,0) — exactly the same as
 * a bare `.nou-catalog-wordmark`. A tie is resolved by source order, and the
 * order of the theme's stylesheets relative to that inline block is not
 * constant: it depends on which catalog CSS files a given template enqueues and
 * what they declare as dependencies.
 *
 * The symptom, measured rather than guessed: on the product template the
 * wordmark rendered at 24px and the menu at 18px, against 15px and 12px on the
 * category template, which pushed the header from 67px to 151px tall and
 * wrapped it onto three lines. Same markup, same CSS files, different order.
 *
 * `:root` lifts this to (0,2,0), so it wins on specificity and no longer cares
 * about order. The same applies to `.nou-catalog-nav` below.
 */
:root .nou-catalog-wordmark {
	margin: 0;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 15px;
	font-weight: var(--wp--custom--font-weight--medium);
	letter-spacing: 0.02em;
	line-height: var(--wp--custom--line-height--one);
}

.nou-catalog-wordmark a {
	color: var(--wp--custom--neutral--900);
	text-decoration: none;
}

.nou-catalog-wordmark a::after {
	content: "_";
	color: var(--wp--custom--accent--strong);
}

/* --- Header account + cart -------------------------------------- *
 *
 * WooCommerce inserts woocommerce/customer-account (icon_only) and
 * woocommerce/mini-cart right after core/navigation via Block Hooks, so both
 * land inside .nou-catalog-nav-wrap. The store sells products, so the header
 * needs them. These rules restyle the two blocks as quiet monochrome icon
 * buttons that sit with the wordmark and nav rather than showing WooCommerce's
 * defaults, and draw the cart count as the same accent the wordmark caret and
 * the CTA hover use.
 *
 * Written self-contained — width, reset and colour are all set here — so the
 * icons hold their shape before WooCommerce's own block CSS loads, and so the
 * design-lab wireframe (which ships no WooCommerce CSS) renders them the same.
 * ================================================================== */

.nou-catalog-header .wc-block-customer-account,
.nou-catalog-header .wc-block-mini-cart {
	margin: 0;
	display: flex;
	align-items: center;
}

.nou-catalog-header .wc-block-customer-account__link,
.nou-catalog-header .wc-block-mini-cart__button {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	padding: 0;
	border: 0;
	border-radius: var(--wp--custom--radius--xs);
	background: transparent;
	color: var(--wp--custom--neutral--600);
	cursor: pointer;
	transition: color 160ms var(--wp--custom--easing--base),
		background-color 160ms var(--wp--custom--easing--base);
}

.nou-catalog-header .wc-block-customer-account__link:hover,
.nou-catalog-header .wc-block-mini-cart__button:hover {
	color: var(--wp--custom--neutral--900);
	background: color-mix(in srgb, var(--wp--custom--neutral--900) 6%, transparent);
}

.nou-catalog-header .wc-block-customer-account__account-icon,
.nou-catalog-header .wc-block-mini-cart__icon {
	width: 20px;
	height: 20px;
	fill: currentColor;
}

/*
 * The cart icon and its count share one positioning context so the badge can
 * sit on the icon's top-right corner.
 */
.nou-catalog-header .wc-block-mini-cart__quantity-badge {
	position: relative;
	display: inline-flex;
}

/*
 * Count pill. Core keeps it hidden at zero items via the `hidden` attribute,
 * so nothing here forces it visible.
 */
.nou-catalog-header .wc-block-mini-cart__badge {
	position: absolute;
	top: -6px;
	right: -8px;
	min-width: 16px;
	height: 16px;
	padding: 0 4px;
	box-sizing: border-box;
	border-radius: 999px;
	background: var(--wp--custom--accent--strong);
	color: #fff;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 10px;
	font-weight: var(--wp--custom--font-weight--medium);
	line-height: 16px;
	text-align: center;
}

/* ================================================================== *
 * NAVIGATION — core/navigation with `overlayMenu: "never"`
 *
 * Platform-first: WordPress and Shopify sit at top level because that is the
 * first filter a buyer applies. Panel labels then shorten to "Themes" and
 * "Plugins" without repeating the platform. Templates has two children (HTML,
 * React) that fit on one line, so it stays a plain link.
 *
 * WHAT CORE PROVIDES AND WHAT THIS FILE ADDS.
 * Core already ships the submenu behaviour the design asks for: they open on
 * hover through CSS, and on the toggle button's `aria-expanded` through the
 * interactivity module — which is still loaded with the overlay off, because
 * the menu has submenus and shows submenu icons. Hidden submenus use
 * `visibility: hidden`, so assistive tech skips them, and the panel already
 * sits at `top: 100%`. So the menu stays editable in the admin and this theme
 * ships no code for opening submenus.
 *
 * The overlay is off because core's small-screen mode is a full-screen modal
 * with its own focus trap and an `html.has-modal-open` scroll lock, while the
 * design drops an inline panel under the header. With `overlayMenu: "never"`
 * core renders the bare `<ul class="wp-block-navigation__container">` and CSS
 * can make that the panel. The Menu button and the close-on-Escape /
 * click-outside behaviour it needs live in assets/js/catalog-nav.js.
 *
 * A NOTE ON THE SELECTORS BELOW. Several of them are longer than they look
 * like they need to be. That is specificity, not style: core's own rules go up
 * to five class selectors deep, and each comment names the rule being
 * outranked so the length is checkable rather than superstitious.
 * ================================================================== */

.nou-catalog-nav-wrap {
	display: flex;
	align-items: center;
	/* Fill the row so the account + cart can sit hard against the right edge. */
	flex: 1;
	/* Space the menu from the account + cart icons WooCommerce appends here. */
	gap: clamp(6px, 1vw, 14px);
}

/*
 * Push the account + cart to the right edge: the nav absorbs the slack between
 * itself and the icons, so the menu stays by the wordmark and the two icons
 * sit at the header's right. `> .nou-catalog-nav` matches the <nav> only — the
 * class is also on the inner <ul>, which must not take the margin.
 */
.nou-catalog-nav-wrap > .nou-catalog-nav {
	margin-right: auto;
}

/*
 * `:root` for the same reason as the wordmark above: core's
 * `:root :where(.wp-block-navigation) { font-size: … }` ties with a bare
 * `.nou-catalog-nav` at (0,1,0), and the winner then depends on stylesheet
 * order, which varies per template. Measured at 18px instead of 12px on the
 * product template before this was raised to (0,2,0).
 */
:root .nou-catalog-nav {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 12px;
	letter-spacing: 0.03em;
	color: var(--wp--custom--neutral--600);
}

/* Beats the per-block layout gap, `.wp-container-core-navigation-…` (0,1,0). */
.nou-catalog-nav .wp-block-navigation__container {
	gap: clamp(10px, 1.6vw, 20px);
}

.nou-catalog-nav a.wp-block-navigation-item__content,
.nou-catalog-nav .wp-block-navigation-submenu__toggle {
	padding: 6px 2px;
	font-family: inherit;
	font-size: inherit;
	letter-spacing: inherit;
	color: inherit;
	text-decoration: none;
	transition: color 160ms var(--wp--custom--easing--base);
}

.nou-catalog-nav a.wp-block-navigation-item__content:hover,
.nou-catalog-nav .wp-block-navigation-submenu__toggle:hover,
.nou-catalog-nav .wp-block-navigation-item:hover > a.wp-block-navigation-item__content {
	color: var(--wp--custom--neutral--900);
}

/* Current page: an accent underline. Colour is never the only signal. */
.nou-catalog-nav .wp-block-navigation-item.current-menu-item > a.wp-block-navigation-item__content {
	color: var(--wp--custom--neutral--900);
	box-shadow: inset 0 -1px 0 var(--wp--custom--accent--strong);
}

/*
 * MOUSE BRIDGE. The panel sits at `top: 100%`; the 12px visible gap comes from
 * the item's own padding, with an equal negative margin so the row height and
 * baseline alignment are untouched — flex centres the margin box, which is
 * unchanged. Put the gap in `top` instead and the cursor has to cross 12px
 * that belong to neither element, firing pointerleave before it arrives.
 */
.nou-catalog-nav .wp-block-navigation-item.has-child {
	padding-bottom: 12px;
	margin-bottom: -12px;
}

/* --- Submenu arrow ---------------------------------------------- */

/*
 * Core renders a chevron SVG inside the toggle button and sizes the button at
 * 0.6em square. Swap both for a filled triangle drawn with borders: it matches
 * the design and needs no icon asset. Three classes to outrank core's
 * `.wp-block-navigation .wp-block-navigation__submenu-icon` (0,2,0).
 */
.nou-catalog-nav .wp-block-navigation-item .wp-block-navigation__submenu-icon {
	width: auto;
	height: auto;
	margin-left: 0.25em;
	line-height: 0;
}

.nou-catalog-nav .wp-block-navigation-item .wp-block-navigation__submenu-icon svg {
	display: none;
}

.nou-catalog-nav .wp-block-navigation__submenu-icon::after {
	content: "";
	display: block;
	width: 0;
	height: 0;
	border: 4px solid transparent;
	border-top-color: currentColor;
	transform: translateY(2px);
	transition: transform 200ms var(--wp--custom--easing--base);
}

/*
 * Two selectors because core moves the icon depending on `openSubmenusOnClick`
 * (wp-includes/blocks/navigation-submenu.php):
 *   false (what this header uses) — the toggle BUTTON carries both
 *     `wp-block-navigation__submenu-icon` and `wp-block-navigation-submenu__toggle`,
 *     so the caret is the button's own ::after.
 *   true — the icon is a nested <span class="wp-block-navigation__submenu-icon">.
 * Covering both keeps the arrow working if that attribute is ever flipped in
 * the site editor.
 */
.nou-catalog-nav .wp-block-navigation-submenu__toggle[aria-expanded="true"]::after,
.nou-catalog-nav .wp-block-navigation-submenu__toggle[aria-expanded="true"] .wp-block-navigation__submenu-icon::after {
	transform: translateY(-2px) rotate(180deg);
}

/* --- Submenu panel --------------------------------------------- */

/*
 * One narrow column, no group headers: this is a dropdown, not a mega menu.
 * A mega menu earns its width at five or more items per group; here it is two.
 *
 * `left: -14px` lines the panel's inner padding up with the label above it,
 * rather than lining up the panel's border.
 *
 * FOUR CLASSES, DELIBERATELY. This has to outrank two (0,3,0) rules that both
 * target the same element:
 *   core   `.wp-block-navigation .has-child .wp-block-navigation__submenu-container`
 *          — sets `background-color: inherit` (which would inherit the
 *          translucent blurred header) and `left: -1px`.
 *   theme  `.wp-block-navigation:not(.has-background) .wp-block-navigation__submenu-container`
 *          in style.css — a dark `contrast` fill with white text, written for
 *          the previous header.
 * Nothing here touches width, height, visibility or overflow: showing and
 * hiding stays entirely core's job.
 */
.nou-catalog-nav .wp-block-navigation-item.has-child > .wp-block-navigation__submenu-container {
	left: -14px;
	min-width: 186px;
	gap: 2px;
	padding: 10px;
	border: 1px solid var(--wp--custom--line--strong);
	border-radius: var(--wp--custom--radius--md);
	background-color: var(--wp--custom--surface--soft);
	color: var(--wp--custom--neutral--700);
	box-shadow: 0 16px 36px rgb(0 0 0 / 0.12);
}

/*
 * FIVE CLASSES PLUS AN ELEMENT. Core sets the padding of these links at
 * `.wp-block-navigation .has-child .wp-block-navigation__submenu-container > .wp-block-navigation-item > .wp-block-navigation-item__content`
 * — (0,5,0) — so anything shorter loses and the links keep core's 0.5em 1em.
 */
.nou-catalog-nav .wp-block-navigation-item.has-child > .wp-block-navigation__submenu-container > .wp-block-navigation-item > a.wp-block-navigation-item__content {
	display: block;
	width: 100%;
	padding: 9px 12px;
	border-radius: var(--wp--custom--radius--xs);
	font-family: var(--wp--preset--font-family--primary);
	font-size: 14px;
	letter-spacing: 0;
	color: var(--wp--custom--neutral--700);
	white-space: nowrap;
}

.nou-catalog-nav .wp-block-navigation-item.has-child > .wp-block-navigation__submenu-container > .wp-block-navigation-item > a.wp-block-navigation-item__content:hover {
	background: color-mix(in srgb, var(--wp--custom--accent--strong) 14%, transparent);
	color: var(--wp--custom--neutral--900);
}

.nou-catalog-nav .wp-block-navigation__submenu-container .wp-block-navigation-item {
	width: 100%;
}

/* --- Menu button ------------------------------------------------- */

/*
 * Not core's overlay toggle — that comes with the modal. This is a plain
 * button from a core/html block, because `aria-expanded` and `aria-controls`
 * are not attributes any core block exposes.
 */
.nou-catalog-burger {
	display: none;
	align-items: center;
	gap: 8px;
	padding: 7px 12px;
	border: 1px solid var(--wp--custom--line--strong);
	border-radius: var(--wp--custom--radius--xs);
	background: none;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 12px;
	letter-spacing: 0.03em;
	color: var(--wp--custom--neutral--900);
	cursor: pointer;
}

.nou-catalog-burger::after {
	content: "";
	width: 0;
	height: 0;
	border: 4px solid transparent;
	border-top-color: currentColor;
	transform: translateY(2px);
	transition: transform 200ms var(--wp--custom--easing--base);
}

.nou-catalog-burger[aria-expanded="true"]::after {
	transform: translateY(-2px) rotate(180deg);
}

/* ------------------------------------------------------------------ *
 * MOBILE PANEL — inline, under the header
 *
 * Six mono items plus a wordmark and a CTA stop fitting below about 860px,
 * which is where the design switches. Nothing here fights core, because with
 * the overlay off core ships no small-screen layout of its own.
 * ------------------------------------------------------------------ */

@media (max-width: 860px) {
	.nou-catalog-burger {
		display: inline-flex;
	}

	/*
	 * Take <nav> out of the positioning chain. Core sets
	 * `.wp-block-navigation { position: relative }`, and the nav element is
	 * only as wide as its items, so a panel at `left: 0; right: 0` would span
	 * the wrong box. With this static, the panel's containing block becomes
	 * `.nou-catalog-header` and it spans the full header width — the same
	 * anchoring the wireframe used.
	 */
	.nou-catalog-nav {
		position: static;
	}

	.nou-catalog-nav .wp-block-navigation__container {
		display: none;
		position: absolute;
		z-index: 55;
		top: calc(100% + 1px);
		left: 0;
		right: 0;
		flex-direction: column;
		align-items: stretch;
		gap: 2px;
		padding: 14px clamp(20px, 4vw, 40px) 22px;
		border-bottom: 1px solid var(--wp--custom--line--soft);
		background: var(--wp--custom--surface--page);
		box-shadow: 0 20px 34px rgb(0 0 0 / 0.12);
	}

	.nou-catalog-burger[aria-expanded="true"] + .nou-catalog-nav .wp-block-navigation__container {
		display: flex;
	}

	/* The 12px mouse bridge is dead weight once the panel flows inline. */
	.nou-catalog-nav .wp-block-navigation-item.has-child {
		padding-bottom: 0;
		margin-bottom: 0;
	}

	/* The submenu wraps onto its own line under the label and its arrow. */
	.nou-catalog-nav .wp-block-navigation-item {
		flex-wrap: wrap;
		width: 100%;
	}

	.nou-catalog-nav a.wp-block-navigation-item__content {
		flex: 1 1 auto;
		padding: 11px 0;
		border-bottom: 1px solid var(--wp--custom--line--soft);
	}

	.nou-catalog-nav .wp-block-navigation-submenu__toggle {
		padding: 11px 0;
		border-bottom: 1px solid var(--wp--custom--line--soft);
	}

	/*
	 * Flow the panel inline instead of floating it. Four classes to outrank
	 * core's `.wp-block-navigation .has-child .wp-block-navigation__submenu-container`
	 * (0,3,0), which sets `position: absolute`. Still no width or visibility
	 * here — closed until opened is core's mechanism, and the design wants the
	 * same behaviour on both screen sizes.
	 */
	.nou-catalog-nav .wp-block-navigation-item.has-child > .wp-block-navigation__submenu-container {
		position: static;
		left: auto;
		margin-bottom: 6px;
		padding: 8px 10px;
		border-radius: var(--wp--custom--radius--xs);
		box-shadow: none;
	}

	.nou-catalog-nav .wp-block-navigation-item.has-child > .wp-block-navigation__submenu-container > .wp-block-navigation-item > a.wp-block-navigation-item__content {
		border-bottom: 0;
		white-space: normal;
	}
}

/* ================================================================== *
 * PAGE HEAD
 *
 * VERTICAL RHYTHM — three gaps that widen with the rank of the boundary:
 *     page head -> first section : 88px
 *     section -> section         : 84px
 *     last section -> footer     : 84 + 44 = 128px
 * The page head carries no rule of its own. Add one and the page reads as four
 * horizontal lines, at which point a line no longer means "a section starts".
 * ================================================================== */

.nou-catalog-pagehead {
	padding-block: clamp(34px, 5vw, 72px) clamp(40px, 6vw, 88px);
}

.nou-catalog-eyebrow {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 0 0 clamp(14px, 1.8vw, 22px);
	font-family: var(--wp--preset--font-family--mono);
	font-size: 11px;
	letter-spacing: var(--wp--custom--tracking--wide);
	text-transform: uppercase;
	color: var(--wp--custom--neutral--600);
}

.nou-catalog-eyebrow::before {
	content: "";
	flex: none;
	width: 22px;
	height: 1px;
	background: var(--wp--custom--accent--strong);
}

/*
 * Two lines of real copy, not a slogan. "Themes" alone stopped being true once
 * the catalogue carried plugins, apps and templates.
 *
 * Monospace is airy by nature, so the tracking has to go negative before the
 * block reads as solid type. Sized here rather than through
 * styles.elements.h1 (36px) because the h1 preset is shared with 67 patterns.
 */
.nou-catalog-title {
	margin: 0;
	font-family: var(--wp--preset--font-family--mono);
	font-size: clamp(30px, 4.8vw, 58px);
	font-weight: var(--wp--custom--font-weight--medium);
	letter-spacing: -0.03em;
	line-height: 1.12;
	color: var(--wp--custom--neutral--900);
	text-wrap: balance;
}

/*
 * Terminal caret, drawn with `::after` so the heading block round-trips
 * through the editor without an empty <span> to lose.
 *
 * Sized in em so it tracks the clamp above: 0.1em is roughly 6px at 58px,
 * about the weight of a real caret. An earlier pass used 0.44em, which drew a
 * 25px slab that read as a rendering fault. The hollow box's baseline is its
 * bottom edge, so `vertical-align: baseline` seats the caret's foot on the
 * text baseline.
 *
 * steps(1, end) makes it snap rather than fade. Under
 * prefers-reduced-motion the caret simply stands still, which still reads
 * correctly — see the reduced-motion block at the end of this file.
 */
.nou-catalog-title::after {
	content: "";
	display: inline-block;
	width: 0.1em;
	height: 0.72em;
	margin-left: 0.08em;
	background: var(--wp--custom--accent--strong);
	vertical-align: baseline;
	animation: nou-catalog-caret 1.1s steps(1, end) infinite;
}

@keyframes nou-catalog-caret {
	0%,
	49% {
		opacity: 1;
	}

	50%,
	100% {
		opacity: 0;
	}
}

/* ================================================================== *
 * SECTION HEAD
 * ================================================================== */

.nou-catalog-section {
	padding-bottom: clamp(44px, 6vw, 84px);
}

:root .nou-catalog-secthead {
	position: relative;
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 6px 14px;
	margin-bottom: clamp(32px, 3.6vw, 44px);
	padding-bottom: 16px;
	border-bottom: 1px solid var(--wp--custom--line--soft);
}

/* Accent stub at the head of the rule — the section's opening mark. */
.nou-catalog-secthead::after {
	content: "";
	position: absolute;
	bottom: -1px;
	left: 0;
	width: 56px;
	height: 1px;
	background: var(--wp--custom--accent--strong);
}

.nou-catalog-secthead__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--mono);
	font-size: clamp(21px, 2.4vw, 27px);
	font-weight: var(--wp--custom--font-weight--medium);
	letter-spacing: -0.02em;
	line-height: 1.1;
	color: var(--wp--custom--neutral--900);
}

.nou-catalog-secthead__meta {
	margin: 0;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 11px;
	letter-spacing: var(--wp--custom--tracking--wide);
	text-transform: uppercase;
	color: var(--wp--custom--neutral--600);
}

.nou-catalog-secthead__all {
	margin: 0 0 0 auto;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 12px;
	white-space: nowrap;
}

/*
 * __all là <p> bọc ngoài <a> — cả hai chỗ trong theme đều dùng pattern này.
 * <p> chiếm phần tử flex, <a> bên trong mới là thứ người dùng thấy và bấm.
 * Transition, gap và mũi tên đặt trên <a> để khớp hành vi của wireframe.
 */
.nou-catalog-secthead__all a {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	color: var(--wp--custom--neutral--600);
	text-decoration: none;
	transition: color 180ms var(--wp--custom--easing--base);
}

.nou-catalog-secthead__all a::after {
	content: "\2192";
	transition: transform 260ms var(--wp--custom--easing--out);
}

.nou-catalog-secthead__all a:hover {
	color: var(--wp--custom--accent--strong);
}

.nou-catalog-secthead__all a:hover::after {
	transform: translateX(4px);
}

/* ================================================================== *
 * CHIP — hairline outline, no solid fill, so a grid of them stays quiet.
 * ================================================================== */

.nou-catalog-chip {
	display: inline-block;
	padding: 3px 9px;
	border: 1px solid var(--wp--custom--line--strong);
	border-radius: var(--wp--custom--radius--pill);
	font-family: var(--wp--preset--font-family--mono);
	font-size: 10px;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--wp--custom--neutral--700);
	white-space: nowrap;
}

/* ================================================================== *
 * FOOTER — mono, columns divided by hairlines.
 * ================================================================== */

/* Plus the 84px bottom padding of the last section = 128px. See the rhythm
 * note under PAGE HEAD. */
.nou-catalog-footer {
	margin-top: clamp(26px, 3.4vw, 44px);
	border-top: 1px solid var(--wp--custom--line--soft);
}

/*
 * Four link columns plus the brand blurb, declared as `repeat(4)` rather than
 * auto-fit. Mixing a fixed track with auto-fit makes auto-fit resolve to a
 * single track and the whole footer collapses into one column.
 */
.nou-catalog-footer__cols {
	display: grid;
	grid-template-columns: 1.5fr repeat(4, minmax(104px, 1fr));
	gap: clamp(24px, 2.6vw, 36px);
	padding-block: clamp(32px, 4.5vw, 60px);
}

.nou-catalog-footer__cols > * + * {
	padding-left: clamp(16px, 2.4vw, 34px);
	border-left: 1px solid var(--wp--custom--line--soft);
}

.nou-catalog-footer__blurb {
	max-width: 36ch;
	font-size: 14px;
	line-height: var(--wp--custom--line-height--medium);
	color: var(--wp--custom--neutral--600);
}

.nou-catalog-footer__blurb p {
	margin: 0;
	font-size: inherit;
	line-height: inherit;
	color: inherit;
}

.nou-catalog-footer__blurb .nou-catalog-wordmark {
	display: block;
	margin-bottom: 10px;
}

/*
 * These are <h2> elements, so theme.json's styles.elements.heading applies a
 * line-height of 1.2 — which at 10px is a 12px line box against the 16px the
 * design was measured with, shaving 4px off the column. Stated explicitly
 * rather than left to inherit, so the number is visible where it matters.
 */
.nou-catalog-footer__title {
	margin: 0 0 13px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 10px;
	font-weight: var(--wp--custom--font-weight--regular);
	letter-spacing: var(--wp--custom--tracking--wide);
	line-height: var(--wp--custom--line-height--body);
	text-transform: uppercase;
	color: var(--wp--custom--neutral--600);
}

/*
 * A list of links is marked up as a list. `ul.` rather than `.` so this beats
 * theme.json's `core/list` padding-left of 40px whatever the stylesheet order,
 * and the disc is dropped here as well as via `is-style-no-disc` so the column
 * still reads correctly if that block style is ever removed.
 */
ul.nou-catalog-footer__links {
	display: grid;
	gap: 9px;
	margin: 0;
	padding-left: 0;
	list-style: none;
	font-size: 14px;
	color: var(--wp--custom--neutral--700);
}

.nou-catalog-footer__links li {
	margin: 0;
}

.nou-catalog-footer a {
	color: inherit;
	text-decoration: none;
	transition: color 160ms var(--wp--custom--easing--base);
}

.nou-catalog-footer__links a:hover {
	color: var(--wp--custom--accent--stronger);
}

.nou-catalog-footer__base {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: 10px;
	padding-block: 16px;
	border-top: 1px solid var(--wp--custom--line--soft);
	font-family: var(--wp--preset--font-family--mono);
	font-size: 11px;
	color: var(--wp--custom--neutral--600);
}

.nou-catalog-footer__base p {
	margin: 0;
	font-size: inherit;
	color: inherit;
}

@media (max-width: 860px) {
	.nou-catalog-footer__cols {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	/* At two columns the vertical hairlines land off-grid, so drop them. */
	.nou-catalog-footer__cols > * + * {
		padding-left: 0;
		border-left: 0;
	}
}

/* ================================================================== *
 * SEARCH RESULTS
 *
 * Products reuse the card grid above. Posts do not sell, so on a results
 * page they are a plain title + meta list rather than a picture card — the
 * eye should land on the products. The list sits under a .nou-catalog-secthead
 * like every other group.
 * ================================================================== */

.nou-catalog-searchlist {
	margin: 0 0 clamp(34px, 4vw, 52px);
	padding: 0;
	list-style: none;
}

.nou-catalog-searchrow {
	padding: 15px 0;
	border-bottom: 1px solid var(--wp--custom--line--soft);
}

.nou-catalog-searchrow__title {
	display: block;
	color: var(--wp--custom--neutral--900);
	font-size: clamp(16px, 1.6vw, 19px);
	line-height: 1.35;
	text-decoration: none;
	transition: color 180ms var(--wp--custom--easing--base);
}

.nou-catalog-searchrow__title:hover {
	color: var(--wp--custom--accent--strong);
}

.nou-catalog-searchrow__meta {
	display: block;
	margin-top: 6px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 11px;
	letter-spacing: var(--wp--custom--tracking--wide);
	text-transform: uppercase;
	color: var(--wp--custom--neutral--600);
}

/*
 * Empty-state exit link. Lives here rather than in an archive-only sheet so
 * both the product archive and the search results page can end a dead end with
 * a way out. A no-results page with no link back is how a filter traps somebody.
 */
.nou-catalog-empty__out {
	margin: 0;
	padding-bottom: clamp(28px, 4vw, 56px);
	text-align: center;
}

/* ================================================================== *
 * REDUCED MOTION
 * ================================================================== */

@media (prefers-reduced-motion: reduce) {
	.nou-catalog-searchrow__title {
		transition: none;
	}

	.nou-catalog-title::after {
		animation: none;
	}

	.nou-catalog-footer a,
	.nou-catalog-topbar a,
	.nou-catalog-secthead__all a,
	.nou-catalog-secthead__all a::after,
	.nou-catalog-nav a.wp-block-navigation-item__content,
	.nou-catalog-nav .wp-block-navigation__submenu-icon::after {
		transition: none;
	}
}
