/*
 * Nomon Theme — base stylesheet. Tailwind (compiled by Blockstudio) owns reset and
 * utilities; this file owns only what utilities can't express: typography defaults,
 * accessibility shells, the WCAG 2.4.4 link decorators, and the editor-only rules
 * that flatten InnerBlocks wrappers and restyle the post title.
 */

/* Layer order is fixed by the first `@layer` the browser sees, so declaring it
 * here wins the load-order race against Blockstudio's inline style. Only correct
 * while Blockstudio emits layered utilities (7.3.3+) — smoke-test in docs/styling.md. */
@layer theme, base, components, utilities;

/* Blockstudio's TailwindPHP compile omits the `@property` registrations upstream
 * Tailwind v4 ships for these. Without them a single-axis `translate-x-*` leaves the
 * other axis empty, so the whole `translate` declaration is invalid and the browser
 * drops it silently. `scale-*` / `rotate-*` set every axis and are unaffected. */
@property --tw-translate-x { syntax: "*"; inherits: false; initial-value: 0; }
@property --tw-translate-y { syntax: "*"; inherits: false; initial-value: 0; }
@property --tw-translate-z { syntax: "*"; inherits: false; initial-value: 0; }

/* Typography defaults at (0,0,2): beats Tailwind preflight's (0,0,1), stays under
 * any utility (0,1,0). This file also loads in the editor iframe via
 * add_editor_style(), where WP rewrites `body` to `.editor-styles-wrapper`. Lists
 * are scoped to `.wp-block-list` because preflight zeroes every list globally. */
body {
	font-size: var(--wp--preset--font-size--regular);
	line-height: 1.618;
}

@layer base {
body p { margin-block: 1.5rem; }
body figure { margin-block: 3rem; }
}

/* `size-full` is both WP's full-size figure class and a Tailwind utility
 * (width/height 100%), so the figure stretched to its parent's height and pushed
 * later siblings out of the column. The only current name collision. */
.wp-block-image.size-full {
	height: auto;
}

/* In `@layer base` so per-instance utilities win: Blockstudio compiles Tailwind into
 * layers (`utilities` above `base`), and an unlayered default here beat every utility
 * regardless of specificity — block headings ignored their own size/margin classes. */
@layer base {
body :is(h1, h2, h3, h4, h5, h6) { font-weight: 600; }

/* Tighter than a mixed-case ramp because headings are uppercase Barlow Condensed: caps carry no descenders, so ink per line is 0.700em against Inter's 0.936em. Floored at 1.05 — uppercase Ä/Ö reach 0.916em and collide below ~1.0. */
body h1 { font-size: var(--wp--preset--font-size--heading-1); line-height: 1.05; margin-block: 3rem 1.5rem; }
body h2 { font-size: var(--wp--preset--font-size--heading-2); line-height: 1.05; margin-block: 3rem 1.5rem; }
body h3 { font-size: var(--wp--preset--font-size--heading-3); line-height: 1.1;  margin-block: 2rem 1.5rem; }
body h4 { font-size: var(--wp--preset--font-size--heading-4); line-height: 1.15; margin-block: 2rem 1.5rem; }
body h5 { font-size: var(--wp--preset--font-size--heading-5); line-height: 1.2;  margin-block: 1.5rem 1.5rem; }
body h6 { font-size: var(--wp--preset--font-size--heading-6); line-height: 1.25; margin-block: 1.5rem 1.5rem; }

/* Stacked headings: any heading directly following another collapses its top margin. */
body :is(h1, h2, h3, h4, h5, h6) + :is(h1, h2, h3, h4, h5, h6) { margin-top: 0; }
}

/* core/list block: restore bullets/numbers and indent that Tailwind preflight zeroes. */
.wp-block-list { margin-block: 1.5rem; padding-inline-start: 1.5em; }
.wp-block-list:where(ul) { list-style: disc; }
.wp-block-list:where(ol) { list-style: decimal; }
.wp-block-list :where(li > *) { margin-block: 0.5rem; }
.wp-block-list :where(li > :first-child) { margin-top: 0; }
.wp-block-list :where(li > :last-child)  { margin-bottom: 0; }

/* First/last reset: heading at top of a section, paragraph at end, don't push the container. */
@layer base {
body :is(h1, h2, h3, h4, h5, h6):first-child { margin-top: 0; }
body p:last-child { margin-bottom: 0; }
}

/* Cap the reading measure while media fills the block width. Descendant, not `>`, so
 * prose in a child group is capped too. */
.wp-block-group :is(p, h1, h2, h3, h4, h5, h6, ul, ol),
.site-content > :is(p, h1, h2, h3, h4, h5, h6, ul, ol) {
	max-width: 72ch;
	/* Position prose at the contentSize start edge whether the parent is constrained or
		 * alignfull, by offsetting half the parent's excess. `!important` beats WP's emitted
		 * `margin-inline: auto !important`; the second selector catches prose left as a direct
		 * child of `<main>` when an unregistered block no longer wraps it. */
	margin-inline-start: max(
		0px,
		calc((100% - var(--wp--style--global--content-size)) / 2)
	) !important;
}

/* Auto-bleed for bg-color Groups, mirroring the native
 * `.has-global-padding > .alignfull` mechanism so editors get bleeding sections
 * without the (disabled) align toolbar. Scoped to direct children of
 * `.has-global-padding`; `!important` matches WP's own centring rule. */
.has-global-padding > .wp-block-group.has-background {
	max-width: none;
	margin-left: calc(var(--wp--style--root--padding-left) * -1) !important;
	margin-right: calc(var(--wp--style--root--padding-right) * -1) !important;
	padding-left: var(--wp--style--root--padding-left);
	padding-right: var(--wp--style--root--padding-right);
}

/* Spacing controls are disabled on `core/group` in theme.json, so colored sections
 * get their breathing room here rather than butting text against the edges. */
.wp-block-group.has-background {
	padding-block: var(--section-space);
}

/* Cascades to all text: our base styles set no colour and preflight resets links to
 * `inherit`. Add a sibling rule per dark swatch as the palette grows. */
.wp-block-group.has-accent-dark-background-color,
.wp-block-group.has-foreground-background-color {
	color: var(--wp--preset--color--background);
}

/* One gap between root-level sections via an owl, so the first never takes a top margin;
 * `--section-space` drives this and the internal padding of bg-color sections. Composites
 * match on `nomon-<name>`, NOT `wp-block-nomon-*` (blocks without `useBlockProps` never
 * emit it). Scoped to `.has-global-padding` children, so composites must not bake their
 * own vertical padding. */
:root {
	--section-space: clamp(2rem, 5vw, 3.125rem);

	/* Accent hover tint. No `theme.json` preset — it is a state, not a palette
	   entry, so it would only clutter the colour picker. `.nomon-btn`,
	   `.nav-toggle::before` and `wsform.css` still carry it as a literal; they
	   should adopt this. */
	--accent-hover: #ffdf4d;

	/* Canonical slant for every angled shape. Negative leans the top edge right.
	 * One-sided variants can't use skewX — they need clip-path with the offset as
	 * height * tan(), read from this token, never a literal.
	 * Deliberately shallower than live's ~15.3deg; being angular, the gap shows by
	 * height — ~2px on a button, ~29px down the hero (PROJECT.md, deviations). */
	--skew-angle: -12deg;
}

.has-global-padding > :is(.wp-block-group, [class*="nomon-"]) + :is(.wp-block-group, [class*="nomon-"]) {
	margin-top: var(--section-space);
}

/* Content-region edges, same token as the inter-section gap. `page.php` puts
 * `has-global-padding` on `<main>`; `front-page.php` wraps only the editable content.
 * `:not([class*="bg-"])` exempts full-bleed bands that own their vertical padding —
 * without it this (0,2,0) clobbers their `py-*` utility (0,1,0). */
.site-content.has-global-padding,
.site-content > .has-global-padding:not([class*="bg-"]) {
	padding-block: var(--section-space);
}

@layer base {
	html {
		scroll-behavior: smooth;
		scroll-padding-top: var(--scroll-offset, 2rem);
	}

	body {
		-webkit-font-smoothing: antialiased;
		-moz-osx-font-smoothing: grayscale;
	}

	/* Gutenberg can't cleanly hide the bold/italic buttons for `core/heading`, so accept
		 * the editor freedom and cancel the effect — heading typography is theme-controlled. */
	:where(h1, h2, h3, h4, h5, h6) :is(strong, b, em, i) {
		font-weight: inherit;
		font-style: inherit;
	}

	/* Core blocks have no theme-side knob to hide the alignment toolbar, so accept the UI
		 * and cancel the effect. The editor iframe loads this file, so preview matches. */
	:is(p, h1, h2, h3, h4, h5, h6):is(
		.has-text-align-left,
		.has-text-align-center,
		.has-text-align-right
	) {
		text-align: inherit;
	}

	.screen-reader-text {
		border: 0;
		clip-path: inset(50%);
		height: 1px;
		margin: -1px;
		overflow: hidden;
		padding: 0;
		position: absolute;
		width: 1px;
		word-wrap: normal !important;
	}

	.skip-link:focus {
		clip-path: none;
		height: auto;
		margin: 0;
		overflow: auto;
		padding: 1rem;
		position: absolute;
		inset-block-start: 0;
		inset-inline-start: 0;
		width: auto;
		z-index: 100000;
		background: #000;
		color: #fff;
		text-decoration: underline;
	}

	/* External-link indicators (assets/js/main.js, WCAG 2.4.4). The screen-reader text is
			 * what counts for compliance — per-site CSS may hide the icon, never the SR text. */
	a.is-external-link::after,
	a.is-new-window::after {
		content: " ↗";
		display: inline-block;
		font-size: 0.85em;
		vertical-align: super;
		line-height: 1;
	}
	a.is-new-window::after {
		content: " ⧉";
	}
	a.is-external-link.is-new-window::after {
		content: " ⧉";
	}

	/* Buttons state their action in the label and read as controls, so the glyph adds
			 * nothing and collides with the skewed fill. Two classes deep to outrank the
			 * `.is-external-link.is-new-window` pair above. SR text is untouched. */
	a.nomon-btn.is-external-link::after,
	a.nomon-btn.is-new-window::after {
		content: none;
	}

	/* Drop the visible glyph in the footer and Nomon Helper's credit bar; the injected
			 * `.screen-reader-text` stays, so 2.4.4 still announces. Wins within @layer base. */
	:is(.site-footer, .nomon_footer) a.is-external-link::after,
	:is(.site-footer, .nomon_footer) a.is-new-window::after,
	:is(.site-footer, .nomon_footer) a.is-external-link.is-new-window::after {
		content: none;
	}
}

/* The Nav_Walker owns the <a>, so the footer hover state lives here rather than as a
   utility (inline-text footer links carry Tailwind's `hover:underline`). */
.site-footer .footer-menu a:hover {
	text-decoration: underline;
}

/* Bridges the pre-init gap so `[data-swiper]` containers don't flash as a vertical
 * stack before the lazy vendor CSS lands. Hidden via `visibility` until Swiper adds
 * `.swiper-initialized`, so layout space is reserved and the reveal doesn't shift.
 * Vendor CSS styles only the chrome; JS owns slide geometry via inline transforms. */
.swiper { overflow: hidden; }
.swiper:not(.swiper-initialized) { visibility: hidden; }
.swiper-wrapper { display: flex; }
.swiper-slide { flex-shrink: 0; width: 100%; }

/* Hero — a slider of promo panels; the panel itself is the shared `.nomon-promo`, so
   only the track, height and pagination belong here. */
.hero-slider__swiper {
	position: relative;
}
/* Unlayered and 0,2,0 so it beats swiper-bundle's unlayered
   `.swiper-slide { height: 100% }` — a Tailwind utility (layered) would lose. */
.hero-slider .swiper-slide {
	height: auto;
}
/* Fill the track: slides differ in copy length, and without this the shorter
   ones stop short of the wrapper and the pagination floats off the panel. */
.hero-slider .nomon-promo {
	--promo-min-h: 518px;
	height: 100%;
}

/* Skewed yellow markers, bottom-left inside the ink panel, as on the live site. */
.hero-slider .hero-slider__dots {
	position: absolute;
	z-index: 2;
	bottom: 25px;
	left: 45px;
	display: flex;
	gap: 10px;
}
.hero-slider .hero-slider__dots .swiper-pagination-bullet {
	width: 20px;
	height: 15px;
	margin: 0;
	border-radius: 0;
	background: var(--wp--preset--color--accent);
	/* Offset tracks height * tan(angle); percentages would re-angle with the box. */
	--bullet-slant: calc(15px * tan(var(--skew-angle)) * -1);
	clip-path: polygon(var(--bullet-slant) 0, 100% 0, calc(100% - var(--bullet-slant)) 100%, 0 100%);
	opacity: 0.25;
	transition: opacity 0.2s;
}
.hero-slider .hero-slider__dots .swiper-pagination-bullet-active {
	opacity: 1;
}

/* ── Icon button ──────────────────────────────────────────────────────────
   Reusable square control. Vary per consumer by overriding the --icon-button-*
   vars in a scoped rule — e.g. `.foo .icon-button { --icon-button-bg: #000; }`. */
.icon-button {
	--icon-button-bg: #fff;
	--icon-button-fg: var(--wp--preset--color--accent);
	--icon-button-bg-hover: var(--wp--preset--color--surface, #f1f3f8);
	display: grid;
	place-items: center;
	width: 3.4375rem;  /* 55px */
	height: 3.375rem;  /* 54px */
	background: var(--icon-button-bg);
	color: var(--icon-button-fg);
	cursor: pointer;
	transition: background-color 0.2s;
}
.icon-button:hover {
	background: var(--icon-button-bg-hover);
}
.icon-button:disabled,
.icon-button.swiper-button-disabled {
	opacity: 0.45;
	cursor: default;
}

/* Editor-only: Gutenberg wraps InnerBlocks children in divs that break flex/grid on the
 * parent, so `display: contents` makes them transparent. Outside `@layer base` so
 * unlayered editor styles can't outrank it, and descendant rather than `>` because
 * `useBlockProps` placement shifts the DOM by a level. */
[data-type^="nomon/"] .block-editor-inner-blocks,
[data-type^="nomon/"] .block-editor-block-list__layout {
	display: contents;
}

/* Editor-only: the title renders as a sibling of the content blocks and would otherwise
 * read as the body's first H1, so it gets chrome and a label. Scoped through
 * `.edit-post-visual-editor__post-title-wrapper` to outweigh the auto-scoped
 * `.editor-styles-wrapper h1` (0,1,1). Inert on the frontend. */
/* Zero the top padding WP core's editor styles put on the iframe body, so the title
 * wrapper sits flush. Inert on the frontend. */
body {
	padding-top: 0;
}

.edit-post-visual-editor__post-title-wrapper {
	background-color: #f0f0f0;
	color: #1e1e1e;
	margin-block-start: 0 !important;
	margin-block-end: 3rem;
	padding-inline: var(--wp--style--root--padding-left, clamp(1rem, 5vw, 5rem));
}

.edit-post-visual-editor__post-title-wrapper .editor-post-title {
	color: inherit;
	margin: 0 auto;
	max-width: var(--wp--style--global--content-size, 1440px);
	padding-block: 3rem;
}

.edit-post-visual-editor__post-title-wrapper .editor-post-title::before {
	content: "Sivun otsikko";
	display: block;
	color: #666;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	margin-block-end: 0.75rem;
}

.edit-post-visual-editor__post-title-wrapper .editor-post-title [data-rich-text-placeholder]::after {
	color: #666;
	opacity: 1;
}

/* =========================================================================
 * Navigation — adapted from air-light: same Nav_Walker, so class names, ARIA wiring
 * and the hover-intent model carry over; its tokens are remapped to our palette, so a
 * per-site retheme is just the :root block. Markup contract in header.php +
 * inc/includes/nav-walker.php; runtime behaviour in assets/js/navigation.js, which
 * reads --breakpoint-nav to pick mobile drill-down vs desktop bar.
 * ========================================================================= */

:root {
	/* JS reads this via getComputedStyle for its matchMedia decisions, so it must stay
		 * numeric — no `var()` lookups inside. */
	--breakpoint-nav: 1029px;

	/* The toggle sits on the header, not the drawer, so the active X needs the same contrast
			 * as the closed bars. Full-overlay forks should switch --hamburger-color-active. */
	--hamburger-color: var(--wp--preset--color--foreground);
	--hamburger-color-active: var(--wp--preset--color--foreground);
	--hamburger-width: 1.5rem;
	--hamburger-layer-height: 2.4px;
	--hamburger-layer-gap: 0.375rem;

	/* Desktop dropdowns */
	--color-main-level: var(--wp--preset--color--background);
	--color-hover-main-level: var(--wp--preset--color--accent);
	--color-current: var(--wp--preset--color--accent);
	--typography-size-main-level: 1.2rem;
	--typography-weight-main-level: 600;
	--padding-main-level-vertical: 0.375rem;
	--gap-main-level-horizontal: 1.875rem;
	--gap-between-dropdown-toggle: 0.9375rem;
	--dropdown-toggle-size: 0.75rem;

	/* Desktop dropdown — a light card matching the search panel and product cards. Hover
		 * fills the row; the active page reads accent. */
	--color-sub-menu: var(--wp--preset--color--foreground);
	--color-hover-sub-menu: var(--wp--preset--color--foreground);
	--color-current-sub-menu: var(--wp--preset--color--accent);
	--color-background-sub-menu: var(--wp--preset--color--background);
	--color-hover-bg-sub-menu: var(--wp--preset--color--surface, #f1f3f8);
	--color-border-sub-menu: var(--wp--preset--color--border, #dbdbdb);
	--radius-sub-menu: 4px;
	--shadow-sub-menu: 0 12px 32px rgb(0 0 0 / 0.12);
	--typography-size-sub-menu: 1rem;
	--typography-weight-sub-menu: 600;
	--padding-sub-menu-vertical: 0.625rem;
	--padding-sub-menu-link-vertical: 0.5rem;
	--padding-sub-menu-link-horizontal: 1.25rem;
	--width-sub-menu: 15rem;
	--gap-dropdown: 1.6rem;

	/* Mobile drawer — a left-docked, partial-width panel with k-rauta-style
	 * drill-down sub-panels. Light surface, palette tokens only. */
	--nav-drawer-width: min(20rem, 86vw);
	--nav-drawer-bg: var(--wp--preset--color--background);
	--nav-drawer-fg: var(--wp--preset--color--foreground);
	--nav-drawer-active: var(--wp--preset--color--accent);
	--nav-drawer-divider: var(--wp--preset--color--border-subtle);
	--nav-drawer-backdrop: rgb(0 0 0 / 0.5);
	--nav-drawer-pad-x: 1rem;
}

/* Set on the container, not the links, so the drawer's drill headers and the
   "Tuotteet" trigger match at every breakpoint. */
.nav-primary {
	font-family: var(--wp--preset--font-family--barlow-condensed);
	text-transform: uppercase;
}
/* The UA sheet resets text-transform on form controls, so the "Tuotteet" trigger
   takes the family but not the casing unless it's restated. */
.nav-primary button {
	text-transform: inherit;
}

/* The brand's signature motif; angle, band widths and the 6px height are measured off
 * live (docs/design-spec.md). Decorative — always pair with aria-hidden. */
.stripe-divider {
	display: block;
	height: 6px;
	background-image: repeating-linear-gradient(
		-70deg,
		var(--wp--preset--color--accent) 0 30px,
		var(--wp--preset--color--ink) 30px 60px
	);
}

.stripe-divider--tight {
	background-image: repeating-linear-gradient(
		-70deg,
		var(--wp--preset--color--accent) 0 20px,
		var(--wp--preset--color--ink) 20px 30px
	);
}

/* Footer column rule: one solid accent bar on the shared skew — the hazard bands' ink half
   vanishes against the dark ground, so the motif carries by angle here rather than by stripe. */
.stripe-divider--solid {
	height: 4px;
	background-image: none;
	background-color: var(--wp--preset--color--accent);
	transform: skewX(var(--skew-angle));
}

/* ----- Burger button (hidden on desktop) -------------------------------- */
.hamburger {
	display: block;
	width: var(--hamburger-width);
	height: var(--hamburger-layer-height);
	background-color: var(--hamburger-color);
	position: relative;
	transition: all 0.2s ease 0s;
	flex-shrink: 0;
}
.hamburger::before,
.hamburger::after {
	content: "";
	display: block;
	width: var(--hamburger-width);
	height: var(--hamburger-layer-height);
	background-color: var(--hamburger-color);
	position: absolute;
	transition: all 0.2s ease 0s;
}
.hamburger::before { top: calc(var(--hamburger-layer-gap) * -1); }
.hamburger::after  { bottom: calc(var(--hamburger-layer-gap) * -1); }

body:not(.js-nav-active) .nav-toggle .hamburger::after,
body:not(.js-nav-active) .nav-toggle:focus .hamburger::after { width: 80%; }
body:not(.js-nav-active) .nav-toggle:hover .hamburger::after { width: 100%; }

.js-nav-active .hamburger { background-color: transparent; }
.js-nav-active .hamburger::before,
.js-nav-active .hamburger::after {
	background-color: var(--hamburger-color-active);
	left: 0;
	top: 0;
}
.js-nav-active .hamburger::before { transform: rotate(-45deg); }
.js-nav-active .hamburger::after  { transform: rotate(45deg); }

.nav-toggle {
	display: flex;
	align-items: center;
	justify-content: center;
	/* Wider than tall: the slant is derived from the height, so the extra width
	   is free — it buys touch target without changing the shape's angle. */
	width: 4rem;
	height: 3rem;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	cursor: pointer;
	position: relative;
	z-index: 1; /* below the full-height drawer (z-60) — the drawer's own X closes it */
	font-size: var(--typography-size-main-level);
	--hamburger-color: var(--wp--preset--color--ink);
	--hamburger-color-active: var(--wp--preset--color--ink);
	--nav-toggle-slant: calc(3rem * tan(var(--skew-angle)) * -1);
}
/* Right edge only, so skewX is out — it leans both edges. The offset tracks
   height * tan(angle); a fixed px would drift the angle if the bar resizes.
   Carried on ::before, not the button, because clip-path crops the focus ring. */
.nav-toggle::before {
	content: "";
	position: absolute;
	z-index: -1;
	inset: 0;
	background-color: var(--wp--preset--color--accent);
	clip-path: polygon(0 0, 100% 0, calc(100% - var(--nav-toggle-slant)) 100%, 0 100%);
	transition: background-color 0.15s ease;
}
.nav-toggle:hover::before { background-color: #ffdf4d; }

/* The trigger stays visible at every width: here it is the "Tuotteet" entry point,
 * not a mobile-only burger. Width/height come from utilities on the button. */
@media (min-width: 1030px) {
	.nav-toggle {
		width: auto;
		height: auto;
		/* em, so the padding rides the fluid nav size instead of needing its own clamp. */
		padding-inline: 0.9375em 2.604em;
		--nav-toggle-slant: calc(3.25rem * tan(var(--skew-angle)) * -1);
	}
}

/* Login — the quiet sibling of the accent cart + burger on the compact bar; on
 * desktop it drops the fill and reads as a plain icon+label link. Palette tokens only. */
.header-btn-soft {
	background-color: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--foreground);
	transition: background-color 0.15s ease, color 0.15s ease;
}
.header-btn-soft:hover { background-color: var(--wp--preset--color--border); }

@media (min-width: 1030px) {
	.header-btn-soft { background-color: transparent; }
	.header-btn-soft:hover {
		background-color: transparent;
		color: var(--wp--preset--color--accent);
	}
}

body.js-nav-active { overflow: hidden; }

.site-topbar a {
	color: inherit;
	text-decoration: none;
	transition: color 0.15s ease;
}
.site-topbar a:hover,
.site-topbar a:focus-visible {
	color: var(--wp--preset--color--accent);
	text-decoration: underline;
}

/* Cart count bubble. The fill sits on a pseudo so the digit stays upright —
   cart.js rewrites the span's textContent, so an inner element to counter-skew
   would be wiped on every update. `isolation` keeps the -1 inside the badge. */
/* No `position` here — the badge is already `absolute` via a utility, and
   main.css is unlayered so re-declaring it would beat and undo that. */
.nomon-cart-trigger__count {
	isolation: isolate;
}
.nomon-cart-trigger__count::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-color: var(--wp--preset--color--accent);
	transform: skewX(var(--skew-angle));
}

/* ----- Sticky header w/ headroom reveal --------------------------------
 * The <header> sticks, hiding on scroll-down and returning on scroll-up (logic in
 * navigation.js). Plain sticky with NO transform at rest, so the fixed mobile drawer
 * inside it stays viewport-anchored; the hide transform exists only while unpinned. */
.site-header[data-headroom] {
	position: sticky;
	top: 0;
	z-index: 50;
	transition: transform 0.3s ease;
}
.site-header[data-headroom].is-unpinned {
	transform: translateY(-100%);
}
.admin-bar .site-header[data-headroom] { top: 32px; }
@media (max-width: 782px) {
	.admin-bar .site-header[data-headroom] { top: 46px; }
}
@media (prefers-reduced-motion: reduce) {
	.site-header[data-headroom] { transition: none; }
}

/* ===== Below --breakpoint-nav ===========================================
 * One drawer serves every width (`#product-menu`, styled further down), so the
 * horizontal bar simply steps aside here and the trigger becomes a burger. The
 * 235-line drill-down drawer this block used to hold is gone with it. */
@media (max-width: 1029.98px) {
	.nav-primary { align-self: center; }

	/* Secondary strip, dropped so the compact header starts at the logo row. Note
	   Varaa huolto / Hae rahoitusta / Ajankohtaista sit in no other menu, so they
	   lose their mobile entry point until they join the drawer or the footer. */
	.site-topbar { display: none; }

	/* Trigger opens the header row, so it reads as a burger: logo takes the
	   leftover width beside it, actions and search follow on their utilities. */
	.site-header__bar > .nav-primary { order: 1; }
	.site-header__logo { order: 2; }

	/* The shape loses its slant off the bottom-right, so reserving that much on
	   the end optically re-centres the bars over the fill rather than the box. */
	.nav-toggle { padding-inline-end: var(--nav-toggle-slant); }

	/* Visually hidden rather than `display: none` — it stays the button's
	   fallback accessible name if navigation.js never sets its aria-label. */
	.nav-toggle__label {
		position: absolute;
		width: 1px;
		height: 1px;
		margin: -1px;
		overflow: hidden;
		clip-path: inset(50%);
	}

	/* The horizontal bar is desktop-only; below here the trigger opens
	   `#product-menu`, which carries this menu as its first tier. */
	.nav-primary .menu-items-wrapper { display: none; }
}

/* While resizing, kill the submenu transitions: crossing the nav breakpoint
 * otherwise animates desktop-visible to hidden. Set by navigation.js. */
html.nav-resizing .nav-primary .menu-items,
html.nav-resizing .nav-primary .sub-menu {
	transition: none !important;
}

/* Logo centred on the viewport, not on the space left between the controls: a
   flex middle child only lands on centre when both flanks measure the same, and
   the account+cart pair is wider than the trigger. Out of flow, so the row's
   height still comes from the controls. `--header-logo-reserve` is the wider
   flank plus a gap; the wordmark is 300×18, so whatever is left divides by 16.7
   into its height. From `md` up the logo is start-aligned and none of it applies. */
@media (max-width: 767.98px) {
	.site-header__bar { position: relative; }

	.site-header__logo {
		--header-logo-reserve: 5.5rem;

		position: absolute;
		/* Absolute insets resolve against the padding box, so this has to clear
		   the bar's own `py-3` or the logo rides 12px above the trigger. */
		inset-block-start: 0.75rem;
		inset-inline-start: 50%;
		width: calc(100% - 2 * var(--header-logo-reserve));
		height: 3rem; /* the trigger's height, so it centres against the row */
		transform: translateX(-50%);
		align-items: center;
	}
}

/* ===== DESKTOP (at and above --breakpoint-nav) ========================== */
@media (min-width: 1030px) {
	.nav-primary { line-height: 0; padding-block: 0; }

	/* At full size the eight links plus the Tuotteet block need ~1155px, but the
	   content region is only ~0.9vw — so from 1285px down they wrapped to a second
	   row. Both scale to 0.78 by the breakpoint, which holds one line with 25px
	   spare. Scoped here so the drawer below the breakpoint keeps full size. */
	.nav-primary,
	.nav-toggle {
		--typography-size-main-level: clamp(0.936rem, -0.13rem + 1.657vw, 1.2rem);
		--gap-main-level-horizontal: clamp(1.4625rem, -0.204rem + 2.588vw, 1.875rem);
	}

	/* Own full-width line at the foot of the header bar — the separate nav bar
	   this used to be. The bar's row-gap reproduces that bar's 12px offset; only
	   its bottom padding has to go, so the band still ends the header flush. */
	.site-header__bar > .nav-primary {
		order: 5;
		width: 100%;
		margin-bottom: -0.75rem;
	}

	/* The nav is a full-height band beside the "Tuotteet" block, so the links
	   centre against the block rather than sitting on their own baseline. */
	.nav-primary .menu-items-wrapper { display: flex; align-items: stretch; }
	.nav-primary .menu-items { align-items: stretch; }
	.nav-primary .menu-item > a { display: flex; align-items: center; }

	.nav-primary .menu-items {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		justify-content: flex-end;
		column-gap: var(--gap-main-level-horizontal);
		row-gap: 0.625rem;
		margin: 0;
		padding: 0;
		list-style: none;
		/* NOT position:relative — the mega panel must anchor to `.nav-row` (the
		 * content-width row), not to this flex-end nav strip. */
		position: static;
	}

	.nav-primary .menu-item { margin: 0; position: relative; }

	.nav-primary .menu-item > a {
		display: inline-flex;
		align-items: center;
		color: var(--color-main-level);
		font-size: var(--typography-size-main-level);
		font-weight: var(--typography-weight-main-level);
		padding-block: var(--padding-main-level-vertical);
		white-space: nowrap;
		text-decoration: none;
	}
	.nav-primary .menu-item > a:hover,
	.nav-primary .menu-item > a:focus { color: var(--color-hover-main-level); }
	.nav-primary .menu-item.current-menu-parent > a,
	.nav-primary .menu-item.current-menu-item > a { color: var(--color-current); }

	/* Appears on hover/focus, held for the current page. Top-level only — sub-menu links
			 * carry their own text-decoration underline. */
	.nav-primary .menu-items > .menu-item > a { position: relative; }
	.nav-primary .menu-items > .menu-item > a::after {
		content: "";
		position: absolute;
		left: 0;
		right: 0;
		/* `.nav-primary` sets line-height: 0, so `bottom: 0` would clip the glyphs. Offsetting
							 * below the line-box also clears descenders ("Yritys", "Yhteystiedot"). */
		/* Grown downward from the old 2px bar: the top edge stays at -7px so the
				 * descender clearance above is unchanged. Skew needs height to read —
				 * at 2px it only offset 0.43px. */
		bottom: -11px;
		height: 4px;
		background: currentColor;
		opacity: 0;
		transform: skewX(var(--skew-angle));
	}
	.nav-primary .menu-items > .menu-item > a:hover::after,
	.nav-primary .menu-items > .menu-item > a:focus-visible::after,
	.nav-primary .menu-items > .menu-item.current-menu-parent > a::after,
	.nav-primary .menu-items > .menu-item.current-menu-item > a::after {
		opacity: 1;
	}
	/* Active page gets an accent-blue underline; hover stays monochrome
	 * (`currentColor` from the base rule above). */
	.nav-primary .menu-items > .menu-item.current-menu-parent > a::after,
	.nav-primary .menu-items > .menu-item.current-menu-item > a::after {
		background: var(--wp--preset--color--accent);
	}

	/* Top-level parents lay link + caret side by side in the bar. */
	.nav-primary .menu-item.menu-item-has-children {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: var(--gap-between-dropdown-toggle);
	}

	/* The mega anchors to the full-width `.site-header`, not the item, so its background
		 * bleeds the header width while the columns stay padded to content width. */
	.nav-primary .menu-items > .menu-item { position: static; }

	/* ===== Mega dropdown =================================================
		 * A top-level submenu docks under the header as a full-width band and lays its
		 * children out in columns — leaf items are one link, parents a heading plus list.
		 * No fly-out boxes; anchored to `.site-header`. */
	.nav-primary .menu-items > .menu-item > .sub-menu {
		/* current/ancestor items read accent-blue via the shared
		 * `current-menu-item/parent > a { color: var(--color-current) }` rule. */
		--color-current: var(--color-current-sub-menu);
		position: absolute;
		top: 100%;            /* dock to the bottom edge of the header */
		left: 0;
		right: 0;
		z-index: 40;
		/* Each first-level item is one cell (1fr), so columns always fill the container and a
				 * 6th item wraps to a new row of 5. */
		display: grid;
		grid-template-columns: repeat(5, 1fr);
		align-items: start;
		gap: 1.5rem 2.5rem;
		margin: 0;
		/* Full-bleed background, columns padded back to content width with EQUAL sides — a 2rem
				 * floor on narrow desktop, content-edge centring beyond the content size. */
		padding-block: 1.5rem 1.75rem;
		padding-inline: max(2rem, calc((100% - var(--wp--style--global--content-size, 1280px)) / 2));
		list-style: none;
		background-color: var(--color-background-sub-menu);
		border-top: 1px solid var(--wp--preset--color--border-subtle, #efefef);
		border-bottom: 1px solid var(--color-border-sub-menu);
		box-shadow: var(--shadow-sub-menu);
		opacity: 0;
		visibility: hidden;
		transition: opacity 0.2s cubic-bezier(0.19, 1, 0.22, 1), visibility 0.2s cubic-bezier(0.19, 1, 0.22, 1);
	}
	/* Hover bridge over the gap between a trigger and the docked panel. Anchored to the
		 * TRIGGER's link box, not the full-width panel: a panel-wide bridge sat over every
		 * other top-level link and blocked them while one mega was open. Hidden at rest so
		 * it is never an invisible hotspot. */
	.nav-primary .menu-items > .menu-item.menu-item-has-children > a::before {
		content: "";
		position: absolute;
		top: 100%;
		left: 0;
		right: -1.75rem; /* reach past the caret toggle, staying within the item's own width */
		height: 1.5rem;  /* spans the gap to the panel and laps a few px onto it */
		visibility: hidden;
	}
	.nav-primary .menu-items > .menu-item-has-children:hover > a::before,
	.nav-primary .menu-items > .menu-item-has-children:focus-within > a::before,
	.nav-primary .menu-items > .menu-item-has-children.hover-intent > a::before {
		visibility: visible;
	}
	/* Each first-level item is a grid cell (one column). */
	.nav-primary .menu-items > .menu-item > .sub-menu > .menu-item {
		display: block;
		position: static;
		min-width: 0; /* let long labels wrap inside the cell instead of stretching it */
		margin: 0;
	}
	/* Nested lists (2nd level and deeper) render in-flow as a static sub-list
	 * under their heading — not a fly-out card. */
	.nav-primary .menu-items > .menu-item > .sub-menu .sub-menu {
		position: static;
		top: auto;
		left: auto;
		width: auto;
		margin: 0.25rem 0 0;
		padding: 0;
		background: none;
		border: 0;
		border-radius: 0;
		box-shadow: none;
		/* Forcing `visibility: visible` kept these lists pointer-active while the band was
							 * hidden — invisible hotspots over the hero that opened the mega on hover. */
		visibility: inherit;
		transition: none;
	}

	/* Links inside the mega panel: full-width row with rounded hover fill. */
	.nav-primary .menu-item .sub-menu a {
		display: block;
		position: relative;
		/* Contains the fill's negative z-index; without it the skewed pseudo
		   drops behind the panel's own white background and never shows. */
		isolation: isolate;
		width: 100%;
		color: var(--color-sub-menu);
		font-size: var(--typography-size-sub-menu);
		font-weight: var(--typography-weight-sub-menu);
		line-height: 1.4;
		padding: 0.3125rem 0.5rem;
		border-radius: 0;
		text-decoration: none;
		/* `normal` re-enables wrapping (the bar links set nowrap, which inherits here);
				 * `break-word` handles a single over-long word. */
		white-space: normal;
		overflow-wrap: break-word;
	}
	/* 1st-level link = column heading: bolder, to head its child list. */
	.nav-primary .menu-items > .menu-item > .sub-menu > .menu-item > a {
		font-weight: 700;
	}
	/* 2nd-level-and-deeper links sit a touch smaller/lighter than the column
	 * heading (the 1st-level link). */
	.nav-primary .menu-items > .menu-item > .sub-menu .sub-menu a {
		font-size: var(--wp--preset--font-size--regular);
		font-weight: 600;
	}
	/* Fill rides a skewed pseudo so the row text stays upright. */
	.nav-primary .menu-item .sub-menu a::before {
		content: "";
		position: absolute;
		inset: 0;
		z-index: -1;
		transform: skewX(var(--skew-angle));
	}
	.nav-primary .menu-item .sub-menu a:hover,
	.nav-primary .menu-item .sub-menu a:focus {
		color: var(--color-hover-sub-menu);
	}
	.nav-primary .menu-item .sub-menu a:hover::before,
	.nav-primary .menu-item .sub-menu a:focus::before {
		background: var(--color-hover-bg-sub-menu);
	}
	/* Explicit and higher-specificity than the `.sub-menu a` colour above, which would
		 * otherwise win on source order. */
	.nav-primary .sub-menu .menu-item.current-menu-item > a,
	.nav-primary .sub-menu .menu-item.current-menu-parent > a {
		color: var(--color-current-sub-menu);
	}
	/* Chevrons are redundant in the mega (children are shown inline). */
	.nav-primary .menu-items > .menu-item > .sub-menu .dropdown-toggle { display: none; }

	/* :hover for mouse, :focus-within for keyboard, and .hover-intent (JS) which holds the
		 * menu open briefly to absorb stray cursor movement. */
	.nav-primary .menu-item-has-children:hover > .sub-menu,
	.nav-primary .menu-item-has-children:focus-within > .sub-menu,
	.nav-primary .menu-item-has-children.hover-intent > .sub-menu {
		opacity: 1;
		visibility: visible;
		z-index: 12;
	}

	/* Dropdown toggle on desktop is decorative — pointer-events: none lets
	 * clicks fall through to the parent <a>. The svg is the visual cue. */
	.nav-primary .dropdown-toggle {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		padding: 0;
		background: transparent;
		border: 0;
		color: var(--wp--preset--color--accent);
		pointer-events: none;
	}
	.nav-primary .dropdown-toggle svg {
		width: var(--dropdown-toggle-size);
		height: var(--dropdown-toggle-size);
		transition: all 0.35s cubic-bezier(0.19, 1, 0.22, 1);
	}
	.nav-primary .menu-item-has-children.hover-intent > .dropdown-toggle svg {
		transform: rotateX(180deg);
	}
	.nav-primary .sub-menu .dropdown-toggle svg { transform: rotate(-90deg); }
	.nav-primary .sub-menu .hover-intent > .dropdown-toggle svg {
		transform: rotate(-90deg) rotateX(180deg);
	}
}

/* Shared by the homepage block, single-product "Katso myös" and the archive. Mobile 2-up
 * and tablet 3-up are deliberate; from ≥lg the column count derives from one target card
 * width, so cards match whether the grid spans the content width or the narrower archive
 * column. Real CSS, not utilities: `repeat(auto-fill, minmax(…))` trips the scanner. */
:root {
	--product-card-min: 252px;
}
/* Floors at the root padding's own floor, so the 2-up grid never parts its cards by more than the page parts them from the viewport edge. */
.nomon-product-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: clamp(0.9375rem, 1.5vw, 1.25rem);
}
@media (min-width: 768px) {
	.nomon-product-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}
@media (min-width: 1024px) {
	.nomon-product-grid {
		grid-template-columns: repeat(auto-fill, minmax(var(--product-card-min), 1fr));
	}
}

/* Reusable product card. Structural rules are real CSS, not utilities: main.css loads in
 * the editor iframe, so the preview keeps them even where its bundled Tailwind doesn't
 * emit the matching utility and the media box would collapse. */
.nomon-product-card {
	height: 100%; /* fill the stretched grid cell → equal height per row */
}
.nomon-product-card__media {
	aspect-ratio: 1 / 1;
}
/* Reserve the brand and name lines so headings and prices align across a row whichever
 * products have them; line-heights are set here so a filled line matches the reserve. */
.nomon-product-card__brand {
	min-height: 18px;
	line-height: 18px;
}
.nomon-product-card__name {
	min-height: 42px;
	line-height: 1.3;
}
/* Priority-ordered stack (max 2) from nomon_wc_product_badges(). Padding lives here, not
 * on the markup, because the right edge's shear has to be added to it. */
.nomon-badge {
	--badge-slant: calc((1em + 14px) * tan(var(--skew-angle)) * -1);

	padding: 7px calc(10px + var(--badge-slant)) 7px 10px;
	clip-path: polygon(0 0, 100% 0, calc(100% - var(--badge-slant)) 100%, 0 100%);
}
/* "Uutuus" and the discount badge share the yellow chip — kept as one rule so they
 * cannot drift apart. */
.nomon-badge--new,
.nomon-badge--sale {
	color: var(--wp--preset--color--ink, #07121c);
	background-color: var(--wp--preset--color--accent, #ffd200);
}
.nomon-badge--used {
	color: var(--wp--preset--color--accent);
	background-color: var(--wp--preset--color--ink);
}
/* Stock dot — colour comes from a `bg-*` token utility; size/shape here because
 * the editor's Tailwind CDN doesn't emit the arbitrary `size-[9px]`. */
/* Stock pill — the live site's tinted chip, replacing the starter's bare dot. */
.nomon-stock-pill {
	/* Shear of the pill's own height (line box + padding), so the edge keeps the
	   canonical angle whatever the type scale does. */
	--pill-slant: calc((1.5em + 6px) * tan(var(--skew-angle)) * -1);

	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 3px calc(10px + var(--pill-slant)) 3px 10px;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	line-height: 1.5;
	color: var(--wp--preset--color--success);
	background-color: var(--wp--preset--color--success-bg);
	/* Right edge only, so skewX is out — it would lean the left edge and the label
	   with it. Same shape as `.nav-toggle::before`. */
	clip-path: polygon(0 0, 100% 0, calc(100% - var(--pill-slant)) 100%, 0 100%);
}
.nomon-stock-pill__dot {
	width: 7px;
	height: 7px;
	background-color: currentColor;
	transform: skewX(var(--skew-angle));
}
.nomon-stock-pill--low,
.nomon-stock-pill--backorder {
	color: var(--wp--preset--color--warning);
	background-color: var(--wp--preset--color--warning-bg);
}
.nomon-stock-pill--out {
	color: var(--wp--preset--color--danger);
	background-color: var(--wp--preset--color--danger-bg);
}

.nomon-product-card__dot {
	width: 9px;
	height: 9px;
}
/* Sale price rides a filled tag. Fixed line-height so the shear resolves off a known
   box, and right edge only — skewX would tip the number with it. */
/* Shared by the card and the single-product summary, so the two render the same
   tag. Slant and padding are em-based: the summary sets a larger font-size and
   the shape scales with it. */
.nomon-sale-price {
	--sale-slant: calc((1.2em + 8px) * tan(var(--skew-angle)) * -1);

	line-height: 1.2;
	padding: 4px calc(10px + var(--sale-slant)) 4px 10px;
	background-color: var(--wp--preset--color--sale);
	color: var(--wp--preset--color--background);
	clip-path: polygon(0 0, 100% 0, calc(100% - var(--sale-slant)) 100%, 0 100%);
}
/* Fixed min-height + centring so a plain price and a boxed sale price share a line —
 * the sale box's padding would otherwise drop its number a few px. */
.nomon-product-card__price {
	display: flex;
	align-items: center;
	gap: 10px;
	min-height: 31px;
}
/* `text-lg` applies a taller line-height that inflates the sale-price box and pushes its
 * number off the line shared with the plain prices. */
.nomon-product-card__price,
.nomon-product-card__price span {
	line-height: 1.3;
}

/* Single-product summary price — same tag as the card (`.nomon-sale-price`),
   sized up. Centring + a fixed line-height for the same reason as the card: the
   tag's padding would otherwise drop its number off the baseline it shares with
   the struck regular price. */
.nomon-product__price-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px;
}
.nomon-product__price-row,
.nomon-product__price-row span {
	line-height: 1.3;
}

/* A real outline (not a Tailwind box-shadow ring) so the whole-card focus
 * indicator is predictable wherever the card is reused. */
.nomon-product-card:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}

/* SEOPress PRO, BEM classes via inc/integrations/seopress.php. The <ol> is renamed away
 * from `.breadcrumb` so the plugin's inline-CSS separator never matches; ours is below. */
/* Sit 25px under the header, not a full --section-space: as the padded wrapper's first
 * child, a negative top margin trims that padding. The parent path is load-bearing for
 * specificity — WP emits `:root :where(.is-layout-constrained) > :first-child
 * { margin-block-start: 0 }` at (0,2,0), which a bare `.site-breadcrumbs` (0,1,0) loses
 * to, silently dropping the negative margin. This (0,3,0) wins. */
.site-content.has-global-padding > .site-breadcrumbs {
	margin-top: calc(1.5625rem - var(--section-space));
}
.site-breadcrumbs__list {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: 1rem; /* 16px (Figma) */
	line-height: 1.3;
	color: var(--wp--preset--color--foreground);
}
.site-breadcrumbs__item,
.site-breadcrumbs__item--current {
	display: flex;
	align-items: center;
}
.site-breadcrumbs__item:not(:last-child)::after {
	content: "/";
	margin-inline: 10px;
	font-weight: 400;
	color: var(--wp--preset--color--muted);
}
/* Links carry the weight and the darker tone; the current page recedes. Two cues, so the
   trail never rests on the 500-vs-400 step in one black it used to. */
.site-breadcrumbs__item a {
	color: var(--wp--preset--color--foreground);
	font-weight: 700;
	text-decoration: none;
}
.site-breadcrumbs__item a:hover {
	text-decoration: underline;
	text-underline-offset: 3px;
}
.site-breadcrumbs__item--current {
	font-weight: 400;
	color: var(--wp--preset--color--muted);
}

/* Every button's label is uppercase Barlow Condensed, matching the nav, the
 * product menu and the category strip — the condensed face is the theme's voice
 * for UI chrome, and buttons were the last surface still set in Inter. Grouped
 * rather than repeated per component so a new button surface joins by being
 * added here. Sizes stay with each component: the face reads narrower than Inter
 * at the same size, so any bump is a per-surface judgement (see the add-to-cart
 * button, which took one). Icon-only controls are excluded — no label to set. */
.nomon-btn,
.nomon-promo__cta,
.header-btn-soft,
.nomon-button,
.woocommerce-account .woocommerce button.button,
.woocommerce-account .woocommerce input.button,
.woocommerce-account .woocommerce a.button,
.woocommerce-account .woocommerce button[type="submit"] {
	font-family: var(--wp--preset--font-family--barlow-condensed);
	text-transform: uppercase;
	letter-spacing: 0.5px;
}

/* ===== BUTTON base =====================================================
 * The shape every button builds on: a skewed fill with an upright label. Variants
 * set the knobs below rather than restating the rules — a different colour, size or
 * padding is a knob; a one-sided skew swaps `transform` for a `clip-path` (see
 * `.nav-toggle::before`, which slants its right edge only, since skewX leans both).
 * Requires a `<span>` around the label to carry the counter-skew. */
.nomon-btn {
	--btn-bg: var(--wp--preset--color--accent);
	--btn-bg-hover: #ffdf4d;
	--btn-fg: var(--wp--preset--color--ink);
	--btn-padding: 5px 18px;
	--btn-size: var(--wp--preset--font-size--heading-6);
	--btn-weight: 700;

	display: inline-flex;
	align-items: center;
	padding: var(--btn-padding);
	border: 0;
	background-color: var(--btn-bg);
	color: var(--btn-fg);
	font-size: var(--btn-size);
	font-weight: var(--btn-weight);
	letter-spacing: 0.5px;
	line-height: 1.7;
	text-decoration: none;
	transform: skewX(var(--skew-angle));
	transition: background-color 0.15s ease, color 0.15s ease;
}
.nomon-btn > span {
	display: inline-block;
	transform: skewX(calc(var(--skew-angle) * -1));
}
.nomon-btn:hover,
.nomon-btn:focus-visible {
	background-color: var(--btn-bg-hover);
}

/* ===== core/button styles ==============================================
 * Registered in inc/integrations/core-blocks.php. Same shape as `.nomon-btn`, but
 * the slant is right-edge only, so it can't use skewX — that leans both edges, and
 * core's markup has no inner span to counter-skew anyway. The fill rides a ::before
 * carrying the clip-path, as on `.nav-toggle::before`: clipping the link itself
 * would crop its focus ring. The offset is the box height * tan(), height being
 * line-height plus the vertical padding, so it tracks the label size. */
.wp-block-button.is-style-nomon-accent > .wp-block-button__link,
.wp-block-button.is-style-nomon-ink > .wp-block-button__link {
	--btn-slant: calc((1.7em + 10px) * tan(var(--skew-angle)) * -1);

	position: relative;
	z-index: 0;
	display: inline-block;
	padding: 5px calc(18px + var(--btn-slant)) 5px 18px;
	border: 0;
	border-radius: 0;
	background-color: transparent;
	font-family: var(--wp--preset--font-family--barlow-condensed);
	font-size: var(--wp--preset--font-size--heading-6);
	font-weight: 700;
	letter-spacing: 0.5px;
	line-height: 1.7;
	text-decoration: none;
	text-transform: uppercase;
}

.wp-block-button.is-style-nomon-accent > .wp-block-button__link::before,
.wp-block-button.is-style-nomon-ink > .wp-block-button__link::before {
	content: "";
	position: absolute;
	z-index: -1;
	inset: 0;
	background-color: var(--btn-fill);
	clip-path: polygon(0 0, 100% 0, calc(100% - var(--btn-slant)) 100%, 0 100%);
	transition: background-color 0.15s ease;
}

.wp-block-button.is-style-nomon-accent > .wp-block-button__link {
	--btn-fill: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--ink);
}
.wp-block-button.is-style-nomon-accent > .wp-block-button__link:hover::before,
.wp-block-button.is-style-nomon-accent > .wp-block-button__link:focus-visible::before {
	--btn-fill: var(--accent-hover);
}

.wp-block-button.is-style-nomon-ink > .wp-block-button__link {
	--btn-fill: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--background);
}
/* Inverts to the accent pairing on hover, as `.nomon-promo__cta` does — the dark
   fill has no lighter tint of its own. */
.wp-block-button.is-style-nomon-ink > .wp-block-button__link:hover,
.wp-block-button.is-style-nomon-ink > .wp-block-button__link:focus-visible {
	color: var(--wp--preset--color--ink);
}
.wp-block-button.is-style-nomon-ink > .wp-block-button__link:hover::before,
.wp-block-button.is-style-nomon-ink > .wp-block-button__link:focus-visible::before {
	--btn-fill: var(--wp--preset--color--accent);
}

/* Promo panel — shared by the `nomon/promo` block and the hero slider
   (template-parts/promo-panel.php), so it lives here rather than the block's
   style.css, which Blockstudio only enqueues when the block is on the page.
   Geometry read off live: content width, 50/50, 690px in-page / 518px in the hero. */
.nomon-promo {
	position: relative;
	display: grid;
	grid-template-columns: 1fr;
	background-color: var(--wp--preset--color--ink);
	overflow: hidden;
	--promo-min-h: 690px;
}

.nomon-promo__panel {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 20px;
	padding: 40px 30px 50px;
}

.nomon-promo__cta {
	display: inline-flex;
	align-items: center;
	padding: 5px 18px;
	border: 2px solid var(--wp--preset--color--accent);
	color: var(--wp--preset--color--background);
	font-size: var(--wp--preset--font-size--heading-5);
	font-weight: 500;
	letter-spacing: 0.5px;
	line-height: 1.7;
	text-decoration: none;
	transition: background-color 0.15s ease, color 0.15s ease;
}
.nomon-promo__cta:hover,
.nomon-promo__cta:focus-visible {
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--ink);
}

/* Both callers of `promo-panel.php` — the hero slider and the `nomon/promo`
   block — pass `cta_style => 'button'`, so the CTA is a `.nomon-btn` (markup,
   not an override). The outlined link above is the template's other branch,
   currently unused by either. */

.nomon-promo__media {
	position: relative;
	min-height: 220px;
}
/* Absolute so the image's intrinsic aspect can't set the grid row height —
   in flow, a portrait source stretched the whole banner past --promo-min-h. */
.nomon-promo__media img {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* 25px, not the 6px `.stripe-divider` default — banners carry the wide stripe. */
.nomon-promo__stripe {
	position: absolute;
	inset-inline: 0;
	bottom: 0;
	height: 25px;
}

.nomon-promo__placeholder {
	display: grid;
	place-items: center;
	height: 100%;
	color: var(--wp--preset--color--muted-on-dark);
	font-size: var(--wp--preset--font-size--small);
}

@media (min-width: 768px) {
	.nomon-promo {
		grid-template-columns: 1fr 1fr;
		align-items: stretch;
		min-height: var(--promo-min-h);
	}

	.nomon-promo__panel {
		justify-content: center;
		padding: 50px;
	}

	/* The slant is an ink parallelogram laid over the image edge rather than a
	   clip on either half — no seam, and the image stays full-bleed behind it. */
	/* Ink wedge over the image edge — no clip on either half, so no seam and the
	   image stays full-bleed behind it.
	   `z-index: -1`: the panel's own `z-index: 1` scopes this, keeping the whole
	   panel layer above `__media` while dropping the wedge below the copy. Painting
	   above it silently ate text (ink on ink).
	   `transform-origin: bottom` pins the slant to the seam at the bottom edge, so
	   its reach is a pure function of the angle. A centred origin needs an offset of
	   height/2 * tan(), which a fixed px value can't track — the old 75px fell short
	   past ~490px tall and the diagonal flattened to vertical near the bottom. */
	.nomon-promo--angled .nomon-promo__panel::after {
		content: "";
		position: absolute;
		z-index: -1;
		inset: 0;
		background-color: var(--wp--preset--color--ink);
		transform: skewX(var(--skew-angle));
		transform-origin: bottom;
	}
}

/* The site navigation drawer (template-parts/product-menu.php) — the one panel
   the trigger opens at every width. */
.product-menu {
	position: fixed;
	inset: 0;
	z-index: 1001;
}
.product-menu[hidden] {
	display: none;
}

.product-menu__backdrop {
	position: absolute;
	inset: 0;
	background: rgb(0 0 0 / 0.25);
	opacity: 0;
	transition: opacity 0.25s ease;
}
.js-product-menu-active .product-menu__backdrop {
	opacity: 1;
}

.product-menu__panel {
	position: absolute;
	inset-block: 0;
	left: 0;
	display: flex;
	width: 577px;
	max-width: 92vw;
	flex-direction: column;
	/* The panel must not scroll: it's also the positioning context for the
	   sub-panels, and an absolute child of a scroll container scrolls away with
	   the content instead of staying over the drawer. `__body` scrolls. */
	overflow: hidden;
	background: var(--wp--preset--color--background);
	transform: translateX(-100%);
	transition: transform 0.25s ease;
}
.js-product-menu-active .product-menu__panel {
	transform: translateX(0);
}

.product-menu__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	padding: 15px 30px;
}
.product-menu__logo {
	display: inline-flex;
	color: var(--wp--preset--color--foreground);
}
.product-menu__close {
	display: grid;
	place-items: center;
	width: 32px;
	height: 32px;
	border: 0;
	background: none;
	color: var(--wp--preset--color--foreground);
	cursor: pointer;
}
.product-menu__close:hover {
	color: var(--wp--preset--color--accent);
}

.product-menu__list {
	margin: 0;
	padding: 0;
	list-style: none;
}
/* Kept `static` so the sub-panels' `inset: 0` still resolves against the panel —
   that also exempts them from this box's clip and scroll. `overflow-x: clip` for
   the reason spelled out on the mobile drawer's panels. */
.product-menu__body {
	position: static;
	flex: 1;
	overflow-x: clip;
	overflow-y: auto;
	padding-bottom: 30px;
}
/* Static so each sub-panel's `inset: 0` resolves against the panel rather than
   its own row — the chevron is a flex sibling instead of absolutely placed. */
.product-menu__item {
	position: static;
	display: flex;
	align-items: center;
}
.product-menu__list a {
	display: block;
	flex: 1;
	padding: 12px 16px 12px 30px;
	font-family: var(--wp--preset--font-family--barlow-condensed);
	font-size: 1.2rem;
	font-weight: 600;
	text-transform: uppercase;
	color: var(--wp--preset--color--foreground);
	text-decoration: none;
}
.product-menu__list a:hover,
.product-menu__list a:focus-visible {
	background: var(--wp--preset--color--surface);
}

/* Second tier: the utility links stay body-font and mixed case, so the two
   groups read as different levels rather than one long list. */
/* Separates the primary-menu tier from the departments below it. */
.product-menu__label {
	margin: 30px 0 10px;
	padding-inline: 30px;
	font-family: var(--wp--preset--font-family--barlow-condensed);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.5px;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
}

.product-menu__list--utility {
	margin-top: 20px;
}
.product-menu__list--utility a {
	font-family: inherit;
	font-size: var(--wp--preset--font-size--regular);
	font-weight: 400;
	text-transform: none;
}

.product-menu__drill {
	display: grid;
	place-items: center;
	flex: 0 0 auto;
	align-self: stretch;
	width: 56px;
	border: 0;
	background: none;
	color: var(--wp--preset--color--foreground);
	cursor: pointer;
}
.product-menu__drill:hover {
	color: var(--wp--preset--color--accent);
}

/* Slides in over the panel; `inset: 0` resolves against `.product-menu__panel`
   because the rows are static. */
.product-menu__sub {
	position: absolute;
	inset: 0;
	z-index: 1;
	overflow-y: auto;
	background: var(--wp--preset--color--background);
	transform: translateX(100%);
	transition: transform 0.25s ease;
	visibility: hidden;
}
.product-menu__sub.is-open {
	transform: translateX(0);
	visibility: visible;
}

.product-menu__drill-header {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 15px 30px;
}
.product-menu__back {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 0;
	border: 0;
	background: none;
	font: inherit;
	color: var(--wp--preset--color--muted);
	cursor: pointer;
}
.product-menu__back:hover {
	color: var(--wp--preset--color--accent);
}
.product-menu__back svg {
	width: 12px;
	transform: rotate(90deg);
}
.product-menu__current {
	font-family: var(--wp--preset--font-family--barlow-condensed);
	font-size: 1.2rem;
	font-weight: 600;
	text-transform: uppercase;
	color: var(--wp--preset--color--foreground);
}

/* Matches --breakpoint-nav (line ~587) — below it the trigger belongs to the
   primary-nav drawer, so this panel must never be reachable. */
/* Category strip — template-parts/category-strip.php. Fixed-width slides so the
   track scrolls rather than reflowing; the arrows straddle the content edge. */
.nomon-category-strip {
	/* Shear of a 151px tile / a 50px arrow; half of it overhangs each side of the box. */
	--cs-slant: calc(151px * tan(var(--skew-angle)) * -1);
	--cs-arrow-shear: calc(50px * tan(var(--skew-angle)) * -1);
}
.nomon-category-strip__viewport {
	position: relative;
}
/* Padded by the overhang so `overflow` can't clip the outer tiles' corners — and
   padded rather than pulled back out with a negative margin, which at the 15px
   mobile gutter would hang past the viewport and add a scrollbar. */
.nomon-category-strip__swiper {
	overflow: hidden;
	padding-inline: calc(var(--cs-slant) / 2);
}
/* Slide pitch is unchanged (was 151 + a 25px gap): the tiles took the width the
   gap gave up, so the track still steps in the same rhythm. */
.nomon-category-strip__slide {
	width: 166px;
	height: auto;
	margin: 0;
	padding: 0;
}
.nomon-category-strip__link {
	display: flex;
	flex-direction: column;
	align-items: center;
	/* Top-aligned, not centred: slides all stretch to the tallest, so centring
	   let a two-line label push its own tile up out of line with the rest. */
	justify-content: flex-start;
	gap: 10px;
	height: 100%;
	padding-block: 1.25rem;
	color: var(--wp--preset--color--foreground);
	text-align: center;
	text-decoration: none;
}
.nomon-category-strip__tile {
	display: grid;
	place-items: center;
	width: 100%;
	height: 151px;
	overflow: hidden;
	border: 1px solid var(--wp--preset--color--border);
	transform: skewX(var(--skew-angle));
}
/* Widened by the shear before counter-skewing, so the upright photo still fills
   the parallelogram's corners — `max-width` because preflight's `img` cap would
   otherwise clamp that extra width straight back off. */
.nomon-category-strip__image {
	width: calc(100% + var(--cs-slant));
	max-width: none;
	height: 100%;
	object-fit: cover;
	transform: skewX(calc(var(--skew-angle) * -1));
}
.nomon-category-strip__placeholder {
	color: var(--wp--preset--color--muted);
	font-family: var(--wp--preset--font-family--barlow-condensed);
	font-size: 3.5rem;
	font-weight: 600;
	line-height: 1;
	text-transform: uppercase;
	transform: skewX(calc(var(--skew-angle) * -1));
}
/* Off the box's centre line by half the shear, which centres it on the tile's bottom
   edge — the edge it sits under, and the one the skew pulls left. */
.nomon-category-strip__label {
	translate: calc(var(--cs-slant) / -2);
	font-family: var(--wp--preset--font-family--barlow-condensed);
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.4;
	text-transform: uppercase;
}
.nomon-category-strip__link:hover .nomon-category-strip__label {
	text-decoration: underline;
}

/* 183px is the desktop measurement; below that the strip sizes to its labels. */
@media (min-width: 48rem) {
	.nomon-category-strip__link {
		min-height: 183px;
		padding-block: 0;
	}
}

.nomon-category-strip__arrow {
	position: absolute;
	top: 50%;
	z-index: 2;
	display: grid;
	place-items: center;
	width: 50px;
	height: 50px;
	transform: translateY(-50%) skewX(var(--skew-angle));
	border: 0;
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--ink);
	cursor: pointer;
}
.nomon-category-strip__arrow-icon {
	display: grid;
	place-items: center;
	transform: skewX(calc(var(--skew-angle) * -1));
}
/* Inset, not overhanging: at the 15px mobile gutter a negative offset pushed
   the arrow past the viewport and gave the page a horizontal scrollbar. */
.nomon-category-strip__prev { left: 15px; }
.nomon-category-strip__next { right: 15px; }
/* Overhang once the gutter fits the 50px arrow + a 15px gap. min-width counts the
   scrollbar, so clearance to the viewport edge at 1540 is 7.5–15px depending on it —
   pulled back by half the arrow's own shear, which otherwise spends 5px of that. */
@media (min-width: 1540px) {
	.nomon-category-strip__prev { left: calc(-65px + var(--cs-arrow-shear) / 2); }
	.nomon-category-strip__next { right: calc(-65px + var(--cs-arrow-shear) / 2); }
}
.nomon-category-strip__arrow.swiper-button-disabled,
.nomon-category-strip__arrow.swiper-button-lock {
	display: none;
}

/* Front-page bands own their spacing: 25px across the strip/hero cluster, full
   --section-space from keypoints down. Matches the generic rule's specificity, so these
   win on source order. */
.site-content > .nomon-category-strip.has-global-padding,
.site-content > .hero-slider.has-global-padding {
	padding-block: 25px 0;
}
.site-content > .nomon-keypoints.has-global-padding {
	padding-block: var(--section-space) 0;
}

/* The description clamp is gated on [data-enhanced], set by main.js only after measuring
   overflow, so a no-JS render keeps full text instead of silently cropping. */
.nomon-keypoints__grid {
	display: grid;
	grid-template-columns: repeat(1, minmax(0, 1fr));
	gap: 0.9375rem; /* 15px */
	margin: 0;
	padding: 0 1.5625rem; /* 25px */
	list-style: none;
	background-color: var(--wp--preset--color--surface);
}
@media (min-width: 48rem) {
	.nomon-keypoints__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}
@media (min-width: 64rem) {
	.nomon-keypoints__grid {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

.nomon-keypoints__item {
	display: flex;
	flex-direction: column;
	row-gap: 0.625rem; /* 10px */
	margin: 0;
	padding: 2.5rem 0.9375rem; /* 40px 15px */
}

/* Rules track the column count, not source order, so no row ends on one. */
@media (min-width: 48rem) {
	.nomon-keypoints__item:not(:nth-child(2n)):not(:last-child) {
		border-right: 1px solid var(--wp--preset--color--border);
	}
}
@media (min-width: 64rem) {
	.nomon-keypoints__item:nth-child(2n):not(:nth-child(4n)):not(:last-child) {
		border-right: 1px solid var(--wp--preset--color--border);
	}
	.nomon-keypoints__item:nth-child(4n) {
		border-right: 0;
	}
}

.nomon-keypoints__more {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	row-gap: 0.625rem;
}

.nomon-keypoints__text {
	font-size: 1rem;
	line-height: 1.7;
}

.nomon-keypoints__grid[data-enhanced] .nomon-keypoints__text:not([data-clamp="off"]) {
	max-height: 9.375rem; /* 150px */
	overflow: hidden;
	mask-image: linear-gradient(to bottom, #000 40%, transparent 90%);
}
.nomon-keypoints__grid[data-enhanced] .nomon-keypoints__text[data-expanded] {
	max-height: none;
	overflow: visible;
	mask-image: none;
}

.nomon-keypoints__toggle {
	padding: 0;
	border: 0;
	background: none;
	color: var(--wp--preset--color--foreground);
	font-size: 1rem;
	font-weight: 500;
	cursor: pointer;
}
.nomon-keypoints__toggle:hover {
	text-decoration: underline;
}

/* ==========================================================================
   Page template — title band + article column (page.php), measured off live.
   The article is a centred column, NOT the 72ch start-edge prose of a Group: live
   runs long-form pages at a wider measure and a lighter, larger face.
   ========================================================================== */

.nomon-page-header {
	padding-block: 3.125rem; /* 50px */
	background-color: var(--wp--preset--color--surface);
}
/* Above the 36px prose h1 of `body h1`, not below it: the live site's 30px was measured on
   mixed-case Inter, and condensed uppercase carries far less mass at the same px. Unlayered,
   so it beats that @layer base default without !important. */
.nomon-page-header__title {
	/* Start-packed grid track: the implicit column sizes to the title text, so the bar
	   below stretches to the title's own width. Shrink-wrapping the box instead would
	   fight WP's `margin-inline: auto !important` and pull it off the content column. */
	display: grid;
	justify-content: start;
	margin: 0.625rem 0 0; /* 10px clear of the breadcrumb trail */
	font-size: clamp(2rem, 4vw, 2.625rem);
	line-height: 1.05;
	font-weight: 700;
	color: var(--wp--preset--color--foreground);
}
.nomon-page-header__title::after {
	content: "";
	display: block;
	height: 6px;
	margin-top: 0.375rem; /* 6px */
	background-color: var(--wp--preset--color--accent);
	transform: skewX(var(--skew-angle));
}
/* `foreground` here, unlike the `muted` date on a post card. Both this and the H1 carry
   a `nomon-` class inside `.has-global-padding`, so the owl (0,3,0) would wedge
   --section-space between them; this outranks it. */
.site-content .nomon-page-header > .has-global-padding > .nomon-page-header__date {
	display: block;
	margin-top: 0.3125rem; /* 5px */
	font-size: var(--wp--preset--font-size--regular);
	line-height: 1.7;
	color: var(--wp--preset--color--foreground);
}

/* Featured image on a single post: content width, natural aspect. The article
   below owns the 75px gap through its own padding, so only the top is set. */
.nomon-single__media {
	margin: 3.125rem 0 0; /* 50px */
}

/* 75px under the band, 50px before the footer — live is asymmetric here, unlike the
   article's even 75/75. Matches the generic wrapper rule's specificity to override it. */
.site-content > .nomon-blog-archive.has-global-padding {
	padding-block: 4.6875rem 3.125rem;
}

/* The reading measure, unchanged at 900px — it used to be expressed as a 1020px
   column minus a 60px inset either side, which is how the column got centred.
   Now the prose is start-aligned, so the measure is the only number left and the
   inset's job (keeping text off the viewport edge) passes to the page gutter
   below, which already clamps down on small screens. */
.nomon-article {
	--article-measure: 56.25rem; /* 900px */
	padding-block: 4.6875rem; /* 75px */
	padding-inline: var(--wp--style--root--padding-left) var(--wp--style--root--padding-right);
}

/* Matched at any depth, so the required core/group wrapper is transparent; the (0,2,1)
   selector and `margin-inline` outrank the 72ch cap near the top of this file.
   Depth also reaches into anything that owns its own layout — the image card, the Oma
   tili shell, the WS Form skin — so those opt out via the shared `:not(:where(…))`.
   Add to that list rather than raising specificity: `:where()` keeps the exclusion at
   zero, and raising these would flip the first/last-child margin resets below, which
   sit at the same (0,3,0). */
.site-content .nomon-article
	:is(p, h1, h2, h3, h4, h5, h6, ul, ol, figure, blockquote, table, pre):not(:where(.nomon-imagecard *, .nomon-account *, .wsf-form *, .nomon-business-location *)) {
	max-width: var(--article-measure);
	/* Start-aligned on the *content region*, not the viewport: the article spans
	   the full padded width, so past the content size it has to give back half
	   its own excess to land where a constrained section starts. Same offset the
	   72ch cap uses near the top of this file. `!important` beats WP's emitted
	   `margin-inline: auto !important`; the end margin stays `auto` so nothing
	   stretches to fill. */
	margin-inline: max(
		0px,
		calc((100% - var(--wp--style--global--content-size)) / 2)
	) auto !important;
}

.site-content .nomon-article p:not(:where(.nomon-imagecard *, .nomon-account *, .wsf-form *, .nomon-business-location *)) {
	font-size: 1.25rem; /* 20px */
	line-height: 1.8; /* 36px */
	font-weight: 300;
	margin-block: 1.875rem; /* 30px */
}
/* Body is 300 here, so `strong` needs a wider step than the live site's 400 to register —
   at 100 units it was all but invisible against the light prose weight. */
.site-content .nomon-article :is(strong, b):not(:where(.nomon-imagecard *, .nomon-account *, .wsf-form *, .nomon-business-location *)) {
	font-weight: 500;
}
/* Prose links underline; the account shell styles its own (cards are whole-card
   links, order numbers are bold) and would otherwise underline entire cards. */
.site-content .nomon-article a:not(:where(.nomon-account *, .nomon-business-location *, .nomon-btn)) {
	text-decoration: underline;
}

/* No `line-height` here on purpose: it falls through to the uppercase-Barlow ramp in
   `@layer base` (1.05 → 1.25 by level). This rule is unlayered, so any value set here
   would silently beat that ramp — which is how the article column kept Inter's 1.6
   after the retune. Size and margin stay local; the rhythm stays central. */
.site-content .nomon-article :is(h1, h2, h3, h4, h5, h6):not(:where(.nomon-imagecard *, .nomon-account *, .wsf-form *, .nomon-business-location *)) {
	font-weight: 600;
	margin-block: 3.125rem 1.875rem; /* 50px / 30px */
}
.site-content .nomon-article :is(h1, h2):not(:where(.nomon-imagecard *, .nomon-account *, .wsf-form *, .nomon-business-location *)) { font-size: 2.25rem; } /* 36px */
.site-content .nomon-article h3:not(:where(.nomon-imagecard *, .nomon-account *, .wsf-form *, .nomon-business-location *)) { font-size: 1.75rem; } /* 28px */
.site-content .nomon-article h4:not(:where(.nomon-imagecard *, .nomon-account *, .wsf-form *, .nomon-business-location *)) { font-size: 1.5rem; } /* 24px */
.site-content .nomon-article h5:not(:where(.nomon-imagecard *, .nomon-account *, .wsf-form *, .nomon-business-location *)) { font-size: 1.25rem; } /* 20px */
.site-content .nomon-article h6:not(:where(.nomon-imagecard *, .nomon-account *, .wsf-form *, .nomon-business-location *)) { font-size: 1.125rem; } /* 18px */

/* Markers hang in the marker allowance so list text keeps the paragraphs' left
   edge. The list carries the body size itself — `1em` resolves against it. */
.site-content .nomon-article :is(ul, ol, li):not(:where(.nomon-imagecard *, .nomon-account *, .wsf-form *, .nomon-business-location *)) {
	font-size: 1.25rem;
	line-height: 1.8;
	font-weight: 300;
}
.site-content .nomon-article :is(ul, ol):not(:where(.nomon-imagecard *, .nomon-account *, .wsf-form *, .nomon-business-location *)) {
	padding-inline: 1em;
	margin-block: 0;
	list-style-position: outside;
}
.site-content .nomon-article li {
	margin-top: 0.625rem; /* 10px */
}

.site-content .nomon-article figure {
	margin-block: 2.8125rem 4.6875rem; /* 45px / 75px */
}

/* That gutter would stack on the article's own page gutter and double-indent;
   the article owns the content-region edges, so a child Group adds none. */
.site-content .nomon-article > .wp-block-group.has-global-padding {
	padding-inline: 0;
}

/* The wrapper's padding owns the content-region edges, so the first and last atoms must
   not add their own on top. Both depths are covered: pages wrap atoms in a Group, `post`
   is relaxed and leaves them at the article root. Reaching into the *first* wrapper only,
   so a page opening with a block keeps the normal gap before the prose after it. */
.site-content .nomon-article > :first-child,
.site-content .nomon-article > :first-child > :first-child {
	margin-top: 0;
}
.site-content .nomon-article > :last-child,
.site-content .nomon-article > :last-child > :last-child {
	margin-bottom: 0;
}

/* ==========================================================================
   Header search — Super Speedy Search (PHP API, header.php). We own the look, the
   plugin owns the behaviour. Scoped under `.nomon-search`. PROPOSED — pending sign-off.
   ========================================================================== */
.nomon-search { position: relative; }

/* Replaces the now-dequeued plugin stylesheet. Scoped to `.nomon-search`; the taxonomy
   margin rule below (0,3,0) out-specifies the `margin: 0` here (0,2,1). */
.nomon-search .sssresults ul,
.nomon-search .sssresults li {
	margin: 0;
	padding: 0;
	list-style: none;
}
.nomon-search .sssresults .sss_content {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	min-width: 0; /* let long titles truncate instead of stretching the row */
}
/* Drop the plugin's own outer border/radius on the form element — our pill border
   lives on `.ssswrapper`; without this you get a double border. */
.nomon-search .super-speedy-search-form,
.nomon-search form.super-speedy-searchform {
	position: relative; /* anchor for the absolutely-positioned results panel */
	margin: 0;
	border: 0;
	border-radius: 0;
	background: transparent;
}

/* Drop the plugin's mobile-reveal close affordance — not used in this inline form. */
.nomon-search .super-speedy-search-form > .sss_maybe_close_button { display: none; }

/* The plugin styles its controls at (0,2,1) and forces `min-width: 48px`, so every
   override below routes through `.super-speedy-search-form` to land at (0,3,1)+. */

/* The pill — mirrors the previous placeholder (h-11, rounded-full, subtle
   border + shadow), so swapping in the live field doesn't shift the header. */
.nomon-search .super-speedy-search-form .ssswrapper {
	display: flex;
	align-items: center;
	gap: 0.625rem;
	height: 2.75rem;
	padding: 0 1rem;
	border: 1px solid var(--wp--preset--color--border-subtle, #efefef);
	border-radius: 0;
	background: var(--wp--preset--color--background, #fff);
	box-shadow: 0 2px 4px rgb(0 0 0 / 0.03);
	/* Right edge only, same derivation as the nav trigger: height * tan(angle).
	   The clip also crops the border and shadow along the diagonal — both are
	   near-invisible here (#efefef and 3% black, on the ink header). */
	--search-slant: calc(2.75rem * tan(var(--skew-angle)) * -1);
	clip-path: polygon(0 0, 100% 0, calc(100% - var(--search-slant)) 100%, 0 100%);
}

/* The plugin's submit button, reordered left. Its glyph is an icon-font <i>, so we zero
   the font and mask in our own search.svg; clicking still submits. */
.nomon-search .super-speedy-search-form .ssswrapper .sssbuttonwrapper {
	order: -1;
	display: flex;
	align-items: center;
	height: auto;
}
.nomon-search .super-speedy-search-form .sssbuttonwrapper button {
	display: inline-grid;
	place-items: center;
	flex: 0 0 auto;
	min-width: 0;
	width: 1.25rem;
	height: 1.25rem;
	padding: 0;
	margin: 0;
	border: 0;
	background: transparent;
	color: var(--wp--preset--color--muted, #6c6c6c);
	cursor: pointer;
}
.nomon-search .super-speedy-search-form .sssbuttonwrapper button i {
	display: block;
	width: 1.125rem;
	height: 1.125rem;
	font-size: 0;
	background-color: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg transform='scale(1.3333)'%3E%3Cpath d='M14.205 12.952 18 16.746 16.746 18l-3.794-3.795a7.94 7.94 0 0 1-4.977 1.745A7.98 7.98 0 0 1 0 7.975 7.98 7.98 0 0 1 7.975 0a7.98 7.98 0 0 1 7.975 7.975 7.94 7.94 0 0 1-1.745 4.977m-1.778-.658a6.18 6.18 0 0 0 1.75-4.32 6.2 6.2 0 0 0-6.202-6.202 6.2 6.2 0 0 0-6.203 6.203 6.2 6.2 0 0 0 6.203 6.202 6.18 6.18 0 0 0 4.32-1.75z'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
	        mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg transform='scale(1.3333)'%3E%3Cpath d='M14.205 12.952 18 16.746 16.746 18l-3.794-3.795a7.94 7.94 0 0 1-4.977 1.745A7.98 7.98 0 0 1 0 7.975 7.98 7.98 0 0 1 7.975 0a7.98 7.98 0 0 1 7.975 7.975 7.94 7.94 0 0 1-1.745 4.977m-1.778-.658a6.18 6.18 0 0 0 1.75-4.32 6.2 6.2 0 0 0-6.202-6.202 6.2 6.2 0 0 0-6.203 6.203 6.2 6.2 0 0 0 6.203 6.202 6.18 6.18 0 0 0 4.32-1.75z'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
}
.nomon-search .super-speedy-search-form .sssbuttonwrapper button:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent, #ffd200);
	outline-offset: 2px;
}

.nomon-search .super-speedy-search-form .ssswrapper .sssinputwrapper {
	flex: 1 1 auto;
	display: flex;
	align-items: center;
	min-width: 0;
	padding: 0;
}
.nomon-search .super-speedy-search-form input.ssstext {
	flex: 1 1 auto;
	min-width: 0;
	width: 100%;
	height: 100%;
	min-height: 0;
	margin: 0;
	padding: 0;
	border: 0;
	outline: none;
	background: transparent;
	font: inherit;
	font-size: var(--wp--preset--font-size--regular);
	line-height: 1.4;
	color: var(--wp--preset--color--foreground, #000);
}
.nomon-search .super-speedy-search-form input.ssstext::placeholder {
	color: var(--wp--preset--color--muted, #6c6c6c);
	opacity: 1;
}

/* Clear (×) button removed by request — users clear the field manually. Hidden
   at (0,4,0) to beat the plugin's show rule on `.ssswrapper .sssresetwrapper`. */
.nomon-search .super-speedy-search-form .ssswrapper .sssresetwrapper {
	display: none;
}

/* Docked to the field so the two read as one box: `top: 100%` removes the gap and
   `border-top: 0` leaves the field's bottom border as the single divider. */
.nomon-search .super-speedy-search-form .sssresults.sssajax {
	/* Positioning previously provided by the dequeued plugin stylesheet. The plugin toggles
		   `display` inline via JS — we only style. */
	position: absolute;
	left: 0;
	right: 0;
	z-index: 999;
	overflow: hidden; /* clip rows to the rounded bottom corners; inner scroll handles overflow */
	top: 100%;
	background: var(--wp--preset--color--background, #fff); /* panel surface (plugin used to set this) */
	border: 1px solid var(--wp--preset--color--border-subtle, #efefef);
	border-top: 0;
	border-radius: 0;
	box-shadow: 0 12px 32px rgb(0 0 0 / 0.12);
	max-height: 70vh;
	padding: 0.5rem 0;
}

/* Visibility keys off the FIELD state plus the plugin's in-flight flag, not off whether
   the list holds rows: the plugin empties its containers for the ~100ms AJAX round-trip
   (marking the input `ssssearching`), so gating on `:has(li)` made the panel vanish mid-
   keystroke. Hide only when the field is empty, or when a result has SETTLED empty. */
.nomon-search .super-speedy-search-form:has( input.ssstext:placeholder-shown ) .sssresults.sssajax,
.nomon-search .super-speedy-search-form:not( :has( input.ssstext.ssssearching ) ) .sssresults.sssajax:not(:has(li)) {
	display: none !important;
}

.nomon-search .sss_scroll_container {
	max-height: calc(70vh - 1rem);
	padding: 0 0.25rem;
	overflow-y: auto; /* the panel's vertical scroll (plugin used to set this) */
	overflow-x: hidden;
}

/* Suppress the suggestions block (and its header) only when it holds NOTHING —
   no post-title suggestions, no taxonomy terms, and no taxonomy-combination
   (category) suggestions. Must cover all three: category suggestions render into
   `.sss-taxonomy-combinations`, so omitting it would hide the category section. */
.nomon-search .sss_suggestions_container:not(:has(.sss-suggestions li)):not(:has(.sss-taxonomies li)):not(:has(.sss-taxonomy-combinations li)) {
	display: none !important;
}

/* Section labels (Hakuehdotukset / Tuotteet / Tuoteryhmät). */
.nomon-search .sssresults .sss_list_header {
	padding: 0.5rem 0.75rem 0.25rem;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted, #6c6c6c);
}
/* The plugin paints the suggestions header a warm grey (#fbf8f8); drop it so the
   label sits on the panel's white surface like the other section labels. Selector
   matches the plugin's own (super-speedy-search.css) + `.nomon-search` to win on
   specificity. */
.nomon-search .super-speedy-search-form .sssresults .sss_suggestions_container .sss_list_header {
	background: none;
}

/* Suggestions, taxonomy links and product items share a hover surface
   (`.sss-taxonomy-combinations` is where native category suggestions render). */
.nomon-search .sssresults .sss-suggestions a,
.nomon-search .sssresults .sss-taxonomies a,
.nomon-search .sssresults .sss-taxonomy-combinations a,
.nomon-search .sssresults .sss_items li a {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	padding: 0.5rem 0.75rem;
	color: var(--wp--preset--color--foreground, #000);
	text-decoration: none;
	line-height: 1.3;
}
.nomon-search .sssresults .sss-suggestions a:hover,
.nomon-search .sssresults .sss-taxonomies a:hover,
.nomon-search .sssresults .sss-taxonomy-combinations a:hover,
.nomon-search .sssresults .sss_items li a:hover,
.nomon-search .sssresults .sss-suggestions a:focus,
.nomon-search .sssresults .sss-taxonomies a:focus,
.nomon-search .sssresults .sss-taxonomy-combinations a:focus,
.nomon-search .sssresults .sss_items li a:focus {
	background: var(--wp--preset--color--surface, #f1f3f8);
	color: var(--wp--preset--color--foreground, #000);
}
/* The plugin's own product-row hover (`… .sssresults.sssajax .sss_items a:hover`)
   carries 5 classes and out-specifies the shared rule above, so product rows
   would hover grey (#eeeeee) while suggestions/taxonomies hover with our surface
   tint. Match the plugin's selector + `.nomon-search` to win and unify them. */
.nomon-search .super-speedy-search-form .sssresults.sssajax .sss_items a:hover,
.nomon-search .super-speedy-search-form .sssresults.sssajax .sss_items a:focus {
	background: var(--wp--preset--color--surface, #f1f3f8);
}

/* The plugin bolds the matched portion in JS with no setting to disable it; render at
   the row's own weight. Selectors mirror and out-specify the plugin's `strong` rule. */
.nomon-search .sss_suggestions_container .sss-suggestions a strong,
.nomon-search .sss_suggestions_container .sss-taxonomies a strong,
.nomon-search .sss_suggestions_container .sss-taxonomy-combinations a strong {
	font-weight: inherit;
	color: inherit;
}
/* Per-category post count ("(33)") — the plugin always appends it in JS (no
   setting to disable). Hidden by request. Remove this rule to bring it back. */
.nomon-search .sssresults .sss-combo-count {
	display: none;
}
/* Taxonomy / category suggestion links ("Ruohonleikkurit") — a touch smaller
   and a little heavier than the default suggestion row, with breathing room
   above and below the taxonomy lists. (The matched-portion `strong` inherits
   this weight via the rule above.) */
.nomon-search .sssresults .sss-taxonomy-combinations,
.nomon-search .sssresults .sss-taxonomies {
	margin-block: 0.375rem;
}
/* Drop the plugin's grey tint so the list sits on the panel's white surface; selector
   mirrors the plugin's plus `.nomon-search` to win. */
.nomon-search .sssresults .sss_scroll_container ul.sss-taxonomy-combinations {
	background-color: transparent;
}
.nomon-search .sssresults .sss-taxonomy-combinations a,
.nomon-search .sssresults .sss-taxonomies a {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
}
.nomon-search .sssresults .sss_items .wp-post-image {
	width: 44px;
	height: 44px;
	object-fit: contain;
	/* Match the single-product gallery frame (1px border token, 4px radius, white);
		   `object-fit: contain` letterboxes onto the white. */
	border: 1px solid var(--wp--preset--color--border, #dbdbdb);
	background: #fff;
	flex-shrink: 0;
}
/* Imageless products — paint the bundled fallback. SSS has two render paths, both broken
   once its stylesheet is dequeued: fast-ajax emits a literal `<img src="">` (and bypasses
   theme loading, so no PHP filter can fix it) — hidden, with the placeholder injected as
   the row's `::before`, scoped by `:has()` so real thumbnails are untouched; the
   admin-ajax template emits an empty `.sss-placeholder`, which just takes a background. */
.nomon-search .sssresults .sss_items .wp-post-image[src=""],
.nomon-search .sssresults .sss_items .wp-post-image:not([src]) {
	display: none;
}
.nomon-search .sssresults .sss_items li a:has( > .wp-post-image[src=""] )::before,
.nomon-search .sssresults .sss_items li a:has( > .wp-post-image:not([src]) )::before,
.nomon-search .sssresults .sss_items .sss-placeholder {
	content: "";
	width: 44px;
	height: 44px;
	margin: 0;
	flex-shrink: 0;
	/* Same frame as the real thumbnail above. */
	border: 1px solid var(--wp--preset--color--border, #dbdbdb);
	background: #fff url('../img/placeholder.webp') center / cover no-repeat;
}
/* The plugin gives the thumbnail `margin: 4px 20px 4px 0` (20px right), which
   doubles up with the row's flex `gap` (0.75rem) → an oversized image↔content
   gap. Zero the margin so the flex gap alone owns the spacing. Selector mirrors
   the plugin's + `.nomon-search` to win on specificity. */
.nomon-search .super-speedy-search-form .sssresults .sss_items .wp-post-image {
	margin: 0;
}
/* The empty `.sss_flash` (sale badge) slot still occupies a flex `gap`, doubling the
   image↔content spacing. Collapse it when empty; a real badge still shows. */
.nomon-search .sssresults .sss_items li a .sss_flash:empty {
	display: none;
}
.nomon-search .sssresults .sss_items .sss-title {
	font-size: var(--wp--preset--font-size--regular);
	font-weight: 600;
}
/* Mirrors the product card, scaled for the panel. SSS prints `get_price_html()`, so the
   active price sits in `<ins>` and a sale adds a leading `<del>`. */
.nomon-search .sssresults .sss_items .sss_price {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	line-height: 1.3;
	color: var(--wp--preset--color--foreground, #000);
}
/* Current price (always `<ins>`) — bold; drop the UA underline on `<ins>`. Shown
   first to match the card's order (pill before struck price). */
.nomon-search .sssresults .sss_items .sss_price ins {
	order: 1;
	font-size: var(--wp--preset--font-size--regular);
	font-weight: 700;
	color: inherit;
	text-decoration: none;
}
/* On sale (`<del>` present): current price becomes the accent pill, white — like
   the card's sale price, smaller padding. */
.nomon-search .sssresults .sss_items .sss_price:has(del) ins {
	padding: 2px 8px;
	background: var(--wp--preset--color--accent, #ffd200);
	color: var(--wp--preset--color--ink, #07121c);
}
/* Old price (`<del>`) — small, medium, struck through, after the current price. */
.nomon-search .sssresults .sss_items .sss_price del {
	order: 2;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	color: var(--wp--preset--color--foreground, #000);
	text-decoration: line-through;
}

/* "See All" → the `nomon/button` light variant, full-width at the foot of the results.
   Needs the plugin's "See All" position = Bottom. Plugin-generated HTML, so we mirror the
   variant's token values rather than its classes and mask in the trailing arrow. */
.nomon-search .sssresults .bottom_see_all_wrapper {
	padding: 0.5rem 0.75rem 0.25rem;
}
/* Plugin makes `.bottom_see_all_wrapper` a flex row, so stretch the inner span
   (flex item) to full width — otherwise the button below shrinks to its label. */
.nomon-search .sssresults .bottom_see_all_wrapper .sss_see_all {
	flex: 1 1 auto;
	display: block;
}
.nomon-search .sssresults .bottom_see_all_wrapper .sss_see_all a {
	display: flex;
	width: 100%;
	align-items: center;
	justify-content: center;
	gap: 10px;
	padding: 17px 25px;
	background: var(--wp--preset--color--surface, #f1f3f8);
	color: var(--wp--preset--color--foreground, #000);
	font-size: 16px;
	font-weight: 700;
	line-height: 1.3;
	text-decoration: none;
	transition: background-color 0.15s;
}
.nomon-search .sssresults .bottom_see_all_wrapper .sss_see_all a:hover,
.nomon-search .sssresults .bottom_see_all_wrapper .sss_see_all a:focus {
	background: #e3e8f4;
}
.nomon-search .sssresults .bottom_see_all_wrapper .sss_see_all a:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent, #ffd200);
	outline-offset: 2px;
}
.nomon-search .sssresults .bottom_see_all_wrapper .sss_see_all a i {
	display: none;
}
.nomon-search .sssresults .bottom_see_all_wrapper .sss_see_all a::after {
	content: "";
	flex: 0 0 auto;
	width: 1rem;
	height: 1rem;
	background-color: var(--wp--preset--color--accent, #ffd200);
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' viewBox='0 0 16 16'%3E%3Cpath fill='%23000' d='M12.172 6.778 6.808 1.414 8.222 0 16 7.778l-7.778 7.778-1.414-1.414 5.364-5.364H0v-2h12.172Z'/%3E%3C/svg%3E") center / contain no-repeat;
	        mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' viewBox='0 0 16 16'%3E%3Cpath fill='%23000' d='M12.172 6.778 6.808 1.414 8.222 0 16 7.778l-7.778 7.778-1.414-1.414 5.364-5.364H0v-2h12.172Z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Whole-card click target via a stretched title link, the only anchor; the focus ring
 * rides the overlay. In main.css so it loads in the editor iframe too. */
.nomon-post-card {
	position: relative;
}
.nomon-post-card__link::after {
	content: "";
	position: absolute;
	inset: 0;
}
.nomon-post-card__link:focus-visible {
	outline: none;
}
.nomon-post-card__link:focus-visible::after {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}

/* Shared by every post listing. Pills echo the single-post share buttons: 44px targets,
   accent border and fill on current/hover. Scoped to .site-content so it can't leak. */
.site-content .pagination {
	margin-top: var(--section-space);
}
.site-content .pagination .nav-links {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
}
.site-content .pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	height: 44px;
	padding: 0 0.75rem;
	border: 1px solid var(--wp--preset--color--border);
	font-size: var(--wp--preset--font-size--regular);
	font-weight: 700;
	line-height: 1;
	color: var(--wp--preset--color--foreground);
	text-decoration: none;
	transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}
/* Accent is a ground, never text on white — yellow on white is 1.45:1. The
   hover reads through the border and underline instead. */
.site-content .pagination a.page-numbers:hover,
.site-content .pagination a.page-numbers:focus-visible {
	border-color: var(--wp--preset--color--accent);
	text-decoration: underline;
}
.site-content .pagination .page-numbers:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}
/* Ink on yellow, not white — white is 1.45:1 here. Same defect as the search
   button and add-to-cart; see the accent sweep in PROJECT.md. */
.site-content .pagination .page-numbers.current {
	background: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--ink);
}
.site-content .pagination .page-numbers.dots {
	min-width: 0;
	padding: 0 0.25rem;
	border-color: transparent;
}
/* Prev/next carry the arrow icon; flip the prev glyph to point back. */
.site-content .pagination .prev svg { transform: scaleX(-1); }

/* Single product. Woo's stylesheets are dequeued, so the Woo-rendered surfaces are
 * styled here; our own markup uses Tailwind on the templates. */

/* Main-gallery arrows — the homepage category strip's shape (skewed accent square,
   glyph counter-skewed upright in its own element), same 50px box. The transform
   lives here rather than in utilities for two reasons: the counter-skew needs a
   child element, and the server-side Tailwind compile doesn't register the
   `--tw-translate-*` @property defaults, so a `translate` utility resolves to
   `none` (see the thumb-strip note in product-gallery.php). */
.nomon-pg-nav {
	position: absolute;
	top: 50%;
	z-index: 10;
	display: grid;
	place-items: center;
	width: 50px;
	height: 50px;
	transform: translateY(-50%) skewX(var(--skew-angle));
	border: 0;
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--ink);
	cursor: pointer;
}
.nomon-pg-nav__icon {
	display: grid;
	place-items: center;
	transform: skewX(calc(var(--skew-angle) * -1));
}
/* Hidden at the ends of the track, as the strip's are — not dimmed like the
   thumb-strip arrows. */
.nomon-pg-nav.swiper-button-disabled,
.nomon-pg-nav.swiper-button-lock {
	display: none;
}
/* The UA ring is washed out against accent, so it's restated in ink. */
.nomon-pg-nav:focus-visible {
	outline: 2px solid var(--wp--preset--color--ink);
	outline-offset: 2px;
}

/* Dim inactive thumbs, accent border on the active one. Both sliders stay hidden until
 * Swiper inits (shared rule above). */
.nomon-product-gallery__thumbs .swiper-slide {
	opacity: 0.55;
	transition: opacity 0.15s ease;
}
.nomon-product-gallery__thumbs .swiper-slide-thumb-active,
.nomon-product-gallery__thumbs .swiper-slide:hover {
	opacity: 1;
}
/* The border width comes from the template (`border border-border`); this only
   recolours it, and unlayered beats Tailwind's `border-border` utility. */
.nomon-product-gallery__thumb {
	transition: border-color 0.15s ease;
}
.nomon-product-gallery__thumbs .swiper-slide-thumb-active .nomon-product-gallery__thumb {
	border-color: var(--wp--preset--color--accent);
}

/* Product accordions — native <details> (template-driven, no editor). */
/* Every row is opened by a top rule. Between rows that reads as the divider it
   always was; on the first it caps the stack — and nothing trails under the last
   row, where a bottom rule had nothing beneath it. */
.nomon-accordion {
	border-top: 1px solid #e0e0e0;
}
/* Air between rows, so each band reads as its own row rather than one continuous
   grey stack. Leading edge only — the last row still ends flush with the column. */
.nomon-accordion + .nomon-accordion {
	margin-top: 10px;
}
/* Header band. The Tailwind classes on the summary carry the vertical padding;
   the inline padding lives here so the band has breathing room at its edges. The
   panel below takes none — its copy runs the full column width. The right edge is
   cut at the canonical angle, derived from the row's own height (line box +
   padding) so it holds whatever the type scale does — same shape as the search
   bar and the nav trigger. The rule above stays on `.nomon-accordion`, full
   width, so the diagonal reads as a cut in the fill, not a ragged row edge. */
.nomon-accordion__summary {
	--acc-slant: calc((1.5em + 30px) * tan(var(--skew-angle)) * -1);

	list-style: none;
	/* Pinned rather than inherited (body is 1.618) so the slant derivation above
	   resolves off a known box, same as the stock pill. */
	line-height: 1.5;
	padding-inline: 15px calc(15px + var(--acc-slant));
	background-color: var(--wp--preset--color--surface-alt);
	clip-path: polygon(0 0, 100% 0, calc(100% - var(--acc-slant)) 100%, 0 100%);
}
/* Inset ring: the clip crops anything outside the border box, so the UA's own
   focus outline would be clipped away entirely. */
.nomon-accordion__summary:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: -4px;
}
.nomon-accordion__summary::-webkit-details-marker {
	display: none;
}
.nomon-accordion[open] .nomon-accordion__icon {
	transform: rotate(180deg);
}
/* Flush under the summary — the first element's top margin would otherwise add a
   stray gap. */
.nomon-accordion__panel > :first-child,
.wp-block-accordion-panel > :first-child {
	margin-top: 0;
}

/* The panel's own heading ramp. Client content runs through `the_content()`, so
   it lands on the global ramp in `@layer base` — sized for the 20px article
   column, where an h2 is 35px and would out-shout the 36px product name two
   sections above it. Same scale, shifted two steps down, so the panel reads
   against its own 15px body.

   No `line-height` here, for the same reason as the article column: this rule is
   unlayered and any value would silently beat the uppercase-Barlow ramp in
   `@layer base`. Size and margin are local; the rhythm stays central. */
.nomon-accordion__panel :is(h1, h2, h3, h4, h5, h6),
.wp-block-accordion-panel :is(h1, h2, h3, h4, h5, h6) {
	margin-block: 1.5rem 0.5rem; /* 24px / 8px — the base ramp's 48/24 is article-column spacing */
}
/* Restated: the unlayered rule above outranks the base ramp's own stacked-heading
   collapse, which would otherwise leave a 24px gap between adjacent headings. */
.nomon-accordion__panel :is(h1, h2, h3, h4, h5, h6) + :is(h1, h2, h3, h4, h5, h6),
.wp-block-accordion-panel :is(h1, h2, h3, h4, h5, h6) + :is(h1, h2, h3, h4, h5, h6) {
	margin-top: 0;
}
.nomon-accordion__panel :is(h1, h2),
.wp-block-accordion-panel :is(h1, h2) { font-size: var(--wp--preset--font-size--heading-4); } /* 22px */
.nomon-accordion__panel h3,
.wp-block-accordion-panel h3 { font-size: var(--wp--preset--font-size--heading-5); } /* 18px */
.nomon-accordion__panel :is(h4, h5, h6),
.wp-block-accordion-panel :is(h4, h5, h6) { font-size: var(--wp--preset--font-size--heading-6); } /* 16px */

/* Prose links. The panel isn't `.nomon-article`, so the article's link rule never
   reached it and Tailwind preflight's `text-decoration: inherit` left client links
   indistinguishable from body copy (WCAG 1.4.1). Underlined at rest; hover
   thickens rather than recolours — accent on white is 1.45:1. The external-link
   and new-window decorators are global, so they already apply here. */
.nomon-accordion__panel a:not(:where(.nomon-contact-people *)),
.wp-block-accordion-panel a:not(:where(.nomon-btn, .nomon-contact-people *, .wsf-form *)) {
	text-decoration: underline;
	text-underline-offset: 3px;
}
.nomon-accordion__panel a:not(:where(.nomon-contact-people *)):hover,
.wp-block-accordion-panel a:not(:where(.nomon-btn, .nomon-contact-people *, .wsf-form *)):hover {
	text-decoration-thickness: 2px;
}
.nomon-accordion__panel a:not(:where(.nomon-contact-people *)):focus-visible,
.wp-block-accordion-panel a:not(:where(.nomon-btn, .nomon-contact-people *, .wsf-form *)):focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}

/* Specs table from `wc_display_product_attributes()` inside the accordion. */
.nomon-accordion__panel .woocommerce-product-attributes {
	width: 100%;
	border-collapse: collapse;
}
.nomon-accordion__panel .woocommerce-product-attributes th,
.nomon-accordion__panel .woocommerce-product-attributes td {
	border-bottom: 1px solid var(--wp--preset--color--border);
	padding: 0.625rem 0;
	text-align: left;
	vertical-align: top;
}
.nomon-accordion__panel .woocommerce-product-attributes th {
	width: 40%;
	padding-right: 1rem;
	font-weight: 600;
}
.nomon-accordion__panel .woocommerce-product-attributes p {
	margin: 0;
}

/* Price (`get_price_html()`) — del = struck regular, ins = sale (no underline). */
.nomon-product__price ins {
	text-decoration: none;
}
.nomon-product__price del {
	margin-left: 0.5rem;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 400;
	color: var(--wp--preset--color--muted);
}

/* Native Woo form as a row: a −/+ stepper (enhanced from the number input in cart.js)
 * left, the add-to-cart button filling the rest. */
/* `align-items: center`, not `stretch`: form.cart is WooCommerce's injection point,
   so it also carries the variations table, grouped-product tables and any add-on's
   option UI. Under `stretch` the tallest of those set the row height and dragged the
   quantity and button up with it — a 390px builder made both 490px tall. */
.nomon-product__cart form.cart {
	margin: 0;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 15px;
}

/* Everything except the two controls takes its own row. Matched by exclusion so
   injected markup is covered without naming each plugin's classes. */
.nomon-product__cart form.cart > :not(.quantity):not(.single_add_to_cart_button) {
	flex: 1 0 100%;
}
.nomon-product__cart .quantity {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: stretch;
	min-height: 50px;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 0;
	overflow: hidden;
}
.nomon-product__cart .quantity .nomon-qty-btn {
	display: inline-flex;
	width: 44px;
	align-items: center;
	justify-content: center;
	border: 0;
	background: transparent;
	color: var(--wp--preset--color--foreground);
	cursor: pointer;
	transition: background-color 0.15s ease;
}
.nomon-product__cart .quantity .nomon-qty-btn svg {
	width: 16px;
	height: 16px;
}
.nomon-product__cart .quantity .nomon-qty-btn:not(:disabled):hover {
	background: var(--wp--preset--color--surface);
}
/* At a bound (stock ceiling / floor) the stepper disables the button so the
   limit is visible — greyed + not-allowed, no hover affordance. */
.nomon-product__cart .quantity .nomon-qty-btn:disabled {
	opacity: 0.35;
	cursor: not-allowed;
}
/* A dedicated display the stepper drives; the native input is the hidden source of
 * truth once enhanced. */
.nomon-product__cart .quantity .nomon-qty-value {
	display: inline-flex;
	min-width: 48px;
	align-items: center;
	justify-content: center;
	border-inline: 1px solid var(--wp--preset--color--border);
	font-weight: 700;
	color: var(--wp--preset--color--foreground);
	user-select: none;
}
.nomon-product__cart .quantity.nomon-qty--ready input.qty {
	display: none;
}
/* No-JS fallback: the native number input stays visible and usable. */
.nomon-product__cart .quantity input.qty {
	width: 48px;
	border: 0;
	border-inline: 1px solid var(--wp--preset--color--border);
	background: #fff;
	text-align: center;
	font: inherit;
	font-weight: 700;
	color: var(--wp--preset--color--foreground);
	-moz-appearance: textfield;
	appearance: textfield;
}
.nomon-product__cart .quantity input.qty::-webkit-outer-spin-button,
.nomon-product__cart .quantity input.qty::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}
/* The summary renders its own stock indicator (dot + label), so hide
 * WooCommerce's plain `.stock` availability line in the add-to-cart area. */
.nomon-product__cart .stock {
	display: none;
}
/* Ink on yellow, not white: white here is ~1.9:1, the same defect the live
   search button carries (see docs/design-spec.md). Live uses black too. */
.nomon-product__cart .single_add_to_cart_button {
	display: flex;
	flex: 1 1 auto;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	border: 0;
	border-radius: 0;
	background: var(--wp--preset--color--accent);
	/* Right edge only, same derivation as the stock pill / nav trigger:
	   height * tan(angle). The extra right padding keeps the label optically
	   centred inside the cropped box. */
	--atc-slant: calc(50px * tan(var(--skew-angle)) * -1);

	padding: 0 calc(1.5rem + var(--atc-slant)) 0 1.5rem;
	min-height: 50px;
	/* Barlow Condensed uppercase, as everywhere else the condensed face appears
	   (nav, product menu, category strip) — and a step up the scale, since the
	   narrower face reads smaller than Inter at the same size. */
	font-family: var(--wp--preset--font-family--barlow-condensed);
	font-size: 1.25rem; /* 20px — between `large` and `heading-4`, which the scale has no token for */
	font-weight: 700;
	line-height: 1;
	text-transform: uppercase;
	letter-spacing: 0.5px;
	color: var(--wp--preset--color--foreground);
	cursor: pointer;
	transition: background-color 0.15s ease, color 0.15s ease;
	clip-path: polygon(0 0, 100% 0, calc(100% - var(--atc-slant)) 100%, 0 100%);
}
.nomon-product__cart .single_add_to_cart_button:hover,
.nomon-product__cart .single_add_to_cart_button:focus-visible {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--background);
}
/* Inset ring: the clip-path above crops anything outside the border box, so an
   offset outline would be clipped away entirely. Drawn inside instead, against
   the ink focus background. */
.nomon-product__cart .single_add_to_cart_button:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: -4px;
}
.nomon-product__cart .single_add_to_cart_button.disabled,
.nomon-product__cart .single_add_to_cart_button[disabled] {
	opacity: 0.5;
	cursor: not-allowed;
}
/* After a successful AJAX add (cart.js playAddSuccess) the button swaps its label for a
   transient confirmation, restored after ~2.6s. */
.nomon-product__cart .single_add_to_cart_button.nomon-atc-success {
	gap: 0; /* the label animates in its own margin so the icon centres alone first */
	background: var(--wp--preset--color--ink, var(--wp--preset--color--accent));
	pointer-events: none;
}
.nomon-atc-icon {
	display: inline-flex;
	align-items: center;
	/* Negative block margins keep the icon visually 1.25em while contributing ~1em to the
		   flex line box, so the swap never makes the button taller than at rest. */
	margin-block: -0.125em;
	animation: nomon-atc-icon-in 0.45s cubic-bezier(0.19, 1, 0.22, 1) both;
}
.nomon-atc-icon svg {
	display: block;
	width: 1.25em;
	height: 1.25em;
}
.nomon-atc-label {
	display: inline-block;
	max-width: 0;
	overflow: hidden;
	white-space: nowrap;
	opacity: 0;
	animation: nomon-atc-label-in 0.35s ease 0.45s both;
}
@keyframes nomon-atc-icon-in {
	from { transform: translateX(-2.5em); opacity: 0; }
	to   { transform: translateX(0); opacity: 1; }
}
@keyframes nomon-atc-label-in {
	from { max-width: 0; margin-left: 0; opacity: 0; }
	to   { max-width: 24ch; margin-left: 0.5rem; opacity: 1; }
}
/* Reduced-motion: skip the slide/expand, just show the confirmation. */
@media (prefers-reduced-motion: reduce) {
	.nomon-atc-icon { animation: none; }
	.nomon-atc-label {
		animation: none;
		max-width: 24ch;
		margin-left: 0.5rem;
		opacity: 1;
	}
}
/* Out-of-stock fallback button stands alone (not inside `form.cart`), so it
   has no flex parent to stretch into — give it full width itself. */
.nomon-product__cart > .single_add_to_cart_button {
	width: 100%;
}

/* Variation selects (variable products) — minimal usable styling. */
.nomon-product__cart .variations {
	width: 100%;
	margin-bottom: 1rem;
	border-collapse: collapse;
}
.nomon-product__cart .variations th,
.nomon-product__cart .variations td {
	padding: 0.25rem 0 0.75rem;
	text-align: left;
	vertical-align: middle;
}
.nomon-product__cart .variations label {
	font-weight: 600;
}
.nomon-product__cart .variations select {
	width: 100%;
	border: 1px solid var(--wp--preset--color--border);
	background: #fff;
	padding: 0.625rem 0.75rem;
	font: inherit;
}
.nomon-product__cart .reset_variations {
	display: inline-block;
	margin-bottom: 1rem;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--muted);
}
.nomon-product__cart .woocommerce-variation-price {
	margin-bottom: 1rem;
	font-size: 20px;
	font-weight: 700;
}

/* ===========================================================================
 * WooCommerce — "Oma tili". Scoped to the `woocommerce-account` body class so cart /
 * checkout / shop are untouched. Woo's stylesheets are dequeued, so every surface here
 * is built from theme tokens and the buttons mirror add-to-cart.
 * ========================================================================== */

/* ── Shared: notices ─────────────────────────────────────────────────────── */
.woocommerce-account .woocommerce-message,
.woocommerce-account .woocommerce-error,
.woocommerce-account .woocommerce-info {
	margin: 0 0 1.5rem;
	padding: 0.875rem 1.125rem;
	border-left: 4px solid var(--wp--preset--color--accent);
	background: var(--wp--preset--color--surface);
	list-style: none;
	font-size: var(--wp--preset--font-size--regular);
}
.woocommerce-account .woocommerce-message { border-left-color: var(--wp--preset--color--success); }
.woocommerce-account .woocommerce-error { border-left-color: var(--wp--preset--color--danger); }
.woocommerce-account .woocommerce-error li { list-style: none; }

/* ── Shared: form controls ───────────────────────────────────────────────── */
.woocommerce-account .woocommerce form .form-row,
.woocommerce-account .woocommerce-form-row {
	display: flex;
	flex-direction: column;
	gap: 0.375rem;
	margin: 0 0 1rem;
}
.woocommerce-account .woocommerce label {
	font-size: var(--wp--preset--font-size--regular);
	font-weight: 600;
	color: var(--wp--preset--color--foreground);
}
.woocommerce-account .woocommerce label .required {
	color: var(--wp--preset--color--danger);
	border: 0;
}
.woocommerce-account .woocommerce input.input-text,
.woocommerce-account .woocommerce input[type="text"],
.woocommerce-account .woocommerce input[type="email"],
.woocommerce-account .woocommerce input[type="tel"],
.woocommerce-account .woocommerce input[type="password"],
.woocommerce-account .woocommerce select,
.woocommerce-account .woocommerce textarea {
	width: 100%;
	border: 1px solid var(--wp--preset--color--border);
	background: #fff;
	padding: 0.75rem 0.875rem;
	font: inherit;
	line-height: 1.4;
	color: var(--wp--preset--color--foreground);
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.woocommerce-account .woocommerce input.input-text:focus,
.woocommerce-account .woocommerce select:focus,
.woocommerce-account .woocommerce textarea:focus {
	outline: none;
	border-color: var(--wp--preset--color--accent);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--wp--preset--color--accent) 18%, transparent);
}
/* "Remember me" / checkbox rows read as a single inline line, not a label block. */
.woocommerce-account .woocommerce-form-login__rememberme {
	flex-direction: row;
	align-items: center;
	gap: 0.5rem;
	font-weight: 500;
}
.woocommerce-account .woocommerce-form-login__rememberme input { width: auto; }
.woocommerce-account .woocommerce form .password-input { display: block; }

/* ── Shared: buttons ─────────────────────────────────────────────────────── */
.woocommerce-account .woocommerce button.button,
.woocommerce-account .woocommerce input.button,
.woocommerce-account .woocommerce button[type="submit"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	border: 0;
	background: var(--wp--preset--color--accent);
	padding: 0.875rem 1.5rem;
	font-size: 1rem;
	font-weight: 700;
	line-height: 1;
	color: var(--wp--preset--color--ink);
	cursor: pointer;
	transition: background-color 0.15s ease, color 0.15s ease;
}
/* The hover flips the ground to ink, so it must flip the text too — inheriting
   the ink base would paint ink on ink. */
.woocommerce-account .woocommerce button.button:hover,
.woocommerce-account .woocommerce input.button:hover,
.woocommerce-account .woocommerce button[type="submit"]:hover {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--background);
}
.woocommerce-account .woocommerce button.button:focus-visible,
.woocommerce-account .woocommerce input.button:focus-visible,
.woocommerce-account .woocommerce button[type="submit"]:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}
/* Link-styled buttons (order actions, "Näytä", address edit) read as the quiet
   soft sibling — surface fill, dark text — so the page has one primary accent CTA. */
.woocommerce-account .woocommerce a.button,
.woocommerce-account .nomon-account-recent__view {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: var(--wp--preset--color--surface);
	padding: 0.625rem 1.125rem;
	font-size: var(--wp--preset--font-size--regular);
	font-weight: 600;
	line-height: 1;
	color: var(--wp--preset--color--foreground);
	text-decoration: none;
	transition: background-color 0.15s ease;
}
.woocommerce-account .woocommerce a.button:hover,
.woocommerce-account .nomon-account-recent__view:hover {
	background: var(--wp--preset--color--border);
}

/* ── Logged out: login primary + create-account aside ────────────────────── */
.woocommerce-account:not(.logged-in) .woocommerce {
	max-width: 620px;
	margin-inline: auto;
}
.woocommerce-account #customer_login {
	display: flex;
	flex-direction: column;
	gap: 2rem;
}
.woocommerce-account #customer_login h2 {
	margin: 0 0 1.25rem;
	font-size: 1.5rem;
	font-weight: 700;
}
/* Login = the prominent card. */
.woocommerce-account #customer_login .u-column1 {
	width: 100%;
	max-width: 440px;
	margin-inline: auto;
	padding: 2rem;
	background: #fff;
	border: 1px solid var(--wp--preset--color--border);
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
}
.woocommerce-account #customer_login .u-column1 button.button { width: 100%; }
.woocommerce-account .woocommerce-LostPassword {
	margin: 0.875rem 0 0;
	font-size: var(--wp--preset--font-size--regular);
}
.woocommerce-account .woocommerce-LostPassword a { text-decoration: underline; }
/* Register = the quieter surface panel below, separated by a labelled rule. */
.woocommerce-account #customer_login .u-column2 {
	width: 100%;
	max-width: 540px;
	margin-inline: auto;
	padding: 1.75rem 2rem;
	background: var(--wp--preset--color--surface);
}
.woocommerce-account #customer_login .u-column2 h2 {
	font-size: 1.25rem;
}
.woocommerce-account #customer_login .u-column2 button.button { width: 100%; }
/* Benefits checklist injected into the register form (woocommerce.php). */
.nomon-account-benefits__lead {
	margin: 0 0 0.625rem;
	font-weight: 600;
}
.nomon-account-benefits {
	list-style: none;
	margin: 0 0 1.25rem;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0.625rem;
}
.nomon-account-benefits li {
	display: flex;
	align-items: flex-start;
	gap: 0.625rem;
	font-weight: 500;
}
.nomon-account-benefits li svg {
	width: 1rem;
	height: 1rem;
	flex: 0 0 auto;
	margin-top: 0.2rem;
	color: var(--wp--preset--color--success);
}

/* ── Logged in: two-column shell ─────────────────────────────────────────── */

/* The shell sits in `.nomon-article`, which is viewport-wide and caps only its prose, so
   without this the sidebar starts at the viewport edge. Same hand-rolled
   `has-global-padding is-layout-constrained` as the image card. */
.woocommerce-account .nomon-account {
	box-sizing: border-box;
	width: 100%;
	max-width: calc(
		var(--wp--style--global--content-size) +
		var(--wp--style--root--padding-left) +
		var(--wp--style--root--padding-right)
	);
	margin-inline: auto;
	padding-inline: var(--wp--style--root--padding-left)
		var(--wp--style--root--padding-right);
}

/* Wrapped in a Group (the atom rule; cutover applies it). The article zeroes nested
   global padding, so the wrapper must re-assert it — the constrained cap alone only
   looks aligned above the content size, and goes flush left below it. */
.woocommerce-account .nomon-article > .wp-block-group.has-global-padding {
	padding-inline: var(--wp--style--root--padding-left)
		var(--wp--style--root--padding-right);
}
.woocommerce-account .has-global-padding .nomon-account {
	max-width: none;
	padding-inline: 0;
}

@media (min-width: 1024px) {
	.woocommerce-account .nomon-account {
		display: grid;
		grid-template-columns: 260px 1fr;
		gap: 50px;
		align-items: start;
	}
	.woocommerce-account .woocommerce-MyAccount-navigation {
		position: sticky;
		top: 30px;
	}
}
.woocommerce-account .woocommerce-MyAccount-content { min-width: 0; }
.woocommerce-account .woocommerce-MyAccount-content > :first-child { margin-top: 0; }

/* Sidebar nav — vertical list on desktop, a horizontal scroll-row on mobile. */
.woocommerce-account .woocommerce-MyAccount-navigation ul {
	list-style: none;
	margin: 0 0 2rem;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 4px;
}
.woocommerce-account .woocommerce-MyAccount-navigation a {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	padding: 0.75rem 1rem;
	color: var(--wp--preset--color--foreground);
	font-weight: 600;
	text-decoration: none;
	white-space: nowrap;
	transition: background-color 0.15s ease, color 0.15s ease;
}
.woocommerce-account .woocommerce-MyAccount-navigation a svg {
	width: 20px;
	height: 20px;
}
.woocommerce-account .woocommerce-MyAccount-navigation a:hover {
	background: var(--wp--preset--color--surface);
}
.woocommerce-account .woocommerce-MyAccount-navigation .is-active a {
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--ink);
}
@media (max-width: 1023px) {
	.woocommerce-account .woocommerce-MyAccount-navigation ul {
		flex-direction: row;
		overflow-x: auto;
		gap: 8px;
		margin-bottom: 1.5rem;
		padding-bottom: 8px;
		-webkit-overflow-scrolling: touch;
	}
	.woocommerce-account .woocommerce-MyAccount-navigation li { flex: 0 0 auto; }
	.woocommerce-account .woocommerce-MyAccount-navigation a {
		border: 1px solid var(--wp--preset--color--border);
	}
	.woocommerce-account .woocommerce-MyAccount-navigation .is-active a { border-color: transparent; }
}

/* ── Dashboard ───────────────────────────────────────────────────────────── */
.nomon-account-dash__greeting {
	margin: 0;
	font-size: 1.5rem;
	font-weight: 700;
}
.nomon-account-dash__intro {
	margin: 0.5rem 0 1.75rem;
	color: var(--wp--preset--color--muted);
	max-width: 60ch;
}
.nomon-account-cards {
	display: grid;
	gap: 1rem;
	grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
	margin-bottom: 2.5rem;
}
.nomon-account-card {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	padding: 1.25rem;
	border: 1px solid var(--wp--preset--color--border);
	color: var(--wp--preset--color--foreground);
	text-decoration: none;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.nomon-account-card:hover {
	border-color: var(--wp--preset--color--accent);
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
}
.nomon-account-card__icon { color: var(--wp--preset--color--accent); }
.nomon-account-card__icon svg { width: 1.5rem; height: 1.5rem; }
.nomon-account-card__title { font-weight: 700; }
.nomon-account-card__desc {
	font-size: var(--wp--preset--font-size--regular);
	color: var(--wp--preset--color--muted);
}

/* Recent orders. */
.nomon-account-recent__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	margin-bottom: 1rem;
}
.nomon-account-recent__title { margin: 0; font-size: var(--wp--preset--font-size--large); font-weight: 600; }
.nomon-account-recent__all { font-size: var(--wp--preset--font-size--regular); font-weight: 600; text-decoration: underline; }
.nomon-account-recent__list { list-style: none; margin: 0; padding: 0; }
.nomon-account-recent__row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem 1rem;
	padding: 0.875rem 0;
	border-top: 1px solid var(--wp--preset--color--border-subtle);
}
.nomon-account-recent__row:last-child { border-bottom: 1px solid var(--wp--preset--color--border-subtle); }
.nomon-account-recent__num { font-weight: 700; color: var(--wp--preset--color--foreground); text-decoration: none; }
.nomon-account-recent__num:hover { text-decoration: underline; }
.nomon-account-recent__date { color: var(--wp--preset--color--muted); font-size: var(--wp--preset--font-size--small); }
.nomon-account-recent__total { color: var(--wp--preset--color--muted); font-size: var(--wp--preset--font-size--small); }
.nomon-account-recent__view { margin-left: auto; }
.nomon-account-recent__empty { color: var(--wp--preset--color--muted); }

/* Base + tone modifiers. Plain CSS, not utilities, so it survives the Blockstudio
   Tailwind scan regardless of what it sees. */
.woocommerce-account .nomon-order-status {
	display: inline-flex;
	align-items: center;
	padding: 0.25rem 0.625rem;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	line-height: 1.2;
	color: #fff;
	white-space: nowrap;
}
.woocommerce-account .nomon-order-status--green  { background: var(--wp--preset--color--success); }
/* Accent tones take ink text — the base white is 1.9:1 on yellow. */
.woocommerce-account .nomon-order-status--blue,
.woocommerce-account .nomon-order-status--orange {
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--ink);
}
.woocommerce-account .nomon-order-status--red    { background: var(--wp--preset--color--danger); }
.woocommerce-account .nomon-order-status--grey   { background: var(--wp--preset--color--muted); }

/* ── Orders / addresses tables ───────────────────────────────────────────── */
.woocommerce-account .woocommerce table.shop_table {
	width: 100%;
	margin: 0 0 1.5rem;
	border-collapse: collapse;
	border: 0;
}
.woocommerce-account .woocommerce table.shop_table th {
	padding: 0.75rem 0.875rem;
	border-bottom: 2px solid var(--wp--preset--color--border);
	text-align: left;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	color: var(--wp--preset--color--muted);
}
.woocommerce-account .woocommerce table.shop_table td {
	padding: 1rem 0.875rem;
	border-bottom: 1px solid var(--wp--preset--color--border-subtle);
	vertical-align: middle;
}
.woocommerce-account .woocommerce table.shop_table .woocommerce-orders-table__cell-order-number a { font-weight: 700; }
.woocommerce-account .woocommerce table.shop_table .woocommerce-orders-table__cell-order-actions { text-align: right; }
.woocommerce-account .woocommerce table.shop_table .woocommerce-orders-table__cell-order-actions .button { margin-left: 0.5rem; }

/* Five columns need ~538px and the pane is viewport-wide once the shell stops
   being two-column, so the table is stacked into labelled rows below 640px.
   WooCommerce's markup already carries the contract for this — `data-title` on
   every cell — but its stylesheet, which normally implements it, is dequeued. */
@media (max-width: 639px) {
	.woocommerce-account .woocommerce table.shop_table_responsive thead {
		position: absolute;
		width: 1px;
		height: 1px;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
	}
	.woocommerce-account .woocommerce table.shop_table_responsive tr {
		display: block;
		margin-bottom: 1rem;
		border-bottom: 1px solid var(--wp--preset--color--border);
	}
	.woocommerce-account .woocommerce table.shop_table_responsive td {
		display: flex;
		align-items: baseline;
		justify-content: space-between;
		gap: 1rem;
		padding: 0.5rem 0;
		border: 0;
		text-align: right;
	}
	.woocommerce-account .woocommerce table.shop_table_responsive td::before {
		content: attr(data-title);
		flex: 0 0 auto;
		font-size: var(--wp--preset--font-size--small);
		font-weight: 700;
		text-align: left;
		color: var(--wp--preset--color--muted);
	}
	.woocommerce-account .woocommerce table.shop_table_responsive .woocommerce-orders-table__cell-order-actions .button { margin-left: 0; }
}

/* Addresses — two cards. */
.woocommerce-account .woocommerce-Addresses {
	display: grid;
	gap: 1.5rem;
	margin-top: 1rem;
}
/* WooCommerce marks these cards `col-1` / `col-2` as semantic names, but those
   are also Tailwind utilities (`grid-column: 1` / `2`), so the second card was
   pinned to an implicit second column at every width and overflowed the page on
   mobile. Auto-placement fills the template instead. */
.woocommerce-account .woocommerce-Addresses > * {
	grid-column: auto;
}
@media (min-width: 768px) {
	.woocommerce-account .woocommerce-Addresses { grid-template-columns: 1fr 1fr; }
}
.woocommerce-account .woocommerce-Address {
	padding: 1.5rem;
	border: 1px solid var(--wp--preset--color--border);
}
.woocommerce-account .woocommerce-Address-title {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	margin-bottom: 0.875rem;
}
.woocommerce-account .woocommerce-Address-title h2,
.woocommerce-account .woocommerce-Address-title h3 {
	margin: 0;
	font-size: var(--wp--preset--font-size--large);
	font-weight: 700;
}
.woocommerce-account .woocommerce-Address-title .edit {
	font-size: var(--wp--preset--font-size--regular);
	font-weight: 600;
	text-decoration: underline;
}
.woocommerce-account .woocommerce-Address address {
	font-style: normal;
	line-height: 1.6;
	color: var(--wp--preset--color--foreground);
}

/* Account-details form — keep the editing form to a comfortable reading width. */
.woocommerce-account .woocommerce-EditAccountForm { max-width: 560px; }
.woocommerce-account .woocommerce-EditAccountForm fieldset {
	margin: 1.5rem 0 0;
	padding: 1.25rem 0 0;
	border: 0;
	border-top: 1px solid var(--wp--preset--color--border-subtle);
}
.woocommerce-account .woocommerce-EditAccountForm legend {
	padding: 0;
	font-weight: 700;
}


/* ----- core/accordion — the product accordion's band, editor-facing -------
   `.nomon-accordion` above is template-driven and never reaches the editor, so
   the block a client actually inserts (`core/accordion`) shipped unstyled on
   core's defaults. These rules give it the same band: `surface-alt` fill, the
   canonical slanted right edge, 10px between rows, chevron toggle. Both stacks
   now render identically; the panel typography above is shared by selector.

   Unlayered on purpose. The heading element carries the global uppercase
   Barlow ramp from `@layer base`, which would out-shout a 16px control band —
   these rules sit outside the layer so they win, the same trick the panel's own
   heading ramp uses. */
.wp-block-accordion-item {
	border-top: 1px solid #e0e0e0;
}
.wp-block-accordion-item + .wp-block-accordion-item {
	margin-top: 10px;
}
/* The band is a control, not a heading: Inter at the body size, sentence case,
   regardless of which heading level the editor picked. */
.wp-block-accordion-heading {
	margin: 0;
	font-family: var(--wp--preset--font-family--inter);
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.5;
	text-transform: none;
	letter-spacing: normal;
}
/* Same derivation as `.nomon-accordion__summary`: the cut is taken from the
   row's own height (line box + padding), so it holds if the type scale moves. */
.wp-block-accordion-heading__toggle {
	--acc-slant: calc((1.5em + 30px) * tan(var(--skew-angle)) * -1);

	gap: 1rem;
	padding: 15px calc(15px + var(--acc-slant)) 15px 15px;
	background-color: var(--wp--preset--color--surface-alt);
	color: var(--wp--preset--color--foreground);
	clip-path: polygon(0 0, 100% 0, calc(100% - var(--acc-slant)) 100%, 0 100%);
}
/* Core underlines the title on hover; the band already reads as a control and
   the underline fights the slant. */
.wp-block-accordion-heading__toggle:hover .wp-block-accordion-heading__toggle-title {
	text-decoration: none;
}
/* Inset ring — the clip would crop an outset outline away entirely. */
.wp-block-accordion-heading__toggle:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: -4px;
}
.wp-block-accordion-heading__toggle-icon {
	width: 0.75rem;
	height: 0.75rem;
	flex: none;
}
/* Core turns its `+` into `×` with a 45deg twist. `inc/integrations/core-blocks.php`
   swaps that glyph for `chevron.svg` to match the product page, and a chevron
   wants a half turn instead. */
.wp-block-accordion-item.is-open > .wp-block-accordion-heading .wp-block-accordion-heading__toggle-icon {
	transform: rotate(180deg);
}
.wp-block-accordion-panel {
	padding-block: 20px;
	font-size: var(--wp--preset--font-size--regular);
	line-height: 1.618;
}
