/* ─────────────────────────────────────────────────────────────
   3 Block Studio — landing page theme
   3 variants share components; differences are theme tokens.
   ───────────────────────────────────────────────────────────── */

@import url('https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600;700;800;900&family=Geist+Mono:wght@400;500&family=Instrument+Serif:ital@0;1&family=Bricolage+Grotesque:opsz,wght@12..96,300..800&family=Fraunces:ital,opsz,wght@0,9..144,300..800;1,9..144,300..800&family=Space+Grotesk:wght@400;500;700&display=swap');

/* ── Defaults (overridden by Tweaks) ─────────────────────────── */
:root {
  --font-display: 'Geist', ui-sans-serif, system-ui, sans-serif;
  --font-serif:   'Instrument Serif', 'Times New Roman', serif;
  --font-mono:    'Geist Mono', ui-monospace, monospace;
  --accent: #E64B2C;
  --motion: 1;            /* 0..2 — scales animation distance/duration */
  --reveal-d: calc(0.9s * var(--motion));
  --reveal-y: calc(40px * var(--motion));
}
[data-font="bricolage"] {
  --font-display: 'Bricolage Grotesque', system-ui, sans-serif;
  --font-serif:   'Fraunces', serif;
}
[data-font="space"] {
  --font-display: 'Space Grotesk', system-ui, sans-serif;
  --font-serif:   'Instrument Serif', serif;
}

* { box-sizing: border-box; margin: 0; padding: 0; -webkit-font-smoothing: antialiased; }
html, body { font-family: var(--font-display); }

/* ── Variant tokens ──────────────────────────────────────────── */
.variant {
  position: relative;
  width: 100%;
  max-width: 1680px;
  margin: 0 auto;
  font-family: var(--font-display);
  background: var(--bg);
  color: var(--fg);
  /* `clip` not `hidden`: an overflow:hidden box is still programmatically
     scrollable, so when focus moved to an element below the fold (e.g.
     returning from a modal) the browser scrolled this whole-page wrapper
     internally — shifting content up and cropping the top with no way to
     scroll back. `clip` clips the same decorative overflow but is never a
     scroll container, so the top can't get stuck off-screen. */
  overflow: clip;
  --line: color-mix(in oklab, var(--fg) 14%, transparent);
  --muted: color-mix(in oklab, var(--fg) 55%, transparent);
  --hover: color-mix(in oklab, var(--fg) 6%, transparent);
}
.variant[data-variant="black"] {
  --bg: #0a0a0a;
  --fg: #f4f1ea;
}
.variant[data-variant="paper"] {
  --bg: #f0ece2;
  --fg: #0a0a0a;
}
.variant[data-variant="cinema"] {
  --bg: #0a0a0a;
  --fg: #f4f1ea;
}

/* Cinema variant: per-section invert */
.variant[data-variant="cinema"] .sect--light { background: #f0ece2; color: #0a0a0a;
  --line: rgba(10,10,10,.14); --muted: rgba(10,10,10,.55); --hover: rgba(10,10,10,.06); }
.variant[data-variant="cinema"] .sect--accent { background: var(--accent); color: #0a0a0a;
  --line: rgba(10,10,10,.2); --muted: rgba(10,10,10,.65); }
.variant[data-variant="cinema"] .sect--dark { background: #0a0a0a; color: #f4f1ea;
  --line: rgba(244,241,234,.14); --muted: rgba(244,241,234,.55); --hover: rgba(244,241,234,.06); }

/* Forced overrides (background-tone tweak) */
[data-mode="light"] .variant[data-variant="black"],
[data-mode="light"] .variant[data-variant="cinema"] { background: #f0ece2; color: #0a0a0a;
  --bg:#f0ece2; --fg:#0a0a0a; --line: rgba(10,10,10,.14); --muted: rgba(10,10,10,.55); --hover: rgba(10,10,10,.06); }
[data-mode="light"] .variant[data-variant="cinema"] .sect--dark { background: #0a0a0a; color: #f4f1ea;
  --line: rgba(244,241,234,.14); --muted: rgba(244,241,234,.55); --hover: rgba(244,241,234,.06); }

/* ── Common layout ───────────────────────────────────────────── */
.section { padding: 96px 60px; position: relative; }
.section.section--tight { padding: 60px 60px; }
.row { display: flex; }
.between { display: flex; justify-content: space-between; align-items: baseline; }
.eyebrow {
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.rule { height: 1px; background: var(--line); width: 100%; }

/* ── Sticky section index (left rail) ────────────────────────── */
.idxrail {
  position: absolute; top: 0; left: 24px; width: 28px;
  height: 100%;
  pointer-events: none;
}
.idxrail .idxrail__num {
  position: sticky; top: 24px;
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.14em;
  color: var(--muted);
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  padding: 14px 0;
}

/* ── NAV ─────────────────────────────────────────────────────── */
.nav {
  display: flex; align-items: center; justify-content: space-between;
  padding: 22px 32px;
  font: 500 13px/1 var(--font-display);
  border-bottom: 1px solid var(--line);
  position: relative;
  z-index: 5;
}
.nav__logo {
  font-weight: 700;
  letter-spacing: -0.01em;
  display: flex; align-items: center; gap: 8px;
  color: inherit;
  text-decoration: none;
}
/* Wordmark — site logo used in every nav. An <img> picks up the
   black SVG; dark mode inverts via CSS filter so it reads as light
   on the dark background. Sizing: height drives the visual; aspect
   ratio is preserved automatically by the SVG. */
.wordmark-logo {
  display: block;
  height: 22px;
  width: auto;
  flex-shrink: 0;
  user-select: none;
  -webkit-user-drag: none;
}
html[data-mode="dark"] .wordmark-logo {
  filter: invert(1);
}
.proj-foot__meta a,
.proj-foot__brand,
.projnav .nav__center a,
.projnav__back {
  text-decoration: none;
}
.nav__logo .dot { display: inline-block; width: 10px; height: 10px; background: var(--accent); border-radius: 50%; }
.nav__mark { color: var(--accent); flex-shrink: 0; }
.footer__mark {
  display: inline-block;
  vertical-align: -0.06em;
  margin-right: 0.18em;
  color: var(--accent);
}
.nav__menu { display: flex; gap: 28px; align-items: center; }
.nav__menu a { color: var(--fg); text-decoration: none; opacity: .85; }
.nav__menu a:hover { opacity: 1; color: var(--accent); }
/* Full Archive — visually set apart from the in-page scroll links with
   an outline pill + ↗ glyph, signalling it leaves the landing page for
   a separate route. Consistent treatment across landing / project /
   archive navs (all share .nav__menu). */
.nav__archive {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  opacity: 1 !important;
  font-weight: 500;
  color: var(--fg);
  text-decoration: none;
  transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.nav__archive:hover { background: var(--accent); color: #fff !important; border-color: var(--accent); }
.nav__archiveArrow { font-size: 0.92em; transition: transform 0.25s; }
.nav__archive:hover .nav__archiveArrow { transform: translate(2px, -2px); }
/* On its own page the pill reads as the current location: filled. */
.nav__archive.is-current {
  background: var(--accent); color: #fff !important; border-color: var(--accent);
}
.nav__meta {
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.14em;
  color: var(--muted);
  text-transform: uppercase;
  display: flex; gap: 18px;
  align-items: center;
}
.nav__pulse { width: 6px; height: 6px; border-radius: 50%; background: #4ade80; box-shadow: 0 0 8px #4ade80;
  animation: pulse 1.8s ease-in-out infinite; }
@keyframes pulse { 0%,100% { opacity: .4; } 50% { opacity: 1; } }

/* Theme toggle (sun/moon) — segmented pill */
.themetoggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--hover);
  cursor: pointer;
  user-select: none;
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.themetoggle__thumb {
  position: absolute;
  top: 3px; bottom: 3px;
  width: calc(50% - 3px);
  border-radius: 999px;
  background: var(--accent);
  transition: left 0.28s cubic-bezier(0.7, 0.1, 0.2, 1);
  left: 3px;
}
[data-mode="light"] .themetoggle__thumb { left: calc(50%); }
.themetoggle__opt {
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 14px;
  color: var(--muted);
  transition: color 0.2s;
}
.themetoggle__opt[data-active="1"] { color: #fff; }
[data-mode="light"] .themetoggle__opt[data-active="1"] { color: #0a0a0a; }
[data-mode="light"] .themetoggle .moon { color: #0a0a0a; }
.themetoggle svg { width: 12px; height: 12px; }

/* ── HERO ────────────────────────────────────────────────────── */
.hero { padding: 140px 60px 120px; position: relative; }
.hero__eyebrow { display: flex; justify-content: space-between; padding-bottom: 80px; }
.hero__big {
  font: 700 clamp(64px, 9.5vw, 132px)/0.96 var(--font-display);
  letter-spacing: -0.04em;
  font-feature-settings: "ss01", "ss02";
  overflow: hidden;
}
.hero__big .word {
  display: flex;
  align-items: center;
  gap: 0.32em;
  line-height: 1.02;
}
.hero__big .word .gly {
  display: inline-block;
  flex: 0 0 auto;
  width: 0.85em; height: 0.85em;
  border-radius: 4px;
}
.hero__big .word--end { color: var(--accent); }
.hero__big i {
  font: italic 400 1em/1 var(--font-serif);
  letter-spacing: -0.02em;
}
.hero__sub {
  margin-top: 56px;
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 60px; align-items: end;
}
.hero__sub .lede {
  max-width: 480px;
  font: 400 22px/1.32 var(--font-display);
  letter-spacing: -0.01em;
  color: var(--muted);
}
.hero__sub .lede strong { color: var(--fg); font-weight: 500; }
.hero__sub .lede i { font-family: var(--font-serif); font-weight: 400; font-style: italic; color: var(--fg); }
.hero__sub .meta { text-align: right; font: 500 12px/1.4 var(--font-mono); color: var(--muted);
  letter-spacing: 0.1em; text-transform: uppercase; }
.hero__sub .meta b { display: block; color: var(--fg); font-weight: 500; margin-top: 4px; }

/* Hero entrance animation. Strategy: base state is the FINAL visible state
   (opacity 1, no transform) so that if the browser ever throttles or skips
   the animation (which it does for backgrounded iframes), the user still
   sees the hero. The pre-entry state is only applied while `.is-loading`
   sits on the hero section — JS removes that class on mount, kicking off
   a CSS transition. If the transition itself doesn't run, properties snap
   to base = visible, which is the correct fail-open behaviour. */
.hero__anim {
  opacity: 1;
  transform: none;
  transition: opacity 0.6s ease,
              transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1);
  transition-delay: calc(var(--i, 0) * 0.12s);
}
.hero.is-loading .hero__anim {
  opacity: 0;
  transform: translateY(20px);
  transition: none;
}

/* ── SHOWREEL ────────────────────────────────────────────────── */
/* Embedded Framerate.tv iframe with text/graphic overlays on top.
   The overlay layer fades out on first click (when `.is-playing` lands
   on the host section) so the video carries the frame alone from then
   on. The host's background colour fills any gap while the iframe
   poster loads.

   The section is constrained to a 16:9 box (the video's native aspect
   ratio) so the Framerate player fills it edge-to-edge with no side
   letterboxing. Width caps at 1600px and never exceeds 88% of the
   viewport, with a min so mobile portrait viewports don't collapse the
   frame to thumbnail size. */
.showreel {
  position: relative;
  width: min(88vw, 1600px);
  aspect-ratio: 16 / 9;
  margin: 0 auto;
  overflow: hidden;
  background: #0a0e08;
  color: #fff;
  border-radius: 20px;
  /* Hide the native cursor — we draw our own circular indicator. */
  cursor: none;
}
@media (max-width: 720px) {
  /* On small viewports give back a bit more width — the 16:9 height
     follows automatically. */
  .showreel { width: 94vw; border-radius: 14px; }
}
.showreel__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0;
  z-index: 0;
  background: transparent;
  /* Click bubbles up to the section so our custom cursor + play logic
     stays in charge until playback starts. After that the iframe owns
     pointer interactions. */
  pointer-events: none;
}
.showreel.is-playing { cursor: default; }
.showreel.is-playing .showreel__video { pointer-events: auto; }
/* Looping backdrop reel — fills the frame behind the overlay, replacing
   the static thumbnail. Click-through so the section play handler fires;
   unmounts on play so only the real reel above remains. */
.showreel__loop {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0; z-index: 0; display: block;
  background: #0a0e08;
  pointer-events: none;
}
.showreel__overlay {
  position: absolute; inset: 0;
  z-index: 3;
  pointer-events: none;
  transition: opacity 0.4s ease;
}
.showreel.is-playing .showreel__overlay {
  opacity: 0;
}
/* A subtle bottom vignette keeps the title legible over a bright video
   poster. Sits between the iframe and the overlay text. Fades with the
   overlay on play. */
.showreel__overlay::before {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(0,0,0,0.25) 0%, transparent 30%, transparent 55%, rgba(0,0,0,0.55) 100%);
  pointer-events: none;
}
.showreel__title {
  position: absolute;
  left: 44px; bottom: 36px;
  font: 600 clamp(140px, 16vw, 248px)/0.86 var(--font-display);
  letter-spacing: -0.045em;
  color: #fff;
  z-index: 3;
  font-feature-settings: "ss01";
  display: flex;
  align-items: baseline;
}
.showreel__title i { font-family: var(--font-serif); font-style: italic; font-weight: 400; letter-spacing: -0.02em; }
.showreel__tag {
  position: absolute;
  right: 56px; top: 38%;
  text-align: right;
  z-index: 2;
}
.showreel__tag h3 {
  font: 500 32px/1.1 var(--font-display);
  letter-spacing: -0.02em;
  color: #fff;
}
.showreel__tag h3 i { font-family: var(--font-serif); font-style: italic; font-weight: 400; }
.showreel__meta {
  position: absolute; left: 56px; top: 36%;
  z-index: 2;
  font: 500 11px/1.6 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.7);
}
.showreel__meta b { display: block; color: #fff; font-weight: 500; margin-bottom: 8px; }
.showreel__counter {
  position: absolute; left: 48px; top: 50%; transform: translateY(-50%);
  font: 700 320px/0.85 var(--font-display);
  letter-spacing: -0.06em;
  color: rgba(255,255,255,0.04);
  z-index: 1;
  font-variant-numeric: tabular-nums;
}

/* Custom circular play cursor. Centered on the pointer; scales up
   slightly when active. Hidden by default, shown when the pointer is
   inside the frame AND the video hasn't started playing. */
.showreel__cursor {
  position: absolute;
  left: 0; top: 0;
  width: 96px; height: 96px;
  border-radius: 50%;
  background: rgba(255,255,255,0.95);
  color: #0a0a0a;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 2px;
  pointer-events: none;
  z-index: 6;
  /* Base state is HIDDEN (no .is-show class). The transition runs to
     visible when .is-show is added; if the transition is throttled the
     property snaps directly to the target value, which is still correct
     in both directions. We deliberately do not use scale here because
     scale is composed with the position-tracking transform set inline. */
  opacity: 0;
  transition: opacity 0.18s ease;
  mix-blend-mode: normal;
  box-shadow: 0 8px 40px -8px rgba(0,0,0,0.4);
  will-change: transform, opacity;
}
.showreel__cursor.is-show { opacity: 1; }
.showreel__cursorIcon {
  font-size: 22px;
  line-height: 1;
  margin-left: 4px; /* optical centring for the ▶ glyph */
}
.showreel__cursorLabel {
  font: 500 9px/1 var(--font-mono);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin-top: 6px;
  opacity: 0.7;
}

/* ── MANIFESTO ───────────────────────────────────────────────── */
.manifesto { padding: 140px 60px 72px; }
.manifesto__body {
  font: 500 clamp(28px, 3.6vw, 56px)/1.18 var(--font-display);
  letter-spacing: -0.02em;
  max-width: 1100px;
}
.manifesto__body .hl {
  position: relative;
  padding: 0 0.12em;
  background: var(--accent);
  color: #fff;
  white-space: nowrap;
}
.variant[data-variant="cinema"] .manifesto__body .hl { color: #0a0a0a; background: #fff; }
.manifesto__body i { font-family: var(--font-serif); font-style: italic; font-weight: 400; letter-spacing: -0.01em; }
.manifesto__body sup {
  font: 500 0.42em/1 var(--font-mono);
  vertical-align: super;
  margin-left: 2px;
  color: var(--accent);
}
.manifesto__foot {
  margin-top: 64px;
  display: grid; grid-template-columns: 1fr 1fr 1fr;
  gap: 32px;
  padding-top: 28px;
  border-top: 1px solid var(--line);
  font: 400 13px/1.5 var(--font-display);
  color: var(--muted);
}
.manifesto__foot b {
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--fg);
  display: block; margin-bottom: 10px;
}

/* ── CLIENT LOGOS MARQUEE ────────────────────────────────────── */
/* Infinite horizontal scroll of monochrome client marks. The track
   holds the logo list twice; the keyframe translates by -50% so the
   second copy lands exactly where the first started, giving a
   seamless loop with no JS. Marquee pauses on hover so users can
   actually read individual logos. Edge fades soften the wraparound. */
.clientlogos {
  padding: 40px 0 96px;
  overflow: hidden;
}
.clientlogos__head {
  text-align: center;
  margin-bottom: 36px;
  padding: 0 60px;
}
.clientlogos__viewport {
  position: relative;
  width: 100%;
  overflow: hidden;
  /* Soft fade on left/right so logos drift in/out of view rather than
     hard-clipping at the section edges. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 8%, #000 92%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 8%, #000 92%, transparent 100%);
}
.clientlogos__track {
  display: inline-flex;
  align-items: center;
  gap: 96px;
  padding-right: 96px;
  animation: logomarquee calc(60s / var(--motion)) linear infinite;
  will-change: transform;
}
.clientlogos__viewport:hover .clientlogos__track { animation-play-state: paused; }
/* Stop the keyframe entirely when the section is off-screen. JS adds
   the .is-paused class via IntersectionObserver; the marquee picks up
   where it left off when the section scrolls back into view. */
.clientlogos.is-paused .clientlogos__track { animation-play-state: paused; }
.clientlogos__cell {
  flex-shrink: 0;
  height: 112px;
  display: flex; align-items: center; justify-content: center;
}
.clientlogos__cell img {
  height: 100%;
  width: auto;
  max-width: 340px;
  object-fit: contain;
  display: block;
  /* Light mode: keep the black logos, soften with grayscale + opacity
     so they feel like a quiet sub-section rather than competing with
     project work below. */
  filter: grayscale(1) opacity(0.62);
  transition: filter 0.3s ease;
  user-select: none;
  -webkit-user-drag: none;
}
.clientlogos__cell img:hover {
  filter: grayscale(0) opacity(1);
}
/* Dark mode: invert black-on-transparent PNGs so they read as white. */
[data-mode="dark"] .clientlogos__cell img {
  filter: brightness(0) invert(1) opacity(0.7);
}
[data-mode="dark"] .clientlogos__cell img:hover {
  filter: brightness(0) invert(1) opacity(1);
}
@keyframes logomarquee { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .clientlogos__track { animation: none; transform: none; flex-wrap: wrap; justify-content: center; }
  .clientlogos__viewport { mask-image: none; -webkit-mask-image: none; }
}

/* ── MARQUEE ─────────────────────────────────────────────────── */
.marquee {
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
  padding: 28px 0;
  white-space: nowrap;
  display: flex;
}
.marquee__track {
  display: inline-flex;
  gap: 56px;
  padding-right: 56px;
  flex-shrink: 0;
  animation: marquee calc(38s / var(--motion)) linear infinite;
  font: 700 64px/1 var(--font-display);
  letter-spacing: -0.03em;
}
.marquee__track .star { color: var(--accent); display: inline-flex; align-items: center; }
.marquee--big .marquee__track { font-size: 92px; }
@keyframes marquee { to { transform: translateX(-100%); } }
.marquee.is-paused .marquee__track { animation-play-state: paused; }

/* ── PROJECTS GRID ───────────────────────────────────────────── */
.projects { padding: 96px 60px 96px; }
.projects__head { display: flex; justify-content: space-between; align-items: flex-end;
  padding-bottom: 36px; border-bottom: 1px solid var(--line); margin-bottom: 36px; }
.projects__head h2 {
  font: 700 96px/0.92 var(--font-display);
  letter-spacing: -0.04em;
}
.projects__head h2 i { font-family: var(--font-serif); font-style: italic; font-weight: 400; color: var(--accent); }
.projects__head .count {
  font: 500 12px/1 var(--font-mono);
  color: var(--muted);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
/* .projects__grid + .proj* defined below in mosaic / supersolid override */

/* ── SERVICES (6A-style menu) ────────────────────────────────── */
.services { padding: 96px 60px; }
.services__head { padding-bottom: 28px; margin-bottom: 28px; border-bottom: 1px solid var(--line);
  display: flex; justify-content: space-between; align-items: flex-end; }
.services__head h2 {
  font: 700 96px/0.92 var(--font-display);
  letter-spacing: -0.04em;
}
.services__head h2 i { font-family: var(--font-serif); font-style: italic; font-weight: 400; }
/* Three-column service cards on desktop, collapsing responsively. Cards
   are arranged as a single row with vertical dividers between columns and
   a continuous top border. */
.services__list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  border-top: 1px solid var(--line);
}
.svc {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 36px 32px 32px;
  cursor: pointer;
  transition: background 0.3s;
  min-height: 360px;
}
.svc + .svc { border-left: 1px solid var(--line); }
.svc:hover { background: var(--hover); }
.svc__num {
  font: 700 88px/0.85 var(--font-display);
  letter-spacing: -0.05em;
  color: var(--accent);
  font-feature-settings: "tnum";
}
.svc__body { display: flex; flex-direction: column; gap: 10px; margin-top: auto; padding-top: 28px; }
.svc__title { font: 700 24px/1.1 var(--font-display); letter-spacing: -0.02em; text-transform: uppercase; }
.svc__desc { font: 400 14px/1.5 var(--font-display); color: var(--muted); }
.svc__tags { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 8px; }
.svc__arrow {
  position: absolute;
  top: 32px; right: 28px;
  font-size: 22px;
  color: var(--muted);
  transition: transform 0.3s, color 0.3s;
}
.svc:hover .svc__arrow { transform: translate(4px,-4px); color: var(--accent); }
@media (max-width: 980px) {
  .services__list { grid-template-columns: 1fr 1fr; }
  .svc:nth-child(3n+1) { border-left: 1px solid var(--line); border-left-color: transparent; }
  .svc:nth-child(2n+1) { border-left: none; }
  .svc:nth-child(2n) { border-left: 1px solid var(--line); }
  .svc:nth-child(3) { border-top: 1px solid var(--line); grid-column: 1 / -1; }
}
@media (max-width: 640px) {
  .services__list { grid-template-columns: 1fr; }
  .svc { border-left: none !important; }
  .svc + .svc { border-top: 1px solid var(--line); }
  .svc:nth-child(3) { grid-column: auto; }
}
.svc__tags span {
  font: 500 11px/1 var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--muted);
}
/* ── CLIENTS / INDEX MENU ────────────────────────────────────── */
.clients { padding: 96px 60px 96px; position: relative; }
.clients__head { padding-bottom: 28px; margin-bottom: 14px; border-bottom: 1px solid var(--line);
  display: flex; justify-content: space-between; align-items: flex-end; }
.clients__head h2 {
  font: 700 96px/0.92 var(--font-display);
  letter-spacing: -0.04em;
}
.clients__head h2 i { font-family: var(--font-serif); font-style: italic; font-weight: 400; }
.clients__list { position: relative; }
/* Bottom-of-index route to the full archive — visible on every viewport,
   but it's the primary way to reach the archive on mobile (header nav
   links are hidden there). Reuses the header button verbatim; this rule
   only handles placement (centred, with a divider above for separation). */
.clients__archiveCta {
  margin-top: 40px;
  padding-top: 36px;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: flex-end;
}
.client {
  display: grid;
  grid-template-columns: 32px 1fr 200px 90px 28px;
  gap: 16px; align-items: center;
  padding: 22px 8px;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
  position: relative;
  color: inherit;
  text-decoration: none;
  transition: padding-left 0.3s;
}
.client:hover { padding-left: 24px; }
.client__no { font: 500 11px/1 var(--font-mono); color: var(--muted); letter-spacing: 0.1em; }
.client__name {
  font: 700 44px/1 var(--font-display);
  letter-spacing: -0.025em;
  text-transform: uppercase;
  transition: color 0.2s;
}
.client:hover .client__name { color: var(--accent); }
.client__role {
  font: 400 13px/1.3 var(--font-display);
  color: var(--muted);
}
.client__year { font: 500 11px/1 var(--font-mono); color: var(--muted); letter-spacing: 0.1em; }
.client__arrow { color: var(--muted); transition: color 0.2s, transform 0.3s; font-size: 18px; }
.client:hover .client__arrow { color: var(--accent); transform: translate(4px,-4px); }
.client__hover {
  position: absolute;
  width: 280px; aspect-ratio: 4/3;
  pointer-events: none;
  opacity: 0; transform: translate(-50%, -50%) scale(0.8);
  transition: opacity 0.2s, transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
  z-index: 10;
  overflow: hidden;
}
.client__hover.is-active { opacity: 1; transform: translate(-50%, -50%) scale(1); }
/* Skip painting the hover preview when it's off-screen — saves the
   browser from decoding hero images that no one is currently
   pointing at. The container has fixed dimensions so layout doesn't
   shift when content-visibility kicks in. */
.client__hover { content-visibility: auto; contain-intrinsic-size: 280px 210px; }
.client__hoverArt {
  position: absolute; inset: 0;
  font-size: 32px;
  display: flex; align-items: center; justify-content: center;
}
/* Real image variant. Sits at the same fill as .client__hoverArt — only
   one is visible at a time (the other is `display: none`). */
.client__hoverImg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: none; /* hidden by default; shown when a project has hero set */
}
/* Label sits over whichever fill is active. Strong shadow so it reads
   on a busy image as well as a solid colour block. */
.client__hoverLabel {
  position: absolute;
  left: 0; right: 0;
  bottom: 16px;
  text-align: center;
  z-index: 1;
  font: 600 22px/1.1 var(--font-display);
  letter-spacing: -0.015em;
  color: #fff;
  text-shadow: 0 2px 14px rgba(0,0,0,0.5);
  padding: 0 12px;
}

/* ── TEAM ────────────────────────────────────────────────────── */
.team { padding: 120px 60px; }
.team__row { display: grid; grid-template-columns: 1fr 1.2fr; gap: 80px; align-items: center; }
.team__row--studio {
  cursor: pointer;
  padding: 32px;
  margin: 0 -32px;
  border-radius: 18px;
  transition: background 0.3s, transform 0.4s;
}
.team__row--studio:hover { background: var(--hover); }
.team__row--studio:hover .team__photo { transform: scale(1.015); }
/* Wider Studio hero — fills its column without the portrait-tile
   letterbox feel that the people cards have. The big "3 BLOCK"
   wordmark scales up to match. */
.team__row--studio .team__photo { aspect-ratio: 16/11; }
.team__row--studio .team__photoBig { font-size: clamp(96px, 11vw, 168px); }
.team__name {
  font: 700 144px/0.86 var(--font-display);
  letter-spacing: -0.045em;
}
.team__name i { font-family: var(--font-serif); font-style: italic; font-weight: 400; color: var(--accent); }
.team__role { margin-top: 18px;
  font: 400 14px/1.55 var(--font-display);
  color: var(--muted); max-width: 380px; }
.team__role b { display: block; color: var(--fg); font-weight: 500; margin-bottom: 8px;
  font: 500 11px/1 var(--font-mono); letter-spacing: 0.14em; text-transform: uppercase; }
.team__cta {
  margin-top: 24px;
  display: inline-flex; align-items: center; gap: 10px;
  padding: 10px 16px 10px 18px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg);
  transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.team__cta .arrow {
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px;
}
.team__row--studio:hover .team__cta { background: var(--accent); color: #fff; border-color: var(--accent); }
.team__row--studio:hover .team__cta .arrow { background: #0a0a0a; }

/* ── Back-to-top pill ─────────────────────────────────────────
   Mono-pill styled to match .team__cta / showreel chips. Fixed
   bottom-right, glassy on dark+light. Hidden state lifts + fades
   so it slips away while scrolling and eases back when settled. */
.backToTop {
  position: fixed;
  right: 28px; bottom: 28px;
  z-index: 60;
  display: inline-flex; align-items: center; gap: 9px;
  padding: 10px 16px 10px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: color-mix(in oklab, var(--bg) 78%, transparent);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  color: var(--fg);
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  opacity: 0;
  transform: translateY(14px) scale(0.6);
  pointer-events: none;
  transition: opacity 2s ease 1s, transform 2s cubic-bezier(0.2,0.7,0.2,1) 1s,
              background 0.2s, border-color 0.2s, color 0.2s;
}
.backToTop.is-visible {
  opacity: 0.75;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}
.backToTop.is-visible:hover { opacity: 1; }
.backToTop:hover { background: var(--accent); color: #fff; border-color: var(--accent); }
.backToTop__arrow {
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; line-height: 1;
  transition: background 0.2s, transform 0.3s;
}
.backToTop:hover .backToTop__arrow { background: #0a0a0a; transform: translateY(-2px); }
@media (max-width: 640px) {
  .backToTop { right: 16px; bottom: 16px; }
}
.team__photo {
  position: relative;
  /* People + roster cards stay portrait. The Studio card overrides
     this below — its 4:5 box was creating tall empty bands around
     "3 BLOCK" that read as letterboxing. */
  aspect-ratio: 4/5;
  overflow: hidden;
  background: var(--hover);
  border-radius: 8px;
  transition: transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.team__photoBig {
  position: relative; z-index: 1;
  font: 700 clamp(72px, 9vw, 132px)/0.9 var(--font-display);
  letter-spacing: -0.04em;
  white-space: pre-line;
  text-align: center;
}
/* Looping reel embedded in the Studio card (Framerate iframe). Sits under
   the grain + wordmark, and is click-through (pointer-events:none) so a tap
   on the card still opens the studio profile. */
.art--hasVideo { background: #0a0a0a; }
.team__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;border: 0; z-index: 0; display: block;
  pointer-events: none;
}
.team__videoTint {
  position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(180deg, rgba(10,10,10,0.10) 0%, rgba(10,10,10,0.15) 45%, rgba(10,10,10,0.50) 100%);
}
/* "Live" indicator on the looping Studio reel — a subtly pulsing
   coral dot + mono label pinned to the bottom-left of the video. */
.team__rec {
  position: absolute; left: 22px; bottom: 20px; z-index: 2;
  display: flex; align-items: center; gap: 9px;
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.2em; text-transform: uppercase;
  color: #fff; pointer-events: none;
  text-shadow: 0 1px 10px rgba(0,0,0,0.45);
}
.team__recDot {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--accent);
  animation: recPulse 1.8s ease-in-out infinite;
}
@keyframes recPulse {
  0%, 100% { opacity: 1; box-shadow: 0 0 7px 1px color-mix(in oklab, var(--accent) 75%, transparent); }
  50% { opacity: 0.3; box-shadow: 0 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .team__recDot { animation: none; }
}
/* Transparent layer above the reel iframe so a click anywhere on the
   Studio video reliably opens the profile (cross-origin embeds can
   otherwise swallow the click). */
.team__clickCatch {
  position: absolute; inset: 0; z-index: 3;
  pointer-events: auto; cursor: pointer;
}
.team__row--studio { cursor: pointer; }
.team__plus {
  position: absolute; top: 12px; right: 12px;
  width: 28px; height: 28px; display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 20px;
  border: 1px solid rgba(255,255,255,.4);
  border-radius: 50%;
  z-index: 2;
}
.team__minirow { margin-top: 28px; display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px;
  padding-top: 28px; border-top: 1px solid var(--line); }
.team__mini {
  aspect-ratio: 4/5; position: relative; overflow: hidden;
  background: var(--hover);
  border-radius: 8px;
  cursor: pointer;
  transition: transform 0.35s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.team__mini:hover { transform: translateY(-4px); }
/* Real portrait fills the card; subtle grayscale→colour on hover keeps it
   editorial. Profiles are 4:5 like the card, so cover barely crops. */
.team__miniPhoto {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 28%;
  display: block;
  filter: grayscale(1) contrast(1.02);
  transition: filter 0.4s ease, transform 0.5s cubic-bezier(0.2,0.8,0.2,1);
}
.team__mini:hover .team__miniPhoto { filter: grayscale(0) contrast(1); transform: scale(1.03); }
/* Bottom scrim so the white name + role stay legible over light portraits. */
.team__mini--person .art::after {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(180deg, transparent 42%, rgba(0,0,0,0.12) 60%, rgba(0,0,0,0.72) 100%);
  pointer-events: none;
}
.team__mini .ph {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.team__miniBig {
  position: relative; z-index: 1;
  font: 700 clamp(48px, 5vw, 80px)/0.9 var(--font-display);
  letter-spacing: -0.04em;
  text-align: center;
}
.team__mini .mname { position: absolute; left: 14px; bottom: 14px;
  font: 600 16px/1.1 var(--font-display); color: #fff;
  letter-spacing: -0.01em;
  z-index: 2;
  text-shadow: 0 1px 12px rgba(0,0,0,0.5);
}
.team__mini .mname span { display: block; font: 500 10px/1 var(--font-mono);
  letter-spacing: 0.14em; text-transform: uppercase; opacity: 0.85; margin-top: 5px; }
.team__miniArrow {
  position: absolute; top: 12px; right: 12px;
  width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 14px;
  background: rgba(10,10,10,0.55);
  backdrop-filter: blur(8px);
  border-radius: 50%;
  z-index: 2;
  transition: transform 0.3s, background 0.2s;
}
.team__mini:hover .team__miniArrow { background: var(--accent); transform: translate(2px,-2px); }
/* Roster card (the "+7 more" tile) — accent fill, no portrait */
.team__mini--roster .ph { background: var(--accent); color: #0a0a0a; }
.team__mini--roster .team__miniBig { color: #0a0a0a; }
.team__mini--roster .mname { color: #0a0a0a; text-shadow: none; }

/* ── FOOTER MEGA ─────────────────────────────────────────────── */
.footer { padding: 80px 60px 40px; position: relative; overflow: hidden; }
.footer__contact { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: 32px;
  padding-bottom: 64px; border-bottom: 1px solid var(--line); }
.footer__contact .col b {
  display: block;
  font: 500 11px/1 var(--font-mono); letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 14px;
}
.footer__contact .col {
  font: 500 16px/1.45 var(--font-display);
  letter-spacing: -0.01em;
}
.footer__contact .col a { color: var(--fg); text-decoration: none; }
.footer__contact .col a:hover { color: var(--accent); }
.footer__mega {
  margin-top: 36px;
  font: 700 clamp(120px, 16vw, 240px)/0.78 var(--font-display);
  letter-spacing: -0.05em;
  text-transform: uppercase;
  white-space: nowrap;
  display: flex;
  align-items: center; gap: 0.1em;
  text-align: center;
  justify-content: center;
}
.footer__mega .sx { color: var(--accent); font-family: var(--font-serif); font-style: italic; font-weight: 400; }
.footer__base {
  margin-top: 12px;
  display: flex; justify-content: space-between;
  font: 500 11px/1 var(--font-mono); color: var(--muted);
  letter-spacing: 0.12em; text-transform: uppercase;
}

/* ── Reveal — smooth scroll entrance. `.reveal` blocks start hidden
   only once JS arms them (`.reveal--armed`); the observer then adds
   `.is-in` as they enter the viewport. Fail-open: if JS never runs,
   nothing is armed and everything stays visible. ── */
.reveal { /* base — visible until armed */ }
.reveal--right { /* no-op */ }
.stagger > * { /* no-op */ }

@media (prefers-reduced-motion: no-preference) {
  .reveal--armed {
    opacity: 0;
    transform: translateY(42px);
    transition:
      opacity 0.75s cubic-bezier(0.34, 1.56, 0.64, 1),
      transform 0.9s cubic-bezier(0.34, 1.56, 0.64, 1);
    will-change: opacity, transform;
  }
  .reveal--armed.is-in {
    opacity: 1;
    transform: none;
  }
  /* Gentle child cascade inside the main collections — each item
     trails the last so elements settle in sequence, not all at once. */
  .reveal--armed.is-in .projects__grid > *,
  .reveal--armed.is-in .services__list > *,
  /* Exclude the cursor-follow hover preview: it's a child of the list,
     so the cascade's `both` fill mode would otherwise pin it at the
     keyframe end-state (opacity:1) forever — leaving a stray thumbnail
     stuck in the gap below the last row once the section reveals. */
  .reveal--armed.is-in .clients__list > *:not(.client__hover),
  .reveal--armed.is-in .footer__contact > *,
  .reveal--armed.is-in .footer__nav > * {
    animation: revealRise 0.7s cubic-bezier(0.34, 1.56, 0.64, 1) both;
  }
  .reveal--armed.is-in .projects__grid > *:nth-child(n+1),
  .reveal--armed.is-in .services__list > *:nth-child(n+1),
  .reveal--armed.is-in .clients__list > *:nth-child(n+1),
  .reveal--armed.is-in .footer__contact > *:nth-child(n+1),
  .reveal--armed.is-in .footer__nav > *:nth-child(n+1) { animation-delay: 0.05s; }
  .reveal--armed.is-in .projects__grid > *:nth-child(2),
  .reveal--armed.is-in .services__list > *:nth-child(2),
  .reveal--armed.is-in .clients__list > *:nth-child(2),
  .reveal--armed.is-in .footer__contact > *:nth-child(2),
  .reveal--armed.is-in .footer__nav > *:nth-child(2) { animation-delay: 0.12s; }
  .reveal--armed.is-in .projects__grid > *:nth-child(3),
  .reveal--armed.is-in .services__list > *:nth-child(3),
  .reveal--armed.is-in .clients__list > *:nth-child(3),
  .reveal--armed.is-in .footer__contact > *:nth-child(3),
  .reveal--armed.is-in .footer__nav > *:nth-child(3) { animation-delay: 0.19s; }
  .reveal--armed.is-in .projects__grid > *:nth-child(4),
  .reveal--armed.is-in .services__list > *:nth-child(4),
  .reveal--armed.is-in .clients__list > *:nth-child(4),
  .reveal--armed.is-in .footer__contact > *:nth-child(4),
  .reveal--armed.is-in .footer__nav > *:nth-child(4) { animation-delay: 0.26s; }
  .reveal--armed.is-in .projects__grid > *:nth-child(5),
  .reveal--armed.is-in .services__list > *:nth-child(5),
  .reveal--armed.is-in .clients__list > *:nth-child(5) { animation-delay: 0.33s; }
  .reveal--armed.is-in .projects__grid > *:nth-child(6),
  .reveal--armed.is-in .services__list > *:nth-child(6),
  .reveal--armed.is-in .clients__list > *:nth-child(6) { animation-delay: 0.40s; }
  .reveal--armed.is-in .clients__list > *:nth-child(n+7) { animation-delay: 0.46s; }
}
@keyframes revealRise {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Loader cap (initial entrance) ───────────────────────────── */
.loader {
  position: absolute; inset: 0;
  background: var(--bg);
  display: flex; align-items: center; justify-content: center;
  z-index: 100;
  pointer-events: none;
  animation: loaderOut 1.1s 0.4s cubic-bezier(0.7, 0, 0.2, 1) forwards;
}
.loader__text {
  font: 700 96px/1 var(--font-display);
  letter-spacing: -0.04em;
  color: var(--fg);
  overflow: hidden;
}
.loader__text span { display: inline-block; animation: loaderUp 0.6s cubic-bezier(0.2, 0.8, 0.2, 1); }
.loader__text .accent { color: var(--accent); }
@keyframes loaderOut {
  0% { transform: translateY(0); }
  100% { transform: translateY(-100%); }
}
@keyframes loaderUp {
  from { transform: translateY(110%); }
  to { transform: translateY(0); }
}

/* ── Project art placeholders (variant-aware) ────────────────── */
.art {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font: 700 80px/0.9 var(--font-display);
  letter-spacing: -0.04em;
  text-transform: uppercase;
  text-align: center;
  padding: 24px;
  overflow: hidden;
}
.art .grain {
  position: absolute; inset: 0;
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/></filter><rect width='100%' height='100%' filter='url(%23n)' opacity='0.18'/></svg>");
  mix-blend-mode: overlay;
  pointer-events: none;
}
/* 6 distinctive cover treatments — each project gets its own visual identity */
.art--01 { /* Laundromat — yellow grid */
  background: #f7d046;
  color: #0a0a0a;
  background-image:
    repeating-linear-gradient(0deg, transparent 0 23px, rgba(10,10,10,0.06) 23px 24px),
    repeating-linear-gradient(90deg, transparent 0 23px, rgba(10,10,10,0.06) 23px 24px),
    radial-gradient(circle at 30% 60%, rgba(230,75,44,0.4) 0%, transparent 40%),
    #f7d046;
}
.art--02 { /* a2 Milk — pastel cream w/ duotone */
  background: #f4e7d0;
  color: #c63a1a;
  background-image:
    radial-gradient(120% 90% at 50% 110%, rgba(198, 58, 26, 0.25) 0%, transparent 60%),
    #f4e7d0;
}
.art--03 { /* Meta — gradient sweep */
  background: #1f2937;
  color: #f4f1ea;
  background-image:
    conic-gradient(from 220deg at 70% 30%, #1d4ed8 0deg, #7c3aed 90deg, #db2777 180deg, #1f2937 270deg, #1d4ed8 360deg);
  filter: contrast(1.05);
}
.art--04 { /* Quarantine — coral block */
  background: linear-gradient(135deg, #E64B2C 0%, #b8341a 100%);
  color: #fff;
}
.art--05 { /* Cat Capable — earth tones */
  background: linear-gradient(180deg, #4a5544 0%, #2a3324 100%);
  color: #f7d046;
  background-image:
    radial-gradient(60% 50% at 30% 30%, rgba(247,208,70,0.25) 0%, transparent 60%),
    linear-gradient(180deg, #4a5544 0%, #2a3324 100%);
}
.art--06 { /* Capped / Toyota — type-driven black */
  background: #0a0a0a;
  color: #f4f1ea;
  background-image:
    linear-gradient(45deg, transparent 49%, var(--accent) 50%, var(--accent) 51%, transparent 52%),
    linear-gradient(-45deg, transparent 49%, rgba(244,241,234,0.08) 50%, rgba(244,241,234,0.08) 51%, transparent 52%);
}
.art em { font-family: var(--font-serif); font-style: italic; font-weight: 400; }
.art__num { position: absolute; top: 16px; left: 16px; font: 500 11px/1 var(--font-mono); letter-spacing: 0.14em; opacity: 0.8; }
.art__year { position: absolute; bottom: 16px; right: 16px; font: 500 11px/1 var(--font-mono); letter-spacing: 0.14em; opacity: 0.8; }
.art__type { position: absolute; bottom: 16px; left: 16px; font: 500 11px/1 var(--font-mono); letter-spacing: 0.14em; opacity: 0.8; text-transform: uppercase; }

/* ── Projects — staggered 2-column layout (supersolid ref) ──── */
.projects__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 32px;
  row-gap: 100px;
}
/* offset the right column downward so cards interlock */
.projects__grid > :nth-child(even) { margin-top: 160px; }
.proj { display: flex; flex-direction: column; cursor: pointer; color: inherit; text-decoration: none; }
.proj__frame {
  position: relative;
  aspect-ratio: 16/10;
  overflow: hidden;
  background: var(--hover);
}
.proj__tag {
  position: absolute;
  top: 18px; right: 18px;
  z-index: 2;
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.9);
  padding: 7px 12px;
  border-radius: 999px;
  background: rgba(10,10,10,0.4);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.proj__meta {
  margin-top: 18px;
  display: flex; align-items: baseline;
  gap: 16px;
}
.proj__client {
  font: 500 13px/1.2 var(--font-display);
  color: var(--muted);
  letter-spacing: -0.01em;
}
.proj__title {
  font: 700 28px/1.1 var(--font-display);
  letter-spacing: -0.025em;
  flex: 1;
}
.proj__title i { font-family: var(--font-serif); font-style: italic; font-weight: 400; }
.proj__year {
  margin-left: auto;
  font: 500 11px/1 var(--font-mono);
  color: var(--muted);
  letter-spacing: 0.1em;
}
.proj__arrow {
  font-size: 18px;
  color: var(--muted);
  transition: transform 0.3s, color 0.2s;
}
.proj:hover .proj__arrow { color: var(--accent); transform: translate(4px,-4px); }
.proj:hover .proj__art,
.proj:hover .proj__img { transform: scale(1.04); }
.proj__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.proj__art {
  position: absolute; inset: 0;
  transition: transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* ── PROJECT MODAL ───────────────────────────────────────────── */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(10,10,10,0.78);
  backdrop-filter: blur(28px) saturate(120%);
  -webkit-backdrop-filter: blur(28px) saturate(120%);
  z-index: 1000;
  display: flex; align-items: center; justify-content: center;
  padding: 40px;
  pointer-events: auto;
}
.modal-backdrop:not(.is-open) { display: none; }
.modal {
  width: 100%;
  max-width: 1850px;
  max-height: calc(100vh - 48px);
  background: #f0ece2;
  color: #0a0a0a;
  border-radius: 14px;
  overflow: hidden;
  display: flex; flex-direction: column;
  font-family: var(--font-display);
}
[data-mode="dark"] .modal { background: #16140f; color: #f4f1ea; }
.modal__head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 22px 28px;
  border-bottom: 1px solid color-mix(in oklab, currentColor 14%, transparent);
}
.modal__title {
  display: flex; align-items: baseline; gap: 16px;
}
.modal__title h3 {
  font: 600 26px/1 var(--font-display);
  letter-spacing: -0.02em;
}
.modal__title h3 i { font-family: var(--font-serif); font-style: italic; font-weight: 400; }
.modal__title .eyebrow { font: 500 11px/1 var(--font-mono); letter-spacing: 0.12em; text-transform: uppercase; opacity: 0.6; }
.modal__close {
  appearance: none; border: 1px solid color-mix(in oklab, currentColor 18%, transparent);
  background: transparent;
  color: inherit;
  width: 38px; height: 38px; border-radius: 50%;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.2s, color 0.2s, transform 0.3s;
}
.modal__close:hover { background: var(--accent); color: #fff; transform: rotate(90deg); }
.modal__body {
  flex: 1; min-height: 0;
  overflow-y: auto;
  padding: 32px 32px 40px;
  display: flex; flex-direction: column; gap: 32px;
}
.modal__video {
  position: relative;
  width: 100%;
  height: 0;
  padding-top: 56.25%; /* 16:9 aspect, fallback for aspect-ratio not always applying in flex */
  background: #050505;
  border-radius: 8px;
  overflow: hidden;
  cursor: pointer;
  flex-shrink: 0;
}
.modal__videoArt {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
}
.modal__videoArt::after {
  content: ""; position: absolute; inset: 0;
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/></filter><rect width='100%' height='100%' filter='url(%23n)' opacity='0.2'/></svg>");
  mix-blend-mode: overlay;
  pointer-events: none;
}
.modal__playbtn {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  width: 110px; height: 110px;
  border-radius: 50%;
  background: rgba(255,255,255,0.92);
  border: none;
  color: #0a0a0a;
  opacity: 0.4;
  display: flex; align-items: center; justify-content: center;
  font-size: 32px;
  cursor: pointer;
  transition: background 0.2s, opacity 0.2s;
}
.modal__video:hover .modal__playbtn { transform: translate(-50%, -50%) scale(1.08); background: var(--accent); color: #fff; }
.modal__playbtn::before {
  content: ""; position: absolute; inset: -12px;
  border-radius: 50%; border: 1px solid rgba(255,255,255,0.4);
}
/* When a Framerate iframe is mounted into the modal video frame it fills
   the same 16:9 container as the placeholder, replacing the play button
   and meta strip. The cursor flips back to default — the iframe owns
   playback from here. */
.modal__videoFrame {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0;
  background: #050505;
  z-index: 4;
}
.modal__video.is-playing,
.modal__portrait.is-playing {
  cursor: default;
}
/* Looping reel preview that fills the studio modal portrait (muted
   background embed). Sits under the play button + tint. */
.modal__portraitLoop {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0; object-fit: cover;
  pointer-events: none;
}
.modal__videoMeta {
  position: absolute; top: 20px; left: 24px; right: 24px;
  z-index: 2;
  display: flex; justify-content: space-between;
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.14em; text-transform: uppercase;
  color: rgba(255,255,255,0.85);
}
.modal__videoMeta b { display: inline-flex; align-items: center; gap: 6px; font-weight: 500; }
.modal__videoMeta b::before {
  content: ""; width: 6px; height: 6px; background: #ef4444; border-radius: 50%;
  display: inline-block;
  box-shadow: 0 0 8px #ef4444;
  animation: pulse 1.6s ease-in-out infinite;
}

.modal__details {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: 24px;
  padding: 4px 0;
}
.modal__details .col b {
  display: block;
  font: 500 10px/1 var(--font-mono);
  letter-spacing: 0.14em; text-transform: uppercase;
  margin-bottom: 8px;
  opacity: 0.55;
}
.modal__details .col { font: 400 14px/1.5 var(--font-display); }
.modal__details .col p { font: 400 15px/1.5 var(--font-display); }

/* Side-scrolling gallery — taller tiles + extra bottom breathing room
   so additional stills can be added later without recropping. */
.modal__gallery {
  position: relative;
  padding-bottom: 24px;
}
.modal__galleryHead {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 14px;
}
.modal__galleryHead b {
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.14em; text-transform: uppercase;
  opacity: 0.6;
}
.modal__galleryControls { display: flex; gap: 6px; }
.modal__galleryControls button {
  appearance: none;
  border: 1px solid color-mix(in oklab, currentColor 18%, transparent);
  background: transparent;
  color: inherit;
  width: 36px; height: 36px;
  border-radius: 50%;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.2s, color 0.2s;
  font-size: 14px;
}
.modal__galleryControls button:hover { background: var(--accent); color: #fff; border-color: var(--accent); }
.modal__galleryControls button:disabled { opacity: 0.3; cursor: default; }
.modal__galleryTrack {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  padding-bottom: 4px;
  scroll-behavior: smooth;
}
.modal__galleryTrack::-webkit-scrollbar { display: none; }
.modal__galleryTrack .tile {
  flex: 0 0 auto;
  width: 560px;
  aspect-ratio: 16/9;
  scroll-snap-align: start;
  position: relative;
  border-radius: 6px;
  overflow: hidden;
  cursor: pointer;
  transition: transform 0.3s;
}
.modal__galleryTrack .tile:hover { transform: translateY(-2px); }
.modal__galleryTrack .tile .art {
  font-size: 64px;
  border-radius: 6px;
}
.modal__galleryTrack .tile__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; display: block;
  -webkit-user-drag: none; user-select: none;
}
/* Click-and-drag affordance for the Selected-work strip. */
.modal__gallery--inBio .modal__galleryTrack { cursor: grab; }
.modal__gallery--inBio .modal__galleryTrack .tile { cursor: grab; }
.modal__gallery--inBio .modal__galleryTrack.is-grabbing,
.modal__gallery--inBio .modal__galleryTrack.is-grabbing .tile { cursor: grabbing; }
.modal__gallery--inBio .modal__galleryTrack.is-grabbing { scroll-behavior: auto; scroll-snap-type: none; }
.modal__galleryTrack .tile .label {
  position: absolute; top: 10px; right: 10px;
  font: 500 10px/1 var(--font-mono);
  letter-spacing: 0.14em; text-transform: uppercase;
  color: #fff;
  background: rgba(10,10,10,0.55);
  padding: 5px 8px;
  border-radius: 999px;
  backdrop-filter: blur(8px);
}

/* ── TEAM MODAL — reuses .modal chrome, swaps body layout ────── */
/* Member profiles: portrait on the left, bio on the right with the
   Selected-work strip tucked under the text. Narrower than the default
   modal and sized to its content (no forced tall panel) so the pop-up
   stays compact now that the work sits inside the column. */
.modal--member {
  max-width: 1320px;
  min-height: 0;
  /* Uniformly scale the whole member lightbox up 25% (sizes, type,
     images, gaps all together). `zoom` keeps it in normal flow so the
     backdrop centring and the body's internal scroll still behave —
     unlike `transform: scale`, which would clip past the viewport. */
  zoom: 1.25;
  /* zoom also multiplies the viewport-based max-height, so pre-divide by
     1.25 → after zoom it lands back at the normal (100vh - 48px) cap. */
  max-height: calc((100vh - 48px) / 1.25);
}

/* Photo fills the full column — the right column (bio + gallery +
   details) drives the row height and the portrait stretches to match. */
.modal--member .modal__teamTop { align-items: start; grid-template-columns: 1fr 1.7fr; }
.modal--member .modal__portrait:not(.modal__portrait--studio) {
  /* Pinned 4:5 frame so every member photo crops identically,
     regardless of how long the bio column is. */
  aspect-ratio: 4/5;
  height: auto;
  max-height: none;
  transform: none;
  background: transparent;
  /* Photo kept ~same visual width; the left column is tighter so the
     content sits closer with only a slim gap. */
  width: 88%;
  justify-self: start;
}
.modal--member .modal__portrait:not(.modal__portrait--studio) .modal__portraitArt {
  position: absolute;
  inset: 0;
  padding: 0;
  display: block;
  background: transparent;
}
/* Roster (+Global Specialists) has no photo — show the same orange
   accent "+" card from the landing page as its profile graphic. */
.modal--member .modal__portrait:not(.modal__portrait--studio) .modal__portraitArt.art--accent {
  background: var(--accent);
  color: #0a0a0a;
  display: flex;
  align-items: center;
  justify-content: center;
}
.modal--member .modal__portraitArt.art--accent .modal__portraitBig {
  opacity: 1;
}
/* Brand icon used in place of the "+" monogram on the roster (full-crew)
   card and its profile — black mark on the accent fill. */
.team__miniIcon {
  position: relative; z-index: 1;
  width: clamp(21px, 2.2vw, 37px);
  height: auto; display: block;
}
.modal__portraitIcon {
  position: relative; z-index: 1;
  width: clamp(42px, 4.8vw, 70px);
  height: auto; display: block;
}
.modal--member .modal__portraitPhoto {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
}
/* Right column is a flex stack; details pin to the bottom so they
   align with the foot of the portrait. */
.modal--member .modal__teamBio { display: flex; flex-direction: column; }
.modal--member .modal__details--inBio { margin-top: auto; padding-top: 28px; }
/* Name/role caption overlaid on the member portrait (mirrors the
   team card overlay). Lives inside the scaled portrait, bottom-left.
   Bottom gradient scrim so white text reads over the photo's bright
   white seamless/shirt area. */
.modal__portraitLabel {
  position: absolute; left: 0; right: 0; bottom: 0;
  z-index: 2; pointer-events: none;
  padding: 56px 24px 20px;
  background: linear-gradient(to top, rgba(0,0,0,0.62) 0%, rgba(0,0,0,0.28) 42%, transparent 100%);
  color: #fff;
  text-shadow: 0 1px 14px rgba(0,0,0,0.55);
}
.modal__portraitLabel b {
  display: block;
  font: 600 30px/1 var(--font-display);
  letter-spacing: -0.015em;
}
.modal__portraitLabel span {
  display: block; margin-top: 9px;
  font: 500 12px/1 var(--font-mono);
  letter-spacing: 0.14em; text-transform: uppercase;
  opacity: 0.92;
}

.modal--member .modal__details,
.modal--member .modal__gallery { flex: 0 0 auto; }

/* Gallery placed inside the bio column — under the expertise tags,
   beside the portrait, above the Reel/Contact detail row. Narrower
   16:9 tiles so a couple peek into view; track scrolls horizontally
   and is width-constrained to the column. */
.modal__gallery--inBio { margin-top: 4px; padding-bottom: 0; min-width: 0; }
.modal__gallery--inBio .modal__galleryTrack { width: 100%; }
.modal__gallery--inBio .modal__galleryTrack .tile { width: 500px; }
/* Selected-work stills should never be cropped: pin each image tile to the
   current height (225px = 400×9/16) and let WIDTH shrink to the image's own
   aspect ratio. The <img> itself becomes the sizer (static, height-driven,
   object-fit: contain) so the rounded tile hugs it with no letterboxing.
   Scoped with :has(.tile__img) so placeholder (.art) tiles keep their box. */
.modal__gallery--inBio .modal__galleryTrack .tile:has(.tile__img) {
  width: auto;
  /* Reserve real area before the (lazy) image loads — a zero-width tile
     never enters the lazy-load IntersectionObserver, so the still would
     otherwise never fetch. Each still is wider than this at 225px tall,
     so the box grows to the image and this min adds no side gaps. */
  min-width: 175px;
  height: 282px;
  aspect-ratio: auto;
}
.modal__gallery--inBio .modal__galleryTrack .tile__img {
  position: static;
  width: auto;
  height: 100%;
  object-fit: contain;
}
.modal--member .modal__teamBio { min-width: 0; }
.modal--team .modal__teamTop {
  display: grid;
  grid-template-columns: 1fr 1.25fr;
  gap: 0;
  align-items: start;
}
/* Studio profile: big reel on the left that stretches to the full height
   of the copy column, with the stats pinned to the bottom — mirrors the
   member layout so the lightbox reads consistently. */
.modal--studio .modal__teamTop {
  gap: 36px;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  min-height: min(80vh, 825px);
}
.modal--studio .modal__teamBio { display: flex; flex-direction: column; }
.modal--studio .modal__details--inBio { margin-top: auto; padding-top: 28px; }
.modal--studio .modal__portrait--studio {
  aspect-ratio: 16/9;
  height: auto;
  align-self: start;
  max-height: none;
}
.modal__portrait {
  position: relative;
  aspect-ratio: 4/5;
  background: #050505;
  border-radius: 8px;
  overflow: hidden;
  flex-shrink: 0;
}
.modal__portrait--studio {
  aspect-ratio: 16/11;
  cursor: pointer;
}
/* Member portraits: shorter ratio + height cap so the profile pop-up
   isn't so tall now that the gallery is gone. */
.modal__portrait:not(.modal__portrait--studio) {
  aspect-ratio: 1/1;
  max-height: 460px;
}
.modal__portraitArt {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
}
.modal__portraitPhoto {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 25%;
  display: block;
}
.modal__portraitBig {
  position: relative; z-index: 1;
  font: 700 clamp(72px, 8vw, 128px)/0.9 var(--font-display);
  letter-spacing: -0.04em;
  opacity: 0.55;
}
.modal__teamBio {
  display: flex; flex-direction: column;
  gap: 18px;
  padding: 6px 4px;
}
.modal__teamBio .eyebrow {
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}
.modal__lede {
  font: 500 22px/1.32 var(--font-display);
  letter-spacing: -0.015em;
}
.modal__lede i { font-family: var(--font-serif); font-style: italic; font-weight: 400; }
.modal__bio {
  font: 400 14px/1.55 var(--font-display);
  color: color-mix(in oklab, currentColor 65%, transparent);
  max-width: 60ch;
}
.modal__expertise {
  margin-top: 6px;
  display: flex; flex-wrap: wrap; gap: 8px;
  align-items: center;
}
.modal__expertise b {
  font: 500 10px/1 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.55;
  margin-right: 6px;
}
.modal__expertise span {
  font: 500 11px/1 var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  padding: 6px 10px;
  border: 1px solid color-mix(in oklab, currentColor 18%, transparent);
  border-radius: 999px;
}
.modal__details--team { grid-template-columns: 1fr 1fr 1fr 1fr; }

/* ── STUDIO MODAL — editorial layout ─────────────────────────────
   Dedicated "The Studio" lightbox: a full-width cinematic reel hero,
   then a dense content band — statement + bio on the left, facts and
   expertise on a ruled sidebar. Fills the panel so the pop-up no
   longer leaves a tall empty column beside the short 16:9 reel. */
/* Narrower than the member modal so the full-width 16:9 reel lands at a
   good height (~720px on wide screens) and fills edge-to-edge with no
   pillar-box bars, instead of a short band in an over-wide frame. */
.modal--studio { max-width: 1280px; }
.studioModal { display: flex; flex-direction: column; gap: 34px; }
.studioModal__reel {
  position: relative; width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 10px; overflow: hidden;
  background: #050505; cursor: pointer; flex-shrink: 0;
}
.studioModal__reel.is-playing { cursor: default; }
.studioModal__reel:hover .modal__playbtn {
  background: var(--accent); color: #fff;
  transform: translate(-50%, -50%) scale(1.08);
}
.studioModal__reelCap {
  position: absolute; left: 22px; bottom: 20px; z-index: 3;
  display: flex; flex-direction: column; gap: 5px;
  color: #fff; text-shadow: 0 1px 16px rgba(0,0,0,0.6);
  pointer-events: none;
}
.studioModal__reelCap b { font: 600 16px/1 var(--font-display); letter-spacing: -0.01em; }
.studioModal__reelCap span {
  font: 500 11px/1 var(--font-mono); letter-spacing: 0.1em;
  text-transform: uppercase; opacity: 0.85;
}
.studioModal__grid {
  display: grid; grid-template-columns: 1.55fr 1fr; gap: 56px;
  align-items: start;
}
.studioModal__eyebrow { display: block; margin-bottom: 16px; }
.studioModal__main .modal__lede { margin: 0 0 18px; }
.studioModal__main .modal__bio { margin: 0; max-width: 58ch; }
.studioModal__side {
  display: flex; flex-direction: column; gap: 24px;
  padding-left: 40px;
  border-left: 1px solid color-mix(in oklab, currentColor 14%, transparent);
}
.studioModal__fact { display: flex; flex-direction: column; gap: 2px; }
.studioModal__fact b {
  font: 500 10px/1 var(--font-mono); letter-spacing: 0.14em;
  text-transform: uppercase; opacity: 0.55; margin-bottom: 5px;
}
.studioModal__fact > span { font: 400 15px/1.45 var(--font-display); }
.studioModal__muted { opacity: 0.55; }
.studioModal__side .modal__expertise { margin-top: 8px; }

@media (max-width: 880px) {
  .modal--team .modal__teamTop { grid-template-columns: 1fr; }
  .modal--member .modal__teamTop { grid-template-columns: 1fr; }
  .modal--studio .modal__teamTop { min-height: 0; }
  /* Stack the reel caption so "REEL" can't collide with the long
     runtime · location string on narrow screens. */
  .modal__videoMeta { flex-direction: column; gap: 5px; align-items: flex-start; }
  .modal__lede { font-size: 19px; line-height: 1.36; }
  .studioModal__grid { grid-template-columns: 1fr; gap: 26px; }
  .studioModal__side {
    padding-left: 0; border-left: 0;
    border-top: 1px solid color-mix(in oklab, currentColor 14%, transparent);
    padding-top: 24px;
  }
  .studioModal__reel { height: clamp(200px, 40vh, 320px); }
}

/* ── STUDIO CTA ──────────────────────────────────────────────── */
.studioCTA {
  padding: 140px 60px 160px;
  text-align: center;
  position: relative;
  overflow: hidden;
}
.studioCTA::before {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(60% 70% at 50% 50%, color-mix(in oklab, var(--accent) 18%, transparent) 0%, transparent 70%);
  pointer-events: none;
}
.studioCTA__inner {
  position: relative;
  max-width: 1080px;
  margin: 0 auto;
  display: flex; flex-direction: column;
  align-items: center;
  gap: 28px;
}
.studioCTA__eyebrow { color: var(--accent); }
.studioCTA__head {
  font: 700 clamp(56px, 8vw, 124px)/0.96 var(--font-display);
  letter-spacing: -0.045em;
  text-wrap: balance;
}
.studioCTA__head i {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  color: var(--accent);
  letter-spacing: -0.02em;
}
.studioCTA__sub {
  font: 400 22px/1.4 var(--font-display);
  letter-spacing: -0.01em;
  color: var(--muted);
  max-width: 540px;
}
.studioCTA__btn {
  margin-top: 12px;
  display: inline-flex; align-items: center; gap: 14px;
  padding: 18px 22px 18px 36px;
  background: var(--accent);
  color: #fff;
  border-radius: 999px;
  font: 600 18px/1 var(--font-display);
  letter-spacing: -0.01em;
  text-decoration: none;
  transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.25s;
  box-shadow: 0 10px 30px -10px color-mix(in oklab, var(--accent) 60%, transparent);
}
.studioCTA__btn:hover { transform: translateY(-3px); box-shadow: 0 18px 40px -10px color-mix(in oklab, var(--accent) 80%, transparent); }
.studioCTA__btnArrow {
  width: 38px; height: 38px;
  display: inline-flex; align-items: center; justify-content: center;
  background: #0a0a0a;
  color: #fff;
  border-radius: 50%;
  font-size: 16px;
  transition: transform 0.3s;
}
.studioCTA__btn:hover .studioCTA__btnArrow { transform: rotate(45deg); }
.studioCTA__meta {
  margin-top: 28px;
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center;
  gap: 14px;
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.studioCTA__dot { color: var(--accent); }

/* Accent-fill art block for the +7 roster card */
.art--accent {
  background: var(--accent);
  color: #0a0a0a;
}

/* ── PROJECT PAGE ────────────────────────────────────────────── */
/* Standalone pages at /work/<slug>.html. Mirrors the landing page's
   typographic system (display + mono + serif italic accent) but with a
   cleaner editorial layout — generous whitespace, varied image widths,
   and no modal chrome.
   Mode follows `data-mode` on <html> (set by the inline boot script
   from localStorage). The variant wrapper used in markup is `"black"`
   so the existing [data-mode="light"] override CSS picks it up
   correctly — paper variant is always light by definition, which is
   why dark mode wasn't taking effect when wrapped in paper. */
.proj-body {
  margin: 0;
  /* First-paint background — switches synchronously with data-mode
     so users never see a flash of the wrong colour. */
  background: #0a0a0a;
  color: #f4f1ea;
}
html[data-mode="light"] .proj-body {
  background: #f0ece2;
  color: #0a0a0a;
}
.proj-page {
  width: 100%;
  max-width: 1680px;
  margin: 0 auto;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-display);
  min-height: 100vh;
}

/* Project-page nav adds a back-link on the right, kept visually quiet
   so it doesn't compete with the project content below. */
.projnav .nav__logo svg { color: var(--accent); }
.projnav__right {
  display: flex; align-items: center; gap: 14px;
}
.themetoggle-mini {
  appearance: none;
  width: 38px; height: 38px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 50%;
  color: var(--fg);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s, color 0.2s, border-color 0.2s, transform 0.25s;
}
.themetoggle-mini:hover {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
  transform: rotate(20deg);
}
.themetoggle-mini__icon { display: inline-block; }
.projnav { position: sticky; top: 0; }
.projnav .nav__center {
  display: flex; align-items: center; gap: 16px;
  font: 500 12px/1 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.projnav .nav__center a { color: inherit; text-decoration: none; transition: color 0.2s; }
.projnav .nav__center a:hover { color: var(--accent); }
.projnav .nav__sep { opacity: 0.4; }
.projnav__back {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 8px 16px;
  border-radius: 999px;
  border: 1px solid var(--line);
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg);
  text-decoration: none;
  transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.projnav__back:hover { background: var(--accent); color: #fff; border-color: var(--accent); }
.projnav__backArrow { transition: transform 0.25s; }
.projnav__back:hover .projnav__backArrow { transform: translateX(-3px); }

/* ── Header ─────────────────────────────────────────────────── */
.proj-header {
  padding: 88px 60px 56px;
}
.proj-header__eyebrow {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 24px;
  margin-bottom: 36px;
}
.proj-header__title {
  font: 700 clamp(80px, 12vw, 188px)/0.9 var(--font-display);
  letter-spacing: -0.05em;
  text-wrap: balance;
}
.proj-header__title i {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  color: var(--accent);
  letter-spacing: -0.02em;
  /* The title's -0.05em tracking also pulls this trailing full-stop hard
     against the last letter — painfully tight after flat-stemmed endings
     (…t, …d, …l). Neutralise that tracking (+a hair) so the dot keeps the
     font's natural spacing regardless of which letter precedes it. */
  margin-left: 0.06em;
}
.proj-header__type {
  margin-top: 18px;
  font: 500 14px/1 var(--font-mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}
.proj-header__meta {
  margin-top: 48px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
  padding-top: 28px;
  border-top: 1px solid var(--line);
}
.proj-header__meta .col {
  font: 500 14px/1.5 var(--font-display);
  color: var(--fg);
}
.proj-header__meta .col b {
  display: block;
  font: 500 10px/1 var(--font-mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
  font-weight: 500;
}

/* ── Video frame ─────────────────────────────────────────────
   Hero image acts as the poster until first click — same UX as the
   landing-page showreel: native cursor hidden, custom circular play
   cursor follows the pointer, click triggers autoplay and the poster
   fades out to reveal the iframe. */
.proj-video {
  position: relative;
  width: 100%;
  margin: 0 auto;
  aspect-ratio: 16 / 9;
  background: #050505;
  overflow: hidden;
  /* Hide the native cursor — we draw our own circular indicator. */
  cursor: none;
}
.proj-video__frame {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0;
  z-index: 0;
  /* While the poster is visible the iframe shouldn't capture clicks —
     our wrapper handles the "start playing" gesture. After play
     starts, pointer-events flip back so the embed's own controls
     (pause/scrub/fullscreen) work. */
  pointer-events: none;
}
.proj-video.is-playing { cursor: default; }
.proj-video.is-playing .proj-video__frame { pointer-events: auto; }

/* Hero poster — sits on top of the iframe until first click, then
   fades out smoothly. A subtle vignette darkens edges so the play
   cursor reads clearly against bright images. */
.proj-video__poster {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: 1;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
  transition: opacity 0.4s ease;
}
.proj-video.is-playing .proj-video__poster {
  opacity: 0;
}

/* Custom circular play cursor — same chrome as the showreel. JS
   translates it to follow the pointer via refs, so this CSS only
   handles the visible / hidden states. */
.proj-video__cursor {
  position: absolute;
  left: 0; top: 0;
  width: 96px; height: 96px;
  border-radius: 50%;
  background: rgba(255,255,255,0.95);
  color: #0a0a0a;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 2px;
  pointer-events: none;
  z-index: 3;
  opacity: 0;
  transition: opacity 0.18s ease;
  box-shadow: 0 8px 40px -8px rgba(0,0,0,0.4);
  will-change: transform, opacity;
}
.proj-video__cursor.is-show { opacity: 1; }
.proj-video__cursorIcon {
  font-size: 22px;
  line-height: 1;
  margin-left: 4px; /* optical centring for the ▶ glyph */
}
.proj-video__cursorLabel {
  font: 500 9px/1 var(--font-mono);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin-top: 6px;
  opacity: 0.7;
}

/* ── Lede paragraph ─────────────────────────────────────────── */
.proj-lede {
  padding: 88px 60px 24px;
  max-width: 920px;
}
.proj-lede p {
  font: 400 24px/1.45 var(--font-display);
  letter-spacing: -0.015em;
  color: var(--fg);
  text-wrap: pretty;
}

/* ── Editorial gallery ──────────────────────────────────────── */
/* 12-column grid; each item picks a layout class from the rhythm.
   Row gap is tighter than column gap so consecutive images feel
   like a pair rather than discrete blocks. */
.proj-gallery {
  padding: 88px 60px 120px;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 40px 32px;
}
.proj-gallery__item {
  position: relative;
  margin: 0;
}
.proj-gallery__item img,
.proj-gallery__art {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 4px;
}
.proj-gallery__art {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  display: flex;
  align-items: center; justify-content: center;
}
.proj-gallery__artLabel {
  position: relative; z-index: 1;
  font: 700 80px/1 var(--font-display);
  letter-spacing: -0.04em;
  color: rgba(255,255,255,0.15);
  font-variant-numeric: tabular-nums;
}
.proj-gallery__item figcaption {
  margin-top: 14px;
  font: 500 11px/1.5 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
/* Editorial rhythm — varied column spans + small vertical offsets so
   adjacent rows don't sit on a hard baseline. */
.proj-gallery__item--full        { grid-column: 1 / -1; }
.proj-gallery__item--left-60     { grid-column: 1 / span 7; }
.proj-gallery__item--right-60    { grid-column: 6 / -1; }
.proj-gallery__item--left-50     { grid-column: 1 / span 6; }
.proj-gallery__item--right-50    { grid-column: 7 / -1; }
.proj-gallery__item--center-70   { grid-column: 2 / span 10; }
.proj-gallery__item--center-60   { grid-column: 3 / span 8; }
.proj-gallery__item--left-80     { grid-column: 1 / span 10; }
.proj-gallery__item--right-80    { grid-column: 3 / -1; }
.proj-gallery__item--left-50-inset  { grid-column: 1 / span 6; margin-top: 24px; }
.proj-gallery__item--right-50-inset { grid-column: 7 / -1; margin-top: 24px; }

@media (max-width: 980px) {
  .proj-gallery { gap: 28px 16px; padding: 56px 32px 88px; }
  .proj-gallery__item { grid-column: 1 / -1 !important; margin-top: 0 !important; }
  .proj-header { padding: 56px 32px 32px; }
  .proj-header__meta { grid-template-columns: 1fr 1fr; gap: 20px; }
  .proj-lede { padding: 56px 32px 24px; }
  .proj-lede p { font-size: 20px; }
}

/* ── Prev / Next pager ──────────────────────────────────────── */
.proj-pager {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 24px;
  align-items: stretch;
  padding: 40px 60px 80px;
  border-top: 1px solid var(--line);
}
.proj-pager__cell {
  display: flex; align-items: center; gap: 18px;
  padding: 28px 24px;
  border-radius: 12px;
  text-decoration: none;
  color: var(--fg);
  transition: background 0.2s, transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.proj-pager__cell:hover { background: var(--hover); }
.proj-pager__cell--prev:hover { transform: translateX(-6px); }
.proj-pager__cell--next:hover { transform: translateX(6px); }
.proj-pager__cell--next { justify-content: flex-end; }
.proj-pager__cell--index {
  border: 1px solid var(--line);
  padding: 18px 28px;
  align-items: center; justify-content: center;
  text-align: center;
  border-radius: 999px;
  min-width: 200px;
}
.proj-pager__arrow {
  font-size: 26px;
  color: var(--muted);
  flex-shrink: 0;
  transition: color 0.2s;
}
.proj-pager__cell:hover .proj-pager__arrow { color: var(--accent); }
.proj-pager__label { display: flex; flex-direction: column; gap: 6px; }
.proj-pager__label--right { text-align: right; }
.proj-pager__title {
  font: 600 28px/1 var(--font-display);
  letter-spacing: -0.02em;
}

@media (max-width: 720px) {
  .proj-pager { grid-template-columns: 1fr; padding: 32px; }
  .proj-pager__cell--index { order: 3; }
  .proj-pager__title { font-size: 22px; }
}

/* ── Footer (project page) ──────────────────────────────────── */
/* Single-row layout: brand · tag · meta. The tag ("Always Making.")
   stays optically centred in the viewport via the symmetric 1fr side
   columns, while brand hugs left and meta hugs right. */
.proj-foot {
  border-top: 1px solid var(--line);
  padding: 32px 60px 40px;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 24px;
}
.proj-foot__brand {
  justify-self: start;
  display: flex; align-items: center; gap: 10px;
  font: 700 14px/1 var(--font-display);
  letter-spacing: -0.01em;
}
.proj-foot__brand svg { color: var(--accent); }
.proj-foot__meta {
  grid-column: 1 / -1;
  justify-self: center;
  margin-top: 20px;
  display: flex; gap: 12px; flex-wrap: wrap; justify-content: center;
  font-size: 11px;
}
.proj-foot__meta a { color: inherit; text-decoration: none; }
.proj-foot__meta a:hover { color: var(--accent); }
/* Narrow viewports: stack so nothing collides */
@media (max-width: 860px) {
  .proj-foot {
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
    gap: 18px;
  }
  .proj-foot__brand,
  .proj-foot__meta { justify-self: center; }
  .proj-foot__meta { justify-content: center; }
}

/* ── 404 — project not found ────────────────────────────────── */
.proj-missing { min-height: 100vh; display: flex; flex-direction: column; }
.proj-missing__body {
  flex: 1;
  display: flex; flex-direction: column; justify-content: center; align-items: flex-start;
  padding: 60px;
  gap: 18px;
}
.proj-missing__body h1 {
  font: 700 80px/0.95 var(--font-display);
  letter-spacing: -0.045em;
}
.proj-missing__body code {
  font-family: var(--font-mono);
  background: var(--hover);
  padding: 2px 6px;
  border-radius: 4px;
}
.proj-missing__back {
  margin-top: 24px;
  display: inline-flex; align-items: center; gap: 10px;
  padding: 12px 22px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font: 600 13px/1 var(--font-display);
  text-decoration: none;
}

/* ── ARCHIVE / INDEX PAGE ────────────────────────────────────── */
/* Standalone shareable archive at /work/index.html. Dense table-style
   list of every project — designed to comfortably hold 50+ rows. No
   iframes or per-row imagery; a single shared thumbnail preview
   follows the cursor on hover. */
.archive {
  width: 100%;
  max-width: 1680px;
  margin: 0 auto;
  background: var(--bg);
  color: var(--fg);
  min-height: 100vh;
  font-family: var(--font-display);
}
.archive__head {
  padding: 88px 60px 56px;
}
.archive__eyebrow {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 24px;
  margin-bottom: 36px;
}
.archive__title {
  font: 700 clamp(80px, 11vw, 168px)/0.9 var(--font-display);
  letter-spacing: -0.045em;
  text-wrap: balance;
}
.archive__title i {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  color: var(--accent);
  letter-spacing: -0.02em;
}
.archive__sub {
  margin-top: 24px;
  max-width: 520px;
  font: 400 16px/1.55 var(--font-display);
  color: var(--muted);
  letter-spacing: -0.005em;
}

/* Wrapper carries the mousemove handler — preview is positioned within. */
.archive__listWrap {
  position: relative;
  padding: 0 60px 80px;
}
.archive__listHead,
.archive__row {
  display: grid;
  /* No / Project / Client / Category / Year / arrow */
  grid-template-columns: 56px minmax(220px, 1.5fr) minmax(180px, 1fr) minmax(220px, 1.4fr) 80px 28px;
  gap: 24px;
  align-items: center;
  padding: 18px 8px;
}
.archive__listHead {
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: 16px 8px;
  font-size: 11px;
  color: var(--muted);
}
.archive__row {
  position: relative;
  border-bottom: 1px solid var(--line);
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.2s, padding-left 0.3s;
}
.archive__row:hover {
  background: var(--hover);
  padding-left: 24px;
}
.archive__no {
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.14em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.archive__name {
  font: 600 22px/1.15 var(--font-display);
  letter-spacing: -0.015em;
}
.archive__client,
.archive__cat {
  font: 500 13px/1.3 var(--font-display);
  color: color-mix(in oklab, currentColor 70%, transparent);
}
.archive__cat {
  font: 500 11px/1.3 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.archive__year {
  font: 500 11px/1 var(--font-mono);
  letter-spacing: 0.14em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.archive__arrow {
  color: var(--muted);
  font-size: 16px;
  text-align: right;
  transition: color 0.2s, transform 0.3s;
}
.archive__row:hover .archive__arrow {
  color: var(--accent);
  transform: translate(4px, -4px);
}

/* Floating hover preview — positioned by JS on the wrapper's mousemove. */
.archive__preview {
  position: absolute;
  width: 280px; aspect-ratio: 16 / 11;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(0.8);
  opacity: 0;
  transition: opacity 0.2s ease, transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
  z-index: 5;
  overflow: hidden;
  border-radius: 6px;
  background: var(--hover);
  box-shadow: 0 12px 36px -12px rgba(0,0,0,0.35);
}
.archive__preview.is-active { opacity: 1; transform: translate(-50%, -50%) scale(1); }
/* Same offscreen optimization as the landing index hover preview. */
.archive__preview { content-visibility: auto; contain-intrinsic-size: 280px 193px; }
.archive__previewImg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: none;
}
.archive__previewArt {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
}

/* Active nav item styling — used to indicate which page you're on. */
.projnav .nav__center a.is-current {
  color: var(--accent);
}

@media (max-width: 880px) {
  .archive__head { padding: 56px 32px 32px; }
  .archive__listWrap { padding: 0 32px 56px; }
  .archive__listHead,
  .archive__row {
    grid-template-columns: 44px 1fr 72px 22px;
    gap: 16px;
  }
  /* Hide client & category on narrow screens — keep no/name/year/arrow */
  .archive__listHead > :nth-child(3),
  .archive__listHead > :nth-child(4),
  .archive__client,
  .archive__cat { display: none; }
  .archive__name { font-size: 18px; }
  .archive__preview { display: none; } /* no hover affordance on touch */
}

/* "Always Making." tag — landing footer.
   Mirrors the showreel section's serif-italic accent styling but at a
   larger display size to fit the mega-type footer composition. Falls
   between the giant 3 BLOCK wordmark and the © line. */
.footer__tag {
  text-align: center;
  padding: 28px 0 16px;
}
.footer__tag h3 {
  font: 500 clamp(40px, 5vw, 64px)/1.0 var(--font-display);
  letter-spacing: -0.025em;
  color: var(--fg);
}
.footer__tag h3 i {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  color: var(--accent);
  letter-spacing: -0.015em;
}

/* "Always Making." tag — project + archive page footers.
   Sits as the centre column of the .proj-foot grid (see Footer section
   above) so the brand mark sits to its left on the same row. */
.proj-foot__tag {
  justify-self: end;
  grid-column: 3;
  text-align: right;
}
.proj-foot__tag h3 {
  font: 500 clamp(28px, 3.6vw, 44px)/1.0 var(--font-display);
  letter-spacing: -0.02em;
  color: var(--fg);
}
.proj-foot__tag h3 i {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  color: var(--accent);
  letter-spacing: -0.015em;
}

/* ── Variant-specific tweaks ─────────────────────────────────── */
/* Paper variant softens grain + uses paper texture */
.variant[data-variant="paper"] {
  background-image:
    repeating-linear-gradient(0deg, rgba(0,0,0,0.012) 0 1px, transparent 1px 3px);
}
.variant[data-variant="paper"] .manifesto__body .hl { color: #fff; }
.variant[data-variant="paper"] .hero__big i,
.variant[data-variant="paper"] .manifesto__body i,
.variant[data-variant="paper"] .projects__head h2 i { color: var(--accent); }

/* Cinema variant: bigger marquees, more visual rhythm */
.variant[data-variant="cinema"] .marquee--big { background: var(--accent); color: #0a0a0a; border: none; }
.variant[data-variant="cinema"] .marquee--big .marquee__track .star { color: #fff; }

/* glyphs as inline chips for hero words */
.gly--circle  { background: var(--accent); border-radius: 50%; }
.gly--square  { background: #f7d046; }
.gly--tri     { background: transparent;
  clip-path: polygon(50% 0, 100% 100%, 0 100%); 
}
.gly--star    { background: transparent; }
.gly--plus    { background: var(--accent); 
  clip-path: polygon(40% 0, 60% 0, 60% 40%, 100% 40%, 100% 60%, 60% 60%, 60% 100%, 40% 100%, 40% 60%, 0 60%, 0 40%, 40% 40%); }
.gly--diamond { background: #4ade80; transform: rotate(45deg) scale(0.7); }
.gly--block   { background: #2563eb; }
.gly--pink    { background: #ec4899; border-radius: 50%; }
.variant[data-variant="paper"] .gly--circle { background: #0a0a0a; }
.variant[data-variant="cinema"] .sect--light .gly--circle { background: #0a0a0a; }

/* tri uses solid color; set via background-color overrides */
.gly--tri { background-color: #2563eb; }
.gly--star { background-color: #f7d046;
  clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}

/* ═══════════════════════════════════════════════════════════════
   RESPONSIVE LAYER
   The desktop rules above are the source of truth. Everything below
   only narrows / restacks them for tablet and phone. Three width
   breakpoints (≤1024 tablet, ≤680 phone, ≤400 small phone) plus a
   coarse-pointer block that grows tap targets and surfaces a static
   "tap to play" badge for touch devices (which never fire the
   pointer-tracking custom play cursor).
   Guard against horizontal overflow globally first.
   ═══════════════════════════════════════════════════════════════ */
/* Use overflow-x: clip rather than hidden — `clip` prevents horizontal
   overflow WITHOUT turning the root into a scroll container, which is what
   made window.scrollTo() (incl. the back-to-top button) land slightly short
   of 0. `hidden` on <html>/<body> hijacks the viewport scroller. */
html, body { max-width: 100%; overflow-x: clip; }

/* ── TABLET ≤1024px ──────────────────────────────────────────── */
@media (max-width: 1024px) {
  /* Pull the generous 60px gutters in to 40px across every section. */
  .section { padding: 72px 40px; }
  .section.section--tight { padding: 48px 40px; }
  .hero { padding: 104px 40px 72px; }
  .manifesto { padding: 104px 40px 56px; }
  .projects, .services, .clients { padding: 72px 40px; }
  .team { padding: 88px 40px; }
  .footer { padding: 64px 40px 36px; }
  .clientlogos__head { padding: 0 40px; }
  .studioCTA { padding: 104px 40px 120px; }
  .nav { padding: 20px 28px; }
  /* 6 menu items + logo + status text get tight here — tighten the menu
     gap and drop the verbose status text so the menu keeps room. */
  .nav__menu { gap: 16px; }
  .nav__meta { gap: 12px; }
  .nav__meta span:not(.nav__pulse) { display: none; }
  .nav__archive { padding: 7px 12px; }

  /* Project pages */
  .proj-header { padding: 72px 40px 44px; }
  .proj-lede { padding: 64px 40px 20px; }
  .proj-gallery { padding: 64px 40px 96px; }

  /* Big display headings ease down a notch before the phone jump. */
  .projects__head h2, .services__head h2, .clients__head h2 { font-size: 72px; }

  /* Team: stack the two-column hero rows. */
  .team__row { grid-template-columns: 1fr; gap: 36px; }
  .team__name { font: 700 clamp(72px, 12vw, 120px)/0.88 var(--font-display); }
  .team__row--studio .team__photo { aspect-ratio: 16/10; }

  /* Footer contact: 4 → 2 columns. */
  .footer__contact { grid-template-columns: 1fr 1fr; gap: 28px 32px; }

  /* Selected Work: keep the 2-column mosaic but shrink the interlock
     offset + row gap so it doesn't open big empty bands on tablet. */
  .projects__grid { row-gap: 64px; }
  .projects__grid > :nth-child(even) { margin-top: 90px; }

  /* Modal detail rows: 4 → 2 columns. */
  .modal__details, .modal__details--team { grid-template-columns: 1fr 1fr; }
}

/* ── PHONE ≤680px ────────────────────────────────────────────── */
@media (max-width: 680px) {
  /* Tighten gutters to a comfortable 20px and trim vertical rhythm. */
  .section { padding: 56px 20px; }
  .section.section--tight { padding: 40px 20px; }
  .hero { padding: 84px 20px 56px; }
  .manifesto { padding: 80px 20px 48px; }
  .projects, .services, .clients { padding: 56px 20px; }
  .team { padding: 64px 20px; }
  .footer { padding: 48px 20px 28px; }
  .clientlogos { padding: 24px 0 64px; }
  .clientlogos__head { padding: 0 20px; }
  .studioCTA { padding: 80px 20px 96px; }

  /* The vertical section-number rail collides with content once the
     gutter shrinks — hide it on phones. */
  .idxrail { display: none; }

  /* NAV: drop the link list + verbose status text; keep the logo and
     the dark/light toggle (the only interactive control). The in-page
     anchors are still reachable by scrolling. */
  .nav { padding: 14px 18px; }
  .nav__menu { display: none; }
  .nav__meta span:not(.nav__pulse) { display: none; }
  .wordmark-logo { height: 20px; }

  /* HERO */
  .hero__eyebrow { padding-bottom: 36px; gap: 12px; font-size: 10px; }
  .hero__big { font: 700 clamp(40px, 13vw, 72px)/0.98 var(--font-display); }
  .hero__sub { grid-template-columns: 1fr; gap: 28px; margin-top: 36px; }
  .hero__sub .lede { font-size: 18px; max-width: none; }
  .hero__sub .meta { text-align: left; }

  /* SHOWREEL overlay — the desktop type is sized for a 1600px frame and
     overflows a phone-width box. Scale the title/counter way down and
     re-anchor the corner labels so they don't stack on top of each
     other. */
  .showreel { border-radius: 12px; }
  .showreel__title { left: 18px; bottom: 16px; font-size: clamp(52px, 17vw, 96px); }
  .showreel__counter { font-size: 120px; left: 14px; }
  .showreel__meta { left: 18px; top: 18px; font-size: 9px; }
  .showreel__tag { right: 18px; top: auto; bottom: 18px; left: auto; max-width: 42%; }
  .showreel__tag h3 { font-size: 17px; }

  /* MANIFESTO foot: 3 → 1 column. */
  .manifesto { }
  .manifesto__foot { grid-template-columns: 1fr; gap: 18px; }

  /* SECTION HEADS: let the count chip wrap under the heading. */
  .projects__head, .services__head, .clients__head {
    flex-wrap: wrap; gap: 12px;
  }
  .projects__head h2, .services__head h2, .clients__head h2 {
    font-size: clamp(44px, 13vw, 60px);
  }

  /* SELECTED WORK grid: the desktop layout is a 2-column staggered
     mosaic (even cards pushed down 160px to interlock). On phones that
     left the second column cropped off-screen — stack to one column and
     drop the vertical offset. */
  .projects__grid { grid-template-columns: 1fr; row-gap: 48px; }
  .projects__grid > :nth-child(even) { margin-top: 0; }

  /* MARQUEE type down so each pass isn't a single word. */
  .marquee__track { font-size: 44px; gap: 36px; padding-right: 36px; }
  .marquee--big .marquee__track { font-size: 60px; }

  /* CLIENTS / INDEX rows: collapse the 5-column grid to No · Name · ›
     and hide the role/year columns (still available inside the modal). */
  .client {
    grid-template-columns: 26px 1fr 22px;
    gap: 14px; padding: 18px 4px;
  }
  .client:hover { padding-left: 4px; }
  .client__role, .client__year { display: none; }
  .client__name { font-size: 26px; }

  /* TEAM */
  .team__name { font: 700 clamp(56px, 16vw, 88px)/0.9 var(--font-display); }
  .team__minirow { grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 40px; }
  .team__row--studio { padding: 20px; margin: 0 -20px; }

  /* STUDIO CTA */
  .studioCTA__head { font-size: clamp(40px, 11vw, 68px); }

  /* FOOTER: on phones, stack the tagline ("Always Making.") above the big
     wordmark, and shrink the wordmark so it fits the viewport instead of
     cropping. Flex + order reorders without touching the desktop DOM. */
  .footer { display: flex; flex-direction: column; }
  .footer__contact { order: 0; grid-template-columns: 1fr 1fr; gap: 24px; padding-bottom: 44px; }
  .footer__tag { order: 1; padding: 6px 0 0; }
  .footer__mega {
    order: 2;
    margin-top: 12px; max-width: 100%;
    white-space: nowrap; flex-wrap: wrap; line-height: 0.9;
    font-size: clamp(28px, 10vw, 64px);
  }
  .footer__base { order: 3; flex-direction: column; gap: 10px; align-items: flex-start; }

  /* PROJECT PAGE */
  .projnav { padding: 12px 18px; }
  .projnav .nav__center { display: none; }
  /* On phones the logo + Dark/Light pill + Back button overflow the row,
     squishing the toggle. The logo already links Home, so drop the
     redundant Back button — leaving just logo + toggle, exactly the clean
     layout the landing nav uses on mobile. */
  .projnav__back { display: none; }
  /* Footer: force a clean single-column stack. An explicit override here
     (last in source order) so it wins regardless of earlier rules. */
  .proj-foot {
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
    gap: 18px;
    padding: 36px 20px 32px;
  }
  .proj-foot__brand, .proj-foot__tag, .proj-foot__meta {
    grid-column: auto;
    justify-self: center;
  }
  .proj-foot__tag { text-align: center; }
  .proj-foot__meta { margin-top: 0; justify-content: center; flex-wrap: wrap; }
  .proj-header { padding: 56px 20px 36px; }
  .proj-header__eyebrow { flex-direction: column; gap: 8px; margin-bottom: 24px; }
  .proj-header__title { font: 700 clamp(44px, 13vw, 80px)/0.92 var(--font-display); }
  .proj-header__meta { grid-template-columns: 1fr 1fr; gap: 18px; margin-top: 32px; }
  .proj-lede { padding: 56px 20px 20px; }
  .proj-lede p { font-size: 19px; }
  .proj-gallery { padding: 48px 20px 80px; gap: 24px 16px; }

  /* MODAL — on phones the backdrop scrolls and pins its content to the
     top (not centred), so a tall pop-up can never push the modal head
     and its × close button off the top of the screen. dvh tracks the
     *visible* viewport (excludes the address bar) so nothing is cropped. */
  .modal-backdrop {
    padding: 14px;
    align-items: flex-start;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  .modal {
    max-height: none;
    margin: auto 0;
  }
  /* The member lightbox's 25% zoom is desktop-only flourish; at phone
     width it just makes the pop-up overflow. Drop it and stack the
     portrait above the bio so everything fits in one readable column. */
  .modal--member {
    zoom: 1;
    max-height: none;
  }
  .modal--member .modal__teamTop { grid-template-columns: 1fr; }
  .modal--member .modal__portrait:not(.modal__portrait--studio) {
    aspect-ratio: 4/5;
    max-height: 60vh;
  }
  .modal__head { padding: 16px 18px; }
  .modal__body { padding: 22px 18px 28px; gap: 24px; }
  .modal__details, .modal__details--team { grid-template-columns: 1fr 1fr; }
  .modal--team .modal__teamTop { grid-template-columns: 1fr; }

  /* ARCHIVE page heading */
  .archive__title { font-size: clamp(48px, 13vw, 96px); }
}

/* ── SMALL PHONE ≤400px ──────────────────────────────────────── */
@media (max-width: 400px) {
  .section, .projects, .services, .clients { padding-left: 16px; padding-right: 16px; }
  .hero { padding-left: 16px; padding-right: 16px; }
  .footer__contact { grid-template-columns: 1fr; }
  .team__minirow { grid-template-columns: 1fr; }
  .modal__details, .modal__details--team { grid-template-columns: 1fr; }
  .client__name { font-size: 22px; }
}

/* ── TOUCH / COARSE POINTER ──────────────────────────────────────
   Two jobs: (1) enlarge interactive controls to a ≥44px tap target,
   and (2) show a static "tap to play" badge on the video surfaces —
   the custom circular play cursor only appears on pointer-tracking
   (mouse) so touch users would otherwise see no play affordance. */
@media (hover: none), (pointer: coarse) {
  .themetoggle__opt { padding: 11px 16px; }
  .projnav__back { padding: 12px 18px; }
  .team__cta { padding: 14px 18px; }
  .nav__menu a { display: inline-flex; align-items: center; min-height: 44px; }
  .footer__contact .col a,
  .proj-foot__meta a { display: inline-block; padding: 6px 0; }

  /* Static play badge for the landing showreel + project hero video.
     pointer-events:none so the existing click-to-play still bubbles to
     the wrapper; fades out with the overlay/poster once playing. */
  .showreel__overlay::after,
  .proj-video::after {
    content: "▶";
    position: absolute; top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    width: 68px; height: 68px;
    border-radius: 50%;
    background: rgba(255,255,255,0.94);
    color: #0a0a0a;
    display: flex; align-items: center; justify-content: center;
    font-size: 22px; padding-left: 4px;
    box-shadow: 0 8px 40px -8px rgba(0,0,0,0.45);
    z-index: 4;
    pointer-events: none;
    transition: opacity 0.3s ease;
  }
  .showreel.is-playing .showreel__overlay::after,
  .proj-video.is-playing::after { opacity: 0; }
}
