/* ═══════════════════════════════════════════════════════════════
   Site header — logo, nav, CTA.
   Desktop frame 1728: logo 229x68 @ y40, nav 16/28 @ y60, CTA 250x50 @ y49.
   Header box is 148px tall on both frames (logo/CTA/burger share centre 74).
   ═══════════════════════════════════════════════════════════════ */
/* The three gaps in this row — logo→right, nav→CTA, and between nav items —
   are all 40px in the design and were all flat, which with the CTA's 250px
   min-width meant the row needed ~1358px before it broke. Ramping them
   together (and the CTA with them) holds the full nav to ~1150 instead.
   Anchored 1150 → 1728: at the design frame every value is the design's own. */
.site-header {
	--gd-header-gap: clamp(18px, -25.77px + 3.8062vw, 40px);
	left: 0;
	position: absolute;
	right: 0;
	top: 0;
	z-index: 1000;
}

.site-header__inner {
	align-items: center;
	display: flex;
	gap: var(--gd-header-gap);
	justify-content: space-between;
	min-height: var(--gd-header-h);
}

.site-header__logo {
	display: block;
	flex: 0 0 auto;
}
.site-header__logo img {
	height: clamp(64px, 62.83px + 0.299vw, 68px);
	transition: height .35s var(--gd-ease);
	width: auto;
}

.site-header__right {
	align-items: center;
	display: flex;
	gap: var(--gd-header-gap);
}

/* 250px is the design's button width, not a width this label needs — "Get in
   touch" measures 142px. Let it give back up to 100px before the nav has to
   go, with 150px keeping the pill comfortably wider than its text. Header
   only; every other .gd-btn on the site keeps the design's 250. */
.site-header__cta {
	min-width: clamp(150px, -48.96px + 17.301vw, 250px);
}

/* ── Nav ─────────────────────────────────────────────────────── */
.site-nav__list {
	align-items: center;
	display: flex;
	gap: var(--gd-header-gap);
	list-style: none;
	margin: 0;
	padding: 0;
}
.site-nav__list li {
	padding: 0;
	position: relative;
}

.site-nav__list a {
	color: var(--gd-ink);
	display: inline-block;
	font-size: 16px;
	font-weight: var(--gd-book);
	line-height: 28px;
	position: relative;
}
.site-nav__list a::after {
	background: var(--gd-blue);
	bottom: 0;
	content: "";
	height: 2px;
	left: 0;
	position: absolute;
	transform: scaleX(0);
	transform-origin: left;
	transition: transform .3s var(--gd-ease);
	width: 100%;
}
.site-nav__list a:hover,
.site-nav__list .current-menu-item > a {
	color: var(--gd-blue);
}
.site-nav__list a:hover::after,
.site-nav__list .current-menu-item > a::after {
	transform: scaleX(1);
}

/* Sub-menus */
.site-nav__list .sub-menu {
	background: var(--gd-white);
	border-radius: var(--gd-radius-tile);
	box-shadow: 0 10px 30px rgba(4, 32, 42, .12);
	left: 0;
	list-style: none;
	min-width: 220px;
	opacity: 0;
	padding: 10px 0;
	position: absolute;
	top: 100%;
	transform: translateY(-8px);
	transition: opacity .25s var(--gd-ease), transform .25s var(--gd-ease), visibility 0s linear .25s;
	visibility: hidden;
	z-index: 5;
}
.site-nav__list li:hover > .sub-menu,
.site-nav__list li:focus-within > .sub-menu {
	opacity: 1;
	transform: translateY(0);
	transition-delay: 0s;
	visibility: visible;
}
.site-nav__list .sub-menu a {
	padding: 6px 20px;
	width: 100%;
}

/* ── Menu button + dropdown ────────────────────────────
   Button 36x36 r5 #2B5F94 with the white expand glyph.
   Panel 193x243 r10 #2B5F94, drop shadow 0 4px 4px rgba(0,0,0,.25),
   right-aligned under the button with a 20px gap.
   ────────────────────────────────────────────────────────────── */
.site-menu {
	display: none;
	position: relative;
}

.site-menu__toggle {
	align-items: center;
	background: var(--gd-blue);
	border: 0;
	border-radius: 5px;
	color: var(--gd-white);
	cursor: pointer;
	display: flex;
	height: 36px;
	justify-content: center;
	padding: 0;
	transition: background-color .3s var(--gd-ease);
	width: 36px;
}
.site-menu__toggle:hover,
.site-menu__toggle[aria-expanded="true"] {
	background: var(--gd-blue-dark);
}

.site-menu__icon {
	background-color: currentColor;
	display: block;
	height: 21px;
	-webkit-mask: url("../img/menu-icon.svg") no-repeat center / contain;
	mask: url("../img/menu-icon.svg") no-repeat center / contain;
	width: 21px;
}
/* The design keeps the same glyph in the open state — no flip. */

/* No display:none while animating. Un-hiding and adding .is-open in the
   same frame gives the browser no rendered starting state, so the opening
   transition never runs — it snaps, while closing animates fine because
   the panel is already laid out. `visibility` IS transitionable and still
   removes the panel from hit-testing and the tab order, so both directions
   are symmetrical with no JS timers.

   The `hidden` attribute stays in the markup for the no-JS case and is
   removed once on init. */
.site-menu__panel {
	background: var(--gd-blue);
	border-radius: 10px;
	box-shadow: 0 4px 4px rgba(0, 0, 0, .25);
	max-width: min(320px, calc(100vw - var(--gd-gutter) * 2));
	min-width: 193px;
	opacity: 0;
	padding: 20px;
	position: absolute;
	right: 0;
	top: calc(100% + 20px);
	transform: translateY(-10px) scale(.97);
	transform-origin: 100% 0;
	transition: opacity .24s var(--gd-ease), transform .24s var(--gd-ease), visibility 0s linear .24s;
	visibility: hidden;
	width: max-content;
	z-index: 1001;
}

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

.site-menu.is-open .site-menu__panel {
	opacity: 1;
	transform: none;
	transition: opacity .28s var(--gd-ease), transform .36s var(--gd-ease), visibility 0s;
	visibility: visible;
}

.site-menu__list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.site-menu__list li {
	opacity: 0;
	padding: 0;
	transform: translateY(-6px);
	transition: opacity .3s var(--gd-ease), transform .3s var(--gd-ease);
}

.site-menu__list li + li {
	margin-top: 12px;
}

/* Delays live only on the open state, so closing exits as one block. */
.site-menu.is-open .site-menu__list li {
	opacity: 1;
	transform: none;
}

.site-menu.is-open .site-menu__list li:nth-child(1) {
	transition-delay: .07s;
}

.site-menu.is-open .site-menu__list li:nth-child(2) {
	transition-delay: .12s;
}

.site-menu.is-open .site-menu__list li:nth-child(3) {
	transition-delay: .17s;
}

.site-menu.is-open .site-menu__list li:nth-child(4) {
	transition-delay: .22s;
}

.site-menu.is-open .site-menu__list li:nth-child(n + 5) {
	transition-delay: .27s;
}

.site-menu__list a {
	color: var(--gd-white);
	display: block;
	font-size: 16px;
	font-weight: var(--gd-book);
	line-height: 24px;
}
.site-menu__list a:hover,
.site-menu__list .current-menu-item > a {
	color: var(--gd-white);
	text-decoration: underline;
}

.site-menu__list .sub-menu {
	list-style: none;
	margin-top: 8px;
	padding-left: 14px;
}
.site-menu__list .sub-menu a {
	font-size: 15px;
	opacity: .85;
}

/* Contact stays reachable — the desktop CTA is hidden at this width */
.site-menu__cta {
	background: var(--gd-white);
	border-radius: var(--gd-radius-pill);
	color: var(--gd-blue);
	display: block;
	font-size: 16px;
	line-height: 24px;
	margin-top: 20px;
	padding: 11px 20px;
	text-align: center;
	opacity: 0;
	transform: translateY(-6px);
	transition: opacity .3s var(--gd-ease), transform .3s var(--gd-ease);
}

.site-menu.is-open .site-menu__cta {
	opacity: 1;
	transform: none;
	transition-delay: .3s;
}

.site-menu__cta:hover {
	color: var(--gd-blue);
	opacity: .85;
}

@media (prefers-reduced-motion: reduce) {
	.site-menu__panel,
	.site-menu__list li,
	.site-menu__cta {
		transform: none !important;
		transition-delay: 0s !important;
		transition-duration: .01s !important;
	}
}

/* With the gaps and the CTA ramping (above), the full row now measures 982px
   at its floor against 1011px of space at 1151 — ~29px spare — so the dropdown
   only takes over below 1150, not 1400. "Specialist engineering consultants"
   is 248px of the nav's 515px on its own; a shorter label is the one change
   that would buy another ~200px, but that is the client's call, not CSS. */
@media (max-width: 1150px) {
	.site-nav,
	.site-header__cta {
		display: none;
	}
	.site-menu {
		display: block;
	}
}

body.menu-open {
	overflow: hidden;
}

/* ── Sticky on scroll ──────────────────────────────────────
   Reveals on scroll UP only, and tightens to --gd-header-h-compact once
   pinned. Two positioning modes, because the header sits differently on the
   two page types and neither may shift the page when it pins:
     · home  — it floats over the hero (absolute), so it is already out of
               flow and going `fixed` reserves nothing either way.
     · inner — it is in flow, so `sticky` is used instead: it keeps its own
               space and pins with no jump, and needs no JS to switch.
   ──────────────────────────────────────────────────── */
.site-header {
	transition: transform .35s var(--gd-ease), background-color .3s var(--gd-ease), box-shadow .3s var(--gd-ease);
	will-change: transform;
}

.site-header__inner {
	transition: min-height .35s var(--gd-ease);
}

body.home .site-header.is-stuck {
	position: fixed;
}

.site-header.is-stuck {
	background: var(--gd-white);
	box-shadow: 0 2px 16px rgba(4, 32, 42, .1);
}

.site-header.is-stuck .site-header__inner {
	min-height: var(--gd-header-h-compact);
}

.site-header.is-stuck .site-header__logo img {
	height: var(--gd-header-logo-compact);
}

/* Held for one forced reflow by js/header.js while it commits the off-screen
   position. Without it the reveal has no rendered starting value and the bar
   appears instead of sliding — see the comment on pin(). Every element that
   carries a transition above has to be listed, or that one animates out of the
   resting state while the transform is starting from off-screen. */
.site-header.is-pinning,
.site-header.is-pinning .site-header__inner,
.site-header.is-pinning .site-header__logo img {
	transition: none;
}

.site-header.is-hidden {
	transform: translateY(-100%);
}

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

	.site-header.is-hidden {
		transform: none;
	}
}

/* Inner pages have no hero to sit over */
body:not(.home) .site-header {
	background: var(--gd-white);
	position: sticky;
	top: 0;
}
