/*
 * Base layer for Eleventh Space.
 *
 * Only document-level behaviour that WordPress does not already handle lives
 * here. Colours, typography, spacing and layout are defined in theme.json and
 * reach this file as generated --wp--preset--* custom properties, so there is
 * no second token system to keep in sync.
 */

*,
*::before,
*::after {
	box-sizing: border-box;
}

/*
 * Shared layers and the desktop header bar.
 *
 * Theme z-indexes stay below 9000 so the Complianz banner always sits on top:
 * header < contact overlay < holding page. The menu and contact overlays are
 * modal <dialog>s in the browser's top layer, which no z-index affects;
 * --es-z-contact only applies if the contact dialog is ever shown non-modally.
 *
 * --es-header-h / --es-header-bg size and colour the desktop sticky bar
 * (blocks/intro/style.css). They match the mobile inner-page bar for now;
 * change them here.
 */
:root {
	--es-z-header: 10;
	--es-z-contact: 7000;
	--es-z-holding: 8000;
	--es-header-h: 4.25rem;
	--es-header-bg: var( --wp--preset--color--base, #f0eeed );
}

/* Remove WordPress's automatic gap between top-level sections and the footer. */
.wp-site-blocks > * {
	margin-block-start: 0;
}

/* About / Services: one set of panel guides (Figma Frames 1–7, 730 × 922). */
.es-about,
.es-services {
	--es-split-gutter-x: clamp( 2rem, 3.6vw, 3.25rem );
	--es-split-gutter-y: clamp( 1.5rem, 5.64svh, 3.25rem );
	--es-split-gap: clamp( 1.5rem, 4svh, 3rem );
	--es-split-image-width: min( 23.22vw, 36.77svh, 21.1875rem );
	--es-split-copy-width: 30.5625rem;
}

@media ( min-width: 768px ) {
	.es-about:not( .es-about--editor, .es-about--preview ) .es-about__chapter,
	.es-services:not( .es-services--editor, .es-services--preview ) .es-services__state {
		display: grid;
		grid-template-columns: minmax( 0, 1fr ) var( --es-split-image-width );
		grid-template-rows: auto minmax( 0, 1fr ) auto;
		gap: var( --es-split-gap ) 1.5rem;
		align-items: start;
	}
}

/* A half-width tablet panel cannot hold a 32px heading beside the photograph. */
@media ( min-width: 768px ) and ( max-width: 1200px ) {
	.es-about:not( .es-about--editor, .es-about--preview ) .es-about__chapter,
	.es-services:not( .es-services--editor, .es-services--preview ) .es-services__state {
		grid-template-columns: minmax( 0, 1fr );
		grid-template-rows: auto auto minmax( 0, 1fr );
	}
}

/* Respect the user's OS text-size preference without breaking zoom. */
html {
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;
}

@media ( prefers-reduced-motion: no-preference ) {
	html {
		scroll-behavior: smooth;
	}

}

/*
 * Keep document snapping on desktop pointers only. Mobile browser chrome
 * changes the visual viewport during loading and scrolling; root snapping
 * can then move the page away from the hero's initial position. Touch devices
 * use native scrolling, including through the Hero/Intro curtain.
 */
@media ( prefers-reduced-motion: no-preference ) and ( hover: hover ) and ( pointer: fine ) {
	html:has( body.home ) {
		scroll-snap-type: y proximity;
	}
}

/* Main section entrances; desktop gallery scenes remain continuous. */
body.home :is(
	#about-block,
	#parallax-block,
	#interactive-gradient-block,
	#services-block,
	#work-block,
	#contact
) {
	scroll-snap-align: start;
	scroll-snap-stop: normal;
}

/*
 * About and Services share the document scroller: their image columns stay
 * sticky while the content moves. Add stops to the existing panels without
 * introducing nested scrolling. Proximity keeps oversized content readable.
 * `normal` (not `always`) lets a single flick pass several panels; `always`
 * forced a hard stop at every chapter, which read as abrupt.
 */
@media ( min-width: 768px ) and ( prefers-reduced-motion: no-preference ) and ( hover: hover ) and ( pointer: fine ) {
	body.home :is(
		.es-about:not( .es-about--editor, .es-about--preview ) .es-about__chapter,
		.es-services:not( .es-services--editor, .es-services--preview ) .es-services__state
	) {
		scroll-snap-align: start;
		scroll-snap-stop: normal;
	}
}

/* WordPress fixes its toolbar above the page only above 600px. */
@media ( min-width: 601px ) and ( width < 768px ) {
	html:has( body.home.admin-bar ) {
		scroll-padding-top: var( --wp-admin--admin-bar--height, 32px );
	}
}

/*
 * Desktop front page: the sticky header bar covers the top of the viewport,
 * so anchor jumps, snapping and keyboard focus land below it (WCAG 2.2 SC
 * 2.4.11), and full-height sections after the hero fill the space beneath
 * it. The hero is unchanged. `body.home` keeps this out of the editor.
 */
@media ( min-width: 768px ) {
	body.home {
		--es-sticky-top: calc( var( --es-header-h ) + var( --wp-admin--admin-bar--height, 0px ) );
	}

	html:has( body.home ) {
		scroll-padding-top: calc( var( --es-header-h ) + var( --wp-admin--admin-bar--height, 0px ) );
	}

	body.home :is(
		.es-about__chapter,
		.es-services__state,
		.es-parallax,
		.es-work:not( .es-work--ready ) .es-work__scene,
		.es-footer
	) {
		min-height: calc( 100svh - var( --es-sticky-top ) );
	}

	body.home :is( .es-about__sticky, .es-services__sticky, .es-services__rail-track, .es-work--ready .es-work__stage ) {
		top: var( --es-sticky-top );
		height: calc( 100svh - var( --es-sticky-top ) );
	}

	body.home .es-interactive-gradient {
		height: calc( 100svh - var( --es-sticky-top ) );
	}
}

/*
 * Media defaults. `height: auto` is required alongside the width/height
 * attributes WordPress adds to images, otherwise responsive images distort.
 */
img,
video,
canvas,
svg,
iframe {
	max-width: 100%;
}

img,
video {
	height: auto;
}

/* Form controls do not inherit typography from the document by default. */
button,
input,
select,
textarea {
	font: inherit;
	color: inherit;
}

/* Shared header template part; the front page renders it inside the Intro. */
.es-header {
	display: grid;
	grid-template-columns: 1fr 1fr auto 1fr 1fr;
	align-items: center;
	width: 100%;
	font-size: 0.8125rem;
	font-weight: 500;
	letter-spacing: 0.125rem;
	line-height: 0.9375rem;
	text-transform: uppercase;
}

.es-header__nav {
	display: flex;
	justify-content: space-between;
	width: min( 100%, 20.125rem );
}

.es-header__list {
	display: flex;
	justify-content: space-between;
	gap: 1rem;
	width: 100%;
	margin: 0;
	padding: 0;
	list-style: none;
}

.es-header__nav--start {
	grid-column: 1 / 3;
	justify-self: start;
}

.es-header__nav--end {
	grid-column: 4 / 6;
	justify-self: end;
}

.es-header a {
	color: inherit;
	text-decoration: none;
}

.es-header a:hover {
	color: var( --wp--preset--color--contrast-alt, #703319 );
}

/*
 * Header links (desktop only; the lists are display: none below 768px and the
 * overlay carries its own hover). The hover deepens the Espresso rather than
 * lifting it to Rust, and an underline wipes in from the left.
 *
 * The line is a pseudo-element so the link keeps text-decoration: none and the
 * rule holds whatever markup wp_nav_menu prints around it. Both transitions run
 * at the 0.3s ease the header already uses for its nav-theme colour flip, and
 * the global reduced-motion block later in this file collapses them with
 * everything else.
 */
.es-header__list a {
	position: relative;
	display: inline-block;
	transition: color 0.3s ease;
}

.es-header__list a::after {
	content: "";
	position: absolute;
	/* The trailing letter-space belongs to no glyph; stop short of it. */
	inset-inline: 0 0.125rem;
	bottom: -0.25rem;
	height: 1px;
	background: currentColor;
	transform: scaleX( 0 );
	transform-origin: left center;
	transition: transform 0.3s ease;
}

.es-header__list a:hover {
	color: color-mix( in srgb, var( --wp--preset--color--contrast, #3d251d ) 82%, #000 );
}

.es-header__list a:hover::after {
	transform: scaleX( 1 );
}

.es-header__wordmark {
	grid-column: 3;
	width: clamp( 10rem, 20vw, 18rem );
	line-height: 0;
}

.es-header__wordmark svg {
	display: block;
	width: 100%;
	height: auto;
	fill: currentColor;
}

/*
 * Mobile menu toggle and overlay (Figma "Nav Dark" 3:198, "Nav Light" 3:260,
 * "Nav Menu" 3:24). Desktop never shows either: the toggle is display: none
 * here and the <dialog> is closed, so the desktop header is unchanged. The
 * mobile rules live in the block below 768px further down with the rest of
 * the header's mobile layout.
 *
 * The toggle ships with `hidden` and main.js removes it, so a page without
 * JavaScript never shows a button that cannot open anything. `hidden` only
 * maps to display: none in the UA stylesheet, so the mobile rule has to
 * respect it explicitly ([hidden] beats the display: grid there).
 */
.es-header__toggle {
	display: none;
}

.es-header__burger path {
	stroke: currentColor;
	stroke-width: 4;
	stroke-linecap: round;
}

/*
 * The overlay is a modal <dialog>: showModal() puts it in the top layer, above
 * the fixed header it is printed inside and above the loading overlay, and
 * makes the rest of the page inert while it is open. The UA sizes a modal
 * dialog to its content and centres it; every one of those defaults is reset
 * so it fills the viewport.
 *
 * Layout follows the 402×745 frame: monogram top at 81px, links centred in the
 * remaining space (17px Work Sans, 3px tracking, 38px lines with a blank line
 * between), close control in an 88px tap zone 37px off the bottom. The
 * background is the design's own value — a step darker than Espresso, and
 * used nowhere else, so it is not a palette entry.
 */
.es-menu {
	position: fixed;
	inset: 0;
	width: 100%;
	max-width: none;
	height: 100%;
	max-height: none;
	margin: 0;
	padding: calc( 5.0625rem + env( safe-area-inset-top, 0px ) ) 1.125rem calc( 2.3125rem + env( safe-area-inset-bottom, 0px ) );
	border: 0;
	overflow-y: auto;
	overscroll-behavior: contain;
	background: #2d1810;
	color: var( --wp--preset--color--base, #f0eeed );
	font-family: var( --wp--preset--font-family--body, sans-serif );
}

.es-menu[open] {
	display: flex;
	flex-direction: column;
	align-items: center;
	animation: es-menu-in 0.35s ease both;
}

.es-menu::backdrop {
	background: transparent;
}

.es-menu__icon {
	flex: none;
	width: 2.8125rem;
	height: 3.5625rem;
	opacity: 0.41;
	line-height: 0;
}

.es-menu__icon svg {
	display: block;
	width: 100%;
	height: 100%;
}

.es-menu__nav {
	display: grid;
	flex: 1;
	place-items: center;
	width: 100%;
}

.es-menu__list {
	display: grid;
	gap: 2.375rem;
	margin: 0;
	padding: 0;
	list-style: none;
	text-align: center;
}

.es-menu__list a {
	display: block;
	padding-inline: 1rem;
	color: inherit;
	font-size: 1.0625rem;
	font-weight: 400;
	letter-spacing: 0.1875rem;
	line-height: 2.375rem;
	text-decoration: none;
	text-transform: uppercase;
}

.es-menu__close {
	flex: none;
	width: 100%;
	height: 5.5rem;
	padding: 0;
	border: 0;
	background: none;
	color: rgba( 222, 209, 213, 0.61 );
	font-size: 1.0625rem;
	font-weight: 500;
	letter-spacing: 0.1875rem;
	line-height: 2.375rem;
	cursor: pointer;
}

.es-menu__close:hover,
.es-menu__list a:hover {
	color: var( --wp--preset--color--base-alt, #fff );
}

/* Focus rings on the overlay need the light colour, as on the hero. */
.es-menu :focus-visible {
	outline-color: var( --wp--preset--color--base, #f0eeed );
}

/* The dialog initially focuses About; use an underline instead of a box. */
.es-menu__list a:focus-visible {
	outline: none;
	text-decoration: underline;
	text-underline-offset: 0.35em;
}

/* Stops the page behind the overlay scrolling on touch devices. */
html.es-menu-open {
	overflow: hidden;
}

@keyframes es-menu-in {
	from {
		opacity: 0;
	}

	to {
		opacity: 1;
	}
}

/*
 * Visible focus for keyboard users. `:where()` keeps specificity at zero so
 * component styles added later can override it without !important.
 */
:where(a, button, input, select, textarea, summary, [tabindex]:not([tabindex="-1"])):focus-visible {
	outline: 2px solid var( --wp--preset--color--contrast, currentColor );
	outline-offset: 2px;
}

/*
 * Visually hidden but available to assistive technology. Core ships an
 * equivalent with its block library styles; defining it here means the theme's
 * own markup does not break if those styles are optimised away.
 */
.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset( 50% );
	border: 0;
	word-wrap: normal !important;
}

.screen-reader-text:focus-visible {
	position: fixed;
	top: var( --wp--preset--spacing--xs, 0.5rem );
	inset-inline-start: var( --wp--preset--spacing--xs, 0.5rem );
	z-index: 100000;
	width: auto;
	height: auto;
	padding: var( --wp--preset--spacing--xs, 0.5rem ) var( --wp--preset--spacing--sm, 1rem );
	clip-path: none;
	background-color: var( --wp--preset--color--base, #fff );
	color: var( --wp--preset--color--contrast, #000 );
}

/*
 * <es-accordion> base (assets/js/es-accordion.js). Native <details> items,
 * click to open; the component only polyfills exclusivity and animation.
 * Consumers set --es-accordion-line and skin the summary/body sizes.
 */
es-accordion { display: block; border-top: 1px solid var( --es-accordion-line, currentColor ); }
.es-accordion__item { border-bottom: 1px solid var( --es-accordion-line, currentColor ); }
.es-accordion__summary { display: flex; align-items: center; gap: 0.25rem; list-style: none; opacity: 0.66; cursor: pointer; transition: opacity 0.4s ease; }
.es-accordion__summary::-webkit-details-marker { display: none; }
.es-accordion__summary::marker { content: ""; }
.es-accordion__summary:focus-visible { outline: 1px solid currentColor; outline-offset: 0.25rem; opacity: 1; }
.es-accordion__number { white-space: pre; }
.es-accordion__marker { margin-left: auto; font-weight: 600; }
.es-accordion__marker::before { content: "+"; }
.es-accordion__item[open] .es-accordion__summary { opacity: 1; }
.es-accordion__item[open] .es-accordion__title { font-weight: 600; }
.es-accordion__item[open] .es-accordion__marker::before { content: "-"; }
.es-accordion__body > :first-child { margin-top: 0; }
.es-accordion__body > :last-child { margin-bottom: 0; }
/* Open/close height animation where the browser can interpolate to auto (Chrome 131+); elsewhere the component animates with WAAPI. */
@supports ( interpolate-size: allow-keywords ) {
	.es-accordion__item { interpolate-size: allow-keywords; }
	.es-accordion__item::details-content { height: 0; overflow: clip; transition: height 0.5s cubic-bezier( 0.65, 0, 0.35, 1 ), content-visibility 0.5s allow-discrete; }
	.es-accordion__item[open]::details-content { height: auto; }
}
@media ( prefers-reduced-motion: reduce ) {
	.es-accordion__item::details-content { transition: none; }
}

/* Site footer (Figma "06 - Footer"). */
.es-footer {
	position: relative;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	min-height: 100vh;
	min-height: 100svh;
	padding: 4.3125rem 1.5rem 1.875rem;
	overflow: hidden;
	background: var( --wp--preset--color--contrast, #3d251d );
	color: var( --wp--preset--color--mist, #dbd0d4 );
}

.es-footer__top {
	display: grid;
	grid-template-columns: minmax( 0, 1.3fr ) minmax( 8rem, 0.7fr ) minmax( 0, 1.6fr );
	column-gap: 1.5rem;
	margin-bottom: clamp( 2rem, 8svh, 6rem );
}

.es-footer__icon {
	width: 5.6875rem;
	height: 7.25rem;
	margin-left: 0;
	line-height: 0;
}

.es-footer__icon svg {
	display: block;
	width: 100%;
	height: 100%;
}

.es-footer__social,
.es-footer__contact {
	display: flex;
	flex-direction: column;
	gap: 1.25rem;
	margin: 1.6875rem 0 0;
	font-family: var( --wp--preset--font-family--display, Georgia, serif );
	font-size: 1.25rem;
	font-style: normal;
	font-weight: 400;
	letter-spacing: -0.0125rem;
	line-height: 1;
}

.es-footer a {
	color: inherit;
	text-decoration: none;
}

.es-footer__contact { min-width: 0; overflow-wrap: anywhere; }
.es-footer__contact-details,
.es-footer__addresses { display: contents; }
.es-footer__address { max-width: 28rem; line-height: 1.3; }
.es-footer__address-label { display: none; }

@media ( min-width: 768px ) {
	.es-footer { padding-top: 3.6875rem; }

	/* Figma's 1440px frame: columns start at 63, 497, 711 and 1083px. */
	.es-footer__top {
		grid-template-columns: minmax( 5.6875rem, 410fr ) minmax( 7rem, 190fr ) minmax( 16.25rem, 348fr ) minmax( 0, 291fr );
		margin-right: 2.625rem;
		margin-left: 2.4375rem;
	}

	.es-footer__icon { margin-top: 0.625rem; }
	.es-footer__social,
	.es-footer__contact { margin-top: 0; }
	.es-footer__contact { display: contents; }

	.es-footer__contact-details,
	.es-footer__addresses {
		display: flex;
		flex-direction: column;
		gap: 1.25rem;
		min-width: 0;
	}

	.es-footer__contact-details { grid-column: 3; }
	.es-footer__addresses { grid-column: 4; }
	.es-footer__address { line-height: 1.4; }

	.es-footer__address-label {
		display: block;
		font-family: var( --wp--preset--font-family--body, "work-sans", sans-serif );
		font-size: 0.8125rem;
		font-weight: 600;
		letter-spacing: 0.125rem;
		line-height: 0.9375rem;
		text-transform: uppercase;
		color: color-mix( in srgb, currentColor 50%, transparent );
	}

	.es-footer__address-prefix { display: none; }
}

.es-footer__bottom {
	display: grid;
	grid-template-columns: 1fr auto auto auto 1fr;
	align-items: center;
	gap: 1.5rem 0.75rem;
	margin-top: auto;
	font-family: var( --wp--preset--font-family--body, sans-serif );
	font-size: 0.8125rem;
	font-weight: 300;
	letter-spacing: -0.008125rem;
	line-height: 0.9375rem;
}

.es-footer__utility,
.es-footer__credits {
	display: contents;
}

.es-footer__get-in-touch { grid-column: 1; grid-row: 1; }
.es-footer__copyright { grid-column: 2; grid-row: 1; margin: 0; }
.es-footer__privacy { grid-column: 3; grid-row: 1; }
.es-footer__site-creds { grid-column: 4; grid-row: 1; }
.es-footer__back-to-top { grid-column: 5; grid-row: 1; justify-self: end; }

/*
 * Complianz "Manage consent" (patterns/footer.php) sits beside Privacy Policy.
 * The extra track exists only while the button is printed, so the row is
 * unchanged when Complianz is inactive.
 */
@media ( min-width: 768px ) {
	.es-footer__bottom:has( > .es-footer__utility .es-footer__consent ) { grid-template-columns: 1fr auto auto auto auto 1fr; }
	.es-footer__bottom:has( > .es-footer__utility .es-footer__consent ) .es-footer__consent { grid-column: 4; grid-row: 1; }
	.es-footer__bottom:has( > .es-footer__utility .es-footer__consent ) .es-footer__site-creds { grid-column: 5; }
	.es-footer__bottom:has( > .es-footer__utility .es-footer__consent ) .es-footer__back-to-top { grid-column: 6; }
}

/*
 * Button reset so it reads exactly like the sibling links. Scoped under the
 * footer, and position/size/shadow reset explicitly, so Complianz's floating
 * tab styles for the same class cannot leak onto it (and ours cannot reach
 * the tab).
 */
.es-footer .cmplz-manage-consent {
	position: static;
	inset: auto;
	z-index: auto;
	display: inline;
	width: auto;
	min-width: 0;
	height: auto;
	min-height: 0;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	background: none;
	color: inherit;
	font: inherit;
	letter-spacing: inherit;
	text-align: inherit;
	text-decoration: none;
	text-transform: inherit;
	transform: none;
	-webkit-appearance: none;
	appearance: none;
	cursor: pointer;
}

.es-footer .cmplz-manage-consent:hover {
	opacity: 0.7;
}

.es-footer .cmplz-manage-consent:focus-visible {
	outline: 1px solid currentColor;
	outline-offset: 0.25rem;
}

.es-footer__back-to-top {
	display: inline-flex;
	align-items: center;
	gap: 0.35em;
	white-space: nowrap;
}

.es-footer__back-to-top svg {
	display: block;
	flex-shrink: 0;
	width: 0.615em;
	height: 0.462em;
}

.es-footer__wordmark {
	grid-column: 1 / -1;
	grid-row: 2;
	/* Keep the SVG's native ratio so its visible edges fill the content width. */
	flex-shrink: 0;
	width: 100%;
	aspect-ratio: 351.88 / 31.98;
	background: var( --wp--preset--color--base, #f0eeed );
	opacity: 0.15;
	-webkit-mask: url( ../svg/wordmark.svg ) center / 100% 100% no-repeat;
	mask: url( ../svg/wordmark.svg ) center / 100% 100% no-repeat;
}

.es-footer__wordmark span {
	display: none;
}

@media ( prefers-reduced-motion: no-preference ) {
	.es-footer__wordmark.is-wordmark-ready,
	.es-footer__wordmark span.is-wordmark-ready {
		opacity: 0;
		transform: translateY( 1.25rem );
		transition: opacity 1.2s cubic-bezier( 0.22, 1, 0.36, 1 ), transform 1.2s cubic-bezier( 0.22, 1, 0.36, 1 );
	}
	.es-footer__wordmark.is-wordmark-visible,
	.es-footer__wordmark span.is-wordmark-visible {
		opacity: 0.15;
		transform: none;
	}
}

/* Each phone number is one tel: link and never breaks mid-number; the pipe is a separator only. */
.es-footer__phones {
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
}

.es-footer__phone-sep { display: none; }

.es-footer__phone {
	white-space: nowrap;
}

.es-footer__contact .es-footer__phone {
	text-decoration: none;
}

@media ( min-width: 768px ) {
	.es-footer__contact .es-footer__contact-details a,
	.es-footer .es-footer__site-creds {
		text-decoration: underline;
		text-underline-position: from-font;
	}

	.es-footer__privacy::before,
	.es-footer .es-footer__consent::before,
	.es-footer__site-creds::before {
		content: "•";
		display: inline-block;
		margin-right: 0.75rem;
		text-decoration: none;
	}

	.es-footer__get-in-touch,
	.es-footer__back-to-top { transform: translateY( -0.375rem ); }
}

/* Keep all four columns readable on narrower desktop/tablet screens. */
@media ( min-width: 768px ) and ( max-width: 1200px ) {
	.es-footer__top {
		grid-template-columns: minmax( 4.5rem, 410fr ) minmax( 7rem, 190fr ) minmax( 15.875rem, 348fr ) minmax( 13rem, 291fr );
		column-gap: 1rem;
		margin-right: 0;
		margin-left: 0;
	}

	.es-footer__icon {
		width: 4.5rem;
		height: auto;
		aspect-ratio: 91 / 116;
	}

	.es-footer__social,
	.es-footer__contact {
		font-size: 1.125rem;
	}
}

.es-footer a:hover {
	opacity: 0.7;
}

@media ( prefers-reduced-motion: reduce ) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

@media ( width < 768px ) {
	/* Mobile: a ruled utility list above the logo and credits grid. */
	.es-footer {
		display: flex;
		flex-direction: column;
		justify-content: flex-start;
		min-height: 0;
		padding: clamp( 4rem, 10svh, 7.5rem ) 1.125rem 0;
	}

	.es-footer__top {
		display: flex;
		flex-direction: column;
		align-items: center;
		margin-bottom: 0;
		text-align: center;
	}

	.es-footer__icon {
		width: 3.125rem;
		height: 4rem;
		margin: 0 0 clamp( 1rem, 3svh, 2.75rem );
	}

	.es-footer__social,
	.es-footer__contact {
		align-items: center;
		gap: 0;
		margin: 0;
		font-size: 0.875rem;
		line-height: 1.625rem;
	}

	.es-footer__contact a {
		text-decoration: none;
	}

	.es-footer__phones {
		justify-content: center;
		gap: 0;
	}

	.es-footer__address { margin-top: 0.75rem; }

	.es-footer__phone-sep {
		display: none;
	}

	.es-footer__phone {
		flex: 0 0 100%;
	}

	.es-footer__bottom {
		grid-template-columns: minmax( 0, 46fr ) minmax( 0, 54fr );
		gap: 0;
		width: calc( 100% + 2.25rem );
		margin: 2rem -1.125rem 0;
	}

	.es-footer__utility {
		display: flex;
		grid-column: 1 / -1;
		grid-row: 1;
		flex-direction: column;
		align-items: center;
		gap: 0.5rem;
		margin: 0 1.125rem 2rem;
		padding: 2.5rem 0;
		border-block: 1px solid color-mix( in srgb, currentColor 45%, transparent );
		font-size: 0.875rem;
		line-height: 1.25rem;
	}

	.es-footer__credits {
		display: flex;
		grid-column: 1;
		grid-row: 3;
		align-self: end;
		flex-direction: column;
		gap: 0.125rem;
		padding: 0 0 0.375rem 0.375rem;
		font-size: clamp( 0.5625rem, 3vw, 1.25rem );
		line-height: 1.2;
		color: color-mix( in srgb, currentColor 60%, transparent );
	}

	.es-footer__copyright {
		white-space: nowrap;
	}

	.es-footer__wordmark {
		display: contents;
		background: none;
		-webkit-mask: none;
		mask: none;
		color: var( --wp--preset--color--base, #f0eeed );
		font-family: var( --wp--preset--font-family--display, Georgia, serif );
		font-weight: 400;
		line-height: 0.82;
		letter-spacing: -0.02em;
		text-transform: uppercase;
	}

	.es-footer__wordmark span {
		display: block;
		opacity: 0.15;
		font-size: 16.8vw;
		letter-spacing: -0.02em;
		white-space: nowrap;
	}

	/* The two mobile words animate themselves; avoid multiplying their opacity. */
	.es-footer__wordmark,
	.es-footer__wordmark.is-wordmark-ready,
	.es-footer__wordmark.is-wordmark-visible {
		opacity: 1;
		transform: none;
		transition: none;
	}

	.es-footer__wordmark span:first-child {
		grid-column: 1 / -1;
		grid-row: 2;
		text-align: left;
	}

	.es-footer__wordmark span:last-child {
		grid-column: 2;
		grid-row: 3;
		text-align: right;
	}

	/*
	 * Header (Figma "Nav Dark" 3:198): 222×20 wordmark at the left gutter,
	 * 27×16 hamburger flush to the right one, 20px row. The link groups move
	 * into the overlay. The row is exactly the wordmark's height so the
	 * button's 44px hit area is carried by negative margins rather than
	 * making the header taller than the design.
	 */
	.es-header {
		grid-template-columns: 1fr auto;
		column-gap: 1rem;
	}

	.es-header__nav {
		display: none;
	}

	.es-header__wordmark {
		grid-column: 1;
		width: min( 13.875rem, 100% );
	}

	.es-header__toggle:not( [hidden] ) {
		display: grid;
		grid-column: 2;
		place-items: center;
		width: 2.75rem;
		height: 2.75rem;
		/* Ink is 31px wide including the round caps; centre it on the 27px box. */
		margin: -0.75rem -0.5rem -0.75rem 0;
		padding: 0;
		border: 0;
		background: none;
		color: inherit;
		cursor: pointer;
	}

	.es-header__burger {
		display: block;
		width: 1.9375rem;
		height: 1.25rem;
	}

	/*
	 * Nav Light over dark sections. main.js reads which [data-es-nav] section
	 * is under the header and writes the variant here; every part of the
	 * header takes currentColor, so one rule flips the lot.
	 */
	.es-header {
		transition: color 0.3s ease;
	}

	.es-header[data-es-nav-theme="light"] {
		color: var( --wp--preset--color--base, #f0eeed );
	}

	.es-header[data-es-nav-theme="light"] a:hover {
		color: var( --wp--preset--color--mist, #dbd0d4 );
	}

	/*
	 * Inner pages print the header as a template part in normal flow (the
	 * front page renders it inside the Intro, which fixes it). Pin it there
	 * too so the menu is always reachable, with a background because it sits
	 * over running text rather than a full-bleed section.
	 */
	header.wp-block-template-part {
		position: sticky;
		top: 0;
		z-index: var( --es-z-header );
		padding: 1.5rem 1.125rem;
		background: var( --wp--preset--color--base, #f0eeed );
	}
}

/* Privacy page: Figma 122:540. Content remains editable in WordPress. */
.es-privacy {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	gap: 2.5rem;
	min-height: 100svh;
	padding: 4.3125rem 2.5rem;
	margin-block: 0;
	background: var(--wp--preset--color--mist, #dbd0d4);
	color: var(--wp--preset--color--contrast, #3d251d);
}
.es-privacy__nav { position: sticky; top: 4rem; align-self: start; display: flex; flex-direction: column; justify-content: space-between; min-height: calc(100svh - 8.625rem); }
.es-privacy h1 { margin: 0; font: 400 2rem/1.16 var(--wp--preset--font-family--display, "formiga", serif); letter-spacing: -.015625rem; }
.es-privacy__home { margin: 2rem 0 0; font: 600 .8125rem/1.2 var(--wp--preset--font-family--body, sans-serif); letter-spacing: .125rem; text-transform: uppercase; }
.es-privacy__nav .es-privacy__home { position: absolute; top: 50%; left: 0; margin: 0; transform: translateY(-50%); }
.es-privacy__home a { color: inherit; text-decoration: none; display: inline-flex; align-items: center; min-height: 2.75rem; }
.es-privacy__home a:hover { text-decoration: underline; }
.es-privacy .es-privacy__consent {
	position: static; inset: auto; display: block; width: auto; height: auto;
	min-width: 0; min-height: 2.75rem; margin: .5rem 0 0; padding: 0;
	border: 0; border-radius: 0; box-shadow: none; background: none;
	color: inherit; font: inherit; letter-spacing: inherit; text-transform: inherit;
	text-align: left; transform: none; cursor: pointer;
}
.es-privacy .es-privacy__consent:hover { text-decoration: underline; }
.es-privacy .es-privacy__consent:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.es-privacy__content { min-width: 0; max-width: 40.9375rem; margin: 0; font: 400 1rem/1.4 var(--wp--preset--font-family--body, sans-serif); overflow-wrap: anywhere; }
.es-privacy__content h2 { margin: 2.5rem 0 1.25rem; font: 400 1.5rem/1.25 var(--wp--preset--font-family--display, "formiga", serif); letter-spacing: -.015625rem; }
.es-privacy__content p, .es-privacy__content ul { margin: 0 0 1.25rem; }
.es-privacy__content li + li { margin-top: .4rem; }
.es-privacy__content a { color: inherit; text-underline-offset: .15em; }
.es-privacy__mobile-back { display: none; }
@media (width < 768px) {
	.es-privacy { grid-template-columns: minmax(0, 1fr); gap: 2rem; padding: 2rem 1.5rem; }
	.es-privacy__nav { position: static; min-height: 0; }
	.es-privacy__nav .es-privacy__home { display: none; }
	.es-privacy h1 { font-size: 1.375rem; }
	.es-privacy__content { max-width: none; font-size: .875rem; }
	.es-privacy__content h2 { font-size: 1.375rem; }
	.es-privacy__mobile-back { display: block; }
}

/* Opt in with es-image-fade. Images remain fully visible without the observer.
 * A gentle opacity transition keeps entry/exit soft; no movement or delayed reveal.
 * Mobile modifiers follow the corresponding blocks' layout breakpoints.
 */
@media ( prefers-reduced-motion: no-preference ) {
	.es-image-fade.is-image-fade-ready {
		opacity: 0.3;
		transition: opacity 650ms cubic-bezier( 0.4, 0, 0.2, 1 );
	}

	.es-image-fade.is-image-fade-ready.is-image-visible {
		opacity: 1;
	}
}

@media ( min-width: 768px ) {
	.es-image-fade.es-image-fade--mobile.is-image-fade-ready {
		opacity: 1;
		transition: none;
	}
}

@media ( min-width: 768px ) {
	.es-image-fade.es-image-fade--gallery-mobile.is-image-fade-ready {
		opacity: 1;
		transition: none;
	}
}
