/* Fonts are loaded via <link> in index.html <head> for faster, non-blocking delivery */

/* ─── Tokens ─────────────────────────────────────────────── */
:root {
  --bg:           #080808;
  --bg-2:         #101010;
  --bg-3:         #181818;
  --text:         #F0EDE8;
  --text-soft:    rgba(240, 237, 232, 0.62);
  --muted:        rgba(240, 237, 232, 0.38);
  --border:       rgba(240, 237, 232, 0.07);
  /* MONOCHROME trial — to revert to orange, restore:
     --accent:#FF4D00; --accent-deep:#CC3D00; --accent-muted:rgba(255,77,0,0.12); --accent-on:#fff; */
  --accent:       #FFFFFF;
  --accent-deep:  #E4DFD8;
  --accent-muted: rgba(255, 255, 255, 0.10);
  --accent-on:    #080808;  /* text/icon colour that sits on an accent fill */
  --nav-h:        76px;
  --max-w:        1320px;
  --pad:          clamp(1.5rem, 5vw, 4rem);
  /* One vertical rhythm for content bands, so section seams are consistent.
     Colour bands (manifesto, cta) get it both sides; the transparent work
     band takes 0 and borrows its air from the padded neighbours — that keeps
     every seam a single --band with no doubling. Full-bleed bands stay 0. */
  --band:         clamp(4rem, 7vw, 7rem);

  /* Type system — to revert: display 'Bebas Neue', body 'Inter' */
  --font-display: 'Cabinet Grotesk', sans-serif;
  --font-body:    'General Sans', 'Helvetica Neue', Arial, sans-serif;
  --font-mono:    'Space Mono', ui-monospace, monospace;
}

/* ─── Reset ──────────────────────────────────────────────── */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; font-size: 16px; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-weight: 300;
  line-height: 1.65;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; height: auto; }
button { cursor: pointer; background: none; border: none; font: inherit; color: inherit; }
ul { list-style: none; }

/* ─── Lenis smooth scroll ────────────────────────────────── */
/* Applied only while Lenis is active (JS adds `.lenis` to <html>). When it's
   driving, native `scroll-behavior: smooth` is turned off so anchor jumps route
   through Lenis instead of fighting it; without JS the native fallback stays. */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }
.lenis.lenis-scrolling iframe { pointer-events: none; }

/* Visible keyboard focus (removed for mouse via :focus-visible) */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}
:focus:not(:focus-visible) { outline: none; }

/* Hero logo wrapped in <h1> for document structure — reset heading box */
.hero-logo-h1 { margin: 0; font-size: 0; line-height: 0; }

/* ─── Utility ─────────────────────────────────────────────── */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}
.container { width: 100%; max-width: var(--max-w); margin: 0 auto; padding: 0 var(--pad); }
.display { font-family: var(--font-display); font-weight: 800; text-transform: uppercase; line-height: 0.95; letter-spacing: -0.005em; }
.text-accent { color: var(--accent); }
.label {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}
.section { padding: clamp(5rem, 10vw, 9rem) 0; }
.section-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}
.section-title {
  font-size: clamp(2.25rem, 5vw, 3.75rem);
  line-height: 1;
  color: var(--text);
}

/* ─── Nav ─────────────────────────────────────────────────── */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--pad);
  border-bottom: 1px solid transparent;
  transition: border-color 0.4s, background 0.4s, backdrop-filter 0.4s;
}
.nav.scrolled {
  background: rgba(8, 8, 8, 0.88);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-color: var(--border);
}
.nav-logo {
  display: flex; align-items: center; height: 28px;
  transition: opacity 0.4s ease, visibility 0.4s ease;
}
/* On the homepage, main.js hides the nav mark until the big hero logo has
   scrolled out of the viewport, so the two IRIS marks never show at once.
   Default is visible, so other pages (and no-JS) always show the mark. */
.nav.logo-hidden .nav-logo {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.nav-logo img { height: 100%; width: auto; }
.nav-logo-text {
  font-family: var(--font-display);
  font-size: 1.5rem;
  letter-spacing: 0.14em;
  color: var(--text);
}
.nav-links {
  display: flex;
  align-items: center;
  gap: 2.5rem;
}
.nav-links a {
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  transition: color 0.25s;
  position: relative;
  padding-bottom: 2px;
}
.nav-links a::after {
  content: '';
  position: absolute;
  bottom: -2px; left: 0;
  width: 100%; height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.nav-links a:hover,
.nav-links a.active { color: var(--text); }
.nav-links a:hover::after,
.nav-links a.active::after { transform: scaleX(1); }

/* Mobile toggle */
.nav-toggle { display: none; flex-direction: column; gap: 5px; padding: 4px; }
.nav-toggle span {
  display: block; width: 22px; height: 1px;
  background: var(--text);
  transition: transform 0.3s, opacity 0.3s;
}
.nav-toggle.open span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-toggle.open span:nth-child(2) { opacity: 0; }
.nav-toggle.open span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* Mobile overlay */
.nav-overlay {
  position: fixed; inset: 0;
  background: var(--bg);
  z-index: 99;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 2rem;
  opacity: 0; pointer-events: none;
  transition: opacity 0.35s;
}
.nav-overlay.open { opacity: 1; pointer-events: all; }
.nav-overlay a {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 8vw, 4rem);
  letter-spacing: 0.06em;
  color: var(--muted);
  transition: color 0.2s;
}
.nav-overlay a:hover { color: var(--text); }

/* ─── Hero ────────────────────────────────────────────────── */
.hero {
  position: relative;
  height: 100vh;
  min-height: 600px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Background loop is a Vimeo <iframe> (16:9), so it can't object-fit. Size it
   to always COVER the viewport: 100vw wide with 16:9 height, but never smaller
   than the viewport in either axis (min-width/height), then centre-crop the
   overflow. min-width uses vh (177.78vh = 16:9 of the height) for tall/portrait. */
.hero-video {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 100vw;
  height: 56.25vw;
  min-width: 177.7778vh;
  min-height: 100vh;
  border: 0;
  z-index: 0;
  pointer-events: none;
}

.hero-overlay {
  position: absolute; inset: 0;
  background:
    linear-gradient(to bottom,
      rgba(8,8,8,0.45) 0%,
      rgba(8,8,8,0.55) 50%,
      rgba(8,8,8,0.88) 100%
    );
  z-index: 1;
}

.hero-content {
  position: relative;
  z-index: 2;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.9rem;
  padding: 0 var(--pad);
}

.hero-eyebrow {
  display: flex;
  align-items: center;
  gap: 1rem;
  font-size: 0.65rem;
  font-weight: 500;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: rgba(240, 237, 232, 0.5);
}
.hero-eyebrow-line {
  display: block;
  width: 28px; height: 1px;
  background: var(--accent);
}

.hero-logo-text {
  font-family: var(--font-display);
  font-size: clamp(5rem, 18vw, 16rem);
  line-height: 0.85;
  letter-spacing: 0.12em;
  color: var(--text);
}
.hero-logo-img {
  height: clamp(60px, 12vw, 140px);
  width: auto;
  filter: brightness(0) invert(1);
}

.hero-strapline {
  /* The only positioning line above the fold — must be readable at a glance */
  font-size: clamp(0.75rem, 1.4vw, 1rem);
  font-weight: 500;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(240, 237, 232, 0.78);
}

.hero-actions {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  justify-content: center;
}
.hero-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  border-radius: 100px;
  padding: 0.9em 2em;
  transition: border-color 0.3s, background 0.3s, color 0.3s, transform 0.3s;
}
.hero-cta--primary {
  background: var(--accent);
  color: var(--accent-on);
  border: 1px solid var(--accent);
}
.hero-cta--primary:hover {
  background: var(--accent-deep);
  border-color: var(--accent-deep);
  color: var(--accent-on);
  transform: translateY(-2px);
}
.hero-cta--ghost {
  color: var(--text);
  border: 1px solid rgba(240, 237, 232, 0.3);
}
.hero-cta--ghost:hover {
  border-color: var(--text);
  background: rgba(240, 237, 232, 0.06);
}

.hero-scroll-cue {
  position: absolute;
  bottom: 2.25rem; left: var(--pad);
  z-index: 2;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.28em;
  text-transform: uppercase;
}
/* A band of light sweeps down through the letters — a bright highlight in a
   mostly dim gradient, clipped to the text, that travels top-to-bottom and rests. */
.hero-scroll-cue span {
  display: inline-block;
  color: rgba(240, 237, 232, 0.45); /* fallback where background-clip:text is unsupported */
  background-image: linear-gradient(
    180deg,
    rgba(240, 237, 232, 0.38) 0%,
    rgba(240, 237, 232, 0.38) 42%,
    rgba(255, 255, 255, 0.95) 50%,
    rgba(240, 237, 232, 0.38) 58%,
    rgba(240, 237, 232, 0.38) 100%
  );
  background-size: 100% 220%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: scrollShimmer 3.4s linear infinite;
}
@keyframes scrollShimmer {
  0%   { background-position: 0 100%; }
  50%  { background-position: 0 0%; }
  100% { background-position: 0 0%; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-scroll-cue span { -webkit-text-fill-color: rgba(240, 237, 232, 0.5); }
}

/* ─── Trusted By ──────────────────────────────────────────── */
/* Mission statement + client credibility share one band. Mission carries
   headline weight up top; the trusted marks sit quietly beneath. */
.intro {
  padding: clamp(3.5rem, 7vw, 5.5rem) 0;
  border-bottom: 1px solid var(--border);
}
.mission { text-align: center; }
.mission-label { display: inline-block; margin-bottom: 1.25rem; }
.mission-headline {
  font-size: clamp(2.1rem, 5.5vw, 4rem);
  line-height: 0.98;
  max-width: 14ch;
  margin: 0 auto;
}
.mission-text {
  margin: 1.5rem auto 0;
  max-width: 54ch;
  font-size: clamp(0.98rem, 1.35vw, 1.2rem);
  line-height: 1.7;
  font-weight: 300;
  color: var(--text-soft);
}
.mission-text .text-accent { color: var(--text); font-weight: 500; }

/* Trusted-by block sits below the mission within the same .intro band */
.trusted-block {
  margin-top: clamp(3rem, 6vw, 4.5rem);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.75rem;
}
.trusted-label {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.trusted-logos {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.85rem clamp(1.25rem, 2vw, 1.8rem);
  flex-wrap: wrap; /* single line on desktop; wraps gracefully on small screens */
}
/* Forced two-row split on desktop — a full-width, zero-height flex item that
   pushes everything after it onto a second line (6 marks up, 5 down) */
.trusted-logos .logo-row-break { flex-basis: 100%; height: 0; }
/* Real client names set as plain text — a list, not fake logo marks */
.trusted-logos span {
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  color: rgba(240, 237, 232, 0.55);
  transition: color 0.25s;
}
.trusted-logos span:hover { color: var(--text); }
/* Client marks: uniform mono treatment, one shared height */
.trusted-logos img {
  height: 22px;
  width: auto;
  opacity: 0.55;
  filter: brightness(0) invert(1);
  transition: opacity 0.25s;
}
.trusted-logos img:hover { opacity: 1; }
/* Solid-background marks (box/disc logos): greyscale keeps their internal
   text readable — the flat mono filter would erase it to a blank shape */
.trusted-logos img.logo-solid {
  filter: grayscale(1) brightness(1.15);
  opacity: 0.7;
}
/* Compact/square marks need extra height to match the optical weight of wordmarks */
.trusted-logos img.logo-compact { height: 31px; }
/* Black-on-white marks: invert to white-on-black, then screen-blend the black
   box away into the page background — leaves just the white glyphs */
.trusted-logos img.logo-knockout {
  filter: invert(1);
  mix-blend-mode: screen;
}
/* Marks whose fine detail needs a touch more size to read */
.trusted-logos img.logo-plus { height: 28px; }

/* ─── Motion Control feature ──────────────────────────────── */
/* Light band: the section flips to the site's light surface with black copy.
   The tokens are redefined locally rather than overriding each rule, so every
   child (.label, .text-accent, .cta-btn--solid, body copy, borders) inherits
   the inverted values. Needed because the monochrome trial sets --accent to
   white, which would otherwise render the label, accent text and solid button
   invisible here. */
.moco-feature {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  align-items: stretch;
  min-height: clamp(480px, 70vh, 760px);
  background: #F0EDE8;
  color: #080808;
  --text:        #080808;
  --text-soft:   rgba(8, 8, 8, 0.68);
  --muted:       rgba(8, 8, 8, 0.45);
  --border:      rgba(8, 8, 8, 0.12);
  --accent:      #080808;
  --accent-deep: #2C2C2C;
  --accent-on:   #F0EDE8;
  border-bottom: 1px solid var(--border);
  overflow: hidden;
}
/* Framed, not full-bleed: the margin insets the picture so the light band
   frames it on all four sides, its left edge landing on the site's gutter. */
.moco-media {
  position: relative;
  overflow: hidden;
  margin: var(--pad);
}
.moco-video {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.moco-text {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  gap: 1.5rem;
  padding: clamp(2.5rem, 6vw, 5rem);
}
.moco-text .label { margin-bottom: 0.25rem; }
.moco-heading {
  font-size: clamp(2.4rem, 4.2vw, 4.2rem);
  line-height: 0.98;
}
.moco-text p {
  font-size: clamp(0.95rem, 1.3vw, 1.08rem);
  color: var(--text-soft);
  line-height: 1.8;
  max-width: 42ch;
}
.moco-capability {
  color: rgba(8, 8, 8, 0.55) !important;
}
.moco-text .cta-btn--solid {
  margin-top: 0.75rem;
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-on);
}
.moco-text .cta-btn--solid:hover {
  background: var(--accent-deep);
  border-color: var(--accent-deep);
  color: var(--accent-on);
}

/* ─── Manifesto — condensed white band (breaks the dark scroll) ─── */
.manifesto {
  background: #F0EDE8;
  color: #080808;
  padding: var(--band) 0;
}
.manifesto-inner {
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 var(--pad);
}
.manifesto-text {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2rem, 3.4vw, 3rem);
  line-height: 1.0;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: #080808;
  max-width: 26ch;
}
.manifesto .text-accent { color: inherit; }  /* white accent would vanish on the light band */
.manifesto .manifesto-link {
  margin-top: 1.75rem;
  color: rgba(8, 8, 8, 0.55);
}
.manifesto .manifesto-link:hover { color: #080808; }

/* Homepage "serious about the craft" band: shot-01 full-bleed behind the copy,
   darkened hard on the left so the left-aligned text stays legible; copy flips
   to light. (About's plain .manifesto band keeps its cream/dark treatment.)
   Height comes from .offer-hero's min-height, so the band's own padding is
   zeroed and the copy centres in the frame. */
.offer {
  padding: 0;
  color: var(--text);
  background:
    linear-gradient(90deg, rgba(8, 8, 8, 0.92) 0%, rgba(8, 8, 8, 0.74) 38%, rgba(8, 8, 8, 0.42) 68%, rgba(8, 8, 8, 0.14) 100%),
    #080808 url('../assets/images/shot-01.jpg') center / cover no-repeat;
}
.offer-sub {
  margin-top: 1.5rem;
  max-width: 48ch;
  font-size: clamp(0.95rem, 1.3vw, 1.08rem);
  line-height: 1.8;
  color: rgba(240, 237, 232, 0.82);
}

/* Header band — title, sub and link over shot-01; links to About. A tall,
   cinematic strip: min-height sets the frame, the padding is the floor when
   the copy runs long (mobile), and align-items centres it either way. */
.offer-hero {
  display: flex;
  align-items: center;
  min-height: clamp(560px, 78vh, 900px);
  padding: clamp(4.5rem, 9vw, 8rem) 0;
  text-decoration: none;
}
.offer-hero .offer-hero-inner { display: flex; flex-direction: column; align-items: flex-start; }
.offer-hero .manifesto-text { font-size: clamp(2.25rem, 5vw, 3.75rem); line-height: 1; max-width: none; color: var(--text); }
.offer-hero .offer-hero-link {
  margin-top: 1.75rem;
  color: rgba(240, 237, 232, 0.72);
}
.offer-hero:hover .offer-hero-link { color: var(--text); gap: 0.85rem; }

.offer-media {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 100%;
  min-height: clamp(360px, 46vw, 520px);
}
/* Two stacked layers so a hovered service crossfades in without a white flash */
.offer-media-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  transition: opacity 0.6s ease;
}
.offer-media-img.is-active { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .offer-media-img { transition: opacity 0.2s ease; }
}
.offer-services { margin-top: 0; --offer-media-col: clamp(440px, 53%, 700px); }
/* Section title. Was a 10px mono eyebrow, which left this the only block on the
   page with no heading; now carries the same display treatment as the about-block
   and about-overlay h3s so it sits level with its neighbours. */
.offer-title {
  display: block;
  margin: 0 0 1.5rem;
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: clamp(1.5rem, 3vw, 2.4rem);
  line-height: 1;
  letter-spacing: -0.01em;
}
/* One-column service list on the left, hover-swap still filling the right
   column. Rolling over a row highlights it (monochrome — a black rule wipes in
   from the left, the row indents, its copy comes to full ink) and crossfades
   that row's still into the .offer-media panel via js/main.js. */
.svc-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--offer-media-col);
  gap: clamp(2.5rem, 5vw, 5rem);
  align-items: stretch;
}
.svc-list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid rgba(8, 8, 8, 0.14);
}
.svc-list li {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 1.05rem 0;
  border-bottom: 1px solid rgba(8, 8, 8, 0.14);
  cursor: default;
  transition: padding-left 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.svc-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: -1px;
  bottom: -1px;
  width: 2px;
  background: #080808;
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.svc-list li:hover { padding-left: 1.1rem; }
.svc-list li:hover::before { transform: scaleY(1); }
.svc-name {
  font-size: clamp(1rem, 1.6vw, 1.3rem);
  font-weight: 300;
  line-height: 1.15;
  color: rgba(8, 8, 8, 0.72);
  transition: color 0.4s ease;
}
.svc-list li:hover .svc-name { color: #080808; }
.svc-desc {
  font-size: clamp(0.82rem, 1vw, 0.92rem);
  line-height: 1.4;
  color: rgba(8, 8, 8, 0.52);
  transition: color 0.4s ease;
}
.svc-list li:hover .svc-desc { color: rgba(8, 8, 8, 0.78); }
.line-wrap {
  display: block;
  overflow: hidden;
}
.line {
  display: block;
  font-style: normal;
  transform: translateY(110%);
  opacity: 0;
  transition: transform 0.85s cubic-bezier(0.16, 1, 0.3, 1),
              opacity 0.85s ease;
}
.line-wrap:nth-child(2) .line { transition-delay: 0.12s; }
.line-wrap:nth-child(3) .line { transition-delay: 0.24s; }

.reveal-lines.visible .line {
  transform: translateY(0);
  opacity: 1;
}

.manifesto-meta {
  margin-top: 3rem;
  display: flex;
  align-items: center;
  gap: 2rem;
}

/* ─── Capabilities (statement + numbered index) ───────────── */
.capabilities { padding: clamp(4.5rem, 9vw, 8rem) 0; }
.cap-grid {
  display: grid;
  grid-template-columns: 0.82fr 1.18fr;
  gap: clamp(2.5rem, 6vw, 6rem);
  align-items: center;
}
.cap-intro {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.75rem;
}
.cap-statement {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 3.4vw, 3.2rem);
  line-height: 1.02;
  letter-spacing: 0.02em;
}
.line-wrap:nth-child(4) .line { transition-delay: 0.36s; }

.cap-index {
  border-top: 1px solid var(--border);
  counter-reset: cap;
}
.cap-row {
  display: flex;
  align-items: baseline;
  gap: clamp(1rem, 2vw, 2rem);
  padding: clamp(1.05rem, 1.9vw, 1.6rem) 0;
  border-bottom: 1px solid var(--border);
  cursor: default;
  transition: padding-left 0.35s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.cap-row:hover { padding-left: 0.85rem; }
.cap-no {
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  color: var(--accent);
  min-width: 2.5ch;
}
.cap-name {
  flex: 1;
  font-size: clamp(1.15rem, 2vw, 1.65rem);
  font-weight: 300;
  transition: color 0.25s;
}
.cap-arrow {
  color: var(--accent);
  font-size: 1.1rem;
  opacity: 0;
  transform: translateX(-8px);
  transition: opacity 0.25s, transform 0.25s;
}
.cap-row:hover .cap-name { color: var(--accent); }
.cap-row:hover .cap-arrow { opacity: 1; transform: translateX(0); }

/* ─── Editorial Images ────────────────────────────────────── */
.editorial {
  padding-bottom: clamp(5rem, 10vw, 9rem);
  overflow: hidden;
}

/* Parallax host */
.parallax-host { overflow: hidden; }
.parallax-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transform: scale(1.08) translateY(0px);
  will-change: transform;
  transition: transform 0s linear;
}

/* Block A: asymmetric 2-col */
.edit-block-a {
  display: grid;
  grid-template-columns: 54% 46%;
  gap: 1.5rem;
  max-width: var(--max-w);
  margin: 0 auto clamp(4rem, 8vw, 7rem);
  padding: 0 var(--pad);
  align-items: start;
}
.edit-img-tall {
  height: clamp(520px, 75vh, 820px);
}
.edit-col-right {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  padding-top: clamp(3rem, 6vw, 6rem);
}
.edit-img-short {
  height: clamp(260px, 35vh, 420px);
}
.edit-text-block {
  padding: 2rem 0 1rem;
}
.edit-text-block .label {
  display: block;
  margin-bottom: 1.25rem;
}
.edit-text-block p {
  font-size: clamp(0.9rem, 1.3vw, 1rem);
  color: var(--muted);
  max-width: 36ch;
  line-height: 1.8;
}

/* Block B: full-bleed with overlay */
.edit-block-b {
  position: relative;
  height: clamp(460px, 70vh, 800px);
  margin-bottom: clamp(4rem, 8vw, 7rem);
  overflow: hidden;
}
.edit-img-full {
  width: 100%; height: 100%;
}
.edit-b-text {
  position: absolute;
  bottom: clamp(2rem, 5vw, 4rem);
  left: var(--pad);
  z-index: 2;
}
.edit-b-text .label { margin-bottom: 1rem; display: block; }
.edit-b-heading {
  font-size: clamp(3.5rem, 8vw, 9rem);
  color: var(--text);
  line-height: 0.92;
}
.edit-block-b::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(to top right,
    rgba(8,8,8,0.75) 0%,
    rgba(8,8,8,0.1) 60%
  );
  pointer-events: none;
}

/* Block C: services list + image */
.edit-block-c {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(3rem, 6vw, 6rem);
  max-width: var(--max-w);
  margin: 0 auto clamp(4rem, 8vw, 7rem);
  padding: 0 var(--pad);
  align-items: start;
}
.edit-services { padding-top: 1rem; }
.services-list { border-top: 1px solid var(--border); }
.services-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: clamp(2rem, 6vw, 5rem);
  border-top: none;
}
.services-grid .service-line { border-top: 1px solid var(--border); border-bottom: none; }
.service-line {
  display: flex;
  align-items: baseline;
  gap: 1.5rem;
  padding: 1.1rem 0;
  border-bottom: 1px solid var(--border);
  font-size: clamp(1rem, 1.8vw, 1.25rem);
  font-weight: 300;
  transition: color 0.25s, padding-left 0.3s;
  cursor: default;
}
.service-line:hover { color: var(--accent); padding-left: 0.5rem; }
.service-line span {
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  color: var(--accent);
  font-weight: 500;
  min-width: 2ch;
}
.edit-img-portrait {
  height: clamp(400px, 60vh, 700px);
}

/* Block D: wide landscape */
.edit-block-d {
  max-width: calc(var(--max-w) - 4rem);
  margin: 0 auto;
  padding: 0 var(--pad);
  position: relative;
}
.edit-img-wide {
  height: clamp(300px, 45vh, 560px);
  border-radius: 2px;
  overflow: hidden;
}
.edit-d-caption {
  margin-top: 1rem;
  padding-left: 0.5rem;
}

/* ─── Work Grid ───────────────────────────────────────────── */
.services-section { padding-top: clamp(2.5rem, 5vw, 4rem); padding-bottom: clamp(2.5rem, 5vw, 4rem); }
/* Transparent band between the cream manifesto and the accent cta. Given its
   own symmetric breathing (it has no background, so this is just spacing, not
   an unbalanced band): a bare seam left the header jammed against the cream
   edge and the gallery against the accent edge. This adds dark air on both
   sides — a deliberately larger seam that sets the work showcase apart. */
.work-teaser { padding-block: clamp(3rem, 4.5vw, 4rem); }
.work-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
}
.work-card {
  background: var(--bg);
  aspect-ratio: 4/3;
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 1.5rem;
  cursor: pointer;
}
.work-card-bg {
  position: absolute; inset: 0;
  background: var(--bg-3);
  transition: transform 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.work-card:nth-child(1) .work-card-bg { background: linear-gradient(135deg, #1a1a1a, #222); }
.work-card:nth-child(2) .work-card-bg { background: linear-gradient(135deg, #161c1a, #1e2420); }
.work-card:nth-child(3) .work-card-bg { background: linear-gradient(135deg, #1c1618, #221c1e); }
.work-card:hover .work-card-bg { transform: scale(1.05); }
.work-card-overlay {
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(8,8,8,0.88) 0%, transparent 55%);
}
.work-card-content { position: relative; z-index: 1; }
.work-card-type {
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text-soft);
  margin-bottom: 0.4rem;
}
.work-card-title {
  font-size: clamp(1rem, 2vw, 1.25rem);
  font-weight: 300;
  line-height: 1.3;
}
.work-card-arrow {
  position: absolute;
  top: 1.5rem; right: 1.5rem;
  z-index: 1;
  font-size: 0.95rem;
  color: var(--accent);
  opacity: 0;
  transform: translate(-4px, 4px);
  transition: opacity 0.25s, transform 0.25s;
}
.work-card:hover .work-card-arrow { opacity: 1; transform: translate(0, 0); }

/* ─── The Work — catalogue grid (A24-style density) ───────── */
/* Homepage work teaser (index.html) — original monochrome-blooms-on-hover grid */
.work-index {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: clamp(170px, 19vw, 250px);
  grid-auto-flow: dense;
  gap: 3px;
  max-width: 1680px;
  margin: 0 auto;
  padding: 0 clamp(0.75rem, 2vw, 1.5rem);
}
.wt {
  position: relative;
  overflow: hidden;
  background: var(--bg-2);
  display: block;
}
.wt--big  { grid-column: span 2; grid-row: span 2; }
.wt--wide { grid-column: span 2; }
.wt-img {
  width: 100%; height: 100%;
  object-fit: cover;
  /* Colour thumbnails at rest; a soft zoom on hover */
  transform: scale(1.02);
  transition: transform 0.8s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.wt:hover .wt-img { transform: scale(1.06); }
.wt::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(8,8,8,0.9) 0%, rgba(8,8,8,0.1) 45%, transparent 70%);
  transition: opacity 0.4s;
}
.wt-meta {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 1;
  padding: 1.1rem 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.wt-no {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: 0.1em;
  color: var(--accent);
}
.wt-cat {
  font-family: var(--font-mono);
  font-size: 0.58rem;
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.wt-title {
  font-size: clamp(1rem, 1.5vw, 1.35rem);
  font-weight: 300;
  line-height: 1.25;
  margin-top: 0.15rem;
}
.wt:hover .wt-cat { color: var(--text-soft); }
/* Index / call-to-action tile */
.wt--index {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.5rem;
  background: var(--bg-3);
  transition: background 0.3s;
}
.wt--index::after { display: none; }
.wt--index:hover { background: var(--accent); }
.wt-index-label {
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  transition: color 0.3s;
}
.wt-index-arrow {
  font-size: 1.4rem;
  transition: transform 0.3s, color 0.3s;
}
.wt--index:hover .wt-index-label,
.wt--index:hover .wt-index-arrow { color: var(--accent-on); }
.wt--index:hover .wt-index-arrow { transform: translateX(6px); }

/* ─── Work gallery (work.html) ───────────────────────────────
   Full-colour tiles in a composed rhythm (hero → row of three →
   wide + full-width close). Job title top-left (bold), client logo
   knocked to white bottom-left. Monochrome — no accent colour, to
   match the rest of the site. A whisper of top/bottom shade holds
   the type; no black slab. */
.work-gallery {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  /* Each tile sets its own height, so small/medium can be taller than the full-width strip */
  grid-auto-rows: auto;
  gap: clamp(10px, 1vw, 16px);
  max-width: 1680px;
  margin: 0 auto;
  padding: 0 clamp(0.75rem, 2vw, 1.5rem) clamp(2.5rem, 5vw, 4rem);
}
.wg {
  position: relative;
  overflow: hidden;
  background: var(--bg-2);
  display: block;
  grid-column: span 2;             /* default tile = one third of the row */
  height: clamp(260px, 28vw, 400px);   /* smallest + medium (wide) — the taller tiles */
}
.wg--hero { grid-column: span 6; height: clamp(440px, 47vw, 676px); }   /* tall showpiece (was 2 rows) */
.wg--wide { grid-column: span 4; }                                      /* medium — inherits the taller height */
.wg--full { grid-column: span 6; height: clamp(215px, 23vw, 330px); }   /* full-width strip stays shorter */
.wg-img {
  width: 100%; height: 100%;
  object-fit: cover;
  /* full colour at rest — the work is the colour; slow zoom on hover */
  transform: scale(1.01);
  transition: transform 0.9s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.wg:hover .wg-img { transform: scale(1.06); }
/* Whisper of protection — a breath top and bottom, not a slab */
.wg::after {
  content: '';
  position: absolute; inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(to bottom,
    rgba(8,8,8,0.36) 0%,
    rgba(8,8,8,0)   26%,
    rgba(8,8,8,0)   66%,
    rgba(8,8,8,0.42) 100%);
}
/* Head: job title, top-left — the client is carried by the logo mark below */
.wg-head {
  position: absolute;
  top: clamp(0.9rem, 1.4vw, 1.4rem);
  left: clamp(0.9rem, 1.4vw, 1.4rem);
  right: clamp(0.9rem, 1.4vw, 1.4rem);
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  text-shadow: 0 1px 14px rgba(0, 0, 0, 0.5);
}
.wg-title {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: clamp(0.82rem, 1vw, 1.05rem);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  line-height: 1.2;
  color: #fff;
}
.wg--hero .wg-title,
.wg--full .wg-title { font-size: clamp(0.98rem, 1.4vw, 1.35rem); }
/* Brand logo — knocked to white, bottom-left, consistent height */
.wg-logo {
  position: absolute;
  left: clamp(0.9rem, 1.4vw, 1.4rem);
  bottom: clamp(0.9rem, 1.4vw, 1.4rem);
  z-index: 2;
  height: clamp(20px, 2vw, 30px);
  width: auto;
  max-width: 42%;
  object-fit: contain;
  object-position: left bottom;
  opacity: 0.95;
  filter: brightness(0) invert(1) drop-shadow(0 1px 8px rgba(0, 0, 0, 0.55));
}
.wg--hero .wg-logo,
.wg--full .wg-logo { height: clamp(28px, 2.6vw, 40px); }
/* Gulf reads as a compact roundel, so nudge it up a touch to sit optically
   level with the wide wordmark logos. */
.wg-logo.is-gulf { height: clamp(30px, 3.2vw, 46px); }
.wg--hero .wg-logo.is-gulf,
.wg--full .wg-logo.is-gulf { height: clamp(40px, 3.8vw, 56px); }

/* Tease variant (homepage) — McLaren half-width and tall on the left; Callum + Entain
   as the two top-right cells; Heritage Fleet a wide tile beneath them. Four-column grid
   so the right half splits cleanly into two. */
.work-gallery--tease {
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: clamp(150px, 16vw, 220px);
}
.work-gallery--tease .wg       { height: auto; grid-column: span 1; }
.work-gallery--tease .wg--hero { grid-column: span 2; grid-row: span 2; }
.work-gallery--tease .wg--wide { grid-column: span 2; grid-row: span 1; }

/* ─── CTA Links ───────────────────────────────────────────── */
.cta-link {
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-soft);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  transition: color 0.2s, gap 0.2s;
}
.cta-link:hover { color: var(--text); gap: 0.85rem; }

/* ─── CTA Banner ──────────────────────────────────────────── */
.cta-banner {
  /* The one full-accent moment on the page — the scarce orange pays off here */
  padding: var(--band) var(--pad);
  background: var(--accent);
}
.cta-banner-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 3rem;
  flex-wrap: wrap;
}
.cta-banner h2 {
  /* Capped below the manifesto scale — conversion prompt shouldn't outrank the brand statement */
  font-size: clamp(3rem, 7vw, 6.5rem);
  color: #080808;
  line-height: 0.92;
}
.cta-banner-sub {
  margin-top: 1rem;
  font-size: clamp(0.95rem, 1.3vw, 1.1rem);
  line-height: 1.6;
  color: rgba(8, 8, 8, 0.82);
  max-width: 44ch;
}
.cta-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  border: 1px solid var(--accent);
  border-radius: 100px;
  padding: 1em 2.5em;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  flex-shrink: 0;
  transition: background 0.3s, color 0.3s, transform 0.3s;
}
.cta-btn:hover { background: var(--accent); color: #fff; }
/* On the orange banner the button inverts to near-black */
.cta-banner .cta-btn {
  background: #080808;
  border-color: #080808;
  color: var(--text);
}
.cta-banner .cta-btn:hover {
  background: #1e1e1e;
  border-color: #1e1e1e;
  color: #fff;
  transform: translateY(-2px);
}

/* ─── Footer ──────────────────────────────────────────────── */
.footer {
  border-top: 1px solid var(--border);
  padding: 2.5rem var(--pad);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  flex-wrap: wrap;
}
.footer-brand { display: flex; flex-direction: column; align-items: flex-start; gap: 0.9rem; }
.footer-logo {
  height: 24px;
  width: auto;
  object-fit: contain;
  opacity: 0.7;
}
.footer-copy { font-size: 0.68rem; letter-spacing: 0.1em; color: var(--muted); }
.footer-contact { display: flex; flex-direction: column; gap: 0.4rem; }
.footer-address {
  font-style: normal;
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--text-soft);
  margin-bottom: 0.5rem;
}
.footer-contact a {
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  color: var(--text-soft);
  transition: color 0.2s;
}
.footer-contact a:hover { color: var(--text); }
.footer-links { display: flex; gap: 2rem; }
.footer-links a {
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  transition: color 0.2s;
}
.footer-links a:hover { color: var(--text); }

/* ─── Page Hero (inner pages) ────────────────────────────── */
.page-hero {
  padding-top: calc(var(--nav-h) + clamp(3rem, 8vw, 6rem));
  padding-bottom: clamp(3rem, 6vw, 5rem);
  padding-left: var(--pad);
  padding-right: var(--pad);
  border-bottom: 1px solid var(--border);
}
/* Work index: the gallery's first tile is a full-bleed image, so its own top
   edge is the seam. The hairline would read as a second one. */
.page-hero--flush { border-bottom: none; }
.page-hero-eyebrow { display: block; margin-bottom: 1rem; }
.page-hero-title { font-size: clamp(3.5rem, 10vw, 10rem); }
/* The hook under a page title is the same voice as a case study's — same size,
   weight, colour and measure as .case-hero-hook, so an inner page hero and a
   case study hero read as one system. Only the gap is larger, because the
   page-hero title runs bigger than a case title. */
.page-hero-sub {
  margin-top: 1.5rem;
  max-width: 44ch;
  color: var(--text-soft);
  font-size: clamp(1rem, 1.6vw, 1.35rem);
  font-weight: 300;
  line-height: 1.5;
}

/* ─── Case Study blocks ───────────────────────────────────────
   A fixed kit assembled per project. Spine (always): hero, brief,
   film, next. Optional (only where content earns it): process,
   build, bts, numbers, award, quote. Same components, two depths. */

/* Shared content wrapper — vertical rhythm + hairline between blocks */
.case-section {
  padding: clamp(3rem, 7vw, 5.5rem) 0;
  border-bottom: 1px solid var(--border);
}
.case-block-label { display: block; margin-bottom: 1.5rem; }

/* ── HERO ── full-bleed key frame, credits pinned bottom-left */
.case-hero {
  position: relative;
  min-height: clamp(520px, 82vh, 840px);
  display: flex;
  align-items: flex-end;
  padding: var(--pad);
  padding-top: calc(var(--nav-h) + clamp(2rem, 6vw, 4rem));
  overflow: hidden;
  border-bottom: 1px solid var(--border);
}
.case-hero-media { position: absolute; inset: 0; }
.case-hero-media img,
.case-hero-media video {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: grayscale(0.25) brightness(0.68);
}
.case-hero::after {
  content: '';
  position: absolute; inset: 0;
  /* Bottom scrim carries the title; a lighter top scrim keeps the nav legible
     over bright cover images */
  background:
    linear-gradient(to bottom, rgba(8,8,8,0.55) 0%, rgba(8,8,8,0) 22%),
    linear-gradient(to top, rgba(8,8,8,0.92) 0%, rgba(8,8,8,0.35) 45%, rgba(8,8,8,0.12) 100%);
}
.case-hero-inner { position: relative; z-index: 1; width: 100%; max-width: var(--max-w); margin: 0 auto; }
.case-hero-tags {
  display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem;
  margin-bottom: 1.25rem;
}
.case-hero-tags span {
  font-family: var(--font-mono);
  font-size: 0.62rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--text-soft);
}
.case-hero-title { font-size: clamp(2.8rem, 8vw, 7rem); }
.case-hero-hook {
  margin-top: 1.25rem; max-width: 44ch;
  font-size: clamp(1rem, 1.6vw, 1.35rem);
  font-weight: 300; line-height: 1.5; color: var(--text-soft);
}
/* Photo credit — sits in the hero's bottom-right corner, clear of the title
   and hook, in the same micro-type as the tags. Drops into the flow under the
   hook on narrow screens, where the hook fills the width. */
/* Photo credit — pinned to the image's bottom-right corner, inside the hero's
   own padding rather than the centred content column, so it sits on the frame
   edge on wide screens too. Type comes from .case-film-caption below, so the
   hero credit and the gallery credit stay identical. */
.case-hero-credit {
  position: absolute;
  right: var(--pad); bottom: var(--pad);
  z-index: 2;
}
.case-hero-credit a,
.case-film-caption a {
  color: var(--text-soft);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.3em;
  transition: color 0.25s;
}
.case-hero-credit a:hover,
.case-film-caption a:hover { color: var(--text); }
/* On narrow screens the hook runs the full width, so lift the content clear of
   the corner credit instead of letting them overlap. */
@media (max-width: 720px) {
  .case-hero--credited .case-hero-inner { padding-bottom: 2.25rem; }
}
/* MoCo hero is a wide landscape rig shot — give the frame extra height so it
   breathes and crops less top-and-bottom than the shared case-hero default.
   Centre the content vertically so the title + hook sit in the dead grey space
   to the left of the robot instead of on the floor of the frame. */
.case-hero--moco { min-height: clamp(640px, 92vh, 1040px); align-items: center; }
/* Title sized to stay in the grey space and clear the arm. */
.case-hero--moco .case-hero-title { font-size: clamp(2.6rem, 6.4vw, 6rem); }
/* Show this rig shot at full brightness — drop the shared mono/darkening filter
   and the scrim gradient so the picture is completely clean. Nudge the crop so
   the rig sits slightly further right, opening up the grey space for the copy. */
.case-hero--moco .case-hero-media img { filter: none; object-position: 42% center; }
/* The tall mobile crop over-reacts to the horizontal nudge above, so re-centre
   on the rig for narrow screens. */
@media (max-width: 960px) {
  .case-hero--moco .case-hero-media img { object-position: 66% center; }
}
.case-hero--moco::after { display: none; }

/* ── MoCo hero stat-strip ── the rig's headline numbers as a quiet technical
   readout pinned to the foot of the hero; stands in for the removed Key Specs
   table without a boxy plate. Carries its OWN bottom gradient so it stays
   legible over the bright rig shot while the rest of the image stays clean. */
.hero-stats {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 2;
  padding: clamp(2.5rem, 7vw, 4.5rem) var(--pad) clamp(1.1rem, 2.4vw, 1.7rem);
  background: linear-gradient(to top,
    rgba(8, 8, 8, 0.9) 0%, rgba(8, 8, 8, 0.55) 55%, rgba(8, 8, 8, 0) 100%);
  pointer-events: none;
}
.hero-stats-inner {
  width: 100%; max-width: var(--max-w); margin: 0 auto;
  display: flex; align-items: stretch;
}
.hero-stats-inner > li {
  flex: 1 1 0;
  padding: 0 clamp(0.75rem, 2vw, 1.5rem);
  border-left: 1px solid rgba(240, 237, 232, 0.16);
  display: flex; flex-direction: column; align-items: center; gap: 0.5rem;
  text-align: center;
}
.hero-stats-inner > li:first-child { border-left: 0; }
.hero-stat-val {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: clamp(1.05rem, 1.7vw, 1.5rem);
  line-height: 1;
  color: var(--text);
}
.hero-stat-unit { font-size: 0.6em; font-weight: 400; color: var(--text-soft); margin-left: 0.12em; }
.hero-stat-key {
  font-family: var(--font-mono);
  font-size: 0.6rem; font-weight: 400;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--text-soft);
  white-space: nowrap;
}
/* Narrow screens — 5 across is too tight; drop to a 3-col grid, dividers off. */
@media (max-width: 720px) {
  .hero-stats { padding-top: clamp(2rem, 8vw, 3rem); }
  .hero-stats-inner {
    display: grid; grid-template-columns: repeat(3, 1fr);
    gap: clamp(1.25rem, 5vw, 1.75rem) 0.75rem; justify-items: center;
  }
  .hero-stats-inner > li { padding: 0; border-left: 0; }
}

/* ── BRIEF + CREDITS ── editorial story on the left, credits ledger alongside */
.case-brief-grid {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: start;
}
.case-brief { max-width: 60ch; }
.case-lede {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.7rem, 4vw, 3rem);
  line-height: 1.08; letter-spacing: -0.015em;
  color: var(--text);
}
.case-brief-body {
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
  max-width: 52ch;
  font-size: clamp(1rem, 1.35vw, 1.15rem);
  line-height: 1.8; color: var(--text-soft); font-weight: 300;
}
.case-brief-body + .case-brief-body { margin-top: 1.25rem; }
.case-meta { display: grid; grid-template-columns: 1fr; gap: 0; }
.case-meta > div {
  display: flex; justify-content: space-between; gap: 1.5rem;
  padding: 0.85rem 0;
  border-top: 1px solid var(--border);
}
.case-meta > div:last-child { border-bottom: 1px solid var(--border); }
.case-meta dt {
  font-family: var(--font-mono);
  font-size: 0.62rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted);
}
.case-meta dd { font-size: 0.92rem; color: var(--text); text-align: right; }
.case-meta dd .sub { color: var(--muted); }
/* Brand/agency shown as real marks — mono knock-out, matching the trusted strip */
.case-meta dd img { height: 26px; width: auto; filter: brightness(0) invert(1); opacity: 0.9; display: inline-block; vertical-align: middle; }
.case-meta dd img.is-small { height: 19px; opacity: 0.72; }
.case-meta dd img.is-callum { height: 30px; }   /* horizontal C + wordmark lockup */
.case-meta dd img.is-gulf { height: 38px; }   /* compact roundel — size up to match wordmarks */

/* ── FILM ── landscape player, or a row of vertical social edits */
.case-film-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--bg-2);
  overflow: hidden;
}
.case-film-frame img,
.case-film-frame video,
.case-film-frame iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; border: 0;
}
.case-film-caption,
.case-hero-credit {
  font-family: var(--font-mono);
  font-size: 0.62rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted);
}
.case-film-caption { margin-top: 1rem; }
.case-film--social {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 3px;
}
.case-film--social .case-film-frame { aspect-ratio: 9 / 16; }
/* Once revealed, drop the leftover identity transform (translateY(0)). A non-
   `none` transform makes this grid the containing block for its children's
   position:fixed, which traps Plyr's fallback fullscreen inside the tile. */
.case-film--social.reveal.visible { transform: none; }

/* Social cut poster that opens its clip in the shared lightbox modal (McLaren).
   Button reset + a persistent accent play disc; click wired in main.js. */
.case-film-tile {
  display: block; width: 100%; padding: 0; border: 0;
  cursor: pointer; color: inherit; text-align: left;
}
.case-film-tile img { transition: transform 0.8s cubic-bezier(0.2, 0.8, 0.2, 1); }
.case-film-tile::after {
  content: '';
  position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to top, rgba(8,8,8,0.5) 0%, rgba(8,8,8,0) 48%);
  transition: background 0.4s ease;
}
.case-film-tile:hover img,
.case-film-tile:focus-visible img { transform: scale(1.05); }
.case-film-tile:hover::after,
.case-film-tile:focus-visible::after { background: linear-gradient(to top, rgba(8,8,8,0.62) 0%, rgba(8,8,8,0.12) 62%); }
.case-film-play {
  position: absolute; z-index: 2; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 3.4rem; height: 3.4rem; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--accent); color: var(--accent-on);
  font-size: 0.9rem; padding-left: 0.12em;
  transition: transform 0.35s ease, background 0.35s ease;
}
.case-film-tile:hover .case-film-play,
.case-film-tile:focus-visible .case-film-play {
  transform: translate(-50%, -50%) scale(1.08);
  background: var(--accent-deep);
}

/* ── PROCESS / BUILD ── copy beside supporting media, alternating */
.case-media-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
.case-media-row.is-flipped .case-media-row-media { order: -1; }
.case-media-row-copy p {
  color: var(--text-soft); line-height: 1.8; font-size: 0.98rem;
  /* Wider than a tight reading measure so the body fills the copy column and
     reads as one block with the heading; still capped to protect the stacked
     (<820px) layout from over-long lines. */
  max-width: 60ch;
}
.case-media-row-copy p + p { margin-top: 1rem; }
.case-media-row-copy h3 {
  font-family: var(--font-display); font-weight: 800; text-transform: uppercase;
  font-size: clamp(1.5rem, 3vw, 2.4rem); line-height: 1; letter-spacing: -0.01em;
  margin-bottom: 1.25rem;
}
.case-media-row-media {
  aspect-ratio: 4 / 3; overflow: hidden; background: var(--bg-2);
}
.case-media-row-media img { width: 100%; height: 100%; object-fit: cover; }
.case-media-row-copy .label { display: block; margin-bottom: 0.9rem; }

/* Kascada light-page: the CG wireframe sits mono so the film stays the only colour
   on the page; hover blooms Cinema 4D's per-part display colours — scrutiny rewards,
   and the build proves itself. Same bloom logic as the BTS grid. */
.case-media-row-media--wire { aspect-ratio: 16 / 11; }
.case-wire {
  filter: grayscale(1) contrast(1.06) brightness(0.9);
  transform: scale(1.01);
  transition: filter 0.6s ease, transform 0.9s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.case-media-row-media--wire:hover .case-wire {
  filter: grayscale(0) contrast(1) brightness(1);
  transform: scale(1.05);
}

/* ── BTS ── stills grid, monochrome, bloom to colour on hover */
.case-bts-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 3px;
}
.case-bts-grid a, .case-bts-grid figure { position: relative; overflow: hidden; aspect-ratio: 3 / 2; background: var(--bg-2); }
.case-bts-grid img {
  width: 100%; height: 100%; object-fit: cover;
  /* Colour thumbnails at rest; a soft zoom on hover */
  transform: scale(1.02);
  transition: transform 0.8s cubic-bezier(0.2,0.8,0.2,1);
}
.case-bts-grid figure:hover img,
.case-bts-grid a:hover img { transform: scale(1.06); }

/* eVITA behind-the-scenes: colour thumbnails in a wider gallery grid; click a
   frame to enlarge (full colour) in the lightbox, then page through with the
   prev/next arrows. */
.case-bts-grid--evita { grid-template-columns: repeat(4, 1fr); }
.case-bts-grid[data-lightbox] figure { cursor: zoom-in; }

/* ── METRICS ── campaign results as an inverted white band (same paper tone as
   the manifesto) so the numbers break the dark scroll. Counts animate up on
   view — a scoreboard of the results that mattered. */
.case-metrics {
  background: #F0EDE8;
  color: #080808;
  padding: clamp(3.5rem, 8vw, 6.5rem) 0;
}
.case-metrics-label {
  display: block;
  color: rgba(8, 8, 8, 0.5);
  margin-bottom: clamp(2rem, 4vw, 3rem);
}
.case-metrics-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
}
.case-metric {
  padding-top: 1.5rem;
  border-top: 1px solid rgba(8, 8, 8, 0.16);
}
.case-metric-num {
  display: block;
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(3rem, 7vw, 6rem); line-height: 0.9; letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: #080808;
}
.case-metric-title {
  margin-top: 1rem;
  font-family: var(--font-mono); font-weight: 700;
  font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: #080808;
}
.case-metric-note {
  margin-top: 0.6rem;
  max-width: 26ch;
  font-size: clamp(0.95rem, 1.3vw, 1.08rem); line-height: 1.5;
  font-weight: 300; color: rgba(8, 8, 8, 0.62);
}

/* ── QUOTE ── client testimonial, large and quiet */
.case-quote blockquote {
  font-size: clamp(1.4rem, 3.2vw, 2.6rem);
  font-weight: 300; line-height: 1.3; letter-spacing: -0.01em;
  max-width: 24ch;
}
.case-quote cite {
  display: block; margin-top: 1.5rem; font-style: normal;
  font-family: var(--font-mono);
  font-size: 0.66rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted);
}

/* ── NEXT ── ends every case study identically, keeps them moving */
.case-next {
  display: flex; align-items: center; justify-content: space-between; gap: 2rem;
  padding: clamp(2.5rem, 6vw, 4.5rem) var(--pad);
  border-bottom: 1px solid var(--border);
  transition: background 0.35s;
}
.case-next:hover { background: var(--bg-2); }
.case-next-label { display: block; margin-bottom: 0.6rem; }
.case-next-title {
  font-family: var(--font-display); font-weight: 800; text-transform: uppercase;
  font-size: clamp(2rem, 6vw, 4.5rem); line-height: 0.95; letter-spacing: -0.01em;
  transition: transform 0.35s cubic-bezier(0.2,0.8,0.2,1);
}
.case-next:hover .case-next-title { transform: translateX(clamp(0.5rem, 2vw, 1.5rem)); }
.case-next-arrow { font-size: clamp(1.5rem, 4vw, 3rem); color: var(--muted); flex-shrink: 0; }

@media (max-width: 820px) {
  .case-brief-grid,
  .case-media-row { grid-template-columns: 1fr; }
  .case-brief-grid { gap: clamp(2rem, 6vw, 3rem); }
  .case-media-row.is-flipped .case-media-row-media { order: 0; }
  .case-bts-grid { grid-template-columns: repeat(2, 1fr); }
  .case-bts-grid--evita { grid-template-columns: repeat(3, 1fr); }
  .case-next { flex-direction: row; align-items: center; }
}
@media (max-width: 520px) {
  .case-bts-grid--evita { grid-template-columns: repeat(2, 1fr); }
}

/* ─── MoCo Page ───────────────────────────────────────────── */
.moco-intro {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(3rem, 6vw, 6rem);
  align-items: start;
}
.moco-intro h2 { font-family: var(--font-display); font-size: clamp(2rem, 4vw, 3rem); font-weight: 800; text-transform: uppercase; letter-spacing: -0.005em; line-height: 1.0; }
.moco-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2rem;
  margin-top: 3rem;
}
.stat-num {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 5vw, 4rem);
  line-height: 1;
  margin-bottom: 0.25rem;
}
.stat-label { font-size: 0.72rem; letter-spacing: 0.15em; text-transform: uppercase; color: var(--muted); }
.media-placeholder {
  width: 100%; aspect-ratio: 16/9;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: 4px;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.7rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--muted);
}
.media-placeholder.tall { aspect-ratio: 4/5; }
/* ─── Studio section (moco) ────────────────────────────────────
   The cove photo runs as a section hero with the title overlaid, then the copy
   sits left and the spec ledger right beneath it. Reuses the on-image caption
   idiom (scrim + display title) from the case heroes, but contained + rounded
   to match the film frame and feature stage rather than a full-bleed page hero. */
.studio-hero {
  position: relative;
  /* Full-bleed like the page hero: a min-height band with object-fit: cover
     rather than a contained, rounded 16/9 frame. */
  min-height: clamp(460px, 68vh, 780px);
  overflow: hidden;
  background: var(--bg-3);
}
.studio-hero img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
}
/* Scrim tuned to this frame: the cove floor at bottom-left is bright, so darken
   the bottom and the left so the eyebrow + title stay legible while the lit
   panels and drapes keep their contrast. */
.studio-hero::after {
  content: '';
  position: absolute; inset: 0;
  background:
    linear-gradient(to top, rgba(8,8,8,0.88) 0%, rgba(8,8,8,0.28) 42%, rgba(8,8,8,0) 68%),
    linear-gradient(to right, rgba(8,8,8,0.62) 0%, rgba(8,8,8,0) 50%);
}
/* Caption inset to the padded, max-width content column so the title lines up
   with the page hero and the section body rather than the raw viewport edge. */
.studio-hero-cap {
  position: absolute; z-index: 1;
  left: 0; right: 0;
  bottom: clamp(1.75rem, 4vw, 3.25rem);
  padding: 0 var(--pad);
}
.studio-hero-cap-inner { width: 100%; max-width: var(--max-w); margin: 0 auto; }
.studio-hero-cap .label { display: block; margin-bottom: 0.9rem; }
.studio-hero-cap h2 { font-size: clamp(2rem, 5vw, 4rem); color: var(--text); }

/* Copy left, spec ledger right, beneath the hero. */
.studio-detail {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(3rem, 6vw, 6rem);
  align-items: start;
  margin-top: clamp(2.5rem, 5vw, 4rem);
}
.studio-detail-copy p {
  color: var(--text-soft); line-height: 1.8;
  font-size: clamp(0.95rem, 1.3vw, 1.08rem); max-width: 48ch;
}
.studio-detail-copy p + p { margin-top: 1.25rem; }
.studio-detail-specs .label { display: block; margin-bottom: 1.5rem; }

@media (max-width: 860px) {
  .studio-hero { min-height: clamp(420px, 62vh, 560px); }
  .studio-detail { grid-template-columns: 1fr; gap: clamp(2.5rem, 6vw, 3.5rem); }
}
.spec-list { border-top: 1px solid var(--border); }
.spec-item {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 1.1rem 0; border-bottom: 1px solid var(--border); font-size: 0.9rem;
}
.spec-item-key { color: var(--muted); font-size: 0.75rem; letter-spacing: 0.1em; text-transform: uppercase; }

/* ─── Robot feature explorer (moco) ────────────────────────────
   Roll over (or tab/tap) a feature to crossfade its still into the shared
   stage and swap the explainer. Two stacked layers avoid a flash; until a
   real still is dropped on a button (data-feat-img), the stage falls back to
   a labelled placeholder. Driven by js/main.js. */
.feat-explorer {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(260px, 33%, 400px);
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: start;
}
/* Stage is now the hero: a large cinematic still that dominates the section,
   with the feature name/benefit riding the image (the Work-grid idiom). The
   list shrinks to a slim rail on the right. */
.feat-stage { position: sticky; top: calc(var(--nav-h) + 2rem); }
.feat-stage-media {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--bg-3);
}
/* Two stacked layers so a picked feature crossfades in without a flash */
.feat-stage-img {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 0;
  transition: opacity 0.6s ease;
}
.feat-stage-img.is-active { opacity: 1; }
/* Faint hint on features whose real still hasn't been shot yet */
.feat-stage-ph {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  pointer-events: none;
  transition: opacity 0.4s ease;
}
.feat-stage.has-img .feat-stage-ph { opacity: 0; }
/* Caption rides the image, bottom-left over a scrim */
.feat-stage-cap {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 1;
  padding: clamp(1.25rem, 3vw, 2rem);
  background: linear-gradient(to top, rgba(8,8,8,0.85) 0%, rgba(8,8,8,0.4) 45%, rgba(8,8,8,0) 100%);
  pointer-events: none;
}
.feat-stage-name {
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  line-height: 1;
  font-size: clamp(1.4rem, 2.6vw, 2.1rem);
}
.feat-stage-tag {
  display: block;
  margin-top: 0.6rem;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-soft);
}
.feat-stage-desc {
  margin-top: 1.1rem;
  max-width: 52ch;
  color: var(--text-soft);
  line-height: 1.7;
  font-size: clamp(0.9rem, 1.2vw, 1rem);
}

/* The list — each row is a <button> so hover, keyboard and touch all activate.
   Active/hover row lights up: a rule wipes in from the left, the row indents,
   its copy comes to full ink (mirrors .svc-list, tuned for the dark page). */
.feat-list { display: flex; flex-direction: column; border-top: 1px solid var(--border); }
.feat-item {
  position: relative;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  width: 100%;
  text-align: left;
  padding: 1.15rem 0;
  border-bottom: 1px solid var(--border);
  transition: padding-left 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.feat-item::before {
  content: "";
  position: absolute;
  left: 0; top: -1px; bottom: -1px;
  width: 2px;
  background: var(--accent);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.feat-item.is-active { padding-left: 1.1rem; }
.feat-item.is-active::before { transform: scaleY(1); }
.feat-name {
  font-size: clamp(1rem, 1.6vw, 1.25rem);
  font-weight: 300;
  line-height: 1.2;
  color: var(--text-soft);
  transition: color 0.4s ease;
}
.feat-item.is-active .feat-name { color: var(--text); }
.feat-val {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--muted);
  transition: color 0.4s ease;
}
.feat-item.is-active .feat-val { color: var(--accent); }
/* Mouse hover mirrors the active state without stealing it from touch/keyboard */
@media (hover: hover) {
  .feat-item:hover { padding-left: 1.1rem; }
  .feat-item:hover::before { transform: scaleY(1); }
  .feat-item:hover .feat-name { color: var(--text); }
  .feat-item:hover .feat-val { color: var(--accent); }
}

/* ─── Moves showreel (moco) — one big cinematic frame + a thumbnail rail you
   click to promote. Placeholder tiles until the process clips are shot; swap
   #movesMedia (and a thumb's poster) for a Plyr holder when a move lands.
   Thumbs sit mono at rest and bloom to colour when active (the BTS-grid move):
   the page's one flicker of warmth, on the frame that comes alive. ── */
.moves-reel { display: flex; flex-direction: column; gap: 3px; }
.moves-stage {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--bg-2);
  border: 1px solid var(--border);
}
.moves-stage-media { position: absolute; inset: 0; }
.moves-stage-media img,
.moves-stage-media iframe,
.moves-stage-media video { width: 100%; height: 100%; object-fit: cover; border: 0; }
.moves-stage-ph {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1rem;
  color: var(--muted);
}
.moves-stage-ph span {
  font-family: var(--font-mono);
  font-size: 0.62rem; letter-spacing: 0.2em; text-transform: uppercase;
}
.moves-stage-cap {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 1;
  padding: clamp(1.25rem, 3vw, 2.25rem);
  background: linear-gradient(to top, rgba(8,8,8,0.85) 0%, rgba(8,8,8,0) 100%);
  font-family: var(--font-mono);
  font-size: clamp(0.7rem, 1vw, 0.8rem);
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text);
  pointer-events: none;
}
.moves-thumbs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 3px; }
.moves-thumb {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--bg-3);
  border: 0;
  cursor: pointer;
  filter: grayscale(1);
  transition: filter 0.5s ease;
}
.moves-thumb img { width: 100%; height: 100%; object-fit: cover; }
.moves-thumb-label {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 0.75rem; text-align: center;
  font-family: var(--font-mono);
  font-size: 0.58rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted);
  transition: color 0.4s ease;
}
.moves-thumb::after {
  content: ""; position: absolute; inset: 0;
  box-shadow: inset 0 0 0 0 var(--accent);
  transition: box-shadow 0.4s ease;
  pointer-events: none;
}
.moves-thumb.is-active { filter: grayscale(0); }
.moves-thumb.is-active .moves-thumb-label { color: var(--text); }
.moves-thumb.is-active::after { box-shadow: inset 0 0 0 2px var(--accent); }
@media (hover: hover) { .moves-thumb:hover { filter: grayscale(0); } }

/* Moves runs as a paper band (the case-metrics inversion) so the showreel breaks
   the dark scroll; the dark video frames read like stills on a magazine page. */
.moves-band { background: #F0EDE8; color: #080808; }
.moves-band .label { color: rgba(8, 8, 8, 0.55); }

/* Features runs as a paper band, same inversion as .moves-band above. Rather than
   restate every colour, the band re-points the tokens its children already use,
   so .feat-name / .feat-val / borders / the active rule all flip on their own.
   Custom properties inherit, so this also catches the intro paragraph's inline
   color:var(--text-soft) — no !important needed. */
.feat-band {
  background: #F0EDE8;
  color: #080808;
  --text:      #080808;
  --text-soft: rgba(8, 8, 8, 0.62);
  --muted:     rgba(8, 8, 8, 0.42);
  --border:    rgba(8, 8, 8, 0.12);
  --accent:    #080808;   /* the active row's rule + value, was white on dark */
  --bg-3:      #E4DFD8;   /* stage placeholder before a still loads */
}
.feat-band .label { color: rgba(8, 8, 8, 0.55); }
/* The stage caption rides the photo over a dark scrim, so it stays light while
   the rest of the band goes to ink. */
.feat-band .feat-stage-name { color: #F0EDE8; }
.feat-band .feat-stage-tag  { color: rgba(240, 237, 232, 0.72); }

/* ─── About ───────────────────────────────────────────────── */
/* About runs on the case-study spine — full-bleed hero, then copy beside frames —
   because the claim the page has to make is that the company is as legible as the
   work. Two blocks of the same component, mirrored: a copy column carrying one or
   two movements, and a single frame. */
.about-block {
  display: grid;
  grid-template-columns: 0.95fr 1.05fr;
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: stretch;
}
/* .is-flipped only reorders, so the wide column has to move with the frame or it
   lands in the narrow slot. */
.about-block.is-flipped { grid-template-columns: 1.05fr 0.95fr; }
.about-block.is-flipped .about-block-media { order: -1; }

/* Copy is centred against the frame, not top-aligned: the blocks no longer carry
   equal amounts of prose (the intro is two beats, the roof block is four), and a
   short column hung from the top left a dead gap under it beside a full 4:5. */
.about-block-copy { align-self: center; }
.about-block-copy .case-brief-body { max-width: 54ch; }
.about-block-copy > .label { display: block; margin-bottom: 0.9rem; }
.about-block-copy h3 {
  font-family: var(--font-display); font-weight: 800; text-transform: uppercase;
  font-size: clamp(1.5rem, 3vw, 2.4rem); line-height: 1; letter-spacing: -0.01em;
  margin-bottom: 1.25rem;
}
.about-block-copy p { color: var(--text-soft); font-size: 1.05rem; line-height: 1.8; max-width: 54ch; }
.about-block-copy p + p { margin-top: 1rem; }
/* .case-lede is display type and sets its own colour — keep it off the body rule */
.about-block-copy .case-lede { color: var(--text); font-size: clamp(1.7rem, 4vw, 3rem); line-height: 1.08; }

/* The turn: where a column changes subject. A hairline marks it the way .case-meta
   rules its rows, so two movements can share one column without running together.
   Currently unused — About's roof block combined its two movements into one, and
   nothing else has needed a turn since. Kept: the next long column will. */
.about-turn {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: clamp(2.5rem, 5vw, 3.5rem);
  border-top: 1px solid var(--border);
}
.about-turn .label { display: block; margin-bottom: 0.9rem; }

/* Default frame: 4:5, centred against the copy. NOT stretched — craft.jpg is a 3:2
   landscape, so the 4:5 already keeps only 53% of its width; the object-position
   holds the subject and the near edge of the softbox inside that slice. */
.about-block-media { align-self: center; aspect-ratio: 4 / 5; overflow: hidden; }
/* .is-wide opts one frame out of the 4:5 and shows its whole 3:2 instead. Used
   where the crop would cost the picture its subject: set.jpg has four people
   spread across the full width, and 4:5 keeps 53% of it and loses two of them. */
.about-block-media.is-wide { aspect-ratio: 3 / 2; }
.about-block-media img { width: 100%; height: 100%; display: block; object-fit: cover; }

/* Both frames share the 4:5. Filling the column height was tried once, on the old
   2:3 rig portrait, and dropped: the column is shorter than the frame is tall, so
   it cropped to near-square and lost 29% of itself. The rule outlived that image —
   keep the 4:5 and move the crop, don't stretch the frame. */

/* ─── About: the full-bleed overlay block ──────────────────────
   One block on the page runs edge to edge with its copy inside the frame instead
   of beside it. Not a variant of .about-block: that one is a two-column grid, this
   is a band with an absolutely positioned image behind a scrim. */
.about-overlay {
  position: relative;
  min-height: clamp(560px, 82vh, 900px);
  display: flex; align-items: center;
  overflow: hidden;
  background: var(--bg-3);
  border-bottom: 1px solid var(--border);
}
.about-overlay img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  /* Full width shows, so only the vertical matters: 40% holds the camera at the
     top and the red car at the bottom without cropping either. */
  object-position: center 40%;
}
/* Scrim weighted RIGHT, opposite to .studio-hero. The operator and the camera own
   the left of this frame and the right half is crew, cable and kit — the busier,
   more forgiving half — so the type goes there and the darkening goes with it. */
.about-overlay::after {
  content: '';
  position: absolute; inset: 0;
  background:
    linear-gradient(to left, rgba(8,8,8,0.94) 0%, rgba(8,8,8,0.88) 30%, rgba(8,8,8,0.35) 58%, rgba(8,8,8,0) 76%),
    linear-gradient(to top, rgba(8,8,8,0.45) 0%, rgba(8,8,8,0) 55%);
}
.about-overlay-inner {
  position: relative; z-index: 1;
  width: 100%; max-width: var(--max-w);
  margin: 0 auto;
  padding: clamp(3rem, 7vw, 5.5rem) var(--pad);
  display: flex; justify-content: flex-end;
}
.about-overlay-copy { max-width: 44ch; }
.about-overlay-copy .label { display: block; margin-bottom: 0.9rem; }
.about-overlay-copy h3 {
  font-family: var(--font-display); font-weight: 800; text-transform: uppercase;
  font-size: clamp(1.5rem, 3vw, 2.4rem); line-height: 1; letter-spacing: -0.01em;
  margin-bottom: 1.25rem;
}
/* Brighter than --text-soft (0.62): that alpha is tuned for a flat panel, and the
   ground here is a photograph the scrim only mostly flattens. */
.about-overlay-copy p {
  color: rgba(240, 237, 232, 0.84);
  font-size: 1.05rem; line-height: 1.8;
}
.about-overlay-copy p + p { margin-top: 1rem; }

@media (max-width: 820px) {
  /* No room to hold type to one side of a phone-width frame, so the scrim goes
     flat across the whole band and the copy runs full width inside it. */
  .about-overlay { min-height: 0; }
  .about-overlay::after {
    background:
      linear-gradient(to top, rgba(8,8,8,0.94) 0%, rgba(8,8,8,0.86) 45%, rgba(8,8,8,0.78) 100%);
  }
  .about-overlay-inner { justify-content: stretch; padding-top: clamp(4rem, 14vw, 6rem); padding-bottom: clamp(4rem, 14vw, 6rem); }
  .about-overlay-copy { max-width: none; }
}

@media (max-width: 820px) {
  .about-block,
  .about-block.is-flipped { grid-template-columns: 1fr; }
  /* Copy leads on a phone in both blocks, so the frame always answers its text */
  .about-block.is-flipped .about-block-media { order: 0; }
}

/* ─── Contact ─────────────────────────────────────────────── */
.contact-grid {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(3rem, 8vw, 8rem);
}
.contact-form { display: flex; flex-direction: column; gap: 1.5rem; }
.form-group { display: flex; flex-direction: column; gap: 0.5rem; }
.form-group label { font-size: 0.68rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--muted); }
.form-group input,
.form-group textarea,
.form-group select {
  background: var(--bg-2); border: 1px solid var(--border);
  border-radius: 4px; padding: 0.85rem 1rem;
  color: var(--text); font-family: var(--font-body);
  font-size: 0.9rem; font-weight: 300;
  transition: border-color 0.2s; outline: none; -webkit-appearance: none;
}
.form-group input:focus,
.form-group textarea:focus,
.form-group select:focus { border-color: rgba(240,237,232,0.3); }
.form-group textarea { resize: vertical; min-height: 140px; }
.form-group select option { background: var(--bg-2); }
.submit-btn {
  align-self: flex-start;
  border: 1px solid var(--border); border-radius: 100px;
  padding: 0.9em 2.5em; font-size: 0.75rem; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--muted); transition: border-color 0.25s, color 0.25s;
}
.submit-btn:hover { border-color: var(--text); color: var(--text); }
.contact-info { display: flex; flex-direction: column; gap: 2.5rem; padding-top: 0.5rem; }
.contact-block h3 { font-size: 0.68rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--muted); margin-bottom: 0.75rem; }
.contact-block p, .contact-block a { font-size: 1rem; font-weight: 300; line-height: 1.75; }
.contact-block a { border-bottom: 1px solid var(--border); padding-bottom: 1px; transition: border-color 0.2s; }
.contact-block a:hover { border-color: var(--text); }

/* ─── Reveal animations ───────────────────────────────────── */
.reveal {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 0.8s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.8s cubic-bezier(0.16, 1, 0.3, 1);
}
.reveal.visible { opacity: 1; transform: translateY(0); }
.reveal-delay-1 { transition-delay: 0.1s; }
.reveal-delay-2 { transition-delay: 0.22s; }
.reveal-delay-3 { transition-delay: 0.36s; }

/* ─── Reduced motion ─────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .reveal, .reveal-lines .line { opacity: 1; transform: none; }
  .parallax-img { transform: scale(1.08); }
}

/* ─── Responsive ──────────────────────────────────────────── */
@media (max-width: 960px) {
  .cap-grid { grid-template-columns: 1fr; gap: 2.5rem; }
  .cap-intro { position: static; }
  .svc-layout { grid-template-columns: 1fr; gap: 2rem; }
  .offer-media { max-width: 100%; height: auto; min-height: 0; aspect-ratio: 3 / 2; }
  .moco-feature { grid-template-columns: 1fr; min-height: 0; }
  /* Stacked: keep the frame, but drop the bottom margin so the picture's
     spacing to the text below comes from .moco-text's own padding. */
  .moco-media { height: clamp(280px, 55vw, 480px); margin-bottom: 0; }
  .edit-block-a { grid-template-columns: 1fr; }
  .edit-img-tall { height: clamp(400px, 60vw, 560px); }
  .edit-col-right { padding-top: 0; }
  .edit-block-c { grid-template-columns: 1fr; }
  .edit-img-portrait { height: clamp(320px, 50vw, 480px); }
  .work-grid { grid-template-columns: repeat(2, 1fr); }
  .work-index { grid-template-columns: repeat(2, 1fr); grid-auto-rows: clamp(150px, 34vw, 220px); }
  .work-index .wt--big { grid-column: span 2; grid-row: span 1; }
  .work-gallery { grid-template-columns: repeat(2, 1fr); grid-auto-rows: clamp(200px, 34vw, 270px); }
  .work-gallery .wg { grid-column: span 1; height: auto; }
  .work-gallery .wg--hero { grid-column: span 2; grid-row: span 1; }
  .work-gallery .wg--wide,
  .work-gallery .wg--full { grid-column: span 2; }
  .moco-intro { grid-template-columns: 1fr; }
  /* Feature explorer stacks: preview on top, list below. Preview stays static
     so it never eats the viewport; tapping a row scrolls it into view (main.js). */
  .feat-explorer { grid-template-columns: 1fr; gap: 1.75rem; }
  .feat-stage { position: static; }
  .feat-stage-media { aspect-ratio: 16 / 10; }
  .contact-grid { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .nav-links { display: none; }
  .nav-toggle { display: flex; }
  /* Copy fills the width on phones, so keep the shot-01 overlay dark across the
     whole band (not just the left) so every line of text stays legible. */
  .offer {
    background:
      linear-gradient(90deg, rgba(8, 8, 8, 0.9) 0%, rgba(8, 8, 8, 0.8) 55%, rgba(8, 8, 8, 0.62) 100%),
      #080808 url('../assets/images/shot-01.jpg') center / cover no-repeat;
  }
  .work-grid { grid-template-columns: 1fr; }
  .work-index { grid-template-columns: 1fr; }
  .work-index .wt--big,
  .work-index .wt--wide { grid-column: span 1; grid-row: span 1; }
  .work-gallery { grid-template-columns: 1fr; grid-auto-rows: clamp(210px, 62vw, 330px); }
  .work-gallery .wg,
  .work-gallery .wg--hero,
  .work-gallery .wg--wide,
  .work-gallery .wg--full { grid-column: span 1; grid-row: span 1; }
  .moves-thumbs { grid-template-columns: repeat(2, 1fr); }
  .cta-banner-inner { flex-direction: column; align-items: flex-start; }
  .footer { flex-direction: column; align-items: flex-start; gap: 1.5rem; }
  .footer-links { flex-wrap: wrap; gap: 1.25rem; }
  .manifesto-text { font-size: clamp(2rem, 8vw, 3rem); }
  .case-metrics-grid { grid-template-columns: 1fr; gap: 0; }
  .case-metric { padding: 1.5rem 0; }
  .case-metric:first-child { padding-top: 0; border-top: none; }
  .case-metric-note { max-width: 40ch; }
  .services-grid { grid-template-columns: 1fr; }
  .moco-stats { grid-template-columns: 1fr 1fr; }
}

/* ─── Motability · The Series ──────────────────────────────────
   The one case study that runs in COLOUR — warmth is the message.
   Nine customers, one 4:5 ratio, click a face to play the moment. */
.mot-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
}
.mot-tile {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--bg-2);
  cursor: pointer;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  text-align: left;
  color: inherit;
}
.mot-tile img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 0.8s cubic-bezier(0.2, 0.8, 0.2, 1);
}
/* legibility scrim behind the name; deepens slightly on hover */
.mot-tile::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(8,8,8,0.72) 0%, rgba(8,8,8,0) 44%);
  transition: background 0.4s ease;
}
.mot-tile:hover img,
.mot-tile:focus-visible img { transform: scale(1.05); }
.mot-tile:hover::after,
.mot-tile:focus-visible::after { background: linear-gradient(to top, rgba(8,8,8,0.82) 0%, rgba(8,8,8,0.18) 62%); }
.mot-tile-meta {
  position: absolute; z-index: 2; left: 0; right: 0; bottom: 0;
  display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem;
  padding: clamp(0.85rem, 2vw, 1.4rem);
}
.mot-tile-name {
  font-family: var(--font-display); font-weight: 800; text-transform: uppercase;
  font-size: clamp(1.05rem, 2vw, 1.5rem); line-height: 1; letter-spacing: -0.01em;
  color: #fff;
}
.mot-tile-play {
  flex-shrink: 0;
  width: 2.4rem; height: 2.4rem; border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.65);
  display: grid; place-items: center;
  color: #fff; font-size: 0.68rem; padding-left: 0.12em;
  opacity: 0; transform: translateY(0.25rem);
  transition: opacity 0.35s ease, transform 0.35s ease, background 0.35s ease;
}
.mot-tile:hover .mot-tile-play,
.mot-tile:focus-visible .mot-tile-play { opacity: 1; transform: translateY(0); }
.mot-tile-play:hover { background: rgba(255,255,255,0.16); }
/* Vicki — portrait pending */
.mot-tile--pending { cursor: default; }
.mot-tile--pending::after { background: none; }
.mot-tile--pending .mot-tile-name { color: var(--muted); }
.mot-tile-pending-note {
  position: absolute; inset: 0; z-index: 1; display: grid; place-items: center;
  font-family: var(--font-mono); font-size: 0.58rem; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--muted); text-align: center; padding: 1rem;
}

/* Lightbox — clip player, click a face to open */
.mot-lightbox {
  position: fixed; inset: 0; z-index: 1000;
  display: none; place-items: center;
  background: rgba(4,4,4,0.92);
  padding: clamp(1rem, 5vw, 3rem);
}
.mot-lightbox.open { display: grid; }
.mot-lightbox-inner { position: relative; width: min(100%, 1080px); }
/* Portrait (9:16) clip — size the frame by viewport height so a vertical player
   fits the screen instead of overflowing the default 1080px-wide landscape frame. */
.mot-lightbox.is-portrait .mot-lightbox-inner { width: min(100%, calc(82vh * 9 / 16)); }
.mot-lightbox-stage { width: 100%; }
/* Raw fallback: self-hosted file with no Plyr, or a non-Vimeo (e.g. Streamable) iframe */
.mot-lightbox-stage > video,
.mot-lightbox-stage > iframe {
  width: 100%; aspect-ratio: 16 / 9; display: block; background: #000; border: 0;
}
.mot-lightbox-stage .plyr { width: 100%; }
/* Still image opened in the lightbox (eVITA behind-the-scenes gallery) */
.mot-lightbox-stage > img {
  display: block; width: 100%; height: auto;
  max-height: 82vh; object-fit: contain; background: #000;
}

/* Plyr — IRIS-branded skin (Plyr loads only on the Motability page).
   Player chrome stays monochrome and reads from the brand tokens. */
.plyr {
  --plyr-color-main: var(--accent);
  --plyr-video-control-color: #fff;
  --plyr-video-control-color-hover: var(--accent-on);
  --plyr-badge-background: var(--accent);
  --plyr-badge-text-color: var(--accent-on);
  --plyr-font-family: var(--font-body);
}
/* Hero film: let the Plyr wrapper fill the 16/9 case-film frame */
.case-film-frame .plyr { position: absolute; inset: 0; height: 100%; }
/* Fullscreen fallback (iOS Safari & any browser without native element
   fullscreen — e.g. Vimeo embeds on touch): Plyr sets .plyr--fullscreen-fallback
   to position:fixed, but `.case-film-frame .plyr` (position:absolute; inset:0)
   out-specifies it and pins the player to the tile. Force it to fill the
   viewport. Pairs with `.case-film--social.reveal.visible { transform:none }`,
   which clears the ancestor transform so this `fixed` resolves to the viewport. */
.case-film-frame .plyr.plyr--fullscreen-fallback {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 2147483000;
}
.case-film-frame .plyr__video-wrapper { height: 100%; }
/* Poster fills the 16:9 frame (crop, don't letterbox) — Plyr defaults to contain */
.case-film-frame .plyr__poster { background-size: cover; }

/* Centre play button — solid white disc with a dark glyph, so the play mark
   reads in BOTH the resting and hover states (default was white-on-white).
   Scoped under .plyr to out-specify plyr.css, which loads after this file. */
.plyr .plyr__control--overlaid {
  background: var(--accent);
  color: var(--accent-on);
  opacity: 1;
}
.plyr .plyr__control--overlaid:hover,
.plyr .plyr__control--overlaid:focus {
  background: var(--accent-deep);   /* subtle off-white shift for hover feedback */
  color: var(--accent-on);
}
/* When the film ends, re-show the poster thumbnail over the final frame */
.plyr.is-ended .plyr__poster { opacity: 1; }
.mot-lightbox-cap {
  margin-top: 0.9rem;
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted);
}
.mot-lightbox-close {
  position: absolute; top: -2.6rem; right: 0;
  background: none; border: 0; color: #fff; cursor: pointer;
  font-size: 1.5rem; line-height: 1;
}

/* Gallery prev/next — branded accent discs (match the Plyr play button). Only
   shown when the lightbox is in gallery/image mode. */
.mot-lightbox-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  display: none; place-items: center;
  width: 3rem; height: 3rem; border-radius: 50%;
  background: var(--accent); color: var(--accent-on);
  border: 0; cursor: pointer; z-index: 2;
  transition: background 0.2s ease, transform 0.2s ease;
}
.mot-lightbox.is-gallery .mot-lightbox-nav { display: grid; }
.mot-lightbox-prev { left: 0.75rem; }
.mot-lightbox-next { right: 0.75rem; }
.mot-lightbox-nav:hover { background: var(--accent-deep); transform: translateY(-50%) scale(1.06); }
.mot-lightbox-nav svg {
  width: 1.4rem; height: 1.4rem;
  fill: none; stroke: currentColor; stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}

@media (max-width: 820px) {
  .mot-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ─── YO! Sushi × KitKat · light-page (COLOUR) ──────────────────
   The second case study to run in COLOUR (after Motability): the whole idea is a
   Japanese spring breaking from monochrome Easter tradition — the warmth IS the
   message, so the hero keeps its colour instead of the case-hero mono drain. */
.case-hero--yo .case-hero-media img { filter: brightness(0.9); }

/* Idea beat — the silent looping paid-social clip (Vimeo) sits beside the copy.
   The media slot drops its fixed 4/3 so the clip keeps Vimeo's own aspect via the
   responsive padding wrapper (4:5 portrait — the paid-social cut); background-mode
   plays it muted, looping and chromeless, capped phone-width like an in-feed clip. */
.case-media-row-media--video { aspect-ratio: auto; overflow: visible; background: transparent; }
/* The looping clip fills its half of the row rather than sitting small inside
   it — grows with the viewport, capped so the 4:5 portrait can't run away with
   the row height. Below 820px the row stacks and width:100% takes over. */
.case-vimeo { position: relative; width: 100%; max-width: clamp(380px, 40vw, 560px); aspect-ratio: 4 / 5; background: var(--bg-2); }
.case-vimeo iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.case-media-row-media--video .case-film-caption { margin-top: 0.9rem; }

/* Client marks in the ledger — the YO! + Nestlé logos are white artwork on a
   transparent ground, so the ledger's default brightness(0) invert(1) knock-out
   applies cleanly (no screen hack). Sized up for presence on the table. */
.case-meta dd img.is-yo { height: 26px; }
.case-meta dd img.is-nestle { height: 22px; }

/* YO idea copy — heading + body sized to the brief section (lede/body) so the two
   text blocks on the page share one scale. */
.case-idea-copy h3 { font-size: clamp(1.7rem, 4vw, 3rem); line-height: 1.08; letter-spacing: -0.015em; }
.case-idea-copy p { font-size: clamp(1rem, 1.35vw, 1.15rem); line-height: 1.8; max-width: 52ch; }

/* ─── Consent banner ──────────────────────────────────────────
   Injected by js/analytics.js (no markup in the pages). Sits bottom-right so it
   never covers the centre of a case-study frame and stays clear of the hero
   SCROLL cue in the opposite corner; goes full-width on mobile. */
.consent-banner {
  position: fixed; z-index: 200;
  right: var(--pad); bottom: var(--pad);
  width: min(360px, calc(100vw - var(--pad) * 2));
  background: rgba(16, 16, 16, 0.92);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 1.4rem 1.5rem 1.25rem;
  opacity: 0; transform: translateY(12px);
  transition: opacity 0.45s ease, transform 0.45s ease;
}
.consent-banner.is-in { opacity: 1; transform: none; }
.consent-copy {
  font-size: 0.85rem; font-weight: 300; line-height: 1.65;
  color: var(--text-soft); margin-bottom: 1.1rem;
}
.consent-actions { display: flex; gap: 0.6rem; }
.consent-btn {
  border: 1px solid var(--border); border-radius: 100px;
  padding: 0.75em 1.9em; font-family: var(--font-body);
  font-size: 0.68rem; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--muted); background: none; cursor: pointer;
  transition: border-color 0.25s, color 0.25s;
}
.consent-btn:hover { border-color: var(--text); color: var(--text); }
.consent-btn:focus-visible { outline: 1px solid var(--text); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  .consent-banner { transition: none; transform: none; }
}

/* ─── Mission reveal (index) — docs/reveal-spec.md, ADR 0001–0004 ─────────────
   Desktop + motion-OK only: the hero showreel goes position:fixed behind the
   page, the .intro band becomes a tall runway whose sticky hold carries a black
   curtain with the headline knocked out (SVG luminance mask), so the live reel
   plays through the letters. Copy + client wall fade in as scroll-driven beats
   (js/main.js). Everywhere else these wrappers are inert and the band renders
   exactly as before. Kept at the END of this file: the beat rules must out-
   cascade `.reveal/.visible` at equal specificity. */

/* Defaults (mobile / reduced-motion / narrow): effect chrome hidden, static band */
.mission-curtain, .mission-lip { display: none; }

@media (min-width: 961px) and (prefers-reduced-motion: no-preference) {

  /* The showreel becomes the fixed stage. z:-1 drops it behind every in-flow
     background (moco bg-2, manifesto white) so normal sections cover it as they
     scroll up — no per-section z management. --stage modifier is index-only. */
  .hero-video--stage { position: fixed; z-index: -1; }
  /* Once the runway has fully scrolled past, JS parks the reel (pause + hide)
     so it can't peek behind any transparent band further down the page */
  .hero-video--stage.is-offstage { visibility: hidden; }

  /* No padding, and drop the static band's hairline — with padding zeroed it
     would otherwise render right at the seam into .moco-feature */
  .intro { padding: 0; border-bottom: none; }

  /* Runway = entry lip + one viewport of curtain, no more. The hold no longer
     pins (ADR-0006): pinning froze the framed tableau on screen for a stretch
     of scroll — a dead "pause". Height auto lets moco follow immediately, so
     the tableau composes and scrolls straight on with the page — continuous. */
  .mission-runway { height: auto; }

  /* Graduated entry (restores the soft fade of ADR-0004 #7, supersedes the hard
     wipe line of ADR-0007): the curtain rises out of the live reel through one
     continuous darken — hero overlay and lip are a single ramp. The hero's
     bottom stop and the lip's top stop share the SAME value (0.72), so the
     handover at the seam is invisible: no opacity step, no line. All stops are
     rgb(8,8,8), landing on the exact --bg the curtain below uses. */
  .hero-video--stage ~ .hero-overlay {
    background: linear-gradient(to bottom,
      rgba(8,8,8,0.45) 0%,
      rgba(8,8,8,0.55) 50%,
      rgba(8,8,8,0.72) 100%
    );
  }
  .mission-lip {
    display: block;
    height: 20vh;
    background: linear-gradient(to bottom,
      rgba(8,8,8,0.72) 0%,
      rgba(8,8,8,0.9) 55%,
      var(--bg) 100%
    );
  }

  /* One viewport tall; scrolls with the page (not pinned) over the fixed reel */
  .mission-hold {
    position: relative;
    height: 100vh;
    overflow: hidden;
  }

  .mission-curtain {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
  }
  /* Knockout type: Cabinet Grotesk at full scale (ADR-0005 — doubled from the
     first pass, 14vw = 2 × 7vw); weight 900 for fat show-through windows.
     The vh cap is where it gives back size. Two lines run ~2.1x the font, and
     the block starts at y=32%, so a 20vh cap put its foot at ~56vh — past the
     copy on every laptop (at 1280x700 the sub copy sat 185px inside the
     letters). 14vh lands the foot near 49vh and leaves the floor to the copy
     and client wall. Height-bound screens only: on tall ones 14vw still wins. */
  .mission-curtain text {
    font-family: var(--font-display);
    font-weight: 900;
    font-size: min(clamp(6.4rem, 14vw, 13rem), 14vh);
    letter-spacing: -0.005em;
  }

  /* Copy + client wall sit below the knockout. Lifted well off the floor
     (18vh) so the trio reads as one centred group rather than bottom-anchored
     with a void beneath the headline — balances the space above the headline */
  .mission-layout {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: center;
    /* 18vh of float is the intent (see above), but on a short stage that much
       floor space is what pushes the copy up into the headline. The ramp pays
       18vh from ~1250px tall and tapers below it, so the trio compresses as a
       group instead of colliding. Same shape for the gaps and copy below. */
    padding-bottom: clamp(3.5rem, calc(30vh - 145px), 18vh);
  }
  /* The SVG paints the headline; the real h2 stays for AT/SEO, visually hidden.
     The label would sit above letters it can't reach — dropped from the tableau. */
  .mission-label { display: none; }
  .mission-headline {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* Inside the hold the IO reveal system stands down — copy and client wall
     ride in with the curtain as one tableau (ADR-0005), no staggered fades */
  .mission-hold .reveal { opacity: 1; transform: none; transition: none; }

  /* Body copy sized up on the black stage to help fill the space under the
     big knockout — larger than the static-band scale, still comfortably read.
     Runs the full width of the client wall below it: .mission stretches to the
     container and the copy drops its column cap, so it spans logo-to-logo. */
  .mission-hold .mission { width: 100%; }
  .mission-hold .mission-text {
    font-size: min(clamp(1.7rem, 2.9vw, 2.7rem), calc(2.2vh + 10px));
    line-height: 1.45;
    max-width: 52ch;
    text-wrap: balance;
  }
  /* Lift the client wall away from the sub copy so the copy sits centred
     between the knockout headline and the logos (equal air above and below) */
  .mission-hold .trusted-block { margin-top: clamp(1.6rem, calc(16vh - 74px), 7.4rem); }
}

