/* ==========================================================================
   Gemial Digital v2 — Homepage
   --------------------------------------------------------------------------
   Loaded by the page-key convention loader from M1: this file exists at
   assets/css/v2/pages/home.css and the template calls
   gemial_use_design_system( 2, 'home' ). No enqueue call anywhere, which is
   what keeps M2 a template-and-CSS-only deploy.

   Loads last, after base.css, so a page can adjust a component without
   raising its own specificity to do it. Scoped :where(body.gd2-page) like
   base.css, so everything here scores exactly what its own selector scores.

   NO HIDDEN STATES IN THIS FILE. Those live in motion.css, all of them.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Page grain
   --------------------------------------------------------------------------
   REDESIGN-PLAN.md §10 item 3. Near-black CSS gradients band visibly on 8-bit
   and cheap Android panels, and this page draws three of them. A grain overlay
   dithers the steps away.

   Fixed rather than absolute so it never scrolls against the content, and
   pointer-events:none so it cannot eat a click. 128px tile, 4.2KB.
   -------------------------------------------------------------------------- */

:where(body.gd2-page)::after {
	content: "";
	position: fixed;
	inset: 0;
	z-index: 9999;
	background-image: url("../../../img/v2/grain.png");
	background-size: 128px 128px;
	opacity: .035;
	pointer-events: none;
	mix-blend-mode: overlay;
}

/* --------------------------------------------------------------------------
   The measurement rail
   --------------------------------------------------------------------------
   A lime hairline down the left margin, filling from the top as the page
   scrolls, with a tick and a monospace number at each section boundary.

   THE FILL COSTS NO JAVASCRIPT. It is scaleY(var(--gd-p)), and --gd-p is
   already written by the one rAF loop. THE TICKS COST NO JAVASCRIPT EITHER:
   each section draws its own from data-gd-n in normal flow, which is exactly
   what avoids the scroll-position-to-section mapping that got the original
   section-number idea cut.

   Hidden below 1180px. The rail needs its own margin to live in, and below
   that width the container gutter is doing real work holding content off the
   edge. A progress indicator is not worth squeezing the text for.
   -------------------------------------------------------------------------- */

:where(body.gd2-page) .gd-rail {
	display: none;
}

@media (min-width: 1180px) {
	:where(body.gd2-page) .gd-rail {
		display: block;
		position: fixed;
		inset-block: 0;
		inset-inline-start: max(1.5rem, calc((100vw - var(--container)) / 2 - 3.25rem));
		width: 1px;
		background: var(--hairline-hi);
		z-index: 5;
		pointer-events: none;
	}

	:where(body.gd2-page) .gd-rail__fill {
		display: block;
		width: 100%;
		height: 100%;
		background: var(--accent-ink);
		transform: scaleY(var(--gd-p, 0));
		transform-origin: 50% 0;
	}

	/* The tick. Sits on the section's own top edge, so nothing measures it. */
	:where(body.gd2-page) .gd-section[data-gd-n]::before {
		content: attr(data-gd-n);
		position: absolute;
		inset-block-start: 0;
		inset-inline-start: max(1.5rem, calc((100vw - var(--container)) / 2 - 3.25rem));
		transform: translate(-50%, -50%);
		padding-block: .4rem;
		font-family: var(--f-mono);
		font-size: 9px;
		letter-spacing: .12em;
		color: var(--text-low);
		background: var(--ground);
		transition: color var(--dur) var(--ease);
	}

	:where(body.gd2-page) .gd-section--raised[data-gd-n]::before {
		background: var(--raised);
	}

	/*
	 * Lights as the section is reached, and stays lit, so the ticks read as a
	 * progress trail alongside the fill rather than as a single moving
	 * highlight. A true "current section only" state would need a second
	 * observer with its own rootMargin, and REDESIGN-PLAN.md §6 allows one.
	 */
	:where(body.gd2-page) .gd-section[data-gd-n].is-in::before {
		color: var(--accent-ink);
	}
}

/* --------------------------------------------------------------------------
   Section top hairline
   --------------------------------------------------------------------------
   The first beat of the calibration wipe. Present at all widths, drawn by
   motion.css when the section arrives.
   -------------------------------------------------------------------------- */

:where(body.gd2-page) .gd-section[data-gd-n] {
	position: relative;
}

:where(body.gd2-page) .gd-section[data-gd-n]::after {
	content: "";
	position: absolute;
	inset-block-start: 0;
	inset-inline: 0;
	height: 1px;
	background: linear-gradient(90deg, var(--accent-ink), var(--hairline-hi) 45%, transparent);
	opacity: .7;
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

:where(body.gd2-page) .hero {
	position: relative;
	overflow: hidden;
	padding-block: clamp(3.5rem, 9vw, 7rem) clamp(3rem, 6vw, 5rem);
}

:where(body.gd2-page) .hero__bg {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
}

:where(body.gd2-page) .hero__in {
	position: relative;
	z-index: 1;
}

/*
 * The drift layers. Each is taller than the box by one tile so that the
 * translate has somewhere to go, and each repeats, so the wrap is invisible.
 * Two layers at different speeds and opacities is what gives the field depth.
 */
/*
 * will-change lives in motion.css, inside the no-preference block, NOT here.
 * Held unconditionally it promotes three full-bleed compositor layers and
 * keeps their textures in GPU memory for the whole session -- including under
 * reduced motion, where nothing on this page animates at all. Measured on
 * production 2026-08-20: both drift layers reported will-change: transform
 * with animation: none and zero running animations on the document.
 */
:where(body.gd2-page) .hero__drift,
:where(body.gd2-page) .hero__grid {
	position: absolute;
	inset-inline: 0;
	inset-block-start: 0;
	height: calc(100% + 256px);
	background-repeat: repeat;
}

:where(body.gd2-page) .hero__drift {
	background-image: url("../../../img/v2/drift-tile.png");
	background-size: 256px 256px;
}

/*
 * Depth here comes from speed and opacity, not scale. A scale(.75) lived on
 * this rule until 2026-08-20 and never had any effect on the page anyone saw:
 * gd-drift animates the `transform` property, so the animation replaced it
 * outright whenever the motion gate was on. Under reduced motion, where it did
 * apply, transform-origin: 0 0 shrank the element rather than just its tiles,
 * so the layer covered the top-left 75% of the hero and stopped with a visible
 * edge. Measured, both states, on production.
 *
 * If smaller tiles are ever wanted as a real depth cue, do it with
 * background-size and match the translate distance to it -- see the loop note
 * in motion.css. Do NOT reach for the individual `scale` property: translate
 * is applied before scale in the fixed order those properties use, so the
 * translate would be in screen space while the tile is scaled, and the loop
 * would break by exactly the scale factor.
 */
:where(body.gd2-page) .hero__drift--far {
	opacity: .3;
}

:where(body.gd2-page) .hero__drift--near {
	opacity: .55;
}

:where(body.gd2-page) .hero__grid {
	background-image:
		linear-gradient(var(--accent-ink) 1px, transparent 1px),
		linear-gradient(90deg, var(--accent-ink) 1px, transparent 1px);
	background-size: 64px 64px;
	opacity: .045;
	-webkit-mask-image: radial-gradient(ellipse 90% 70% at 50% 0%, #000 0%, transparent 72%);
	mask-image: radial-gradient(ellipse 90% 70% at 50% 0%, #000 0%, transparent 72%);
}

:where(body.gd2-page) .hero__glow {
	position: absolute;
	inset-block-start: -30%;
	inset-inline-start: 50%;
	width: min(900px, 110vw);
	aspect-ratio: 1;
	transform: translateX(-50%);
	background: radial-gradient(circle, color-mix(in srgb, var(--lime) 13%, transparent) 0%, transparent 62%);
	filter: blur(30px);
}

:where(body.gd2-page) .hero__h em {
	font-style: normal;
	color: var(--accent-ink);
}

:where(body.gd2-page) .hero__lead {
	margin-block-start: 2rem;
}

/*
 * The wireframe layer.
 *
 * The original problem was presence, not size, so this fixes presence: it sits
 * at .62 rather than a uniform wash, and the mask is weighted so the solid,
 * resolved end of the artwork reads clearly behind the stats bar while the
 * wireframe end thins out under the headline. Anchored bottom-right, sized to
 * about three quarters of the hero, so the copy column on the left stays on
 * near-black and keeps its 18.44:1.
 */
:where(body.gd2-page) .hero__wire {
	position: absolute;
	inset-block-end: 0;
	inset-inline-end: 0;
	width: min(76%, 1100px);
	opacity: .62;
	-webkit-mask-image:
		linear-gradient(90deg, transparent, #000 42%),
		linear-gradient(180deg, transparent 4%, #000 34%);
	mask-image:
		linear-gradient(90deg, transparent, #000 42%),
		linear-gradient(180deg, transparent 4%, #000 34%);
	-webkit-mask-composite: source-in;
	mask-composite: intersect;
}

:where(body.gd2-page) .hero__wire img {
	width: 100%;
	height: auto;
}

/*
 * On narrow screens the copy runs the full width, so the artwork drops well
 * back rather than sitting under the headline at 62%.
 */
/*
 * Below 900 the copy runs full width, so the artwork has to get out from
 * under it rather than just dim. Measured: at .38 across the whole box the
 * lead paragraph fell to 4.26:1 against 4.5. The vertical mask now holds the
 * image to the lower third, where only the stats sit, and those were already
 * moved to --text-mid for exactly this reason.
 */
@media (max-width: 900px) {
	:where(body.gd2-page) .hero__wire {
		width: 118%;
		inset-inline-end: -12%;
		opacity: .34;
		-webkit-mask-image: linear-gradient(180deg, transparent 34%, #000 68%);
		mask-image: linear-gradient(180deg, transparent 34%, #000 68%);
		-webkit-mask-composite: source-over;
		mask-composite: add;
	}
}

/* ---- Stats bar ---- */

:where(body.gd2-page) .hstat {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	margin-block-start: clamp(3rem, 6vw, 4.5rem);
	border-block-start: 1px solid var(--hairline);
}

:where(body.gd2-page) .hstat__cell {
	padding: 1.5rem 1.25rem 0 0;
	border-inline-end: 1px solid var(--hairline);
}

:where(body.gd2-page) .hstat__cell:last-child {
	border-inline-end: 0;
}

:where(body.gd2-page) .hstat__fig {
	font-family: var(--f-display);
	font-size: clamp(1.75rem, 3.2vw, 2.6rem);
	font-weight: 700;
	letter-spacing: -.04em;
	line-height: 1;
	color: var(--text-hi);
}

/* "0 to 65+" is text, not a figure, so it sets smaller and wraps rather than
   forcing the whole row down a size. */
:where(body.gd2-page) .hstat__fig--sm {
	font-size: clamp(1.25rem, 2.1vw, 1.75rem);
}

:where(body.gd2-page) .hstat__fig small {
	font-size: .45em;
	font-weight: 500;
	color: var(--accent-ink);
}

/*
 * --text-mid here, not --text-low, and the reason is measured.
 *
 * --text-low is calibrated against flat ground and flat raised (4.82:1 and
 * 4.58:1). These labels do not sit on flat anything: the wireframe's resolved,
 * concrete end runs behind the right-hand cells. Sampled off a rendered
 * screenshot, the brightest tenth of the background behind the fourth label
 * took --text-low down to 3.66:1.
 *
 * --text-mid clears it at about 5:1 against that same background without
 * darkening the artwork, which was the alternative and would have needed a
 * 77% scrim to work -- effectively hiding the thing we just gave presence to.
 */
:where(body.gd2-page) .hstat__lab {
	max-width: 19ch;
	margin: .7rem 0 0;
	font-family: var(--f-mono);
	font-size: 9.5px;
	letter-spacing: .16em;
	text-transform: uppercase;
	line-height: 1.6;
	color: var(--text-mid);
}

/* A light scrim under the whole row, so the figures keep their weight over
   the busiest part of the artwork. Not enough to flatten the image. */
:where(body.gd2-page) .hstat {
	background: linear-gradient(
		180deg,
		transparent,
		color-mix(in srgb, var(--ground) 34%, transparent) 45%
	);
}

@media (max-width: 760px) {
	:where(body.gd2-page) .hstat {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	:where(body.gd2-page) .hstat__cell {
		padding-block-end: 1.25rem;
		border-block-end: 1px solid var(--hairline);
	}

	:where(body.gd2-page) .hstat__cell:nth-child(2n) {
		border-inline-end: 0;
	}

	:where(body.gd2-page) .hstat__cell:nth-last-child(-n+2) {
		border-block-end: 0;
	}
}

/* --------------------------------------------------------------------------
   01 Services
   -------------------------------------------------------------------------- */

:where(body.gd2-page) .svc__lead {
	margin-block-start: 1.5rem;
}

/*
 * 01-services as a surface, not a band. It is a plan view of six squares with
 * leader lines, which is a diagram of this section, so it backs the section
 * header at low opacity and is gone by the time the rows start.
 *
 * If this does not read on the real page, delete these six declarations and
 * the image goes unused. That is a better outcome than a full-width slab.
 */
/*
 * 01-services IS NOT USED, and the reason is worth keeping.
 *
 * It was tried as a faint section background and screenshotted. Every image in
 * this set except 08 and 09 carries deliberate "frame furniture" -- an inset
 * lime rule, corner crosshairs, edge ticks and numerals (IMAGE-PROMPTS.md §1).
 * That furniture is what makes them read as instrument plates, and it is
 * exactly what makes them unusable as backgrounds: the frame's bottom edge
 * cut a hard horizontal line straight across the service list.
 *
 * 08-blog and 09-closing were generated WITHOUT the border on purpose -- their
 * prompts say "do not include the inset border or numerals on this one" -- so
 * those two are the two that work as surfaces. That was designed in from the
 * start and only became visible once the page was rendered.
 *
 * An image placed because it exists is worse than a section that breathes.
 */

:where(body.gd2-page) .svc__list {
	margin-block-start: clamp(1rem, 2vw, 1.5rem);
	border-block-start: 1px solid var(--hairline);
}

:where(body.gd2-page) .svcrow {
	position: relative;
	display: grid;
	grid-template-columns: auto minmax(0, 1.05fr) minmax(0, 1.15fr) auto;
	align-items: start;
	gap: clamp(1rem, 2.5vw, 2.5rem);
	padding-block: clamp(1.6rem, 3vw, 2.4rem);
	border-block-end: 1px solid var(--hairline);
	transition: padding-inline .4s var(--ease);
}

:where(body.gd2-page) .svcrow::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(90deg, color-mix(in srgb, var(--lime) 6%, transparent), transparent 55%);
	opacity: 0;
	transition: opacity .4s var(--ease);
	pointer-events: none;
}

:where(body.gd2-page) .svcrow:hover::before,
:where(body.gd2-page) .svcrow:focus-visible::before {
	opacity: 1;
}

:where(body.gd2-page) .svcrow:hover {
	padding-inline: clamp(.75rem, 2vw, 1.5rem);
}

:where(body.gd2-page) .svcrow__n {
	padding-block-start: .5rem;
	font-family: var(--f-mono);
	font-size: 10px;
	letter-spacing: .14em;
	color: var(--text-low);
}

:where(body.gd2-page) .svcrow__t {
	font-family: var(--f-display);
	font-size: clamp(1.25rem, 2.5vw, 1.9rem);
	font-weight: 700;
	font-stretch: 104%;
	letter-spacing: -.03em;
	line-height: 1.1;
	color: var(--text-mid);
	transition: color var(--dur) var(--ease);
}

:where(body.gd2-page) .svcrow:hover .svcrow__t {
	color: var(--text-hi);
}

:where(body.gd2-page) .svcrow__d {
	font-size: 14.5px;
	line-height: 1.6;
	color: var(--text-low);
}

:where(body.gd2-page) .svcrow__go {
	display: grid;
	place-items: center;
	flex: none;
	width: 44px;
	height: 44px;
	margin-block-start: .25rem;
	border: 1px solid var(--hairline-hi);
	border-radius: var(--r-pill);
	color: var(--text-low);
	transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease), transform var(--dur) var(--ease);
}

:where(body.gd2-page) .svcrow:hover .svcrow__go {
	border-color: var(--accent-ink);
	color: var(--accent-ink);
	transform: rotate(-45deg);
}

@media (max-width: 900px) {
	:where(body.gd2-page) .svcrow {
		grid-template-columns: auto minmax(0, 1fr) auto;
		gap: 1rem 1.25rem;
	}

	:where(body.gd2-page) .svcrow__d {
		grid-column: 2 / 4;
		font-size: 14px;
	}
}

@media (max-width: 560px) {
	:where(body.gd2-page) .svcrow {
		grid-template-columns: auto minmax(0, 1fr);
	}

	:where(body.gd2-page) .svcrow__go {
		display: none;
	}

	:where(body.gd2-page) .svcrow__d {
		grid-column: 2 / 3;
	}
}

/* --------------------------------------------------------------------------
   02 Proof
   -------------------------------------------------------------------------- */

/*
 * 05-scale-collaboration backs the whole section rather than sitting in it.
 * A wireframe reading as a webpage with two figures for scale is the argument
 * this section is making, so it belongs underneath the evidence rather than
 * competing with it for a row of its own.
 *
 * The gradient layer is --raised, not --ground, because this is a raised band.
 */
/*
 * 05-scale-collaboration-plate: the same artwork with its frame furniture
 * cropped off by tools/deframe.mjs, which then verifies numerically that no
 * rule survives on any edge. It is a borderless plate and behaves like 08 and
 * 09, so it can sit at natural scale instead of being pushed off the corner.
 *
 * The previous version scaled the full plate to 152% and anchored it past the
 * corner so the furniture fell outside the section. That worked and it was a
 * workaround: it showed a fragment of the best image in the set at four times
 * the bytes that fragment needed. Cropping is 23.4KB against the original's
 * 36.6KB, and the whole wireframe panel and both scale figures are visible.
 *
 * Anchored right and top at 62%, which puts the panel behind the section
 * heading and the two figures clear of the first Proof row. The gradient does
 * the legibility work, as it does for 08 and 09.
 */
:where(body.gd2-page) .proof {
	position: relative;
	background-image:
		linear-gradient(200deg, color-mix(in srgb, var(--raised) 62%, transparent) 0 20%, var(--raised) 52%),
		url("../../../img/v2/05-scale-collaboration-plate@1x.webp");
	background-repeat: no-repeat;
	background-position: center, right -4% top 2rem;
	background-size: 100% 100%, 62% auto;
}

@media (min-width: 901px) {
	:where(body.gd2-page) .proof {
		background-image:
			linear-gradient(200deg, color-mix(in srgb, var(--raised) 62%, transparent) 0 20%, var(--raised) 52%),
			url("../../../img/v2/05-scale-collaboration-plate.webp");
	}
}

/*
 * Not on phones. At 390 a 62% panel behind five rows of dense text is a
 * compromise at both ends: too small to read as an image, too present to
 * ignore. Better a strong background at 1440 and none here.
 */
@media (max-width: 700px) {
	:where(body.gd2-page) .proof {
		background-image: none;
	}
}

:where(body.gd2-page) .proof__in {
	position: relative;
	z-index: 1;
}

:where(body.gd2-page) .proof__lead {
	margin-block-start: 1.5rem;
}

:where(body.gd2-page) .proof__list {
	margin-block-start: clamp(2.5rem, 5vw, 3.5rem);
	border-block-start: 1px solid var(--hairline-hi);
}

:where(body.gd2-page) .prow {
	display: grid;
	grid-template-columns: minmax(0, 8rem) minmax(0, 1fr);
	gap: clamp(1.25rem, 3vw, 2.5rem);
	padding-block: clamp(1.5rem, 3vw, 2rem);
	border-block-end: 1px solid var(--hairline-hi);
}

:where(body.gd2-page) .prow__fig {
	display: flex;
	flex-direction: column;
	gap: .4rem;
}

:where(body.gd2-page) .prow__num {
	font-family: var(--f-display);
	font-size: clamp(1.5rem, 2.6vw, 2.1rem);
	font-weight: 700;
	letter-spacing: -.04em;
	line-height: 1;
	color: var(--mint);
}

:where(body.gd2-page) .prow__lab {
	font-family: var(--f-mono);
	font-size: 9px;
	letter-spacing: .14em;
	text-transform: uppercase;
	line-height: 1.7;
	color: var(--text-low);
}

:where(body.gd2-page) .prow__name {
	font-size: clamp(1.125rem, 1.9vw, 1.4rem);
	letter-spacing: -.025em;
}

:where(body.gd2-page) .prow__name a {
	display: inline-flex;
	align-items: baseline;
	gap: .45rem;
	color: var(--text-hi);
	transition: color var(--dur-fast) var(--ease);
}

:where(body.gd2-page) .prow__name a:hover {
	color: var(--accent-ink);
}

:where(body.gd2-page) .prow__ext {
	flex: none;
	transform: translateY(-1px);
	opacity: .6;
}

:where(body.gd2-page) .prow__sector {
	margin-block-start: .35rem;
	font-family: var(--f-mono);
	font-size: 9.5px;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--text-low);
}

:where(body.gd2-page) .prow__sum {
	max-width: 62ch;
	margin-block-start: .75rem;
	font-size: 14.5px;
	line-height: 1.65;
	color: var(--text-mid);
}

@media (max-width: 700px) {
	:where(body.gd2-page) .prow {
		grid-template-columns: minmax(0, 1fr);
		gap: .9rem;
	}
}

/* --------------------------------------------------------------------------
   03 Why us
   -------------------------------------------------------------------------- */

:where(body.gd2-page) .why__split {
	display: grid;
	grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
	gap: clamp(2.5rem, 6vw, 5rem);
	align-items: start;
}

:where(body.gd2-page) .why__intro {
	position: sticky;
	inset-block-start: calc(var(--header-h) + 2rem);
}

:where(body.gd2-page) .why__lead {
	margin-block-start: 1.5rem;
}

:where(body.gd2-page) .why__art {
	margin: 2.5rem 0 0;
	border: 1px solid var(--hairline);
	border-radius: var(--r-md);
	overflow: hidden;
}

:where(body.gd2-page) .why__list {
	border-block-start: 1px solid var(--hairline-hi);
}

:where(body.gd2-page) .whyrow {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	gap: 1.5rem;
	padding-block: 1.6rem;
	border-block-end: 1px solid var(--hairline-hi);
}

:where(body.gd2-page) .whyrow__n {
	padding-block-start: .35rem;
	font-family: var(--f-mono);
	font-size: 10px;
	letter-spacing: .14em;
	color: var(--accent-ink);
}

:where(body.gd2-page) .whyrow__h {
	margin-block-end: .45rem;
}

:where(body.gd2-page) .whyrow__p {
	font-size: 14.5px;
	line-height: 1.65;
	color: var(--text-low);
}

@media (max-width: 900px) {
	:where(body.gd2-page) .why__split {
		grid-template-columns: minmax(0, 1fr);
	}

	:where(body.gd2-page) .why__intro {
		position: static;
	}
}

/* --------------------------------------------------------------------------
   04 Process — the triptych
   --------------------------------------------------------------------------
   DEFAULT IS THE THREE-UP GRID. That is deliberate and it is doing three jobs
   at once: the no-JavaScript state, the reduced-motion state, and the mobile
   layout. Building the fallback as the default is what makes all three free.

   The stacked cross-fade is layered on top only at >=901px, and only when the
   motion gate is present. See CLAUDE.md §7.8.
   -------------------------------------------------------------------------- */

:where(body.gd2-page) .proc__lead {
	margin-block-start: 1.5rem;
}

:where(body.gd2-page) .proc__grid {
	display: grid;
	grid-template-columns: minmax(0, .88fr) minmax(0, 1fr) minmax(0, 1.12fr);
	gap: clamp(1rem, 2.5vw, 2rem);
	margin-block-start: clamp(2.5rem, 5vw, 3.5rem);
}

:where(body.gd2-page) .pstep {
	margin: 0;
}

:where(body.gd2-page) .pstep__art {
	aspect-ratio: 1122 / 1402;
	border: 1px solid var(--hairline);
	border-radius: var(--r-md);
	overflow: hidden;
	background: var(--raised);
}

:where(body.gd2-page) .pstep__art img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

:where(body.gd2-page) .pstep__body {
	padding-block-start: 1.25rem;
}

:where(body.gd2-page) .pstep__n {
	display: block;
	font-family: var(--f-mono);
	font-size: 10px;
	letter-spacing: .14em;
	color: var(--accent-ink);
}

:where(body.gd2-page) .pstep__h {
	margin-block: .6rem .5rem;
}

:where(body.gd2-page) .pstep__p {
	font-size: 14.5px;
	line-height: 1.65;
	color: var(--text-low);
}

/*
 * ASYMMETRIC ON PURPOSE. The three columns widen left to right, .88 / 1 / 1.12.
 *
 * An equal three-up grid says "these are peers, choose among them". The
 * process is a sequence -- scattered, half resolved, locked -- and the images
 * are one field in three states. The grid was the only element on the page
 * contradicting that, and the tell was that repeat(3, minmax(0, 1fr)) appeared
 * exactly twice in this file: here and on the blog. Blog posts genuinely are
 * peers; process steps are not. One shape was doing two contradictory jobs.
 *
 * Widening rather than narrowing because the last step is the one the copy
 * says agencies skip, and it is the one that compounds. The cells still total
 * 3fr, so the block width is unchanged.
 *
 * THE HEIGHT RULE IS NOT OPTIONAL. Different column widths against a fixed
 * aspect-ratio give three different image heights, which pushes the captions
 * to three different baselines -- a stepped layout arrived at by accident,
 * which is exactly the failure mode that argued against building a deliberate
 * one. A common height with object-position: top keeps the captions aligned
 * and keeps the top of each field, where 03c's resolved lattice sits.
 */
@media (min-width: 901px) {
	:where(body.gd2-page) .pstep__art {
		aspect-ratio: auto;
		height: clamp(18rem, 24vw, 26rem);
	}

	:where(body.gd2-page) .pstep__art img {
		object-position: center top;
	}
}

@media (max-width: 900px) {
	:where(body.gd2-page) .proc__grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 2.5rem;
	}

	:where(body.gd2-page) .pstep__art {
		max-width: 22rem;
	}
}

/* --------------------------------------------------------------------------
   05 Founder
   -------------------------------------------------------------------------- */

:where(body.gd2-page) .founder__split {
	display: grid;
	grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
	gap: clamp(2rem, 5vw, 4rem);
	align-items: center;
}

:where(body.gd2-page) .founder__art {
	margin: 0;
	border: 1px solid var(--hairline);
	border-radius: var(--r-md);
	overflow: hidden;
	background: var(--raised);
}

:where(body.gd2-page) .founder__art img {
	width: 100%;
	height: auto;
}

:where(body.gd2-page) .founder__quote {
	margin: 0;
	font-family: var(--f-display);
	font-size: clamp(1.4rem, 2.6vw, 2.1rem);
	font-weight: 700;
	font-stretch: 104%;
	letter-spacing: -.03em;
	line-height: 1.22;
	color: var(--text-hi);
	max-width: 24ch;
}

:where(body.gd2-page) .founder__p {
	max-width: 56ch;
	margin-block-start: 1.5rem;
	font-size: 15.5px;
	line-height: 1.7;
	color: var(--text-mid);
}

:where(body.gd2-page) .founder__by {
	display: flex;
	align-items: baseline;
	gap: .75rem;
	margin-block-start: 1.5rem;
	padding-block-start: 1.25rem;
	border-block-start: 1px solid var(--hairline);
}

:where(body.gd2-page) .founder__name {
	font-family: var(--f-display);
	font-size: 1rem;
	font-weight: 700;
	color: var(--text-hi);
}

:where(body.gd2-page) .founder__role {
	font-family: var(--f-mono);
	font-size: 9.5px;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--accent-ink);
}

@media (max-width: 900px) {
	:where(body.gd2-page) .founder__split {
		grid-template-columns: minmax(0, 1fr);
	}

	:where(body.gd2-page) .founder__art {
		max-width: 18rem;
	}
}

/* --------------------------------------------------------------------------
   06 Audit
   -------------------------------------------------------------------------- */

:where(body.gd2-page) .audit {
	position: relative;
	overflow: hidden;
}

:where(body.gd2-page) .audit__glow {
	position: absolute;
	inset-block-start: -40%;
	inset-inline-end: -10%;
	width: min(760px, 90vw);
	aspect-ratio: 1;
	background: radial-gradient(circle, color-mix(in srgb, var(--lime) 15%, transparent), transparent 62%);
	filter: blur(36px);
	pointer-events: none;
}

:where(body.gd2-page) .audit__in {
	position: relative;
	z-index: 1;
}

:where(body.gd2-page) .audit__split {
	display: grid;
	grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
	gap: clamp(2.5rem, 6vw, 5rem);
	align-items: center;
}

:where(body.gd2-page) .audit__lead {
	margin-block-start: 1.5rem;
}

:where(body.gd2-page) .audit__note {
	max-width: 46ch;
	margin-block-start: 1.5rem;
	font-family: var(--f-mono);
	font-size: 10px;
	letter-spacing: .08em;
	line-height: 1.8;
	color: var(--text-low);
}

:where(body.gd2-page) .auditbox {
	padding: clamp(1.5rem, 2.6vw, 2rem);
	border: 1px solid var(--hairline-hi);
	border-radius: var(--r-md);
	background: color-mix(in srgb, var(--ground) 70%, transparent);
}

:where(body.gd2-page) .auditbox__art {
	margin: 0 auto 1.5rem;
	max-width: 11rem;
}

:where(body.gd2-page) .auditbox__h {
	margin-block-end: 1.25rem;
	color: var(--accent-ink);
}

:where(body.gd2-page) .auditbox__list li {
	display: flex;
	align-items: baseline;
	gap: .75rem;
	padding-block: .65rem;
	font-size: 14.5px;
	line-height: 1.5;
	color: var(--text);
	border-block-end: 1px solid var(--hairline);
}

:where(body.gd2-page) .auditbox__list li:last-child {
	border-block-end: 0;
}

:where(body.gd2-page) .auditbox__list li::before {
	content: "";
	flex: none;
	width: 8px;
	height: 4px;
	margin-block-start: .35rem;
	border-inline-start: 1.5px solid var(--accent-ink);
	border-block-end: 1.5px solid var(--accent-ink);
	transform: rotate(-45deg);
}

@media (max-width: 900px) {
	:where(body.gd2-page) .audit__split {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* --------------------------------------------------------------------------
   07 Blog
   -------------------------------------------------------------------------- */

/*
 * 08-blog is used twice, and both are the job it was drawn for.
 *
 * Its brief was "a quiet background that text will sit on top of, so nothing
 * in it should draw the eye" -- a grid fragment in the lower left dissolving
 * to black. So it backs the section here, and it is also the fallback card art
 * in blog.php when a post has no featured image. It will usually not appear in
 * the cards, which is correct: a real featured image beats a placeholder.
 */
:where(body.gd2-page) .blog {
	position: relative;
	background-image:
		linear-gradient(20deg, color-mix(in srgb, var(--ground) 72%, transparent) 0 22%, var(--ground) 60%),
		url("../../../img/v2/08-blog@1x.webp");
	background-repeat: no-repeat;
	background-position: center, left bottom;
	background-size: 100% 100%, min(70%, 900px) auto;
}

@media (min-width: 901px) {
	:where(body.gd2-page) .blog {
		background-image:
			linear-gradient(20deg, color-mix(in srgb, var(--ground) 72%, transparent) 0 22%, var(--ground) 60%),
			url("../../../img/v2/08-blog.webp");
	}
}

:where(body.gd2-page) .blog > * {
	position: relative;
	z-index: 1;
}

:where(body.gd2-page) .blog__lead {
	margin-block-start: 1.5rem;
}

:where(body.gd2-page) .blog__grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: clamp(1rem, 2vw, 1.75rem);
	margin-block-start: clamp(2.5rem, 5vw, 3.5rem);
}

:where(body.gd2-page) .bcard {
	display: flex;
	flex-direction: column;
	background: var(--raised);
	border: 1px solid var(--hairline);
	border-radius: var(--r-md);
	overflow: hidden;
	transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}

:where(body.gd2-page) .bcard:hover {
	border-color: var(--border-int);
	transform: translateY(-3px);
}

:where(body.gd2-page) .bcard__art {
	display: block;
	aspect-ratio: 16 / 9;
	background: var(--raised-2);
	overflow: hidden;
}

:where(body.gd2-page) .bcard__art img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

:where(body.gd2-page) .bcard__body {
	display: flex;
	flex-direction: column;
	gap: .6rem;
	flex: 1;
	padding: 1.35rem 1.5rem 1.6rem;
}

:where(body.gd2-page) .bcard__kicker {
	font-family: var(--f-mono);
	font-size: 9px;
	letter-spacing: .15em;
	text-transform: uppercase;
	color: var(--accent-ink);
}

:where(body.gd2-page) .bcard__title {
	font-family: var(--f-display);
	font-size: 1.0625rem;
	font-weight: 700;
	letter-spacing: -.025em;
	line-height: 1.22;
	color: var(--text-hi);
}

:where(body.gd2-page) .bcard__ex {
	font-size: 13.5px;
	line-height: 1.55;
	color: var(--text-low);
}

:where(body.gd2-page) .bcard__go {
	display: inline-flex;
	align-items: center;
	gap: .5rem;
	margin-block-start: auto;
	padding-block-start: .9rem;
	font-family: var(--f-mono);
	font-size: 9.5px;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--text-mid);
}

:where(body.gd2-page) .bcard:hover .bcard__go {
	color: var(--accent-ink);
}

@media (max-width: 900px) {
	:where(body.gd2-page) .blog__grid {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* --------------------------------------------------------------------------
   Closing CTA
   -------------------------------------------------------------------------- */

:where(body.gd2-page) .cta {
	position: relative;
	overflow: hidden;
	text-align: center;
}

:where(body.gd2-page) .cta__in {
	position: relative;
	z-index: 1;
}

/*
 * 09-closing backs the section at its own aspect. contain, never cover: the
 * artwork is almost entirely empty and the single lime square is the only
 * thing in it, so cropping threw away the point. Anchored to the bottom so
 * the square lands under the buttons as a full stop before the footer.
 */
:where(body.gd2-page) .cta {
	background-image:
		linear-gradient(180deg, var(--ground) 0 34%, color-mix(in srgb, var(--ground) 62%, transparent)),
		url("../../../img/v2/09-closing@1x.webp");
	background-repeat: no-repeat;
	background-position: center, center bottom;
	background-size: 100% 100%, min(100%, 1915px) auto;
}

@media (min-width: 901px) {
	:where(body.gd2-page) .cta {
		background-image:
			linear-gradient(180deg, var(--ground) 0 34%, color-mix(in srgb, var(--ground) 62%, transparent)),
			url("../../../img/v2/09-closing.webp");
	}
}

:where(body.gd2-page) .cta .gd-eyebrow {
	justify-content: center;
}

:where(body.gd2-page) .cta__h {
	max-width: 17ch;
	margin-inline: auto;
	font-size: clamp(2rem, 5.4vw, 4rem);
	font-stretch: 110%;
	line-height: .99;
}

:where(body.gd2-page) .cta__lead {
	margin: 1.75rem auto 0;
}

:where(body.gd2-page) .cta__btns {
	justify-content: center;
}
