/*
 * Header — Top Utility Bar + Main Navigation.
 *
 * Every value traces to Swiftheat Home v2.dc.html, measured with Chrome
 * DevTools. Uses tokens.css wherever a matching token exists; the
 * handful of values with no reusable equivalent are commented with
 * their source measurement instead of being forced into an unrelated
 * token.
 *
 * Container: --site-container (1200px, the project's locked value — the
 * design file itself uses 1640px; not used here per instruction).
 */

/* ---- Typography foundation: self-hosted Manrope ----
 * Global @font-face declarations live here rather than in tokens.css
 * (which holds custom-property variables only — see the docblock above)
 * for the same reason the canonical .site-container rule lives here:
 * header.css is one of only two stylesheets this theme enqueues
 * unconditionally on every page (alongside tokens.css itself), so a
 * font declared here is guaranteed available everywhere --font-primary
 * is used, with nothing to duplicate across page-scoped files.
 *
 * The approved design (every .dc.html file, confirmed by direct
 * inspection, not assumption) loads Manrope 400/500/600/700/800 and
 * IBM Plex Mono 400/500/600 from Google Fonts. Both are self-hosted here
 * instead, so page rendering never depends on an external Google Fonts
 * request.
 *
 * Manrope: a genuine, appropriately-licensed (GPLv2, redistributed as
 * part of WordPress core's own bundled "Twenty Twenty-Five" theme)
 * variable font file — copied as-is into this theme's own assets/fonts/,
 * not downloaded from the internet. Its declared weight axis (200–800)
 * covers every Manrope weight the approved design actually uses.
 *
 * IBM Plex Mono: sourced from the official IBM/plex GitHub repository's
 * own release asset (@ibm/plex-mono-variable@1.0.0,
 * "fonts/complete/woff2/IBM Plex Mono Var-Roman.woff2", SIL Open Font
 * License, copyright IBM Corp.) — verified byte-for-byte against that
 * release's own published file size before being copied in here. The
 * design uses normal style only (no italic anywhere — confirmed by
 * search), so only the Roman variable file was kept; its weight axis
 * (100–700, per IBM's own release notes) covers every IBM Plex Mono
 * weight the approved design actually uses.
 */
@font-face {
	font-family: 'Manrope';
	src: url('../fonts/manrope/Manrope-VariableFont_wght.woff2') format('woff2-variations'), url('../fonts/manrope/Manrope-VariableFont_wght.woff2') format('woff2');
	font-weight: 200 800;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: 'IBM Plex Mono';
	src: url('../fonts/ibm-plex-mono/IBM-Plex-Mono-Var-Roman.woff2') format('woff2-variations'), url('../fonts/ibm-plex-mono/IBM-Plex-Mono-Var-Roman.woff2') format('woff2');
	font-weight: 100 700;
	font-style: normal;
	font-display: swap;
}

/* Every approved design file's own <body> rule sets
   font-family:'Manrope' as the page-wide default — no theme stylesheet
   ever declared this at the body level (confirmed by search), so any
   text relying on inheritance rather than an explicit component class
   was silently falling back to the browser default font. This restores
   the design's own stated default; it changes no size/color/spacing. */
body {
	font-family: var(--font-primary);
}

/* ---- Accessibility: visually-hidden utility ----
 * Site-wide utility class, not specific to the header — placed here
 * because header.css (along with tokens.css, which holds custom
 * properties only, not component rules) is the only stylesheet this
 * theme enqueues unconditionally on every page (see inc/enqueue.php;
 * home.css only loads on the front page). header.php's own "Skip to
 * content" link and mobile-menu accessible label already reference this
 * exact class name, but no matching CSS rule existed anywhere in the
 * theme until now — that text was rendering as ordinary visible content
 * rather than being hidden from sighted users while staying available to
 * assistive technology. Standard WordPress core-theme pattern: hidden via
 * clipping (not display:none/visibility:hidden, which would also remove
 * it from the accessibility tree), and restored to visible on keyboard
 * focus so a skip-link is actually usable, not just present. */
.screen-reader-text {
	border: 0;
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
	word-wrap: normal;
}

.screen-reader-text:focus {
	background-color: var(--color-bg-white);
	border-radius: 3px;
	box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6);
	clip-path: none;
	color: var(--text-base);
	display: block;
	font-size: var(--fs-body-small);
	font-weight: var(--fw-bold);
	height: auto;
	left: 5px;
	line-height: normal;
	padding: 15px 23px 14px;
	text-decoration: none;
	top: 5px;
	width: auto;
	z-index: 100000;
}

/* ---- Layout: site-wide container utility ----
 * Same reasoning as `.screen-reader-text` above: this is a generic, cross-cutting utility,
 * not header-specific, placed here only because header.css is one of the
 * two stylesheets this theme enqueues unconditionally on every page (the
 * other, tokens.css, holds custom properties only — no selectors, per its
 * own docblock).
 *
 * Previously this exact rule lived only in home.css (front-page-only), so
 * `.site-container` silently failed to constrain any element on every
 * other page — Header/Footer/Product Archive elements carrying this class
 * rendered at the full viewport width there instead of the locked 1200px.
 * This is now the ONE canonical definition; home.css's own former copy has
 * been removed (see that file's own note at the same location), and the
 * few component stylesheets that had separately duplicated the same
 * max-width/margin values on their own inner-container class (in addition
 * to already carrying the `site-container` class) have had those
 * redundant declarations removed too — see header.css's own
 * `.site-header__inner` and archive-product.css's `.archive-cta__inner`.
 *
 * `box-sizing: border-box` is included here as the container's own
 * baseline (every current consumer already redeclares it on its own
 * `__inner` class too — left in place there, harmless/idempotent) so any
 * future consumer gets safe max-width behavior even if it
 * forgets to add that itself. `margin: 0 auto` (not the logical
 * `margin-inline: auto`) matches this codebase's own established
 * convention of physical, not logical, CSS properties throughout. */
.site-container {
	width: 100%;
	max-width: var(--site-container);
	margin: 0 auto;
	box-sizing: border-box;
}

/* ---- Top Utility Bar ---- */

.site-utility-bar {
	background: var(--color-navy-deepest);
	color: var(--text-on-dark-muted);
}

.site-utility-bar__inner {
	display: flex;
	justify-content: space-between;
	align-items: center;
	/* 10px vertical is a one-off measured value, not part of the reusable
	   section-padding scale (that scale starts at 56px+) — left literal. */
	padding: 10px var(--gutter-desktop);
	font-family: var(--font-mono);
	font-size: var(--fs-utility);
	letter-spacing: var(--ls-utility);
}

.site-utility-bar__contact {
	display: flex;
	/* 32px gap is a one-off measured value (design: display:flex;gap:32px
	   on this exact element) — not part of the reusable gap scale. */
	gap: 32px;
}

.site-utility-bar__contact a,
.site-utility-bar__location {
	color: inherit;
	text-decoration: none;
}

/* ---- Main Header ---- */

/* `position: sticky` per Source A (the approved design's own <header>
   uses this exact rule — position:sticky;top:0, confirmed live against
   Swiftheat Home v2.dc.html). This was already declared here but did
   NOT actually stick when scrolled — verified live: the header scrolled
   fully off-screen instead of stopping at top:0. Root cause: `.site-header`
   used to be nested inside a `.site-header-wrap` element that only wrapped
   the Utility Bar + this header (~114px tall total) — a sticky element
   cannot stick further than its own containing block's box, so it only had
   ~36px of real "stick room" before being forced to scroll away with its
   too-short parent. Fixed by promoting this element to be the page's own
   `<header>` landmark directly under `<body>` (see header.php) — `<body>`
   spans the full page height, giving the sticky header its intended
   unlimited room to remain stuck through the whole scroll. The Utility Bar
   is now a sibling `<div>` before this element, not a parent — it remains
   in normal document flow, not sticky, unaffected by this fix. */
.site-header {
	position: sticky;
	top: 0;
	z-index: 50;
	background: rgba(255, 255, 255, 0.94);
	-webkit-backdrop-filter: blur(var(--blur-glass));
	backdrop-filter: blur(var(--blur-glass));
	border-bottom: 1px solid var(--border-light);
}

.site-header__inner {
	/* max-width/margin intentionally not declared here — this element
	   already carries the `site-container` HTML class in header.php, which
	   provides these two declarations from the one canonical
	   `.site-container` rule above; redeclaring the identical values here
	   would be dead-weight duplication. */
	display: flex;
	align-items: center;
	justify-content: space-between;
	/* 16px vertical padding is a one-off measured value specific to this
	   component (the header's own compact rhythm, distinct from the
	   section-padding scale). 20px gap matches the design's own
	   header row gap. */
	padding: 16px var(--gutter-desktop);
	gap: 20px;
	flex-wrap: wrap;
	/* box-sizing: border-box is required here. Combining max-width
	   with padding on the same element under the browser default
	   (content-box) means a block box's width:auto fill algorithm solves
	   for CONTENT width = containing-block width − padding; max-width only
	   constrains that content width. At a 1280px viewport with a 1200px
	   max-width and 128px total horizontal padding, the unconstrained
	   content width (1280−128=1152) never reached 1200px, so max-width
	   silently never engaged — measured live before this fix: the header's
	   inner content rendered at the full 1280px viewport width, left-
	   aligned at 0, not the intended capped-and-centered 1200px. border-box
	   makes max-width constrain the border box (padding included), so the
	   1200px cap now applies correctly and margin:auto centers it. This
	   element's own box-sizing:border-box is now also redundant with the
	   canonical `.site-container` rule's own border-box, kept here anyway
	   as harmless/idempotent — not worth touching for this fix. */
	box-sizing: border-box;
	/* position: relative — anchors the
	   Mega Menu panel (.site-header__mega-panel, absolutely positioned) to
	   this exact 1200px-capped, centered box — never to the raw viewport —
	   so the panel can only ever span 1200px or the current viewport width,
	   whichever is smaller, and can never overflow horizontally regardless
	   of which nav item it belongs to. Zero visual effect on its own (no
	   offset properties set here), so this does not change the Header's
	   existing layout at all. */
	position: relative;
}

.site-header__logo {
	display: block;
	line-height: 0;
	flex-shrink: 0;
}

/* The approved logo FILE itself (not CSS) has a large amount of empty
 * canvas around the visible mark — measured directly by sampling pixel
 * alpha/color across the actual source file (swiftheat-logo-1.webp,
 * 625×208 natural canvas): the visible logo only occupies x:[20,559]
 * y:[50,141] of that canvas — i.e. the real mark is 540×92px sitting
 * inside a canvas 208px tall, wasting ~56% of the image's own vertical
 * space. No alternate, tighter-canvas Swiftheat logo asset exists
 * anywhere in the project's design source. The ORIGINAL FILE IS NOT
 * MODIFIED — this crops the DISPLAY only, using the classic CSS-sprite
 * technique: an overflow:hidden wrapper sized to the visible mark's own
 * footprint, containing the full image scaled up and shifted with
 * negative margins so only the visible region shows through. All values
 * below are computed directly from that one measurement (not guessed),
 * documented alongside so the math can be re-derived if the logo file is
 * ever replaced with a tighter-canvas export.
 *
 * Desktop: wrapper height held at the SAME 42px the plain <img> previously
 * rendered at (no arbitrary height increase); width grows to
 * ~246.5px as a direct, unavoidable consequence of the visible mark's
 * own 540:92 aspect ratio at that height, not a separate choice.
 * scale = 42 / 92 = 0.456522 → full image at this scale: 285.33×94.96px;
 * visible region within it: left 9.13px, top 22.83px, width 246.52px
 * (= wrapper width), height 42px (= wrapper height, exactly).
 */
.site-header__logo-crop {
	display: block;
	overflow: hidden;
	width: 246.52px;
	height: 42px;
}

.site-header__logo-crop img {
	display: block;
	width: 285.33px;
	height: 94.96px;
	max-width: none;
	margin-top: -22.83px;
	margin-left: -9.13px;
}

/* Narrow-desktop regression guard.
 * The wider 246.52px crop above is safe at common desktop widths
 * (1440/1366/1280/1024px) when measured in isolation, but
 * .site-header__inner is a flex-wrap:wrap row of logo + nav + CTA with a
 * fixed nav (457.95px) and CTA (171.46px) footprint — live measurement
 * (getBoundingClientRect + a bisection sweep) showed that the wider crop
 * pushes that row's total required width past .site-header__inner's
 * available content box (innerWidth − 128px padding) starting at
 * viewport ≈1044px, whereas the original 126px-wide logo only
 * required ≈924px — a wrap regression (CTA drops to its own row, header
 * height 78px → 140px) spanning ≈924–1044px, which includes the common
 * 1024px test point. Below ≈924px the row already didn't fit even with
 * the old 126px logo (pre-existing, unrelated to this crop).
 * Fix: revert to the original logo footprint (126px / 42px, no crop —
 * full image scaled to 42px height, its own natural ~126px width) for
 * this squeezed band only, so behavior there is provably identical to
 * the already-verified original layout. Widths at or above 1100px
 * (safely past the 1044px threshold) keep the fuller crop.
 */
@media (min-width: 769px) and (max-width: 1099px) {
	.site-header__logo-crop {
		width: 126px;
		height: 42px;
	}

	.site-header__logo-crop img {
		width: auto;
		height: 42px;
		max-width: none;
		margin-top: 0;
		margin-left: 0;
	}
}

.site-header__menu-toggle {
	display: none; /* shown only below --bp-mobile, see media query below */
	background: none;
	border: 0;
	padding: 8px;
	cursor: pointer;
	line-height: 0;
}

.site-header__menu-toggle-bars,
.site-header__menu-toggle-bars::before,
.site-header__menu-toggle-bars::after {
	display: block;
	width: 22px;
	height: 2px;
	background: var(--text-nav);
	border-radius: 1px;
}

.site-header__menu-toggle-bars {
	position: relative;
}

.site-header__menu-toggle-bars::before,
.site-header__menu-toggle-bars::after {
	content: "";
	position: absolute;
	left: 0;
}

.site-header__menu-toggle-bars::before {
	top: -7px;
}

.site-header__menu-toggle-bars::after {
	top: 7px;
}

.site-header__nav-list {
	display: flex;
	align-items: center;
	gap: var(--gap-grid-4col); /* 36px — matches the design's exact nav gap; reused, not duplicated */
	list-style: none;
	margin: 0;
	padding: 0;
}

.site-header__nav-list a {
	font-family: var(--font-primary);
	font-size: var(--fs-nav);
	font-weight: var(--fw-bold);
	color: var(--text-nav);
	text-decoration: none;
	white-space: nowrap;
	transition: color var(--transition-fast);
}

.site-header__nav-list a:hover,
.site-header__nav-list a:focus-visible {
	color: var(--color-red);
}

/* Active/current-page state, per the approved design's own pattern
   (e.g. Products.dc.html's "Products" link when on that page):
   navy text + red 2px underline. WP applies .current-menu-item /
   .current_page_item to the <li> when the URL matches exactly. */
.site-header__nav-list .current-menu-item > a,
.site-header__nav-list .current_page_item > a {
	color: var(--color-navy);
	border-bottom: 2px solid var(--color-red);
	padding-bottom: 3px;
}

.site-header__cta {
	display: inline-block;
	flex-shrink: 0;
	padding: var(--pad-button-compact);
	background: var(--color-red);
	color: var(--color-bg-white);
	font-family: var(--font-primary);
	font-size: var(--fs-body-small);
	font-weight: var(--fw-extrabold);
	letter-spacing: var(--ls-cta);
	border-radius: var(--radius-sharp);
	text-decoration: none;
	white-space: nowrap;
	transition: background var(--transition-fast);
}

.site-header__cta:hover,
.site-header__cta:focus-visible {
	background: var(--color-navy);
	color: var(--color-bg-white);
}

/* ---- Products Mega Menu ----
 * No approved Mega Menu / dropdown / navigation-panel design exists
 * anywhere in the design source (confirmed by grep across every design
 * file and its assets). Built instead as a natural extension of this Header's own already-approved
 * language: existing typography tokens, the existing navy/red palette, the
 * existing card border/radius/shadow tokens, and the existing 1200px
 * content foundation. No new colors, radii, shadows, or breakpoints were
 * introduced — every value below is an existing token from tokens.css.
 *
 * This is a compact NAVIGATION layout, deliberately not the Home/Archive
 * 3/2/1 Product grid (different purpose, different component, own scoped
 * class names — home.css's and archive-product.css's own grids are
 * untouched). Column count is responsive to available width via
 * `repeat(auto-fill, minmax(...))`, not a hardcoded count tied to today's
 * 8-Product catalogue.
 */

.site-header__mega-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: none;
	border: 0;
	padding: 4px;
	margin-left: 2px;
	cursor: pointer;
	line-height: 0;
	vertical-align: middle;
}

.site-header__mega-toggle-chevron {
	display: block;
	width: 7px;
	height: 7px;
	border-right: 2px solid var(--text-nav);
	border-bottom: 2px solid var(--text-nav);
	transform: rotate(45deg);
	/* Rotation only — no opening/closing transition exists for the panel
	   itself (shown/hidden instantly via the native `hidden` attribute), so
	   there is nothing here for prefers-reduced-motion to need to disable. */
	transition: transform var(--transition-fast);
}

.site-header__mega-toggle[aria-expanded="true"] .site-header__mega-toggle-chevron {
	transform: rotate(-135deg);
}

.site-header__mega-panel {
	position: absolute;
	top: 100%;
	left: 0;
	right: 0;
	margin-top: -1px; /* sits flush against .site-header's own 1px bottom border, doesn't double it */
	/* Deep navy panel, not white — the same "deep panel" surface already
	   used for Quality's own inspection panel and the Hero image frame,
	   reused here rather than inventing a new dark value. */
	background: var(--color-navy-deep);
	border: 1px solid var(--color-navy-raised);
	/* --shadow-panel-deep is this project's own existing dark-panel shadow
	   token (Quality panel, Hero frame) — a more accurate semantic match
	   now that this is a dark panel, not a light card. */
	box-shadow: var(--shadow-panel-deep);
	/* 18px/16px vertical padding: measured live (getBoundingClientRect())
	   — the panel previously rendered at 263.5px tall for two rows of
	   48px-image items, with ~29px of empty space above the first row and
	   ~25.5px below "View All Products". Horizontal padding
	   (var(--gutter-desktop)) is intentionally UNCHANGED — that governs
	   left/right alignment with the Header's own 1200px content width,
	   not vertical whitespace, and must stay put. */
	padding: 20px var(--gutter-desktop) 16px;
	box-sizing: border-box;
	z-index: 45; /* below .site-header's own 50, above normal page content */
}

.site-header__mega-panel[hidden] {
	display: none;
}

.site-header__mega-panel::before {
	content: "";
	position: absolute;
	inset: 0;
	/* Same grid-line texture literal already established on this dark-navy
	   family of surfaces elsewhere (Why Swiftheat on Home; the Product
	   grid frames on Home/Products) — reused a third time here for
	   cross-component consistency rather than inventing a new texture.
	   Sits behind the grid/eyebrow/viewall content below it in normal
	   paint order, so it never competes with the product photography. */
	background-image: linear-gradient(rgba(143, 166, 201, 0.05) 1px, transparent 1px),
		linear-gradient(90deg, rgba(143, 166, 201, 0.05) 1px, transparent 1px);
	background-size: 56px 56px;
	pointer-events: none;
}

.site-header__mega-eyebrow {
	/* Same eyebrow typography convention used throughout the site (About/
	   Home/Quality/etc.) — font-mono + fs-eyebrow + fw-semibold +
	   ls-eyebrow + red. text-transform:uppercase matches Home Hero's own
	   eyebrow (hero.css), the one existing eyebrow that applies case via
	   CSS rather than an all-caps string, kept consistent with that
	   approach here since the markup string is sentence-case. */
	position: relative;
	font-family: var(--font-mono);
	font-size: var(--fs-eyebrow);
	font-weight: var(--fw-semibold);
	letter-spacing: var(--ls-eyebrow);
	color: var(--color-red);
	text-transform: uppercase;
	margin-bottom: 14px;
}

.site-header__mega-grid {
	position: relative;
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
	/* var(--gap-form) (16px), not var(--gap-grid-6col) (24px) — an
	   existing token, reused rather than inventing a new value, tightening
	   the space between the two Product rows to match the panel's own
	   padding above. */
	gap: var(--gap-form);
}

/* Item surface language matches the Product grid "frame vs. card" pair
 * already established on Home/Products: the panel above is the deep
 * --color-navy-deep frame; each item's own surface is --color-navy — one
 * shade lighter — so items read as distinct surfaces sitting on the
 * panel, not flat text rows. No new colors introduced.
 * - normal state: transparent (the panel's own navy shows through), plus
 *   --color-navy-raised for the border, giving each item a defined edge
 *   at rest without a heavy card look.
 * - hover/focus-visible: background shifts to --color-navy (the lighter
 *   navy surface) and a 3px --color-red accent appears on the left edge —
 *   ONE coherent hover treatment, matching the brief's own "thin left
 *   border" example. The border-left is reserved at 3px `transparent` in
 *   the normal state (not `0`) so the accent appearing on hover never
 *   shifts layout.
 * - the Product image tray's own border picks up the same red on hover,
 *   reinforcing the accent without touching the image asset, blend mode,
 *   or sizing (all explicitly protected — only the wrapper's border
 *   color changes).
 * - :focus-visible gets an explicit white outline — this project's usual
 *   --color-blue-link-dark focus-ring token is itself a dark navy and
 *   would be nearly invisible against this panel's own dark background,
 *   so --text-on-dark (white) is used here instead, scoped only to this
 *   dark panel; the site-wide focus-ring convention elsewhere is
 *   untouched. */
.site-header__mega-item {
	position: relative;
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 10px 12px;
	background: transparent;
	border: 1px solid var(--color-navy-raised);
	border-left: 3px solid transparent;
	border-radius: var(--radius-card);
	box-sizing: border-box;
	text-decoration: none;
	color: inherit;
	transition: background var(--transition-fast), border-color var(--transition-fast);
}

.site-header__mega-item:hover,
.site-header__mega-item:focus-visible {
	background: var(--color-navy);
	border-left-color: var(--color-red);
}

.site-header__mega-item:focus-visible {
	outline: 2px solid var(--text-on-dark);
	outline-offset: 2px;
}

.site-header__mega-item:hover .site-header__mega-item-name,
.site-header__mega-item:focus-visible .site-header__mega-item-name {
	color: var(--color-red);
}

.site-header__mega-item:hover .site-header__mega-item-image,
.site-header__mega-item:focus-visible .site-header__mega-item-image {
	border-color: var(--color-red);
}

/* Fix: the Product images previously looked
   like flat white icon-placeholders, not photos. Root cause (confirmed by
   sampling actual pixel alpha values, not assumed): the real Product
   photos have an OPAQUE white background baked into the file — they are
   not transparent cutouts — exactly like the images on the Home Product
   Range and Product Archive cards. Those cards make the same opaque-white
   photos look like deliberate product photography via `mix-blend-mode:
   multiply` on the <img> itself (see `.product-card__img` in home.css /
   archive-product.css) — a rule this Mega Menu was missing. Reproducing
   that exact treatment here: a wrapper span owns the tray background/
   border/radius/padding (`.site-header__mega-item-image`, matching
   `.product-card__image`'s own role) and the <img>
   (`.site-header__mega-item-img`, matching `.product-card__img`) owns
   object-fit + the blend mode, so it blends against the tray instead of
   sitting on it as a visible white square.
   Size increased from 48→60px — the brief's own "larger and more useful
   than currently, but should not dominate" — a visible but restrained
   step up, still well short of the Product grid's own 290px cards. */
.site-header__mega-item-image {
	width: 60px;
	height: 60px;
	flex-shrink: 0;
	background: var(--color-bg-tray); /* the existing product-photo tray color, reused as-is */
	border: 1px solid var(--color-navy-raised);
	border-radius: var(--radius-card);
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 8px;
	box-sizing: border-box;
	overflow: hidden;
	transition: border-color var(--transition-fast);
}

.site-header__mega-item-img {
	max-width: 100%;
	max-height: 100%;
	display: block;
	object-fit: contain;
	mix-blend-mode: multiply;
}

.site-header__mega-item-name {
	font-family: var(--font-primary);
	font-size: var(--fs-body-small);
	font-weight: var(--fw-bold);
	/* White — was --text-nav (a dark slate meant for the light header bar),
	   now on a dark navy panel where that color would be nearly invisible. */
	color: var(--text-on-dark);
	transition: color var(--transition-fast);
}

/* Moved inside .site-header__mega-grid (header.php) as its own grid cell —
 * previously a sibling block below the grid with its own border-top
 * divider, which left the 8th slot in the 7-product/4-column layout empty.
 * As a grid item it now naturally fills that slot (7 products + 1 CTA = 8
 * cells, exactly 2 full rows at 4 columns) instead of floating in unused
 * space below. It does NOT reuse .site-header__mega-item's own card
 * treatment (no image slot, no navy-tint hover) — a distinct bordered
 * action box, per the brief's own "does not need to look like another
 * product card" instruction, using --color-red as its own border/hover-fill
 * accent so it reads as the deliberate CTA, not an eighth product. Grid's
 * default align-items:stretch (unchanged, not overridden anywhere) already
 * matches its height to the row's tallest item, so it lines up with the
 * product cells beside it without any explicit height rule needed. */
.site-header__mega-panel .site-header__mega-viewall {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 10px 12px;
	box-sizing: border-box;
	border: 1px solid var(--color-red);
	border-radius: var(--radius-card);
	font-family: var(--font-primary);
	font-size: var(--fs-body-small);
	font-weight: var(--fw-extrabold);
	/* White/light label text, red reserved for the border/hover-fill
	   accent — the brief's own explicit fix for the previous all-red
	   label reading as too low-contrast against the navy panel. */
	color: var(--text-on-dark);
	text-decoration: none;
	transition: background var(--transition-fast), transform var(--transition-fast);
}

.site-header__mega-panel .site-header__mega-viewall:focus-visible {
	outline: 2px solid var(--text-on-dark);
	outline-offset: 2px;
}

.site-header__mega-panel .site-header__mega-viewall:hover,
.site-header__mega-panel .site-header__mega-viewall:focus-visible {
	background: var(--color-red);
	transform: translateX(2px);
}

/* Tablet: force exactly 2 columns instead of the auto-fill count (which
 * naturally lands on 3 columns through most of this range, still a
 * reasonably long grid for 7 products). Range boundaries reuse two
 * already-established values, not new ones — 769px is the exact mirror of
 * this file's own 768px hamburger breakpoint below (where the panel
 * becomes a static in-flow mobile accordion, not this dropdown), and
 * 1024px is --bp-tablet, the project's own existing tablet token already
 * used the same way (a plain max-width:1024px tablet cutoff) in
 * home.css/about.css/archive-product.css. Still the dark dropdown panel
 * here — only the mobile accordion below 769px changes surface color. */
@media (min-width: 769px) and (max-width: 1024px) {
	.site-header__mega-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

/* Fix — root cause of the Mega Menu
 * disappearing during mouse travel, confirmed by direct measurement
 * (getBoundingClientRect(), not assumed): the Products <li> is only as
 * tall as its own "Products ⌄" content (~22px) and sits vertically
 * CENTERED inside the ~78px header row, while the Mega Menu panel is
 * positioned at `top: 100%` of `.site-header__inner` — i.e. flush with
 * the very BOTTOM of the whole header row. That left a real ~27.5px
 * invisible gap between the bottom of the li's own hoverable box and the
 * top of the panel. Moving the pointer straight down from "Products" into
 * the panel crossed that gap, which belongs to neither element, firing
 * `mouseleave` on the li before the pointer ever reached the panel.
 *
 * Fix: make the Products <li> itself fill the header row's full height —
 * `.site-header__nav`/`.site-header__nav-list` are stretched to match
 * (harmless: they were already invisibly centered inside that same
 * height, so no other nav item's text moves), then the Products <li>
 * specifically is stretched to match and given `padding-bottom: 16px` —
 * the same literal value as `.site-header__inner`'s own
 * `padding-bottom` two rules above — closing the remaining gap down to
 * exactly where the panel begins. The pointer path from the trigger into
 * the panel is now geometrically continuous, so no JavaScript delay is
 * needed. Scoped to `min-width: 769px` (the exact mirror of the existing
 * 768px hamburger breakpoint below) since the panel is `position: static`
 * on mobile, where this gap does not exist. */
@media (min-width: 769px) {
	.site-header__nav {
		align-self: stretch;
	}

	.site-header__nav-list {
		height: 100%;
	}

	.site-header__nav-list li:has(> .site-header__mega-panel) {
		display: flex;
		align-items: center;
		/* height:100% (an explicit value, NOT align-self:stretch) resolves
		   against .site-header__nav-list's own definite height (itself
		   100% of the stretched .site-header__nav two rules above) — i.e.
		   exactly the header's content band, matching every other nav
		   item's own vertical center. padding-bottom then ADDS 16px of
		   invisible, hit-testable space beyond that (standard content-box
		   math: height is content height, padding is additional) —
		   closing the gap down to exactly where the Mega Menu panel
		   begins. align-self:stretch was tried first and rejected: it
		   treats the stretched size as a hard total-box target, so the
		   same padding-bottom got silently absorbed INTO that target
		   instead of adding beyond it — confirmed live while developing
		   this fix. 16px is not a guessed value — it is literally
		   .site-header__inner's own padding-bottom two rules above; if
		   that value is ever changed, this one must change with it.
		   Deliberately NOT position:relative on this <li>: the panel is a
		   direct DOM child of it, and the panel's own containing block
		   must stay .site-header__inner (for the 1200px-wide horizontal
		   span) — giving this <li> a position would make IT the panel's
		   containing block instead, collapsing the panel's width down to
		   this <li>'s own ~130px, also confirmed live. */
		height: 100%;
		padding-bottom: 16px;
		box-sizing: content-box;
		/* align-self:flex-start pins this <li>'s own TOP to match every
		   other nav item's top (nav-list's own align-items:center still
		   applies to them); without this, nav-list would center THIS
		   li's now-taller (61px) box within its own 45px band, pushing
		   its top 8px higher than the others instead of only extending
		   downward — confirmed live while developing this fix. */
		align-self: flex-start;
	}
}

/* ---- Responsive ----
 * The approved design has no @media queries at all (desktop-only static
 * export, confirmed by grep across the whole design folder) beyond its
 * own flex-wrap:wrap on the header row. A collapsing hamburger menu below
 * is not a design-sourced behavior — it's the minimal, standard
 * accessible pattern (aria-expanded, accessible menu button). --bp-mobile
 * (768px) matches this project's already-established convention: nav +
 * CTA visible on desktop AND tablet, collapsing to a toggle only below
 * mobile. */
@media (max-width: 768px) {
	.site-utility-bar__inner {
		padding: 8px var(--gutter-mobile);
		flex-wrap: wrap;
		row-gap: 4px;
	}

	.site-header__inner {
		padding: 14px var(--gutter-mobile);
		/* Fix: reduced from the unconditional
		   20px (--gap-grid-4col) so Logo + CTA + Hamburger have enough
		   combined room to stay on one row instead of the hamburger
		   wrapping to its own line — see the mobile CTA's own reduced
		   padding/font-size below, the other half of this fix. Does not
		   affect the gap used when .site-header__nav wraps onto its own
		   row when the mobile menu is open (that row has no siblings on
		   it, so gap has no visible effect there). */
		gap: 10px;
	}

	/* Mobile keeps the crop wrapper's WIDTH
	   fixed at 126px — the exact footprint the logo already had —
	   rather than growing it the way desktop does,
	   specifically to avoid regressing the one-row Logo + CTA + Hamburger
	   layout (mobile horizontal space is the
	   scarce resource there, unlike desktop). Height shrinks to match
	   that width at the visible mark's own 540:92 aspect ratio: scale =
	   126 / 540 = 0.233333 → full image at this scale 145.83×48.53px;
	   visible region within it: left 4.67px, top 11.67px, width 126px
	   (= wrapper width), height 21.47px (= wrapper height). Net effect:
	   same on-screen width as before, a tighter (and therefore slightly
	   taller-looking, better-filled) mark within it. */
	.site-header__logo-crop {
		width: 126px;
		height: 21.47px;
	}

	.site-header__logo-crop img {
		width: 145.83px;
		height: 48.53px;
		margin-top: -11.67px;
		margin-left: -4.67px;
	}

	.site-header__menu-toggle {
		display: block;
		order: 3;
		/* Prevents the icon from shrinking if space is ever tight —
		   pairs with the CTA being the one element that flexes down. */
		flex-shrink: 0;
	}

	.site-header__nav {
		order: 4;
		flex-basis: 100%;
		display: none;
	}

	.site-header.is-menu-open .site-header__nav {
		display: block;
	}

	.site-header__nav-list {
		flex-direction: column;
		align-items: flex-start;
		gap: 16px;
		padding: 20px 0 8px;
	}

	.site-header__cta {
		order: 2;
		/* Fix: the desktop size
		   (--pad-button-compact: 13px 28px, --fs-body-small: 14px) left no
		   room for Logo + CTA + Hamburger to fit on one row at any tested
		   mobile width — confirmed live (the hamburger measurably wrapped
		   to its own second row). Reduced here to a one-off compact size;
		   --fs-micro (11px) is an existing token, reused rather than
		   invented. Wording ("Talk to the Team") and an adequate ~34px
		   tap-target height are both preserved — only physical size
		   shrinks. */
		padding: 8px 12px;
		font-size: var(--fs-micro);
		flex-shrink: 0;
	}

	/* ---- Products Mega Menu: mobile ----
	 * Reuses the exact same markup as the desktop dropdown (no second
	 * mobile-only panel, no second hamburger, no separate mobile nav
	 * system) — only its own layout changes, from an absolutely-positioned
	 * dropdown to a plain in-flow expandable submenu inside the existing
	 * mobile nav list, matching the design's own mockup: "Products ▼"
	 * becomes "Products ▲ / Cartridge Heaters / Band Heaters / ... /
	 * View All Products" when expanded. */
	/* Scoped to only the "Products" <li> (the one that actually contains a
	   Mega Menu panel) — not every nav item — via :has(), so no other nav
	   item's layout changes. A column-flex item without this would only be
	   as wide as its own "Products" text, cramping the expanded submenu
	   below it into that same narrow width. */
	.site-header__nav-list li:has(> .site-header__mega-panel) {
		width: 100%;
	}

	.site-header__mega-panel {
		position: static;
		margin-top: 12px;
		border: 0;
		box-shadow: none;
		padding: 0 0 0 16px;
		background: transparent;
	}

	.site-header__mega-panel::before {
		/* No grid texture on mobile — the panel here is transparent and
		   in-flow inside the header's own light bar, not the dark boxed
		   panel the texture is designed for. */
		content: none;
	}

	.site-header__mega-eyebrow {
		margin-bottom: 10px;
	}

	.site-header__mega-grid {
		grid-template-columns: 1fr;
		/* 4px — a compact list rhythm; each row is still clearly separated by
		   its own border below, so the gap itself doesn't need to carry all
		   the separation on its own. */
		gap: 4px;
	}

	/* This is a compact NAVIGATION LIST here, not seven standalone cards —
	   padding/gap/image size all reduced from the previous pass (which was
	   still reading as oversized rows), and the border switches from the
	   desktop panel's --color-navy-raised (a dark navy line meant for the
	   dark dropdown) to --border-light — this project's own standard
	   restrained divider token, already used the same way for plain list
	   separators elsewhere (e.g. Quality's checklist items). :active is
	   handled alongside :focus-visible since :hover is unreliable on touch. */
	.site-header__mega-item {
		gap: 10px;
		padding: 6px 10px;
		border-color: var(--border-light);
	}

	/* Text/hover colors flip back to their light-background values here —
	   the desktop panel above is a dark boxed dropdown, but on mobile the
	   Products submenu is in-flow and transparent, sitting directly on the
	   header's own light bar (see .site-header's own near-white
	   background), so the dark-panel white text/navy hover from the base
	   rules above would be unreadable here. */
	.site-header__mega-item-name {
		color: var(--text-nav);
	}

	.site-header__mega-item:hover,
	.site-header__mega-item:focus-visible,
	.site-header__mega-item:active {
		background: color-mix(in srgb, var(--color-navy) 7%, var(--color-bg-white));
		border-left-color: var(--color-red);
	}

	.site-header__mega-item:active .site-header__mega-item-name {
		color: var(--color-red);
	}

	/* Focus ring flips back to the site-wide dark-on-light convention here,
	   for the same reason the text/hover colors do above — the base
	   white-on-dark ring would be invisible against this light context. */
	.site-header__mega-item:focus-visible,
	.site-header__mega-panel .site-header__mega-viewall:focus-visible {
		outline-color: var(--color-blue-link-dark);
	}

	.site-header__mega-item-image {
		/* 30px, down from 36px — still clearly a recognizable product photo,
		   just matching the tighter list rhythm above. */
		width: 30px;
		height: 30px;
		padding: 5px;
	}

	/* Reverts the desktop boxed-CTA treatment (red border/pill, centered)
	   to a plain left-aligned list row with a top divider — matching the
	   product rows above it rather than floating as a separate button, per
	   the brief's own "navigation list, not seven cards" direction applied
	   to this row too. Text is red at rest (readable on this light
	   background, same as the previous pass); on hover/focus/active the
	   fill still goes solid red (inherited target color from the base
	   rule), so the label flips to white here to stay readable against it. */
	.site-header__mega-panel .site-header__mega-viewall {
		width: 100%;
		justify-content: flex-start;
		border: 0;
		border-top: 1px solid var(--border-light);
		border-radius: 0;
		margin-top: 4px;
		padding: 10px 10px 6px;
		color: var(--color-red);
	}

	.site-header__mega-panel .site-header__mega-viewall:hover,
	.site-header__mega-panel .site-header__mega-viewall:focus-visible,
	.site-header__mega-panel .site-header__mega-viewall:active {
		background: var(--color-red);
		color: var(--text-on-dark);
	}
}
