/*
 * Sticky site header - dark glass bar matched to the landing hero.
 * Loaded on every page; see sok_enqueue_header_styles().
 *
 * GeneratePress paints #masthead #004aaa from the Customizer, which collided
 * with the #0d2144 hero directly beneath it: two unrelated blues meeting on a
 * hard line at the bottom of the bar. The header now takes the hero gradient's
 * own top stop, so at scroll top the bar and the hero read as one surface.
 *
 * Once the page scrolls the bar turns translucent and blurs whatever passes
 * under it, and a hairline plus a shadow fade in to lift it off the content.
 *
 * Every colour here is dark enough that the existing white nav text clears AA
 * comfortably - #ffffff on #0d2144 is 15.93:1, against 4.94:1 for the
 * white-on-#1e73be dropdown this replaces.
 */

.site-header {
	/* The top stop of the hero gradient in landing.css - the colour the hero
	   actually paints where the two meet. The glass is the same value at 82%,
	   which still reads 9.06:1 against white nav text over the brightest
	   possible content. */
	--sok-hd-bg: #0d2144;
	--sok-hd-bg-glass: rgba(13, 33, 68, .82);
	--sok-hd-menu: #0a1a36;
	--sok-hd-border: rgba(255, 255, 255, .10);
	--sok-hd-hover: rgba(255, 255, 255, .08);
	--sok-hd-shadow: 0 8px 28px rgba(2, 6, 23, .38);

	position: sticky;
	top: 0;
	/* Above page content, below WordPress' 99999 admin bar. */
	z-index: 100;
	background-color: var(--sok-hd-bg);
	transition: background-color .25s ease, box-shadow .25s ease;
}

/*
 * The hairline lives on a pseudo-element rather than border-bottom so it can
 * fade in on scroll without moving the bar - and everything below it - by 1px.
 */
.site-header::after {
	content: "";
	position: absolute;
	right: 0;
	bottom: 0;
	left: 0;
	height: 1px;
	background-color: var(--sok-hd-border);
	opacity: 0;
	transition: opacity .25s ease;
	pointer-events: none;
}

/* .sok-header--stuck is toggled past 4px of scroll by assets/js/header.js. */
.site-header.sok-header--stuck {
	box-shadow: var(--sok-hd-shadow);
}

.site-header.sok-header--stuck::after {
	opacity: 1;
}

/*
 * Firefox only shipped backdrop-filter unprefixed in 103, and it is still off
 * by default behind a flag in some builds. Without the blur a translucent bar
 * just lets text scroll through it legibly, so the glass is opt-in: browsers
 * that cannot blur keep the opaque bar and lose nothing but the effect.
 */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
	.site-header.sok-header--stuck {
		background-color: var(--sok-hd-bg-glass);
		-webkit-backdrop-filter: blur(14px) saturate(140%);
		backdrop-filter: blur(14px) saturate(140%);
	}
}

/* ------------------------------------------------------------------
   Navigation - retuned for the dark bar

   GP prints these from the Customizer as .site-header / .main-navigation
   rules, so matching that specificity and loading later is enough for the
   first two. The hover rule is a 0,4,3 selector, hence the .site-header
   prefix here.
   ------------------------------------------------------------------ */

.main-navigation,
.main-navigation ul ul {
	background-color: transparent;
}

/* Submenus sit a shade darker than the bar so the panel reads as a layer. */
.main-navigation ul ul {
	background-color: var(--sok-hd-menu);
}

/*
 * GP's hover is `color: var(--accent); background-color: var(--base-3)`, i.e.
 * blue text on a solid white block. That was built for the light blue bar and
 * would punch a white hole in the glass, so it becomes a faint white wash.
 */
.site-header .main-navigation .main-nav ul li:not([class*="current-menu-"]):hover > a,
.site-header .main-navigation .main-nav ul li:not([class*="current-menu-"]):focus > a,
.site-header .main-navigation .main-nav ul li.sfHover:not([class*="current-menu-"]) > a,
.site-header .main-navigation .menu-bar-item:hover > a,
.site-header .main-navigation .menu-bar-item.sfHover > a {
	color: #ffffff;
	background-color: var(--sok-hd-hover);
}

/* ------------------------------------------------------------------
   Bar height - 108px down to 72px

   The old bar was the 68px logo plus .inside-header's 20px of vertical
   padding. Three things have to agree on the new 40px content row or the
   tallest one silently sets the height again: the logo, the nav rows (GP
   ships line-height: 60px) and the CTA.

   40 + 16 + 16 = 72.

   The nav rules are (0,3,3) to clear GP's own (0,2,3), and are matched with
   the child combinator so they reach only the top level - GP styles submenu
   anchors at (0,2,4), which a descendant selector here would outrank and
   flatten to 40px rows.
   ------------------------------------------------------------------ */

/*
 * 19px -> 16px, at every width.
 *
 * The weight matters more than the size here. GP ships the nav at 400, which
 * is what made 15px read as thin and undersized; nexstepteenacademy.com, the
 * reference for this, runs 16px/600. Going to 600 is most of the difference,
 * and 16px is where nav labels stop competing with body copy.
 */
.site-header .main-navigation .main-nav > ul > li > a {
	font-size: 16px;
	font-weight: 600;
}

/*
 * Rendering the 340x68 source at 40px tall is also the one sharpness win
 * available without a new asset: it puts the logo at roughly 1.7x density
 * instead of 1x, so it stops looking soft on a retina screen.
 */
.site-header .site-logo img {
	height: 40px;
	width: auto;
}

.site-header .inside-header {
	padding-top: 16px;
	padding-bottom: 16px;
}

/*
 * Align the logo with the page content below it.
 *
 * .inside-header and the content share the same 1200px grid-container, so the
 * boxes already line up - it was GP's 40px of inner padding that pushed the
 * logo in while the post cards and article bodies sit flush against the
 * container edge. Dropping it puts the logo on the first card's left edge and
 * the CTA on its right.
 *
 * Gated at 1200px because the content has no gutter of its own: below the
 * cap the container fills the viewport, and zero padding here would put the
 * logo hard against the screen edge. The existing gutter is kept there
 * instead - see the note about a shared gutter, which is the real fix.
 */
@media (min-width: 1200px) {
	.site-header .inside-header {
		padding-left: 0;
		padding-right: 0;
	}
}

/* 1025px, not 769px: below that the nav is the hamburger accordion, whose
   rows GeneratePress sizes itself. See sok_mobile_menu_media_query(). */
@media (min-width: 1025px) {
	.site-header .main-navigation .main-nav > ul > li > a {
		line-height: 40px;
	}
}

/* ------------------------------------------------------------------
   "Get Support" call to action

   Printed into .menu-bar-items by sok_nav_cta(), which GP renders both after
   the desktop menu and inside the mobile toggle wrapper - so this is styled
   once and holds at every width.

   The selectors are deliberately (0,3,1). GP's own `.main-navigation a` is
   (0,1,1) and sets `display: block`, which outranked a bare `.sok-nav-cta`
   and left the button as a block: align-items had nothing to align, so the
   label sat in the top 30.4px of the 44px box instead of centred. The
   Customizer's `.main-navigation a` rule sets 19px/1.6 from the same
   specificity, so the type has to be re-asserted here too.
   ------------------------------------------------------------------ */

.site-header .main-navigation a.sok-nav-cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* 44px is the minimum comfortable touch target; the bar is 16px text. */
	min-height: 44px;
	margin-left: 12px;
	padding: 0 22px;
	border-radius: 8px;
	background-color: #1668d6;
	color: #ffffff;
	/* Matches the nav links so the button is not visually demoted next to them. */
	font-size: 16px;
	font-weight: 600;
	line-height: 1.2;
	white-space: nowrap;
	text-decoration: none;
	transition: background-color .18s ease, box-shadow .18s ease;
}

/*
 * The hero's primary button hovers to #2b7dea, which is only 4.02:1 against
 * white and fails AA. This stops at #1d6ede - 4.84:1, the same lift in
 * intent, still legible. Base #1668d6 is 5.27:1.
 */
.site-header .main-navigation a.sok-nav-cta:hover,
.site-header .main-navigation a.sok-nav-cta:focus {
	background-color: #1d6ede;
	color: #ffffff;
	box-shadow: 0 6px 18px rgba(22, 104, 214, .38);
}

.site-header .main-navigation a.sok-nav-cta:focus-visible {
	outline: 2px solid #ffffff;
	outline-offset: 2px;
}

/*
 * 44px is the touch minimum, but above this breakpoint the desktop nav is
 * showing, the pointer is a mouse and the bar's content row is 40px - a 44px
 * button would set the header height back to 76px on its own. Below the
 * breakpoint it keeps its 44px.
 *
 * This has to come after the base rule: the two selectors are both (0,3,1),
 * and a media query adds no specificity, so source order is what decides it.
 */
@media (min-width: 1025px) {
	.site-header .main-navigation a.sok-nav-cta {
		min-height: 40px;
	}
}

/*
 * Phones: the button comes off the bar and moves into the menu.
 *
 * GeneratePress lays .inside-header out as a wrapping flex row, so the three
 * items have to fit on one line or the bar silently doubles in height. They
 * do not: the logo is 200px and the control wrapper is 191px (122px button +
 * 59px hamburger + gap), which needs 391px of content box. A 390px phone
 * offers 330px after GP's 30px gutters, so the wrapper wrapped to a second
 * row on every phone in use and left the logo sitting alone on the first -
 * a 116px bar instead of 72px. One row only clears at about 451px, which is
 * past every phone and short of the 769px breakpoint where the desktop menu
 * returns, so there is no width at which the button both fits and is needed.
 *
 * Dropping it entirely would lose the only call to action outside the menu,
 * so it is not dropped: GeneratePress prints sok_nav_cta() twice - once in
 * .mobile-menu-control-wrapper, which is what sits on the bar, and once in
 * .menu-bar-items inside the navigation, which GP hides below 769px. The bar
 * copy goes; the menu copy is brought back as a full width button, which GP's
 * flex ordering lands at the top of the opened menu - ahead of Home, which is
 * where a call to action wants to be anyway.
 */
@media (max-width: 768px) {
	.site-header .mobile-menu-control-wrapper a.sok-nav-cta {
		display: none;
	}

	/*
	 * GP hides this with
	 * `.has-inline-mobile-toggle #site-navigation .inside-navigation > *:not(.navigation-search):not(.main-nav)`,
	 * which is (1,4,0) - :not() carries its argument's specificity. Matching
	 * that and loading later is what wins; a shorter selector would not.
	 */
	.has-inline-mobile-toggle #site-navigation.toggled .inside-navigation > .menu-bar-items {
		display: block;
		/*
		 * .inside-navigation is a flex container, so this box is sized to its
		 * content unless told otherwise - without the width the button below
		 * stretches to 100% of a box that is itself only as wide as the label.
		 */
		width: 100%;
		padding: 12px 20px;
	}

	.site-header #site-navigation.toggled .menu-bar-items a.sok-nav-cta {
		display: flex;
		width: 100%;
		margin-left: 0;
		padding: 0 20px;
	}

}

/*
 * Everywhere the hamburger is on show - phones and tablets alike, so this
 * tracks the menu breakpoint rather than the 768px phone one. A tablet is a
 * touch device, and GP's default 30px toggle is well under the 44px minimum
 * the CTA beside it already meets.
 *
 * The 14px of padding (down from 16px) is what keeps 44px from pushing the
 * bar past 72px: 14 + 44 + 14 = 72, the same height as the desktop bar.
 */
@media (max-width: 1024px) {
	.site-header .inside-header {
		padding-top: 14px;
		padding-bottom: 14px;
	}

	.site-header .mobile-menu-control-wrapper .menu-toggle {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
	}
}

/*
 * 320px is the last width where the logo and the hamburger still do not fit
 * side by side: 200px + 59px against the 260px GP's 30px gutters leave. The
 * gutters are kept - they align the logo with the article below it - and the
 * logo gives way instead, which is the smaller compromise of the two.
 */
@media (max-width: 400px) {
	.site-header .site-logo img {
		height: 34px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.site-header .main-navigation a.sok-nav-cta {
		transition: none;
	}
}

/* The toggle's rgba(0,0,0,.02) was already invisible; on dark it is nothing. */
.mobile-menu-control-wrapper .menu-toggle,
.mobile-menu-control-wrapper .menu-toggle:hover,
.mobile-menu-control-wrapper .menu-toggle:focus,
.has-inline-mobile-toggle #site-navigation.toggled {
	background-color: var(--sok-hd-hover);
}

/* ------------------------------------------------------------------
   Sticky side effects
   ------------------------------------------------------------------ */

/*
 * In-page anchors - the table of contents on the HowTo posts, #content from
 * the skip link - would otherwise land their target underneath the bar.
 *
 * --sok-header-h is the height of the band the bar occludes, measured by
 * header.js: its own height plus its sticky top offset, which the admin bar
 * moves for logged-in users. 72px is the logged-out desktop height, used
 * until the script runs and on the no-JS path.
 */
html {
	scroll-padding-top: calc(var(--sok-header-h, 72px) + 16px);
}

@media (max-width: 1024px) {
	/*
	 * Up to 1024px GP swaps the dropdowns for an in-flow accordion inside the
	 * header. Sticky caps the bar at the viewport, and the menu is taller than
	 * a phone screen once HowTo is open, so it has to scroll on its own.
	 *
	 * Tracks the mobile menu breakpoint, not the 768px phone one: above 1024px
	 * the submenus are absolutely positioned and overflow here would clip them.
	 */
	.site-header {
		max-height: 100vh;
		max-height: 100dvh;
		overflow-y: auto;
		overscroll-behavior: contain;
	}

	.admin-bar .site-header {
		max-height: calc(100dvh - 46px);
	}
}

/* The admin bar is fixed above 600px and scrolls away below it. */
.admin-bar .site-header {
	top: 32px;
}

@media (max-width: 782px) {
	.admin-bar .site-header {
		top: 46px;
	}
}

@media (max-width: 600px) {
	.admin-bar .site-header {
		top: 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	.site-header,
	.site-header::after {
		transition: none;
	}
}
