/*
 * MF Suite: Site Header (divb-hq#294, docs/SPEC-site-header.md, docs/modules/site-header.md).
 *
 * The theme's header part, pinned with `position: sticky` and — on the desktop, in browsers
 * with scroll-driven animations, for readers who did not ask for less motion — transformed
 * while the page scrolls. Everything else gets 01, the plain sticky bar (D9).
 *
 * Three rules hold the whole sheet together:
 *
 * 1. **Nothing animated is an ancestor of the navigation's overlay.** A transform, filter,
 *    backdrop-filter or container-type on an ancestor makes it the containing block of the
 *    overlay's `position: fixed`, and the opened menu is squeezed into the bar (P1). So the
 *    surface is a sibling (`.mf-sh-surface`), our pieces sit in a sibling layer, and of the
 *    navigation only the items' wrapper moves — and never while the menu is open.
 * 2. **Every animation sits inside both guards** below, and animates only translate, scale,
 *    opacity, visibility, clip-path (06), box-shadow (08) and the search field's own colours
 *    (06). `site-header.test.js` holds the sheet to that.
 * 3. **The numbers are measured** off the live header (2026-10-29): bar 75px, logo 120 × 27 at
 *    the root padding, search 230px with a 24px button, items ending 20px before it.
 */

/* ---------- 01, and everyone's fallback: the bar sticks ---------- */

.mf-sh {
	position: sticky;
	top: var(--wp-admin--admin-bar--height, 0);
	z-index: 50;

	/* Twentig puts `transition: .3s` on the header; the bar must follow the scroll (P4). */
	transition: none !important;

	/* The space between the viewport edge and the logo, as the theme lays it out. vw, not %:
	   the layer's cqi is exact, but the theme's own elements have no container to measure. */
	--mf-sh-pad: var(--wp--style--root--padding-left, 24px);
	--mf-sh-wide: var(--wp--style--global--wide-size, 1280px);
	--mf-sh-edge-vw: max(var(--mf-sh-pad), calc((100vw - var(--mf-sh-wide)) / 2));
}

/* The menu, opened, covers the Read Meter too. */
.mf-sh:has(.is-menu-open) {
	z-index: 100001;
}

/* The blur moves off the theme's section onto a sibling (§4.2): a backdrop-filter on the
   section would trap the overlay. The preset classes use !important, so this must too. */
.mf-sh > :not(.mf-sh-surface, .mf-sh-layer) {
	position: relative;

	/* Core's sticky support gives the section `top: <admin bar offset>`; relative, that would
	   push it down by the admin bar for everyone logged in (measured: 32px). */
	top: auto;
	z-index: 1;
	background-color: transparent !important;
	backdrop-filter: none !important;
	-webkit-backdrop-filter: none !important;
}

.mf-sh-surface {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	background: var(--wp--preset--color--base, #f9f9f9);
	backdrop-filter: blur(24px);
	-webkit-backdrop-filter: blur(24px);
}

/* ---------- the layer: what the bar transforms into ---------- */

.mf-sh-layer {
	position: absolute;
	inset: 0;

	/* Above the theme's section, which core's sticky position support lifts to z-index 10. */
	z-index: 30;
	pointer-events: none;

	/* The only container in the header, and nothing of the theme's is inside it. */
	container-type: inline-size;
	--mf-sh-edge: max(var(--mf-sh-pad), calc((100cqi - var(--mf-sh-wide)) / 2));
}

.mf-sh-layer > * {
	position: absolute;
	opacity: 0;
	visibility: hidden;
}

/* The header's own material: the base colour at 94% (small grey text holds 4.5:1 over a dark
   picture, measured in the catalogue), blurred. */
.mf-sh-cap,
.mf-sh-burger::before {
	background: color-mix(in srgb, var(--wp--preset--color--base, #f9f9f9) 94%, transparent);
	backdrop-filter: blur(24px);
	-webkit-backdrop-filter: blur(24px);
	box-shadow: 0 0 0 1px rgba(17, 17, 17, 0.06), 0 6px 20px -8px rgba(17, 17, 17, 0.28);
}

.mf-sh-cap {
	top: 20px;
	left: 16px;
	width: 112px;
	height: 44px;
	border-radius: 999px;
}

.mf-sh--05 .mf-sh-cap {
	width: 156px;
}

.mf-sh--04.mf-sh--signet .mf-sh-cap {
	width: 44px;
}

.mf-sh--05.mf-sh--signet .mf-sh-cap {
	width: 96px;
}

/* 05's divider between the sign and the burger */
.mf-sh--05 .mf-sh-cap::after {
	content: "";
	position: absolute;
	top: 11px;
	right: 48px;
	width: 1px;
	height: 22px;
	background: rgba(17, 17, 17, 0.14);
}

.mf-sh-isl {
	top: 20px;
	left: calc(50% - 300px);
	width: 600px;
	height: 52px;
	border-radius: 26px;
	box-shadow: 0 0 0 1px rgba(17, 17, 17, 0.06), 0 6px 20px -8px rgba(17, 17, 17, 0.28);
}

/* The sign starts exactly on the wordmark's "A" (§6; the numbers come from Mf_Sh_Settings). */
.mf-sh-sail {
	top: calc((75px - var(--mf-sh-logo-h, 27px)) / 2 + var(--mf-sh-sail-y, 0px));
	left: calc(var(--mf-sh-edge) + var(--mf-sh-sail-x, 0px));
	width: var(--mf-sh-sail-s, 18px);
	height: var(--mf-sh-sail-s, 18px);
	transform-origin: 0 0;
	--mf-sh-fly-y: calc(30px - (75px - var(--mf-sh-logo-h, 27px)) / 2 - var(--mf-sh-sail-y, 0px));
}

.mf-sh--04 .mf-sh-sail {
	--mf-sh-fly-x: calc(26px - var(--mf-sh-edge) - var(--mf-sh-sail-x, 0px));
}

.mf-sh--05 .mf-sh-sail {
	--mf-sh-fly-x: calc(28px - var(--mf-sh-edge) - var(--mf-sh-sail-x, 0px));
}

.mf-sh--06 .mf-sh-sail {
	--mf-sh-fly-x: calc(50cqi - 280px - var(--mf-sh-edge) - var(--mf-sh-sail-x, 0px));
	--mf-sh-fly-y: calc(34px - (75px - var(--mf-sh-logo-h, 27px)) / 2 - var(--mf-sh-sail-y, 0px));
}

/* 08 keeps it simple: the sign appears where it lands, in the docked bar. */
.mf-sh--08 .mf-sh-sail {
	top: 37px;
	left: var(--mf-sh-edge);
	width: 24px;
	height: 24px;
}

/* Without a sign, a small copy of the wordmark lands instead (D3). */
.mf-sh-mark {
	top: 33px;
	left: 30px;
	width: 84px;
	height: auto;
}

.mf-sh--06 .mf-sh-mark {
	top: 37px;
	left: calc(50% - 278px);
	width: 92px;
}

.mf-sh-title {
	top: 37px;
	right: calc(var(--mf-sh-edge) + 48px);
	left: calc(var(--mf-sh-edge) + 112px);
	height: 24px;
	overflow: hidden;
	font-size: 15px;
	font-weight: 600;
	line-height: 24px;
	white-space: nowrap;
	text-overflow: ellipsis;
}

.mf-sh--signet .mf-sh-title {
	left: calc(var(--mf-sh-edge) + 40px);
}

.mf-sh-title small {
	margin-right: 6px;
	color: var(--wp--preset--color--contrast-2, #636363);
	font-size: 13px;
	font-weight: 400;
}

.mf-sh-title::before {
	content: "";
	display: inline-block;
	width: 1px;
	height: 22px;
	margin: -3px 14px 0 0;
	vertical-align: middle;
	background: rgba(17, 17, 17, 0.14);
}

/* ---------- the buttons ---------- */

.mf-sh-burger {
	top: 20px;
	right: 16px;
	z-index: 1;
	display: grid;
	place-items: center;
	isolation: isolate;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	color: var(--wp--preset--color--contrast, #111);
	background: none;
	cursor: pointer;
	pointer-events: auto;
}

.mf-sh-burger::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	border-radius: inherit;
}

.mf-sh--05 .mf-sh-burger {
	right: auto;
	left: 128px;
}

.mf-sh--05.mf-sh--signet .mf-sh-burger {
	left: 68px;
}

.mf-sh--08 .mf-sh-burger {
	top: 27px;
	right: calc(var(--mf-sh-edge) - 10px);
}

.mf-sh--05 .mf-sh-burger::before,
.mf-sh--08 .mf-sh-burger::before {
	display: none;
}

.mf-sh-burger svg,
.mf-sh-fab svg {
	fill: currentcolor;
}

/* The phone's menu button (D11): shown by the script on the way up, once the header is gone. */
.mf-sh-fab {
	position: fixed;
	right: 16px;
	bottom: 20px;
	z-index: 90;
	display: grid;
	place-items: center;
	width: 56px;
	height: 56px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	color: var(--wp--preset--color--base, #fff);
	background: var(--wp--preset--color--contrast, #111);
	box-shadow: 0 10px 24px -8px rgba(17, 17, 17, 0.5);
	cursor: pointer;
	visibility: hidden;
	opacity: 0;
	translate: 0 12px;
	transition: opacity 0.2s ease, translate 0.2s ease, visibility 0s linear 0.2s;
}

.mf-sh-fab.is-on {
	visibility: visible;
	opacity: 1;
	translate: 0 0;
	transition: opacity 0.2s ease, translate 0.2s ease, visibility 0s;
}

.mf-sh-fab:focus-visible,
.mf-sh-burger:focus-visible {
	outline: 3px solid var(--wp--preset--color--contrast, #111);
	outline-offset: 2px;
}

/* ---------- the space the header covers (§7, D10) ---------- */

:root:has(.mf-sh) {
	--mf-site-header-height: calc(75px + var(--wp-admin--admin-bar--height, 0px));
}

/* Jump targets land below the header. Not `scroll-padding-top` on html: that makes every
   element focused inside the sticky header count as covered, and Chrome scrolls the page to
   the top on each focus — the burger, every menu item (measured: 300 → 0). */
:where(h1, h2, h3, h4, h5, h6, [id]):not(.mf-sh, .mf-sh *) {
	scroll-margin-top: var(--mf-site-header-height, 0);
}

/* ---------- phones: the header scrolls away ---------- */

@media (max-width: 599.98px) {

	.mf-sh {
		position: relative;
		top: auto;
	}

	.mf-sh-layer {
		display: none;
	}

	:root:has(.mf-sh) {
		/* stylelint-disable-next-line length-zero-no-unit -- read inside calc() by Sticky Companion,
		   where a unitless 0 makes `calc(24px + 0)` invalid and the aside stops sticking. */
		--mf-site-header-height: 0px;
	}
}

@media (min-width: 600px) {

	.mf-sh-fab {
		display: none;
	}
}

@media (prefers-reduced-motion: reduce) {

	.mf-sh-fab,
	.mf-sh-fab.is-on {
		transition: none;
	}
}

/* ============================================================
   The transformations. Both guards, always (D9).
   ============================================================ */

/* stylelint-disable max-line-length -- core's navigation class names, in full: shortening them
   with a looser selector would reach the overlay while it is open. */
@supports (animation-timeline: scroll()) {

	@media (prefers-reduced-motion: no-preference) and (min-width: 600px) {

		:root:has(.mf-sh--04),
		:root:has(.mf-sh--05) {
			--mf-site-header-height: calc(64px + var(--wp-admin--admin-bar--height, 0px));
		}

		:root:has(.mf-sh--06) {
			--mf-site-header-height: calc(72px + var(--wp-admin--admin-bar--height, 0px));
		}

		:root:has(.mf-sh--08) {
			--mf-site-header-height: calc(52px + var(--wp-admin--admin-bar--height, 0px));
		}

		/* Once the bar has dissolved (04, 05) or contracted (06), its empty parts must not
		   catch the clicks meant for the page below. Hidden pieces take none anyway. */
		.mf-sh--04,
		.mf-sh--05,
		.mf-sh--06,
		:is(.mf-sh--04, .mf-sh--05, .mf-sh--06) > :not(.mf-sh-surface, .mf-sh-layer),
		:is(.mf-sh--04, .mf-sh--05, .mf-sh--06) .wp-block-group {
			pointer-events: none;
		}

		/* Only what can be seen takes clicks: the logo and the items until they fade (then
		   visibility: hidden takes them out), and the overlay once it is open. The
		   navigation's own boxes stay transparent to the pointer — `nav.`, because core puts
		   the class `wp-block-navigation` on the items' <ul> too. */
		:is(.mf-sh--04, .mf-sh--05, .mf-sh--06) :is(.wp-block-site-logo, .wp-block-navigation__responsive-container-content, .wp-block-navigation__responsive-container.is-menu-open) {
			pointer-events: auto;
		}

		:is(.mf-sh--04, .mf-sh--05, .mf-sh--06) :is(nav.wp-block-navigation, .wp-block-navigation__responsive-container:not(.is-menu-open), .wp-block-navigation__responsive-container:not(.is-menu-open) :is(.wp-block-navigation__responsive-close, .wp-block-navigation__responsive-dialog)) {
			pointer-events: none;
		}

		/* --- 04, 05: the surface dissolves, the menu gives way, the corners take over --- */

		.mf-sh--04 .mf-sh-surface,
		.mf-sh--05 .mf-sh-surface {
			animation: mf-sh-fade linear both;
			animation-timeline: scroll(root);
			animation-range: 40px 120px;
		}

		.mf-sh--04 .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__responsive-container-content,
		.mf-sh--05 .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__responsive-container-content {
			animation: mf-sh-out linear both;
			animation-timeline: scroll(root);
			animation-range: 0 60px;
		}

		.mf-sh--04 .wp-block-site-logo,
		.mf-sh--05 .wp-block-site-logo,
		.mf-sh--06 .wp-block-site-logo {
			animation: mf-sh-gone linear both;
			animation-timeline: scroll(root);
			animation-range: 0 40px;
		}

		.mf-sh--04 .mf-sh-cap,
		.mf-sh--05 .mf-sh-cap,
		.mf-sh-mark {
			animation: mf-sh-in linear both;
			animation-timeline: scroll(root);
			animation-range: 60px 120px;
		}

		.mf-sh--04 .mf-sh-burger,
		.mf-sh--05 .mf-sh-burger {
			animation: mf-sh-btn linear both;
			animation-timeline: scroll(root);
			animation-range: 60px 120px;
		}

		/* The letters dissolve first (0–40px); the sign holds on the "A" and only then flies,
		   or two sails show at once (§6). */
		.mf-sh--04 .mf-sh-sail,
		.mf-sh--05 .mf-sh-sail,
		.mf-sh--06 .mf-sh-sail {
			animation: mf-sh-sail linear both;
			animation-timeline: scroll(root);
			animation-range: 0 120px;
		}

		/* --- 06: the surface itself contracts into the island; the menu travels with it --- */

		.mf-sh--06 .mf-sh-surface {
			animation: mf-sh-clip linear both;
			animation-timeline: scroll(root);
			animation-range: 0 120px;
		}

		.mf-sh--06 .mf-sh-isl {
			animation: mf-sh-in linear both;
			animation-timeline: scroll(root);
			animation-range: 80px 120px;
		}

		.mf-sh--06 .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__responsive-container-content {
			animation: mf-sh-nav6 linear both;
			animation-timeline: scroll(root);
			animation-range: 0 120px;
		}

		.mf-sh--06 .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container {
			animation: mf-sh-items6 linear both;
			animation-timeline: scroll(root);
			animation-range: 0 120px;
		}

		.mf-sh--06 .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-search__input {
			animation: mf-sh-gone linear both;
			animation-timeline: scroll(root);
			animation-range: 0 50px;
		}

		.mf-sh--06 .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-search__inside-wrapper {
			animation: mf-sh-field linear both;
			animation-timeline: scroll(root);
			animation-range: 0 50px;
		}

		/* --- 08: dock on the first 23px, then trade the menu for the title --- */

		body:has(.mf-sh--08) {
			/* stylelint-disable-next-line property-no-unknown -- Chrome 116+, behind the guard */
			timeline-scope: --mf-sh-title;
		}

		.mf-sh--08 {
			top: calc(var(--wp-admin--admin-bar--height, 0px) - 23px);
			animation: mf-sh-shadow linear both;
			animation-timeline: scroll(root);
			animation-range: 0 23px;
		}

		.mf-sh--08 .wp-block-site-logo {
			transform-origin: 0 50%;
			animation: mf-sh-dock-logo linear both;
			animation-timeline: scroll(root);
			animation-range: 0 23px;
		}

		.mf-sh--08.mf-sh--signet .wp-block-site-logo {
			animation: mf-sh-dock-logo linear both, mf-sh-gone linear both;
			animation-timeline: scroll(root), --mf-sh-title;
			animation-range: 0 23px, exit 0% exit 33%;
		}

		.mf-sh--08 .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__responsive-container-content {
			animation: mf-sh-dock linear both, mf-sh-gone linear both;
			animation-timeline: scroll(root), --mf-sh-title;
			animation-range: 0 23px, exit 0% exit 60%;
		}

		.mf-sh--08 .mf-sh-title,
		.mf-sh--08 .mf-sh-sail {
			animation: mf-sh-in linear both;
			animation-timeline: --mf-sh-title;
			animation-range: exit 30% exit 100%;
		}

		.mf-sh--08 .mf-sh-burger {
			animation: mf-sh-btn linear both;
			animation-timeline: --mf-sh-title;
			animation-range: exit 30% exit 100%;
		}
	}
}

/* stylelint-enable max-line-length */

@keyframes mf-sh-fade {

	to {
		opacity: 0;
	}
}

@keyframes mf-sh-gone {

	to {
		visibility: hidden;
		opacity: 0;
	}
}

@keyframes mf-sh-in {

	from {
		visibility: hidden;
		opacity: 0;
	}

	to {
		visibility: visible;
		opacity: 1;
	}
}

@keyframes mf-sh-out {

	to {
		visibility: hidden;
		opacity: 0;
		translate: 16px 0;
	}
}

@keyframes mf-sh-btn {

	from {
		visibility: hidden;
		opacity: 0;
		scale: 0.8;
	}

	to {
		visibility: visible;
		opacity: 1;
		scale: 1;
	}
}

@keyframes mf-sh-sail {

	0% {
		visibility: hidden;
		opacity: 0;
	}

	5% {
		visibility: visible;
		opacity: 1;
	}

	33% {
		translate: 0 0;
		scale: 1;
	}

	100% {
		visibility: visible;
		opacity: 1;
		translate: var(--mf-sh-fly-x, 0) var(--mf-sh-fly-y, 0);
		scale: var(--mf-sh-sail-k, 1);
	}
}

@keyframes mf-sh-clip {

	from {
		clip-path: inset(0 0 0 0 round 0);
	}

	to {
		clip-path: inset(20px calc(50% - 300px) 3px round 26px);
	}
}

/* The search button's right edge travels to the island's right edge less 14px. */
@keyframes mf-sh-nav6 {

	to {
		translate: calc(var(--mf-sh-edge-vw) - 50vw + 286px) 8.5px;
	}
}

/* The items close the gap the search field leaves: 230px field, 24px button, 20px gap, 16px
   kept before the button. */
@keyframes mf-sh-items6 {

	to {
		translate: 210px 0;
	}
}

@keyframes mf-sh-field {

	to {
		border-bottom-color: transparent;
		background-color: transparent;
	}
}

@keyframes mf-sh-shadow {

	to {
		box-shadow: 0 1px 0 rgba(17, 17, 17, 0.08), 0 8px 18px -14px rgba(17, 17, 17, 0.35);
	}
}

@keyframes mf-sh-dock {

	to {
		translate: 0 11.5px;
	}
}

@keyframes mf-sh-dock-logo {

	to {
		translate: 0 11.5px;
		scale: 0.78;
	}
}
