/* =============================================================
   HIGHER PERFORMANCE — inner-page styles
   ----------------------------------------------------------
   Split out of main.css (2026-07-11) so the homepage no longer
   parses ~250KB of page-specific CSS it never uses. Contains the
   SEO, PPC, Videography, Web Design, About, Coming Soon and
   Contact page sections plus the EB LIB library. Enqueued on
   every page EXCEPT the front page (inc/enqueue.php), after
   hp-main so the original cascade order is preserved.
   The EB chassis ([data-eb-section] grounds, .hp-eb-dot) and the
   Reviews slider stay in main.css — the homepage uses them.
   ============================================================= */

/* =============================================================
   SEO services page
   ----------------------------------------------------------
   Reuses the homepage utilities (.hp-gradient-text, .hp-scroll-color,
   .hp-btn, brand-thread .hp-ribbon, IntersectionObserver reveal via
   data-section + .is-pending → .is-visible).
   Every section sets overflow-x: clip so decorative glows can sit off
   the edge of the viewport without ever producing a horizontal scroll.
   ============================================================= */

.hp-seo {
	overflow-x: clip;
}
.hp-seo section { overflow-x: clip; }

/* ---- Shared reveal entrance (fade-up + stagger by --r index) ---- */
.hp-seo [data-section].is-pending [data-reveal],
.hp-seo [data-section].is-pending .hp-seo-case,
.hp-seo [data-section].is-pending .hp-seo-quote,
.hp-seo [data-section].is-pending .hp-seo-deliver__card,
.hp-seo [data-section].is-pending .hp-seo-hero__stat,
.hp-seo [data-section].is-pending .hp-seo-experts__paras p,
.hp-seo [data-section].is-pending .hp-seo-experts__panel,
.hp-seo [data-section].is-pending .hp-seo-opps__head,
.hp-seo [data-section].is-pending .hp-seo-opps__body,
.hp-seo [data-section].is-pending .hp-seo-faq__item {
	opacity: 0;
	transform: translateY(28px);
	transition: opacity 0.7s cubic-bezier(0.2, 0.7, 0.2, 1),
	            transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.hp-seo [data-section].is-visible [data-reveal],
.hp-seo [data-section].is-visible .hp-seo-case,
.hp-seo [data-section].is-visible .hp-seo-quote,
.hp-seo [data-section].is-visible .hp-seo-deliver__card,
.hp-seo [data-section].is-visible .hp-seo-hero__stat,
.hp-seo [data-section].is-visible .hp-seo-experts__paras p,
.hp-seo [data-section].is-visible .hp-seo-experts__panel,
.hp-seo [data-section].is-visible .hp-seo-opps__head,
.hp-seo [data-section].is-visible .hp-seo-opps__body,
.hp-seo [data-section].is-visible .hp-seo-faq__item {
	opacity: 1;
	transform: translateY(0);
}
/* Per-item stagger using the index variables set in PHP. */
.hp-seo [data-section].is-visible .hp-seo-case        { transition-delay: calc(0.1s + var(--ci, 0) * 0.1s); }
.hp-seo [data-section].is-visible .hp-seo-quote       { transition-delay: calc(0.1s + var(--qi, 0) * 0.1s); }
.hp-seo [data-section].is-visible .hp-seo-deliver__card { transition-delay: calc(0.08s + var(--di, 0) * 0.07s); }
.hp-seo [data-section].is-visible .hp-seo-hero__stat:nth-child(1) { transition-delay: 0.35s; }
.hp-seo [data-section].is-visible .hp-seo-hero__stat:nth-child(2) { transition-delay: 0.43s; }
.hp-seo [data-section].is-visible .hp-seo-hero__stat:nth-child(3) { transition-delay: 0.51s; }
.hp-seo [data-section].is-visible .hp-seo-hero__stat:nth-child(4) { transition-delay: 0.59s; }
.hp-seo [data-section].is-visible .hp-seo-experts__paras p:nth-child(1) { transition-delay: 0.18s; }
.hp-seo [data-section].is-visible .hp-seo-experts__paras p:nth-child(2) { transition-delay: 0.26s; }
.hp-seo [data-section].is-visible .hp-seo-experts__paras p:nth-child(3) { transition-delay: 0.34s; }
.hp-seo [data-section].is-visible .hp-seo-opps__body  { transition-delay: 0.12s; }
.hp-seo [data-section].is-visible .hp-seo-faq__item:nth-child(1) { transition-delay: 0.05s; }
.hp-seo [data-section].is-visible .hp-seo-faq__item:nth-child(2) { transition-delay: 0.12s; }
.hp-seo [data-section].is-visible .hp-seo-faq__item:nth-child(3) { transition-delay: 0.19s; }
.hp-seo [data-section].is-visible .hp-seo-faq__item:nth-child(4) { transition-delay: 0.26s; }
.hp-seo [data-section].is-visible .hp-seo-faq__item:nth-child(5) { transition-delay: 0.33s; }
.hp-seo [data-section].is-visible .hp-seo-faq__item:nth-child(6) { transition-delay: 0.40s; }
.hp-seo [data-section].is-visible .hp-seo-faq__item:nth-child(7) { transition-delay: 0.47s; }

/* =============================================================
   SEO Hero
   ============================================================= */
.hp-seo-hero {
	position: relative;
	background: var(--color-primary);
	color: var(--color-paper);
	padding: clamp(8rem, 16vw, 13rem) clamp(1.25rem, 5vw, 4rem) clamp(5rem, 10vw, 9rem);
	isolation: isolate;
}
/* Brand glow (from the logo brand image, 2026-07-29): soft blue radial
   bleeding in from the left edge of every internal-page hero. Static
   gradient only — no blur filter, no animation — so it costs nothing on
   PSI. z-index -1 inside the hero's isolated stacking context paints it
   above the hero's own navy background but below the thread + copy. */
.hp-seo-hero::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	background: radial-gradient(45% 75% at 0% 42%,
		color-mix(in oklab, var(--color-radial) 34%, transparent) 0%,
		color-mix(in oklab, var(--color-radial) 13%, transparent) 45%,
		transparent 75%);
}
/* Brand thread emanating from the H1 period (.hp-seo-hero__dot). Layered
   above the glow, below the H1/copy. preserveAspectRatio default keeps
   stroke px consistent with the dot. JS (wireSeoHeroThread) writes the d=
   from the dot's live position; CSS keeps it offscreen-safe via the
   parent hero's overflow rules. */
.hp-seo-hero-thread {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	z-index: 1;
	overflow: visible;
}

.hp-seo-hero__glow {
	position: absolute;
	inset: -10% -10% auto auto;
	width: min(900px, 90vw);
	aspect-ratio: 1 / 1;
	background: radial-gradient(circle at 70% 30%,
		rgba(253, 46, 152, 0.35) 0%,
		rgba(81, 112, 255, 0.25) 30%,
		transparent 65%);
	filter: blur(30px);
	z-index: 0;
	pointer-events: none;
	animation: hp-seo-glow 14s ease-in-out infinite alternate;
}
@keyframes hp-seo-glow {
	0%   { transform: translate3d(0, 0, 0) scale(1); opacity: 0.85; }
	100% { transform: translate3d(-4%, 4%, 0) scale(1.07); opacity: 1; }
}
.hp-seo-hero__inner {
	position: relative;
	z-index: 1;
	max-width: 1280px;
	margin-inline: auto;
}
.hp-seo-hero__eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: rgba(244, 241, 234, 0.7);
	margin-bottom: clamp(1.25rem, 2.5vw, 2rem);
}
.hp-seo-hero__eyebrow-dot {
	width: 0.5rem;
	height: 0.5rem;
	background: var(--color-accent);
	border-radius: 50%;
	box-shadow: 0 0 0 4px rgba(253, 46, 152, 0.25);
	animation: hp-seo-pulse 2.4s ease-in-out infinite;
}
@keyframes hp-seo-pulse {
	0%, 100% { box-shadow: 0 0 0 4px rgba(253, 46, 152, 0.18); }
	50%      { box-shadow: 0 0 0 8px rgba(253, 46, 152, 0.05); }
}
/* SEO H1 needs higher specificity than .hp-eb-hero__h1 (0,1,0) so the
   stair-stack wordmark reads at full impact. The .hp-seo-hero ancestor
   pushes specificity to (0,2,0). */
.hp-seo-hero .hp-seo-hero__h1 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(3rem, 10.5vw, 8rem);
	line-height: 0.96;
	letter-spacing: -0.045em;
	margin: 0 0 clamp(1.5rem, 3vw, 2.5rem);
	padding-bottom: 0.12em;
	max-width: 14ch;
}
/* SEO page only (scoped by data-section, the section has no page-unique
   class). The shared 10.5vw clamp above suits short titles (legal /
   contact / coming-soon heroes), but "East Anglia's" is 13 characters and
   wrapped mid-word inside the 1.7fr copy column, blowing the stair-stack
   out to 5 lines. Same reduced clamp as the About hero. */
.hp-seo-hero[data-section="seo-hero"] .hp-seo-hero__h1 {
	font-size: clamp(2.25rem, 7.5vw, 6.5rem);
}
.hp-seo-hero__line { display: block; }
/* The brand period — rendered as a styled circle (not a "." glyph) so
   getBoundingClientRect returns the visible dot's bounds exactly. That
   lets wireSeoHeroThread anchor the brand thread at the precise centre
   of the dot. Sized in em so it scales with the H1's clamp font-size.
   inline-block on the baseline mimics where a real period would sit. */
/* Was a filled pink circle. Now a real "." character coloured pink
   (user feedback: "should be the normal period but the color is pink").
   wireSeoHeroThread still uses this element's bounding box to anchor
   the thread; the period glyph gives a slightly smaller anchor box
   than the previous filled circle but the visual thread origin still
   lands at the right of the wordmark. */
/* SEO-page sibling of .hp-eb-hero__dot — same styled-circle treatment
   (see the note on .hp-eb-hero__dot at line ~7237). Kept as its own
   selector because wireSeoHeroThread queries `.hp-seo-hero__dot`
   specifically when picking the anchor element. */
.hp-seo-hero__dot {
	display: inline-block;
	width: 0.18em;
	height: 0.18em;
	margin-left: 0.08em;
	vertical-align: 0.05em;
	background: var(--color-accent);
	border-radius: 50%;
	color: transparent;
	-webkit-text-fill-color: transparent;
	overflow: hidden;
	font-size: inherit;
	line-height: 1;
}
/* Lead + sub need .hp-seo-hero ancestor for the same reason as the H1
   (override .hp-eb-hero__lead at line ~6971). The 40ch cap pulls the
   copy back to a tight, scannable measure beside the bigger H1. */
.hp-seo-hero .hp-seo-hero__lead {
	font-size: clamp(1.125rem, 1.8vw, 1.5rem);
	line-height: 1.45;
	color: rgba(244, 241, 234, 0.92);
	max-width: 40ch;
	margin: 0 0 clamp(1rem, 2vw, 1.5rem);
}
.hp-seo-hero .hp-seo-hero__sub {
	display: flex;
	align-items: flex-start;
	gap: 1rem;
	font-size: clamp(0.95rem, 1.1vw, 1.0625rem);
	color: rgba(244, 241, 234, 0.6);
	max-width: 40ch;
	margin: 0 0 clamp(2rem, 4vw, 3rem);
	line-height: 1.55;
}
.hp-seo-hero__sub-rule {
	flex: 0 0 auto;
	width: 2.5rem;
	height: 2px;
	background: var(--color-accent);
	margin-top: 0.7em;
}
.hp-seo-hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.875rem;
	margin-bottom: clamp(3rem, 6vw, 5rem);
}
.hp-seo-hero__stats {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: clamp(1rem, 2.5vw, 2.5rem);
	padding-top: clamp(2rem, 4vw, 3rem);
	border-top: 1px solid rgba(244, 241, 234, 0.14);
}
.hp-seo-hero__stat {
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
	min-width: 0;
}
.hp-seo-hero__stat-num {
	font-family: var(--font-heading-family);
	font-size: clamp(1.75rem, 4.4vw, 3.5rem);
	font-weight: 800;
	letter-spacing: -0.03em;
	line-height: 1;
	background: linear-gradient(135deg, #FFFFFF 0%, #FF7BC0 60%, #FD2E98 100%);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}
.hp-seo-hero__stat-label {
	font-size: clamp(0.78rem, 1vw, 0.95rem);
	color: rgba(244, 241, 234, 0.65);
	line-height: 1.35;
}
@media (max-width: 760px) {
	.hp-seo-hero__stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* =============================================================
   SEO hero — Geek-style showcase column
   -------------------------------------------------------------
   Three decorative cards (PageSpeed rings, organic-visitors
   chart, Google search autocomplete) stacked vertically in the
   right column with light Y overlap. Cards are aria-hidden in
   the markup; they restate what the H1+lead already say.
   ============================================================= */

/* Give the SEO hero's copy column more grid share than the default
   .hp-eb-hero__inner ratio — the bigger H1 (up to 11rem) needs the
   extra width to keep the stair-stack on three lines. Higher
   specificity (0,2,0) wins over the .hp-eb-hero__inner default. */
.hp-seo-hero .hp-eb-hero__inner {
	grid-template-columns:
		minmax(0, 1.7fr)
		clamp(40px, 5vw, 90px)
		minmax(0, 1fr);
}

.hp-seo-hero__showcase {
	grid-column: 3;
	position: relative;
	display: flex;
	flex-direction: column;
	gap: clamp(1.25rem, 2.2vw, 2rem);
	align-self: stretch;
	justify-content: center;
	min-width: 0;
}

.hp-seo-hero__card {
	position: relative;
	background: var(--color-paper);
	color: var(--color-primary);
	border-radius: 22px;
	box-shadow:
		0 28px 60px -28px rgba(0, 0, 16, 0.45),
		0 8px 20px -10px rgba(0, 0, 16, 0.25);
	padding: clamp(1rem, 1.4vw, 1.35rem) clamp(1.1rem, 1.6vw, 1.5rem);
	transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.5s ease;
}
.hp-seo-hero__card:hover {
	transform: translateY(-4px);
}

/* ---------- PageSpeed card ---------- */
.hp-seo-hero__card--psi {
	/* Geek-reference stagger offsets removed per user spec — the three
	   showcase cards align flush, matching the About hero credentials. */
	margin: 0;
}
.hp-seo-hero__psi-tabs {
	display: flex;
	justify-content: center;
	gap: 0.6rem;
	margin-bottom: 0.85rem;
	font-size: 0.78rem;
	color: rgba(0, 0, 16, 0.55);
}
.hp-seo-hero__psi-tab {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	padding: 0.3rem 0.6rem;
	border-radius: 999px;
	font-weight: 500;
	letter-spacing: 0.01em;
}
.hp-seo-hero__psi-tab.is-active {
	background: rgba(26, 115, 232, 0.1);
	/* #1055C0, not Google's #1a73e8: the mock is aria-hidden but still
	   visible, and axe checks contrast for low-vision users — the raw
	   Google blue is 3.5:1 on the card grey. */
	color: #1055C0;
	box-shadow: inset 0 -2px 0 #1055C0;
}
.hp-seo-hero__psi-rings {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: clamp(0.5rem, 1vw, 1rem);
	align-items: start;
}
.hp-seo-hero__psi-ring {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.35rem;
	min-width: 0;
}
.hp-seo-hero__psi-ring--green { --psi-color: #0cce6b; }
.hp-seo-hero__psi-ring--amber { --psi-color: #ffa400; }
.hp-seo-hero__psi-ring--red   { --psi-color: #ff4e42; }

.hp-seo-hero__psi-svg {
	width: clamp(48px, 5vw, 70px);
	height: clamp(48px, 5vw, 70px);
}
.hp-seo-hero__psi-track {
	fill: none;
	stroke: color-mix(in srgb, var(--psi-color) 18%, transparent);
	stroke-width: 3;
}
.hp-seo-hero__psi-fill {
	fill: none;
	stroke: var(--psi-color);
	stroke-width: 3;
	stroke-linecap: round;
	/* Circumference of r=16 ≈ 100.5 → dasharray 100 lets us treat
	   stroke-dashoffset as `(100 - score)`. Start the stroke at 12
	   o'clock by rotating the fill circle inside the SVG so the val
	   text above doesn't rotate with it. */
	stroke-dasharray: 100;
	stroke-dashoffset: calc(100 - var(--psi-score));
	transform: rotate(-90deg);
	transform-origin: center;
	transition: stroke-dashoffset 1.4s cubic-bezier(0.22, 1, 0.36, 1) 0.3s;
}
.hp-seo-hero__psi-val {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: clamp(48px, 5vw, 70px);
	display: flex;
	align-items: center;
	justify-content: center;
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: clamp(0.95rem, 1.4vw, 1.25rem);
	color: var(--psi-color);
	letter-spacing: -0.02em;
	font-variant-numeric: tabular-nums;
	pointer-events: none;
}
.hp-seo-hero__psi-lbl {
	font-size: clamp(0.65rem, 0.78vw, 0.78rem);
	color: rgba(0, 0, 16, 0.65);
	text-align: center;
	line-height: 1.2;
}

/* ---------- Organic Visitors chart card ---------- */
.hp-seo-hero__card--chart {
	margin: 0;
}
.hp-seo-hero__card-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	margin-bottom: 0.6rem;
}
.hp-seo-hero__card-title {
	font-family: var(--font-heading-family);
	font-size: clamp(0.95rem, 1.1vw, 1.05rem);
	font-weight: 700;
	margin: 0;
	letter-spacing: -0.01em;
}
.hp-seo-hero__card-meta {
	font-size: 0.72rem;
	color: rgba(0, 0, 16, 0.55);
	font-variant-numeric: tabular-nums;
}
.hp-seo-hero__chart {
	display: block;
	width: 100%;
	height: clamp(90px, 12vh, 130px);
	margin: 0.25rem 0 0.6rem;
}
.hp-seo-hero__card-foot {
	font-size: 0.82rem;
	color: rgba(0, 0, 16, 0.7);
	margin: 0;
	font-weight: 600;
	letter-spacing: -0.005em;
}

/* ---------- Search autocomplete card ---------- */
.hp-seo-hero__card--search {
	margin: 0;
	padding-block: clamp(0.85rem, 1.2vw, 1.15rem);
}
.hp-seo-hero__search-row {
	display: flex;
	align-items: center;
	gap: 0.7rem;
	padding: 0.55rem 0.25rem;
	color: rgba(0, 0, 16, 0.85);
	font-size: 0.95rem;
}
.hp-seo-hero__search-row + .hp-seo-hero__search-row {
	border-top: 1px solid rgba(0, 0, 16, 0.08);
}
.hp-seo-hero__search-row svg { flex: 0 0 auto; color: rgba(0, 0, 16, 0.55); }
.hp-seo-hero__search-q {
	flex: 1;
	font-weight: 500;
	color: rgba(0, 0, 16, 0.9);
	display: inline-flex;
	align-items: center;
	letter-spacing: -0.005em;
}
.hp-seo-hero__search-caret {
	display: inline-block;
	width: 1px;
	height: 1.05em;
	margin-left: 2px;
	background: rgba(0, 0, 16, 0.85);
	animation: hp-seo-caret 1.05s steps(1) infinite;
}
@keyframes hp-seo-caret { 50% { opacity: 0; } }
.hp-seo-hero__search-row--suggest { color: rgba(0, 0, 16, 0.72); }
.hp-seo-hero__search-sug { font-weight: 500; }

/* ---------- Showcase responsive collapse ---------- */
/* 1024px, not 900px: must match the .hp-eb-hero__inner grid collapse so the
   showcase never sits in a non-existent column 3 (which forced horizontal
   overflow in the 900-1024 band). */
@media (max-width: 1024px) {
	.hp-seo-hero__showcase {
		grid-column: 1;
		margin-top: clamp(2rem, 5vw, 3rem);
	}
	.hp-seo-hero__card--psi,
	.hp-seo-hero__card--chart,
	.hp-seo-hero__card--search {
		margin: 0;
	}
}
@media (max-width: 560px) {
	.hp-seo-hero__psi-rings { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 1rem; }
}

/* =============================================================
   Opportunities section
   ============================================================= */
.hp-seo-opps {
	background: var(--color-primary);
	color: var(--color-paper);
	padding: clamp(5rem, 10vw, 9rem) clamp(1.25rem, 5vw, 4rem);
}
.hp-seo-opps__inner {
	max-width: 1280px;
	margin-inline: auto;
	display: grid;
	grid-template-columns: 1.05fr 1fr;
	gap: clamp(2.5rem, 6vw, 6rem);
	align-items: start;
}
@media (max-width: 900px) {
	.hp-seo-opps__inner { grid-template-columns: 1fr; }
}
.hp-seo-opps__eyebrow {
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: rgba(244, 241, 234, 0.55);
	margin: 0 0 1.5rem;
}
.hp-seo-opps__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2rem, 4.6vw, 4rem);
	line-height: 1.04;
	letter-spacing: -0.03em;
	margin: 0 0 1.25rem;
	color: var(--color-paper);
}
.hp-seo-opps__pretitle {
	font-size: clamp(1rem, 1.4vw, 1.2rem);
	color: rgba(244, 241, 234, 0.7);
	max-width: 38ch;
	line-height: 1.5;
}
.hp-seo-opps__lead {
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-size: clamp(1.25rem, 2vw, 1.75rem);
	line-height: 1.4;
	color: rgba(244, 241, 234, 0.55);
	margin: 0 0 2rem;
}
.hp-seo-opps__chips {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 0.6rem;
}
.hp-seo-opps__chips li {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.55rem 1rem;
	border-radius: 999px;
	background: rgba(244, 241, 234, 0.05);
	border: 1px solid rgba(244, 241, 234, 0.12);
	font-size: 0.875rem;
	color: rgba(244, 241, 234, 0.85);
	transition: background 0.25s ease, border-color 0.25s ease, transform 0.25s ease;
}
.hp-seo-opps__chips li:hover {
	background: rgba(253, 46, 152, 0.12);
	border-color: rgba(253, 46, 152, 0.5);
	transform: translateY(-2px);
}
.hp-seo-opps__chip-dot {
	width: 0.4rem;
	height: 0.4rem;
	border-radius: 50%;
	background: var(--color-accent);
}

/* =============================================================
   Experts split section
   ============================================================= */
.hp-seo-experts {
	background: var(--color-primary);
	color: var(--color-paper);
	padding: clamp(5rem, 10vw, 9rem) clamp(1.25rem, 5vw, 4rem) clamp(4rem, 8vw, 7rem);
}

/* Brand thread SVG — covers the full section. Sits below content
   (z-index 0) so the thread wraps behind the prose + image without
   intercepting clicks. wireSeoExpertsThread writes the d= live. */
.hp-seo-experts-thread {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	z-index: 0;
	overflow: visible;
}
/* Stroke bumped from the hardcoded 18px (a micro-decorative band) to
   the canonical 22-30px clamp the WD hero / process / outperform /
   quotes threads all use. Per [[feedback-eb-thread-mandatory]] every
   continuous-spine thread on an internal page ships at hero band on
   the first pass; 18px is for bracket borders, stats baselines, and
   other passive decorative pulls. */
.hp-seo-experts-thread path {
	stroke-width: clamp(22px, 2vw, 30px);
}
.hp-seo-experts .hp-eb-split__inner { position: relative; z-index: 1; }
.hp-seo-experts__inner {
	max-width: 1280px;
	margin-inline: auto;
	display: grid;
	grid-template-columns: 1.1fr 1fr;
	gap: clamp(2.5rem, 6vw, 6rem);
	align-items: center;
}
@media (max-width: 980px) {
	.hp-seo-experts__inner { grid-template-columns: 1fr; }
}
.hp-seo-experts__eyebrow {
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: rgba(244, 241, 234, 0.55);
	margin: 0 0 1.5rem;
}
.hp-seo-experts__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2rem, 4.6vw, 4rem);
	line-height: 1.04;
	letter-spacing: -0.03em;
	margin: 0 0 2rem;
	padding-bottom: 0.1em;
	max-width: 18ch;
}
.hp-seo-experts__paras {
	display: flex;
	flex-direction: column;
	gap: 1.1rem;
	color: rgba(244, 241, 234, 0.82);
	font-size: clamp(1rem, 1.15vw, 1.125rem);
	line-height: 1.65;
	max-width: 56ch;
	margin-bottom: clamp(2rem, 4vw, 3rem);
}
.hp-seo-experts__paras p { margin: 0; }
.hp-seo-experts__meta {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
}
.hp-seo-experts__badge {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	padding: 0.65rem 1.1rem;
	border-radius: 999px;
	background: rgba(253, 46, 152, 0.12);
	color: var(--color-accent-light);
	border: 1px solid rgba(253, 46, 152, 0.4);
	font-size: 0.875rem;
	font-weight: 600;
}
.hp-seo-experts__badge svg {
	width: 1rem;
	height: 1rem;
}
.hp-seo-experts__badge--ghost {
	background: rgba(244, 241, 234, 0.04);
	color: var(--color-paper);
	border-color: rgba(244, 241, 234, 0.2);
}
.hp-seo-experts__panel {
	position: relative;
	border-radius: 28px;
	overflow: hidden;
	border: 1px solid rgba(244, 241, 234, 0.12);
	background: rgba(244, 241, 234, 0.03);
	box-shadow: 0 30px 80px rgba(0, 0, 0, 0.35);
	transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.hp-seo-experts__panel:hover { transform: translateY(-6px); }
.hp-seo-experts__panel-media {
	position: relative;
	aspect-ratio: 16 / 10;
	overflow: hidden;
}
.hp-seo-experts__panel-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transform: scale(1.05);
	transition: transform 0.9s ease;
}
.hp-seo-experts__panel:hover .hp-seo-experts__panel-media img { transform: scale(1.12); }
.hp-seo-experts__panel-veil {
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg,
		rgba(0, 0, 16, 0.25) 0%,
		rgba(0, 0, 16, 0.5) 60%,
		rgba(0, 0, 16, 0.85) 100%);
}
.hp-seo-experts__panel-stats {
	display: grid;
	grid-template-columns: 1fr;
	gap: 1px;
	background: rgba(244, 241, 234, 0.1);
}
.hp-seo-experts__panel-stat {
	padding: 1.25rem 1.5rem;
	background: var(--color-primary);
	display: grid;
	grid-template-columns: auto 1fr;
	gap: 1.25rem;
	align-items: center;
}
.hp-seo-experts__panel-num {
	font-family: var(--font-heading-family);
	font-size: clamp(1.75rem, 3vw, 2.5rem);
	font-weight: 800;
	color: var(--color-accent);
	line-height: 1;
	min-width: 4ch;
}
.hp-seo-experts__panel-lbl {
	font-size: 0.9375rem;
	color: rgba(244, 241, 234, 0.75);
	line-height: 1.4;
}

/* =============================================================
   Case study cards (Results)
   ============================================================= */
.hp-seo-results {
	background: var(--color-paper);
	color: var(--color-primary);
	padding: clamp(5rem, 10vw, 9rem) clamp(1.25rem, 5vw, 4rem);
}
.hp-seo-results__inner {
	max-width: 1280px;
	margin-inline: auto;
}
.hp-seo-results__head {
	max-width: 60ch;
	margin: 0 auto clamp(3rem, 5vw, 4.5rem);
	text-align: center;
}
.hp-seo-results__eyebrow {
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: rgba(8, 20, 39, 0.55);
	margin: 0 0 1rem;
}
.hp-seo-results__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2rem, 4.6vw, 4rem);
	line-height: 1.04;
	letter-spacing: -0.03em;
	margin: 0 0 1rem;
}
.hp-seo-results__sub {
	font-size: clamp(1rem, 1.2vw, 1.15rem);
	color: rgba(8, 20, 39, 0.7);
	margin: 0;
}
.hp-seo-results__grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: clamp(1.25rem, 2.5vw, 2rem);
}
@media (max-width: 980px) {
	.hp-seo-results__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
	.hp-seo-results__grid { grid-template-columns: 1fr; }
}
.hp-seo-case {
	position: relative;
	display: flex;
	flex-direction: column;
	border-radius: 24px;
	background: var(--color-white);
	overflow: hidden;
	border: 1px solid rgba(8, 20, 39, 0.08);
	box-shadow: 0 4px 14px rgba(8, 20, 39, 0.04);
	transition: transform 0.45s cubic-bezier(0.2, 0.7, 0.2, 1),
	            box-shadow 0.45s cubic-bezier(0.2, 0.7, 0.2, 1),
	            border-color 0.45s ease;
}
.hp-seo-case:hover {
	transform: translateY(-8px);
	border-color: rgba(253, 46, 152, 0.4);
	box-shadow: 0 24px 60px rgba(8, 20, 39, 0.12);
}
.hp-seo-case__media {
	position: relative;
	aspect-ratio: 5 / 3;
	overflow: hidden;
}
.hp-seo-case__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transform: scale(1.04);
	transition: transform 0.9s ease;
}
.hp-seo-case:hover .hp-seo-case__media img { transform: scale(1.12); }
.hp-seo-case__tag {
	position: absolute;
	top: 1rem;
	left: 1rem;
	padding: 0.4rem 0.8rem;
	background: rgba(0, 0, 16, 0.78);
	color: var(--color-paper);
	border-radius: 999px;
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	backdrop-filter: blur(8px);
}
.hp-seo-case__body {
	padding: clamp(1.5rem, 2.5vw, 2rem);
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
	flex: 1;
}
.hp-seo-case__stat {
	display: flex;
	align-items: baseline;
	gap: 0.6rem;
	margin-bottom: 0.25rem;
}
.hp-seo-case__stat-num {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.75rem, 3vw, 2.5rem);
	letter-spacing: -0.03em;
	color: var(--color-accent);
	line-height: 1;
}
.hp-seo-case__stat-lbl {
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: rgba(8, 20, 39, 0.55);
}
.hp-seo-case__title {
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: clamp(1.25rem, 1.8vw, 1.5rem);
	letter-spacing: -0.02em;
	margin: 0;
	line-height: 1.2;
}
.hp-seo-case__kpi {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-size: 0.9375rem;
	font-weight: 600;
	color: var(--color-secondary);
	margin: 0;
}
.hp-seo-case__kpi-dot {
	width: 0.5rem;
	height: 0.5rem;
	border-radius: 50%;
	background: var(--color-accent);
}
.hp-seo-case__copy {
	font-size: 0.9375rem;
	line-height: 1.6;
	color: rgba(8, 20, 39, 0.72);
	margin: 0;
}

/* =============================================================
   Testimonials
   ============================================================= */
.hp-seo-quotes {
	background: var(--color-primary);
	color: var(--color-paper);
	padding: clamp(5rem, 10vw, 9rem) clamp(1.25rem, 5vw, 4rem);
}
.hp-seo-quotes__inner {
	max-width: 1280px;
	margin-inline: auto;
}
.hp-seo-quotes__head {
	text-align: center;
	margin: 0 auto clamp(3rem, 5vw, 4.5rem);
	max-width: 60ch;
}
.hp-seo-quotes__eyebrow {
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: rgba(244, 241, 234, 0.55);
	margin: 0 0 1rem;
}
.hp-seo-quotes__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2rem, 4.6vw, 4rem);
	line-height: 1.04;
	letter-spacing: -0.03em;
	margin: 0;
	padding-bottom: 0.12em;
}
.hp-seo-quotes__grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: clamp(1.25rem, 2.5vw, 2rem);
}
@media (max-width: 900px) {
	.hp-seo-quotes__grid { grid-template-columns: 1fr; }
}
.hp-seo-quote {
	position: relative;
	margin: 0;
	padding: clamp(1.75rem, 2.5vw, 2.5rem);
	border-radius: 24px;
	background: rgba(244, 241, 234, 0.03);
	border: 1px solid rgba(244, 241, 234, 0.12);
	display: flex;
	flex-direction: column;
	gap: 1.5rem;
	transition: transform 0.4s ease, border-color 0.4s ease, background 0.4s ease;
}
.hp-seo-quote:hover {
	transform: translateY(-6px);
	border-color: rgba(253, 46, 152, 0.45);
	background: rgba(253, 46, 152, 0.06);
}
.hp-seo-quote__mark {
	width: 2.5rem;
	height: 2.5rem;
	color: var(--color-accent);
	opacity: 0.85;
}
.hp-seo-quote__body p {
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-size: clamp(1.0625rem, 1.4vw, 1.25rem);
	line-height: 1.5;
	color: rgba(244, 241, 234, 0.92);
	margin: 0;
}
.hp-seo-quote__cap {
	display: flex;
	flex-direction: column;
	gap: 0.2rem;
	border-top: 1px solid rgba(244, 241, 234, 0.12);
	padding-top: 1.25rem;
}
.hp-seo-quote__author {
	font-weight: 700;
	font-size: 0.9375rem;
	color: var(--color-paper);
}
.hp-seo-quote__role {
	font-size: 0.8125rem;
	color: rgba(244, 241, 234, 0.55);
	font-style: italic;
}

/* =============================================================
   Deliverables bento grid
   ============================================================= */
.hp-seo-deliver {
	background: var(--color-paper);
	color: var(--color-primary);
	padding: clamp(5rem, 10vw, 9rem) clamp(1.25rem, 5vw, 4rem);
}
.hp-seo-deliver__inner {
	max-width: 1280px;
	margin-inline: auto;
}
.hp-seo-deliver__head {
	margin: 0 0 clamp(3rem, 5vw, 4.5rem);
	max-width: 60ch;
}
.hp-seo-deliver__eyebrow {
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: rgba(8, 20, 39, 0.55);
	margin: 0 0 1rem;
}
.hp-seo-deliver__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2rem, 4.6vw, 4rem);
	line-height: 1.04;
	letter-spacing: -0.03em;
	margin: 0 0 1rem;
}
.hp-seo-deliver__sub {
	font-size: clamp(1rem, 1.2vw, 1.15rem);
	color: rgba(8, 20, 39, 0.7);
	margin: 0;
	max-width: 56ch;
}
.hp-seo-deliver__grid {
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	gap: clamp(1rem, 2vw, 1.5rem);
}
.hp-seo-deliver__card {
	grid-column: span 2;
	position: relative;
	padding: clamp(1.5rem, 2.4vw, 2.25rem);
	border-radius: 24px;
	background: var(--color-white);
	border: 1px solid rgba(8, 20, 39, 0.08);
	display: flex;
	flex-direction: column;
	gap: 0.85rem;
	overflow: hidden;
	transition: transform 0.4s cubic-bezier(0.2, 0.7, 0.2, 1),
	            box-shadow 0.4s ease,
	            border-color 0.4s ease;
}
.hp-seo-deliver__card::after {
	content: "";
	position: absolute;
	inset: auto -40% -40% auto;
	width: 70%;
	aspect-ratio: 1 / 1;
	background: radial-gradient(circle at center, rgba(253, 46, 152, 0.18), transparent 70%);
	opacity: 0;
	transition: opacity 0.45s ease;
	pointer-events: none;
}
.hp-seo-deliver__card:hover {
	transform: translateY(-6px);
	border-color: rgba(253, 46, 152, 0.45);
	box-shadow: 0 24px 60px rgba(8, 20, 39, 0.1);
}
.hp-seo-deliver__card:hover::after { opacity: 1; }
.hp-seo-deliver__card--wide { grid-column: span 4; }
.hp-seo-deliver__card--wide .hp-seo-deliver__card-title { font-size: clamp(1.5rem, 2.4vw, 2rem); }
@media (max-width: 980px) {
	.hp-seo-deliver__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.hp-seo-deliver__card,
	.hp-seo-deliver__card--wide { grid-column: span 1; }
	.hp-seo-deliver__card--wide { grid-column: span 2; }
}
@media (max-width: 560px) {
	.hp-seo-deliver__grid { grid-template-columns: 1fr; }
	.hp-seo-deliver__card,
	.hp-seo-deliver__card--wide { grid-column: span 1; }
}
.hp-seo-deliver__num {
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: 0.875rem;
	letter-spacing: 0.18em;
	color: var(--color-accent);
}
.hp-seo-deliver__icon {
	width: 3rem;
	height: 3rem;
	display: inline-grid;
	place-items: center;
	border-radius: 14px;
	background: linear-gradient(135deg, rgba(253, 46, 152, 0.18), rgba(81, 112, 255, 0.16));
	color: var(--color-accent);
	margin-bottom: 0.25rem;
}
.hp-seo-deliver__icon svg {
	width: 1.5rem;
	height: 1.5rem;
}
.hp-seo-deliver__card-title {
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: clamp(1.125rem, 1.6vw, 1.375rem);
	letter-spacing: -0.02em;
	line-height: 1.2;
	margin: 0;
}
.hp-seo-deliver__card-body {
	font-size: 0.9375rem;
	line-height: 1.6;
	color: rgba(8, 20, 39, 0.7);
	margin: 0;
}

/* =============================================================
   Discovery CTA
   ============================================================= */
.hp-seo-cta {
	position: relative;
	background: var(--color-primary);
	color: var(--color-paper);
	padding: clamp(6rem, 12vw, 10rem) clamp(1.25rem, 5vw, 4rem);
	isolation: isolate;
	text-align: center;
	overflow: hidden;
}
.hp-seo-cta__glow {
	position: absolute;
	inset: -20% -10% auto -10%;
	height: 80%;
	background: radial-gradient(ellipse at 50% 0%,
		rgba(253, 46, 152, 0.3) 0%,
		rgba(81, 112, 255, 0.18) 40%,
		transparent 70%);
	filter: blur(40px);
	z-index: 0;
	pointer-events: none;
}
.hp-seo-cta__inner {
	position: relative;
	z-index: 1;
	max-width: 900px;
	margin-inline: auto;
}
.hp-seo-cta__eyebrow {
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: rgba(244, 241, 234, 0.6);
	margin: 0 0 1.5rem;
}
.hp-seo-cta__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.25rem, 5vw, 4.5rem);
	line-height: 1.05;
	letter-spacing: -0.03em;
	margin: 0 0 1.5rem;
	padding-bottom: 0.12em;
}
.hp-seo-cta__body {
	font-size: clamp(1rem, 1.25vw, 1.1875rem);
	line-height: 1.6;
	color: rgba(244, 241, 234, 0.82);
	max-width: 60ch;
	margin: 0 auto 2.5rem;
}
.hp-seo-cta__actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 0.875rem;
	margin-bottom: 2rem;
}
.hp-seo-cta__foot {
	font-size: 0.875rem;
	color: rgba(244, 241, 234, 0.55);
	margin: 0;
}

/* =============================================================
   FAQ accordion
   ============================================================= */
.hp-seo-faq {
	background: var(--color-paper);
	color: var(--color-primary);
	padding: clamp(5rem, 10vw, 9rem) clamp(1.25rem, 5vw, 4rem);
}
.hp-seo-faq__inner {
	max-width: 960px;
	margin-inline: auto;
}
.hp-seo-faq__head {
	margin: 0 0 clamp(2.5rem, 5vw, 4rem);
	max-width: 60ch;
}
.hp-seo-faq__eyebrow {
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: rgba(8, 20, 39, 0.55);
	margin: 0 0 1rem;
}
.hp-seo-faq__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2rem, 4.4vw, 3.75rem);
	line-height: 1.04;
	letter-spacing: -0.03em;
	margin: 0;
}
.hp-seo-faq__list {
	display: flex;
	flex-direction: column;
	gap: 0.85rem;
}
.hp-seo-faq__item {
	border-radius: 20px;
	background: var(--color-white);
	border: 1px solid rgba(8, 20, 39, 0.08);
	overflow: hidden;
	transition: border-color 0.35s ease, box-shadow 0.35s ease, background 0.35s ease;
}
.hp-seo-faq__item[open] {
	border-color: rgba(253, 46, 152, 0.4);
	box-shadow: 0 18px 40px rgba(8, 20, 39, 0.08);
}
.hp-seo-faq__q {
	list-style: none;
	cursor: pointer;
	display: grid;
	grid-template-columns: auto 1fr auto;
	gap: clamp(1rem, 2vw, 1.5rem);
	align-items: center;
	padding: clamp(1.25rem, 2vw, 1.75rem);
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: clamp(1.0625rem, 1.5vw, 1.25rem);
	letter-spacing: -0.01em;
	line-height: 1.3;
	color: var(--color-primary);
	transition: color 0.25s ease;
}
.hp-seo-faq__q::-webkit-details-marker { display: none; }
.hp-seo-faq__q:hover { color: var(--color-accent); }
.hp-seo-faq__q-num {
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.1em;
	color: var(--color-accent);
	min-width: 2.5ch;
}
.hp-seo-faq__q-text { min-width: 0; }
.hp-seo-faq__q-icon {
	position: relative;
	width: 2.25rem;
	height: 2.25rem;
	border-radius: 999px;
	background: rgba(253, 46, 152, 0.1);
	display: inline-grid;
	place-items: center;
	flex-shrink: 0;
	transition: background 0.3s ease, transform 0.4s cubic-bezier(0.34, 1.5, 0.64, 1);
}
.hp-seo-faq__q-icon span {
	position: absolute;
	background: var(--color-accent);
	border-radius: 2px;
}
.hp-seo-faq__q-icon span:nth-child(1) { width: 12px; height: 2px; }
.hp-seo-faq__q-icon span:nth-child(2) {
	width: 2px;
	height: 12px;
	transition: transform 0.4s cubic-bezier(0.34, 1.5, 0.64, 1);
}
.hp-seo-faq__item[open] .hp-seo-faq__q-icon { background: var(--color-accent); transform: rotate(180deg); }
.hp-seo-faq__item[open] .hp-seo-faq__q-icon span { background: var(--color-white); }
.hp-seo-faq__item[open] .hp-seo-faq__q-icon span:nth-child(2) { transform: scaleY(0); }
.hp-seo-faq__a {
	padding: 0 clamp(1.25rem, 2vw, 1.75rem) clamp(1.25rem, 2vw, 1.75rem);
	padding-left: calc(clamp(1.25rem, 2vw, 1.75rem) + 2.5ch + clamp(1rem, 2vw, 1.5rem));
	transform-origin: top center;
}
.hp-seo-faq__a p {
	font-size: 1rem;
	line-height: 1.65;
	color: rgba(8, 20, 39, 0.72);
	margin: 0;
}
@media (max-width: 560px) {
	.hp-seo-faq__a { padding-left: clamp(1.25rem, 2vw, 1.75rem); }
}

/* Shared FAQ bounce — applied to BOTH the SEO FAQ (.hp-seo-faq) and the
   Web Design / Editorial-Brutalism FAQ (.hp-wd-faq) when their <details>
   gets [open]. Multi-stop keyframe gives a satisfying spring: overshoots
   on the way in, settles back. Not wrapped in prefers-reduced-motion so
   the bounce reads as brand content per [[feedback-hp-animations-are-content]]. */
@keyframes hp-faq-bounce-in {
	0%   { opacity: 0; transform: translateY(-10px) scaleY(0.94); }
	55%  { opacity: 1; transform: translateY(4px)  scaleY(1.04); }
	78%  {            transform: translateY(-2px) scaleY(0.99); }
	100% { opacity: 1; transform: translateY(0)    scaleY(1);    }
}
.hp-seo-faq__item[open] .hp-seo-faq__a,
.hp-wd-faq__details[open] .hp-wd-faq__a {
	animation: hp-faq-bounce-in 0.55s cubic-bezier(0.34, 1.45, 0.5, 1) both;
	transform-origin: top center;
}

/* =============================================================
   SEO brand thread strips
   ----------------------------------------------------------
   Each thread lives in its own padding-block strip between two
   sections, so the stroke never sits over any text or image. The
   strip's background colour matches whichever section it is leaving
   (navy or paper), so the seam disappears. The actual draw-on logic
   (stroke-dasharray + --p) is shared with .hp-ribbon and powered by
   wireScrollRibbon().
   ============================================================= */
.hp-seo-thread {
	position: relative;
	line-height: 0;
	overflow: hidden;
	padding-block: clamp(2rem, 5vw, 4rem) clamp(2rem, 5vw, 4rem);
}
.hp-seo-thread--navy  { background: var(--color-primary); }
.hp-seo-thread--paper { background: var(--color-paper); }

/* All thread strips render at the SAME SVG height as the homepage
   ribbon (clamp(280px, 35vh, 500px)) so the visible stroke thickness
   is uniform — preserveAspectRatio="none" means stroke width scales
   with SVG height, so identical height = identical pixel thickness.
   wireScrollRibbon() further normalises this to the hero dot's
   diameter at runtime; the static size is the no-JS fallback. */
.hp-seo-thread .hp-ribbon__svg {
	display: block;
	width: 100%;
	overflow: visible;
	height: clamp(280px, 35vh, 500px);
}
.hp-seo-thread--short .hp-ribbon__svg { height: clamp(280px, 35vh, 500px); }
.hp-seo-thread--tall  .hp-ribbon__svg { height: clamp(280px, 35vh, 500px); }
.hp-seo-thread--wave  .hp-ribbon__svg { height: clamp(280px, 35vh, 500px); }

/* =============================================================
   Expectations grid (reusable section, template-parts/section-expectations.php)
   ----------------------------------------------------------
   Top intro on the left, five staggered cards (row 1 = 3 cards,
   row 2 = 2 cards offset right) on a navy or paper ground. The
   pink brand thread weaves through the cards' negative space via
   an absolutely-positioned SVG that reuses [data-scroll-ribbon]
   so wireScrollRibbon() animates the draw-on for free.

   Mobile collapses to a single column and hides the thread —
   the stair-step path only reads at 2–3 column widths.
   ============================================================= */
.hp-expectations {
	position: relative;
	padding: clamp(4rem, 9vw, 7rem) 1.5rem clamp(5rem, 11vw, 8rem);
	overflow: hidden;
}
.hp-expectations--navy  { background: var(--color-primary); color: var(--color-paper); }
.hp-expectations--paper { background: var(--color-paper);   color: var(--color-primary); }
.hp-expectations__inner {
	max-width: 1320px;
	margin-inline: auto;
}

/* Intro lockup mirrors hp-services: small uppercase eyebrow + a tight
   display-scale lede. Capped at ~52ch so the line breaks where the
   geek reference breaks rather than running edge to edge. */
.hp-expectations__intro {
	max-width: 52ch;
	margin-bottom: clamp(3rem, 7vw, 6rem);
}
.hp-expectations__eyebrow {
	font-size: 0.8125rem;
	text-transform: uppercase;
	letter-spacing: 0.22em;
	color: color-mix(in srgb, currentColor 55%, transparent);
	margin: 0 0 clamp(1rem, 2vw, 1.5rem);
	font-weight: 600;
}
.hp-expectations__lede {
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: clamp(1.5rem, 2.8vw, 2.25rem);
	line-height: 1.3;
	letter-spacing: -0.01em;
	color: inherit;
}
.hp-expectations__lede p { margin: 0 0 0.6em; }
.hp-expectations__lede p:last-child { margin-bottom: 0; }

/* Grid is the positioning context for the absolute thread layer. The
   cards sit above it via z-index so the stroke draws BEHIND the text. */
.hp-expectations__grid {
	position: relative;
}
.hp-expectations__cards {
	position: relative;
	z-index: 2;
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	column-gap: clamp(1.5rem, 4vw, 4rem);
	row-gap: clamp(7rem, 14vw, 12rem); /* large row gap so the thread has room to weave */
}
/* Staggered placement — row 1 fills cols 1/2/3, row 2 skips col 1 so
   cards 4 and 5 sit under cols 2 and 3. Matches the reference layout. */
.hp-expectations__card--1 { grid-column: 1; grid-row: 1; }
.hp-expectations__card--2 { grid-column: 2; grid-row: 1; }
.hp-expectations__card--3 { grid-column: 3; grid-row: 1; }
.hp-expectations__card--4 { grid-column: 2; grid-row: 2; }
.hp-expectations__card--5 { grid-column: 3; grid-row: 2; }

.hp-expectations__card-heading {
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: clamp(1.5rem, 2.4vw, 2rem);
	line-height: 1.15;
	letter-spacing: -0.015em;
	margin: 0 0 clamp(1rem, 1.6vw, 1.4rem);
	color: inherit;
}
.hp-expectations__card-body {
	font-size: clamp(1rem, 1.15vw, 1.0625rem);
	line-height: 1.6;
	margin: 0;
	color: color-mix(in srgb, currentColor 75%, transparent);
	max-width: 38ch;
}

/* Thread layer — absolute over the grid, behind the cards (z-index 1).
   Uses the same .hp-ribbon__svg / .hp-ribbon__path hooks so the existing
   wireScrollRibbon() picks it up. The SVG stretches to the grid's full
   width and height; the path is authored in 2000×700 viewBox units. */
.hp-expectations__thread {
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	line-height: 0;
}
.hp-expectations__thread-svg {
	display: block;
	width: 100%;
	height: 100%;
	overflow: visible;
}

/* Tablet: still 3 columns, the path geometry still reads. Tighten the
   row gap so the section doesn't get too tall. */
@media (max-width: 1080px) {
	.hp-expectations__cards { row-gap: clamp(5rem, 10vw, 8rem); }
	.hp-expectations__card-heading { font-size: clamp(1.35rem, 2.4vw, 1.75rem); }
}

/* Mobile: stack everything into a single column and drop the weaving
   thread (a 2-row stair-step doesn't survive a 1-col layout — it just
   reads as a vertical line). Card 1 of the second row no longer needs
   to skip a column, so reset the grid placement. */
@media (max-width: 720px) {
	.hp-expectations { padding-inline: 1.25rem; }
	.hp-expectations__cards {
		grid-template-columns: 1fr;
		row-gap: clamp(2.5rem, 7vw, 4rem);
	}
	.hp-expectations__card--1,
	.hp-expectations__card--2,
	.hp-expectations__card--3,
	.hp-expectations__card--4,
	.hp-expectations__card--5 {
		grid-column: 1;
		grid-row: auto;
	}
	.hp-expectations__thread { display: none; }
	.hp-expectations__card-body { max-width: none; }
}

/* =====================================================================
   PPC PAGE — Editorial brutalism
   ---------------------------------------------------------------------
   Hard rules, oversized numerals, paper / navy ground, single pink
   accent. Brand thread + scroll-reveal infrastructure is inherited
   from the homepage / SEO page (data-section reveal hooks).

   Type stack: Oceanwide for display, system body via theme defaults.
   Numerals: tabular for the section indices so they line up cleanly.
   ===================================================================== */

.hp-ppc {
	background: var(--color-paper);
	color: var(--color-primary);
	font-feature-settings: "ss01" on, "tnum" on;
}
.hp-ppc section { overflow-x: clip; position: relative; }
.hp-ppc img,
.hp-ppc svg { max-width: 100%; }

/* Buttons inherit the global pill radius (var(--radius-pill)) from .hp-btn.
   Do NOT square-off .hp-btn on a page; it must stay consistent site-wide.
   See docs/buttons.md. */

/* Kill the EB section cross-fade on this page — every section keeps its
   own static ground, no morph at the seam. */
.hp-ppc [data-eb-section].hp-eb-fading {
	background: none;
	color: inherit;
}
.hp-ppc [data-eb-section][data-eb-ground="saturated"].hp-eb-fading {
	background: var(--eb-ground-saturated);
	color: var(--eb-ink-on-saturated);
}
.hp-ppc [data-eb-section][data-eb-ground="light"].hp-eb-fading {
	background: var(--eb-ground-light);
	color: var(--eb-ink-on-light);
}

/* Full-width layout overrides (max-width: none on inners + flat 4rem
   horizontal padding on sections) live at the end of this block so they
   win the cascade against the per-section rules below. */

/* ---- Editorial masthead (sits above the hero) ---- */
.hp-ppc-masthead {
	display: flex;
	align-items: center;
	gap: clamp(0.75rem, 1.5vw, 1.25rem);
	padding: 0.9rem clamp(1.25rem, 4vw, 4rem);
	border-bottom: 1px solid var(--color-primary);
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: clamp(0.72rem, 0.95vw, 0.85rem);
	letter-spacing: 0.02em;
	color: var(--color-primary);
	background: var(--color-paper);
}
.hp-ppc-masthead__rule {
	flex: 1;
	min-width: 1.25rem;
	height: 1px;
	background: var(--color-primary);
}
@media (max-width: 640px) {
	.hp-ppc-masthead { flex-wrap: wrap; row-gap: 0.4rem; }
	.hp-ppc-masthead__rule { display: none; }
}

/* ---- Editorial byline strip (above a section body) ---- */
.hp-ppc-byline {
	max-width: 1280px;
	margin: 0 auto;
	padding: 0 clamp(1.25rem, 4vw, 4rem) clamp(1rem, 2vw, 1.5rem);
	display: flex;
	align-items: center;
	gap: 0.85rem;
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: 0.78rem;
	letter-spacing: 0.04em;
}
.hp-ppc-byline__sep {
	width: 1.5rem;
	height: 1px;
	background: currentColor;
	flex: 0 0 auto;
}

/* ---- Folio (bottom of every editorial section) ---- */
.hp-ppc-folio {
	max-width: 1280px;
	margin: clamp(3rem, 5vw, 4.5rem) auto 0;
	padding: 1rem clamp(1.25rem, 4vw, 4rem) 0;
	border-top: 1px solid currentColor;
	display: flex;
	align-items: center;
	gap: 1rem;
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: 0.78rem;
	letter-spacing: 0.06em;
	color: var(--color-primary);
}
.hp-ppc-folio--light { color: rgba(244,241,234,0.7); }
.hp-ppc-folio__num { font-size: 0.95rem; font-variant-numeric: tabular-nums; }
.hp-ppc-folio__sep { flex: 1; height: 1px; background: currentColor; opacity: 0.4; }

/* ---- Colophon (closing line at end of the issue) ---- */
.hp-ppc-colophon {
	margin: clamp(3rem, 5vw, 4.5rem) auto 0;
	padding-top: 2rem;
	border-top: 3px solid var(--color-primary);
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 1rem;
	flex-wrap: wrap;
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: 0.85rem;
	letter-spacing: 0.08em;
	color: var(--color-primary);
}
.hp-ppc-colophon__sep { width: 2rem; height: 2px; background: var(--color-accent); }

/* ---- Drop cap (editorial brutalism move) ---- */
.hp-ppc-dropcap::first-letter {
	font-family: var(--font-heading-family);
	font-weight: 900;
	float: left;
	font-size: 4.2em;
	line-height: 0.82;
	padding: 0.05em 0.18em 0 0;
	margin-top: 0.05em;
	color: var(--color-accent);
	letter-spacing: -0.04em;
}
.hp-ppc-dropcap--light::first-letter { color: var(--color-accent); }

/* ---- Pull quote (massive hanging mark) ---- */
.hp-ppc-pullquote {
	position: relative;
	margin: clamp(2rem, 5vw, 3.5rem) 0;
	padding: 1.5rem 0 1rem clamp(2.5rem, 5vw, 4.5rem);
	border-left: 6px solid var(--color-accent);
}
.hp-ppc-pullquote__mark {
	position: absolute;
	top: -0.55em;
	left: -0.05em;
	font-family: var(--font-heading-family);
	font-weight: 900;
	font-size: clamp(7rem, 14vw, 12rem);
	line-height: 1;
	color: var(--color-accent);
	pointer-events: none;
	user-select: none;
}
.hp-ppc-pullquote__q {
	margin: 0 0 1rem;
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.5rem, 3.4vw, 2.75rem);
	line-height: 1.05;
	letter-spacing: -0.025em;
	color: var(--color-primary);
}
.hp-ppc-pullquote__a {
	margin: 0;
	font-size: 1rem;
	line-height: 1.6;
	max-width: 60ch;
	color: rgba(0,0,16,0.78);
}
.hp-ppc-pullquote--center {
	margin-left: auto;
	margin-right: auto;
	max-width: 760px;
	padding: 2rem 1rem;
	border-left: 0;
	text-align: center;
}
.hp-ppc-pullquote--center .hp-ppc-pullquote__mark {
	position: static;
	display: block;
	font-size: clamp(5rem, 10vw, 8rem);
	line-height: 0.6;
	margin-bottom: 0.5rem;
}
.hp-ppc-pullquote--center .hp-ppc-pullquote__q {
	font-size: clamp(1.5rem, 3vw, 2.25rem);
	margin-bottom: 1rem;
}

/* ---- Rotated section rail ---- */
.hp-ppc-vertical-rail {
	position: absolute;
	top: 50%;
	left: clamp(0.5rem, 1.5vw, 1.25rem);
	transform: translateY(-50%) rotate(180deg);
	writing-mode: vertical-rl;
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: 0.78rem;
	letter-spacing: 0.18em;
	color: rgba(244,241,234,0.55);
	pointer-events: none;
	user-select: none;
}
.hp-ppc-rail-vertical { display: none; }
@media (min-width: 901px) {
	.hp-ppc-rail-vertical {
		display: inline-block;
		writing-mode: vertical-rl;
		transform: rotate(180deg);
		margin-top: 2rem;
		font-family: var(--font-heading-family);
		font-weight: 700;
		font-size: 0.78rem;
		letter-spacing: 0.16em;
		color: rgba(0,0,16,0.5);
	}
}

/* ---- Multi-column editorial flow ---- */
.hp-ppc-columns {
	display: block !important;
	column-count: 3;
	column-gap: clamp(1.5rem, 3vw, 2.5rem);
	column-rule: 1px solid rgba(244,241,234,0.2);
}
.hp-ppc-columns > p { margin: 0 0 1rem; break-inside: avoid; }
@media (max-width: 900px) {
	.hp-ppc-columns { column-count: 1; }
}

/* Scroll-reveal hook (same pattern as the SEO page) */
.hp-ppc [data-section].is-pending .hp-ppc-hero__h1,
.hp-ppc [data-section].is-pending .hp-ppc-hero__answer,
.hp-ppc [data-section].is-pending .hp-ppc-hero__actions,
.hp-ppc [data-section].is-pending .hp-ppc-hero__badges,
.hp-ppc [data-section].is-pending .hp-ppc-mani__body > *,
.hp-ppc [data-section].is-pending .hp-ppc-google__head,
.hp-ppc [data-section].is-pending .hp-ppc-tile,
.hp-ppc [data-section].is-pending .hp-ppc-meta__body > *,
.hp-ppc [data-section].is-pending .hp-ppc-meta__rail > *,
.hp-ppc [data-section].is-pending .hp-ppc-business__head > *,
.hp-ppc [data-section].is-pending .hp-ppc-business__pull,
.hp-ppc [data-section].is-pending .hp-ppc-pillar,
.hp-ppc [data-section].is-pending .hp-ppc-loc__head > *,
.hp-ppc [data-section].is-pending .hp-ppc-loc__row,
.hp-ppc [data-section].is-pending .hp-ppc-cta > * {
	opacity: 0;
	transform: translateY(24px);
	transition: opacity 0.7s ease, transform 0.7s ease;
}
.hp-ppc [data-section].is-visible .hp-ppc-hero__h1,
.hp-ppc [data-section].is-visible .hp-ppc-hero__answer,
.hp-ppc [data-section].is-visible .hp-ppc-hero__actions,
.hp-ppc [data-section].is-visible .hp-ppc-hero__badges,
.hp-ppc [data-section].is-visible .hp-ppc-mani__body > *,
.hp-ppc [data-section].is-visible .hp-ppc-google__head,
.hp-ppc [data-section].is-visible .hp-ppc-tile,
.hp-ppc [data-section].is-visible .hp-ppc-meta__body > *,
.hp-ppc [data-section].is-visible .hp-ppc-meta__rail > *,
.hp-ppc [data-section].is-visible .hp-ppc-business__head > *,
.hp-ppc [data-section].is-visible .hp-ppc-business__pull,
.hp-ppc [data-section].is-visible .hp-ppc-pillar,
.hp-ppc [data-section].is-visible .hp-ppc-loc__head > *,
.hp-ppc [data-section].is-visible .hp-ppc-loc__row,
.hp-ppc [data-section].is-visible .hp-ppc-cta > * {
	opacity: 1;
	transform: none;
}
.hp-ppc [data-section].is-visible .hp-ppc-tile:nth-child(1) { transition-delay: 0.05s; }
.hp-ppc [data-section].is-visible .hp-ppc-tile:nth-child(2) { transition-delay: 0.12s; }
.hp-ppc [data-section].is-visible .hp-ppc-tile:nth-child(3) { transition-delay: 0.19s; }
.hp-ppc [data-section].is-visible .hp-ppc-tile:nth-child(4) { transition-delay: 0.26s; }
.hp-ppc [data-section].is-visible .hp-ppc-tile:nth-child(5) { transition-delay: 0.33s; }
.hp-ppc [data-section].is-visible .hp-ppc-pillar:nth-child(1) { transition-delay: 0.05s; }
.hp-ppc [data-section].is-visible .hp-ppc-pillar:nth-child(2) { transition-delay: 0.15s; }
.hp-ppc [data-section].is-visible .hp-ppc-pillar:nth-child(3) { transition-delay: 0.25s; }
.hp-ppc [data-section].is-visible .hp-ppc-loc__row:nth-child(1)  { transition-delay: 0.04s; }
.hp-ppc [data-section].is-visible .hp-ppc-loc__row:nth-child(2)  { transition-delay: 0.08s; }
.hp-ppc [data-section].is-visible .hp-ppc-loc__row:nth-child(3)  { transition-delay: 0.12s; }
.hp-ppc [data-section].is-visible .hp-ppc-loc__row:nth-child(4)  { transition-delay: 0.16s; }
.hp-ppc [data-section].is-visible .hp-ppc-loc__row:nth-child(5)  { transition-delay: 0.20s; }
.hp-ppc [data-section].is-visible .hp-ppc-loc__row:nth-child(6)  { transition-delay: 0.24s; }
.hp-ppc [data-section].is-visible .hp-ppc-loc__row:nth-child(7)  { transition-delay: 0.28s; }
.hp-ppc [data-section].is-visible .hp-ppc-loc__row:nth-child(8)  { transition-delay: 0.32s; }
.hp-ppc [data-section].is-visible .hp-ppc-loc__row:nth-child(9)  { transition-delay: 0.36s; }
.hp-ppc [data-section].is-visible .hp-ppc-loc__row:nth-child(10) { transition-delay: 0.40s; }

/* ---- Shared editorial primitives ---- */
.hp-ppc-eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	margin: 0 0 1.5rem;
	font-family: var(--font-body-family);
	font-size: 0.825rem;
	font-weight: 600;
	letter-spacing: 0.04em;
	color: var(--color-primary);
}
.hp-ppc-eyebrow--light { color: var(--color-paper); }
.hp-ppc-eyebrow__sq {
	width: 0.55rem;
	height: 0.55rem;
	background: var(--color-accent);
	display: inline-block;
}

.hp-ppc-h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.25rem, 5.4vw, 4.5rem);
	line-height: 0.98;
	letter-spacing: -0.025em;
	margin: 0 0 1.5rem;
}
.hp-ppc-h2--center { text-align: center; }

.hp-ppc-num {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(6rem, 18vw, 16rem);
	line-height: 0.82;
	letter-spacing: -0.04em;
	color: transparent;
	-webkit-text-stroke: 2px currentColor;
	display: block;
	font-variant-numeric: tabular-nums;
}
.hp-ppc-num--pink { -webkit-text-stroke-color: var(--color-accent); color: transparent; }

.hp-ppc-rail-label {
	display: block;
	margin-top: 1rem;
	font-family: var(--font-body-family);
	font-size: 0.78rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	color: rgba(0,0,16,0.55);
}

.hp-ppc-watermark {
	position: absolute;
	top: 1.6rem;
	right: clamp(1rem, 4vw, 3.5rem);
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(8rem, 22vw, 22rem);
	line-height: 1;
	letter-spacing: -0.05em;
	color: transparent;
	-webkit-text-stroke: 1.5px rgba(244,241,234,0.18);
	pointer-events: none;
	user-select: none;
	font-variant-numeric: tabular-nums;
}

.hp-ppc-link {
	display: inline-flex;
	align-items: center;
	gap: 0.75rem;
	padding: 0.4rem 0;
	border-bottom: 2px solid currentColor;
	font-family: var(--font-body-family);
	font-weight: 600;
	font-size: 1rem;
	color: var(--color-primary);
	text-decoration: none;
	transition: gap 0.25s ease, color 0.25s ease;
}
.hp-ppc-link:hover,
.hp-ppc-link:focus-visible { gap: 1.1rem; color: var(--color-accent); }
.hp-ppc-link__arrow { font-size: 1.05em; }

.hp-ppc-section--dark {
	background: var(--color-primary);
	color: var(--color-paper);
}
.hp-ppc-section--dark .hp-ppc-link { color: var(--color-paper); }

/* ---- HERO ---- */
.hp-ppc-hero {
	position: relative;
	padding: clamp(4rem, 8vw, 6rem) clamp(1.25rem, 4vw, 4rem) clamp(5rem, 9vw, 7rem);
	border-bottom: 3px solid var(--color-primary);
}
.hp-ppc-hero .hp-eb-hero__lead {
	max-width: 45ch;
}

/* Three hero taglines that animate the same way as the homepage outro
   ("Real work. / Real results. / No filters."): a single pink highlight
   sweeps through the lines and rests on the last. The outro is scroll-
   driven, but this block lives in the hero (above the fold on load) so
   we drive it with a time-based @keyframe instead — @property registers
   `--active` as a number so it interpolates cleanly. Reuses
   .hp-outro__sequence + .hp-outro__line so the colour formula stays in
   one place. */
@property --active {
	syntax: '<number>';
	inherits: true;
	initial-value: -1;
}
.hp-ppc-hero__taglines {
	margin: clamp(1.5rem, 3.5vw, 2.5rem) 0 clamp(2rem, 4vw, 3rem);
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.75rem, 4vw, 3rem);
	line-height: 1.05;
	letter-spacing: -0.02em;
	--active: -1;
	animation: hp-ppc-tagline-sweep 2.2s 0.4s ease-out forwards;
}
@keyframes hp-ppc-tagline-sweep {
	from { --active: -1; }
	to   { --active: 2; }
}
/* Note: deliberately NOT gated on prefers-reduced-motion — HP animations
   are brand content and play for everyone. */
.hp-ppc-hero__rail {
	position: absolute;
	top: clamp(4.5rem, 9vw, 7rem);
	left: clamp(1.25rem, 3vw, 3rem);
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	pointer-events: none;
}
.hp-ppc-hero__rail-num {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.5rem, 4.5vw, 4rem);
	line-height: 1;
	color: transparent;
	-webkit-text-stroke: 1.5px rgba(0,0,16,0.4);
	letter-spacing: -0.04em;
	font-variant-numeric: tabular-nums;
}
.hp-ppc-hero__rail-label {
	margin-top: 0.5rem;
	font-size: 0.72rem;
	font-weight: 600;
	letter-spacing: 0.1em;
	color: rgba(0,0,16,0.45);
	writing-mode: horizontal-tb;
}
.hp-ppc-hero__inner {
	max-width: 1280px;
	margin: 0 auto;
	padding-left: clamp(0px, 6vw, 6.5rem);
}

.hp-ppc-hero__h1 {
	font-family: var(--font-heading-family);
	font-weight: 900;
	font-size: clamp(3rem, 11vw, 10.5rem);
	line-height: 0.88;
	letter-spacing: -0.045em;
	margin: 0;
}
.hp-ppc-hero__line { display: block; }
.hp-ppc-hero__line--tail {
	font-style: italic;
	font-weight: 700;
	font-size: 0.78em;
	margin-top: 0.25rem;
	color: rgba(0,0,16,0.7);
}
.hp-ppc-hero__mark {
	position: relative;
	display: inline-block;
	padding: 0 0.2em;
}
.hp-ppc-hero__mark-bg {
	position: absolute;
	inset: 0.18em 0 0.12em;
	background: var(--color-accent);
	z-index: 0;
	transform: skewX(-6deg);
	box-shadow: 8px 8px 0 var(--color-primary);
}
.hp-ppc-hero__mark-text {
	position: relative;
	z-index: 1;
	color: var(--color-paper);
}

.hp-ppc-hero__answer {
	margin: clamp(2rem, 4vw, 3.5rem) 0 0;
	display: grid;
	grid-template-columns: 1fr;
	gap: 1.5rem;
	max-width: 56ch;
}
.hp-ppc-hero__lead {
	font-size: clamp(1.125rem, 1.5vw, 1.375rem);
	line-height: 1.55;
	margin: 0;
}
.hp-ppc-hero__triplet {
	display: flex;
	flex-wrap: wrap;
	gap: 1.5rem;
	margin: 0;
	padding: 1rem 0 0;
	border-top: 1px solid rgba(0,0,16,0.18);
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.1rem, 1.8vw, 1.5rem);
	letter-spacing: -0.01em;
}
.hp-ppc-hero__triplet span:not(:last-child)::after {
	content: '';
	display: inline-block;
	width: 0.45rem;
	height: 0.45rem;
	background: var(--color-accent);
	margin-left: 1.4rem;
	transform: translateY(-0.2em);
}

.hp-ppc-hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 1rem;
	margin: clamp(2rem, 4vw, 3rem) 0 0;
}

.hp-ppc-hero__badges {
	margin: clamp(3rem, 6vw, 4.5rem) 0 0;
	padding-top: 2rem;
	border-top: 2px solid var(--color-primary);
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
	gap: clamp(1.25rem, 3vw, 2.5rem);
}
.hp-ppc-hero__badge { display: flex; flex-direction: column; gap: 0.25rem; }
.hp-ppc-hero__badge dt {
	font-size: 0.72rem;
	font-weight: 600;
	letter-spacing: 0.12em;
	color: rgba(0,0,16,0.55);
}
.hp-ppc-hero__badge dd {
	margin: 0;
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: 1.25rem;
	letter-spacing: -0.005em;
	color: var(--color-primary);
}

/* ---- MARQUEE ---- */
.hp-ppc-marquee {
	background: var(--color-accent);
	color: var(--color-primary);
	border-top: 3px solid var(--color-primary);
	border-bottom: 3px solid var(--color-primary);
	overflow: hidden;
}
.hp-ppc-marquee__track {
	display: flex;
	gap: 2.5rem;
	align-items: center;
	padding: 1.4rem 0;
	width: max-content;
	animation: hpPpcMarquee 32s linear infinite;
	font-family: var(--font-heading-family);
	font-weight: 900;
	font-size: clamp(1.75rem, 4vw, 3rem);
	letter-spacing: -0.02em;
	text-transform: none;
}
.hp-ppc-marquee__word { white-space: nowrap; }
.hp-ppc-marquee__sep {
	display: inline-block;
	width: 0.8em;
	height: 0.8em;
	background: var(--color-primary);
	font-size: 0;
	transform: rotate(45deg);
	margin: 0 0.25em;
}
@keyframes hpPpcMarquee {
	from { transform: translate3d(0, 0, 0); }
	to   { transform: translate3d(-50%, 0, 0); }
}

/* ---- MANIFESTO (section 01) ---- */
.hp-ppc-mani {
	padding: clamp(4rem, 7vw, 6rem) clamp(1.25rem, 4vw, 4rem) clamp(5rem, 9vw, 7rem);
	border-bottom: 3px solid var(--color-primary);
}
.hp-ppc-mani > .hp-ppc-byline {
	border-top: 0;
	border-bottom: 1px solid var(--color-primary);
	padding-top: 0;
	padding-bottom: clamp(1.5rem, 3vw, 2.5rem);
	margin-bottom: clamp(2rem, 4vw, 3rem);
}
.hp-ppc-mani__inner {
	max-width: 1280px;
	margin: 0 auto;
	display: grid;
	grid-template-columns: minmax(180px, 22%) 1fr;
	gap: clamp(2rem, 5vw, 5rem);
	align-items: start;
}
.hp-ppc-mani__rail {
	position: sticky;
	top: 7rem;
	display: block;
}
.hp-ppc-mani__rail .hp-ppc-num { color: transparent; -webkit-text-stroke-color: var(--color-primary); }

.hp-ppc-mani__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.5rem, 6vw, 5rem);
	line-height: 0.98;
	letter-spacing: -0.03em;
	margin: 0 0 2rem;
	max-width: 18ch;
}
.hp-ppc-mani__lead {
	font-size: clamp(1.0625rem, 1.4vw, 1.25rem);
	line-height: 1.6;
	margin: 0 0 2rem;
	max-width: 60ch;
}

.hp-ppc-callout {
	border-left: 4px solid var(--color-accent);
	padding: 1.25rem 0 1.25rem 1.5rem;
	margin: 2rem 0;
}
.hp-ppc-callout__q {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.4rem, 2.6vw, 2.25rem);
	line-height: 1.15;
	letter-spacing: -0.02em;
	margin: 0 0 0.75rem;
	color: var(--color-primary);
}
.hp-ppc-callout__a {
	margin: 0;
	font-size: 1rem;
	line-height: 1.6;
	max-width: 60ch;
	color: rgba(0,0,16,0.78);
}

.hp-ppc-mani__close {
	font-size: 1rem;
	line-height: 1.6;
	margin: 0 0 2rem;
	max-width: 60ch;
	color: rgba(0,0,16,0.78);
}
.hp-ppc-mani__cta { margin: 0; }

/* ---- GOOGLE (section 02) ---- */
.hp-ppc-google {
	padding: clamp(6rem, 12vw, 9rem) clamp(1.25rem, 4vw, 4rem);
}
.hp-ppc-google__inner {
	max-width: 1280px;
	margin: 0 auto;
	position: relative;
	z-index: 1;
}
.hp-ppc-google__head {
	max-width: 78ch;
	margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
.hp-ppc-google__head .hp-ppc-h2 { color: var(--color-paper); max-width: 22ch; }
.hp-ppc-google__paras {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 1.5rem;
	margin-top: 2rem;
}
.hp-ppc-google__paras p {
	margin: 0;
	font-size: 1rem;
	line-height: 1.65;
	color: rgba(244,241,234,0.82);
}

.hp-ppc-google__grid {
	margin: 0;
	padding: 0;
	list-style: none;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
	border-top: 2px solid rgba(244,241,234,0.85);
	border-left: 2px solid rgba(244,241,234,0.85);
}
.hp-ppc-tile {
	padding: clamp(1.5rem, 2vw, 2rem);
	border-right: 2px solid rgba(244,241,234,0.85);
	border-bottom: 2px solid rgba(244,241,234,0.85);
	background: transparent;
	transition: none;
	position: relative;
	cursor: pointer;
}
.hp-ppc-tile:hover { background: var(--color-accent); }
.hp-ppc-tile:hover .hp-ppc-tile__index { color: var(--color-primary); }
.hp-ppc-tile:hover .hp-ppc-tile__title,
.hp-ppc-tile:hover .hp-ppc-tile__copy { color: var(--color-paper); }
.hp-ppc-tile::before {
	content: '';
	position: absolute;
	inset: 0;
	border: 0 solid var(--color-accent);
	pointer-events: none;
	transition: none;
}
.hp-ppc-tile:hover::before { border-width: 2px; }
.hp-ppc-tile__index {
	display: block;
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: 0.85rem;
	letter-spacing: 0.08em;
	color: var(--color-accent);
	margin-bottom: 1.25rem;
	font-variant-numeric: tabular-nums;
}
.hp-ppc-tile__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.25rem, 1.8vw, 1.625rem);
	line-height: 1.1;
	letter-spacing: -0.015em;
	margin: 0 0 0.75rem;
	color: var(--color-paper);
}
.hp-ppc-tile__copy {
	margin: 0;
	font-size: 0.95rem;
	line-height: 1.55;
	color: rgba(244,241,234,0.7);
}

.hp-ppc-google__foot {
	margin-top: clamp(2.5rem, 5vw, 4rem);
	display: flex;
	justify-content: flex-start;
}

/* ---- META (section 03) ---- */
.hp-ppc-meta {
	padding: clamp(5rem, 10vw, 8rem) clamp(1.25rem, 4vw, 4rem);
	border-bottom: 3px solid var(--color-primary);
}
.hp-ppc-meta__inner {
	max-width: 1280px;
	margin: 0 auto;
	display: grid;
	grid-template-columns: 1fr 1px 1fr;
	gap: clamp(1.5rem, 3vw, 3rem);
	align-items: start;
}
.hp-ppc-meta__inner::before {
	content: '';
	grid-column: 2;
	background: var(--color-accent);
	width: 1px;
	height: 100%;
	min-height: 320px;
}
.hp-ppc-meta__body { grid-column: 1; padding-right: clamp(0px, 2vw, 1.5rem); }
.hp-ppc-meta__rail { grid-column: 3; padding-left: clamp(0px, 2vw, 1.5rem); }

.hp-ppc-meta__paras > p {
	margin: 0 0 1.25rem;
	font-size: 1.0625rem;
	line-height: 1.65;
	max-width: 50ch;
}
.hp-ppc-meta__cta { margin-top: 1.5rem; }

.hp-ppc-meta__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2rem, 4.4vw, 3.75rem);
	line-height: 0.98;
	letter-spacing: -0.025em;
	margin: 0.5rem 0 0;
	max-width: 18ch;
}

.hp-ppc-stamp {
	max-width: 1280px;
	margin: clamp(3rem, 6vw, 5rem) auto 0;
	display: flex;
	align-items: center;
	gap: 1.25rem;
	font-family: var(--font-body-family);
	font-size: 0.78rem;
	font-weight: 600;
	letter-spacing: 0.12em;
	color: rgba(0,0,16,0.55);
}
.hp-ppc-stamp__rule {
	flex: 1;
	height: 1px;
	background: rgba(0,0,16,0.18);
}

/* ---- BUSINESS (section 04) ---- */
.hp-ppc-business {
	padding: clamp(6rem, 11vw, 9rem) clamp(1.25rem, 4vw, 4rem);
	border-bottom: 3px solid var(--color-primary);
}
.hp-ppc-business__inner {
	max-width: 1100px;
	margin: 0 auto;
	text-align: center;
}
.hp-ppc-business__head .hp-ppc-eyebrow { justify-content: center; }
.hp-ppc-business__pull {
	margin: clamp(2rem, 5vw, 3.5rem) auto;
	max-width: 60ch;
}
.hp-ppc-business__pull p {
	margin: 0 0 1rem;
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-size: clamp(1.25rem, 2vw, 1.625rem);
	line-height: 1.35;
	letter-spacing: -0.01em;
}
.hp-ppc-business__pull-end {
	font-style: italic;
	color: var(--color-accent);
}

.hp-ppc-business__grid {
	list-style: none;
	margin: 0 0 clamp(2rem, 5vw, 3.5rem);
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
	gap: 0;
	border-top: 2px solid var(--color-primary);
	border-bottom: 2px solid var(--color-primary);
	text-align: left;
}
.hp-ppc-pillar {
	padding: clamp(1.75rem, 3vw, 2.5rem);
	border-right: 1px solid rgba(0,0,16,0.12);
	position: relative;
}
.hp-ppc-pillar:last-child { border-right: 0; }
.hp-ppc-pillar__mark {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.4rem;
	height: 2.4rem;
	background: var(--color-primary);
	color: var(--color-paper);
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: 1.05rem;
	margin-bottom: 1.25rem;
}
.hp-ppc-pillar__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.25rem, 1.8vw, 1.5rem);
	margin: 0 0 0.5rem;
	letter-spacing: -0.015em;
}
.hp-ppc-pillar__copy {
	margin: 0;
	font-size: 0.975rem;
	line-height: 1.55;
	color: rgba(0,0,16,0.72);
}
.hp-ppc-business__cta { margin: 0; }

/* ---- LOCATIONS (section 05) ---- */
.hp-ppc-loc {
	padding: clamp(6rem, 12vw, 9rem) clamp(1.25rem, 4vw, 4rem);
}
.hp-ppc-loc__inner {
	max-width: 1280px;
	margin: 0 auto;
	position: relative;
	z-index: 1;
}
.hp-ppc-loc__head {
	max-width: 72ch;
	margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
.hp-ppc-loc__head .hp-ppc-h2 { color: var(--color-paper); max-width: 22ch; }
.hp-ppc-loc__lead {
	font-size: 1.0625rem;
	line-height: 1.65;
	color: rgba(244,241,234,0.8);
	margin: 1.5rem 0 0;
	max-width: 60ch;
}

.hp-ppc-loc__list {
	list-style: none;
	margin: 0;
	padding: 0;
	border-top: 1px solid rgba(244,241,234,0.2);
}
.hp-ppc-loc__row {
	display: grid;
	grid-template-columns: minmax(180px, 28%) 1fr minmax(180px, 28%);
	align-items: baseline;
	gap: 1rem;
	padding: 1.1rem 0;
	border-bottom: 1px solid rgba(244,241,234,0.2);
	transition: color 0.25s ease;
}
.hp-ppc-loc__row:hover { color: var(--color-accent-light); }
.hp-ppc-loc__city {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.5rem, 3vw, 2.5rem);
	line-height: 1;
	letter-spacing: -0.02em;
	color: var(--color-paper);
}
.hp-ppc-loc__row.is-hq .hp-ppc-loc__city { color: var(--color-accent); }
.hp-ppc-loc__leader {
	height: 1px;
	background: rgba(244,241,234,0.25);
	align-self: center;
}
.hp-ppc-loc__role {
	font-size: 0.85rem;
	font-weight: 600;
	letter-spacing: 0.06em;
	color: rgba(244,241,234,0.6);
	text-align: right;
}
.hp-ppc-loc__foot {
	margin-top: clamp(2.5rem, 5vw, 4rem);
}

/* ---- FINAL CTA ---- */
.hp-ppc-cta {
	padding: clamp(6rem, 12vw, 10rem) clamp(1.25rem, 4vw, 4rem);
	text-align: center;
	border-top: 3px solid var(--color-primary);
	position: relative;
}
.hp-ppc-cta__watermark {
	position: absolute;
	bottom: -0.18em;
	right: clamp(1rem, 4vw, 3rem);
	font-family: var(--font-heading-family);
	font-weight: 900;
	font-size: clamp(10rem, 32vw, 32rem);
	line-height: 0.78;
	letter-spacing: -0.06em;
	color: transparent;
	-webkit-text-stroke: 2px rgba(0,0,16,0.08);
	pointer-events: none;
	user-select: none;
	font-variant-numeric: tabular-nums;
}
.hp-ppc-cta__inner {
	max-width: 880px;
	margin: 0 auto;
	position: relative;
	z-index: 1;
}
.hp-ppc-cta .hp-ppc-eyebrow { justify-content: center; }
.hp-ppc-cta__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.5rem, 6.5vw, 5.5rem);
	line-height: 0.98;
	letter-spacing: -0.03em;
	margin: 0 0 1.5rem;
}
.hp-ppc-cta__body {
	font-size: clamp(1rem, 1.3vw, 1.125rem);
	line-height: 1.65;
	margin: 0 auto 1.5rem;
	max-width: 60ch;
	color: rgba(0,0,16,0.78);
}
.hp-ppc-cta__kicker {
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: clamp(1.1rem, 1.8vw, 1.5rem);
	letter-spacing: -0.01em;
	color: var(--color-accent);
	margin: 0 0 2rem;
}
.hp-ppc-cta__actions {
	display: flex;
	gap: 1rem;
	justify-content: center;
	flex-wrap: wrap;
}

/* ---- Mobile ---- */
@media (max-width: 900px) {
	.hp-ppc-hero__inner { padding-left: 0; }
	.hp-ppc-hero__rail {
		position: static;
		flex-direction: row;
		align-items: baseline;
		gap: 0.85rem;
		margin-bottom: 1.25rem;
	}
	.hp-ppc-hero__rail-num { font-size: 2rem; }
	.hp-ppc-hero__rail-label { margin-top: 0; }

	.hp-ppc-mani__inner { grid-template-columns: 1fr; }
	.hp-ppc-mani__rail { position: static; display: flex; align-items: baseline; gap: 1rem; }
	.hp-ppc-mani__rail .hp-ppc-num { font-size: 4.5rem; }

	.hp-ppc-meta__inner {
		grid-template-columns: 1fr;
	}
	.hp-ppc-meta__inner::before { display: none; }
	.hp-ppc-meta__body,
	.hp-ppc-meta__rail { grid-column: 1; padding: 0; }
	.hp-ppc-meta__rail { margin-top: 2rem; padding-top: 2rem; border-top: 2px solid var(--color-accent); }

	.hp-ppc-loc__row {
		grid-template-columns: 1fr;
		gap: 0.25rem;
	}
	.hp-ppc-loc__leader { display: none; }
	.hp-ppc-loc__role { text-align: left; }

	.hp-ppc-watermark {
		font-size: 8rem;
		top: 1rem;
		right: 1rem;
	}
}

/* Full-width layout: flat 4rem horizontal padding on every PPC section,
   no boxed inner container. Uses padding-inline so the per-section
   vertical padding (clamp ...) is preserved. Sits after the per-section
   rules so the cascade wins. */
.hp-ppc .hp-ppc-masthead,
.hp-ppc-hero,
.hp-ppc-mani,
.hp-ppc-google,
.hp-ppc-meta,
.hp-ppc-business,
.hp-ppc-loc,
.hp-ppc-cta {
	padding-inline: 4rem;
}
.hp-ppc-hero__inner,
.hp-ppc-mani__inner,
.hp-ppc-google__inner,
.hp-ppc-meta__inner,
.hp-ppc-business__inner,
.hp-ppc-loc__inner,
.hp-ppc-cta__inner,
.hp-ppc-byline,
.hp-ppc-folio,
.hp-ppc-stamp,
.hp-ppc-colophon {
	max-width: none;
	margin-inline: 0;
	padding-inline: 0;
}

/* Mobile taper — flat 4rem (64px) leaves no room on a 375px viewport.
   Drop to 1.25rem so content stays readable without changing the boxed
   → fullwidth intent. */
@media (max-width: 640px) {
	.hp-ppc .hp-ppc-masthead,
	.hp-ppc-hero,
	.hp-ppc-mani,
	.hp-ppc-google,
	.hp-ppc-meta,
	.hp-ppc-business,
	.hp-ppc-loc,
	.hp-ppc-cta {
		padding-inline: 1.25rem;
	}
}

/* PPC hero — two-column layout (image | copy). The thread channel is
   collapsed so columns sit edge-to-edge: col 1 = image, col 2 = H1 +
   lead + buttons. Mobile keeps the stacked layout from the base
   hp-eb-hero rule (media gets order: -1, so image stays on top). */
@media (min-width: 1025px) {
	.hp-ppc-hero .hp-eb-hero__inner {
		grid-template-columns:
			minmax(0, 1fr)
			minmax(0, 1.2fr);
		grid-template-rows: auto;
		column-gap: clamp(2rem, 4vw, 4rem);
		align-items: start;
	}
	/* Explicit row + column placement on both items so neither can be
	   auto-flowed onto row 2 — the empty channel div was claiming col 1
	   before display:none kicked in for the layout pass. */
	.hp-ppc-hero .hp-eb-hero__media {
		grid-column: 1;
		grid-row: 1;
		margin-top: 0;
		align-self: start;
	}
	.hp-ppc-hero .hp-eb-hero__copy {
		grid-column: 2;
		grid-row: 1;
	}
	/* The reserved thread channel collapses on this hero — no longer a
	   layout track. !important to win against any later rule that
	   un-hides it for animation reveals. */
	.hp-ppc-hero .hp-eb-hero__channel {
		display: none !important;
	}
}

/* =====================================================================
   PPC — Editorial-brutalism layout overrides per section.
   The five body sections now each adopt a different EB LIB pattern,
   reusing the shared .hp-eb-* primitives. This block holds only the
   per-section nudges (numeric eyebrows, pull-quotes, list spines)
   that are not already covered by the canonical EB chassis.
   ===================================================================== */

/* Reset the legacy magazine-slab 3px navy separators between body
   sections — the new EB chassis handles seam rhythm via grounds, no
   hard rule needed. */
.hp-ppc-mani,
.hp-ppc-google,
.hp-ppc-meta,
.hp-ppc-business,
.hp-ppc-loc {
	border-bottom: 0;
}

/* Reveal anchors for the new EB-class subtrees on the PPC page. The
   legacy reveal list (around line 5040) targets the old per-section
   classes; we add the new EB-class anchors so each section still fades
   in cleanly when [data-section] flips to .is-visible. */
.hp-ppc [data-section].is-pending .hp-eb-approach__head,
.hp-ppc [data-section].is-pending .hp-eb-approach__list > *:not(.hp-eb-spine),
.hp-ppc [data-section].is-pending .hp-eb-split__h2,
.hp-ppc [data-section].is-pending .hp-eb-split__grid > *,
.hp-ppc [data-section].is-pending .hp-eb-grid3__h2,
.hp-ppc [data-section].is-pending .hp-eb-grid3__row > *,
.hp-ppc [data-section].is-pending .hp-eb-cases__pull,
.hp-ppc [data-section].is-pending .hp-ppc-loc__bracket {
	opacity: 0;
	transform: translateY(24px);
	transition: opacity 0.7s ease, transform 0.7s ease;
}
.hp-ppc [data-section].is-visible .hp-eb-approach__head,
.hp-ppc [data-section].is-visible .hp-eb-approach__list > *:not(.hp-eb-spine),
.hp-ppc [data-section].is-visible .hp-eb-split__h2,
.hp-ppc [data-section].is-visible .hp-eb-split__grid > *,
.hp-ppc [data-section].is-visible .hp-eb-grid3__h2,
.hp-ppc [data-section].is-visible .hp-eb-grid3__row > *,
.hp-ppc [data-section].is-visible .hp-eb-cases__pull,
.hp-ppc [data-section].is-visible .hp-ppc-loc__bracket {
	opacity: 1;
	transform: none;
}
.hp-ppc [data-section].is-visible .hp-eb-grid3__row > *:nth-child(1) { transition-delay: 0.05s; }
.hp-ppc [data-section].is-visible .hp-eb-grid3__row > *:nth-child(2) { transition-delay: 0.15s; }
.hp-ppc [data-section].is-visible .hp-eb-grid3__row > *:nth-child(3) { transition-delay: 0.25s; }
.hp-ppc [data-section].is-visible .hp-eb-approach__list > *:nth-child(2) { transition-delay: 0.05s; }
.hp-ppc [data-section].is-visible .hp-eb-approach__list > *:nth-child(3) { transition-delay: 0.10s; }
.hp-ppc [data-section].is-visible .hp-eb-approach__list > *:nth-child(4) { transition-delay: 0.15s; }
.hp-ppc [data-section].is-visible .hp-eb-approach__list > *:nth-child(5) { transition-delay: 0.20s; }
.hp-ppc [data-section].is-visible .hp-eb-approach__list > *:nth-child(6) { transition-delay: 0.25s; }
.hp-ppc [data-section].is-visible .hp-eb-approach__list > *:nth-child(7) { transition-delay: 0.30s; }

/* ---------- Section 1 — Manifesto (LIB-03 editorial body block) ----- */
/* Override the legacy .hp-ppc-mani 3-column grid (rail / title / lead /
   close) from earlier design — the new mani uses .hp-eb-prose__inner
   which is a clean 2-column grid (head / body). */
.hp-ppc-mani.hp-eb-prose .hp-eb-prose__inner {
	grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.2fr);
	column-gap: clamp(2rem, 6vw, 6rem);
}
.hp-ppc-mani__head {
	display: flex;
	flex-direction: column;
	gap: clamp(1.25rem, 2.5vw, 2rem);
	min-width: 0;
}
/* .hp-ppc-mani__eyebrow ("01 / The point of paid media") removed per user
   request — the H2 now leads the section directly. The ppc_mani_eyebrow SCF
   field is retained (marked unused in its label) so no saved content is lost
   if the eyebrow is ever restored. */
.hp-ppc-mani__pull {
	position: relative;
	margin: clamp(1rem, 2vw, 1.75rem) 0 0;
	padding: clamp(1.25rem, 2vw, 1.75rem) 0 clamp(1.25rem, 2vw, 1.75rem) clamp(1.5rem, 3vw, 2.25rem);
	border-left: 4px solid var(--color-accent);
}
.hp-ppc-mani__pull p {
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-style: italic;
	font-size: clamp(1.25rem, 2vw, 1.85rem);
	line-height: 1.25;
	letter-spacing: -0.01em;
	margin: 0;
	max-width: 22ch;
}
.hp-ppc-mani__pull-mark {
	position: absolute;
	left: clamp(0.5rem, 1vw, 0.75rem);
	top: -0.2em;
	font-family: var(--font-heading-family);
	font-weight: 900;
	font-size: clamp(3rem, 5vw, 5rem);
	line-height: 1;
	color: var(--color-accent);
	opacity: 0.7;
}
.hp-ppc-mani__body p {
	font-size: clamp(1rem, 1.2vw, 1.15rem);
	line-height: 1.7;
	max-width: 58ch;
	/* Belt-and-braces: the chassis .hp-eb-prose__body is a flex column whose
	   `gap` is the ONLY paragraph separation. A `p + p` margin-top used to sit
	   on top of that gap, stacking to ~2.8rem at desktop — the "huge space
	   between paragraphs" the user reported. Zeroing the margin here keeps the
	   gap as the single source of rhythm. */
	margin: 0;
}
/* Sits on top of the flex gap, so keep it modest — the combined separation
   before the CTA pill is gap + this value. Was clamp(2rem, 3vw, 2.5rem). */
.hp-ppc-mani__cta { margin-top: clamp(0.75rem, 1.4vw, 1.1rem) !important; }
@media (max-width: 1024px) {
	.hp-ppc-mani.hp-eb-prose .hp-eb-prose__inner { grid-template-columns: 1fr; }
}

/* ---------- Section 2 — Google Ads (live brand thread) -------------- */
/* The right-column list mirrors the wd-process "How We Work" pattern —
   numbered cream circles threaded by a live-computed pink brand thread
   that enters off-canvas left, curves down R=80, runs vertically through
   every circle's centre, then curves and exits left at the bottom (see
   wirePpcGoogleThread in main.js). Each circle lights up `.is-active`
   as the scroll-draw reaches it. */
.hp-ppc-google.hp-eb-approach {
	color: var(--color-paper);
	/* Position context for the absolute-positioned SVG thread, and
	   overflow visible so the path can extend off-canvas. Overrides the
	   global `.hp-ppc section { overflow-x: clip }` rule for this
	   section only — the thread enters and exits at x = -80. */
	position: relative;
	overflow: visible;
	overflow-x: visible;
}
.hp-ppc-google .hp-eb-approach__inner {
	grid-template-columns: minmax(0, 1fr) minmax(0, 0.95fr);
	column-gap: clamp(2.5rem, 6vw, 6rem);
}
.hp-ppc-google .hp-eb-approach__h2 {
	color: var(--color-paper);
	max-width: 18ch;
}
.hp-ppc-google__intro,
.hp-ppc-google__close {
	display: flex;
	flex-direction: column;
	gap: clamp(0.75rem, 1.4vw, 1.1rem);
}
.hp-ppc-google__close { margin-top: clamp(2rem, 3vw, 2.5rem); }
.hp-ppc-google .hp-eb-approach__lead {
	font-size: clamp(0.98rem, 1.15vw, 1.1rem);
	opacity: 0.85;
}
.hp-ppc-google__cta { margin-top: clamp(1.5rem, 2.5vw, 2rem) !important; }
.hp-ppc-google__list {
	/* The right column is just an eyebrow + the numbered phase list —
	   no editorial border rules needed. The thread is the visual spine. */
	padding-block: 0;
}
.hp-ppc-google__list-eyebrow {
	margin: 0 0 clamp(1.25rem, 2.4vw, 1.75rem) 0;
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: clamp(1.25rem, 4vw, 2rem);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	opacity: 0.7;
	/* Right-aligned so the brand thread's vertical run (which lives on
	   the LEFT edge of this column, threading the numbered circles) has
	   a clear lane and never collides with the eyebrow text. */
	text-align: right;
}
.hp-ppc-google__phases {
	list-style: none;
	margin: 0;
	/* Top pad lets the R=80 entry corner land above circle 1. */
	padding: clamp(1.5rem, 3vw, 2.25rem) 0 0;
	display: flex;
	flex-direction: column;
	/* Bumped per user — was clamp(2rem, 3.5vw, 3rem). Larger circles
	   need a bit more breathing room between phases. */
	gap: clamp(2.75rem, 4.5vw, 4rem);
}
.hp-ppc-google__phase {
	display: grid;
	/* Numbered circle column + name column. The circle column width =
	   circle diameter so every circle's centre aligns on the same x —
	   the thread's vertical run sits exactly on that line. Bumped per
	   user — was clamp(2.75rem, 3vw, 3.5rem). */
	grid-template-columns: clamp(3.5rem, 4vw, 4.5rem) minmax(0, 1fr);
	column-gap: clamp(1.5rem, 2.5vw, 2.25rem);
	align-items: center;
}
.hp-ppc-google__num {
	/* Bumped per user — larger circles with larger numerals inside.
	   Was width/height clamp(2.75rem, 3vw, 3.5rem) and font-size
	   clamp(1.5rem, 1.8vw, 2rem). */
	width:  clamp(3.5rem, 4vw, 4.5rem);
	height: clamp(3.5rem, 4vw, 4.5rem);
	border-radius: 50%;
	background: var(--color-paper);
	color: var(--color-primary);
	display: grid;
	place-items: center;
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2rem, 2.4vw, 2.75rem);
	line-height: 1;
	padding-block-start: 0.08em;
	position: relative;
	z-index: 2;
	/* Navy ring around the circle visually CUTS the pink thread at the
	   circle edge — same trick wd-process uses on saturated ground. */
	box-shadow: 0 0 0 6px var(--color-primary);
	transition:
		transform   0.45s cubic-bezier(0.34, 1.56, 0.64, 1),
		box-shadow  0.45s cubic-bezier(0.34, 1.56, 0.64, 1),
		background  0.45s cubic-bezier(0.2,  0.7,  0.2,  1),
		color       0.45s cubic-bezier(0.2,  0.7,  0.2,  1);
}
.hp-ppc-google__name {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.35rem, 2.1vw, 2rem);
	line-height: 1.1;
	letter-spacing: -0.015em;
	margin: 0;
	color: var(--color-paper);
	/* Rest state — dimmed and slightly offset so the .is-active reveal
	   (thread reaches the circle) is visible. */
	opacity: 0.35;
	transform: translateX(-12px);
	transition:
		opacity 0.5s cubic-bezier(0.2, 0.7, 0.2, 1),
		transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.hp-ppc-google__phase.is-active .hp-ppc-google__num {
	background: var(--color-accent);
	color: var(--color-paper);
	transform: scale(1.08);
	box-shadow:
		0 0 0 6px var(--color-primary),
		0 0 0 14px color-mix(in srgb, var(--color-accent) 35%, transparent),
		0 0 32px  color-mix(in srgb, var(--color-accent) 55%, transparent);
}
.hp-ppc-google__phase.is-active .hp-ppc-google__name {
	opacity: 1;
	transform: translateX(0);
}

/* SVG thread overlay — z-index: 0 so the numbered circles (inside
   .hp-eb-approach__inner's z-index: 1 stacking context) cleanly cover
   the stroke at each anchor. Same layering rule as wd-process. */
.hp-ppc-google__thread {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	z-index: 0;
	overflow: visible;
}
.hp-ppc-google__thread path {
	fill: none;
	stroke: var(--color-accent);
	stroke-width: clamp(22px, 2vw, 30px);
	stroke-linecap: round;
	stroke-linejoin: round;
}

@media (max-width: 1024px) {
	.hp-ppc-google .hp-eb-approach__inner { grid-template-columns: 1fr; }
	.hp-ppc-google__phases { gap: clamp(2.5rem, 6vw, 3.5rem); }
	.hp-ppc-google__phase {
		/* Circles scaled DOWN per user spec (was clamp(3rem, 10vw,
		   3.75rem)) — matches the WD "How We Work" mobile scale. */
		grid-template-columns: clamp(2rem, 6vw, 2.5rem) minmax(0, 1fr);
		column-gap: clamp(1rem, 4vw, 1.5rem);
	}
	.hp-ppc-google__num {
		width:  clamp(2rem, 6vw, 2.5rem);
		height: clamp(2rem, 6vw, 2.5rem);
		font-size: clamp(1.05rem, 3.2vw, 1.35rem);
	}
	/* Thread now RUNS on mobile (was display:none) — same call as the WD
	   "How We Work" section. On single-column the JS anchors the entry
	   to the "We specialise in" eyebrow (not the H2), so the run only
	   spans the list and never crosses the head prose — no head indent
	   needed. The scroll-draw keeps driving the `.is-active` circle/name
	   reveal, and the navy ring on each circle keeps cutting the stroke
	   cleanly. At ≤767px the stroke drops to the homepage brand-thread
	   thickness (see below). */
	/* Left-align and shrink the eyebrow (the desktop right-align existed
	   for the desktop thread lane; on mobile it overflowed), and indent
	   it past the thread's entry corner + vertical run so the stroke
	   sweeps in beside the text, aligned with the phase names. */
	.hp-ppc-google__list-eyebrow {
		text-align: left;
		font-size: clamp(1.1rem, 5vw, 1.4rem);
		padding-left: calc(clamp(2rem, 6vw, 2.5rem) + clamp(1rem, 4vw, 1.5rem));
	}
}

/* Phone: match the homepage brand-thread's mobile thickness — same
   dot-scaled formula as .hp-ppc-loc__thread and .hp-wd-process__thread
   (see wireScrollRibbon). The 22-30px band is desktop-only. */
@media (max-width: 767px) {
	.hp-ppc-google__thread path { stroke-width: calc(1.46vw + 2px); }
}

/* ---------- Section 3 — Meta Ads (prose + partner card + photo) ----- */
/* 3-column LIB-06 grid per user spec: the previous 2-column version left a
   large empty corner on the right at desktop widths. Prose column, then the
   brutalist "Verified Meta Business Partner" callout, then a photo in the
   third column.

   Ground is SATURATED (navy) so this section blends into the continuous dark
   run around it — which means the three places that used to hardcode navy ink
   (.hp-ppc-meta__lead, .hp-ppc-meta__badge-eyebrow, .hp-ppc-meta__badge-body)
   now resolve to paper, and the badge's interior tint is paper-based. */
.hp-ppc-meta__grid {
	/* Prose gets the wider column; the callout and the photo split the rest
	   evenly. Overrides the chassis 1fr / 1fr / 1.1fr. */
	grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1fr);
	column-gap: clamp(2.5rem, 4vw, 3.5rem);
	align-items: start;
}
/* The chassis pins .hp-eb-split__media to `grid-row: 1 / span 2`, which would
   open an implicit second row in this single-row grid. This section has one
   row, so let the figure sit naturally in it.

   Both class names are carried so this reaches (0,2,0) and beats the chassis
   rule outright. Equal specificity is NOT enough: the chassis block is
   declared LATER in this stylesheet, so a (0,1,0) rule up here would lose on
   source order. Same trap the .hp-eb-split--reverse rules document. */
.hp-ppc-meta__media.hp-eb-split__media {
	grid-column: 3;
	grid-row: auto;
}
.hp-ppc-meta__prose {
	display: flex;
	flex-direction: column;
	gap: clamp(1.25rem, 2vw, 1.75rem);
}
.hp-ppc-meta__lead {
	font-family: var(--font-heading-family);
	font-size: clamp(1.2rem, 1.55vw, 1.5rem);
	line-height: 1.5;
	font-weight: 500;
	/* Paper, not navy — the section moved to the saturated ground. */
	color: var(--color-paper);
	max-width: 38ch;
	margin: 0;
}
.hp-ppc-meta__body {
	font-size: clamp(1rem, 1.2vw, 1.15rem);
	line-height: 1.65;
	margin: 0;
	max-width: 42ch;
	opacity: 0.88;
}
.hp-ppc-meta__cta { margin-top: clamp(0.75rem, 1.5vw, 1.25rem) !important; }

.hp-ppc-meta__badge {
	/* Brutalist verified-partner card: pink hairline thread on the
	   LEFT edge, faint paper-tint interior, oversized eyebrow with a
	   pink "verified" dot. Replaces the previous stock Instagram
	   image — same column real-estate, substantive on-brand content. */
	position: relative;
	padding: clamp(1.75rem, 3vw, 2.5rem) clamp(1.5rem, 2.5vw, 2.25rem);
	/* Paper-tinted interior — the card sits on the navy ground now, so a
	   navy tint was invisible. 6% lifts the panel just off the ground. */
	background: color-mix(in oklab, var(--color-paper) 6%, transparent);
	border-left: 4px solid var(--color-accent);
	display: flex;
	flex-direction: column;
	gap: clamp(1rem, 1.5vw, 1.25rem);
}
.hp-ppc-meta__badge-eyebrow {
	display: flex;
	align-items: center;
	gap: 0.65rem;
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(0.85rem, 1vw, 0.95rem);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--color-paper);
	margin: 0;
}
.hp-ppc-meta__badge-dot {
	width: 0.625rem;
	height: 0.625rem;
	border-radius: 50%;
	background: var(--color-accent);
	box-shadow:
		0 0 0 4px color-mix(in oklab, var(--color-accent) 22%, transparent),
		0 0 12px color-mix(in oklab, var(--color-accent) 45%, transparent);
	flex: 0 0 auto;
}
.hp-ppc-meta__badge-body {
	font-family: var(--font-heading-family);
	font-weight: 500;
	font-size: clamp(1.05rem, 1.3vw, 1.25rem);
	line-height: 1.55;
	color: var(--color-paper);
	margin: 0;
}

@media (max-width: 1024px) {
	.hp-ppc-meta__grid { grid-template-columns: 1fr; row-gap: clamp(2rem, 5vw, 3rem); }
	/* Once stacked, the chassis rule already sets grid-column: 1 / grid-row:
	   auto / order: -1 on .hp-eb-split__media. Match it here so the PPC-scoped
	   grid-column: 3 above does not win on source order and push the figure
	   into a phantom third column. */
	.hp-ppc-meta__media.hp-eb-split__media {
		grid-column: 1;
		grid-row: auto;
		/* The chassis flips to a 5/4 landscape crop on mobile, which is right
		   for a photograph but cuts the top and bottom off these centred app
		   tiles (object-fit: cover trims the axis the frame is short on).
		   Holding the source's own 4/5 means no re-crop at all, so both
		   tiles stay whole at every width. */
		aspect-ratio: 4 / 5;
	}
}

/* ---------- Section 4 — Meta Business (3-up oversized numerals) ----- */
/* Layout rebuilt per user spec — the static `.hp-eb-grid3__line` brand
   thread under the cells has been dropped; each cell is now anchored
   by a giant SOLID PINK numeral (01 / 02 / 03) sitting above the body
   prose. Vertical hairlines between cells replace the previous 4px
   pink top border on each cell so the rhythm reads as columns of an
   editorial spread rather than three disconnected blocks.

   GROUND: this section is where the page's navy → cream → navy wash
   begins. It shares --hp-ppc-wash with .hp-ppc-loc below (see the
   "PPC ground wash" block after the locations section), so every piece
   of copy here takes --ppc-ink rather than a fixed paper, and the
   dividers take currentColor. The pink numerals stay pink: pink reads
   on navy and on cream alike, same rule the Web Design page follows. */
.hp-ppc-business.hp-eb-grid3 {
	color: var(--ppc-ink, var(--color-paper));
}
.hp-ppc-business .hp-eb-grid3__h2 {
	color: var(--ppc-ink, var(--color-paper));
	max-width: 22ch;
}
.hp-ppc-business__row {
	gap: 0;
	align-items: stretch;
}
.hp-ppc-business__cell {
	position: relative;
	padding: 0 clamp(1.5rem, 3vw, 2.5rem);
	border-top: 0;
	gap: clamp(1.25rem, 2vw, 1.75rem);
	/* Hairline vertical divider between columns — drawn on the LEFT of
	   every cell, then suppressed on the first. Mixes currentColor (which
	   tracks the ground wash) at 15% so it reads as a structural rule on
	   navy AND on cream without competing with the pink accent. */
	border-left: 1px solid color-mix(in oklab, currentColor 15%, transparent);
}
.hp-ppc-business__cell:first-child {
	border-left: 0;
	padding-left: 0;
}
.hp-ppc-business__cell:last-child {
	padding-right: 0;
}
.hp-ppc-business__cell-num {
	font-family: var(--font-heading-family);
	font-weight: 800;
	/* Oversized SOLID numeral — filled pink, no outline (user spec; it was
	   transparent-with-a-pink-stroke). Same typeface and size as before.
	   The stroke is explicitly reset so it cannot linger from the old rule
	   or from a cached stylesheet. Pink is NOT mapped to --ppc-ink: it reads
	   on both the navy and the cream end of the ground wash. */
	font-size: clamp(4.5rem, 8vw, 7.5rem);
	line-height: 0.9;
	color: var(--color-accent);
	-webkit-text-stroke: 0;
	letter-spacing: -0.04em;
	font-variant-numeric: tabular-nums;
}
.hp-ppc-business__cell-body {
	font-size: clamp(1.05rem, 1.25vw, 1.2rem);
	line-height: 1.65;
	color: var(--ppc-ink, var(--color-paper));
	opacity: 0.92;
	font-style: normal;
	margin: 0;
	max-width: 42ch;
}
.hp-ppc-business__foot {
	display: flex;
	justify-content: flex-end;
	margin-top: clamp(3rem, 5vw, 4.5rem);
}
@media (max-width: 1024px) {
	.hp-ppc-business__row { grid-template-columns: 1fr; gap: clamp(2rem, 5vw, 3rem); }
	.hp-ppc-business__cell {
		border-left: 0;
		padding: 0;
		/* On mobile, restore a slim top accent rule per cell so the
		   stack still reads as three discrete blocks once the columns
		   collapse. */
		padding-top: clamp(1.5rem, 4vw, 2rem);
		border-top: 1px solid color-mix(in oklab, currentColor 20%, transparent);
	}
	.hp-ppc-business__cell:first-child {
		border-top: 0;
		padding-top: 0;
	}
	.hp-ppc-business__cell-num { font-size: clamp(3.5rem, 14vw, 5rem); }
	.hp-ppc-business__foot { justify-content: flex-start; }
}

/* ---------- Section 5 — Locations (live brand-thread bracket) ------- */
/* Static CSS `::before` bracket replaced by a live SVG thread that
   uses the same stroke band (clamp(22px, 2vw, 30px)) as the hero +
   spine threads, per [[feedback-eb-thread-mandatory]]. The SVG is a
   sibling of `.hp-eb-cases__inner`; geometry is computed live by
   wirePpcLocThread (main.js) from the bracket's getBoundingClientRect
   and scroll-drawn via stroke-dasharray. */
.hp-ppc-loc {
	position: relative;
	/* Allow the entry / exit horizontal segments to extend off-canvas
	   left (x = -80). Overrides `.hp-ppc section { overflow-x: clip }`. */
	overflow: visible;
	overflow-x: visible;
	/* Extra headroom so the thread's top horizontal run (drawn at
	   bracket.top - ENTRY_LIFT, i.e. 60px above the body box) is not
	   crowded against the section above. Was the chassis
	   clamp(5rem, 10vh, 9rem). */
	padding-block-start: clamp(7rem, 14vh, 12rem);
}
/* Push the sticky H2 down so it clears the thread's top horizontal instead
   of sitting tight beneath it — user request. The bracket in the right
   column keeps its natural top, so the thread geometry (tuned to the
   bracket's rect in wirePpcLocThread) is untouched. */
.hp-ppc-loc .hp-eb-cases__pull {
	padding-top: clamp(2.5rem, 5vw, 4.5rem);
}
.hp-ppc-loc .hp-eb-bracket::before {
	/* Suppress the 18px static-bordered bracket — the live SVG thread
	   on this section is the visible bracket now. */
	display: none;
}
.hp-ppc-loc .hp-eb-cases__inner {
	grid-template-columns: minmax(0, 0.75fr) minmax(0, 1.25fr);
	/* Stacking context so the SVG (z-index: 0) sits BELOW the body
	   text — same pattern wd-process / ppc-google use. */
	position: relative;
	z-index: 1;
}
.hp-ppc-loc__bracket {
	min-height: clamp(280px, 36vw, 420px);
	display: flex;
	align-items: center;
}
.hp-ppc-loc__bracket-body {
	display: flex;
	flex-direction: column;
	gap: clamp(1rem, 1.8vw, 1.5rem);
	max-width: 56ch;
}
.hp-ppc-loc__copy {
	font-size: clamp(1rem, 1.2vw, 1.15rem);
	line-height: 1.65;
	margin: 0;
}
.hp-ppc-loc__cta { margin: clamp(0.5rem, 1vw, 0.75rem) 0 0 !important; }

.hp-ppc-loc__thread {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	z-index: 0;
	overflow: visible;
}
.hp-ppc-loc__thread path {
	fill: none;
	stroke: var(--color-accent);
	stroke-width: clamp(22px, 2vw, 30px);
	stroke-linecap: round;
	stroke-linejoin: round;
}

@media (max-width: 1024px) {
	.hp-ppc-loc .hp-eb-cases__inner { grid-template-columns: 1fr; }
	/* Keep enough height for the two R=80 corners of the live thread to
	   fit. Once collapsed to one column the two short paragraphs render
	   wide and shallow; without a floor the bracket drops below the
	   wirePpcLocThread guard (yBot - yTop < R*2 + 8 = 168px) and the
	   thread vanishes on md/tablet. This floor keeps the brand thread —
	   at its standard clamp(22px, 2vw, 30px) thickness — drawing on
	   mobile and md alike. */
	.hp-ppc-loc__bracket { min-height: clamp(240px, 44vw, 340px); }
}

/* Mobile: match the homepage brand-thread thickness exactly. The homepage
   scales its stroke to the hero dot (dot ≈ 1.46% of the full-bleed 16:9
   media = ~1.46vw on a portrait phone, + 2px) — see wireScrollRibbon.
   Above this breakpoint the section keeps the uniform internal-page
   clamp(22px, 2vw, 30px). The JS `half` offset in wirePpcLocThread mirrors
   this formula so the ribbon edge stays aligned to the bracket. */
@media (max-width: 767px) {
	.hp-ppc-loc__thread path { stroke-width: calc(1.46vw + 2px); }
}

/* ---------- PPC ground wash — navy → cream → navy ------------------- */
/* User spec: "Meta Ads That Mean Business" STARTS turning white, "Google Ads
   and Meta Ads Across the UK" lands on white, and the page is dark again by
   the reviews slider. This is the Web Design process + results pair ported
   across: both sections take their ground from ONE shared --hp-ppc-wash so
   the seam between them never shows a hard edge.

   wirePpcLocColorShift (main.js) writes --hp-ppc-wash onto BOTH sections from
   the locations section's own top and bottom edge: 0 → 1 as it enters, 1 → 0
   as it leaves.

   --ppc-ground = the current ground (navy at 0, cream at 1).
   --ppc-ink    = its inverse (cream at 0, navy at 1) — used for every piece
                  of copy in both sections so it stays legible through the
                  mid-transition grey. The pink thread, the pink cell numerals
                  and the pink CTA pills are deliberately NOT mapped to it:
                  pink reads on both grounds and must stay pink. */
.hp-ppc-business,
.hp-ppc-loc {
	--ppc-ground: color-mix(
		in oklab,
		var(--color-paper) calc(var(--hp-ppc-wash) * 100%),
		var(--color-primary)
	);
	--ppc-ink: color-mix(
		in oklab,
		var(--color-primary) calc(var(--hp-ppc-wash) * 100%),
		var(--color-paper)
	);
}
/* Rest values match each section's declared data-eb-ground, so no-JS,
   reduced-motion and no-color-mix visitors see exactly what the attribute
   promises: business navy, locations cream. */
.hp-ppc-business { --hp-ppc-wash: 0; }
.hp-ppc-loc      { --hp-ppc-wash: 1; }

/* Carried on the attribute so these outrank the generic
   [data-eb-section][data-eb-ground="…"] rules in main.css — same selector
   shape .hp-wd-process / .hp-wd-results use. */
.hp-ppc-business[data-eb-ground="saturated"],
.hp-ppc-loc[data-eb-ground="light"] {
	background: var(--ppc-ground);
	color: var(--ppc-ink);
}

/* No color-mix support: hold each section at its declared solid ground so
   neither ever renders illegible. */
@supports not (color: color-mix(in oklab, red, blue)) {
	.hp-ppc-business[data-eb-ground="saturated"] {
		background: var(--color-primary);
		color: var(--color-paper);
	}
	.hp-ppc-loc[data-eb-ground="light"] {
		background: var(--color-paper);
		color: var(--color-primary);
	}
}

/* Scroll-color word fill inside the washing pair. The default recipe in
   main.css is tuned for paper-on-navy and would paint paper-on-cream (i.e.
   invisible) once the wash completes, so both the lit and unlit ends are
   mixed against --ppc-ink instead. Same shape as the .hp-eb-about override. */
.hp-ppc-business .hp-scroll-color__word,
.hp-ppc-loc .hp-scroll-color__word {
	color: color-mix(
		in srgb,
		var(--ppc-ink) calc(var(--lit) * 100%),
		color-mix(in srgb, var(--ppc-ink) 52%, transparent)
	);
}
@supports not (color: color-mix(in srgb, red, blue)) {
	.hp-ppc-business .hp-scroll-color__word { color: var(--color-paper); }
	.hp-ppc-loc .hp-scroll-color__word      { color: var(--color-primary); }
}

/* =====================================================================
   VIDEOGRAPHY PAGE — Editorial brutalism (sister page to PPC)
   ---------------------------------------------------------------------
   Same brutalism dialect as the PPC page: paper / navy ground, hard
   hairline rules, oversized outlined section numerals, single hot-pink
   accent on H1 marks and watermark glyphs. The page alternates paper
   and navy slabs so the rhythm punches.

   Namespace: .hp-vid (page root) + .hp-vid-{section} (block). Reuses
   the global .hp-btn utility for buttons and the generic data-section
   scroll-reveal hooks.
   ===================================================================== */

.hp-vid {
	background: var(--color-paper);
	color: var(--color-primary);
	overflow-x: clip;
}
.hp-vid section { overflow-x: clip; position: relative; }
.hp-vid img,
.hp-vid svg { max-width: 100%; }

/* Opt out of the JS-driven adjacent-section cross-fade. Each section
   keeps its own static ground; the seam between saturated and light
   sections is hard, not animated. */
.hp-vid [data-eb-section][data-eb-ground="saturated"].hp-eb-fading {
	background: var(--eb-ground-saturated);
	color: var(--eb-ink-on-saturated);
}
.hp-vid [data-eb-section][data-eb-ground="light"].hp-eb-fading {
	background: var(--eb-ground-light);
	color: var(--eb-ink-on-light);
}

/* ---- Scroll reveal (mirrors PPC pattern) ---- */
.hp-vid [data-section].is-pending .hp-vid-hero__body > *,
.hp-vid [data-section].is-pending .hp-vid-impact__inner > *,
.hp-vid [data-section].is-pending .hp-vid-kit__body > *,
.hp-vid [data-section].is-pending .hp-vid-kit__rail,
.hp-vid [data-section].is-pending .hp-vid-kit__badges,
.hp-vid [data-section].is-pending .hp-vid-produce__head,
.hp-vid [data-section].is-pending .hp-vid-produce__row,
.hp-vid [data-section].is-pending .hp-vid-produce__foot,
.hp-vid [data-section].is-pending .hp-vid-brands__head,
.hp-vid [data-section].is-pending .hp-vid-brands__row,
.hp-vid [data-section].is-pending .hp-vid-brands__actions,
.hp-vid [data-section].is-pending .hp-vid-cta__inner > *,
.hp-vid [data-section].is-pending .hp-vid-hero__chips li,
.hp-vid [data-section].is-pending .hp-vid-kit__badges .hp-vid-badge {
	opacity: 0;
	transform: translateY(22px);
	transition: opacity 0.7s ease, transform 0.7s ease;
}
.hp-vid [data-section].is-visible .hp-vid-hero__body > *,
.hp-vid [data-section].is-visible .hp-vid-impact__inner > *,
.hp-vid [data-section].is-visible .hp-vid-kit__body > *,
.hp-vid [data-section].is-visible .hp-vid-kit__rail,
.hp-vid [data-section].is-visible .hp-vid-kit__badges,
.hp-vid [data-section].is-visible .hp-vid-produce__head,
.hp-vid [data-section].is-visible .hp-vid-produce__row,
.hp-vid [data-section].is-visible .hp-vid-produce__foot,
.hp-vid [data-section].is-visible .hp-vid-brands__head,
.hp-vid [data-section].is-visible .hp-vid-brands__row,
.hp-vid [data-section].is-visible .hp-vid-brands__actions,
.hp-vid [data-section].is-visible .hp-vid-cta__inner > *,
.hp-vid [data-section].is-visible .hp-vid-hero__chips li,
.hp-vid [data-section].is-visible .hp-vid-kit__badges .hp-vid-badge {
	opacity: 1;
	transform: none;
}
.hp-vid [data-section].is-visible .hp-vid-produce__row { transition-delay: calc(0.04s + var(--pi, 0) * 0.06s); }
.hp-vid [data-section].is-visible .hp-vid-brands__row  { transition-delay: calc(0.04s + var(--bi, 0) * 0.05s); }

/* ---- Shared editorial primitives (page-scoped twin of PPC's) ---- */
.hp-vid-mono {
	font-family: var(--font-body-family);
	font-size: 0.78rem;
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	line-height: 1;
	color: rgba(0,0,16,0.62);
	font-variant-numeric: tabular-nums;
}
.hp-vid-mono--lg {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1rem, 1.6vw, 1.25rem);
	letter-spacing: 0.02em;
	color: var(--color-primary);
}
.hp-vid-mono--right { margin-left: auto; }
.hp-vid-mono--inline {
	display: inline-block;
	color: var(--color-accent);
	margin-right: 0.4em;
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: 1.05em;
}

.hp-vid-section__rule { height: 1px; background: rgba(0,0,16,0.18); }
.hp-vid-section__rule--paper { background: rgba(244,241,234,0.22); }
.hp-vid-section__head {
	display: flex;
	align-items: center;
	gap: clamp(1rem, 3vw, 2.5rem);
	padding: 1.1rem clamp(1.25rem, 5vw, 4rem);
	border-bottom: 1px solid rgba(0,0,16,0.18);
}
.hp-vid-section__head--inv {
	background: var(--color-primary);
	color: var(--color-paper);
	border-bottom: 1px solid rgba(244,241,234,0.18);
}
.hp-vid-section__head--inv .hp-vid-mono { color: rgba(244,241,234,0.6); }
.hp-vid-section__head--inv .hp-vid-mono--lg { color: var(--color-paper); }

.hp-vid-eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	margin: 0 0 1.5rem;
	font-family: var(--font-body-family);
	font-size: 0.825rem;
	font-weight: 600;
	letter-spacing: 0.04em;
	color: var(--color-primary);
}
.hp-vid-eyebrow--inv { color: var(--color-paper); }
.hp-vid-eyebrow__sq {
	width: 0.55rem;
	height: 0.55rem;
	background: var(--color-accent);
	display: inline-block;
}
.hp-vid-eyebrow__sq--pink { background: var(--color-accent); }

.hp-vid-h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.25rem, 5.4vw, 4.5rem);
	line-height: 0.98;
	letter-spacing: -0.025em;
	margin: 0 0 1.5rem;
	color: var(--color-primary);
}
.hp-vid-h2--inv { color: var(--color-paper); }
.hp-vid-mark {
	display: block;
	font-size: 0.62em;
	font-weight: 800;
	line-height: 1.1;
	letter-spacing: -0.015em;
	margin-top: 0.55em;
	padding: 0.05em 0.35em;
	background: var(--color-accent);
	color: var(--color-paper);
	width: max-content;
	max-width: 100%;
	box-decoration-break: clone;
	-webkit-box-decoration-break: clone;
}
.hp-vid-mark--pink {
	background: var(--color-paper);
	color: var(--color-primary);
}

.hp-vid-tag {
	display: inline-block;
	font-family: var(--font-body-family);
	font-size: 0.7rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	padding: 0.45rem 0.7rem;
	background: var(--color-accent);
	color: var(--color-paper);
}
.hp-vid-tag--pink {
	background: var(--color-accent);
	color: var(--color-paper);
}

.hp-vid-inline-link {
	display: inline-flex;
	align-items: center;
	gap: 0.75rem;
	padding: 0.4rem 0;
	border-bottom: 2px solid var(--color-accent);
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: 1rem;
	color: var(--color-primary);
	text-decoration: none;
	transition: gap 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}
.hp-vid-inline-link:hover,
.hp-vid-inline-link:focus-visible {
	gap: 1.1rem;
	color: var(--color-accent);
	border-color: var(--color-primary);
	outline: none;
}
.hp-vid-inline-link--lg { font-size: 1.15rem; }
.hp-vid-inline-link__arrow { font-family: var(--font-heading-family); font-weight: 800; }

/* ---- Editorial-brutalism primitives ---- */

/* Brutalist hard-edged button — 0px radius, thick border, no shadow, instant hover */
.hp-vid-btn {
	display: inline-flex;
	align-items: center;
	gap: 0.7rem;
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: 0.95rem;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	text-decoration: none;
	padding: 1.05rem 1.55rem;
	border: 2.5px solid var(--color-primary);
	background: var(--color-primary);
	color: var(--color-paper);
	border-radius: 0;
	transition: background-color 0.08s linear, color 0.08s linear, border-color 0.08s linear;
	white-space: nowrap;
}
.hp-vid-btn:hover,
.hp-vid-btn:focus-visible {
	background: var(--color-accent);
	border-color: var(--color-accent);
	color: var(--color-paper);
	outline: none;
}
.hp-vid-btn--ghost { background: transparent; color: var(--color-primary); }
.hp-vid-btn--ghost:hover,
.hp-vid-btn--ghost:focus-visible {
	background: var(--color-primary);
	color: var(--color-paper);
}
.hp-vid-btn--ghost-inv {
	background: transparent;
	color: var(--color-paper);
	border-color: var(--color-paper);
}
.hp-vid-btn--ghost-inv:hover,
.hp-vid-btn--ghost-inv:focus-visible {
	background: var(--color-paper);
	color: var(--color-primary);
	border-color: var(--color-paper);
}
.hp-vid-btn--solid {
	background: var(--color-accent);
	border-color: var(--color-accent);
	color: var(--color-paper);
}
.hp-vid-btn--solid:hover,
.hp-vid-btn--solid:focus-visible {
	background: var(--color-paper);
	border-color: var(--color-primary);
	color: var(--color-primary);
}
.hp-vid-btn--lg { padding: 1.25rem 1.85rem; font-size: 1.05rem; }
.hp-vid-btn__arrow { font-family: var(--font-heading-family); font-weight: 800; }

/* Editorial drop cap — first letter of a paragraph, oversized & pink */
.hp-vid-dropcap::first-letter {
	float: left;
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: 5em;
	line-height: 0.85;
	padding: 0.12em 0.18em 0 0;
	margin: 0.08em 0.1em 0 0;
	color: var(--color-accent);
	letter-spacing: -0.05em;
}
.hp-vid-dropcap--inv::first-letter { color: var(--color-accent); }

/* Magazine pull quote — italic, hanging quotation mark, thick top/bottom rules */
.hp-vid-pullquote {
	position: relative;
	margin: 0;
	padding: clamp(1.25rem, 2.5vw, 2rem) 0 clamp(1.25rem, 2.5vw, 2rem) clamp(2.5rem, 4vw, 3.5rem);
	font-family: var(--font-heading-family);
	font-style: italic;
	font-weight: 700;
	font-size: clamp(1.85rem, 4vw, 3.25rem);
	line-height: 1.1;
	letter-spacing: -0.02em;
	color: var(--color-primary);
	border-top: 2.5px solid var(--color-primary);
	border-bottom: 2.5px solid var(--color-primary);
}
.hp-vid-pullquote::before {
	content: '\201C';
	position: absolute;
	top: -0.1em;
	left: 0;
	font-family: var(--font-heading-family);
	font-style: italic;
	font-weight: 800;
	font-size: clamp(4.5rem, 9vw, 8rem);
	line-height: 0.9;
	color: var(--color-accent);
	letter-spacing: -0.05em;
}
.hp-vid-pullquote__cite {
	display: block;
	margin-top: 1rem;
	font-family: var(--font-body-family);
	font-style: normal;
	font-weight: 600;
	font-size: 0.78rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: rgba(0,0,16,0.6);
}
.hp-vid-pullquote--inv {
	color: var(--color-paper);
	border-top-color: var(--color-paper);
	border-bottom-color: var(--color-paper);
}
.hp-vid-pullquote--inv .hp-vid-pullquote__cite { color: rgba(244,241,234,0.65); }

/* Dotted leader — used between left/right text in catalogue & TOC rows */
.hp-vid-leader {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: baseline;
	gap: 0.6rem;
	width: 100%;
}
.hp-vid-leader__rule {
	border-bottom: 2px dotted rgba(0,0,16,0.4);
	transform: translateY(-0.35em);
	height: 0;
}
.hp-vid-leader--inv .hp-vid-leader__rule { border-bottom-color: rgba(244,241,234,0.4); }

/* Ledger column header — bold rule + mono column labels */
.hp-vid-ledger-head {
	display: grid;
	gap: clamp(1rem, 3vw, 2rem);
	padding: 0.9rem 0;
	border-bottom: 2.5px solid var(--color-primary);
	border-top: 2.5px solid var(--color-primary);
	font-family: var(--font-body-family);
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--color-primary);
}
.hp-vid-ledger-head--inv {
	border-color: var(--color-paper);
	color: var(--color-paper);
}

/* Two-column body text — flows like a magazine on desktop */
.hp-vid-cols2 {
	column-count: 2;
	column-gap: clamp(1.5rem, 3vw, 2.5rem);
	column-rule: 1px solid rgba(0,0,16,0.18);
}
.hp-vid-cols2 > p {
	break-inside: avoid;
	margin: 0 0 1rem;
	font-family: var(--font-heading-family);
	font-weight: 500;
	font-size: clamp(1rem, 1.15vw, 1.075rem);
	line-height: 1.55;
	color: var(--color-primary);
}
.hp-vid-cols2 > p:last-child { margin-bottom: 0; }
.hp-vid-cols2--inv { column-rule-color: rgba(244,241,234,0.22); }
.hp-vid-cols2--inv > p { color: rgba(244,241,234,0.92); }

/* Mono specs ledger — used in the kit section */
.hp-vid-specs {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
	gap: 0;
	margin: clamp(1.75rem, 3vw, 2.5rem) 0 0;
	padding: 0;
	list-style: none;
	border-top: 1px solid rgba(244,241,234,0.22);
	border-left: 1px solid rgba(244,241,234,0.22);
}
.hp-vid-specs li {
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
	padding: 0.95rem 1rem;
	border-right: 1px solid rgba(244,241,234,0.22);
	border-bottom: 1px solid rgba(244,241,234,0.22);
}
.hp-vid-specs__k {
	font-family: var(--font-body-family);
	font-size: 0.68rem;
	font-weight: 700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: rgba(244,241,234,0.55);
}
.hp-vid-specs__v {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: 1.05rem;
	line-height: 1.1;
	letter-spacing: -0.01em;
	color: var(--color-paper);
}
.hp-vid-specs__v em {
	font-style: italic;
	color: var(--color-accent);
	font-weight: 700;
}

/* Brutalist rotated stamp — sits in section corners as a printers' mark */
.hp-vid-stamp {
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 0.25rem;
	padding: 0.7rem 1.1rem;
	border: 2.5px solid var(--color-accent);
	color: var(--color-accent);
	font-family: var(--font-heading-family);
	font-weight: 800;
	text-align: center;
	text-transform: uppercase;
	background: transparent;
	rotate: -6deg;
	line-height: 1;
}
.hp-vid-stamp__big { font-size: 1rem; letter-spacing: 0.02em; }
.hp-vid-stamp__sm {
	font-family: var(--font-body-family);
	font-size: 0.6rem;
	letter-spacing: 0.18em;
	font-weight: 600;
}
.hp-vid-stamp--inv { color: var(--color-paper); border-color: var(--color-paper); }
.hp-vid-stamp--fixed-tr {
	position: absolute;
	top: clamp(1rem, 3vw, 2.5rem);
	right: clamp(1.25rem, 5vw, 4rem);
	z-index: 2;
}

/* Asymmetric column header bar — DEPT / ISSUE / DATELINE / VOL */
.hp-vid-masthead {
	display: grid;
	grid-template-columns: 1.4fr 1fr 1.4fr 1fr;
	gap: 0;
	border-bottom: 2.5px solid var(--color-primary);
}
.hp-vid-masthead__cell {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	padding: 0.9rem clamp(1rem, 3vw, 1.5rem);
	border-right: 1px solid rgba(0,0,16,0.2);
	min-width: 0;
}
.hp-vid-masthead__cell:last-child { border-right: 0; }
.hp-vid-masthead__k {
	font-family: var(--font-body-family);
	font-size: 0.62rem;
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: rgba(0,0,16,0.55);
}
.hp-vid-masthead__v {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: 0.95rem;
	line-height: 1;
	color: var(--color-primary);
	font-variant-numeric: tabular-nums;
}

/* Vertical caption — rotated -90deg "VIDEOGRAPHY" stamp on hero rail */
.hp-vid-vertical-caption {
	font-family: var(--font-body-family);
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.4em;
	text-transform: uppercase;
	color: rgba(0,0,16,0.45);
	writing-mode: vertical-rl;
	transform: rotate(180deg);
	margin-top: 1rem;
}

/* Footnote / marginalia */
.hp-vid-footnote {
	display: flex;
	gap: 0.5rem;
	margin: clamp(2rem, 3vw, 2.5rem) 0 0;
	padding: 0.85rem 0 0;
	border-top: 1px solid rgba(0,0,16,0.18);
	font-family: var(--font-body-family);
	font-size: 0.78rem;
	line-height: 1.4;
	color: rgba(0,0,16,0.6);
}
.hp-vid-footnote__num {
	font-family: var(--font-heading-family);
	font-weight: 800;
	color: var(--color-accent);
	font-size: 0.78rem;
	flex-shrink: 0;
}
.hp-vid-footnote--inv {
	border-top-color: rgba(244,241,234,0.22);
	color: rgba(244,241,234,0.65);
}

/* Tape-strip badge — replaces .hp-vid-badge with harder edges */
.hp-vid-tape {
	display: block;
	padding: 0.65rem 0.85rem;
	background: var(--color-paper);
	color: var(--color-primary);
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: 0.95rem;
	letter-spacing: -0.01em;
	line-height: 1;
	border: none;
	rotate: -2deg;
}
.hp-vid-tape:nth-child(even) { rotate: 1.5deg; }
.hp-vid-tape--pink { background: var(--color-accent); color: var(--color-paper); }
.hp-vid-tape__big {
	display: block;
	font-size: 1.7rem;
	line-height: 0.95;
	margin-bottom: 0.2rem;
	letter-spacing: -0.025em;
}
.hp-vid-tape__sm {
	display: block;
	font-family: var(--font-body-family);
	font-size: 0.6rem;
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
}

/* =============================================================
   Videography Hero
   ============================================================= */
.hp-vid-hero {
	background: var(--color-paper);
	padding-bottom: clamp(4rem, 8vw, 7rem);
	position: relative;
	border-bottom: 1px solid rgba(0,0,16,0.12);
}
.hp-vid-hero__rule { height: 1px; background: rgba(0,0,16,0.18); }
.hp-vid-hero__topbar {
	display: flex;
	gap: 1rem;
	padding: 0.9rem clamp(1.25rem, 5vw, 4rem);
	border-bottom: 1px solid rgba(0,0,16,0.18);
}
.hp-vid-hero__inner {
	display: grid;
	grid-template-columns: minmax(10rem, 14rem) 1fr;
	gap: clamp(1.5rem, 4vw, 3.5rem);
	padding: clamp(3rem, 6vw, 5rem) clamp(1.25rem, 5vw, 4rem) 0;
	align-items: start;
	max-width: 1400px;
	margin: 0 auto;
}
.hp-vid-hero__index {
	display: flex;
	flex-direction: column;
	gap: 0.9rem;
	border-right: 1px solid rgba(0,0,16,0.18);
	padding-right: clamp(1rem, 2.5vw, 2rem);
	position: sticky;
	top: 6rem;
}
.hp-vid-hero__index .hp-vid-mono--lg {
	color: transparent;
	-webkit-text-stroke: 1.5px var(--color-primary);
	font-size: clamp(2rem, 3.5vw, 2.75rem);
	line-height: 0.95;
	letter-spacing: -0.02em;
}

.hp-vid-hero__body { max-width: 70rem; }

/* ---------- Vid hero H1 + lead overrides ----------
   Higher specificity (0,2,0 via the .hp-vid-hero ancestor) so these win
   over the .hp-eb-hero__h1 / .hp-eb-hero__lead base rules without having
   to reorder source. */
.hp-vid-hero .hp-eb-hero__h1 {
	font-size: clamp(3rem, 8vw, 8.8rem);
	line-height: 0.96;
	letter-spacing: -0.04em;
}
.hp-vid-hero .hp-eb-hero__lead {
	max-width: 40ch;
}

/* ---------- Vid hero two-image stack ----------
   Replaces the single figure that used to occupy the media column.
   Lead card sits flush right; the drone card slides in below with a
   small leftward overhang so the two read as an editorial pair, not
   a uniform grid. */
.hp-vid-hero__media-stack {
	display: flex;
	flex-direction: column;
	gap: clamp(1.25rem, 2.4vw, 2rem);
	min-width: 0;
}
.hp-vid-hero__media-card {
	position: relative;
	margin: 0;
	overflow: hidden;
	border-radius: 8px;
	background: rgba(0, 0, 16, 0.06);
}
.hp-vid-hero__media-card img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.hp-vid-hero__media-card--lead {
	aspect-ratio: 4 / 5;
}
.hp-vid-hero__media-card--alt {
	aspect-ratio: 5 / 3;
	/* Slight leftward overhang for the editorial pair feel; pulls the
	   second image partially behind the first column's gutter. */
	margin-left: clamp(-3rem, -4vw, -1.25rem);
	max-width: 88%;
	align-self: flex-start;
}
.hp-vid-hero__media-card:hover img { transform: scale(1.03); }

/* 1024px, not 900px: matches the .hp-eb-hero__inner grid collapse so the
   two-image stack behaves consistently the moment the hero goes single-column
   (previously the 900-1024 band kept the desktop overhang on a stacked card). */
@media (max-width: 1024px) {
	.hp-vid-hero__media-card--alt {
		margin-left: 0;
		max-width: 100%;
		/* Clear the desktop editorial overhang so the second card fills
		   the column width like the lead card once the stack is vertical
		   (without this it stays shrunk-to-content and left-aligned). */
		align-self: stretch;
	}
	/* Same setup as the SEO hero on mobile: the media follows the copy (H1 →
	   lead → CTAs → images) instead of the base LIB-00 order:-1 that dropped
	   the photos above the heading with no gap. The base .hp-eb-hero__media is
	   a single clipped image box (fixed aspect-ratio + overflow:hidden + scrim)
	   — wrong for a two-card flex stack, so those are cleared here and a top
	   margin adds the breathing room the user asked for between the buttons
	   and the images. */
	.hp-vid-hero .hp-eb-hero__media {
		order: 0;
		aspect-ratio: auto;
		overflow: visible;
		background: none;
		margin-top: clamp(2rem, 5vw, 3rem);
	}
	.hp-vid-hero .hp-eb-hero__media::after { display: none; }
}

.hp-vid-hero__h1 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(3rem, 9vw, 8rem);
	line-height: 0.92;
	letter-spacing: -0.035em;
	margin: 0 0 clamp(2rem, 4vw, 3rem);
	color: var(--color-primary);
}
.hp-vid-hero__line { display: block; }
.hp-vid-hero__line--inset { padding-left: clamp(1.5rem, 5vw, 4rem); }
.hp-vid-hero__line--small {
	font-size: 0.45em;
	font-weight: 800;
	letter-spacing: -0.02em;
	color: rgba(0,0,16,0.78);
	margin-top: 0.45em;
}
.hp-vid-hero__amp {
	color: var(--color-accent);
	font-style: italic;
	font-weight: 700;
	margin-right: 0.18em;
}
.hp-vid-hero__period {
	display: inline-block;
	width: 0.42em;
	height: 0.42em;
	background: var(--color-accent);
	margin-left: 0.15em;
	vertical-align: baseline;
}

.hp-vid-hero__pull {
	position: relative;
	max-width: 56rem;
	border-left: 4px solid var(--color-accent);
	padding: 0.4rem 0 0.4rem 1.4rem;
	margin: 0 0 clamp(2rem, 4vw, 3rem);
}
.hp-vid-hero__lead {
	font-family: var(--font-heading-family);
	font-weight: 500;
	font-size: clamp(1.1rem, 1.6vw, 1.4rem);
	line-height: 1.5;
	margin: 0;
	color: var(--color-primary);
}
.hp-vid-hero__pull-mark {
	position: absolute;
	right: clamp(-1.5rem, -1.5rem + 2vw, 0rem);
	bottom: -1rem;
	font-family: var(--font-heading-family);
	font-weight: 800;
	color: var(--color-accent);
	font-size: 2rem;
	line-height: 1;
}

.hp-vid-hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 1rem;
	margin-bottom: clamp(2rem, 4vw, 3rem);
}

.hp-vid-hero__chips {
	list-style: none;
	padding: 1.25rem 0 0;
	margin: 0;
	border-top: 2px solid var(--color-primary);
	display: flex;
	flex-wrap: wrap;
	gap: 0.6rem;
}
.hp-vid-hero__chips li {
	font-family: var(--font-body-family);
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	padding: 0.55rem 0.85rem;
	border: 1px solid var(--color-primary);
	background: transparent;
	color: var(--color-primary);
}

.hp-vid-hero__footrule {
	display: flex;
	gap: 1rem;
	margin-top: clamp(3.5rem, 6vw, 5rem);
	padding: 0.9rem clamp(1.25rem, 5vw, 4rem);
	border-top: 1px solid rgba(0,0,16,0.18);
	justify-content: space-between;
}

/* =============================================================
   Section 01 — Impact (paper)
   ============================================================= */
.hp-vid-impact {
	background: var(--color-paper);
	border-bottom: 1px solid rgba(0,0,16,0.12);
}
.hp-vid-impact__inner {
	display: grid;
	grid-template-columns: 1fr 1.2fr;
	gap: clamp(2rem, 6vw, 5rem);
	padding: clamp(4rem, 8vw, 7rem) clamp(1.25rem, 5vw, 4rem);
	align-items: start;
	max-width: 1400px;
	margin: 0 auto;
}
.hp-vid-impact__head { position: sticky; top: 6rem; }
.hp-vid-impact__body { max-width: 48rem; }
.hp-vid-impact__lead {
	font-family: var(--font-heading-family);
	font-weight: 500;
	font-size: clamp(1.15rem, 1.7vw, 1.5rem);
	line-height: 1.45;
	color: var(--color-primary);
	margin: 0 0 1.75rem;
}
.hp-vid-impact__statement {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.5rem, 2.6vw, 2.2rem);
	line-height: 1.2;
	letter-spacing: -0.015em;
	margin: 0 0 2.25rem;
	color: var(--color-primary);
	padding-left: 1.25rem;
	border-left: 4px solid var(--color-accent);
}
.hp-vid-impact__cta { margin: 0; }

/* =============================================================
   Section 02 — Kit (DARK)
   ============================================================= */
.hp-vid-kit {
	background: var(--color-primary);
	color: var(--color-paper);
	border-bottom: 1px solid rgba(244,241,234,0.12);
	position: relative;
	isolation: isolate;
}
.hp-vid-kit__inner {
	position: relative;
	z-index: 1;
	display: grid;
	grid-template-columns: minmax(7rem, 10rem) 1fr minmax(10rem, 14rem);
	gap: clamp(1.5rem, 4vw, 3.5rem);
	padding: clamp(4rem, 8vw, 7rem) clamp(1.25rem, 5vw, 4rem);
	align-items: start;
	max-width: 1400px;
	margin: 0 auto;
}
.hp-vid-kit__rail {
	display: flex;
	flex-direction: column;
	gap: 0.85rem;
	color: rgba(244, 241, 234, 0.65);
	border-right: 1px solid rgba(244, 241, 234, 0.18);
	padding-right: clamp(0.8rem, 2vw, 1.5rem);
}
.hp-vid-kit__body { max-width: 52rem; }
.hp-vid-kit__paras {
	display: flex;
	flex-direction: column;
	gap: 1.15rem;
	margin-top: 1.75rem;
}
.hp-vid-kit__paras p {
	font-family: var(--font-heading-family);
	font-weight: 500;
	font-size: clamp(1.05rem, 1.4vw, 1.2rem);
	line-height: 1.55;
	color: rgba(244,241,234,0.92);
	margin: 0;
}
.hp-vid-kit__badges {
	display: flex;
	flex-direction: column;
	gap: 0.85rem;
	align-items: flex-end;
}
.hp-vid-badge {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: 1rem;
	line-height: 1.05;
	letter-spacing: 0.01em;
	text-align: center;
	width: clamp(7rem, 11vw, 9rem);
	aspect-ratio: 1 / 1;
	border: 1.5px solid var(--color-paper);
	color: var(--color-paper);
	background: transparent;
	rotate: -3deg;
}
.hp-vid-badge:nth-child(even) { rotate: 2deg; }
.hp-vid-badge--pink {
	background: var(--color-accent);
	border-color: var(--color-accent);
}

/* Kit supporting image — full-width cinematic band sitting under the
   prose grid (.hp-eb-prose__inner). Duotone at rest, reverts to full
   colour on pointer-hover (EB R-11). Spans both grid columns; the grid
   is single-column ≤1024px so it stays full width when stacked. */
.hp-vid-kit .hp-vid-kit__figure {
	grid-column: 1 / -1;
	position: relative;
	margin: clamp(1.25rem, 2.5vw, 2.25rem) 0 0;
	overflow: hidden;
	border-radius: 10px;
	aspect-ratio: 16 / 7;
	background: rgba(0, 0, 16, 0.25);
	isolation: isolate;
}
.hp-vid-kit__figure img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	filter: grayscale(1) contrast(1.05);
	opacity: 0.9;
	transition:
		filter 0.45s ease,
		opacity 0.45s ease,
		transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.hp-vid-kit__figure::after {
	content: "";
	position: absolute;
	inset: 0;
	background:
		linear-gradient(
			145deg,
			color-mix(in oklab, var(--color-accent) 30%, transparent),
			color-mix(in oklab, var(--color-primary) 55%, transparent) 65%
		);
	mix-blend-mode: multiply;
	pointer-events: none;
	opacity: 1;
	transition: opacity 0.45s ease;
}
.hp-vid-kit__figcaption {
	position: absolute;
	left: clamp(0.75rem, 1.5vw, 1.25rem);
	bottom: clamp(0.75rem, 1.5vw, 1.25rem);
	z-index: 1;
	font-size: 0.75rem;
	letter-spacing: 0.04em;
	color: var(--color-paper);
	background: color-mix(in oklab, var(--color-primary) 70%, transparent);
	padding: 0.35rem 0.65rem;
	border-radius: 2px;
}
@media (hover: hover) and (pointer: fine) {
	.hp-vid-kit__figure:hover img,
	.hp-vid-kit__figure:focus-within img {
		filter: none;
		opacity: 1;
		transform: scale(1.02);
	}
	.hp-vid-kit__figure:hover::after,
	.hp-vid-kit__figure:focus-within::after {
		opacity: 0;
	}
}
@media (max-width: 1024px) {
	.hp-vid-kit .hp-vid-kit__figure { aspect-ratio: 3 / 2; }
}
@media (max-width: 600px) {
	.hp-vid-kit .hp-vid-kit__figure { aspect-ratio: 4 / 3; }
}

/* =============================================================
   Section 03 — Catalogue (paper, dense list)
   ============================================================= */
.hp-vid-produce {
	background: var(--color-paper);
	border-bottom: 1px solid rgba(0,0,16,0.12);
}
.hp-vid-produce__inner {
	padding: clamp(4rem, 8vw, 7rem) clamp(1.25rem, 5vw, 4rem);
	max-width: 1280px;
	margin: 0 auto;
	position: relative;
}
.hp-vid-produce__head { margin-bottom: clamp(2.5rem, 5vw, 4rem); max-width: 56rem; }
.hp-vid-produce__sub {
	font-family: var(--font-heading-family);
	font-weight: 500;
	font-size: clamp(1.05rem, 1.3vw, 1.2rem);
	line-height: 1.5;
	color: rgba(0,0,16,0.78);
	margin: 1.5rem 0 0;
}
.hp-vid-produce__list {
	list-style: none;
	padding: 0;
	margin: 0;
	border-top: 2px solid var(--color-primary);
}
.hp-vid-produce__row {
	display: grid;
	grid-template-columns: clamp(5rem, 9vw, 8rem) 1fr 2rem;
	gap: clamp(1rem, 3vw, 2.5rem);
	padding: clamp(1.75rem, 3vw, 2.5rem) 0;
	border-bottom: 1px solid rgba(0,0,16,0.18);
	position: relative;
	transition: background-color 0.2s ease;
	align-items: start;
}
.hp-vid-produce__row:last-child { border-bottom: 2px solid var(--color-primary); }
.hp-vid-produce__row:hover { background: rgba(253, 46, 152, 0.06); }
.hp-vid-produce__num {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(3rem, 6vw, 5rem);
	line-height: 0.85;
	color: transparent;
	-webkit-text-stroke: 1.5px var(--color-primary);
	letter-spacing: -0.04em;
	font-variant-numeric: tabular-nums;
}
.hp-vid-produce__row:hover .hp-vid-produce__num { -webkit-text-stroke-color: var(--color-accent); }
.hp-vid-produce__tag {
	margin: 0 0 0.7rem;
	color: var(--color-accent);
}
.hp-vid-produce__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.5rem, 2.5vw, 2.25rem);
	line-height: 1.05;
	letter-spacing: -0.02em;
	margin: 0 0 1rem;
	color: var(--color-primary);
	max-width: 38rem;
}
.hp-vid-produce__body {
	font-family: var(--font-heading-family);
	font-weight: 500;
	font-size: clamp(1rem, 1.2vw, 1.1rem);
	line-height: 1.55;
	color: rgba(0,0,16,0.78);
	margin: 0;
	max-width: 50rem;
}
.hp-vid-produce__link { margin: 1rem 0 0; }
.hp-vid-produce__corner {
	font-family: var(--font-heading-family);
	font-weight: 800;
	color: var(--color-primary);
	font-size: 1.5rem;
	line-height: 1;
	opacity: 0.35;
	align-self: start;
	margin-top: 0.4rem;
	transition: color 0.2s ease, transform 0.2s ease, opacity 0.2s ease;
}
.hp-vid-produce__row:hover .hp-vid-produce__corner {
	color: var(--color-accent);
	opacity: 1;
	transform: translate(2px, -2px);
}
.hp-vid-produce__foot { margin: clamp(2.5rem, 4vw, 3.5rem) 0 0; }

/* =============================================================
   Section 04 — Brands (paper, row ledger)
   ============================================================= */
.hp-vid-brands {
	background: var(--color-paper);
	border-bottom: 1px solid rgba(0,0,16,0.12);
}
.hp-vid-brands__inner {
	padding: clamp(4rem, 8vw, 7rem) clamp(1.25rem, 5vw, 4rem);
	max-width: 1280px;
	margin: 0 auto;
}
.hp-vid-brands__head { margin-bottom: clamp(2.5rem, 5vw, 4rem); max-width: 56rem; }
.hp-vid-brands__sub {
	font-family: var(--font-heading-family);
	font-weight: 500;
	font-size: clamp(1.05rem, 1.3vw, 1.2rem);
	line-height: 1.5;
	color: rgba(0,0,16,0.78);
	margin: 1.5rem 0 0;
}
.hp-vid-brands__list {
	list-style: none;
	padding: 0;
	margin: 0;
	border-top: 2px solid var(--color-primary);
}
.hp-vid-brands__row {
	display: grid;
	grid-template-columns: clamp(3rem, 5vw, 4.5rem) 1.5fr 1fr;
	gap: clamp(1rem, 3vw, 2rem);
	padding: clamp(1.2rem, 2.5vw, 1.8rem) 0;
	border-bottom: 1px solid rgba(0,0,16,0.18);
	align-items: baseline;
	transition: background-color 0.2s ease, color 0.2s ease;
}
.hp-vid-brands__row:last-child { border-bottom: 2px solid var(--color-primary); }
.hp-vid-brands__row:hover { background: rgba(253, 46, 152, 0.06); }
.hp-vid-brands__num { color: var(--color-accent); }
.hp-vid-brands__name {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.6rem, 2.6vw, 2.4rem);
	line-height: 1;
	letter-spacing: -0.025em;
	color: var(--color-primary);
}
.hp-vid-brands__row:hover .hp-vid-brands__name { color: var(--color-accent); }
.hp-vid-brands__label {
	font-family: var(--font-body-family);
	font-weight: 500;
	font-size: clamp(0.95rem, 1.1vw, 1.05rem);
	line-height: 1.4;
	color: rgba(0,0,16,0.68);
}
.hp-vid-brands__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 1rem;
	margin-top: clamp(2.5rem, 4vw, 3.5rem);
}

/* Full-width tile strip: three equal images, a third of the width each, all the
   same size via a shared aspect-ratio + object-fit cover. Sits edge to edge
   beneath the copy (outside the padded __inner container). */
.hp-vid-brands__tiles {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: clamp(4px, 0.6vw, 8px);
	width: 100%;
	/* Breathing room between the CTA buttons and the tile strip. */
	margin-top: clamp(2.5rem, 5vw, 4.5rem);
}
.hp-vid-brands__tile {
	margin: 0;
	overflow: hidden;
	background: rgba(0, 0, 16, 0.06);
}
.hp-vid-brands__tile img {
	display: block;
	width: 100%;
	height: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	/* Same slow-zoom hover as the hero + kit tiles across the page. */
	transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
@media (hover: hover) and (pointer: fine) {
	.hp-vid-brands__tile:hover img,
	.hp-vid-brands__tile:focus-within img {
		transform: scale(1.03);
	}
}
@media (max-width: 768px) {
	.hp-vid-brands__tiles { grid-template-columns: 1fr; }
	.hp-vid-brands__tile img { aspect-ratio: 16 / 9; }
}

/* =============================================================
   Section 05 — Colophon CTA (DARK)
   ============================================================= */
.hp-vid-cta {
	background: var(--color-primary);
	color: var(--color-paper);
	position: relative;
	isolation: isolate;
}
/* Legacy giant "UK" outline watermark from the bespoke Videography CTA
   that pre-dated the shared eb-cta partial. Its stroke is cream, so it
   was invisible while this section sat on the cream ground; now the CTA
   runs navy site-wide it would suddenly appear on Videography only, top-
   right, straight through the action panel. Kept (not deleted) but held
   off so the CTA band reads identically on every page. */
.hp-vid-cta::before {
	content: none;
	position: absolute;
	top: clamp(3rem, 6vw, 5rem);
	right: clamp(1rem, 4vw, 3.5rem);
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(10rem, 28vw, 26rem);
	line-height: 0.85;
	letter-spacing: -0.06em;
	color: transparent;
	-webkit-text-stroke: 1.5px rgba(244,241,234,0.14);
	pointer-events: none;
	user-select: none;
	z-index: 0;
}
.hp-vid-cta__inner {
	position: relative;
	z-index: 1;
	padding: clamp(4rem, 8vw, 7rem) clamp(1.25rem, 5vw, 4rem);
	max-width: 1280px;
	margin: 0 auto;
}
.hp-vid-cta__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.75rem, 7.5vw, 6.5rem);
	line-height: 0.92;
	letter-spacing: -0.035em;
	margin: 0 0 clamp(2rem, 4vw, 3rem);
	color: var(--color-paper);
}
.hp-vid-cta__line { display: block; }
.hp-vid-cta__line--accent { padding-left: clamp(1.5rem, 4vw, 3rem); }
.hp-vid-cta__amp {
	color: var(--color-accent);
	font-style: italic;
	margin-right: 0.18em;
}
.hp-vid-cta__paras {
	display: flex;
	flex-direction: column;
	gap: 1rem;
	max-width: 52rem;
	margin-bottom: clamp(2.5rem, 4vw, 3.5rem);
}
.hp-vid-cta__paras p {
	font-family: var(--font-heading-family);
	font-weight: 500;
	font-size: clamp(1.05rem, 1.4vw, 1.3rem);
	line-height: 1.5;
	margin: 0;
	color: rgba(244,241,234,0.92);
}
.hp-vid-cta__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 1rem;
	margin-bottom: clamp(2.5rem, 4vw, 3.5rem);
}
.hp-vid-cta__regions {
	list-style: none;
	padding: 1.25rem 0 0;
	margin: 0;
	border-top: 1px solid rgba(244,241,234,0.22);
	display: flex;
	flex-wrap: wrap;
	gap: 0.6rem;
}
.hp-vid-cta__regions li {
	font-family: var(--font-body-family);
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	padding: 0.55rem 0.85rem;
	border: 1px solid var(--color-paper);
	color: var(--color-paper);
}
.hp-vid-cta__footrule {
	display: flex;
	gap: 1rem;
	padding: 0.9rem clamp(1.25rem, 5vw, 4rem);
	border-top: 1px solid rgba(244,241,234,0.18);
	justify-content: space-between;
	color: rgba(244,241,234,0.65);
	position: relative;
	z-index: 1;
}

/* ---- Section-specific brutalism touches ---- */

/* Italic display run inside H1/H2 lines (faux serif accent) */
.hp-vid-impact__italic,
.hp-vid-kit__italic,
.hp-vid-brands__italic {
	font-style: italic;
	font-weight: 700;
	color: var(--color-accent);
}

/* Impact section — "filed under" mono note + multi-column body */
.hp-vid-impact__filed { margin: 1.25rem 0 0; color: rgba(0,0,16,0.55); }
.hp-vid-impact__cols { margin: 1.5rem 0 2rem; }

/* Hero — pink mark-bg highlight on the H1 (signature brutalism move) */
.hp-vid-hero__line--mark { padding-left: clamp(1.5rem, 5vw, 4rem); }
.hp-vid-hero__mark {
	position: relative;
	display: inline-block;
	padding: 0 0.25em;
	line-height: 0.95;
}
.hp-vid-hero__mark-bg {
	position: absolute;
	inset: 0.18em 0 0.12em;
	background: var(--color-accent);
	z-index: 0;
}
.hp-vid-hero__mark-text {
	position: relative;
	z-index: 1;
	color: var(--color-paper);
}

/* Hero — vertical caption pinned below the index */
.hp-vid-hero__index .hp-vid-vertical-caption { align-self: flex-start; margin-top: 1.25rem; }
.hp-vid-hero__index .hp-vid-stamp { margin: 0.75rem 0; }

/* Hero — masthead cell value should not overflow */
.hp-vid-masthead__cell .hp-vid-masthead__v {
	overflow: hidden;
	text-overflow: ellipsis;
}

/* Produce — outlined display numerals, dotted leader, mono ref footer */
.hp-vid-produce__ledger {
	grid-template-columns: clamp(5rem, 9vw, 8rem) 1fr 2rem;
	gap: clamp(1rem, 3vw, 2.5rem);
	margin-bottom: 0;
}
.hp-vid-produce__leader { margin: 0 0 1rem; }
.hp-vid-produce__tag { color: var(--color-accent); margin: 0; white-space: nowrap; }
.hp-vid-produce__format { color: rgba(0,0,16,0.6); margin: 0; white-space: nowrap; text-align: right; }
.hp-vid-produce__ref {
	margin: 1rem 0 0;
	color: rgba(0,0,16,0.45);
	font-size: 0.68rem;
	letter-spacing: 0.12em;
}
.hp-vid-produce__list { border-top: 0; }

/* Brands — 4-column ledger row */
.hp-vid-brands__ledger,
.hp-vid-brands__row {
	grid-template-columns: clamp(3rem, 5vw, 4.5rem) minmax(0, 1.4fr) minmax(0, 1.2fr) clamp(4rem, 6vw, 6rem);
}
.hp-vid-brands__since {
	color: rgba(0,0,16,0.55);
	text-align: right;
	font-size: 0.85rem;
	letter-spacing: 0.06em;
}
.hp-vid-brands__list { border-top: 0; }

/* CTA — italic accent line, regions ledger */
.hp-vid-cta__line--accent { font-style: italic; font-weight: 700; }
.hp-vid-cta__amp { font-style: italic; }
.hp-vid-cta__ledger {
	grid-template-columns: 1fr auto;
	color: var(--color-paper);
	margin: 0 0 1.25rem;
}
.hp-vid-cta__regions { border-top: 0; padding-top: 0; }
.hp-vid-cta .hp-vid-stamp--fixed-tr {
	color: var(--color-accent);
	border-color: var(--color-accent);
}

/* =============================================================
   Tablet down
   ============================================================= */
@media (max-width: 1100px) {
	.hp-vid-masthead { grid-template-columns: 1fr 1fr; }
	.hp-vid-masthead__cell:nth-child(2) { border-right: 0; }
	.hp-vid-masthead__cell:nth-child(1),
	.hp-vid-masthead__cell:nth-child(2) { border-bottom: 1px solid rgba(0,0,16,0.2); }
	.hp-vid-cols2 { column-count: 1; }
	.hp-vid-cols2 > p { font-size: 1.05rem; }
}

@media (max-width: 960px) {
	.hp-vid-section__head { flex-wrap: wrap; }

	.hp-vid-hero__inner { grid-template-columns: 1fr; }
	.hp-vid-hero__index {
		flex-direction: row;
		align-items: center;
		gap: 1rem;
		border-right: none;
		border-bottom: 1px solid rgba(0,0,16,0.18);
		padding: 0 0 1.25rem;
		position: static;
	}
	.hp-vid-hero__line--inset { padding-left: 1.5rem; }

	.hp-vid-impact__inner { grid-template-columns: 1fr; }
	.hp-vid-impact__head { position: static; }

	.hp-vid-kit__inner { grid-template-columns: 1fr; }
	.hp-vid-kit__rail {
		flex-direction: row;
		gap: 1rem;
		border-right: none;
		border-bottom: 1px solid rgba(244,241,234,0.18);
		padding: 0 0 1.25rem;
	}
	.hp-vid-kit__badges {
		flex-direction: row;
		flex-wrap: wrap;
		align-items: flex-start;
	}
	.hp-vid-badge { width: clamp(6rem, 22vw, 8rem); }

	.hp-vid-produce__row {
		grid-template-columns: clamp(4rem, 12vw, 6rem) 1fr;
		gap: 1rem;
	}
	.hp-vid-produce__corner { display: none; }

	.hp-vid-brands__ledger,
	.hp-vid-brands__row {
		grid-template-columns: clamp(3rem, 12vw, 4rem) 1fr clamp(3.5rem, 12vw, 5rem);
		row-gap: 0.3rem;
	}
	.hp-vid-brands__ledger > span:nth-child(3),
	.hp-vid-brands__label { grid-column: 2 / 3; }
	.hp-vid-brands__ledger > span:nth-child(4),
	.hp-vid-brands__since { grid-column: 3; }

	.hp-vid-cta__line--accent { padding-left: 1.25rem; }
	.hp-vid-kit::before,
	.hp-vid-cta::before { font-size: clamp(6rem, 24vw, 14rem); }
}

@media (max-width: 560px) {
	.hp-vid-hero__topbar,
	.hp-vid-hero__footrule,
	.hp-vid-cta__footrule {
		flex-direction: column;
		gap: 0.4rem;
		align-items: flex-start;
	}
	.hp-vid-mono--right { margin-left: 0; }
	.hp-vid-section__head { padding: 0.9rem 1.25rem; }
	.hp-vid-hero__line--inset { padding-left: 0; }
	.hp-vid-hero__pull { padding-left: 1rem; border-left-width: 3px; }
	.hp-vid-hero__pull-mark { right: 0; bottom: -1.4rem; }
	.hp-vid-impact__statement { font-size: 1.35rem; }
	.hp-vid-produce__num { font-size: 2.25rem; }
	.hp-vid-brands__name { font-size: 1.5rem; }
	.hp-vid-cta__line--accent { padding-left: 0; }
}



/* ============== LIB-00 — Hero ============== */

.hp-eb-hero {
	min-height: clamp(640px, 92vh, 1100px);
	padding:
		clamp(7rem, 18vh, 12rem)
		max(var(--eb-channel-w), clamp(1.25rem, 4vw, 3rem))
		clamp(5rem, 10vh, 8rem);
	display: flex;
	align-items: stretch;
}
.hp-eb-hero__inner {
	width: 100%;
	max-width: 1480px;
	margin-inline: auto;
	display: grid;
	/* Three-column grid: copy | thread-channel | media. The middle
	   column is an EXPLICIT layout track that the thread runs inside;
	   no text or image can grow into it (R-10 strict-channel rule). */
	grid-template-columns:
		minmax(0, 1.35fr)
		clamp(60px, 7vw, 130px)
		minmax(0, 1fr);
	column-gap: clamp(1.25rem, 2.4vw, 2rem);
	align-items: start;
	position: relative;
	z-index: 1;
}
.hp-eb-hero__copy {
	grid-column: 1;
	display: flex;
	flex-direction: column;
	gap: clamp(1.5rem, 3vw, 2.75rem);
	/* Belt + braces: also cap the H1 and lead so they cannot bleed
	   into the thread channel under any wrap condition. */
	min-width: 0;
}
.hp-eb-hero__channel {
	grid-column: 2;
	/* Empty layout track reserved for the brand thread. To debug:
	   `background: rgba(255,0,0,0.2);` — only the thread should
	   appear inside this strip. */
	pointer-events: none;
}
.hp-eb-hero__media { grid-column: 3; }
.hp-eb-hero__h1 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	/* Sized so the longest stair-stack line ("East Anglia's" / "SEO
	   Agency") always fits inside the copy column at 3-col widths. */
	font-size: clamp(2.25rem, 6.5vw, 6rem);
	line-height: 0.96;
	letter-spacing: -0.02em;
	margin: 0;
	text-wrap: balance;
	hyphens: none;
	overflow-wrap: break-word;
}
.hp-eb-hero__line { display: block; }
/* Period dot — anchor for wireSeoHeroThread.
   Rendered as a styled inline-block circle (not the font's "." glyph)
   so the span's bounding-box centre and the visible dot's centre are
   the same point. The previous "real . character" approach made the
   span as tall as the line-height, so the JS computed an anchor in
   the middle of the line while the visible glyph sat at the baseline,
   producing two stacked pink dots. The inline "." character inside the
   span is hidden via color: transparent — it's still in the DOM for
   screen readers / copy-paste so the H1 reads as a normal sentence. */
.hp-eb-hero__dot {
	display: inline-block;
	width: 0.18em;
	height: 0.18em;
	margin-left: 0.08em;
	vertical-align: 0.05em;
	background: var(--eb-thread);
	border-radius: 50%;
	color: transparent;
	-webkit-text-fill-color: transparent;
	overflow: hidden;
	font-size: inherit;
	line-height: 1;
}
/* Simple pink full-stop that replaces the old .hp-eb-hero__dot circle on
   the hero H1. It is a real "." glyph (not an inline-block box), so it
   stays attached to the last word and never wraps onto its own line — the
   responsive fix. Colour is forced with -webkit-text-fill-color too, in
   case the H1 ever carries a gradient text-fill. */
.hp-eb-hero__period {
	color: var(--eb-thread);
	-webkit-text-fill-color: var(--eb-thread);
	font: inherit;
}
/* Glue wrapper for "word + period". The H1 carries an emergency
   overflow-wrap: break-word, which is allowed to break BETWEEN the last
   word and the .hp-eb-hero__period span when the word barely fits the
   copy column — leaving the pink dot alone on its own line. nowrap
   disables every soft-wrap opportunity inside the pair. */
.hp-eb-hero__nowrap,
.hp-title-nobreak {
	/* .hp-title-nobreak is hp_dotted_title()'s wrapper — also declared in
	   work.css, but the legal / sitemap / coming-soon templates only load
	   main.css, so the token must exist here too. */
	white-space: nowrap;
}
.hp-eb-hero__lead {
	font-size: clamp(1.05rem, 1.55vw, 1.35rem);
	line-height: 1.55;
	max-width: 56ch;
	margin: 0;
}
/* Hero sub-line (verbatim "No inexperienced 'account managers' here…"
   from source doc). Sits below the lead, smaller, with the brand
   accent dot before it. */
.hp-eb-hero__sub {
	font-size: clamp(0.95rem, 1.15vw, 1.1rem);
	line-height: 1.5;
	max-width: 50ch;
	margin: 0;
	padding-left: 1.2rem;
	position: relative;
	opacity: 0.9;
}
.hp-eb-hero__sub::before {
	content: "";
	position: absolute;
	left: 0;
	top: 50%;
	transform: translateY(calc(-50% - 0.15em));
	width: 0.5rem;
	height: 0.5rem;
	background: var(--eb-thread);
	border-radius: 50%;
}
/* CTA cluster — LIB-00 optional variant (R: see plan). Primary +
   secondary side-by-side on desktop, stacks to column on mobile. Stays
   inside the copy column; never extends into the thread channel. */
.hp-eb-hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: clamp(0.75rem, 1.4vw, 1.25rem);
	margin-top: clamp(0.5rem, 1vw, 1rem);
}
.hp-eb-hero__actions .hp-btn { flex: 0 1 auto; }
/* Phones: the CTA sits to its own width, not edge to edge.
   Full-bleed made a single button read as a banner rather than a button, and
   with the phone CTA gone from every hero there is no second pill that needs
   to line up with it. align-items: flex-start stops the column stretching it
   back out. Applies to every EB hero, so all pages match. */
@media (max-width: 560px) {
	.hp-eb-hero__actions { flex-direction: column; align-items: flex-start; }
	.hp-eb-hero__actions .hp-btn { width: auto; justify-content: center; }
}
.hp-eb-hero__media {
	grid-column: 3;
	position: relative;
	align-self: stretch;
	margin-top: clamp(0rem, 4vw, 3rem);
	border-radius: 8px;
	overflow: hidden;
	aspect-ratio: 4 / 5;
	background: color-mix(in oklab, var(--eb-from-bg) 80%, black);
}
.hp-eb-hero__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	filter: grayscale(1) contrast(1.1);
	mix-blend-mode: luminosity;
	opacity: 0.92;
	transition: filter 0.45s ease, mix-blend-mode 0.45s ease, opacity 0.45s ease;
}
.hp-eb-hero__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background:
		linear-gradient(
			145deg,
			color-mix(in oklab, var(--eb-thread) 35%, transparent),
			color-mix(in oklab, var(--eb-from-bg) 60%, transparent) 65%
		);
	mix-blend-mode: multiply;
	pointer-events: none;
	opacity: 1;
	transition: opacity 0.45s ease;
}
/* Duotone → full colour on hover (R-11). Desktop only — touch devices
   keep the duotone rest state so we don't get a stuck-on hover after a
   tap. */
@media (hover: hover) and (pointer: fine) {
	.hp-eb-hero__media:hover img,
	.hp-eb-hero__media:focus-within img {
		filter: none;
		mix-blend-mode: normal;
		opacity: 1;
	}
	.hp-eb-hero__media:hover::after,
	.hp-eb-hero__media:focus-within::after {
		opacity: 0;
	}
}
.hp-eb-hero__media-caption {
	position: absolute;
	left: clamp(0.75rem, 1.5vw, 1.5rem);
	bottom: clamp(0.75rem, 1.5vw, 1.5rem);
	font-size: 0.75rem;
	letter-spacing: 0.04em;
	color: var(--eb-ink-on-saturated);
	background: color-mix(in oklab, var(--eb-from-bg) 70%, transparent);
	padding: 0.35rem 0.65rem;
	border-radius: 2px;
}
/* Hero brand thread — reuses the existing wireSeoHeroThread JS, which
   the migrated partial keeps. Channel-aware: stroke runs in the
   right-side gutter so it doesn't cross the copy column. */
.hp-eb-hero-thread {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	z-index: 0;
}
.hp-eb-hero-thread .hp-ribbon__path {
	stroke: var(--eb-thread);
	/* Matches the homepage brand-thread's VISIBLE thickness (~22-30px)
	   across every internal-page hero. The homepage scales stroke to
	   the .hp-hero__dot diameter; here we use a clamped fixed range
	   so SEO / PPC / Vid heroes all read at the same weight. */
	stroke-width: clamp(22px, 2vw, 30px);
}

@media (max-width: 1024px) {
	/* Both selectors listed so this beats the elevated-specificity
	   .hp-seo-hero .hp-eb-hero__inner (0,2,0) declared outside this query;
	   without the .hp-seo-hero variant the About / SEO / PPC heroes keep
	   their desktop 3-column grid on mobile and never stack. */
	.hp-eb-hero__inner,
	.hp-seo-hero .hp-eb-hero__inner {
		grid-template-columns: 1fr;
	}
	.hp-eb-hero__copy { grid-column: 1; }
	/* Below 1024px the explicit thread channel collapses to right padding
	   on the section so the thread still has clear space along the right
	   edge of the viewport. */
	.hp-eb-hero { padding-right: max(var(--eb-channel-w), 1.5rem); }
	.hp-eb-hero__channel { display: none; }
	.hp-eb-hero__media {
		grid-column: 1;
		aspect-ratio: 5 / 4;
		order: -1;
	}
}

/* ============== Web Design hero (page-specific override) ============== */
/* Replaces LIB-00's 3-col grid for the Web Design page only:
   Row 1 — H1 full width + sub full width.
   Row 2 — 30% copy + buttons / 70% image. Image stretches to match
   the copy column's height so the row sits as a single balanced block. */

.hp-wd-hero {
	/* Inherits .hp-eb-hero base for padding + min-height; overrides the
	   block padding. Top padding keeps the H1 clear of the pill nav.
	   Bottom padding is matched to the "Outperform" (Why Our Websites)
	   section — clamp(6rem, 14vh, 12rem) — so the gap below the hero is
	   consistent with the spacing used between the sections below it
	   (per user spec: the old ~340px bottom made the hero an outlier). */
	padding-top:    clamp(8rem, 14vh, 12rem);
	padding-bottom: clamp(6rem, 14vh, 12rem);
	padding-left:  clamp(1.5rem, 5vw, 6rem);
	padding-right: clamp(1.5rem, 5vw, 6rem);
}
.hp-wd-hero__inner {
	width: 100%;
	/* Full-width — no max-width / margin-inline. Fills the section's
	   padded box edge to edge. */
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	/* Row 1 (H1 + sub-headline) reads as ONE group, so the gap down to
	   row 2 (lead copy + image) is deliberately much larger than the
	   internal gap inside row 1 — see .hp-wd-hero__top below. */
	gap: clamp(3.5rem, 7vw, 7rem);
}
.hp-wd-hero__top {
	display: flex;
	flex-direction: column;
	/* Tight gap between the H1 and "Your website should win…" — the two
	   read as one unit; the real space is __inner's gap below them. */
	gap: clamp(0.5rem, 1vw, 1rem);
}
.hp-wd-hero__h1 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	/* Slope+intercept clamp so the H1 scales smoothly across the full
	   desktop range — 44px @ 320, ~123px @ 1280, 176px @ 1920. The
	   previous `10vw` middle term hit max too early on medium desktop
	   and stayed stuck. */
	font-size: clamp(2.75rem, calc(1.1rem + 8.25vw), 11rem);
	/* Line-height bumped from 0.96 → 1.08 so the two stair-stack lines
	   ("Web Design Agency" / "Suffolk & Cambridge.") have breathing
	   room between them. */
	line-height: 1.08;
	letter-spacing: -0.02em;
	margin: 0;
	max-width: 100%;
	text-wrap: balance;
}
.hp-wd-hero__sub {
	/* Slope+intercept — scales linearly with viewport across the desktop
	   range instead of snapping to floor/max at the ends. */
	font-size: clamp(1.15rem, calc(0.9rem + 1.125vw), 2.25rem);
	line-height: 1.35;
	letter-spacing: -0.005em;
	margin: 0;
	max-width: 50ch;
	opacity: 0.92;
}
.hp-wd-hero__bottom {
	display: grid;
	grid-template-columns: 30% 1fr;
	column-gap: clamp(2rem, 4vw, 4rem);
	align-items: stretch;
}
.hp-wd-hero__copy {
	display: flex;
	flex-direction: column;
	gap: clamp(1.25rem, 2.4vw, 2rem);
	min-width: 0;
}
.hp-wd-hero__lead {
	/* Slope+intercept — 15px @ 320, 19px @ 1024, 22px @ 1600, 24px @
	   1920. Smooth desktop-wide scaling instead of long floor-stuck
	   stretch from earlier `1.2vw` middle term. */
	font-size: clamp(0.95rem, calc(0.825rem + 0.5625vw), 1.5rem);
	line-height: 1.6;
	margin: 0;
	opacity: 0.95;
}
.hp-wd-hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: clamp(0.6rem, 1vw, 0.85rem);
	/* Buttons sit IMMEDIATELY after the lead ("…furious."), not pinned
	   to the column bottom. The thread then anchors 30px below them. */
	margin-top: clamp(0.25rem, 0.5vw, 0.5rem);
}
.hp-wd-hero__actions .hp-btn { flex: 0 1 auto; }

/* Custom hero brand-thread — emerges 30px below the buttons, runs
   horizontal right across the copy column, steps down 30px at the
   30% column boundary, then runs horizontal right across the image
   column and exits the section right edge. Path is computed live by
   wireWdHeroThread (main.js) so it tracks the buttons' real position. */
.hp-wd-hero__thread {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	z-index: 2;
	overflow: visible;
}
.hp-wd-hero__thread path {
	fill: none;
	stroke: var(--color-accent);
	/* Matches the homepage brand-thread's VISIBLE thickness (~22-30px
	   depending on viewport — homepage scales stroke to .hp-hero__dot
	   diameter via wireScrollRibbon). Was a flat 18 which read thinner
	   than the homepage. */
	stroke-width: clamp(22px, 2vw, 30px);
	stroke-linecap: round;
	stroke-linejoin: round;
}
.hp-wd-hero__media {
	margin: 0;
	border-radius: 8px;
	overflow: hidden;
	background: color-mix(in oklab, var(--eb-from-bg, var(--color-primary)) 80%, black);
	position: relative;
	min-height: 100%;
}
.hp-wd-hero__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	min-height: 360px; /* keeps image readable if the copy column is short */
	filter: grayscale(1) contrast(1.1);
	mix-blend-mode: luminosity;
	opacity: 0.92;
	transition: filter 0.45s ease, mix-blend-mode 0.45s ease, opacity 0.45s ease;
}
.hp-wd-hero__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background:
		linear-gradient(
			145deg,
			color-mix(in oklab, var(--eb-thread) 32%, transparent),
			color-mix(in oklab, var(--eb-from-bg, var(--color-primary)) 55%, transparent) 65%
		);
	mix-blend-mode: multiply;
	pointer-events: none;
	opacity: 1;
	transition: opacity 0.45s ease;
}
@media (hover: hover) and (pointer: fine) {
	.hp-wd-hero__media:hover img,
	.hp-wd-hero__media:focus-within img {
		filter: none;
		mix-blend-mode: normal;
		opacity: 1;
	}
	.hp-wd-hero__media:hover::after,
	.hp-wd-hero__media:focus-within::after {
		opacity: 0;
	}
}

/* Below 900px the 30/70 collapses; image moves above the copy block
   so the dual CTAs stay in tap-reach without scrolling past the image. */
@media (max-width: 900px) {
	.hp-wd-hero__bottom {
		grid-template-columns: 1fr;
		row-gap: clamp(1.5rem, 3vw, 2.5rem);
	}
	.hp-wd-hero__media {
		order: -1;
		min-height: 0;
		aspect-ratio: 16 / 10;
	}
	.hp-wd-hero__media img { min-height: 0; }
}

/* ============== Web Design "Outperform" (page-specific) ==============
   Ordinary flow: gradient H2, then body copy + image stacked beneath.
   This was formerly a 360vh sticky-pinned crossfade (two overlapping
   states driven by --h2-op / --body-op from wireOutperformSwap). */

.hp-wd-outperform {
	position: relative;
	/* NORMAL FLOW — the 360vh sticky pin was removed per user request.
	   While the inner was pinned the section's box stopped moving
	   relative to the viewport, so the brand thread (whose draw maps
	   onto that box) had no travel to animate against and read as
	   static. Height is now driven by content. */
	background: var(--color-primary);
	color: var(--color-paper);
	overflow: visible;
	/* Breathing band of navy ground between this section's content and
	   the start of the next one. */
	padding-bottom: clamp(6rem, 14vh, 12rem);
}
.hp-wd-outperform__inner {
	/* Full-width layout with bigger left/right padding (per user spec
	   — was boxed via max-width on .__states). Padding scales with the
	   viewport so the content never touches the edges but uses the
	   full available width on big screens. */
	padding:
		clamp(4rem, 12vh, 8rem)
		clamp(1.5rem, 5vw, 6rem);
}
.hp-wd-outperform__states {
	width: 100%;
	/* No max-width / margin-inline — full-width fills the inner's
	   padded box edge to edge. */
}
.hp-wd-outperform__state {
	display: flex;
	flex-direction: column;
	align-items: center;
}
.hp-wd-outperform__state--heading {
	/* Left-aligned (not centred) — the brutalist oversized H2 anchored
	   to the section's content edge. */
	align-items: flex-start;
	text-align: left;
	margin-bottom: clamp(3rem, 9vh, 6rem);
}
.hp-wd-outperform__state--body {
	width: 100%;
}
.hp-wd-outperform__state--body .hp-wd-outperform__body-grid {
	align-items: start;
}
.hp-wd-outperform__h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	/* Brutalist scale — slope+intercept so the H2 scales smoothly
	   across desktop. 56px @ 320, ~109px @ 1024, ~128px @ 1280, 176px
	   @ 1920. Replaces `11vw` which clamped early. */
	font-size: clamp(3.5rem, calc(2rem + 7.5vw), 11rem);
	line-height: 0.92;
	letter-spacing: -0.03em;
	margin: 0;
	max-width: none;
	text-align: left;
	text-wrap: balance;
	overflow-wrap: break-word;
	/* Glyph-ascent guard is now handled by the gradient inner's
	   padding-top: 0.15em (above). Drop the H2's padding-block-start
	   so the heading shifts UP by ~0.12em — matches user spec ("move
	   it up a little bit"). */
	padding-block-start: 0;
}
/* Body state — image LEFT, text RIGHT (swapped per user spec — image
   was on the right; reordered so the visual anchor leads and the
   reading column trails). */
.hp-wd-outperform__body-grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	column-gap: clamp(2rem, 5vw, 5rem);
	row-gap: clamp(1.5rem, 3vw, 2.5rem);
	align-items: center;
	/* Centre both columns within their tracks so the image (left) and
	   the 50ch text measure (right) sit at the visual middle of each
	   track — balanced composition. */
	justify-items: center;
}
.hp-wd-outperform__media { order: -1; }   /* image FIRST → left column */
.hp-wd-outperform__text  { order:  1; }   /* text  SECOND → right column */
.hp-wd-outperform__text {
	display: flex;
	flex-direction: column;
	gap: clamp(1rem, 1.6vw, 1.4rem);
	/* Body column locked to a narrow editorial measure: 50ch on
	   desktop, 70% of the column on mobile. */
	width: 50ch;
	max-width: 100%;
}
.hp-wd-outperform__text p {
	/* Body text clamped — 18px on mobile through 25px on large
	   desktop, scaling smoothly between. Replaces the fixed 25px /
	   mobile-override 18px so it adapts at every viewport width. */
	font-size: clamp(1.125rem, 1vw + 0.6rem, 1.5625rem);
	line-height: 1.5;
	margin: 0;
	color: var(--color-paper);
}
.hp-wd-outperform__media {
	margin: 0;
	border-radius: 8px;
	overflow: hidden;
	aspect-ratio: 4 / 3;
	position: relative;
	/* Match the section's saturated ground (var(--color-primary)) so the
	   mockup box reads as one colour with the background instead of a darker
	   rectangle behind the semi-transparent image. */
	background: var(--color-primary);
}
.hp-wd-outperform__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	filter: grayscale(1) contrast(1.05);
	opacity: 0.7;
	transition: filter 0.45s ease, opacity 0.45s ease;
}
@media (hover: hover) and (pointer: fine) {
	.hp-wd-outperform__media:hover img,
	.hp-wd-outperform__media:focus-within img {
		filter: none;
		opacity: 1;
	}
}

/* Brand thread on the right edge — vertical stroke draws in as the
   user scrolls through the section. Path is computed by
   wireOutperformThread (main.js). */
.hp-wd-outperform__thread {
	position: absolute;
	top: 0;
	right: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	z-index: 2;
	overflow: visible;
}
.hp-wd-outperform__thread path {
	fill: none;
	stroke: var(--color-accent);
	stroke-width: clamp(22px, 2vw, 30px);
	stroke-linecap: round;
	stroke-linejoin: round;
}

@media (max-width: 900px) {
	/* Single column, and STRETCH both items to the full track. The desktop
	   grid uses justify-items:center (each item shrinks to content), which
	   on one column left the text as a narrow, centred measure with big
	   gaps either side and let the image size independently — so image and
	   text no longer lined up. Stretch makes them share identical edges. */
	.hp-wd-outperform__body-grid {
		grid-template-columns: 1fr;
		justify-items: stretch;
	}
	.hp-wd-outperform__media { aspect-ratio: 16 / 10; order: -1; width: 100%; }
	.hp-wd-outperform__text { width: 100%; }
	/* font-size override removed — the body clamp above handles mobile. */
}

/* Outperform — phone tuning. The old ≤768px block here existed to UNPIN
   the section on mobile (the sticky 360vh range was rebuilt every time a
   mobile browser toolbar collapsed, so the block shook). The pin is gone
   at every width now, so only the genuine small-screen type fixes remain. */
@media (max-width: 768px) {
	.hp-wd-outperform {
		/* The inner's own padding-block already spaces the bottom; the
		   extra desktop band doubled up and made the bottom gap far
		   bigger than the top. Zero balances top and bottom exactly. */
		padding-bottom: 0;
	}
	.hp-wd-outperform__inner {
		padding-block: clamp(4rem, 12vh, 7rem);
	}
	.hp-wd-outperform__state--heading {
		margin-bottom: clamp(2rem, 7vh, 3.5rem);
	}
	/* Brutalist H2's 56px floor overflows narrow phones on its longest
	   word ("Competition."). Lower the floor so it wraps instead of
	   forcing a horizontal scrollbar. */
	.hp-wd-outperform__h2 {
		font-size: clamp(2.5rem, 11vw, 4rem);
		overflow-wrap: break-word;
	}
	/* Full-width reading column (the 70% above is too pinched on a phone). */
	.hp-wd-outperform__text { width: 100%; }
}

/* ============== Web Design "Perform" (page-specific) ==============
   Three-column layout: H2 / body / image. Drops the .hp-scroll-color
   treatment that produced white-on-white on this LIGHT ground. */

.hp-wd-perform {
	/* Overflow visible so the brand-thread SVG can extend past the
	   section's bottom edge (its bottom horizontal anchors 80px above
	   the NEXT section's H2, which sits below this section). Left/right
	   padding matches the page-wide full-width clamp (per user spec —
	   was boxed via max-width on .__inner). */
	overflow: visible !important;
	/* Block padding bumped per user spec — every WD section gets more
	   vertical breathing room. Was clamp(6rem, 12vh, 10rem). */
	padding:
		clamp(9rem, 18vh, 16rem)
		clamp(1.5rem, 5vw, 6rem);
	position: relative;
}
.hp-wd-perform__inner {
	width: 100%;
	/* Full-width — no max-width / margin-inline. Fills the section's
	   padded box edge to edge. */
	display: grid;
	/* image (col 1) | H2 (col 2) | body (col 3) */
	grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr) minmax(0, 1.1fr);
	/* Maximised gaps so the H2 and body have visible breathing space
	   between them and from the image (user request). */
	column-gap: clamp(3rem, 6vw, 6rem);
	row-gap: clamp(3rem, 5vw, 4rem);
	align-items: start;
}

/* Brand thread inside the perform section. Enters from the right
   (off-canvas), runs LEFT 80px below the H2, wraps around the image
   on its right edge (80px gap), drops down to 80px above the next
   section's heading, then exits right. Computed live by
   wirePerformThread (main.js). */
.hp-wd-perform__thread {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	pointer-events: none;
	z-index: 2;
	overflow: visible;
}
.hp-wd-perform__thread path {
	fill: none;
	stroke: var(--color-accent);
	stroke-width: clamp(22px, 2vw, 30px);
	stroke-linecap: round;
	stroke-linejoin: round;
}
.hp-wd-perform__title { min-width: 0; }
.hp-wd-perform__h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	/* Slope+intercept — 32px @ 320, ~67px @ 1024, ~80px @ 1280, 96px
	   @ 1920. Max bumped down from 7rem → 6rem per user spec. */
	font-size: clamp(2rem, calc(1rem + 5vw), 6rem);
	line-height: 1.02;
	letter-spacing: -0.02em;
	margin: 0;
	max-width: 14ch;
	text-wrap: balance;
}

/* Sequence variant — H2 uses the homepage outro line-lighting effect:
   each .hp-outro__line lights pink in turn as the user scrolls, then
   settles on the last (period-anchored) line. The container is flex
   column so the three lines stack with the same tight brutalist
   line-height as the H2's own. The section sits on the SATURATED navy
   ground throughout (it used to self-shift out of cream), so the unlit
   colour is a flat paper. */
.hp-wd-perform__h2--seq {
	display: flex;
	flex-direction: column;
}
.hp-wd-perform__h2--seq .hp-outro__line {
	display: block;
	--dist: max(calc(var(--i) - var(--active, 999)), calc(var(--active, 999) - var(--i)));
	--lit: clamp(0, calc(1 - var(--dist)), 1);
	/* Unlit = paper on the navy ground. Lit = pink. */
	color: color-mix(
		in srgb,
		var(--color-accent) calc(var(--lit) * 100%),
		var(--color-paper)
	);
	transition: color 0.12s linear;
}
@supports not (color: color-mix(in srgb, red, blue)) {
	.hp-wd-perform__h2--seq .hp-outro__line {
		color: var(--color-paper);
	}
}

/* Perform body — no colour override needed. The section is on the
   SATURATED navy ground for its whole scroll, which is exactly what
   the default .hp-scroll-color__word recipe in main.css is tuned for
   (dim paper at a 0.52 floor → full paper). The previous nested
   color-mix here existed only to track the light → saturated
   self-shift, which has been removed. */
.hp-wd-perform__body { min-width: 0; }
.hp-wd-perform__body p {
	/* Slope+intercept — 16px @ 320, ~19px @ 1024, ~21px @ 1280, 24px
	   @ 1920. Scales linearly across desktop. */
	font-size: clamp(1rem, calc(0.9rem + 0.5vw), 1.5rem);
	line-height: 1.65;
	margin: 0;
	max-width: 48ch;
}
.hp-wd-perform__media {
	margin: 0;
	border-radius: 8px;
	overflow: hidden;
	aspect-ratio: 4 / 5;
	position: relative;
	background: color-mix(in oklab, currentColor 10%, transparent);
}
.hp-wd-perform__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	filter: grayscale(1) contrast(1.1);
	mix-blend-mode: luminosity;
	opacity: 0.92;
	transition: filter 0.45s ease, mix-blend-mode 0.45s ease, opacity 0.45s ease;
}
.hp-wd-perform__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background:
		linear-gradient(
			145deg,
			color-mix(in oklab, var(--eb-thread) 28%, transparent),
			color-mix(in oklab, currentColor 18%, transparent) 65%
		);
	mix-blend-mode: multiply;
	pointer-events: none;
	opacity: 1;
	transition: opacity 0.45s ease;
}
@media (hover: hover) and (pointer: fine) {
	.hp-wd-perform__media:hover img,
	.hp-wd-perform__media:focus-within img {
		filter: none;
		mix-blend-mode: normal;
		opacity: 1;
	}
	.hp-wd-perform__media:hover::after,
	.hp-wd-perform__media:focus-within::after {
		opacity: 0;
	}
}

@media (max-width: 1024px) {
	.hp-wd-perform__inner {
		grid-template-columns: 1fr;
	}
	/* Image stays first on mobile too — title and body stack beneath. */
	.hp-wd-perform__media {
		aspect-ratio: 16 / 10;
	}
	/* Thread hides once the grid stacks. Single-column puts the image at
	   full width and leaves only ~50px between the H2's bottom and the
	   body copy, so there is no channel for the ribbon to wrap or drop
	   through — wirePerformThread's fallback could only draw a ~390px nub
	   in the bottom-right corner, which read as a broken/shrunken ribbon.
	   Same rule the outperform thread already applies below 900px. Above
	   this breakpoint the full wrap now fits at every width. */
	.hp-wd-perform__thread { display: none; }
}

/* ============== LIB-11 — Stats Strip ============== */

.hp-eb-stats {
	padding:
		clamp(3.5rem, 7vh, 6rem)
		max(var(--eb-channel-w), clamp(1.25rem, 4vw, 3rem));
}
.hp-eb-stats__inner {
	width: 100%;
	max-width: 1480px;
	margin-inline: auto;
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 0;
}
.hp-eb-stats__cell {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	padding: clamp(0.75rem, 1.6vw, 1.5rem) clamp(1rem, 2.4vw, 2rem);
}
.hp-eb-stats__cell + .hp-eb-stats__cell {
	border-left: 1px solid color-mix(in oklab, currentColor 28%, transparent);
}
.hp-eb-stats__num {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.75rem, 7vw, 7rem);
	line-height: 0.95;
	letter-spacing: -0.02em;
	font-variant-numeric: tabular-nums;
}
.hp-eb-stats__lbl {
	font-size: clamp(0.8rem, 1vw, 0.95rem);
	line-height: 1.4;
	max-width: 22ch;
	opacity: 0.85;
}
/* Horizontal thread baseline under the strip — scaleX(0) → 1 on first
   viewport entry (toggle .is-visible via wireRevealOnScroll). Height
   fixed at 18px to match the homepage brand-thread stroke. */
.hp-eb-stats__line {
	margin-top: clamp(2rem, 4vw, 3rem);
	height: 18px;
	width: 100%;
	background: var(--eb-thread);
	border-radius: 999px;
	transform-origin: left center;
	transform: scaleX(0);
	transition: transform 1.1s cubic-bezier(0.22, 1, 0.36, 1);
}
.hp-eb-stats[data-section].is-visible .hp-eb-stats__line { transform: scaleX(1); }

@media (max-width: 900px) {
	.hp-eb-stats__inner {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
	.hp-eb-stats__cell:nth-child(2n+1) { border-left: none; }
	.hp-eb-stats__cell:nth-child(n+3) {
		border-top: 1px solid color-mix(in oklab, currentColor 28%, transparent);
	}
}
@media (max-width: 480px) {
	.hp-eb-stats__inner { grid-template-columns: 1fr; }
	.hp-eb-stats__cell { border-left: none !important; }
	.hp-eb-stats__cell + .hp-eb-stats__cell {
		border-top: 1px solid color-mix(in oklab, currentColor 28%, transparent);
	}
}

/* ============== Simple titled-prose (opportunities) ==============
   Used when a section's source copy is just H2 + N body paragraphs
   with no categorical list / image / additional structure. Falls
   between LIB-03 and LIB-06 — minimal chassis, ground-aware. */

.hp-eb-prose {
	padding:
		clamp(5rem, 10vh, 9rem)
		max(var(--eb-channel-w), clamp(1.25rem, 4vw, 3rem));
}
.hp-eb-prose__inner {
	width: 100%;
	max-width: 1200px;
	margin-inline: auto;
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
	column-gap: clamp(2rem, 5vw, 5rem);
	row-gap: clamp(2rem, 4vw, 3rem);
	align-items: start;
}
.hp-eb-prose__h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.25rem, 5.5vw, 5rem);
	line-height: 1.02;
	letter-spacing: -0.02em;
	margin: 0;
	max-width: 18ch;
}
.hp-eb-prose__body {
	display: flex;
	flex-direction: column;
	gap: clamp(1rem, 1.6vw, 1.4rem);
	max-width: 60ch;
}
.hp-eb-prose__body p {
	margin: 0;
	font-size: clamp(0.95rem, 1.15vw, 1.1rem);
	line-height: 1.65;
	opacity: 0.92;
}

@media (max-width: 1024px) {
	.hp-eb-prose__inner { grid-template-columns: 1fr; }
}

/* ============== LIB-08 — Categorical Approach List ============== */

.hp-eb-approach {
	padding:
		clamp(5rem, 10vh, 9rem)
		max(var(--eb-channel-w), clamp(1.25rem, 4vw, 3rem));
}
.hp-eb-approach__inner {
	width: 100%;
	max-width: 1480px;
	margin-inline: auto;
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
	column-gap: clamp(2rem, 5vw, 5rem);
	row-gap: clamp(2rem, 4vw, 4rem);
	align-items: start;
}
.hp-eb-approach__head { min-width: 0; }
.hp-eb-approach__h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.25rem, 5.5vw, 5rem);
	line-height: 1.02;
	letter-spacing: -0.02em;
	margin: 0 0 clamp(1rem, 2vw, 1.75rem);
}
.hp-eb-approach__h2-em {
	font-style: italic;
	font-weight: 800;
}
.hp-eb-approach__lead {
	font-size: clamp(1rem, 1.4vw, 1.25rem);
	line-height: 1.55;
	max-width: 56ch;
	margin: 0;
}
.hp-eb-approach__list {
	position: relative;
	padding-left: clamp(2.5rem, 4vw, 4rem);
	min-width: 0;
}
.hp-eb-approach__row {
	padding: clamp(1.25rem, 2.4vw, 2rem) 0;
	border-top: 1px solid color-mix(in oklab, currentColor 18%, transparent);
}
.hp-eb-approach__row:first-of-type { border-top: 0; padding-top: 0; }
.hp-eb-approach__row-title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.5rem, 2.4vw, 2.25rem);
	line-height: 1.1;
	letter-spacing: -0.01em;
	margin: 0 0 0.5rem;
}
.hp-eb-approach__row-body {
	font-size: clamp(0.95rem, 1.1vw, 1.05rem);
	line-height: 1.6;
	max-width: 60ch;
	margin: 0;
	opacity: 0.88;
}

/* Progress spine (LIB-08) — wireEbProgressSpine injects .hp-eb-spine__node
   children positioned by JS to align with each .hp-eb-spine-row's H3. */
.hp-eb-spine {
	position: absolute;
	left: clamp(0.5rem, 1.2vw, 1.25rem);
	top: 0;
	bottom: 0;
	/* 18px matches the homepage brand-thread stroke. */
	width: 18px;
	background: color-mix(in oklab, var(--eb-thread) 18%, transparent);
	border-radius: 999px;
	pointer-events: none;
}
.hp-eb-spine__node {
	position: absolute;
	left: 50%;
	width: clamp(18px, 1.8vw, 28px);
	height: clamp(18px, 1.8vw, 28px);
	background: color-mix(in oklab, var(--eb-thread) 20%, transparent);
	border: 2px solid color-mix(in oklab, var(--eb-thread) 30%, transparent);
	border-radius: 50%;
	transform: translate(-50%, -50%) scale(0.6);
	opacity: 0;
	transition: transform 0.55s cubic-bezier(0.22,1,0.36,1), opacity 0.4s ease, background 0.4s ease, border-color 0.4s ease;
}
.hp-eb-spine__node.is-lit {
	background: var(--eb-thread);
	border-color: var(--eb-thread);
	opacity: 1;
	transform: translate(-50%, -50%) scale(1);
	box-shadow: 0 0 0 6px color-mix(in oklab, var(--eb-thread) 20%, transparent);
}

@media (max-width: 1024px) {
	.hp-eb-approach__inner { grid-template-columns: 1fr; }
}

/* ============== LIB-06 — Titled Split-Prose with Image ============== */

.hp-eb-split {
	padding:
		clamp(5rem, 10vh, 9rem)
		max(var(--eb-channel-w), clamp(1.25rem, 4vw, 3rem));
}
.hp-eb-split__inner {
	width: 100%;
	max-width: 1480px;
	margin-inline: auto;
}
.hp-eb-split__h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.25rem, 5.5vw, 5rem);
	line-height: 1.02;
	letter-spacing: -0.02em;
	margin: 0 0 clamp(2rem, 4vw, 3.5rem);
	max-width: 22ch;
}
.hp-eb-split__grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.1fr);
	column-gap: clamp(1.5rem, 3.5vw, 3rem);
	row-gap: clamp(2rem, 4vw, 3rem);
	align-items: start;
}
/* The prose columns hold MULTIPLE paragraphs (About owners, About
   specialists, SEO experts are the only three users, and all three are
   multi-paragraph). Their `p` is margin: 0 and the column had no gap, so
   consecutive paragraphs butted straight together and read as one wall of
   text. Flex + gap gives them the same rhythm the other prose chassis
   (.hp-eb-prose__body) already uses. */
.hp-eb-split__prose {
	display: flex;
	flex-direction: column;
	gap: clamp(0.9rem, 1.5vw, 1.3rem);
	min-width: 0;
}
.hp-eb-split__prose p {
	font-size: clamp(0.95rem, 1.15vw, 1.1rem);
	line-height: 1.65;
	margin: 0;
	max-width: 42ch;
	opacity: 0.92;
}
.hp-eb-split__media {
	grid-column: 3;
	grid-row: 1 / span 2;
	position: relative;
	margin: 0;
	border-radius: 8px;
	overflow: hidden;
	aspect-ratio: 4 / 5;
	background: color-mix(in oklab, currentColor 8%, transparent);
}
.hp-eb-split__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	filter: grayscale(1) contrast(1.1);
	mix-blend-mode: luminosity;
	opacity: 0.92;
	transition: filter 0.45s ease, mix-blend-mode 0.45s ease, opacity 0.45s ease;
}
.hp-eb-split__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background:
		linear-gradient(
			145deg,
			color-mix(in oklab, var(--eb-thread) 30%, transparent),
			color-mix(in oklab, currentColor 25%, transparent) 70%
		);
	mix-blend-mode: multiply;
	pointer-events: none;
	opacity: 1;
	transition: opacity 0.45s ease;
}
@media (hover: hover) and (pointer: fine) {
	.hp-eb-split__media:hover img,
	.hp-eb-split__media:focus-within img {
		filter: none;
		mix-blend-mode: normal;
		opacity: 1;
	}
	.hp-eb-split__media:hover::after,
	.hp-eb-split__media:focus-within::after {
		opacity: 0;
	}
}

@media (max-width: 1024px) {
	/* The --reverse selectors carry an extra .hp-eb-split so they reach
	   (0,3,0) — STRICTLY higher than the (0,2,0) .hp-eb-split--reverse
	   desktop rules declared later in the file. Equal specificity is not
	   enough: a later equal-specificity rule wins on source order, which is
	   why the reverse "Built By Business Owners" split kept its desktop
	   3-column grid on mobile and overflowed instead of stacking. */
	.hp-eb-split__grid,
	.hp-eb-split.hp-eb-split--reverse .hp-eb-split__grid {
		grid-template-columns: 1fr;
	}
	.hp-eb-split__media,
	.hp-eb-split.hp-eb-split--reverse .hp-eb-split__media {
		grid-column: 1;
		grid-row: auto;
		order: -1;
		aspect-ratio: 5 / 4;
	}
	/* The desktop 22ch measure (~435px) is wider than a phone viewport, so
	   the long "Built By Business Owners Like You." heading pushed the whole
	   section past the right edge and clipped. Cap the heading (and prose) to
	   the container on mobile so they wrap inside the viewport. */
	.hp-eb-split__h2 {
		max-width: 100%;
		overflow-wrap: break-word;
	}
	.hp-eb-split__prose p {
		max-width: 100%;
	}
}

/* ---- LIB-06 reverse: image on the LEFT. Used on About → Owners so two
   adjacent split sections (Owners, then Specialists) mirror each other
   instead of reading as one repeated block. Prose flows into the two
   right-hand columns; source reading order (primary → secondary) is kept. */
.hp-eb-split--reverse .hp-eb-split__grid {
	grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr) minmax(0, 1fr);
}
.hp-eb-split--reverse .hp-eb-split__media {
	grid-column: 1;
	grid-row: 1 / span 2;
}

/* Landscape media slot (e.g. a wide team photo) — a 4:3 frame vertically
   centred against the taller prose columns, instead of the default tall 4:5
   crop that would clip the ends off a group shot. */
.hp-eb-split__media--wide {
	aspect-ratio: 4 / 3;
	align-self: center;
}

/* ---- LIB-03 manifesto variant — About → Partnerships. A pull-quote led
   editorial block (no image) so the page's closing section reads clearly
   apart from the split sections above it. Saturated ground; inherits the
   section ink colour, pink accent on the quote rule + mark. */
.hp-about-partnerships .hp-eb-prose__inner {
	grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.15fr);
	column-gap: clamp(2rem, 6vw, 6rem);
	align-items: start;
}
.hp-about-partnerships__head {
	display: flex;
	flex-direction: column;
	gap: clamp(1.5rem, 3vw, 2.25rem);
	min-width: 0;
}
.hp-about-partnerships__pull {
	position: relative;
	margin: 0;
	padding: clamp(0.5rem, 1.5vw, 1rem) 0 clamp(0.5rem, 1.5vw, 1rem) clamp(1.5rem, 3vw, 2.25rem);
	border-left: 4px solid var(--color-accent);
}
.hp-about-partnerships__pull p {
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-style: italic;
	font-size: clamp(1.35rem, 2.2vw, 2.1rem);
	line-height: 1.22;
	letter-spacing: -0.01em;
	margin: 0;
	max-width: 20ch;
}
.hp-about-partnerships__mark {
	position: absolute;
	left: clamp(0.4rem, 1vw, 0.7rem);
	top: -0.25em;
	font-family: var(--font-heading-family);
	font-weight: 900;
	font-size: clamp(3rem, 5vw, 5rem);
	line-height: 1;
	color: var(--color-accent);
	opacity: 0.65;
}
/* Right column is a stack: supporting copy, then the photo that fills what
   used to be roughly 450px of dead space beneath two short paragraphs. */
.hp-about-partnerships__col {
	display: flex;
	flex-direction: column;
	gap: clamp(2rem, 3.5vw, 3rem);
	min-width: 0;
}
/* The chassis pins .hp-eb-split__media into column 3 / rows 1-2 of the
   3-column split grid. This section is a 2-column prose grid and the figure
   sits inside a flex stack, so all of that has to be unset. Both class names
   are carried to reach (0,2,0) and beat the chassis outright — equal
   specificity would lose, because the chassis block is declared later in
   this stylesheet. */
.hp-about-partnerships__media.hp-eb-split__media {
	grid-column: auto;
	grid-row: auto;
	width: 100%;
	aspect-ratio: 3 / 2;
}
@media (max-width: 1024px) {
	.hp-about-partnerships .hp-eb-prose__inner { grid-template-columns: 1fr; }
	/* The chassis mobile rule pulls split media to order: -1 (image first).
	   Here the figure belongs at the END of its stack, under the copy. */
	.hp-about-partnerships__media.hp-eb-split__media {
		order: 0;
		aspect-ratio: 16 / 10;
	}
}

/* ============== LIB-04 — Bracketed Frame ============== */
/* Shared chassis: results (.hp-eb-cases) and deliverables (.hp-eb-deliver)
   both share the bracket motif. */

.hp-eb-bracket {
	position: relative;
	padding:
		clamp(2rem, 4vw, 3.5rem)
		clamp(1.5rem, 3vw, 3rem)
		clamp(2rem, 4vw, 3.5rem)
		clamp(1.5rem, 3vw, 3rem);
}
.hp-eb-bracket::before {
	content: "";
	position: absolute;
	inset: 0;
	/* 18px borders match the homepage brand-thread stroke thickness. */
	border-top:    18px solid var(--eb-thread);
	border-right:  18px solid var(--eb-thread);
	border-bottom: 18px solid var(--eb-thread);
	border-radius: 0 clamp(28px, 4vw, 64px) clamp(28px, 4vw, 64px) 0;
	pointer-events: none;
	opacity: 0;
	transform: scaleY(0.4);
	transform-origin: center left;
	transition: opacity 0.5s ease, transform 0.8s cubic-bezier(0.22, 1, 0.36, 1);
}
.hp-eb-bracket.is-visible::before,
[data-section].is-visible .hp-eb-bracket::before {
	opacity: 1;
	transform: scaleY(1);
}

/* Case studies (results) */
.hp-eb-cases {
	padding:
		clamp(5rem, 10vh, 9rem)
		max(var(--eb-channel-w), clamp(1.25rem, 4vw, 3rem));
}
.hp-eb-cases__inner {
	width: 100%;
	max-width: 1480px;
	margin-inline: auto;
	display: grid;
	grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.4fr);
	column-gap: clamp(2rem, 5vw, 5rem);
	row-gap: clamp(2rem, 4vw, 4rem);
	align-items: start;
}
.hp-eb-cases__pull {
	min-width: 0;
	position: sticky;
	top: clamp(5rem, 10vh, 7rem);
}
.hp-eb-cases__pull-text {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2rem, 4.8vw, 4.5rem);
	line-height: 1.02;
	letter-spacing: -0.02em;
	margin: 0 0 1rem;
	max-width: 16ch;
}
.hp-eb-cases__pull-sub {
	font-size: clamp(0.95rem, 1.15vw, 1.1rem);
	line-height: 1.55;
	margin: 0;
	max-width: 28ch;
	opacity: 0.85;
}
.hp-eb-cases__bracket {
	display: grid;
	grid-template-columns: 1fr;
	gap: clamp(1.5rem, 3vw, 2.5rem);
}
.hp-eb-case {
	display: grid;
	grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
	gap: clamp(1rem, 2vw, 1.5rem);
	padding: clamp(0.75rem, 1.5vw, 1.25rem) 0;
	border-bottom: 1px solid color-mix(in oklab, currentColor 18%, transparent);
}
.hp-eb-case:last-of-type { border-bottom: 0; }
.hp-eb-case__media {
	margin: 0;
	overflow: hidden;
	border-radius: 6px;
	aspect-ratio: 4 / 3;
}
.hp-eb-case__media img {
	width: 100%; height: 100%; object-fit: cover; display: block;
	filter: grayscale(1) contrast(1.1);
	mix-blend-mode: luminosity;
	opacity: 0.95;
	transition: filter 0.45s ease, mix-blend-mode 0.45s ease, opacity 0.45s ease;
}
@media (hover: hover) and (pointer: fine) {
	.hp-eb-case__media:hover img,
	.hp-eb-case:hover .hp-eb-case__media img {
		filter: none;
		mix-blend-mode: normal;
		opacity: 1;
	}
}
.hp-eb-case__body {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
}
.hp-eb-case__tag {
	font-size: 0.75rem;
	letter-spacing: 0.04em;
	text-transform: none;
	font-weight: 600;
	opacity: 0.75;
}
.hp-eb-case__stat {
	display: flex;
	align-items: baseline;
	gap: 0.6rem;
	margin: 0.2rem 0 0.3rem;
}
.hp-eb-case__stat-num {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.75rem, 3.2vw, 2.75rem);
	font-variant-numeric: tabular-nums;
	line-height: 1;
	color: var(--eb-thread);
}
.hp-eb-case__stat-lbl {
	font-size: 0.85rem;
	opacity: 0.78;
}
.hp-eb-case__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.25rem, 1.7vw, 1.55rem);
	line-height: 1.15;
	margin: 0;
}
.hp-eb-case__kpi {
	font-size: 0.9rem;
	font-weight: 600;
	margin: 0;
}
.hp-eb-case__copy {
	font-size: 0.95rem;
	line-height: 1.55;
	margin: 0;
	opacity: 0.85;
}

/* ---------- SEO results — full-bleed case media + sticky pull ----------
   1. Drop the pink bracket frame (this section was the only place it
      lived on the SEO page; user wants the area unframed).
   2. Stack each case vertically: image first (full width of the right
      column), copy below.
   3. Overlay the case title inside the image, bottom-anchored.
   4. overflow: clip on the section so the sticky pull-aside in the
      first column actually sticks (default [data-eb-section] uses
      overflow: hidden which neutralises position: sticky on children). */

.hp-seo-results {
	overflow: clip;
}
.hp-seo-results .hp-eb-bracket {
	padding: 0;
}
.hp-seo-results .hp-eb-bracket::before {
	content: none;
}
.hp-seo-results .hp-eb-case {
	display: block;
	padding: 0 0 clamp(2.5rem, 5vw, 4rem);
	border-bottom: 0;
}
.hp-seo-results .hp-eb-case + .hp-eb-case {
	padding-top: clamp(2.5rem, 5vw, 4rem);
	border-top: 1px solid color-mix(in oklab, currentColor 14%, transparent);
}
.hp-seo-results .hp-eb-case__media {
	position: relative;
	width: 100%;
	aspect-ratio: 16 / 10;
	margin: 0 0 clamp(1.25rem, 2.5vw, 2rem);
	border-radius: 8px;
}
.hp-seo-results .hp-eb-case__media::after {
	content: '';
	position: absolute;
	inset: auto 0 0 0;
	height: 60%;
	background: linear-gradient(
		to top,
		rgba(0, 0, 16, 0.78) 0%,
		rgba(0, 0, 16, 0.35) 45%,
		transparent 100%
	);
	z-index: 1;
	pointer-events: none;
}
.hp-seo-results .hp-eb-case__title {
	position: absolute;
	bottom: clamp(1.25rem, 2.5vw, 2.25rem);
	left:   clamp(1.25rem, 2.5vw, 2.25rem);
	right:  clamp(1.25rem, 2.5vw, 2.25rem);
	z-index: 2;
	color: var(--color-paper);
	font-size: clamp(1.4rem, 2.4vw, 2.25rem);
	line-height: 1.1;
	letter-spacing: -0.015em;
	text-shadow: 0 2px 16px rgba(0, 0, 16, 0.5);
	margin: 0;
}
.hp-seo-results .hp-eb-case__body {
	max-width: 70ch;
}
.hp-seo-results .hp-eb-case__copy {
	font-size: clamp(0.98rem, 1.1vw, 1.1rem);
	line-height: 1.6;
	opacity: 0.92;
}
.hp-seo-results .hp-eb-case__copy + .hp-eb-case__copy {
	margin-top: 0.85rem;
}

/* Deliverables list */
.hp-eb-deliver {
	padding:
		clamp(5rem, 10vh, 9rem)
		max(var(--eb-channel-w), clamp(1.25rem, 4vw, 3rem));
}
.hp-eb-deliver__inner {
	width: 100%;
	max-width: 1480px;
	margin-inline: auto;
	display: grid;
	grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.4fr);
	column-gap: clamp(2rem, 5vw, 5rem);
	row-gap: clamp(2rem, 4vw, 4rem);
	align-items: start;
}
.hp-eb-deliver__pull {
	min-width: 0;
	position: sticky;
	top: clamp(5rem, 10vh, 7rem);
}
.hp-eb-deliver__pull-text {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2rem, 4.8vw, 4.5rem);
	line-height: 1.02;
	letter-spacing: -0.02em;
	margin: 0 0 1rem;
	max-width: 16ch;
}
.hp-eb-deliver__pull-sub {
	font-size: clamp(0.95rem, 1.15vw, 1.1rem);
	line-height: 1.55;
	margin: 0;
	max-width: 28ch;
	opacity: 0.85;
}
.hp-eb-deliver__bracket {
	display: flex;
	flex-direction: column;
}
.hp-eb-deliver__row {
	display: grid;
	grid-template-columns: clamp(48px, 6vw, 80px) 1fr;
	gap: clamp(1rem, 2vw, 1.5rem);
	padding: clamp(1rem, 2vw, 1.5rem) 0;
	border-top: 1px solid color-mix(in oklab, currentColor 16%, transparent);
}
.hp-eb-deliver__row:first-of-type { border-top: 0; }
.hp-eb-deliver__num {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.5rem, 2.4vw, 2.2rem);
	font-variant-numeric: tabular-nums;
	line-height: 1;
	color: var(--eb-thread);
}
.hp-eb-deliver__row-title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.25rem, 1.8vw, 1.65rem);
	line-height: 1.15;
	margin: 0 0 0.4rem;
}
.hp-eb-deliver__row-copy {
	font-size: clamp(0.95rem, 1.05vw, 1.05rem);
	line-height: 1.55;
	margin: 0;
	max-width: 60ch;
	opacity: 0.88;
}

@media (max-width: 1024px) {
	.hp-eb-cases__inner,
	.hp-eb-deliver__inner { grid-template-columns: 1fr; }
	.hp-eb-cases__pull,
	.hp-eb-deliver__pull { position: static; }
	.hp-eb-case { grid-template-columns: 1fr; }
	.hp-eb-case__media { aspect-ratio: 16 / 10; }
}

/* ============== LIB-07 — Three-Column Feature Grid ============== */

.hp-eb-grid3 {
	padding:
		clamp(5rem, 10vh, 9rem)
		max(var(--eb-channel-w), clamp(1.25rem, 4vw, 3rem));
}
.hp-eb-grid3__inner {
	width: 100%;
	max-width: 1480px;
	margin-inline: auto;
}
.hp-eb-grid3__h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.25rem, 5.5vw, 5rem);
	line-height: 1.02;
	letter-spacing: -0.02em;
	margin: 0 0 clamp(2.5rem, 5vw, 4rem);
	max-width: 18ch;
}
.hp-eb-grid3__row {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: clamp(2rem, 4vw, 3.5rem);
	align-items: start;
}
.hp-eb-grid3__cell { display: flex; flex-direction: column; gap: 1rem; }
.hp-eb-grid3__cell-quote {
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-size: clamp(1.05rem, 1.45vw, 1.35rem);
	line-height: 1.45;
	margin: 0;
	font-style: italic;
	opacity: 0.7;
}
.hp-eb-grid3__line {
	display: block;
	margin-top: clamp(2.5rem, 5vw, 4rem);
	/* 18px matches the homepage brand-thread stroke. */
	height: 18px;
	width: 100%;
	background: var(--eb-thread);
	border-radius: 999px;
	transform-origin: left center;
	transform: scaleX(0);
	transition: transform 1.1s cubic-bezier(0.22, 1, 0.36, 1);
}
.hp-eb-grid3[data-section].is-visible .hp-eb-grid3__line { transform: scaleX(1); }

@media (max-width: 1024px) {
	.hp-eb-grid3__row { grid-template-columns: 1fr; gap: clamp(1.5rem, 4vw, 2.5rem); }
}

/* ============== FAQ — in-place restyle to match EB ============== */

.hp-eb-faq.hp-seo-faq {
	padding-block: clamp(5rem, 10vh, 9rem);
	background: transparent;
	color: inherit;
}
.hp-eb-faq .hp-seo-faq__head { margin-bottom: clamp(2rem, 4vw, 3rem); }
.hp-eb-faq__h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.25rem, 5.5vw, 5rem);
	line-height: 1.02;
	letter-spacing: -0.02em;
	margin: 0;
	max-width: 22ch;
	color: inherit;
	background: none;
	-webkit-text-fill-color: currentColor;
}
.hp-eb-faq .hp-seo-faq__item {
	background: transparent;
	border: 0;
	border-top: 1px solid color-mix(in oklab, currentColor 22%, transparent);
	border-radius: 0;
	box-shadow: none;
}
.hp-eb-faq .hp-seo-faq__item:last-of-type {
	border-bottom: 1px solid color-mix(in oklab, currentColor 22%, transparent);
}
.hp-eb-faq .hp-seo-faq__item[open] {
	border-color: color-mix(in oklab, currentColor 22%, transparent);
	box-shadow: none;
}
.hp-eb-faq .hp-seo-faq__q {
	padding: clamp(1rem, 1.8vw, 1.5rem) clamp(1.25rem, 2.5vw, 2rem);
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: clamp(1.15rem, 1.7vw, 1.5rem);
	letter-spacing: -0.01em;
	color: inherit;
}
.hp-eb-faq .hp-seo-faq__q:hover { color: var(--eb-thread); }
.hp-eb-faq .hp-seo-faq__a {
	padding: 0 clamp(1.25rem, 2.5vw, 2rem) clamp(1.25rem, 2vw, 1.75rem);
	padding-left: calc(clamp(1.25rem, 2.5vw, 2rem) + 2.5ch + clamp(1rem, 2vw, 1.5rem));
}
.hp-eb-faq .hp-seo-faq__a p { color: inherit; opacity: 0.78; }
@media (max-width: 560px) {
	.hp-eb-faq .hp-seo-faq__a { padding-left: clamp(1.25rem, 2.5vw, 2rem); }
}

/* =====================================================================
   INTERNAL PAGES — full-bleed responsive layout
   ---------------------------------------------------------------------
   Single source of truth for the left/right page gutter on every
   internal page (SEO / Web Design / PPC / Videography). The gutter is
   driven by --page-pad-x and ramps up at Tailwind v4 breakpoints,
   landing on 3.125rem (50px) at >=1440px to match the reference site
   the layout is modelled on. Inner containers shed their boxed
   max-width caps so content fills the section minus the gutter.
   Plan: C:\Users\User\.claude\plans\can-you-checkit-here-mutable-harbor.md
   ===================================================================== */

:root {
	--page-pad-x: 1rem;          /* mobile default */
}
@media (min-width: 640px)  { :root { --page-pad-x: 1.5rem;   } }  /* sm  */
@media (min-width: 768px)  { :root { --page-pad-x: 2rem;     } }  /* md  */
@media (min-width: 1024px) { :root { --page-pad-x: 2.5rem;   } }  /* lg  */
@media (min-width: 1280px) { :root { --page-pad-x: 3rem;     } }  /* xl  */
@media (min-width: 1440px) { :root { --page-pad-x: 3.125rem; } }  /* 2xl */

/* Apply the shared gutter to every EB section + the Web Design hero
   (the only internal-page hero that intentionally opts out of the EB
   cross-fade). padding-inline overrides the inline values set by
   each section's `padding` shorthand earlier in the cascade
   (specificity ties; this rule wins by source order). */
[data-eb-section],
.hp-wd-hero {
	padding-inline: var(--page-pad-x);
}

/* Lift every boxed max-width cap off the inner containers so content
   fills the section. The attribute catch-all covers any future
   __inner without enumeration; the child combinator keeps nested
   __inner containers (e.g. inside cards) out of scope. */
[data-eb-section] > [class$="__inner"] {
	max-width: none;
}

/* Exceptions — sections explicitly designed to stay narrow / centred.
   CTA cards are conversion-focused boxes (one button + one short
   message) and the FAQ list keeps a readable line length. These
   re-pin after the reset above so the global rule doesn't stretch
   them edge-to-edge. */
.hp-seo-cta__inner             { max-width: 900px;  }
.hp-ppc-cta__inner             { max-width: 880px;  }
.hp-vid-cta__inner             { max-width: 1280px; }
.hp-seo-faq__inner             { max-width: 960px;  }

/* ============== CTA — in-place restyle to match EB ============== */

.hp-eb-cta__h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.5rem, 6vw, 5.5rem);
	line-height: 1.02;
	letter-spacing: -0.02em;
	color: inherit;
	background: none;
	-webkit-text-fill-color: currentColor;
}

/* ============== Numbered List (LIB-12, no bracket) ==============
   For long titled lists (7+ items, short bodies). Replaces LIB-04
   when the bracket would be too tall to read comfortably. Hairline
   rules between rows, numbered chip on the left, title + short
   body on the right. */

.hp-eb-numlist {
	padding:
		clamp(5rem, 10vh, 9rem)
		max(var(--eb-channel-w), clamp(1.25rem, 4vw, 3rem));
}
.hp-eb-numlist__inner {
	width: 100%;
	max-width: 1280px;
	margin-inline: auto;
}
.hp-eb-numlist__h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.25rem, 5.5vw, 5rem);
	line-height: 1.02;
	letter-spacing: -0.02em;
	margin: 0 0 clamp(2.5rem, 5vw, 4rem);
	max-width: 22ch;
}
.hp-eb-numlist__list {
	list-style: none;
	margin: 0;
	padding: 0;
	border-top: 1px solid color-mix(in oklab, currentColor 22%, transparent);
}
.hp-eb-numlist__row {
	display: grid;
	grid-template-columns: clamp(56px, 6vw, 90px) minmax(0, 1fr);
	gap: clamp(1rem, 2vw, 2rem);
	padding: clamp(1.5rem, 2.6vw, 2.2rem) 0;
	border-bottom: 1px solid color-mix(in oklab, currentColor 22%, transparent);
	align-items: baseline;
}
.hp-eb-numlist__num {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.75rem, 3.2vw, 3rem);
	font-variant-numeric: tabular-nums;
	line-height: 1;
	color: var(--eb-thread);
}
.hp-eb-numlist__body { display: flex; flex-direction: column; gap: 0.55rem; min-width: 0; }
.hp-eb-numlist__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.4rem, 2.2vw, 2rem);
	line-height: 1.15;
	margin: 0;
	letter-spacing: -0.01em;
}
.hp-eb-numlist__copy {
	font-size: clamp(0.95rem, 1.1vw, 1.05rem);
	line-height: 1.6;
	margin: 0;
	max-width: 62ch;
	opacity: 0.9;
}

@media (max-width: 720px) {
	.hp-eb-numlist__row {
		grid-template-columns: 1fr;
		gap: 0.35rem;
	}
	.hp-eb-numlist__num { font-size: 1.6rem; }
}

/* ============== Stacked Case Studies (LIB-13, no bracket) ==============
   For 3-4 long case studies with multi-paragraph bodies. Each case is
   a full-width essay block separated by a thick rule in the thread
   colour — gives the cases room to breathe instead of cramming them
   into a frame. */

.hp-eb-casestack {
	padding:
		clamp(5rem, 10vh, 9rem)
		max(var(--eb-channel-w), clamp(1.25rem, 4vw, 3rem));
}
.hp-eb-casestack__inner {
	width: 100%;
	max-width: 1280px;
	margin-inline: auto;
}
.hp-eb-casestack__h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.25rem, 5.5vw, 5rem);
	line-height: 1.02;
	letter-spacing: -0.02em;
	margin: 0 0 clamp(2.5rem, 5vw, 4rem);
	max-width: 22ch;
}
.hp-eb-casestack__case {
	padding: clamp(2.5rem, 5vw, 4.5rem) 0;
	/* 18px matches the homepage brand-thread stroke. */
	border-top: 18px solid var(--eb-thread);
}
.hp-eb-casestack__case:first-of-type { border-top-width: 18px; }
.hp-eb-casestack__case:last-of-type {
	border-bottom: 18px solid var(--eb-thread);
}
.hp-eb-casestack__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.75rem, 3.4vw, 3.25rem);
	line-height: 1.05;
	letter-spacing: -0.015em;
	margin: 0 0 clamp(1.25rem, 2.4vw, 2rem);
	max-width: 24ch;
}
.hp-eb-casestack__body {
	display: flex;
	flex-direction: column;
	gap: clamp(0.85rem, 1.4vw, 1.25rem);
	max-width: 70ch;
}
.hp-eb-casestack__body p {
	margin: 0;
	font-size: clamp(0.95rem, 1.15vw, 1.1rem);
	line-height: 1.65;
	opacity: 0.92;
}

/* ============== SEO "What we Deliver" (brutalist process, mirrored) ======
   Mirrors .hp-wd-process exactly with one inversion: the sticky H2 is
   on the RIGHT (was LEFT on the WD page), the numbered phase list is
   on the LEFT, and the pink thread enters / exits from the RIGHT
   edge. Per-circle reveal animation (is-active) is identical to WD.

   Numbered circles sit at the RIGHT edge of the list (adjacent to the
   H2 column) so the vertical thread runs between the list body and
   the H2 column — same brand-thread / numbered-anchor relationship,
   mirrored. */

.hp-seo-deliver {
	position: relative;
	padding:
		clamp(9rem, 18vh, 16rem)
		clamp(1.5rem, 5vw, 6rem);
	overflow: visible;
}
.hp-seo-deliver__inner {
	width: 100%;
	display: grid;
	/* Left list column ~ 7fr, right H2 column ~ 5fr — MIRROR of WD. */
	grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
	column-gap: clamp(3rem, 7vw, 7rem);
	align-items: start;
	position: relative;
	z-index: 1;
}
.hp-seo-deliver__head {
	position: sticky;
	top: clamp(4rem, 12vh, 8rem);
	align-self: start;
	/* H2 sits hard-right inside the column. */
	display: flex;
	justify-content: flex-end;
}
.hp-seo-deliver__h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	/* Same slope+intercept clamp as .hp-wd-process__h2 (the mirror
	   pattern) and the WD perform H2 — keeps the brutalist H2 family
	   at one scale across pages, with a 32px floor that reads
	   comfortably on tablet widths. */
	font-size: clamp(2rem, calc(1rem + 5vw), 6rem);
	line-height: 0.95;
	letter-spacing: -0.03em;
	margin: 0;
	max-width: 9ch;
	text-wrap: balance;
	text-align: right;
}
.hp-seo-deliver__list {
	list-style: none;
	margin: 0;
	padding: clamp(1.5rem, 3vw, 2.25rem) 0 0;
	display: flex;
	flex-direction: column;
	gap: clamp(3rem, 5vw, 5rem);
}
.hp-seo-deliver__phase {
	display: grid;
	/* Body column + numbered circle column. Circle at RIGHT — MIRROR. */
	grid-template-columns: minmax(0, 1fr) clamp(2.75rem, 3vw, 3.5rem);
	column-gap: clamp(1.5rem, 2.5vw, 2.5rem);
	align-items: start;
}
.hp-seo-deliver__num {
	width:  clamp(2.75rem, 3vw, 3.5rem);
	height: clamp(2.75rem, 3vw, 3.5rem);
	border-radius: 50%;
	background: var(--color-paper);
	color: var(--color-primary);
	display: grid;
	place-items: center;
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.5rem, 1.8vw, 2rem);
	line-height: 1;
	text-indent: 0;
	padding-block-start: 0.08em;
	position: relative;
	z-index: 2;
	box-shadow: 0 0 0 6px var(--color-primary);
	/* Reveal transitions — same as WD process. */
	transition:
		transform   0.45s cubic-bezier(0.34, 1.56, 0.64, 1),
		box-shadow  0.45s cubic-bezier(0.34, 1.56, 0.64, 1),
		background  0.45s cubic-bezier(0.2,  0.7,  0.2,  1),
		color       0.45s cubic-bezier(0.2,  0.7,  0.2,  1);
}
.hp-seo-deliver__phase-body { min-width: 0; }
.hp-seo-deliver__name {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.5rem, calc(0.75rem + 1.6vw), 2.5rem);
	line-height: 1.1;
	letter-spacing: -0.015em;
	margin: 0 0 clamp(0.75rem, 1.2vw, 1rem) 0;
	color: var(--color-paper);
	border-bottom: 1px solid color-mix(in srgb, var(--color-paper) 40%, transparent);
	padding-bottom: clamp(0.75rem, 1.2vw, 1rem);
	/* Rest state — dimmed and offset RIGHT (mirror of WD's translateX(-12px)).
	   0.45 is the contrast floor: 24px bold paper on #000010 needs 3:1
	   even before the thread reveal (0.35 measured 2.78). */
	opacity: 0.45;
	transform: translateX(12px);
	transition:
		opacity 0.5s cubic-bezier(0.2, 0.7, 0.2, 1),
		transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.hp-seo-deliver__paras {
	display: flex;
	flex-direction: column;
	gap: clamp(0.75rem, 1.4vw, 1.25rem);
	padding-top: clamp(0.75rem, 1.4vw, 1.25rem);
	/* 0.55 floor: body text on #000010 needs 4.5:1 pre-reveal (0.25
	   measured 1.77). Active state still lifts to 0.92. */
	opacity: 0.55;
	transform: translateY(8px);
	transition:
		opacity 0.5s cubic-bezier(0.2, 0.7, 0.2, 1) 80ms,
		transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1) 80ms;
}
.hp-seo-deliver__paras p {
	margin: 0;
	font-size: clamp(1rem, calc(0.9rem + 0.45vw), 1.35rem);
	line-height: 1.6;
	color: var(--color-paper);
	opacity: 0.92;
	max-width: 60ch;
}

/* ---------- .is-active reveal — thread has reached this circle ---------- */
.hp-seo-deliver__phase.is-active .hp-seo-deliver__num {
	background: var(--color-accent);
	color: var(--color-paper);
	transform: scale(1.08);
	box-shadow:
		0 0 0 6px var(--color-primary),
		0 0 0 14px color-mix(in srgb, var(--color-accent) 35%, transparent),
		0 0 32px color-mix(in srgb, var(--color-accent) 55%, transparent);
}
.hp-seo-deliver__phase.is-active .hp-seo-deliver__name {
	opacity: 1;
	transform: translateX(0);
}
.hp-seo-deliver__phase.is-active .hp-seo-deliver__paras {
	opacity: 0.92;
	transform: translateY(0);
}

/* Thread SVG — overlays the section. Path geometry mirrors the WD
   process thread (right-side instead of left-side). */
.hp-seo-deliver__thread {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	z-index: 0;
	overflow: visible;
}
.hp-seo-deliver__thread path {
	fill: none;
	stroke: var(--color-accent);
	stroke-width: clamp(22px, 2vw, 30px);
	stroke-linecap: round;
	stroke-linejoin: round;
}

@media (max-width: 1024px) {
	.hp-seo-deliver__inner {
		grid-template-columns: 1fr;
		row-gap: clamp(2.5rem, 6vw, 4rem);
	}
	.hp-seo-deliver__head {
		position: static;
		justify-content: flex-start;
		/* Markup lists the numbered items FIRST and the H2 last (that's
		   the desktop mirror: list left, H2 right). Once the grid stacks
		   to one column, that source order drops "What we deliver." to the
		   bottom under all 7 items. Pull the heading to the top so it
		   introduces the section, as it should. */
		order: -1;
	}
	.hp-seo-deliver__h2 { text-align: left; max-width: none; }
	.hp-seo-deliver__list { gap: clamp(2.5rem, 5vw, 4rem); }
	.hp-seo-deliver__phase {
		/* On mobile, body left + circle right keeps the mirror, but
		   floor the circle a bit larger so the stroke still covers it. */
		grid-template-columns: minmax(0, 1fr) clamp(3.75rem, 12vw, 4rem);
		column-gap: clamp(1rem, 4vw, 1.5rem);
	}
	.hp-seo-deliver__num {
		width:  clamp(3.75rem, 12vw, 4rem);
		height: clamp(3.75rem, 12vw, 4rem);
	}
}
@media (max-width: 640px) {
	.hp-seo-deliver__thread { display: none; }
}

/* ============== Web Design "How We Work" (geek.-style roadmap) ==============
   Two-column layout: gradient H2 left, numbered phase list right with
   per-row hairline rule under each phase title. Thread enters from the
   section's right edge, curves down 80px radius, runs vertically along
   the right column's left edge passing through every numbered circle's
   centre, then curves and exits at the bottom — see wireWdProcessThread
   (main.js) for live geometry. */

.hp-wd-process {
	position: relative;
	/* Generous block padding so the long phase list breathes AND the
	   pink brand thread has its 50px gap above the H2 / below the last
	   phase body without clipping. Block padding bumped per user spec
	   — every WD section gets more vertical breathing room. Was
	   clamp(6rem, 14vh, 12rem). */
	padding:
		clamp(9rem, 18vh, 16rem)
		clamp(1.5rem, 5vw, 6rem);
	overflow: visible;

	/* Scroll-driven ground shift — this section washes navy → white
	   TOGETHER with the results section below it so the seam between
	   them has no visible line (homepage Featured Work parity, user
	   spec). wireWdResultsColorShift writes --hp-wd-results-shift here
	   from the results section's scroll position; at rest it stays 0
	   (navy) so no-JS / reduced-motion visitors keep the dark roadmap.

	   --wd-ground = the current ground colour (navy → cream as shift
	   0 → 1). --wd-ink = its inverse (cream → navy), used for every
	   piece of copy and the numbered circles so they stay legible on
	   both grounds and ghost through the mid-transition grey exactly
	   like the homepage services list. The pink brand thread and the
	   active-circle pink are NOT mapped to these — pink reads on both
	   grounds and must stay pink. */
	--hp-wd-results-shift: 0;
	--wd-ground: color-mix(
		in oklab,
		var(--color-paper) calc(var(--hp-wd-results-shift) * 100%),
		var(--color-primary)
	);
	--wd-ink: color-mix(
		in oklab,
		var(--color-primary) calc(var(--hp-wd-results-shift) * 100%),
		var(--color-paper)
	);
}
/* Ground + ink applied at (class + attribute) specificity so they beat
   the generic [data-eb-section][data-eb-ground="saturated"] rule in
   main.css (same 0,2,0 specificity → later stylesheet, inner-pages,
   wins). Kept on the SAME selector shape as the results rule below. */
.hp-wd-process[data-eb-ground="saturated"] {
	background: var(--wd-ground);
	color: var(--wd-ink);
}
/* No color-mix support: hold the section at its solid navy ground so
   the roadmap never renders as unstyled/illegible. */
@supports not (color: color-mix(in oklab, red, blue)) {
	.hp-wd-process {
		background: var(--color-primary);
		color: var(--color-paper);
	}
}
.hp-wd-process__inner {
	width: 100%;
	display: grid;
	/* Left H2 column ~ 5fr, right list column ~ 7fr. */
	grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
	column-gap: clamp(3rem, 7vw, 7rem);
	align-items: start;
	position: relative;
	z-index: 1;
}
.hp-wd-process__head {
	/* Sticky pin so the H2 stays in view as the user scrolls the long
	   phase list — mirrors the editorial behaviour in the reference. */
	position: sticky;
	top: clamp(4rem, 12vh, 8rem);
	align-self: start;
}
.hp-wd-process__h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	/* Brutalist scale — slope+intercept matches the WD perform H2 so
	   the headings across the page sit at the same scale. Was
	   clamp(3rem, 1.5rem+6vw, 8rem) which floored at 48px and felt
	   oversized on tablets where the H2 sits next to the numbered
	   list at narrow widths. */
	font-size: clamp(2rem, calc(1rem + 5vw), 6rem);
	line-height: 0.95;
	letter-spacing: -0.03em;
	margin: 0;
	max-width: 9ch;
	text-wrap: balance;
}
.hp-wd-process__list {
	list-style: none;
	margin: 0;
	/* padding-top pushes the first phase row DOWN by ~32px so the
	   R=80 entry corner can land ABOVE the first circle's centre.
	   Without this, yEntry+R (h2Top + 30) ends up below yFirstCx
	   (pad-top + 22 for the smaller 44px circle) — the JS sanity
	   guard then blanks the path. 32px gives R=80 corner clearance
	   PLUS a safety margin, so the thread always threads circle 1. */
	padding: clamp(1.5rem, 3vw, 2.25rem) 0 0;
	display: flex;
	flex-direction: column;
	gap: clamp(3rem, 5vw, 5rem);
}
.hp-wd-process__phase {
	display: grid;
	/* Numbered circle column + phase body column. The circle column
	   width = circle diameter, so the thread channel sits exactly on
	   the boundary between the two — every circle's centre aligns on
	   the same x. */
	grid-template-columns: clamp(2.75rem, 3vw, 3.5rem) minmax(0, 1fr);
	column-gap: clamp(1.5rem, 2.5vw, 2.5rem);
	align-items: start;
}
.hp-wd-process__num {
	/* Rest state: an INK-coloured circle with a GROUND-coloured numeral.
	   --wd-ink / --wd-ground track the section's ground shift, so on navy
	   this is a cream circle + navy numeral (as before) and on white it
	   is a navy circle + cream numeral — legible on both. The circle
	   only turns pink when the scroll-driven thread reaches it
	   (`.is-active`); the ink cover lets the pink thread "approach" the
	   circle without overlapping its colour. */
	width:  clamp(2.75rem, 3vw, 3.5rem);
	height: clamp(2.75rem, 3vw, 3.5rem);
	border-radius: 50%;
	background: var(--wd-ink);
	color: var(--wd-ground);
	display: grid;
	place-items: center;
	font-family: var(--font-heading-family);
	font-weight: 800;
	/* Numeral target ~55-60% of circle diameter — reads big, fills
	   the circle. */
	font-size: clamp(1.5rem, 1.8vw, 2rem);
	line-height: 1;
	/* Optical-centre fix — digits sit on the baseline so the glyph's
	   visual centre is ABOVE the line-box centre by ~0.05em. Translate
	   the numeral down a hair so it reads as centred inside the
	   circle instead of crowded against the top. */
	text-indent: 0;
	padding-block-start: 0.08em;
	position: relative;
	z-index: 2;                         /* in inner's stacking layer */
	/* Ground-colour ring around the circle — visually CUTS the pink
	   thread at the circle's edge so the pink stroke doesn't merge
	   into the circle. --wd-ground matches the section ground at every
	   shift step (navy at rest, white once washed), so the ring stays
	   invisible against the ground; on .is-active the halo shadows
	   extend OUTSIDE this ring to add the pink glow. */
	box-shadow: 0 0 0 6px var(--wd-ground);
}
.hp-wd-process__phase-body { min-width: 0; }
.hp-wd-process__name {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.5rem, calc(0.75rem + 1.6vw), 2.5rem);
	line-height: 1.1;
	letter-spacing: -0.015em;
	margin: 0 0 clamp(0.75rem, 1.2vw, 1rem) 0;
	color: var(--wd-ink);
	/* Hairline rule directly under the title — full width of the body
	   column. Matches the reference's per-row underline. Tracks --wd-ink
	   so it stays visible on both grounds. */
	border-bottom: 1px solid color-mix(in srgb, var(--wd-ink) 40%, transparent);
	padding-bottom: clamp(0.75rem, 1.2vw, 1rem);

	/* Rest state — dimmed and slightly offset so the .is-active
	   reveal (when the pink thread "hits" the circle) is visible.
	   0.45 is the 3:1 contrast floor for the 24px bold title. */
	opacity: 0.45;
	transform: translateX(-12px);
	transition:
		opacity 0.5s cubic-bezier(0.2, 0.7, 0.2, 1),
		transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.hp-wd-process__paras {
	display: flex;
	flex-direction: column;
	gap: clamp(0.75rem, 1.4vw, 1.25rem);
	padding-top: clamp(0.75rem, 1.4vw, 1.25rem);

	/* Body content fades in slightly after the title — staggered
	   reveal as the thread passes through. 0.55 = 4.5:1 contrast
	   floor on the dark ground (matches .hp-seo-deliver__paras). */
	opacity: 0.55;
	transform: translateY(8px);
	transition:
		opacity 0.5s cubic-bezier(0.2, 0.7, 0.2, 1) 80ms,
		transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1) 80ms;
}
.hp-wd-process__paras p {
	margin: 0;
	font-size: clamp(1rem, calc(0.9rem + 0.45vw), 1.35rem);
	line-height: 1.6;
	color: var(--wd-ink);
	opacity: 0.92;
	max-width: 60ch;
}

/* Circle reveal animation. Rest state = cream circle, dark numeral.
   When the thread hits it (`.is-active`), the circle flips to pink
   with cream numeral, scales up briefly, and a pink halo ring pulses
   outward. Pure CSS — driven by the class toggled in updateDraw. */
.hp-wd-process__num {
	transition:
		transform   0.45s cubic-bezier(0.34, 1.56, 0.64, 1),
		box-shadow  0.45s cubic-bezier(0.34, 1.56, 0.64, 1),
		background  0.45s cubic-bezier(0.2,  0.7,  0.2,  1),
		color       0.45s cubic-bezier(0.2,  0.7,  0.2,  1);
}

/* ---------- .is-active reveal — thread has reached this circle ---------- */
.hp-wd-process__phase.is-active .hp-wd-process__num {
	background: var(--color-accent);   /* HP brand pink — reads on both grounds */
	color: var(--color-paper);
	/* Bouncy scale to settle at 1.08, with a soft pink halo behind
	   the ground-colour ring so the circle "lights up" when the thread
	   hits. Ring tracks --wd-ground so it keeps cutting the thread on
	   the washed-white ground too. */
	transform: scale(1.08);
	box-shadow:
		0 0 0 6px var(--wd-ground),
		0 0 0 14px color-mix(in srgb, var(--color-accent) 35%, transparent),
		0 0 32px color-mix(in srgb, var(--color-accent) 55%, transparent);
}
.hp-wd-process__phase.is-active .hp-wd-process__name {
	opacity: 1;
	transform: translateX(0);
}
.hp-wd-process__phase.is-active .hp-wd-process__paras {
	opacity: 0.92;
	transform: translateY(0);
}

/* Thread SVG — overlays the whole section. Path is computed live by
   wireWdProcessThread and threads through each numbered circle.
   z-index: 0 (not 1) because `.hp-wd-process__inner` is its own
   stacking context at z-index: 1, and the numbered circles live INSIDE
   that context. A circle's own z-index can never pop above a sibling
   of inner — it can only stack within inner's layer. So the SVG has
   to sit *below* inner for the circles to cleanly cover the thread. */
.hp-wd-process__thread {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	z-index: 0;
	overflow: visible;
}
.hp-wd-process__thread path {
	fill: none;
	/* HP brand pink — matches the homepage ribbon. */
	stroke: var(--color-accent);
	/* Hero / structural-spine thread band per [[feedback-eb-thread-mandatory]]:
	   clamp(22px, 2vw, 30px). 18px is for micro-decorative threads only
	   (bracket border, stats baseline). A continuous spine that threads
	   through numbered anchors uses the same 22-30px band as the hero. */
	stroke-width: clamp(22px, 2vw, 30px);
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* Vid "What We Produce" — pink pill CTA now sits in the LEFT H2
   column, directly below the "What We Produce." heading (per user
   spec). Left-aligned under the heading rather than centred across
   the full grid width. */
.hp-vid-produce__cta {
	margin: clamp(1.75rem, 3vw, 2.5rem) 0 0;
	text-align: left;
}
/* Button holds a SHORT label ("Get in touch") so the pill stays compact
   instead of the old bulky wrapped block. Keep it capped to its column so
   it never overruns the viewport on a phone. */
.hp-vid-produce__cta .hp-btn {
	max-width: 100%;
}
/* Supporting prompt sits directly BELOW the button (per user spec) so the
   full message reads without bloating the pill. This section is on the EB
   "saturated" (navy) ground, so inherit its light paper ink and just mute
   it slightly — never hard-code a dark colour here or it vanishes. Plain,
   sentence case, matches the dyslexia-readable copy baseline. */
.hp-vid-produce__cta-note {
	margin: clamp(0.75rem, 1.5vw, 1rem) 0 0;
	max-width: 34ch;
	text-align: left;
	color: inherit;
	opacity: 0.8;
	font-size: clamp(0.95rem, 1.1vw, 1.05rem);
	line-height: 1.6;
}

@media (max-width: 1024px) {
	.hp-wd-process__inner {
		/* minmax(0, 1fr) — NOT plain 1fr. A plain 1fr track resolves to
		   minmax(auto, 1fr), whose auto floor = the widest min-content
		   child. The long nowrap CTA pill below then blows the track (and
		   the whole section) wider than the viewport, cutting off the
		   button and every body paragraph. minmax(0,...) lets the track
		   shrink so nothing overflows. */
		grid-template-columns: minmax(0, 1fr);
		row-gap: clamp(2.5rem, 6vw, 4rem);
	}
	.hp-wd-process__head {
		position: static;
		top: auto;
		/* Single-column: the thread's vertical run drops down the circle
		   column's x (~left edge) and would cross the full-width H2 (and
		   the vid-produce CTA that shares this head). Indent the head by
		   circle column + gap so it aligns with the phase-body text and
		   sits clear of the thread lane. */
		padding-left: calc(clamp(2rem, 6vw, 2.5rem) + clamp(1rem, 4vw, 1.5rem));
	}
	.hp-wd-process__h2 { max-width: none; }
	.hp-wd-process__list { gap: clamp(2.5rem, 5vw, 4rem); }
	.hp-wd-process__phase {
		/* Mobile circles scaled DOWN per user spec (was clamp(2.5rem, 8vw,
		   3rem)). Still comfortably wider than the thin homepage-scale
		   thread stroke (calc(1.46vw + 2px), below) that runs through the
		   circle centres on phones, so every circle fully covers the
		   thread at its row. */
		grid-template-columns: clamp(2rem, 6vw, 2.5rem) minmax(0, 1fr);
		column-gap: clamp(1rem, 4vw, 1.5rem);
	}
	.hp-wd-process__num {
		width:  clamp(2rem, 6vw, 2.5rem);
		height: clamp(2rem, 6vw, 2.5rem);
		font-size: clamp(1.05rem, 3.2vw, 1.35rem);
	}
}

/* Phone: run the process thread at the homepage brand-thread's mobile
   thickness — same dot-scaled formula as .hp-ppc-loc__thread (the
   homepage scales its stroke to the hero dot ≈ 1.46vw + 2px, see
   wireScrollRibbon). The uniform 22-30px internal-page band would
   overpower the scaled-down mobile circles above. */
@media (max-width: 767px) {
	.hp-wd-process__thread path { stroke-width: calc(1.46vw + 2px); }
}

/* ============== Web Design "What Our Websites Actually Deliver" ============
   Stacking-card pattern modelled on the homepage Featured Work
   (.hp-portfolio__card). Each case-study card is sticky-pinned at the
   top of the viewport for one viewport's worth of scroll; the next
   card scrolls up from below, and wireWdResultsStack scales / dims
   the pinned card as the next one covers it (scale 0.86, opacity 0.5
   at full cover). Cards are 90vw — the user requested 90% full-width
   instead of the 1500px cap the portfolio uses. */

.hp-wd-results {
	position: relative;
	/* Top padding bumped per user spec — more breathing room above the
	   first stacking card. Bottom stays 0 because sticky cards handle
	   their own bottom spacing via the last-card padding rule below. */
	padding-top:    clamp(7rem, 14vh, 11rem);
	padding-bottom: 0;
	overflow: visible;
}
.hp-wd-results__head {
	max-width: none;
	padding:
		0
		clamp(1.5rem, 5vw, 6rem)
		clamp(3rem, 6vw, 5rem);
	/* Hard-right alignment — R-02 inversion: the previous section
	   (process) anchored its H2 hard-left, so this section's H2
	   anchors hard-right to create asymmetric rhythm. */
	display: flex;
	justify-content: flex-end;
}
.hp-wd-results__h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	/* Brutalist scale — slope+intercept clamp matching the WD
	   outperform H2 so the two anchor headings on the page (left-aligned
	   gradient outperform H2 and right-aligned deliver H2) read at the
	   same brutalist size. 56px → 176px. */
	font-size: clamp(3.5rem, calc(2rem + 7.5vw), 11rem);
	line-height: 0.95;
	letter-spacing: -0.03em;
	margin: 0;
	max-width: 14ch;
	text-align: right;
	text-wrap: balance;
}
/* Scroll-driven ground shift — the homepage Featured Work beat
   (.hp-work / --hp-work-shift in main.css) ported to this section,
   per user request. 0 = navy ground with paper text, 1 = cream ground
   with navy text. wireWdResultsColorShift drives it from this
   section's OWN top and bottom edge, so it reads navy where it meets
   the navy process section above and the navy reviews below, and
   cream through the middle — no hard seam at either end.

   Rest value is 1 so no-JS / reduced-motion / no-color-mix visitors
   still get the declared data-eb-ground="light" appearance. The
   attribute is carried in the selector so this outranks the generic
   [data-eb-section][data-eb-ground="light"] rule in main.css.

   Only the ground and the H2 morph: the stacking cards paint their
   own navy panels and paper text, so they are unaffected. */
.hp-wd-results[data-eb-ground="light"] {
	--hp-wd-results-shift: 1;
	background: color-mix(
		in oklab,
		var(--color-paper) calc(var(--hp-wd-results-shift) * 100%),
		var(--color-primary)
	);
	color: color-mix(
		in oklab,
		var(--color-primary) calc(var(--hp-wd-results-shift) * 100%),
		var(--color-paper)
	);
}

.hp-wd-results__stack {
	position: relative;
}
.hp-wd-results__card {
	/* Sticky pin — each card holds the top of the viewport for one
	   viewport-height of scroll while the next card scrolls in. */
	position: sticky;
	top: 0;
	height: 100vh;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: clamp(1rem, 2.5vw, 2rem);
}
.hp-wd-results__card-inner {
	position: relative;
	/* 90% viewport width — user spec. No max-width cap so the card
	   fills 90vw at all desktop sizes. */
	width: 90vw;
	max-width: none;
	height: min(85vh, 880px);
	border-radius: clamp(20px, 2vw, 36px);
	overflow: hidden;
	box-shadow: 0 40px 90px rgba(0, 0, 0, 0.45);
	transform-origin: center top;
	will-change: transform, opacity;
	color: var(--color-paper);
	/* Solid navy background — user spec, all cards now share the
	   brand navy instead of per-case gradients. */
	background: var(--color-primary);
	/* Two-column layout — image-led. The portfolio mockup is the star,
	   so it takes the LARGER column (was 60/40 content-led); the copy is
	   deliberately lean because the "Read the full story" popup carries
	   the detail (user spec). Using fr units keeps the ratio strict
	   across viewport widths. */
	display: grid;
	grid-template-columns: 46fr 54fr;
	column-gap: clamp(1.5rem, 4vw, 3.5rem);
	align-items: stretch;
	padding: clamp(2rem, 4vw, 3.5rem);
}
.hp-wd-results__content {
	position: relative;
	z-index: 1;
	min-width: 0;
	display: flex;
	flex-direction: column;
	justify-content: center;
	/* Tightened (was clamp(1.5rem, 3vw, 2.25rem)). The image-led 46/54
	   split makes the content column narrower, so long titles wrap to
	   3 lines; the smaller gap keeps the stacked head/stats/hook/button
	   inside the fixed-height card at every width (was overflowing ~19px
	   at 1440 and clipping the title top). */
	gap: clamp(1.15rem, 2.1vw, 1.6rem);
	overflow: hidden;
}
.hp-wd-results__media {
	position: relative;
	z-index: 1;
	margin: 0;
	min-width: 0;
	border-radius: clamp(12px, 1.5vw, 24px);
	overflow: hidden;
	/* Transparent device mockups (alpha PNG to WebP) float directly on the
	   navy card: no panel fill, and object-fit:contain shows the whole
	   phone and laptop mockup without cropping. */
	background: transparent;
}
.hp-wd-results__media img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	display: block;
}
.hp-wd-results__card-head {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	column-gap: clamp(1.25rem, 2.5vw, 2.25rem);
	align-items: end;
	border-bottom: 1px solid color-mix(in srgb, var(--color-paper) 35%, transparent);
	padding-bottom: clamp(1rem, 1.5vw, 1.35rem);
}
.hp-wd-results__index {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.5rem, 2.4vw, 2.5rem);
	letter-spacing: -0.02em;
	line-height: 1;
	color: var(--color-accent);
}

/* Headline result stats — the proof the card leads with. A responsive
   auto-fit row so 2 or 3 stats sit evenly at every width. Values in
   accent pink at a brutalist scale; labels in muted paper. */
.hp-wd-results__stats {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(clamp(6rem, 12vw, 9rem), 1fr));
	gap: clamp(1.25rem, 3vw, 2.5rem);
}
.hp-wd-results__stat {
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
	min-width: 0;
}
.hp-wd-results__stat-value {
	font-family: var(--font-heading-family);
	font-weight: 800;
	/* Low floor + steep slope: desktop lands where it always did (~53px
	   at 1440px) but the numbers keep shrinking on smaller screens
	   instead of parking at 2rem and crowding the card. */
	font-size: clamp(1.375rem, calc(0.5rem + 3.1vw), 3.5rem);
	line-height: 0.95;
	letter-spacing: -0.03em;
	color: var(--color-accent);
}
.hp-wd-results__stat-label {
	font-size: clamp(0.75rem, 0.65rem + 0.4vw, 1.0625rem);
	line-height: 1.35;
	color: color-mix(in srgb, var(--color-paper) 80%, transparent);
}

/* Card hook — the verbatim lead sentence, clamped to TWO lines (was
   three) so the card stays lean and the enlarged mockup leads. The
   rest of the story reads on in the dialog. */
.hp-wd-results__hook {
	margin: 0;
	max-width: 42ch;
	font-size: clamp(1.0625rem, 0.9rem + 0.6vw, 1.5rem);
	line-height: 1.55;
	color: color-mix(in srgb, var(--color-paper) 92%, transparent);
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	/* Reserve exactly two lines and never let the flex column squeeze
	   this box. Without this, the -webkit-box reports a 0 min-content
	   height to the centring flex parent, so on the taller cards it
	   collapsed to a single line (or vanished) instead of clamping.
	   3.1em = 2 × 1.55 line-height. */
	min-height: 3.1em;
	flex-shrink: 0;
}
.hp-wd-results__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 1rem;
}
.hp-wd-results__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2rem, calc(1rem + 3.6vw), 5rem);
	line-height: 1.02;
	letter-spacing: -0.025em;
	margin: 0;
	color: var(--color-paper);
	text-wrap: balance;
}
/* Final card doesn't need to pin all the way — drop the next-card
   coverage and let it settle naturally at the section bottom. */
.hp-wd-results__card:last-of-type { padding-bottom: clamp(2rem, 5vw, 4rem); }

/* Laptop-class screens — 13" MacBook and any window narrower than a
   large desktop (961–1500px wide). At these widths the side-by-side
   split width-constrains the landscape mockup, so it reads small with
   dead navy either side. Here the card UNPINS (natural height, flows /
   scrolls like the phone layout) so the image becomes a genuine
   FULL-WIDTH banner ABOVE the project title, with the stats / hook /
   button flowing below it (user spec).

   Trigger is WIDTH-based (was height-based, which missed narrower-but-
   tall windows — a 13" MacBook at 1440 wide can still be >900px tall,
   so max-height never matched and the old small side-by-side showed).
   max-width:1500 catches every 13"-class width AND a maximised 1440
   MacBook; monitors ≥1501px keep the pinned image-led side-by-side
   split, and the ≤960 rule below still owns phones/tablets.

   Why unpin: a pinned card is exactly one viewport tall, and a
   full-width image + all the copy cannot both fit in ~765px — capping
   the image to fit would make it SMALLER, not bigger. Dropping the pin
   (as the ≤768 layout already does) lets the banner be large and the
   content sit underneath. */
@media (min-width: 961px) and (max-width: 1500px) {
	.hp-wd-results__card {
		position: relative;
		height: auto;
	}
	.hp-wd-results__card-inner {
		height: auto;
		grid-template-columns: minmax(0, 1fr);
		column-gap: 0;
		row-gap: clamp(1.5rem, 3vh, 2.25rem);
		grid-template-rows: auto auto;
	}
	.hp-wd-results__media {
		order: -1;              /* banner ABOVE the content */
		width: 100%;
		/* Let the banner take the MOCKUP'S OWN aspect ratio instead of a
		   fixed 16/9. The mockups are ~1.438:1; forcing 16/9 (1.778) made
		   object-fit:contain letterbox them, so you saw navy gaps and the
		   image's rectangular edges inside the band. With the box matched
		   to the image, the mockup fills it edge to edge — no letterbox,
		   no visible edges. Height is image-driven (see the img override
		   below); the card is unpinned here so a tall banner just scrolls. */
		aspect-ratio: auto;
		max-height: none;
	}
	.hp-wd-results__media img {
		/* Image drives the media height so it fills the full width with no
		   contain letterbox. */
		height: auto;
		/* Trim the mockup WebP's 1px alpha edge-fringe (a faint
		   rgb(13,13,28) row baked into the file's outer pixels). In this
		   full-width banner the image fills its box, so that fringe landed
		   right on the banner edge and read as a visible rectangle. The
		   devices sit inside transparent padding, so clipping 2px removes
		   only the fringe. */
		clip-path: inset(2px);
	}
	.hp-wd-results__content {
		justify-content: flex-start;
	}
}

@media (max-width: 960px) {
	/* Below 960px the side-by-side split crushes the image. Stack
	   content on top, image below, both full width. Sticky pin stays so
	   the stacked-deck effect still works on tablets. Image cap bumped
	   to 38vh (was 30vh) so the portfolio mockup still leads on tablet,
	   in line with the image-led desktop split. */
	.hp-wd-results__card-inner {
		grid-template-columns: minmax(0, 1fr);
		column-gap: 0;
		row-gap: clamp(1.5rem, 3vw, 2rem);
		grid-template-rows: minmax(0, 1fr) auto;
	}
	.hp-wd-results__media {
		aspect-ratio: 16 / 9;
		max-height: 38vh;
	}
}
@media (max-width: 768px) {
	.hp-wd-results__card { height: auto; position: relative; padding: 0 clamp(1rem, 4vw, 1.5rem) clamp(1rem, 3vw, 1.5rem); }
	.hp-wd-results__card-inner { height: auto; width: 100%; }
}

/* ---- 13"-class screens and below: shorter card ------------------------
   User spec: below a 13" screen the cards read too tall. Two height cuts,
   both scoped to <=1500px so the large-desktop pinned layout is untouched:

     1. the hook line is dropped — that sentence is verbatim the FIRST
        paragraph of the full-story dialog, so no copy is lost, it just
        stops being duplicated on the card front;
     2. the CTA moves up onto the stats row, right-aligned beside the
        three numbers, instead of taking a whole line of its own beneath
        them. Removes one row + one column gap from every card.

   The inline CTA is 961px and up only: below that the stats grid
   auto-fits down to 1–2 columns and a button sitting next to it would
   crush both, so phones/tablets keep the button under the stats. */
@media (max-width: 1500px) {
	.hp-wd-results__hook { display: none; }
}
@media (min-width: 961px) and (max-width: 1500px) {
	.hp-wd-results__content {
		display: grid;
		grid-template-columns: minmax(0, 1fr) auto;
		grid-template-areas:
			"head  head"
			"stats cta";
		column-gap: clamp(1.5rem, 3vw, 2.5rem);
		/* Card is unpinned in this range (banner on top, copy below), so
		   pack the rows to the top instead of centring them. */
		align-content: start;
		/* Baseline-ish: the button sits on the bottom edge of the stats
		   block rather than floating against the big stat values. */
		align-items: end;
	}
	.hp-wd-results__card-head { grid-area: head; }
	.hp-wd-results__stats     { grid-area: stats; }
	.hp-wd-results__actions   { grid-area: cta; justify-content: flex-end; }
}
@media (max-width: 0) /* reduced motion neutralised — see main.js header */ {
	.hp-wd-results__card-inner { transform: none !important; opacity: 1 !important; }
}

/* ---- Full-story dialog ------------------------------------------------
   Native <dialog> opened by "Read the full story". Renders in the top
   layer (escapes the card's overflow:hidden), Esc + focus-return handled
   by the platform, backdrop dimmed + blurred. Body scrolls INSIDE the
   panel so the whole verbatim narrative is reachable without touching
   the sticky-stack behind it. */
.hp-wd-story {
	width: min(760px, calc(100vw - 2rem));
	max-height: min(88vh, 900px);
	padding: 0;
	border: none;
	border-radius: clamp(18px, 2vw, 28px);
	background: var(--color-primary);
	color: var(--color-paper);
	box-shadow: 0 50px 120px rgba(0, 0, 0, 0.55);
	overflow: hidden;
}
.hp-wd-story::backdrop {
	background: color-mix(in srgb, var(--color-primary) 78%, black 22%);
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
}
/* Entrance — respected only when motion is allowed. */
.hp-wd-story[open] { animation: hpWdStoryIn 0.28s ease both; }
.hp-wd-story[open]::backdrop { animation: hpWdStoryFade 0.28s ease both; }
@keyframes hpWdStoryIn {
	from { opacity: 0; transform: translateY(14px) scale(0.98); }
	to   { opacity: 1; transform: none; }
}
@keyframes hpWdStoryFade { from { opacity: 0; } to { opacity: 1; } }

.hp-wd-story__inner {
	position: relative;
	display: flex;
	flex-direction: column;
	max-height: inherit;
	padding: clamp(1.75rem, 4vw, 3rem);
}
.hp-wd-story__close {
	position: absolute;
	top: clamp(0.85rem, 2vw, 1.25rem);
	right: clamp(0.85rem, 2vw, 1.25rem);
	width: clamp(40px, 5vw, 48px);
	height: clamp(40px, 5vw, 48px);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	border: 1px solid color-mix(in srgb, var(--color-paper) 30%, transparent);
	background: transparent;
	color: var(--color-paper);
	cursor: pointer;
	transition: background 0.2s ease, color 0.2s ease, transform 0.2s ease;
}
.hp-wd-story__close:hover,
.hp-wd-story__close:focus-visible {
	background: var(--color-accent);
	border-color: var(--color-accent);
	transform: rotate(90deg);
	outline: none;
}
.hp-wd-story__head {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	column-gap: clamp(1rem, 2.5vw, 1.75rem);
	align-items: baseline;
	padding: 0 clamp(2.5rem, 6vw, 3.25rem) clamp(1.25rem, 2.5vw, 1.75rem) 0;
	border-bottom: 1px solid color-mix(in srgb, var(--color-paper) 22%, transparent);
}
.hp-wd-story__index {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.25rem, 2vw, 2rem);
	line-height: 1;
	letter-spacing: -0.02em;
	color: var(--color-accent);
}
.hp-wd-story__title {
	margin: 0;
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.5rem, 1rem + 2vw, 2.75rem);
	line-height: 1.05;
	letter-spacing: -0.02em;
	color: var(--color-paper);
	text-wrap: balance;
}
.hp-wd-story__body {
	overflow-y: auto;
	padding: clamp(1.5rem, 3vw, 2rem) clamp(0.75rem, 1.5vw, 1.25rem) clamp(1.5rem, 3vw, 2rem) 0;
	scrollbar-width: thin;
	scrollbar-color: color-mix(in srgb, var(--color-paper) 45%, transparent) transparent;
	overscroll-behavior: contain;
}
.hp-wd-story__body p {
	margin: 0 0 clamp(0.85rem, 1.4vw, 1.15rem) 0;
	font-size: clamp(1rem, 0.9rem + 0.35vw, 1.1875rem);
	line-height: 1.65;
	color: color-mix(in srgb, var(--color-paper) 92%, transparent);
}
.hp-wd-story__body p:last-child { margin-bottom: 0; }
.hp-wd-story__foot {
	padding-top: clamp(1.25rem, 2.5vw, 1.75rem);
	border-top: 1px solid color-mix(in srgb, var(--color-paper) 22%, transparent);
}
.hp-wd-story__visit { align-self: flex-start; }
@media (prefers-reduced-motion: reduce) {
	.hp-wd-story[open],
	.hp-wd-story[open]::backdrop { animation: none; }
	.hp-wd-story__close:hover,
	.hp-wd-story__close:focus-visible { transform: none; }
}

/* ============== Web Design "What Our Clients Say" (brutalist) ============
   Replaces the shared 3-col grid with a stacked brutalist layout —
   each testimonial is its own full-width block with an oversized
   numbered tab, giant pink opening quote mark, display-sans quote
   body, optional attribution. Pink hairline rules separate the
   blocks; the last block's bottom rule doubles as the section
   thread baseline (mandatory thread per [[feedback-eb-thread-mandatory]]). */

.hp-wd-quotes {
	position: relative;
	padding:
		clamp(8rem, 16vw, 14rem)
		clamp(1.5rem, 5vw, 6rem);
	overflow: visible;
}
/* Pink brand thread on the right — enters at H2 level, runs vertically
   through the empty right side of the testimonial column, exits at
   section bottom. Geometry + stroke-draw via wireWdQuotesThread. */
.hp-wd-quotes__thread {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	z-index: 0;
	overflow: visible;
}
.hp-wd-quotes__thread path {
	fill: none;
	stroke: var(--color-accent);
	stroke-width: clamp(22px, 2vw, 30px);
	stroke-linecap: round;
	stroke-linejoin: round;
}
.hp-wd-quotes__head,
.hp-wd-quotes__list { position: relative; z-index: 1; }
.hp-wd-quotes__head {
	display: flex;
	justify-content: flex-start;
	margin-bottom: clamp(4rem, 8vw, 6rem);
}
.hp-wd-quotes__h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	/* Brutalist scale — matches the WD page's other anchor H2s. */
	font-size: clamp(3rem, calc(1.5rem + 6vw), 8rem);
	line-height: 0.95;
	letter-spacing: -0.03em;
	margin: 0;
	max-width: 14ch;
	color: var(--color-paper);
	text-wrap: balance;
}
.hp-wd-quotes__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
}
.hp-wd-quotes__item {
	/* Pink hairline thread rules between testimonials. The first
	   block gets a top rule too; the last block keeps its bottom
	   rule so the closing thread reads as section terminator. */
	display: grid;
	grid-template-columns: minmax(0, 0.18fr) minmax(0, 1fr);
	column-gap: clamp(2rem, 4vw, 4rem);
	padding: clamp(3rem, 6vw, 5rem) 0;
	border-top: 2px solid color-mix(in srgb, var(--color-accent) 70%, transparent);
}
.hp-wd-quotes__item:last-child {
	border-bottom: 2px solid color-mix(in srgb, var(--color-accent) 70%, transparent);
}
.hp-wd-quotes__index {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.5rem, calc(1rem + 4.5vw), 6rem);
	line-height: 1;
	letter-spacing: -0.02em;
	color: var(--color-accent);
	align-self: start;
}
.hp-wd-quotes__quote {
	margin: 0;
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	column-gap: clamp(1rem, 2vw, 1.75rem);
	align-items: start;
}
.hp-wd-quotes__mark {
	font-family: var(--font-heading-family);
	font-weight: 800;
	/* Giant pink opening quote — the brutalist anchor for each row. */
	font-size: clamp(5rem, calc(2rem + 9vw), 12rem);
	line-height: 0.7;
	color: var(--color-accent);
	user-select: none;
}
.hp-wd-quotes__text {
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: clamp(1.5rem, calc(0.75rem + 1.8vw), 3rem);
	line-height: 1.15;
	letter-spacing: -0.015em;
	margin: 0;
	color: var(--color-paper);
	max-width: 28ch;
	text-wrap: balance;
}
.hp-wd-quotes__attr {
	grid-column: 2;
	margin-top: clamp(1.5rem, 3vw, 2.5rem);
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
}
.hp-wd-quotes__cite {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-style: normal;
	font-size: clamp(1rem, 1.2vw, 1.25rem);
	color: var(--color-paper);
	letter-spacing: -0.005em;
}
.hp-wd-quotes__role {
	font-family: var(--font-heading-family);
	font-size: clamp(0.85rem, 1vw, 1rem);
	color: color-mix(in srgb, var(--color-paper) 60%, transparent);
}

@media (max-width: 768px) {
	.hp-wd-quotes__item {
		grid-template-columns: minmax(0, 1fr);
		row-gap: clamp(1rem, 3vw, 1.5rem);
	}
	.hp-wd-quotes__quote {
		grid-template-columns: minmax(0, 1fr);
		row-gap: 0;
	}
	.hp-wd-quotes__mark { line-height: 0.85; }
}

/* ============== Web Design "Book a Discovery Call" (brutalist v2) =========
   Asymmetric two-column anchor: huge stair-stacked gradient H2 hard-
   left, action panel hard-right with body prose + giant pink CTA pill
   + secondary phone link. Pink hairline thread baseline footer with
   geographic foot copy.

   Ground: SATURATED (navy) on every page — user spec 2026-07-23. The
   "Let's Talk" / discovery band was a cream island between the dark
   section above it and the navy footer below; it now runs dark so the
   page closes on one continuous surface. Nothing here hardcodes an ink
   colour: the body, phone link and foot copy all take `color: inherit`,
   so they resolve to paper on the navy ground. Declared per page via
   data_eb_ground on the shared eb-cta partial. */

.hp-wd-cta {
	position: relative;
	/* Bottom padding is real now (was 0). The foot band used to supply the
	   section's closing space from its own margin + padding; with the
	   geographic line moved up into the left column, this band is what
	   keeps the panel off the footer AND gives the brand thread the room
	   it needs to sweep out horizontally below the content. */
	padding:
		clamp(8rem, 16vw, 14rem)
		clamp(1.5rem, 5vw, 6rem)
		clamp(5rem, 10vw, 8rem);
	overflow: visible;
}
.hp-wd-cta__inner {
	width: 100%;
	display: grid;
	/* H2 left ~6fr | action panel right ~5fr | thin gutter. */
	grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
	column-gap: clamp(3rem, 6vw, 6rem);
	row-gap: clamp(2.5rem, 5vw, 4rem);
	align-items: start;
}
.hp-wd-cta__head { min-width: 0; }
.hp-wd-cta__h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	/* Was raw 5vw = 18.75px @ 375 (barely bigger than body) and unbounded
	   on ultrawide. Clamp gives a real mobile floor + desktop ceiling. */
	font-size: clamp(2.5rem, calc(1.5rem + 4vw), 5.5rem);
	line-height: 0.95;
	letter-spacing: -0.03em;
	margin: 0;
	max-width: 10ch;
	text-align: left;
	text-wrap: balance;
}
.hp-wd-cta__panel {
	display: flex;
	flex-direction: column;
	gap: clamp(1.75rem, 3vw, 2.5rem);
	min-width: 0;
}
.hp-wd-cta__body {
	display: flex;
	flex-direction: column;
	gap: clamp(0.85rem, 1.4vw, 1.25rem);
	max-width: 52ch;
	text-align: left;
}
.hp-wd-cta__body p {
	margin: 0;
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-size: clamp(1.05rem, calc(0.85rem + 0.6vw), 1.5rem);
	line-height: 1.5;
	/* Inherit the section's ground ink (navy on light, cream on saturated)
	   so the body stays visible on BOTH grounds — legal/sitemap render this
	   CTA on the navy 'saturated' ground where hardcoded navy vanished. */
	color: inherit;
	text-align: left;
}
/* Primary CTA — now the global .hp-btn pink pill (large variant) so it
   stays uniform with every other button site-wide. This scope hook only
   controls its placement in the action panel: left-aligned at natural
   pill width instead of stretching to the flex column's full width. */
.hp-wd-cta__primary {
	align-self: flex-start;
}
/* Action panel — everything in the right column reads hard-left, in line
   with the body copy and the CTA pill. Stated here because two pages
   still carry a legacy `text-align: center` on the SECTION element from
   their pre-shared-partial CTAs (.hp-seo-cta, .hp-ppc-cta): the h2 and
   body set their own left alignment, so only the phone link inherited
   the centring and sat adrift of the button above it. */
.hp-wd-cta__panel {
	text-align: left;
}
/* Phone link — secondary, smaller, follows the ground ink. */
.hp-wd-cta__phone {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.25rem;
	text-decoration: none;
	color: inherit; /* follow the ground ink (see body note above) */
	max-width: 28ch;
	/* No trailing gutter — the label and number start on the same left
	   edge as the body copy and the pill, and nothing pads them inward
	   from the right. */
	text-align: left;
	padding-right: 0;
	transition: color 0.3s ease;
}
.hp-wd-cta__phone:hover { color: var(--color-accent); }
.hp-wd-cta__phone-label {
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-size: clamp(0.85rem, 0.95vw, 1rem);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	opacity: 0.7;
}
.hp-wd-cta__phone-number {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.5rem, calc(0.75rem + 1.4vw), 2.5rem);
	line-height: 1.05;
	letter-spacing: -0.015em;
}
/* Geographic line — now a block inside the LEFT column, under the H2,
   introduced by the pink hairline (user spec 2026-07-23). It was a
   full-width band pinned to the section bottom, but the brand thread
   closes with a horizontal sweep 30px above that band's rule, so the two
   pink lines stacked and the divider read as part of the ribbon. Sitting
   under the heading it is unambiguously a divider, and the bottom of the
   section is left to the thread. */
.hp-wd-cta__foot {
	margin-top: clamp(2rem, 4vw, 3rem);
	padding-top: clamp(1rem, 2vw, 1.5rem);
	border-top: 2px solid color-mix(in srgb, var(--color-accent) 70%, transparent);
}
.hp-wd-cta__foot p {
	/* Left-anchored under the heading (was right-anchored across the full
	   section width). Narrower measure because it now lives in the 6fr
	   column rather than spanning everything. */
	margin: 0;
	max-width: 34ch;
	text-align: left;
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-size: clamp(0.85rem, 0.95vw, 1rem);
	line-height: 1.5;
	letter-spacing: 0.02em;
	color: inherit; /* follow the ground ink; dimmed via opacity below */
	opacity: 0.65;
}
/* Thread SVG — pink ribbon enters off-canvas left at the panel top,
   sweeps right, runs vertically alongside the action column, curves
   left at the foot baseline, exits left. */
.hp-wd-cta__thread {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	z-index: 0;
	overflow: visible;
}
.hp-wd-cta__thread path {
	fill: none;
	stroke: var(--color-accent);
	stroke-width: clamp(22px, 2vw, 30px);
	stroke-linecap: round;
	stroke-linejoin: round;
}
/* Lift the content above the thread SVG. The geographic line no longer
   needs its own entry: it sits inside this grid now. */
.hp-wd-cta__inner { position: relative; z-index: 1; }

@media (max-width: 960px) {
	.hp-wd-cta__inner { grid-template-columns: minmax(0, 1fr); }
	/* Once the heading spans the full column, 5vw is far too small on a
	   phone (~19px at 390px wide). Rescale against the now-full width so
	   it stays a proper display heading down to the smallest screens. */
	.hp-wd-cta__h2 { font-size: clamp(2.5rem, 11vw, 4.5rem); }
}

/* ============== Web Design FAQ (brutalist numbered stack) =================
   Hard-right H2 (R-02 alternation vs CTA's hard-left H2 above), tall
   numbered list, native `<details>` for open/close with custom + → ×
   toggle, pink hairline thread rules between every row. Saturated
   navy ground — the page's closing dark surface. */

.hp-wd-faq {
	position: relative;
	/* Generous brutalist top padding separates the FAQ from the section
	   above. The bottom is trimmed: this partial is always the last
	   content section before the footer, and the footer supplies its own
	   top padding (clamp(4rem,9vw,7rem)) on the same navy ground — so a
	   full-height bottom pad here just doubled up into a huge navy gap. */
	padding-block-start: clamp(8rem, 16vw, 14rem);
	padding-block-end: clamp(4rem, 8vw, 7rem);
	padding-inline: clamp(1.5rem, 5vw, 6rem);
	overflow: visible;
}
.hp-wd-faq__head {
	display: flex;
	justify-content: flex-end;
	margin-bottom: clamp(4rem, 7vw, 6rem);
}
.hp-wd-faq__h2 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.75rem, calc(1.25rem + 5.5vw), 8rem);
	line-height: 0.95;
	letter-spacing: -0.03em;
	margin: 0;
	max-width: 14ch;
	color: var(--color-paper);
	text-align: right;
	text-wrap: balance;
}
.hp-wd-faq__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
}
.hp-wd-faq__item {
	border-top: 2px solid color-mix(in srgb, var(--color-accent) 70%, transparent);
}
.hp-wd-faq__item:last-child {
	border-bottom: 2px solid color-mix(in srgb, var(--color-accent) 70%, transparent);
}
.hp-wd-faq__details {
	padding: 0;
}
.hp-wd-faq__details > summary {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	column-gap: clamp(1.5rem, 3vw, 2.5rem);
	align-items: center;
	padding: clamp(1.75rem, 3vw, 2.75rem) 0;
	cursor: pointer;
	list-style: none;
}
.hp-wd-faq__details > summary::-webkit-details-marker { display: none; }
.hp-wd-faq__num {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.5rem, calc(0.75rem + 1.6vw), 2.5rem);
	line-height: 1;
	letter-spacing: -0.02em;
	color: var(--color-accent);
}
.hp-wd-faq__q-text {
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: clamp(1.15rem, calc(0.85rem + 1vw), 2rem);
	line-height: 1.2;
	letter-spacing: -0.015em;
	color: var(--color-paper);
	text-wrap: balance;
}
/* Custom toggle — two pink bars forming a + (closed) / − (open). */
.hp-wd-faq__toggle {
	position: relative;
	width:  clamp(2.25rem, 3vw, 2.75rem);
	height: clamp(2.25rem, 3vw, 2.75rem);
	border-radius: 50%;
	background: color-mix(in srgb, var(--color-accent) 18%, transparent);
	display: grid;
	place-items: center;
	flex-shrink: 0;
}
.hp-wd-faq__toggle-bar {
	position: absolute;
	left: 50%;
	top:  50%;
	width:  45%;
	height: 3px;
	background: var(--color-accent);
	border-radius: 2px;
	transform: translate(-50%, -50%);
	transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.2, 1), opacity 0.3s ease;
}
.hp-wd-faq__toggle-bar--v {
	transform: translate(-50%, -50%) rotate(90deg);
}
.hp-wd-faq__details[open] .hp-wd-faq__toggle-bar--v {
	transform: translate(-50%, -50%) rotate(0deg);
	opacity: 0;
}
.hp-wd-faq__a {
	overflow: hidden;
	padding-left: calc(clamp(1.5rem, 3vw, 2.5rem) + clamp(1.5rem, calc(0.75rem + 1.6vw), 2.5rem));
	padding-right: calc(clamp(1.5rem, 3vw, 2.5rem) + clamp(2.25rem, 3vw, 2.75rem));
	padding-bottom: clamp(1.75rem, 3vw, 2.75rem);
}
.hp-wd-faq__a p {
	margin: 0;
	font-family: var(--font-heading-family);
	font-weight: 500;
	font-size: clamp(1rem, calc(0.85rem + 0.5vw), 1.35rem);
	line-height: 1.6;
	color: color-mix(in srgb, var(--color-paper) 85%, transparent);
	max-width: 80ch;
}

/* Open/close animation — bouncy spring via the shared hp-faq-bounce-in
   keyframe defined alongside .hp-seo-faq__a. The prefers-reduced-motion
   wrap is intentionally removed: per [[feedback-hp-animations-are-content]],
   the FAQ bounce reads as brand content and plays for everyone. */
.hp-wd-faq__details:not([open]) .hp-wd-faq__a { display: none; }

@media (max-width: 768px) {
	.hp-wd-faq__head { justify-content: flex-start; }
	.hp-wd-faq__h2 { text-align: left; }
	.hp-wd-faq__details > summary {
		grid-template-columns: auto minmax(0, 1fr);
		row-gap: 0.5rem;
	}
	.hp-wd-faq__toggle { grid-column: 1 / -1; justify-self: end; }
	.hp-wd-faq__a {
		padding-left: 0;
		padding-right: 0;
	}
}

/* ============== Web Design — thread-channel responsive guards ============
   Per [[feedback-eb-thread-mandatory]] R-10 strict rule: every section
   reserves a "thread channel" as a real layout track so text content
   can NEVER grow into the thread's path. The channel width scales
   from ~60px on narrow viewports up to ~160px on wide. Each section
   that hosts a right-side or left-side vertical thread reserves this
   channel via padding on its content containers.

   Mobile (<640px) hides the structural threads entirely — the
   stroke clamp's floor of 22px is too thick to share a 320px viewport
   with content, and the corner R=80 needs ≥160px of vertical room
   the layout doesn't have when content stacks to single column. */
:root {
	--wd-thread-channel: clamp(60px, 8vw, 160px);
}

/* CTA — thread runs vertically along the right side of the panel
   column. Only the inner grid needs the channel now: the geographic foot
   line moved inside the left column, so the inner's own right padding
   already keeps it clear of xVert. */
.hp-wd-cta__inner {
	padding-right: var(--wd-thread-channel);
}

/* Quotes — thread runs vertically along the right side of every
   testimonial row. Reserve channel on the list + header so the H2
   and quote bodies stop before the thread x. */
.hp-wd-quotes__head,
.hp-wd-quotes__list {
	padding-right: var(--wd-thread-channel);
}

/* Outperform — reserve the channel the ribbon actually occupies.
   wireOutperformThread builds the vertical column in FIXED pixels:
   the horizontal run stops 50px inside the right edge, then the R=80
   corner puts the column centre at x = w - 130. Half the stroke
   (clamp(22px, 2vw, 30px) → 15px at its widest) puts the ribbon's
   inner edge at w - 145.

   The shared --wd-thread-channel is 8vw, which falls under 145px below
   ~1810px wide — so from roughly 1150px down the body copy ran into
   the stroke ("…keeps people on your site" was struck through at
   1100px, measured -13px of overlap). Floor the channel at 169px
   (130 + 15 stroke + 24 breathing gap) so the text clears the ribbon
   at every width the ribbon is drawn. Above ~2113px, 8vw takes over
   again and the gap simply widens.

   The <640px rule below resets this to 0 — the thread is hidden there,
   so the space is handed back to content. */
.hp-wd-outperform__inner {
	padding-right: max(var(--wd-thread-channel), 169px);
}

/* Process — thread runs through the numbered circle column on the
   right column's left edge. The grid track already isolates it from
   body text, but on very narrow widths the index column shrinks; cap
   the inner with a small extra right pad so the bottom-exit corner
   has room. */
.hp-wd-process__inner {
	padding-right: clamp(0.5rem, 2vw, 1.5rem);
}

@media (max-width: 640px) {
	/* Below 640px every structural thread on the WD page hides — the
	   18-30px stroke can't coexist with stacked single-column content
	   in a 320-639px viewport without bleeding through text.
	   EXCEPTION: .hp-wd-process__thread stays on — per user spec it runs
	   on mobile at the homepage brand-thread's thin mobile stroke
	   (calc(1.46vw + 2px), override below), which threads through the
	   numbered circle column without bleeding into the phase copy. */
	.hp-wd-hero__thread,
	.hp-wd-perform__thread,
	.hp-wd-outperform__thread,
	.hp-wd-quotes__thread,
	.hp-wd-cta__thread {
		display: none;
	}
	/* Reclaim the channel space for content. */
	.hp-wd-cta__inner,
	.hp-wd-quotes__head,
	.hp-wd-quotes__list,
	.hp-wd-outperform__inner {
		padding-right: 0;
	}
}

/* ============== Web Design — page-wide section padding bump ==============
   Per user spec: every WD section gets MORE vertical breathing room.
   The hp-wd-* sections set their padding directly (above). For the
   shared EB sections used on the WD page (eb-approach, hp-eb-grid3,
   eb-cta, eb-faq, eb-stats), we override --eb-section-pad-y just for
   the .hp-eb-wd main wrapper so the bump doesn't leak onto the SEO /
   PPC / Videography pages. */
.hp-eb-wd {
	--eb-section-pad-y: clamp(8rem, 16vw, 14rem);
}

/* WD "Why Higher Performance" — no word-colour override. The section
   moved from the cream LIGHT ground to the SATURATED navy ground (user
   request: the whole run from the hero down to "What Our Websites
   Actually Deliver" stays dark), so the default paper-on-navy
   .hp-scroll-color__word recipe in main.css is already correct. The
   navy override that used to live here would now paint navy-on-navy. */

/* ============== H1 word-by-word entrance ==============
   Every <h1> on every page gets a staggered word reveal on first
   appearance (or on viewport entry for below-fold H1s). wireH1Entrance
   wraps each word in <span class="hp-h1-word"> with a per-word `--i`
   and adds .is-h1-entered to the H1 when it's in view. The reveal
   is pure CSS: opacity 0 → 1, translateY 0.35em → 0, with a per-word
   delay of `--i × 70ms`. Brand-content motion — plays for everyone
   per [[feedback-hp-animations-are-content]]. */
.hp-h1-word {
	display: inline-block;
	opacity: 0;
	transform: translateY(0.35em);
	transition:
		opacity   0.7s cubic-bezier(0.2, 0.75, 0.2, 1),
		transform 0.7s cubic-bezier(0.2, 0.75, 0.2, 1);
	transition-delay: calc(var(--i, 0) * 70ms);
	will-change: opacity, transform;
}
h1.is-h1-entered .hp-h1-word {
	opacity: 1;
	transform: translateY(0);
}

/* ============== About Us page ==============
   Editorial Brutalism long-form page. Reuses .hp-seo-hero,
   .hp-eb-split and .hp-eb-prose chassis classes; the rules below
   add the About-only touches:

   - hero eyebrow line above the H1
   - right-column credentials showcase (stat / quote / pin cards)
   - prose body uses navy-on-cream colour for the scroll-color sweep
     on the light "More Than Just Marketing" section (same recipe as
     .hp-eb-wd .hp-eb-prose, scoped to .hp-eb-about so the WD page
     keeps its own scope). */

.hp-eb-about {
	--eb-section-pad-y: clamp(7rem, 14vw, 12rem);
}

/* About H1 clamp — smaller than the shared .hp-seo-hero .hp-seo-hero__h1
   clamp(3rem, 10.5vw, 8rem), which is sized for short stair-stack words
   ("SEO Agency"). "Performance" is 11 characters and overflowed the 1.7fr
   copy column at mid widths, forcing the pink period to wrap. Same
   specificity (0,2,0) but declared later, so it wins. */
.hp-about-hero .hp-about-hero__h1 {
	font-size: clamp(2.25rem, 7.5vw, 6.5rem);
}

.hp-about-hero__eyebrow {
	font-family: var(--font-heading-family, var(--font-display, sans-serif));
	font-size: clamp(0.78rem, 0.9vw, 0.95rem);
	font-weight: 600;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--color-accent, #ff4d8d);
	margin: 0 0 clamp(1.25rem, 2vw, 1.75rem) 0;
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
}

.hp-about-hero__showcase {
	grid-column: 3;
	position: relative;
	display: flex;
	flex-direction: column;
	gap: clamp(1.1rem, 2vw, 1.8rem);
	align-self: stretch;
	justify-content: center;
	min-width: 0;
}

.hp-about-hero__card {
	position: relative;
	background: var(--color-paper, #f5efe6);
	color: var(--color-primary, #081427);
	border-radius: 22px;
	padding: clamp(1rem, 1.4vw, 1.4rem) clamp(1.1rem, 1.6vw, 1.55rem);
	box-shadow:
		0 28px 60px -28px rgba(0, 0, 16, 0.45),
		0 8px 20px -10px rgba(0, 0, 16, 0.25);
	transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.5s ease;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
}
.hp-about-hero__card:hover {
	transform: translateY(-4px);
}

.hp-about-hero__card--stat {
	/* Stagger offsets removed per user spec — the three credentials
	   cards now align flush in the showcase column. */
	margin: 0;
}
.hp-about-hero__card-eyebrow {
	font-size: 0.72rem;
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: rgba(0, 0, 16, 0.55);
}
.hp-about-hero__card-num {
	font-family: var(--font-heading-family, sans-serif);
	font-weight: 800;
	font-size: clamp(2.4rem, 4.5vw, 3.6rem);
	line-height: 1;
	color: var(--color-accent, #ff4d8d);
	letter-spacing: -0.03em;
	font-variant-numeric: tabular-nums;
}
.hp-about-hero__card-label {
	font-size: 0.92rem;
	color: rgba(0, 0, 16, 0.75);
	line-height: 1.45;
}

.hp-about-hero__card--quote {
	margin: 0;
}
.hp-about-hero__card--quote svg {
	color: var(--color-accent, #ff4d8d);
}
.hp-about-hero__card-quote {
	font-family: var(--font-heading-family, sans-serif);
	font-weight: 700;
	font-size: clamp(1rem, 1.2vw, 1.15rem);
	line-height: 1.35;
	margin: 0;
	letter-spacing: -0.01em;
	color: rgba(0, 0, 16, 0.92);
}

.hp-about-hero__card--pin {
	margin: 0;
	flex-direction: row;
	align-items: center;
	flex-wrap: wrap;
	gap: 0.5rem 0.7rem;
}
.hp-about-hero__card--pin svg {
	color: var(--color-accent, #ff4d8d);
	flex: 0 0 auto;
}
.hp-about-hero__card-pin-label {
	font-family: var(--font-heading-family, sans-serif);
	font-weight: 700;
	font-size: 0.98rem;
	color: rgba(0, 0, 16, 0.95);
	letter-spacing: -0.005em;
}
.hp-about-hero__card-pin-sub {
	flex: 1 1 100%;
	font-size: 0.82rem;
	color: rgba(0, 0, 16, 0.6);
	margin-left: calc(18px + 0.7rem);
	margin-top: -0.2rem;
}

/* 1024px, not 900px: matches the .hp-eb-hero__inner grid collapse so the
   credentials cards drop full-width under the copy instead of overflowing
   the right edge in the 900-1024 band. */
@media (max-width: 1024px) {
	.hp-about-hero__showcase {
		grid-column: 1 / -1;
		/* Once stacked, the cards fall directly under the Call Us button.
		   Add breathing room so the Combined Experience card isn't crowded
		   against the actions row. */
		margin-top: clamp(1.5rem, 5vw, 2.5rem);
	}
	.hp-about-hero__card--stat,
	.hp-about-hero__card--quote,
	.hp-about-hero__card--pin {
		margin: 0;
	}
}

/* ---------- About ground wash — navy → cream → navy ----------------- */
/* User spec: the About page runs dark throughout, with "More Than Just
   Marketing" as the single section that washes to cream mid-scroll. The
   specialists section above it takes the SAME --hp-about-wash (declared via
   data-eb-wash-with, driven by wireEbGroundWash) so the seam between the two
   morphs as one surface instead of showing a hard line mid-viewport.

   --about-ground = current ground (navy at 0, cream at 1).
   --about-ink    = its inverse, used for every piece of copy in the pair so
                    it stays legible through the mid-transition grey. The
                    pink brand thread and pink pull-rules are NOT mapped to
                    it: pink reads on both grounds. Same rules as the PPC
                    wash block above. */
.hp-about-specialists,
.hp-about-marketing {
	--about-ground: color-mix(
		in oklab,
		var(--color-paper) calc(var(--hp-about-wash) * 100%),
		var(--color-primary)
	);
	--about-ink: color-mix(
		in oklab,
		var(--color-primary) calc(var(--hp-about-wash) * 100%),
		var(--color-paper)
	);
}
/* Rest values match each section's declared data-eb-ground, so no-JS and
   reduced-motion visitors see exactly what the attribute promises. */
.hp-about-specialists { --hp-about-wash: 0; }
.hp-about-marketing   { --hp-about-wash: 1; }

.hp-about-specialists[data-eb-ground="saturated"],
.hp-about-marketing[data-eb-ground="light"] {
	background: var(--about-ground);
	color: var(--about-ink);
}
@supports not (color: color-mix(in oklab, red, blue)) {
	.hp-about-specialists[data-eb-ground="saturated"] {
		background: var(--color-primary);
		color: var(--color-paper);
	}
	.hp-about-marketing[data-eb-ground="light"] {
		background: var(--color-paper);
		color: var(--color-primary);
	}
}

/* Scroll-color word fill inside the washing pair — mixed against
   --about-ink so it tracks the ground instead of sitting at a fixed colour
   (paper would vanish at the cream end, navy at the dark end).

   The .hp-eb-about ancestor is REQUIRED, not decorative: it takes these to
   (0,3,0) so they beat `.hp-eb .hp-scroll-color__word` in
   editorial-brutalism.css, which is (0,2,0) and is enqueued AFTER this
   stylesheet — equal specificity would lose on source order. That base EB
   rule paints paper-on-dark and its per-ground variants key off
   data-eb-ground="paper"/"dark", which these sections do not use (they are
   "light"/"saturated"), so without this the marketing copy renders paper on
   a cream ground: invisible. The PPC equivalents need only (0,2,0) because
   the PPC template's main element carries no .hp-eb class. */
.hp-eb-about .hp-about-specialists .hp-scroll-color__word,
.hp-eb-about .hp-about-marketing .hp-scroll-color__word {
	color: color-mix(
		in srgb,
		var(--about-ink) calc(var(--lit) * 100%),
		color-mix(in srgb, var(--about-ink) 52%, transparent)
	);
}
@supports not (color: color-mix(in srgb, red, blue)) {
	.hp-eb-about .hp-about-specialists .hp-scroll-color__word { color: var(--color-paper); }
	.hp-eb-about .hp-about-marketing .hp-scroll-color__word   { color: var(--color-primary); }
}

/* Every OTHER About prose block now sits on the permanent navy ground, so
   the default paper-on-navy recipe in main.css is already correct. The
   navy-on-cream override that used to live here would paint navy-on-navy;
   it is superseded by the --about-ink rules above, which are scoped to the
   two washing sections only. */


/* ============== Coming Soon placeholder template ==============
   Service-page placeholder used while real copy is being written.
   Reuses .hp-seo-hero chassis (so wireSeoHeroThread picks up the
   period dot automatically); the rules below only add the
   placeholder-specific eyebrow + "in production" credentials card. */

.hp-eb-soon {
	--eb-section-pad-y: clamp(7rem, 14vw, 12rem);
}

.hp-soon-hero__eyebrow {
	font-family: var(--font-heading-family, sans-serif);
	font-size: clamp(0.78rem, 0.9vw, 0.95rem);
	font-weight: 600;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--color-accent, #ff4d8d);
	margin: 0 0 clamp(1.25rem, 2vw, 1.75rem) 0;
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
}

.hp-soon-hero__showcase {
	grid-column: 3;
	position: relative;
	display: flex;
	align-self: center;
	min-width: 0;
}

.hp-soon-hero__card {
	background: var(--color-paper, #f5efe6);
	color: var(--color-primary, #081427);
	border-radius: 22px;
	padding: clamp(1.5rem, 2.5vw, 2.25rem);
	box-shadow:
		0 28px 60px -28px rgba(0, 0, 16, 0.45),
		0 8px 20px -10px rgba(0, 0, 16, 0.25);
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
	width: 100%;
	transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
.hp-soon-hero__card:hover {
	transform: translateY(-4px);
}
.hp-soon-hero__card svg {
	color: var(--color-accent, #ff4d8d);
	flex: 0 0 auto;
}
.hp-soon-hero__card-title {
	font-family: var(--font-heading-family, sans-serif);
	font-weight: 800;
	font-size: clamp(1.1rem, 1.4vw, 1.35rem);
	margin: 0;
	letter-spacing: -0.01em;
	color: rgba(0, 0, 16, 0.95);
}
.hp-soon-hero__card-body {
	font-size: 0.95rem;
	line-height: 1.55;
	color: rgba(0, 0, 16, 0.75);
	margin: 0;
}

@media (max-width: 900px) {
	.hp-soon-hero__showcase {
		grid-column: 1 / -1;
	}
}

.hp-soon-prose {
	padding-top: clamp(4rem, 8vw, 7rem);
	padding-bottom: clamp(4rem, 8vw, 7rem);
}
.hp-soon-prose .hp-eb-prose__body p {
	font-size: clamp(1rem, 1.15vw, 1.15rem);
	line-height: 1.7;
	color: rgba(0, 0, 16, 0.85);
	max-width: 70ch;
	margin: 0 auto 1.2em;
}

/* ============== Contact page ==============
   Hero + form chassis. Two-column hero with brand copy on the left
   and the enquiry form on the right. Reuses .hp-seo-hero so the
   period dot thread anchors automatically.

   Form state machine:
     default          form visible, thanks hidden
     [is-submitting]  submit button disabled, spinner visible
     [is-done]        form display:none, thanks panel visible

   Honeypot lives off-canvas with screen-reader-text-style positioning. */

.hp-eb-contact {
	--eb-section-pad-y: clamp(7rem, 14vw, 12rem);
}

.hp-contact-hero {
	padding:
		clamp(7rem, 14vw, 12rem)
		max(var(--eb-channel-w), clamp(1.25rem, 4vw, 3rem));
}
.hp-contact-hero__inner {
	max-width: 1480px;
	margin: 0 auto;
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
	gap: clamp(2rem, 5vw, 5rem);
	align-items: start;
}
@media (max-width: 1024px) {
	.hp-contact-hero__inner { grid-template-columns: 1fr; }
}

.hp-contact-hero__copy { min-width: 0; }
.hp-contact-hero__eyebrow {
	font-family: var(--font-heading-family, sans-serif);
	font-size: clamp(0.78rem, 0.9vw, 0.95rem);
	font-weight: 600;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--color-accent, #ff4d8d);
	margin: 0 0 clamp(1.25rem, 2vw, 1.75rem);
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
}
.hp-contact-hero__lead {
	font-size: clamp(1.05rem, 1.4vw, 1.3rem);
	line-height: 1.55;
	max-width: 38ch;
	color: color-mix(in srgb, currentColor 85%, transparent);
	margin: clamp(1.5rem, 3vw, 2.5rem) 0 clamp(2rem, 4vw, 3rem);
}
.hp-contact-hero__details {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: clamp(1.25rem, 2.2vw, 1.75rem);
}
.hp-contact-hero__detail {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
}
.hp-contact-hero__detail-label {
	font-size: 0.78rem;
	font-weight: 600;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: color-mix(in srgb, currentColor 55%, transparent);
}
.hp-contact-hero__detail-value {
	font-family: var(--font-heading-family, sans-serif);
	font-weight: 700;
	font-size: clamp(1.1rem, 1.3vw, 1.3rem);
	color: inherit;
	text-decoration: none;
	font-style: normal;
	line-height: 1.4;
	letter-spacing: -0.005em;
}
a.hp-contact-hero__detail-value:hover {
	color: var(--color-accent, #ff4d8d);
}

/* Form column — paper card sitting on the saturated hero ground. */
.hp-contact-hero__form-col { min-width: 0; }

.hp-contact-form-wrap {
	background: var(--color-paper, #f5efe6);
	color: var(--color-primary, #081427);
	border-radius: 22px;
	padding: clamp(1.75rem, 3vw, 2.75rem);
	box-shadow:
		0 32px 70px -30px rgba(0, 0, 16, 0.55),
		0 12px 30px -16px rgba(0, 0, 16, 0.3);
}

.hp-contact-form {
	display: flex;
	flex-direction: column;
	gap: clamp(1.1rem, 1.8vw, 1.6rem);
}
.hp-contact-form__hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}
.hp-contact-form__row { margin: 0; }
.hp-contact-form__row--split {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: clamp(0.85rem, 1.4vw, 1.25rem);
}
@media (max-width: 620px) {
	.hp-contact-form__row--split { grid-template-columns: 1fr; }
}

.hp-contact-form__field {
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
	min-width: 0;
}
.hp-contact-form__label {
	font-family: var(--font-heading-family, sans-serif);
	font-size: 0.85rem;
	font-weight: 600;
	letter-spacing: 0.04em;
	color: rgba(0, 0, 16, 0.7);
}
.hp-contact-form__label span[aria-hidden] {
	color: var(--color-accent, #ff4d8d);
	margin-left: 0.15rem;
}
.hp-contact-form__hint {
	font-weight: 500;
	font-size: 0.78rem;
	color: rgba(0, 0, 16, 0.55);
	letter-spacing: 0.02em;
	margin-left: 0.4rem;
}
.hp-contact-form__input {
	width: 100%;
	font-family: inherit;
	font-size: 1rem;
	line-height: 1.5;
	color: rgba(0, 0, 16, 0.95);
	background: #fff;
	border: 1px solid rgba(0, 0, 16, 0.12);
	border-radius: 12px;
	padding: 0.85rem 1rem;
	transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
	appearance: none;
	-webkit-appearance: none;
}
.hp-contact-form__input:focus {
	outline: none;
	border-color: var(--color-accent, #ff4d8d);
	box-shadow: 0 0 0 4px color-mix(in srgb, var(--color-accent, #ff4d8d) 18%, transparent);
}
.hp-contact-form__input::placeholder {
	color: rgba(0, 0, 16, 0.4);
	font-weight: 400;
}
.hp-contact-form__textarea {
	resize: vertical;
	min-height: 140px;
}
select.hp-contact-form__input {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23081427' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 1rem center;
	background-size: 18px 18px;
	padding-right: 2.6rem;
}

.hp-contact-form__error {
	font-size: 0.82rem;
	color: #d63638;
	min-height: 1.2em;
	font-weight: 500;
}
.hp-contact-form__error:empty { min-height: 0; }
.hp-contact-form__input[aria-invalid="true"] {
	border-color: #d63638;
	box-shadow: 0 0 0 3px rgba(214, 54, 56, 0.15);
}

/* Services chip group — rendered as pill checkboxes. */
.hp-contact-form__services {
	border: 0;
	margin: 0;
	padding: 0;
	min-width: 0;
}
.hp-contact-form__chips {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 0.55rem;
	margin-top: 0.55rem;
}
.hp-contact-form__chip {
	display: inline-flex;
	align-items: center;
	cursor: pointer;
	user-select: none;
}
.hp-contact-form__chip input {
	position: absolute;
	left: -9999px;
	opacity: 0;
}
.hp-contact-form__chip-label {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	padding: 0.55rem 1rem;
	border-radius: 999px;
	border: 1px solid rgba(0, 0, 16, 0.18);
	background: #fff;
	font-size: 0.92rem;
	font-weight: 600;
	letter-spacing: -0.005em;
	color: rgba(0, 0, 16, 0.78);
	transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
.hp-contact-form__chip-label::before {
	content: "";
	width: 14px;
	height: 14px;
	border-radius: 4px;
	border: 1.5px solid rgba(0, 0, 16, 0.3);
	background: #fff;
	transition: background 0.2s ease, border-color 0.2s ease;
}
.hp-contact-form__chip input:checked + .hp-contact-form__chip-label {
	background: color-mix(in srgb, var(--color-accent, #ff4d8d) 14%, #fff);
	border-color: var(--color-accent, #ff4d8d);
	color: rgba(0, 0, 16, 0.95);
}
.hp-contact-form__chip input:checked + .hp-contact-form__chip-label::before {
	background: var(--color-accent, #ff4d8d);
	border-color: var(--color-accent, #ff4d8d);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12l5 5L20 7'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: center;
	background-size: 10px 10px;
}
.hp-contact-form__chip input:focus-visible + .hp-contact-form__chip-label {
	outline: 2px solid var(--color-accent, #ff4d8d);
	outline-offset: 2px;
}

.hp-contact-form__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.85rem 1.5rem;
	margin-top: 0.25rem;
}
.hp-contact-form__small {
	font-size: 0.82rem;
	color: rgba(0, 0, 16, 0.55);
	margin: 0;
}
.hp-contact-form__submit[disabled] {
	opacity: 0.6;
	cursor: progress;
}
.hp-contact-form.is-submitting .hp-contact-form__submit-label::after {
	content: "…";
}

.hp-contact-form__status {
	margin: 0;
	font-size: 0.92rem;
	font-weight: 600;
	color: #d63638;
	min-height: 1.2em;
}
.hp-contact-form__status:empty { min-height: 0; }

/* Thank-you panel — swapped in by JS on success. */
.hp-contact-form-wrap.is-done .hp-contact-form {
	display: none;
}
.hp-contact-form__thanks {
	display: none;
	flex-direction: column;
	align-items: flex-start;
	gap: clamp(1rem, 1.8vw, 1.5rem);
	padding: clamp(0.5rem, 1vw, 1rem) 0;
}
.hp-contact-form-wrap.is-done .hp-contact-form__thanks {
	display: flex;
}
.hp-contact-form__thanks-icon {
	color: var(--color-accent, #ff4d8d);
	flex: 0 0 auto;
}
.hp-contact-form__thanks-h2 {
	font-family: var(--font-heading-family, sans-serif);
	font-weight: 800;
	font-size: clamp(2rem, 3.5vw, 2.75rem);
	letter-spacing: -0.02em;
	line-height: 1;
	margin: 0;
	color: rgba(0, 0, 16, 0.95);
}
.hp-contact-form__thanks-body {
	font-size: clamp(1rem, 1.15vw, 1.1rem);
	line-height: 1.6;
	color: rgba(0, 0, 16, 0.75);
	margin: 0;
	max-width: 40ch;
}
.hp-contact-form__thanks-actions {
	display: flex;
	gap: 0.85rem;
	flex-wrap: wrap;
	margin-top: 0.5rem;
}

/* ---------- Duotone → colour: touch fallback (R-11 mobile) ----------
   Desktop reveals full colour on pointer-hover (each component's rules
   are gated behind `(hover: hover) and (pointer: fine)` above). Touch
   devices get the same reveal while the image is scrolled into view:
   wireDuotoneInView (main.js) toggles `.is-colour`, and it only runs on
   non-hover devices, so no media gate is needed here. Keep this list in
   sync with the selector list in wireDuotoneInView. */
.hp-eb-hero__media.is-colour img,
.hp-wd-hero__media.is-colour img,
.hp-wd-perform__media.is-colour img,
.hp-eb-split__media.is-colour img,
.hp-eb-case__media.is-colour img {
	filter: none;
	mix-blend-mode: normal;
	opacity: 1;
}
.hp-eb-hero__media.is-colour::after,
.hp-wd-hero__media.is-colour::after,
.hp-wd-perform__media.is-colour::after,
.hp-eb-split__media.is-colour::after {
	opacity: 0;
}
.hp-vid-kit__figure.is-colour img {
	filter: none;
	opacity: 1;
	transform: scale(1.02);
}
.hp-vid-kit__figure.is-colour::after { opacity: 0; }
.hp-wd-outperform__media.is-colour img {
	filter: none;
	opacity: 1;
}

