/**
 * Hero Longevity — structural rules only.
 *
 * The card opens by animating its own width, height and border-radius on a native CSS
 * scroll timeline — the same mechanism as the source — with the image filling it via
 * `object-cover`, so the crop tracks the source at every point in the scroll. No JS, no
 * GSAP, no scroll listener.
 *
 * Layout properties (width/height) are animated deliberately. The "only animate
 * transform/opacity" rule is about compositor eligibility across *many* elements — for a
 * single contained card, a per-frame layout is single-digit microseconds (~1000x under
 * the 16.7ms frame budget on desktop); the dominant cost is painting the image, kept
 * modest here (one <img>, no shadow/filter on the growing card). This matches the
 * source's crop exactly without the transform/clip gymnastics — which distort an
 * object-fit image's aspect and corners anyway.
 *
 * Gated behind `@supports` + `prefers-reduced-motion`; the element's default IS the
 * animation's rest state (the inset card), so reduced-motion users and browsers without
 * scroll-driven-animation support (e.g. Firefox stable until it ships) render that static
 * inset card — no flash, nothing hidden. Every dimension is a custom property for
 * per-breakpoint dialling.
 */

.hero-longevity {
	--hl-rest-w: calc(100% - 2rem); /* rest card width */
	--hl-rest-h: 20rem; /* rest card height */
	--hl-full-h: 22rem; /* full-bleed (end) height */
	--hl-radius: 1.25rem; /* rest corner radius */
	--hl-scrub: 560px; /* scroll distance over which the card opens */
}

/* Sticky-header overlap. With `felix_header_fixed_first_block` on, the shared rule in
 * critical/header.css pulls the first block up by --felix-header-overlap-offset, so this
 * section's white ground paints the strip behind the header instead of the slate-98 body
 * showing through it. That move is wanted for the background and not for the lockup, which
 * would otherwise sit 16px under the nav. Adding the same offset back as top padding puts
 * the content where the pt-* utilities alone would have put it, at both breakpoints, and
 * leaves the negative margin doing its job.
 *
 * Scoped to :first-child because only the first block is pulled — the closing banner is the
 * same block and must not gain the padding. Two classes plus the pseudo beat the pt-*
 * utilities on specificity, which is what makes this hold: utilities load after block CSS. */
.has-fixed-header-first-block .hero-longevity:first-child {
	padding-top: calc(var(--wp--preset--spacing--64) + var(--felix-header-overlap-offset));
}

@media (min-width: 64rem) {
	.has-fixed-header-first-block .hero-longevity:first-child {
		padding-top: calc(var(--wp--preset--spacing--96) + var(--felix-header-overlap-offset));
	}
}

.hero-longevity__content {
	max-width: 33.75rem;
}

.hero-longevity__asset {
	/* Rest state = the inset rounded card — the default, and the fallback reduced-motion +
	   no-scroll-animation browsers stay on. Width is 100% via `.w-full` on the markup; this
	   caps it to the rest size and the keyframe animates the cap open to full-bleed.
	   (max-width, not width, so the utility rule for width:100% is honoured.) */
	max-width: var(--hl-rest-w);
	height: var(--hl-rest-h);
	border-radius: var(--hl-radius);
	/* `layout paint` scopes the card's per-frame reflow/repaint to itself so the
	   width/height animation doesn't dirty the whole document — while still letting the
	   card resize its parent and push content below it as it grows, like the source.
	   NOT `size`/`strict`: those collapse a growing element to 0x0. */
	contain: layout paint;
}

@keyframes hero-longevity-open {
	to {
		max-width: 100%;
		height: var(--hl-full-h);
		border-radius: 0;
	}
}

/* The section's bottom padding closes as the card opens, so by the end of the scrub the
 * full-bleed image meets the next section with no seam — the source does the same, 96px
 * to 0 linearly across the same range. There is deliberately no `from`: the implicit
 * start is the element's own computed padding, which keeps the responsive `pb-*`
 * utilities on the markup as the single source of truth for the rest value. */
@keyframes hero-longevity-close-gap {
	to {
		padding-bottom: 0;
	}
}

/* ---------------------------------------------------------------------------
   Background style

   The artwork fills the section and the lockup sits on top of it. Used for the closing
   banner, whose art is a full-bleed composite that already contains its own subject and
   gradient. The scroll effect still applies — it opens the backdrop rather than a card.

   Height and framing match the source: 720px tall below 64rem and 850px above it, with
   the art anchored low so the subject stays in frame as the section is cropped. The
   subject sits in the lower half of the composite, which is why object-position pulls
   toward the bottom rather than centring.
   --------------------------------------------------------------------------- */
.hero-longevity--background {
	min-height: 45rem; /* 720px */
}

/* The hero's 540px measure exists to force its long headline onto two lines over the
 * card. A closing banner has no card under it and a short headline, and the source
 * leaves this one effectively uncapped so it sits on one line — 45rem keeps a readable
 * measure while giving a banner headline room not to wrap. */
.hero-longevity--background .hero-longevity__content {
	max-width: 45rem;
}

/* How far the backdrop insets at its rest size, mirroring the hero card's proportions so
   the two transitions read as the same move. The hero's rest card is `calc(100% - 2rem)`
   on mobile and 810px of ~1425 on desktop, so the sides inset 1rem and ~21% to match; a
   uniform inset would only reveal an edge and read as nothing happening. Radius reuses
   --hl-radius, so the inset banner and the inset hero card round identically. */
.hero-longevity--background {
	--hl-bg-inset-x: 1rem;
	--hl-bg-inset-y: 1.5rem;
}

@media (min-width: 48rem) {
	.hero-longevity--background {
		--hl-bg-inset-x: 10%;
		--hl-bg-inset-y: 2.5rem;
	}
}

@media (min-width: 64rem) {
	.hero-longevity--background {
		--hl-bg-inset-x: 21%;
		--hl-bg-inset-y: 4rem;
	}
}

.hero-longevity--background .hero-longevity__picture,
.hero-longevity--background .hero-longevity__picture img {
	object-position: 50% 90%;
}

/* lg — desktop */
@media (min-width: 64rem) {
	.hero-longevity--background {
		min-height: 53.125rem; /* 850px */
	}

	.hero-longevity--background .hero-longevity__picture,
	.hero-longevity--background .hero-longevity__picture img {
		object-position: 50% 70%;
	}
}

/* ---------------------------------------------------------------------------
   Reversed (closing banner)

   Same growth, keyed to the element instead of the document. The top hero opens as it
   scrolls AWAY, so its timeline is the document's scroll from 0. A closing banner has to
   open as it scrolls INTO view, which is what `view()` describes — progress through the
   element's own visibility. Nothing else changes: identical geometry, identical custom
   properties, no JS.

   The rest state is inverted with it. At the top of the page the card's resting form is
   the inset card, so that is the correct no-animation fallback. At the bottom the banner
   is read fully in view, so its resting form is the OPEN card — which is why this rule
   sets the open geometry as the default and the keyframe supplies only a `from`. Firefox
   (no scroll-driven animations yet) and reduced-motion users get the full-bleed banner
   rather than a small card floating in white space.
   --------------------------------------------------------------------------- */
.hero-longevity--reversed .hero-longevity__asset {
	max-width: 100%;
	height: var(--hl-full-h);
	border-radius: 0;
}

@keyframes hero-longevity-enter {
	from {
		max-width: var(--hl-rest-w);
		height: var(--hl-rest-h);
		border-radius: var(--hl-radius);
	}
}

/* Background style — the backdrop opens instead of a card. Only the absolutely-positioned
 * backdrop changes box, so the content above it never reflows.
 *
 * Two things are load-bearing here. The two-class selector: utilities load after block
 * CSS, so a single-class rule would tie with `.inset-0` on the same element and lose. And
 * the offsets are written as longhands, not the `inset` shorthand — a shorthand in
 * @keyframes does not interpolate, so the animation attaches and then does nothing.
 *
 * Same rest-state inversion as the card: opening on the way out starts inset, opening on
 * the way in ends full-bleed (and so is the correct no-animation fallback). */
.hero-longevity .hero-longevity__bg--animated {
	top: var(--hl-bg-inset-y);
	right: var(--hl-bg-inset-x);
	bottom: var(--hl-bg-inset-y);
	left: var(--hl-bg-inset-x);
	border-radius: var(--hl-radius);
}

@keyframes hero-longevity-bg-open {
	to {
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		border-radius: 0;
	}
}

@keyframes hero-longevity-bg-enter {
	from {
		top: var(--hl-bg-inset-y);
		right: var(--hl-bg-inset-x);
		bottom: var(--hl-bg-inset-y);
		left: var(--hl-bg-inset-x);
		border-radius: var(--hl-radius);
	}
}

@supports (animation-timeline: scroll()) and (animation-range: 0% 100%) {
	@media (prefers-reduced-motion: no-preference) {
		.hero-longevity__asset--animated {
			animation: hero-longevity-open linear both;
			animation-timeline: scroll(root block);
			animation-range: 0 var(--hl-scrub);
		}

		/* Barely in view = the inset card; fully in view = full-bleed. `entry` covers the
		 * element crossing the bottom edge, so the growth finishes as it lands. */
		.hero-longevity__asset--entering {
			animation: hero-longevity-enter linear both;
			animation-timeline: view();
			animation-range: entry 0% entry 100%;
		}

		/* Background style — the same two behaviours on the backdrop instead of a card. */
		.hero-longevity .hero-longevity__bg--animated {
			animation: hero-longevity-bg-open linear both;
			animation-timeline: scroll(root block);
			animation-range: 0 var(--hl-scrub);
		}

		.hero-longevity .hero-longevity__bg--entering {
			animation: hero-longevity-bg-enter linear both;
			animation-timeline: view();
			animation-range: entry 0% entry 100%;
		}

		/* Only when the card is actually animating — with the effect off, the static inset
		 * card keeps its bottom padding. `:has()` is safe to rely on here: it shipped well
		 * before scroll-driven animations, which this block already gates on. */
		.hero-longevity:has(.hero-longevity__asset--animated) {
			animation: hero-longevity-close-gap linear both;
			animation-timeline: scroll(root block);
			animation-range: 0 var(--hl-scrub);
		}
	}
}

/* md — tablet */
@media (min-width: 48rem) {
	.hero-longevity {
		--hl-rest-w: 32rem;
		--hl-rest-h: 24rem;
		--hl-full-h: 30rem;
		--hl-radius: 1.5rem;
		--hl-scrub: 720px;
	}
}

/* lg — desktop. Rest card ≈ 810×600 (matching the source), opening to full-bleed 800px. */
@media (min-width: 64rem) {
	.hero-longevity {
		--hl-rest-w: 810px;
		--hl-rest-h: 600px;
		--hl-full-h: 800px;
		--hl-radius: 2rem;
		--hl-scrub: 900px;
	}
}
