/*
 * Section: Header — Figma 4:6
 *
 * The section is 1676x661. The photo stack behind it is a separate frame,
 * 1676x927 with the image itself 893.82 tall, so the picture runs well past
 * the section and is clipped by it — that overhang is the composition. The
 * 1280 container is centred (Figma's left:198px is (1676-1280)/2), so it maps
 * to a normal centred container with the 768px block left-aligned inside it.
 */

.section-header {
	position: relative;
	display: flex;
	align-items: flex-start;

	/* 661 as a share of the frame. The 927 this used to carry is the photo
	   stack's frame, not the section's — it made the hero 122 too tall and
	   pulled the video's framing with it. The padding below matches the frame's
	   own 80.5, so a taller headline grows the section from the same figure
	   rather than fighting the floor. */
	min-height: 39.44vw; /* 661 */
	padding-bottom: 4.803vw; /* 80.5 */
	overflow: hidden;
	background: var(--paper);
}

/* Media stack ------------------------------------------------------------ */

/* 893.82 against the section's 661 — the picture overhangs by a third and the
   section clips it. Expressed against the section rather than the viewport
   (893.82 / 661 = 135.25%) so the overhang survives the section growing past
   its own ratio: on a narrow screen the copy is taller than 39.44vw, and a
   fixed 53.33vw left the picture barely taller than the box, which is what
   made the framing fall apart below ~1300. */
.section-header__media {
	position: absolute;
	inset: 0 0 auto;
	height: 135.25%;
	min-height: 53.33vw; /* 893.82 */
}

/* The photo is always wider and taller than the band it fills, so something
   has to be cropped away. Which part survives is the editor's call: the block
   sets --hero-focus as a pair of percentages, and centre is only the default.
   A skyline usually wants the top kept, a street-level shot the bottom. */
.section-header__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: var(--hero-focus, var(--img-focus, 50% 50%));
}

/* Sits over the still, under both scrims. It fades in once the first frame
   has painted so a slow start never flashes an empty box. */
.section-header__video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: var(--hero-focus, var(--img-focus, 50% 50%));
	opacity: 0;
	transition: opacity 400ms ease;
}

.section-header__video.is-playing {
	opacity: 1;
}

.section-header__scrim {
	position: absolute;
	inset: 0;
	display: block;
}

/* Left-to-right white wash so the copy stays legible over the photo. */
.section-header__scrim--x {
	background: linear-gradient(
		90deg,
		rgba(255 255 255 / 0.6) 57.846%,
		rgba(255 255 255 / 0.3) 68.31%,
		rgba(255 255 255 / 0.12) 100%
	);
}

/* Top-down wash so the nav sits on light ground. */
.section-header__scrim--y {
	background: linear-gradient(
		177.44deg,
		rgba(255 255 255 / 0.6) 13.644%,
		rgba(255 255 255 / 0.3) 20.592%,
		rgba(255 255 255 / 0.21) 24.804%,
		rgba(255 255 255 / 0.12) 34.432%
	);
}

/* Figma NOISE effect, DUOTONE, black 25% / white 25%, density 1, on the
   interior hero's Image frame (4006:6363, 2089:1020, 2089:1646 — HOME's hero
   4:6 has none). Each pixel takes black or white at a quarter alpha, so the
   net is photo x 0.75 + 25% mid grey: the sky comes down and the facade comes
   up. The tile is 128px of per-pixel black/white at alpha 0.25. */
.section-header__grain {
	position: absolute;
	inset: 0;
	display: block;
	background-image: url("../../assets/img/hero-grain.png");
	background-repeat: repeat;
	background-size: 128px 128px;
	pointer-events: none;
}

/* Grain at whatever --grain says, 0.12 as of 2026-10-28 — the frame's effect
   turned down, tuned by eye on Get in touch (2331:4557) and then taken
   site-wide. It is the layer's
   opacity rather than a different tile because the alpha is per-pixel in the
   art: 0.25 x 0.245 is 0.061, and the grain's amplitude follows it exactly.

   The tile is near enough black-and-white in equal measure that the tone it
   carries very nearly cancels: turning it down moves the hero's mean by only a
   few of 255, up in the sky and down in the shadows. The grain goes, the
   exposure stays.

   HOME (4:6) is drawn without the effect in Figma and carries it here anyway,
   on request, so that no photograph on the site is the odd one out. It sits
   under both white washes, as the frame puts noise below Darken.

   The article pages are the exception: the photo attached to an individual
   insight, news item or customer story renders clean. See inc/grain.php. */
.section-header__grain {
	opacity: var(--grain);
}

.is-grain-none .section-header__grain {
	display: none;
}

/* Figma 4:10. The Mark frame is 1676x585 at y=51, but it only clips a much
   larger vector: the SVG box is 2595x1006 sitting at x=0, y=-215 inside that
   frame — i.e. y=-164 against the hero — and the artwork's ink starts at
   x=838, exactly half the frame width, which is what puts the mark on the
   right-hand side. Stretching the SVG to the frame's own 1676x585 (as this
   did) both squashed it — the file carries preserveAspectRatio="none" — and
   pulled the ink to the wrong place.

   Sized in vw off the 1676 frame so the ink stays anchored at the 50% line
   whatever the viewport. */
.section-header__mark {
	position: absolute;
	top: -9.785vw; /* -164 */
	left: 0;
	display: block;
	width: 154.833vw; /* 2595 */
	height: 60.024vw; /* 1006 */
	pointer-events: none;
}

.section-header__mark svg {
	width: 100%;
	height: 100%;
}

/* Content ---------------------------------------------------------------- */

.section-header__container {
	position: relative;
	z-index: 1;
	width: var(--content);
	max-width: 100%;
	margin-inline: auto;
	padding: 60px 0 0;
}

.section-header__block {
	max-width: 64%; /* 768 / 1200 */
	padding-top: 39px;
}

/* The frame's headline text box is 872px inside a 768px block — it is meant
   to run past the block's edge rather than be clipped by it. */
.section-header__headline {
	width: max-content;
	max-width: 100vw;
}

.section-header__eyebrow {
	margin: 0 0 30.5px;
}

.section-header__headline {
	margin: 0;
	/* The frame gives this an 872px text box with whitespace-nowrap: the
	   line breaks are explicit, it never wraps. */
	white-space: nowrap;
	color: var(--mars);
	font-size: var(--wp--preset--font-size--display);
	font-weight: 800;
	line-height: 1.06;
	letter-spacing: -0.025em;
}

.section-header__body {
	max-width: 75%; /* 576 / 768, measured against the block */
	margin: 28px 0 0;
	color: var(--harbor);
	font-size: var(--wp--preset--font-size--body-lg);
	font-weight: 600;
	line-height: 1.625;
}

.section-header__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 16px;
	margin-top: 40px;
}

/* HOME: one scale, every width -------------------------------------------
 *
 * The section is 661 in a 1676 frame — a fixed 39.44% of the width. It only
 * holds that if everything stacked inside it is the same share of the frame:
 * the paddings above were plain pixels (60, 39, 30.5, 28, 40, and a 70 button)
 * and the type clamps stop shrinking well before the design width — body-lg
 * floors at 17px below 1425 — so as the window narrowed the stack stayed put
 * while the width halved, and the hero grew proportionally taller. Everything
 * below is the Figma value over 1676, so the whole hero is the same picture at
 * a different size rather than a taller one.
 *
 * Scoped away from the interior hero, which is sized by its own copy on
 * purpose — its frames are 371 to 542 depending on the page.
 *
 * The mobile block further down takes over at 782, where a strictly
 * proportional headline would be too small to read.
 */
.section-header:not(.is-style-interior) .section-header__container {
	padding-top: 3.58vw; /* 60 */
}

.section-header:not(.is-style-interior) .section-header__block {
	padding-top: 2.327vw; /* 39 */
}

.section-header:not(.is-style-interior) .section-header__eyebrow {
	margin-bottom: 1.82vw; /* 30.5 */
	font-size: 0.716vw; /* 12 */
}

.section-header:not(.is-style-interior) .section-header__headline {
	font-size: 5.251vw; /* 88 */
}

.section-header:not(.is-style-interior) .section-header__body {
	margin-top: 1.671vw; /* 28 */
	font-size: 1.193vw; /* 20 */
}

.section-header:not(.is-style-interior) .section-header__actions {
	gap: 0.955vw; /* 16 */
	margin-top: 2.387vw; /* 40 */
}

.section-header:not(.is-style-interior) .section-header__actions .btn--solid {
	height: 4.177vw; /* 70 */
	padding: 0 1.432vw; /* 24 */
	border-radius: 0.43vw; /* 7.2 */
	font-size: 0.955vw; /* 16 */
}

/* Interior pages use a shorter hero — Figma 2089:1018 (Capital Solutions).
   The frame is 542 tall with the photo running 617, so the image bleeds past
   the section and is clipped. Where HOME washes the photo white to carry dark
   copy, an interior hero darkens it and sets the copy in white. */
/* Every interior frame sizes this from its own copy — 120 above, 64 below —
   which is why they come out at 371, 404, 497, 510 and 542 rather than sharing
   one height. Both figures are scaled off the 1676 frame so the copy keeps its
   share of the hero as the page widens, which is what a fixed 120 on a fluid
   box failed to do. */
.is-style-interior.section-header {
	min-height: 0;
	padding-bottom: clamp(40px, 3.819vw, 83px); /* 64 */
}

.is-style-interior .section-header__media {
	height: 36.81vw; /* 617 */
	min-height: 100%;
	max-height: none;
}

.is-style-interior .section-header__scrim--x {
	background: linear-gradient(
		90deg,
		rgba(11 22 40 / 0.18) 57.846%,
		rgba(11 22 40 / 0.12) 72.436%,
		rgba(11 22 40 / 0.04) 100%
	);
}

/* The frame carries no second wash on an interior hero. */
.is-style-interior .section-header__scrim--y {
	display: none;
}

.is-style-interior .section-header__mark {
	top: -9.785vw; /* -164, as on HOME */

	/* hero-mark.svg bakes the mark at white 20%, which is HOME's value (4:6).
	   Every interior frame — 2089:1018, 2089:1644, 4006:6361 — sets it at 10%,
	   so halve the layer rather than ship a second copy of the artwork. */
	opacity: 0.5;
}

/* The frame's 120 above the headline is 22.14% of its 542-tall hero. The
   section height is fluid, so a fixed 120 would let the copy drift toward the
   top as the box grows — it has to keep the same share of the height. The
   clamp bounds are that share of the height clamp's own ends: 420 -> 93,
   700 -> 155. */
.is-style-interior .section-header__container {
	padding-top: clamp(93px, 7.16vw, 155px);
}

.is-style-interior .section-header__block {
	padding-top: 0;
}

.is-style-interior .section-header__headline {
	color: #fff;
}

.is-style-interior .section-header__body {
	color: rgba(255 255 255 / 0.8);
}

/* The interior hero has to hold its share of the frame the same way HOME does.
   Its body copy was on the --body-lg preset, which floors at 17px from 1425
   down, and its 28 above was a plain pixel value — so as the window narrowed
   the copy kept its size while the width shrank and the hero grew
   proportionally deeper (404 at 1676, 424-equivalent at 1280). Both are shares
   of the 1676 frame now. Above 1024 only: below the handover the preset ramp
   takes back over, or the body would be 9px on a phone. */
@media (min-width: 1025px) {
	/* The clamp's 93px floor was the last fixed value in the stack: at 1025 it
	   is 152 against the frame rather than 120, which put the hero 32 deeper
	   than 4006:6361. Pure vw above the handover. The nav is a fixed 56 at
	   every width and sits over the hero, so the gap under it narrows as the
	   window does (64 at 1676, 17 at 1025) — the frame's own proportion, not a
	   fixed inset. */
	.is-style-interior .section-header__container {
		padding-top: 7.16vw; /* 120 */
	}

	.is-style-interior.section-header {
		padding-bottom: 3.819vw; /* 64 */
	}

	.is-style-interior .section-header__body {
		margin-top: 1.671vw; /* 28 */
		font-size: 1.193vw; /* 20 */
		line-height: 1.625; /* 32.5 / 20 */
	}
}

/* Legal documents (inc/legal.php): their sub is one or two lines against the
   four on About and Careers, and since the interior hero is as deep as its
   copy they ran 65 short of every other hero (370 against 435 at 1676). The
   body holds four lines' worth so the hero is the same depth as its
   neighbours', whatever the sub says. In em so it follows the type through
   both regimes — 20 x 1.625 x 4 = 130 at 1676. */
.is-legal-document .is-style-interior .section-header__body {
	min-height: 6.5em; /* 4 x 1.625 */
}

/* Figma 2328:3855 (article page): the Buttons frame is 106 tall — 36 of top
   padding over a 70 button — where HOME leaves 40. Scaled off the frame like
   the rest of the interior hero, so the button keeps its share of the box. */
.is-style-interior .section-header__actions {
	gap: 0.955vw; /* 16 */
	margin-top: 2.148vw; /* 36 */
}

.is-style-interior .section-header__actions .btn--solid {
	height: 4.177vw; /* 70 */
	padding: 0 1.432vw; /* 24 */
	border-radius: 0.43vw; /* 7.2 */
	font-size: 0.955vw; /* 16 */
}

/* Steel rather than Harbor on the dark ground. */
.is-style-interior .section-header__actions .btn--solid {
	background: var(--steel);
}

.is-style-interior .section-header__actions .btn--solid:hover,
.is-style-interior .section-header__actions .btn--solid:focus-visible {
	background: var(--harbor);
}

/* Multifamily (2089:1644) runs the same interior hero over a lighter photo, so
   the wash is twice as deep and the button goes back to Harbor. */
.is-style-interior.is-tone-deep .section-header__scrim--x {
	background: linear-gradient(
		90deg,
		rgba(11 22 40 / 0.36) 57.846%,
		rgba(11 22 40 / 0.24) 72.436%,
		rgba(11 22 40 / 0.08) 100%
	);
}

.is-style-interior.is-tone-deep .section-header__actions .btn--solid {
	background: var(--harbor);
}

.is-style-interior.is-tone-deep .section-header__actions .btn--solid:hover,
.is-style-interior.is-tone-deep .section-header__actions .btn--solid:focus-visible {
	background: var(--night);
}

/* The article hero (2328:3856) is washed as deep as Multifamily's but keeps the
   Steel button, so the two are not the same switch after all — this puts Steel
   back where a page asks for it, without disturbing the pages that read the
   deep wash and the Harbor button as one thing. */
.is-style-interior.is-cta-steel .section-header__actions .btn--solid {
	background: var(--steel);
}

.is-style-interior.is-cta-steel .section-header__actions .btn--solid:hover,
.is-style-interior.is-cta-steel .section-header__actions .btn--solid:focus-visible {
	background: var(--harbor);
}

/* The Team hero (2243:1605) doubles the wash again — its photo is the
   brightest of the set. */
.is-style-interior.is-tone-deepest .section-header__scrim--x {
	background: linear-gradient(
		90deg,
		rgba(11 22 40 / 0.72) 57.846%,
		rgba(11 22 40 / 0.48) 72.234%,
		rgba(11 22 40 / 0.16) 93.107%
	);
}

/* Responsive -------------------------------------------------------------- */

@media (max-width: 1024px) {
	/* No height or media overrides: both are shares of the frame now, so the
	   picture keeps the same overhang — and the same framing — all the way
	   down. HOME keeps its block measure and its left-to-right wash too: the
	   whole hero is one scale, and widening the copy or turning the gradient
	   through 90 degrees would make it a different picture rather than a
	   smaller one. Both give way at 782, in the mobile block below. */
	.is-style-interior .section-header__block {
		max-width: none;
		padding-top: 0;
	}
}

@media (max-width: 1024px) {
	/* Left over from when the interior hero was a fixed box: a 420 floor with
	   128 above the copy left 131 of dead space under a headline that had come
	   down to 161. The hero sizes to its copy now, so only the photo needs
	   saying — it stops overshooting and fills the section instead. */
	.is-style-interior .section-header__media {
		height: 100%;
	}

	/* No padding-top of its own: the fluid clamp already bottoms out at 93,
	   which clears the 56 bar. An override here only made the gap jump
	   upward as the screen got narrower. */
}

/* Between 782 and 1024 the hero still held its single scale, by the decision
   recorded above - and the picture and the measure should. The type should
   not: at 900 that ramp puts the body copy at 10.7px and the button label at
   8.6, inside a 37px control. Those three come off the frame here, and only
   those three. Everything that makes the hero the picture it is - the photo's
   overhang, the block measure, the left-to-right wash - still gives way at 782
   in the block below. */

@media (max-width: 1024px) {
	.section-header:not(.is-style-interior) .section-header__body,
	.is-style-interior .section-header__body {
		font-size: var(--wp--preset--font-size--body-lg);
	}

	.section-header:not(.is-style-interior) .section-header__actions .btn--solid,
	.is-style-interior .section-header__actions .btn--solid {
		height: 56px;
		padding: 0 24px;
		border-radius: 7.2px;
		font-size: var(--fs-16);
	}
}

@media (max-width: 782px) {
	/* Below here a strictly proportional hero would set the headline at 41px
	   and the body at 9, so HOME drops the single scale and takes the type and
	   spacing back off the preset ramp. */
	.section-header:not(.is-style-interior) .section-header__container {
		padding-top: 96px;
	}

	.section-header:not(.is-style-interior) .section-header__eyebrow {
		margin-bottom: 20px;
		font-size: var(--wp--preset--font-size--eyebrow);
	}

	.section-header:not(.is-style-interior) .section-header__headline {
		font-size: var(--wp--preset--font-size--display);
	}

	.section-header:not(.is-style-interior) .section-header__body {
		margin-top: 20px;
		font-size: var(--wp--preset--font-size--body-lg);
	}

	.section-header:not(.is-style-interior) .section-header__actions {
		gap: 16px;
		margin-top: 28px;
	}

	.section-header:not(.is-style-interior) .section-header__actions .btn--solid {
		height: 56px;
		padding: 0 24px;
		border-radius: 7.2px;
		font-size: var(--fs-16);
	}

	.section-header__block {
		max-width: none;
		padding-top: 0;
	}

	/* The left-to-right wash does not work on a narrow column. */
	.section-header__scrim--x {
		background: linear-gradient(
			180deg,
			rgba(255 255 255 / 0.75) 0%,
			rgba(255 255 255 / 0.55) 100%
		);
	}

	.is-style-interior.section-header {
		padding-bottom: 48px;
	}

	.is-style-interior .section-header__container {
		padding-top: 88px;
	}

	/* 4.177vw is 32px here — smaller than the label on it. */
	.is-style-interior .section-header__actions {
		gap: 16px;
		margin-top: 28px;
	}

	.is-style-interior .section-header__actions .btn--solid {
		height: 56px;
		padding: 0 24px;
		border-radius: 7.2px;
		font-size: var(--fs-16);
	}

	.section-header__body {
		max-width: none;
	}

	/* Below this the headline no longer fits on one line even at the
	   smallest step of the fluid size, so let it wrap inside the column. */
	.section-header__headline {
		width: auto;
		max-width: 100%;
		white-space: normal;
	}

	.section-header__actions .btn {
		width: 100%;
		justify-content: center;
	}
}
