﻿/*
 * Single source of truth for the brand token system.
 * (This is the only :root in the theme — style.css is header-only.)
 * Brand tokens are named to match their intended role; the base field colour
 * is confirmed, while remaining exact brand values can still be swapped here.
 */
:root {
	--color-sage: #879484;                 /* soft sage — larger brand fields and decorative use */
	--color-sage-deep: #556457;            /* deep sage — primary actions and high-contrast brand chrome */
	--color-stone: #FAF7F2;                /* soft warm white — confirmed page field  */
	--color-cream: #F2ECE1;                /* warm cream — section-band tone (the freed-up old field) */
	--color-gold: #C4A870;                 /* soft gold accent                         */
	--color-ink: #1A1A18;                  /* charcoal text                            */
	--color-white: #FFFFFF;
	--font-display: 'Playfair Display', Georgia, serif;
	--font-body: Georgia, serif; /* placeholder until body font confirmed */

	/*
	 * Derived surface + ink tones.
	 * These are computed from the brand tokens above (never hardcoded), so
	 * confirming the real brand hexes updates every surface in one place.
	 */
	--surface-page: var(--color-stone);
	--surface-warm: var(--color-cream);   /* second section tone — floats as an inset band in the page field */
	--surface-raised: var(--color-white);
	--surface-topbar: var(--color-sage-deep); /* decisive brand band; stone text = 5.87:1 AA */
	--surface-ink: var(--color-ink);
	--line: color-mix(in srgb, var(--color-ink) 14%, transparent);
	--line-warm: color-mix(in srgb, var(--color-ink) 20%, transparent); /* hairlines promoted for the warmer cream band (verified to hold) */
	--line-strong: color-mix(in srgb, var(--color-ink) 24%, transparent);
	--ink-soft: color-mix(in srgb, var(--color-ink) 65%, var(--color-stone));
	--color-sage-text: color-mix(in srgb, var(--color-sage) 60%, var(--color-ink)); /* text-safe sage for eyebrows/labels — >=4.5:1 on stone (5.83) & cream (5.30); keep --color-sage for decorative/large use */
	--ink-on-dark: color-mix(in srgb, var(--color-white) 88%, var(--color-stone));
	--ink-on-sage: var(--color-stone);
	--gold-line: color-mix(in srgb, var(--color-gold) 70%, transparent);
	--sage-veil: color-mix(in srgb, var(--color-sage) 55%, transparent);

	/* Spacing rhythm — 4px base, one scale for every gap and pad. */
	--space-3xs: 0.25rem;
	--space-2xs: 0.5rem;
	--space-xs: 0.75rem;
	--space-sm: 1rem;
	--space-md: 1.5rem;
	--space-lg: 2rem;
	--space-xl: 3rem;
	--space-2xl: 4rem;
	--space-3xl: 5rem;

	/* Shared layout primitives. */
	--container: 72rem;   /* max content width */
	--topbar-h: 2.75rem;  /* one-line mobile announcement + 44px dismiss target */
	--nav-primary-h: 4.6875rem;
	--nav-secondary-h: 0rem;
	--nav-h: calc(var(--nav-primary-h) + var(--nav-secondary-h));
	--nav-ease: cubic-bezier(0.4, 0, 0.2, 1); /* the quiet nav state-swap easing */
	--radius-sm: 2px;     /* controls, cards — kept tight for a precise, non-soft feel */
	--radius-md: 4px;

	/* Fluid modular type scale. */
	--step--1: clamp(0.8125rem, 0.79rem + 0.11vw, 0.875rem);
	--step-0: clamp(1rem, 0.97rem + 0.15vw, 1.0625rem);
	--step-1: clamp(1.1875rem, 1.12rem + 0.34vw, 1.375rem);
	--step-2: clamp(1.375rem, 1.24rem + 0.68vw, 1.75rem);
	--step-3: clamp(1.5rem, 1.28rem + 1.1vw, 2.125rem);
	--step-4: clamp(2rem, 1.6rem + 2vw, 2.75rem);
	--step-5: clamp(2.5rem, 1.9rem + 3vw, 4rem);
}

/* Navbar grows a touch on wider viewports. */
@media (min-width: 48em) {
	:root {
		--topbar-h: 1.75rem;
		/* The utility row stays comfortably above its 44px controls without
		   consuming the first product-viewing fold. */
		--nav-primary-h: 3.25rem;
		--nav-secondary-h: 2.75rem;
	}
}

/* ============================================================
   Base / reset
   (All global styling lives here; style.css is the theme header only.)
   ============================================================ */
*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	font-size: 100%;
	-webkit-text-size-adjust: 100%;
	/* Reserve the full chrome height (announcement bar + navbar tier 1) for in-page
	   anchor jumps so a targeted heading (#our-story, #newsletter, #contact) is never
	   tucked under the fixed/sticky banner. Uses the live tokens, so it tracks the
	   responsive bar heights. The desktop nav tier is small enough that the extra
	   --space-md keeps anchors clear on both breakpoints. */
	scroll-padding-top: calc(var(--topbar-h) + var(--nav-h) + var(--space-md));
}

body {
	margin: 0;
	background: var(--surface-page);
	color: var(--color-ink);
	font-family: var(--font-body);
	font-size: var(--step-0);
	line-height: 1.6;
}

img,
picture,
video,
canvas,
svg {
	display: block;
	max-width: 100%;
	height: auto;
}

a {
	color: currentColor;
}

/* Two-tone focus ring: an ink outer ring guarantees >=3:1 against the light
   fields (stone 16.3:1, cream 14.8:1), while the gold inner ring keeps the brand
   accent and stays visible against dark elements (gold vs ink 7.62:1). Holds on
   every ground the theme actually focuses on. Elements with a resting box-shadow
   (PDP swatches) re-append it in their own focus rule so the ring doesn't clobber it. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
	outline: 2px solid var(--color-ink);
	outline-offset: 3px;
	box-shadow: 0 0 0 3px var(--color-gold);
}

:where(h1, h2, h3, h4) {
	font-family: var(--font-display);
	font-weight: 500;
	line-height: 1.1;
	color: var(--color-ink);
}

.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* ============================================================
   Layout chrome — main, footer
   ============================================================ */
.site-main {
	width: min(100% - 2rem, var(--container));
	margin-inline: auto;
	padding-block: var(--space-lg);
}

/* ============================================================
   Site footer — sitewide chrome. A quiet, premium "floor": a full-bleed
   warm-cream band with a top hairline, holding the brand + social links, three
   wayfinding groups (Shop / Company / Support), a slim (UI-only) newsletter,
   and a copyright rule. Full-bleed ground with a container-constrained inner —
   the same idiom as the header. Cart/checkout use a compact commerce footer
   instead (cart-checkout.css).
   ============================================================ */
.site-footer {
	margin-top: var(--space-3xl);
	background: var(--surface-warm);
	border-top: 1px solid var(--line-warm);
	color: var(--ink-soft);
}

.site-footer__inner {
	width: min(100% - 2rem, var(--container));
	margin-inline: auto;
	padding-block: var(--space-2xl) var(--space-lg);
}

.site-footer__top {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-xl);
}

.site-footer__brand {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-sm);
}

.site-footer__logo {
	display: inline-flex;
}

.site-footer__logo-img {
	display: block;
	height: 1.5rem;
	width: auto;
}

.site-footer__tagline {
	margin: 0;
	max-width: 24ch;
	font-family: var(--font-display);
	font-style: italic;
	font-size: var(--step-0);
	line-height: 1.3;
	color: var(--color-ink);
}

.site-footer__social {
	display: inline-flex;
	align-items: center;
	min-height: 44px; /* comfortable touch target */
	gap: var(--space-2xs);
	color: var(--ink-soft);
	font-size: var(--step--1);
	letter-spacing: 0.02em;
	text-decoration: none;
}

.site-footer__social:hover {
	color: var(--color-ink);
}

.site-footer__social svg {
	width: 1.1rem;
	height: 1.1rem;
	flex: 0 0 auto;
}

.site-footer__nav {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
	gap: var(--space-lg) var(--space-md);
}

.site-footer__heading {
	margin: 0 0 var(--space-sm);
	font-family: var(--font-body);
	font-size: var(--step--1);
	font-weight: 400;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--color-sage-text);
}

.site-footer__socials {
	display: flex;
	flex-wrap: wrap;
	gap: 0 var(--space-md);
}

.site-footer__toggle {
	display: none;
}

.site-footer__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	/* No row gap: each link is a >=44px flush row, which supplies its own rhythm
	   and a comfortable touch target (the 19px text rows were below the minimum). */
	gap: 0;
}

.site-footer__list[hidden] {
	display: none;
}

@media (max-width: 51.999em) {
	/* Compact footer navigation is one deliberate disclosure stack. Allowing the
	   auto-fit grid here creates orphaned groups on phones and a stepped row at
	   tablet widths once the disclosure spacing is applied. */
	.site-footer__nav {
		grid-template-columns: 1fr;
		gap: 0;
	}

	.js .site-footer__heading--group {
		display: none;
	}

	.js .site-footer__toggle {
		display: flex;
		width: 100%;
		min-height: 44px;
		align-items: center;
		justify-content: space-between;
		padding: 0;
		border: 0;
		background: transparent;
		color: var(--color-sage-text);
		font: inherit;
		font-size: var(--step--1);
		letter-spacing: 0.14em;
		text-transform: uppercase;
		text-align: left;
		cursor: pointer;
	}

	.site-footer__toggle-icon {
		position: relative;
		width: 0.75rem;
		height: 0.75rem;
		flex: none;
	}

	.site-footer__toggle-icon::before,
	.site-footer__toggle-icon::after {
		content: "";
		position: absolute;
		top: 50%;
		left: 0;
		width: 100%;
		height: 1px;
		background: currentColor;
		transition: transform 180ms ease;
	}

	.site-footer__toggle-icon::after {
		transform: rotate(90deg);
	}

	.site-footer__toggle[aria-expanded="true"] .site-footer__toggle-icon::after {
		transform: rotate(0);
	}

	.js .site-footer__group {
		border-top: 1px solid var(--line-warm);
	}

	.js .site-footer__group:last-child {
		border-bottom: 1px solid var(--line-warm);
	}

	.js .site-footer__list {
		padding-block: var(--space-2xs);
	}
}

.site-footer__link {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: var(--ink-soft);
	text-decoration: none;
	font-size: var(--step-0);
}

.site-footer__link:hover {
	color: var(--color-ink);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.site-footer__signup-note {
	margin: 0 0 var(--space-sm);
	max-width: 32ch;
	font-size: var(--step--1);
}

.site-footer__form-row {
	display: flex;
	align-items: stretch;
	flex-wrap: wrap;
	gap: var(--space-2xs);
}

.site-footer__input {
	flex: 1 1 11rem;
	min-width: 0;
}

/* Compact the shared .button just for the slim footer row (keeps the ink fill,
   focus ring and hover from the global component; only the size changes). */
.site-footer__submit {
	min-height: auto;
	padding: 0 var(--space-md);
	flex: 0 0 auto;
}

.site-footer__bottom {
	margin-top: var(--space-2xl);
	padding-top: var(--space-md);
	border-top: 1px solid var(--line-warm);
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	align-items: center;
	gap: var(--space-2xs) var(--space-md);
	font-size: var(--step--1);
}

.site-footer__copy,
.site-footer__fineprint {
	margin: 0;
}

@media (min-width: 52em) {
	.site-footer__top {
		grid-template-columns: 1.1fr 2fr 1.35fr;
		gap: var(--space-xl);
		align-items: start;
	}

	/* Three even columns for the wayfinding groups (Shop / Company / Support),
	   rather than the mobile 2-up wrap that leaves one group orphaned. */
	.site-footer__nav {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

/* ============================================================
   Sitewide chrome — announcement bar + centered-logo, two-tier navbar.
   The `.site-banner` WRAPPER owns positioning: `sticky` on every page by default
   (bar sits in flow, content naturally below — no offset hack). The homepage-only
   TRANSPARENT-over-hero state, its `fixed` positioning, the scrim and the scroll
   swap all live in home.css and stay on the inner `.site-header`, so this block is
   unaffected by that system.
   ============================================================ */
.site-banner {
	position: sticky;
	top: 0;
	z-index: 50;
	width: 100%;
}

/* ---- Announcement bar — a clean, full-width rectangular message band. Its
   proportions and restraint follow the client's reference while the colour,
   type and copy remain Latch'd. Calm, confirmed-true copy only. Dismissible via
   the ✕ (see .site-topbar__dismiss + main.js). ---- */
.site-topbar {
	position: relative;
	z-index: 1;
	isolation: isolate;
	display: flex;
	align-items: center;
	justify-content: center;
	min-block-size: var(--topbar-h);
	background: var(--surface-topbar);
	background-image: none;
	color: var(--ink-on-sage);
	border-bottom: 1px solid color-mix(in srgb, var(--color-ink) 24%, var(--color-sage-deep));
}

/* Dismissed for the session — collapse the bar and zero its height token so
   scroll-padding-top and the homepage hero (which subtracts --topbar-h) reclaim
   the space with no gap. Class set on <html> by main.js. */
.topbar-dismissed .site-topbar {
	display: none;
}

.topbar-dismissed {
	--topbar-h: 0px;
}

.site-topbar__social {
	display: none;
}

.site-topbar__social:hover {
	color: var(--color-ink);
}

.site-topbar__social svg {
	inline-size: 1rem;
	block-size: 1rem;
	flex: 0 0 auto;
}

/* Dismiss ✕ — anchored at the right edge while the message remains centred in
   the full-width track. */
.site-topbar__dismiss {
	position: absolute;
	inset-block-start: 50%;
	inset-inline-end: max(0.5rem, calc((100vw - var(--container)) / 2));
	z-index: 2;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: 44px;
	block-size: 44px;
	padding: 0;
	border: 0;
	background: none;
	color: currentColor;
	cursor: pointer;
	transform: translateY(-50%);
}

.site-topbar__dismiss svg {
	inline-size: 0.9rem;
	block-size: 0.9rem;
	flex: 0 0 auto;
}

@media (max-width: 43.75rem) {
	.site-topbar__dismiss {
		inset-inline-end: 0.25rem;
		justify-content: flex-end;
		padding-inline-end: 0.125rem;
	}

	.site-topbar__dismiss svg {
		inline-size: 0.8rem;
		block-size: 0.8rem;
	}
}

/* Full-width centring track: no capsule, radius or secondary ornament. Symmetric
   padding keeps rotating copy clear of the dismiss control. */
.site-topbar__viewport {
	position: relative;
	inline-size: 100%;
	max-inline-size: none;
	margin-inline: auto;
	padding-block: 0;
	padding-inline: 3rem;
	background: transparent;
	border-radius: 0;
	overflow: hidden;
}

@media (max-width: 43.75rem) {
	/* MOBILE keeps the same rectangular band and quiet hierarchy. */
	:root {
		/* Cartier lets the announcement's copy determine its depth. Latch'd uses
		   one short line, so the 44px close target sets the appropriate minimum
		   instead of reserving the space needed by Cartier's three-line message. */
		--topbar-h: 2.75rem;
	}

	.site-topbar__dismiss {
		inset-inline-end: 0.5rem;
		justify-content: flex-end;
		padding-inline-end: 0.125rem;
	}

	.site-topbar__viewport {
		padding-inline: 2.75rem;
	}

	.site-footer__top--without-signup {
		grid-template-columns: minmax(12rem, 0.8fr) minmax(0, 2fr);
	}
}

.site-topbar__track {
	margin: 0;
	padding: 0;
	list-style: none;
	/* Grid stack: every message shares one cell, so the track (and the capsule
	   around it) sizes to the WIDEST message and never collapses mid-crossfade —
	   the old absolute `inset:0` stacking needed a full-width parent to hold width,
	   which a content-sized capsule cannot give. */
	display: grid;
}

.site-topbar__item {
	/* Each message occupies the same centred cell; a single message shows plainly,
	   multiple messages crossfade (rules below). */
	grid-area: 1 / 1;
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: center;
	font-size: var(--step--1);
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

.site-topbar__text--mobile {
	display: none;
}

@media (max-width: 43.75rem) {
	.site-topbar__text--desktop {
		display: none;
	}

	.site-topbar__text--mobile {
		display: inline;
	}

	/* Quiet the mobile announcement so it recedes UNDER the LATCH'D wordmark: soft
	   sentence case, calm tracking, and clear stone text. This block sits
	   AFTER the base .site-topbar__item so it wins by source
	   order — the base rule (tracked-caps for the desktop band) is equal
	   specificity, so an earlier mobile block would be overridden. */
	.site-topbar__item {
		text-transform: none;
		font-size: 0.8125rem;
		line-height: 1.35;
		letter-spacing: 0.015em;
		color: var(--ink-on-sage);
		white-space: nowrap;
	}
}

/* Rotator: stack the messages and slow-crossfade through them (no JS). The
   keyframe is tuned for ~3 messages (each visible ~1/3 of the cycle); the cycle
   length scales with the message count via --announce-count so timing stays
   sensible as copy changes. */
.site-topbar__viewport[data-rotate] .site-topbar__item {
	/* Grid-stacked (see .site-topbar__track) — no absolute positioning, so the
	   capsule keeps the width of the widest message while these crossfade. */
	opacity: 0;
	animation-name: latchd-announce;
	animation-duration: calc(var(--announce-count, 3) * 4s);
	animation-timing-function: ease;
	animation-iteration-count: infinite;
	animation-delay: calc(var(--i, 0) * 4s);
}

@keyframes latchd-announce {
	0% { opacity: 0; transform: translateY(0.35rem); }
	3% { opacity: 1; transform: none; }
	28% { opacity: 1; transform: none; }
	33% { opacity: 0; transform: translateY(-0.35rem); }
	100% { opacity: 0; transform: translateY(-0.35rem); }
}

/* Reduced motion: no rotation — the catch-all would otherwise run the animation
   once and leave every item on its final (hidden) keyframe. Pin the first message
   statically. */
@media (prefers-reduced-motion: reduce) {
	.site-topbar__viewport[data-rotate] .site-topbar__item {
		animation: none;
		opacity: 0;
	}

	.site-topbar__viewport[data-rotate] .site-topbar__item:first-child {
		opacity: 1;
	}
}

/* ---- Header (navbar tier 1 + the nav tier). SOLID cream by default: black
   wordmark, ink utilities, a live cart with a gold badge, a soft bottom hairline.
   Positioning is on `.site-banner`; the header is static within it. ---- */
.site-header {
	position: relative;
	width: 100%;
	background: var(--surface-page);
	/* A whisper of separation from content — hairline, never a heavy border. */
	border-bottom: 1px solid var(--line);
	transition: background-color 260ms var(--nav-ease), border-color 260ms var(--nav-ease);
}

/* Mobile keeps the original shape: utility/logo row plus the hamburger panel.
   The `auto` centre column + equal 1fr flanks keep the wordmark truly centred. */
.site-header__inner {
	position: relative;
	z-index: 1;
	width: min(100% - 2rem, var(--container));
	margin-inline: auto;
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	grid-template-rows: var(--nav-h) auto;
	grid-template-areas:
		"start center end"
		"nav   nav    nav";
	align-items: center;
	column-gap: var(--space-sm);
}

.site-header__zone--start {
	grid-area: start;
	justify-self: start;
	display: inline-flex;
	align-items: center;
	gap: var(--space-2xs);
}

.site-header__zone--center {
	grid-area: center;
	justify-self: center;
	/* Flex container so the logo is centered via flex geometry, not IFC baseline
	   alignment (which would pin the logo's bottom to the strut baseline and shift
	   the wordmark off-center as the SVG grows). */
	display: flex;
	align-items: center;
}

.site-header__zone--nav,
.site-header__nav-tier {
	grid-area: nav;
}

.site-header__zone--end {
	grid-area: end;
	justify-self: end;
	display: inline-flex;
	align-items: center;
	gap: var(--space-2xs);
}

.site-navigation.site-navigation--desktop {
	display: none;
}

/* Preserve four 44px utility targets at the narrowest supported screens by
   tightening only the non-interactive gaps and wordmark width. */
@media (max-width: 22em) {
	.site-header__inner {
		column-gap: var(--space-2xs);
	}

	.site-header__zone--start,
	.site-header__zone--end {
		gap: 0;
		min-inline-size: 0;
	}

	.site-logo {
		inline-size: 5rem;
	}
}

/* ---- Search toggle + account: icon controls matching the cart's 44px hit area
   and currentColor flip. Search is icon-only in the chrome; the button keeps an
   explicit aria-label in markup. ---- */
.site-search-toggle,
.site-account {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-3xs);
	min-inline-size: 2.75rem;
	block-size: 2.75rem;
	padding: 0;
	border: 0;
	background: transparent;
	color: var(--color-ink);
	text-decoration: none;
	font: inherit;
	cursor: pointer;
	transition: color 260ms var(--nav-ease);
}

.site-search-toggle__glyph,
.site-account__glyph {
	inline-size: 1.4rem;
	block-size: 1.4rem;
	display: block;
}

.site-search-toggle__label {
	display: none;
	font-size: var(--step--1);
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

/* ---- Search overlay panel — layers below the banner without entering flow.
   Cream ground, soft veil, hairline base, and quiet controls. ---- */
.site-search-panel {
	position: absolute;
	inset-inline: 0;
	top: 100%;
	z-index: 10;
	background:
		linear-gradient(
			180deg,
			var(--surface-page) 0%,
			color-mix(in srgb, var(--surface-page) 99%, transparent) 72%,
			color-mix(in srgb, var(--surface-page) 96%, transparent) 100%
		);
	border-block: 1px solid color-mix(in srgb, var(--color-ink) 10%, transparent);
	box-shadow: 0 1.25rem 3rem -2.75rem color-mix(in srgb, var(--color-ink) 55%, transparent);
	backdrop-filter: blur(14px) saturate(90%);
	opacity: 0;
	transform: translateY(-0.35rem);
	transition: opacity 200ms var(--nav-ease), transform 200ms var(--nav-ease);
}

.site-search-panel[hidden] {
	display: none;
}

.site-search-panel.is-open {
	opacity: 1;
	transform: none;
}

.site-search-panel__inner {
	width: min(100% - 2rem, var(--container));
	margin-inline: auto;
	padding-block: var(--space-sm) var(--space-md);
}

/* Contained, centred field — the label + field read as one composed unit,
   sitting mid-panel rather than stretched hairline-to-edge. The submit glyph
   lives INSIDE the field's right edge; the ✕ sits just beside it, outside. */
.site-search-form {
	max-inline-size: 44rem;
	margin-inline: auto;
}

.site-search-form__label {
	display: block;
	margin-bottom: var(--space-sm);
	font-family: var(--font-display);
	font-size: var(--step-1);
	font-weight: 500;
	line-height: 1.15;
	letter-spacing: 0;
	text-transform: none;
	text-align: center;
	color: var(--color-ink);
}

.site-search-form__row {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2xs);
}

/* The field itself: a soft cream box with a quiet hairline — a surface you
   type into, not a plain utility box. Caps ~40rem so it reads contained. */
.site-search-form__field {
	position: relative;
	display: flex;
	align-items: center;
	flex: 1 1 auto;
	min-inline-size: 0;
	max-inline-size: 40rem;
	gap: var(--space-2xs);
	padding-inline: var(--space-sm) var(--space-3xs);
	background: var(--surface-warm);
	border: 1px solid var(--line-strong);
	border-radius: var(--radius-md);
	transition: border-color 200ms var(--nav-ease), box-shadow 200ms var(--nav-ease);
}

.site-search-form__field:focus-within {
	border-color: var(--color-ink);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-gold) 32%, transparent);
}

.site-search-form .site-search-form__input {
	flex: 1 1 auto;
	min-inline-size: 0;
	min-height: 3rem;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: transparent;
	color: var(--color-ink);
	font-family: var(--font-body);
	font-size: var(--step-1);
	text-align: start;
	box-shadow: none;
}

.site-search-form .site-search-form__input::placeholder {
	color: color-mix(in srgb, var(--ink-soft) 72%, transparent);
}

.site-search-form .site-search-form__input:focus-visible {
	outline: 0;
	box-shadow: none;
}

/* Submit glyph — inside the field, right edge. Quiet sage that inks on hover. */
.site-search-form__submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	inline-size: 2.5rem;
	block-size: 2.5rem;
	padding: 0;
	border: 0;
	border-radius: var(--radius-sm);
	background: transparent;
	color: var(--color-sage-text);
	cursor: pointer;
	transition: color 160ms ease;
}

.site-search-form__submit svg {
	inline-size: 1.15rem;
	block-size: 1.15rem;
}

.site-search-form__submit:hover {
	color: var(--color-ink);
}

/* Close — a separate control just outside the field. */
.site-search-form__close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	inline-size: 2.75rem;
	block-size: 2.75rem;
	padding: 0;
	border: 0;
	background: transparent;
	color: var(--ink-soft);
	cursor: pointer;
	transition: color 160ms ease;
}

.site-search-form__close svg {
	inline-size: 1rem;
	block-size: 1rem;
}

.site-search-form__close:hover {
	color: var(--color-ink);
}

@media (max-width: 47.999em) {
	.site-search-panel__inner {
		padding-block: var(--space-xs) var(--space-sm);
	}

	.site-search-form__label {
		margin-bottom: var(--space-xs);
		font-size: var(--step-0);
	}

	.site-search-form__field {
		padding-inline: var(--space-xs) var(--space-3xs);
	}

	.site-search-form .site-search-form__input {
		min-height: 2.75rem;
		font-size: var(--step-0);
	}
}

@media (prefers-reduced-motion: reduce) {
	.site-search-panel {
		transform: none;
		transition: opacity 1ms linear;
	}
}

/* Wordmark lockup. The visible brand is the SVG; text remains for AT only. The
   SVG viewBox is cropped tight to the glyphs, so the box height IS the wordmark
   height — logo and nav then centre on a shared baseline with no dead space. */
.site-logo {
	display: inline-flex;
	align-items: center;
	inline-size: calc(var(--space-3xl) + var(--space-lg));
	text-decoration: none;
}

.site-logo__image {
	inline-size: 100%;
	display: block;
}

/* The wordmark fill (ink here, white in the overlay state) eases with the swap. */
.site-logo__image text {
	transition: fill 260ms var(--nav-ease);
}

/* ---- Cart: real store element, present + tappable on every page ----
   The icon uses currentColor so it flips with the header state; the count badge
   is the one warm accent (gold + ink numeral — a filled sage disc with a white
   numeral would fail contrast at 2.98:1, hence gold). Zero state hides the badge
   (a "0" is negative noise); the bag alone still invites. */
.site-cart {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* 44px hit area — comfortable one-handed tap on mobile. */
	inline-size: 2.75rem;
	block-size: 2.75rem;
	color: var(--color-ink);
	text-decoration: none;
	transition: color 260ms var(--nav-ease);
}

.site-cart__glyph {
	inline-size: 1.4rem;
	block-size: 1.4rem;
	display: block;
}

.site-cart__badge {
	position: absolute;
	top: 0.15rem;
	inset-inline-end: 0.1rem;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-inline-size: 1.05rem;
	block-size: 1.05rem;
	padding-inline: 0.2rem;
	border-radius: 999px;
	background: var(--color-gold);
	color: var(--color-ink);
	font-size: 0.62rem;
	font-weight: 600;
	line-height: 1;
	font-variant-numeric: tabular-nums;
	/* Thin ring detaches the disc from the icon strokes on the cream bar. */
	box-shadow: 0 0 0 1.5px var(--surface-page);
}

.site-cart__badge[hidden] {
	display: none;
}

/* ---- Menu toggle (mobile only) ---- */
.menu-toggle {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* 44px hit area to match the cart. */
	inline-size: 2.75rem;
	min-inline-size: 2.75rem;
	min-height: 2.75rem;
	padding: 0;
	border: 0;
	background: transparent;
	color: var(--color-ink);
	font: inherit;
	font-size: var(--step--1);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	cursor: pointer;
	transition: color 260ms var(--nav-ease);
}

.menu-toggle__label {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.menu-toggle__icon,
.menu-toggle__icon::before,
.menu-toggle__icon::after {
	display: block;
	inline-size: var(--space-md);
	block-size: 1px;
	background: currentColor;
	transition: transform 160ms ease, opacity 160ms ease;
}

.menu-toggle__icon {
	position: relative;
}

.menu-toggle__icon::before,
.menu-toggle__icon::after {
	position: absolute;
	inset-inline-start: 0;
	content: "";
}

.menu-toggle__icon::before {
	transform: translateY(calc(var(--space-2xs) * -1));
}

.menu-toggle__icon::after {
	transform: translateY(var(--space-2xs));
}

.site-header.is-navigation-open .menu-toggle__icon {
	background: transparent;
}

.site-header.is-navigation-open .menu-toggle__icon::before {
	transform: rotate(45deg);
}

.site-header.is-navigation-open .menu-toggle__icon::after {
	transform: rotate(-45deg);
}

/* ---- Centre nav (collapses to the mobile panel; inline + centred on desktop) ---- */
.site-navigation {
	display: grid;
	grid-template-rows: 1fr;
	overflow: visible;
	opacity: 1;
	visibility: visible;
}

.site-header.is-navigation-ready .site-navigation {
	grid-template-rows: 0fr;
	overflow: hidden;
	opacity: 0;
	visibility: hidden;
	transition: grid-template-rows 180ms ease, opacity 160ms ease, visibility 160ms ease;
}

/* Anti-flash: when JS is available (the <head> script sets `.js` before first
   paint), the mobile panel starts COLLAPSED immediately — so it never flashes
   open as a vertical list in the gap before main.js adds `is-navigation-ready`.
   No transition here (a first-paint collapse must be instant, not animated);
   the ready + open rules above/below still own the animated toggle. Without JS
   the base `.site-navigation` stays expanded as the accessible fallback. */
.js .site-navigation--mobile {
	grid-template-rows: 0fr;
	overflow: hidden;
	opacity: 0;
	visibility: hidden;
}

.site-header.is-navigation-ready.is-navigation-open .site-navigation {
	grid-template-rows: 1fr;
	opacity: 1;
	visibility: visible;
}

.site-navigation .primary-menu {
	display: flex;
	flex-direction: column;
	gap: var(--space-2xs);
	margin: 0;
	padding: 0;
	overflow: hidden;
	list-style: none;
	font-size: var(--step--1);
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

/* Breathing room for the open mobile panel. */
.site-header.is-navigation-open .site-navigation .primary-menu {
	padding-block: var(--space-sm) var(--space-md);
}

.site-navigation .menu-item {
	display: flex;
}

.site-navigation a {
	position: relative;
	display: inline-flex;
	padding-block: var(--space-2xs);
	text-decoration: none;
	color: var(--color-ink);
	transition: color 260ms var(--nav-ease), font-weight 160ms var(--nav-ease);
}

/* Craft: a sage underline that DRAWS IN on hover/focus (reuses the site's
   draw-in idiom) — not a colour flip. Persists on the current section for
   wayfinding. */
.site-navigation a::after {
	content: "";
	position: absolute;
	inset-inline: 0;
	bottom: 0;
	block-size: 1px;
	background: var(--color-sage-deep);
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform 220ms var(--nav-ease);
}

.site-navigation a:hover::after,
.site-navigation a:focus-visible::after,
.site-navigation .current-menu-item > a::after,
.site-navigation .current-menu-parent > a::after,
.site-navigation .current-menu-ancestor > a::after,
.site-navigation .current_page_item > a::after,
.site-navigation .current_page_parent > a::after,
.site-navigation .current_page_ancestor > a::after,
.site-navigation .is-current-scope > a::after {
	transform: scaleX(1);
}

.site-navigation .current-menu-item > a,
.site-navigation .current-menu-parent > a,
.site-navigation .current-menu-ancestor > a,
.site-navigation .current_page_item > a,
.site-navigation .current_page_parent > a,
.site-navigation .current_page_ancestor > a,
.site-navigation .is-current-scope > a {
	font-weight: 600;
}

/* ---- Sub-menus (Shop → Covers · Accessories) ----
   Base = the mobile panel: children sit as an indented, hairline-ruled list
   under their parent, always visible (no per-item disclosure to fumble with).
   Desktop turns them into a hover/focus dropdown card (in the media query). */
.site-navigation .menu-item.has-submenu {
	flex-direction: column;
	align-items: flex-start;
}

.site-navigation .sub-menu {
	list-style: none;
	margin: var(--space-3xs) 0 var(--space-2xs);
	padding: 0 0 0 var(--space-sm);
	display: flex;
	flex-direction: column;
	gap: var(--space-3xs);
	border-inline-start: 1px solid var(--line);
}

.site-navigation .sub-menu .menu-item {
	display: flex;
}

.site-navigation .sub-menu a {
	font-size: calc(var(--step--1) * 0.94);
	letter-spacing: 0.1em;
	color: var(--ink-soft);
}

.site-navigation .sub-menu a:hover,
.site-navigation .sub-menu .current-menu-item > a {
	color: var(--color-ink);
}

/* A small chevron on the parent, only rendered on desktop where it drops down. */
.menu-caret {
	display: none;
	inline-size: 0.4em;
	block-size: 0.4em;
	margin-inline-start: 0.5em;
	border-inline-end: 1.5px solid currentColor;
	border-block-end: 1.5px solid currentColor;
	transform: translateY(-0.15em) rotate(45deg);
	transition: transform 200ms var(--nav-ease);
}

/* Cartier-reference mobile navigation: the menu is a dedicated viewport below
   the 75px utility row, not an expanding list that pushes the page downward. */
@media (max-width: 47.999em) {
	.navigation-open {
		overflow: hidden;
	}

	.site-navigation.site-navigation--mobile,
	.js .site-navigation--mobile,
	.site-header.is-navigation-ready .site-navigation--mobile {
		position: fixed;
		inset-inline: 0;
		top: calc(var(--topbar-h) + var(--nav-primary-h));
		z-index: 70;
		display: block;
		width: 100vw;
		height: calc(100dvh - var(--topbar-h) - var(--nav-primary-h));
		padding: 0;
		background: var(--surface-page);
		border-top: 1px solid var(--line);
		overflow-x: hidden;
		overflow-y: auto;
		opacity: 0;
		visibility: hidden;
		pointer-events: none;
		transform: translateX(-1rem);
		transition: opacity 180ms var(--nav-ease), transform 220ms var(--nav-ease), visibility 180ms;
	}

	.site-header.is-navigation-ready.is-navigation-open .site-navigation--mobile {
		opacity: 1;
		visibility: visible;
		pointer-events: auto;
		transform: none;
	}

	.mobile-nav__screen {
		width: min(100% - 2rem, var(--container));
		min-height: 100%;
		margin-inline: auto;
		padding-block: var(--space-lg) var(--space-2xl);
	}

	.mobile-nav__screen[hidden] {
		display: none;
	}

	.mobile-nav__eyebrow {
		margin: 0 0 var(--space-sm);
		color: var(--color-sage-text);
		font-size: var(--step--1);
		letter-spacing: 0.14em;
		text-transform: uppercase;
	}

	.mobile-nav__title {
		margin: var(--space-md) 0 var(--space-lg);
		font-family: var(--font-display);
		font-size: var(--step-4);
		font-weight: 500;
		line-height: 1.05;
	}

	.mobile-nav__back,
	.mobile-nav__next {
		width: 100%;
		min-height: 3.5rem;
		padding: 0;
		border: 0;
		border-bottom: 1px solid var(--line);
		border-radius: 0;
		background: transparent;
		color: var(--color-ink);
		font: inherit;
		text-align: start;
		cursor: pointer;
	}

	.mobile-nav__back {
		display: inline-flex;
		width: auto;
		align-items: center;
		gap: var(--space-xs);
		border-bottom: 0;
		color: var(--ink-soft);
		font-size: var(--step--1);
		letter-spacing: 0.08em;
		text-transform: uppercase;
	}

	.mobile-nav__next {
		display: flex;
		align-items: center;
		justify-content: space-between;
		letter-spacing: 0.08em;
		text-transform: uppercase;
	}

	.site-navigation .mobile-nav__list {
		gap: 0;
		overflow: visible;
	}

	.site-header.is-navigation-open .site-navigation .mobile-nav__list {
		padding-block: 0;
	}

	.mobile-nav__list .menu-item,
	.mobile-nav__list > li {
		display: block;
		width: 100%;
	}

	.mobile-nav__list a,
	.mobile-nav__all {
		display: flex;
		align-items: center;
		gap: var(--space-xs);
		width: 100%;
		min-height: 3.5rem;
		padding: 0;
		border-bottom: 1px solid var(--line);
		font-size: var(--step--1);
		letter-spacing: 0.08em;
		text-decoration: none;
		text-transform: uppercase;
	}

	.mobile-nav__all {
		margin-bottom: var(--space-sm);
		color: var(--color-sage-text);
	}

	.mobile-nav__list--products a {
		min-height: 3.25rem;
		font-family: var(--font-display);
		font-size: var(--step-1);
		letter-spacing: 0;
		text-transform: none;
	}

	.mobile-nav__swatch {
		width: 0.85rem;
		height: 0.85rem;
		flex: 0 0 auto;
		border: 1px solid var(--line-strong);
		border-radius: 50%;
		background: var(--swatch, var(--color-sage));
	}
}

@media (min-width: 48em) {
	.site-header__inner {
		grid-template-rows: var(--nav-primary-h) var(--nav-secondary-h);
		grid-template-areas:
			"start center end"
			"nav nav nav";
		column-gap: clamp(var(--space-sm), 2.4vw, var(--space-xl));
	}

	.site-header::after {
		position: absolute;
		inset-inline: 0;
		top: var(--nav-primary-h);
		block-size: 1px;
		background: var(--line);
		content: '';
		pointer-events: none;
	}

	.menu-toggle {
		display: none;
	}

	.site-header__zone--start,
	.site-header__zone--end {
		gap: clamp(var(--space-xs), 1.6vw, var(--space-md));
		min-inline-size: 0;
	}

	.site-search-toggle__label {
		display: inline;
	}

	/* Wordmark scales up to anchor the header as the clear visual hero — the ratio
	   stays locked to the SVG viewBox (424×74), so height scales proportionally. */
	.site-logo {
		inline-size: 9.5rem;
	}

	.site-navigation--desktop,
	.site-header.is-navigation-ready .site-navigation--desktop {
		display: flex;
		align-items: stretch;
		justify-content: center;
		align-self: stretch;
		grid-template-rows: 1fr;
		overflow: visible;
		opacity: 1;
		visibility: visible;
	}

	.site-navigation--mobile,
	.site-header.is-navigation-ready .site-navigation--mobile {
		display: none;
	}

	.site-navigation--desktop .primary-menu {
		flex-flow: row nowrap;
		align-items: center;
		justify-content: center;
		gap: clamp(var(--space-md), 2.8vw, var(--space-xl));
		min-block-size: 100%;
		overflow: visible;
		padding-block: 0;
		/* Quiet wayfinding: tight tracking so nav recedes behind the wordmark texture.
		   Mobile panel keeps 0.14em for panel legibility at larger size. */
		letter-spacing: 0.04em;
	}

	.site-navigation--desktop a {
		align-items: center;
		min-block-size: 2.75rem;
		padding-block: 0;
		white-space: nowrap;
	}

	/* ---- Desktop dropdown ---- */
	/* The Shop item hosts the mega-panel. It is intentionally NOT position:relative
	   — the panel anchors to `.site-header__inner` so it sits FLUSH under the header
	   bar (attached), not floating below the nav item. */
	.site-navigation--desktop .menu-item.has-submenu {
		flex-direction: row; /* undo the mobile column stack */
		align-items: center;
	}

	.site-navigation--desktop .menu-caret {
		display: inline-block;
	}

	/* ---- Shop mega-panel: image-led, attached under the header ---- */
	.nav-panel {
		position: absolute;
		top: 100%;               /* flush against the header's bottom hairline */
		inset-inline-start: 0;   /* anchored to the container's left content edge */
		z-index: 50;
		inline-size: max-content;
		max-inline-size: min(92vw, 27rem);
		background: var(--surface-page);
		/* No top border: the header's own bottom hairline reads as this panel's top,
		   so it looks part of the header rather than a detached box. */
		border: 1px solid var(--line);
		border-top: 0;
		border-radius: 0 0 var(--radius-sm) var(--radius-sm);
		/* A whisper of depth only — not a floating drop-shadow. */
		box-shadow: 0 16px 26px -24px color-mix(in srgb, var(--color-ink) 42%, transparent);
		opacity: 0;
		visibility: hidden;
		pointer-events: none;
		transform: translateY(-6px);
		transition: opacity 200ms var(--nav-ease), transform 200ms var(--nav-ease), visibility 200ms;
	}

	/* JS drives `.is-open` (hover-intent + keyboard). Without JS the panel still
	   opens on hover/focus (the `.no-js` fallbacks). */
	.site-navigation--desktop .menu-item.has-submenu.is-open > .nav-panel,
	.no-js .site-navigation--desktop .menu-item.has-submenu:hover > .nav-panel,
	.no-js .site-navigation--desktop .menu-item.has-submenu:focus-within > .nav-panel {
		opacity: 1;
		visibility: visible;
		pointer-events: auto;
		transform: translateY(0);
	}

	.site-navigation--desktop .menu-item.has-submenu.is-open > a .menu-caret,
	.no-js .site-navigation--desktop .menu-item.has-submenu:hover > a .menu-caret,
	.no-js .site-navigation--desktop .menu-item.has-submenu:focus-within > a .menu-caret {
		transform: translateY(0.05em) rotate(225deg); /* down → up when open */
	}

	.nav-panel__inner {
		padding: var(--space-md);
	}

	.nav-panel__grid {
		list-style: none;
		margin: 0;
		padding: 0;
		display: flex;
		flex-direction: column;
		gap: var(--space-3xs);
	}

	.nav-panel__cell {
		display: flex;
	}

	/* Image-led row: thumbnail + name + one-line descriptor. */
	.nav-card {
		display: grid;
		grid-template-columns: 3.25rem 1fr;
		align-items: center;
		gap: var(--space-sm);
		inline-size: 100%;
		padding: var(--space-2xs);
		border-radius: var(--radius-sm);
		text-decoration: none;
		transition: background 180ms var(--nav-ease);
	}

	.nav-card::after {
		content: none; /* suppress the nav's draw-in underline inside the panel */
	}

	.nav-card:hover,
	.nav-panel__cell.is-current .nav-card {
		background: color-mix(in srgb, var(--color-ink) 4%, transparent);
	}

	.nav-card__media {
		inline-size: 3.25rem;
		aspect-ratio: 4 / 5;
		border-radius: calc(var(--radius-sm) - 2px);
		overflow: hidden;
		background: color-mix(in srgb, var(--color-cream) 78%, var(--color-white));
	}

	.nav-card__img {
		display: block;
		inline-size: 100%;
		block-size: 100%;
		object-fit: cover;
	}

	.nav-card__text {
		min-inline-size: 0;
	}

	.nav-card__name {
		display: block;
		font-family: var(--font-display, "Playfair Display", Georgia, serif);
		font-size: var(--step-0);
		font-weight: 500;
		letter-spacing: 0.01em;
		text-transform: none;
		line-height: 1.1;
		color: var(--color-ink);
	}

	.nav-card__desc {
		display: block;
		margin-block-start: 3px;
		font-size: calc(var(--step--1) * 0.96);
		letter-spacing: normal;
		text-transform: none;
		line-height: 1.35;
		color: var(--ink-soft);
	}

	.nav-panel__all {
		display: flex;
		align-items: center;
		gap: 0.5em;
		margin-block-start: var(--space-sm);
		padding-block-start: var(--space-sm);
		border-top: 1px solid var(--line);
		font-size: var(--step--1);
		letter-spacing: 0.14em;
		text-transform: uppercase;
		color: var(--color-ink);
	}

	.nav-panel__all::after {
		content: none;
	}

	.nav-panel__arrow {
		transition: transform 180ms var(--nav-ease);
	}

	.nav-panel__all:hover .nav-panel__arrow {
		transform: translateX(3px);
	}

	/* Full-width, clean-lined catalogue panel. The first column establishes the
	   product family; the second changes in place on hover or keyboard focus.
	   One editorial frame changes with that branch, giving the menu a recognisable
	   Latch'd moment without asking placeholder photography to represent a SKU. */
	.nav-panel {
		inset-inline-start: 50%;
		width: 100vw;
		max-inline-size: none;
		min-height: 0;
		border-inline: 0;
		border-bottom: 1px solid var(--line-strong);
		border-radius: 0;
		box-shadow: 0 22px 34px -32px color-mix(in srgb, var(--color-ink) 55%, transparent);
		transform: translate(-50%, -6px);
	}

	.site-navigation--desktop .menu-item.has-submenu.is-open > .nav-panel,
	.no-js .site-navigation--desktop .menu-item.has-submenu:hover > .nav-panel,
	.no-js .site-navigation--desktop .menu-item.has-submenu:focus-within > .nav-panel {
		transform: translate(-50%, 0);
	}

	.nav-panel__inner {
		width: min(100% - 3rem, var(--container));
		margin-inline: auto;
		padding: var(--space-sm) 0 var(--space-md);
	}

	.nav-panel__heading {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: var(--space-md);
		min-height: 2.75rem;
		padding-bottom: var(--space-xs);
		border-bottom: 1px solid var(--line);
	}

	.nav-panel__eyebrow {
		margin: 0;
		color: var(--color-sage-text);
		font-size: var(--step--1);
		letter-spacing: 0.14em;
		text-transform: uppercase;
	}

	.nav-panel__heading .nav-panel__all {
		margin: 0;
		padding: 0;
		border: 0;
		min-height: 2.75rem;
	}

	.nav-panel__catalogue {
		display: grid;
		grid-template-columns: minmax(11rem, 0.24fr) minmax(0, 1fr);
		gap: clamp(var(--space-lg), 4vw, var(--space-xl));
		padding-top: var(--space-xs);
	}

	.nav-panel__categories,
	.nav-panel__products {
		list-style: none;
		margin: 0;
		padding: 0;
	}

	.nav-panel__category {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: var(--space-sm);
		width: 100%;
		min-height: 2.75rem;
		border-bottom: 1px solid var(--line);
		color: var(--ink-soft);
		font-family: var(--font-display);
		font-size: var(--step-1);
		letter-spacing: 0;
		text-transform: none;
		transition: color 160ms var(--nav-ease), box-shadow 180ms var(--nav-ease), padding 180ms var(--nav-ease);
	}

	.nav-panel__category::after,
	.nav-panel__products a::after,
	.nav-panel__branch-head a::after {
		content: none;
	}

	.nav-panel__category:hover,
	.nav-panel__category:focus-visible,
	.nav-panel__category.is-active {
		padding-inline-start: var(--space-2xs);
		box-shadow: inset 2px 0 var(--color-sage-deep);
		color: var(--color-sage-text);
	}

	.nav-panel__branch[hidden] {
		display: none;
	}

	.nav-panel__branch-layout {
		display: grid;
		grid-template-columns: minmax(0, 1fr) minmax(10rem, 13.5rem);
		gap: clamp(var(--space-lg), 3vw, var(--space-xl));
		align-items: stretch;
	}

	.nav-panel__branch-head {
		display: flex;
		align-items: end;
		justify-content: space-between;
		gap: var(--space-lg);
		margin-bottom: var(--space-xs);
	}

	.nav-panel__branch-head h2 {
		margin: 0;
		font-family: var(--font-display);
		font-size: var(--step-2);
		font-weight: 500;
		line-height: 1.05;
	}

	.nav-panel__branch-head p {
		margin: var(--space-2xs) 0 0;
		color: var(--ink-soft);
		font-size: var(--step--1);
		letter-spacing: 0;
		text-transform: none;
	}

	.nav-panel__branch-head a {
		display: inline-flex;
		align-items: center;
		gap: var(--space-2xs);
		min-height: 2.75rem;
		color: var(--color-sage-text);
		font-size: var(--step--1);
		letter-spacing: 0.1em;
		text-transform: uppercase;
	}

	.nav-panel__products {
		display: grid;
		grid-template-columns: repeat(5, minmax(0, 1fr));
		column-gap: var(--space-sm);
	}

	.nav-panel__branch--accessories .nav-panel__products {
		grid-template-columns: repeat(2, minmax(9rem, 1fr));
	}

	.nav-panel__branch--gifting .nav-panel__products {
		grid-template-columns: minmax(12rem, 0.5fr);
	}

	.nav-panel__products a {
		display: flex;
		align-items: center;
		gap: var(--space-xs);
		min-height: 2.625rem;
		border-bottom: 1px solid var(--line);
		color: var(--color-ink);
		font-family: var(--font-display);
		font-size: var(--step-0);
		letter-spacing: 0;
		text-transform: none;
		transition: color 160ms var(--nav-ease), border-color 160ms var(--nav-ease);
	}

	.nav-panel__products a:hover {
		border-color: var(--color-sage-deep);
		color: var(--color-sage-text);
	}

	.nav-panel__swatch {
		width: 0.8rem;
		height: 0.8rem;
		flex: 0 0 auto;
		border: 1px solid var(--line-strong);
		border-radius: 50%;
		background: var(--swatch, var(--color-sage));
	}

	.nav-panel__media {
		position: relative;
		min-height: 10rem;
		margin: 0;
		overflow: hidden;
		background: var(--surface-warm);
	}

	.nav-panel__media picture,
	.nav-panel__image {
		display: block;
		width: 100%;
		height: 100%;
	}

	.nav-panel__image {
		position: absolute;
		inset: 0;
		object-fit: cover;
	}
}

/* At the tablet/compact-desktop boundary the catalogue remains the useful
   content. The editorial frame returns once there is enough width for it not to
   squeeze colour names or inflate the panel. */
@media (min-width: 48em) and (max-width: 68.749em) {
	.nav-panel__branch-layout {
		grid-template-columns: minmax(0, 1fr);
	}

	.nav-panel__branch--cover .nav-panel__products {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}

	.nav-panel__media {
		display: none;
	}
}

/* ============================================================
   Global component layer
   Token-driven skin for controls that appear across every page, so
   un-designed pages inherit the brand. WooCommerce's own "general" skin
   is dequeued (see functions.php) — these styles own those surfaces
   without a specificity fight.
   ============================================================ */

/* ---- Prose rhythm (bare pages, page/post content) ---- */
.entry-title {
	font-size: var(--step-4);
	margin: 0 0 var(--space-md);
}

.entry-content {
	max-width: 68ch;
}

.entry-content > * + * {
	margin-top: var(--space-sm);
}

.entry-content h2 {
	font-size: var(--step-3);
	margin-top: var(--space-xl);
}

.entry-content h3 {
	font-size: var(--step-2);
	margin-top: var(--space-lg);
}

.entry-content a {
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.15em;
	transition: color 160ms ease;
}

.entry-content a:hover {
	color: var(--color-sage-text);
}

/* ---- Buttons (theme + WooCommerce + block button) ---- */
.button,
.wp-element-button,
.wp-block-button__link,
input[type="submit"],
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 3rem;
	padding: 0 var(--space-lg);
	border: 1px solid var(--color-sage-deep);
	border-radius: var(--radius-sm);
	background: var(--color-sage-deep);
	color: var(--ink-on-sage);
	font-family: var(--font-body);
	font-size: var(--step-0);
	line-height: 1.2;
	letter-spacing: 0.04em;
	text-decoration: none;
	cursor: pointer;
	transition: background 180ms ease, color 180ms ease, border-color 180ms ease;
}

.button:hover,
.wp-element-button:hover,
.wp-block-button__link:hover,
input[type="submit"]:hover,
.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce #respond input#submit:hover {
	background: color-mix(in srgb, var(--color-sage-deep) 82%, var(--color-ink));
	border-color: color-mix(in srgb, var(--color-sage-deep) 82%, var(--color-ink));
	color: var(--ink-on-sage);
}

/* Secondary / ghost buttons (e.g. WooCommerce non-primary actions). */
.button.alt,
.woocommerce a.button.alt,
.woocommerce button.button.alt {
	background: var(--color-sage-deep);
	border-color: var(--color-sage-deep);
	color: var(--ink-on-sage);
}

.woocommerce a.button:where(:not(.alt)):not(.add_to_cart_button),
.woocommerce button.button:where(:not(.alt)) {
	background: transparent;
	color: var(--color-ink);
}

.woocommerce a.button:where(:not(.alt)):not(.add_to_cart_button):hover,
.woocommerce button.button:where(:not(.alt)):hover {
	background: var(--color-ink);
	color: var(--ink-on-dark);
}

/* ---- Form controls ---- */
input[type="text"],
input[type="email"],
input[type="search"],
input[type="tel"],
input[type="url"],
input[type="password"],
input[type="number"],
textarea,
select {
	font: inherit;
	color: var(--color-ink);
	background: var(--surface-raised);
	border: 1px solid var(--line-strong);
	border-radius: var(--radius-sm);
	padding: 0.6em 0.75em;
	max-width: 100%;
}

textarea {
	line-height: 1.5;
}

/* Native select with a token chevron (fixes the raw "Default sorting" look). */
select {
	appearance: none;
	-webkit-appearance: none;
	padding-right: 2.25em;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%231A1A18' stroke-width='1.5'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 0.85em center;
	cursor: pointer;
}

::placeholder {
	color: color-mix(in srgb, var(--color-ink) 45%, var(--color-stone));
	opacity: 1;
}

/* ---- Links inside the WooCommerce chrome shouldn't get prose underlines ---- */
.woocommerce a.button {
	text-decoration: none;
}

/* ---- Price ---- */
.price,
.woocommerce .price {
	color: var(--color-ink);
}

.price del,
.woocommerce .price del {
	color: var(--ink-soft);
	margin-right: var(--space-2xs);
}

.price ins,
.woocommerce .price ins {
	text-decoration: none;
	font-weight: 600;
}

/* ---- WooCommerce product loop — baseline flow only ----
   Owned from the dequeued general skin so the archive isn't broken (removes
   list bullets, restores block flow, stops the title/price/button overlap).
   Intentionally minimal — the full shop-archive DESIGN is a separate ticket. */
.woocommerce ul.products {
	margin: 0;
	padding: 0;
	list-style: none;
}

.woocommerce ul.products li.product {
	margin: 0 0 var(--space-xl);
	list-style: none;
	text-align: left;
}

.woocommerce ul.products li.product a {
	text-decoration: none;
}

.woocommerce ul.products li.product a.woocommerce-LoopProduct-link,
.woocommerce ul.products li.product a.woocommerce-loop-product__link {
	display: block;
	margin-bottom: var(--space-sm);
}

.woocommerce ul.products li.product img {
	margin-bottom: var(--space-sm);
}

.woocommerce ul.products li.product .woocommerce-loop-product__title {
	display: block;
	margin: 0 0 var(--space-2xs);
	font-family: var(--font-display);
	font-weight: 500;
	font-size: var(--step-1);
	line-height: 1.2;
}

.woocommerce ul.products li.product .price {
	display: block;
	margin-bottom: var(--space-sm);
	font-size: var(--step-0);
}

/* ---- WooCommerce notices ---- */
.woocommerce-message,
.woocommerce-info,
.woocommerce-error,
.woocommerce-noreviews {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-sm);
	margin: 0 0 var(--space-lg);
	padding: var(--space-sm) var(--space-md);
	background: var(--surface-raised);
	border: 1px solid var(--line);
	border-left: 3px solid var(--color-sage);
	border-radius: var(--radius-sm);
	list-style: none;
	color: var(--color-ink);
	font-size: var(--step--1);
}

.woocommerce-error {
	border-left-color: color-mix(in srgb, var(--color-gold) 70%, var(--color-ink));
}

.woocommerce-message .button,
.woocommerce-info .button,
.woocommerce-error .button {
	min-height: 2.5rem;
	margin-left: auto;
	padding-inline: var(--space-md);
	font-size: var(--step--1);
}

/* ============================================================
   Product card (.shop-card)
   The shared commerce card unit. Introduced for the shop grid; now also used by
   the homepage accessories row and the PDP + cart cross-sells, so it lives in
   the global component layer. Self-contained (its own --card-* tokens) so it
   renders identically wherever it is dropped. Placement layouts (grids/rows)
   live in each page-scoped stylesheet; only the card itself is here.
   ============================================================ */
.shop-card {
	--card-tile: color-mix(in srgb, var(--color-cream) 78%, var(--color-white));
	--card-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
	display: flex;
	flex-direction: column;
}

.shop-card__tile {
	position: relative;
	overflow: hidden;
	background: var(--card-tile);
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
}

.shop-card__media {
	display: block;
}

.shop-card__img {
	display: block;
	width: 100%;
	height: 100%;
	aspect-ratio: 4 / 5;
	object-fit: cover;
	transition: transform 0.6s var(--card-ease);
}

.shop-card__tile:hover .shop-card__img {
	transform: scale(1.03);
}

.shop-card__tag {
	position: absolute;
	top: var(--space-2xs);
	left: var(--space-2xs);
	z-index: 2;
	padding: 0.25rem 0.5rem;
	background: var(--surface-page);
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	font-size: 0.6875rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--color-ink);
}

.shop-card__body {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-3xs);
	padding-top: var(--space-sm);
	text-align: center;
	/* Grow so the CTA aligns to a common baseline across a grid row. */
	flex: 1 1 auto;
}

.shop-card__name {
	font-size: var(--step--1);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--color-ink);
	text-decoration: none;
}

.shop-card__name:hover {
	color: var(--color-sage-text);
}

.shop-card__descriptor {
	display: flex;
	align-items: center;
	gap: var(--space-2xs);
	margin: 0;
	font-size: var(--step--1);
	color: var(--ink-soft);
}

.shop-card__swatch {
	width: 0.7rem;
	height: 0.7rem;
	border-radius: 50%;
	background: var(--swatch, var(--color-sage));
	box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-ink) 18%, transparent);
	flex: none;
}

/* Accessory colour cluster — several made-to-order colours on one listing,
   reusing the single-swatch dot above. */
.shop-card__swatches {
	display: inline-flex;
	align-items: center;
	gap: var(--space-3xs);
	flex: none;
}

.shop-card__price {
	margin: 0;
	font-size: var(--step-0);
	color: var(--color-ink);
}

.shop-card__price del {
	color: var(--ink-soft);
	margin-right: 0.4em;
}

/* The CTA is a distinct button BELOW the card, always visible (no overlay, no
   hover-reveal — those hid the primary action and shifted layout). margin-top
   auto pins it to the card foot so buttons align across a grid row. */
.shop-card__cta {
	margin-top: var(--space-sm);
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2xs);
	min-height: 44px;
	padding: var(--space-2xs) var(--space-sm);
	background: var(--color-sage-deep);
	color: var(--ink-on-sage);
	border: 1px solid var(--color-sage-deep);
	border-radius: var(--radius-sm);
	font-size: var(--step--1);
	letter-spacing: 0.12em;
	text-transform: uppercase;
	text-align: center;
	text-decoration: none;
	transition: background 0.2s var(--card-ease), color 0.2s var(--card-ease);
}

.shop-card__cta:hover {
	background: color-mix(in srgb, var(--color-sage-deep) 82%, var(--color-ink));
	color: var(--ink-on-sage);
}

/* Non-addable/placeholder cards read as a quiet ghost link, not a primary CTA. */
.shop-card__cta--ghost {
	background: transparent;
	color: var(--color-ink);
	border-color: var(--line-strong);
}

.shop-card__cta--ghost:hover {
	background: transparent;
	color: var(--color-ink);
	border-color: var(--color-ink);
}

/* Added-state feedback from WooCommerce's AJAX flow. */
.shop-card__cta.loading {
	opacity: 0.7;
	pointer-events: none;
}

/* ============================================================
   Accessory cross-sell (.xsell)
   The shared "push the accessories" section — homepage row, PDP, and cart.
   One quiet, premium treatment (calm heading + a small grid of shared product
   cards), varied only by modifier. Lives here so all three placements stay
   of-a-piece; page-scoped stylesheets add only field/spacing context.
   ============================================================ */
.xsell {
	padding-block: var(--space-2xl);
}

.xsell__inner {
	width: min(100% - 2rem, var(--container));
	margin-inline: auto;
}

.xsell__head {
	text-align: center;
	margin-bottom: var(--space-lg);
}

.xsell__eyebrow {
	margin: 0 0 var(--space-2xs);
	font-size: var(--step--1);
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--color-sage-text);
}

.xsell__title {
	margin: 0;
	font-family: var(--font-display);
	font-weight: 500;
	font-size: var(--step-3);
	line-height: 1.1;
	color: var(--color-ink);
}

.xsell__grid {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--space-md) var(--space-sm);
}

.xsell__more {
	margin: var(--space-lg) 0 0;
	text-align: center;
}

.xsell__more-link {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2xs);
	min-height: 44px;
	font-size: var(--step--1);
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--color-ink);
}

.xsell__more-arrow {
	transition: transform 0.25s var(--ease, ease);
}

.xsell__more-link:hover .xsell__more-arrow {
	transform: translateX(0.25rem);
}

/* On the cart, the section sits on the warm band as a calm suggestion. */
.xsell--cart {
	margin-top: var(--space-2xl);
	padding-block: var(--space-xl);
	background: var(--surface-warm);
	border-top: 1px solid var(--line-warm);
}

.xsell--cart .xsell__title {
	font-size: var(--step-2);
}

@media (min-width: 62rem) {
	.xsell__grid {
		grid-template-columns: repeat(4, 1fr);
		gap: var(--space-lg) var(--space-md);
	}

	/* Cart is a narrower reading column — three across keeps the cards calm. */
	.xsell--cart .xsell__grid {
		grid-template-columns: repeat(3, 1fr);
		max-width: 46rem;
		margin-inline: auto;
	}
}

/* ============================================================
   Cart drawer (mini-cart) — sitewide chrome
   Slides in from the right over a scrim on add-to-bag. Tokens only; calm and
   premium, not a loud popup. Reduced motion is handled by the global catch-all
   (transitions snap), so it simply appears.
   ============================================================ */
html.cart-drawer-locked {
	overflow: hidden;
}

.cart-drawer {
	position: fixed;
	inset: 0;
	z-index: 1000;
}

.cart-drawer[hidden] {
	display: none;
}

.cart-drawer__scrim {
	position: absolute;
	inset: 0;
	background: color-mix(in srgb, var(--color-ink) 45%, transparent);
	opacity: 0;
	transition: opacity 0.3s var(--card-ease, ease);
}

.cart-drawer.is-open .cart-drawer__scrim {
	opacity: 1;
}

.cart-drawer__panel {
	position: absolute;
	top: 0;
	right: 0;
	height: 100%;
	width: min(92vw, 27rem);
	display: flex;
	flex-direction: column;
	background: var(--surface-page);
	border-left: 1px solid var(--line);
	box-shadow: -12px 0 40px -24px color-mix(in srgb, var(--color-ink) 55%, transparent);
	transform: translateX(100%);
	transition: transform 0.32s var(--card-ease, ease);
}

.cart-drawer.is-open .cart-drawer__panel {
	transform: translateX(0);
}

.cart-drawer__close {
	position: absolute;
	top: var(--space-2xs);
	right: var(--space-2xs);
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	background: transparent;
	border: 0;
	font-size: 1.75rem;
	line-height: 1;
	color: var(--color-ink);
	cursor: pointer;
}

.cart-drawer__inner {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	min-height: 0;
	padding: var(--space-lg) var(--space-md) var(--space-md);
}

.cart-drawer__title {
	margin: 0 0 var(--space-md);
	padding-right: 2.5rem;
	font-family: var(--font-display);
	font-weight: 500;
	font-size: var(--step-1);
	letter-spacing: 0.02em;
	color: var(--color-ink);
}

.cart-drawer__count {
	color: var(--ink-soft);
}

/* ---- Items ---- */
.cart-drawer__items {
	list-style: none;
	margin: 0;
	padding: 0;
	overflow-y: auto;
	/* Vertical scroll only — never horizontal. overflow-y:auto alone computes
	   overflow-x to auto, which was surfacing a stray horizontal scrollbar. */
	overflow-x: hidden;
	flex: 1 1 auto;
	border-top: 1px solid var(--line);
}

.cart-drawer__item {
	display: grid;
	/* minmax(0, 1fr) lets the body column shrink below its content width so a
	   long name/price wraps instead of forcing horizontal overflow. */
	grid-template-columns: 4rem minmax(0, 1fr) auto;
	gap: var(--space-sm);
	align-items: start;
	padding: var(--space-md) 0;
	border-bottom: 1px solid var(--line);
}

.cart-drawer__thumb {
	display: block;
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	overflow: hidden;
	background: var(--card-tile, var(--color-cream));
}

.cart-drawer__thumb img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 5;
	object-fit: cover;
}

.cart-drawer__item-body {
	display: flex;
	flex-direction: column;
	gap: var(--space-3xs);
	min-width: 0;
}

.cart-drawer__item-name {
	font-size: var(--step--1);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-ink);
	text-decoration: none;
	overflow-wrap: anywhere;
}

.cart-drawer__item-name:hover {
	color: var(--color-sage-text);
}

.cart-drawer__item-descriptor {
	font-size: var(--step--1);
	color: var(--ink-soft);
	overflow-wrap: anywhere;
}

/* Beaded personalisation summary on a cart line (colour · "name"). */
.cart-drawer__item-personalise {
	font-size: var(--step--1);
	color: var(--color-sage-text);
	overflow-wrap: anywhere;
}

.cart-drawer__item-meta {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: var(--space-3xs) var(--space-sm);
	margin-top: var(--space-3xs);
	font-size: var(--step--1);
}

.cart-drawer__item-qty {
	color: var(--ink-soft);
}

.cart-drawer__item-price {
	color: var(--color-ink);
}

.cart-drawer__remove {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	/* Negative TOP only, to align the glyph with the name row. No negative right
	   margin — that pushed the button past the list edge and forced overflow. */
	margin: -0.5rem 0 0 0;
	background: transparent;
	border: 0;
	font-size: 1.4rem;
	line-height: 1;
	color: var(--ink-soft);
	cursor: pointer;
	transition: color 0.2s var(--card-ease, ease);
}

.cart-drawer__remove:hover {
	color: var(--color-ink);
}

/* ---- Foot ---- */
.cart-drawer__foot {
	padding-top: var(--space-md);
	border-top: 1px solid var(--line-strong);
}

.cart-drawer__total {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	margin-bottom: var(--space-md);
}

.cart-drawer__total-label {
	font-size: var(--step--1);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--ink-soft);
}

.cart-drawer__total-value {
	font-size: var(--step-1);
	color: var(--color-ink);
}

.cart-drawer__checkout {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 48px;
	padding: var(--space-2xs) var(--space-md);
	background: var(--color-ink);
	color: var(--ink-on-dark);
	border: 1px solid var(--color-ink);
	border-radius: var(--radius-sm);
	font-size: var(--step--1);
	letter-spacing: 0.12em;
	text-transform: uppercase;
	text-decoration: none;
	transition: background 0.2s var(--card-ease, ease), color 0.2s var(--card-ease, ease);
}

.cart-drawer__checkout:hover {
	background: color-mix(in srgb, var(--color-ink) 82%, var(--color-white));
	color: var(--color-white);
}

.cart-drawer__view-cart {
	display: block;
	margin-top: var(--space-sm);
	text-align: center;
	font-size: var(--step--1);
	letter-spacing: 0.08em;
	color: var(--ink-soft);
}

.cart-drawer__view-cart:hover {
	color: var(--color-ink);
}

/* ---- Empty ---- */
.cart-drawer__empty {
	padding: var(--space-2xl) 0;
	text-align: center;
}

.cart-drawer__empty-line {
	margin: 0 0 var(--space-md);
	color: var(--ink-soft);
}

.cart-drawer__continue {
	font-size: var(--step--1);
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--color-ink);
}

.cart-drawer.is-busy .cart-drawer__inner {
	opacity: 0.6;
	pointer-events: none;
}

/* ============================================================
   Reduced motion
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		scroll-behavior: auto !important;
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}
}

/* ============================================================
   WhatsApp floating action button
   ============================================================ */
.whatsapp-fab {
	position: fixed;
	/* Safe-area inset so the button clears the iOS home indicator (the sticky
	   buy bar already accounts for this; the FAB must match to stay aligned). */
	bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px));
	right: 1.5rem;
	z-index: 900;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 3.25rem;
	height: 3.25rem;
	border-radius: 50%;
	background: var(--color-sage-deep);
	color: var(--ink-on-sage);
	box-shadow: 0 4px 16px color-mix(in srgb, var(--color-ink) 28%, transparent);
	transition: transform 0.2s ease, box-shadow 0.2s ease, bottom 260ms var(--nav-ease), opacity 200ms var(--nav-ease), visibility 200ms;
	text-decoration: none;
}

/* The mobile hero has no unoccupied lower corner: its privacy line and CTA row
   fill that zone. Keep this secondary support action out of the hero entirely,
   then reveal it once home.js confirms the hero has left the viewport. The
   render-blocking `.js` class prevents a first-paint flash; visibility and
   pointer-events also keep the hidden link out of keyboard/tap interaction. */
@media (max-width: 47.99rem) {
	.whatsapp-fab {
		display: none;
	}

	.js body:has(.home-hero) .whatsapp-fab {
		opacity: 0;
		visibility: hidden;
		pointer-events: none;
	}

	.js body.home-hero-is-past:has(.home-hero) .whatsapp-fab {
		opacity: 1;
		visibility: visible;
		pointer-events: auto;
	}
}

/* Avoid the sticky buy bar. When the homepage-mobile buy bar is showing (home.js
   toggles `.is-visible`), lift the FAB clear above it so the green bubble never
   paints over — or intercept taps meant for — the "Shop the cover" CTA. Scoped
   via :has() to the exact collision state only; every other page/state keeps the
   resting position. Browsers without :has() gracefully retain today's behaviour.
   The measured buy-bar box includes its safe-area padding, so the lifted state
   adds the bar height plus a quiet gap. */
body:has(.home-buybar.is-visible) .whatsapp-fab {
	/* The buy bar reports its actual rendered height from home.js. Measuring the
	   bar matters here because its price/name can wrap at narrow widths and its
	   safe-area padding is part of its rendered box. */
	bottom: calc(1.5rem + var(--home-buybar-height, 0px) + var(--space-sm));
}

/* Keep the floating support shortcut away from purchase-critical UI. WhatsApp
   remains available in the footer; transactional controls retain an
   unobstructed lower-right tap zone. */
.woocommerce-cart .whatsapp-fab,
.woocommerce-checkout .whatsapp-fab,
.woocommerce-account .whatsapp-fab,
.single-product .whatsapp-fab,
.post-type-archive-product .whatsapp-fab,
.tax-product_cat .whatsapp-fab {
	display: none;
}

.whatsapp-fab svg {
	width: 1.75rem;
	height: 1.75rem;
}

.whatsapp-fab:hover,
.whatsapp-fab:focus-visible {
	transform: scale(1.05);
	box-shadow: 0 6px 20px color-mix(in srgb, var(--color-ink) 36%, transparent);
}

.whatsapp-fab:focus-visible {
	outline: 2px solid var(--color-ink);
	outline-offset: 3px;
}
