/* layout/header.css
   Top bar, header, primary nav and the mobile menu.

   Part of assets/css/. The load order lives in
   inc/setup.php - add new files there, not with @import. */

.skip-link {
	position: absolute;
	left: -9999px;
}

.skip-link:focus {
	left: 12px;
	top: 12px;
	z-index: 200;
	background: #fff;
	padding: 10px 16px;
	border: 2px solid var(--navy);
}

.topbar {
	background: var(--navy);
	color: #fff;
	font-size: 12px;
	letter-spacing: 0.03em;
	padding: 9px 0;
}

.topbar-inner {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 24px;
	flex-wrap: wrap;
	opacity: 0.85;
}

.topbar-contacts { display: flex; gap: 20px; }

.site-header {
	position: sticky;
	top: 0;
	z-index: 50;
	background: rgba(255, 255, 255, 0.96);
	backdrop-filter: blur(10px);
	border-bottom: 1px solid var(--line);
}

body.admin-bar .site-header { top: 32px; }

.header-inner {
	height: 96px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 28px;
}

.brand {
	display: flex;
	align-items: center;
	gap: 14px;
	flex: none;
}

.brand-logo { height: 62px; width: auto; max-width: none; object-fit: contain; display: block; }

.brand-rule { width: 1px; height: 38px; background: #E0E3EC; flex: none; }

.brand-tag {
	font-size: 10px;
	letter-spacing: 0.11em;
	line-height: 1.5;
	font-weight: 500;
	color: var(--ink-3);
	max-width: 96px;
}

.header-right {
	display: flex;
	align-items: center;
	gap: 26px;
}

.nav { display: flex; align-items: center; gap: 26px; }

.nav-link {
	position: relative;
	padding: 6px 0;
	font-size: 14px;
	font-weight: 500;
	color: var(--ink);
}

/* The global a:hover turns links blue, which is wrong in the header - the red line
   below is the whole hover signal, so hold the text colour steady. */
.nav-link:hover,
.nav-link:focus-visible { color: var(--ink); }

/* One red line for both hover and the active page. The active state used to be a
   separate span, which rendered a hair different to this transform-scaled one - same
   element for both means they cannot disagree. */
.nav-link::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: -2px;
	height: 2px;
	background: var(--red);
	transform: scaleX(0);
	transition: transform 0.26s cubic-bezier(0.4, 0, 0.2, 1);
}

.nav-link.is-active::after,
.nav-link:hover::after,
.nav-link:focus-visible::after { transform: scaleX(1); }

.site-search {
	display: flex;
	align-items: center;
	border: 1px solid var(--line-2);
	background: #fff;
	min-width: 236px;
	transition: border-color 0.15s, box-shadow 0.15s;
}

.site-search:hover { border-color: #C2C8D6; }

.site-search:focus-within {
	border-color: var(--navy);
	box-shadow: 0 0 0 3px rgba(25, 29, 126, 0.1);
}

.site-search input[type="search"] {
	flex: 1;
	min-width: 0; /* inputs carry an intrinsic min width that would overflow narrow viewports */
	border: 0;
	outline: none;
	background: none;
	font-size: 13px;
	color: var(--ink);
	padding: 11px 6px 11px 15px;
	-webkit-appearance: none;
	appearance: none;
}

.site-search input::placeholder { color: #8A90A0; }

.site-search input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }

.site-search-go {
	flex: none;
	border: 0;
	background: none;
	cursor: pointer;
	width: 40px;
	align-self: stretch;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--ink-3);
	transition: color 0.15s, background 0.15s;
}

.site-search-go:hover { color: #fff; background: var(--navy); }

.site-search-go:focus-visible { outline: 2px solid var(--navy); outline-offset: -2px; }

/* Bigger variant on the search results page and the 404. Both templates ask for it with
   vivo_search_form( 'lg' ). A cleanup pass removed these three rules as unused, which
   they were not - the check that "proved" it only visited the home, products, contact
   and product pages, none of which render this variant. */
.site-search-lg { min-width: 0; max-width: 520px; }

.site-search-lg input[type="search"] { font-size: 15px; padding: 15px 8px 15px 18px; }

.site-search-lg .site-search-go { width: 52px; }

/* The button only gets a display value inside the 980px block below, and only under
   .js-on. With JS off it never appears and the panel stays in the flow, so there is no
   control on screen that opens nothing. */
.nav-toggle {
	display: none;
	align-items: center;
	gap: 9px;
	height: 44px;
	padding: 0 15px;
	border: 1px solid var(--line-2);
	border-radius: 9px;
	background: #fff;
	color: var(--ink);
	font-family: inherit;
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	cursor: pointer;
	flex: none;
	transition: border-color 0.2s, background-color 0.2s;
}

.nav-toggle:hover { border-color: #C2C8D6; background: var(--soft); }

/* The 4px spacing between the bars is not a style choice, it is a rendering one.
   Each bar is its own box, so the browser rounds each one to device pixels
   independently. The bars only round the same way if the step between them is a whole
   number of device pixels - and the icon's own top edge is usually on a half pixel, so
   any leftover fraction alternates down the stack.
   The previous 5px step is 7.5 device px at a 1.5 ratio (Windows at 150%), which put
   the outer two bars on half pixels and the middle one on whole ones: the middle bar
   rendered crisp and the other two blurred, so they read as different weights. Measured
   coverage per bar was [0.5,1,1,0.5] / [1,1,1] / [0.5,1,1,0.5].
   4px is whole at 1, 1.25, 1.5, 1.75, 2, 2.5, 2.75, 3 and 3.5, so all three bars land
   the same way and look identical. 2.625 (some Android phones) is the one ratio where
   no whole-pixel step under 8px exists; 8px fixes that too but makes the icon 18px
   tall against a 9px cap-height label, which is worse than the artefact it cures. */
.nav-toggle-bars {
	position: relative;
	width: 18px;
	height: 10px;
	flex: none;
}

.nav-toggle-bars span {
	position: absolute;
	left: 0;
	width: 100%;
	height: 2px;
	border-radius: 2px;
	background: var(--ink);
	transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.15s linear;
}

.nav-toggle-bars span:nth-child(1) { top: 0; }

.nav-toggle-bars span:nth-child(2) { top: 4px; }

.nav-toggle-bars span:nth-child(3) { top: 8px; }

/* Into an X: the outer two meet in the middle and cross, the middle one goes. */
.menu-open .nav-toggle-bars span:nth-child(1) { transform: translateY(4px) rotate(45deg); }

.menu-open .nav-toggle-bars span:nth-child(2) { opacity: 0; }

.menu-open .nav-toggle-bars span:nth-child(3) { transform: translateY(-4px) rotate(-45deg); }

@media (prefers-reduced-motion: reduce) {
	/* Show the hover underline outright rather than sweeping it in. */
	.nav-link::after { transition: none; }

	/* The panel's own transition is cancelled at the bottom of the file - it is declared
		   inside the 980px block, which comes after this one and would win here. */
	.nav-toggle,
		.nav-toggle-bars span { transition: none; }
}

.topbar .contact-link:hover { opacity: 0.75; }

@media (max-width: 1180px) {
	/* Deliberately nowrap. This is the last width where the whole header still fits on
		   one line; below 980px it becomes the button and the panel instead, so there is no
		   longer any width at which the header is allowed to wrap into stacked rows. */
	.header-inner { height: 88px; flex-wrap: nowrap; gap: 20px; }

	.header-right { gap: 20px; flex-wrap: nowrap; }

	/* Scoped to the header. Unscoped, this also hit the search results and 404 forms,
		   and those sit in a column flex container where flex-basis is the HEIGHT, not the
		   width - it stretched the form to 200px tall and .site-search-go's align-self:
		   stretch took the button with it. */
	.header-right .site-search { min-width: 0; flex: 0 1 200px; }
}

@media (max-width: 980px) {
	/* The address needs 396px and the two phone numbers plus the email need 415px, so
		   the row runs out of space at 859px and drops to two lines. The address is the item
		   the footer already carries in full, so it is the one that goes. */
	.topbar-inner { justify-content: center; }

	.topbar-inner > span:first-child { display: none; }

	/* Header collapses to brand + button.
		   Keyed on .js-on, which inc/setup.php writes inline in the head, so the collapsed
		   header is what the first frame paints. A class added from site.js at
		   DOMContentLoaded would arrive ~450ms in and stack the header, then snap it. */
	.header-inner { height: 74px; gap: 14px; }

	.brand-logo { height: 50px; }

	.brand-rule { height: 32px; }

	.js-on .nav-toggle { display: inline-flex; }

	/* JS off entirely: nothing collapses and the button never appears, so let the header
		   stack. Otherwise the nav, search and button sit in a 74px nowrap row and hang off
		   the side of the screen. */
	html:not(.js-on) .header-inner { height: auto; padding-top: 14px; padding-bottom: 14px; flex-wrap: wrap; }

	html:not(.js-on) .header-right { width: 100%; flex-wrap: wrap; gap: 14px; }

	/* The panel hangs off .site-header rather than sitting in the flow, so opening it
		   cannot move the page, and only opacity and transform animate. */
	.js-on .header-right {
			position: absolute;
			top: 100%;
			left: 0;
			right: 0;
			display: flex;
			flex-direction: column;
			align-items: stretch;
			gap: 0;
			padding: 4px var(--pad) 22px;
			background: #fff;
			border-bottom: 1px solid var(--line);
			box-shadow: 0 20px 44px rgba(14, 16, 48, 0.13);
			max-height: calc(100vh - 100%);
			overflow-y: auto;
			opacity: 0;
			visibility: hidden;
			transform: translateY(-10px);
			transition: opacity 0.22s ease, transform 0.3s cubic-bezier(0.22, 1, 0.36, 1), visibility 0.3s;
		}

	.js-on .site-header.menu-open .header-right {
			opacity: 1;
			visibility: visible;
			transform: translateY(0);
		}

	.js-on .header-right .nav { flex-direction: column; align-items: stretch; gap: 0; }

	.js-on .header-right .nav-link {
			padding: 15px 2px;
			font-size: 15px;
			border-bottom: 1px solid var(--line);
		}

	/* The sliding 2px rule is a desktop cue. Under a stacked list it reads as a stray
		   line sitting on top of the row divider, so the active item takes the brand red
		   instead. */
	.js-on .header-right .nav-link::after { display: none; }

	.js-on .header-right .nav-link.is-active { color: var(--red); }

	/* Scoped through .header-right on purpose - .site-search is also the search results
		   page's own form, which is not in the header and must not pick these up. */
	.js-on .header-right .site-search { margin-top: 18px; width: 100%; flex: none; }

	/* .btn is inline-block, so this needs text-align rather than justify-content. */
	.js-on .header-right .btn-enquire { margin-top: 12px; width: 100%; text-align: center; }
}

@media (max-width: 680px) {
	.topbar { font-size: 11px; }

	.topbar-inner { gap: 6px 14px; }

	.topbar-contacts { gap: 12px; }

	.header-inner { height: 68px; gap: 12px; }

	.brand-logo { height: 46px; }
}

@media (max-width: 420px) {
	.brand-rule,
		.brand-tag { display: none; }

	.nav-toggle { padding: 0 13px; gap: 8px; }

	/* Both phone numbers plus the email want 346px and the row has 346px at 390px wide,
		   so the email wraps onto a second line. It is still on the Enquire button in the
		   menu and in the footer. The phone numbers are the ones worth a tap here. */
	.topbar-contacts > span:last-child { display: none; }
}

@media (prefers-reduced-motion: reduce) {
	.js-on .header-right {
			transition: none;
			transform: none;
		}
}
