/* ============================================================
   The Reel Firm — Social Video Agency
   Monochrome editorial: warm near-black ink on cream. Colour
   comes from the client reels.
   Type: Helvetica, bold for titles, regular for body (client
   instruction, 2026-08-10). Two weights only, 400 and 700, so
   the page renders the same whether the machine has Helvetica
   Neue (Mac, iOS) or falls back to Arial (Windows, Android).
   No webfont request.
   ============================================================ */

:root {
  --brand-primary: #15120D;
  --brand-accent: #15120D;
  --ink: #15120D;
  --ink-soft: #3A352C;
  --canvas: #F6F3EA;        /* exact match to reel video backgrounds */
  --canvas-2: #ECE6D8;      /* deeper cream for alt sections */
  --canvas-video: #F7F5EE;  /* the RENDERED colour of the projector clips, not their raw pixel value: video colour management paints them ~2 values lighter, which left a visible seam at the frame edge */
  --stone: #8C8475;         /* muted text */
  --line: rgba(21,18,13,0.12);
  --line-strong: rgba(21,18,13,0.24);
  --font-display: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --font-body: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --maxw: 1240px;
  --pad: clamp(1.25rem, 4vw, 3rem);
}

/* ---------- floor (universal) ---------- */
html { color-scheme: light; }
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
/* NOT overflow-x on html/body: on iOS Safari that makes position:fixed behave
   like position:absolute, so the fixed nav scrolls away mid-page and the
   full-screen menu opens at document top (off-screen when you are scrolled
   down), which reads as a dead hamburger. Every overflow source here already
   clips at its own container (the rails, the showreel frame), and the WebKit
   audit confirms zero horizontal overflow on all 12 pages at 375, 390 and 414. */
html { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; scroll-behavior: smooth; }
body { font-family: var(--font-body); font-size: 16px; line-height: 1.55; color: var(--ink); background: var(--canvas); }
img, video, picture { max-width: 100%; display: block; }
.hero__media, .page-hero__media, .cta-strip__media, .about__media, .gallery-grid figure, .service-card__media, .parallax, [data-parallax] { overflow: hidden; }
.parallax img, [data-parallax] img { width: 100%; height: 100%; object-fit: cover; }
h1, h2, h3, h4, h5, h6 { font-family: var(--font-display); margin: 0 0 0.5em; line-height: 1.04; font-weight: 700; letter-spacing: -0.022em; }
h1 { letter-spacing: -0.035em; }
h1, h2, h3, h4 { text-wrap: balance; }
p, li { text-wrap: pretty; }
a { color: inherit; }
input, textarea, select, button { font-family: inherit; font-size: 16px; min-height: 44px; }
button, .btn, a.btn, [role="button"] { min-height: 44px; min-width: 44px; cursor: pointer; }
button:active, .btn:active { transform: scale(0.97); }
[data-count] { font-variant-numeric: tabular-nums; }
@media (scripting: none) { .reveal-up, .reveal-fade, .reveal-stagger > *, .reveal-section { opacity: 1 !important; visibility: visible !important; transform: none !important; } }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } }
.placeholder { display: block; padding: 1.25rem; border: 1px dashed currentColor; border-radius: 12px; opacity: 0.65; text-align: center; }
.bottom-cta, .fixed-cta-bar { padding-bottom: calc(1rem + env(safe-area-inset-bottom)); }

/* ---------- layout primitives ---------- */
.container { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 var(--pad); }
.container--wide { max-width: 1440px; }
.section { padding: clamp(4rem, 9vw, 7.5rem) 0; }
.section--alt { background: var(--canvas-2); }
.section--ink { background: var(--ink); color: var(--canvas); }
.section--ink h1, .section--ink h2, .section--ink h3 { color: var(--canvas); }
.eyebrow { font-family: var(--font-body); font-weight: 700; font-size: 0.78rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--stone); margin: 0 0 1rem; display: inline-flex; align-items: center; gap: 0.6rem; }
.eyebrow::before { content: ""; width: 1.6rem; height: 1px; background: var(--line-strong); display: inline-block; }

/* The eyebrow's leading rule is a LEFT-hand motif. In a centred block it still
   occupies 1.6rem plus the 0.6rem gap, pushing the label 18px right of centre,
   and on the dark bands the rule itself is invisible (near-black at 24% opacity
   on near-black) so it reads as sloppy alignment rather than a design element.
   Drop it wherever the block is centred. Flagged by Avara 2026-08-27. */
.conv .eyebrow::before,
.thankyou .eyebrow::before,
.notfound .eyebrow::before,
.showreel__head .eyebrow::before { display: none; }
.conv .eyebrow,
.thankyou .eyebrow,
.notfound .eyebrow,
.showreel__head .eyebrow { gap: 0; }

/* Same fault, other half: the eyebrow rule is --line-strong, a near-black at 24%
   opacity. Visible on the cream and alt sections, INVISIBLE on the ink ones, where
   it left the label indented 35px from the heading with nothing on screen to explain
   it. Give it a light rule on dark. Found on the visual pass, 2026-08-27. */
.section--ink .eyebrow::before { background: rgba(246, 243, 234, 0.38); }
.section-head { max-width: 46rem; margin: 0 0 clamp(2rem, 4vw, 3.25rem); }
.section-head h2 { font-size: clamp(2rem, 4.6vw, 3.4rem); }
.section-head p { font-size: clamp(1.05rem, 1.8vw, 1.2rem); color: var(--ink-soft); margin: 0.75rem 0 0; max-width: 40rem; }
.lede { font-size: clamp(1.1rem, 2vw, 1.35rem); color: var(--ink-soft); line-height: 1.5; }

/* ---------- buttons ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; padding: 0.95rem 1.6rem; border-radius: 999px; font-family: var(--font-body); font-weight: 700; font-size: 1rem; text-decoration: none; border: 1.5px solid transparent; transition: background .25s, color .25s, border-color .25s, transform .15s; white-space: nowrap; }
.btn--primary { background: var(--ink); color: var(--canvas); }
.btn--primary:hover { background: #2c271d; }
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--line-strong); }
.btn--ghost:hover { border-color: var(--ink); background: rgba(21,18,13,0.04); }
.btn--on-ink { background: var(--canvas); color: var(--ink); }
.btn--on-ink:hover { background: #fff; }
.btn--lg { padding: 1.1rem 2rem; font-size: 1.05rem; }
.btn .ico { width: 1.05em; height: 1.05em; }

/* ---------- nav ---------- */
.nav { position: fixed; top: 0; left: 0; right: 0; z-index: 100; transition: background .3s, box-shadow .3s, border-color .3s; border-bottom: 1px solid transparent; }
.nav.is-scrolled { background: rgba(246,243,234,0.88); backdrop-filter: saturate(1.2) blur(12px); border-bottom-color: var(--line); }
.nav__inner { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; height: var(--nav-h, 76px); }
.nav__brand { display: inline-flex; align-items: center; }
.nav__brand img { height: 22px; width: auto; }
.nav__links { display: flex; align-items: center; gap: clamp(1.25rem, 2.4vw, 2.4rem); list-style: none; margin: 0; padding: 0; }
.nav__links a { text-decoration: none; font-weight: 400; font-size: 0.98rem; color: var(--ink); white-space: nowrap; position: relative; padding: 0.4rem 0; }
.nav__links a::after { content: ""; position: absolute; left: 0; bottom: 0; width: 0; height: 2px; background: var(--ink); transition: width .25s; }
.nav__links a:hover::after, .nav__links a[aria-current="page"]::after { width: 100%; }
.nav__actions { display: flex; align-items: center; gap: 0.75rem; }
.nav__toggle { display: none; background: none; border: 0; padding: 0.5rem; min-width: 44px; min-height: 44px; cursor: pointer; color: var(--ink); }
.nav__toggle-bar { display: block; width: 24px; height: 2px; background: currentColor; margin: 5px 0; transition: transform .3s, opacity .3s; }
.nav__toggle[aria-expanded="true"] .nav__toggle-bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] .nav__toggle-bar:nth-child(2) { opacity: 0; }
.nav__toggle[aria-expanded="true"] .nav__toggle-bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ---------- nav: Services dropdown (CSS only, hover + focus-within) ----------
   Reverted 2026-08-11 to the plain floating panel. Three variations were tried
   (slimmed, hung off the bar, joined to the label with a shared background) and
   all read worse than the standard one. Left alone deliberately. */
.nav__links .has-sub { position: relative; }
.nav__links .has-sub > a { display: inline-flex; align-items: center; gap: 0.35rem; }
.nav__links .has-sub > a .chev { width: 0.62em; height: 0.62em; flex: none; transition: transform .25s; }
.nav__links .has-sub:hover > a .chev, .nav__links .has-sub:focus-within > a .chev { transform: rotate(180deg); }
.nav__sub {
  position: absolute; top: 100%; left: -0.9rem; z-index: 20;
  min-width: 12.5rem; list-style: none; margin: 0; padding: 0.45rem;
  background: var(--canvas); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 22px 48px -28px rgba(21,18,13,0.55);
  display: grid; gap: 0.1rem;
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity .2s ease, transform .2s ease, visibility .2s;
}
.nav__links .has-sub:hover > .nav__sub,
.nav__links .has-sub:focus-within > .nav__sub { opacity: 1; visibility: visible; transform: translateY(0); }
.nav__sub a { display: block; padding: 0.6rem 0.8rem; border-radius: 9px; font-size: 0.95rem; white-space: nowrap; }
.nav__sub a::after { display: none; }
.nav__sub a:hover, .nav__sub a[aria-current="page"] { background: rgba(21,18,13,0.06); }

/* Links that sit alone on their own line get a 44px hit area without moving the
   text: padding grows the box, the negative margin cancels its layout effect.
   Deliberately NOT applied to links inside running prose, where 44px boxes would
   overlap each other and make mis-taps worse rather than better. */
@media (max-width: 767px) {
  .cta-band__contact a, .form-embed__fallback a, .cookie-banner p a,
  .legal__body p a {
    padding: 0.75rem 0; margin: -0.75rem 0; display: inline-block;
  }
  /* several links inside one sentence: 44px boxes would overlap each other, so
     the paragraph gets extra leading instead, which separates the targets
     vertically without creating overlapping hit areas */
  .prose-links { line-height: 2.2; }
  .prose-links a { padding: 0.35rem 0; }
}

/* ---------- sticky contact bar: REMOVED 2026-08-11 ----------
   Was a fixed mobile bar carrying Get a quote / Email us on every page. Avara
   removed it: at the foot of the page it was a third copy of the CTA band's own
   buttons, and it cost 76px of every screen for the whole visit. Client ask #6
   (a contact button on every page) is still met by the hero CTA on all 12 pages
   plus the CTA band. `body { padding-bottom: 4.75rem }` went with it — that
   reserved space was the cream strip you could scroll into below the footer. */
@media (max-width: 767px) {
  /* .nav opens a stacking context at z-index 100, so the menu's own z-index 1000
     is scoped inside it and the banner would paint over the open menu. */
  body.menu-open .cookie-banner { display: none; }
}

/* ---------- hero: bold type + live phones ---------- */
.hero { background: var(--canvas); padding-top: calc(var(--nav-h, 76px) + clamp(2rem, 5vw, 4rem)); padding-bottom: clamp(2.5rem, 5vw, 4.5rem); min-height: 100dvh; display: flex; align-items: center; }
.hero__inner { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: clamp(2rem, 5vw, 4.5rem); align-items: center; width: 100%; }
.hero__kicker { font-family: var(--font-body); font-weight: 700; font-size: 0.82rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--stone); margin: 0 0 1.25rem; display: inline-flex; align-items: center; gap: 0.6rem; }
.hero__kicker::before { content: ""; width: 2rem; height: 1px; background: var(--line-strong); }
.hero h1 { font-size: clamp(2.6rem, 6.4vw, 5.4rem); line-height: 0.98; margin: 0 0 1.5rem; }
.hero h1 em { font-style: normal; }
.hero__sub { font-size: clamp(1.1rem, 1.9vw, 1.35rem); color: var(--ink-soft); line-height: 1.5; max-width: 32rem; margin: 0 0 2rem; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 0.9rem; margin-bottom: 2.25rem; }
.hero__meta { display: flex; flex-wrap: wrap; gap: 1.5rem 2.25rem; padding-top: 1.75rem; border-top: 1px solid var(--line); }
.hero__meta .stat { display: flex; flex-direction: column; }
.hero__meta .stat b { font-family: var(--font-display); font-weight: 700; font-size: clamp(1.5rem, 2.4vw, 2rem); letter-spacing: -0.02em; line-height: 1; }
/* `> span` on purpose: the label span only. A descendant selector also hit the
   [data-count] span inside <b>, which shrank every count-up number to label size. */
.hero__meta .stat > span { font-size: 0.86rem; color: var(--stone); margin-top: 0.35rem; }

/* the two reel videos sit directly on cream (their baked-in bg = #F6F3EA) */
.hero__phones { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(0.5rem, 2vw, 1.25rem); align-items: start; }
.reel { position: relative; }
.reel video, .reel img { width: 100%; height: auto; display: block; border-radius: 6px; }
.hero__phones .reel:nth-child(2) { transform: translateY(clamp(1.5rem, 4vw, 3rem)); }
.reel__tag { position: absolute; left: 50%; bottom: -0.5rem; transform: translateX(-50%); background: var(--ink); color: var(--canvas); font-size: 0.72rem; font-weight: 700; letter-spacing: 0.04em; padding: 0.3rem 0.7rem; border-radius: 999px; white-space: nowrap; }

/* ---------- showreel feature band ---------- */
/* The projector clip is a cut-out already sitting on cream (its own baked
   background is #F5F4EB). A radius + drop shadow drew a visible card around
   mostly-empty cream, which read as a rendering fault. It now sits directly on
   the page, the way it does on their own site, and runs at their scale. */
.showreel { background: var(--canvas-video); }
.showreel__head { text-align: center; max-width: 40rem; margin: 0 auto clamp(2rem,4vw,3rem); }
.showreel__head h2 { font-size: clamp(1.9rem, 4vw, 3rem); }
/* Full-bleed and cropped to their own framing: their site shows this clip at
   object-fit:cover in a 1.21 box against a 1.78 source, i.e. a 1.47x zoom that
   trims the empty cream sides. Measured off thereelfirm.com 2026-08-11. */
/* Sized so the whole band fits one screen: heading + clip inside the viewport.
   Held at the source's native 16:9 with no crop, because the plinth runs to the
   very bottom edge of the file (1px of background below it) so cropping even
   slightly takes the projector's base off. Their own site shows the same cut,
   it just reads as deliberate there because the black footer starts on it. */
.showreel { padding-top: clamp(2.5rem, 5vw, 4rem); padding-bottom: 0; }
.showreel__head { margin-bottom: clamp(1rem, 2vw, 1.5rem); }
.showreel__frame {
  position: relative; margin: 0 auto; overflow: hidden;
  /* NO crop. The projector occupies the bottom of the frame, so trimming the
     bottom deletes it, and there is only 1px of background under the plinth
     anyway. Held at native 16:9 and sized so the band fits one screen; the
     band's zero bottom padding puts the plinth base on the section edge. */
  height: calc(100dvh - 15.5rem); max-height: 720px;
  aspect-ratio: 16 / 9; width: auto; max-width: 100%;
}
.showreel__frame video { width: 100%; height: 100%; object-fit: cover; display: block; background: var(--canvas-video); }
.showreel__note { text-align: center; color: var(--stone); font-size: 0.92rem; margin-top: 1.25rem; }

/* ---------- client logos marquee ---------- */
.client-logos-rail { overflow: hidden; padding: 0.5rem 0; -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.client-logos-rail .rail-track { display: flex; align-items: center; gap: clamp(2.5rem, 6vw, 5rem); width: max-content; animation: rail-marquee 120s linear infinite; }
.client-logos-rail .rail-track:hover { animation-play-state: paused; }
.client-logo { height: clamp(34px, 4.5vw, 52px); width: auto; opacity: 0.62; filter: grayscale(1); transition: opacity .25s, filter .25s; flex: none; }
.client-logo:hover { opacity: 1; filter: grayscale(0); }
/* Logo rail sizing. Every logo was set to the same HEIGHT, so wide wordmarks
   rendered huge and square or portrait marks rendered tiny: measured live,
   Pieminister came out 199px wide against Chicken Lunch Club at 65px. Height is
   now set PER LOGO from its aspect ratio so the rendered WIDTHS land in a
   comparable band (62px to 130px rather than 58px to 199px), which is what the
   eye actually reads as "the same size". The three the client named as their
   best stories (Boardwalk, Chicken Lunch Club, Wookey Hole) are the three
   narrowest marks, so they take the tallest heights. Client request 2026-08-14. */
.client-logo[src*="unnamed-blrf"],
.client-logo[src*="chicken-lunch-club"],
.client-logo[src*="wookey-hole"]      { height: clamp(60px, 7.8vw, 88px); opacity: 0.72; }
.client-logo[src*="bfg"]              { height: clamp(54px, 7vw, 80px); }
.client-logo[src*="anna-cake"]        { height: clamp(42px, 5.5vw, 62px); }
.client-logo[src*="ravi-ollie"]       { height: clamp(34px, 4.4vw, 49px); }
.client-logo[src*="cor.png"]          { height: clamp(33px, 4.3vw, 48px); }
.client-logo[src*="pedal-progression"]{ height: clamp(32px, 4.2vw, 47px); }
.client-logo[src*="ragu.svg"]         { height: clamp(31px, 4vw, 45px); }
.client-logo[src*="footerlogo"]       { height: clamp(30px, 3.9vw, 44px); }
.client-logo[src*="blank-vintage"]    { height: clamp(28px, 3.7vw, 42px); }
.client-logo[src*="pieminister"]      { height: clamp(24px, 3.1vw, 34px); }

@keyframes rail-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.proof-label { text-align: center; font-size: 0.8rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--stone); margin: 0 0 2rem; }

/* The showreel leads the page (client instruction 2026-08-14): it carries the
   fixed nav's clearance, and the hero behind it stops being a full-screen
   arrival panel because it is no longer what you arrive on. */
/* The lead band is ONE WHOLE VIEWPORT (client instruction 2026-08-17).
   Three things make this work, all measured off the source file:

   1. svh, NOT dvh. dvh is banned in this build: a dvh-driven box grows and
      shrinks as the iOS address bar collapses, which is what made the
      projector resize the whole way down the page. svh is the SMALLEST
      viewport state, so it is static and never overflows.
   2. The 16/25 frame crops the dead cream SIDES only. Measured with ffmpeg +
      magick -trim at five timestamps: the reel and projector occupy just
      535x950 of the 1920x1080 source, centred (x=697, y=130). That is 28% of
      the width, which is why it read as a small object floating in cream.
   3. scale(1.137) from a BOTTOM origin lifts the 130px of cream off the TOP.
      1080/950 = 1.1368, so the content ends up exactly filling the frame.
      The origin must stay `bottom`: the plinth runs to the file's bottom edge
      with ~1px under it, so any bottom crop deletes it.

   Frame height + the section's padding-top add up to exactly 100svh, and
   align-items:flex-end with zero bottom padding keeps the plinth base sitting
   on the section edge, which is the framing their own site uses. */
.showreel--lead {
  min-height: 100svh;
  display: flex; align-items: flex-end; justify-content: center;
  padding-top: calc(var(--nav-h, 76px) + clamp(0.75rem, 2vw, 1.5rem));
  padding-bottom: 0;
}
.showreel--lead .showreel__frame {
  height: calc(100svh - var(--nav-h, 76px) - clamp(0.75rem, 2vw, 1.5rem));
  max-height: none;
  aspect-ratio: 16 / 25;
  width: auto; max-width: 100%;
}
.showreel--lead .showreel__frame video { transform: scale(1.137); transform-origin: bottom center; }
.showreel--lead ~ .hero { min-height: auto; padding-top: clamp(2.5rem, 5vw, 4.5rem); }

/* ---------- featured-work rail (scroll-velocity) ---------- */
.featured-projects-rail { overflow: hidden; padding: 0.5rem 0; -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent); mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent); }
.featured-projects-rail .rail-track { display: flex; gap: clamp(1rem, 2vw, 1.5rem); width: max-content; will-change: transform; }
.fp-card { flex: none; width: clamp(230px, 28vw, 310px); background: var(--canvas); border: 1px solid var(--line); border-radius: 16px; padding: clamp(1.4rem, 2.2vw, 1.9rem); display: flex; flex-direction: column; gap: 0.25rem; }
.fp-card .num { font-family: var(--font-display); font-weight: 700; font-size: clamp(2rem, 3.6vw, 2.8rem); line-height: 0.95; letter-spacing: -0.03em; }
.fp-card .metric { font-weight: 700; font-size: 1rem; }
.fp-card .client { color: var(--stone); font-size: 0.92rem; margin-top: 0.4rem; }
.fp-card .plat { margin-top: 0.9rem; font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--stone); }

/* ---------- results grid ---------- */
.results__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1rem, 2vw, 1.5rem); }
.result-card { background: var(--canvas); border: 1px solid var(--line); border-radius: 16px; padding: clamp(1.5rem, 2.4vw, 2.25rem); display: flex; flex-direction: column; gap: 0.4rem; }
.section--ink .result-card { background: rgba(255,255,255,0.04); border-color: rgba(255,255,255,0.14); }
.result-card .num { font-family: var(--font-display); font-weight: 700; font-size: clamp(2.4rem, 4.6vw, 3.4rem); line-height: 0.95; letter-spacing: -0.03em; }
.result-card .metric { font-weight: 700; font-size: 1.02rem; }
.result-card .client { font-size: 0.9rem; color: var(--stone); margin-top: 0.35rem; }
.section--ink .result-card .client { color: rgba(246,243,234,0.6); }
.result-card .plat { margin-top: 1rem; font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--stone); }

/* ---------- reel case studies ---------- */
.reels__grid { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: clamp(1.5rem, 4vw, 3.5rem); align-items: center; }
.reel-case { display: grid; grid-template-columns: minmax(160px, 240px) 1fr; gap: clamp(1.25rem, 3vw, 2rem); align-items: center; }
.reel-case__video { border-radius: 8px; overflow: hidden; }
.reel-case__video video { width: 100%; height: auto; display: block; background: var(--canvas); }
.reel-case__body h3 { font-size: clamp(1.3rem, 2.2vw, 1.7rem); margin-bottom: 0.5rem; }
.reel-case__body p { color: var(--ink-soft); margin: 0 0 1rem; }
.reel-case__stats { display: flex; gap: 1.5rem; }
.reel-case__stats .s { display: flex; flex-direction: column; }
.reel-case__stats .s b { font-family: var(--font-display); font-weight: 700; font-size: 1.3rem; }
.reel-case__stats .s > span { font-size: 0.78rem; color: var(--stone); }

/* ---------- what we do ---------- */
.wwd__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.25rem, 3vw, 2.5rem); margin-top: 1rem; }
.wwd__item { border-top: 2px solid var(--ink); padding-top: 1.25rem; }
.wwd__item .n { font-family: var(--font-display); font-weight: 700; font-size: 0.95rem; color: var(--stone); }
.wwd__item h3 { font-size: clamp(1.25rem, 2vw, 1.6rem); margin: 0.6rem 0 0.5rem; }
.wwd__item p { color: var(--ink-soft); margin: 0; font-size: 1rem; }

/* ---------- service list (Agency / Consultancy / Training) ----------
   Full-width rows with hairline rules, no boxes. Replaces a three-up card grid:
   web-design-taste calls "three equal cards by reflex" the generic tell, and the
   grid sat directly under another three-up row on the same page. A list also
   matches the client's own word for it, "List of our product offerings", and the
   rows grow when they send the detail for each product. */
.svc-list { border-top: 1px solid var(--line-strong); }
.svc-row {
  display: grid; grid-template-columns: 11rem 1fr auto; gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: start; padding: clamp(1.75rem, 3.5vw, 2.75rem) 0;
  border-bottom: 1px solid var(--line-strong); text-decoration: none; color: inherit;
  transition: background .25s;
}
.svc-row:hover { background: rgba(21,18,13,0.03); }
.svc-row__tag { font-size: 0.74rem; letter-spacing: 0.16em; text-transform: uppercase; font-weight: 700; color: var(--stone); padding-top: 0.45rem; }
.svc-row h3 { font-size: clamp(1.5rem, 2.8vw, 2.1rem); margin: 0 0 0.5rem; }
.svc-row p { color: var(--ink-soft); margin: 0; max-width: 40rem; }
.svc-row__go { display: inline-flex; align-items: center; align-self: center; gap: 0.5rem; font-weight: 700; white-space: nowrap; }
.svc-row__go svg { width: 1.1em; height: 1.1em; transition: transform .25s; }
.svc-row:hover .svc-row__go svg { transform: translateX(4px); }

/* ---------- offers (retained: unused by the service block, kept for reuse) ---------- */
.offer__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1rem, 2vw, 1.5rem); }
.offer { background: var(--canvas); border: 1px solid var(--line); border-radius: 16px; padding: clamp(1.6rem, 2.6vw, 2.25rem); display: flex; flex-direction: column; }
.section--alt .offer { background: var(--canvas); }
.offer__tag { font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--stone); font-weight: 700; }
.offer h3 { font-size: clamp(1.35rem, 2.2vw, 1.75rem); margin: 0.7rem 0 0.6rem; }
.offer p { color: var(--ink-soft); margin: 0 0 1.25rem; }
.offer ul { list-style: none; padding: 0; margin: 0 0 1.5rem; display: grid; gap: 0.55rem; }
.offer li { position: relative; padding-left: 1.4rem; color: var(--ink-soft); font-size: 0.98rem; }
.offer li::before { content: ""; position: absolute; left: 0; top: 0.62em; width: 0.6rem; height: 1px; background: var(--ink); }
.offer .offer__foot { margin-top: auto; }

/* ---------- numbered process steps ---------- */
.steps { display: grid; gap: clamp(1.5rem, 3vw, 2.25rem); counter-reset: step; max-width: 52rem; }
.step { display: grid; grid-template-columns: 3.25rem 1fr; gap: clamp(1rem, 2.5vw, 1.75rem); align-items: start; padding-bottom: clamp(1.5rem, 3vw, 2.25rem); border-bottom: 1px solid var(--line); }
.step:last-child { border-bottom: 0; padding-bottom: 0; }
.step__n { font-family: var(--font-display); font-weight: 700; font-size: 1.6rem; letter-spacing: -0.03em; line-height: 1; color: var(--ink); }
.step h3 { font-size: clamp(1.2rem, 2vw, 1.5rem); margin: 0 0 0.5rem; }
.step p { color: var(--ink-soft); margin: 0; }

/* ---------- two-column prose split ---------- */
.split { display: grid; grid-template-columns: 0.85fr 1.15fr; gap: clamp(2rem, 5vw, 4.5rem); align-items: start; }
.split__aside h2 { font-size: clamp(1.7rem, 3.2vw, 2.4rem); }
.split__body p { color: var(--ink-soft); font-size: 1.05rem; margin: 0 0 1.1rem; }
.split__body p:last-child { margin-bottom: 0; }
.pullquote { border-left: 2px solid var(--ink); padding-left: clamp(1rem, 2.5vw, 1.75rem); margin: 0 0 1.75rem; }
.pullquote p { font-family: var(--font-display); font-weight: 700; font-size: clamp(1.2rem, 2.4vw, 1.6rem); line-height: 1.25; letter-spacing: -0.02em; color: var(--ink); margin: 0; }

/* ---------- embedded Google Form ---------- */
.form-embed { border: 1px solid var(--line); border-radius: 16px; overflow: hidden; background: #fff; max-width: 780px; }
.form-embed iframe { display: block; width: 100%; height: min(74dvh, 760px); border: 0; }
.form-embed__fallback { margin-top: 1rem; font-size: 0.95rem; color: var(--stone); max-width: 780px; }
.form-embed__fallback a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

/* ---------- case study (single client, deep numbers) ---------- */
.case { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.5rem, 4vw, 3.5rem); align-items: center; }
.case__stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(0.9rem, 2vw, 1.4rem); }
.case__stat { border-top: 2px solid var(--ink); padding-top: 0.9rem; }
.section--ink .case__stat { border-top-color: var(--canvas); }
.case__stat b { display: block; font-family: var(--font-display); font-weight: 700; font-size: clamp(1.9rem, 3.6vw, 2.7rem); line-height: 0.95; letter-spacing: -0.03em; }
.case__stat > span { display: block; font-size: 0.88rem; color: var(--stone); margin-top: 0.35rem; }
.section--ink .case__stat > span { color: rgba(246,243,234,0.62); }
.case__note { font-size: 0.92rem; color: var(--stone); margin-top: 1.5rem; }
.section--ink .case__note { color: rgba(246,243,234,0.6); }

/* ---------- to-confirm panel (build note, visible on the mockup only) ---------- */
.tbc { border: 1px dashed var(--line-strong); border-radius: 14px; padding: clamp(1.1rem, 2vw, 1.5rem); background: rgba(21,18,13,0.02); max-width: 46rem; }
.tbc__label { font-size: 0.7rem; letter-spacing: 0.14em; text-transform: uppercase; font-weight: 700; color: var(--stone); margin: 0 0 0.5rem; }
.tbc p { margin: 0; color: var(--ink-soft); font-size: 0.97rem; }

/* ---------- CTA band ---------- */
.cta-band { text-align: center; }
.cta-band h2 { font-size: clamp(2.2rem, 5.5vw, 4.2rem); margin-bottom: 1rem; }
.cta-band p { font-size: clamp(1.05rem, 1.8vw, 1.25rem); color: rgba(246,243,234,0.72); max-width: 34rem; margin: 0 auto 2.25rem; }
.cta-band .btn--on-ink { margin: 0 auto; }
/* The button sits centred between the sub and the email line. It used to have
   36px above and 0 below, because `.cta-band p`'s margin shorthand is (0,1,1)
   and its `margin-top: 0` beat `.cta-band__contact { margin-top: 1.5rem }` at
   (0,1,0). Both written at (0,2,1) so the pair actually balances. */
.cta-band p:not(.cta-band__contact) { margin: 0 auto 1.75rem; }
.cta-band p.cta-band__contact { margin: 1.75rem auto 0; font-size: 0.95rem; color: rgba(246,243,234,0.7); }
.cta-band__contact a { color: var(--canvas); text-decoration: underline; text-underline-offset: 3px; }

/* ---------- page hero (sub-pages) ---------- */
.page-hero { padding-top: calc(var(--nav-h,76px) + clamp(3rem, 7vw, 6rem)); padding-bottom: clamp(2rem, 4vw, 3.5rem); background: var(--canvas); }
.page-hero h1 { font-size: clamp(2.4rem, 6vw, 4.8rem); line-height: 1; margin: 0 0 1.25rem; }
.page-hero p { font-size: clamp(1.1rem, 2vw, 1.4rem); color: var(--ink-soft); max-width: 40rem; }
/* every page opens with something to click, per the client's "add a contact
   button on each page to increase conversion" */
.page-hero__actions { margin-top: clamp(1.5rem, 3vw, 2.25rem); display: flex; flex-wrap: wrap; gap: 0.9rem; }

/* ---------- forms ---------- */
.form { display: grid; gap: 1.1rem; max-width: 560px; }
.form .row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; }
.field { display: flex; flex-direction: column; gap: 0.4rem; }
.field label { font-size: 0.85rem; font-weight: 700; letter-spacing: 0.02em; }
.field input, .field textarea { width: 100%; padding: 0.9rem 1rem; border: 1.5px solid var(--line-strong); border-radius: 12px; background: #fff; color: var(--ink); font-size: 16px; transition: border-color .2s; }
.field input:focus, .field textarea:focus { outline: none; border-color: var(--ink); }
.field textarea { min-height: 140px; resize: vertical; }
.form__check { display: flex; align-items: center; gap: 0.6rem; font-size: 0.92rem; color: var(--ink-soft); }
/* inline form states (JS replaces the form in place; /thank-you is the no-JS fallback) */
.form__sent { padding: clamp(1.5rem, 4vw, 2.75rem) 0; }
.form__sent h3 { font-family: var(--font-display); font-weight: 700; letter-spacing: -0.02em; font-size: clamp(1.6rem, 4.5vw, 2.4rem); line-height: 1.08; margin: 0 0 0.75rem; color: var(--ink); }
.form__sent p { margin: 0; max-width: 34ch; color: var(--ink-soft); }
.form__legal { margin: 0.9rem 0 0; font-size: 0.78rem; color: var(--stone); }
.form__legal a { color: inherit; }
.form__error { margin: 0 0 0.9rem; font-size: 0.92rem; font-weight: 700; color: #8C2C1F; }
.form__check input { min-height: auto; width: 18px; height: 18px; }
.contact__cols { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: clamp(2rem, 5vw, 4.5rem); align-items: start; }
.contact__aside h3 { font-size: 1.3rem; margin-bottom: 0.75rem; }
.contact__aside a { color: var(--ink); }
.contact__links { list-style: none; padding: 0; margin: 1.25rem 0 0; display: grid; gap: 0.5rem; }
.contact__links a { display: inline-flex; align-items: center; gap: 0.6rem; text-decoration: none; font-weight: 400; }
.contact__links a:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ---------- footer ---------- */
.footer { background: var(--ink); color: var(--canvas); padding: clamp(3rem,6vw,5rem) 0 2rem; }
.footer__top { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 2.5rem; }
.footer__brand-mark { font-family: var(--font-display); font-weight: 700; font-size: 1.8rem; letter-spacing: -0.02em; }
.footer__brand p { color: rgba(246,243,234,0.62); max-width: 22rem; margin: 1rem 0 1.5rem; font-size: 0.95rem; }
.footer__col h4 { font-family: var(--font-body); font-weight: 700; font-size: 0.8rem; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(246,243,234,0.55); margin: 0 0 1rem; }
.footer__col ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.6rem; }
.footer__col a { color: rgba(246,243,234,0.85); text-decoration: none; font-size: 0.96rem; }
.footer__col a:hover { color: var(--canvas); }
.footer__social { display: flex; gap: 0.75rem; margin-top: 0.5rem; }
.footer__social a { width: 44px; height: 44px; border: 1px solid rgba(246,243,234,0.25); border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; color: var(--canvas); transition: background .2s, border-color .2s; }
.footer__social a:hover { background: rgba(246,243,234,0.1); border-color: rgba(246,243,234,0.5); }
.footer__social svg { width: 20px; height: 20px; }
.footer__bottom { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 1rem; margin-top: clamp(2.5rem,5vw,4rem); padding-top: 1.5rem; border-top: 1px solid rgba(246,243,234,0.16); font-size: 0.85rem; color: rgba(246,243,234,0.55); }
.footer__credit a { color: rgba(246,243,234,0.6); text-decoration: none; font-size: 0.8rem; opacity: 0.85; }
.footer__credit a:hover { color: var(--canvas); }

/* ---------- legal / utility pages ---------- */
.legal { padding-top: calc(var(--nav-h,76px) + clamp(3rem,6vw,5rem)); }
.legal__body { max-width: 48rem; }
.legal__body h2 { font-size: 1.4rem; margin: 2rem 0 0.6rem; }
.legal__body p, .legal__body li { color: var(--ink-soft); line-height: 1.65; }
.notfound { min-height: 80vh; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 2rem; }
.notfound h1 { font-size: clamp(4rem, 14vw, 9rem); margin: 0; }
.thankyou { min-height: 84vh; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 2rem; }
.thankyou h1 { font-size: clamp(2.5rem, 7vw, 4.5rem); }
.thankyou p { color: var(--ink-soft); max-width: 32rem; font-size: 1.15rem; }

/* ---------- case study head: copy left, client logo in the space right ---------- */
/* The copy column is capped at 46rem by .section-head, but this grid was
   1fr auto across the full 1240px container, so the logo was pushed to the far
   right edge with ~220px of dead space between it and the text it belongs to.
   Size the first column to the copy instead and let the logo sit just after it,
   top-aligned with the heading rather than floating centred in the void. */
.case-head { display: grid; grid-template-columns: minmax(0, 46rem) auto; justify-content: start; gap: clamp(2rem, 5vw, 4.5rem); align-items: start; margin: 0 0 clamp(2rem, 4vw, 3.25rem); }
/* The supplied wordmark is pale pastel, which disappears on cream. This build is
   monochrome by design ("colour comes from the client reels"), so the logo is
   rendered in ink on light and in canvas on the ink band, matching everything
   else on the page rather than being the one pastel object on it. */
.case-head__logo { width: clamp(110px, 11vw, 150px); height: auto; align-self: start; margin-top: 0.35rem; filter: brightness(0); opacity: 0.86; }
.case-head__logo--on-ink { filter: brightness(0) invert(1); opacity: 0.9; }

/* ---------- Blank Vintage: the three reels themselves ---------- */
.bv-reels { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(0.75rem, 2vw, 1.5rem); margin-top: clamp(2rem, 4vw, 3rem); max-width: 780px; }
.bv-reel { margin: 0; }
.bv-reel video { width: 100%; height: auto; display: block; border-radius: 8px; background: var(--canvas); }
.bv-reel figcaption { margin-top: 0.6rem; font-size: 0.82rem; color: var(--stone); }
.bv-reel figcaption b { font-family: var(--font-display); font-weight: 700; font-size: 1.05rem; color: var(--ink); display: block; letter-spacing: -0.02em; }

/* ---------- cookie banner ---------- */
.cookie-banner { position: fixed; left: 1rem; right: 1rem; bottom: 1rem; z-index: 200; background: var(--ink); color: var(--canvas); border-radius: 16px; padding: 1.25rem 1.5rem; display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; max-width: 720px; margin: 0 auto; box-shadow: 0 20px 50px -20px rgba(0,0,0,0.5); padding-bottom: calc(1.25rem + env(safe-area-inset-bottom)); }
.cookie-banner[hidden] { display: none !important; }
.cookie-banner p { margin: 0; font-size: 0.9rem; flex: 1 1 260px; color: rgba(246,243,234,0.85); }
.cookie-banner a { color: var(--canvas); }
.cookie-banner__actions { display: flex; gap: 0.6rem; }
.cookie-banner .btn { padding: 0.6rem 1.1rem; font-size: 0.9rem; min-height: 44px; }

/* reveal defaults (JS animates; static-visible fallback handled by @scripting) */
.reveal-up, .reveal-fade { opacity: 0; }
.reveal-stagger > * { opacity: 0; }

/* ============================================================
   Mobile floor (mobile-web-build SSOT — single 767px gate)
   ============================================================ */
@media (max-width: 767px) {
  h1 { font-size: clamp(2rem, 8vw, 2.75rem); }
  h2 { font-size: clamp(1.5rem, 6vw, 1.875rem); }
  h3 { font-size: clamp(1.25rem, 5vw, 1.5rem); }
  .hero__sub, .page-hero p, .lede { font-size: clamp(1rem, 4vw, 1.0625rem); line-height: 1.5; }
  .section-head p, .reel-case__body p, .wwd__item p { max-width: 38ch; }
  .container, .container--wide { padding: 0 clamp(1.25rem, 5vw, 1.5rem); }

  .nav__toggle { display: inline-block; }
  .nav__actions .btn { display: none; }
  .nav { background: rgba(246,243,234,0.92); backdrop-filter: blur(10px); border-bottom-color: var(--line); }
  /* logo hit area >= 44 tall */
  .nav__brand { min-height: 44px; }
  /* tap-target floor: footer + contact links (mobile-web-build 44px rule) */
  .footer__col a, .footer__bottom a, .contact__links a {
    display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; padding: 4px 2px;
  }
  .footer__bottom { gap: 0.4rem 1.25rem; }

  .hero { min-height: auto; padding-top: calc(var(--nav-h,68px) + 2rem); }
  .hero__inner { grid-template-columns: 1fr; gap: 2.25rem; }
  .hero h1 { font-size: clamp(2.2rem, 11vw, 3rem); }
  .hero__actions { flex-direction: column; }
  .hero__actions .btn { width: 100%; }
  .hero__meta { gap: 1.25rem 2rem; }
  .hero__phones { max-width: 420px; }
  .hero__phones .reel:nth-child(2) { transform: translateY(1.25rem); }

  /* narrower crop on a phone: the dead cream sides go, the projector fills */
  .showreel__frame { aspect-ratio: 4 / 5; }
  .results__grid { grid-template-columns: 1fr; }
  .svc-row { grid-template-columns: 1fr; gap: 0.6rem; }
  .svc-row__tag { padding-top: 0; }
  .svc-row__go { padding-top: 0.75rem; }
  .offer__grid { grid-template-columns: 1fr; }
  .split { grid-template-columns: 1fr; gap: 1.75rem; }
  .case { grid-template-columns: 1fr; gap: 2rem; }
  .step { grid-template-columns: 2.5rem 1fr; gap: 1rem; }
  /* svh, not dvh: same iOS trap as the showreel. A dvh-sized box grows and
     shrinks as the address bar collapses, and reflowing a Google Form while
     someone is part way through filling it in is worse than a fixed height.
     svh is the smallest viewport state, so it never overflows either. */
  .form-embed iframe { height: min(70svh, 620px); }
  .reels__grid { grid-template-columns: 1fr; gap: 2.5rem; }
  .reel-case { grid-template-columns: 150px 1fr; gap: 1.25rem; }
  .wwd__grid { grid-template-columns: 1fr; gap: 1.75rem; }
  .contact__cols { grid-template-columns: 1fr; }
  .form .row2 { grid-template-columns: 1fr; }
  .footer__top { grid-template-columns: 1fr; gap: 2rem; }
  .footer__bottom { flex-direction: column; align-items: flex-start; }
}

@media (max-width: 420px) {
  .hero h1 { font-size: clamp(2rem, 12vw, 2.6rem); }
  .reel-case { grid-template-columns: 120px 1fr; }
}

/* mobile nav menu overlay (handler in animations.js) */
.nav__menu { }
@media (max-width: 767px) {
  .nav__menu {
    /* .nav carries a backdrop-filter, which makes it the containing block for
       fixed-position descendants. `inset: 0` therefore resolved against the
       76px nav bar, not the viewport, so the open menu was a thin strip across
       the top. Explicit viewport units fix it without dropping the blur. */
    position: fixed; inset: 0; width: 100vw; height: 100dvh;
    background: var(--ink); color: var(--canvas);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 1.1rem; padding: 2rem;
    transform: translateX(100%); transition: transform .35s ease, visibility 0s linear .35s;
    z-index: 1000; overflow-y: auto;
    /* Closed, this panel was only translated off-screen: still visibility:visible,
       pointer-events:auto, links focusable. A keyboard or screen-reader user could
       tab straight into a menu sitting outside the viewport. Hide it properly when
       closed; the 0.35s visibility delay lets the slide-out still animate. */
    visibility: hidden;
  }
  .nav__menu.is-open {
    transform: translateX(0); visibility: visible;
    transition: transform .35s ease, visibility 0s;
  }
  .nav__menu .nav__links { display: flex; flex-direction: column; align-items: center; gap: 0.15rem; width: 100%; }

  /* Every destination reads at one size. Agency, Consultancy and Training are
     real pages, not a submenu, so on touch they are listed flat alongside the
     rest rather than demoted to small grey body text. Eight entries plus the
     CTA have to clear a 664px viewport with both iOS toolbars showing, which
     is what sets the size — not taste. */
  .nav__menu .nav__links a,
  .nav__menu .nav__sub a {
    font-family: var(--font-display); font-weight: 700;
    font-size: clamp(1.25rem, 5.8vw, 1.7rem); letter-spacing: -0.02em;
    color: var(--canvas); text-decoration: none;
    display: flex; align-items: center; justify-content: center;
    min-height: 46px; padding: 0.15rem 1rem;
  }
  .nav__menu .nav__links a::after { display: none; }
  .nav__menu .nav__sub a:hover { background: none; color: var(--canvas); }
  .nav__menu .nav__sub {
    position: static; opacity: 1; transform: none; /* visibility inherits from .nav__menu */
    background: none; border: 0; box-shadow: none; padding: 0;
    margin: 0; display: flex; flex-direction: column; align-items: center; gap: 0.15rem;
  }
  .nav__links .has-sub > a .chev { display: none; }

  /* solid white, so the one action on the screen actually reads as the action */
  .nav__menu .nav__menu-cta {
    margin-top: 1.1rem; padding: 0.75rem 2.4rem;
    background: var(--canvas); color: var(--ink);
    border: 1.5px solid var(--canvas); border-radius: 999px;
    font-family: var(--font-display); font-weight: 700; font-size: 1.1rem;
    display: flex; align-items: center; justify-content: center; min-height: 48px;
    text-decoration: none;
  }

  /* ---- a way back out ----
     The overlay is z 1000 inside `.nav`'s stacking context, so the hamburger
     (which already animates into an X via aria-expanded) was painting behind
     it and there was no visible way to close. Lift it above the overlay and
     recolour it for the dark ground. Both live inside `.nav`, so these
     z-indexes are compared against each other. */
  .nav__toggle[aria-expanded="true"] {
    position: relative; z-index: 1001; color: var(--canvas);
  }
}
@media (min-width: 768px) {
  .nav__menu { display: contents; }
  /* `display: contents` promotes every child of .nav__menu into the desktop bar,
     which was printing the mobile menu's Enquire link next to the real button.
     The button in .nav__actions is the desktop one. */
  .nav__menu-cta { display: none; }
}
body.menu-open { position: fixed; width: 100%; overflow: hidden; }

/* mobile fallback for the scroll-velocity rail (animations.js rail handler is desktop-only) */
@media (max-width: 767px) {
  .rail--scroll-velocity .rail-track { animation: mobile-rail-drift 40s linear infinite; }
  .rail--scroll-velocity .rail-track:hover { animation-play-state: paused; }
}
@keyframes mobile-rail-drift { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* Short viewports (landscape phone, a squat desktop window) are above the 767px
   gate, so they keep the desktop `height: calc(100dvh - 15.5rem)` rule and the
   projector collapses — 252x142 on a 844x390 phone in landscape. Size from
   width there too. Height query, not width, because the problem is the height. */
@media (max-height: 560px) and (min-width: 768px) {
  .showreel__frame { height: auto; width: min(100%, 52vw); max-height: none; aspect-ratio: 16 / 9; }

  /* Lead band, landscape phone / very short window. Matching specificity again,
     or the desktop (0,2,0) rule wins here. Sized from the short viewport so it
     still fills the screen rather than stretching a 16/25 box past the fold. */
  .showreel--lead { min-height: auto; padding-top: calc(var(--nav-h, 76px) + 0.5rem); }
  .showreel--lead .showreel__frame {
    height: calc(100svh - var(--nav-h, 76px) - 0.5rem);
    width: auto; max-width: 100%; max-height: none;
    aspect-ratio: 16 / 25;
  }
}

/* reduced-motion: marquees off (animation:none alone stops them — no transform:none, which would freeze the keyframe) */
@media (prefers-reduced-motion: reduce) {
  .client-logos-rail .rail-track, .rail--scroll-velocity .rail-track { animation: none !important; }
}

/* ============================================================
   Mobile pass 2 — measured on WebKit at 390x844, not Blink.
   The block above set bare `h1`/`h2` caps, but every real heading
   on this site is styled through a SCOPED rule (.section-head h2,
   .cta-band h2, .page-hero h1 ...). Those are (0,1,1) and beat a
   bare tag at (0,0,1), so the caps never applied to anything.
   Each one is re-capped below at its own specificity.
   ============================================================ */
@media (max-width: 767px) {

  /* ---- headings: the caps, actually applied ---- */
  .section-head h2,
  .showreel__head h2,
  .split__aside h2 { font-size: clamp(1.65rem, 7vw, 1.875rem); }
  .cta-band h2 { font-size: clamp(1.75rem, 7.6vw, 1.875rem); }
  .page-hero h1 { font-size: clamp(2rem, 8.6vw, 2.6rem); }
  .notfound h1 { font-size: clamp(2.4rem, 11vw, 2.75rem); }
  .thankyou h1 { font-size: clamp(2.1rem, 9vw, 2.75rem); }
  .svc-row h3 { font-size: clamp(1.25rem, 5.4vw, 1.5rem); }

  /* ---- the reel IS the product: stop rendering it as a thumbnail ----
     Was a 150px (120px under 420px) column beside the copy, which put a
     phone-inside-a-phone reel at a third of the screen width. Stack it. */

  /* three portrait reels side by side on a 390px screen would be 105px each,
     which is the thumbnail problem the reel-case fix solved. Two up instead,
     with the strongest one full width above them. */
  .case-head { grid-template-columns: 1fr; gap: 1.5rem; }
  .case-head__logo { justify-self: start; width: 150px; }
  .bv-reels { grid-template-columns: 1fr 1fr; gap: 0.75rem; }
  .bv-reel:first-child { grid-column: 1 / -1; max-width: min(72vw, 280px); }

  .reel-case { grid-template-columns: 1fr; gap: 1.1rem; align-items: start; }
  .reel-case__video { max-width: min(72vw, 280px); }
  .reel-case__body h3 { font-size: clamp(1.3rem, 5.6vw, 1.55rem); }

  /* ---- hero reels: the desktop arrangement, scaled down ----
     A swipe rail was tried here and rejected: hiding the second reel behind
     an interaction read worse than simply showing both. Keep the two-up pair
     with its offset, sized to the phone. Do NOT reintroduce a carousel. */
  .hero__phones { max-width: 420px; margin: 0 auto; gap: 0.7rem; }
  .hero__phones .reel:nth-child(2) { transform: translateY(1.25rem); }

  /* ---- nav: opaque. At 0.92 alpha the big display headings ghosted
     straight through the bar as you scrolled past them. The menu sizes
     itself with explicit 100vw/100dvh, so it does not need the
     backdrop-filter's containing block to stay full-screen. ---- */
  /* `.nav.is-scrolled` is (0,2,0) and beats a bare `.nav`, media query or not,
     so the opaque rule has to be written at the same specificity or the bar
     silently reverts to 0.88 alpha the moment you scroll past 64px — which is
     precisely when there is a heading behind it to ghost through. */
  .nav, .nav.is-scrolled { background: var(--canvas); backdrop-filter: none; }

  /* ---- hamburger sits at the right edge, not near the middle ----
     `.nav__inner` is space-between over THREE in-flow children: brand,
     toggle, and `.nav__actions`. Hiding only `.nav__actions .btn` left the
     empty wrapper in the flex row holding the right-hand slot, so the toggle
     was distributed into the middle of the bar. Hide the wrapper itself. */
  .nav__actions { display: none; }
  .nav__toggle { margin-left: auto; margin-right: -0.5rem; }

  /* ---- the showreel must not resize while you scroll ----
     It was `height: calc(100dvh - 15.5rem)` with `aspect-ratio` and
     `width: auto`, so its box was driven by viewport HEIGHT. On iOS the
     address bar collapses and expands as you scroll, 100dvh moves with it,
     and the projector visibly grew and shrank the whole way down the page.
     Size it from WIDTH instead: fixed against the toolbar, and held at the
     larger of the two sizes it used to flip between. */
  .showreel__frame {
    height: auto; width: 100%; max-width: 100%; max-height: none;
    aspect-ratio: 3 / 4;
  }

  /* The lead band fills the phone screen too. This MUST be written at
     `.showreel--lead .showreel__frame` (0,2,0) to match the base rule, not at
     bare `.showreel__frame` (0,1,0) — a lower-specificity mobile override
     loses to the desktop rule regardless of the media query, which is the
     mistake this build made four separate times.
     Height-driven is safe HERE because svh is static, unlike the dvh that
     caused the scroll-resize bug. The composition is narrow (0.64), so width
     never binds: 661x413 on a 390px phone, 583x364 on a 375px one. */
  .showreel--lead {
    padding-top: calc(var(--nav-h, 76px) + 0.5rem);
  }
  .showreel--lead .showreel__frame {
    /* Width-driven, capped by the height that is actually available. On a tall
       narrow phone a full-height portrait box wants to be WIDER than the screen;
       letting `max-width:100%` clamp it silently breaks the declared ratio and
       squeezes the side margin to ~3px, which clips the projector edges. Taking
       the min up front keeps 5/9 exact in every state. The section stays
       100svh and bottom-aligned, so the plinth still sits on the screen edge. */
    width: min(100%, calc((100svh - var(--nav-h, 76px) - 0.5rem) * 0.5555));
    height: auto; max-width: 100%; max-height: none;
    aspect-ratio: 5 / 9;
  }
  .showreel--lead .showreel__frame video { transform: none; }

  /* ---- featured-work cards: 230px minimum was too wide for the rail, so
     every card was clipped mid-sentence at both edges ---- */
  .fp-card { width: 200px; padding: 1.1rem 1.15rem; border-radius: 12px; }
  .fp-card .num { font-size: 1.75rem; }
  .fp-card .metric { font-size: 0.92rem; }
  .fp-card .client { font-size: 0.85rem; }
  .featured-projects-rail .rail-track { gap: 0.75rem; }

  /* the CTA band's own button is the last call to action now; there is no
     fixed bar to retract, so nothing to declare here */

  /* ---- fixed nav is 77px: anchor jumps must clear it ---- */
  [id] { scroll-margin-top: 88px; }

  /* ---- footer was 1159px, nearly two viewports of links ---- */
  .footer__col ul { grid-template-columns: 1fr 1fr; gap: 0.3rem 1rem; }
  .footer__col:has(a[href^="mailto"]) ul { grid-template-columns: 1fr; }
  .footer__brand p { margin: 0.75rem 0 1rem; }

  /* ---- cookie banner: 145px of a 664px viewport, sitting on the hero's
     second CTA. Same content, two thirds the height. ---- */
  .cookie-banner { padding: 0.85rem 1rem; gap: 0.7rem; border-radius: 14px;
    padding-bottom: calc(0.85rem + env(safe-area-inset-bottom)); }
  .cookie-banner[hidden] { display: none !important; }
.cookie-banner p { font-size: 0.82rem; flex: 1 1 100%; }
  .cookie-banner__actions { width: 100%; gap: 0.5rem; }
  .cookie-banner .btn { flex: 1; padding: 0.5rem 0.8rem; font-size: 0.85rem; }

  /* ---- form: 16px floor stops iOS zooming on focus; the checkbox
     itself was an 18px target inside a full-width label ---- */
  .form input, .form textarea, .form select { font-size: 16px; }
  .form__check { display: flex; align-items: center; gap: 0.6rem; min-height: 44px; }
  .form__check input[type="checkbox"] { width: 22px; height: 22px; flex: 0 0 22px; }
}


/* Conversion band (option B, chosen 2026-08-26).
   Every other number on this site measures attention. This one
   measures what somebody did next, so it gets its own ground. */
.conv { text-align: center; }
.conv .conv__num {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(3.5rem, 11vw, 8rem);
  line-height: 0.92;
  letter-spacing: -0.04em;
  color: var(--canvas);
}
.conv h2 { color: var(--canvas); max-width: 22ch; margin: 1rem auto 0; }
.conv p  { color: rgba(246,243,234,0.8); max-width: 44rem; margin: 1rem auto 0; font-size: 1.05rem; }

/* Event space: the film is the only look anyone gets at the room, so it gets more
   width than a case-study reel. Declared inside a min-width query on purpose: an
   inline style or a bare rule here would beat the 767px rule that stacks
   .reel-case on phones, which is exactly how this shipped with horizontal
   overflow the first time. */
@media (min-width: 768px) {
  .reel-case--wide { grid-template-columns: minmax(0, 360px) minmax(0, 1fr); gap: clamp(1.5rem, 4vw, 3.5rem); align-items: center; }
}
