/*
 * Scott Pool 2026 -- header & navigation (Phase 2A).
 *
 * Targets the block markup in parts/header.html: a Group(header) > Group
 * (.sp-header__inner) containing the logo paragraph, the core Navigation
 * block (.sp-nav), and a Group of header actions (.sp-header__actions).
 * All values reference tokens from theme.json (--wp--preset--*) or
 * assets/css/tokens.css -- no new colors, fonts, shadows, radii or spacing
 * introduced here.
 *
 * One rule per selector per breakpoint -- duplicate rules for the same
 * selector across separate media blocks is exactly how an earlier pass of
 * this file went wrong (a later, forgotten duplicate silently overrode an
 * intended fix). Keep it that way on any future edit.
 */

/* ===== Header shell ===== */

/* Sticky positioning lives on the OUTER wrapper WordPress always generates
   around a template part (`header.wp-block-template-part`), not on
   .sp-header itself. .sp-header's own parent is exactly as tall as the
   header's content, giving a sticky child no room to stick within it; the
   wrapper's parent (.wp-site-blocks) spans the full page, which is what a
   sticky header actually needs. :has() scopes this to the header's own
   wrapper only -- the footer's template-part wrapper carries the same
   generic class and must stay unaffected. */
header.wp-block-template-part:has(> .sp-header) {
	position: sticky;
	top: 0;
	z-index: 50;
}

.sp-header {
	background: var(--wp--preset--color--white);
	border-bottom: var(--border-width-hairline) solid var(--wp--preset--color--divider);
	transition: box-shadow var(--duration-base) var(--ease-out);
}
.sp-header.is-scrolled {
	box-shadow: var(--shadow-header);
}

.sp-header__inner {
	/* Wide token (theme.json's wideSize, 1440px, same value as tokens.css's
	   --container-wide), not --container-max (1200px, the body content
	   width) -- the header row alone was noticeably narrower than the
	   viewport at desktop widths above ~1200px, leaving excess unused side
	   space next to the brand block and Donate button. Scoped to the header
	   only; page/body content still uses --container-max via .sp-container. */
	max-width: var(--container-wide);
	margin: 0 auto;
	padding: 0 var(--gutter-m);
	min-height: var(--header-height-m);
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--4);
	transition: min-height var(--duration-base) var(--ease-out);
}

/* .sp-header__inner is a wp-block-group whose block-editor layout type is
   still "flow" (stamped `is-layout-flow` in markup) even though this file
   overrides it to `display:flex` above -- core doesn't know that, so it
   still applies its flow-layout block-gap rule
   (`:where(.is-layout-flow) > *`, zero specificity but real margin) as
   margin-block-start on every child after the first. On a flex row with
   align-items:center, that lopsided margin (32px top, 0 bottom) shifts
   the nav and the actions group down out of true vertical center with the
   brand block, which has no such margin (it's the first child, exempted
   by core's own `:first-child` rule) -- confirmed via computed-style
   inspection: brand block centered at the row's true midpoint, nav and
   actions both sitting 16px low. Zeroing it here restores real centering
   without touching align-items. Applies at every width, so it fixes the
   same misalignment in the mobile header row too (logo/hamburger/Donate
   are the same three flex children there). */
.sp-header__inner > * {
	margin-block-start: 0;
}

/* Desktop breakpoint (>=1024px, bp-lg -- matches the design system's own
   "desktop nav appears" breakpoint). The design system's full spacing
   (32px inner gaps, 18px/space-8 nav gaps) is sized for a wide desktop nav
   with room to spare. This campaign's real 7-label set (Meet Scott / Issues
   & Vision / About the Office / Volunteer / Contact / Blog / Events) plus
   the logo plate and Donate button doesn't fit inside the 1200px container
   at that scale, at ANY viewport width, because the container itself never
   exceeds 1200px. Reusing smaller steps already on the same token scale
   (never a new value) is what actually fits. */
@media (min-width: 1024px) {
	.sp-header__inner {
		padding: 0 var(--gutter);
		min-height: var(--header-height);
		gap: var(--wp--preset--spacing--3);
	}
	.sp-header.is-scrolled .sp-header__inner {
		min-height: var(--header-height-scrolled);
	}

	.sp-logo a {
		padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--3);
		gap: var(--wp--preset--spacing--2);
	}

	/* Safety net, not the primary fix: if a future label change still
	   doesn't fit, the nav scrolls within itself instead of ever causing
	   page-level horizontal overflow. Flex items default to
	   min-width:auto (won't shrink below their content's intrinsic
	   width), which silently defeats overflow-x on a descendant --
	   .sp-nav needs min-width:0 explicitly for the overflow-x below to
	   ever actually engage. */
	.sp-nav {
		flex: 1 1 auto;
		min-width: 0;
	}
	.sp-nav .wp-block-navigation__responsive-container,
	.sp-nav .wp-block-navigation__responsive-container-content {
		min-width: 0;
		max-width: 100%;
	}
	.sp-nav .wp-block-navigation__responsive-container-content {
		overflow-x: auto;
	}
}

/* ===== Logo / brand plate ===== */

.sp-logo {
	margin: 0;
	flex-shrink: 0;
}
.sp-logo a {
	display: inline-flex;
	align-items: center;
	gap: var(--wp--preset--spacing--3);
	background: var(--wp--preset--color--primary-navy);
	color: var(--wp--preset--color--white);
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--5);
	border-top: var(--border-width-rule) solid var(--wp--preset--color--campaign-red);
	border-bottom: var(--border-width-rule) solid var(--wp--preset--color--campaign-red);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--body-sm);
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	text-decoration: none;
	white-space: nowrap;
	transition: color var(--duration-fast) var(--ease-out);
}
.sp-logo a::before,
.sp-logo a::after {
	content: "\2605"; /* ★ -- decorative, matches the design system's aria-hidden star spans */
	font-size: 12px;
	line-height: 1;
}
.sp-logo a:hover {
	color: var(--wp--preset--color--white);
}

/* Base rule for .sp-header__donate-wrap lives here, ahead of the
   max-width:460px override below -- both are single-class selectors of
   equal specificity, so source order decides the tie. Keeping the
   unconditional rule first lets the 460px media query's display:none
   actually win at that width instead of being silently overridden by
   this rule loading later (the exact failure mode this file's own
   header comment warns about). */
.sp-header__donate-wrap {
	display: flex;
}

/* Logo + burger + Donate genuinely don't fit in one row at full size below
   desktop width -- found by testing, not assumed. Below 1024px the plate's
   horizontal padding tightens (never touches the text itself); below
   429px it also drops the two decorative stars (aria-hidden, matches the
   design system's own "decorative by default" rule for stars/icons) and
   the header's own gaps tighten one more step, all reusing existing spacing
   tokens. */
@media (max-width: 1023px) {
	.sp-logo a {
		padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--3);
		gap: var(--wp--preset--spacing--2);
	}
	.sp-header__inner {
		gap: var(--wp--preset--spacing--2);
	}
	.sp-header__actions {
		gap: var(--wp--preset--spacing--2);
	}
}
/* Below 460px, logo + burger + Donate no longer fit in one row even with
   every other tightening applied above (measured, not assumed -- the full
   "VOTESCOTTPOOL.COM" wordmark alone needs ~200px+ at the smallest token
   size available). Rather than shrink the wordmark below the design
   system's type scale or wrap the header to two rows, the top-bar Donate
   button steps aside: Donate is already duplicated inside the mobile
   drawer (.sp-nav__drawer-actions, added when the wp_navigation entity was
   created), so it stays one tap away via the burger, and the top row never
   crowds. */
@media (max-width: 460px) {
	.sp-logo a {
		padding: var(--wp--preset--spacing--1) var(--wp--preset--spacing--2);
	}
	.sp-logo a::before,
	.sp-logo a::after {
		content: none;
	}
	/* Full ancestor-chain selector, not just .sp-header__donate-wrap alone
	   (Phase 4B fix) -- core stamps an auto-generated `.is-layout-flex`
	   class onto every Buttons block (confirmed present on this exact
	   element: wp-block-buttons sp-header__donate-wrap is-layout-flex...),
	   which out-specifies a plain single-class rule regardless of source
	   order, exactly the same gotcha this file already solves for
	   .sp-nav__drawer-actions below. This was silently never hiding the
	   button below 460px, causing real horizontal overflow on small
	   phones -- verified via computed-style inspection, not assumed. */
	.sp-header .sp-header__actions .sp-header__donate-wrap {
		display: none;
	}
}

/* ===== Header actions (Donate + burger) ===== */

.sp-header__actions {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--3);
	flex-shrink: 0;
}

/* sp-header__donate: header CTA is always the "sm" button size regardless of
   viewport -- matches SiteHeader's own `<Button size="sm">` in the source. */
.sp-header__donate .wp-block-button__link {
	min-height: var(--touch-min);
	padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--5);
	font-size: var(--wp--preset--font-size--body-sm);
}

/* ===== Button block style variations (core/button) =====
   Registered via register_block_style() in functions.php; reusable by every
   future phase, not just the header. */

.wp-block-button.is-style-sp-primary .wp-block-button__link {
	background: var(--wp--preset--color--campaign-red);
	color: var(--wp--preset--color--white);
	border-radius: var(--radius-none);
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	min-height: var(--touch-min);
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--8);
	transition: background-color var(--duration-base) var(--ease-out), transform var(--duration-base) var(--ease-out);
}
.wp-block-button.is-style-sp-primary .wp-block-button__link:hover {
	background: var(--wp--preset--color--campaign-red-pressed);
	color: var(--wp--preset--color--white);
	transform: translateY(var(--hover-lift));
}
.wp-block-button.is-style-sp-primary .wp-block-button__link:active {
	transform: translateY(0);
}

.wp-block-button.is-style-sp-outline-on-dark .wp-block-button__link {
	background: transparent;
	color: var(--wp--preset--color--white);
	border: var(--border-width-hairline) solid var(--border-on-inverse);
	border-radius: var(--radius-none);
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	min-height: var(--touch-min);
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--8);
	transition: background-color var(--duration-base) var(--ease-out), border-color var(--duration-base) var(--ease-out);
}
.wp-block-button.is-style-sp-outline-on-dark .wp-block-button__link:hover {
	background: rgba(255, 255, 255, 0.12);
	border-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--white);
}

/* Mobile-drawer-only action buttons (Donate + Volunteer) added as extra
   Navigation children -- see the wp_navigation entity created for Phase 2A.
   The header's own always-visible Donate button already covers desktop, so
   these only appear inside the mobile overlay. Selector is deliberately
   long/specific: core stamps auto-generated `.is-layout-flex` utility
   classes onto every Buttons block, which otherwise out-specifies a plain
   single-class rule and leaks the buttons onto desktop. */
.sp-header .sp-nav .wp-block-navigation__responsive-container-content .sp-nav__drawer-actions {
	display: none;
}
@media (max-width: 1023px) {
	.sp-header .sp-nav .wp-block-navigation__responsive-container-content .sp-nav__drawer-actions {
		display: grid;
		gap: var(--wp--preset--spacing--3);
		margin-top: var(--wp--preset--spacing--8);
		width: 100%;
	}
	.sp-nav__drawer-actions .wp-block-button__link {
		width: 100%;
	}
}

/* ===== Navigation: force our 1024px breakpoint =====
   Core's Navigation block defaults to a 600px responsive breakpoint. The
   design system's nav appears at 1024px (bp-lg), so these rules override
   core's own ones -- extra ancestor classes (.sp-header .sp-nav) give each
   rule higher specificity than the core selector it replaces, so it wins
   regardless of stylesheet load order. */

/* 600-1023px: put core's own "show inline" state back to "stay mobile". */
@media (min-width: 600px) and (max-width: 1023px) {
	.sp-header .sp-nav .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex;
	}
	.sp-header .sp-nav .wp-block-navigation__responsive-container:not(.is-menu-open) {
		display: none;
	}
}

/* >=1024px: nav shows inline, burger + overlay chrome hide entirely. */
@media (min-width: 1024px) {
	.sp-header .sp-nav .wp-block-navigation__responsive-container-open {
		display: none;
	}
	.sp-header .sp-nav .wp-block-navigation__responsive-container:not(.is-menu-open) {
		display: block;
		width: 100%;
		position: relative;
		z-index: auto;
		background-color: inherit;
	}
	.sp-header .sp-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__responsive-container-close,
	.sp-header .sp-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__responsive-dialog > button {
		display: none;
	}
}

/* ===== Burger (open) button -- matches .sp-burger: 44px hairline box ===== */
.sp-nav .wp-block-navigation__responsive-container-open {
	width: var(--touch-min);
	height: var(--touch-min);
	border: var(--border-width-hairline) solid var(--border-default);
	color: var(--wp--preset--color--primary-navy);
	align-items: center;
	justify-content: center;
}

/* ===== Desktop inline links -- matches .sp-nav__link ===== */
@media (min-width: 1024px) {
	.sp-nav .wp-block-navigation__responsive-container-content > .wp-block-navigation__container {
		display: flex;
		flex-wrap: nowrap;
		align-items: center;
		gap: var(--wp--preset--spacing--3);
	}
	.sp-nav .wp-block-navigation-item__content {
		position: relative;
		display: inline-flex;
		font-family: var(--wp--preset--font-family--text);
		font-size: var(--wp--preset--font-size--body-sm);
		color: var(--wp--preset--color--primary-navy);
		text-decoration: none;
		white-space: nowrap;
		padding: var(--wp--preset--spacing--3) 0;
		transition: color var(--duration-fast) var(--ease-out);
	}
	.sp-nav .wp-block-navigation-item__content::after {
		content: "";
		position: absolute;
		left: 0;
		right: 0;
		bottom: 0;
		height: var(--border-width-rule);
		background: var(--wp--preset--color--campaign-red);
		transform: scaleX(0);
		transform-origin: left;
		transition: transform var(--duration-base) var(--ease-out);
	}
	.sp-nav .wp-block-navigation-item__content:hover::after,
	.sp-nav .wp-block-navigation-item__content[aria-current="page"]::after {
		transform: scaleX(1);
	}
	.sp-nav .wp-block-navigation-item__content[aria-current="page"] {
		font-weight: 600;
	}
	/* Drawer-only rows never show inline on desktop. */
	.sp-nav__drawer-brand {
		display: none;
	}
}

/* ===== Mobile overlay -- matches .sp-drawer: full-screen navy panel ===== */
@media (max-width: 1023px) {
	/* !important on background/color only: core ships hardcoded fallback
	   rules for the open state --
	   `.wp-block-navigation:not(.has-background) ... .is-menu-open:not(.disable-default-overlay){background:#fff}`
	   and the equivalent for `color:#000` -- confirmed via computed-style
	   inspection to out-cascade a plain override regardless of selector
	   specificity used here. This is the one place in this file that
	   needs it, specifically to beat those two core fallback rules. */
	.sp-nav .wp-block-navigation__responsive-container.is-menu-open {
		background: var(--wp--preset--color--primary-navy) !important;
		padding: var(--wp--preset--spacing--5) var(--gutter-m) var(--wp--preset--spacing--8);
	}
	.sp-nav .wp-block-navigation__responsive-container-close {
		width: var(--touch-min);
		height: var(--touch-min);
		border: var(--border-width-hairline) solid var(--border-on-inverse);
		color: var(--wp--preset--color--white);
	}
	.sp-nav__drawer-brand {
		margin: 0 0 var(--wp--preset--spacing--8);
	}
	.sp-nav__drawer-brand a {
		display: inline-flex;
		align-items: center;
		gap: var(--wp--preset--spacing--3);
		background: transparent;
		color: var(--wp--preset--color--white);
		padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--5);
		border-top: var(--border-width-rule) solid var(--wp--preset--color--campaign-red);
		border-bottom: var(--border-width-rule) solid var(--wp--preset--color--campaign-red);
		font-family: var(--wp--preset--font-family--display);
		font-size: var(--wp--preset--font-size--body-sm);
		font-weight: 700;
		letter-spacing: 0.12em;
		text-transform: uppercase;
		text-decoration: none;
	}
	.sp-nav__drawer-brand a::before,
	.sp-nav__drawer-brand a::after {
		content: "\2605";
		font-size: 12px;
	}
	.sp-nav .wp-block-navigation__container {
		display: flex;
		flex-direction: column;
	}
	.sp-nav .wp-block-navigation-item {
		border-bottom: var(--border-width-hairline) solid var(--border-on-inverse);
	}
	.sp-nav .wp-block-navigation-item__content {
		min-height: var(--touch-min);
		display: flex;
		align-items: center;
		width: 100%;
		font-family: var(--wp--preset--font-family--display);
		font-size: var(--wp--preset--font-size--h4);
		font-weight: 700;
		color: var(--wp--preset--color--white) !important;
		text-decoration: none;
		padding: var(--wp--preset--spacing--3) 0;
		transition: color var(--duration-fast) var(--ease-out);
	}
	.sp-nav .wp-block-navigation-item__content:hover {
		color: var(--wp--preset--color--pale-steel) !important;
	}
}

@media (prefers-reduced-motion: reduce) {
	.sp-header,
	.sp-header__inner,
	.sp-logo a,
	.sp-nav .wp-block-navigation-item__content,
	.sp-nav .wp-block-navigation-item__content::after,
	.wp-block-button.is-style-sp-primary .wp-block-button__link,
	.wp-block-button.is-style-sp-outline-on-dark .wp-block-button__link {
		transition-duration: 1ms;
	}
}
