/* ==========================================================================
   Service landing pages (page-service-landing.php)
   1. Hero: brand-blue panel, copy beside a person in front of a white keyhole
      1b. Mirrored hero with its own strip (Digital Marketing Training)
   2. Staged services: sticky rail (desktop) and stages
   3. Service rows, and the columns layout for a stage
      3b. Statement band (Digital Marketing Consulting: How We Work)
   4. Motion: hero entrance, module orbit, rail marker, row fill, statement draw

   The case studies, logo strip, support band, FAQ and closing CTA are shared:
   case-studies.css, logos.css, support.css and closing.css.
   All motion for this page lives in section 4 at the bottom.
   ========================================================================== */

/* 1. Hero
   Full bleed brand blue under the light header. Left: breadcrumb, headline,
   paragraph, actions, and the stage strip along the bottom. Right: the scene,
   a solid white keyhole with a cut-out of a person standing in front of it.
   The scene sits on the bottom edge of the panel: the keyhole's stem runs off
   it and the section clips it, and the person's base sits on it.
   Phones and tablets: stacked, the scene centred below the copy.
   ========================================================================== */

.landing-hero {
	--focus-color: var(--on-blue);
	--person-width: 18rem; /* the cut-out: about 306px tall */

	position: relative;
	isolation: isolate;
	overflow: clip;
	padding-top: var(--space-8);
	color: var(--on-blue);
	background-color: var(--brand-blue);
}

.landing-hero__inner {
	display: grid;
	gap: var(--space-8);
}

.landing-hero__copy {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
}

/* Breadcrumb: eyebrow style, white, with a slash between crumbs. */
.breadcrumb__list {
	display: flex;
	flex-wrap: wrap;
	margin: 0;
	padding: 0;
	font-size: var(--text-sm);
	font-weight: var(--weight-semibold);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	list-style: none;
}

.breadcrumb__item + .breadcrumb__item::before {
	content: "/" / "";
	margin-inline: var(--space-2);
	opacity: 0.7;
}

.breadcrumb a {
	color: var(--on-blue);
	text-decoration: underline;
	text-decoration-color: color-mix(in srgb, var(--on-blue) 50%, transparent);
	text-underline-offset: 0.3em;
}

.breadcrumb a:hover {
	text-decoration-color: var(--accent-yellow);
}

.landing-hero__title {
	max-width: 16ch;
	margin-top: var(--space-5);
	color: var(--on-blue);
}

/* Each word is its own box so the entrance can rise them in turn. */
.landing-hero__word {
	display: inline-block;
}

.landing-hero__text {
	max-width: var(--measure);
	margin-top: var(--space-5);
	font-size: var(--text-lg);
}

.landing-hero__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-4) var(--space-6);
	margin-top: var(--space-6);
}

.landing-hero__link {
	font-weight: var(--weight-semibold);
	color: var(--on-blue);
	text-decoration: underline;
	text-decoration-color: var(--accent-yellow);
	text-decoration-thickness: 2px;
	text-underline-offset: 0.3em;
}

.landing-hero__link:hover {
	text-decoration-color: var(--on-blue);
}

/* Stage strip: the five stages in small white caps, yellow dots between them.
   Each dot belongs to the name before it, so a wrapped line never starts with
   a dot; hovering or focusing a name grows the dots either side of it. Wraps
   on narrow screens. */
.stage-strip {
	margin-top: var(--space-7);
}

.stage-strip__list {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	row-gap: var(--space-2);
	margin: 0;
	padding: 0;
	list-style: none;
}

/* A block-level flex box, not inline-flex: an inline box would sit on a text
   line by its baseline, and a link that starts with a dot (every one but the
   first) takes its baseline from the dot, lifting the first name about 2px. */
.stage-strip__link {
	display: flex;
	align-items: center;
	padding-block: var(--space-1);
	font-size: var(--text-sm);
	font-weight: var(--weight-extrabold);
	letter-spacing: 0.08em;
	line-height: 1.2;
	text-transform: uppercase;
	color: var(--on-blue);
	text-decoration: none;
}

.stage-strip__item {
	display: flex;
	align-items: center;
}

.stage-strip__item:not(:last-child)::after {
	content: "";
	flex-shrink: 0;
	width: 6px;
	height: 6px;
	margin-inline: var(--space-3);
	background-color: var(--accent-yellow);
	border-radius: 50%;
}

.stage-strip__link:hover {
	text-decoration: underline;
	text-decoration-color: var(--accent-yellow);
	text-decoration-thickness: 2px;
	text-underline-offset: 0.35em;
}

.stage-strip__item:has(.stage-strip__link:hover, .stage-strip__link:focus-visible)::after,
.stage-strip__item:has(+ .stage-strip__item .stage-strip__link:hover, + .stage-strip__item .stage-strip__link:focus-visible)::after {
	transform: scale(1.6);
}

/* The scene. Its box is the person's box; the keyhole is placed against it.
   Both layers are wrappers the cursor lean moves (landing-hero.js), so it
   never fights the entrance, which animates what is inside them. */
.landing-hero__scene {
	position: relative;
	justify-self: center;
	width: var(--person-width);
	max-width: 100%;
	aspect-ratio: var(--scene-ratio, 1398 / 1486);
}

.landing-hero__keyhole-layer,
.landing-hero__person-layer {
	position: absolute;
	inset: 0;
}

/* Solid white keyhole: circle and stem, sized and placed from the cut-out.
   Measured on the 1398 x 1486 photo: her face is centred at x 709, her head
   about 520 wide, her hair starts near the top edge.
   - The round top is centred on her face (50.7% across), 63% of the photo's
     width: about 1.7 times her head, so white shows round her head like a halo,
     with about 90px of white above her hair.
   - Its top sits 6.06% of the photo's height above the photo; with the shape's
     proportions (123 x 220) its base lands exactly on the photo's bottom edge,
     so both sit on the bottom of the panel.
   The keyhole's neck and upper stem show beside her neck; her shoulders cover
   the stem's flared base. Chosen over fading her shoulders: the stem is only
   81% as wide as the circle, so no scale gives both a halo and a stem wider
   than her shoulders.
   Another page's photo sets its own placement on the scene (--keyhole-top,
   --keyhole-left, --keyhole-width; see 'keyhole' in inc/landing-pages.php).
   These defaults are the Branding and Marketing photo's. */
.landing-hero__keyhole {
	position: absolute;
	top: var(--keyhole-top, -6.06%);
	left: var(--keyhole-left, calc(50.7% - 31.5%));
	width: var(--keyhole-width, 63%);
	height: auto;
	max-width: none;
	overflow: visible;
	transform-origin: 50% 25%;
}

.landing-hero__keyhole path {
	fill: var(--on-blue);
}

/* The person: natural colour with a subtle cool grade (#landing-hero-cool, and
   slightly less saturation) so warm skin tones sit with the brand blue, and a
   soft shadow that falls on the keyhole behind her. */
.landing-hero__person {
	display: block;
}

.landing-hero__person img {
	display: block;
	width: 100%;
	height: auto;
	filter:
		url("#landing-hero-cool")
		saturate(0.9)
		drop-shadow(0 0.5rem 0.75rem color-mix(in srgb, var(--brand-blue-900) 22%, transparent));
}

/* An uploaded cut-out (the page's Hero image field) fills the box set for the
   built-in photo, standing on its bottom edge, so any upload size or shape
   keeps the keyhole placement and the panel height. */
.landing-hero__person--upload,
.landing-hero__person--upload img {
	height: 100%;
}

.landing-hero__person--upload img {
	object-fit: contain;
	object-position: 50% 100%;
}

/* A photo whose top edge is pale (Digital Marketing Training: sunlit hair at
   her parting) gets a second, faint shadow cast upward, so her head outline
   stays readable against the white circle. It only darkens upward-facing
   edges; her hair colour is unchanged. */
.landing-hero__person--top-edge img {
	filter:
		url("#landing-hero-cool")
		saturate(0.9)
		drop-shadow(0 0.5rem 0.75rem color-mix(in srgb, var(--brand-blue-900) 22%, transparent))
		drop-shadow(0 -1px 2px color-mix(in srgb, var(--brand-blue-900) 35%, transparent));
}

.landing-hero__defs {
	position: absolute;
}

@media (min-width: 40em) {
	.landing-hero {
		--person-width: 28rem;
	}
}

/* Desktop: copy about 55%, scene about 45%. The panel is as tall as the scene
   plus its top padding; the stage strip sits along the bottom of the copy. */
@media (min-width: 64em) {
	.landing-hero {
		--person-width: 32rem; /* about 545px tall; the keyhole about 560px */

		padding-top: var(--space-9);
	}

	.landing-hero__inner {
		grid-template-columns: minmax(0, 11fr) minmax(0, 9fr);
		gap: var(--space-6);
	}

	.landing-hero__copy {
		padding-bottom: var(--space-7);
	}

	.stage-strip {
		margin-top: auto;
		padding-top: var(--space-8);
	}

	.landing-hero__scene {
		align-self: end;
	}
}

/* 1b. Mirrored hero (landing-hero--mirrored)
   The same panel and parts with the scene on the left and the copy on the
   right, from desktop. Phones and tablets stack exactly as above: copy, then
   the scene centred below it. Reading order is always copy first.

   A photo placed with its own keyhole (landing-hero__scene--placed) gets room
   above it for the keyhole's round top: --keyhole-headroom is how far the top
   rises above the photo, as a share of its width. The top may rise up to
   --space-7 into the panel's top padding, as on Branding and Marketing.
   ========================================================================== */

.landing-hero__scene--placed {
	margin-top: max(0px, calc(var(--person-width) * var(--keyhole-headroom, 0) - var(--space-7)));
}

.landing-hero--mirrored {
	--person-width: 17rem;
}

@media (min-width: 40em) {
	.landing-hero--mirrored {
		--person-width: 24rem;
	}
}

@media (min-width: 64em) {
	/* The panel comes out the same height as Branding and Marketing's. */
	.landing-hero--mirrored {
		--person-width: 25rem;
	}

	.landing-hero--mirrored .landing-hero__inner {
		grid-template-columns: minmax(0, 9fr) minmax(0, 11fr);
	}

	.landing-hero--mirrored .landing-hero__copy {
		grid-column: 2;
		grid-row: 1;
	}

	.landing-hero--mirrored .landing-hero__scene {
		grid-column: 1;
		grid-row: 1;
	}
}

/* The orbiting names are drawn above the scene (landing-orbit.js). */
.landing-hero--orbit .landing-hero__copy {
	position: relative;
	z-index: 1;
}

/* 2. Staged services
   Desktop: the rail (about 256px) beside the stages. The rail sticks just
   below the top of the window while the stages scroll past. Its track fills
   with brand blue as the reader moves through the section, and the stage in
   view gets a yellow marker and blue name (assets/js/service-stages.js).
   Phones and tablets: no rail; each stage's own heading leads its rows.
   ========================================================================== */

.stages {
	padding-block: var(--space-section);
	background-color: var(--surface);
}

.stages__title {
	max-width: 24ch;
	margin-top: var(--space-4);
	color: var(--brand-blue);
}

.stages__layout {
	margin-top: var(--space-8);
}

.stages__rail {
	display: none;
}

@media (min-width: 64em) {
	.stages__layout {
		display: grid;
		grid-template-columns: 16rem minmax(0, 1fr);
		gap: var(--space-8);
	}

	.stages__rail {
		position: sticky;
		top: var(--space-7);
		align-self: start;
		display: block;
		padding-left: var(--space-6);
	}
}

/* The track: a 2px line down the left of the list. The fill is scaled by
   --stage-progress (0 to 1), set by the script. */
.stages__track {
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	width: 2px;
	overflow: hidden;
	background-color: var(--border-subtle);
	border-radius: 1px;
}

.stages__fill {
	display: block;
	height: 100%;
	background-color: var(--brand-blue);
	transform: scaleY(var(--stage-progress, 0));
	transform-origin: top;
}

.stages__list {
	display: grid;
	gap: var(--space-2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.stages__link {
	position: relative;
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	align-items: baseline;
	column-gap: var(--space-3);
	padding-block: var(--space-3);
	color: var(--ink-muted);
	text-decoration: none;
}

.stages__num {
	font-size: var(--text-sm);
	font-weight: var(--weight-extrabold);
	font-variant-numeric: tabular-nums;
}

.stages__name {
	font-size: var(--text-lg);
	font-weight: var(--weight-extrabold);
	line-height: var(--leading-snug);
	text-transform: uppercase;
}

.stages__count {
	grid-column: 2;
	font-size: var(--text-sm);
}

.stages__link:hover {
	color: var(--brand-blue);
}

.stages__link[aria-current="true"] .stages__num,
.stages__link[aria-current="true"] .stages__name {
	color: var(--brand-blue);
}

/* Yellow marker on the track beside the active stage. The track sits at the
   rail's left edge, --space-6 to the left of the link. */
.stages__link::before {
	content: "";
	position: absolute;
	top: calc(var(--space-3) + 0.55em);
	left: calc(-1 * var(--space-6) - 5px);
	width: 12px;
	height: 12px;
	background-color: var(--accent-yellow);
	border-radius: 50%;
	transform: scale(0);
}

.stages__link[aria-current="true"]::before {
	transform: scale(1);
}

/* A stage: its number and large name, then its rows. */
.stage {
	scroll-margin-top: var(--space-6);
}

/* Focused only by the rail's jump links, to move keyboard position; not interactive. */
.stage:focus {
	outline: none;
}

.stage + .stage {
	margin-top: var(--space-8);
}

.stage__head {
	display: flex;
	align-items: baseline;
	gap: var(--space-4);
	padding-bottom: var(--space-5);
}

.stage__num {
	font-size: var(--text-base);
	font-weight: var(--weight-extrabold);
	font-variant-numeric: tabular-nums;
	color: var(--brand-blue);
}

.stage__title {
	font-size: var(--text-4xl);
	line-height: var(--leading-tight);
	color: var(--brand-blue);
}

/* 3. Service rows
   Editorial rows separated by hairlines: no cards. Phones: number and icon,
   then name and description, then the link. From tablet: number, icon, text
   and link in one line.

   Hover (on devices that hover) and keyboard focus inside the row fill it
   with brand blue from the left; text turns white, number and icon yellow
   (3.8:1 on brand blue, fine for large numerals and icons). The row is never a
   link itself: only "Explore More" is, once the service's page exists.
   ========================================================================== */

.service-rows {
	margin: 0;
	border-top: 1px solid var(--border-subtle);
}

.service-row {
	position: relative;
	isolation: isolate;
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	grid-template-areas:
		"num icon"
		"body body"
		"link link";
	align-items: center;
	gap: var(--space-4);
	padding: var(--space-5) var(--space-4);
	border-bottom: 1px solid var(--border-subtle);
}

.service-row::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-color: var(--brand-blue);
	transform: scaleX(0);
	transform-origin: left;
}

.service-row__num {
	grid-area: num;
	min-width: 2ch;
	font-size: var(--text-3xl);
	font-weight: var(--weight-regular);
	line-height: 1;
	font-variant-numeric: tabular-nums;
	color: var(--brand-blue);
}

.service-row__icon {
	grid-area: icon;
	width: 2rem;
	height: 2rem;
	color: var(--brand-blue);
}

.service-row__body {
	grid-area: body;
}

.service-row__name {
	font-size: var(--text-lg);
	color: var(--ink);
}

.service-row__desc {
	max-width: var(--measure);
	margin-top: var(--space-2);
	color: var(--ink);
}

.service-row__link {
	grid-area: link;
	justify-self: start;
	font-size: var(--text-sm);
	font-weight: var(--weight-semibold);
	white-space: nowrap;
	color: var(--brand-blue);
	text-decoration: underline;
	text-decoration-color: var(--accent-yellow);
	text-decoration-thickness: 2px;
	text-underline-offset: 0.3em;
}

@media (min-width: 40em) {
	.service-row {
		grid-template-columns: 4.5rem 2rem minmax(0, 1fr) auto;
		grid-template-areas: "num icon body link";
		align-items: start;
		column-gap: var(--space-5);
		padding-block: var(--space-6);
	}

	.service-row__icon {
		margin-top: 0.1em;
	}

	.service-row__link {
		align-self: center;
	}
}

/* The filled state: keyboard focus anywhere in the row, always. */
.service-row:focus-within {
	--focus-color: var(--on-blue);
}

.service-row:focus-within::before {
	transform: scaleX(1);
}

.service-row:focus-within .service-row__name,
.service-row:focus-within .service-row__desc,
.service-row:focus-within .service-row__link {
	color: var(--on-blue);
}

.service-row:focus-within .service-row__num,
.service-row:focus-within .service-row__icon {
	color: var(--accent-yellow);
}

/* The same on hover, only where hover exists, so touch screens don't leave
   a row stuck filled after a tap. */
@media (hover: hover) {
	.service-row:hover::before {
		transform: scaleX(1);
	}

	.service-row:hover .service-row__name,
	.service-row:hover .service-row__desc,
	.service-row:hover .service-row__link {
		color: var(--on-blue);
	}

	.service-row:hover .service-row__num,
	.service-row:hover .service-row__icon {
		color: var(--accent-yellow);
	}
}

/* A module row is a jump target from the hero strip. */
.service-row[id] {
	scroll-margin-top: var(--space-7);
}

/* Columns (a stage with 'layout' => 'columns'): its items side by side, two
   equal columns split by a vertical hairline, from 768px. Each: a large
   regular-weight number, icon, name and description. Stacked below 768px,
   split by hairlines like rows. Never links. Hover and keyboard focus fill a
   column with brand blue from the left, exactly as a row. */
.stage-columns {
	display: grid;
	margin: 0;
	border-top: 1px solid var(--border-subtle);
	border-bottom: 1px solid var(--border-subtle);
}

.stage-column {
	position: relative;
	isolation: isolate;
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	align-items: center;
	gap: var(--space-4) var(--space-5);
	padding: var(--space-6) var(--space-4);
}

.stage-column + .stage-column {
	border-top: 1px solid var(--border-subtle);
}

.stage-column::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-color: var(--brand-blue);
	transform: scaleX(0);
	transform-origin: left;
}

.stage-column__num {
	font-size: var(--text-4xl);
	font-weight: var(--weight-regular);
	line-height: 1;
	font-variant-numeric: tabular-nums;
	color: var(--brand-blue);
}

.stage-column__icon {
	width: 2rem;
	height: 2rem;
	color: var(--brand-blue);
}

.stage-column__name,
.stage-column__desc {
	grid-column: 1 / -1;
}

.stage-column__name {
	margin-top: var(--space-2);
	font-size: var(--text-lg);
	color: var(--ink);
}

.stage-column__desc {
	color: var(--ink);
}

@media (min-width: 48em) {
	.stage-columns {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.stage-column {
		align-content: start;
		padding: var(--space-7) var(--space-6);
	}

	.stage-column + .stage-column {
		border-top: 0;
		border-left: 1px solid var(--border-subtle);
	}
}

.stage-column:focus-within {
	--focus-color: var(--on-blue);
}

.stage-column:focus-within::before {
	transform: scaleX(1);
}

.stage-column:focus-within .stage-column__name,
.stage-column:focus-within .stage-column__desc {
	color: var(--on-blue);
}

.stage-column:focus-within .stage-column__num,
.stage-column:focus-within .stage-column__icon {
	color: var(--accent-yellow);
}

@media (hover: hover) {
	.stage-column:hover::before {
		transform: scaleX(1);
	}

	.stage-column:hover .stage-column__name,
	.stage-column:hover .stage-column__desc {
		color: var(--on-blue);
	}

	.stage-column:hover .stage-column__num,
	.stage-column:hover .stage-column__icon {
		color: var(--accent-yellow);
	}
}

/* The button after the last stage. */
.stages__button {
	margin-top: var(--space-7);
}

/* 3b. Statement band (template-parts/landing/statement.php)
   Full width on deep blue: eyebrow, one large extrabold caps claim, a short
   paragraph and a button, all white on --brand-blue-900. No keyhole device.
   Finished state, shown by default (and so with reduced motion, or without
   JavaScript): a thick yellow underline under the first phrase and the
   second phrase in muted white. Muted white is 50% white on blue-900, 4.4:1,
   above the 3:1 needed for large text. The draw is in section 4.
   Desktop: the headline on the left, the paragraph and button on the right,
   lined up along the bottom.
   ========================================================================== */

.statement {
	--focus-color: var(--on-blue);
	--statement-muted: color-mix(in srgb, var(--on-blue) 50%, var(--brand-blue-900));

	padding-block: var(--space-section);
	color: var(--on-blue);
	background-color: var(--brand-blue-900);
}

.statement__eyebrow {
	color: var(--on-blue);
}

.statement__title {
	max-width: 20ch;
	margin-top: var(--space-4);
	font-size: var(--text-4xl);
	line-height: var(--leading-snug);
	color: var(--on-blue);
}

/* A background, not a border or text-decoration, so the line can draw from
   the left and still follow the phrase if it wraps onto a second line. It sits
   in the descender space, just under the caps. */
.statement__underline {
	background-image: linear-gradient(var(--accent-yellow), var(--accent-yellow));
	background-repeat: no-repeat;
	background-position: 0 calc(100% - 0.1em);
	background-size: 100% 0.14em;
	box-decoration-break: clone;
	-webkit-box-decoration-break: clone;
}

.statement__muted {
	color: var(--statement-muted);
}

.statement__text {
	max-width: var(--measure);
	margin-top: var(--space-6);
	font-size: var(--text-lg);
}

.statement__button {
	margin-top: var(--space-7);
}

@media (min-width: 64em) {
	.statement .container {
		display: grid;
		grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
		align-items: end;
		column-gap: var(--space-8);
	}

	.statement__title {
		font-size: clamp(3.5rem, 1rem + 3.9vw, 4.5rem); /* 56 → 72px: the page's statement, larger than a section heading */
	}

	.statement__text {
		margin-top: 0;
	}
}

/* 4. Motion
   Only when the visitor allows it. With reduced motion: the hero is there
   from the start, with no entrance and no cursor lean, the rail marker and row fill
   change instantly, and the rail's fill steps from stage to stage
   (service-stages.js) instead of following the scroll.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
	/* Entrance, about 1.2s in all. The headline rises word by word, 60ms
	   apart; then the paragraph, actions and stage strip. At the same time the
	   keyhole scales up from 0.92 and fades in. The person rises 40px into
	   place last. */
	.landing-hero__word,
	.landing-hero__text,
	.landing-hero__actions,
	.stage-strip {
		animation: landing-rise 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
	}

	.landing-hero__word {
		animation-delay: calc(0.05s + var(--i, 0) * 60ms);
	}

	.landing-hero__text {
		animation-delay: 0.3s;
	}

	.landing-hero__actions {
		animation-delay: 0.38s;
	}

	.stage-strip {
		animation-delay: 0.46s;
	}

	.landing-hero__keyhole {
		animation: landing-grow 0.7s cubic-bezier(0.22, 1, 0.36, 1) 0.05s both;
	}

	.landing-hero__person {
		animation: landing-stand 0.7s cubic-bezier(0.22, 1, 0.36, 1) 0.5s both;
	}

	.stage-strip__item::after {
		transition: transform 0.2s ease-out;
	}

	.stages__link {
		transition: color 0.2s ease-out;
	}

	.stages__link::before {
		transition: transform 0.25s ease-out;
	}

	.service-row::before {
		transition: transform 0.25s ease-out;
	}

	.service-row__num,
	.service-row__icon,
	.service-row__name,
	.service-row__desc,
	.service-row__link {
		transition: color 0.25s ease-out;
	}

	.stage-column::before {
		transition: transform 0.25s ease-out;
	}

	.stage-column__num,
	.stage-column__icon,
	.stage-column__name,
	.stage-column__desc {
		transition: color 0.25s ease-out;
	}

	/* Module orbit page, phones and tablets: no orbit; the strip simply fades in. */
	.landing-hero--orbit .stage-strip {
		animation-name: landing-fade;
	}

	/* Statement band (landing-statement.js). Armed: no underline, the second
	   phrase still white. Drawn: the underline draws left to right in 600ms,
	   a beat after the section's own fade-in starts; as it finishes, the second
	   phrase fades to muted white. Once only. */
	.statement.is-armed .statement__underline {
		background-size: 0% 0.14em;
	}

	.statement.is-armed .statement__muted {
		color: var(--on-blue);
	}

	.statement.is-armed.is-drawn .statement__underline {
		background-size: 100% 0.14em;
		transition: background-size 0.6s cubic-bezier(0.65, 0, 0.35, 1) 0.3s;
	}

	.statement.is-armed.is-drawn .statement__muted {
		color: var(--statement-muted);
		transition: color 0.5s ease-out 0.85s;
	}
}

/* Module orbit, desktop (landing-orbit.js). The strip itself stays still;
   the script flies each name in from the keyhole's round top and cancels the
   fallback below. The dots fade in as the names land. If the script never
   runs, the names simply fade in at the end, so they always show. The links
   are always in the page, readable and focusable. */
@media (prefers-reduced-motion: no-preference) and (min-width: 64em) {
	.landing-hero--orbit .stage-strip {
		animation: none;
	}

	.landing-hero--orbit .stage-strip__link {
		animation: landing-fade 0.4s ease-out 2.1s both;
	}

	.landing-hero--orbit .stage-strip__item::after {
		animation: landing-fade 0.4s ease-out 2s both;
	}
}

@keyframes landing-fade {
	from {
		opacity: 0;
	}

	to {
		opacity: 1;
	}
}

@keyframes landing-rise {
	from {
		opacity: 0;
		transform: translateY(1rem);
	}

	to {
		opacity: 1;
		transform: none;
	}
}

@keyframes landing-grow {
	from {
		opacity: 0;
		transform: scale(0.92);
	}

	to {
		opacity: 1;
		transform: none;
	}
}

@keyframes landing-stand {
	from {
		opacity: 0;
		transform: translateY(2.5rem);
	}

	to {
		opacity: 1;
		transform: none;
	}
}
