/* =============================================================
   Higher Performance — main.css
   Single source of truth for site styles.
   Customizer values override the :root variables via inline <style>
   emitted at wp_head priority 99, so the cascade wins predictably.
   ============================================================= */

/* Self-hosted Oceanwide (Semibold only — no other weights licensed).
   Mapped to weight 600 so the font-matching algorithm picks it up
   for any request between 500 and 700. Lighter and heavier weights
   fall back to system-ui. */
@font-face {
	font-family: 'Oceanwide';
	src: url('../fonts/Oceanwide-Semibold.woff') format('woff');
	font-weight: 600;
	font-style: normal;
	font-display: swap;
}
@font-face {
	font-family: 'Oceanwide';
	src: url('../fonts/Oceanwide-SemiboldOblique.woff') format('woff');
	font-weight: 600;
	font-style: italic;
	font-display: swap;
}

:root {
	/* Colours (fallbacks, Customizer wins) */
	--color-primary: #000010;
	--color-secondary: #0E2348;
	--color-accent: #FD2E98;
	--color-accent-light: #FF7BC0;
	--color-paper: #F4F1EA;
	--color-white: #FFFFFF;
	--color-radial: #5170FF;
	--color-button-bg: #FD2E98;
	--color-button-text: #FFFFFF;
	--color-button-hover-bg: #FFFFFF;
	--color-button-hover-text: #000010;
	--color-link: #FD2E98;
	--color-link-hover: #FF7BC0;

	/* Typography (fallbacks) */
	--font-heading-family: 'Oceanwide', system-ui, sans-serif;
	--font-body-family: 'Oceanwide', system-ui, sans-serif;
	--font-h1-size: 6.5rem;
	--font-h1-size-mobile: 3.25rem;
	--font-h1-weight: 800;
	--font-h1-line-height: 0.95;
	--font-h1-letter-spacing: -0.03em;
	--font-h2-size: 4.5rem;
	--font-h2-size-mobile: 2.5rem;
	--font-h2-weight: 700;
	--font-h2-line-height: 1.02;
	--font-h2-letter-spacing: -0.02em;
	--font-h3-size: 2.5rem;
	--font-h3-size-mobile: 1.75rem;
	--font-h3-weight: 700;
	--font-h3-line-height: 1.1;
	--font-body-size: 1.0625rem;
	--font-body-size-mobile: 1rem;
	--font-body-weight: 400;
	--font-body-line-height: 1.6;

	/* Spacing */
	--space-1: 0.5rem;
	--space-2: 1rem;
	--space-3: 1.5rem;
	--space-4: 2rem;
	--space-5: 3rem;
	--space-6: 4rem;
	--space-7: 6rem;
	--space-8: 8rem;

	--radius-pill: 999px;
	--radius-lg: 32px;
}

/* ---------- Page transition (brand-gradient circular reveal) ----------
   A full-screen brand-gradient overlay (pink → purple) with a circular HOLE
   punched out via a radial mask. On an internal page load the hole grows from
   the centre outward, so the page is revealed through an expanding circle
   while the gradient retreats to the edges and disappears. On an internal link
   click the hole shrinks back (gradient covers) before navigating, so pages
   hand off through the gradient. --hp-hole is the hole radius. */
@property --hp-hole {
	syntax: '<length>';
	inherits: false;
	initial-value: 0px;
}
.hp-page-transition {
	position: fixed;
	inset: 0;
	z-index: 9998;
	pointer-events: none;
	background: linear-gradient(115deg, #FD2E98 0%, #B026FF 52%, #6D4DFF 100%);
	--hp-hole: 150vmax; /* default: hole fully open = overlay invisible */
	-webkit-mask: radial-gradient(circle at 50% 50%, transparent var(--hp-hole), #000 calc(var(--hp-hole) + 2px));
	        mask: radial-gradient(circle at 50% 50%, transparent var(--hp-hole), #000 calc(var(--hp-hole) + 2px));
	will-change: --hp-hole;
}
/* Entrance reveal — internal pages only (the home hero is its own intro). The
   hole grows from 0 (gradient fully covers) to past the corners (revealed). */
body:not(.home) .hp-page-transition {
	animation: hp-page-reveal 1.15s cubic-bezier(0.65, 0, 0.35, 1) both;
}
@keyframes hp-page-reveal {
	from { --hp-hole: 0px; }
	to   { --hp-hole: 150vmax; }
}
/* Exit cover — JS adds .is-leaving on click; the hole shrinks so the gradient
   closes back over the page before navigating. */
body:not(.home) .hp-page-transition.is-leaving {
	pointer-events: auto;
	animation: hp-page-cover 0.55s cubic-bezier(0.7, 0, 0.25, 1) forwards;
}
@keyframes hp-page-cover {
	from { --hp-hole: 150vmax; }
	to   { --hp-hole: 0px; }
}
@media (prefers-reduced-motion: reduce) {
	.hp-page-transition { display: none; }
}

/* ---------- Reset / base ---------- */

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; overflow-x: clip; }

body.hp-body {
	margin: 0;
	background: var(--color-primary);
	color: var(--color-paper);
	font-family: var(--font-body-family);
	font-size: var(--font-body-size);
	line-height: var(--font-body-line-height);
	font-weight: var(--font-body-weight);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	text-rendering: optimizeLegibility;
	/* Kill the stray horizontal scroll caused by 100vw full-bleed elements
	   (100vw includes the scrollbar width) and off-canvas brand-thread tails.
	   `clip` (not `hidden`) does NOT create a scroll container, so the sticky
	   showreel / promise sections keep working. */
	overflow-x: clip;
}

img { max-width: 100%; height: auto; display: block; }

a { color: var(--color-link); text-decoration: none; transition: color 0.2s ease; }
a:hover { color: var(--color-link-hover); }

h1, h2, h3, h4, h5, h6 {
	font-family: var(--font-heading-family);
	margin: 0 0 var(--space-3);
}

h1 { font-size: var(--font-h1-size); font-weight: var(--font-h1-weight); line-height: var(--font-h1-line-height); letter-spacing: var(--font-h1-letter-spacing); }
h2 { font-size: var(--font-h2-size); font-weight: var(--font-h2-weight); line-height: var(--font-h2-line-height); letter-spacing: var(--font-h2-letter-spacing); }
h3 { font-size: var(--font-h3-size); font-weight: var(--font-h3-weight); line-height: var(--font-h3-line-height); }

p { margin: 0 0 var(--space-3); }

.screen-reader-text, .skip-link {
	position: absolute;
	left: -10000px;
	width: 1px; height: 1px; overflow: hidden;
}
.skip-link:focus { left: var(--space-3); top: var(--space-3); width: auto; height: auto; padding: var(--space-2); background: var(--color-accent); color: var(--color-white); z-index: 9999; }

.container { width: 100%; margin-inline: auto; }
.container--narrow { width: 100%; margin-inline: auto; }
.container--center { text-align: center; }

/* ---------- Buttons ----------
   Geek-style pill: heavy weight, generous horizontal padding, subtle lift
   on hover. Pink is the primary, navy/paper ghosts for secondary actions.
   ----------------------------------------------------- */

.hp-btn {
	display: inline-flex;
	align-items: center;
	gap: 0.625rem;
	padding: 1rem 1.875rem;
	border-radius: var(--radius-pill);
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: 1rem;
	letter-spacing: -0.005em;
	text-decoration: none;
	transition: background 0.25s ease, color 0.25s ease, transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
	cursor: pointer;
	border: 1px solid transparent;
	white-space: nowrap;
}
.hp-btn:hover { transform: translateY(-2px); }

.hp-btn--pink {
	background: var(--color-button-bg);
	color: var(--color-button-text);
	box-shadow: 0 10px 30px rgba(253, 46, 152, 0.28);
}
.hp-btn--pink:hover {
	background: var(--color-button-hover-bg);
	color: var(--color-button-hover-text);
	box-shadow: 0 14px 36px rgba(0, 0, 0, 0.25);
}

.hp-btn--ghost {
	background: transparent;
	color: var(--color-paper);
	border-color: rgba(244, 241, 234, 0.35);
}
.hp-btn--ghost:hover {
	background: var(--color-paper);
	color: var(--color-primary);
	border-color: var(--color-paper);
}

/* Ghost button rendered on light grounds (paper) needs inverted contrast. */
.hp-btn--ghost-dark {
	background: transparent;
	color: var(--color-primary);
	border-color: rgba(8, 20, 39, 0.25);
}
.hp-btn--ghost-dark:hover {
	background: var(--color-primary);
	color: var(--color-paper);
	border-color: var(--color-primary);
}

.hp-btn--large {
	padding: 1.25rem 2.25rem;
	font-size: 1.125rem;
}

.hp-btn__arrow {
	display: inline-flex;
	transition: transform 0.25s ease;
}
.hp-btn:hover .hp-btn__arrow { transform: translateX(4px); }

/* ---------- Site header (pills) ---------- */

.site-header {
	position: fixed;
	top: var(--space-3);
	left: var(--space-4);
	right: var(--space-4);
	display: flex;
	justify-content: space-between;
	align-items: center;
	z-index: 50;
	pointer-events: none;
}
/* Centred brand mark, parked in the middle of the header. Hidden until the
   hero/showreel is scrolled past (body.hp-header-logo-on), then fades in.
   Links home. */
.site-header__logo {
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%) translateY(-6px);
	display: inline-flex;
	align-items: center;
	pointer-events: none;
	opacity: 0;
	transition: opacity 0.4s ease, transform 0.4s cubic-bezier(0.34, 1.4, 0.64, 1);
}
.site-header__logo svg {
	height: clamp(20px, 2.4vw, 28px);
	width: auto;
	display: block;
}
.hp-body.hp-header-logo-on .site-header__logo {
	opacity: 1;
	pointer-events: auto;
	transform: translate(-50%, -50%) translateY(0);
}
/* While the menu panel is open, drop the centred logo so it doesn't sit over
   the open state. */
.hp-body.menu-open .site-header__logo {
	opacity: 0;
	pointer-events: none;
}
.site-header__pill {
	pointer-events: auto;
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.75rem 1.25rem;
	background: rgba(0, 0, 16, 0.78);
	backdrop-filter: blur(18px) saturate(140%);
	-webkit-backdrop-filter: blur(18px) saturate(140%);
	border: 1px solid rgba(244, 241, 234, 0.18);
	border-radius: var(--radius-pill);
	color: var(--color-paper);
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-size: 0.9375rem;
	line-height: 1; /* same tight line box for both labels so they sit level */
	letter-spacing: -0.005em;
	box-shadow: 0 6px 24px rgba(0, 0, 0, 0.25);
	transition: background 0.25s ease, color 0.25s ease, transform 0.25s ease, border-color 0.25s ease;
}
.site-header__pill:hover {
	background: var(--color-accent);
	color: var(--color-white);
	border-color: var(--color-accent);
	transform: translateY(-1px);
}
.site-header__pill-dot {
	width: 8px; height: 8px; border-radius: 50%;
	background: var(--color-accent);
	transition: background 0.25s ease;
}
/* On hover the pill fills with the accent pink, so the pink dot would vanish
   into it. Flip the dot to white so it stays visible (matches the open state). */
.site-header__pill:hover .site-header__pill-dot {
	background: var(--color-white);
}
.site-header__pill-arrow { transition: transform 0.2s ease; }
.site-header__contact:hover .site-header__pill-arrow { transform: translateX(2px); }

/* Roll container for the Menu / Close labels. Two faces stacked vertically
   inside an overflow:hidden window; on open both faces translate up by
   one face-height, so "Menu" rolls out the top and "Close" rolls into
   place from below. */
.site-header__pill-flip {
	position: relative;
	display: inline-block;
	overflow: hidden;
	min-width: 3.5em; /* reserve width so the pill doesn't jump when label swaps */
	height: 1em;
	line-height: 1;
	vertical-align: middle;
}
.site-header__pill-face {
	display: block;
	height: 1em;
	line-height: 1;
	white-space: nowrap;
	transition: transform 0.45s cubic-bezier(0.65, 0, 0.35, 1);
}
.site-header__pill-face--close {
	position: absolute;
	inset: 0;
	transform: translateY(100%); /* parked one face-height below the window */
}
.hp-body.menu-open .site-header__pill-face--menu {
	transform: translateY(-100%);
}
.hp-body.menu-open .site-header__pill-face--close {
	transform: translateY(0);
}
.hp-body.menu-open .site-header__menu {
	background: var(--color-accent);
	border-color: var(--color-accent);
	color: var(--color-white);
}
.hp-body.menu-open .site-header__menu .site-header__pill-dot {
	background: var(--color-white);
}

/* Drop-down menu panel. A 400px-wide card anchored at the top-left with
   margin all around it and a generous border-radius. Hidden by default
   via translateY off the top of the viewport; .menu-open on body drops
   it in. The `inert` HTML attribute keeps it out of tab order / AT
   while closed (set by JS). */
.site-nav {
	position: fixed;
	top: var(--space-3);
	bottom: var(--space-3);
	left: var(--space-4);
	width: clamp(340px, 88vw, 460px);
	max-width: calc(100vw - 2 * var(--space-4));
	background: var(--color-primary);
	padding: 5rem 2rem 2rem;
	z-index: 40;
	border: 1px solid rgba(244, 241, 234, 0.18);
	border-radius: 28px;
	box-shadow: 0 30px 60px rgba(0, 0, 0, 0.4);
	transform: translateY(calc(-100% - var(--space-3) - 1rem));
	/* Default = the CLOSE transition: a clean, fairly quick slide back up. */
	transition: transform 0.4s cubic-bezier(0.65, 0, 0.35, 1);
	overflow-y: auto;
	/* Centre the menu list vertically within the panel. */
	display: flex;
	flex-direction: column;
	justify-content: center;
}
.hp-body.menu-open .site-nav {
	transform: translateY(0);
	/* OPEN = slower drop that overshoots and springs back into place. */
	transition: transform 0.72s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.site-nav__list { list-style: none; margin: 0; padding: 0; }
.site-nav__list li { margin-bottom: clamp(0.5rem, 1.5vw, 1rem); }
.site-nav__list a {
	position: relative;
	display: inline-flex;
	align-items: center;
	padding-left: 0; /* opens up on hover to make room for the bullet */
	font-family: var(--font-heading-family);
	font-size: clamp(2rem, 6vw, 3.5rem);
	font-weight: 600;
	line-height: 1.04;
	letter-spacing: -0.02em;
	color: var(--color-paper);
	white-space: nowrap; /* labels stay on one line — the bullet shove never wraps them */
	transition: color 0.25s ease, padding-left 0.4s cubic-bezier(0.34, 1.5, 0.64, 1);
}
/* Accent bullet parked off to the left; on hover/focus it pops into the
   reserved column and the link turns pink. Mirrors the services-row dot. */
.site-nav__list a::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.52em;
	width: 0.4em;
	height: 0.4em;
	border-radius: 50%;
	background: var(--color-accent);
	opacity: 0;
	transform: translate(-0.5em, -50%) scale(0.4);
	transition: opacity 0.2s ease, transform 0.4s cubic-bezier(0.34, 1.7, 0.64, 1);
}
.site-nav__list a:hover,
.site-nav__list a:focus-visible {
	color: var(--color-accent);
	padding-left: 0.8em; /* text slides right just enough to clear the bullet */
}
.site-nav__list a:hover::before,
.site-nav__list a:focus-visible::before {
	opacity: 1;
	transform: translate(0, -50%) scale(1);
}

@media (prefers-reduced-motion: reduce) {
	.site-header__pill-face,
	.site-nav {
		transition: none;
	}
}

/* ---------- Hero ----------
   Full-viewport video hero. The video uses object-fit: contain so the full
   wordmark is always visible on any aspect ratio (no cropping on mobile
   portrait or ultrawide). Any letterbox area blends into the section
   background which is exactly the navy of the video (#081427 via
   --color-primary), so the letterbox is invisible.
   ----------------------------------------------------- */

/* Scroll lock applied while the hero video is still playing. Released by
   main.js as soon as the video's `ended` event fires (or a safety timeout).
   scrollbar-gutter keeps layout stable when the scrollbar disappears. */
html.hp-scroll-lock,
html.hp-scroll-lock body {
	overflow: hidden;
	height: 100%;
	touch-action: none;
}
html.hp-scroll-lock { scrollbar-gutter: stable; }

.hp-hero {
	position: relative;
	min-height: 100vh;
	min-height: 100dvh;
	display: flex;
	align-items: center;
	justify-content: center;
	/* Flat #000010 across the whole hero — matches the video's encoded canvas
	   edge exactly so the letterbox bands and the plate read as one surface. */
	background: #000010;
	overflow: hidden;
	isolation: isolate;
}

/* Scroll cue — centred at the hero bottom. Hidden until the wordmark video
   finishes (body.hp-hero-cue), fades out again on the first scroll. */
.hp-hero__scroll {
	/* Fixed to the VIEWPORT bottom (not the hero box) so it's always on-screen
	   regardless of 100vh/100dvh differences; it only shows at the top and
	   hides on the first scroll anyway. */
	position: fixed;
	left: 50%;
	bottom: clamp(1.25rem, 4vh, 2.75rem);
	z-index: 30;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.7rem;
	color: var(--color-paper);
	pointer-events: none;
	opacity: 0;
	transform: translateX(-50%) translateY(10px);
	transition: opacity 0.6s ease, transform 0.6s ease;
}
.hp-body.hp-hero-cue .hp-hero__scroll {
	opacity: 0.85;
	transform: translateX(-50%) translateY(0);
}
.hp-hero__scroll-label {
	font-family: var(--font-heading-family);
	font-size: 0.6875rem;
	font-weight: 600;
	letter-spacing: 0.22em;
	text-transform: uppercase;
}
.hp-hero__scroll-mouse {
	width: 22px;
	height: 34px;
	border: 2px solid currentColor;
	border-radius: 12px;
	position: relative;
}
.hp-hero__scroll-mouse::after {
	content: "";
	position: absolute;
	left: 50%;
	top: 6px;
	width: 3px;
	height: 7px;
	border-radius: 2px;
	background: var(--color-accent);
	transform: translateX(-50%);
	animation: hp-hero-scroll-dot 1.6s ease-in-out infinite;
}
@keyframes hp-hero-scroll-dot {
	0%   { opacity: 0; transform: translate(-50%, 0); }
	30%  { opacity: 1; }
	60%  { opacity: 1; transform: translate(-50%, 11px); }
	100% { opacity: 0; transform: translate(-50%, 11px); }
}
@media (prefers-reduced-motion: reduce) {
	.hp-hero__scroll-mouse::after { animation: none; top: 9px; opacity: 1; }
	.hp-hero__scroll { transition: opacity 0.3s ease; }
}

/* Media wrapper locked to the video's native 16:9 aspect ratio. This is the
   positioning context for the overlay dot, so the dot tracks the wordmark
   at every viewport size, not the hero section's bounding box. The wrapper
   takes the largest 16:9 rectangle that fits the viewport (limited by 100%
   width AND 100dvh height), exactly matching where `object-fit: contain`
   would have rendered the video inside .hp-hero. */
.hp-hero__media {
	position: relative;
	aspect-ratio: 16 / 9;
	width: 100%;
	max-height: 100dvh;
	/* Cap width so we never exceed the height budget. Solving 16/9 against
	   100dvh gives a max width of (100dvh * 16/9). */
	max-width: calc(100dvh * 16 / 9);
	margin: auto;
	background: #000010;
	overflow: hidden; /* clip the video to the wordmark box */
}

.hp-hero__video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover; /* wrapper already matches video AR, so cover = no crop */
	object-position: center;
	background: #000010; /* exact match to the video's encoded edge navy */
	z-index: 0;
}

/* ---------- Hero pink accent dot ----------
   Brand-signature pink dot that lands at the EXACT coordinates of the
   period after "performance" in the wordmark video. Sampled from the
   source frame (1920x1080):
     - period centre: (1686.5, 699) px = (87.81%, 64.77%) of frame
     - period width:  27 px = 1.46% of frame width
   The dot is positioned inside .hp-hero__media (a 16:9 box), so the
   same percentage coords resolve to the same point regardless of viewport.

   Geometry: width = 1.46% of the media width, aspect-ratio: 1 / 1 so it's
   a perfect square box, border-radius: 50% renders it as a circle.

   left/top point to the centre of the period; translate(-50%, -50%) then
   centres the dot box on that point. */
.hp-hero__dot {
	position: absolute;
	left: 87.81%;
	top: 64.77%;
	width: 1.46%; /* of wrapper width = matches the video's period exactly */
	aspect-ratio: 1 / 1;
	height: auto;
	background: #FD2E98;
	border-radius: 50%;
	z-index: 2;
	pointer-events: none;
	transform: translate(-50%, -50%);
	transform-origin: center center;
	/* Pop-in timed to the wordmark video's period emergence (~2.5s).
	   Starts hidden at scale 0, snaps to full size in 0.18s with a
	   slight overshoot so it merges with the video's baked-in period. */
	animation: hp-hero-dot-pop 0.18s cubic-bezier(0.34, 1.56, 0.64, 1) 2.45s both;
}

@keyframes hp-hero-dot-pop {
	0% {
		transform: translate(-50%, -50%) scale(0);
		opacity: 0;
	}
	100% {
		transform: translate(-50%, -50%) scale(1);
		opacity: 1;
	}
}

@media (prefers-reduced-motion: reduce) {
	.hp-hero__dot {
		animation: none;
		transform: translate(-50%, -50%) scale(1);
		opacity: 1;
	}
}

/* ---------- Scroll-drawn pink line ----------
   Injected by main.js as a sibling of <body>, anchored to the document-space
   centre of .hp-hero__dot. Height tracks window.scrollY so the line appears
   to write itself downward out of the dot as the user scrolls. Drawn above
   page content but below the fixed pills via z-index. */
/* SVG path that weaves through the page, drawn progressively with scroll.
   Stroke width, position, and the path's d attribute are all set in JS so
   the path can be re-measured on resize / new content. */
.hp-scroll-line {
	position: absolute;
	left: 0;
	top: 0;
	pointer-events: none;
	z-index: 3;
	overflow: visible;
	opacity: 0; /* held hidden until the hero dot has popped in */
	animation: hp-scroll-line-in 0.18s linear 2.63s forwards;
	filter: drop-shadow(0 0 8px rgba(253, 46, 152, 0.45));
	transition: opacity 0.35s ease;
}
/* Hide the brand thread while the showreel is occupying the viewport,
   then let it fade back in once the user has scrolled past the video. */
.hp-body.hp-thread-hidden .hp-scroll-line {
	opacity: 0 !important;
}
.hp-scroll-line path {
	fill: none;
	stroke: #FD2E98;
	stroke-linecap: round;
	stroke-linejoin: round;
}

@keyframes hp-scroll-line-in {
	to { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
	.hp-scroll-line { display: none; }
}

/* Subtle vignette to keep pills legible against bright frames of the video.
   Rendered via ::after so we don't need an extra DOM node. */
.hp-hero::after {
	content: "";
	position: absolute;
	inset: 0;
	background:
		linear-gradient(180deg, rgba(0, 0, 16, 0.55) 0%, rgba(0, 0, 16, 0) 22%, rgba(0, 0, 16, 0) 78%, rgba(0, 0, 16, 0.45) 100%);
	pointer-events: none;
	z-index: 1;
}

/* Preserved rule (not currently rendered). Kept for an opt-in overlay if we
   want the blue radial back as a top-layer legibility aid. */
.hp-hero__radial {
	position: absolute;
	inset: -20%;
	background: radial-gradient(closest-side, color-mix(in oklab, var(--color-radial) 33%, transparent), transparent 70%);
	z-index: 1;
	pointer-events: none;
	opacity: 0.25;
	mix-blend-mode: screen;
}

/* Visually-hidden brand-name heading so screen readers / SEO still read the
   wordmark even though the visual is a video. */
.hp-hero__brand-sr {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* ---------- Marketing intro ----------
   Big bold headline with an Apple-style flowing gradient on the h1.
   The text colour is "painted" by a background-clip: text gradient that
   shifts horizontally on a loop. background-size:200% lets the gradient
   slide across the text without ever exposing the page background. */

.hp-marketing {
	position: relative;
	background: var(--color-primary);
	/* Extra right padding leaves room for the brand-thread vertical
	   drop that runs down the right side after the horizontal frame. */
	padding: clamp(6rem, 14vw, 12rem) clamp(5rem, 10vw, 10rem) clamp(6rem, 14vw, 12rem) clamp(1.25rem, 4vw, 3rem);
	color: var(--color-paper);
}
.hp-marketing__inner {
	width: 100%;
	margin-inline: auto;
	text-align: left;
}
.hp-marketing__h1 {
	font-family: var(--font-heading-family);
	font-weight: 800;
	/* Scales 3rem on mobile up to ~10rem on wide screens. */
	font-size: clamp(3rem, 9.5vw, 10rem);
	/* Slightly taller line-height + small bottom padding so descenders
	   on letters like g, p, y aren't clipped by background-clip: text. */
	line-height: 1.02;
	letter-spacing: -0.045em;
	margin-bottom: clamp(1.5rem, 3vw, 2.5rem);
	padding-bottom: 0.15em;
}
/* Each h1 line is its own block so the headline always renders as the
   intended number of lines (3 by default), no matter the viewport. */
.hp-marketing__h1-line {
	display: block;
}
/* Brand-pink period after the headline, decoupled from the gradient
   fill so it always renders solid accent-pink. aria-hidden because it
   reads as decorative punctuation rather than meaningful content. */
.hp-marketing__h1-dot {
	color: var(--color-accent);
	-webkit-text-fill-color: var(--color-accent);
}
.hp-marketing__h2 {
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: clamp(1.5rem, 3.4vw, 3rem);
	line-height: 1.1;
	letter-spacing: -0.02em;
	color: var(--color-accent);
	margin-bottom: clamp(2rem, 4vw, 3.5rem);
	opacity: 1;
}
/* Contemporary asymmetric body layout. Lead statement (left, big and
   bold) sits opposite a smaller, lighter supporting line (right) with a
   short pink rule that marks it as the "trusted by" credential. Stacks
   to a single column on narrow viewports. */
.hp-marketing__body {
	display: grid;
	grid-template-columns: 1.4fr 1fr;
	gap: clamp(2rem, 5vw, 5rem);
	align-items: end;
	margin-top: clamp(2rem, 4vw, 4rem);
	max-width: 1200px;
}
.hp-marketing__body p {
	margin: 0;
}
.hp-marketing__body-lead {
	font-size: clamp(1.375rem, 2vw, 2rem);
	line-height: 1.3;
	font-weight: 600;
	color: var(--color-paper);
	letter-spacing: -0.005em;
	max-width: 30ch;
}
.hp-marketing__body-meta {
	display: flex;
	align-items: flex-start;
	gap: 1rem;
	font-size: clamp(0.9375rem, 1.05vw, 1.0625rem);
	line-height: 1.55;
	color: rgba(244, 241, 234, 0.62);
	letter-spacing: 0.01em;
	max-width: 36ch;
}
.hp-marketing__body-rule {
	flex: 0 0 auto;
	width: 2.5rem;
	height: 2px;
	background: var(--color-accent);
	margin-top: 0.65em; /* aligns with the cap-height of the first line */
	border-radius: 2px;
}
.hp-marketing__body-meta-text {
	flex: 1 1 auto;
}
@media (max-width: 768px) {
	.hp-marketing__body {
		grid-template-columns: 1fr;
		gap: clamp(1.5rem, 4vw, 2.5rem);
	}
	.hp-marketing__body-meta { max-width: 100%; }
}

/* Scroll-driven VERTICAL gradient text. As the user scrolls past the
   element, the gradient slides downward through the letters, drawing
   the eye down through the headline. JS sets --hp-gradient-y on the
   .hp-gradient-text container based on how far the element has moved
   through the viewport (0% when entering from the bottom, 100% when
   leaving out the top). */
.hp-gradient-text {
	display: block;
	--hp-gradient-y: 0%;
}
.hp-gradient-text__inner {
	/* Brand-palette gradient — uses the Customizer colour variables so
	   it adapts if the brand colours change: accent (pink) → accent-light
	   → radial (blue) → back. */
	background: linear-gradient(
		180deg,
		var(--color-accent) 0%,
		var(--color-accent-light) 25%,
		var(--color-radial) 55%,
		var(--color-accent-light) 80%,
		var(--color-accent) 100%
	);
	background-size: 100% 260%;
	background-position: 0% var(--hp-gradient-y, 0%);
	background-clip: text;
	-webkit-background-clip: text;
	color: transparent;
	-webkit-text-fill-color: transparent;
	display: inline-block;
	padding-bottom: 0.15em; /* breathing room for descenders inside the clipped fill */
}

@media (prefers-reduced-motion: reduce) {
	.hp-gradient-text__inner {
		background-position: 0% 50%;
	}
}

/* Horizontal variant: gradient flows LEFT → RIGHT through the letters
   as the user scrolls. Same scroll-progress value used as a vertical
   gradient elsewhere, just applied to the X axis. */
.hp-gradient-text--horizontal .hp-gradient-text__inner {
	background: linear-gradient(
		90deg,
		#FD2E98 0%,
		#FF7BC0 20%,
		#A570FF 40%,
		#5170FF 60%,
		#1FD0FF 80%,
		#FD2E98 100%
	);
	background-size: 260% 100%;
	background-position: var(--hp-gradient-y, 0%) 0%;
}

/* ---------- Promise statement ----------
   Single big bold line with the same scroll-driven animated gradient
   the marketing H1 uses. Pink period as a brand mark. */

.hp-promise {
	position: relative;
	background: var(--color-primary);
	color: var(--color-paper);
	/* Tall enough to scroll through while the inner sticks at viewport
	   top. The phrase-swap happens partway through the scroll, then the
	   user "passes" the section into the next one. */
	min-height: 200vh;
}
.hp-promise__inner {
	position: sticky;
	top: 0;
	width: 100%;
	height: 100dvh;
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	padding: 0 clamp(1.25rem, 4vw, 3rem);
	text-align: center;
}
.hp-promise__heading {
	font-family: var(--font-heading-family);
	font-weight: 800;
	/* Very large — fills the section. Scales 3.15rem on mobile up to
	   ~14.4rem on widescreens (10% under the original). */
	font-size: clamp(3.15rem, 12.6vw, 14.4rem);
	line-height: 1.02;
	letter-spacing: -0.045em;
	margin: 0;
	padding-bottom: 0.15em;
	/* Layer the two phrases in the same grid cell so the heading auto-
	   sizes to whichever phrase is longer, and they can crossfade in
	   place without one pushing the other around. */
	display: inline-grid;
	grid-template-areas: 'swap';
}
.hp-promise__phrase {
	grid-area: swap;
	display: block;
	will-change: opacity, transform;
}
/* Both phrases are driven continuously by --swap (0 → 1) which JS sets
   from the scroll position. They occupy the SAME grid cell at the SAME
   size and alignment and simply crossfade opacity in place — no offset,
   no movement. */
.hp-promise__phrase--lead {
	opacity: calc(1 - var(--swap, 0));
}
.hp-promise__phrase--accent {
	opacity: var(--swap, 0);
}
/* Each pipe-split chunk is its own block so both phrases render as two
   lines, keeping them the same height and position while crossfading. */
.hp-promise__line {
	display: block;
}
.hp-promise__dot {
	color: var(--color-accent);
	-webkit-text-fill-color: var(--color-accent);
}

/* ---------- Why Higher Performance / Our Process ----------
   Sits after the promise beat. Two stacked statements; each body paragraph
   lights up word-by-word as the user scrolls it through the viewport. JS sets
   --p (0 → 1, scroll progress through the block) on each [data-scroll-color]
   element. Per word: how lit it is = clamp( p·n − i , 0 , 1 ), so words turn
   on in reading order. Lit colour mixes from a dim navy-tinted paper toward
   full paper, with the brand pink bleeding through at the leading edge. */

.hp-why {
	position: relative;
	background: var(--color-primary);
	color: var(--color-paper);
	padding: clamp(5rem, 14vh, 12rem) clamp(1.25rem, 4vw, 3rem);
}
.hp-why__inner {
	max-width: 70rem;
	margin: 0 auto;
	display: flex;
	flex-direction: column;
	gap: clamp(4rem, 10vh, 9rem);
}
.hp-why__block {
	display: flex;
	flex-direction: column;
	gap: clamp(1.5rem, 4vh, 3rem);
}
.hp-why__eyebrow {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2rem, 5vw, 4.5rem);
	line-height: 1.04;
	letter-spacing: -0.03em;
	margin: 0;
}
.hp-why__body {
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: clamp(1.6rem, 3.8vw, 3rem);
	line-height: 1.28;
	letter-spacing: -0.01em;
	margin: 0;
	--p: 0;
}

/* Scroll-driven word colour-fill. Each word's "lit" amount is the scroll
   progress (p) scaled across the word count (n) minus the word's index (i),
   clamped 0..1 — so the fill sweeps through the words in reading order. */
.hp-scroll-color__word {
	--lit: clamp(0, calc(var(--p, 0) * var(--n, 1) - var(--i, 0)), 1);
	color: color-mix(
		in srgb,
		var(--color-paper) calc(var(--lit) * 100%),
		rgba(244, 241, 234, 0.45)
	);
	/* Brand pink glows on the word currently being lit (--lit between 0 and 1),
	   then settles to plain paper once fully lit. Peaks at the leading edge. */
	text-shadow: 0 0 calc(var(--lit) * (1 - var(--lit)) * 40px)
		rgba(253, 46, 152, calc(var(--lit) * (1 - var(--lit)) * 2));
	transition: color 0.08s linear;
}

/* No color-mix support, no JS, or reduced motion: show fully lit + readable. */
@supports not (color: color-mix(in srgb, white, black)) {
	.hp-scroll-color__word { color: var(--color-paper); text-shadow: none; }
}
@media (prefers-reduced-motion: reduce) {
	.hp-scroll-color__word {
		color: var(--color-paper);
		text-shadow: none;
		transition: none;
	}
}

/* ---------- Clients marquee ----------
   Infinite-scroll horizontal row of client names (or logos once images
   are dropped in). The track is duplicated in the markup so translating
   the wrapper by -50% loops seamlessly. Edge fades on the container
   soft-mask the ends so items appear/disappear smoothly. */

.hp-clients {
	position: relative;
	background: var(--color-primary);
	padding: clamp(3.5rem, 6vw, 6rem) 0;
	color: var(--color-paper);
	overflow: hidden;
}
/* Blue shadow at the left/right edges so the marquee reads as fading into the
   ground and only the centre logos are fully visible. */
.hp-clients::before,
.hp-clients::after {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	width: clamp(80px, 16vw, 240px);
	z-index: 2;
	pointer-events: none;
}
.hp-clients::before {
	left: 0;
	background: linear-gradient(90deg, var(--color-primary) 0%, var(--color-primary) 35%, transparent 100%);
}
.hp-clients::after {
	right: 0;
	background: linear-gradient(270deg, var(--color-primary) 0%, var(--color-primary) 35%, transparent 100%);
}
.hp-clients__inner {
	width: 100%;
	margin-inline: auto;
}
.hp-clients__label {
	font-family: var(--font-heading-family);
	font-size: clamp(0.75rem, 0.9vw, 0.9rem);
	font-weight: 600;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: rgba(244, 241, 234, 0.45);
	margin: 0 0 clamp(1.5rem, 3vw, 2.5rem);
	padding-inline: clamp(1.5rem, 4vw, 3rem);
	text-align: center;
}

.hp-clients__marquee {
	display: flex;
	gap: clamp(2rem, 4vw, 4rem);
	width: max-content;
	/* Soft edges so items fade in/out rather than appearing abruptly. */
	mask-image: linear-gradient(90deg, transparent 0, #000 8%, #000 92%, transparent 100%);
	-webkit-mask-image: linear-gradient(90deg, transparent 0, #000 8%, #000 92%, transparent 100%);
	animation: hp-clients-marquee 40s linear infinite;
}
.hp-clients:hover .hp-clients__marquee {
	animation-play-state: paused;
}

.hp-clients__track {
	display: flex;
	align-items: center;
	gap: clamp(2rem, 4vw, 4rem);
	list-style: none;
	margin: 0;
	padding: 0;
}
/* No chip: logos sit straight on the navy ground. Sized by HEIGHT so the
   square source files all read at the same visual size (fixes "some too
   small"). */
.hp-clients__item {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	height: clamp(72px, 8vw, 112px);
	transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.hp-clients__logo {
	height: 100%;
	width: auto;
	max-width: none;
	object-fit: contain;
	display: block;
	/* All white by default so every mark reads on the navy ground. */
	filter: brightness(0) invert(1);
	opacity: 0.82;
	transition: filter 0.3s ease, opacity 0.3s ease;
}
/* Hover reveals the logo's original colours (marquee already pauses on hover). */
.hp-clients__item:hover {
	transform: translateY(-4px);
}
.hp-clients__item:hover .hp-clients__logo {
	filter: none;
	opacity: 1;
}

@keyframes hp-clients-marquee {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
	.hp-clients__marquee {
		animation: none;
		flex-wrap: wrap;
		justify-content: center;
		width: 100%;
		padding-inline: clamp(1.5rem, 4vw, 3rem);
	}
}

/* ---------- Featured work — stacking cards ----------
   Each .hp-portfolio__card is position: sticky at the top of the
   viewport. Because they're sequential, later cards scroll up and cover
   earlier ones; JS scales + dims the covered card to create a stacked-
   deck effect. The inner card is boxed (not full width) with rounded
   corners, matching the reference layout. */

.hp-portfolio {
	position: relative;
	/* Transparent so it sits on the work section's (scroll-shifting)
	   background; the cards carry their own colour. */
	background: transparent;
	padding: clamp(1rem, 2vw, 2rem) 0 0;
}
.hp-portfolio__eyebrow {
	font-family: var(--font-heading-family);
	font-size: clamp(0.75rem, 0.9vw, 0.9rem);
	font-weight: 600;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: rgba(244, 241, 234, 0.45);
	margin: 0 0 clamp(1.5rem, 3vw, 2.5rem);
	padding-inline: clamp(1.5rem, 4vw, 3rem);
}
.hp-portfolio__card {
	position: sticky;
	top: 0;
	height: 100vh;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: clamp(1rem, 3vw, 2.5rem);
}
.hp-portfolio__card-inner {
	position: relative;
	width: 100%;
	max-width: 1500px;
	height: min(78vh, 720px);
	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;
}
/* Placeholder background — per-project brand gradient. Swap for an
   <img>/<video> inside .hp-portfolio__media when real imagery arrives. */
.hp-portfolio__media {
	position: absolute;
	inset: 0;
	background: linear-gradient(135deg, var(--card-a) 0%, var(--card-b) 100%);
}
.hp-portfolio__overlay {
	position: absolute;
	inset: 0;
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: center;
	gap: clamp(1rem, 3vw, 3rem);
	padding: clamp(2rem, 5vw, 4.5rem);
}
.hp-portfolio__name {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2rem, 4.5vw, 5rem);
	line-height: 1.0;
	letter-spacing: -0.03em;
	margin: 0;
	max-width: 12ch;
}
.hp-portfolio__card--light .hp-portfolio__name,
.hp-portfolio__card--light .hp-portfolio__service { color: var(--color-white); }
.hp-portfolio__card--dark .hp-portfolio__name,
.hp-portfolio__card--dark .hp-portfolio__service { color: var(--color-primary); }

/* Circular View-work button, centred over the media. */
.hp-portfolio__view {
	justify-self: center;
	display: flex;
	align-items: center;
	justify-content: center;
	width: clamp(7rem, 11vw, 10rem);
	height: clamp(7rem, 11vw, 10rem);
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.16);
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	border: 1px solid rgba(255, 255, 255, 0.4);
	color: var(--color-white);
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: clamp(0.875rem, 1.1vw, 1.0625rem);
	line-height: 1.05;
	text-align: center;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	transition: transform 0.3s ease, background 0.3s ease;
}
.hp-portfolio__view:hover {
	transform: scale(1.08);
	background: rgba(255, 255, 255, 0.28);
	color: var(--color-white);
}

/* Services list, right-aligned with divider rules between items. */
.hp-portfolio__services {
	justify-self: end;
	list-style: none;
	margin: 0;
	padding: 0;
	text-align: right;
	max-width: 18ch;
}
.hp-portfolio__service {
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-size: clamp(0.875rem, 1.2vw, 1.25rem);
	padding: clamp(0.5rem, 1vw, 0.85rem) 0;
	border-top: 1px solid rgba(255, 255, 255, 0.25);
}
.hp-portfolio__card--dark .hp-portfolio__service {
	border-top-color: rgba(8, 20, 39, 0.25);
}
.hp-portfolio__service:first-child { border-top: 0; }

@media (max-width: 768px) {
	.hp-portfolio__overlay {
		grid-template-columns: 1fr;
		grid-template-rows: auto 1fr auto;
		justify-items: start;
		text-align: left;
	}
	.hp-portfolio__view { justify-self: start; }
	.hp-portfolio__services { justify-self: start; text-align: left; }
	.hp-portfolio__service { border-top: 0; padding: 0.2rem 0; }
}

@media (prefers-reduced-motion: reduce) {
	.hp-portfolio__card { position: relative; height: auto; }
	.hp-portfolio__card-inner { transform: none !important; opacity: 1 !important; }
}

/* ---------- Our Insights (blog teaser) ----------
   Editorial layout: large featured post + compact list of the rest.
   Image-zoom on hover, card lift, animated arrow reveal. */

.hp-insights {
	position: relative;
	background: var(--color-primary);
	color: var(--color-paper);
	padding: clamp(5rem, 11vw, 9rem) clamp(1.5rem, 4vw, 3rem);
}
.hp-insights__inner {
	width: min(1400px, 100%);
	margin-inline: auto;
}
.hp-insights__header {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 2rem;
	flex-wrap: wrap;
	margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
.hp-insights__eyebrow {
	font-family: var(--font-heading-family);
	font-size: clamp(0.75rem, 0.9vw, 0.9rem);
	font-weight: 600;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--color-accent);
	margin: 0 0 0.75rem;
}
.hp-insights__heading {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2rem, 4.5vw, 3.75rem);
	line-height: 1.0;
	letter-spacing: -0.03em;
	margin: 0;
}

.hp-insights__layout {
	display: grid;
	grid-template-columns: 1.3fr 1fr;
	gap: clamp(2rem, 4vw, 4rem);
	align-items: start;
}

/* Shared media + chip styling */
.hp-insights__media,
.hp-insights__row-media {
	display: block;
	overflow: hidden;
	border-radius: clamp(16px, 1.5vw, 24px);
	background: var(--color-secondary);
}
.hp-insights__media img,
.hp-insights__row-media img,
.hp-insights__media-fallback {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.hp-insights__media-fallback {
	min-height: 100%;
	background: linear-gradient(135deg, var(--color-secondary), var(--color-accent));
}
.hp-insights__chip {
	display: inline-block;
	font-family: var(--font-heading-family);
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--color-accent-light);
	border: 1px solid rgba(253, 46, 152, 0.4);
	border-radius: var(--radius-pill);
	padding: 0.25rem 0.7rem;
}
.hp-insights__metarow {
	display: flex;
	align-items: center;
	gap: 0.85rem;
	margin-bottom: 0.85rem;
}
.hp-insights__meta {
	font-size: 0.8125rem;
	color: rgba(244, 241, 234, 0.55);
	letter-spacing: 0.01em;
}

/* Featured post */
.hp-insights__featured {
	display: block;
	color: inherit;
	text-decoration: none;
}
.hp-insights__featured .hp-insights__media {
	aspect-ratio: 16 / 10;
	margin-bottom: 1.5rem;
}
.hp-insights__body { display: block; }
.hp-insights__title {
	display: block;
	font-family: var(--font-heading-family);
	font-weight: 700;
	letter-spacing: -0.02em;
	line-height: 1.1;
	color: var(--color-paper);
	transition: color 0.25s ease;
}
.hp-insights__title--lg {
	font-size: clamp(1.5rem, 2.6vw, 2.5rem);
	margin-bottom: 0.75rem;
}
.hp-insights__excerpt {
	display: block;
	color: rgba(244, 241, 234, 0.7);
	line-height: 1.55;
	margin-bottom: 1rem;
	max-width: 52ch;
}
.hp-insights__more {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-family: var(--font-heading-family);
	font-weight: 600;
	color: var(--color-accent);
}
.hp-insights__featured:hover .hp-insights__media img,
.hp-insights__featured:hover .hp-insights__media-fallback {
	transform: scale(1.05);
}
.hp-insights__featured:hover .hp-insights__title { color: var(--color-accent-light); }
.hp-insights__featured:hover .hp-insights__more .hp-btn__arrow { transform: translateX(4px); }

/* Compact list */
.hp-insights__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: clamp(1rem, 2vw, 1.75rem);
}
.hp-insights__row {
	display: grid;
	grid-template-columns: 96px 1fr auto;
	align-items: center;
	gap: 1.25rem;
	padding-bottom: clamp(1rem, 2vw, 1.75rem);
	border-bottom: 1px solid rgba(244, 241, 234, 0.12);
	color: inherit;
	text-decoration: none;
}
.hp-insights__list li:last-child .hp-insights__row {
	border-bottom: 0;
	padding-bottom: 0;
}
.hp-insights__row-media {
	width: 96px;
	height: 72px;
	border-radius: 14px;
	flex: 0 0 auto;
}
.hp-insights__row .hp-insights__metarow { margin-bottom: 0.4rem; }
.hp-insights__row .hp-insights__title { font-size: clamp(1rem, 1.4vw, 1.25rem); }
.hp-insights__row-arrow {
	color: var(--color-accent);
	opacity: 0;
	transform: translateX(-6px);
	transition: opacity 0.25s ease, transform 0.25s ease;
}
.hp-insights__row:hover { border-bottom-color: rgba(253, 46, 152, 0.4); }
.hp-insights__row:hover .hp-insights__row-media img,
.hp-insights__row:hover .hp-insights__media-fallback { transform: scale(1.08); }
.hp-insights__row:hover .hp-insights__title { color: var(--color-accent-light); }
.hp-insights__row:hover .hp-insights__row-arrow { opacity: 1; transform: translateX(0); }

/* ---- Scroll-reveal entrance (staggered fade-up) ----
   wireRevealOnScroll() adds .is-pending immediately and swaps to
   .is-visible when the section enters the viewport. */
.hp-insights__header > div,
.hp-insights__header > .hp-btn,
.hp-insights__featured,
.hp-insights__list li {
	transition: opacity 0.6s ease, transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.hp-insights.is-pending .hp-insights__header > div,
.hp-insights.is-pending .hp-insights__header > .hp-btn,
.hp-insights.is-pending .hp-insights__featured,
.hp-insights.is-pending .hp-insights__list li {
	opacity: 0;
	transform: translateY(34px);
}
.hp-insights.is-visible .hp-insights__header > div,
.hp-insights.is-visible .hp-insights__header > .hp-btn,
.hp-insights.is-visible .hp-insights__featured,
.hp-insights.is-visible .hp-insights__list li {
	opacity: 1;
	transform: translateY(0);
}
/* Stagger: header → featured → list items in sequence. */
.hp-insights.is-visible .hp-insights__header > div      { transition-delay: 0s; }
.hp-insights.is-visible .hp-insights__header > .hp-btn  { transition-delay: 0.08s; }
.hp-insights.is-visible .hp-insights__featured          { transition-delay: 0.16s; }
.hp-insights.is-visible .hp-insights__list li:nth-child(1) { transition-delay: 0.24s; }
.hp-insights.is-visible .hp-insights__list li:nth-child(2) { transition-delay: 0.32s; }
.hp-insights.is-visible .hp-insights__list li:nth-child(3) { transition-delay: 0.40s; }
.hp-insights.is-visible .hp-insights__list li:nth-child(4) { transition-delay: 0.48s; }
.hp-insights.is-visible .hp-insights__list li:nth-child(5) { transition-delay: 0.56s; }

/* Lift the featured card on hover for a touch more depth. */
.hp-insights__featured { will-change: transform; }
.hp-insights.is-visible .hp-insights__featured:hover {
	transform: translateY(-5px);
	transition-delay: 0s;
}

@media (prefers-reduced-motion: reduce) {
	.hp-insights__header > div,
	.hp-insights__header > .hp-btn,
	.hp-insights__featured,
	.hp-insights__list li {
		opacity: 1 !important;
		transform: none !important;
		transition: none;
	}
}

/* Tablet: stack the featured post above the list, keep generous gaps. */
@media (max-width: 900px) {
	.hp-insights__layout {
		grid-template-columns: 1fr;
		gap: clamp(2rem, 5vw, 3rem);
	}
	.hp-insights__header {
		flex-direction: column;
		align-items: flex-start;
		gap: 1.25rem;
	}
	.hp-insights__excerpt { max-width: none; }
}
/* Mobile: tighten spacing, shrink the row thumbnails, ensure the arrow
   is always visible (no hover on touch) and nothing overflows. */
@media (max-width: 600px) {
	.hp-insights { padding-left: clamp(1.1rem, 5vw, 1.5rem); padding-right: clamp(1.1rem, 5vw, 1.5rem); }
	.hp-insights__featured .hp-insights__media { margin-bottom: 1.1rem; }
	.hp-insights__title--lg { font-size: clamp(1.35rem, 6vw, 1.75rem); }
	.hp-insights__row {
		grid-template-columns: 72px 1fr;
		gap: 0.9rem;
		align-items: start;
	}
	.hp-insights__row-media { width: 72px; height: 54px; }
	.hp-insights__row-arrow { display: none; }
	.hp-insights__metarow { flex-wrap: wrap; gap: 0.5rem; row-gap: 0.35rem; }
}

/* ---------- Blog index (home.php) ----------
   Featured first post spanning the grid, then a responsive card grid.
   Shares the Insights hover language: image-zoom, title colour, arrow. */

.hp-blog {
	background: var(--color-primary);
	color: var(--color-paper);
	padding: clamp(7rem, 12vw, 11rem) clamp(1.5rem, 4vw, 3rem) clamp(5rem, 10vw, 8rem);
	min-height: 100vh;
}
.hp-blog__header {
	width: min(1400px, 100%);
	margin: 0 auto clamp(2.5rem, 5vw, 4rem);
}
.hp-blog__eyebrow {
	font-family: var(--font-heading-family);
	font-size: clamp(0.75rem, 0.9vw, 0.9rem);
	font-weight: 600;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--color-accent);
	margin: 0 0 0.75rem;
}
.hp-blog__heading {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.5rem, 6vw, 5.5rem);
	line-height: 1.0;
	letter-spacing: -0.035em;
	margin: 0 0 clamp(1.5rem, 3vw, 2.5rem);
}
.hp-blog__rail {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	list-style: none;
	margin: 0;
	padding: 0;
}
.hp-blog__rail li a {
	display: inline-block;
	font-family: var(--font-heading-family);
	font-size: 0.875rem;
	font-weight: 600;
	color: rgba(244, 241, 234, 0.7);
	border: 1px solid rgba(244, 241, 234, 0.18);
	border-radius: var(--radius-pill);
	padding: 0.4rem 1rem;
	transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.hp-blog__rail li a:hover,
.hp-blog__rail li.is-active a {
	background: var(--color-accent);
	border-color: var(--color-accent);
	color: var(--color-white);
}

.hp-blog__grid {
	width: min(1400px, 100%);
	margin-inline: auto;
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: clamp(1.5rem, 3vw, 2.5rem);
}
.hp-blog__card { margin: 0; }
.hp-blog__card--featured { grid-column: 1 / -1; }

.hp-blog__link {
	display: block;
	color: inherit;
	text-decoration: none;
}
.hp-blog__card--featured .hp-blog__link {
	display: grid;
	grid-template-columns: 1.3fr 1fr;
	gap: clamp(1.5rem, 4vw, 3.5rem);
	align-items: center;
}
.hp-blog__media {
	display: block;
	overflow: hidden;
	border-radius: clamp(16px, 1.5vw, 24px);
	background: var(--color-secondary);
	aspect-ratio: 16 / 11;
	margin-bottom: 1.25rem;
}
.hp-blog__card--featured .hp-blog__media {
	aspect-ratio: 16 / 10;
	margin-bottom: 0;
}
.hp-blog__media img,
.hp-blog__media-fallback {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.hp-blog__media-fallback {
	background: linear-gradient(135deg, var(--color-secondary), var(--color-accent));
}
.hp-blog__metarow {
	display: flex;
	align-items: center;
	gap: 0.85rem;
	margin-bottom: 0.75rem;
}
.hp-blog__chip {
	display: inline-block;
	font-family: var(--font-heading-family);
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--color-accent-light);
	border: 1px solid rgba(253, 46, 152, 0.4);
	border-radius: var(--radius-pill);
	padding: 0.25rem 0.7rem;
}
.hp-blog__meta {
	font-size: 0.8125rem;
	color: rgba(244, 241, 234, 0.55);
}
.hp-blog__title {
	display: block;
	font-family: var(--font-heading-family);
	font-weight: 700;
	letter-spacing: -0.02em;
	line-height: 1.12;
	font-size: clamp(1.125rem, 1.6vw, 1.5rem);
	margin-bottom: 0.6rem;
	transition: color 0.25s ease;
}
.hp-blog__card--featured .hp-blog__title {
	font-size: clamp(1.75rem, 3.2vw, 3rem);
	margin-bottom: 0.85rem;
}
.hp-blog__excerpt {
	display: block;
	color: rgba(244, 241, 234, 0.7);
	line-height: 1.55;
	margin-bottom: 1rem;
	max-width: 56ch;
}
.hp-blog__more {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-family: var(--font-heading-family);
	font-weight: 600;
	color: var(--color-accent);
}
.hp-blog__card:not(.hp-blog__card--featured) .hp-blog__more { display: none; }
.hp-blog__link:hover .hp-blog__media img,
.hp-blog__link:hover .hp-blog__media-fallback { transform: scale(1.05); }
.hp-blog__link:hover .hp-blog__title { color: var(--color-accent-light); }
.hp-blog__link:hover .hp-blog__more .hp-btn__arrow { transform: translateX(4px); }

.hp-blog__pagination {
	width: min(1400px, 100%);
	margin: clamp(3rem, 6vw, 5rem) auto 0;
}
.hp-blog__pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.75rem;
	height: 2.75rem;
	padding: 0 0.5rem;
	margin: 0 0.2rem;
	border-radius: var(--radius-pill);
	font-family: var(--font-heading-family);
	font-weight: 600;
	color: var(--color-paper);
	border: 1px solid rgba(244, 241, 234, 0.18);
	transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.hp-blog__pagination .page-numbers.current,
.hp-blog__pagination a.page-numbers:hover {
	background: var(--color-accent);
	border-color: var(--color-accent);
	color: var(--color-white);
}
.hp-blog__empty {
	width: min(1400px, 100%);
	margin-inline: auto;
	color: rgba(244, 241, 234, 0.7);
}

@media (max-width: 900px) {
	.hp-blog__grid { grid-template-columns: repeat(2, 1fr); }
	.hp-blog__card--featured .hp-blog__link { grid-template-columns: 1fr; }
	.hp-blog__card--featured .hp-blog__media { margin-bottom: 1.25rem; }
}
@media (max-width: 560px) {
	.hp-blog__grid { grid-template-columns: 1fr; }
}

/* ---------- Single post ----------
   Editorial article with a sticky right "floating" sidebar (share +
   latest posts) and a slim reading-progress bar. */

.hp-reading-progress {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 3px;
	background: transparent;
	z-index: 60;
	pointer-events: none;
}
.hp-reading-progress span {
	display: block;
	height: 100%;
	width: 0;
	background: var(--color-accent);
	transition: width 0.1s linear;
}

.hp-single {
	background: var(--color-primary);
	color: var(--color-paper);
	/* Top padding only needs to clear the fixed header pills (~5rem),
	   not the big hero allowance. */
	padding: clamp(5rem, 7vw, 6.5rem) clamp(1.5rem, 4vw, 3rem) clamp(5rem, 10vw, 8rem);
}
.hp-single__article { margin: 0; }

.hp-single__header {
	width: min(900px, 100%);
	margin: 0 auto clamp(1.75rem, 3.5vw, 2.5rem);
	text-align: center;
}
.hp-single__back {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-size: 0.875rem;
	color: rgba(244, 241, 234, 0.6);
	margin-bottom: 1.5rem;
}
.hp-single__back:hover { color: var(--color-accent); }
.hp-single__chip {
	display: inline-block;
	font-family: var(--font-heading-family);
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--color-accent-light);
	border: 1px solid rgba(253, 46, 152, 0.4);
	border-radius: var(--radius-pill);
	padding: 0.3rem 0.85rem;
	margin-bottom: 1.25rem;
}
.hp-single__chip:hover { background: rgba(253, 46, 152, 0.15); color: var(--color-accent-light); }
.hp-single__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2rem, 5vw, 4rem);
	line-height: 1.05;
	letter-spacing: -0.03em;
	margin: 0 0 1.5rem;
}
.hp-single__meta {
	display: inline-flex;
	align-items: center;
	gap: 0.75rem;
	text-align: left;
}
.hp-single__avatar { border-radius: 50%; }
.hp-single__byline { display: flex; flex-direction: column; line-height: 1.2; }
.hp-single__author { font-family: var(--font-heading-family); font-weight: 600; }
.hp-single__sub { font-size: 0.8125rem; color: rgba(244, 241, 234, 0.55); }

.hp-single__feature {
	width: min(1280px, 100%);
	margin: 0 auto clamp(2.5rem, 5vw, 4rem);
}
.hp-single__feature img {
	width: 100%;
	border-radius: clamp(16px, 2vw, 28px);
}

/* Three columns: TOC (left) | content (centre, wide) | sidebar (right). */
.hp-single__layout {
	width: min(1320px, 100%);
	margin-inline: auto;
	display: grid;
	grid-template-columns: 220px minmax(0, 1fr) 300px;
	gap: clamp(2rem, 4vw, 3.5rem);
	align-items: start;
}

/* On-this-page table of contents.
   --toc-top sets how far below the viewport top it sticks; the matching
   max-height lets a long list scroll within its own thin scrollbar instead
   of overflowing past the screen. */
.hp-single__toc {
	--toc-top: clamp(3rem, 6vw, 5rem);
	position: sticky;
	top: var(--toc-top);
	align-self: start;
	max-height: calc(100vh - var(--toc-top) - 1.5rem);
	overflow-y: auto;
	overscroll-behavior: contain;
	padding-right: 0.5rem;
	scrollbar-width: thin;
	scrollbar-color: rgba(244, 241, 234, 0.3) transparent;
}
.hp-single__toc::-webkit-scrollbar { width: 6px; }
.hp-single__toc::-webkit-scrollbar-thumb { background: rgba(244, 241, 234, 0.25); border-radius: 3px; }
.hp-single__toc::-webkit-scrollbar-track { background: transparent; }
.hp-single__toc-nav { display: flex; flex-direction: column; gap: 0.1rem; }
.hp-single__toc-link {
	display: block;
	font-size: 0.875rem;
	line-height: 1.35;
	color: rgba(244, 241, 234, 0.55);
	padding: 0.4rem 0 0.4rem 0.85rem;
	border-left: 2px solid rgba(244, 241, 234, 0.14);
	transition: color 0.2s ease, border-color 0.2s ease;
}
.hp-single__toc-link:hover { color: var(--color-paper); }
.hp-single__toc-link--h3 { padding-left: 1.75rem; font-size: 0.8125rem; }
.hp-single__toc-link.is-active {
	color: var(--color-accent);
	border-left-color: var(--color-accent);
}

/* Article body typography */
.hp-single__content {
	font-size: clamp(1.0625rem, 1.25vw, 1.1875rem);
	line-height: 1.75;
	color: rgba(244, 241, 234, 0.88);
}
.hp-single__content > * { margin-bottom: 1.4em; }
.hp-single__content h2 { font-size: clamp(1.5rem, 2.4vw, 2.25rem); line-height: 1.2; margin-top: 1.8em; color: var(--color-paper); }
.hp-single__content h3 { font-size: clamp(1.25rem, 1.8vw, 1.6rem); line-height: 1.25; margin-top: 1.6em; color: var(--color-paper); }
.hp-single__content a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 3px; }
.hp-single__content a:hover { color: var(--color-accent-light); }
.hp-single__content img { border-radius: 16px; }
.hp-single__content blockquote {
	margin: 2em 0;
	padding: 0.5em 0 0.5em 1.5em;
	border-left: 3px solid var(--color-accent);
	font-size: 1.2em;
	font-style: italic;
	color: var(--color-paper);
}
.hp-single__content ul, .hp-single__content ol { padding-left: 1.4em; }
.hp-single__content li { margin-bottom: 0.5em; }

.hp-single__tags {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin-top: 2.5rem;
	padding-top: 2rem;
	border-top: 1px solid rgba(244, 241, 234, 0.12);
}
.hp-single__tag {
	font-size: 0.875rem;
	color: rgba(244, 241, 234, 0.6);
	border: 1px solid rgba(244, 241, 234, 0.18);
	border-radius: var(--radius-pill);
	padding: 0.3rem 0.8rem;
}
.hp-single__tag:hover { border-color: var(--color-accent); color: var(--color-accent); }

/* Floating sidebar */
.hp-single__sidebar-sticky {
	position: sticky;
	top: clamp(5rem, 9vw, 7rem);
	display: flex;
	flex-direction: column;
	gap: 2.5rem;
}
.hp-single__widget-label {
	font-family: var(--font-heading-family);
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: rgba(244, 241, 234, 0.45);
	margin: 0 0 1rem;
}
.hp-single__share-row { display: flex; gap: 0.6rem; }
.hp-single__share-btn {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.75rem;
	height: 2.75rem;
	border-radius: 50%;
	background: rgba(244, 241, 234, 0.06);
	border: 1px solid rgba(244, 241, 234, 0.16);
	color: var(--color-paper);
	cursor: pointer;
	transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}
.hp-single__share-btn svg { width: 1.05rem; height: 1.05rem; }
.hp-single__share-btn:hover {
	background: var(--color-accent);
	border-color: var(--color-accent);
	color: var(--color-white);
	transform: translateY(-2px);
}
.hp-single__copied {
	position: absolute;
	bottom: calc(100% + 0.4rem);
	left: 50%;
	transform: translateX(-50%);
	font-size: 0.6875rem;
	font-weight: 600;
	white-space: nowrap;
	background: var(--color-accent);
	color: var(--color-white);
	padding: 0.2rem 0.5rem;
	border-radius: 6px;
	opacity: 0;
	transition: opacity 0.2s ease;
	pointer-events: none;
}
.hp-single__share-copy.is-copied .hp-single__copied { opacity: 1; }

.hp-single__latest ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1.1rem; }
.hp-single__latest-item {
	display: grid;
	grid-template-columns: 64px 1fr;
	gap: 0.85rem;
	align-items: center;
	color: inherit;
}
.hp-single__latest-media {
	width: 64px;
	height: 64px;
	border-radius: 12px;
	overflow: hidden;
	background: var(--color-secondary);
	flex: 0 0 auto;
}
.hp-single__latest-media img,
.hp-single__latest-fallback {
	width: 100%; height: 100%; object-fit: cover; display: block;
	transition: transform 0.4s ease;
}
.hp-single__latest-fallback { background: linear-gradient(135deg, var(--color-secondary), var(--color-accent)); }
.hp-single__latest-date { display: block; font-size: 0.75rem; color: rgba(244, 241, 234, 0.5); margin-bottom: 0.2rem; }
.hp-single__latest-title {
	display: block;
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-size: 0.9375rem;
	line-height: 1.25;
	transition: color 0.2s ease;
}
.hp-single__latest-item:hover .hp-single__latest-title { color: var(--color-accent-light); }
.hp-single__latest-item:hover .hp-single__latest-media img,
.hp-single__latest-item:hover .hp-single__latest-fallback { transform: scale(1.08); }

/* Tablet: drop the left TOC, keep content + right sidebar. */
@media (max-width: 1100px) {
	.hp-single__layout { grid-template-columns: minmax(0, 1fr) 280px; }
	.hp-single__toc { display: none; }
}
/* Mobile: single column, right sidebar reflows below the article. */
@media (max-width: 900px) {
	.hp-single__layout { grid-template-columns: 1fr; }
	.hp-single__sidebar-sticky { position: static; flex-direction: row; flex-wrap: wrap; gap: 2rem; }
	.hp-single__latest { flex: 1 1 100%; }
}

/* ---------- Positioning ---------- */

.hp-positioning {
	position: relative;
	background: var(--color-primary);
	padding: 0 0 clamp(4rem, 8vw, 8rem);
}
.hp-positioning__inner {
	width: 100%;
	margin-inline: auto;
	display: grid;
	grid-template-columns: 1.25fr 1fr;
	gap: clamp(3rem, 6vw, 6rem);
	align-items: center;
}
.hp-positioning__heading {
	font-size: clamp(2.25rem, 5.8vw, 5.25rem);
	font-weight: 800;
	line-height: 0.98;
	letter-spacing: -0.035em;
	margin-bottom: var(--space-4);
}
.hp-positioning__body {
	font-size: clamp(1.0625rem, 1.2vw, 1.25rem);
	color: rgba(244, 241, 234, 0.78);
	max-width: 52ch;
	line-height: 1.55;
}
.hp-positioning__body p { margin-bottom: var(--space-3); }
.hp-positioning__collage {
	position: relative;
	height: 520px;
}
.hp-positioning__tile {
	position: absolute;
	border-radius: var(--radius-lg);
	overflow: hidden;
	box-shadow: 0 30px 80px rgba(0,0,0,0.4);
}
.hp-positioning__tile img { width: 100%; height: 100%; object-fit: cover; }
.hp-positioning__tile--1 { width: 60%; height: 70%; top: 0; left: 10%; transform: rotate(-4deg); }
.hp-positioning__tile--2 { width: 50%; height: 55%; bottom: 5%; right: 0; transform: rotate(5deg); }
.hp-positioning__tile--3 { width: 38%; height: 40%; top: 30%; right: 25%; transform: rotate(-2deg); }
.hp-positioning__tile--placeholder {
	background: linear-gradient(135deg, var(--color-secondary), var(--color-accent));
}

/* Showreel: a video that scales from a small box to full-width as the
   user scrolls past the section's midpoint. Driven by main.js setting
   --hp-reel-progress on the [data-showreel] block as 0 → 1.
   The frame is `position: sticky` so the video stays centred in the
   viewport while the surrounding section provides the scroll-room for
   the scale animation to play out. */
/* Full-bleed showreel: the video fills the whole viewport (no rounding,
   no inset) and the sticky frame pins it in place while the surrounding
   section provides the scroll-room. The pin reads as a brief "loading
   screen" — the brand thread keeps drawing across the bottom over the
   top of the video — until the user scrolls past and the page moves on.
   min-height controls how long the video stays pinned. */
.hp-positioning__showreel {
	position: relative;
	margin-top: 25vh; /* gap above the video so it clears the brand thread before pinning */
	min-height: 200vh; /* extra scroll-room so the slower scale plays out, then holds full-size while pinned */
	--hp-reel-progress: 0; /* JS drives 0 → 1 as the user scrolls in */
}
.hp-positioning__showreel-frame {
	position: sticky;
	top: 0;
	/* Break out to the VISIBLE viewport width. 100vw includes the scrollbar,
	   so it overflowed ~scrollbar-width and the sides got clipped; subtract the
	   measured scrollbar width (--sbw, set in JS) and re-centre. */
	width: calc(100vw - var(--sbw, 0px));
	margin-left: calc(50% - 50vw + var(--sbw, 0px) / 2);
	height: 100dvh;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
}
/* The video always fills the frame; as the user scrolls in, --hp-reel-progress
   climbs 0 → 1 and we scale it up from a small, rounded, shadowed box to the
   full-bleed screen (radius and shadow ease away as it reaches full size). */
.hp-positioning__showreel-video {
	display: block;
	/* Size the element to the video's own 16:9 shape (largest that fits the
	   frame, capped by both width and height) so there's no letterbox box.
	   The element edges = the visible video edges, so border-radius rounds the
	   actual video corners instead of an invisible letterbox box. */
	width: min(100%, calc((100dvh) * 16 / 9));
	height: auto;
	aspect-ratio: 16 / 9;
	max-height: 100%;
	object-fit: cover; /* element already matches 16:9, so this never crops */
	background: var(--color-primary, #081427);
	transform-origin: center center;
	transform: scale(calc(0.3 + 0.6 * var(--hp-reel-progress))); /* scales up to 0.9 (90%) at full progress, leaving a margin so nothing reaches the screen edge */
	border-radius: calc(24px + (1 - var(--hp-reel-progress)) * 76px); /* eases from 100px down to a resting 24px so the showreel keeps rounded corners at full size */
	box-shadow: 0 40px 100px rgba(0, 0, 0, calc(0.5 * (1 - var(--hp-reel-progress))));
	will-change: transform, border-radius;
}
@media (prefers-reduced-motion: reduce) {
	.hp-positioning__showreel { min-height: auto; margin-top: 10vh; --hp-reel-progress: 1; }
	.hp-positioning__showreel-frame { position: static; height: auto; }
	.hp-positioning__showreel-video { height: auto; aspect-ratio: 16 / 9; transform: none; border-radius: 0; box-shadow: none; }
}

/* ---------- As featured in (3D book) ----------
   The closed cover shows the magazine; on hover/focus it swings open on its
   left edge (the spine) to reveal an inside brand page. Built with CSS 3D
   transforms: the cover is a two-faced panel (front = magazine, back = paper)
   that rotates -158deg, uncovering the .hp-book__page sitting beneath it.
   ----------------------------------------------------- */
.hp-featured {
	background: var(--color-primary);
	color: var(--color-paper);
	padding: clamp(4rem, 9vw, 7rem) 1.5rem clamp(4rem, 9vw, 7rem);
	overflow: hidden; /* contains the cover as it swings past the left edge */
}
.hp-featured__inner {
	width: 100%;
	max-width: 1200px;
	margin-inline: auto;
	display: grid;
	grid-template-columns: 1.1fr 0.9fr;
	align-items: center;
	gap: clamp(2.5rem, 6vw, 6rem);
}
.hp-featured__copy {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
}
.hp-featured__kicker {
	font-size: 0.8125rem;
	text-transform: uppercase;
	letter-spacing: 0.22em;
	color: var(--color-accent);
	margin: 0 0 clamp(1rem, 2vw, 1.5rem);
	font-weight: 600;
}
.hp-featured__title {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(2.75rem, 7vw, 5.5rem);
	line-height: 0.98;
	letter-spacing: -0.035em;
	margin: 0;
}
.hp-featured__lead {
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-size: clamp(1.125rem, 2.2vw, 1.625rem);
	line-height: 1.3;
	letter-spacing: -0.01em;
	color: color-mix(in srgb, currentColor 80%, transparent);
	max-width: 24ch;
	margin: clamp(1.25rem, 2.5vw, 1.75rem) 0 0;
}
/* The book sits in the right column. */
.hp-featured__media {
	display: flex;
	justify-content: center;
}
/* The book. Sized to the cover's 358:467 ratio; perspective gives the open
   swing its depth. extra right margin reserves room for the opened cover so
   the layout stays centred. */
.hp-book {
	position: relative;
	width: clamp(220px, 24vw, 320px);
	aspect-ratio: 358 / 467;
	perspective: 2200px;
	margin-bottom: clamp(1.75rem, 3vw, 2.5rem);
	cursor: pointer;
	border-radius: 4px 10px 10px 4px;
	outline: none;
	/* Soft ground shadow under the closed book. */
	filter: drop-shadow(0 24px 40px rgba(0, 0, 0, 0.45));
	transition: filter 0.6s ease;
}
/* Inside brand page, revealed when the cover opens. */
.hp-book__page {
	position: absolute;
	inset: 0;
	border-radius: 4px 10px 10px 4px;
	background:
		radial-gradient(120% 100% at 0% 50%, rgba(0, 0, 0, 0.28), transparent 38%),
		var(--color-secondary);
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: clamp(0.75rem, 2vw, 1.25rem);
	padding: clamp(1.25rem, 3vw, 2rem);
	box-shadow: inset 0 0 0 1px rgba(244, 241, 234, 0.08);
}
.hp-book__page-logo { width: clamp(80px, 9vw, 120px); height: auto; }
.hp-book__wordmark {
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-size: clamp(1.25rem, 2.4vw, 1.75rem);
	line-height: 1.05;
	letter-spacing: -0.01em;
}
.hp-book__wordmark-dot { color: var(--color-accent); }
.hp-book__page-text {
	margin: 0;
	font-size: clamp(0.8125rem, 1.4vw, 0.95rem);
	line-height: 1.5;
	color: color-mix(in srgb, currentColor 75%, transparent);
	max-width: 24ch;
}
/* The swinging cover. */
.hp-book__cover {
	position: absolute;
	inset: 0;
	transform-origin: left center;
	transform-style: preserve-3d;
	transform: rotateY(0deg);
	transition: transform 1.1s cubic-bezier(0.6, 0.02, 0.1, 1);
	will-change: transform;
}
.hp-book:hover .hp-book__cover,
.hp-book:focus-visible .hp-book__cover,
.hp-book:focus-within .hp-book__cover {
	transform: rotateY(-158deg);
}
.hp-book__face {
	position: absolute;
	inset: 0;
	backface-visibility: hidden;
	-webkit-backface-visibility: hidden;
	border-radius: 4px 10px 10px 4px;
	overflow: hidden;
}
.hp-book__face--front { background: #000; }
.hp-book__cover-img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* The back of the cover (seen once opened) reads as a blank paper leaf. */
.hp-book__face--back {
	transform: rotateY(180deg);
	background:
		linear-gradient(90deg, rgba(0, 0, 0, 0.18), transparent 22%),
		var(--color-paper);
}
/* Faux spine shading down the hinge edge of the cover. */
.hp-book__spine {
	position: absolute;
	top: 0;
	left: 0;
	width: 14%;
	height: 100%;
	background: linear-gradient(90deg, rgba(0, 0, 0, 0.35), transparent);
	pointer-events: none;
}
.hp-featured__caption {
	margin: 0;
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-size: clamp(1rem, 2vw, 1.375rem);
	letter-spacing: -0.01em;
	max-width: 30ch;
}
.hp-featured__hint {
	margin-top: clamp(1.5rem, 3vw, 2.5rem);
	font-size: 0.75rem;
	text-transform: uppercase;
	letter-spacing: 0.18em;
	color: color-mix(in srgb, currentColor 45%, transparent);
}
/* Stack on narrow screens: copy on top, book below, both centred. */
@media (max-width: 820px) {
	.hp-featured__inner { grid-template-columns: 1fr; gap: clamp(2rem, 6vw, 3rem); }
	.hp-featured__copy { align-items: center; text-align: center; }
	.hp-featured__lead { max-width: 30ch; }
	.hp-featured__media { order: -1; } /* book first, then the headline below it */
}
@media (prefers-reduced-motion: reduce) {
	.hp-book__cover { transition: none; }
}

/* ---------- YouTube (latest uploads) ----------
   Auto-populated from the channel RSS feed. Cards are lazy thumbnail facades;
   the iframe is only injected on click (main.js). Grid collapses 3 → 2 → 1.
   ----------------------------------------------------- */
.hp-youtube {
	background: var(--color-primary);
	color: var(--color-paper);
}
/* Pin wrapper. Static by default (an accessible swipe row that works with no
   JS); main.js adds .hp-youtube--pinned to upgrade it to a sticky, scroll-
   driven horizontal carousel and sets the section height so the page resumes
   vertical scrolling once the last card arrives. */
.hp-youtube__pin {
	padding: clamp(4rem, 10vw, 8rem) 0 clamp(5rem, 12vw, 9rem);
	display: flex;
	flex-direction: column;
	gap: clamp(2rem, 4vw, 3rem);
}
.hp-youtube--pinned .hp-youtube__pin {
	position: sticky;
	top: 0;
	height: 100vh;
	padding-block: 0;
	justify-content: center;
	overflow: hidden;
}
.hp-youtube__header {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: clamp(1rem, 3vw, 2rem);
	flex-wrap: wrap;
	width: 100%;
	max-width: 1400px;
	margin-inline: auto;
	padding-inline: clamp(1.5rem, 6vw, 5rem);
}
.hp-youtube__eyebrow {
	font-size: 0.8125rem;
	text-transform: uppercase;
	letter-spacing: 0.22em;
	color: color-mix(in srgb, currentColor 55%, transparent);
	margin: 0 0 0.5rem;
	font-weight: 600;
}
.hp-youtube__heading {
	font-family: var(--font-heading-family);
	font-weight: 800;
	font-size: clamp(1.875rem, 4.5vw, 3.25rem);
	letter-spacing: -0.02em;
	line-height: 1.02;
	margin: 0;
}
/* Horizontal carousel track. A single row of fixed-width cards that the user
   drives sideways. Baseline: native horizontal scroll (works without JS).
   Pinned mode: JS translates the whole row with --yt-x as the page scrolls. */
.hp-youtube__track {
	list-style: none;
	margin: 0;
	display: flex;
	gap: clamp(0.75rem, 1.5vw, 1.5rem);
	padding: 0.5rem clamp(1.5rem, 6vw, 5rem);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;
}
.hp-youtube__track::-webkit-scrollbar { display: none; }
.hp-youtube--pinned .hp-youtube__track {
	overflow: visible;
	scroll-snap-type: none;
	transform: translate3d(calc(var(--yt-x, 0) * -1px), 0, 0);
	will-change: transform;
}
.hp-youtube__item {
	flex: 0 0 auto;
	min-width: 0;
	width: clamp(360px, 46vw, 680px);
	scroll-snap-align: start;
}
.hp-youtube__card {
	position: relative;
	display: block;
	height: auto;
	aspect-ratio: 16 / 9;
	border-radius: clamp(14px, 1.5vw, 22px);
	overflow: hidden;
	background: #000;
	color: inherit;
	text-decoration: none;
	box-shadow: 0 16px 40px rgba(0, 0, 0, 0.35);
}
.hp-youtube__thumb {
	position: absolute;
	inset: 0;
	display: block;
	overflow: hidden;
}
.hp-youtube__thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.hp-youtube__card:hover .hp-youtube__thumb img,
.hp-youtube__card:focus-visible .hp-youtube__thumb img {
	transform: scale(1.06);
}
/* Play button overlay, centred. */
.hp-youtube__play {
	position: absolute;
	inset: 0;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: transform 0.25s ease;
}
.hp-youtube__play svg { filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.5)); width: clamp(48px, 5vw, 68px); height: auto; }
.hp-youtube__play-bg { fill: #212121; opacity: 0.85; transition: fill 0.25s ease, opacity 0.25s ease; }
.hp-youtube__card:hover .hp-youtube__play-bg,
.hp-youtube__card:focus-visible .hp-youtube__play-bg {
	fill: var(--color-accent);
	opacity: 1;
}
.hp-youtube__card:hover .hp-youtube__play,
.hp-youtube__card:focus-visible .hp-youtube__play {
	transform: scale(1.08);
}
/* Title overlaid at the bottom over a gradient scrim. */
.hp-youtube__title {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 2;
	padding: clamp(1.5rem, 3vw, 2.25rem) clamp(1rem, 2vw, 1.5rem) clamp(0.9rem, 1.6vw, 1.25rem);
	background: linear-gradient(to top, rgba(0, 0, 16, 0.88) 0%, rgba(0, 0, 16, 0.5) 45%, transparent 100%);
	color: var(--color-white);
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-size: clamp(0.875rem, 1.2vw, 1.0625rem);
	line-height: 1.3;
	letter-spacing: -0.01em;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
/* Once clicked, the facade is replaced by the player iframe. */
.hp-youtube__thumb iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
}
/* Prev/next arrows — desktop uses the pinned scroll, so they stay hidden here
   and only appear in the mobile swipe-row block below. */
.hp-youtube__nav {
	display: none;
}
.hp-youtube__arrow {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 3rem;
	height: 3rem;
	border-radius: 50%;
	border: 1px solid rgba(244, 241, 234, 0.3);
	background: rgba(244, 241, 234, 0.06);
	color: var(--color-paper);
	cursor: pointer;
	transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease, opacity 0.2s ease;
	-webkit-tap-highlight-color: transparent;
}
.hp-youtube__arrow:hover,
.hp-youtube__arrow:focus-visible {
	background: var(--color-accent);
	border-color: var(--color-accent);
	color: var(--color-white);
}
.hp-youtube__arrow[disabled] {
	opacity: 0.3;
	pointer-events: none;
}
@media (max-width: 900px) {
	/* Show the arrows and right-align them under the swipe row. */
	.hp-youtube__nav {
		display: flex;
		gap: 0.75rem;
		justify-content: flex-end;
		padding: 1.25rem clamp(1.5rem, 6vw, 5rem) 0;
	}
}
@media (max-width: 900px) {
	/* Touch: never pin. Fall back to a native horizontal swipe row even if JS
	   tried to enable the carousel, so the page scrolls naturally on mobile. */
	.hp-youtube--pinned .hp-youtube__pin {
		position: static;
		height: auto;
		padding-block: clamp(4rem, 12vw, 6rem);
		overflow: visible;
	}
	.hp-youtube--pinned .hp-youtube__track {
		overflow-x: auto;
		scroll-snap-type: x mandatory;
		transform: none;
	}
	.hp-youtube__item { width: clamp(260px, 78vw, 360px); }
}

/* ---------- Curve ----------
   Big rounded bridge between dark and light grounds. The container sits flush
   with the next section, the SVG arc carves the upper edge so the transition
   reads as a single rounded scoop, geek-style.
   ----------------------------------------------------- */

.hp-curve {
	position: relative;
	margin-top: -1px;
	background: var(--color-paper);
	line-height: 0;
}
.hp-curve__svg {
	display: block;
	width: 100%;
	height: clamp(80px, 14vw, 200px);
}
.hp-curve--invert { background: var(--color-primary); }

/* ---------- Services ----------
   Oversized service rows on the paper ground. Each row is a wide grid: a
   small pink dot, the service title at display scale, and a one-line blurb
   right-aligned. Hover nudges the row inwards, swells the dot to pink, and
   draws a faint accent underline beneath the title.
   ----------------------------------------------------- */

/* Services + Work share a scroll-driven colour shift. --hp-work-shift runs
   0 (navy ground, light text) → 1 (paper ground, navy text); JS sets it on
   both sections from the work section's scroll position so the seam between
   them fades as one. Services rests at 0, Work rests at 1 when JS is absent
   (no-JS / reduced motion). Children use currentColor so they follow along. */
.hp-services {
	--hp-work-shift: 0;
	background: color-mix(in oklab, var(--color-paper) calc(var(--hp-work-shift) * 100%), var(--color-primary));
	color: color-mix(in oklab, var(--color-primary) calc(var(--hp-work-shift) * 100%), var(--color-paper));
	padding: clamp(5rem, 11vw, 9rem) 1.5rem clamp(6rem, 13vw, 11rem);
}
.hp-services__inner {
	width: 100%;
	margin-inline: auto;
}
.hp-services__eyebrow {
	font-size: 0.8125rem;
	text-transform: uppercase;
	letter-spacing: 0.22em;
	color: color-mix(in srgb, currentColor 55%, transparent);
	margin-bottom: clamp(1rem, 2vw, 1.5rem);
	font-weight: 600;
}
.hp-services__intro {
	font-family: var(--font-heading-family);
	font-weight: 700;
	font-size: clamp(1.25rem, 2.6vw, 2rem);
	line-height: 1.3;
	letter-spacing: -0.01em;
	max-width: 30ch;
	margin: 0 0 clamp(2.5rem, 5vw, 4rem);
	color: inherit;
}
.hp-services__list {
	list-style: none;
	margin: 0;
	padding: 0;
	border-top: 1px solid color-mix(in srgb, currentColor 18%, transparent);
}
.hp-services__item {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: center;
	gap: clamp(1rem, 2vw, 2rem);
	padding: clamp(1.5rem, 3vw, 2.5rem) 0;
	border-bottom: 1px solid color-mix(in srgb, currentColor 18%, transparent);
	cursor: default;
	transition: padding 0.35s ease, color 0.35s ease;
	position: relative;
}
.hp-services__item:hover {
	padding-left: clamp(0.75rem, 2vw, 1.5rem);
}
/* Bullet dot is hidden by default and slides in from the left as the user
   hovers (or keyboard-focuses) the service row. The grid reserves its column
   so the title never shifts; only the dot's opacity + position animate. */
.hp-services__dot {
	width: clamp(36px, 3.6vw, 50px);
	height: clamp(36px, 3.6vw, 50px);
	border-radius: 50%;
	background: var(--color-accent);
	opacity: 0;
	/* The big heading glyphs sit slightly low inside their tight line-box, so
	   a centred dot reads a touch low; this margin nudges it up to the text's
	   optical centre (cap-height). */
	margin-bottom: 0.12em;
	/* Start tiny so it pops up to size on hover. */
	transform: scale(0);
	transition: opacity 0.18s ease, transform 0.18s ease;
}
.hp-services__item:hover .hp-services__dot,
.hp-services__item:focus-within .hp-services__dot {
	opacity: 1;
	/* Overshoot-then-settle "bubble pop": the back-ease curve pushes past
	   scale(1) and springs back, like a bubble popping into place. */
	transform: scale(1);
	transition: opacity 0.18s ease,
		transform 0.42s cubic-bezier(0.34, 1.8, 0.64, 1);
}
.hp-services__title {
	font-family: var(--font-heading-family);
	font-size: clamp(2.25rem, 7vw, 6rem);
	font-weight: 800;
	letter-spacing: -0.035em;
	line-height: 0.98;
	transition: color 0.25s ease;
}
.hp-services__item:hover .hp-services__title { color: var(--color-accent); }
.hp-services__blurb {
	color: color-mix(in srgb, currentColor 62%, transparent);
	font-size: 1rem;
	text-align: right;
	max-width: 30ch;
	line-height: 1.45;
}

/* ---------- Work ----------
   Edge-to-edge oversized "Our Work" with the inset image clipped to the
   letterforms via background-clip: text. The heading is set to crop at the
   viewport boundaries, geek-style.
   ----------------------------------------------------- */

.hp-work {
	--hp-work-shift: 1;
	background: color-mix(in oklab, var(--color-paper) calc(var(--hp-work-shift) * 100%), var(--color-primary));
	color: color-mix(in oklab, var(--color-primary) calc(var(--hp-work-shift) * 100%), var(--color-paper));
	padding: clamp(4rem, 10vw, 8rem) 0 0;
	text-align: center;
	/* NOTE: no overflow:hidden here — it would clip and break the
	   sticky stacking of the nested portfolio cards. */
}
.hp-work__inner {
	padding-inline: 1.5rem;
}
.hp-work__inner {
	width: 100%;
	margin-inline: auto;
}
.hp-work__eyebrow {
	font-size: 0.8125rem;
	text-transform: uppercase;
	letter-spacing: 0.22em;
	color: color-mix(in srgb, currentColor 55%, transparent);
	margin-bottom: clamp(1.5rem, 3vw, 2.5rem);
	font-weight: 600;
}
.hp-work__heading {
	font-size: clamp(5rem, 22vw, 20rem);
	line-height: 0.86;
	font-weight: 900;
	letter-spacing: -0.05em;
	color: currentColor;
	margin: 0 0 clamp(2rem, 4vw, 3rem);
	background-position: center;
	background-size: cover;
	background-clip: text;
	-webkit-background-clip: text;
	text-transform: none;
}
.hp-work__heading[style*="background-image"] {
	color: transparent;
	-webkit-text-fill-color: transparent;
}
/* Brand pink dot after the heading. Forced solid even when the heading text is
   image-filled via background-clip, so the dot never goes transparent. */
.hp-work__dot {
	color: var(--color-accent);
	-webkit-text-fill-color: var(--color-accent);
}

/* ---------- Opinions ----------
   Navy ground card grid. Header is a two-column band: eyebrow + heading on
   the left, category rail (pill chips) on the right. Cards are softly
   rounded with the media bleeding to the top edges, geek-style.
   ----------------------------------------------------- */

.hp-opinions {
	background: var(--color-primary);
	padding: clamp(5rem, 12vw, 10rem) 1.5rem clamp(5rem, 12vw, 10rem);
}
.hp-opinions__inner {
	width: 100%;
	margin-inline: auto;
}
.hp-opinions__header {
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: end;
	margin-bottom: clamp(2.5rem, 5vw, 4rem);
	gap: var(--space-4);
}
.hp-opinions__eyebrow {
	font-size: 0.8125rem;
	text-transform: uppercase;
	letter-spacing: 0.22em;
	color: rgba(244, 241, 234, 0.55);
	margin: 0 0 var(--space-2);
	font-weight: 600;
}
.hp-opinions__heading {
	font-size: clamp(2.25rem, 5vw, 4.5rem);
	font-weight: 800;
	letter-spacing: -0.035em;
	line-height: 1;
	margin: 0;
}

.hp-opinions__rail {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	list-style: none;
	margin: 0;
	padding: 0;
}
.hp-opinions__rail li a,
.hp-opinions__rail li span {
	display: inline-flex;
	align-items: center;
	padding: 0.5rem 0.9375rem;
	border-radius: var(--radius-pill);
	background: rgba(244, 241, 234, 0.06);
	border: 1px solid rgba(244, 241, 234, 0.15);
	color: rgba(244, 241, 234, 0.78);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: -0.005em;
	transition: background 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}
.hp-opinions__rail li a:hover,
.hp-opinions__rail li.is-active a,
.hp-opinions__rail li.is-active span {
	background: var(--color-accent);
	color: var(--color-white);
	border-color: var(--color-accent);
}

.hp-opinions__grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: clamp(1.25rem, 2vw, 2rem);
	margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
.hp-opinions__card {
	background: var(--color-secondary);
	border-radius: 28px;
	padding: clamp(1.25rem, 2vw, 1.75rem);
	display: flex;
	flex-direction: column;
	transition: transform 0.35s ease, box-shadow 0.35s ease;
}
.hp-opinions__card:hover {
	transform: translateY(-4px);
	box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
}
.hp-opinions__media {
	display: block;
	margin: clamp(-1.75rem, -2vw, -1.25rem) clamp(-1.75rem, -2vw, -1.25rem) var(--space-3);
	border-radius: 28px 28px 0 0;
	overflow: hidden;
	aspect-ratio: 4 / 3;
}
.hp-opinions__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.6s ease; }
.hp-opinions__card:hover .hp-opinions__media img { transform: scale(1.04); }
.hp-opinions__media--placeholder {
	aspect-ratio: 4 / 3;
	background: linear-gradient(135deg, var(--color-radial), var(--color-accent));
}
.hp-opinions__meta {
	font-size: 0.75rem;
	text-transform: uppercase;
	letter-spacing: 0.18em;
	color: rgba(244, 241, 234, 0.5);
	margin: 0 0 var(--space-2);
	font-weight: 600;
}
.hp-opinions__title {
	font-size: clamp(1.375rem, 1.6vw, 1.625rem);
	font-weight: 700;
	line-height: 1.15;
	letter-spacing: -0.02em;
	margin: 0 0 var(--space-2);
}
.hp-opinions__title a { color: var(--color-paper); }
.hp-opinions__title a:hover { color: var(--color-accent); }
.hp-opinions__excerpt {
	color: rgba(244, 241, 234, 0.7);
	font-size: 0.9375rem;
	line-height: 1.55;
	margin: 0;
}

/* ---------- Outro ----------
   Closing statement at display scale, geek-style. Tight tracking, generous
   vertical space above and below, single CTA below.
   ----------------------------------------------------- */

.hp-outro {
	position: relative;
	background: var(--color-primary);
	padding: clamp(6rem, 14vw, 12rem) 1.5rem clamp(5rem, 10vw, 8rem);
	text-align: left;
	overflow: hidden;
}
.hp-outro__inner {
	width: 100%;
	margin-inline: auto;
	display: flex;
	justify-content: space-between;
	align-items: flex-end;
	gap: clamp(2rem, 5vw, 4rem);
	flex-wrap: wrap;
}
.hp-outro__statement {
	flex: 1 1 60%;
	min-width: 0;
	font-family: var(--font-heading-family);
	font-size: clamp(2.75rem, 9vw, 8rem);
	font-weight: 900;
	line-height: 0.96;
	letter-spacing: -0.045em;
	margin-bottom: 0;
}
.hp-outro .hp-btn { flex: 0 0 auto; }
.hp-outro__statement p { margin: 0; }
.hp-outro__statement em,
.hp-outro__statement strong .hp-accent { color: var(--color-accent); font-style: normal; }

/* Scroll-driven moving highlight. Each line sits white; JS sets --active
   (a float that climbs from -1 up to n-1 as the section scrolls in) on the
   container. A line is pink only when --active is near its --i, so a single
   pink highlight travels down the lines and rests on the last one. */
.hp-outro__sequence { display: flex; flex-direction: column; }
.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);
	color: color-mix(in srgb, var(--color-accent) calc(var(--lit) * 100%), var(--color-paper));
	transition: color 0.12s linear;
}
/* The <em> on "No filters." must follow the line's scroll colour rather than
   the always-pink rule above. */
.hp-outro__line em { color: inherit; font-style: normal; }
/* No color-mix / reduced motion / no JS: lines rest readable white. */
@supports not (color: color-mix(in srgb, red, blue)) {
	.hp-outro__line { color: var(--color-paper); }
}
@media (prefers-reduced-motion: reduce) {
	.hp-outro__line { color: var(--color-paper); transition: none; }
}

/* ---------- Footer ----------
   Brand-forward footer: oversized wordmark + studio details, a "Speak with
   us" CTA to the Contact page, the menu, and a base bar with social icons
   that bubble-wiggle on hover. No contact email is printed (scraper defence).
   ----------------------------------------------------- */

.site-footer {
	background: var(--color-primary);
	color: var(--color-paper);
	border-top: 1px solid rgba(244, 241, 234, 0.12);
	padding: clamp(4rem, 9vw, 7rem) 1.5rem var(--space-5);
}
.site-footer__inner {
	width: 100%;
	margin-inline: auto;
}
.site-footer__top {
	display: grid;
	grid-template-columns: 1.5fr 1fr 1fr;
	gap: var(--space-5);
	align-items: start;
}

/* Brand block: oversized logo + studio details. */
.site-footer__logo { display: inline-block; color: var(--color-paper); }
.site-footer__logo:hover { color: var(--color-paper); }
.site-footer__logo-img { max-width: 420px; height: auto; }
.site-footer__logo-svg { display: block; width: clamp(260px, 32vw, 440px); height: auto; }
.site-footer__wordmark {
	display: block;
	font-family: var(--font-heading-family);
	font-weight: 600;
	font-size: clamp(3.25rem, 7vw, 5.5rem);
	line-height: 0.9;
	letter-spacing: -0.02em;
	text-transform: lowercase;
}
.site-footer__wordmark-dot { color: var(--color-accent); }
.site-footer__address {
	font-style: normal;
	color: rgba(244, 241, 234, 0.7);
	font-size: 0.9375rem;
	line-height: 1.6;
	margin: var(--space-4) 0 var(--space-3);
}
.site-footer__phone a { color: var(--color-paper); font-size: 1.125rem; font-weight: 600; }
.site-footer__phone a:hover { color: var(--color-accent); }

/* "Speak with us" CTA. */
.site-footer__cta-text {
	font-family: var(--font-heading-family);
	font-size: clamp(1.5rem, 2.6vw, 2rem);
	font-weight: 700;
	letter-spacing: -0.02em;
	margin: 0 0 var(--space-3);
}

/* Menu column. */
.site-footer__col-title {
	font-size: 0.8125rem;
	text-transform: uppercase;
	letter-spacing: 0.18em;
	color: rgba(244, 241, 234, 0.5);
	margin: 0 0 var(--space-3);
	font-weight: 600;
}
.site-footer__list { list-style: none; margin: 0; padding: 0; }
.site-footer__list li { margin-bottom: var(--space-2); }
.site-footer__list a { color: var(--color-paper); }
.site-footer__list a:hover { color: var(--color-accent); }

/* Base bar. */
.site-footer__base {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-top: var(--space-6);
	padding-top: var(--space-4);
	border-top: 1px solid rgba(244, 241, 234, 0.12);
	font-size: 0.8125rem;
	color: rgba(244, 241, 234, 0.5);
	flex-wrap: wrap;
	gap: var(--space-3);
}
.site-footer__legal { margin: 0; }
.site-footer__legal-menu { list-style: none; margin: 0; padding: 0; display: flex; gap: var(--space-3); }
.site-footer__legal-menu a { color: rgba(244, 241, 234, 0.5); }
.site-footer__legal-menu a:hover { color: var(--color-accent); }

/* Social icons with hover bubble-wiggle. */
.site-footer__social {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	gap: var(--space-2);
}
.site-footer__social-link {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	border: 1px solid rgba(244, 241, 234, 0.25);
	color: var(--color-paper);
	transition: color 0.25s ease, border-color 0.25s ease;
}
.site-footer__social-icon {
	position: relative;
	z-index: 1;
	width: 20px;
	height: 20px;
}
.site-footer__social-bubble {
	position: absolute;
	inset: 0;
	border-radius: 50%;
	background: var(--color-accent);
	transform: scale(0);
	opacity: 0;
	transition: transform 0.3s ease, opacity 0.3s ease;
	z-index: 0;
}
.site-footer__social-link:hover,
.site-footer__social-link:focus-visible {
	color: var(--color-white);
	border-color: var(--color-accent);
	animation: hp-social-wiggle 0.6s ease-in-out infinite;
}
.site-footer__social-link:hover .site-footer__social-bubble,
.site-footer__social-link:focus-visible .site-footer__social-bubble {
	transform: scale(1);
	opacity: 1;
}
@keyframes hp-social-wiggle {
	0%, 100% { transform: translateY(0) rotate(0); }
	25%      { transform: translateY(-3px) rotate(-7deg); }
	50%      { transform: translateY(0) rotate(7deg); }
	75%      { transform: translateY(-2px) rotate(-4deg); }
}

/* ---------- Shared social icon row (footer + popup menu) ----------
   Circular icon buttons with the same bubble-wiggle hover as the footer.
   Reuses the @keyframes hp-social-wiggle defined above. */
.hp-social {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	gap: var(--space-2);
}
.hp-social__link {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	border: 1px solid rgba(244, 241, 234, 0.25);
	color: var(--color-paper);
	transition: color 0.25s ease, border-color 0.25s ease;
}
.hp-social__icon {
	position: relative;
	z-index: 1;
	width: 20px;
	height: 20px;
}
.hp-social__bubble {
	position: absolute;
	inset: 0;
	border-radius: 50%;
	background: var(--color-accent);
	transform: scale(0);
	opacity: 0;
	transition: transform 0.3s ease, opacity 0.3s ease;
	z-index: 0;
}
.hp-social__link:hover,
.hp-social__link:focus-visible {
	color: var(--color-white);
	border-color: var(--color-accent);
	animation: hp-social-wiggle 0.6s ease-in-out infinite;
}
.hp-social__link:hover .hp-social__bubble,
.hp-social__link:focus-visible .hp-social__bubble {
	transform: scale(1);
	opacity: 1;
}

/* Popup menu placement: sit the icons below the nav links, left-aligned to
   match the menu items. */
.site-nav__social {
	justify-content: flex-start;
	margin-top: clamp(2rem, 5vh, 3.5rem);
}

/* ---------- Newsletter form ---------- */

.hp-newsletter {
	display: grid;
	gap: var(--space-3);
	background: var(--color-secondary);
	padding: var(--space-5);
	border-radius: var(--radius-lg);
}
.hp-newsletter__heading { font-size: 1.5rem; margin: 0 0 var(--space-1); }
.hp-newsletter__sub { color: rgba(244, 241, 234, 0.65); margin: 0; }
.hp-newsletter__fields { display: grid; grid-template-columns: 1fr auto; gap: var(--space-2); }
.hp-newsletter__fields input {
	padding: 0.875rem 1rem;
	background: rgba(244, 241, 234, 0.08);
	border: 1px solid rgba(244, 241, 234, 0.18);
	color: var(--color-paper);
	border-radius: var(--radius-pill);
	font: inherit;
}
.hp-newsletter__feedback { margin: 0; font-size: 0.875rem; min-height: 1.25em; }

/* ---------- Page / archive / post ---------- */

/* Scope to the MAIN content element, NOT the body. WordPress also puts a
   `page` class on <body> (incl. the static front page), so a bare `.page`
   selector padded the homepage body and shoved the hero down. Targeting the
   `.site-main` keeps the front page (main.hp-home) and single posts
   (main.hp-single, which has its own padding) untouched. */
.site-main.page, .site-main.archive, .site-main.error-404 {
	/* Top padding only needs to clear the fixed header pills (~70px), not the
	   old 10rem. */
	padding: clamp(5rem, 9vw, 7rem) 0 var(--space-7);
	background: var(--color-primary);
	min-height: 80vh;
}
.archive-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--space-4);
}
.archive-card { background: var(--color-secondary); border-radius: var(--radius-lg); padding: var(--space-4); }
.archive-card__media { display: block; aspect-ratio: 4/3; overflow: hidden; border-radius: var(--radius-lg); margin-bottom: var(--space-3); }
.archive-card__media img { width: 100%; height: 100%; object-fit: cover; }
.archive-card__title { font-size: 1.5rem; margin: 0 0 var(--space-2); }
.archive-card__title a { color: var(--color-paper); }

.error-404__title { font-size: clamp(5rem, 18vw, 14rem); margin: 0; }
.error-404__copy { color: rgba(244, 241, 234, 0.7); margin: var(--space-3) 0 var(--space-4); }

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

@media (max-width: 1024px) {
	.hp-positioning__inner { grid-template-columns: 1fr; }
	.hp-positioning__collage { height: 420px; max-width: 560px; margin-inline: auto; }
	.hp-opinions__header { grid-template-columns: 1fr; align-items: start; }
	.hp-opinions__grid { grid-template-columns: repeat(2, 1fr); }
	.archive-grid { grid-template-columns: repeat(2, 1fr); }
	.hp-services__blurb { text-align: left; max-width: none; }
	.hp-services__item { grid-template-columns: auto 1fr; }
	.hp-services__blurb { grid-column: 2; }
}

@media (max-width: 899px) {
	h1 { font-size: var(--font-h1-size-mobile); }
	h2 { font-size: var(--font-h2-size-mobile); }
	h3 { font-size: var(--font-h3-size-mobile); }
	body.hp-body { font-size: var(--font-body-size-mobile); }
	.site-header { left: var(--space-3); right: var(--space-3); top: var(--space-2); }
	.site-header__pill { padding: 0.5625rem 1rem; font-size: 0.875rem; }
	.hp-opinions__grid { grid-template-columns: 1fr; }
	.archive-grid { grid-template-columns: 1fr; }
	.site-footer__top { grid-template-columns: 1fr; gap: var(--space-4); }
	.hp-services__title { font-size: clamp(1.875rem, 9.5vw, 3.75rem); }
	.hp-services__item { padding: 1.5rem 0; }
	.hp-services__blurb { font-size: 0.9375rem; }
	.hp-work__heading { font-size: clamp(2.5rem, 16vw, 9rem); }
}

@media (max-width: 480px) {
	.hp-positioning, .hp-services, .hp-work, .hp-opinions, .hp-outro, .site-footer { padding-left: 1rem; padding-right: 1rem; }
	.hp-newsletter__fields { grid-template-columns: 1fr; }
	.site-footer__base { flex-direction: column; align-items: flex-start; }
	.hp-btn { padding: 0.875rem 1.5rem; font-size: 0.9375rem; }
	.hp-btn--large { padding: 1rem 1.75rem; font-size: 1rem; }
}

/* ---------- Reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
	}
}
