/* ==========================================================================
   Site header + primary navigation
   ========================================================================== */

.nsn-header {
	position: fixed;
	inset: 0 0 auto 0;
	z-index: 60;

	/*
	 * A little air above and below the navigation.
	 *
	 * Added to the height rather than taken out of it: box-sizing is
	 * border-box site-wide, so padding inside a fixed height would only shrink
	 * the content box and the vertically centred navigation would not move at
	 * all.
	 *
	 * --nsn-header-h is deliberately left as it is. Every other route offsets
	 * its content from that token, so changing it would push the top of every
	 * page down; only this band grows, and the navigation keeps its distance
	 * from the content below.
	 */
	--nsn-header-pad: clamp(0.5rem, 1.1vh, 0.875rem);

	height: calc(var(--nsn-header-h) + var(--nsn-header-pad) * 2);
	padding-block: var(--nsn-header-pad);

	display: flex;
	align-items: center;
	/*
	 * Sits over both imagery and the scrolling project list, so it carries
	 * its own legibility rather than relying on what is behind it.
	 */
	background: linear-gradient(
		to bottom,
		rgba(15, 15, 14, 0.94) 0%,
		rgba(15, 15, 14, 0.78) 45%,
		rgba(15, 15, 14, 0) 100%
	);
	pointer-events: none;
}

.nsn-header__inner {
	width: 100%;
	max-width: var(--nsn-maxw);
	margin: 0 auto;
	padding: 0 var(--nsn-gutter);
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--nsn-space-3);
	pointer-events: none;
}

.nsn-header__inner > * {
	pointer-events: auto;
}

/* --------------------------------------------------------------------------
   Wordmark
   -------------------------------------------------------------------------- */
.nsn-logo {
	display: inline-flex;
	align-items: baseline;
}

/*
 * The inlined wordmark SVG. Only the height is set — the viewBox supplies the
 * intrinsic 6.59:1 ratio, so the browser derives the width and the header
 * never reflows. `currentColor` in the path picks this up.
 */
.nsn-logo__mark {
	display: block;
	height: clamp(15px, 1.9vw, 24px);
	width: auto;
	color: var(--nsn-bone);
}

.custom-logo-link img,
.nsn-header__brand img {
	height: clamp(24px, 3.4vw, 40px);
	width: auto;
}

/* --------------------------------------------------------------------------
   Navigation
   -------------------------------------------------------------------------- */
.nsn-nav__list {
	display: flex;
	align-items: center;
	gap: clamp(1.25rem, 3vw, 3rem);
}

.nsn-nav__link,
.nsn-nav .menu-item > a {
	position: relative;
	display: inline-block;
	padding: 0.5rem 0;
	font-size: var(--nsn-step-xs);
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--nsn-bone-72);
	transition: color var(--nsn-dur-fast) var(--nsn-ease);
}

/* A rule that draws in from the left, rather than a colour flash. */
.nsn-nav__link::after,
.nsn-nav .menu-item > a::after {
	content: '';
	position: absolute;
	left: 0;
	bottom: 0.25rem;
	width: 100%;
	height: 1px;
	background: currentColor;
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform var(--nsn-dur) var(--nsn-ease);
}

.nsn-nav__link:hover,
.nsn-nav__link:focus-visible,
.nsn-nav .menu-item > a:hover,
.nsn-nav .menu-item > a:focus-visible,
.nsn-nav__item.is-current .nsn-nav__link,
.nsn-nav .current-menu-item > a {
	color: var(--nsn-bone);
}

.nsn-nav__link:hover::after,
.nsn-nav__link:focus-visible::after,
.nsn-nav .menu-item > a:hover::after,
.nsn-nav .menu-item > a:focus-visible::after,
.nsn-nav__item.is-current .nsn-nav__link::after,
.nsn-nav .current-menu-item > a::after {
	transform: scaleX(1);
}

/* --------------------------------------------------------------------------
   Mobile toggle. Hidden above the breakpoint (see responsive.css).
   -------------------------------------------------------------------------- */
.nsn-header__toggle {
	display: none;
	align-items: center;
	gap: 0.6rem;
	font-size: var(--nsn-step-xs);
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--nsn-bone);
}

.nsn-header__toggle-bars {
	display: inline-flex;
	flex-direction: column;
	justify-content: center;
	gap: 5px;
	width: 22px;
}

.nsn-header__toggle-bars i {
	display: block;
	height: 1px;
	width: 100%;
	background: currentColor;
	transition: transform var(--nsn-dur-fast) var(--nsn-ease), opacity var(--nsn-dur-fast) var(--nsn-ease);
}

.nsn-header__toggle[aria-expanded='true'] .nsn-header__toggle-bars i:first-child {
	transform: translateY(3px) rotate(45deg);
}

.nsn-header__toggle[aria-expanded='true'] .nsn-header__toggle-bars i:last-child {
	transform: translateY(-3px) rotate(-45deg);
}

/* --------------------------------------------------------------------------
   The label's roll

   Each menu label is split into characters by nav.js and set twice: the face
   that is read, and a copy waiting a line below it. On hover the first leaves
   upward and the second arrives in its place, a character at a time - the same
   movement the Contact address makes, on the same curve.

   Everything here describes only the two copies and the boxes around them. The
   link's own size, padding, colour, tracking and underline are untouched, and
   the label keeps the box it always had:

     clip-path, not overflow   an inline-block whose overflow is not visible
                               takes its baseline from its bottom margin edge
                               instead of its last line box, which drops the
                               whole menu by a couple of pixels. clip-path cuts
                               the same box without touching the baseline.

   Nothing in this section applies until nav.js has split a label, so a page
   without JavaScript - or a visitor on reduced motion, where the split is
   skipped - has the menu exactly as it was.
   -------------------------------------------------------------------------- */

.nsn-nav__label[data-nsn-split] {
	display: inline-block;
	position: relative;
	clip-path: inset(0);
}

/*
 * The sizer.
 *
 * Both faces are taken out of flow, and a hidden copy of the original text is
 * what the label measures itself against. Letting the characters size the box
 * did not work: each one becomes its own inline-block and its advance is
 * rounded on its own, so a nineteen-letter label came out a fraction wider
 * than the shaped run it replaced and the whole menu slid 3.43px left. The
 * sizer is the untouched text, shaped exactly as before, so the label keeps
 * the width it always had - and keeps it fluid, which a measured pixel value
 * written once could not.
 */
.nsn-nav__sizer {
	visibility: hidden;
}

.nsn-nav__face {
	position: absolute;
	inset: 0;
	white-space: nowrap;
}

.nsn-nav__char {
	display: inline-block;
	will-change: transform;
}

.nsn-nav__face--in .nsn-nav__char {
	transform: translateY(105%);
}
