/* =============================================================================
 * ETUMAX POWER — design system
 *
 * Implements knowledge-base/brand/11-visual-identity.md. The colour and type
 * tokens there are binding; what follows is how they are arranged.
 *
 * The design argument, in one line: in a category whose visual default is a
 * glowing sachet on a gold gradient, our ornament is the published quantity.
 *
 * Three devices carry that, and they are the only decorative moves in the file:
 *
 *   1. THE TAPERED RULE — lifted from the logo lockup, where a tapered rule sits
 *      under "ROYAL HONEY". It is the section divider everywhere. `.etx-rule`.
 *
 *   2. THE PANEL — ingredient and specification data set as a ruled list, name
 *      left in Inter, figure right in tabular figures. It appears at three
 *      scales: the homepage proof strip, the card composition preview, and the
 *      full product-page table. `.etx-panel`.
 *
 *   3. THE EYEBROW — a short uppercase label in the body face. VI-09 bars wide
 *      tracking outside the lockup style and bars letterspacing lowercase body
 *      text; these are uppercase and tracked at 0.08–0.12em, matching the h6
 *      token already in theme.json.
 *
 * What is deliberately absent, per VI section 7: glows, radiating shots, flame
 * and lightning motifs, starbursts, countdown timers, urgency badges, invented
 * seals, saturated gold gradients. VI-27 also holds — one accent per screen, so
 * gold marks the single most important thing in a view and nothing else.
 *
 * Compliance rules that constrain layout, not just content:
 *   CP-FMT-03  a disclosure is never collapsed, hidden, shrunk, or overlaid.
 *   VI-29      safety content sits in flow at normal weight, never styled to recede.
 *   VI-01      safety headings use the warning colour, never gold.
 *   VI-02      body text is never gold — it fails contrast at body sizes.
 *   VI-28      the ingredient table is a hero element, not fine print.
 *
 * ========================================================================== */

/* -----------------------------------------------------------------------------
 * 1. Local tokens
 *
 * Derived values only. Every colour resolves to a theme.json preset, which
 * resolves to knowledge-base/brand/11-visual-identity.md section 8. Nothing here
 * introduces a colour — VI-03.
 * -------------------------------------------------------------------------- */

/*
 * Border-box everywhere.
 *
 * Neither WordPress core nor the parent theme sets this globally — computed
 * box-sizing on <body> is content-box — so every component in this file that
 * combines a percentage width with padding overflowed its container by exactly
 * the padding. It cost 10px of horizontal scroll on the mobile product page, via
 * the gallery, the search panel, and the card buttons simultaneously.
 *
 * Fixing it once here is the correct repair. Fixing it per component is how the
 * same bug comes back with the next component.
 */
*,
*::before,
*::after {
	box-sizing: border-box;
}

:root {
	--etx-hairline: color-mix(in srgb, var(--wp--preset--color--stone) 30%, transparent);
	--etx-hairline-dark: color-mix(in srgb, var(--wp--preset--color--gold-pale) 18%, transparent);
	--etx-gold-wash: color-mix(in srgb, var(--wp--preset--color--gold) 8%, transparent);

	--etx-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
	--etx-dur: 220ms;

	/* Card image ground. Packshots are shot on plain white — VI-16. */
	--etx-shot-ground: var(--wp--preset--color--white);
}

/* -----------------------------------------------------------------------------
 * 2. Typographic primitives
 * -------------------------------------------------------------------------- */

/*
 * VI-06 — quantities are set in the body face with tabular figures, never in the
 * display serif. Numbers must read as data, not decoration.
 */
.etx-figure,
.etx-panel__value,
.etx-ingredients td,
.etx-ingredients th,
.woocommerce-Price-amount,
.wc-block-components-product-price,
.woocommerce-product-attributes td,
.woocommerce-product-attributes th {
	font-family: var(--wp--preset--font-family--body);
	font-variant-numeric: tabular-nums;
	font-feature-settings: "tnum" 1, "lnum" 1;
}

/* VI-09 — never letterspace lowercase body text. */
body,
p,
li {
	letter-spacing: normal;
}

/*
 * The eyebrow. Uppercase body face, modest tracking — the same treatment the h6
 * token already carries. Used to name a section without spending a heading on it.
 */
.etx-eyebrow {
	display: block;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.75rem, 12px);
	font-weight: 600;
	line-height: 1.4;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--wp--preset--color--gold-deep);
	margin-block-end: 0.75rem;
}

.etx-on-dark .etx-eyebrow,
.etx-hero .etx-eyebrow {
	color: var(--wp--preset--color--gold);
}

/* A lead paragraph — one step up from body, never a heading. */
.etx-lead {
	font-size: clamp(1.0625rem, 0.98rem + 0.4vw, 1.25rem);
	line-height: 1.55;
	max-inline-size: 62ch;
}

/*
 * Display headings are set tight. Playfair at large sizes opens up considerably,
 * and the default tracking reads as a wordmark rather than a sentence.
 */
.etx-display {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 500;
	line-height: 1.06;
	letter-spacing: -0.02em;
	text-wrap: balance;
}

/* -----------------------------------------------------------------------------
 * 3. Signature: the tapered rule
 *
 * From the logo lockup, where a tapered rule sits beneath "ROYAL HONEY". One
 * hairline that fades to nothing at both ends. It is the only divider used.
 * -------------------------------------------------------------------------- */

.etx-rule {
	border: 0;
	block-size: 1px;
	inline-size: min(100%, 22rem);
	margin-inline: 0;
	margin-block: 2rem;
	background: linear-gradient(
		90deg,
		transparent 0%,
		var(--wp--preset--color--gold) 22%,
		var(--wp--preset--color--gold) 78%,
		transparent 100%
	);
	opacity: 0.85;
}

.etx-rule--center {
	margin-inline: auto;
}

.etx-rule--full {
	inline-size: 100%;
}

/* Core separators inherit the same treatment so an editor cannot break the system. */
.wp-block-separator.is-style-wide {
	border: 0;
	block-size: 1px;
	background: linear-gradient(
		90deg,
		transparent,
		var(--wp--preset--color--gold-deep) 15%,
		var(--wp--preset--color--gold-deep) 85%,
		transparent
	);
	opacity: 0.7;
}

/* -----------------------------------------------------------------------------
 * 4. Section rhythm
 *
 * VI-26 — generous whitespace. Density reads as discount. Sections alternate
 * ground rather than tint, so the accent stays scarce (VI-27).
 * -------------------------------------------------------------------------- */

/*
 * The root stack has no gap.
 *
 * theme.json sets a global blockGap of spacing-40, and WordPress turns that into
 * a root-layout rule of its own:
 *
 *   :where(.wp-site-blocks) > * { margin-block-start: var(--wp--preset--spacing--40) }
 *
 * The direct children of .wp-site-blocks are only ever the three regions —
 * header, main, footer — so that declaration inserts 1.5rem of bare page
 * background between the black header and the first band, and again between the
 * last band and the ink footer. That was the white strip under the header and the
 * white strip above the footer: one rule, seen twice, on every page of the site.
 *
 * It is corrected here rather than by lowering blockGap, because blockGap is also
 * the default spacing between blocks inside every flow and constrained layout on
 * the site; zeroing it globally would collapse the rhythm of the content to fix
 * the seams around it. The three regions carry their own vertical padding, so the
 * gap between them is not spacing that was lost — it is spacing that was never
 * wanted.
 *
 * Core's rule is wrapped in :where(), which is specificity zero by design, so a
 * plain class selector overrides it as intended rather than by force. No
 * !important, and nothing per-page.
 */
.wp-site-blocks > * {
	margin-block-start: 0;
	margin-block-end: 0;
}

/*
 * …and the same seam, arriving by a different route.
 *
 * Cart, Checkout and My account are rendered by templates whose `main` has no
 * padding or border of its own, so the top margin of whatever block opens the page
 * collapses straight out through it and moves `main` itself down — reinstating the
 * identical gap under the header that the rule above removes.
 *
 * flow-root makes `main` a block formatting context, so that spacing stays inside
 * the region where it was meant to be. It changes nothing on the templates whose
 * first child is a full-bleed band, because those have no margin to escape.
 */
.wp-site-blocks > main {
	display: flow-root;
}

.etx-band {
	padding-block: clamp(3.5rem, 2rem + 6vw, 7rem);
}

.etx-band--tight {
	padding-block: clamp(2.5rem, 1.5rem + 4vw, 4.5rem);
}

.etx-band--dark {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--bone);
}

.etx-band--black {
	background: var(--wp--preset--color--black);
	color: var(--wp--preset--color--bone);
}

.etx-band--bone {
	background: var(--wp--preset--color--bone);
	color: var(--wp--preset--color--near-black);
}

/* VI-02 — body text is never gold. Headings on dark grounds are bone, not gold. */
.etx-band--dark :is(h1, h2, h3, h4, h5),
.etx-band--black :is(h1, h2, h3, h4, h5),
.etx-hero :is(h1, h2, h3, h4, h5),
.etx-shophead :is(h1, h2, h3, h4, h5),
.etx-on-dark :is(h1, h2, h3, h4, h5) {
	color: var(--wp--preset--color--bone);
}

.etx-band--dark a:not(.wp-element-button):not(.etx-card__link),
.etx-band--black a:not(.wp-element-button):not(.etx-card__link),
.etx-on-dark a:not(.wp-element-button):not(.etx-card__link) {
	color: var(--wp--preset--color--gold-pale);
}

.etx-band--dark a:not(.wp-element-button):hover,
.etx-band--black a:not(.wp-element-button):hover,
.etx-on-dark a:not(.wp-element-button):hover {
	color: var(--wp--preset--color--white);
}

/* A section header: eyebrow, heading, optional lead. */
.etx-sectionhead {
	max-inline-size: 46rem;
	margin-block-end: clamp(2rem, 1rem + 3vw, 3.5rem);
}

.etx-sectionhead--center {
	margin-inline: auto;
	text-align: center;
}

.etx-sectionhead--center .etx-lead {
	margin-inline: auto;
}

.etx-sectionhead h2 {
	margin-block: 0 0.75rem;
}

/* -----------------------------------------------------------------------------
 * 5. Buttons and links
 *
 * Two weights only. A page has one primary action; everything else is quiet.
 * -------------------------------------------------------------------------- */

.wp-element-button,
.wp-block-button__link,
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;

	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.9375rem, 15px);
	font-weight: 500;
	line-height: 1.2;
	text-decoration: none;
	letter-spacing: 0.01em;

	padding: 0.9rem 1.9rem;
	border: 1px solid transparent;
	border-radius: 2px;

	background: var(--wp--preset--color--near-black);
	color: var(--wp--preset--color--bone);

	transition: background-color var(--etx-dur) var(--etx-ease),
		color var(--etx-dur) var(--etx-ease),
		border-color var(--etx-dur) var(--etx-ease);
}

.wp-element-button:hover,
.wp-block-button__link:hover,
.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce #respond input#submit:hover {
	background: var(--wp--preset--color--gold-deep);
	color: var(--wp--preset--color--white);
}

/* The gold action. VI-27 — one per screen. */
.is-style-etx-gold .wp-block-button__link,
.etx-button--gold {
	background: var(--wp--preset--color--gold);
	color: var(--wp--preset--color--black);
	font-weight: 600;
}

.is-style-etx-gold .wp-block-button__link:hover,
.etx-button--gold:hover {
	background: var(--wp--preset--color--gold-pale);
	color: var(--wp--preset--color--black);
}

/* The quiet action: a hairline outline that works on either ground. */
.is-style-etx-outline .wp-block-button__link,
.etx-button--outline {
	background: transparent;
	border-color: currentColor;
	color: inherit;
}

.is-style-etx-outline .wp-block-button__link:hover,
.etx-button--outline:hover {
	background: var(--wp--preset--color--gold);
	border-color: var(--wp--preset--color--gold);
	color: var(--wp--preset--color--black);
}

/* A text action with the tapered rule as its underline. */
.etx-textlink {
	display: inline-block;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.9375rem, 15px);
	font-weight: 500;
	text-decoration: none;
	padding-block-end: 0.35rem;
	border-block-end: 1px solid var(--wp--preset--color--gold);
	transition: border-color var(--etx-dur) var(--etx-ease), color var(--etx-dur) var(--etx-ease);
}

.etx-textlink:hover {
	border-block-end-color: currentColor;
}

.etx-textlink::after {
	content: " →";
	font-variant-numeric: normal;
}

/*
 * Focus. Visible on both grounds, and never removed. The gold ring is the one
 * place gold is allowed to appear more than once per screen — an accessibility
 * affordance is not decoration.
 */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
	outline: 2px solid var(--wp--preset--color--gold);
	outline-offset: 3px;
	border-radius: 1px;
}

/* -----------------------------------------------------------------------------
 * 6. Header
 * -------------------------------------------------------------------------- */

.etx-header {
	position: relative;
	z-index: 60;
	border-block-end: 1px solid var(--etx-hairline-dark);
}

.etx-header__bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: clamp(1rem, 3vw, 2.5rem);
}

.etx-header .wp-block-site-logo img {
	inline-size: clamp(132px, 14vw, 180px);
	block-size: auto;
}

/* Navigation */
.etx-header .wp-block-navigation {
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.9375rem, 15px);
	font-weight: 500;
}

.etx-header .wp-block-navigation .wp-block-navigation-item__content {
	position: relative;
	padding-block: 0.5rem;
	text-decoration: none;
	color: var(--wp--preset--color--bone);
	transition: color var(--etx-dur) var(--etx-ease);
}

.etx-header .wp-block-navigation .wp-block-navigation-item__content:hover {
	color: var(--wp--preset--color--gold-pale);
}

/*
 * The active-state marker is the tapered rule again, at nav scale. It grows from
 * the centre so it reads as the same object as the section dividers.
 */
.etx-header .wp-block-navigation .wp-block-navigation-item__content::after {
	content: "";
	position: absolute;
	inset-inline: 0;
	inset-block-end: 0;
	block-size: 1px;
	background: linear-gradient(90deg, transparent, var(--wp--preset--color--gold), transparent);
	transform: scaleX(0);
	transition: transform var(--etx-dur) var(--etx-ease);
}

.etx-header .wp-block-navigation .wp-block-navigation-item__content:hover::after,
.etx-header .wp-block-navigation .current-menu-item > .wp-block-navigation-item__content::after {
	transform: scaleX(1);
}

/* Submenu, styled as a quiet panel rather than a dropdown list. */
.etx-header .wp-block-navigation .wp-block-navigation-submenu__toggle + .wp-block-navigation__submenu-container,
.etx-header .wp-block-navigation .wp-block-navigation__submenu-container {
	background: var(--wp--preset--color--ink);
	border: 1px solid var(--etx-hairline-dark);
	border-radius: 2px;
	padding: 0.75rem 0;
	min-inline-size: 15rem;
	box-shadow: 0 24px 48px rgb(0 0 0 / 45%);
}

.etx-header .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	padding: 0.55rem 1.25rem;
	inline-size: 100%;
}

.etx-header .wp-block-navigation__submenu-container .wp-block-navigation-item__content::after {
	display: none;
}

/* Utility cluster: search, account, cart, language. */
.etx-utils {
	display: flex;
	align-items: center;
	gap: 0.35rem;
}

/*
 * The paragraph wpautop puts round the middle of the cluster.
 *
 * [etumax_header_utils] returns a <details> for search, two bare <a> elements for
 * account and basket, and a <details> for language. The shortcode block runs that
 * through wpautop, which sees the two anchors as a run of inline content between two
 * block elements and wraps them in a <p>.
 *
 * That paragraph then becomes a single flex item holding two icons, and it is the item
 * that gives way when the row is tight: the account and basket icons stacked one above
 * the other — at 600px and 900px before the language control existed, and at 390px once
 * it did — while `flex-wrap: nowrap` on the cluster made the cause look impossible.
 *
 * `display: contents` removes the box and promotes the two anchors to flex items of the
 * cluster itself, which is what the markup meant in the first place. The anchors keep
 * their own semantics; only the generated paragraph's box disappears.
 */
.etx-utils > p {
	display: contents;
}

.etx-utils__item {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: 2.75rem;
	block-size: 2.75rem;
	border-radius: 2px;
	color: var(--wp--preset--color--bone);
	text-decoration: none;
	transition: color var(--etx-dur) var(--etx-ease), background-color var(--etx-dur) var(--etx-ease);
}

.etx-utils__item:hover {
	color: var(--wp--preset--color--gold-pale);
	background: rgb(255 255 255 / 6%);
}

.etx-utils__item svg {
	inline-size: 1.25rem;
	block-size: 1.25rem;
}

/* Cart count. A real number, so it is set in tabular figures like every other. */
.etx-utils__count {
	position: absolute;
	inset-block-start: 0.35rem;
	inset-inline-end: 0.3rem;

	min-inline-size: 1.15rem;
	padding: 0 0.25rem;
	border-radius: 999px;

	background: var(--wp--preset--color--gold);
	color: var(--wp--preset--color--black);

	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.6875rem, 11px);
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	line-height: 1.15rem;
	text-align: center;
}

.etx-utils__count[data-count="0"] {
	display: none;
}

/* Search, revealed inline rather than in a modal. No JS: it is a details element. */
.etx-search {
	position: relative;
}

.etx-search > summary {
	list-style: none;
	cursor: pointer;
}

.etx-search > summary::-webkit-details-marker {
	display: none;
}

/* A closed <details> should not lay its panel out at all. */
.etx-search:not([open]) .etx-search__panel {
	display: none;
}

.etx-search__panel {
	position: absolute;
	inset-block-start: calc(100% + 0.75rem);
	inset-inline-end: 0;
	z-index: 20;

	inline-size: min(24rem, calc(100vw - 3rem));
	padding: 1rem;

	background: var(--wp--preset--color--ink);
	border: 1px solid var(--etx-hairline-dark);
	border-radius: 2px;
	box-shadow: 0 24px 48px rgb(0 0 0 / 45%);
}

.etx-search__panel .wp-block-search__input,
.etx-search__panel input[type="search"] {
	inline-size: 100%;
	padding: 0.75rem 0.9rem;
	background: var(--wp--preset--color--black);
	border: 1px solid var(--etx-hairline-dark);
	border-radius: 2px;
	color: var(--wp--preset--color--bone);
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.9375rem, 15px);
}

.etx-search__panel input[type="search"]::placeholder {
	color: var(--wp--preset--color--stone);
}

/*
 * Announcement strip. Factual only — never urgency or a countdown (LCR-03).
 *
 * The ground goes on the wrapper, not on the strip.
 *
 * theme.json sets useRootPaddingAwareAlignments, which puts the root padding on the
 * body, so a background inside an alignfull group still stops at that padding. The
 * bar shipped as a black band with a white sliver down each side — the same defect
 * the header and footer already carry a note about. Painting the wrapper and letting
 * the strip inside stay constrained fixes it without moving any content.
 */
.etx-announce-wrap {
	background: var(--wp--preset--color--black);
	/* The hairline rides the wrapper too, or it stops at the content width. */
	border-block-end: 1px solid var(--etx-hairline-dark);
	padding: 0;
}

.etx-announce {
	background: var(--wp--preset--color--black);
	color: var(--wp--preset--color--gold-pale);
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.8125rem, 13px);
	letter-spacing: 0.04em;
	text-align: center;
	padding-block: 0.6rem;
}

/*
 * Three messages, rotated in CSS.
 *
 * The track is a grid with every message stacked in cell 1/1, so the strip's height
 * is the tallest message and never changes as they cycle. Each item runs the same
 * keyframe on the same duration with a staggered negative delay, which is what
 * keeps them in sequence without a timer, a script, or a layout shift.
 *
 * No script means nothing to break, nothing to load, and no message that appears
 * late on a slow connection. It also means the strip is honest about what it is:
 * three facts on a loop, not a countdown. LCR-03 bars urgency devices outright.
 */
.etx-announce__track {
	display: grid;
	place-items: center;
	min-block-size: 1.2em;
	padding-inline: var(--wp--style--root--padding-right, 1rem);
}

/*
 * One message every 6s. The cycle is N × 6s, with N emitted by
 * etumax_announcement_bar() so adding a message lengthens the cycle instead of
 * dropping the last one off the end.
 *
 * The keyframe windows below are written for four messages: each is visible for
 * about 25% of the cycle. Changing the message count to something other than four
 * still rotates correctly — the timing stays in step — but the visible and blank
 * spans drift a little from even; retune the percentages if it ever settles at a
 * different number.
 */
.etx-announce__item {
	grid-area: 1 / 1;
	opacity: 0;
	animation: etx-announce-cycle calc(var(--etx-announce-n, 4) * 6s) linear infinite;
	animation-delay: calc(var(--etx-announce-i, 0) * 6s);
}

@keyframes etx-announce-cycle {
	0%,
	1% { opacity: 0; }
	3%,
	22% { opacity: 1; }
	25%,
	100% { opacity: 0; }
}

/*
 * Reduced motion: the rotation stops and the first message stands.
 *
 * Hiding the other two rather than letting them stack is the point — three
 * overlapping lines of text in one grid cell is unreadable, which is a worse
 * outcome than one fact shown permanently.
 */
@media (prefers-reduced-motion: reduce) {
	.etx-announce__item {
		animation: none;
		opacity: 0;
	}

	.etx-announce__item:first-child {
		opacity: 1;
	}
}

/* -----------------------------------------------------------------------------
 * 7. Hero
 *
 * The thesis, stated in type and then immediately evidenced. No lifestyle
 * photography exists yet (VI section 9 open item) and VI-19 bars the glowing
 * packshot the category reaches for, so the hero's proof is the panel.
 * -------------------------------------------------------------------------- */

.etx-hero {
	position: relative;
	background: var(--wp--preset--color--black);
	color: var(--wp--preset--color--bone);
	overflow: hidden;
}

/*
 * A single very soft radial, well under the threshold where it reads as a glow.
 * VI-19 bars visual exaggeration of potency; this lights the type, not a product.
 */
.etx-hero::before {
	content: "";
	position: absolute;
	inset: 0;
	background: radial-gradient(
		120% 80% at 50% 0%,
		rgb(198 162 100 / 10%) 0%,
		transparent 62%
	);
	pointer-events: none;
}

.etx-hero__inner {
	position: relative;
	padding-block: clamp(4rem, 2rem + 9vw, 9rem);
}

.etx-hero__title {
	font-size: var(--wp--preset--font-size--hero);
	max-inline-size: 20ch;
}

.etx-hero__title em {
	font-style: italic;
	color: var(--wp--preset--color--gold);
}

.etx-hero__lead {
	margin-block-start: 1.75rem;
	color: color-mix(in srgb, var(--wp--preset--color--bone) 82%, transparent);
}

.etx-hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 1rem;
	margin-block-start: 2.25rem;
}

/*
 * The terms line under the hero buttons.
 *
 * Origin, delivery window, packaging — the three things a first-time buyer from an
 * unfamiliar manufacturer needs before they will click anything. Set small and
 * quiet: it removes friction, it is not an argument, and at hero scale it must not
 * compete with the headline.
 */
.etx-hero__terms {
	margin-block-start: 1.5rem;
	font-size: max(0.8125rem, 13px);
	line-height: 1.6;
	color: color-mix(in srgb, var(--wp--preset--color--bone) 60%, transparent);
}

/* Hero layout: statement left, evidence right. */
.etx-hero__grid {
	display: grid;
	gap: clamp(2.5rem, 1rem + 5vw, 5rem);
	align-items: center;
}

@media (min-width: 900px) {
	.etx-hero__grid {
		grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
	}
}

.etx-hero__proof {
	/* The panel needs a ground of its own or the hairlines vanish into the black. */
	background: color-mix(in srgb, var(--wp--preset--color--near-black) 88%, transparent);
	border: 1px solid var(--etx-hairline-dark);
	border-radius: 2px;
	padding: clamp(1.25rem, 0.5rem + 2vw, 2rem);
}

.etx-hero__proof .etx-panel {
	border-block-color: var(--wp--preset--color--gold-deep);
}

/*
 * The proof column's own headline.
 *
 * It carries the milligram total — the number the whole page turns on — so it is
 * set larger than the body but well below the h1. The hero has one voice and this
 * is not it; this is the evidence answering it.
 */
.etx-hero__prooftitle {
	margin-block: 0.5rem 0.75rem;
	font-family: var(--wp--preset--font-family--body);
	font-size: clamp(1.125rem, 1rem + 0.6vw, 1.4rem);
	font-weight: 600;
	line-height: 1.3;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--bone);
}

.etx-hero__proofbody {
	margin-block: 0 1.5rem;
	font-size: max(0.875rem, 14px);
	line-height: 1.65;
	color: color-mix(in srgb, var(--wp--preset--color--bone) 66%, transparent);
}

/*
 * The sub-bar under the hero.
 *
 * One line, four terms, on the bone ground so it reads as a ledge the hero sits on
 * rather than a second banner. It wraps rather than scrolls on narrow screens —
 * a horizontally scrolling strip of terms is a strip nobody reads.
 */
.etx-subbar__line {
	margin-block: 0;
	font-size: max(0.8125rem, 13px);
	line-height: 1.7;
	letter-spacing: 0.01em;
	color: var(--wp--preset--color--stone);
}

/* -----------------------------------------------------------------------------
 * 7A. Homepage sections
 * -------------------------------------------------------------------------- */

/* A two-up split that collapses to one column. Used for categories, authenticity,
   and the claims section. */
.etx-split {
	display: grid;
	gap: clamp(1.5rem, 0.5rem + 3vw, 4rem);
}

/*
 * Grid tracks own their own spacing.
 *
 * These containers are authored as block groups with a flow layout and turned into
 * grids here, so core's `:root :where(.is-layout-flow) > * { margin-block-start }`
 * still applies to every child after the first. In a grid that margin does not
 * collapse into the gap — it offsets the cell, which is why the second card in the
 * 404's pair and in the homepage's category pair sat 24px lower than the first.
 */
.etx-split > *,
.etx-trustrow > *,
.etx-steps > *,
.etx-brands > *,
.etx-header__bar > *,
.etx-hero__grid > *,
.etx-footer__grid > *,
.etx-faq > * {
	margin-block-start: 0;
	margin-block-end: 0;
}

@media (min-width: 800px) {
	.etx-split {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

.etx-splitcard {
	padding: clamp(1.5rem, 1rem + 2vw, 2.5rem);
	background: var(--wp--preset--color--white);
	border: 1px solid var(--etx-hairline);
	border-radius: 2px;
}

.etx-splitcard h3 {
	margin-block: 0 0.75rem;
}

.etx-splitcard p {
	color: var(--wp--preset--color--stone);
}

.etx-splitcard p:last-child {
	margin-block-end: 0;
	color: inherit;
}

/* The trust row on the homepage has no top border — the band edge already reads
   as one, and two hairlines a few pixels apart is a mistake, not a rhythm. */
.etx-trustrow--flat {
	border: 0;
	margin-block: 0;
	padding-block: 0;
}

/*
 * How we work.
 *
 * Numbered because this is a real sequence: a panel can only be published after
 * the thing is made, and it is published before it is sold. The numeral is set
 * in the body face with tabular figures like every other number on the site —
 * VI-06 — so it reads as an index, not as ornament.
 */
.etx-steps {
	display: grid;
	gap: clamp(2rem, 1rem + 3vw, 3.5rem);
	counter-reset: etx-step;
}

@media (min-width: 800px) {
	.etx-steps {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

.etx-step {
	padding-block-start: 1.5rem;
	border-block-start: 1px solid var(--etx-hairline-dark);
}

.etx-step__n {
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.8125rem, 13px);
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	letter-spacing: 0.12em;
	color: var(--wp--preset--color--gold);
	margin-block: 0 1rem;
}

.etx-step h3 {
	font-size: clamp(1.25rem, 1.1rem + 0.5vw, 1.5625rem);
	margin-block: 0 0.65rem;
}

.etx-step p {
	margin: 0;
	color: color-mix(in srgb, var(--wp--preset--color--bone) 74%, transparent);
	font-size: max(0.9375rem, 15px);
	line-height: 1.55;
}

/* Closing call to action. */
.etx-cta .etx-rule,
.etx-cta .wp-block-separator {
	margin-inline: auto;
	margin-block: 2rem;
	max-inline-size: 16rem;
}

.etx-cta .wp-block-buttons {
	justify-content: center;
}

/* -----------------------------------------------------------------------------
 * 8. Signature: the panel
 *
 * VI-28 — specifications get real space; the ingredient table is a hero element,
 * not fine print. This is that instruction taken literally: the data is set like
 * a certificate, and it is the most designed object on the site.
 * -------------------------------------------------------------------------- */

.etx-panel {
	--etx-panel-rule: var(--etx-hairline);

	border-block: 1px solid var(--wp--preset--color--gold);
	padding-block: 0.5rem;
	margin-block: 0;
}

.etx-on-dark .etx-panel,
.etx-band--dark .etx-panel,
.etx-band--black .etx-panel,
.etx-hero .etx-panel {
	--etx-panel-rule: var(--etx-hairline-dark);
}

.etx-panel__caption {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.5rem 1rem;
	padding-block: 0.9rem;
	border-block-end: 1px solid var(--etx-panel-rule);
}

.etx-panel__caption-title {
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.8125rem, 13px);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.1em;
}

.etx-panel__caption-note {
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.8125rem, 13px);
	color: var(--wp--preset--color--stone);
}

.etx-on-dark .etx-panel__caption-note,
.etx-hero .etx-panel__caption-note {
	color: color-mix(in srgb, var(--wp--preset--color--bone) 62%, transparent);
}

.etx-panel__row {
	display: flex;
	align-items: baseline;
	gap: 1rem;
	padding-block: 0.85rem;
	border-block-end: 1px solid var(--etx-panel-rule);
}

.etx-panel__row:last-child {
	border-block-end: 0;
}

.etx-panel__name {
	flex: 1 1 auto;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.9375rem, 15px);
	line-height: 1.4;
}

/*
 * The leader line. It is what makes a list of quantities read as a document
 * rather than a table, and it is the reason the figure can sit far right without
 * losing its row.
 */
.etx-panel__leader {
	flex: 1 1 2rem;
	min-inline-size: 1.5rem;
	align-self: center;
	block-size: 1px;
	background: repeating-linear-gradient(
		90deg,
		var(--etx-panel-rule) 0 2px,
		transparent 2px 6px
	);
}

.etx-panel__value {
	flex: none;
	font-size: max(0.9375rem, 15px);
	font-weight: 600;
	white-space: nowrap;
}

.etx-panel__row--total {
	border-block-end: 0;
	padding-block-start: 1rem;
}

.etx-panel__row--total .etx-panel__name,
.etx-panel__row--total .etx-panel__value {
	font-weight: 600;
	color: var(--wp--preset--color--gold-deep);
}

.etx-on-dark .etx-panel__row--total :is(.etx-panel__name, .etx-panel__value),
.etx-hero .etx-panel__row--total :is(.etx-panel__name, .etx-panel__value) {
	color: var(--wp--preset--color--gold);
}

.etx-panel__latin {
	font-style: italic;
	color: var(--wp--preset--color--stone);
}

.etx-on-dark .etx-panel__latin,
.etx-hero .etx-panel__latin {
	color: color-mix(in srgb, var(--wp--preset--color--bone) 55%, transparent);
}

.etx-panel__foot {
	padding-block: 0.9rem 0.2rem;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.8125rem, 13px);
	color: var(--wp--preset--color--stone);
}

.etx-on-dark .etx-panel__foot,
.etx-hero .etx-panel__foot {
	color: color-mix(in srgb, var(--wp--preset--color--bone) 62%, transparent);
}

/*
 * Staggered reveal, scroll-driven, no JavaScript. Progressive enhancement: where
 * animation-timeline is unsupported the rows are simply present.
 */
@supports (animation-timeline: view()) {
	@media (prefers-reduced-motion: no-preference) {
		.etx-panel--reveal .etx-panel__row {
			animation: etx-row-in linear both;
			animation-timeline: view();
			animation-range: entry 5% cover 22%;
		}
	}
}

@keyframes etx-row-in {
	from { opacity: 0; transform: translateY(0.5rem); }
	to   { opacity: 1; transform: none; }
}

/* -----------------------------------------------------------------------------
 * 9. Product cards
 *
 * Used on the shop archive, in related products, and in the homepage featured
 * grid. One component, one set of rules — a card must not look different
 * depending on which template printed it.
 * -------------------------------------------------------------------------- */

.woocommerce ul.products,
.etx-grid {
	display: grid;
	/*
	 * auto-fit, not auto-fill. auto-fill keeps the empty tracks it created, so a
	 * three-product category left a card-shaped hole on the right of the row and
	 * read as a failed render. auto-fit collapses them and the row fills.
	 */
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
	gap: clamp(1.25rem, 0.5rem + 2vw, 2.25rem);
	margin: 0;
	padding: 0;
	list-style: none;
}

.woocommerce ul.products::before,
.woocommerce ul.products::after {
	display: none;
}

.woocommerce ul.products li.product,
.etx-card {
	position: relative;
	display: flex;
	flex-direction: column;
	inline-size: 100% !important;
	margin: 0 !important;
	padding: 0;
	float: none !important;
	background: var(--wp--preset--color--white);
	border: 1px solid var(--etx-hairline);
	border-radius: 2px;
	overflow: hidden;
	transition: border-color var(--etx-dur) var(--etx-ease),
		box-shadow var(--etx-dur) var(--etx-ease),
		transform var(--etx-dur) var(--etx-ease);
}

.etx-band--dark .etx-card,
.etx-band--black .etx-card,
.etx-on-dark .etx-card {
	background: var(--wp--preset--color--near-black);
	border-color: var(--etx-hairline-dark);
}

.woocommerce ul.products li.product:hover,
.etx-card:hover {
	border-color: var(--wp--preset--color--gold);
	box-shadow: var(--wp--preset--shadow--lift);
	transform: translateY(-3px);
}

/* The image well. A fixed ratio so an inconsistent packshot cannot break the row. */
.etx-card__media {
	display: block;
	position: relative;
	background: var(--etx-shot-ground);
	aspect-ratio: 1 / 1;
	overflow: hidden;
	text-decoration: none;
}

.woocommerce ul.products li.product img,
.etx-card__media img {
	inline-size: 100%;
	block-size: 100%;
	object-fit: contain;
	padding: clamp(0.75rem, 3%, 1.5rem);
	margin: 0;
	transition: transform 400ms var(--etx-ease);
}

.woocommerce ul.products li.product:hover img,
.etx-card:hover .etx-card__media img {
	transform: scale(1.035);
}

.etx-card__body {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	gap: 0.5rem;
	padding: 1.25rem 1.25rem 1.5rem;
}

/* Brand line. Names the maker before the product — VI-15, BD-11 transparency. */
.etx-card__brand {
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.6875rem, 11px);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.11em;
	color: var(--wp--preset--color--gold-deep);
}

.etx-on-dark .etx-card__brand,
.etx-band--dark .etx-card__brand,
.etx-band--black .etx-card__brand {
	color: var(--wp--preset--color--gold);
}

.woocommerce ul.products li.product .woocommerce-loop-product__title,
.etx-card__title {
	font-family: var(--wp--preset--font-family--display);
	font-size: max(1.125rem, 18px);
	font-weight: 500;
	line-height: 1.25;
	letter-spacing: -0.01em;
	padding: 0;
	margin: 0;
	text-wrap: balance;
}

.woocommerce ul.products li.product .woocommerce-loop-product__title a,
.etx-card__title a {
	color: inherit;
	text-decoration: none;
}

/* The card's composition preview — the panel at its smallest scale. */
.etx-card__panel {
	margin-block-start: 0.35rem;
	padding-block-start: 0.85rem;
	border-block-start: 1px solid var(--etx-hairline);
}

.etx-on-dark .etx-card__panel,
.etx-band--dark .etx-card__panel,
.etx-band--black .etx-card__panel {
	border-block-start-color: var(--etx-hairline-dark);
}

.etx-card__panel .etx-panel__row {
	padding-block: 0.3rem;
	border-block-end: 0;
	gap: 0.6rem;
}

.etx-card__panel .etx-panel__name,
.etx-card__panel .etx-panel__value {
	font-size: max(0.8125rem, 13px);
}

.etx-card__panel .etx-panel__value {
	font-weight: 600;
}

/*
 * The card's reason to buy — the one sentence no other SKU could claim (PL-01).
 *
 * It replaces the three-row ingredient preview that used to sit here. The panel
 * itself is unchanged and in full on the product page; what the archive needed
 * was a reason, not a specification.
 */
.etx-card__reason {
	margin: 0.6rem 0 0;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.875rem, 14px);
	line-height: 1.45;
	color: color-mix(in srgb, currentcolor 78%, transparent);
}

.etx-card__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.5rem 1rem;
	margin-block-start: auto;
	padding-block-start: 1rem;
}

/*
 * Cost per unit, beside the price.
 *
 * Tabular figures because these are meant to be compared down a column — VI-06.
 * It is the only thing that distinguishes two SKUs sold at the same price for the
 * same net weight, so it is set to be read, not tucked away.
 */
.etx-card__unit {
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.8125rem, 13px);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
	color: var(--wp--preset--color--stone);
}

.etx-on-dark .etx-card__unit,
.etx-band--dark .etx-card__unit,
.etx-band--black .etx-card__unit {
	color: color-mix(in srgb, var(--wp--preset--color--bone) 58%, transparent);
}

.woocommerce ul.products li.product .price,
.etx-card__price {
	margin: 0;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(1.0625rem, 17px);
	font-weight: 600;
	color: inherit;
}

.woocommerce ul.products li.product .price del {
	opacity: 0.55;
	font-weight: 400;
}

/* Format note — "12 × 20 g", the one spec that belongs on a card. */
.etx-card__format {
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.8125rem, 13px);
	font-variant-numeric: tabular-nums;
	color: var(--wp--preset--color--stone);
}

.etx-on-dark .etx-card__format,
.etx-band--dark .etx-card__format,
.etx-band--black .etx-card__format {
	color: color-mix(in srgb, var(--wp--preset--color--bone) 58%, transparent);
}

.woocommerce ul.products li.product .button,
.etx-card__cta {
	inline-size: 100%;
	margin-block-start: 1rem;
}

/*
 * No card badges.
 *
 * The badge layer is gone, not merely unstyled. It only ever carried the 18+
 * marker, which went with the age gate on 2026-08-03, and VI section 7 bars every
 * other candidate — starbursts, urgency flashes, invented seals — while BD-17 bars
 * a certification badge until certificate references are on file. Nothing may be
 * laid over the packshot; the photograph is the card's first argument.
 */

/*
 * The card has exactly two links: the image well and the title. Both point at the
 * product, the image one is aria-hidden and untabbable, so a keyboard user meets
 * one link per card.
 *
 * An earlier revision used a stretched overlay anchor. It needed position:absolute
 * on the anchor and position:relative on everything that had to sit above it —
 * two single-class rules of equal specificity, where the later one silently won
 * and the visually-hidden link text rendered on top of the title. Two honest
 * links are simpler and do not have a cancellation to remember.
 */
/*
 * WooCommerce's *block* product grids.
 *
 * Used by the empty-cart cross-sell and anywhere an editor drops a products
 * block. They cannot carry the composition panel — that is composed on the
 * classic loop hooks — so they are not pretending to be the same card. They are
 * given the same well, the same border, and the same type so they read as a
 * quieter member of the same family rather than as a different site.
 */
.wc-block-grid__products,
.wp-block-woocommerce-product-template {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
	gap: clamp(1.25rem, 0.5rem + 2vw, 2.25rem);
	list-style: none;
	margin: 0;
	padding: 0;
}

.wc-block-grid__product,
.wp-block-woocommerce-product-template .wc-block-product {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	inline-size: 100%;
	margin: 0;
	padding: 0 0 1.25rem;
	text-align: start;
	background: var(--wp--preset--color--white);
	border: 1px solid var(--etx-hairline);
	border-radius: 2px;
	overflow: hidden;
	transition: border-color var(--etx-dur) var(--etx-ease), box-shadow var(--etx-dur) var(--etx-ease);
}

.wc-block-grid__product:hover,
.wp-block-woocommerce-product-template .wc-block-product:hover {
	border-color: var(--wp--preset--color--gold);
	box-shadow: var(--wp--preset--shadow--card);
}

.wc-block-grid__product-image,
.wc-block-components-product-image {
	margin: 0 0 0.75rem;
	background: var(--etx-shot-ground);
}

.wc-block-grid__product-image img,
.wc-block-components-product-image img {
	aspect-ratio: 1 / 1;
	object-fit: contain !important;
	inline-size: 100%;
	padding: clamp(0.75rem, 3%, 1.5rem);
}

.wc-block-grid__product-title,
.wc-block-components-product-title {
	font-family: var(--wp--preset--font-family--display);
	font-size: max(1rem, 16px) !important;
	font-weight: 500;
	line-height: 1.3;
	letter-spacing: -0.01em;
	margin: 0;
	padding-inline: 1.25rem;
}

.wc-block-grid__product-title a,
.wc-block-components-product-title a {
	color: inherit;
	text-decoration: none;
}

.wc-block-grid__product-price,
.wc-block-components-product-price {
	display: block;
	padding-inline: 1.25rem;
	font-weight: 600;
	font-size: max(1rem, 16px);
}

.wc-block-grid__product-add-to-cart,
.wp-block-woocommerce-product-button {
	padding-inline: 1.25rem;
	margin-block-start: auto;
	padding-block-start: 0.75rem;
}

.wc-block-grid__product-add-to-cart .wp-block-button__link {
	inline-size: 100%;
}

/* -----------------------------------------------------------------------------
 * 10. Shop archive
 * -------------------------------------------------------------------------- */

.etx-shophead {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--bone);
	padding-block: clamp(2rem, 1.25rem + 2.5vw, 3.25rem);
}

/* Content pages get a shallower band — there is no lead or chip row under it. */
.etx-pagehead {
	padding-block: clamp(2rem, 1.25rem + 3vw, 3.5rem);
}

/*
 * The band under the shop head opens tighter than a standalone band.
 *
 * With the full tight-band padding, the shop page put its breadcrumb at 616px, the
 * result count at 683px, and the first product card at 760px on a 900px viewport —
 * a catalogue of nine products where not one of them was visible without scrolling.
 * The dark head above has already given the page its opening space; repeating it
 * below the fold line is where the products should be.
 */
.etx-shophead + .etx-band {
	padding-block-start: clamp(1.5rem, 1rem + 1.5vw, 2.25rem);
}

.etx-shophead h1 {
	color: var(--wp--preset--color--bone);
	margin-block: 0 0.75rem;
}

.etx-shophead__lead {
	color: color-mix(in srgb, var(--wp--preset--color--bone) 78%, transparent);
	max-inline-size: 54ch;
}

/* Category navigation — a row of quiet chips, current one marked with gold. */
.etx-catnav {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.etx-catnav a {
	display: inline-block;
	padding: 0.5rem 1rem;
	border: 1px solid var(--etx-hairline);
	border-radius: 999px;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.875rem, 14px);
	text-decoration: none;
	color: inherit;
	transition: border-color var(--etx-dur) var(--etx-ease),
		background-color var(--etx-dur) var(--etx-ease),
		color var(--etx-dur) var(--etx-ease);
}

.etx-catnav a:hover {
	border-color: var(--wp--preset--color--gold);
}

.etx-catnav a[aria-current="page"] {
	background: var(--wp--preset--color--near-black);
	border-color: var(--wp--preset--color--near-black);
	color: var(--wp--preset--color--bone);
}

.etx-catnav__count {
	font-variant-numeric: tabular-nums;
	opacity: 0.6;
	margin-inline-start: 0.35rem;
}

/* Toolbar: result count on the left, ordering on the right. */
.etx-toolbar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding-block: 0.85rem;
	border-block-end: 1px solid var(--etx-hairline);
	margin-block-end: clamp(1.5rem, 1rem + 2vw, 2.5rem);
}

.woocommerce .woocommerce-result-count {
	margin: 0;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.875rem, 14px);
	font-variant-numeric: tabular-nums;
	color: var(--wp--preset--color--stone);
}

.woocommerce .woocommerce-ordering {
	margin: 0;
}

.woocommerce .woocommerce-ordering select,
.etx-select {
	appearance: none;
	padding: 0.6rem 2.5rem 0.6rem 0.9rem;
	border: 1px solid var(--etx-hairline);
	border-radius: 2px;
	background-color: var(--wp--preset--color--white);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%236B6560' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 0.9rem center;
	background-size: 0.7rem;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.875rem, 14px);
	color: inherit;
	cursor: pointer;
}

[dir="rtl"] .woocommerce .woocommerce-ordering select,
[dir="rtl"] .etx-select {
	background-position: left 0.9rem center;
	padding: 0.6rem 0.9rem 0.6rem 2.5rem;
}

/* Empty state. An invitation to act, never an apology. */
/*
 * The empty state opens tight.
 *
 * It already sits below the dark head and the breadcrumb, so its own 5rem of top
 * padding pushed the one useful sentence on the page 170px down an otherwise blank
 * screen. Space below it, not above.
 */
.etx-empty {
	padding-block: clamp(1rem, 0.5rem + 1vw, 1.5rem) clamp(3rem, 2rem + 4vw, 5rem);
	max-inline-size: 42rem;
}

.etx-empty h2 {
	margin-block: 0 0.75rem;
}

.etx-empty p {
	color: var(--wp--preset--color--stone);
	margin-block-end: 1.5rem;
}

/* Pagination */
.woocommerce nav.woocommerce-pagination ul {
	display: flex;
	gap: 0.35rem;
	border: 0;
	margin-block-start: 3rem;
	justify-content: center;
}

.woocommerce nav.woocommerce-pagination ul li {
	border: 0;
	overflow: visible;
}

.woocommerce nav.woocommerce-pagination ul li :is(a, span) {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-inline-size: 2.75rem;
	block-size: 2.75rem;
	padding: 0 0.5rem;
	border: 1px solid var(--etx-hairline);
	border-radius: 2px;
	font-family: var(--wp--preset--font-family--body);
	font-variant-numeric: tabular-nums;
	text-decoration: none;
	background: transparent;
	color: inherit;
}

.woocommerce nav.woocommerce-pagination ul li span.current {
	background: var(--wp--preset--color--near-black);
	border-color: var(--wp--preset--color--near-black);
	color: var(--wp--preset--color--bone);
}

.woocommerce nav.woocommerce-pagination ul li a:hover {
	border-color: var(--wp--preset--color--gold);
	background: transparent;
	color: inherit;
}

/* -----------------------------------------------------------------------------
 * 11. Single product
 * -------------------------------------------------------------------------- */

.woocommerce div.product {
	margin-block-start: clamp(1.5rem, 1rem + 2vw, 2.5rem);
}

.woocommerce-breadcrumb {
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.8125rem, 13px);
	color: var(--wp--preset--color--stone);
	padding-block: 0.5rem 0.75rem;
	margin: 0;
}

.woocommerce-breadcrumb a {
	display: inline-block;
	padding-block: 0.25rem;
	min-block-size: 24px;
	color: inherit;
}

/*
 * Two columns: gallery and summary. Gallery sticks on desktop.
 *
 * Not a child selector. inc/storefront.php wraps both in .etx-product-top so
 * they can be a grid, which stopped `div.product > .woocommerce-product-gallery`
 * from matching — and WooCommerce's own `width: 48%` came back, leaving the
 * gallery at half the width of its own track with a hole beside it.
 */
.woocommerce div.product .woocommerce-product-gallery,
.woocommerce div.product .summary {
	float: none !important;
	inline-size: auto !important;
	margin: 0 !important;
}

@media (min-width: 900px) {
	.woocommerce div.product .etx-product-top {
		display: grid;
		grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
		gap: clamp(2rem, 1rem + 4vw, 4.5rem);
		align-items: start;
	}

	.woocommerce div.product .woocommerce-product-gallery {
		position: sticky;
		inset-block-start: 2rem;
	}
}

.woocommerce div.product .woocommerce-product-gallery {
	background: var(--etx-shot-ground);
	border: 1px solid var(--etx-hairline);
	border-radius: 2px;
	padding: clamp(1rem, 3vw, 2rem);
}

.woocommerce div.product .woocommerce-product-gallery__image img {
	object-fit: contain;
	aspect-ratio: 1 / 1;
}

/*
 * Only the first slide occupies space until flexslider has run.
 *
 * WooCommerce prints every gallery image into the wrapper as an ordinary block,
 * so before its script initialises a two-image gallery is twice as tall as the
 * one it settles at. On desktop that costs nothing — gallery and summary are
 * separate grid columns, so the summary does not move — but below 900px they
 * stack, and the summary was jumping upward as the gallery collapsed and then
 * downward again as the thumbnail strip appeared. Measured on the product page:
 * CLS 0.36 at 320px, 0.28 at 375px, 0.24 at 390px, against 0.003 at 1440px.
 *
 * No matching rule is needed to put the slides back. flexslider writes
 * `display: block` inline on each slide as it builds the track, and an inline
 * declaration beats this one — so the hiding lasts exactly as long as the
 * unstyled state it exists to cover.
 *
 * `div.images` is in the selector for specificity, not for reach. WooCommerce
 * ships `.woocommerce div.product div.images .woocommerce-product-gallery__image:nth-child(n+2)`
 * at (0,5,2) with `display: inline-block`; the natural shorter selector here is
 * (0,5,1) and loses silently — the rule is served, the computed style stays
 * `inline-block`, and nothing indicates why. Same trap as the thumbnail grid
 * below.
 */
.woocommerce div.product div.images .woocommerce-product-gallery__wrapper > .woocommerce-product-gallery__image:not(:first-child) {
	display: none;
}

/*
 * Hold the gallery's box square through flexslider's initialisation.
 *
 * Hiding the extra slides above is necessary but not sufficient. There is one
 * frame, between flexslider inserting `.flex-viewport` and giving it a height,
 * where the slides are laid out at full size inside an unsized box: the gallery
 * measured 327px, then 1313px, then settled at 434px, and everything below it
 * moved twice. On mobile "everything below it" is the entire product summary —
 * name, price, add to cart.
 *
 * A square is the correct reservation because the packshots are square and
 * `.woocommerce-product-gallery__image img` above already declares that ratio.
 *
 * `aspect-ratio` only decides a dimension that would otherwise be `auto`, so
 * flexslider's inline height on `.flex-viewport` still wins the moment it is
 * written. This governs the transient frame and nothing else — the settled
 * gallery is identical, on every viewport.
 *
 * Measured on /en/products/black-horse-royal-honey/, CLS before → after:
 * 320px 0.44 → 0.05, 375px 0.37 → 0.04, 390px 0.33 → 0.04. Desktop was already
 * 0.003 — gallery and summary are separate grid columns there, so the summary
 * never moved.
 */
.woocommerce div.product div.images .woocommerce-product-gallery__wrapper,
.woocommerce div.product div.images .flex-viewport {
	aspect-ratio: 1 / 1;
}

/*
 * These mirror WooCommerce's own selector, `.woocommerce div.product div.images
 * .flex-control-thumbs li`, rather than inventing a shorter one.
 *
 * That rule is (0,4,3); the obvious `.woocommerce div.product .flex-control-thumbs
 * li` is (0,3,2) and loses silently, which is what left every thumbnail floated at
 * 21px inside an 84px grid track — four stamps in the corners of their cells, which
 * reads as a broken gallery. Matching the selector exactly puts this sheet's later
 * load order in charge, which is how the rest of this file beats Woo.
 */
.woocommerce div.product div.images .flex-control-thumbs {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr));
	gap: 0.6rem;
	margin-block-start: 1rem;
	padding: 0;
	list-style: none;
}

.woocommerce div.product div.images .flex-control-thumbs li {
	inline-size: auto;
	margin: 0;
	float: none;
	list-style: none;
}

/*
 * The thumbnails have to be sized explicitly.
 *
 * FlexSlider sizes them with inline styles it only applies once its own layout
 * runs, and clearing the float above takes them out of that path — so they
 * rendered at the intrinsic size of a 100px file inside a 4.5rem grid cell:
 * four little stamps floating in the corners of their tracks, which reads as a
 * broken gallery rather than a small one. The cell defines the size here.
 */
.woocommerce div.product div.images .flex-control-thumbs img {
	display: block;
	inline-size: 100%;
	block-size: auto;
	aspect-ratio: 1 / 1;
	object-fit: contain;
	background: var(--etx-shot-ground);
	border: 1px solid var(--etx-hairline);
	border-radius: 2px;
	opacity: 0.65;
	cursor: pointer;
	transition: opacity var(--etx-dur) var(--etx-ease), border-color var(--etx-dur) var(--etx-ease);
}

.woocommerce div.product div.images .flex-control-thumbs img.flex-active,
.woocommerce div.product div.images .flex-control-thumbs img:hover {
	opacity: 1;
	border-color: var(--wp--preset--color--gold);
}

.woocommerce div.product .product_title {
	font-size: clamp(1.9531rem, 1.4rem + 2.2vw, 3.0518rem);
	margin-block: 0.35rem 1rem;
}

.woocommerce div.product .summary > .price,
.woocommerce div.product p.price {
	font-family: var(--wp--preset--font-family--body);
	font-size: clamp(1.5625rem, 1.2rem + 1.2vw, 1.9531rem);
	font-weight: 600;
	color: inherit;
	margin-block: 0 1.5rem;
}

.woocommerce div.product .woocommerce-product-details__short-description {
	font-size: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
	line-height: 1.6;
	max-inline-size: 54ch;
}

.woocommerce div.product form.cart {
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
	gap: 0.75rem;
	margin-block: 1.75rem;
}

.woocommerce div.product form.cart .quantity input.qty {
	inline-size: 5rem;
	block-size: 100%;
	min-block-size: 3.1rem;
	padding: 0.5rem;
	text-align: center;
	border: 1px solid var(--etx-hairline);
	border-radius: 2px;
	font-family: var(--wp--preset--font-family--body);
	font-variant-numeric: tabular-nums;
	font-size: max(1rem, 16px);
}

.woocommerce div.product form.cart .single_add_to_cart_button {
	flex: 1 1 14rem;
	background: var(--wp--preset--color--gold);
	color: var(--wp--preset--color--black);
	font-weight: 600;
	font-size: max(1rem, 16px);
	padding-block: 1rem;
}

.woocommerce div.product form.cart .single_add_to_cart_button:hover {
	background: var(--wp--preset--color--gold-pale);
	color: var(--wp--preset--color--black);
}

.woocommerce div.product .product_meta {
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.8125rem, 13px);
	color: var(--wp--preset--color--stone);
	padding-block-start: 1.25rem;
	border-block-start: 1px solid var(--etx-hairline);
}

.woocommerce div.product .product_meta > span {
	display: block;
	margin-block: 0.2rem;
}

/* Category and brand links in the product meta — same 24px floor as everywhere. */
.woocommerce div.product .product_meta a {
	display: inline-block;
	padding-block: 0.25rem;
	min-block-size: 24px;
}

/*
 * The product body: everything below the buy box. Specification, ingredients,
 * how to use, disclosures. VI-28 gives it real width rather than a narrow column.
 */
.etx-product-body {
	margin-block-start: clamp(3rem, 2rem + 4vw, 5.5rem);
}

.etx-product-body > h2 {
	font-size: clamp(1.5625rem, 1.3rem + 1vw, 1.9531rem);
	margin-block: 2.5rem 1rem;
}

.etx-product-body > h2:first-child {
	margin-block-start: 0;
}

/*
 * Unit price and pack format, on one line under the price.
 *
 * The per-unit figure is the emphasised one: it is what makes €67 comparable to
 * the €57 next to it, and five SKUs in this catalogue share a price.
 */
.etx-summary__unit {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.35rem 1rem;
	margin-block: 0.35rem 0;
	font-size: max(0.875rem, 14px);
	color: var(--wp--preset--color--stone);
}

.etx-summary__per {
	font-weight: 600;
	color: var(--wp--preset--color--near-black);
}

/* The 404's search block, under the two category routes. */
.etx-404__search {
	max-inline-size: 46rem;
	margin-block-start: clamp(2.5rem, 1.5rem + 3vw, 4rem);
}

.etx-404__search .wp-block-search__input {
	padding: 0.85rem 1rem;
	border: 1px solid var(--etx-hairline);
	border-radius: 2px;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(1rem, 16px);
}

/* Trust row — factual statements only, no seals (BD-17, VI section 7). */
.etx-trustrow {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
	gap: clamp(1rem, 0.5rem + 2vw, 2rem);
	padding-block: clamp(1.5rem, 1rem + 2vw, 2.25rem);
	border-block: 1px solid var(--etx-hairline);
	margin-block: clamp(2rem, 1rem + 3vw, 3rem);
}

.etx-trust__title {
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.8125rem, 13px);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: var(--wp--preset--color--gold-deep);
	margin-block: 0 0.5rem;
}

.etx-trust p {
	margin: 0;
	font-size: max(0.9375rem, 15px);
	line-height: 1.55;
	color: var(--wp--preset--color--stone);
}

.etx-on-dark .etx-trust p,
.etx-band--dark .etx-trust p,
.etx-band--black .etx-trust p {
	color: color-mix(in srgb, var(--wp--preset--color--bone) 72%, transparent);
}

.etx-on-dark .etx-trust__title,
.etx-band--dark .etx-trust__title,
.etx-band--black .etx-trust__title {
	color: var(--wp--preset--color--gold);
}

/*
 * Basket and checkout reassurance.
 *
 * The same three facts as the product trust row — delivery window, replacement
 * terms, plain packaging — but in the order-summary column, which is narrow. A
 * three-track grid would collapse to one track and read as three orphaned
 * headings, so this is a list with a hairline rule above it and no headings at
 * all: at this point the customer is scanning, not reading.
 *
 * No icons. A row of green ticks is the visual signature of exactly the category
 * this brand is positioned against, and it would be the only unearned graphic on
 * the site.
 */
.etx-reassure-wrap {
	margin-block-start: 1.5rem;
}

/*
 * The buy-box variant sits directly under the add-to-cart button, so it opens on a
 * hairline of its own and stays tighter than the checkout one.
 */
.etx-reassure--buybox {
	margin-block-start: 1.5rem;
	padding-block-start: 1.25rem;
}

.etx-reassure {
	list-style: none;
	margin: 0;
	padding: 1.25rem 0 0;
	border-block-start: 1px solid var(--etx-hairline);
	display: grid;
	gap: 0.6rem;
}

.etx-reassure li {
	margin: 0;
	padding-inline-start: 1rem;
	position: relative;
	font-size: max(0.875rem, 14px);
	line-height: 1.5;
	color: var(--wp--preset--color--stone);
}

/*
 * The marker is a rule, not a bullet or a tick — it is the tapered rule of the
 * brand at its smallest scale, which is the one ornament this system allows.
 */
.etx-reassure li::before {
	content: "";
	position: absolute;
	inset-inline-start: 0;
	inset-block-start: 0.7em;
	inline-size: 0.4rem;
	block-size: 1px;
	background: var(--wp--preset--color--gold);
}

/*
 * Numbered process steps — used by the replacements page.
 *
 * Ordinary ordered list, set with room to breathe. The numbers are the point: a
 * customer making a claim wants to know how many things they have to do, and the
 * answer being visibly three is itself reassuring.
 */
.etx-steps {
	margin-block: 1.25rem 0;
	padding-inline-start: 1.25rem;
	display: grid;
	gap: 0.75rem;
}

.etx-steps li {
	padding-inline-start: 0.35rem;
	line-height: 1.6;
}

/*
 * Sticky buy bar — mobile only, and only once the main buy box has scrolled away.
 *
 * CP-FMT-03 bars overlaying a disclosure, so this is suppressed at the foot of
 * the document where the contraindication block and the standard disclaimer sit.
 * inc/storefront.php ends the sentinel above them.
 */
.etx-buybar {
	position: fixed;
	inset-inline: 0;
	inset-block-end: 0;

	/* Above the WhatsApp float (90) so the primary CTA always wins a collision. */
	z-index: 95;

	display: flex;
	align-items: center;
	gap: 1rem;
	padding: 0.75rem clamp(1rem, 4vw, 1.5rem);
	padding-block-end: max(0.75rem, env(safe-area-inset-bottom));

	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--bone);
	border-block-start: 1px solid var(--etx-hairline-dark);

	transform: translateY(101%);
	visibility: hidden;
	transition: transform 260ms var(--etx-ease), visibility 260ms;
}

.etx-buybar.is-visible {
	transform: none;
	visibility: visible;
}

.etx-buybar__info {
	flex: 1 1 auto;
	min-inline-size: 0;
}

.etx-buybar__name {
	display: block;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.8125rem, 13px);
	line-height: 1.3;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	color: color-mix(in srgb, var(--wp--preset--color--bone) 78%, transparent);
}

.etx-buybar__price {
	display: block;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(1rem, 16px);
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

.etx-buybar__cta {
	flex: none;
	background: var(--wp--preset--color--gold);
	color: var(--wp--preset--color--black);
	font-weight: 600;
	padding: 0.8rem 1.5rem;
}

.etx-buybar__cta:hover {
	background: var(--wp--preset--color--gold-pale);
	color: var(--wp--preset--color--black);
}

/*
 * Desktop keeps the bar, in a slimmer form.
 *
 * It used to be display:none above 900px, which left the longest page on the site
 * with no persistent CTA on the device where a considered purchase is actually
 * deliberated. The desktop variant is a rail rather than a mobile overlay: shorter,
 * centred, with the name and price on one baseline.
 */
@media (min-width: 900px) {
	.etx-buybar {
		justify-content: center;
		gap: 2rem;
		padding-block: 0.6rem;
	}

	.etx-buybar__info {
		flex: 0 1 auto;
		display: flex;
		align-items: baseline;
		gap: 0.9rem;
	}

	.etx-buybar__name {
		max-inline-size: 40ch;
	}
}

/*
 * The buy bar and the WhatsApp button must not stack on top of each other.
 *
 * Two independent guards, because this failed once already: the offset below was
 * keyed on a body class that was never applied (see etumax_buybar_body_class),
 * so the float sat on top of the primary CTA on every product page.
 *
 * 1. The reserve is scoped to the breakpoint where the bar actually exists. Above
 *    900px the bar is display:none and the float keeps its normal corner.
 * 2. The bar outranks the float in the stacking order, so if the class ever
 *    regresses again the CTA still wins. 95 stays below the skip link at 200.
 */
body.etx-has-buybar .etx-whatsapp-float {
	inset-block-end: 5.5rem;
}

/*
 * Where :has() is available, lift the float only while the bar is actually on
 * screen rather than for the whole page — the bar stays hidden until the buy box
 * has scrolled away, and until then the float has no reason to move.
 *
 * This is deliberately not scoped to a breakpoint: the bar now renders at every
 * width, so a max-width guard here would let the float land on top of it again on
 * desktop, which is the exact failure this pair of rules exists to prevent.
 */
@supports selector(:has(*)) {
	body.etx-has-buybar .etx-whatsapp-float {
		inset-block-end: clamp(1rem, 4vw, 2rem);
	}

	body.etx-has-buybar:has(.etx-buybar.is-visible) .etx-whatsapp-float {
		inset-block-end: 5.5rem;
	}
}

/* Related products */
.woocommerce .related.products,
.woocommerce .up-sells.products {
	margin-block-start: clamp(3rem, 2rem + 4vw, 5rem);
	padding-block-start: clamp(2rem, 1rem + 3vw, 3rem);
	border-block-start: 1px solid var(--etx-hairline);
}

.woocommerce .related.products > h2,
.woocommerce .up-sells.products > h2 {
	font-size: clamp(1.5625rem, 1.3rem + 1vw, 1.9531rem);
	margin-block: 0 clamp(1.5rem, 1rem + 2vw, 2.25rem);
}

/* -----------------------------------------------------------------------------
 * 12. FAQ
 *
 * A details/summary accordion is permitted HERE and nowhere else: these are
 * ordinary questions, not disclosures. CP-FMT-03 bars collapsing required
 * safety material, and the rule in section 15 below enforces that even if a
 * disclosure is ever nested inside one of these by mistake.
 * -------------------------------------------------------------------------- */

.etx-faq {
	border-block-start: 1px solid var(--etx-hairline);
	max-inline-size: 52rem;
}

.etx-on-dark .etx-faq,
.etx-band--dark .etx-faq,
.etx-band--black .etx-faq {
	border-block-start-color: var(--etx-hairline-dark);
}

.etx-faq__item {
	border-block-end: 1px solid var(--etx-hairline);
}

.etx-on-dark .etx-faq__item,
.etx-band--dark .etx-faq__item,
.etx-band--black .etx-faq__item {
	border-block-end-color: var(--etx-hairline-dark);
}

.etx-faq__q {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 1.5rem;
	padding-block: 1.35rem;
	cursor: pointer;
	list-style: none;

	font-family: var(--wp--preset--font-family--display);
	font-size: max(1.125rem, 18px);
	font-weight: 500;
	line-height: 1.35;
}

.etx-faq__q::-webkit-details-marker {
	display: none;
}

.etx-faq__q::after {
	content: "";
	flex: none;
	inline-size: 0.85rem;
	block-size: 0.85rem;
	margin-block-start: 0.35rem;
	background: currentColor;
	opacity: 0.55;
	clip-path: polygon(46% 0, 54% 0, 54% 46%, 100% 46%, 100% 54%, 54% 54%, 54% 100%, 46% 100%, 46% 54%, 0 54%, 0 46%, 46% 46%);
	transition: transform var(--etx-dur) var(--etx-ease), opacity var(--etx-dur) var(--etx-ease);
}

.etx-faq__item[open] .etx-faq__q::after {
	transform: rotate(45deg);
	opacity: 1;
}

.etx-faq__a {
	padding-block: 0 1.5rem;
	max-inline-size: 62ch;
	color: var(--wp--preset--color--stone);
}

.etx-on-dark .etx-faq__a,
.etx-band--dark .etx-faq__a,
.etx-band--black .etx-faq__a {
	color: color-mix(in srgb, var(--wp--preset--color--bone) 76%, transparent);
}

.etx-faq__a > :last-child {
	margin-block-end: 0;
}

/* -----------------------------------------------------------------------------
 * 13. Brand strip
 *
 * VI-15 — product brand logos sit inside the ETUMAX POWER system, never
 * replacing it. They are rendered small, monochrome-quiet, and gain colour on
 * hover so the page still reads as ETUMAX POWER first.
 * -------------------------------------------------------------------------- */

.etx-brands {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: clamp(1.5rem, 1rem + 3vw, 4rem);
}

.etx-brands__item {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0.5rem;
	text-decoration: none;
}

/*
 * These marks are gold line art on transparency. Desaturating them — the usual
 * way to quieten a logo wall — turned them into pale grey on a bone ground and
 * they disappeared. Contrast is the thing to hold and scale is the thing to
 * spend, so they stay in colour and stay small: VI-15 asks the page to read as
 * ETUMAX POWER first, and at this size it does.
 */
.etx-brands__item img {
	block-size: clamp(2.5rem, 1.5rem + 2.5vw, 3.75rem);
	inline-size: auto;
	opacity: 0.85;
	transition: opacity var(--etx-dur) var(--etx-ease), transform var(--etx-dur) var(--etx-ease);
}

.etx-brands__item:hover img {
	opacity: 1;
	transform: translateY(-2px);
}

/* -----------------------------------------------------------------------------
 * 14. Footer
 * -------------------------------------------------------------------------- */

.etx-footer {
	border-block-start: 1px solid var(--etx-hairline-dark);
}

/*
 * A grid, not wp:columns.
 *
 * The columns block divides a row into equal flexible tracks and does not wrap,
 * so six of them turned every link list into one word per line. auto-fit with a
 * minimum track width wraps to two rows on a laptop and one column on a phone,
 * without a breakpoint per layout.
 *
 * The brand and contact cells are given wider minimums because both carry the
 * company address, which BI-04 forbids abbreviating to fit.
 */
.etx-footer__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
	gap: clamp(2rem, 1rem + 3vw, 3.5rem);
	align-items: start;
}

.etx-footer__brand,
.etx-footer__col--contact {
	grid-column: span 2;
	min-inline-size: min(100%, 18rem);
}

.etx-footer__brand p {
	font-size: max(0.875rem, 14px);
	line-height: 1.6;
	color: color-mix(in srgb, var(--wp--preset--color--bone) 76%, transparent);
	max-inline-size: 34ch;
}

.etx-footer__brand .wp-block-site-logo {
	margin-block-end: 1.25rem;
}

@media (max-width: 599px) {
	.etx-footer__brand,
	.etx-footer__col--contact {
		grid-column: span 1;
	}
}

/*
 * At laptop width and up the six cells are placed explicitly. auto-fit was
 * wrapping Legal and Contact onto a second row while leaving a gap on the first,
 * which reads as a mistake rather than a rhythm.
 */
@media (min-width: 1100px) {
	.etx-footer__grid {
		grid-template-columns: 1.7fr 1fr 1fr 1fr 1fr 1.8fr;
	}

	.etx-footer__brand,
	.etx-footer__col--contact {
		grid-column: span 1;
	}
}

.etx-footer h2 {
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.75rem, 12px) !important;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--wp--preset--color--gold);
	margin-block: 0 1.25rem;
}

.etx-footer-list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.etx-footer-list li {
	margin-block: 0 0.15rem;
}

/*
 * Footer links are set as blocks with vertical padding rather than as inline
 * text. At 15px/1.35 the hit area was 20px tall, under the 24px minimum, and a
 * column of six of them is exactly where a thumb misses.
 */
.etx-footer-list a {
	display: inline-block;
	padding-block: 0.3rem;
	min-block-size: 24px;
	color: color-mix(in srgb, var(--wp--preset--color--bone) 82%, transparent);
	text-decoration: none;
	transition: color var(--etx-dur) var(--etx-ease);
}

.etx-footer-list a:hover {
	color: var(--wp--preset--color--gold-pale);
}

.etx-footer__colophon {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding-block-start: 1.75rem;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.8125rem, 13px);
	color: color-mix(in srgb, var(--wp--preset--color--bone) 62%, transparent);
}

/* -----------------------------------------------------------------------------
 * 15. Mandatory disclosure blocks — CP-FMT-01, CP-FMT-02, CP-FMT-03
 *
 * Unchanged in substance from the original implementation. These rules are
 * defensive: they survive a careless designer as well as a careless editor, and
 * nothing in the redesign above is permitted to weaken them.
 *
 * VI-29 — safety content sits in the document flow with normal visual weight.
 * Never styled to recede.
 * -------------------------------------------------------------------------- */

.etx-disclosure {
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.875rem, 14px);
	line-height: 1.6;
	border-inline-start: 3px solid var(--wp--preset--color--gold);
	padding: 1.25rem 1.5rem;
	margin-block: 1.5rem;
	background: var(--wp--preset--color--bone);
	color: var(--wp--preset--color--near-black);
}

.etx-disclosure--safety {
	border-inline-start-color: var(--wp--preset--color--warning);
}

/* VI-01 — safety headings take the warning colour, never gold. */
.etx-disclosure--safety > :is(h2, h3, h4, strong:first-child) {
	color: var(--wp--preset--color--warning);
}

.etx-disclosure :is(h2, h3, h4) {
	font-family: var(--wp--preset--font-family--body);
	font-size: max(1rem, 16px);
	font-weight: 600;
	letter-spacing: normal;
	margin-block: 0 0.5rem;
}

.etx-disclosure ul {
	margin-block: 0.5rem;
	padding-inline-start: 1.25rem;
}

.etx-disclosure li {
	margin-block: 0.25rem;
}

.etx-disclosure p:last-child,
.etx-disclosure ul:last-child {
	margin-block-end: 0;
}

/*
 * A disclosure may never be collapsed, hidden, shrunk, or overlaid. These are
 * the exact treatments CP-FMT-03 prohibits, so they are neutralised at the
 * stylesheet level rather than left to review.
 *
 * The FAQ accordion in section 12 is the only details/summary on the site. If a
 * disclosure is ever nested inside one, this forces it open and legible.
 */
details .etx-disclosure,
.etx-disclosure[hidden] {
	display: block !important;
	visibility: visible !important;
	opacity: 1 !important;
	font-size: max(0.875rem, 14px) !important;
}

/* A disclosure is never clipped by a card, a grid cell, or an aspect ratio. */
.etx-disclosure {
	overflow: visible;
	max-block-size: none;
}

/* -----------------------------------------------------------------------------
 * 16. Ingredient and specification tables
 *
 * BD-11 — the full breakdown appears on every product page with quantities and
 * percentages. Nothing is omitted for elegance, so these are styled to stay
 * readable at full length rather than to be visually compact.
 * -------------------------------------------------------------------------- */

.etx-ingredients {
	inline-size: 100%;
	border-collapse: collapse;
	margin-block: 1.5rem;
	border-block: 1px solid var(--wp--preset--color--gold);
}

.etx-ingredients caption {
	text-align: start;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.8125rem, 13px);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: var(--wp--preset--color--gold-deep);
	margin-block-end: 0.85rem;
}

.etx-ingredients :is(th, td) {
	text-align: start;
	padding: 0.85rem 0.25rem;
	border-block-end: 1px solid var(--etx-hairline);
	vertical-align: baseline;
}

.etx-ingredients thead th {
	font-size: max(0.75rem, 12px);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.09em;
	color: var(--wp--preset--color--stone);
	border-block-end-width: 1px;
}

/*
 * The value column is right-aligned and never nowrap.
 *
 * nowrap suits the ingredient table, whose values are short figures. The
 * specification table shares this class and carries values like "Enriched honey
 * sachets, semi-liquid paste", which forced the table 100px wider than a phone
 * and took the whole page with it. Wrapping a long value is the correct
 * behaviour; scrolling a table sideways to read a published quantity is not —
 * VI-28 makes this table a hero element, and a hero element is not half
 * off-screen.
 */
.etx-ingredients td:last-child,
.etx-ingredients th:last-child {
	text-align: end;
	font-weight: 600;
}

/* Figures still hold their line — they are short by nature and read as data. */
.etx-ingredients tfoot td:last-child {
	white-space: nowrap;
}

.etx-ingredients tbody tr:last-child :is(th, td) {
	border-block-end: 0;
}

.etx-ingredients tfoot :is(th, td) {
	font-weight: 600;
	border-block-end: none;
	border-block-start: 1px solid var(--etx-hairline);
	color: var(--wp--preset--color--gold-deep);
}

.etx-ingredients .etx-latin {
	font-style: italic;
	color: var(--wp--preset--color--stone);
}

/* Long tables scroll inside themselves rather than pushing the page sideways. */
.etx-tablewrap {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

/* -----------------------------------------------------------------------------
 * 17. Certification statements
 *
 * BD-15 / BD-17 — the text is cleared to display; the badge graphic is not, and
 * will not be until certificate references are on file. Deliberately typographic
 * with no seal, mark, or shield of any kind.
 * -------------------------------------------------------------------------- */

.etx-certification {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem 1.5rem;
	padding: 1rem 0;
	font-size: max(0.9375rem, 15px);
}

.etx-certification span {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
}

.etx-certification span::before {
	content: "";
	inline-size: 6px;
	block-size: 6px;
	border-radius: 50%;
	background: var(--wp--preset--color--gold);
	flex: none;
}

.etx-certification__note {
	flex-basis: 100%;
	font-size: max(0.875rem, 14px);
	color: var(--wp--preset--color--stone);
}

/* -----------------------------------------------------------------------------
 * 18. Logo — VI-11, VI-12
 * -------------------------------------------------------------------------- */

.wp-block-site-logo img {
	min-inline-size: 120px;
	padding-block: 0.35em;
}

/* -----------------------------------------------------------------------------
 * 19. Arabic and RTL
 *
 * VI-07 — a genuine Arabic design, never a Latin face with fallback glyphs.
 * VI-31 — RTL mirrors completely: layout direction, not only text alignment.
 * The whole file is written in logical properties for exactly this reason.
 * -------------------------------------------------------------------------- */

:root[lang^="ar"] body,
[dir="rtl"] body {
	font-family: var(--wp--preset--font-family--arabic);
}

/* -----------------------------------------------------------------------------
 * 19b. Japanese
 *
 * VI-07 for Japanese: a page set in a real Japanese face, never Latin with the
 * browser guessing a fallback for every kana.
 *
 * No webfont ships. A Japanese font covering the jōyō set is several megabytes
 * before italics, which would cost more on a Tokyo 4G connection than any type
 * choice is worth — so both stacks lead with the site's own Latin faces and hand
 * CJK to the operating system's. Latin inside a Japanese sentence — the brand
 * names, "600 mg", the € figures — therefore renders in Inter exactly as it does
 * in the English tree, and only the kana and kanji change face.
 *
 * The pairing is preserved rather than flattened: sans for body, mincho for the
 * display headings, which is the Japanese counterpart of the Inter/Playfair
 * relationship the rest of the site is built on.
 * -------------------------------------------------------------------------- */

:root[lang^="ja"] body {
	font-family: var(--wp--preset--font-family--japanese);
}

:root[lang^="ja"] .etx-display,
:root[lang^="ja"] h1,
:root[lang^="ja"] h2 {
	font-family: var(--wp--preset--font-family--japanese-display);
}

/*
 * Japanese has no inter-word space, so a line may break anywhere. These two keep
 * the break where a Japanese reader expects it rather than mid-word.
 */
:root[lang^="ja"] body {
	line-break: strict;
	overflow-wrap: anywhere;
}

/* The one physical-direction value in the file, mirrored explicitly. */
[dir="rtl"] .etx-rule,
[dir="rtl"] .wp-block-separator.is-style-wide {
	background: linear-gradient(
		270deg,
		transparent 0%,
		var(--wp--preset--color--gold) 22%,
		var(--wp--preset--color--gold) 78%,
		transparent 100%
	);
}

/* -----------------------------------------------------------------------------
 * 20. Motion
 *
 * VI has no motion rule, so the standard applies: motion is an enhancement and
 * never load-bearing. Everything below degrades to a static, complete page.
 * -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}

	.woocommerce ul.products li.product:hover,
	.etx-card:hover {
		transform: none;
	}
}

/* -----------------------------------------------------------------------------
 * 21. Business identity
 *
 * The entity and contact blocks rendered by inc/identity.php. Values come from
 * knowledge-base/company/business-identity.md §1 (BD-36…BD-40); nothing here
 * changes a value, only how it sits on the page.
 *
 * BI-04 — the address is never abbreviated. That is a content rule with a layout
 * consequence: these blocks are never truncated, clamped, or collapsed to fit a
 * column. They wrap instead.
 * -------------------------------------------------------------------------- */

.etx-entity,
.etx-contact {
	font-size: max(0.875rem, 14px);
	line-height: 1.6;
}

.etx-entity p,
.etx-contact p {
	margin-block: 0 0.9em;
}

.etx-entity__label,
.etx-contact__label {
	display: inline-block;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.75rem, 12px);
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--gold);
}

/* The registration number is data, not prose — VI-06. */
.etx-entity__reg {
	font-variant-numeric: tabular-nums;
}

/* Same 24px minimum as the footer list — these are the two links a customer is
   most likely to tap, and they sit in the same column. */
.etx-contact a {
	display: inline-block;
	padding-block: 0.3rem;
	min-block-size: 24px;
	overflow-wrap: anywhere;
}

/* Social profiles — BI-11, BI-13.
 *
 * Deliberately the same object as the floating WhatsApp button in section 22: ink
 * ground, gold glyph, gold hairline, lift and fill on hover. VI-03 bars any colour
 * outside the palette, so no platform brand colour appears — a blue Facebook mark
 * and a magenta Instagram mark in the corner of a black-and-gold footer would be the
 * two loudest things on the page and would read as someone else's brand.
 *
 * The ink ground is set rather than inherited even though the footer is already ink:
 * this block also renders on the coming-soon page, which is not.
 */

.etx-social {
	margin-block-start: 1.25rem;
}

.etx-social__label {
	display: inline-block;
	margin-block: 0 0.6rem;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.75rem, 12px);
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--gold);
}

.etx-social__list {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.etx-social__link {
	display: flex;
	align-items: center;
	justify-content: center;

	/* 44px: the same tap target the footer lists and the contact links use. */
	inline-size: 2.75rem;
	block-size: 2.75rem;
	border-radius: 50%;

	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--gold);
	border: 1px solid var(--wp--preset--color--gold-deep);

	/* Depth, then a gold halo held at almost nothing until hover. */
	box-shadow: 0 2px 10px rgb(0 0 0 / 20%), 0 0 10px rgb(198 162 100 / 10%);

	transition: transform var(--etx-dur) var(--etx-ease),
		background-color var(--etx-dur) var(--etx-ease),
		border-color var(--etx-dur) var(--etx-ease),
		box-shadow var(--etx-dur) var(--etx-ease);
}

.etx-social__link:hover,
.etx-social__link:focus-visible {
	background: var(--wp--preset--color--gold-deep);
	color: var(--wp--preset--color--white);
	border-color: var(--wp--preset--color--gold);
	transform: translateY(-2px);
	box-shadow: 0 6px 18px rgb(0 0 0 / 28%), 0 0 18px rgb(198 162 100 / 32%);
}

.etx-social__icon {
	inline-size: 1.25rem;
	block-size: 1.25rem;
}

/*
 * The tap target is already 44px, so it does not shrink on small screens the way
 * the WhatsApp float does — that one shrinks because it overlays content and this
 * one sits in the flow.
 */
@media (prefers-reduced-motion: reduce) {
	.etx-social__link:hover,
	.etx-social__link:focus-visible {
		transform: none;
	}
}

/* -----------------------------------------------------------------------------
 * 22. WhatsApp
 *
 * BI-07 — the official customer messaging channel. A plain anchor: no script, no
 * third-party chat widget. LCR-18 treats purchase intent in this category as
 * sensitive above the legal minimum, and a widget served from someone else's
 * domain puts a processor in front of that.
 * -------------------------------------------------------------------------- */

.etx-whatsapp-cta {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
}

.etx-whatsapp-float {
	position: fixed;
	inset-block-end: clamp(1rem, 4vw, 2rem);
	inset-inline-end: clamp(1rem, 4vw, 2rem);
	z-index: 90;

	display: flex;
	align-items: center;
	justify-content: center;
	inline-size: 3.5rem;
	block-size: 3.5rem;
	border-radius: 50%;

	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--gold);
	border: 1px solid var(--wp--preset--color--gold-deep);
	box-shadow: 0 6px 20px rgb(0 0 0 / 22%);

	transition: transform var(--etx-dur) var(--etx-ease),
		background-color var(--etx-dur) var(--etx-ease),
		inset-block-end var(--etx-dur) var(--etx-ease);
}

.etx-whatsapp-float:hover,
.etx-whatsapp-float:focus-visible {
	background: var(--wp--preset--color--gold-deep);
	color: var(--wp--preset--color--white);
	transform: translateY(-2px);
}

.etx-whatsapp-float__icon {
	inline-size: 1.75rem;
	block-size: 1.75rem;
}

/*
 * CP-FMT-03 — nothing carrying a disclosure may be collapsed, hidden, or
 * overlaid. A fixed button sits above the page, so at the end of a scroll it
 * would rest on top of the footer disclaimer. The footer reserves room for it
 * instead: the button gets a corner nobody is reading.
 *
 * That reserve is vertical, not horizontal — horizontal padding would shift the
 * footer's constrained content out of alignment with every other section — and it
 * lives in parts/footer.html, because a block's inline padding wins against a
 * class selector and a rule here would silently do nothing.
 *
 * z-index 90 keeps it under any modal or notice, for the same reason.
 */

@media (max-width: 599px) {
	.etx-whatsapp-float {
		inline-size: 3rem;
		block-size: 3rem;
	}

	.etx-whatsapp-float__icon {
		inline-size: 1.5rem;
		block-size: 1.5rem;
	}
}

/* -----------------------------------------------------------------------------
 * 23. Prose
 *
 * Content pages — About, Safety, the legal set. VI-08 fixes the minimum sizes;
 * this fixes the measure, which is the other half of legibility.
 * -------------------------------------------------------------------------- */

.etx-band p,
.etx-band li {
	max-inline-size: 72ch;
}

/* Tables, disclosures, and grids are not prose and set their own width. */
.etx-band :is(.etx-disclosure, .etx-ingredients, .etx-panel, .etx-trustrow, .etx-faq, .etx-split, .etx-steps, .woocommerce) :is(p, li) {
	max-inline-size: none;
}

.etx-band h2 {
	margin-block: 2.5rem 1rem;
}

.etx-band h3 {
	margin-block: 2rem 0.75rem;
}

.etx-band > :first-child,
.etx-band .etx-sectionhead > :first-child {
	margin-block-start: 0;
}

/* -----------------------------------------------------------------------------
 * 24. Skip link
 *
 * Visually hidden until focused, then a real, high-contrast target. It is the
 * first thing a keyboard user meets and it must not be a 1px box.
 * -------------------------------------------------------------------------- */

.skip-link:focus-visible {
	position: fixed !important;
	inset-block-start: 1rem;
	inset-inline-start: 1rem;
	z-index: 200;
	inline-size: auto !important;
	block-size: auto !important;
	clip: auto !important;
	clip-path: none !important;
	padding: 0.75rem 1.25rem;
	background: var(--wp--preset--color--gold);
	color: var(--wp--preset--color--black);
	font-family: var(--wp--preset--font-family--body);
	font-weight: 600;
	text-decoration: none;
	border-radius: 2px;
}

/* -----------------------------------------------------------------------------
 * 25. The one next step — PL-10
 *
 * A single cross-modality companion, replacing the three same-category
 * alternatives WooCommerce shipped. One card, one decision. It is deliberately
 * quieter than a product card: it is an attach, not a competing offer, and it
 * must never read as a comparison against the product being viewed (PL-08).
 * -------------------------------------------------------------------------- */

.etx-next-step {
	margin-block-start: clamp(3rem, 2rem + 4vw, 5rem);
	padding-block-start: clamp(2rem, 1rem + 3vw, 3rem);
	border-block-start: 1px solid var(--etx-hairline);
}

.etx-next-step > h2 {
	font-size: clamp(1.25rem, 1.1rem + 0.6vw, 1.5625rem);
	margin-block-end: 1.25rem;
}

/* The relationship between the two products, above the card. */
.etx-next-step__why {
	max-inline-size: 52ch;
	margin-block: 0 1.25rem;
	font-size: max(0.9375rem, 15px);
	color: var(--wp--preset--color--stone);
}

.etx-next-step__card {
	display: flex;
	align-items: center;
	gap: clamp(1rem, 3vw, 1.75rem);
	padding: clamp(0.75rem, 2vw, 1.25rem);
	border: 1px solid var(--etx-hairline);
	border-radius: 2px;
	color: inherit;
	transition: border-color var(--etx-dur) var(--etx-ease);
}

.etx-next-step__card:hover,
.etx-next-step__card:focus-within {
	border-color: var(--wp--preset--color--gold-deep);
}

.etx-next-step__media {
	flex: none;
	line-height: 0;
}

.etx-next-step__card img {
	inline-size: clamp(72px, 18vw, 116px);
	block-size: auto;
	flex: none;
	background: var(--etx-shot-ground);
}

.etx-next-step__body {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	min-inline-size: 0;
}

.etx-next-step__name {
	font-family: var(--wp--preset--font-family--body);
	font-size: max(1rem, 16px);
	font-weight: 600;
}

.etx-next-step__reason {
	font-size: max(0.875rem, 14px);
	line-height: 1.45;
	color: color-mix(in srgb, currentcolor 78%, transparent);
}

.etx-next-step__price {
	font-family: var(--wp--preset--font-family--body);
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	margin-block-start: 0.25rem;
}

.etx-next-step__unit {
	font-size: max(0.8125rem, 13px);
	font-variant-numeric: tabular-nums;
	color: var(--wp--preset--color--stone);
}

/* Price and unit cost on one baseline, so the button can sit under both. */
.etx-next-step__figures {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.25rem 0.75rem;
	margin-block-start: 0.25rem;
}

.etx-next-step__figures .etx-next-step__price,
.etx-next-step__figures .etx-next-step__unit {
	margin-block-start: 0;
}

.etx-next-step__name {
	text-decoration: none;
	color: inherit;
}

.etx-next-step__name:hover {
	text-decoration: underline;
}

/*
 * The attach button is the quiet weight, never gold.
 *
 * VI-27 allows one accent per screen and on a product page that accent is already
 * spent — it is the add-to-cart button in the buy box. A second gold button here
 * would make the companion compete with the product being viewed, which is exactly
 * what PL-08 bars.
 */
.etx-next-step__cta {
	align-self: flex-start;
	margin-block-start: 0.85rem;
	padding: 0.6rem 1.25rem;
	font-size: max(0.875rem, 14px);
	background: transparent;
	color: var(--wp--preset--color--near-black);
	border: 1px solid var(--wp--preset--color--near-black);
}

.etx-next-step__cta:hover,
.etx-next-step__cta:focus-visible {
	background: var(--wp--preset--color--near-black);
	color: var(--wp--preset--color--bone);
}

/* Woo's "View basket" link, printed after an ajax add. */
.etx-next-step .added_to_cart {
	display: inline-block;
	margin-block-start: 0.5rem;
	margin-inline-start: 0.85rem;
	font-size: max(0.875rem, 14px);
}

/* -----------------------------------------------------------------------------
 * 26. Conversion surfaces — Phase 6, 2026-08-03
 *
 * Everything added when the site was rewritten to sell rather than to disclose.
 * Grouped here rather than scattered through the file above, because these are
 * one decision: the commercial terms and the milligram figures now appear at
 * every point where a customer hesitates, and they need to look like one object
 * wherever they land.
 *
 * Nothing here hides, shrinks, collapses, or overlays a disclosure — CP-FMT-03
 * still governs, and the safety block on a product page is untouched by all of it.
 * -------------------------------------------------------------------------- */

/*
 * The shipping terms, wherever they sit under a price.
 *
 * Small, quiet, and never gold — VI-02 bars gold body text and VI-27 allows one
 * accent per screen, which on a product page is already the add-to-cart button.
 * This removes friction; it is not an argument, and it must not look like one.
 */
.etx-summary__shipping,
.etx-card__shipping,
.etx-cta__terms,
.etx-footer__terms {
	font-size: max(0.8125rem, 13px);
	line-height: 1.55;
	color: var(--wp--preset--color--stone);
}

.etx-summary__shipping {
	margin-block: 0.5rem 0;
}

.etx-card__shipping {
	display: block;
	inline-size: 100%;
	margin-block-start: 0.15rem;
}

.etx-on-dark .etx-card__shipping,
.etx-band--dark .etx-card__shipping,
.etx-band--black .etx-card__shipping,
.etx-cta__terms,
.etx-footer__terms {
	color: color-mix(in srgb, var(--wp--preset--color--bone) 60%, transparent);
}

.etx-cta__terms {
	margin-block-start: 1.5rem;
}

.etx-footer__terms {
	margin-block-start: 1rem;
}

/*
 * The subhead under a product title.
 *
 * One line, set in the display face at reading size, so it reads as the product's
 * own sentence rather than as a second heading competing with the h1 above it.
 */
.etx-summary__subhead {
	margin-block: 0.35rem 1rem;
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.25rem);
	line-height: 1.4;
	color: var(--wp--preset--color--stone);
}

/*
 * The three reasons above the add-to-cart button.
 *
 * Ticks rather than bullets, because each item is something the reader gets rather
 * than an entry in a list. Drawn in CSS: VI section 7 bars invented seals and
 * decorative badges, and an icon font here would be three network requests to say
 * three things a character already says.
 */
.etx-reasons {
	list-style: none;
	margin-block: 1.25rem;
	padding: 0;
	display: grid;
	gap: 0.5rem;
}

.etx-reasons li {
	position: relative;
	padding-inline-start: 1.5rem;
	font-size: max(0.9375rem, 15px);
	line-height: 1.5;
}

.etx-reasons li::before {
	content: "✓";
	position: absolute;
	inset-inline-start: 0;
	color: var(--wp--preset--color--gold-deep);
	font-weight: 600;
}

/* The same tick treatment on the homepage's four checkable facts. */
.etx-checklist {
	list-style: none;
	margin-block: 0;
	padding: 0;
	display: grid;
	gap: 0.75rem;
}

.etx-checklist li {
	position: relative;
	padding-inline-start: 1.75rem;
	line-height: 1.55;
}

.etx-checklist li::before {
	content: "✓";
	position: absolute;
	inset-inline-start: 0;
	color: var(--wp--preset--color--gold);
	font-weight: 600;
}

/*
 * The milligram panel on the product page — VI-28.
 *
 * The ingredient data is a hero element on this site, not fine print, and this is
 * the scale at which it first appears. It is the same .etx-panel object as the
 * homepage proof strip and the card preview; only the surrounding spacing differs.
 */
.etx-actives__total {
	margin-block: 0 1rem;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(1rem, 16px);
	font-weight: 600;
	line-height: 1.45;
	font-variant-numeric: tabular-nums;
}

.etx-panel--actives {
	margin-block-end: 0.75rem;
}

/* The pointer to the full percentage table below. Never a substitute for it. */
.etx-actives__note {
	margin-block: 0 2rem;
	font-size: max(0.8125rem, 13px);
	color: var(--wp--preset--color--stone);
}

/*
 * How to use, as a numbered ritual.
 *
 * Three short steps, numbered in the display face. The number is decoration doing
 * a job: it tells the reader at a glance that this is short, which is the honest
 * description of tearing a sachet open.
 */
.etx-ritual {
	list-style: none;
	margin-block: 0 1rem;
	padding: 0;
	display: grid;
	gap: 1rem;
	counter-reset: none;
}

.etx-ritual li {
	display: flex;
	align-items: baseline;
	gap: 1rem;
}

.etx-ritual__n {
	flex: none;
	inline-size: 2.5ch;
	font-family: var(--wp--preset--font-family--display);
	font-size: max(1rem, 16px);
	font-variant-numeric: tabular-nums;
	color: var(--wp--preset--color--gold-deep);
}

.etx-ritual__t {
	line-height: 1.55;
}

.etx-ritual__freq {
	margin-block: 0 2rem;
	font-size: max(0.875rem, 14px);
	color: var(--wp--preset--color--stone);
}

/* The route out of an empty basket. */
.etx-empty-cta {
	margin-block-start: 0.5rem;
	font-size: max(0.9375rem, 15px);
}

/* -----------------------------------------------------------------------------
 * 27. Language
 *
 * Two surfaces for one set: a disclosure in the header cluster and a flat row in
 * the footer. Both are built from the same alternates and both are ordinary links —
 * nothing here reads a browser setting, an IP address, or performs a redirect.
 *
 * Written in logical properties throughout, like the rest of this file, so the
 * Arabic tree mirrors without a single directional override below.
 * -------------------------------------------------------------------------- */

/* The header control. Same <details> mechanics as the search beside it. */
.etx-lang {
	position: relative;
}

.etx-lang > summary {
	list-style: none;
	cursor: pointer;
}

.etx-lang > summary::-webkit-details-marker {
	display: none;
}

/*
 * The closed control is the ISO code, set in the same tabular figures the price
 * and the basket count use so the three read as one row of furniture.
 */
.etx-lang__current {
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.8125rem, 13px);
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	letter-spacing: 0.06em;
}

.etx-lang:not([open]) .etx-lang__panel {
	display: none;
}

.etx-lang__panel {
	position: absolute;
	inset-block-start: calc(100% + 0.75rem);
	inset-inline-end: 0;
	z-index: 20;

	inline-size: max-content;
	min-inline-size: 12rem;
	max-inline-size: calc(100vw - 3rem);
	padding: 0.75rem;

	background: var(--wp--preset--color--ink);
	border: 1px solid var(--etx-hairline-dark);
	border-radius: 2px;
	box-shadow: 0 24px 48px rgb(0 0 0 / 45%);
}

.etx-lang__title {
	margin: 0 0 0.5rem;
	padding-inline: 0.65rem;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.6875rem, 11px);
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--stone);
}

.etx-lang__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.etx-lang__list a {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1.5rem;

	padding: 0.5rem 0.65rem;
	border-radius: 2px;

	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.9375rem, 15px);
	color: color-mix(in srgb, var(--wp--preset--color--bone) 82%, transparent);
	text-decoration: none;
	transition: color var(--etx-dur) var(--etx-ease), background-color var(--etx-dur) var(--etx-ease);
}

.etx-lang__list a:hover,
.etx-lang__list a:focus-visible {
	color: var(--wp--preset--color--gold-pale);
	background: rgb(255 255 255 / 6%);
}

/*
 * The language being served is marked, not removed. A switcher missing its own
 * entry is a set with a hole in it: the visitor cannot see what they are reading
 * now, only what they could read instead.
 */
.etx-lang__list a[aria-current] {
	color: var(--wp--preset--color--gold);
	font-weight: 600;
}

/* The ISO code trails each endonym in the panel, as the quiet second column. */
.etx-lang__list .etx-lang__code {
	font-size: max(0.75rem, 12px);
	font-variant-numeric: tabular-nums;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--stone);
}

/*
 * A Japanese or Arabic endonym in the panel is set in that language's own face,
 * not in the face of the tree the visitor is currently reading. 日本語 rendered in
 * a Latin stack is the one string on the page that must not fall back.
 */
.etx-lang__list a[lang="ja"] .etx-lang__name {
	font-family: "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Yu Gothic", Meiryo, sans-serif;
}

.etx-lang__list a[lang="ar"] .etx-lang__name {
	font-family: "IBM Plex Sans Arabic", "Noto Sans Arabic", "Geeza Pro", sans-serif;
}

/* The footer row. */
.etx-footer__languages {
	padding-block-start: 1.75rem;
}

.etx-langrow {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.75rem 1.25rem;
}

.etx-langrow__label {
	margin: 0;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.6875rem, 11px);
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--stone);
}

.etx-langrow__list {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 1.25rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.etx-langrow__list a {
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.875rem, 14px);
	color: color-mix(in srgb, var(--wp--preset--color--bone) 82%, transparent);
	text-decoration: none;
	transition: color var(--etx-dur) var(--etx-ease);
}

.etx-langrow__list a:hover,
.etx-langrow__list a:focus-visible {
	color: var(--wp--preset--color--gold-pale);
}

.etx-langrow__list a[aria-current] {
	color: var(--wp--preset--color--gold);
	font-weight: 600;
}

/*
 * The code is the header control's affordance and would be noise in a row that
 * already has room for the full name.
 */
.etx-langrow__list .etx-lang__code {
	position: absolute;
	inline-size: 1px;
	block-size: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.etx-langrow__list a[lang="ja"] .etx-lang__name {
	font-family: "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Yu Gothic", Meiryo, sans-serif;
}

.etx-langrow__list a[lang="ar"] .etx-lang__name {
	font-family: "IBM Plex Sans Arabic", "Noto Sans Arabic", "Geeza Pro", sans-serif;
}

/*
 * The phone header budget.
 *
 * One row has to hold the logo, the menu toggle and now four utilities rather than
 * three. Measured, the row needed 361px at 375px viewport — so adding the language
 * control pushed the page into horizontal scroll at 375 and 360, which are iPhone
 * SE/8/X and the older Android width. 390 and up were never affected.
 *
 * Reclaimed from three places at once rather than by taking it all from one:
 *
 *   - the icon boxes drop from 44px to 40px, which stays well clear of the 24px
 *     minimum in WCAG 2.5.8 and keeps three fingers' worth of separation;
 *   - the gap between them halves, which they can afford because each icon already
 *     carries its own padding;
 *   - the wordmark loses 20px, at a size where it is still legible and still the
 *     largest thing on the row.
 *
 * The language control is narrower again — 36px — because it is the one item whose
 * target is a word rather than an icon, so it reads at a smaller width, and it is the
 * one a customer touches at most once a visit.
 *
 * Below 400px the gap between the three header zones tightens as well. That width was
 * already overflowing by 23px before any of this existed; it now overflows by less.
 */
@media (max-width: 599px) {
	.etx-header .wp-block-site-logo img {
		inline-size: 112px;
	}

	.etx-utils {
		gap: 0.2rem;
	}

	.etx-utils__item {
		inline-size: 2.5rem;
		block-size: 2.5rem;
	}

	.etx-lang__toggle {
		inline-size: 2.25rem;
	}

	.etx-lang__panel {
		inline-size: min(14rem, calc(100vw - 2rem));
	}
}

@media (max-width: 399px) {
	.etx-header__bar {
		gap: 0.5rem;
	}
}

/*
 * 320px — the narrowest width still worth serving, and the one with no slack at all:
 * the root padding alone is 48px of it.
 *
 * The block above already buys back more than the language control costs at 350px and
 * up. Below that the row needs a second, smaller set of numbers or it scrolls
 * sideways, which it did by 23px before any of this work and does not now.
 *
 * 36px icons are the floor. That is above the 24px minimum in WCAG 2.5.8 and it is
 * reached only here, at a viewport essentially no current handset reports.
 */
@media (max-width: 349px) {
	/*
	 * The root padding is spacing-40 — 1.5rem a side, 48px of a 320px viewport, 15% of
	 * the screen spent on margin before anything is drawn. At every other width that is
	 * the right measure and it is not touched. Here it is the actual constraint, so it
	 * drops to 1rem, which is the last of the difference and gives the content back
	 * 16px on every page rather than only in the header.
	 */
	body {
		--wp--style--root--padding-left: var(--wp--preset--spacing--30);
		--wp--style--root--padding-right: var(--wp--preset--spacing--30);
	}

	.etx-header .wp-block-site-logo img {
		inline-size: 76px;
	}

	.etx-utils {
		gap: 0.15rem;
	}

	.etx-utils__item {
		inline-size: 2.25rem;
		block-size: 2.25rem;
	}

	.etx-lang__toggle {
		inline-size: 2rem;
	}

	.etx-header__bar {
		gap: 0.25rem;
	}
}

/* -----------------------------------------------------------------------------
 * 28. Header shell — utility bar and mobile drawer
 *
 * The approved Navigation System design, expressed in this file's tokens rather
 * than the comp's literals: the comp's #C8A24A is this palette's gold, its #EDE9E3
 * is bone, and its Marcellus/Jost pair maps to the brand's Playfair Display and
 * Inter, which are already self-hosted. What is reproduced exactly is the system —
 * the 42px bar, the 26px bordered circles, 10.5px uppercase at .18em tracking, the
 * gold fill with a 2px lift, and every duration and curve in the motion table.
 *
 * The comp's easing, kept as a local token because it is springier than the
 * theme's --etx-ease and the drawer is the one place that wants it.
 *
 * Logical properties throughout, so the Arabic tree mirrors with the single
 * direction override at the end rather than a parallel set of rules.
 * -------------------------------------------------------------------------- */

.etx-utilbar,
.etx-drawer {
	--etx-nav-ease: cubic-bezier(0.16, 1, 0.3, 1);
	--etx-nav-line: color-mix(in srgb, var(--wp--preset--color--gold) 22%, transparent);
}

/* --- Utility bar ---------------------------------------------------------- */

/*
 * The bar owns a stacking context above the header.
 *
 * The header group follows this one in the DOM and paints an opaque background, so
 * a dropdown opening downwards out of the bar was covered by it — the currency
 * panel lost its title and its first three rows behind the black header bar.
 */
.etx-utilbar-wrap {
	position: relative;
	z-index: 70;
	background: color-mix(in srgb, var(--wp--preset--color--black) 92%, #000);
	border-block-end: 1px solid var(--etx-hairline-dark);
	padding: 0;
}

.etx-utilbar__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	min-block-size: 42px;
	padding-inline: var(--wp--style--root--padding-right, 1rem);
}

.etx-utilbar__left,
.etx-utilbar__right {
	display: flex;
	align-items: center;
	gap: 1.375rem;
}

/* The hairline between the customer rows and the preference controls. */
.etx-utilbar__rule {
	inline-size: 1px;
	block-size: 14px;
	background: var(--etx-nav-line);
}

/* --- Social row ----------------------------------------------------------- */

.etx-navsocial {
	display: flex;
	align-items: center;
	gap: 1.375rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.etx-navsocial__link {
	display: flex;
	align-items: center;
	justify-content: center;
	inline-size: 26px;
	block-size: 26px;
	border: 1px solid var(--etx-nav-line);
	border-radius: 50%;
	color: var(--wp--preset--color--gold);
	transition:
		background-color 320ms var(--etx-nav-ease),
		border-color 320ms var(--etx-nav-ease),
		color 320ms var(--etx-nav-ease),
		transform 320ms var(--etx-nav-ease);
}

.etx-navsocial__link:hover,
.etx-navsocial__link:focus-visible {
	background: var(--wp--preset--color--gold);
	border-color: var(--wp--preset--color--gold);
	color: var(--wp--preset--color--black);
	transform: translateY(-2px);
}

.etx-nav-icon {
	inline-size: 13px;
	block-size: 13px;
}

/* In the drawer's Contact group the same row sits at 40px. */
.etx-navsocial--drawer {
	gap: 0.875rem;
}

.etx-navsocial--drawer .etx-navsocial__link {
	inline-size: 40px;
	block-size: 40px;
}

.etx-navsocial--drawer .etx-nav-icon {
	inline-size: 17px;
	block-size: 17px;
}

/* --- Account shortcuts ---------------------------------------------------- */

.etx-acct {
	display: flex;
	align-items: center;
	gap: 1.625rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.etx-acct--bar .etx-acct__link {
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.65625rem, 10.5px);
	letter-spacing: 0.18em;
	text-transform: uppercase;
	text-decoration: none;
	color: var(--wp--preset--color--stone);
	transition: color 280ms ease;
}

.etx-acct--bar .etx-acct__link:hover,
.etx-acct--bar .etx-acct__link:focus-visible {
	color: var(--wp--preset--color--gold);
}

/* --- Currency control ----------------------------------------------------- */

.etx-cur {
	position: relative;
}

.etx-cur > summary {
	display: flex;
	align-items: center;
	gap: 0.4375rem;
	cursor: pointer;
	list-style: none;
	color: var(--wp--preset--color--gold);
	font-size: max(0.65625rem, 10.5px);
	letter-spacing: 0.18em;
	text-transform: uppercase;
	transition: color 280ms ease;
}

.etx-cur > summary::-webkit-details-marker {
	display: none;
}

/* The word "Currency" is for a screen reader on the bar; the code is the control. */
.etx-cur--bar .etx-cur__label {
	position: absolute;
	inline-size: 1px;
	block-size: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* The chevron, drawn rather than fetched. */
.etx-cur > summary::after {
	content: "";
	inline-size: 5px;
	block-size: 5px;
	border-inline-end: 1px solid currentColor;
	border-block-end: 1px solid currentColor;
	transform: rotate(45deg) translateY(-1px);
	opacity: 0.7;
	transition: transform 280ms var(--etx-nav-ease);
}

.etx-cur[open] > summary::after {
	transform: rotate(225deg) translateY(-2px);
}

.etx-cur__panel {
	position: absolute;
	inset-block-start: calc(100% + 0.5rem);
	inset-inline-end: 0;
	z-index: 60;
	min-inline-size: 9rem;
	/* Ten currencies is a tall list on a short laptop viewport. */
	max-block-size: min(70vh, 30rem);
	overflow-y: auto;
	padding: 0.75rem 0;
	background: color-mix(in srgb, var(--wp--preset--color--black) 96%, #000);
	border: 1px solid var(--etx-nav-line);
}

.etx-cur__title {
	margin: 0 0 0.5rem;
	padding-inline: 1rem;
	font-size: max(0.5625rem, 9px);
	letter-spacing: 0.34em;
	text-transform: uppercase;
	color: color-mix(in srgb, var(--wp--preset--color--gold) 70%, var(--wp--preset--color--stone));
}

.etx-cur__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

/*
 * The choices are submit buttons, so they are reset to look like the rows they are.
 * They stay buttons because that is what keeps the currency out of every URL.
 */
.etx-cur__choice {
	display: flex;
	inline-size: 100%;
	align-items: center;
	min-block-size: 44px;
	padding: 0.625rem 1rem;
	border: 0;
	background: none;
	font-family: var(--wp--preset--font-family--body);
	font-size: max(0.6875rem, 11px);
	letter-spacing: 0.12em;
	text-align: start;
	color: var(--wp--preset--color--bone);
	cursor: pointer;
	transition:
		background-color 260ms var(--etx-nav-ease),
		color 260ms var(--etx-nav-ease);
}

.etx-cur__choice:hover,
.etx-cur__choice:focus-visible {
	background: var(--wp--preset--color--gold);
	color: var(--wp--preset--color--black);
}

.etx-cur__item.is-current .etx-cur__choice {
	color: var(--wp--preset--color--gold);
}

/* --- Mobile drawer -------------------------------------------------------- */

/* The burger. 26px, three 1.5px gold lines, 6px apart. */
.etx-drawer > summary {
	display: flex;
	align-items: center;
	justify-content: center;
	inline-size: 44px;
	block-size: 44px;
	cursor: pointer;
	list-style: none;
}

.etx-drawer > summary::-webkit-details-marker {
	display: none;
}

.etx-drawer__burger {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 6px;
	inline-size: 26px;
}

.etx-drawer__burger i {
	display: block;
	block-size: 1.5px;
	background: var(--wp--preset--color--gold);
	transform-origin: center;
	transition:
		opacity 200ms ease,
		transform 380ms var(--etx-nav-ease);
}

/*
 * Burger to X: the middle line fades while the outer two travel to the centre and
 * rotate ±45°. 7.5px is half the 15px between the outer lines.
 */
.etx-drawer[open]:not(.is-closing) .etx-drawer__burger i:first-child {
	transform: translateY(7.5px) rotate(45deg);
}

.etx-drawer[open]:not(.is-closing) .etx-drawer__burger i:nth-child(2) {
	opacity: 0;
	transform: scaleX(0.4);
}

.etx-drawer[open]:not(.is-closing) .etx-drawer__burger i:last-child {
	transform: translateY(-7.5px) rotate(-45deg);
}

/* The scrim. */
.etx-drawer__scrim {
	position: fixed;
	inset: 0;
	z-index: 90;
	background: rgb(4 4 3 / 72%);
	backdrop-filter: blur(2px);
	opacity: 0;
	animation: etx-drawer-scrim 400ms ease-out forwards;
}

@keyframes etx-drawer-scrim {
	to { opacity: 1; }
}

.etx-drawer.is-closing .etx-drawer__scrim {
	animation: etx-drawer-scrim 300ms cubic-bezier(0.4, 0, 0.2, 1) reverse forwards;
}

/* The panel. Slides in from the inline-end edge. */
.etx-drawer__panel {
	--etx-drawer-x: 100%;

	position: fixed;
	inset-block: 0;
	inset-inline-end: 0;
	z-index: 91;
	inline-size: min(326px, 88vw);
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: 5.25rem 0 2.5rem;
	background: color-mix(in srgb, var(--wp--preset--color--black) 94%, #000);
	border-inline-start: 1px solid var(--etx-nav-line);
	animation: etx-drawer-in 460ms var(--etx-nav-ease) forwards;
}

@keyframes etx-drawer-in {
	from { translate: var(--etx-drawer-x) 0; }
	to { translate: 0 0; }
}

.etx-drawer.is-closing .etx-drawer__panel {
	animation: etx-drawer-in 300ms cubic-bezier(0.4, 0, 0.2, 1) reverse forwards;
}

.etx-drawer__group + .etx-drawer__group {
	margin-block-start: 1.75rem;
}

.etx-drawer__label {
	margin: 0 0 0.5rem;
	padding-inline: 1.5rem;
	font-size: max(0.5625rem, 9px);
	letter-spacing: 0.34em;
	text-transform: uppercase;
	color: color-mix(in srgb, var(--wp--preset--color--gold) 70%, var(--wp--preset--color--stone));
}

.etx-drawer__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.etx-drawer__link {
	display: flex;
	align-items: center;
	min-block-size: 44px;
	padding: 0.5rem 1.5rem;
	color: var(--wp--preset--color--bone);
	text-decoration: none;
	letter-spacing: 0.1em;
	transition:
		background-color 280ms var(--etx-nav-ease),
		color 280ms var(--etx-nav-ease);
}

.etx-drawer__link:hover,
.etx-drawer__link:focus-visible {
	background: var(--wp--preset--color--gold);
	color: var(--wp--preset--color--black);
}

/* Store rows carry the display face; account rows stay in the text face, smaller. */
.etx-drawer__link--store {
	font-family: var(--wp--preset--font-family--display);
	font-size: max(1.0625rem, 17px);
	min-block-size: 46px;
}

.etx-drawer__link--acct {
	font-size: max(0.71875rem, 11.5px);
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

/*
 * The staggered entrance. 45ms apart, 26px of travel, per the motion table.
 * Scoped to the rows so the group labels do not move.
 */
.etx-drawer[open]:not(.is-closing) .etx-drawer__list > li {
	opacity: 0;
	animation: etx-drawer-row 420ms var(--etx-nav-ease) forwards;
}

.etx-drawer__list > li:nth-child(1) { animation-delay: 45ms; }
.etx-drawer__list > li:nth-child(2) { animation-delay: 90ms; }
.etx-drawer__list > li:nth-child(3) { animation-delay: 135ms; }
.etx-drawer__list > li:nth-child(4) { animation-delay: 180ms; }
.etx-drawer__list > li:nth-child(5) { animation-delay: 225ms; }
.etx-drawer__list > li:nth-child(6) { animation-delay: 270ms; }

@keyframes etx-drawer-row {
	from {
		opacity: 0;
		translate: 26px 0;
	}

	to {
		opacity: 1;
		translate: 0 0;
	}
}

/* Preferences: the two disclosures become full-width rows with the value trailing. */
.etx-drawer__group--prefs .etx-cur,
.etx-drawer__group--prefs .etx-lang {
	position: static;
}

.etx-drawer__group--prefs .etx-cur > summary,
.etx-drawer__group--prefs .etx-lang > summary {
	/*
	 * Explicitly flex. The currency summary already is; the language one takes its
	 * layout from .etx-utils__item, so without this the label, the value and the
	 * chevron stacked up against each other as "LANGUAGEEN".
	 */
	display: flex;
	align-items: center;
	gap: 0.5rem;
	justify-content: space-between;
	min-block-size: 44px;
	padding: 0.5rem 1.5rem;
	inline-size: auto;
	font-size: max(0.71875rem, 11.5px);
	letter-spacing: 0.16em;
	/* Both rows in caps: the currency control is already, the language one is not. */
	text-transform: uppercase;
	color: var(--wp--preset--color--bone);
}

/*
 * The label takes the free space so the value lands at the trailing edge. Without
 * this the two ran together as "LANGUAGEEN" — the language summary is not a
 * space-between flex row the way the currency one is.
 */
.etx-drawer__group--prefs .etx-cur__label,
.etx-drawer__group--prefs .etx-lang__label {
	flex: 1 1 auto;
}

.etx-drawer__group--prefs .etx-cur__current,
.etx-drawer__group--prefs .etx-lang__current {
	margin-inline-start: auto;
	padding-inline-end: 0.5rem;
	color: var(--wp--preset--color--gold);
}

/* The language row gets the currency row's chevron, so the two read as one pair. */
.etx-drawer__group--prefs .etx-lang > summary::after {
	content: "";
	inline-size: 5px;
	block-size: 5px;
	border-inline-end: 1px solid var(--wp--preset--color--gold);
	border-block-end: 1px solid var(--wp--preset--color--gold);
	transform: rotate(45deg) translateY(-1px);
	opacity: 0.7;
	transition: transform 280ms var(--etx-nav-ease);
}

.etx-drawer__group--prefs .etx-lang[open] > summary::after {
	transform: rotate(225deg) translateY(-2px);
}

.etx-drawer__group--prefs .etx-cur__panel,
.etx-drawer__group--prefs .etx-lang__panel {
	position: static;
	border-inline: 0;
	min-inline-size: 0;
}

/* Body scroll lock while the drawer is open. */
body.etx-drawer-open {
	overflow: hidden;
}

/* --- Where each header lives --------------------------------------------- */

/*
 * 834px is the design's breakpoint between the tablet header and the mobile one.
 * Below it: no utility bar, no inline menu, drawer available. Above it: the
 * reverse. The drawer markup is always in the document — it is the same five
 * links, so hiding it costs nothing and removes a source of layout shift.
 */
@media (max-width: 833px) {
	.etx-utilbar-wrap {
		display: none;
	}

	.etx-header__bar .wp-block-navigation {
		display: none;
	}
}

@media (min-width: 834px) {
	.etx-drawer {
		display: none;
	}
}

/*
 * 834–1279: the five customer rows no longer fit beside the preferences, so all but
 * the first are dropped. The design condenses them into a hover panel; one row
 * reading "My Account" reaches the same dashboard in one tap and adds no hover-only
 * affordance to a viewport that may well be a touchscreen.
 */
@media (max-width: 1279px) {
	.etx-acct--bar .etx-acct__item:not(:first-child) {
		display: none;
	}

	.etx-utilbar__left,
	.etx-utilbar__right {
		gap: 1.125rem;
	}

	.etx-navsocial {
		gap: 1.125rem;
	}
}

/* --- Direction ------------------------------------------------------------ */

/*
 * The one directional rule in this section. `translate` is physical, so the panel
 * has to be told which way "off-screen towards the inline-end edge" is; everything
 * else above is logical and needs no mirror.
 */
[dir="rtl"] .etx-drawer__panel {
	--etx-drawer-x: -100%;
}

/* --- Reduced motion ------------------------------------------------------- */

/*
 * Per the design: drawer and scrim cross-fade at 160ms, the stagger and the lift
 * are removed, and the gold hover fills stay.
 */
@media (prefers-reduced-motion: reduce) {
	.etx-drawer__panel,
	.etx-drawer.is-closing .etx-drawer__panel {
		animation-duration: 160ms;
		animation-timing-function: ease;
	}

	.etx-drawer__panel {
		--etx-drawer-x: 0;
	}

	.etx-drawer__scrim,
	.etx-drawer.is-closing .etx-drawer__scrim {
		animation-duration: 160ms;
	}

	.etx-drawer[open]:not(.is-closing) .etx-drawer__list > li {
		animation: none;
		opacity: 1;
	}

	.etx-drawer__burger i {
		transition-duration: 1ms;
	}

	.etx-navsocial__link:hover,
	.etx-navsocial__link:focus-visible {
		transform: none;
	}
}

/*
 * The language control inside the utility bar.
 *
 * It is the same <details> as before, moved from the main header cluster, so it
 * arrives carrying .etx-utils__item — which sizes it as a 44px square icon button.
 * In this row it has to read as a text control at the bar's own scale, matching the
 * currency beside it. Scoped to .etx-utilbar so the footer row and the drawer's
 * Preferences group are untouched.
 */
.etx-utilbar .etx-lang__toggle.etx-utils__item {
	inline-size: auto;
	block-size: auto;
	padding: 0;
	color: var(--wp--preset--color--gold);
	font-size: max(0.65625rem, 10.5px);
	letter-spacing: 0.18em;
	text-transform: uppercase;
}

.etx-utilbar .etx-lang__panel {
	inset-block-start: calc(100% + 0.5rem);
	inset-inline-end: 0;
}

/*
 * The hamburger has to stay above the panel it opens.
 *
 * The panel and scrim are fixed at z-index 91 and 90; the summary is in the normal
 * flow inside the header, so when open it was painted underneath both and the
 * animated X — the whole close affordance — was invisible. The design's mock puts
 * the header row above the drawer for the same reason. Raised only while open, so
 * the closed header keeps its natural stacking.
 */
.etx-drawer[open] > summary {
	position: relative;
	z-index: 92;
}

/*
 * The language label: hidden everywhere except the drawer's Preferences group,
 * which is the one place the design shows "Language" beside the value.
 */
.etx-lang__label {
	position: absolute;
	inline-size: 1px;
	block-size: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.etx-drawer__group--prefs .etx-lang__label {
	position: static;
	inline-size: auto;
	block-size: auto;
	overflow: visible;
	clip-path: none;
}

/* -----------------------------------------------------------------------------
 * 29. Gulf currency signs — U+20C3 dirham, U+20C1 riyal
 *
 * Both signs were assigned in Unicode 17.0 (September 2025). Every Latin subset
 * this theme self-hosts stops its currency coverage at U+20AD-20C0 (see
 * theme.json), so neither can be drawn from Inter or Playfair Display — the
 * browser must find them in a system font or draw the notdef/hex box instead.
 *
 * Measured on this server: of 50 installed fonts, only Unifont claims either
 * codepoint, and Unifont *is* the hex-box fallback — so the price rendered as a
 * box printing "20C3". 34 of the same 50 fonts have the euro.
 *
 * This stack names the faces that ship the signs on each platform, so a visitor
 * whose OS has been updated gets the real mark rather than depending on the
 * browser's default fallback order happening to reach it. It is a *fallback*:
 * Inter is still first, so €, £, $ and ¥ are unaffected and keep the price
 * typography exactly as it was.
 *
 * ── U+20C3 no longer depends on any of that ──────────────────────────────────
 *
 * The dirham is now self-hosted. `ETUMAX Dirham` (assets/fonts/etumax-dirham-*.
 * woff2, built by scripts/build/make-dirham-font.py) carries exactly one glyph
 * and claims exactly one codepoint, and theme.json puts it first in every font
 * stack — body, display, arabic and both Japanese families. Because the
 * unicode-range is a single codepoint the browser fetches roughly 0.9 KB, and
 * only on a page that actually paints an AED price; every other character falls
 * straight through to the next family in the stack, so Inter, Playfair Display
 * and IBM Plex Sans Arabic are untouched.
 *
 * THE RULES BELOW MUST STAY HERE, AND theme.json MUST NOT NAME THIS FAMILY.
 *
 * WP_Font_Face_Resolver::maybe_parse_name_from_comma_separated_list() takes the
 * *first* family out of a `fontFamilies[].fontFamily` stack and then
 * convert_font_face_properties() force-assigns that one name to every `fontFace`
 * in the entry, discarding each face's own `fontFamily`. So putting
 * "ETUMAX Dirham" at the head of the `body` stack in theme.json re-labelled all
 * six *Inter* faces as "ETUMAX Dirham": one family holding sixteen unrelated
 * files, Inter never fetched at all, and every price silently falling through to
 * Playfair Display. Measured, not theorised — `CSS.getPlatformFontsForNode`
 * reported Playfair painting the figures on the AED *and* the EUR storefront,
 * and no inter-*.woff2 request was made on either.
 *
 * Hence: theme.json keeps its five stacks exactly as they were, the faces are
 * declared as plain CSS here, and the family is pushed onto the front of each
 * stack by redefining the five presets below. system.css is enqueued at priority
 * 20, after WordPress prints its own `:root` block at priority 10, so these win
 * on source order at equal specificity.
 *
 * The five stacks are therefore duplicated from theme.json. If a stack changes
 * there, change it here too — `python3 -c` over theme.json regenerates them.
 *
 * U+20C1 riyal is NOT covered and still relies on the platform stack below.
 *
 * Neither this stack nor the webfont reaches email — a mail client uses its own
 * fonts and ignores site CSS. That gap is unchanged.
 * -------------------------------------------------------------------------- */

@font-face {
	font-family: "ETUMAX Dirham";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("../fonts/etumax-dirham-400.woff2") format("woff2");
	unicode-range: U+20C3;
}

@font-face {
	font-family: "ETUMAX Dirham";
	font-style: normal;
	font-weight: 500;
	font-display: swap;
	src: url("../fonts/etumax-dirham-500.woff2") format("woff2");
	unicode-range: U+20C3;
}

@font-face {
	font-family: "ETUMAX Dirham";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("../fonts/etumax-dirham-600.woff2") format("woff2");
	unicode-range: U+20C3;
}

/*
 * The family is first in every stack, which is safe precisely because its
 * unicode-range is one codepoint: for any character other than U+20C3 the
 * browser skips straight past it to Inter, Playfair Display or IBM Plex Sans
 * Arabic, and never requests the file.
 */
:root {
	--wp--preset--font-family--body:
		"ETUMAX Dirham", Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
	--wp--preset--font-family--display:
		"ETUMAX Dirham", "Playfair Display", ui-serif, Georgia, "Times New Roman", serif;
	--wp--preset--font-family--arabic:
		"ETUMAX Dirham", "IBM Plex Sans Arabic", ui-sans-serif, system-ui, sans-serif;
	--wp--preset--font-family--japanese:
		"ETUMAX Dirham", Inter, "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Yu Gothic", YuGothic, "Noto Sans JP", Meiryo, ui-sans-serif, system-ui, sans-serif;
	--wp--preset--font-family--japanese-display:
		"ETUMAX Dirham", "Playfair Display", "Hiragino Mincho ProN", "Yu Mincho", YuMincho, "Noto Serif JP", ui-serif, Georgia, serif;
}

.woocommerce-Price-currencySymbol,
.etx-cur__code,
.etx-announce__item {
	font-family:
		var(--wp--preset--font-family--body),
		/* Windows */ "Segoe UI Symbol", "Segoe UI Emoji",
		/* macOS, iOS */ "SF Pro Text", "Apple Symbols",
		/* Android, Chrome OS, Linux */ "Noto Sans Symbols 2", "Noto Sans Arabic", "Noto Sans",
		sans-serif;
}
