/* ═══════════════════════════════════════════════════════
   OPERIO — design system
   Palette: near-black base, off-white ink, hairline glass
   borders, Operio navy + cream from the brand mark.
   Type: Bebas Neue (display) · Space Mono (labels) · Archivo (body)
   ═══════════════════════════════════════════════════════ */

:root {
  --bg: #040508;
  --ink: #d8d8d8;
  --ink-dim: rgba(216, 216, 216, 0.55);
  --ink-faint: rgba(216, 216, 216, 0.28);
  --panel: #c8c8c8;
  --line: rgba(255, 255, 255, 0.14);
  --line-strong: rgba(255, 255, 255, 0.3);
  --navy: #1f2b5b;
  --navy-bright: #8fa2e6;
  --cream: #f2f1ea;
  --cream-ink: #10173a;
  /* belt colour == the exact top colour of the work screen, so a closed
     belt and the section beneath it read as one continuous surface */
  --wipe-grey: #d5d6da;
  /* same trick going the other way, into the dark voice screen */
  --wipe-dark: #05060a;

  --font-display: "Bebas Neue", sans-serif;
  --font-mono: "Space Mono", monospace;
  --font-body: "Archivo", sans-serif;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.83, 0, 0.17, 1);

  --pad: clamp(1.25rem, 4vw, 4rem);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: auto; }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

::selection { background: var(--navy-bright); color: var(--bg); }

[data-mono] {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  font-weight: 400;
}

a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }

/* ── SVG logo mark ─────────────────────────────── */
#operio-blades { transform-origin: 256px 256px; }

/* ── Intro ─────────────────────────────────────────
   A cream registration-mark sequence that shutters away
   through ten belts to reveal the dark hero. Never traps
   clicks — rAF can be suspended in a background tab.   */
.intro {
  position: fixed; inset: 0; z-index: 200;
  pointer-events: none;
  color: var(--cream-ink);
  /* Covers from the very first paint, before JS builds the belts. */
  background: var(--cream);
}

.intro__flying { position: absolute; inset: 0; }
.intro__plus,
.intro__corner {
  position: absolute; width: 13px; height: 13px;
  stroke: var(--cream-ink); stroke-width: 1;
  overflow: visible;
}
.intro__plus { top: 0; left: 0; margin: -6.5px 0 0 -6.5px; }

.intro__center {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 2.4rem;
}
.intro__logo-wrap {
  position: relative;
  width: 132px; height: 132px;
  display: grid; place-items: center;
  border-radius: 2px;
}
/* Scales up on the GPU to become the page. Kept as its own layer because the
   box used to grow via width/height/top/left, which relayouts and repaints the
   border, corners and mark on every frame — the jankiest moment of the intro. */
.intro__panel {
  position: absolute; inset: 0; z-index: 0;
  border-radius: 2px;
  transform: scale(1);
  will-change: transform;
}
/* Chrome sits above the growing surface. .intro__mark is a grid item, so
   without an explicit layer the absolutely-positioned panel would paint over
   it. The corners/border are already absolute — they must only get a z-index,
   never `position: relative`, or their offset placement collapses. */
.intro__mark { position: relative; }
.intro__mark, .intro__border, .intro__corner { z-index: 1; }
.intro__border { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.intro__border-rect { stroke: rgba(16, 23, 58, 0.45); stroke-width: 1; vector-effect: non-scaling-stroke; }
.intro__corner--tl { top: -6.5px; left: -6.5px; }
.intro__corner--tr { top: -6.5px; right: -6.5px; }
.intro__corner--bl { bottom: -6.5px; left: -6.5px; }
.intro__corner--br { bottom: -6.5px; right: -6.5px; }
.intro__mark { width: 94px; height: 94px; fill: var(--navy); overflow: visible; }

.intro__tagline {
  display: flex; align-items: center; gap: 0.7rem;
  font-family: var(--font-mono);
  font-size: 0.68rem; letter-spacing: 0.3em;
}
.intro__dot { color: rgba(16, 23, 58, 0.4); }

.intro__counter {
  position: absolute; bottom: 12%;
  display: flex; align-items: center;
  font-family: var(--font-display);
  font-size: 1.6rem; line-height: 1;
}
.intro__reel { height: 1em; overflow: hidden; }
.intro__strip { display: flex; flex-direction: column; will-change: transform; }
.intro__strip span { height: 1em; line-height: 1; display: block; text-align: center; min-width: 0.62em; }

/* ── Custom cursor ─────────────────────────────── */
.cursor {
  position: fixed; top: 0; left: 0; z-index: 150;
  pointer-events: none; mix-blend-mode: difference;
}
.cursor__dot {
  position: absolute; top: -6px; left: -6px;
  width: 12px; height: 12px; border-radius: 50%;
  background: #fff;
  transition: transform 0.25s var(--ease-out);
}
.cursor__label {
  position: absolute; top: -10px; left: 18px;
  font-family: var(--font-mono); font-size: 0.6rem;
  letter-spacing: 0.2em; color: #fff; white-space: nowrap;
  opacity: 0; transition: opacity 0.2s;
}
.cursor.is-hover .cursor__dot { transform: scale(2.4); }
.cursor.is-view .cursor__dot { transform: scale(4.5); }
.cursor.is-view .cursor__label { opacity: 1; }
@media (hover: none) { .cursor { display: none; } }

/* ── Corner frame marks ────────────────────────── */
.frame-marks { position: fixed; inset: 0; z-index: 90; pointer-events: none; }
.frame-marks__plus {
  position: absolute;
  font-family: var(--font-mono); font-size: 0.9rem;
  color: var(--ink-faint); line-height: 1;
}
.frame-marks__plus--tl { top: 12px; left: 14px; }
.frame-marks__plus--tr { top: 12px; right: 14px; }
.frame-marks__plus--bl { bottom: 12px; left: 14px; }
.frame-marks__plus--br { bottom: 12px; right: 14px; }

/* ── Header ────────────────────────────────────── */
.header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.1rem var(--pad);
  transition: background 0.4s, backdrop-filter 0.4s;
}
.header.is-scrolled {
  /* No block. The reference keeps its header floating on the page with no
     panel, backdrop or rule behind it at any scroll position. */
  background: none;
  backdrop-filter: none;
  border-bottom: 0;
}
.header__brand { display: flex; align-items: center; gap: 0.65rem; }
.header__mark { width: 30px; height: 30px; fill: var(--ink); }
.header__wordmark {
  font-family: var(--font-display); font-size: 1.35rem;
  letter-spacing: 0.14em; line-height: 1; padding-top: 2px;
}
.header__controls { display: flex; align-items: center; gap: 0.6rem; }
/* Three items won't fit beside the wordmark on a phone — the menu overlay
   carries contact, so the CTA is the one to drop. */
@media (max-width: 620px) {
  /* two classes deep so it beats .btn's own display, which is declared later */
  .header__controls .header__cta { display: none; }
  .header__controls .header__menu { padding: 0.6rem 1.1rem; }
}
.header__menu { gap: 0.65rem; background: transparent; }
.header__burger { display: flex; flex-direction: column; gap: 4px; }
.header__burger i {
  display: block; width: 14px; height: 1px;
  background: currentColor;
  transition: transform 0.35s var(--ease-out), opacity 0.3s;
}
.header__menu[aria-expanded="true"] .header__burger i:first-child { transform: translateY(2.5px) rotate(45deg); }
.header__menu[aria-expanded="true"] .header__burger i:last-child { transform: translateY(-2.5px) rotate(-45deg); }

/* ── Menu overlay ──────────────────────────────── */
.menu {
  position: fixed; inset: 0; z-index: 95;
  background: rgba(4, 5, 8, 0.94);
  backdrop-filter: blur(18px);
  display: flex; flex-direction: column;
  justify-content: center;
  padding: 7rem var(--pad) 3rem;
  visibility: hidden; opacity: 0; pointer-events: none;
  transition: opacity 0.45s var(--ease-out);
}
.menu.is-open { visibility: visible; opacity: 1; pointer-events: auto; }
.menu__nav { display: flex; flex-direction: column; gap: 0.4rem; margin-bottom: auto; margin-top: auto; }
.menu__link {
  display: flex; align-items: baseline; gap: 1.2rem;
  font-family: var(--font-body);
  font-size: clamp(2rem, 6vw, 4.5rem);
  font-weight: 400; letter-spacing: -0.05em; line-height: 1.15;
  color: var(--ink-dim);
  transition: color 0.35s var(--ease-out);
}
.menu__link span { font-size: 0.7rem; color: var(--ink-faint); letter-spacing: 0.16em; }
.menu__link:hover { color: var(--ink); }
.menu__link:hover span { color: var(--navy-bright); }
.menu__foot {
  display: flex; flex-wrap: wrap; gap: 0.8rem 2rem;
  justify-content: space-between;
  border-top: 1px solid var(--line); padding-top: 1.4rem;
  color: var(--ink-dim); letter-spacing: 0.14em;
}

/* ── Buttons ───────────────────────────────────── */
.btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  padding: 0.95rem 2rem;
  font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.18em;
  border: 1px solid var(--line-strong); border-radius: 999px;
  cursor: pointer; overflow: visible;
  color: inherit; /* <button> defaults to black otherwise */
  transition: background-color 0.4s var(--ease-out), border-color 0.4s var(--ease-out);
}
/* Two stacked copies of the label; chars blur-swap on hover. */
.btn__text {
  position: relative; display: inline-flex;
  line-height: 1; white-space: pre;
}
.btn__layer { display: inline-flex; white-space: pre; }
.btn__layer--clone { position: absolute; left: 0; top: 0; pointer-events: none; }
.btn__char { display: inline-block; will-change: transform, opacity, filter; }

.btn:hover { background: rgba(216, 216, 216, 0.09); border-color: var(--ink); }
.btn--fill { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.btn--fill:hover { background: rgba(216, 216, 216, 0.82); border-color: rgba(216, 216, 216, 0.82); }
.header__cta { padding: 0.7rem 1.5rem; }

.btn--navy { border-color: rgba(16, 23, 58, 0.35); color: var(--cream-ink); }
.btn--navy:hover { background: rgba(16, 23, 58, 0.07); border-color: var(--cream-ink); }
.btn--fill-navy { background: var(--cream-ink); color: var(--cream); border-color: var(--cream-ink); }
.btn--fill-navy:hover { background: rgba(16, 23, 58, 0.82); border-color: rgba(16, 23, 58, 0.82); }

/* ── WebGL scene ────────────────────────────────────
   Fixed behind every section so the aperture keeps
   revolving as the page scrolls past it. */
.scene {
  position: fixed; inset: 0; z-index: 0;
  pointer-events: none;
}
.scene canvas { display: block; width: 100%; height: 100%; }
@media (max-width: 900px) { .scene { opacity: 0.5; } }

/* WebGL unavailable: a CSS-only stand-in for the orbit, set by hero3d.js
   when the renderer fails to get a context. A visitor should never need to
   fix their own browser to see a good-looking site, so this isn't a bare
   apology gradient — it's the brand mark itself, slowly turning, at the
   same drift speed as the real orbit's idle rotation. */
.scene--fallback {
  background:
    radial-gradient(ellipse 60% 45% at 50% 38%, rgba(216, 216, 216, 0.09), transparent 70%),
    radial-gradient(ellipse 40% 30% at 50% 38%, rgba(216, 216, 216, 0.05), transparent 70%);
  display: grid; place-items: center;
}
.scene--fallback__mark {
  width: min(46vw, 560px);
  aspect-ratio: 1;
  fill: rgba(216, 216, 216, 0.16);
  transform-origin: 50% 50%;
  animation: scene-fallback-spin 110s linear infinite;
}
@media (max-width: 900px) {
  .scene--fallback__mark { width: min(72vw, 420px); }
}
@keyframes scene-fallback-spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .scene--fallback__mark { animation: none; }
}

main > section,
main > footer { position: relative; z-index: 1; }

/* ── Hero ──────────────────────────────────────── */
.hero {
  min-height: 100svh;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: 8rem var(--pad) 3.5rem;
  position: relative; text-align: center;
}
.hero__center {
  flex: 1;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
}
.hero__eyebrow {
  font-family: var(--font-body);
  font-size: 0.875rem; font-weight: 400;
  letter-spacing: -0.02em; text-transform: uppercase;
  color: var(--ink); margin-bottom: 1.6rem;
}

/* Regular weight, tight tracking, centred — the scale carries it. */
.hero__title {
  font-family: var(--font-body);
  font-size: clamp(2.4rem, 7.2vw, 6.6rem);
  font-weight: 400; line-height: 0.93;
  letter-spacing: -0.06em;
  color: var(--ink);
}
.hero__line { display: block; overflow: hidden; padding-bottom: 0.08em; }
.hero__line-inner { display: inline-block; }

/* Split text: chars animate, words keep lines from breaking mid-word. */
.char { display: inline-block; }
.word { display: inline-block; white-space: nowrap; }

/* Services, centred under the orbit. */
.hero__services {
  display: flex; flex-wrap: wrap;
  justify-content: center; align-items: center;
  gap: 0.5rem 2rem;
  max-width: 56rem;
  margin-top: 2.5rem;
}
.hero__service a {
  font-family: var(--font-body);
  font-size: 0.875rem; font-weight: 400;
  letter-spacing: -0.02em; text-transform: uppercase;
  color: var(--ink-dim);
  transition: color 0.3s var(--ease-out);
}
.hero__service a:hover { color: var(--ink); }
.hero__service--flag a { color: var(--navy-bright); }

.hero__scroll {
  position: absolute; right: var(--pad); bottom: 2.4rem;
  width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid var(--line-strong);
  display: grid; place-items: center;
  color: var(--ink-dim); font-size: 0.9rem;
  transition: color 0.3s var(--ease-out), border-color 0.3s var(--ease-out);
}
.hero__scroll:hover { color: var(--ink); border-color: var(--ink); }
.hero__scroll span { animation: scrollnudge 2s var(--ease-in-out) infinite; }
@keyframes scrollnudge { 50% { transform: translateY(3px); } }

@media (max-width: 900px) {
  .hero { padding: 7rem var(--pad) 4.5rem; }
  .hero__services { gap: 0.4rem 1.2rem; }
  .hero__service a { font-size: 0.78rem; }
  .hero__scroll { display: none; }
}

/* ── Statement ─────────────────────────────────────
   Big centred sentence, two underlined arrow links,
   the orbit forms drifting past at the edges. */
.statement {
  min-height: 100svh;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: 6rem var(--pad);
  text-align: center;
}
.statement__title {
  font-family: var(--font-body);
  font-size: clamp(1.85rem, 5.3vw, 4.7rem);
  font-weight: 400; line-height: 0.96;
  letter-spacing: -0.055em;
  color: var(--ink);
  max-width: 24ch;
}
.statement__title > span { display: block; overflow: hidden; padding-bottom: 0.08em; }

.statement__links {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: clamp(1.2rem, 4vw, 3rem);
  margin-top: clamp(2.5rem, 6vw, 5rem);
}
.arrowlink {
  display: flex; align-items: center; justify-content: space-between;
  gap: 2.5rem; min-width: 13.5rem;
  padding: 0.65rem 0.1rem 0.8rem;
  border-bottom: 1px solid var(--line-strong);
  font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.14em;
  color: var(--ink-dim);
  transition: color 0.35s var(--ease-out), border-color 0.35s var(--ease-out);
}
.arrowlink i { font-style: normal; transition: transform 0.4s var(--ease-out); }
.arrowlink:hover { color: var(--ink); border-color: var(--ink); }
.arrowlink:hover i { transform: translateX(6px); }
@media (max-width: 620px) { .arrowlink { min-width: 100%; } }

/* ── Who we build for ──────────────────────────────
   The only block added on top of the live stylesheet. Nothing outside these
   .audience__ rules is touched. */
.audience {
  padding: clamp(4rem, 12vh, 8rem) var(--pad);
  border-top: 1px solid var(--line);
}
.audience__head { margin-bottom: clamp(2rem, 6vh, 3.5rem); }
.audience__title {
  font-family: var(--font-body); font-weight: 400;
  /* Floor set by the longest line, "B2B service businesses." — 23 characters
     must clear 320px minus the padding, or it wraps and the mask that hides
     the incoming reveal clips the second row. */
  font-size: clamp(1.75rem, 5.2vw, 4.2rem);
  line-height: 0.96; letter-spacing: -0.05em;
  margin-top: 1.2rem;
}
.audience__title > span { display: block; overflow: hidden; padding-bottom: 0.08em; }

.audience__body {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 6vw, 5rem); align-items: start;
}
.audience__lede { color: var(--ink-dim); max-width: 32rem; }
.audience__soon {
  margin-top: clamp(1.2rem, 3vh, 2rem);
  color: var(--navy-bright); letter-spacing: 0.18em;
}

.audience__list { display: flex; flex-direction: column; }
.audience__list li {
  display: flex; align-items: baseline; gap: clamp(0.9rem, 2vw, 1.6rem);
  padding: clamp(0.7rem, 1.8vh, 1rem) 0;
  border-top: 1px solid var(--line);
  font-size: clamp(0.95rem, 1.4vw, 1.15rem);
  letter-spacing: -0.02em;
  color: var(--ink);
}
.audience__list li:last-child { border-bottom: 1px solid var(--line); }
.audience__list li span { color: var(--navy-bright); letter-spacing: 0.16em; }

@media (max-width: 900px) {
  .audience__body { grid-template-columns: 1fr; }
}

/* ── Capabilities marquee ──────────────────────────
   Giant words tracking sideways as the page scrolls,
   with the orbit forms drifting behind them. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.capabilities {
  min-height: 100svh;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: clamp(2rem, 6vw, 4.5rem);
  padding: 6rem 0;
  overflow: hidden;
}
.capabilities__marquee { width: 100%; overflow: hidden; }
.capabilities__track { display: flex; width: max-content; will-change: transform; }
.capabilities__group {
  display: flex; align-items: center;
  gap: clamp(1.2rem, 3vw, 3rem);
  padding-right: clamp(1.2rem, 3vw, 3rem);
}
.capabilities__word {
  font-family: var(--font-body);
  font-size: clamp(3rem, 10.5vw, 10.5rem);
  font-weight: 500; line-height: 1;
  letter-spacing: -0.05em; text-transform: uppercase;
  color: var(--ink); white-space: nowrap;
}
.capabilities__group i {
  font-style: normal; font-weight: 300;
  font-size: clamp(1.4rem, 3.4vw, 3.4rem);
  color: var(--ink-faint);
}
.capabilities__caption {
  font-family: var(--font-body);
  font-size: 0.875rem; font-weight: 400;
  letter-spacing: -0.02em; text-transform: uppercase;
  color: var(--ink); text-align: center;
  padding: 0 var(--pad);
}

/* ── Belt wipe (section transition) ────────────────
   Five belts that grow upward from their own bottom edge,
   closing the capabilities screen off in bands.

   ABSOLUTE, not fixed, and a child of .capabilities — this is
   the whole trick. The wipe is part of that section, so it
   scrolls away with it. It only ever CLOSES; it never reopens.
   Because a closed belt is exactly the colour of the top of the
   work screen (--wipe-grey), the two read as one continuous
   surface and the handover is invisible without any pin. */
.wipe {
  position: absolute; inset: 0; z-index: 30;
  display: flex; flex-direction: column;
  pointer-events: none;
}
.wipe__belt {
  flex: 1 1 0%; width: 100%;
  margin-top: -1px; padding-bottom: 1px; /* kill hairline seams between belts */
  background: var(--wipe-grey);
  transform: scaleY(0);
  transform-origin: center bottom;
  will-change: transform;
}
/* Going into a dark screen instead of a light one. Belts grow from the TOP
   edge here, so the black arrives from above as the white page rides up —
   the opposite direction to the one out of capabilities, which keeps the two
   transitions from reading as the same move twice. */
.wipe--dark .wipe__belt {
  background: var(--wipe-dark);
  transform-origin: center top;
}

/* ── Selected work (light, horizontal) ─────────────
   One viewport tall and clipped. Inside, a nowrap track
   of half-viewport panels that slides left while the
   section is pinned, so the page scrolls sideways.

   The heading is panel 1 rather than a fixed column —
   that is what lets it ride off to the left with
   everything else instead of sitting there statically. */
.work {
  position: relative;
  height: 100svh;
  overflow: hidden;
  /* top edge is exactly --wipe-grey so the closed belts hand over invisibly */
  background: linear-gradient(180deg, #d5d6da 0%, #ffffff 58%);
  color: #3f4148;
}
/* Two stacked layers inside the one pinned section. The services screen never
   moves; the gallery rides off it to the left in the pin's second phase. */
.work__services {
  position: absolute; inset: 0; z-index: 1;
  display: flex; flex-direction: column; justify-content: space-between;
  padding: clamp(5rem, 9vh, 7rem) var(--pad) clamp(2rem, 5vh, 3rem);
  background: #06070a; /* the dark end state; the veil supplies the light one */
}
/* Atmosphere. Drifting haze over near-black, with a lit form floating above
   the type — the dark state you only see once the veil has gone. */
.services__bg { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
/* Dialled right back now that the footage brings its own volumetric smoke —
   at full strength these blurred blobs sat over real smoke and muddied it.
   They only survive to cover the moment before the video fades up. */
.services__haze {
  position: absolute; border-radius: 50%;
  filter: blur(70px); opacity: 0.12;
}
.services__haze--a {
  width: 70vw; height: 60vh; left: -10vw; top: 10vh;
  background: radial-gradient(circle, rgba(150,163,190,0.34), transparent 70%);
}
.services__haze--b {
  width: 60vw; height: 55vh; right: -8vw; top: -8vh;
  background: radial-gradient(circle, rgba(120,132,158,0.3), transparent 70%);
}
.services__haze--c {
  width: 80vw; height: 50vh; left: 12vw; bottom: -12vh;
  background: radial-gradient(circle, rgba(96,106,130,0.26), transparent 70%);
}
/* Rock plate. mix-blend-screen drops the video's black to nothing, so the
   smoke composites onto the section instead of sitting in a hard box. */
.services__rock {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  /* Normal, NOT screen — this plate carries the block and its smoke in one
     shot, so screening it would make the shadowed faces go transparent. */
  mix-blend-mode: normal;
  will-change: opacity;
  pointer-events: none;
}
/* Engraved mark. A dark recess plus a light lip along the top edge — that
   pair is what reads as carved rather than printed on. multiply keeps it
   sitting in the stone's own shading instead of floating over it. */
/* OFF: the supplied footage already carries the engraving on its own last
   frame, so drawing our SVG mark on top would put two logos on the stone.
   Kept wired up (JS still drives it) — delete this one rule to bring it back
   if a future cut of the video ships without the carve. */
.services__engrave { display: none; }
.services__engrave {
  position: absolute; left: 50%; top: 44%;
  width: clamp(90px, 11vw, 170px); height: auto;
  transform: translate(-50%, -50%);
  fill: rgba(6, 7, 10, 0.72);
  mix-blend-mode: multiply;
  filter: drop-shadow(0 -1.5px 0 rgba(255, 255, 255, 0.3))
          drop-shadow(0 2px 3px rgba(0, 0, 0, 0.55));
  opacity: 0; pointer-events: none;
}
/* Retained for the reduced-motion path, which never loads the video. */
.services__orb {
  position: absolute; left: 50%; top: 26%;
  width: clamp(120px, 15vw, 210px); aspect-ratio: 1.12;
  transform: translate(-50%, -50%);
  border-radius: 48% 52% 44% 56% / 52% 46% 54% 48%;
  background:
    radial-gradient(circle at 34% 28%, #f0ece4 0%, #c9c3b8 32%, #8d8880 62%, #4a4843 85%, #2b2a28 100%);
  box-shadow: 0 30px 90px rgba(0, 0, 0, 0.55);
}
/* ── Service cards ─────────────────────────────────
   Deep perspective so they arrive with real depth. Above the
   stone but below the label/tagline chrome. */
.services__cards {
  position: absolute; inset: 0; z-index: 2;
  perspective: 93.75rem;
  transform-style: preserve-3d;
  pointer-events: none;
}
.services__card {
  position: absolute;
  opacity: 0; will-change: transform, opacity;
  color: rgba(233, 230, 223, 0.9);
}
/* One panel treatment for all six content cards. They used to be a mixed set —
   two panelled, four bare — which read as an accident rather than a system once
   they arrived in pairs, because a pair would be half-panel, half-floating. */
.services__card--panel {
  padding: 2.5rem;
  border-radius: 0.5rem;
  background: rgba(0, 0, 0, 0.2);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(233, 230, 223, 0.12);
}
/* Line icon. Stroke-only and hairline, so it sits at the same weight as the
   rules and arcs already on this screen instead of reading as a filled glyph. */
.services__icon {
  display: block;
  width: 1.75rem; height: 1.75rem;
  margin-bottom: 1.5rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.25;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: rgba(233, 230, 223, 0.62);
}
.services__card h3 {
  font-family: var(--font-body);
  font-size: clamp(1.15rem, 2vw, 1.75rem);
  font-weight: 400; line-height: 1.15; letter-spacing: -0.035em;
  color: #f2f0ea;
}
.services__card p {
  margin-top: 1.1rem; max-width: 20rem;
  font-size: 0.86rem; line-height: 1.55;
  color: rgba(233, 230, 223, 0.62);
}
/* Resting positions. Each pair sits on one beat, right card high and left card
   low, so the two cross the frame in opposite directions past these points. */
.services__card--tr { top: 15%; right: 6%; width: min(30rem, 38vw); }
.services__card--bl { bottom: 17%; left: 5%; width: min(28rem, 34vw); }
.services__card--tr2 { top: 20%; right: 8%; width: min(29rem, 36vw); }
.services__card--bl2 { bottom: 22%; left: 8%; width: min(28rem, 35vw); }
.services__card--tr3 { top: 26%; right: 4%; width: min(28rem, 35vw); }
.services__card--bl3 { bottom: 28%; left: 6%; width: min(28rem, 34vw); }
/* Hairline rule block. */
.services__card--rule {
  bottom: 27%; left: 33%;
  display: flex; gap: 7px;
}
.services__card--rule span {
  display: block; width: 1px; height: clamp(60px, 9vw, 105px);
  background: rgba(233, 230, 223, 0.3);
}
.services__card--arcs {
  top: 21%; right: 2%;
  width: clamp(90px, 9vw, 150px); height: auto;
  color: rgba(233, 230, 223, 0.42);
}
@media (max-width: 900px) {
  .services__card--panel { padding: 1.6rem; }
  .services__icon { width: 1.5rem; height: 1.5rem; margin-bottom: 1rem; }
  .services__card--tr { top: 10%; right: 4%; width: 66vw; }
  .services__card--bl { bottom: 22%; left: 4%; width: 66vw; }
  .services__card--tr2 { top: 12%; right: 4%; width: 66vw; }
  .services__card--bl2 { bottom: 20%; left: 4%; width: 66vw; }
  .services__card--tr3 { top: 14%; right: 4%; width: 66vw; }
  .services__card--bl3 { bottom: 18%; left: 4%; width: 66vw; }
  .services__card--rule, .services__card--arcs { display: none; }
}

.services__veil {
  position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(180deg, #ffffff 0%, #c3c3c3 100%);
  will-change: opacity;
}
/* Copy always sits above BOTH the atmosphere and the veil. */
.services__label,
.services__stack,
.services__foot { position: relative; z-index: 2; }
.work__gallery {
  position: absolute; inset: 0; z-index: 2;
  will-change: transform;
  /* MUST be opaque. The services screen sits directly beneath it at z-1, so a
     transparent gallery lets the giant service words show straight through the
     project cards. The reference gives every card panel its own copy of this
     gradient; carrying it on the container instead is equivalent and cannot
     seam between panels. Top colour stays --wipe-grey so the belt handover
     into this section is still invisible. */
  background: linear-gradient(180deg, #d5d6da 0%, #ffffff 58%);
}

/* ── Services screen ───────────────────────────────
   Four words stacked on a line-height far tighter than
   their own size, so the block reads as one mass rather
   than four lines. That ratio is the whole effect. */
.services__label {
  font-family: var(--font-body);
  font-size: 0.85rem; font-weight: 400;
  letter-spacing: -0.02em; text-align: center;
  color: rgba(43, 45, 51, 0.75);
}
.services__stack {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  flex: 1; min-height: 0;
  /* 3D depth for the character throw — measured off the reference (93.75rem). */
  perspective: 93.75rem;
  transform-style: preserve-3d;
}
/* Each letter is its own element so it can tumble independently. */
.services__char {
  display: inline-block;
  will-change: transform, filter;
  backface-visibility: hidden;
}
.services__word {
  display: block; text-align: center;
  font-family: var(--font-body);
  font-size: clamp(2.4rem, 9.16vw, 8.2rem);
  font-weight: 400; text-transform: uppercase;
  line-height: 0.672;          /* measured ratio — lines deliberately crowd */
  letter-spacing: -0.08em;
  color: #2b2d33;
  white-space: nowrap;
}
/* Light → dark. The veil handles the background; type has to cross over on its
   own, so every text colour is a transition and `is-dark` flips them together. */
.services__label,
.services__word,
.services__tagline,
.work__services .arrowlink { transition: color 0.5s ease, border-color 0.5s ease; }
.work__services.is-dark .services__word { color: #e9e6df; }
.work__services.is-dark .services__label,
.work__services.is-dark .services__tagline { color: rgba(233, 230, 223, 0.72); }
.work__services.is-dark .arrowlink {
  color: rgba(233, 230, 223, 0.8);
  border-bottom-color: rgba(233, 230, 223, 0.35);
}
.work__services.is-dark .arrowlink:hover {
  color: #ffffff; border-bottom-color: #ffffff;
}

.services__foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 2rem; flex-wrap: wrap;
}
/* Both taglines occupy one slot and cross-fade, so the line changes without
   the row reflowing under it. */
.services__taglines { position: relative; min-height: 1.4em; flex: 1 1 auto; }
.services__tagline { position: absolute; left: 0; top: 0; white-space: nowrap; }
.services__tagline--b { opacity: 0; }
@media (max-width: 900px) {
  .services__taglines { min-height: 2.8em; }
  .services__tagline { white-space: normal; }
}
.services__tagline {
  font-family: var(--font-body);
  font-size: 0.85rem; letter-spacing: -0.01em;
  color: rgba(43, 45, 51, 0.8);
  text-transform: uppercase;
}
@media (max-width: 900px) {
  .services__foot { flex-direction: column; align-items: flex-start; gap: 1rem; }
  .services__word { letter-spacing: -0.06em; }
}

.work__viewport {
  height: 100%;
  /* base state is a real horizontal scroller, so the section still works
     with no JS and under reduced motion; main.js switches this to hidden
     once it takes the track over */
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none;
}
.work__viewport::-webkit-scrollbar { display: none; }
.work__track {
  display: flex; flex-wrap: nowrap; align-items: center;
  height: 100%; width: max-content;
  will-change: transform;
}
.work__panel {
  position: relative;
  flex: 0 0 50vw; width: 50vw; height: 100%;
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(3rem, 6vw, 5rem) clamp(1.5rem, 3.2vw, 3rem);
}
/* Divider at each panel's leading edge. It is not a static border: it draws
   itself downward as the panel arrives (scaleY 0→1 from the top). */
.work__line {
  position: absolute; left: 0; top: 0;
  width: 1px; height: 100%;
  background: rgba(67, 67, 67, 0.15);
  transform: scaleY(0); transform-origin: top;
  pointer-events: none;
}
/* The element that rises. Kept separate from .work__panel so the panel can own
   horizontal position while the inner owns the vertical entrance. */
.work__card-inner {
  display: flex; flex-direction: column;
  width: 100%;
  will-change: transform;
}
.work__outro {
  font-family: var(--font-body);
  font-size: clamp(1.15rem, 1.9vw, 1.6rem);
  font-weight: 400; line-height: 1.35; letter-spacing: -0.035em;
  color: #434343; max-width: 22rem;
  margin-bottom: clamp(1.6rem, 3vw, 2.4rem);
}

.work__title {
  font-family: var(--font-body);
  font-size: clamp(2.4rem, 5.4vw, 4.8rem);
  font-weight: 500; line-height: 0.95;
  letter-spacing: -0.06em; color: #434343;
  margin-bottom: clamp(2rem, 4vw, 3.2rem);
}
.work__title > span { display: block; overflow: hidden; padding-bottom: 0.06em; }

/* ink variant of the arrow link, for light sections */
.arrowlink--ink {
  border-bottom-color: rgba(67, 67, 67, 0.3);
  color: rgba(67, 67, 67, 0.75);
}
.arrowlink--ink:hover { color: #2b2d33; border-bottom-color: #2b2d33; }

/* Aspect and inset match the gallery proportion: the image sits
   at 80% of the panel width, so the panels breathe as they pass. */
.work__media {
  position: relative; aspect-ratio: 512 / 352;
  width: 80%; align-self: center;
  border-radius: 12px; overflow: hidden;
  display: grid; place-items: end start;
  padding: clamp(1.2rem, 2.5vw, 2rem);
}
.work__media--a, .work__media--b, .work__media--c { background-size: cover; background-position: center; }
.work__media--a {
  background-image: linear-gradient(0deg, rgba(20, 18, 14, 0.42) 0%, rgba(20, 18, 14, 0) 45%),
    url("../assets/work/north-fade.jpg");
}
.work__media--b {
  background-image: linear-gradient(0deg, rgba(14, 16, 22, 0.42) 0%, rgba(14, 16, 22, 0) 45%),
    url("../assets/work/rideau.jpg");
}
.work__media--c {
  background-image: linear-gradient(0deg, rgba(16, 18, 22, 0.42) 0%, rgba(16, 18, 22, 0) 45%),
    url("../assets/work/lakeshore.jpg");
}
.work__frame {
  position: absolute; inset: 14px;
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 4px; pointer-events: none;
}
.work__overlay {
  position: relative;
  font-family: var(--font-body);
  font-size: clamp(1.4rem, 2.6vw, 2.4rem);
  font-weight: 400; letter-spacing: -0.05em; line-height: 1;
  color: #ffffff;
}
.work__meta {
  width: 80%; align-self: center;
  margin-top: 1.6rem;
}
.work__name {
  font-family: var(--font-body);
  font-size: clamp(1.3rem, 2vw, 1.75rem);
  font-weight: 400; letter-spacing: -0.04em; color: #434343;
}
.work__desc {
  font-size: 0.9rem; line-height: 1.6;
  color: rgba(67, 67, 67, 0.65); max-width: 24rem; margin-top: 0.5rem;
}
.work__explore { display: inline-flex; margin-top: 1.4rem; }

/* One panel per screen on phones — half a viewport is too narrow to read. */
@media (max-width: 900px) {
  .work__panel { flex-basis: 88vw; width: 88vw; padding: 4rem 1.5rem; }
  .work__media, .work__meta { width: 100%; }
}

/* Fixed chrome must flip to dark ink over the white work screen. */
.is-light .header { color: #2b2d33; }
.is-light .header__mark { fill: #2b2d33; }
.is-light .header__cta {
  background: #2b2d33; color: #ffffff; border-color: #2b2d33;
}
.is-light .header__cta:hover { background: rgba(43, 45, 51, 0.82); border-color: rgba(43, 45, 51, 0.82); }
.is-light .header__menu { border-color: rgba(67, 67, 67, 0.35); color: #2b2d33; }
.is-light .header__menu:hover { background: rgba(67, 67, 67, 0.07); border-color: #2b2d33; }
.is-light .header.is-scrolled { background: none; border-bottom: 0; }
.is-light .frame-marks__plus { color: rgba(67, 67, 67, 0.3); }
.is-light .cursor { mix-blend-mode: normal; }
.is-light .cursor__dot { background: #2b2d33; }
.header, .header__mark, .frame-marks__plus {
  transition: color 0.45s var(--ease-out), fill 0.45s var(--ease-out),
              border-color 0.45s var(--ease-out), background-color 0.45s var(--ease-out);
}

/* ── Section heads ─────────────────────────────── */
section { position: relative; }
.section-head { padding: clamp(5rem, 11vw, 9rem) var(--pad) clamp(2.5rem, 5vw, 4rem); }
.section-head__meta {
  display: flex; align-items: center; gap: 0.9rem;
  color: var(--ink-dim); letter-spacing: 0.22em;
  margin-bottom: 1.8rem;
}
.section-head__meta--center { justify-content: center; padding-top: clamp(5rem, 10vw, 8rem); }
.section-head__index {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem;
  border: 1px solid var(--line-strong); border-radius: 50%;
  font-size: 0.6rem;
}
.section-head__title {
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(2.8rem, 8.5vw, 8rem);
  line-height: 0.94; text-transform: uppercase; letter-spacing: 0.01em;
}
.section-head__title > span { display: block; overflow: hidden; }
.section-head__title-ghost {
  color: transparent;
  -webkit-text-stroke: 1.5px var(--ink-faint);
}
.section-head__title--light .section-head__title-ghost {
  -webkit-text-stroke-color: rgba(16, 23, 58, 0.3);
}
.section-head__sub { max-width: 30rem; color: var(--ink-dim); margin-top: 1.6rem; }

/* ── AI Voice — pinned arc screen ──────────────────
   The wheel of tiles sits ABOVE the giant type, not behind it: the bottom
   word runs under the arc and is cut by it, which is what gives the screen
   its layered depth. Copy and chrome sit above both. */
.voice {
  background:
    radial-gradient(120% 80% at 50% 108%, rgba(63, 78, 140, 0.28), transparent 62%),
    linear-gradient(180deg, #05060a 0%, #090c16 52%, #05060a 100%);
}
/* Its own class, deliberately — NOT `.voice > .voice__pin`. ScrollTrigger
   wraps a pinned element in a .pin-spacer, so the child combinator stops
   matching the moment the pin is created and the screen silently falls back
   to the detail screen's flex/padding rules. */
.voice__stage {
  position: relative;
  height: 100svh;
  overflow: hidden;
}
/* Scrim under the bottom copy. The arc runs right through where the note and
   the link sit, so without this the copy is set over photographs. Starts
   below the bottom word so it grounds the wheel without dimming the type.
   Same z as the ring and declared after it, so it paints over the tiles. */
.voice__stage::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 34%; z-index: 3; pointer-events: none;
  background: linear-gradient(180deg, rgba(5, 6, 10, 0) 0%, rgba(5, 6, 10, 0.55) 42%, rgba(5, 6, 10, 0.94) 100%);
}
/* Blueprint hairlines drifting behind everything — the same registration
   language as the intro and the stories rule, at architectural scale. */
.voice__arcs {
  position: absolute; inset: -10% -20%; z-index: 0;
  width: 140%; height: 120%;
  fill: none; stroke: rgba(216, 216, 216, 0.09); stroke-width: 1;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}
.voice__meta {
  position: absolute; top: clamp(5rem, 11vh, 7.5rem); left: var(--pad);
  z-index: 4; margin: 0;
}

/* ── The wheel ─────────────────────────────────────
   Tiles are absolutely placed and positioned entirely from JS, which puts
   each one on the circumference of a circle whose centre is far below the
   fold. CSS only owns their size and skin. */
.voice__ring {
  position: absolute; inset: 0; z-index: 3;
  list-style: none; pointer-events: none;
}
.voice__tile {
  position: absolute; top: 0; left: 0;
  width: clamp(10rem, 20vw, 21rem);
  opacity: 0;
  will-change: transform, opacity;
}
.voice__tile img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: 0.5rem;
  border: 1px solid rgba(233, 230, 223, 0.14);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
}
.voice__tile-meta { display: block; margin-top: 0.75rem; padding-left: 0.1rem; }
.voice__tile-meta b {
  display: block;
  font-size: 0.82rem; font-weight: 500;
  letter-spacing: -0.025em; line-height: 1.2;
  color: rgba(233, 230, 223, 0.92);
}
.voice__tile-meta i {
  display: block; margin-top: 0.2rem;
  font-style: normal; font-size: 0.56rem;
  letter-spacing: 0.14em; color: var(--navy-bright);
}

/* ── Counter-sliding display type ──────────────────
   Top word settles flush left, bottom word flush right, and they arrive from
   opposite sides. Uppercase at marquee scale here rather than the sentence
   case used for ordinary headings — this is the same register as the
   capabilities and services words, not a section title. */
.voice__type {
  position: absolute; left: 0; right: 0; top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  display: flex; flex-direction: column;
  padding: 0 var(--pad);
  pointer-events: none;
}
.voice__word {
  font-family: var(--font-body); font-weight: 400;
  font-size: clamp(2.6rem, 12.2vw, 11rem);
  line-height: 0.8; letter-spacing: -0.055em;
  text-transform: uppercase; white-space: nowrap;
  color: var(--ink);
  will-change: transform, filter;
}
.voice__word--top { align-self: flex-start; }
.voice__word--bottom { align-self: flex-end; }
.voice__lede {
  align-self: center; text-align: center;
  margin: clamp(0.6rem, 1.6vh, 1.2rem) 0;
  font-size: 0.875rem; font-weight: 400;
  letter-spacing: -0.02em; text-transform: uppercase;
  line-height: 1.35; color: var(--ink-dim);
}

.voice__foot {
  position: absolute; left: 0; right: 0; bottom: clamp(1.6rem, 4.5vh, 3rem);
  z-index: 4; padding: 0 var(--pad);
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 2rem;
}
.voice__note {
  font-size: 0.9rem; line-height: 1.5; letter-spacing: -0.01em;
  color: var(--ink-dim); max-width: 26rem;
}
.voice__jump { min-width: 11rem; flex: 0 0 auto; }

@media (max-width: 900px) {
  .voice__tile { width: 46vw; }
  /* No room for a caption under each tile at this size — it lands straight on
     the bottom copy. The businesses still read from the images. */
  .voice__tile-meta { display: none; }
  .voice__lede { font-size: 0.78rem; }
  .voice__foot { flex-direction: column; align-items: flex-start; gap: 1.2rem; }
  .voice__note { max-width: none; font-size: 0.82rem; }
  .voice__jump { min-width: 100%; }
  .voice__stage::after { height: 46%; }
}

/* ── AI Voice — detail / conversion screen ─────── */
.voice-detail { background: linear-gradient(180deg, var(--bg) 0%, #070a14 50%, var(--bg) 100%); }
.voice__pin { min-height: 100svh; display: flex; align-items: center; padding: 5rem var(--pad); }
.voice__grid {
  display: grid; grid-template-columns: 1.1fr 0.9fr;
  gap: clamp(2rem, 6vw, 6rem); width: 100%; align-items: center;
}
/* Archivo, sentence case, tight negative tracking — the same display voice as
   the hero, statement, work and stories headings. This was the last Bebas
   all-caps heading on the page and it read as a different site. */
.voice__title {
  font-family: var(--font-body); font-weight: 400;
  font-size: clamp(2.4rem, 6vw, 5.4rem);
  line-height: 0.93; letter-spacing: -0.055em;
  margin: 1.4rem 0;
}
/* padding-bottom so the masked line reveal cannot clip descenders */
.voice__title > span { display: block; overflow: hidden; padding-bottom: 0.08em; }
.voice__sub { color: var(--ink-dim); max-width: 30rem; }
.voice__specs {
  margin: 1.8rem 0; border: 1px solid var(--line); border-radius: 12px;
  overflow: hidden;
}
.voice__spec-row {
  display: flex; justify-content: space-between; align-items: center;
  gap: 1.2rem; padding: 0.9rem 1.2rem;
  letter-spacing: 0.12em;
}
.voice__spec-row + .voice__spec-row { border-top: 1px solid var(--line); }
.voice__spec-row span { color: var(--ink-dim); flex: 0 0 auto; }
.voice__spec-row strong { color: var(--navy-bright); text-align: right; }
.voice__features {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 0.7rem 1.4rem; margin-bottom: 2.2rem;
  font-size: 0.9rem; line-height: 1.45; letter-spacing: -0.01em;
}
.voice__features li { color: var(--ink-dim); padding-left: 1.1rem; position: relative; }
.voice__features li::before { content: "→"; position: absolute; left: 0; color: var(--navy-bright); }
.voice__ctas { display: flex; gap: 1rem; flex-wrap: wrap; }

.phone {
  border: 1px solid var(--line-strong); border-radius: 20px;
  background: rgba(255, 255, 255, 0.02);
  backdrop-filter: blur(6px);
  padding: 1.4rem; display: flex; flex-direction: column; gap: 0.9rem;
  max-width: 26rem; margin-left: auto;
  box-shadow: 0 40px 80px rgba(0, 0, 0, 0.45);
}
.phone__head {
  display: flex; justify-content: space-between;
  color: var(--ink-dim); padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--line);
}
.phone__live { display: flex; align-items: center; gap: 0.45rem; }
.phone__live-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: #6ee7a0; animation: pulse 1.6s infinite;
}
.phone__incoming {
  display: flex; flex-direction: column; gap: 0.2rem;
  padding: 0.9rem 1rem; border: 1px dashed var(--line-strong); border-radius: 12px;
}
.phone__incoming span { color: var(--ink-dim); }
.phone__msg {
  max-width: 85%; padding: 0.8rem 1rem; border-radius: 14px;
  font-size: 0.9rem; line-height: 1.45;
}
.phone__msg--caller {
  align-self: flex-start;
  background: rgba(255, 255, 255, 0.06);
  border-bottom-left-radius: 4px;
}
.phone__msg--ai {
  align-self: flex-end;
  background: var(--navy);
  color: #e6eaff;
  border-bottom-right-radius: 4px;
}
.phone__tag { display: block; color: var(--navy-bright); margin-bottom: 0.25rem; letter-spacing: 0.18em; }
.phone__confirm {
  display: flex; flex-direction: column; gap: 0.3rem;
  padding: 0.95rem 1rem; border-radius: 12px;
  background: rgba(110, 231, 160, 0.08);
  border: 1px solid rgba(110, 231, 160, 0.25);
}
.phone__confirm strong { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.14em; color: #6ee7a0; }
.phone__confirm span { color: var(--ink-dim); }
@media (max-width: 900px) {
  .voice__grid { grid-template-columns: 1fr; }
  .phone { margin: 0 auto; }
  .voice__features { grid-template-columns: 1fr; }
}

/* ── Work ──────────────────────────────────────── */
.work__grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem; padding: 0 var(--pad) clamp(4rem, 8vw, 7rem);
}
.case { display: block; }
.case__media {
  aspect-ratio: 4 / 5; border-radius: 14px; overflow: hidden;
  display: grid; place-items: center;
  border: 1px solid var(--line);
  position: relative;
  transition: transform 0.6s var(--ease-out);
}
.case__media::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(120% 90% at 20% 10%, rgba(255,255,255,0.1), transparent 55%);
}
.case__media--a { background: linear-gradient(160deg, #131b3f, #060810); }
.case__media--b { background: linear-gradient(160deg, #3a2416, #0b0705); }
.case__media--c { background: linear-gradient(160deg, #16303a, #05090b); }
.case__mark {
  font-family: var(--font-display);
  font-size: clamp(4rem, 8vw, 7rem);
  color: transparent; -webkit-text-stroke: 1.5px rgba(255, 255, 255, 0.25);
  transition: transform 0.6s var(--ease-out);
}
.case:hover .case__media { transform: scale(0.97); }
.case:hover .case__mark { transform: scale(1.18); }
.case__meta { color: var(--ink-faint); margin: 1.1rem 0 0.35rem; letter-spacing: 0.16em; }
.case__title { font-family: var(--font-display); font-weight: 400; font-size: 1.8rem; letter-spacing: 0.03em; }
.case__result { color: var(--ink-dim); margin-top: 0.3rem; font-size: 0.92rem; }
.case__result span { color: var(--navy-bright); }
@media (max-width: 850px) { .work__grid { grid-template-columns: 1fr; } }

/* ── Testimonials ──────────────────────────────── */
.voices { padding-bottom: clamp(3rem, 7vw, 6rem); }
.marquee--quotes { border: none; padding: 2.4rem 0 0; }
.quote {
  width: clamp(20rem, 30vw, 26rem);
  margin-right: 1.5rem; padding: 1.6rem;
  border: 1px solid var(--line); border-radius: 14px;
  white-space: normal; flex-shrink: 0;
}
.marquee--quotes .marquee__group {
  font-family: var(--font-body); font-size: 1rem; letter-spacing: 0;
  color: var(--ink); gap: 0; padding-right: 0; align-items: stretch;
}
.quote p { font-size: 1.02rem; line-height: 1.55; color: var(--ink); }
.quote footer { margin-top: 1.1rem; color: var(--ink-dim); letter-spacing: 0.14em; }

/* ── Process ───────────────────────────────────── */
.process__list {
  display: grid; grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--line);
}
.pstep {
  padding: 2.8rem var(--pad) 3.4rem;
  border-right: 1px solid var(--line);
}
.pstep:last-child { border-right: none; }
.pstep__num { color: var(--navy-bright); letter-spacing: 0.2em; }
.pstep__title {
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(1.8rem, 3.4vw, 2.8rem);
  margin: 1rem 0 0.8rem; letter-spacing: 0.03em;
}
.pstep__desc { color: var(--ink-dim); max-width: 24rem; }
@media (max-width: 850px) {
  .process__list { grid-template-columns: 1fr; }
  .pstep { border-right: none; border-bottom: 1px solid var(--line); }
  .pstep:last-child { border-bottom: none; }
}

/* ── FAQ ───────────────────────────────────────── */
.faq__list { border-top: 1px solid var(--line); margin: 0 var(--pad) clamp(4rem, 8vw, 6rem); }
.faq__item { border-bottom: 1px solid var(--line); }
.faq__item summary {
  display: flex; justify-content: space-between; align-items: center;
  list-style: none; cursor: pointer;
  padding: 1.6rem 0.2rem;
  font-family: var(--font-body); font-weight: 400; font-size: clamp(1.05rem, 2vw, 1.3rem);
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__icon {
  font-family: var(--font-mono); font-size: 1.2rem; color: var(--ink-dim);
  transition: transform 0.4s var(--ease-out);
}
.faq__item[open] .faq__icon { transform: rotate(45deg); color: var(--navy-bright); }
.faq__item p { color: var(--ink-dim); max-width: 42rem; padding: 0 0.2rem 1.6rem; }

/* ── Motion design ─────────────────────────────── */
.motion {
  padding: clamp(4.5rem, 12vh, 8rem) var(--pad);
  border-top: 1px solid var(--line);
  background: linear-gradient(180deg, var(--bg) 0%, #070a12 45%, var(--bg) 100%);
}
.motion__head { max-width: 46rem; margin-bottom: clamp(2.5rem, 7vh, 4.5rem); }
.motion__title {
  font-family: var(--font-body); font-weight: 400;
  font-size: clamp(1.95rem, 5vw, 4rem);
  line-height: 0.96; letter-spacing: -0.05em;
  margin: 1.2rem 0 1.5rem;
}
.motion__title > span { display: block; overflow: hidden; padding-bottom: 0.08em; }
.motion__lede { color: var(--ink-dim); max-width: 34rem; }

.motion__body {
  display: grid; grid-template-columns: 1fr auto;
  gap: clamp(2rem, 6vw, 5rem); align-items: start;
}
.motion__list { display: flex; flex-direction: column; gap: clamp(1.4rem, 3.5vh, 2.4rem); }
.motion__item { display: flex; gap: clamp(0.9rem, 2vw, 1.6rem); align-items: flex-start; }
.motion__item-key {
  flex: 0 0 auto; color: var(--navy-bright);
  letter-spacing: 0.16em; padding-top: 0.35rem;
}
.motion__item h3 {
  font-family: var(--font-body); font-weight: 400;
  font-size: clamp(1.05rem, 1.7vw, 1.35rem);
  letter-spacing: -0.035em; line-height: 1.2;
  color: #f2f0ea; margin-bottom: 0.4rem;
}
.motion__item p { font-size: 0.92rem; line-height: 1.55; color: var(--ink-dim); max-width: 32rem; }

.motion__foot {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 2rem; flex-wrap: wrap;
  margin-top: clamp(2.5rem, 7vh, 4.5rem);
  padding-top: clamp(1.2rem, 3vh, 2rem);
  border-top: 1px solid var(--line);
}
.motion__foot-note { color: var(--ink-dim); max-width: 30rem; }

/* ── The listing reel ──────────────────────────────
   A phone-shaped 9:16 frame with the shots stacked inside it; JS cuts between
   them and pushes each one slowly. Story-style segment bars along the top
   because that is the format this deliverable is actually made for. */
.reel { display: flex; flex-direction: column; align-items: center; gap: 0.9rem; }
.reel__frame {
  position: relative;
  width: clamp(13rem, 21vw, 17.5rem);
  aspect-ratio: 9 / 16;
  border-radius: 1.1rem; overflow: hidden;
  border: 1px solid rgba(233, 230, 223, 0.16);
  background: #0a0c12;
  box-shadow: 0 40px 90px rgba(0, 0, 0, 0.6);
}
.reel__shots { position: absolute; inset: 0; }
.reel__shots img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  opacity: 0; will-change: transform, opacity;
}
/* Segment bars, one per shot. */
.reel__bars {
  position: absolute; top: 0.65rem; left: 0.65rem; right: 0.65rem; z-index: 2;
  display: flex; gap: 0.25rem;
}
.reel__bar {
  position: relative; flex: 1 1 0%; height: 2px;
  border-radius: 2px; background: rgba(255, 255, 255, 0.28);
  overflow: hidden;
}
.reel__bar i {
  position: absolute; inset: 0; display: block;
  background: #fff; transform: scaleX(0); transform-origin: left center;
  will-change: transform;
}
.reel__meta {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  display: flex; justify-content: space-between; gap: 1rem;
  padding: 2.5rem 0.9rem 0.85rem;
  color: rgba(255, 255, 255, 0.82); letter-spacing: 0.14em;
  background: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.75));
}
.reel__note { color: var(--ink-faint); letter-spacing: 0.16em; }

@media (max-width: 1000px) {
  .motion__body { grid-template-columns: 1fr; justify-items: start; }
  /* justify-self, not align-self — in a single-column grid the horizontal
     axis is the inline one, and align-self does nothing to it. */
  .reel { justify-self: center; }
}

/* ── Lead magnet — missed-call audit ───────────── */
.audit {
  position: relative;
  padding: clamp(4rem, 11vh, 7.5rem) var(--pad);
  border-top: 1px solid var(--line);
  background: linear-gradient(180deg, var(--bg) 0%, #080b13 52%, var(--bg) 100%);
}
.audit__inner {
  display: grid; grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(2rem, 6vw, 5rem); align-items: start;
  max-width: 78rem; margin: 0 auto;
}
.audit__title {
  font-family: var(--font-body); font-weight: 400;
  font-size: clamp(1.85rem, 4.4vw, 3.5rem);
  line-height: 0.98; letter-spacing: -0.05em;
  margin: 1.2rem 0 1.4rem;
}
.audit__title > span { display: block; overflow: hidden; padding-bottom: 0.08em; }
.audit__lede { color: var(--ink-dim); max-width: 32rem; }
.audit__points { margin-top: 1.7rem; display: flex; flex-direction: column; gap: 0.65rem; }
.audit__points li {
  position: relative; padding-left: 1.5rem;
  font-size: 0.95rem; color: var(--ink-dim);
}
.audit__points li::before {
  content: ""; position: absolute; left: 0; top: 0.66em;
  width: 9px; height: 1px; background: var(--navy-bright);
}

.audit__form {
  display: flex; flex-direction: column; gap: 1.15rem;
  padding: clamp(1.4rem, 3vw, 2.4rem);
  border: 1px solid var(--line); border-radius: 14px;
  background: rgba(255, 255, 255, 0.02);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.audit__field { display: flex; flex-direction: column; gap: 0.45rem; }
.audit__field label { color: var(--ink-faint); letter-spacing: 0.18em; }
.audit__field input {
  background: transparent; border: 0;
  border-bottom: 1px solid var(--line-strong);
  padding: 0.55rem 0.1rem;
  font-family: var(--font-body); font-size: 1rem; font-weight: 300;
  color: var(--ink);
  border-radius: 0; /* iOS rounds inputs by default */
  transition: border-color 0.3s var(--ease-out);
}
.audit__field input::placeholder { color: rgba(216, 216, 216, 0.22); }
.audit__field input:focus { outline: none; border-bottom-color: var(--navy-bright); }
.audit__field input:focus-visible { outline: none; }
.audit__submit { margin-top: 0.4rem; width: 100%; }
.audit__fine { color: var(--ink-faint); letter-spacing: 0.14em; line-height: 1.7; }
.audit__status { font-size: 0.85rem; line-height: 1.5; color: var(--navy-bright); }
.audit__status:empty { display: none; }
.audit__status.is-error { color: #e8a2a2; }
.audit__status.is-success { color: #a3d9b1; }
@media (max-width: 900px) {
  .audit__inner { grid-template-columns: 1fr; }
}

/* ── Footer — closing screen ─────────────────────
   Copy stacked in the upper half, then a field of hairlines taking whatever
   height is left under it. The field is a flex item rather than an absolute
   band at a guessed percentage, so the copy can never sit on top of it. */
.footer {
  position: relative;
  min-height: 100svh;
  display: flex; flex-direction: column;
  padding: clamp(5rem, 11vh, 7.5rem) var(--pad) 0;
  border-top: 1px solid var(--line);
  overflow: hidden;
  background:
    radial-gradient(65% 45% at 22% 58%, rgba(63, 78, 140, 0.16), transparent 70%),
    var(--bg);
}

.footer__top {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 2rem; color: var(--ink-dim); letter-spacing: 0.14em;
}
.footer__clock i { font-style: normal; color: var(--ink-faint); margin: 0 0.25rem; }
#footer-clock { color: var(--ink); font-variant-numeric: tabular-nums; }

/* Giant type left, arrow link right, both sitting on the same baseline. */
.footer__lead {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: clamp(1.5rem, 6vw, 5rem);
  margin: clamp(2rem, 6vh, 4rem) 0 clamp(2.4rem, 7vh, 4rem);
}
.footer__giant {
  display: block;
  font-family: var(--font-body); font-weight: 400;
  /* Floor is set by the longest line, "something worth": 15 chars at ~0.44em
     must clear 320px minus the pad, or it wraps — and a wrapped line breaks
     the reveal, because the mask that hides the incoming chars is the line
     box itself. */
  font-size: clamp(2.6rem, 5.6vw, 5.4rem);
  line-height: 0.95; letter-spacing: -0.05em;
}
/* padding-bottom clears the descenders in "Ready" and "something", which the
   masked char reveal would otherwise cut off. */
.footer__giant-line {
  display: block; overflow: hidden;
  padding-bottom: 0.12em;
  transition: color 0.4s;
}
.footer__giant:hover .footer__giant-line { color: var(--navy-bright); }
.footer__collab { flex: 0 0 auto; min-width: 15rem; margin-bottom: 0.7rem; }

.footer__base {
  display: grid; grid-template-columns: 1fr auto auto;
  gap: clamp(1.5rem, 5vw, 5rem);
}
.footer__base-title {
  font-weight: 400; letter-spacing: 0.2em;
  color: var(--ink-faint); margin-bottom: clamp(0.7rem, 2vh, 1.1rem);
}
.footer__copy { color: var(--ink-dim); letter-spacing: 0.14em; }
.footer__place { color: var(--ink-faint); letter-spacing: 0.14em; margin-top: 0.5rem; }
.footer__hint { color: var(--ink-faint); letter-spacing: 0.14em; margin-top: clamp(1rem, 3vh, 2rem); }
.footer__row { display: flex; gap: 0.75rem; font-size: 0.95rem; line-height: 1.85; }
.footer__row-key { flex: 0 0 1.2rem; color: var(--ink-faint); padding-top: 0.35rem; }
.footer__grid {
  display: grid; grid-template-columns: repeat(2, minmax(5.5rem, auto));
  gap: 0.1rem 2.2rem; font-size: 0.95rem; line-height: 1.85;
}
.footer__row a,
.footer__grid a { color: var(--ink-dim); transition: color 0.35s var(--ease-out); }
.footer__row a:hover,
.footer__grid a:hover { color: var(--ink); }

/* ── The hairline field ────────────────────────────
   Rows of thin rules of varying length, woven across columns. Lines brighten
   and stretch under the pointer. Deterministic widths, not random, so the
   composition is the same on every load. */
.footer__field {
  position: relative;
  flex: 1 1 auto;
  min-height: clamp(9rem, 30vh, 22rem);
  margin-top: clamp(1.5rem, 5vh, 3.5rem);
  overflow: hidden;
}
.footer__line {
  position: absolute; height: 1px;
  background: var(--ink);
  opacity: 0.12;
  transform-origin: left center;
  will-change: transform, opacity;
}

@media (max-width: 900px) {
  .footer__base { grid-template-columns: 1fr 1fr; gap: 2rem 1.5rem; }
  .footer__base-col:first-child { grid-column: 1 / -1; }
  .footer__lead { flex-direction: column; align-items: stretch; }
  .footer__collab { min-width: 100%; margin-bottom: 0; }
}
@media (max-width: 620px) {
  .footer { min-height: 0; }
  .footer__base { grid-template-columns: 1fr; }
  .footer__base-col:first-child { grid-column: auto; }
  .footer__top { flex-direction: column; gap: 0.5rem; }
  .footer__field { min-height: 11rem; }
}

/* ── Reveal defaults (no-motion-first) ─────────── */
[data-reveal], [data-reveal-stagger] > *, [data-split] .char, [data-split-lines] .line-inner {
  opacity: 1;
}


/* ── Client stories ────────────────────────────────────
   Light editorial screen: oversized heading with a short
   lede beside it, a hairline with a registration mark,
   then a client list that drives one large quote. */
.stories {
  position: relative; min-height: 100svh;
  background: linear-gradient(180deg, #ffffff 0%, #e8e8ea 100%);
  color: #2b2d33;
  padding: clamp(6rem, 12vh, 9rem) var(--pad) clamp(4rem, 8vh, 6rem);
  display: flex; flex-direction: column; justify-content: center;
  gap: clamp(2.5rem, 6vh, 4.5rem);
}
.stories__top {
  display: grid; grid-template-columns: 1.6fr 1fr;
  gap: clamp(2rem, 6vw, 5rem); align-items: start;
}
.stories__title {
  font-family: var(--font-body);
  font-size: clamp(2.8rem, 7.4vw, 6.6rem);
  font-weight: 400; line-height: 0.92; letter-spacing: -0.055em;
  color: #2b2d33;
}
.stories__lede {
  font-size: 0.95rem; line-height: 1.5; max-width: 17rem;
  color: rgba(43, 45, 51, 0.72); padding-top: 0.6rem;
}
.stories__rule { position: relative; height: 1px; background: rgba(43,45,51,0.16); }
.stories__rule svg {
  position: absolute; left: 50%; top: 50%;
  width: 13px; height: 13px; margin: -6.5px 0 0 -6.5px;
  stroke: rgba(43,45,51,0.5); stroke-width: 1; overflow: visible;
}
.stories__body {
  display: grid; grid-template-columns: 1fr 2.1fr;
  gap: clamp(2rem, 6vw, 5rem); align-items: start;
}
.stories__list { display: flex; flex-direction: column; gap: 0.55rem; }
.stories__name {
  display: flex; align-items: center; gap: 0.6rem;
  font-family: var(--font-mono); font-size: 0.72rem;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: rgba(43, 45, 51, 0.34);
  background: none; border: 0; padding: 0; cursor: pointer;
  text-align: left; transition: color 0.35s var(--ease-out);
}
.stories__name i { opacity: 0; transition: opacity 0.35s, transform 0.35s; transform: translateX(-4px); }
.stories__name:hover { color: rgba(43, 45, 51, 0.7); }
.stories__name.is-active { color: #2b2d33; }
.stories__name.is-active i { opacity: 1; transform: translateX(0); }
.stories__quote {
  font-family: var(--font-body);
  font-size: clamp(1.15rem, 2.5vw, 2.15rem);
  font-weight: 400; line-height: 1.28; letter-spacing: -0.035em;
  color: #2b2d33;
}
.stories__who { display: flex; align-items: center; gap: 0.9rem; margin-top: clamp(2rem, 5vh, 3.2rem); }
.stories__avatar {
  width: 54px; height: 62px; flex-shrink: 0; border-radius: 2px;
  background: linear-gradient(150deg, #cfd6e6, #d8cfc4);
  display: grid; place-items: center;
}
.stories__avatar svg { width: 54%; height: 54%; fill: #2b2d33; opacity: 0.82; }
.stories__person { font-size: 0.92rem; line-height: 1.35; }
.stories__person b { font-weight: 500; display: block; color: #2b2d33; }
.stories__person span { color: rgba(43, 45, 51, 0.55); }
@media (max-width: 900px) {
  .stories__top, .stories__body { grid-template-columns: 1fr; }
  .stories__lede { max-width: none; }
}


/* ── Services exit wipe ────────────────────────────
   White because the screen it hands over to is white: once shut, the slab and
   Client stories are the same colour and the seam disappears. Grows from each
   stripe's bottom edge, exactly like the belt wipe further up the page. */
.services__blinds {
  position: absolute; inset: 0; z-index: 40;
  width: 100%; height: 100%;
  pointer-events: none;
}

/* ── Consent banner ─────────────────────────────── */
.consent {
  position: fixed; z-index: 200; right: clamp(1rem, 3vw, 3rem); bottom: clamp(1rem, 3vw, 3rem);
  width: min(25rem, calc(100vw - 2rem)); padding: 1.15rem 1.2rem;
  background: #11131a; border: 1px solid rgba(255,255,255,.22); color: #f3f2ed;
  box-shadow: 0 18px 50px rgba(0,0,0,.36);
}
.consent[hidden] { display: none; }
.consent__title { margin: 0 0 .55rem; font-size: .67rem; letter-spacing: .11em; color: #d8b744; }
.consent p:not(.consent__title) { margin: 0; font-size: .85rem; line-height: 1.5; color: rgba(255,255,255,.8); }
.consent__actions { display: flex; align-items: center; gap: .8rem; margin: 1rem 0 .75rem; }
.consent__accept { font-size: .66rem; min-height: 2.4rem; }
.consent__decline { appearance: none; border: 0; background: none; color: rgba(255,255,255,.75); cursor: pointer; font: .67rem var(--font-mono); letter-spacing: .08em; }
.consent a { color: rgba(255,255,255,.65); font: .66rem var(--font-mono); }
/* NB: the stripes themselves are SVG rects built in JS and animated on their
   `height`/`y` ATTRIBUTES, not on a transform. The div-era `.services__stripe`
   rule that used to live here (scaleY 0 from centre bottom) is gone — its
   scaleY counterpart in JS was silently collapsing every rect to nothing. */
