/*
 * 3V Infrastructure — global styles.
 *
 * Colour, type and spacing tokens come from theme.json as
 * --wp--preset--* custom properties. Local aliases below keep
 * declarations readable; do not hardcode hex values anywhere.
 */

:root {
	--mars: var(--wp--preset--color--mars);
	--harbor: var(--wp--preset--color--harbor);
	--paper: var(--wp--preset--color--paper);
	--ivory: var(--wp--preset--color--ivory);
	--night: var(--wp--preset--color--night);
	--steel: var(--wp--preset--color--steel);
	--verdigris: var(--wp--preset--color--verdigris);
	--cement: var(--wp--preset--color--cement);

	/* Used in the FAQ and several later sections but absent from the Figma
	   variable set, so they are defined here rather than in theme.json. */
	--ink: #0B1628;
	--slate: #64748B;

	/* Figma's "Blue - Main". A shade off Harbor and used only by the Get in
	   touch band's button (6010:4356), which is drawn in it rather than in the
	   Harbor the same component carries on Partners (2261:2147). */
	--blue-main: #253F78;

	/* Content column, measured off the Figma hero: the 1280px container has
	   40px of padding, so the content itself is 1200px inside a 1676px frame
	   — 71.6% of the width, with 14.2% of dead space either side. The nav
	   container in the same frame is an explicit 1200px, so header, sections
	   and footer all share this one column.

	   Inner widths below are expressed as percentages of this column.

	   A flat 71.6vw held the frame's 14.2% gutters at every width, which made
	   the column 734 on a 1025 screen — narrower than the 944 the same page
	   gets at 1024, so widening the window shrank the content. The second term
	   walks the gutter from 40 at 1024 up to the frame's 238 at 1676
	   (gutter = 40 + (vw - 1024) * 198 / 652); the first keeps the frame's own
	   ratio on anything wider. Both give 1200 at 1676 and 944 at 1024, so the
	   column is continuous across the breakpoint. */
	--content: max(71.6vw, 39.26vw + 542px);

	/* Sizes used outside the preset scale, derived the same way: the Figma
	   value over the 1676px frame, so they track the column. */
	--fs-32: clamp(20px, 1.909vw, 48px);
	--fs-28: clamp(20px, 1.671vw, 42px);
	--fs-20: clamp(16px, 1.194vw, 28px);
	--fs-16: clamp(14px, 0.955vw, 22px);
	--fs-13: clamp(12px, 0.776vw, 16px);
	--fs-12: clamp(11px, 0.716vw, 15px);
	--fs-11: clamp(11px, 0.656vw, 14px);
	--fs-10: clamp(10px, 0.597vw, 13px);

	--container: 1200px;
	--container-wide: 1280px;
	--gutter: 40px;

	--radius-sm: 3.2px;
	--radius: 7.2px;
	--radius-pill: 6px;
	--radius-lg: 15px;

	--header-height: 56px;

	/* The gap between a section's small label rule and the headline under it.
	   The frame sets these tight; run 3x on request. Each section keeps its own
	   base value — the frame does not use one number — and multiplies by this. */
	--label-gap-scale: 3;

	/* How strongly the noise tile reads over a photograph. The frame's effect
	   was run at 0.245 against the original blue-toned photography; a lot of
	   those pictures have since been replaced with lighter, flatter ones, and
	   at that strength the grain sat on top of them rather than in them. Halved
	   on the client's note of 2026-10-28. One token so the heroes and the cards
	   cannot drift apart. */
	--grain: 0.12;
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

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

body {
	margin: 0;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

img,
svg,
video {
	max-width: 100%;
	height: auto;
	display: block;
}

a {
	color: inherit;
}

button {
	font: inherit;
	color: inherit;
}

.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* :focus-visible, not :focus — a mouse click on or near it should not park a
   visible panel over the logo; only keyboard users need to see it. */
.skip-link:focus-visible {
	position: fixed;
	inset: 8px auto auto 8px;
	z-index: 100;
	width: auto;
	height: auto;
	padding: 12px 20px;
	clip-path: none;
	background: var(--harbor);
	color: #fff;
	border-radius: var(--radius);
}

:where(a, button, input, select, textarea):focus-visible {
	outline: 2px solid var(--mars);
	outline-offset: 3px;
}

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */

.container {
	width: var(--content);
	max-width: 100%;
	margin-inline: auto;
}

.container--narrow {
	max-width: 768px;
}

.section {
	position: relative;
}

@media (max-width: 1024px) {
	:root {
		--content: calc(100vw - 2 * var(--gutter));
	}
}

@media (max-width: 782px) {
	:root {
		--gutter: 20px;
	}
}

/* In-page jumps (the PARTNERS button to its own form) glide rather than cut,
   for anyone who has not asked the OS to keep motion down. */
@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}
}

/* --------------------------------------------------------------------------
   Buttons — Figma "Button - Solid" (44:882) and "Button - Short" (6057:7558)
   -------------------------------------------------------------------------- */

.btn {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	border: 0;
	border-radius: var(--radius);
	font-weight: 700;
	line-height: 1.5;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
	transition: background-color 0.18s ease, color 0.18s ease;
}

/* Figma gives 70px height with 24px padding and a 24px line-height, which
   sums to 72 — the design frame clips. Fix the height and let the padding
   apply on the inline axis only. */
.btn--solid {
	height: 70px;
	padding: 0 24px;
	background: var(--harbor);
	color: #fff;
	font-size: var(--fs-16);
}

.btn--solid:hover,
.btn--solid:focus-visible {
	background: var(--night);
	text-decoration: none;
}

.btn--short {
	height: 36px;
	padding: 0 24px;
	background: var(--mars);
	color: var(--paper);
	font-size: var(--wp--preset--font-size--eyebrow);
	white-space: nowrap;
}

.btn--short:hover,
.btn--short:focus-visible {
	background: var(--harbor);
	text-decoration: none;
}

.btn--outline {
	height: 70px;
	padding: 0 24px;
	background: transparent;
	color: var(--harbor);
	box-shadow: inset 0 0 0 1.5px currentColor;
	font-size: var(--fs-16);
}

/* Figma "Button (large) - Outline" (4120:4035): 2px Harbor rule, 10px radius,
   32px label — set 10% below that on request. The 81px frame height is run 40%
   taller on request too, hence the calc; width stays as measured. Fixed 558px
   in the frame; capped rather than fixed so it can shrink on narrow
   viewports. */
.btn--large-outline {
	justify-content: center;
	width: 558px;
	max-width: 100%;
	height: calc(81px * 1.4);
	padding: 0 26px;
	border: 2px solid var(--harbor);
	border-radius: 10px;
	background: transparent;
	color: var(--harbor);
	font-size: calc(var(--fs-32) * 0.9);
}

.btn--large-outline:hover,
.btn--large-outline:focus-visible {
	background: var(--harbor);
	color: var(--paper);
	text-decoration: none;
}

@media (max-width: 782px) {
	.btn--large-outline {
		height: calc(64px * 1.4);
		font-size: var(--wp--preset--font-size--body-lg);
	}
}

/* Photo grain --------------------------------------------------------------
 *
 * Figma's DUOTONE noise effect, run at a quarter of the frame's density over
 * every photograph on the site. The hero draws its own (section-header); this
 * is every other picture.
 *
 * The list lives here rather than in each block because it is one decision
 * about the whole site: what is named below carries grain, and what is absent
 * is a deliberate exception — the team headshots, the partner logos, and the
 * photo attached to an individual article.
 *
 * The cards hold their copy above a full-bleed photo at z-index -2, so their
 * layer sits at -1: over the picture and under the words. The media wrappers
 * hold nothing but the image, so theirs paints on top.
 */
.media-card::after,
.customer-card::after,
.section-case-study::after,
.section-contact__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background-image: url("../img/hero-grain.png");
	background-repeat: repeat;
	background-size: 128px 128px;
	opacity: var(--grain);
	pointer-events: none;
}

.media-card::after,
.customer-card::after,
.section-case-study::after {
	z-index: -1;
}

/* Figma "Button (short) - Outline + arrow" (I2001:959;76:438): the outlined
   white button on the Solution cards. */
.btn--card-outline {
	height: 36px;
	padding: 0 25px;
	border: 1px solid #fff;
	border-radius: 7.2px;
	background: transparent;
	color: #fff;
	font-size: var(--fs-12);
	font-weight: 700;
	line-height: 2;
}

.btn--card-outline:hover,
.btn--card-outline:focus-visible {
	background: #fff;
	color: var(--night);
	text-decoration: none;
}

/* The same outlined short button in Harbor, on light ground — Figma
   2108:2032 ("Compare plans"). */
.btn--harbor-outline {
	height: 36px;
	padding: 0 25px;
	border: 1px solid var(--harbor);
	border-radius: 7.2px;
	background: transparent;
	color: var(--harbor);
	font-size: var(--fs-12);
	font-weight: 700;
	line-height: 2;
}

.btn--harbor-outline:hover,
.btn--harbor-outline:focus-visible {
	background: var(--harbor);
	color: #fff;
	text-decoration: none;
}

/* The solid short button — Figma 4006:5317 ("Meet the team"). Same box as the
   nav CTA, in Harbor rather than Mars. */
.btn--short-solid {
	height: 36px;
	padding: 0 24px;
	border-radius: 7.2px;
	background: var(--harbor);
	color: #fff;
	font-size: var(--fs-12);
	font-weight: 700;
	line-height: 2;
	white-space: nowrap;
}

.btn--short-solid:hover,
.btn--short-solid:focus-visible {
	background: var(--night);
	text-decoration: none;
}

/* Small light pill button used on the Return cards. */
.btn--pill {
	height: 36px;
	padding: 0 20px;
	border-radius: 4px;
	background: rgba(255 255 255 / 0.95);
	color: var(--harbor);
	font-size: var(--wp--preset--font-size--eyebrow);
}

.btn--pill:hover,
.btn--pill:focus-visible {
	background: var(--mars);
	color: #fff;
	text-decoration: none;
}

/* --------------------------------------------------------------------------
   Eyebrow pill — Figma 4:14
   -------------------------------------------------------------------------- */

.eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	height: 32px;
	padding: 8px 14px;
	border-radius: var(--radius-pill);
	background: var(--paper);
	color: var(--harbor);
	font-size: var(--wp--preset--font-size--eyebrow);
	font-weight: 800;
	line-height: 1.333;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	white-space: nowrap;
}

.eyebrow .icon {
	color: var(--mars);
}

/* Figma mirrors the small eyebrow tick in place; the raw export is a
   backslash. The 32x54 heading slash is already the right way round. */
.eyebrow .icon svg {
	transform: scaleX(-1);
}

.eyebrow .icon svg {
	width: 8px;
	height: 12px;
}

/* --------------------------------------------------------------------------
   Site header / navigation — Figma 6011:4880 (HOME) and 2089:1351 (interior)
   -------------------------------------------------------------------------- */

/* Every frame draws this bar 56 tall against the top of the page, HOME
   included — the 10 of padding here made HOME's sit 10 lower than the interior
   pages' and stand 76 tall. Position only; the transparent-over-photo
   treatment HOME uses is untouched. */
.site-header {
	position: absolute;
	inset: 0 0 auto;
	z-index: 20;
	padding-block: 0;
}

/* Back on the page column at every width: the column itself is now wide
   enough to hold the nav, so the logo lines up with the content below it. */
.site-header__container {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 32px;
	width: var(--content);
	max-width: 100%;
	min-height: var(--header-height);
	margin-inline: auto;
	border-radius: var(--radius-lg);
}

.site-header__logo {
	flex: 0 0 auto;
	line-height: 0;
}

.site-header__logo svg,
.site-header__logo img {
	width: 158px;
	height: 14px;
}

/* The container is a constant 71.6vw, so between 1025 and the design width it
   is a good deal narrower than 1200 while the nav's own text stops shrinking —
   at ~1070 the two met and the labels broke mid-phrase. The gaps and padding
   scale off the 1676 frame instead, exact at the design width and tightening
   as the column does. */
.nav {
	display: flex;
	align-items: center;
	gap: clamp(4px, 0.477vw, 8px);
	margin-left: auto;
}

.nav__list {
	display: flex;
	align-items: center;
	gap: clamp(4px, 0.477vw, 8px);
	margin: 0;
	padding: 0;
	list-style: none;
}

.nav__item {
	position: relative;
}

.nav__trigger,
.nav__item--depth-0 > .nav__link {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	height: 36px;
	padding: 8px clamp(10px, 0.716vw, 12px) 8px clamp(10px, 1.432vw, 24px);
	border: 0;
	border-radius: var(--radius-sm);
	background: transparent;
	color: var(--harbor);
	font-size: var(--wp--preset--font-size--caption);
	font-weight: 600;
	line-height: 1.429;
	text-decoration: none;

	/* A label is a phrase — it never breaks across lines, whatever the room. */
	white-space: nowrap;
	cursor: pointer;
}

.nav__trigger:hover,
.nav__item--depth-0 > .nav__link:hover,
.nav__item.is-current > .nav__link {
	background: rgba(41 73 117 / 0.06);
}

/* Interior variant: a full-bleed Cement bar laid over the top of the hero,
   with the logo and links reversed out in white. The bar is exactly the
   container's own 56, so the frame's padding disappears here. */
.site-header--solid {
	background: var(--cement);
}

.site-header--solid .site-header__logo svg [fill],
.site-header--solid .site-header__logo svg path {
	fill: #fff;
}

.site-header--solid .nav__trigger,
.site-header--solid .nav__item--depth-0 > .nav__link {
	color: rgba(255 255 255 / 0.9);
}

.site-header--solid .nav__trigger:hover,
.site-header--solid .nav__item--depth-0 > .nav__link:hover,
.site-header--solid .nav__item.is-current > .nav__link {
	background: rgba(255 255 255 / 0.1);
}

.nav__chevron svg {
	width: 11px;
	height: 13.5px;
	transition: transform 0.18s ease;
}

.nav__trigger[aria-expanded="true"] .nav__chevron svg {
	transform: rotate(180deg);
}

.nav__submenu {
	position: absolute;
	top: calc(100% + 8px);
	left: 12px;
	z-index: 30;
	display: none;
	min-width: 220px;
	margin: 0;
	padding: 8px;
	list-style: none;
	background: #fff;
	border-radius: var(--radius);
	box-shadow: 0 12px 32px rgba(10 10 9 / 0.12);
}

/* The menu hangs 8px below the trigger. That gap is outside the item, so
   moving the pointer down into the menu fired mouseleave and closed it before
   anything could be clicked. This bridges the gap: it belongs to the submenu,
   so the pointer never leaves the item on the way in. */
.nav__submenu::before {
	content: "";
	position: absolute;
	/* The menu is offset 12 right of the trigger's left edge, so the bridge
	   reaches back to cover a pointer leaving from that side too. */
	inset: -8px 0 auto -12px;
	height: 8px;
}

.nav__item--has-children.is-open .nav__submenu {
	display: block;
}

.nav__submenu .nav__link {
	display: block;
	padding: 10px 14px;
	border-radius: var(--radius-sm);
	color: var(--harbor);
	font-size: var(--wp--preset--font-size--caption);
	font-weight: 600;
	text-decoration: none;
}

.nav__submenu .nav__link:hover {
	background: var(--paper);
}

.nav-toggle {
	display: none;
	width: 44px;
	height: 44px;
	border: 0;
	background: transparent;
	cursor: pointer;
}

@media (max-width: 1024px) {
	.nav__list,
	.site-header__cta {
		display: none;
	}

	.nav-toggle {
		display: block;
	}

	/* The drawer is the whole <nav>, not just the list inside it. It used to be
	   the list, which left "Get in touch" - the only call to action in the
	   header - with nowhere to go, so it was hidden outright and a phone had no
	   way to reach the contact page from the top of any page. */
	.site-header.is-open .nav {
		position: absolute;
		inset: 100% 0 auto;
		display: block;
		padding: 16px var(--gutter) 24px;
		background: #fff;
		box-shadow: 0 12px 32px rgba(10 10 9 / 0.12);
	}

	.site-header.is-open .nav__list {
		display: block;
	}

	.site-header.is-open .site-header__cta {
		display: flex;
		justify-content: center;
		width: 100%;
		margin-top: 16px;
	}
}

/* --------------------------------------------------------------------------
   Site footer — Figma 2296:5654
   Paper ground, not Harbor: brand column plus four link columns, then a rule
   and a legal row.
   -------------------------------------------------------------------------- */

.site-footer {
	background: var(--paper);
	color: var(--harbor);
}

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

.site-footer a:hover {
	color: var(--mars);
}

.site-footer__container {
	display: flex;
	flex-wrap: wrap;
	gap: 64px;
	width: var(--content);
	max-width: 100%;
	margin-inline: auto;
	padding: 72px 0 96px;
}

.site-footer__brand {
	flex: 0 0 300px;
	max-width: 300px;
}

.site-footer__logo {
	display: block;
	line-height: 0;
}

.site-footer__logo svg {
	width: 138px;
	height: 12px;
}

.site-footer__blurb {
	margin: 20px 0 0;
	color: var(--slate);
	font-size: var(--wp--preset--font-size--eyebrow);
	font-weight: 500;
	line-height: 1.5;
}

.site-footer__phone {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 20px 0 0;
	font-size: var(--wp--preset--font-size--eyebrow);
	font-weight: 500;
}

.site-footer__phone-icon {
	width: 12px;
	height: 12px;
	background: currentColor;
	opacity: 0.7;
	-webkit-mask: no-repeat center / contain;
	mask: no-repeat center / contain;
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6.6 10.8a15.1 15.1 0 0 0 6.6 6.6l2.2-2.2a1 1 0 0 1 1-.24 11.4 11.4 0 0 0 3.6.58 1 1 0 0 1 1 1V20a1 1 0 0 1-1 1A17 17 0 0 1 3 4a1 1 0 0 1 1-1h3.5a1 1 0 0 1 1 1c0 1.25.2 2.46.57 3.6a1 1 0 0 1-.25 1l-2.2 2.2Z'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6.6 10.8a15.1 15.1 0 0 0 6.6 6.6l2.2-2.2a1 1 0 0 1 1-.24 11.4 11.4 0 0 0 3.6.58 1 1 0 0 1 1 1V20a1 1 0 0 1-1 1A17 17 0 0 1 3 4a1 1 0 0 1 1-1h3.5a1 1 0 0 1 1 1c0 1.25.2 2.46.57 3.6a1 1 0 0 1-.25 1l-2.2 2.2Z'/%3E%3C/svg%3E");
}

.site-footer__social {
	margin: 24px 0 0;
}

.site-footer__social-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 27px;
	height: 27px;
	border: 1px solid rgba(41 73 117 / 0.35);
	border-radius: 4px;
}

.site-footer__social-link svg {
	width: 13px;
	height: 13px;
}

.site-footer__menus {
	display: flex;
	flex: 1 1 auto;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: 40px;
}

.site-footer__col {
	flex: 1 1 0;
	min-width: 140px;
}

.site-footer__col-title {
	margin: 0 0 18px;
	color: var(--harbor);
	font-size: var(--fs-11);
	font-weight: 800;
	line-height: 1.333;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.site-footer__list {
	display: grid;
	gap: 14px;
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: var(--fs-13);
	font-weight: 500;
}

.site-footer__legal {
	border-top: 1px solid rgba(41 73 117 / 0.15);
}

.site-footer__container--legal {
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	padding-block: 24px;
}

.site-footer__copyright {
	margin: 0;
	color: var(--slate);
	font-size: var(--wp--preset--font-size--eyebrow);
}

.site-footer__legal-list {
	display: flex;
	gap: 24px;
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: var(--wp--preset--font-size--eyebrow);
	color: var(--slate);
}

@media (max-width: 1024px) {
	.site-footer__brand {
		flex: 1 1 100%;
		max-width: none;
	}
}

@media (max-width: 782px) {
	.site-footer__container {
		gap: 40px;
		padding-block: 56px 64px;
	}

	.site-footer__menus {
		gap: 32px;
	}

	.site-footer__col {
		flex: 1 1 45%;
	}
}

/* Section label ---------------------------------------------------------- */

/* Emitted by threev_section_label() (inc/helpers.php) and used by several
   blocks, so it lives here rather than in any one block's stylesheet — block
   styles only load on pages where that block is present, which left the label
   unstyled on pages that use it without the statement section. */
.section-label {
	display: flex;
	align-items: center;
	gap: 12px;
	height: 16px;
}

.section-label__text {
	color: var(--harbor);
	font-size: var(--wp--preset--font-size--eyebrow);
	font-weight: 800;
	line-height: 1.333;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	white-space: nowrap;
}

.section-label__rule {
	flex: 1 1 auto;
	height: 2px;
	background: rgba(11 22 40 / 0.08);
}

.text-link {
	margin: 0;
	color: var(--harbor);
	font-size: var(--wp--preset--font-size--body);
	font-weight: 600;
	line-height: 1.625;
}

/* A link inside a sentence: it takes the copy's colour and weight and is only
   underlined, so the line reads as one sentence rather than as copy with a
   button in it. Mars on hover, like every other link on the site. */
.inline-link {
	color: inherit;
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 2px;
}

.inline-link:hover,
.inline-link:focus-visible {
	color: var(--mars);
}

/* --------------------------------------------------------------------------
   404
   Not a block, so it lives here. Laid out like a section head: label rule,
   slash heading, a short paragraph, the two button styles. Every vertical
   measure is a share of the 1676 frame so the page holds its shape from
   1025 up, and the block is tall enough that the footer sits below the fold
   on a laptop rather than crowding the copy.
   -------------------------------------------------------------------------- */

.page-404 {
	background: var(--paper);
}

.page-404__container {
	width: var(--content);
	max-width: 100%;
	min-height: 33.413vw; /* 560 */
	margin-inline: auto;
	padding: 5.967vw 0 7.160vw; /* 100 / 120 */
}

.page-404__heading {
	display: flex;
	align-items: baseline;
	gap: 0.5em;
	max-width: 71.6vw; /* 1200 */
	margin: 3.580vw 0 0; /* 60 */
	color: var(--night);
	/* Pure vw above 1024, per the frame; the presets floor and would stop
	   scaling before the box does. Handed back to them below. */
	font-size: 3.461vw; /* 58 */
	font-weight: 700;
	line-height: 1.19;
	letter-spacing: -0.026em;
	text-wrap: balance;
}

.page-404__slash {
	flex: 0 0 auto;
}

.page-404__slash svg {
	width: 0.552em;  /* 32 / 58 */
	height: 0.931em; /* 54 / 58 */
}

.page-404__body {
	max-width: 34.368vw; /* 576 */
	margin: 1.671vw 0 0; /* 28 */
	color: var(--slate);
	font-size: 1.193vw; /* 20 */
	font-weight: 600;
	line-height: 1.625;
}

.page-404__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.955vw; /* 16 */
	margin-top: 2.864vw; /* 48 */
}

/* The shared buttons are a fixed 70 tall, which is the one thing here that
   would not scale with the frame; sized the way the hero sizes its own. */
.page-404__actions .btn {
	height: 4.177vw; /* 70 */
	padding: 0 1.432vw; /* 24 */
	border-radius: 0.43vw; /* 7.2 */
	font-size: 0.955vw; /* 16 */
}

@media (max-width: 1024px) {
	.page-404__container {
		min-height: 0;
		padding: 64px 0 80px;
	}

	.page-404__heading {
		max-width: none;
		margin-top: 40px;
		font-size: var(--wp--preset--font-size--heading-xl);
	}

	.page-404__body {
		max-width: none;
		margin-top: 20px;
		font-size: var(--wp--preset--font-size--body-lg);
	}

	.page-404__actions {
		gap: 12px;
		margin-top: 32px;
	}

	.page-404__actions .btn {
		height: 56px;
		padding: 0 24px;
		border-radius: var(--radius);
		font-size: var(--fs-16);
	}
}

@media (max-width: 782px) {
	.page-404__actions .btn {
		flex: 1 1 100%;
		justify-content: center;
	}
}

/* --------------------------------------------------------------------------
   Phone
   --------------------------------------------------------------------------
   Everything above this point describes the 1676 frame and the stacked layout
   it hands over to at 1024. This is the phone pass on top of that. The frame's
   proportions survive the trip down; three things do not.

   1. Type. The clamp() presets stop scaling at their floor, and those floors
      were chosen against the frame rather than against a phone - so a 10px
      eyebrow and an 11px feature description are not a scaled-down anything,
      they are fine print. They are restated here as fixed sizes, which keeps
      every block in step without each one repeating its own scale.

   2. Vertical rhythm. --label-gap-scale runs the gap between a section's rule
      and the headline under it at 3x on request. At 1676 that is a considered
      pause. At 375 it is 144px of nothing under the Models label - a third of
      the screen - and the reader scrolls past an empty room to reach the copy.

   3. Touch. The frame draws its short buttons 36px tall, which is below what a
      thumb reliably hits. The boxes grow; the labels inside them do not move.
   -------------------------------------------------------------------------- */

/* The type and the touch targets belong to the whole stacked tier, not to
   phones alone. 1024 is where the site stops being a scaled copy of the frame,
   and from there down the clamps are all sitting on their floors - a tablet at
   900 was reading the same 10px eyebrow as a phone at 375. The vertical rhythm
   is the one thing that is genuinely a matter of degree, so it keeps two
   steps. */

@media (max-width: 1024px) {
	:root {
		--label-gap-scale: 2;

		/* Fixed rather than clamped: below 1024 every one of these is sitting on
		   its floor anyway, so a plain value says what is actually rendered. */
		--fs-32: 26px;
		--fs-28: 24px;
		--fs-20: 18px;
		--fs-16: 16px;
		--fs-13: 14px;
		--fs-12: 13px;
		--fs-11: 13px;
		--fs-10: 12px;

		--wp--preset--font-size--eyebrow: 12px;
		--wp--preset--font-size--caption: 14px;
		--wp--preset--font-size--body: 16px;
		--wp--preset--font-size--body-lg: 17px;
		--wp--preset--font-size--heading-md: 20px;
	}

	/* 44px is the smallest target both Apple's HIG and WCAG 2.2 accept. These
	   buttons are 36 in the frame and 34 once the vw height hits its floor.
	   Tablets are touch devices too, so this starts at the same 1024. */
	.btn--short,
	.btn--short-solid,
	.btn--card-outline,
	.btn--harbor-outline,
	.btn--pill,
	.model-card .btn--model {
		height: 44px;
		min-height: 44px;
	}

	.btn--solid,
	.btn--outline {
		height: 56px;
	}
}

@media (max-width: 782px) {
	:root {
		--label-gap-scale: 1.5;
	}

	/* Links that are a target in their own right rather than a word inside a
	   sentence. The footer's social icon was 27px square and the phone number
	   18px tall - both are things someone taps, not reads. */
	.site-footer__social-link {
		width: 44px;
		height: 44px;
	}

	.site-footer a[href^="tel:"],
	.site-footer a[href^="mailto:"] {
		display: inline-block;
		padding-block: 10px;
	}

	/* The drawer is the whole navigation on a phone, so these are the most
	   tapped targets on the site - and they were the smallest, at 36. Set as a
	   floor with the label centred in it, so a two-line entry still grows. */
	.site-header.is-open .nav__list a,
	.site-header.is-open .nav__list .nav__trigger {
		display: flex;
		align-items: center;
		min-height: 44px;
	}

	/* The logo is a 12px-tall mark in a link box that was the same 12px. The
	   padding gives the thumb something to land on without moving the mark. */
	.site-header__logo {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
	}
}
