/**
 * Accessibility panel — the control, and the preferences it applies.
 *
 * Everything above the "APPLIED PREFERENCES" divider styles the control
 * itself. Everything below it is what the control actually does to the page,
 * expressed as classes on <html>: `nxa11y-size-2`, `nxa11y-contrast`,
 * `nxa11y-links`, `nxa11y-nomotion`, `nxa11y-spacing`, `nxa11y-readable`.
 * Keep the two halves in one file — a preference with no rule here is a button
 * that lies to the visitor who pressed it.
 *
 * ── Placement ─────────────────────────────────────────────────────────────
 *
 * The floating corners are crowded, and every one of them is owned elsewhere:
 *
 *   .nxwa                WhatsApp           bottom-RIGHT, z-index 55
 *   .nxchat              chat launcher      bottom-LEFT,  z-index 900
 *   .consent             cookie banner      bottom-LEFT,  z-index 60
 *   .xmod-cart-bar       mobile cart bar    full width,   z-index 60
 *   .sticky-legal-bar    legal links        full width,   z-index 45
 *
 * So this launcher lives in the bottom-RIGHT column, stacked directly above
 * `.nxwa` when that button is on the page (`body.has-nxwa`) and dropping into
 * the empty corner on the cart and checkout pages where it is suppressed. On
 * the mobile cart page the pinned cart bar is also in the way, so
 * `body.has-cartbar` lifts the launcher above it as well.
 *
 * Nothing here relies on `--legal-bar-h` alone. Every extra bar is a height
 * published at runtime — `--legal-bar-h` by consent.js, `--nxa11y-cartbar-h`
 * by accessibility.js — because a hardcoded number would silently rot the next
 * time one of those components changed its padding.
 *
 * ⚠ `right` and `left` below are PHYSICAL on purpose. `inset-inline-end`
 * resolves to the LEFT in Hebrew, which is where the chatbot already lives.
 * That mistake was made once and fixed in chatbot.css and whatsapp.css; do not
 * "tidy" these back into logical properties.
 *
 * @package newxmod
 */

/* Shared geometry.
   `--nxa11y-bottom` is the distance from the bottom of the viewport to the
   launcher's bottom edge, assembled from every surface already docked there:

     --legal-bar-h            measured by consent.js; we must always clear it
     --nxa11y-edge            the same gutter the WhatsApp button uses, so the
                              two buttons line up as one column on the right
     --nxa11y-stack           the WhatsApp button and the gap above it
     --nxa11y-cartbar-h       the pinned mobile cart bar, measured by
                              accessibility.js
     --nxa11y-cartbar-guess   first-paint estimate, used only until that
                              measurement arrives

   The fallback pattern is the same one main.css uses for `--legal-bar-h` on
   phones: a sane CSS value now, the measured value as soon as the script can
   take it. */
.nxa11y {
	--nxa11y-btn: 2.75rem;
	--nxa11y-edge: 1.25rem;
	--nxa11y-stack: 0rem;
	--nxa11y-cartbar-guess: 0rem;
	--nxa11y-cartbar-h: var(--nxa11y-cartbar-guess);
	--nxa11y-bottom: calc(var(--legal-bar-h) + var(--nxa11y-edge) + var(--nxa11y-stack) + var(--nxa11y-cartbar-h));
}

/* The WhatsApp button is 2.6rem tall and sits 1.25rem above the legal bar, so
   3.5rem clears it by about 0.9rem. If that button's padding or label ever
   changes, this is the number to re-check. */
body.has-nxwa .nxa11y {
	--nxa11y-stack: 3.5rem;
}

/* whatsapp.css hides its button on pages whose sidebar would sit underneath it.
   When that happens there is nothing to stack above, so the gap collapses too.
   `:has()` gives this rule a higher specificity than the one above it, so no
   source-order trick is needed. */
@media (min-width: 40rem) {
	body:has(.sidebar) .nxa11y,
	body:has(.shop-sidebar) .nxa11y,
	body:has(.widget-area) .nxa11y {
		--nxa11y-stack: 0rem;
	}
}

/* ==========================================================================
   LAUNCHER
   ========================================================================== */

/*
 * The one surface in the theme that is a *mark* rather than a themed surface.
 * A white wheelchair on a blue disc is the internationally recognised sign for
 * accessibility, so the blue is written literally here instead of being read
 * from the palette — both palettes otherwise drive this button from a red
 * accent, and a red accessibility button is not the sign anyone is looking for.
 *
 * The value is pinned to measured contrast, not to taste, because the button
 * floats over whatever is behind it. Re-measured for all three palettes — the
 * ratios live in `scripts/_palette-contrast.php`, which fails if any of them
 * drops below its floor:
 *
 *     #ffffff on #0d6fb8                    = 5.27:1   (the glyph, 1.4.11 wants 3:1)
 *     #0d6fb8 on forge       --bg #ded3bb   = 3.55:1
 *     #0d6fb8 on aurora      --bg #eef1ef   = 4.64:1
 *     #0d6fb8 on singularity --bg #120e0c   = 3.64:1
 *
 * Forge is the tight case now, and it is tight for a structural reason worth
 * knowing before anyone retunes it: a contrast ratio is smallest when the two
 * luminances are closest, and a warm mid-tone page sits far nearer this blue's
 * own luminance than a near-white or a near-black one does. Forge may be
 * lightened freely; darkening it far takes the disc through the 3:1 floor.
 * That is also why this is a specific blue rather than "a blue": #0b5fa5
 * measures 2.93:1 on the night palette and fails 1.4.11, while anything light
 * enough to clear the brightest palette comfortably starts to look washed out
 * on the darkest one. #0d6fb8 is inside every window, so one literal still
 * serves all three.
 *
 * High contrast still pre-empts both values below — a "maximise contrast"
 * request gets the preference's own accent pair, which in the light
 * high-contrast palette is itself blue on white.
 */
.nxa11y__launcher {
	--nxa11y-brand-bg: #0d6fb8;
	--nxa11y-brand-ink: #ffffff;

	position: fixed;
	/* Above the legal bar (45), the cookie banner (60) and the mobile cart bar
	   (60); below the chat launcher (900) so an open conversation is never
	   trapped behind this panel. */
	z-index: 62;
	right: var(--nxa11y-edge);
	left: auto;
	bottom: var(--nxa11y-bottom);
	display: grid;
	place-items: center;
	inline-size: var(--nxa11y-btn);
	block-size: var(--nxa11y-btn);
	padding: 0;
	border: 1px solid rgba(255, 255, 255, 0.22);
	border-radius: 50%;
	background: var(--nxa11y-brand-bg);
	color: var(--nxa11y-brand-ink);
	box-shadow: 0 10px 24px rgba(0, 0, 0, 0.28);
	cursor: pointer;
	transition: translate 0.2s var(--ease), box-shadow 0.2s var(--ease), border-color 0.2s var(--ease);
}

.nxa11y__launcher:hover,
.nxa11y__launcher:focus-visible {
	translate: 0 -2px;
	border-color: rgba(255, 255, 255, 0.5);
	box-shadow: 0 14px 30px rgba(0, 0, 0, 0.34);
}

/* main.css draws every focus ring in `--accent`, which the dark palette makes
   red — on this button that is a 1.1:1 outline, i.e. no ring at all. Same trap
   the skip link was caught in. `--text-bright` is near-black on the light
   palette and pure white on the dark one, so the ring clears 3:1 against the
   blue disc and 12:1 against the page behind it. */
.nxa11y__launcher:focus-visible {
	outline-color: var(--text-bright);
}

/* Anything other than the default settings is on. Without this the visitor who
   enlarged the text three visits ago has no way to tell why the site looks
   unusual, or that a control exists which would put it back.
 *
 * The fill can no longer be the signal, because the fill is now the fixed brand
 * blue. The replacement is a halo, in two layers on purpose: `--bg` for the
 * inner ring and `--text` for the outer one. One ring cannot work here — the
 * ring's inner edge touches the blue disc and its outer edge touches the page,
 * and in each palette there is no single colour that clears 3:1 against both
 * (in high contrast the light palette leaves a usable band of about 0.04
 * luminance). Splitting it gives four colours, each measured against its own
 * neighbour:
 *
 *     forge        --bg    #ded3bb vs the disc   3.6:1   --text #1e1a12 vs page 11.7:1
 *     aurora       --bg    #eef1ef vs the disc   4.6:1   --text #14201a vs page 14.8:1
 *     singularity  --bg    #120e0c vs the disc   3.6:1   --text #f3ebe3 vs page 16.3:1
 *     contrast HE  --bg    #ffffff vs the disc   5.3:1   --text #000000 vs page 21.0:1
 *     contrast DA  --bg    #000000 vs the disc   4.0:1   --text #ffffff vs page 21.0:1
 *
 * The inner ring reads as a gap and the outer one as the mark, which is the
 * same construction as a focus halo — and it needs no high-contrast twin,
 * because it is already built from the palette. It replaces the drop shadow
 * while it is on; nothing else in the theme stacks a halo and a depth shadow,
 * and the halo is the more important of the two. */
.nxa11y__launcher--active {
	box-shadow: 0 0 0 3px var(--bg), 0 0 0 6px var(--text);
}

/* ==========================================================================
   PANEL
   ========================================================================== */

.nxa11y__panel {
	position: fixed;
	z-index: 62;
	right: var(--nxa11y-edge);
	left: auto;
	bottom: calc(var(--nxa11y-bottom) + var(--nxa11y-btn) + 0.5rem);
	inline-size: min(21rem, calc(100vw - 2rem));
	/* Derived from the stack above it rather than a magic number, so whatever
	   is docked at the bottom of the screen the panel always fits on top of it
	   without ever reaching past the top of the viewport. */
	/* Anchored to the bottom, so its ceiling is everything above the launcher.
	   The extra 2.5rem is deliberate breathing room: without it the panel ends
	   up flush against the top of the screen on a small phone (measured at
	   320x640), which reads as clipped even though nothing is actually cut off.

	   Two declarations on purpose. `100dvh` is the honest unit on a phone,
	   where the collapsing URL bar makes `100vh` taller than the visible area
	   and a bottom-anchored panel would push its own header off-screen; the
	   `100vh` line above it is the fallback for browsers that lack `dvh`. */
	max-block-size: calc(100vh - var(--nxa11y-bottom) - var(--nxa11y-btn) - 2.5rem);
	max-block-size: calc(100dvh - var(--nxa11y-bottom) - var(--nxa11y-btn) - 2.5rem);
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: 1.1rem 1.15rem 1rem;
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--bg-elev);
	box-shadow: 0 18px 50px rgba(0, 0, 0, 0.35);
	text-align: start;
	animation: nxa11y-in 0.28s var(--ease) both;
}

.nxa11y__panel[hidden] {
	display: none;
}

@keyframes nxa11y-in {
	from {
		opacity: 0;
		transform: translateY(0.75rem);
	}

	to {
		opacity: 1;
		transform: none;
	}
}

.nxa11y__title {
	margin: 0 0 0.85rem;
	color: var(--text-bright);
	font-size: 1.05rem;
	font-weight: 700;
	line-height: 1.2;
}

.nxa11y__close {
	position: absolute;
	inset-block-start: 0.65rem;
	inset-inline-end: 0.65rem;
	display: grid;
	place-items: center;
	inline-size: 1.9rem;
	block-size: 1.9rem;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	color: var(--text-dim);
	cursor: pointer;
	transition: background-color 0.2s var(--ease), color 0.2s var(--ease);
}

.nxa11y__close:hover,
.nxa11y__close:focus-visible {
	background: var(--accent-subtle);
	color: var(--accent-text);
}

/* ==========================================================================
   CONTROLS
   ========================================================================== */

/* Reset the browser's default fieldset chrome — the group is a label, not a box. */
.nxa11y__group {
	margin: 0 0 0.9rem;
	padding: 0;
	border: 0;
}

.nxa11y__legend {
	padding: 0;
	margin-block-end: 0.45rem;
	color: var(--text-dim);
	font-size: 0.78rem;
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

/* --- Text size ---
   Real radio inputs, restyled as a segmented control. Native radios bring
   arrow-key navigation, "2 of 4" announcements and the checked state for free —
   a row of buttons with aria-pressed would have to reimplement all three. */
.nxa11y__sizes {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 0.35rem;
}

.nxa11y__size {
	display: grid;
	place-items: center;
	padding: 0.5rem 0.3rem;
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	background: var(--surface);
	color: var(--text);
	font-size: 0.8rem;
	font-weight: 600;
	text-align: center;
	cursor: pointer;
	transition: background-color 0.2s var(--ease), border-color 0.2s var(--ease), color 0.2s var(--ease);
}

/* The input is clipped off-screen by .screen-reader-text, so the focus ring has
   to be drawn on the label it controls. Without this rule the size control is
   keyboard-operable but gives no visible feedback at all. */
.nxa11y__radio:focus-visible + .nxa11y__size {
	outline: 2px solid var(--accent-ring);
	outline-offset: 2px;
}

.nxa11y__radio:checked + .nxa11y__size {
	border-color: var(--accent);
	background: var(--accent);
	color: var(--on-accent);
}

/* --- Display toggles --- */
.nxa11y__toggles {
	display: flex;
	flex-direction: column;
	gap: 0.3rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.nxa11y__toggle {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.75rem;
	inline-size: 100%;
	min-block-size: 2.5rem;
	padding: 0.5rem 0.6rem;
	border: 1px solid transparent;
	border-radius: var(--radius-sm);
	background: transparent;
	color: var(--text);
	font-size: 0.88rem;
	font-weight: 500;
	text-align: start;
	cursor: pointer;
	transition: background-color 0.2s var(--ease), border-color 0.2s var(--ease);
}

.nxa11y__toggle:hover,
.nxa11y__toggle:focus-visible {
	border-color: var(--border);
	background: var(--accent-subtle);
}

/* The switch is decoration. `aria-pressed` on the button carries the state to
   assistive tech; this only has to look like the state it describes. */
.nxa11y__switch {
	position: relative;
	flex: 0 0 auto;
	inline-size: 2.1rem;
	block-size: 1.15rem;
	border: 1px solid var(--border-light);
	border-radius: 999px;
	background: var(--surface-2);
	transition: background-color 0.2s var(--ease), border-color 0.2s var(--ease);
}

.nxa11y__switch::after {
	content: '';
	position: absolute;
	inset-block-start: 0.13rem;
	inset-inline-end: 0.13rem;
	inline-size: 0.72rem;
	block-size: 0.72rem;
	border-radius: 50%;
	background: var(--text-dim);
	transition: transform 0.2s var(--ease), background-color 0.2s var(--ease);
}

.nxa11y__toggle--on .nxa11y__switch {
	border-color: var(--accent);
	background: var(--accent);
}

.nxa11y__toggle--on .nxa11y__switch::after {
	background: var(--on-accent);
	transform: translateX(-0.95rem);
}

/* --- Footer of the panel --- */
.nxa11y__actions {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	margin-block-start: 0.9rem;
}

.nxa11y__reset {
	flex: 1 1 auto;
	padding: 0.55rem 1rem;
	border: 1px solid var(--border-light);
	border-radius: var(--radius-sm);
	background: transparent;
	color: var(--text);
	font-size: 0.85rem;
	font-weight: 600;
	cursor: pointer;
	transition: background-color 0.2s var(--ease), border-color 0.2s var(--ease), color 0.2s var(--ease);
}

.nxa11y__reset:hover,
.nxa11y__reset:focus-visible {
	border-color: var(--accent);
	background: var(--accent-subtle);
	color: var(--accent-text);
}

.nxa11y__statement {
	flex: 0 0 auto;
	color: var(--accent-text);
	font-size: 0.83rem;
	font-weight: 600;
}

.nxa11y__note {
	margin: 0.85rem 0 0;
	color: var(--text-dim);
	font-size: 0.76rem;
	line-height: 1.5;
}

/* ==========================================================================
   APPLIED PREFERENCES
   ========================================================================== */

/* ---------- 1. Text size ----------
   The theme is authored in rems off the root font size, so scaling the root
   scales headings, spacing and boxes together. Scaling only the text would
   leave it overflowing fixed-height containers. Step 1 adds no class. */
html.nxa11y-size-2 {
	font-size: 112.5%;
}

html.nxa11y-size-3 {
	font-size: 125%;
}

html.nxa11y-size-4 {
	font-size: 140%;
}

/* ---------- 2. High contrast ----------
   Overriding the tokens reaches every surface in the theme, because nothing
   outside main.css hardcodes a themed colour. Setting --accent and --accent-2
   to the same value also flattens every `linear-gradient(accent, accent-2)`
   badge, button and floating control into a solid block — no
   `background-image: none !important` needed.

   Two properties of the palettes make this work:
     - `--accent` (the fill) is only ever used as a background together with
       `--on-accent`, and `--accent-text` only as a foreground together with
       `--bg`. Each pair is chosen so both directions clear 7:1.
     - `--text-dim` is the single biggest contrast failure in the default
       palettes, so it is promoted to full strength in both directions.

   Every `-text` token must be redeclared here alongside its fill twin. The
   -text variants do not derive from the fill, so omitting one silently falls
   back to the theme's default accent and reintroduces the failure this mode
   exists to remove.

   Which register a visitor gets is decided by the same rule the palettes
   themselves use: the light block serves the two light-backed palettes, the
   dark block serves the night palette.

   THE BARE SELECTOR IS ON THE LIGHT BLOCK, and it was on the dark one until
   2026-10. The reasoning for the old placement was that a page with no
   attribute resolves the singularity tokens from main.css; the reasoning was
   right and the premise changed, because such a page resolves the bright
   tokens now. Leaving the bare selector on the dark block would paint black
   on black — or, with the haloes below, white on white — if a contrast class
   ever reached an unpainted page.

   That case is not reachable today: these classes are set from localStorage by
   inc/accessibility.php, and header.php has already written `data-theme` by
   then. This is stated anyway because it is the kind of invariant that a later
   change to either script would silently break. */
html.nxa11y-contrast,
html.nxa11y-contrast[data-theme="forge"],
html.nxa11y-contrast[data-theme="aurora"] {
	--bg: #ffffff;
	--bg-elev: #ffffff;
	--surface: #ffffff;
	--surface-2: #eeeeee;
	--border: #000000;
	--border-light: #000000;
	--text: #000000;
	--text-dim: #1a1a1a;
	--text-bright: #000000;
	--accent: #0b3d91;
	--accent-text: #0b3d91;
	--accent-rgb: 11, 61, 145;
	--accent-2: #0b3d91;
	--accent-2-text: #0b3d91;
	--accent-glow: rgba(11, 61, 145, 0.3);
	--accent-subtle: #e2e2e2;
	/* Above, --accent-ring derives from --accent. Here it cannot: the aurora
	   block declares the ring as a literal green, so overriding --accent alone
	   would leave a green ring inside a blue high-contrast mode. */
	--accent-ring: #0b3d91;
	--metal: #000000;
	--danger: #a10000;
	--warning: #7a4800;
	--warning-text: #7a4800;
	--on-accent: #ffffff;
	--ok: #0a6136;
	--ok-text: #0a6136;
}

/* Dark register: the night palette, and only it. A page that has not been
   painted is bright now — see the note above the light block. */
html.nxa11y-contrast[data-theme="singularity"] {
	--bg: #000000;
	--bg-elev: #000000;
	--surface: #000000;
	--surface-2: #141414;
	--border: #ffffff;
	--border-light: #ffffff;
	--text: #ffffff;
	--text-dim: #f0f0f0;
	--text-bright: #ffffff;
	--accent: #ffd400;
	--accent-text: #ffd400;
	--accent-rgb: 255, 212, 0;
	--accent-2: #ffd400;
	--accent-2-text: #ffd400;
	--accent-glow: rgba(255, 212, 0, 0.35);
	--accent-subtle: #3a3a3a;
	--metal: #ffffff;
	--danger: #ff8a8a;
	--warning: #ffd400;
	--warning-text: #ffd400;
	--on-accent: #000000;
	--ok: #31d07e;
	--ok-text: #31d07e;
}

/* The sticky header is deliberately translucent, which means a page title
   scrolling underneath it competes with the header's own text. */
html.nxa11y-contrast .site-header {
	background: var(--bg);
	backdrop-filter: none;
}

/* The partner-brands showcase draws its own dark panel and uses
   white-on-transparency logos, so no token reaches it. Its dim subtitle is AA
   but not AAA; promote it rather than leave a gap in the middle of the page. */
html.nxa11y-contrast .site-footer__brands-subtitle {
	color: #ffffff;
}

/* These three used to paint a literal white on `var(--accent)` instead of
   reading `--on-accent`. In the dark palette high contrast uses a light
   accent, which turned those three into white on yellow. They now read the
   token at the source, so this block is redundant — it is kept as the record
   of which three rules were wrong and as a guard if a literal comes back. */
html.nxa11y-contrast .products-slider__nav:hover,
html.nxa11y-contrast .magazine-chip--active,
html.nxa11y-contrast .magazine-pagination .page-numbers.current {
	color: var(--on-accent);
}

/* One surface deliberately does NOT follow the override, and it is worth
   writing down so it is not "fixed" later: the accessibility launcher keeps its
   literal blue disc under high contrast. It is the only place in the theme that
   carries a *mark* rather than a themed surface — a white wheelchair on a blue
   disc — and in the dark high-contrast palette the accent pair is yellow on
   black, which is a higher-contrast button but no longer the sign anyone is
   looking for. The literals still measure 5.3:1 (light) and 4.0:1 (dark)
   against those palettes' backgrounds, both above the 3:1 that WCAG 1.4.11 asks
   of a UI component, so nothing is traded away. See the launcher block. */

/* ---------- 3. Highlighted links ----------
   WCAG 1.4.1: colour must not be the only way to identify a link.

   `!important` is deliberate and is the whole point of the preference. The
   theme strips underlines from most links on purpose — nav items, product
   titles, footer columns, the legal bar — so an ordinary declaration would
   either lose to those rules or need a specificity arms race with every one of
   them. A visitor who has asked for underlined links has asked for exactly
   this override, and `!important` is how a user-preference layer is meant to
   win.

   Links shaped like buttons are exempt. They carry a fill, a border or a
   shadow, so colour is already not their only cue, and underlining them reads
   as a rendering fault rather than as help. */
html.nxa11y-links a:not([class*="btn"]):not([class*="button"]):not([class*="cta"]):not([class*="chip"]):not([class*="card"]),
html.nxa11y-links .sticky-legal-bar__link {
	text-decoration: underline !important;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.18em;
}

/* ---------- 4. Stop animations ----------
   Deliberately not wrapped in `prefers-reduced-motion: no-preference`, because
   this toggle has to work for the visitor whose operating system does not
   expose the setting at all.

   Duration is set to 0.01ms rather than `none`: an element mid-entry-animation
   with `animation-fill-mode: both` would otherwise be stuck at `opacity: 0`,
   and the panel, the consent banner and the product cards would all vanish. */
:where(html.nxa11y-nomotion) *,
:where(html.nxa11y-nomotion) *::before,
:where(html.nxa11y-nomotion) *::after {
	animation-duration: 0.01ms !important;
	animation-iteration-count: 1 !important;
	transition-duration: 0.01ms !important;
	scroll-behavior: auto !important;
}

/* ---------- 5. Text spacing ----------
   The WCAG 1.4.12 values: line height 1.5x, letter spacing 0.12x, word spacing
   0.16x, paragraph spacing 2x. Line height is set on all text blocks, but the
   letter and word spacing only on prose — applying them to a product grid would
   push the card layout apart for no readability gain. */
:where(html.nxa11y-spacing) p,
:where(html.nxa11y-spacing) li,
:where(html.nxa11y-spacing) dd,
:where(html.nxa11y-spacing) dt,
:where(html.nxa11y-spacing) figcaption,
:where(html.nxa11y-spacing) blockquote {
	line-height: 1.6 !important;
}

:where(html.nxa11y-spacing) p,
:where(html.nxa11y-spacing) blockquote {
	letter-spacing: 0.12em !important;
	word-spacing: 0.16em !important;
	margin-block-end: 2em !important;
}

/* ---------- 6. Readable font ----------
   Redeclaring the three font tokens on <html> is enough: every component reads
   them, so replacing the values swaps the whole typography in one place. The
   real win is `--font-mono` — prices, specs and stock codes are set in IBM Plex
   Mono, which costs legibility for anyone reading slowly. */
html.nxa11y-readable {
	--font-body: system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
	--font-display: system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
	--font-mono: system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
}

/* The theme's headings are 800-weight with negative tracking — a deliberate
   luxury look, and exactly the treatment this preference exists to undo. */
html.nxa11y-readable h1,
html.nxa11y-readable h2,
html.nxa11y-readable h3,
html.nxa11y-readable h4,
html.nxa11y-readable h5,
html.nxa11y-readable h6 {
	font-weight: 700;
	letter-spacing: 0;
}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */

/* ---------------------------------------------------------------- tablet */

/* 48rem is where cart-responsive.css turns the cart bar into a pinned strip.
   Its real height is measured by accessibility.js; this is only the value used
   for the first paint, and it errs tall because being too short is the
   direction that puts the launcher underneath the bar. */
@media (max-width: 48rem) {
	body.has-cartbar .nxa11y {
		--nxa11y-cartbar-guess: 6.5rem;
	}
}

/* ------------------------------------------------------------- smartphone */

/* 40rem is the WhatsApp button's own breakpoint (whatsapp.css): below it the
   labelled pill becomes a round icon bubble, so the stack shrinks with it. */
@media (max-width: 40rem) {
	.nxa11y {
		--nxa11y-edge: 0.9rem;
		--nxa11y-btn: 3rem;
	}

	body.has-nxwa .nxa11y {
		--nxa11y-stack: 3.7rem;
	}

	/* The cookie banner becomes a full-width sheet in this same corner on a
	   phone, and it asks a question that has to be answered before the shop
	   works. The launcher steps aside rather than sit underneath it — nothing is
	   lost, because the legal bar keeps a permanent נגישות button on every
	   page. */
	body:has(.consent:not([hidden])) .nxa11y__launcher {
		display: none;
	}
}

/* ------------------------------------------------------------ small phone */

/* Under 30rem the chat panel becomes a full-screen sheet (chatbot.css), so the
   launcher would float over a live conversation. Same rule whatsapp.css uses
   for its own button. */
@media (max-width: 30rem) {
	body:has(.nxchat[data-open="true"]) .nxa11y__launcher {
		display: none;
	}

	/* The panel spans the screen. `right`/`left` stay physical on purpose. */
	.nxa11y__panel {
		right: 0.5rem;
		left: 0.5rem;
		inline-size: auto;
	}
}

@media (prefers-reduced-motion: reduce) {
	.nxa11y__panel {
		animation: none;
	}
}

@media print {
	.nxa11y {
		display: none;
	}
}
