/* ============================================================
   NewXmod — Luxury Custom PC Design System
   Three palettes: Aurora (Bright White & Green, default),
   Singularity (Dark Void & Garnet), Forge (Warm Limewash).
   RTL-aware (logical properties), responsive, cinematic media.
   ============================================================ */

@import url("https://fonts.googleapis.com/css2?family=Heebo:wght@300;400;500;700;800;900&family=IBM+Plex+Mono:wght@400;500;600&display=swap");

/* ---------- Structural Tokens (identical in every palette) ----------
   Kept apart from the palettes below because not one of them is a colour.
   Each palette block redeclares colours only, so moving which palette is the
   default never moves the layout with it. */
:root {
	--radius: 12px;
	--radius-sm: 6px;
	--max-w: 1240px;
	--header-h: 72px;
	/* Height of the sticky bottom legal bar. Used for the body's bottom
	   padding (so the footer is never hidden) and by the cookie banner
	   (consent.css) so the two never overlap. This is the no-JS fallback:
	   consent.js measures the real bar height and updates it at runtime,
	   because the bar wraps to 2-3 rows on narrow screens. */
	--legal-bar-h: 2.75rem;
	--font-body: "Heebo", system-ui, -apple-system, "Segoe UI", sans-serif;
	--font-display: "Heebo", system-ui, -apple-system, "Segoe UI", sans-serif;
	--font-mono: "IBM Plex Mono", ui-monospace, "Cascadia Mono", monospace;
	--ease: cubic-bezier(0.22, 1, 0.36, 1);
	/* The focus-ring token: --accent has three jobs and only one palette has
	   had to take the third away from it. It is a fill (button backgrounds,
	   carrying --on-accent), a boundary (this focus ring, and the input borders
	   that stand in for their own removed outline) and, in a handful of places,
	   a written colour. A boundary wants 3:1 of itself against the surface
	   behind it, which caps how bright a fill can be.

	   So the ring is its own token, and its DEFAULT lives up here with the
	   structural tokens rather than in a palette, because that is what it is: a
	   reference to whatever --accent this element ended up with, for every
	   palette that has not hit that cap. `var()` is substituted on the element,
	   so singularity and forge read their own --accent through it and paint
	   exactly the colour they painted before, and aurora — the one palette whose
	   lime cannot also hold 3:1 — overrides it with a darker green. See the
	   aurora block.

	   This used to sit in the singularity block, which reached the other two
	   only because that block's selector also carried `:root` and therefore
	   matched every document. It moved here when the default changed and that
	   `:root` went away; forge is the palette it would have silently broken. */
	--accent-ring: var(--accent);
}

/* ---------------------------------------------------------------------------
   PALETTES — three of them, selected by `data-theme` on <html>.

     aurora        Bright White & Green   (the default)
     singularity   Dark Void & Garnet     (the night register)
     forge         Warm Limewash         (the middle register)

   SOURCE ORDER IS LOAD-BEARING, and so is the shape of the default's selector.
   `[data-theme="x"]` and `:root` are both specificity (0,1,0), so the last
   matching block is what decides. That is why the structural block above comes
   first.

   THE DEFAULT IS DECLARED AS `:root:not([data-theme])`, NOT AS `:root`.
   `header.php` paints `data-theme` before first paint, so the attribute is
   normally there and the default block is reached through
   `[data-theme="aurora"]`. A visitor with JavaScript off never gets an
   attribute at all, and `:root:not([data-theme])` is the one selector that
   catches exactly that page and nothing else. A bare `:root` would also match
   `<html data-theme="singularity">`, and because specificity ties are broken
   by source order it would then quietly repaint the night and warm registers
   with the bright tokens unless those blocks happened to come later — which is
   a coupling nobody should have to keep in their head while editing a colour.

   The two rules every palette here obeys, both re-derived from this file by
   `scripts/_palette-contrast.php`:

     1. `--accent` is a SOLID FILL. It is painted as a background and carries
        `--on-accent` text. `--accent-text` is the variant used for `color:`.
        They are separate tokens because the two jobs pull in opposite
        directions — lightening the fill breaks the text sitting on it. Use
        `--accent-text` whenever the accent is written, `--accent` when it is
        painted.
     2. Every status colour is split the same way where it has to be, because
        a red dark enough to read on a pale surface is too dark to read on a
        dark one.
   --------------------------------------------------------------------------- */

/* ---------- Palette: Singularity (Dark Void & Garnet) ---------- */
[data-theme="singularity"] {
	--bg: #120e0c;
	--bg-elev: #1c1714;
	--surface: #221c18;
	--surface-2: #2d2520;
	--border: #3a322c;
	--border-light: #52473f;
	--text: #f3ebe3;
	--text-dim: #9a8b7e;
	--text-bright: #ffffff;
	/* #b53a3a measures only 2.91-3.32:1 as text against the three dark surfaces
	   below (--bg, --bg-elev, --surface), so it fails WCAG 1.4.3 the moment it
	   is used for `color:` — which it was, in 16 stylesheets. Lightening
	   --accent itself is NOT the fix: the same token paints button backgrounds
	   that carry white --on-accent text, and white on #e06b62 is 3.26:1. Hence
	   the split. #e06b62 measures 5.90 / 5.17 / 5.46:1 on those surfaces, and
	   #e8897c (the accent-2 counterpart) clears them too. Fixed 2026-09-15. */
	--accent: #b53a3a;
	--accent-text: #e06b62;
	--accent-rgb: 181, 58, 58;
	--ok: #31d07e;
	/* The bright green already clears 4.5:1 on dark surfaces. */
	--ok-text: #31d07e;
	--accent-glow: rgba(181, 58, 58, 0.28);
	--accent-subtle: rgba(181, 58, 58, 0.12);
	/* No --accent-ring here: this palette has never needed to separate its
	   boundary from its fill, so it simply inherits the structural default
	   (`var(--accent)`) and paints the same colour it always did. */
	/* --accent-2 is a FILL as well as a decorative second stop: it is the
	   solid background of .btn--primary:hover and the far stop of every
	   `linear-gradient(135deg, var(--accent), var(--accent-2))` pill, both
	   carrying --on-accent text. #c45c4a left that white at 4.21:1, under
	   4.5:1. #b34a38 measures 5.14:1 on it and stays lighter than --accent,
	   so the gradient keeps a direction. Fixed 2026-09-15. */
	--accent-2: #b34a38;
	--accent-2-text: #e8897c;
	--metal: #c9c2b6;
	--danger: #ff6b6b;
	--warning: #e0a53c;
	/* On this palette the amber already clears 7:1, so unlike forge the fill
	   and text variants are the same value. */
	--warning-text: #e0a53c;
	--on-accent: #ffffff;
}

/* ---------- Palette: Aurora (Bright White & Green) — the default ----------
   The bright register: white cards on a pale green-grey page, and a green
   accent where Forge carries steel blue. It is the same construction the
   storefront shipped as its light mode, one step brighter and one hue across,
   so nothing about the layout had to move with it.

   Its green is no longer derived from the footage. It is sampled from the
   brand art itself — assets/images/xmodzGreenlogowithBG.png, the wordmark the
   owner sent and then pointed at: take the green from here, sample it, that is
   the colour. The art measures hue 92.7 over 74,103 coolant pixels, and that
   is a LIME. The liquid in hero-poster.jpg measures hue 132. Both greens are
   real, they are 39 degrees apart, and this palette now wears the logo's — the
   BUTTONS wear that same hue taken one register down, and the ladder below
   records every step of how deep that is.

   AND THIS IS WHAT EVERYONE LANDS ON. It used to be singularity, until Valery
   asked for the reverse: "קודם כל תעשה שמצב הבהיר יהיה הדיפולטיבי הראשון
   שכולם נוחתים בו". The selector below is therefore the pair of them —
   `[data-theme="aurora"]` for the ordinary visitor, whose attribute header.php
   painted before first paint, and `:root:not([data-theme])` for the ones with
   JavaScript off, who never get an attribute at all. See the PALETTES note
   above for why the second half is not simply `:root`. */
:root:not([data-theme]),
[data-theme="aurora"] {
	--bg: #eef1ef;
	--bg-elev: #f9fbfa;
	--surface: #ffffff;
	--surface-2: #e2e9e5;
	--border: #cdd8d2;
	--border-light: #aab9b1;
	--text: #14201a;
	--text-dim: #55645c;
	--text-bright: #040d08;
	--accent: #4a6633;
	--accent-text: #376113;
	--accent-rgb: 74, 102, 51;
	--accent-glow: rgba(74, 102, 51, 0.28);
	--accent-subtle: rgba(74, 102, 51, 0.14);
	/* The boundary green, and the one token on this palette that does not
	   follow the fill. Same hue 92.7, taken down to value 0.55, because a
	   boundary owes 3:1 to whatever is behind it: 3.28:1 on --surface-2, 3.56:1
	   on --bg, 4.05:1 on white. A focus ring is drawn a small offset away from
	   the control, so what it faces is the page and not the button — which is
	   exactly why it cannot follow --accent. It matters more in this palette
	   than in the other two, and the note below says why. Focus states are also
	   the only accent-coloured boundaries left in the theme.

	   The fill has since gone deeper than this ring — value 0.40 against the
	   ring's 0.55 — so the two no longer read as one colour. That is right for
	   an indicator drawn on the page rather than on the control, and it is the
	   whole reason the ring is fixed by what is UNDER it instead of by what it
	   belongs to. */
	--accent-ring: #578c2a;
	/* The green is the logo's now, not the coolant's: #4a6633 is the art's own
	   hue 92.7 at saturation 0.50 and value 0.40 — the art's hue at every step
	   of this ladder, and one register deeper than the fill it replaces.

	   Valery asked for that depth on 2026-10-06, about the buttons: "from the
	   bright green to a slightly more faded green, professional, so it does not
	   look so shouty — like the warm version, where the blue is a dark blue.
	   Keep it greenish, just not shouty and not glaring." So the lever is the
	   one he named: this palette's CTA now weighs what the warm palette's
	   already does. #4a6270, forge's steel blue, measures relative luminance
	   0.1136, carries white at 6.42:1 and holds a 5.64:1 edge against its own
	   page. #4a6633 measures 0.1120, 6.48:1 and 5.70:1 — the same weight within
	   1.4%, reached by holding the hue and cutting chroma and value, never by
	   picking a colour by eye. The saturation is the one judgement in the round:
	   chroma is what makes a green read as faded rather than merely dark, so it
	   came down with the value, and 0.50 is where the fill still reads as green
	   at a glance instead of as a grey-olive. Every other number here was
	   measured.

	   The ladder, all of it hue 92.7, and why it moved twice:
	     #85d640  sat 0.70  val 0.84  L 0.5345   the art's saturated core
	     #4a6633  sat 0.50  val 0.40  L 0.1120   this round, the muted deep green
	   Behind those, two greens of the footage's hue 127: #28c73b at value 0.78
	   and #2a9737 at 0.59. The 0.59 was arithmetic rather than taste — --accent
	   was doing two jobs at once, a fill (every button, the sale badge, the
	   pagination pill) and a boundary (the focus ring and the form borders that
	   stand in for their own removed outline). A boundary owes 3:1 to whatever
	   is behind it, --surface-2 is the darkest of this palette's three light
	   surfaces, and that ceiling is 3.05:1 — so #2a9737 sat exactly on it and no
	   amount of taste could push the green past it. The two jobs became two
	   tokens in 0.3.79, and the fill was free from then on.

	   What the bright step paid for that freedom, and what this round hands
	   back: the fill's own edge against the page went 3.31:1 -> 1.58:1 as the
	   green brightened, because a lime on a near-white page cannot hold an edge,
	   which left the label carrying the entire button. It is 5.70:1 again, so
	   the button reads as a button before anyone reads its word. The ink
	   inverts with the fill, as it must: --on-accent is white here now, because
	   ink on this green measures 2.95:1 and white 6.48:1. A green this light
	   could not carry white text and a green this deep cannot carry dark text —
	   same inversion, opposite direction, the same green.

	   --accent-glow is the soft shadow under the button, and at last it is a
	   shadow rather than the pale wash a lime casts on a near-white page. It is
	   also an `outline` in two files: chatbot.css pairs it with
	   `border-color: var(--accent-ring)`, so a real boundary survives there,
	   while whatsapp.css ~62-64 uses the glow ALONE (`outline: 2px solid
	   var(--accent-glow); outline-offset: 3px`) and, because of the offset,
	   draws on the PAGE rather than on the control. Composited there it reads
	   1.14:1 before this round and 1.49:1 now — still under the 3:1 a focus
	   indicator owes. That gap is pre-existing and identical in all three
	   palettes, not something this round introduced; the one-line repair
	   (`var(--accent-ring)` at whatsapp.css:63) would move forge and
	   singularity as well, so it stays Valery's call and is reported, not
	   applied.

	   The ~60 `border-color: var(--accent)` sites were checked one at a time
	   and are not boundaries — every one of them lands together with a fill,
	   an ink change, a transform, a shadow or an opacity change, so none is
	   the only thing saying "this is the state". They follow the fill.

	   --accent-text and --accent-2-text are deliberately NOT re-derived with it.
	   They are the WRITTEN green — `a { color: var(--accent-text) }` — and they
	   already sit in this fill's own hue at the same luminance with a little
	   more chroma, so a link and a button still read as one colour: #376113
	   measures 5.91:1 on --surface-2 and its hover #3f7016 4.81:1. Muting the
	   written green as well is a separate decision for the owner. */
	/* --accent-2 does double duty here, as it does everywhere: it is the far
	   stop of `linear-gradient(accent, accent-2)` and the solid background of
	   .btn--primary:hover. It carries no boundary duty — its one border-color
	   use (consent.css) shares its own fill — so unlike --accent it is free to
	   be the brighter hover stop, which is the direction the theme already
	   uses. It has to stay above --accent or the hover stops reading as a
	   lightening at all: 0.1367 against 0.1120 is a 22.1% lift, the same step
	   the pair held at its previous two values. It is bounded from above by the
	   ink as well as below by the fill — white on it is 5.62:1 — so the hover
	   may be one saturation-step brighter than the fill and no more, or it
	   drops under 4.5:1 and the button's own word becomes the thing that
	   breaks. The two written variants are held a step apart in luminance on
	   purpose: #376113 is a link at rest and #3f7016 is its hover, so if they
	   measured the same the hover would show no change at all. */
	--accent-2: #527038;
	--accent-2-text: #3f7016;
	--metal: #8b968f;
	/* The bright status green is a mark here, never a word: on white it is
	   1.95:1, so anything written uses --ok-text. Its hue is 150 against this
	   palette's 92.7, so aurora ships two greens deliberately — the brand's
	   lime and the conventional success green. Do not unify them. */
	--ok: #31d07e;
	--ok-text: #0a6136;
	/* Unchanged from Forge. Green is this palette's accent, so a red that also
	   reads on a white surface is worth more than a red that matches it. */
	--danger: #a32d26;
	--warning: #b06a10;
	--warning-text: #7a4800;
	/* White, not ink — the third time this token has flipped, and it flips for
	   the same reason every time: it follows the fill. Ink on this green
	   measures 2.95:1 and white 6.48:1 on --accent, 5.62:1 on the --accent-2
	   hover, so the deep palette writes light on its fills. The lime needed the
	   opposite — white on it was 1.80:1 — and so did the two greens before it. */
	--on-accent: #ffffff;
}

/* ---------- Palette: Forge (Warm Limewash) ----------
   The middle register, and no longer the light one: the surfaces stop at
   limewash and never reach white, the page sits several stops below the old
   #ece8e2, and the whole ramp is warmed toward yellow. Tuned for long reading
   rather than for the brightest possible white.

   The steel blue stays. It was already the token pair with the most
   measurement behind it, and warm paper under a cool ink is the pairing the
   palette was named for — changing the hue here would have re-derived every
   contrast claim in the theme for no gain in legibility. */
[data-theme="forge"] {
	--bg: #ded3bb;
	--bg-elev: #e8dfcb;
	--surface: #ebe3d1;
	--surface-2: #d1c5a8;
	--border: #b9ac90;
	--border-light: #a09173;
	--text: #1e1a12;
	/* Darker than the light register's #676058 could ever have been. This
	   palette's deepest surface is --surface-2 #d1c5a8, several stops below
	   the old #e4ded6, and #5b5340 only reached 4.45:1 on it. #4d4634 is
	   5.47:1 there, 6.31:1 on --bg and 7.34:1 on --surface. */
	--text-dim: #4d4634;
	--text-bright: #0b0903;
	--accent: #4a6270;
	--accent-text: #3f5560;
	--accent-rgb: 74, 98, 112;
	--accent-glow: rgba(74, 98, 112, 0.25);
	--accent-subtle: rgba(74, 98, 112, 0.12);
	--accent-2: #2d3e48;
	--accent-2-text: #2d3e48;
	--metal: #857a63;
	/* --ok is the bright status green used for dots and borders. As text even
	   on the old white surface it only reached 2.01:1, so written status uses
	   --ok-text. On limewash it is lower still, and the rule is unchanged. */
	--ok: #31d07e;
	/* The light register's #0a6136 measured 4.42:1 on #d1c5a8 and its
	   #7a4800 measured 4.45:1 — both just under the line, both fixed here
	   rather than by lightening the surface, because a recessed surface that
	   is not actually darker than the page is not a recessed surface. */
	--ok-text: #084f2b;
	/* #a32d26 measured 4.14:1 on #d1c5a8. #8e2620 is 5.01:1 there and
	   6.72:1 on --surface, so the red stays readable as `color:` on every
	   surface the palette paints. */
	--danger: #8e2620;
	--warning: #b06a10;
	--warning-text: #6b3f00;
	--on-accent: #ffffff;
}

/* ---------- Reset ---------- */
*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
}

body {
	margin: 0;
	font-family: var(--font-body);
	font-size: 1rem;
	line-height: 1.6;
	color: var(--text);
	background: var(--bg);
	-webkit-font-smoothing: antialiased;
}

img {
	max-width: 100%;
	height: auto;
	display: block;
}

a {
	color: var(--accent-text);
	text-decoration: none;
}

a:hover {
	text-decoration: underline;
}

h1, h2, h3, h4, h5, h6 {
	font-family: var(--font-display);
	font-weight: 800;
	line-height: 1.25;
	margin: 0 0 0.5em;
}

h3, h4, h5, h6 {
	font-weight: 700;
}

p {
	margin: 0 0 1em;
}

/* ---------- Accessibility ---------- */
.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

/*
 * Skip link. Parked just above the top edge and pulled back down by :focus.
 * The reveal is written for BOTH :focus and :focus-visible on purpose: this is
 * the first tab stop on every page, and the original rule carried no reveal at
 * all, so `inset-block-start: -100%` — which resolves against the initial
 * containing block, not the link — parked it a full viewport above the top
 * edge permanently. The keyboard audit found it at y=-900 on a 900px viewport
 * on all four audited pages, so the skip mechanism existed but was invisible:
 * it satisfied WCAG 2.4.1 on paper while failing 2.4.7 outright. `translateY`
 * replaces the percentage inset so the parked position depends on the link's
 * own height rather than on the containing block. Fixed 2026-09-15.
 */
.skip-link {
	position: absolute;
	inset-block-start: 0;
	inset-inline-start: 1rem;
	z-index: 100;
	transform: translateY(-120%);
	background: var(--accent);
	color: var(--on-accent);
	padding: 0.7rem 1.25rem;
	border-radius: 0 0 var(--radius-sm) var(--radius-sm);
	transition: transform var(--ease) 0.18s;
}

.skip-link:focus,
.skip-link:focus-visible {
	transform: translateY(0);
}

/* The chip paints --accent, so the inherited accent-coloured ring would be
   invisible against its own fill. --text-bright is near-black in the light
   palette and white in the dark one, so the ring reads in both. */
.skip-link:focus-visible {
	outline-color: var(--text-bright);
}

:focus-visible {
	outline: 2px solid var(--accent-ring);
	outline-offset: 2px;
}

/* ---------- Layout ---------- */
.site-header {
	position: sticky;
	inset-block-start: 0;
	z-index: 50;
	background: color-mix(in srgb, var(--bg) 82%, transparent);
	backdrop-filter: blur(10px);
	border-block-end: 1px solid var(--border);
}

.section__inner,
.page__inner,
.site-footer__inner {
	max-width: var(--max-w);
	margin-inline: auto;
	padding-inline: 1.25rem;
}

.site-header__inner {
	width: 100%;
	max-width: 100%;
	padding-inline: clamp(1rem, 2.5vw, 2.5rem);
	display: flex;
	align-items: center;
	/* This row must NEVER overflow sideways. Its min-content width is ~362px,
	   which is wider than every phone viewport, and at 768px the restored
	   labels make it ~795px inside a ~721px box. The measured consequence was
	   the language switcher pushed to left:-73px — off-screen and unreachable,
	   a loss of function, not just polish (WCAG 1.4.4 Reflow). Wrapping is the
	   only fix that survives future label changes and translations, and it
	   changes nothing at widths where the row already fits. Fixed 2026-09-15. */
	flex-wrap: wrap;
	gap: 1rem;
	row-gap: 0.4rem;
	min-height: var(--header-h);
}

.site-brand a {
	display: inline-flex;
	align-items: center;
	text-decoration: none;
}

.site-brand__wrap {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
}

.site-brand__icon {
	width: 28px;
	height: 28px;
	object-fit: contain;
	display: inline-block;
	flex-shrink: 0;
}

.site-brand__name {
	font-weight: 800;
	letter-spacing: 0.02em;
	font-size: 1.25rem;
	color: var(--text);
}

/* Nav. `display: contents` on desktop: the wrapper leaves the layout, so the
   toggle (hidden there) and the menu's contents — the categories accordion —
   join the header row where they always sat. One markup, two shapes. */
.nav {
	display: contents;
}

/*
 * The drawer's copy of the account link (header.php). Desktop already has the
 * row copy after Contact, so this one only exists on a phone.
 */
.nav__account {
	display: none;
}

/*
 * The six header actions (Home / Categories / Build a PC / Magazine / Contact /
 * Account) live in this wrapper so the phone can turn them into the hamburger's
 * panel. On desktop it is `display: contents`: the wrapper leaves the layout and
 * its children join `.site-header__inner`'s flex row exactly as they always did.
 * One copy of the markup serves both shapes — the alternative (a second, mobile
 * only menu) is how two navigations start disagreeing.
 */
.site-header__primary {
	display: contents;
}

/* Categories Dropdown (accordion menu) */
.mega-cat {
	position: relative;
}

.mega-cat__btn {
	display: inline-flex;
	flex-direction: row; /* Hebrew (RTL): icon on the right */
	align-items: center;
	gap: 0.4rem;
	padding: 0.25rem 0;
	background: none;
	color: var(--text);
	border: 0;
	border-radius: 0;
	font-family: inherit;
	font-size: 0.875rem;
	font-weight: 600;
	cursor: pointer;
	transition: color 0.2s var(--ease);
}

.mega-cat__btn:hover,
.mega-cat__btn[aria-expanded="true"] {
	background: none;
	color: var(--accent-text);
}

.mega-cat__btn-icon {
	display: flex;
	align-items: center;
	color: currentColor;
}

.mega-cat__btn-arrow {
	font-size: 0.75rem;
	transition: transform 0.2s var(--ease);
}

.mega-cat__btn[aria-expanded="true"] .mega-cat__btn-arrow {
	transform: rotate(180deg);
}

/* Dropdown panel: compact, anchored under the button.
   The height cap is a safety net, not a design decision: the panel is an
   accordion whose length depends on how many catalogue branches are on sale and
   which one the visitor expanded, so it must scroll rather than run off the
   bottom of a short window. */
.mega-cat__panel {
	display: none;
	position: absolute;
	inset-block-start: calc(100% + 10px);
	inset-inline-start: 0; /* Hebrew (RTL): opens from the right side */
	width: min(330px, calc(100vw - 1rem));
	max-height: calc(100vh - var(--header-h) - 1rem);
	overflow-y: auto;
	background: var(--bg-elev);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	box-shadow: 0 18px 40px rgba(0, 0, 0, 0.35);
	z-index: 100;
	padding: 0.5rem;
}

.mega-cat.is-open .mega-cat__panel {
	display: block;
	animation: megaSlideDown 0.18s var(--ease) forwards;
}

@keyframes megaSlideDown {
	from {
		opacity: 0;
		transform: translateY(-6px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

.mega-cat__backdrop {
	display: none;
	position: fixed;
	inset: 0;
	background: rgba(0, 0, 0, 0.4);
	z-index: 90;
}

.mega-cat.is-open .mega-cat__backdrop {
	display: block;
}

/* Main category list (accordion) */
.mega-cat__menu {
	list-style: none;
	margin: 0;
	padding: 0;
}

.mega-cat__item + .mega-cat__item {
	border-block-start: 1px solid var(--border);
}

.mega-cat__item-head {
	display: flex;
	flex-direction: row; /* Hebrew (RTL): icon on the right */
	align-items: center;
	gap: 0.6rem;
	width: 100%;
	padding: 0.7rem 0.5rem;
	background: none;
	border: 0;
	cursor: pointer;
	color: var(--text);
	font-family: inherit;
	font-size: 0.9rem;
	font-weight: 600;
	text-align: start;
	border-radius: var(--radius-sm);
	transition: all 0.15s var(--ease);
}

.mega-cat__item-head:hover,
.mega-cat__item.is-open .mega-cat__item-head {
	background: var(--surface);
	color: var(--accent-text);
}

.mega-cat__item-icon {
	font-size: 1.05rem;
	line-height: 1;
}

.mega-cat__item-name {
	flex: 1;
}

.mega-cat__item-caret {
	font-size: 0.7rem;
	color: var(--text-dim);
	transition: transform 0.2s var(--ease);
}

.mega-cat__item.is-open .mega-cat__item-caret {
	transform: rotate(180deg);
	color: var(--accent-text);
}

/* Animated expand wrapper */
.mega-cat__subwrap {
	display: grid;
	grid-template-rows: 0fr;
	visibility: hidden;
	transition: grid-template-rows 0.25s var(--ease), visibility 0s linear 0.25s;
}

.mega-cat__item.is-open .mega-cat__subwrap {
	grid-template-rows: 1fr;
	visibility: visible;
	transition: grid-template-rows 0.25s var(--ease), visibility 0s;
}

.mega-cat__subwrap > .mega-cat__sub {
	overflow: hidden;
}

/* Sub-category list */
.mega-cat__sub {
	list-style: none;
	margin: 0;
	padding: 0 0.4rem 0.5rem 1.1rem;
	display: flex;
	flex-direction: column;
	gap: 0.1rem;
}

.mega-cat__sub a {
	display: block;
	padding: 0.42rem 0.6rem;
	border-radius: var(--radius-sm);
	color: var(--text-dim);
	font-size: 0.85rem;
	text-decoration: none;
	transition: all 0.15s var(--ease);
}

.mega-cat__sub a:hover {
	background: var(--surface-2);
	color: var(--accent-text);
	padding-inline-start: 0.85rem;
}

/* Header action links — Home, Build a PC, Magazine, Contact, Account.
   One uniform style for every text + icon action in the header row, so a new
   action (e.g. Account) only needs a markup block, never new CSS. */
.site-header__home a,
.site-header__builder a,
.site-header__magazine a,
.site-header__contact a,
.site-header__account a {
	display: inline-flex;
	flex-direction: row; /* Hebrew (RTL): icon on the right */
	align-items: center;
	gap: 0.4rem;
	padding: 0.25rem 0;
	background: none;
	color: var(--text);
	font-family: inherit;
	font-size: 0.875rem;
	font-weight: 600;
	text-decoration: none;
	white-space: nowrap;
	transition: color 0.2s var(--ease);
}

.site-header__home a:hover,
.site-header__builder a:hover,
.site-header__magazine a:hover,
.site-header__contact a:hover,
.site-header__account a:hover {
	color: var(--accent-text);
}

.site-header__home-icon,
.site-header__builder-icon,
.site-header__magazine-icon,
.site-header__contact-icon,
.site-header__account-icon {
	display: flex;
	align-items: center;
	color: currentColor;
}

/* Mobile: keep panel inside the viewport */
@media (max-width: 767px) {
	.mega-cat__panel {
		position: fixed;
		inset-block-start: var(--header-h);
		inset-inline-start: 0.5rem; /* Hebrew (RTL): panel opens from the right side */
		max-height: calc(100vh - var(--header-h) - 1rem);
		overflow-y: auto;
	}
}

/*
 * The drawer. `display: contents` on desktop because it carries the categories
 * accordion, which belongs in the row there; on a phone it becomes the panel
 * the hamburger opens.
 */
.nav__menu {
	display: contents;
}

/*
 * The WordPress primary menu is NOT part of the desktop row — the row already
 * carries Home / Categories / Build a PC / Magazine / Contact, and rendering the
 * menu inline as well produced a visible second navigation. On a phone it is the
 * menu, and the row is what goes away.
 */
.nav__list {
	list-style: none;
	margin: 0;
	padding: 0;
	flex-direction: column;
	gap: 0.25rem;
	display: none;
}

.nav__list a {
	display: block;
	padding: 0.6rem 0.75rem;
	color: var(--text);
	border-radius: var(--radius-sm);
}

.nav__list a:hover {
	background: var(--surface);
	text-decoration: none;
}

.nav__toggle {
	display: none; /* phones only, see the 767px block */
	background: none;
	border: 0;
	cursor: pointer;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	gap: 5px;
	/* A thumb target, not a 22px glyph: WCAG 2.5.8 asks for 24px minimum and a
	   comfortable phone target is 44px. The rows it opens are the menu, so the
	   button itself must be the easiest thing on the row to hit. */
	min-inline-size: 44px;
	min-block-size: 44px;
	margin-inline-start: -0.5rem;
}

.nav__toggle-bar {
	width: 24px;
	height: 2px;
	background: var(--text);
	border-radius: 2px;
	transition: transform 0.2s var(--ease), opacity 0.2s var(--ease);
}

/* Open state: the three bars become a cross, so the same control closes the
   panel it opened. */
.nav__toggle[aria-expanded="true"] .nav__toggle-bar:nth-child(1) {
	transform: translateY(7px) rotate(45deg);
}

.nav__toggle[aria-expanded="true"] .nav__toggle-bar:nth-child(2) {
	opacity: 0;
}

.nav__toggle[aria-expanded="true"] .nav__toggle-bar:nth-child(3) {
	transform: translateY(-7px) rotate(-45deg);
}

/* Cart — pushed to the far left end of the header (Hebrew e-commerce convention) */
.site-header__cart {
	display: flex;
	align-items: center;
	margin-inline-start: auto; /* Hebrew (RTL): absorbs free space, cart goes to the far left */
}

/* Cart link */
.cart-link {
	position: relative;
	color: var(--text);
	padding: 0.5rem;
}

.cart-link__count {
	position: absolute;
	inset-block-start: 0;
	inset-inline-end: 0;
	min-width: 18px;
	height: 18px;
	padding: 0 4px;
	border-radius: 999px;
	background: var(--accent);
	color: var(--on-accent);
	font-size: 0.7rem;
	font-weight: 700;
	display: grid;
	place-items: center;
}

/* Theme toggle button — in normal flex flow, pinned to the very far left edge */
.site-header__theme-toggle {
	position: static;
	top: auto;
	right: auto;
	transform: none;
	display: flex;
	align-items: center;
	margin-inline-start: 0;
}

/* Cart pushes the toggle + cart pair to the far left (Hebrew RTL: inline-start = right side) */
.site-header__cart {
	margin-inline-start: auto;
}

/* ==========================================================================
   Header call block — the number to tap, and one action beside it
   ========================================================================== */

.site-header__call {
	display: flex;
	align-items: center;
	gap: 0.75rem;
}

/*
 * The pin, and the reason this block exists at all.
 *
 * The far-left edge of this row was always produced by `margin-inline-start:
 * auto` on the CART. Production runs in lead mode (inc/shop-mode.php), where the
 * cart is deliberately not printed — so no item carried the auto margin, the row
 * packed to the right, and the language switcher sat at the RIGHT end of the
 * cluster instead of the left edge. Measured on the live site 2026-10-22: the
 * rendered header had no `site-header__cart` at all.
 *
 * So: when the cart is absent this block takes over the pin. When the cart is
 * present its own auto margin already sends everything after it to the left,
 * and a second auto margin would split the free space and centre the group.
 */
.site-header__inner:not(:has(.site-header__cart)) .site-header__call {
	margin-inline-start: auto;
}

.site-header__phone {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	color: var(--text);
	font-size: 0.9375rem;
	font-weight: 700;
	text-decoration: none;
	white-space: nowrap;
	letter-spacing: 0.01em;
	transition: color 0.2s var(--ease);
}

.site-header__phone:hover,
.site-header__phone:focus-visible {
	color: var(--accent-text);
}

.site-header__phone-icon {
	display: flex;
	align-items: center;
	color: currentColor;
}

/* The one filled control in the header row: it is the only item that asks for
   something rather than showing where you are. */
.site-header__cta {
	display: inline-flex;
	align-items: center;
	padding: 0.4rem 0.95rem;
	border-radius: 999px;
	background: var(--accent);
	color: var(--on-accent);
	font-size: 0.875rem;
	font-weight: 700;
	text-decoration: none;
	white-space: nowrap;
	transition: background-color 0.2s var(--ease), color 0.2s var(--ease);
}

.site-header__cta:hover,
.site-header__cta:focus-visible {
	background: var(--accent-2);
	color: var(--on-accent);
}

/* ==========================================================================
   Language switcher (always visible in the header)
   One control, three languages (HE / EN / RU). Built on <details> so it works
   with JavaScript disabled; main.js only adds close-on-outside-click.
   ========================================================================== */
.site-header__lang {
	display: flex;
	align-items: center;
}

.lang-switch {
	position: relative;
}

.lang-switch__btn {
	display: inline-flex;
	align-items: center;
	gap: 0.3rem;
	padding: 0.35rem 0.5rem;
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	background: var(--surface);
	color: var(--text);
	font-size: 0.8125rem;
	font-weight: 700;
	line-height: 1;
	cursor: pointer;
	list-style: none;
	transition: border-color 0.2s var(--ease), color 0.2s var(--ease);
}

/* Hide the native disclosure triangle on <summary>. */
.lang-switch__btn::-webkit-details-marker {
	display: none;
}

.lang-switch__btn::marker {
	content: "";
}

.lang-switch__btn:hover,
.lang-switch[open] .lang-switch__btn {
	border-color: var(--accent);
	color: var(--accent-text);
}

.lang-switch__globe {
	font-size: 0.9rem;
	line-height: 1;
}

.lang-switch__current {
	letter-spacing: 0.04em;
}

.lang-switch__caret {
	font-size: 0.7rem;
	opacity: 0.7;
	transition: transform 0.2s var(--ease);
}

.lang-switch[open] .lang-switch__caret {
	transform: rotate(180deg);
}

.lang-switch__list {
	position: absolute;
	inset-block-start: calc(100% + 0.4rem);
	inset-inline-end: 0;
	z-index: 60;
	min-width: 9.5rem;
	margin: 0;
	padding: 0.3rem;
	list-style: none;
	background: var(--bg-elev);
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	box-shadow: 0 12px 32px rgb(0 0 0 / 18%);
}

.lang-switch__item + .lang-switch__item {
	margin-block-start: 0.15rem;
}

.lang-switch__link {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.45rem 0.55rem;
	border-radius: var(--radius-sm);
	color: var(--text);
	font-size: 0.875rem;
	text-decoration: none;
}

.lang-switch__link:hover {
	background: var(--surface);
	text-decoration: none;
}

.lang-switch__link.is-current {
	color: var(--accent-text);
	font-weight: 700;
}

.lang-switch__code {
	min-width: 1.9rem;
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.06em;
	opacity: 0.75;
}

.lang-switch__name {
	flex: 1 1 auto;
}

.lang-switch__check {
	font-size: 0.8rem;
}

/* Menu variant (kept for the no-JS mobile fallback inside the nav panel). */
.newxmod-lang-switcher__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem;
}

.newxmod-lang-switcher__link {
	display: inline-block;
	padding: 0.35rem 0.6rem;
	border-radius: var(--radius-sm);
	color: var(--text);
	font-size: 0.8125rem;
	text-decoration: none;
}

.newxmod-lang-switcher__link.is-current,
.newxmod-lang-switcher__item.is-current .newxmod-lang-switcher__link {
	background: var(--accent);
	color: var(--on-accent);
	font-weight: 700;
}

/* Mobile: icon-only links + cart at the far left, so the header fits and
   the cart stays visible at the left edge of the screen. */
@media (max-width: 767px) {
	.site-header__inner {
		gap: 0.25rem;
	}

	/*
	 * THE MOBILE ROW IS THREE THINGS.
	 *
	 * Valery, 2026-10-22: "שים את הלוגו XMODZ באמצע ואת ההמבורגר הכי ימינה שאפשר
	 * ובאנגלית הכי שמאלה שאפשר".
	 *
	 * The logo is taken out of the flow and pinned to the middle of the header,
	 * so it is centred against the SCREEN and not against whatever is left over
	 * after its neighbours — a flex `space-between` only centres an item when the
	 * two sides happen to weigh the same, and they never do. What stays in the row
	 * is the hamburger (pushed to the inline start = the right edge in Hebrew) and
	 * the palette + language pair at the inline end (the left edge).
	 */
	.site-brand {
		position: absolute;
		inset-block-start: 50%;
		left: 50%;
		transform: translate(-50%, -50%);
		min-inline-size: 0;
	}

	/* Everything else in the row steps aside: Home is the logo's job, the four
	   product links and the account are drawers rows, and the number is one tap
	   away in the always-visible quick bar (inc/location.php). */
	.site-header__home,
	.site-header__primary,
	.site-header__inner > .site-header__account,
	.site-header__call {
		display: none;
	}

	.nav,
	.site-header__theme-toggle {
		flex: 0 0 auto;
	}

	.nav {
		margin-inline-end: auto; /* inline-end in RTL is the left side: pushes the toggle to the right edge */
	}

	/* The drawer carries the account link on a phone. */
	.nav__account {
		display: block;
	}

	.nav__account .site-header__account a {
		display: flex;
		inline-size: 100%;
		align-items: center;
		gap: 0.7rem;
		padding: 0.9rem 0.25rem;
		font-size: 1rem;
		font-weight: 600;
	}

	/* The language pill is the one header item that must stay visible: it is the
	   leftmost thing in the row, per the same request. */
	.site-header__theme-toggle .theme-toggle-btn__label {
		display: none;
	}

	.site-header__lang {
		flex: 0 0 auto;
		margin-inline-start: 0;
	}
	/*
	 * THE MENU IS THE HAMBURGER'S, NOT THE ROW'S.
	 *
	 * Valery, 2026-10-22: "במובייל על הפאנל למעלה כל התפריט — כפתורים קטנים,
	 * איזה אצבע יכולה ללחוץ על זה? במקום זה צריך להיות המבורגר שיורד והקטגוריות
	 * — תעשה עוד תפריט שנפתח בהמבורגר."
	 *
	 * The icons were tiny because the hamburger was opening an EMPTY panel: a
	 * rule hid `.nav__list` on the assumption that no WordPress menu existed,
	 * while `newxmod_menu( 'primary' )` had been printing one all along. Now the
	 * hamburger opens that menu — full width rows, 1rem text, the category
	 * accordion nested underneath — and the six row actions step aside.
	 */
	.nav {
		display: flex;
		align-items: center;
	}

	.nav__toggle {
		display: flex;
		/* The base rule pulls the button half a rem towards the brand to sit
		   optically flush; with a real menu behind it that would steal 8px from
		   its own 44px target and let it overlap the account icon. */
		margin-inline-start: 0;
	}

	.nav__menu {
		display: none;
		position: absolute;
		inset-block-start: var(--header-h);
		inset-inline: 0;
		flex-direction: column;
		align-items: stretch;
		gap: 0;
		max-block-size: calc(100vh - var(--header-h));
		overflow-y: auto;
		overscroll-behavior: contain;
		padding: 0.35rem 1.25rem 1rem;
		background: var(--bg-elev);
		border-block-end: 1px solid var(--border);
		box-shadow: 0 18px 40px rgba(0, 0, 0, 0.3);
		z-index: 100;
	}

	body.nav-open .nav__menu {
		display: flex;
	}

	.nav__list {
		display: flex;
	}

	/* Every row: full width, 1rem text, and tall enough to tap without aiming. */
	.nav__list a,
	.nav__menu .mega-cat__btn {
		display: flex;
		inline-size: 100%;
		align-items: center;
		gap: 0.7rem;
		padding: 0.9rem 0.25rem;
		font-size: 1rem;
		font-weight: 600;
		border-radius: 0;
		text-align: start;
	}

	/* Separators between rows, never above the first one. */
	.nav__list > li + li,
	.nav__menu > * + * {
		border-block-start: 1px solid var(--border);
	}

	.nav__menu .mega-cat__btn-arrow {
		margin-inline-start: auto;
	}

	/* The category panel is an accordion INSIDE the drawer here, not a floating
	   dropdown with a second backdrop behind it. */
	.nav__menu .mega-cat__panel {
		position: static;
		inline-size: auto;
		max-height: none;
		overflow: visible;
		padding: 0;
		background: none;
		border: 0;
		border-radius: 0;
		box-shadow: none;
	}

	.nav__menu .mega-cat__panel a {
		display: block;
		padding: 0.7rem 0.25rem;
		font-size: 0.9375rem;
	}

	.nav__menu .mega-cat__backdrop {
		display: none !important;
	}

	.site-header__inner {
		padding-inline: 0.75rem;
	}

	/* The theme toggle is deliberately NOT hidden here. It used to be, when one
	   palette was the default and the other a nicety; now that a press is the
	   only way to reach two of the three, removing it on phones would strand the
	   smaller-screen majority of this site's traffic. It survives icon-only and a
	   little smaller — see the toggle rules further down. */

	.site-header__cart {
		margin-inline-start: auto; /* keeps the cart pinned to the far left */
	}

	/*
	 * Phones: the number stays — it is the one header item the owner called
	 * mandatory — but the appointment button does not. This row already carries a
	 * contact icon on phones, and it leads to the same page, so a second control
	 * for one destination would only push the row onto another line.
	 */
	.site-header__cta {
		display: none;
	}
}

.theme-toggle-btn {
	background: none;
	border: 0;
	padding: 0;
	cursor: pointer;
	color: var(--text);
	display: inline-flex;
	flex-direction: row; /* Hebrew (RTL): icon on the right */
	align-items: center;
	gap: 0.5rem;
	font-family: var(--font-body);
	transition: color 0.2s var(--ease);
}

.theme-toggle-btn__icon-circle {
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: var(--bg-elev);
	border: 1px solid var(--border);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	transition: border-color 0.2s var(--ease), background-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}

.theme-toggle-btn:hover .theme-toggle-btn__icon-circle {
	border-color: var(--accent);
	box-shadow: 0 0 0 1px var(--accent-subtle), 0 0 14px var(--accent-glow);
}

.theme-toggle-btn__icon {
	font-size: 1.05rem;
	line-height: 1;
	display: inline-flex;
}

/* Only the mode you will switch to is shown, and the cycle is
   aurora → forge → singularity → aurora (`assets/js/main.js` walks this exact
   order, and its first entry is the default). Each icon and label therefore
   names a destination:

     aurora (bright)     →  forge  🌅 "חמים"
     forge (warm)        →  singularity 🌙 "כהה"
     singularity (dark)  →  aurora ☀️ "בהיר"

   Every arm of this is now stated as an explicit `[data-theme="…"]`, with no
   `:root:not(...)` anywhere. The old rule spelled the default out as
   `:root:not([data-theme="forge"]):not([data-theme="aurora"])`, which meant
   "the palette a page with no attribute resolves" — and that palette is aurora
   now, not singularity, so the same selector would silently hand an unpainted
   page the wrong button (and, worse, hand `[data-theme="singularity"]` the
   wrong one too, since singularity is what it was really describing).

   THE NIGHT ARM WAS ONE PALETTE BEHIND (fixed 2026-10-02). Valery: "משחור
   לחמים רושם חמים וגם מחמים לביהר רושם חמים" — the button read "חמים" in two
   consecutive palettes. `[data-theme="singularity"]` was paired with the
   FORGE icon and label, which is the palette *before* it in the cycle, so
   pressing out of the night palette promised the warm one and then delivered
   the bright one — and the bright palette then promised warm again, which is
   the "חמים" twice he saw. The pair is named by where a press GOES, so the
   night arm belongs to `--aurora`. The three arms below are the cycle above,
   shifted by one, and that is the whole trick: check them against the comment
   block, not against each other.

   The unpainted page is not left out by that: `main.js`'s `getActiveTheme()`
   falls back to the first entry of its cycle, which is aurora, and this rule
   set with `data-theme="aurora"` is therefore already the right one for it.
   The unpainted page is in every arm below, next to `[data-theme="aurora"]`,
   because that is the palette it resolves: without JavaScript nothing ever
   writes the attribute, and the control would otherwise be an empty circle
   (the icon and the label are hidden until one of these rules shows them).
   The pre-paint script in header.php means this only ever applies to a
   visitor with scripts off, who cannot press the control anyway — but a blank
   button is a visible defect and a wrong icon is not. */
.theme-toggle-btn__icon,
.theme-toggle-btn__label {
	display: none;
}

[data-theme="singularity"] .theme-toggle-btn__icon--aurora,
[data-theme="forge"] .theme-toggle-btn__icon--singularity,
[data-theme="aurora"] .theme-toggle-btn__icon--forge,
:root:not([data-theme]) .theme-toggle-btn__icon--forge {
	display: inline-flex;
}

[data-theme="singularity"] .theme-toggle-btn__label--aurora,
[data-theme="forge"] .theme-toggle-btn__label--singularity,
[data-theme="aurora"] .theme-toggle-btn__label--forge,
:root:not([data-theme]) .theme-toggle-btn__label--forge {
	display: inline;
}

/* Phones get the icon and nothing else. The header row is nowrap and the
   toggle is the only control that can reach two of the three palettes, so it
   cannot be removed the way it used to be — the label is what gives way.
   `!important` because the rules above select with two classes. */
@media (max-width: 767px) {
	.theme-toggle-btn__label {
		display: none !important;
	}

	.theme-toggle-btn__icon-circle {
		width: 34px;
		height: 34px;
	}
}

.theme-toggle-btn__label {
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--text-dim);
	white-space: nowrap;
	transition: color 0.2s var(--ease);
}

.theme-toggle-btn:hover .theme-toggle-btn__label {
	color: var(--text);
}

/* Visibility toggling by palette.

   Two families are switched here and they are no longer the same shape, so
   they are no longer one rule set.

   TEXT (craft-mode, cinematic-hero__kicker) is two registers: the night copy
   and the day copy. Valery's rule: BLACK = NIGHT/singularity, WHITE = DAY.
   There are two light-backed palettes and they share the day copy, so the
   registers are stated as "the warm or bright palette" and "the night one"
   rather than by naming one light palette.

   THE DAY COPY IS WHAT AN UNPAINTED PAGE GETS, and that is the change of
   2026-10. This block used to spell the night register as
   `:root:not([data-theme="forge"]):not([data-theme="aurora"])` — "anything
   that is not one of the two light palettes", which is the default palette —
   and it was written with the reasoning above, that an unpainted page resolves
   singularity's tokens and so must resolve the night copy. The tokens an
   unpainted page resolves are aurora's now, so the same selector would print
   black copy on a white page. Singularity is named, and the unpainted root is
   added to the day arm, where it belongs.

   BRAND ART is three registers, because it wears its palette in the coolant
   rather than in a tint. It is switched in its own block below.

   Images only. The ambient videos are NOT switched here any more: hiding a
   second <video> with display:none still downloaded and decoded it, so each
   palette-aware loop is now a single element whose src is chosen by
   assets/js/palette-media.js (see inc/template-tags.php). */
[data-theme="singularity"] .craft-mode--light,
[data-theme="singularity"] .cinematic-hero__kicker--light {
	display: none !important;
}

[data-theme="singularity"] .craft-mode--dark,
[data-theme="singularity"] .cinematic-hero__kicker--dark {
	display: inline-block;
}

[data-theme="forge"] .craft-mode--dark,
[data-theme="forge"] .cinematic-hero__kicker--dark,
[data-theme="aurora"] .craft-mode--dark,
[data-theme="aurora"] .cinematic-hero__kicker--dark,
:root:not([data-theme]) .craft-mode--dark,
:root:not([data-theme]) .cinematic-hero__kicker--dark {
	display: none !important;
}

[data-theme="forge"] .craft-mode--light,
[data-theme="forge"] .cinematic-hero__kicker--light,
[data-theme="aurora"] .craft-mode--light,
[data-theme="aurora"] .cinematic-hero__kicker--light,
:root:not([data-theme]) .craft-mode--light,
:root:not([data-theme]) .cinematic-hero__kicker--light {
	display: inline-block;
}

/* Brand art: one file per palette, switched by name.

   The wordmark, the brand icon and the favicon each draw the coolant in the
   palette's own accent — garnet for singularity, light blue for forge, green
   for aurora — so the file has to change when the palette does, and a
   two-register swap cannot say that. Until this block existed both
   light-backed palettes shared one file, which meant the art was wrong in one
   of them by construction.

   Every rule here is !important and the blanket hide is stated on the bare
   class, so the winner is decided by specificity and never by source order:
   (0,3,0) for the unpainted root, (0,2,0) for a named palette, (0,1,0) for
   the hide. The !important on the *show* rules is what makes that work — the
   old block instead leaned on the hide and the show having opposite
   specificity, which does not survive being extended to three.

   THE UNPAINTED ROOT SHOWS THE GREEN ART SINCE 2026-10, and it used to show
   the garnet one, because it used to be spelled `:root:not(forge):not(aurora)`
   and that is a way of writing "the default palette" rather than a way of
   writing "singularity". Now that the default is aurora, the same selector
   would put the GARNET wordmark on a bright green page — visible, wrong, and
   hard to explain to whoever sees it. Singularity is therefore named
   explicitly, and the attribute-less root is handled by its own arm. */
.site-brand__icon--light,
.site-brand__icon--dark,
.site-brand__icon--aurora,
.cinematic-hero__logo--light,
.cinematic-hero__logo--dark,
.cinematic-hero__logo--aurora {
	display: none !important;
}

[data-theme="forge"] .site-brand__icon--light,
[data-theme="forge"] .cinematic-hero__logo--light {
	display: inline-block !important;
}

[data-theme="aurora"] .site-brand__icon--aurora,
[data-theme="aurora"] .cinematic-hero__logo--aurora,
:root:not([data-theme]) .site-brand__icon--aurora,
:root:not([data-theme]) .cinematic-hero__logo--aurora {
	display: inline-block !important;
}

[data-theme="singularity"] .site-brand__icon--dark,
[data-theme="singularity"] .cinematic-hero__logo--dark {
	display: inline-block !important;
}

/* ---------- Buttons ---------- */
.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	padding: 0.75rem 1.6rem;
	border-radius: var(--radius-sm);
	font-weight: 600;
	font-family: var(--font-body);
	cursor: pointer;
	border: 1px solid transparent;
	letter-spacing: 0.02em;
	transition: transform 0.15s var(--ease), background 0.15s var(--ease), border-color 0.15s var(--ease), box-shadow 0.15s var(--ease);
}

.btn:hover {
	text-decoration: none;
	transform: translateY(-2px);
}

.btn--primary {
	background: var(--accent);
	color: var(--on-accent);
	box-shadow: 0 4px 16px var(--accent-glow);
}

.btn--primary:hover {
	background: var(--accent-2);
	box-shadow: 0 6px 20px var(--accent-glow);
}

.btn--ghost {
	background: var(--surface);
	color: var(--text);
	border-color: var(--border);
}

.btn--ghost:hover {
	border-color: var(--accent);
	color: var(--accent-text);
}

.btn--sm {
	padding: 0.45rem 1rem;
	font-size: 0.875rem;
}

/* ---------- Cinematic Hero (Ninebend / Concept Style) ---------- */
.cinematic-hero {
	position: relative;
	min-height: 82vh;
	display: grid;
	place-items: end start;
	padding: 5rem 1.25rem 4rem;
	overflow: hidden;
	color: var(--text-bright);
	text-align: start;
}

.cinematic-hero__media {
	position: absolute;
	inset: 0;
	z-index: 0;
	overflow: hidden;
}

.cinematic-hero__video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	filter: brightness(0.72) contrast(1.08);
	transform: scale(1.02);
	transition: opacity 0.5s var(--ease);
}

/* The light register, which is the one an unpainted page resolves: both
   non-dark palettes are light-backed, so they share one video register — the
   clip is shown less crushed than it is on the night palette, where the page's
   own darkness would otherwise swallow it. The value in the base rule above is
   the night one, and singularity is the palette that keeps it by not being in
   this list. */
[data-theme="forge"] .cinematic-hero__video,
[data-theme="aurora"] .cinematic-hero__video,
:root:not([data-theme]) .cinematic-hero__video {
	filter: brightness(0.85) contrast(1.02);
}

.cinematic-hero__scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(
		180deg,
		color-mix(in srgb, var(--bg) 35%, transparent) 0%,
		color-mix(in srgb, var(--bg) 65%, transparent) 60%,
		var(--bg) 100%
	);
	pointer-events: none;
}

.cinematic-hero__inner {
	position: relative;
	z-index: 2;
	max-width: 820px;
	margin-inline: 0;
}

.cinematic-hero__kicker {
	margin: 0 0 1rem;
	font-family: var(--font-body);
	font-size: 0.85rem;
	letter-spacing: 0.06em;
	color: var(--accent-text);
	font-weight: 600;
}

.cinematic-hero__title {
	margin-block-end: 0.5rem;
}

.cinematic-hero__logo {
	display: block;
	max-width: min(380px, 85vw);
	height: auto;
	object-fit: contain;
	filter: drop-shadow(0 4px 20px rgba(0, 0, 0, 0.45));
}

.cinematic-hero__subtitle {
	color: var(--text);
	font-size: clamp(1.1rem, 2.2vw, 1.35rem);
	line-height: 1.6;
	margin-block-end: 1.75rem;
	text-shadow: 0 1px 12px rgba(0, 0, 0, 0.7);
}

.cinematic-hero__perks {
	list-style: none;
	margin: 0 0 2.25rem;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 1rem 1.75rem;
	justify-content: flex-start;
	max-width: 780px;
}

.cinematic-hero__perks li {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-size: 0.95rem;
	color: var(--text);
	background: color-mix(in srgb, var(--bg-elev) 75%, transparent);
	padding: 0.4rem 0.9rem;
	border-radius: 999px;
	border: 1px solid var(--border);
	backdrop-filter: blur(8px);
}

.cinematic-hero__perks li::before {
	content: "◈";
	color: var(--accent-text);
	font-size: 0.85rem;
}

[data-theme="forge"] .cinematic-hero__perks li::before,
[data-theme="aurora"] .cinematic-hero__perks li::before,
:root:not([data-theme]) .cinematic-hero__perks li::before {
	content: "◇";
}

.cinematic-hero__actions {
	display: flex;
	gap: 1rem;
	justify-content: flex-start;
	flex-wrap: wrap;
}

/* ---------- Concept Showcase (Watercooling / Atelier Diptych) ---------- */
.concept-showcase {
	border-block: 1px solid var(--border);
	background: var(--bg-elev);
}

.concept-showcase__head {
	text-align: center;
	max-width: 780px;
	margin-inline: auto;
	margin-block-end: 3rem;
}

.concept-showcase__lede {
	color: var(--text-dim);
	font-size: 1.1rem;
	line-height: 1.7;
	margin-top: 0.75rem;
}

.concept-diptych {
	display: grid;
	grid-template-columns: 1fr;
	gap: 2rem;
	margin-block-end: 2.5rem;
}

@media (min-width: 768px) {
	.concept-diptych {
		grid-template-columns: 1fr 1fr;
	}
}

.concept-diptych__item {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	overflow: hidden;
	display: flex;
	flex-direction: column;
	transition: transform 0.25s var(--ease), border-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
}

.concept-diptych__item:hover {
	transform: translateY(-4px);
	border-color: var(--accent);
	box-shadow: 0 12px 32px var(--accent-subtle);
}

.concept-diptych__media {
	position: relative;
	aspect-ratio: 16 / 10;
	background: var(--surface-2);
	overflow: hidden;
}

.concept-video,
.concept-still {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.concept-diptych__caption {
	padding: 1.5rem;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
}

.concept-diptych__title {
	margin: 0;
	font-size: 1.25rem;
	font-weight: 700;
	color: var(--text-bright);
}

.concept-diptych__text {
	margin: 0;
	color: var(--text-dim);
	font-size: 0.95rem;
	line-height: 1.6;
}

.concept-specs {
	display: flex;
	justify-content: center;
	padding-top: 1rem;
}

.concept-specs__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	justify-content: center;
}

.concept-specs__tag {
	display: inline-block;
	padding: 0.4rem 1rem;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: 999px;
	font-family: var(--font-mono);
	font-size: 0.78rem;
	letter-spacing: 0.06em;
	color: var(--text);
	text-transform: uppercase;
}

/* ---------- Sections ---------- */
.section {
	padding-block: 4rem;
}

.section--alt {
	background: var(--bg-elev);
}

.section-head {
	margin-block-end: 2rem;
}

.section-head__eyebrow {
	color: var(--accent-text);
	font-weight: 700;
	font-size: 0.85rem;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	margin-block-end: 0.35em;
}

.section-head__title {
	font-size: clamp(1.5rem, 3vw, 2.25rem);
	font-weight: 800;
}

/* ---------- Cards ---------- */
.card-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
	gap: 1.25rem;
}

.card-grid--3 {
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

.product-card,
.service-card {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	overflow: hidden;
	display: flex;
	flex-direction: column;
	transition: transform 0.2s var(--ease), border-color 0.2s var(--ease);
}

.product-card:hover,
.service-card:hover {
	transform: translateY(-3px);
	border-color: var(--accent);
}

.product-card__media {
	aspect-ratio: 1;
	background: var(--surface-2);
	display: grid;
	place-items: center;
	overflow: hidden;
}

.product-card__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.product-card__placeholder {
	color: var(--text-dim);
	padding: 1rem;
	text-align: center;
}

.product-card__body {
	padding: 1rem;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	flex: 1;
}

.product-card__title {
	font-size: 1rem;
	font-weight: 700;
	margin: 0;
}

.product-card__price {
	color: var(--accent-text);
	font-weight: 700;
}

.product-card__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin-block-start: auto;
}

.service-card {
	padding: 1.5rem;
}

.service-card__title {
	font-size: 1.15rem;
	font-weight: 800;
}

.service-card__text {
	color: var(--text-dim);
	margin-block-end: 1rem;
}

/* ---------- Page / posts ---------- */
/* Scoped to the wrapper div inside <main> — WordPress also adds a "page"
   class to <body> on static pages, which would pad the body and push the
   header down. Never let that happen. */
.site-main > .page {
	padding-block: 3rem;
}

.page__inner--narrow {
	max-width: 760px;
}

.page-content__title,
.post-single__title,
.archive-head__title {
	font-size: clamp(1.75rem, 4vw, 2.5rem);
	font-weight: 800;
}

.post-single__date {
	color: var(--text-dim);
	font-size: 0.875rem;
}

.page-content__body,
.post-single__body {
	line-height: 1.8;
}

.post-list {
	display: grid;
	gap: 1.5rem;
}

.post {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 1.25rem;
}

.post__title {
	font-size: 1.25rem;
	margin: 0 0 0.5em;
}

.post__excerpt {
	color: var(--text-dim);
}

/* ---------- WooCommerce base & Square Product Cards ---------- */
.woocommerce .products {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	/* Fluid card width (~250px min). One consistent size for the whole shop:
	   5 columns on ultra-wide, 4 on desktop, 3 on tablet, 2 on mobile.
	   Valery 2026-08-30: the fixed 4×377px cards were too big. */
	grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
	gap: 1.25rem;
}

/* Square product card — media frame + sale badge */
.product-card__media-wrap {
	position: relative;
}

.product-card__media {
	position: relative;
}

.product-card__media img {
	transition: transform 0.35s var(--ease);
}

.product-card:hover .product-card__media img {
	transform: scale(1.05);
}

.product-card__placeholder {
	color: var(--text-dim);
	padding: 1rem;
	text-align: center;
}

/* Sale badge (also used by WooCommerce sale flash on product pages). */
.product-card__badge,
.woocommerce span.onsale {
	position: absolute;
	inset-block-start: 0.6rem;
	inset-inline-start: 0.6rem;
	background: linear-gradient(135deg, var(--accent), var(--accent-2));
	color: var(--on-accent);
	font-size: 0.75rem;
	font-weight: 800;
	padding: 0.25rem 0.65rem;
	border-radius: 999px;
	letter-spacing: 0.03em;
	z-index: 2;
	box-shadow: 0 2px 8px var(--accent-glow);
}

.product-card__cat {
	font-size: 0.72rem;
	font-weight: 600;
	color: var(--text-dim);
	letter-spacing: 0.04em;
}

.product-card__cat a {
	color: var(--text-dim);
	text-decoration: none;
	transition: color 0.2s;
}

.product-card__cat a:hover {
	color: var(--accent-text);
}

.product-card__title {
	/* Clamp the title to two lines so cards keep equal height. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	min-height: 2.8em;
}

/* The whole card opens the product.

   .product-card__link in the markup is an empty anchor stretched across the
   card, so any click that is not aimed at one of the card's own controls
   navigates instead of dying. Its containing block is the article, which
   matters: the stretched-link trick is normally done with the title
   anchor's ::after, and that would have been clipped away here, because
   .product-card__title carries the overflow: hidden the two-line clamp
   needs and sits between the pseudo-element and the card. */
.product-card {
	position: relative;
}

.product-card__link {
	position: absolute;
	inset: 0;
	z-index: 1;
}

/* Its own controls sit above the stretched link or it would swallow them.
   The category link is kept clickable on purpose — it still goes to the
   category, which is what it has always done; move it in with the rest of
   the card if that is ever not wanted. */
.product-card__cat a,
.product-card__view,
.product-card__buy {
	position: relative;
	z-index: 2;
}

/* The sale badge is painted at z-index 2 too, so without this it would be a
   dead patch on a card whose whole surface is now a link. It is decoration:
   it takes no clicks, and the overlay underneath receives them instead. */
.product-card__badge {
	pointer-events: none;
}

.product-card__actions {
	margin-block-start: auto;
}

/* Category Filter Bar */
.shop-filter-bar {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	flex-wrap: wrap;
	margin-block-end: 1.5rem;
	padding: 0.75rem 1rem;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
}

.shop-filter-bar__item {
	padding: 0.4rem 0.85rem;
	border-radius: 999px;
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--text-dim);
	background: var(--bg-elev);
	border: 1px solid var(--border);
	transition: all 0.2s;
}

.shop-filter-bar__item:hover,
.shop-filter-bar__item.is-active {
	color: var(--on-accent);
	background: var(--accent);
	border-color: var(--accent);
	text-decoration: none;
	box-shadow: 0 2px 8px var(--accent-glow);
}

.woocommerce .price {
	color: var(--accent-text);
	font-weight: 700;
}

.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.7rem 1.25rem;
	border-radius: var(--radius-sm);
	background: var(--accent);
	color: var(--on-accent);
	font-weight: 600;
	border: 0;
	cursor: pointer;
}

.woocommerce a.button:hover {
	background: var(--accent-2);
	text-decoration: none;
}

.woocommerce-message,
.woocommerce-info,
.woocommerce-error {
	border-radius: var(--radius);
	padding: 1rem 1.25rem;
	margin-block-end: 1.5rem;
	list-style: none;
}

.woocommerce-message { background: color-mix(in srgb, var(--ok) 12%, transparent); border: 1px solid var(--ok-text); }
.woocommerce-info    { background: color-mix(in srgb, var(--accent) 10%, transparent); border: 1px solid var(--accent); }
.woocommerce-error   { background: color-mix(in srgb, var(--danger) 12%, transparent); border: 1px solid var(--danger); }

/* ---------- Footer ---------- */
.site-footer {
	border-block-start: 1px solid var(--border);
	/* The footer may darken only as far as the palette's own floor. The old
	   `color-mix(--bg-elev 80%, #0c0e12)` end took the light palette down to
	   rgb(199 197 194), where --text-dim (#676058) measures 3.76:1 — every
	   footer line in the lower half failed WCAG 1.4.3 even though the token is
	   correct on every surface in the palette. Ending on --bg keeps the same
	   downward direction in both palettes: --text-dim reads 5.08:1 in forge
	   and 5.82:1 in singularity. Fixed 2026-09-15. */
	background: linear-gradient(180deg, var(--bg-elev) 0%, var(--bg) 100%);
	padding-block: 3.5rem 2rem;
	margin-block-start: 5rem;
	position: relative;
}

.site-footer::before {
	content: '';
	position: absolute;
	inset-block-start: -1px;
	inset-inline: 0;
	height: 1px;
	background: linear-gradient(90deg, transparent 0%, var(--accent) 50%, transparent 100%);
	opacity: 0.6;
}

.site-footer__inner {
	display: flex;
	flex-direction: column;
	gap: 2.75rem;
}

/* Partner brands showcase — prominent luxury brand pedestals for hardware giants */
.site-footer__brands {
	background: linear-gradient(180deg, rgba(28, 32, 42, 0.85) 0%, rgba(14, 16, 22, 0.95) 100%);
	border: 1px solid rgba(255, 255, 255, 0.09);
	box-shadow: 0 16px 40px rgba(0, 0, 0, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.1);
	border-radius: calc(var(--radius) * 1.3);
	padding: 2.2rem 1.8rem;
	display: flex;
	flex-direction: column;
	gap: 1.8rem;
	position: relative;
	overflow: hidden;
}

.site-footer__brands::before {
	content: '';
	position: absolute;
	top: -50px;
	left: 50%;
	transform: translateX(-50%);
	width: 400px;
	height: 100px;
	background: radial-gradient(circle, var(--accent) 0%, transparent 70%);
	opacity: 0.12;
	pointer-events: none;
}

.site-footer__brands-header {
	text-align: center;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.45rem;
}

.site-footer__brands-title {
	margin: 0;
	color: #ffffff;
	font-size: 1.45rem;
	font-weight: 800;
	letter-spacing: -0.01em;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.75rem;
}

.site-footer__brands-title::before,
.site-footer__brands-title::after {
	content: '';
	width: 28px;
	height: 2px;
	background: linear-gradient(90deg, transparent, var(--accent));
	opacity: 0.8;
}

.site-footer__brands-title::after {
	background: linear-gradient(90deg, var(--accent), transparent);
}

.site-footer__brands-subtitle {
	margin: 0;
	color: rgba(255, 255, 255, 0.62);
	font-size: 0.92rem;
	font-weight: 400;
	max-width: 600px;
}

.site-footer__brands-list {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 1rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

@media (min-width: 600px) {
	.site-footer__brands-list {
		grid-template-columns: repeat(4, 1fr);
		gap: 1.25rem;
	}
}

@media (min-width: 1024px) {
	.site-footer__brands {
		padding: 2.5rem 3rem;
	}
	.site-footer__brands-title {
		font-size: 1.7rem;
	}
	.site-footer__brands-list {
		grid-template-columns: repeat(4, 1fr);
		gap: 1.5rem;
	}
}

.site-footer__brand-card {
	background: rgba(255, 255, 255, 0.03);
	border: 1px solid rgba(255, 255, 255, 0.07);
	border-radius: var(--radius);
	padding: 1rem 1.25rem;
	height: 104px;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: transform var(--ease) 0.25s, border-color var(--ease) 0.25s, background-color var(--ease) 0.25s, box-shadow var(--ease) 0.25s;
	position: relative;
	backdrop-filter: blur(8px);
}

.site-footer__brand-card:hover {
	transform: translateY(-4px);
	background: rgba(255, 255, 255, 0.07);
	border-color: rgba(255, 255, 255, 0.22);
	box-shadow: 0 12px 24px rgba(0, 0, 0, 0.5), 0 0 20px rgba(var(--accent-rgb, 255, 77, 0), 0.15);
}

/* Logos are authored white-on-transparency; -white.svg files carry an explicit
   #ffffff fill because an SVG loaded through <img> cannot inherit currentColor. */
.site-footer__brand-card img {
	max-height: 64px;
	width: auto;
	max-width: 100%;
	object-fit: contain;
	opacity: 0.92;
	filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.6));
	transition: opacity var(--ease) 0.25s, transform var(--ease) 0.25s, filter var(--ease) 0.25s;
}

.site-footer__brand-card:hover img {
	opacity: 1;
	transform: scale(1.05);
	filter: drop-shadow(0 0 16px rgba(255, 255, 255, 0.5));
}

@media (min-width: 1024px) {
	.site-footer__brand-card {
		height: 118px;
	}
	.site-footer__brand-card img {
		max-height: 74px;
	}
}

/* Three-column content area: two nav columns + socials/contact. */
.site-footer__grid {
	display: grid;
	gap: 2.25rem;
	grid-template-columns: 1fr;
}

@media (min-width: 768px) {
	.site-footer__grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1024px) {
	.site-footer__grid {
		grid-template-columns: 1.1fr 1.1fr 1.3fr;
		gap: 3rem;
	}
}

.site-footer__col,
.site-footer__connect {
	display: flex;
	flex-direction: column;
}

.site-footer__col-title {
	margin: 0 0 1.25rem;
	color: var(--text);
	font-size: 1.05rem;
	font-weight: 800;
	letter-spacing: -0.01em;
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	padding-block-end: 0.65rem;
	border-block-end: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
	position: relative;
}

.site-footer__col-title::after {
	content: '';
	position: absolute;
	inset-block-end: -1px;
	inset-inline-start: 0;
	width: 32px;
	height: 2px;
	background: var(--accent);
	border-radius: 999px;
}

.site-footer__col-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	color: var(--accent-text);
	opacity: 0.9;
}

.site-footer__col ul {
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.site-footer__col a {
	color: var(--text-dim);
	text-decoration: none;
	font-size: 0.95rem;
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	transition: color var(--ease) 0.15s, transform var(--ease) 0.15s;
}

.site-footer__col a::before {
	content: '‹';
	font-size: 1rem;
	line-height: 1;
	opacity: 0;
	transform: translateX(4px);
	transition: opacity var(--ease) 0.15s, transform var(--ease) 0.15s, color var(--ease) 0.15s;
	color: var(--accent-text);
}

.site-footer__col a:hover,
.site-footer__col a:focus-visible {
	color: var(--text);
	transform: translateX(-4px);
}

.site-footer__col a:hover::before,
.site-footer__col a:focus-visible::before {
	opacity: 1;
	transform: translateX(0);
}

/* Social icons — circular ghost buttons with cyber glow hover. */
.site-footer__socials {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	margin: 0 0 1.5rem;
	padding: 0;
	list-style: none;
}

.site-footer__socials a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border: 1px solid var(--border);
	border-radius: 12px;
	background: var(--surface);
	color: var(--text-dim);
	box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
	transition: color var(--ease) 0.2s, border-color var(--ease) 0.2s, background var(--ease) 0.2s, transform var(--ease) 0.2s, box-shadow var(--ease) 0.2s;
}

.site-footer__socials a:hover,
.site-footer__socials a:focus-visible {
	color: var(--on-accent);
	border-color: var(--accent);
	background: var(--accent);
	transform: translateY(-3px);
	box-shadow: 0 6px 16px var(--accent-subtle);
}

.site-footer__socials svg {
	display: block;
}

/* Contact block card. */
.site-footer__contact {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 1.15rem 1.25rem;
	display: flex;
	flex-direction: column;
	gap: 0.85rem;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}

.site-footer__contact-item {
	display: flex;
	align-items: flex-start;
	gap: 0.65rem;
	color: var(--text-dim);
	font-size: 0.9rem;
	line-height: 1.55;
}

.site-footer__contact-icon {
	color: var(--accent-text);
	flex-shrink: 0;
	margin-block-start: 0.2rem;
}

.site-footer__phone-link {
	color: var(--text);
	text-decoration: none;
	font-weight: 600;
	transition: color var(--ease) 0.15s;
}

.site-footer__phone-link strong {
	color: var(--text-dim);
	font-weight: 500;
}

.site-footer__phone-link span {
	font-family: monospace;
	font-size: 0.95rem;
	letter-spacing: 0.03em;
}

.site-footer__phone-link:hover,
.site-footer__phone-link:focus-visible {
	color: var(--accent-text);
	text-decoration: underline;
}

.site-footer__address strong {
	color: var(--text-dim);
	font-weight: 500;
}

/* Bottom row: brand mark + legal / developer credit. */
.site-footer__bottom {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1.25rem 2rem;
	border-block-start: 1px solid var(--border);
	padding-block-start: 1.75rem;
	margin-block-start: 0.5rem;
}

.site-footer__brand {
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
}

.site-footer__brand .site-brand__name {
	font-size: 1.35rem;
	font-weight: 800;
	color: var(--text);
	letter-spacing: -0.01em;
}

.site-footer__tagline {
	margin: 0;
	color: var(--text-dim);
	font-size: 0.88rem;
	line-height: 1.5;
}

.site-footer__legal {
	margin: 0;
	color: var(--text-dim);
	font-size: 0.875rem;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.4rem;
}

@media (min-width: 640px) {
	.site-footer__legal {
		align-items: flex-end;
		text-align: end;
	}
}

.site-footer__legal p {
	margin: 0;
}

/* Dealer identity: owner + ח.פ + address. Required on the site itself, so it
   sits above the copyright line rather than only inside the policy pages. */
.site-footer__identity {
	display: flex;
	flex-wrap: wrap;
	gap: 0.15rem 0.5rem;
	line-height: 1.5;
}

@media (min-width: 640px) {
	.site-footer__identity {
		justify-content: flex-end;
	}
}

.site-footer__identity-owner {
	color: var(--text);
	font-weight: 600;
}

.site-footer__identity-no {
	color: var(--text-dim);
	white-space: nowrap;
}

.site-footer__identity-address {
	color: var(--text-dim);
	font-size: 0.8rem;
	line-height: 1.5;
}

.site-footer__credit {
	display: inline-flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.08rem;
	background: color-mix(in srgb, var(--accent) 10%, transparent);
	padding: 0.42rem 0.85rem;
	border-radius: var(--radius-sm);
	border: 1px solid color-mix(in srgb, var(--accent) 24%, transparent);
	font-size: 0.82rem;
	color: var(--text-dim);
	text-decoration: none;
	cursor: pointer;
	transition: color var(--ease) 0.15s, background var(--ease) 0.15s, border-color var(--ease) 0.15s, transform var(--ease) 0.15s;
}

.site-footer__credit:hover,
.site-footer__credit:focus-visible {
	color: var(--text);
	background: color-mix(in srgb, var(--accent) 16%, transparent);
	border-color: color-mix(in srgb, var(--accent) 40%, transparent);
	text-decoration: none;
	transform: translateY(-1px);
}

/* The chip paints a 10% --accent tint over the footer gradient. On that tint
   --text-dim falls to 4.45:1 in forge and 4.25:1 in singularity, so the two
   meta lines use --text, which clears 11:1 in both palettes. */
.site-footer__credit-label {
	font-size: 0.72rem;
	color: var(--text);
}

.site-footer__credit-name {
	color: var(--accent-text);
	font-weight: 700;
	line-height: 1.3;
}

.site-footer__credit:hover .site-footer__credit-name,
.site-footer__credit:focus-visible .site-footer__credit-name {
	color: var(--text);
}

.site-footer__credit-url {
	font-family: var(--font-mono);
	font-size: 0.72rem;
	color: var(--text);
	word-break: break-all;
	line-height: 1.3;
}

.site-footer__credit:hover .site-footer__credit-url,
.site-footer__credit:focus-visible .site-footer__credit-url {
	color: var(--accent-text);
}

/* ---------- Sticky Bottom Legal Bar ---------- */
/* Reserve room at the very bottom so the fixed legal bar never covers the
   footer brand row (icon, name, tagline, © credit). The plain `body` rule is
   overridden by WP's global-styles-inline-css (`body { padding: 0px; }`), so
   we raise specificity AND give the footer its own bottom margin as a
   self-contained guarantee that works on every page. */
html body {
	padding-block-end: var(--legal-bar-h);
}

.site-footer {
	margin-block-end: var(--legal-bar-h);
}

/* ---------- Sticky legal bar ----------
   The bar is fixed to the bottom edge. To keep the footer readable we push
   the whole page up by the bar's height (--legal-bar-h), and consent.js
   re-publishes the measured height so the cookie banner sits just above it. */
.sticky-legal-bar {
	position: fixed;
	inset-block-end: 0;
	inset-inline: 0;
	z-index: 45;
	background: color-mix(in srgb, var(--bg-elev) 88%, transparent);
	backdrop-filter: blur(12px);
	-webkit-backdrop-filter: blur(12px);
	border-block-start: 1px solid var(--border);
	box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.25);
	font-size: 0.82rem;
	line-height: 1.2;
}

.sticky-legal-bar__inner {
	max-width: var(--max-w);
	margin-inline: auto;
	padding: 0.55rem 1rem;
	display: flex;
	align-items: center;
	justify-content: center;
}

.sticky-legal-bar__nav {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
	gap: 0.4rem 0.65rem;
	text-align: center;
}

.sticky-legal-bar__link {
	color: var(--text-dim);
	text-decoration: none;
	font-weight: 500;
	padding: 0.2rem 0.35rem;
	border-radius: var(--radius-sm);
	transition: color var(--ease) 0.15s, background var(--ease) 0.15s;
	white-space: nowrap;
}

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

.sticky-legal-bar__sep {
	color: var(--border);
	font-size: 0.65rem;
	user-select: none;
}

/* Reopen trigger for the cookie banner. Styled as a link so the bar keeps
   one visual language, but it is a real <button> for keyboard/screen-reader
   semantics. */
.sticky-legal-bar__btn {
	font-family: inherit;
	background: none;
	border: 0;
	cursor: pointer;
}

@media (max-width: 600px) {
	/* The sticky legal bar wraps to two rows on phones. CSS-only fallback for
	   the first paint; consent.js replaces this with the measured height. */
	:root {
		--legal-bar-h: 5.5rem;
	}

	.sticky-legal-bar__inner {
		padding: 0.45rem 0.5rem;
	}

	.sticky-legal-bar__nav {
		gap: 0.25rem 0.45rem;
	}

	.sticky-legal-bar__link {
		font-size: 0.76rem;
		padding: 0.15rem 0.25rem;
	}
}

/* ---------- Responsive (≥ 768px) ---------- */
@media (min-width: 768px) {
	/*
	 * `.nav` is NOT hidden here any more. Its base rule is `display: contents`, so
	 * the wrapper leaves the layout and its two children take part directly: the
	 * toggle stays hidden and the menu shows the categories accordion in the row.
	 * Hiding the wrapper would also hide the accordion, which now lives inside it
	 * so a phone can open it from the hamburger.
	 */

	.site-footer__grid {
		grid-template-columns: 1.2fr 1.2fr 1fr;
	}
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
	* {
		animation: none !important;
		transition: none !important;
	}

	html {
		scroll-behavior: auto;
	}

	/* Scroll-reveal must never hide content for reduced-motion users. */
	html.reveal-js [data-reveal] {
		opacity: 1 !important;
		transform: none !important;
	}
}
/* ---------- Category cards (landing + home) ---------- */
.cat-card {
        display: block;
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius);
        overflow: hidden;
        text-decoration: none;
        color: var(--text);
        transition: transform var(--ease) 0.2s, border-color var(--ease) 0.2s;
}

.cat-card:hover {
        transform: translateY(-4px);
        border-color: var(--accent);
}

.cat-card__img {
        width: 100%;
        aspect-ratio: 16 / 10;
        object-fit: cover;
        display: block;
        background: var(--bg-elev);
}

.cat-card__body {
        padding: 1rem 1.1rem 1.2rem;
}

.cat-card__title {
        margin: 0 0 0.3rem;
        font-size: 1.15rem;
        font-weight: 700;
}

.cat-card__text {
        margin: 0;
        color: var(--text-dim);
        font-size: 0.92rem;
}

/* The home page shows five catalog cards, one per machine type. Two numbers
   differ from the landing pages' cards, and both are deliberate: three columns
   on a desktop screen so five cards read as 3 + 2 instead of four cramped ones
   plus an orphan, and a 4:3 picture frame because the shop photographs its own
   builds nearly square — a 16:10 window would cut the top and bottom off every
   tower, while 4:3 trims a little of the sides. */
.home-catalog {
        grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

@media (min-width: 1100px) {
        .home-catalog {
                grid-template-columns: repeat(3, 1fr);
        }
}

.home-catalog .cat-card__img {
        aspect-ratio: 4 / 3;
}

/* ---------- Page lede + prose ---------- */
.page-content__body--lede {
        color: var(--text-dim);
        font-size: 1.05rem;
        max-width: 720px;
}

.page-content__body--prose {
        max-width: 720px;
        line-height: 1.7;
}

/* ---------- Builder disclaimer (3D is schematic, not a real render) ----------
 * Sits directly under the builder lede. Deliberately quiet — a bordered note,
 * not an alert — so it reads as an honest heads-up rather than an error. */
.builder-note {
	max-width: 720px;
	margin: 0 0 1.5rem;
	padding: 0.85rem 1.1rem;
	background: var(--surface-2);
	border: 1px solid var(--border);
	border-inline-start: 3px solid var(--accent);
	border-radius: var(--radius-sm);
}

.builder-note__title {
	margin: 0 0 0.3rem;
	color: var(--text);
	font-size: 0.9rem;
	font-weight: 700;
}

.builder-note__text {
	margin: 0;
	color: var(--text-dim);
	font-size: 0.86rem;
	line-height: 1.6;
}

/* ---------- Scroll reveal (landing-page feel) ----------
 * Elements hide only after JS adds .reveal-js to <html>; without JS
 * everything stays visible. Stagger is per-element via --reveal-delay. */
html.reveal-js [data-reveal] {
	opacity: 0;
	transform: translateY(28px);
	transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
	transition-delay: var(--reveal-delay, 0ms);
	will-change: opacity, transform;
}

html.reveal-js [data-reveal].is-revealed {
	opacity: 1;
	transform: none;
}

/* ---------- Ready-PCs slider ---------- */
.products-slider {
	position: relative;
}

.products-slider__track {
	display: flex;
	gap: 1.25rem;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;
	cursor: grab;
}

.products-slider__track::-webkit-scrollbar {
	display: none;
}

.products-slider__track.is-dragging {
	cursor: grabbing;
	scroll-snap-type: none;
	scroll-behavior: auto;
}

.products-slider__item {
	flex: 0 0 min(78vw, 300px);
	scroll-snap-align: start;
}

.products-slider__item .product-card {
	height: 100%;
}

/* The cards are links end to end now, and in Chromium every anchor and image
   is natively draggable — a native link drag cancels the pointermove stream
   that the drag-to-scroll above depends on, so the carousel would fight the
   cursor. Mouse dragging is the only thing that needs this (touch scrolls
   the track natively), and -webkit-user-drag is the Blink/WebKit property,
   so it is scoped to the track's contents. */
.products-slider__track a,
.products-slider__track img {
	-webkit-user-drag: none;
}

.products-slider__nav {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 2;
	width: 2.5rem;
	height: 2.5rem;
	border-radius: 50%;
	border: 1px solid var(--border);
	background: var(--surface);
	color: var(--text);
	font-size: 1.4rem;
	line-height: 1;
	display: grid;
	place-items: center;
	cursor: pointer;
	box-shadow: 0 4px 14px rgb(0 0 0 / 0.25);
	transition: background 0.2s var(--ease), border-color 0.2s var(--ease), color 0.2s var(--ease);
}

.products-slider__nav:hover {
	background: var(--accent);
	border-color: var(--accent);
	/* Reads the token, not a literal white: on a bright accent a white arrow
	   is invisible, and this is the third of the three rules the note in
	   accessibility.css used to have to correct by hand. */
	color: var(--on-accent);
}

.products-slider__nav[hidden] {
	display: none;
}

.products-slider__nav--prev {
	inset-inline-start: -0.75rem;
}

.products-slider__nav--next {
	inset-inline-end: -0.75rem;
}

/* The band the rail sits in, in the shop.
   template-parts/ready-pcs.php lands under the deals carousel on the shop root
   (2026-10; it used to be a section of the home page). Two things have to
   change there and nothing has to change on a page that uses it as a plain
   `.section`:

   - `.section`'s 4rem of padding above it is wasted, because `.promo-carousel`
     already closes with `margin-block-end: 2.5rem`. Inside the shop the band is
     spaced by that gap and by its own closing padding, which is what separates
     it from the layout below.
   - `.section__inner` caps at `--max-w` (1240px) while `.shop-page__inner` goes
     to `min(96vw, 1920px)`, so the rail would stop short of the carousel above
     it and of the grid beside it and read as a component from another page. In
     the shop it takes the shop's own measure instead. */
.shop-page .ready-pcs-section {
	padding-block: 0 2.5rem;
}

.shop-page .ready-pcs-section > .section__inner {
	max-width: none;
	padding-inline: 0;
}

/* ---------- Instant-buy button ---------- */
.product-card__buy.is-added {
	background: #16a34a;
	border-color: #16a34a;
}

/* ---------- Google Reviews strip ---------- */
.reviews__head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: 1rem;
	margin-block-end: 2rem;
}

.reviews__badge {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.5rem 0.9rem;
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	background: var(--surface);
	font-size: 0.9rem;
	color: var(--text-dim);
}

.reviews__badge-logo {
	flex: none;
}

.reviews__badge-stars {
	color: #fbbc04;
	letter-spacing: 0.08em;
}

.reviews__badge-score {
	color: var(--text);
	font-size: 1.05rem;
}

/* Fixed column counts rather than auto-fit.
   The number that decides whether a review card looks right is not the card
   width but the number of text lines it can hold, so the track has to be
   predictable: at four columns the track is 285px inside --max-w (1240px),
   which is what the 4-line clamp was measured against. auto-fit could hand
   back five narrower columns (240px, the old minmax) and clip the last line
   of every card mid-glyph. */
.card-grid--4 {
	grid-template-columns: 1fr;
}

@media (min-width: 640px) {
	.card-grid--4 {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 980px) {
	.card-grid--4 {
		grid-template-columns: repeat(3, 1fr);
	}
}

@media (min-width: 1240px) {
	.card-grid--4 {
		grid-template-columns: repeat(4, 1fr);
	}
}

/* A review card is a square, not a container sized by whatever the customer
   happened to write. Before this the text ran to full length, so one long
   review set the height of its whole row and the strip read as uneven
   (Valery, 2026-09-20).

   aspect-ratio is a preferred size and align-self keeps the card off the
   row's stretch, so expanding one card grows that card alone instead of
   reshaping its neighbours. Below 640px the strip is a single column, where
   a forced square would be a very large card holding four lines of text, so
   the card is free to hug its clamp instead. */
.review-card {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 1.25rem;
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
	transition: transform 0.2s var(--ease), border-color 0.2s var(--ease);
	align-self: start;
}

@media (min-width: 640px) {
	.review-card {
		aspect-ratio: 1 / 1;
	}
}

.review-card:hover {
	transform: translateY(-3px);
	border-color: var(--accent);
}

/* Expanded by the reader: the clamp is off and the card takes the height the
   review actually needs (the row grows with it, which is what makes an
   expanded card readable instead of a scroll box). */
.review-card.is-open {
	aspect-ratio: auto;
}

.review-card__stars {
	color: #fbbc04;
	letter-spacing: 0.1em;
	font-size: 1rem;
	margin: 0;
}

/* Empty star slots. Google returns halves constantly, so the filler stars
   ship as markup and fade here rather than being dropped — a literal
   ★★★★★ beside a 4.6 is a claim nobody made. */
.stars__off {
	opacity: 0.3;
}

/* The clamp is gated on a class the JS adds, deliberately. Without JS nothing
   is hidden, so a no-JS visitor reads the whole review and is never offered a
   button that was rendered but could not work. */
.review-card.is-clamped .review-card__text {
	display: -webkit-box;
	-webkit-line-clamp: 4;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.review-card__text {
	/* No flex growth: the toggle is shown only when this box was really cut
	   off, and the check compares its clamped height with its full one. A box
	   stretched by flex to fill the card would report the same number in both
	   states, so no review would ever look truncated. */
	font-size: 0.95rem;
	line-height: 1.6;
	margin: 0;
}

/* "Read more" / "Show less". One control, two labels: the browser swaps them
   off the is-open class so the script only toggles one thing. Rendered
   hidden for every card and unhidden by the same code that measures the
   text. */
.review-card__more {
	font: inherit;
	font-size: 0.82rem;
	font-weight: 600;
	line-height: 1.4;
	color: var(--accent-text);
	background: none;
	border: 0;
	padding: 0;
	margin: 0;
	cursor: pointer;
	text-align: start;
	align-self: flex-start;
}

.review-card__more:hover,
.review-card__more:focus-visible {
	text-decoration: underline;
}

.review-card__more-close,
.review-card.is-open .review-card__more-open {
	display: none;
}

.review-card.is-open .review-card__more-close {
	display: inline;
}

.review-card__author {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	border-top: 1px solid var(--border);
	padding-top: 0.75rem;
	/* Pinned to the bottom of the card, so every square ends with the
	   reviewer on the same line whether the review ran to one line or four. */
	margin-block-start: auto;
}

.review-card__avatar {
	display: grid;
	place-items: center;
	width: 2.1rem;
	height: 2.1rem;
	border-radius: 50%;
	background: var(--accent);
	color: var(--on-accent);
	font-weight: 700;
	font-size: 0.9rem;
}

/* Real Google avatar. The accent disc must go first — it is the fallback
   colour and would ring the photo. */
.review-card__avatar--photo {
	background: none;
	object-fit: cover;
	flex: none;
}

.review-card__who {
	display: flex;
	flex-direction: column;
	gap: 0.1rem;
	min-width: 0;
}

.review-card__name {
	font-weight: 600;
	line-height: 1.3;
}

a.review-card__name {
	color: inherit;
	text-decoration: none;
}

/* --accent is a fill, not a foreground: as text it is 3.31:1 on --bg. Any
   rule that writes with it wants --accent-text instead. */
a.review-card__name:hover {
	color: var(--accent-text);
}

.review-card__date {
	font-size: 0.8rem;
	color: var(--text-dim);
}

.reviews__cta {
	margin-block-start: 2rem;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 0.75rem;
}

/* Google requires third-party data providers to be named when the response
   carries an attribution. Usually empty; must not be dropped when it is not. */
.reviews__attribution {
	margin-block-start: 1.25rem;
	text-align: center;
	font-size: 0.8rem;
	color: var(--text-dim);
}

.reviews__attribution a {
	color: inherit;
	text-decoration: underline;
}

/* Five reviews, five columns, one row.
   Google returns at most five, so a four-column grid always left the fifth
   card alone beside three empty slots and the strip read as unfinished
   (Valery, 2026-09-22). The count comes from the markup via --reviews-cards
   because it is data, not a design constant.
   minmax(0, 1fr) rather than 1fr: a 1fr track refuses to shrink below its
   content, so one unbroken word would push a column wider than its share.
   Only from 1240px, where five 224px tracks still hold a readable line — at
   the 3-column breakpoint below it, five in a row would be 170px of card. */
@media (min-width: 1240px) {
	.card-grid--4.reviews__grid--fill {
		grid-template-columns: repeat(var(--reviews-cards, 5), minmax(0, 1fr));
	}

	/* The square is what does not survive the narrower track: a card needs
	   257px for stars, four clamped lines, the toggle and the author row, so a
	   224px square would spill past its own border. Stretching instead keeps
	   every card in the row the same height, and the clamp keeps the tallest
	   one at four lines so that height does not wander with the review text.
	   The author row is pinned with margin-block-start:auto, so it still lands
	   on the same baseline across the row. */
	.reviews__grid--fill .review-card {
		aspect-ratio: auto;
		align-self: stretch;
	}
}

/* Reachable when every review Google returns falls below the star floor, so
   no card survives filtering. An empty grid still occupies its margins and
   reads as a broken section, so it is removed outright and the badge and the
   "all reviews" link carry the block on their own. */
.reviews__grid--no-cards {
	display: none;
}

/* ---------- Works gallery (homepage strip) ---------- */
.works__grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
	gap: 1.25rem;
}

.work-card {
	position: relative;
	margin: 0;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	overflow: hidden;
}

.work-card__img {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	transition: transform 0.35s var(--ease);
}

.work-card:hover .work-card__img {
	transform: scale(1.04);
}

.work-card__date {
	position: absolute;
	inset-block-end: 0.75rem;
	inset-inline-start: 0.75rem;
	padding: 0.3rem 0.7rem;
	border-radius: var(--radius-sm);
	background: rgba(0, 0, 0, 0.6);
	color: #fff;
	font-size: 0.8rem;
	font-weight: 600;
}

.work-card--video {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 0.85rem;
	aspect-ratio: 4 / 3;
	padding: 1rem;
	text-align: center;
	background: radial-gradient(120% 120% at 50% 0%, var(--surface-2) 0%, var(--bg-elev) 70%);
}

.work-card__play {
	display: grid;
	place-items: center;
	width: 3.5rem;
	height: 3.5rem;
	border-radius: 50%;
	background: var(--accent);
	color: var(--on-accent);
	box-shadow: 0 6px 18px var(--accent-glow);
}

.work-card__video-label {
	font-size: 0.9rem;
	color: var(--text-dim);
}

.works__cta {
	margin-block-start: 2rem;
	display: flex;
	justify-content: center;
}

/* ---------- Works gallery page ---------- */
.page-head {
	margin-block-end: 2rem;
}

.page-head__title {
	font-size: clamp(1.75rem, 4vw, 2.5rem);
	font-weight: 800;
	margin-block-end: 0.4em;
}

.page-head__lede {
	color: var(--text-dim);
	max-width: 60ch;
}

.works-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
	gap: 1.25rem;
}

.work-thumb {
	display: block;
	border: 1px solid var(--border);
	border-radius: var(--radius);
	overflow: hidden;
	background: var(--surface);
}

.work-thumb__img {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	transition: transform 0.35s var(--ease);
}

.work-thumb:hover .work-thumb__img {
	transform: scale(1.04);
}

.page-content__body--prose h2,
.page-content__body--prose h3 {
        margin-top: 1.75rem;
        color: var(--text);
}

.page__inner--narrow {
        max-width: 860px;
        margin-inline: auto;
}

.landing-cta {
        margin-top: 2rem;
}

/* ---------- Contact page ---------- */
.contact-grid {
        display: grid;
        gap: 2rem;
        margin-top: 1.5rem;
}

@media (min-width: 900px) {
        .contact-grid {
                grid-template-columns: 1fr 1.2fr;
                align-items: start;
        }
}

.contact-block {
        margin-bottom: 1.5rem;
}

/*
 * The form's own column. It exists so the map can sit above the form as a
 * sibling without becoming a THIRD grid child — a bare `<section>` beside
 * `.contact-info` and `.contact-form` would claim a column of its own and
 * break the two-column layout on every contact page.
 */
.contact-col {
        min-width: 0;
}

.contact-block__title {
        margin: 0 0 0.5rem;
        font-size: 1.05rem;
}

.contact-list {
        list-style: none;
        margin: 0;
        padding: 0;
        color: var(--text-dim);
}

.contact-list li {
        margin-bottom: 0.25rem;
}

.contact-info a[href^="tel"],
.contact-info a[href^="mailto"] {
        color: var(--accent-text);
        text-decoration: none;
        font-weight: 600;
}

.contact-info a[href^="tel"]:hover,
.contact-info a[href^="mailto"]:hover {
        text-decoration: underline;
}

.contact-block__note {
        margin-top: 0.5rem;
        font-size: 0.85rem;
        color: var(--text-dim);
}

.contact-form__tabs {
        display: flex;
        gap: 0.25rem;
        padding: 0.25rem;
        margin: 0 0 1.25rem;
        background: var(--bg-elev);
        border-radius: calc(var(--radius) + 4px);
}

.contact-form__tab {
        flex: 1;
        padding: 0.55rem 1rem;
        border: 0;
        border-radius: var(--radius);
        background: transparent;
        color: var(--text-dim);
        font: inherit;
        font-size: 0.875rem;
        font-weight: 600;
        cursor: pointer;
        transition: background-color 0.2s, color 0.2s, box-shadow 0.2s;
}

.contact-form__tab:hover {
        color: var(--text);
}

.contact-form__tab.is-active {
        background: var(--surface);
        color: var(--text);
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}

.contact-form__label {
        margin: 0 0 0.5rem;
        font-size: 0.8rem;
        font-weight: 700;
        color: var(--text-dim);
}

.contact-form__topics {
        display: flex;
        flex-wrap: wrap;
        gap: 0.5rem;
        margin: 0 0 1.25rem;
}

.contact-form__topics[hidden] {
        display: none;
}

.contact-form__topic {
        display: inline-flex;
        align-items: center;
        gap: 0.4rem;
        padding: 0.45rem 0.9rem;
        border: 1px solid var(--border);
        border-radius: 999px;
        background: var(--surface);
        color: var(--text-dim);
        font: inherit;
        font-size: 0.8rem;
        font-weight: 600;
        cursor: pointer;
        transition: background-color 0.2s, color 0.2s, border-color 0.2s;
}

.contact-form__topic:hover {
        border-color: var(--accent);
        color: var(--text);
}

.contact-form__topic.is-active {
        border-color: var(--accent);
        background: var(--accent);
        color: var(--on-accent);
}

.contact-form {
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius);
        padding: 1.5rem;
}

.form-field {
        margin: 0 0 1rem;
}

.form-field label {
        display: block;
        margin-bottom: 0.35rem;
        font-size: 0.9rem;
        color: var(--text-dim);
}

.form-field input,
.form-field textarea {
        width: 100%;
        padding: 0.6rem 0.75rem;
        background: var(--bg);
        color: var(--text);
        border: 1px solid var(--border);
        border-radius: var(--radius-sm);
        font: inherit;
        transition: border-color var(--ease) 0.15s;
}

.form-field input:focus,
.form-field textarea:focus {
        outline: none;
        /* The border is the whole focus cue here, so it is the ring token
           rather than the fill. */
        border-color: var(--accent-ring);
}

.contact-form__status {
        margin: 0;
        min-height: 1.4em;
        color: var(--ok-text);
        font-size: 0.92rem;
}

/* ---------- Deals / empty states ---------- */
.empty-state {
        text-align: center;
        padding: 3rem 1rem;
        background: var(--surface);
        border: 1px dashed var(--border);
        border-radius: var(--radius);
}

.empty-state__title {
        font-size: 1.3rem;
        margin: 0 0 0.4rem;
}

.empty-state__text {
        color: var(--text-dim);
        max-width: 480px;
        margin: 0 auto 1.25rem;
}

/* ---------- Thank you ---------- */
.thanks-summary {
        margin-top: 1.25rem;
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius);
        padding: 1.5rem;
}

.thanks-summary__lead {
        font-size: 1.1rem;
        margin: 0 0 1rem;
}

.thanks-summary__list {
        list-style: none;
        margin: 0;
        padding: 0;
}

.thanks-summary__list li {
        display: flex;
        justify-content: space-between;
        gap: 1rem;
        padding: 0.45rem 0;
        border-bottom: 1px solid var(--border);
        font-size: 0.95rem;
}

.thanks-summary__list li:last-child {
        border-bottom: 0;
}

.thanks-summary__total {
        font-weight: 700;
        padding-top: 0.8rem !important;
}

/* PC builder styles moved to assets/css/builder.css (enqueued with the
   builder template only). */

/* ==========================================================================
   E-COMMERCE SHOP & CATEGORY FACETED ARCHITECTURE (RTL)
   ========================================================================== */

.shop-page {
	padding-block: 1.5rem 3.5rem;
}

.shop-page__inner {
	/* Wider than the site default so the catalog spreads right-to-left
	   instead of sitting in a narrow centered band (Valery 2026-08-30). */
	max-width: min(96vw, 1920px);
	margin-inline: auto;
	padding-inline: 1.25rem;
}

/* Breadcrumbs */
.shop-breadcrumbs {
	margin-block-end: 1rem;
}

.shop-breadcrumbs__list {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 0.4rem 0.6rem;
	list-style: none;
	padding: 0;
	margin: 0;
	font-size: 0.88rem;
}

.shop-breadcrumbs__item {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	color: var(--text-dim);
}

.shop-breadcrumbs__item.is-current span {
	color: var(--text);
	font-weight: 600;
}

.shop-breadcrumbs__link {
	color: var(--text-dim);
	text-decoration: none;
	transition: color 0.15s var(--ease);
}

.shop-breadcrumbs__link:hover {
	color: var(--accent-text);
}

.shop-breadcrumbs__sep {
	font-size: 0.75rem;
	color: var(--border);
	user-select: none;
}

/* Page Header */
.shop-page__header {
	margin-block-end: 1.75rem;
	padding-block-end: 1.25rem;
	border-block-end: 1px solid var(--border);
}

.shop-page__title {
	font-size: clamp(1.6rem, 3vw, 2.2rem);
	font-weight: 800;
	margin: 0 0 0.35rem;
	letter-spacing: -0.02em;
}

.shop-page__subtitle {
	margin: 0;
	font-size: 0.92rem;
	color: var(--text-dim);
}

/* 2-Column Shop Layout */
.shop-layout {
	display: grid;
	grid-template-columns: 280px 1fr;
	gap: 2rem;
	align-items: start;
}

@media (max-width: 980px) {
	.shop-layout {
		grid-template-columns: 1fr;
		gap: 1.25rem;
	}
}

/* Sidebar */
.shop-sidebar__inner {
	display: flex;
	flex-direction: column;
	gap: 1.25rem;
}

.shop-sidebar__mobile-header {
	display: none;
}

.shop-sidebar__toggle {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	position: relative;
}

.shop-sidebar__content {
	display: flex;
	flex-direction: column;
	gap: 1.25rem;
}

@media (max-width: 980px) {
	.shop-sidebar__mobile-header {
		display: block;
	}

	.shop-sidebar__toggle {
		width: 100%;
		justify-content: center;
	}

	.shop-sidebar__content {
		display: none;
	}

	.shop-sidebar.is-open .shop-sidebar__content {
		display: flex;
	}
}

/* Sidebar Widgets & Panels */
.shop-widget {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 1.15rem;
}

.shop-widget__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-block-end: 0.85rem;
	padding-block-end: 0.6rem;
	border-block-end: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
}

.shop-widget__title {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	font-size: 1.02rem;
	font-weight: 700;
	margin: 0;
	color: var(--text);
	letter-spacing: -0.01em;
}

.shop-widget__icon {
	display: inline-flex;
	color: var(--accent-text);
}

/* Category Tree Navigation */
.shop-cat-nav {
	display: flex;
	flex-direction: column;
	gap: 1rem;
}

.shop-cat-nav__all {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 0.5rem 0.65rem;
	border-radius: var(--radius-sm);
	color: var(--text);
	text-decoration: none;
	font-size: 0.9rem;
	font-weight: 700;
	transition: all 0.15s var(--ease);
}

.shop-cat-nav__all:hover {
	background: var(--bg-elev);
	color: var(--accent-text);
}

.shop-cat-nav__all.is-active {
	background: color-mix(in srgb, var(--accent) 15%, transparent);
	color: var(--accent-text);
	border-inline-start: 3px solid var(--accent);
}

.shop-cat-nav__badge {
	font-size: 0.76rem;
	color: var(--text-dim);
	background: var(--bg);
	padding: 0.15rem 0.45rem;
	border-radius: 999px;
	border: 1px solid var(--border);
}

.shop-cat-nav__all.is-active .shop-cat-nav__badge {
	background: var(--accent);
	color: var(--on-accent);
	border-color: var(--accent);
}

.shop-cat-group {
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
}

.shop-cat-group__heading {
	font-size: 0.8rem;
	font-weight: 700;
	text-transform: uppercase;
	color: var(--text-dim);
	letter-spacing: 0.04em;
	padding-inline-start: 0.4rem;
	margin-block-end: 0.15rem;
}

.shop-cat-group__list {
	list-style: none;
	padding: 0;
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: 0.2rem;
}

.shop-cat-group__link {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 0.45rem 0.65rem;
	border-radius: var(--radius-sm);
	color: var(--text);
	text-decoration: none;
	font-size: 0.9rem;
	font-weight: 500;
	transition: all 0.15s var(--ease);
}

.shop-cat-group__link:hover {
	background: var(--bg-elev);
	color: var(--accent-text);
	padding-inline-start: 0.85rem;
}

.shop-cat-group__item.is-active .shop-cat-group__link {
	background: color-mix(in srgb, var(--accent) 15%, transparent);
	color: var(--accent-text);
	font-weight: 700;
	border-inline-start: 3px solid var(--accent);
}

.shop-cat-group__count {
	font-size: 0.76rem;
	color: var(--text-dim);
	background: var(--bg);
	padding: 0.15rem 0.45rem;
	border-radius: 999px;
	border: 1px solid var(--border);
}

.shop-cat-group__item.is-active .shop-cat-group__count {
	background: var(--accent);
	color: var(--on-accent);
	border-color: var(--accent);
}

/* Horizontal Faceted Filter Bar (above the products) */
.shop-filters {
	width: 100%;
	margin-block-end: 1.5rem;
}

.shop-filters__bar {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	gap: 0.75rem;
	padding: 0.85rem;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
}

/* One facet group = a compact dropdown card in the bar. Only its title is
   visible; clicking the toggle opens the options as a floating popover (an
   overlay, so the bar never grows when a group opens). */
.shop-facet-group {
	display: flex;
	flex-direction: column;
	flex: 1 1 11.5rem;
	min-width: 11.5rem;
	background: var(--bg);
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
}

/* Price range dropdown: a touch of breathing room for the slider inside its
   popover. The wider panel width itself is declared AFTER the base popover
   rules below (see .shop-facet-group--dropdown.shop-facet-group--price). */
.shop-facet-group--price .shop-price-range {
	padding-block-start: 0.2rem;
}

/* Dropdown groups: the toggle button IS the whole card; the options panel is
   a floating popover anchored below it (overlay — never reflows the bar). */
.shop-facet-group--dropdown {
	position: relative;
}

.shop-facet-group__toggle {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.5rem;
	width: 100%;
	padding: 0.6rem 0.85rem;
	background: transparent;
	border: 0;
	color: var(--text);
	font-family: inherit;
	font-size: 0.86rem;
	font-weight: 700;
	text-align: start;
	cursor: pointer;
	transition: color 0.15s var(--ease);
}

.shop-facet-group__toggle:hover {
	color: var(--accent-text);
}

.shop-facet-group__label {
	flex: 1;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.shop-facet-group__chevron {
	flex-shrink: 0;
	color: var(--text-dim);
	transition: transform 0.2s var(--ease);
}

.shop-facet-group.is-open .shop-facet-group__chevron {
	transform: rotate(180deg);
}

/* Dropdown popover — absolutely positioned, floats above the content. */
.shop-facet-group--dropdown .shop-facet-group__panel {
	position: absolute;
	top: calc(100% + 0.5rem);
	inset-inline-end: 0;
	width: min(17rem, 80vw);
	min-width: 14rem;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);
	opacity: 0;
	visibility: hidden;
	transform: translateY(-6px);
	pointer-events: none;
	z-index: 30;
	transition:
		opacity 0.18s var(--ease),
		transform 0.18s var(--ease),
		visibility 0s linear 0.18s;
}

.shop-facet-group--dropdown.is-open .shop-facet-group__panel {
	opacity: 1;
	visibility: visible;
	transform: translateY(0);
	pointer-events: auto;
	transition:
		opacity 0.18s var(--ease),
		transform 0.18s var(--ease);
}

/* Price dropdown panel: wider than the default option popover so the
   dual-thumb slider has room to breathe. Deliberately declared after the base
   popover rules (equal specificity) and with the extra class so it always wins. */
.shop-facet-group--dropdown.shop-facet-group--price .shop-facet-group__panel {
	width: min(19rem, 80vw);
	min-width: 16rem;
}

.shop-facet-group__panel-inner {
	overflow: hidden;
	padding: 0.6rem 0.85rem 0.85rem;
}

.shop-facet-group__panel-inner .shop-facet__options {
	display: flex;
	flex-direction: column;
	gap: 0.3rem;
	max-height: 220px;
	overflow-y: auto;
	padding-inline-end: 0.35rem;
	scrollbar-width: thin;
}

/* Reset link at the far end of the bar (start side in RTL). */
.shop-filters__reset {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	align-self: center;
	margin-inline-start: auto;
	padding: 0.45rem 0.8rem;
	border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--border));
	border-radius: var(--radius-sm);
	background: color-mix(in srgb, var(--accent) 6%, transparent);
	color: var(--accent-text);
	text-decoration: none;
	font-size: 0.82rem;
	font-weight: 700;
	transition: all 0.15s var(--ease);
}

.shop-filters__reset:hover {
	background: color-mix(in srgb, var(--accent) 14%, transparent);
	border-color: var(--accent);
}

.shop-filters__reset-icon {
	font-size: 0.85rem;
	line-height: 1;
}

/* Custom Checkbox */
.shop-checkbox {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.5rem;
	cursor: pointer;
	padding: 0.25rem 0.35rem;
	border-radius: var(--radius-sm);
	user-select: none;
	transition: background 0.15s var(--ease);
}

.shop-checkbox:hover {
	background: var(--bg-elev);
}

.shop-checkbox input {
	position: absolute;
	opacity: 0;
	width: 0;
	height: 0;
}

.shop-checkbox__mark {
	position: relative;
	width: 17px;
	height: 17px;
	border-radius: 4px;
	background: var(--bg);
	border: 1px solid var(--border);
	flex-shrink: 0;
	transition: all 0.15s var(--ease);
}

.shop-checkbox input:checked ~ .shop-checkbox__mark {
	background: var(--accent);
	border-color: var(--accent);
}

.shop-checkbox input:checked ~ .shop-checkbox__mark::after {
	content: '';
	position: absolute;
	top: 2px;
	left: 5px;
	width: 4px;
	height: 8px;
	border: solid var(--on-accent);
	border-width: 0 2px 2px 0;
	transform: rotate(45deg);
}

.shop-checkbox__label {
	flex: 1;
	font-size: 0.88rem;
	color: var(--text);
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
}

.shop-checkbox input:checked ~ .shop-checkbox__label {
	font-weight: 600;
	color: var(--accent-text);
}

.shop-checkbox__count {
	font-size: 0.74rem;
	color: var(--text-dim);
}

/* Dual-Thumb Price Range Slider */
.shop-price-range {
	display: flex;
	flex-direction: column;
	gap: 0.6rem;
	padding-block-start: 0.45rem;
}

.shop-price-range__track {
	position: relative;
	height: 1.4rem;
}

.shop-price-range__fill {
	position: absolute;
	top: 50%;
	height: 4px;
	transform: translateY(-50%);
	background: var(--accent);
	border-radius: 999px;
	pointer-events: none;
}

.shop-price-range__input {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	margin: 0;
	background: transparent;
	-webkit-appearance: none;
	appearance: none;
	pointer-events: none;
	z-index: 2;
}

.shop-price-range__input::-webkit-slider-runnable-track {
	background: transparent;
	height: 4px;
	border-radius: 999px;
}

.shop-price-range__input::-webkit-slider-thumb {
	-webkit-appearance: none;
	appearance: none;
	pointer-events: auto;
	width: 18px;
	height: 18px;
	margin-top: -7px;
	border-radius: 50%;
	background: var(--accent);
	border: 3px solid var(--on-accent);
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
	cursor: grab;
}

.shop-price-range__input::-moz-range-track {
	background: transparent;
	height: 4px;
	border-radius: 999px;
}

.shop-price-range__input::-moz-range-thumb {
	pointer-events: auto;
	width: 12px;
	height: 12px;
	border-radius: 50%;
	background: var(--accent);
	border: 3px solid var(--on-accent);
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
	cursor: grab;
}

.shop-price-range__input:active::-webkit-slider-thumb,
.shop-price-range__input:active::-moz-range-thumb {
	cursor: grabbing;
}

.shop-price-range__values {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.5rem;
}

.shop-price-range__value {
	padding: 0.15rem 0.55rem;
	background: var(--bg-elev);
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	color: var(--text);
	font-size: 0.8rem;
	font-weight: 700;
	white-space: nowrap;
}

.shop-price-range__sep {
	color: var(--text-dim);
	font-size: 0.8rem;
}

@media (max-width: 720px) {
	.shop-facet-group {
		flex-basis: 100%;
	}

	.shop-facet-group--dropdown .shop-facet-group__panel {
		width: min(18rem, 90vw);
	}
}

/* Active Filter Tags */
.shop-active-filters {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 0.5rem 0.75rem;
	margin-block-end: 1.5rem;
	padding: 0.75rem 1rem;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
}

.shop-active-filters__title {
	font-size: 0.85rem;
	font-weight: 700;
	color: var(--text-dim);
}

.shop-active-filters__list {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 0.4rem;
}

.shop-filter-pill {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	padding: 0.3rem 0.75rem;
	background: var(--bg-elev);
	border: 1px solid var(--accent);
	color: var(--accent-text);
	border-radius: 999px;
	font-size: 0.82rem;
	font-weight: 600;
	text-decoration: none;
	transition: all 0.15s var(--ease);
}

.shop-filter-pill:hover {
	background: var(--accent);
	color: var(--on-accent);
}

.shop-filter-pill__remove {
	font-size: 0.75rem;
	line-height: 1;
}

.shop-active-filters__clear {
	font-size: 0.82rem;
	color: var(--text-dim);
	text-decoration: underline;
	margin-inline-start: 0.5rem;
}

.shop-active-filters__clear:hover {
	color: var(--danger);
}

/* Catalog Pagination (WooCommerce ul.page-numbers) — horizontal pill row.
   Valery 2026-08-30: "החלק הזה לא לרוחב הוא לאורך וזה לא יפה" — the default
   block-level list rendered as a vertical bullet list; now a centered flex row. */
.woocommerce-pagination {
	display: flex;
	justify-content: center;
	margin-block-start: 2.5rem;
}

.woocommerce-pagination ul.page-numbers {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 0.4rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.woocommerce-pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.4rem;
	height: 2.4rem;
	padding: 0 0.7rem;
	background: var(--bg);
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	color: var(--text);
	font-size: 0.9rem;
	font-weight: 600;
	line-height: 1;
	text-decoration: none;
	transition: all 0.15s var(--ease);
}

.woocommerce-pagination a.page-numbers:hover {
	border-color: var(--accent);
	color: var(--accent-text);
	background: var(--bg-elev);
	transform: translateY(-1px);
}

.woocommerce-pagination .page-numbers.current {
	background: var(--accent);
	border-color: var(--accent);
	color: var(--on-accent);
	box-shadow: 0 0 0 3px var(--accent-subtle);
}

.woocommerce-pagination .page-numbers.dots {
	min-width: auto;
	height: auto;
	padding: 0 0.3rem;
	background: none;
	border: 0;
	color: var(--text-dim);
	font-weight: 700;
}

.woocommerce-pagination .page-numbers.prev,
.woocommerce-pagination .page-numbers.next {
	font-size: 1rem;
}

/* Shop Main Head */
.shop-main__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-block-end: 1.25rem;
}

.shop-main__title {
	font-size: 1.25rem;
	font-weight: 700;
	margin: 0;
	letter-spacing: -0.01em;
}

/* Empty State / No Results */
.shop-no-results {
	text-align: center;
	padding: 3.5rem 1.5rem;
	background: var(--surface);
	border: 1px dashed var(--border);
	border-radius: var(--radius);
	margin-block-start: 1rem;
}

.shop-no-results__icon {
	font-size: 2.5rem;
	margin-block-end: 0.75rem;
}

.shop-no-results__title {
	font-size: 1.25rem;
	font-weight: 700;
	margin: 0 0 0.5rem;
}

.shop-no-results__text {
	color: var(--text-dim);
	font-size: 0.95rem;
	max-width: 420px;
	margin: 0 auto 1.5rem;
}

/* ==========================================================================
   SHOP LANDING PAGE COMPONENTS (HERO, DEALS, CATALOG TILES)
   ========================================================================== */

.shop-landing {
	display: flex;
	flex-direction: column;
	gap: 2.5rem;
	margin-block-end: 3rem;
	padding-block-end: 2rem;
	border-block-end: 1px solid var(--border);
}

/* Landing Hero */
.shop-landing__hero {
	position: relative;
	overflow: hidden;
	/* Full-bleed band: the wide shop container is intentional, but the
	   text/badges inside must not stretch — they live in __hero-inner
	   which is capped below. (Redesign 2026-08-30, Valery: "לא נירא טוב שזה ככה מתפרס") */
	background:
		radial-gradient(1100px 440px at 88% -25%, color-mix(in srgb, var(--accent) 16%, transparent), transparent 65%),
		linear-gradient(135deg, var(--surface) 0%, color-mix(in srgb, var(--accent) 9%, var(--surface)) 100%);
	border: 1px solid var(--border);
	border-radius: var(--radius);
}

.shop-landing__hero::before {
	content: "";
	position: absolute;
	inset-inline-start: -130px;
	inset-block-start: -130px;
	width: 360px;
	height: 360px;
	border-radius: 50%;
	background: radial-gradient(circle, color-mix(in srgb, var(--accent) 15%, transparent), transparent 70%);
	pointer-events: none;
}

.shop-landing__hero-inner {
	position: relative;
	display: grid;
	grid-template-columns: 1.5fr 1fr;
	gap: clamp(1.5rem, 4vw, 3.25rem);
	align-items: center;
	max-width: 1240px;
	margin-inline: auto;
	padding: clamp(2rem, 5vw, 3.25rem) clamp(1.25rem, 4vw, 2.5rem);
}

@media (max-width: 720px) {
	.shop-landing__hero-inner {
		grid-template-columns: 1fr;
	}
}

.shop-landing__tag {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.35rem 0.8rem;
	background: color-mix(in srgb, var(--accent) 20%, transparent);
	color: var(--accent-text);
	border: 1px solid var(--accent);
	border-radius: 999px;
	font-size: 0.82rem;
	font-weight: 700;
	margin-block-end: 0.85rem;
}

.pulse-dot {
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: var(--accent);
	box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 60%, transparent);
	animation: newxmod-pulse 2s infinite;
}

@keyframes newxmod-pulse {
	0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 60%, transparent); }
	70% { box-shadow: 0 0 0 8px transparent; }
	100% { box-shadow: 0 0 0 0 transparent; }
}

.shop-landing__title {
	font-size: clamp(1.4rem, 2.5vw, 1.85rem);
	font-weight: 800;
	margin: 0 0 0.6rem;
	letter-spacing: -0.02em;
}

.shop-landing__lede {
	font-size: 0.98rem;
	color: var(--text-dim);
	max-width: 620px;
	margin: 0;
	line-height: 1.6;
}

.shop-landing__hero-badges {
	display: flex;
	flex-direction: column;
	gap: 0.8rem;
}

/* Trust points — plain icon + text rows, NOT boxed buttons.
   Valery 2026-08-30: "בכלל לא סגור בתור כפתור אלה רק נקודות". */
.shop-badge-pill {
	display: flex;
	align-items: center;
	gap: 0.7rem;
}

.shop-badge-pill__icon {
	font-size: 1.15rem;
	flex-shrink: 0;
}

.shop-badge-pill__text {
	display: flex;
	flex-direction: column;
	line-height: 1.35;
}

.shop-badge-pill__text strong {
	font-size: 0.9rem;
	color: var(--text);
}

.shop-badge-pill__text span {
	font-size: 0.8rem;
	color: var(--text-dim);
}

/* Deals & Section Head */
.shop-deals-head {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 1rem;
	margin-block-end: 1.25rem;
}

.shop-deals-head__title-wrap {
	display: flex;
	flex-direction: column;
	gap: 0.3rem;
}

.shop-deals-head__badge {
	display: inline-flex;
	align-items: center;
	gap: 0.3rem;
	color: var(--accent-text);
	font-size: 0.82rem;
	font-weight: 700;
}

.shop-deals-head__title {
	font-size: 1.3rem;
	font-weight: 800;
	margin: 0;
	letter-spacing: -0.01em;
}

/* Hot Deals Grid — same min card width as the catalog (.woocommerce .products)
   so deal cards and product cards are one consistent size. */
.shop-deals-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
	gap: 1.25rem;
}

.shop-deal-card {
	position: relative;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 1rem;
	display: flex;
	flex-direction: column;
	color: var(--text);
	transition: all 0.2s var(--ease);
}

.shop-deal-card:hover {
	transform: translateY(-4px);
	border-color: var(--accent);
	box-shadow: 0 8px 24px var(--accent-glow);
}

.shop-deal-card__badge {
	position: absolute;
	inset-block-start: 0.75rem;
	inset-inline-start: 0.75rem;
	z-index: 2;
	padding: 0.25rem 0.55rem;
	background: #e11d48;
	color: #ffffff;
	font-size: 0.76rem;
	font-weight: 800;
	border-radius: 999px;
	box-shadow: 0 2px 6px rgba(225, 29, 72, 0.4);
}

.shop-deal-card__media {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	aspect-ratio: 1 / 1;
	background: var(--bg-elev);
	border-radius: var(--radius-sm);
	overflow: hidden;
	margin-block-end: 0.85rem;
}

.shop-deal-card__media img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	transition: transform 0.3s var(--ease);
}

.shop-deal-card:hover .shop-deal-card__media img {
	transform: scale(1.05);
}

.shop-deal-card__body {
	display: flex;
	flex-direction: column;
	gap: 0.45rem;
	flex: 1;
}

.shop-deal-card__title {
	font-size: 0.95rem;
	font-weight: 700;
	margin: 0;
	line-height: 1.35;
}

.shop-deal-card__title a {
	color: var(--text);
	text-decoration: none;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.shop-deal-card__title a:hover {
	color: var(--accent-text);
}

.shop-deal-card__price {
	margin-block-start: auto;
	font-size: 1.05rem;
	font-weight: 800;
	color: var(--accent-text);
}

.shop-deal-card__price del {
	font-size: 0.82rem;
	color: var(--text-dim);
	font-weight: 400;
	margin-inline-end: 0.35rem;
}

.shop-deal-card__price ins {
	text-decoration: none;
}

.shop-deal-card__cta {
	margin-block-start: 0.5rem;
	align-self: flex-start;
}

/* ==========================================================================
   DEALS CAROUSEL (קרוסלת מבצעים)
   ========================================================================== */

.promo-carousel {
	position: relative;
	width: 100%;
	margin-block-end: 2.5rem;
	border-radius: var(--radius);
	overflow: hidden;
	border: 1px solid var(--border);
	background: var(--bg-elev);
	isolation: isolate;
}

.promo-carousel__viewport {
	overflow: hidden;
	border-radius: inherit;
}

.promo-carousel__track {
	display: flex;
	width: 100%;
	transition: transform 0.55s cubic-bezier(0.4, 0, 0.2, 1);
	direction: rtl; /* Slides flow RTL to match Hebrew reading order. */
}

.promo-carousel__slide {
	flex: 0 0 100%;
	min-width: 0;
	position: relative;
	aspect-ratio: 16 / 5;
}

.promo-carousel__link {
	position: relative;
	display: block;
	width: 100%;
	height: 100%;
}

/* Legibility scrim for the caption. A text-shadow is not a backdrop — WCAG
   1.4.3 measures text against what is actually painted behind it — and the
   banner image is admin-uploaded, so the worst case is a light or all-white
   photo. Before this, white caption text on the light demo placeholder
   measured 1.11:1. The gradient keeps it above 4.5:1 whatever is uploaded.
   Added 2026-09-15. */
.promo-carousel__link::after {
	content: "";
	position: absolute;
	inset-inline: 0;
	bottom: 0;
	height: 72%;
	background: linear-gradient(
		to top,
		rgb(0 0 0 / 0.82) 0%,
		rgb(0 0 0 / 0.58) 42%,
		rgb(0 0 0 / 0) 100%
	);
	pointer-events: none;
}

.promo-carousel__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.promo-carousel__caption {
	position: absolute;
	inset-inline-start: 2rem;
	bottom: 1.5rem;
	/* Sits above the .promo-carousel__link::after scrim. */
	z-index: 1;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.5rem;
	max-width: 60%;
}

.promo-carousel__eyebrow {
	display: inline-block;
	padding: 0.3rem 0.8rem;
	background: rgba(0, 0, 0, 0.55);
	backdrop-filter: blur(6px);
	color: #fff;
	font-size: 0.82rem;
	font-weight: 700;
	border-radius: 999px;
	letter-spacing: 0.01em;
}

.promo-carousel__title {
	display: block;
	color: #fff;
	font-size: clamp(1.1rem, 2.4vw, 1.7rem);
	font-weight: 800;
	line-height: 1.25;
	text-shadow: 0 2px 12px rgb(0 0 0 / 0.55);
}

.promo-carousel__cta {
	display: inline-block;
	padding: 0.55rem 1.2rem;
	background: var(--accent);
	color: var(--on-accent);
	font-size: 0.9rem;
	font-weight: 700;
	border-radius: 999px;
	transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}

.promo-carousel__link:hover .promo-carousel__cta {
	transform: translateY(-2px);
	box-shadow: 0 8px 22px var(--accent-glow);
}

/* Prev / next arrows */
.promo-carousel__nav {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 2;
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	border: 1px solid var(--border);
	border-radius: 999px;
	background: color-mix(in srgb, var(--surface) 82%, transparent);
	backdrop-filter: blur(8px);
	color: var(--text);
	font-size: 1.6rem;
	line-height: 1;
	cursor: pointer;
	transition: all 0.2s var(--ease);
}

.promo-carousel__nav:hover {
	background: var(--accent);
	color: var(--on-accent);
	border-color: var(--accent);
}

/* RTL convention (matches the products slider): reading flows right-to-left,
   so the "next" arrow sits on the LEFT and "prev" on the RIGHT. Logical
   properties flip sides automatically in an LTR context. */
.promo-carousel__nav--prev {
	inset-inline-start: 1rem;
}

.promo-carousel__nav--next {
	inset-inline-end: 1rem;
}

/* Dots */
.promo-carousel__dots {
	position: absolute;
	bottom: 0.9rem;
	inset-inline-start: 50%;
	transform: translateX(50%);
	z-index: 2;
	display: flex;
	gap: 0.5rem;
}

.promo-carousel__dot {
	width: 9px;
	height: 9px;
	padding: 0;
	border: none;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.5);
	cursor: pointer;
	transition: all 0.25s var(--ease);
}

.promo-carousel__dot:hover {
	background: rgba(255, 255, 255, 0.85);
}

.promo-carousel__dot.is-active {
	width: 24px;
	background: var(--accent);
}

/* Responsive: taller slides + smaller captions on narrow screens. */
@media (max-width: 720px) {
	.promo-carousel__slide {
		aspect-ratio: 16 / 9;
	}

	.promo-carousel__caption {
		inset-inline-start: 1rem;
		bottom: 1.75rem;
		max-width: 75%;
	}

	.promo-carousel__cta {
		font-size: 0.8rem;
		padding: 0.45rem 0.95rem;
	}

	.promo-carousel__nav {
		width: 36px;
		height: 36px;
		font-size: 1.3rem;
	}
}