/* ==========================================================================
   ITV STORE — HEADER (loaded on every template; header is a global part)
   ========================================================================== */

/* 0.1.27/0.1.28: two white horizontal gaps were visible — between
   .itv-utility and .itv-header, and between .itv-header and .itv-navbar.

   ROOT CAUSE, confirmed directly against the live DOM's actual matched CSS
   rules (not assumed): WordPress's global-styles engine injects
   ":root :where(.is-layout-flow) > * { margin-block: 1.75rem 0px; }"
   (theme.json's sitewide styles.spacing.blockGap) into an inline stylesheet
   printed in <head>. ".itv-site-header" (parts/header.html) is a
   "layout":{"type":"default"} (flow) group with no blockGap override, so
   its three children — .itv-utility, .itv-header, .itv-navbar — each get
   margin-block-start: 1.75rem (28px) from that rule. The visible "white" is
   the page's own background showing through that margin, not a colored
   element.

   0.1.27 ATTEMPTED TWO FIXES, BOTH CONFIRMED INEFFECTIVE ON LIVE, WITH THE
   EXACT REASON WHY:
   1. parts/header.html's outer group was given
      "style":{"spacing":{"blockGap":"0"}}, expected to render as an inline
      style="--wp--style--block-gap:0" on <header class="itv-site-header">.
      Confirmed via live DOM inspection: that inline style attribute is
      simply absent from the rendered markup — WordPress's block-supports
      style engine did not apply it the way a hand-authored static block
      template part apparently needed it to (unlike blocks placed through
      the actual block editor, which get this generated for them).
   2. This file's own ".itv-site-header, .itv-utility, .itv-header,
      .itv-navbar { margin: 0; }" WAS confirmed present and loading
      correctly (verified via a cache-bypassed fetch of the live, deployed
      CSS bundle) — it simply LOST the cascade. ":root :where(.is-layout-
      flow) > *" and a plain ".itv-header" selector have the EXACT SAME
      specificity (0,1,0) — :root counts as one pseudo-class, :where()
      always contributes zero, and a single class also equals one. With
      equal specificity, whichever rule is later in the merged/bundled
      stylesheet order wins, and WordPress's rule was winning that coin
      flip. This was a genuine specificity tie, not a deployment failure —
      confirmed by matching the live element against every stylesheet rule
      that touches its margin.

   REAL FIX below: a selector with deliberately HIGHER specificity —
   two classes via a direct child combinator — that beats WordPress's rule
   outright regardless of stylesheet order, with no !important needed.

   0.1.31: .itv-header and .itv-navbar are no longer DIRECT children of
   .itv-site-header — they're now wrapped in .itv-sticky-wrap (added this
   release for the single-sticky-wrapper behavior below), so
   ".itv-site-header > .itv-header" no longer matches anything and would
   have silently let the exact same white-gap bug back in. Updated to
   match the new nesting, and .itv-sticky-wrap itself — now the second
   direct child of .itv-site-header, after .itv-utility — needs the same
   treatment, since it's just as subject to the sitewide blockGap rule as
   .itv-header/.itv-navbar were.

   0.1.34: .itv-sticky-placeholder (new this release, see the fixed-on-
   scroll rule further down) is a third direct child of .itv-site-header
   and needs the exact same treatment — without it, the sitewide blockGap
   rule would give it a 28px top margin, reintroducing this same white-gap
   bug on the new element. */
.itv-site-header > .itv-utility,
.itv-site-header > .itv-sticky-wrap,
.itv-site-header > .itv-sticky-placeholder,
.itv-sticky-wrap > .itv-header,
.itv-sticky-wrap > .itv-navbar {
	margin: 0;
}

/* 0.1.29: a second, separate white gap remained — between the header
   template part and the page's own content — after 0.1.28 fixed the three
   gaps *inside* the header. Same underlying mechanism (WordPress's
   sitewide theme.json blockGap, this time applied one level up: every
   direct child of <div class="wp-site-blocks"> after the first gets
   margin-block-start via ":where(.wp-site-blocks) > * { margin-block:
   1.75rem 0px; }" — confirmed by walking the live stylesheet rules that
   matched the actual next element on each page type).

   That "first content element after the header" is NOT the same element on
   every page type — confirmed live on all three requested page types:
     - Homepage (templates/front-page.html / index.html): <main id="main">
     - Product page (WooCommerce's classic single-product template):
       <div class="woocommerce-notices-wrapper">, which sits BEFORE #main
     - Category archive (WooCommerce's ClassicTemplate archive render,
       which never uses a <main> wrapper at all — see the 0.1.17
       admin-safety-audit.md finding): <header class="woocommerce-products-header">
   Naming each of those three specifically would be fragile (a future
   WooCommerce or plugin change could introduce yet another first element).
   Targeting the ADJACENCY itself instead is general and correct regardless
   of what that first element turns out to be: */
.wp-site-blocks > header.wp-block-template-part + * {
	margin-block-start: 0;
}

/* 0.1.36: white/light theme replacing black/dark — see CHANGELOG.md 0.1.36.
   Yellow is used as an underline/background accent throughout this file,
   never as text color on a light background: solid #FEDC23 text on white
   is roughly 1.6:1 contrast, well under WCAG's 4.5:1 (text) / 3:1
   (UI component) minimums. Where the approved design calls for a yellow
   hover accent, it's paired with dark text plus an underline, or replaced
   with #B89B00 (a darker, accessible yellow) — same technique used
   throughout footer.css. */
.itv-utility { background: #F5F5F5; color: #333333; border-bottom: 1px solid #E6E6E6; font-size: 12.5px; }
.itv-utility .itv-utility-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 36px; max-width: 1320px; margin-inline: auto; padding-inline: var(--pad-inline); }
.itv-utility .u-left, .itv-utility .u-right { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.itv-utility a { color: inherit; }
.itv-utility a:hover { color: #0B0B0B; text-decoration: underline; text-decoration-color: var(--c-yellow); text-decoration-thickness: 2px; }
.itv-utility .icon { width: 14px; height: 14px; color: #555555; }

/* 0.1.34: position:sticky is no longer used at all. 0.1.31-0.1.33 each
   confirmed the theme's OWN sticky CSS was correct on the origin server,
   but production repeatedly served it from a stale cached copy — first
   Hostinger's hCDN, then a database-level template-part override, then
   LiteSpeed's separate CSS Combine/Minify optimizer cache (see
   CHANGELOG.md 0.1.28/0.1.32/0.1.33) — three different caching layers,
   each requiring its own workaround. Rather than keep chasing a fourth
   possible cache layer, .itv-sticky-wrap is now fixed-on-scroll instead:
   plain position:relative at rest, switched to position:fixed by
   assets/js/itv-sticky-header-v2.js once the user has scrolled past the
   utility bar, with a placeholder element holding its vacated space so
   the page never jumps. This has no dependency on how any layer chooses
   to cache the CSS.

   Normal (in-flow) state — no ancestor of this element has any transform,
   filter, perspective, or contain property (re-verified 0.1.33; nothing
   in base.css/style.css touches an ancestor of .itv-site-header), so a
   later position:fixed on .itv-is-fixed is guaranteed relative to the
   viewport, not a transformed ancestor. */
.itv-sticky-wrap {
	position: relative;
	width: 100%;
}

/* Fixed state — added by JS only, never by CSS alone. Shadow lightened
   0.1.34's rgba(0,0,0,.14) -> rgba(0,0,0,.08) for the white theme, per
   instruction — a shadow tuned for a dark header read as too heavy once
   the header itself turned white. */
.itv-sticky-wrap.itv-is-fixed {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	width: 100%;
	z-index: 9999;
	box-shadow: 0 4px 14px rgba(0,0,0,.08);
}

/* Admin bar: only relevant once .itv-is-fixed is applied — in normal flow
   the wrapper is already correctly positioned below the admin bar via
   WordPress's own "html { margin-top }" push, same as every other
   in-flow element on the page. 782px matches WordPress core's own
   admin-bar breakpoint (wp-admin/css/admin-bar.min.css), not an
   arbitrary value. */
body.admin-bar .itv-sticky-wrap.itv-is-fixed { top: 32px; }
@media (max-width: 782px) {
	body.admin-bar .itv-sticky-wrap.itv-is-fixed { top: 46px; }
}

/* Spacer that takes over the wrapper's vacated in-flow space the instant
   it goes position:fixed, so nothing below it jumps upward. Height is set
   by JS (measured from the real, rendered header) — 0 whenever the header
   is not fixed. */
.itv-sticky-placeholder { height: 0; }

/* Normal, non-fixed children of the wrapper — explicit so neither can
   independently acquire its own position:sticky/fixed again. Only
   .itv-sticky-wrap.itv-is-fixed owns fixed positioning. */
.itv-header, .itv-navbar { position: relative; }

.itv-header { background: #FFFFFF; color: #0B0B0B; border-bottom: 1px solid #E7E7E7; }
/* 0.1.31: reduced from min-height:86px — that value, combined with a bug
   in itv_store_shortcode_header_actions() (stray <br> tags from wpautop
   inflating .itv-header-actions to ~120px, fixed this release in
   inc/shortcodes.php), was producing a ~120px-tall row in practice. With
   that bug fixed, .itv-header-actions/.itv-logo/.itv-search naturally sit
   well under 100px, so min-height is now the actual controlling value.
   0.1.37: 100px -> 92px — density pass (measured combined header+nav at
   156px live; target ~142px). Logo/search/actions aren't cramped by this —
   none of their own intrinsic heights (62px logo, 44px search after the
   change below) are close to 92px. */
.itv-header-row { display: flex; align-items: center; gap: 20px; min-height: 92px; max-width: 1320px; margin-inline: auto; padding-inline: var(--pad-inline); }
.itv-logo { flex: 0 0 auto; display: inline-flex; align-items: center; line-height: 0; }
/* 0.1.36: itv-logo-black.avif is 400x146 intrinsic (2.74:1) — 62px height
   lands desktop visual width at ~170px, the middle of the requested
   150-190px range. width:auto preserves the ratio exactly; the aspect
   ratio is never set explicitly in pixels so it can't be distorted. */
.itv-logo img { height: 62px; width: auto; }

/* Request a Quote — moved from the category nav into the main header row,
   far right (spec: #FEDC23 bg, #0B0B0B text, ~45px height, 7px radius,
   800 weight). Hidden below 782px — same breakpoint the mobile burger
   already appears at — since the mobile menu overlay has its own
   Request a Quote button (.mm-actions .btn-primary, inc/shortcodes.php's
   itv_store_shortcode_mobile_menu(), unchanged) so the mobile header
   itself never has to fit both a hamburger and a full CTA button. */
.itv-header-quote-cta {
	display: inline-flex; align-items: center; justify-content: center;
	height: 45px; padding: 0 20px; flex: 0 0 auto;
	background: var(--c-yellow); color: var(--c-black);
	font-family: var(--font-head); font-weight: 800; font-size: 14px;
	border-radius: 7px; text-decoration: none; white-space: nowrap;
	transition: background .15s ease;
}
.itv-header-quote-cta:hover { background: #ffe666; }
@media (max-width: 782px) { .itv-header-quote-cta { display: none; } }

/* Reserve space so the sticky header never causes layout shift once JS/
   images settle — matches the "no CLS" requirement in the Phase 4 brief. */
.itv-header, .itv-utility { contain: layout; }

/* 0.1.37: explicit height:44px added — measured live at 64-65px before
   this change, despite no explicit height rule anywhere; align-items:
   stretch on an unconstrained <input>/<button> pair let the browser's own
   form-control intrinsic sizing determine the box height implicitly,
   which is what produced 64-65px. An explicit height is deterministic
   regardless of that mechanism and matches the 42-46px target. */
.itv-search { flex: 1 1 auto; max-width: 640px; height: 44px; display: flex; align-items: stretch; border: 1px solid #DCDCDC; border-radius: var(--radius-btn); overflow: hidden; background: #F7F7F7; }
.itv-search input { flex: 1 1 auto; border: 0; background: transparent; color: #0B0B0B; padding: 0 16px; font-size: 14.5px; font-family: var(--font-body); }
.itv-search input::placeholder { color: #707070; }
.itv-search input:focus { outline: none; }
.itv-search:focus-within { border-color: var(--c-yellow); box-shadow: 0 0 0 3px rgba(254,220,35,.35); }
.itv-search button { flex: 0 0 auto; width: 52px; border: 0; background: var(--c-yellow); color: var(--c-black); display: flex; align-items: center; justify-content: center; cursor: pointer; }

.itv-header-actions { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.itv-action { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 6px 10px; border-radius: 8px; position: relative; color: #0B0B0B; background: none; border: 0; font-family: var(--font-body); cursor: pointer; }
.itv-action:hover { background: #F5F5F5; }
/* #B89B00 (dark yellow), not the brand yellow #FEDC23 — see the file-top
   accessibility note; a small icon is still a "graphical object essential
   to understanding" under WCAG 1.4.11 and #FEDC23 doesn't clear 3:1 on
   white. */
.itv-action:hover .icon { color: #B89B00; }
.itv-action .icon { width: 21px; height: 21px; }
.itv-action .lbl { font-size: 10.5px; font-weight: 600; color: #555555; }
.itv-action .count { position: absolute; top: 0; right: 4px; background: var(--c-yellow); color: var(--c-black); font-family: var(--font-head); font-weight: 800; font-size: 10px; width: 17px; height: 17px; border-radius: 50%; display: flex; align-items: center; justify-content: center; }

.itv-navbar { background: #FFFFFF; border-top: 1px solid #EAEAEA; border-bottom: 1px solid #EAEAEA; }
/* 0.1.37: min-height:50px added (was content-driven only, measuring
   54-56px live) — the row's own height came entirely from .itv-nav a's
   padding below, now trimmed 15px->13px vertical to match. Desktop-only
   (this nav is hidden below 782px), so no mobile tap-target impact. */
.itv-navbar .itv-navbar-row { display: flex; align-items: center; justify-content: space-between; gap: 20px; min-height: 50px; max-width: 1320px; margin-inline: auto; padding-inline: var(--pad-inline); }
.itv-nav { display: flex; align-items: center; gap: 2px; flex-wrap: wrap; }
.itv-nav a { display: inline-flex; align-items: center; padding: 13px 14px; font-family: var(--font-head); font-weight: 600; font-size: 14px; color: #161616; border-bottom: 2px solid transparent; text-decoration: none; }
.itv-nav a:hover { color: #0B0B0B; border-bottom-color: var(--c-yellow); }
.itv-nav a[aria-current="page"] { color: #0B0B0B; border-bottom-color: var(--c-yellow); }
/* 0.1.31: the "Request a Quote" button that used to live in .itv-navbar
   (styled via ".itv-navbar .btn") moved to the main header row — see
   .itv-header-quote-cta above. Nothing with class .btn remains inside
   .itv-navbar now. */

/* 0.1.36: color was #fff (white-on-white, invisible) before the header
   went white — caught via live testing of the approved preview, not just
   inferred from the color swap. */
.itv-burger { display: none; align-items: center; justify-content: center; width: 44px; height: 44px; border: 0; background: transparent; color: #0B0B0B; cursor: pointer; }
.itv-burger:hover { background: #F5F5F5; border-radius: 8px; }

/* Hides at the exact same breakpoint the hamburger/mobile search appears
   (782px, immediately below) — not a wider one. A gap between these two
   values would leave a range with no visible way to search at all. */
@media (max-width: 782px) { .itv-search { display: none; } }

@media (max-width: 782px) {
	.itv-header-row { min-height: 68px; gap: 10px; }
	/* 47px height -> ~129px visual width at this logo's 2.74:1 ratio, inside
	   the requested 120-145px mobile range (see the desktop note above). */
	.itv-logo img { height: 47px; }
	.itv-navbar { display: none; }
	.itv-utility { display: none; }
	.itv-burger { display: inline-flex; order: -1; }
	/* Visually hidden, not display:none — the icon has aria-hidden="true",
	   so this label is each link's only accessible name. Hiding it with
	   display:none removed it from the accessibility tree too, leaving
	   these three header links with no discernible name on mobile. */
	.itv-action .lbl {
		position: absolute !important;
		width: 1px; height: 1px;
		padding: 0; margin: -1px;
		overflow: hidden;
		clip: rect(0, 0, 0, 0);
		white-space: nowrap;
		border: 0;
	}
	.itv-header-actions { gap: 2px; }
}

/* ---- mobile overlay menu ---- */
/* 0.1.33: z-index raised 1000 -> 10000 so this fullscreen overlay still
   covers .itv-sticky-wrap (raised to 9999 this release) when open — it
   must stay above the sticky header, not under it. */
.itv-mobile-menu { position: fixed; inset: 0; background: var(--c-black); color: #fff; z-index: 10000; display: none; flex-direction: column; padding: 18px clamp(20px, 6vw, 40px) 32px; overflow-y: auto; }
.itv-mobile-menu.is-open { display: flex; }
.itv-mobile-menu .mm-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 22px; }
.itv-mobile-menu .mm-close { background: none; border: 0; color: #fff; width: 40px; height: 40px; cursor: pointer; }
.itv-mobile-menu .mm-search { display: flex; border: 1px solid rgba(255,255,255,.18); border-radius: var(--radius-btn); margin-bottom: 24px; background: rgba(255,255,255,.04); }
.itv-mobile-menu .mm-search input { flex: 1; background: none; border: 0; color: #fff; padding: 12px 14px; }
.itv-mobile-menu .mm-search button { border: 0; background: var(--c-yellow); width: 48px; color: var(--c-black); cursor: pointer; }
.itv-mobile-menu ul { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }
.itv-mobile-menu li { border-bottom: 1px solid rgba(255,255,255,.08); }
.itv-mobile-menu a { display: flex; align-items: center; justify-content: space-between; padding: 16px 2px; font-family: var(--font-head); font-weight: 700; font-size: 17px; color: #fff; text-decoration: none; }
.itv-mobile-menu a .icon { color: var(--c-yellow); width: 18px; height: 18px; }
.itv-mobile-menu .mm-actions { display: flex; gap: 10px; margin-top: 24px; }
.itv-mobile-menu .mm-actions .btn { flex: 1; }

/* Body scroll lock while the mobile menu is open — applied/removed by JS. */
body.itv-menu-open { overflow: hidden; }

/* ==========================================================================
   0.1.39 — DESKTOP DENSITY (>=1024px only)
   Approved "NEW 55-60%" tier — target: the desktop store at 100% browser
   zoom should feel approximately like the previous site at ~55% browser
   zoom. Supersedes 0.1.38's "COMPACT 75-80%" values below (this is a
   replacement of that single block's content, not a second competing
   block — per explicit instruction, "do not enqueue previous and new
   versions together" applies to the CSS rules themselves too, not just
   the file). See previews/store-55-density-preview.html (approved) and
   the equivalent note in base-v3.css for the full rationale. Everything
   above this block (0.1.36/0.1.37 values) is the unconditional baseline,
   serving 768-1023px tablet sizing; <782px is governed entirely by the
   existing @media(max-width:782px) block above, untouched — mobile is
   explicitly excluded from this density tier per instruction.

   The fixed-on-scroll mechanism itself (.itv-sticky-wrap/.itv-is-fixed/
   .itv-sticky-placeholder above, assets/js/itv-sticky-header-v2.js) is
   completely untouched by this block — the JS measures
   stickyWrap.offsetHeight at runtime, so the new ~98px combined
   header+nav height (was ~120px) is picked up automatically with no JS
   change needed. */
@media (min-width: 1024px) {
	.itv-utility { min-height: 23px; font-size: 11.5px; }
	.itv-utility .itv-utility-row { min-height: 23px; }
	.itv-utility .icon { width: 11px; height: 11px; }

	.itv-header-row { min-height: 62px; gap: 14px; }
	/* ~115px visual width at this logo's 2.74:1 ratio. */
	.itv-logo img { height: 42px; }

	.itv-search { height: 33px; }
	.itv-search input { font-size: 12.5px; padding: 0 10px; }
	.itv-search button { width: 34px; }
	.itv-search button .icon { width: 14px; height: 14px; }

	.itv-action .icon { width: 19px; height: 19px; }
	.itv-action .lbl { font-size: 10.5px; }
	.itv-header-actions { gap: 2px; }

	.itv-header-quote-cta { height: 35px; padding: 0 13px; font-size: 11.5px; }

	.itv-navbar .itv-navbar-row { min-height: 36px; }
	.itv-nav a { padding: 7px 9px; font-size: 11.5px; }
}
