/* Tier-3 plumbing CSS — realises editor-native choices only.
 * Everything token-valued lives in theme.json; this file carries the rules
 * the editor cannot express (states, pseudo-selectors). */

/* Heading + nav links carry no underline (live design); body links keep the default underline. */
h1 a, h2 a, h3 a, h4 a,
.wp-block-navigation a,
.wp-block-site-title a {
	text-decoration: none;
}

/* Active nav item — the live design underlines the current section. */
.wp-block-navigation .current-menu-item > a,
.wp-block-navigation [aria-current="page"] {
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.4em;
}

.wp-block-navigation a:hover {
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.4em;
}

/* Header overlays the hero on cover pages (live-site poster layout): the header
 * floats over a full-viewport cover; on dark covers its chrome flips to white
 * while transparent. Once nav-scroll marks it stuck (solid white reveal), the
 * default black chrome returns. Content-driven via the Cover block's own
 * light/dark state — no page IDs. */
body:has(.wp-block-post-content > .wp-block-cover:first-child) .site-header {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 100;
}

body:has(.wp-block-post-content > .wp-block-cover:first-child:not(.is-light)) .site-header:not(.nav-scroll--stuck),
body:has(.wp-block-post-content > .wp-block-cover:first-child:not(.is-light)) .site-header:not(.nav-scroll--stuck) a {
	color: #fff;
}

body:has(.wp-block-post-content > .wp-block-cover:first-child:not(.is-light)) .site-header:not(.nav-scroll--stuck) .site-social-icon img {
	filter: invert(1);
}

body:has(.wp-block-post-content > .wp-block-cover:first-child:not(.is-light)) .site-header:not(.nav-scroll--stuck) .wp-block-button.is-style-boxed .wp-block-button__link {
	color: #fff;
	border-color: #fff;
}

/* Same invert, mirrored: while the chrome is white over a dark hero, the CV
 * button fills solid white and its label goes black. Must carry the
 * .is-style-boxed selector too, or the rest-state rule above outranks it and
 * the label stays white on a white fill. */
body:has(.wp-block-post-content > .wp-block-cover:first-child:not(.is-light)) .site-header:not(.nav-scroll--stuck) .wp-block-button.is-style-boxed .wp-block-button__link:hover {
	background-color: #fff;
	border-color: #fff;
	color: var(--wp--preset--color--contrast, #000);
}

/* The live design's revealed header is flat white — suppress the house shadow. */
.site-header.nav-scroll--stuck {
	box-shadow: none;
}

/* The first section owns its own top padding on every page (live sections carry
 * their spacing internally), so drop the root block-gap margin WP inserts above
 * main / post-content / the first section. Without this the grid sits ~20px low
 * and hero covers never reach the top of the page. */
main.wp-block-group,
.wp-block-post-content,
.wp-block-post-content > *:first-child {
	margin-block-start: 0;
}

/* Live section-highlighting: "selected work" stays underlined on portfolio
 * child pages (they belong to that section; WP has no ancestor relation to the
 * front page, so the state is realised here — keyed to the stable portfolio
 * parent page). */
body.page-child.parent-pageid-9 .wp-block-navigation .wp-block-navigation-item:first-child a {
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.4em;
}

/* The icon's <img> is inline by default, so its <a>/<figure> line box adds the
 * body line-height (18px x 1.8 = 32.4px) as descender space under a 22px mark.
 * Zeroing the strut collapses the figure to the icon's real height. */
.site-social-icon,
.site-social-icon a,
.site-social-icon img {
	display: block;
	line-height: 0;
}

/* Mobile portrait — the live site switches every heading scale to the
 * viewport-height formula ((v−1) × 0.012 × min(100vh, 900px) + 18px), and
 * grid card titles jump to the h3 scale. Presets are var-referenced, so
 * overriding the custom properties cascades everywhere. */
@media screen and (max-width: 767px) and (orientation: portrait) {
	:root {
		--wp--preset--font-size--display: calc(3 * 0.012 * min(100vh, 900px) + 1.125rem);
		--wp--preset--font-size--title: calc(1.8 * 0.012 * min(100vh, 900px) + 1.125rem);
		--wp--preset--font-size--subtitle: calc(1.2 * 0.012 * min(100vh, 900px) + 1.125rem);
		--wp--preset--font-size--small-title: calc(0.2 * 0.012 * min(100vh, 900px) + 1.125rem);
		--wp--preset--font-size--card-title: calc(1.2 * 0.012 * min(100vh, 900px) + 1.125rem);
	}
}

/* Mobile header — live shows site title + burger only; LinkedIn and CV live
 * inside the flow the menu replaces. */
@media (max-width: 767px) {
	.site-header .site-social-icon,
	.site-header .wp-block-buttons {
		display: none;
	}
}

/* Buttons are outlined at rest and INVERT on hover — a solid fill, never an
 * opacity fade (Brandon's call 2026-08-09; the source site fades to .8 instead).
 * The fill takes the chrome colour and the label flips to the canvas, so the
 * same rule reads correctly in both header states. */
.wp-block-button__link {
	transition:
		background-color 0.1s linear,
		border-color 0.1s linear,
		color 0.1s linear;
}

.wp-block-button__link:hover {
	background-color: var(--wp--preset--color--contrast, #000);
	border-color: var(--wp--preset--color--contrast, #000);
	color: var(--wp--preset--color--base, #fff);
}

/* The "Boxed" variant is the same outline the default now carries (theme.json);
 * it stays registered as design-system vocabulary and asserts nothing extra —
 * a border shorthand here would outrank the header sizing rule below. */

/* Header chrome — all values measured off the live header at 1440px:
 * header box 131px tall · nav items 18px with 20px gutters · LinkedIn mark 22px
 * box with 15px ink · CV button 60×59 (2px border, 16.27px text, 9.76/16.3
 * padding, 35.5px content box). */
/* Live header padding scales with the viewport (Squarespace's vmax scale):
 * 131px tall @1440 · 157 @2000 · 177 @2400 = 2.5vmax each side + the 59px button. */
.site-header {
	padding-top: 2.45vmax !important;
	padding-bottom: 2.45vmax !important;
}

.site-header .wp-block-navigation {
	--wp--style--block-gap: 20px;
	gap: 20px;
}

.site-header .wp-block-navigation .wp-block-navigation__container {
	gap: 20px;
}

.site-header .site-social-icon img {
	width: 22px;
	height: 22px;
}

.site-header .wp-block-button__link {
	font-size: 16.27px;
	line-height: 35.5px;
	padding: 9.76px 16.3px;
	border-width: 2px;
}

/* LinkedIn mark sits 21px clear of the CV button (live spacing). */
.site-header .site-social-icon {
	margin-right: 0;
}

.site-header > .wp-block-group:last-child {
	gap: 21px;
}

/* Sticky header on ALL pages: the wrapper must be the sticky element — the
 * inner group's own wrapper is exactly its height, so sticky on the group
 * never engages. Cover pages override the group to fixed separately. */
header.wp-block-template-part:has(.site-header) {
	position: sticky;
	top: 0;
	z-index: 100;
}
