/* ========================================
   A MEASURED FORCE — Premium Build v2
   375.studio-inspired with AMF brand
   ======================================== */

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

/* ============ WEBGL SHADER BACKGROUND ============ */
#shaderBg {
  position: fixed;
  top: 0; left: 0;
  width: 100%; height: 100%;
  z-index: -1;
  pointer-events: none;
}

:root {
  /* Semantic palette — warm neutral, light-dominant. */
  --paper:       #F1EDE7;
  --bone:        #E6E1D9;
  --ink:         #171512;
  --ash:         #6B6862;
  --stone:       #A09C94;
  --line:        rgba(23,21,18,0.10);
  --line-med:    rgba(23,21,18,0.18);
  --line-strong: rgba(23,21,18,0.28);

  /* Legacy aliases mapped to the new palette (no accent color in use). */
  --black:        var(--ink);
  --white:        var(--ink);
  --orange:       var(--ink);
  --accent:       var(--ink);
  --gray:         var(--ash);
  --gray-light:   var(--ash);
  --border:       var(--line);
  --border-med:   var(--line-med);
  --border-light: var(--line-strong);

  --font-serif: 'Playfair Display', Georgia, serif;
  --font-sans: 'Inter', -apple-system, sans-serif;
  --pad: clamp(1.5rem, 4vw, 3.5rem);
}

html { scroll-behavior: smooth; font-size: 16px; background: var(--paper); }
/* Permanent dark mode: the page backdrop (seen during page transitions / overscroll)
   should read pure black, not the dark blue that paper inverts to. A white source
   becomes black under the global html.inverted filter. */
html.inverted { background: #fff; }

body {
  background: transparent;
  color: var(--ink);
  font-family: var(--font-sans);
  font-weight: 300;
  line-height: 1.6;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  cursor: none;
}

@media (pointer: coarse) { body { cursor: auto; } }

a { color: var(--ink); text-decoration: none; transition: opacity 0.3s; cursor: none; }
a:hover { opacity: 0.6; }

em { font-family: var(--font-serif); font-style: italic; font-weight: 400; }

::selection { background: var(--ink); color: var(--paper); }
img { display: block; }

/* ============ CUSTOM CURSOR ============ */
.cursor {
  position: fixed; top: 0; left: 0;
  width: 20px; height: 20px;
  background: #fff;
  border-radius: 50%;
  pointer-events: none;
  z-index: 100000;  /* above the sculpture info card (10001) so it reads in front */
  transform: translate(-50%, -50%);
  transition: width 0.4s cubic-bezier(0.16,1,0.3,1),
              height 0.4s cubic-bezier(0.16,1,0.3,1),
              opacity 0.3s;
  mix-blend-mode: difference;
  display: flex; align-items: center; justify-content: center;
  opacity: 0;
}
.cursor.visible { opacity: 1; }
.cursor-text {
  font-family: var(--font-sans);
  font-size: 0; font-weight: 500;
  color: var(--ink);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  white-space: nowrap;
  transition: font-size 0.3s cubic-bezier(0.16,1,0.3,1);
}
/* Hover: the cursor becomes a thin RING that FRAMES the target instead of a
   filled blob that covers it — so the hovered element (which also brightens via
   its own :hover) stays fully visible. mix-blend-mode:difference (from .cursor)
   keeps the ring legible on any background, light or dark. */
.cursor.hovering {
  width: 50px; height: 50px;
  background: transparent;
  border: 1.5px solid #fff;
  animation: cursor-pulse 1.8s ease-in-out infinite;
}
.cursor.hovering .cursor-text { font-size: 0; }
/* Over a WebGL sculpture: the same thin pulsing ring as links, signalling it's
   clickable (opens the info card). Transparent center → the warm WebGL glow on
   the statue still shows through. Driven by amf:relief-hover/-out (desktop only). */
.cursor.hovering-relief {
  width: 50px; height: 50px;
  background: transparent;
  border: 1.5px solid #fff;
  animation: cursor-pulse 1.8s ease-in-out infinite;
}
.cursor.hovering-relief .cursor-text { font-size: 0; }
/* Over a work image: a slightly larger ring + a "View" label so the affordance
   is unmistakable (the image itself brightens/zooms via its wrapper :hover). */
.cursor.hovering-work {
  width: 64px; height: 64px;
  background: transparent;
  border: 1.5px solid #fff;
  animation: cursor-pulse 1.8s ease-in-out infinite;
}
.cursor.hovering-work .cursor-text { font-size: 9px; }
@keyframes cursor-pulse {
  0%, 100% { transform: translate(-50%, -50%) scale(1); }
  50%      { transform: translate(-50%, -50%) scale(1.08); }
}
@media (pointer: coarse) { .cursor { display: none; } }
/* On non-touch the custom cursor IS the only pointer feedback, so never let an
   element's `cursor: pointer` re-expose the native hand alongside the ring (it
   showed through over the hamburger + pill buttons). Touch keeps native cursors
   via the coarse override on body above. */
@media not all and (pointer: coarse) {
  /* !important so later `cursor: pointer` declarations can't win on source order
     and re-expose the native hand. Keep this list in sync with the elements that
     set `cursor: pointer` elsewhere (search the file for it). */
  button, [role="button"], summary,
  .menu-trigger, .invert-dot, .pill-btn, .studio-pill, .service-pill,
  .works-card, .case-play-btn, .case-films-grid.is-single, .case-film {
    cursor: none !important;
  }
}

/* One-time mobile coach hint ("Tap a sculpture to explore"). Authored in light-
   mode colours (paper pill, ink text) so it rides the global html.inverted filter
   into the dark theme, exactly like the sculpture info card. Never intercepts taps. */
.relief-hint {
  /* Sits just below the "A Measured Force" header wordmark (top is refined in JS
     to the wordmark's exact bottom; the value here is a pre-JS fallback). */
  position: fixed; left: 50%; top: 56px;
  transform: translate(-50%, -6px);
  background: rgba(241, 237, 231, 0.94);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 0.78rem; font-weight: 500; letter-spacing: 0.03em;
  padding: 11px 18px; border-radius: 100px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.22);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  opacity: 0; pointer-events: none; z-index: 9000; white-space: nowrap;
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.relief-hint.visible { opacity: 1; transform: translate(-50%, 0); }
@media (prefers-reduced-motion: reduce) {
  .relief-hint { transition: opacity 0.2s ease; }
}

/* ============ HEADER ============ */
.header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center;
  /* extra top cushion on desktop so the logo/menu don't hug the viewport top
     (mobile keeps its own tighter padding via the max-width:768 rule below) */
  padding: 1.8rem var(--pad) 1.1rem;
  transition: background 0.4s, backdrop-filter 0.4s;
}
/* margin-left pulls the logo's CENTRE left to mirror the menu icon's centre
   (the logo is wider than the icon, so equal outer margins look lopsided).
   Per-breakpoint value ≈ (logoHeight - menuBoxWidth) / 2. */
.header-logo { justify-self: start; margin-left: -3px; }
.header-logo a { display: flex; align-items: center; }
.header-logo-img { height: 26px; width: auto; }
.header-center-name { justify-self: center; transition: opacity 0.8s ease; }

/* First-load intro sequence: the header pieces start hidden and are faded in, in
   order, by the JS timeline (bootHomeIntro). The class is removed once they're in,
   so the normal scroll-hide behaviour takes over afterwards. */
html.intro-seq .header-center-name,
html.intro-seq .header-logo,
html.intro-seq .header-actions { opacity: 0; }
.header-center-name a {
  font-family: var(--font-sans); font-weight: 400;
  font-size: 0.65rem; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--ash);
  transition: color 0.3s ease;
}
.header-center-name a:hover { color: var(--ink); }
.header-actions {
  justify-self: end;
  display: flex;
  gap: 1.25rem;
  align-items: center;
}

/* Scroll-down hides the left logo + right actions; scroll-up brings them
   back. Center wordmark stays put at all times. */
.header-logo,
.header-actions {
  transition: opacity 0.4s ease, transform 0.4s ease;
}
body.header-hidden .header-logo,
body.header-hidden .header-actions {
  opacity: 0;
  transform: translateY(-8px);
  pointer-events: none;
}

/* Quiet invert-colors toggle — half-disc glyph that previews its own action
   on hover (rotation flips the light/dark halves). */
.invert-dot {
  width: 22px; height: 22px;
  background: transparent;
  border: none; padding: 0; cursor: pointer;
  color: var(--ash);
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  transition:
    color 0.3s ease,
    transform 0.7s cubic-bezier(0.65, 0, 0.35, 1);
}
.invert-dot:hover { color: var(--ink); }
.invert-dot svg { width: 100%; height: 100%; display: block; }
/* Horizontal flip on toggle — the filled/outline halves swap, mirroring
   the page's color flip. */
html.inverted .invert-dot { transform: scaleX(-1); }

/* Site is locked to dark (inverted) mode — the manual invert toggle is hidden.
   To restore the light/dark switch: remove this rule and drop the default
   `class="inverted"` from each page's <html> tag. */
.invert-dot { display: none !important; }

/* Invert the whole site when active. The canvas and work photos are counter-
   inverted so they stay untouched — pure invert(1) self-cancels cleanly. */
html.inverted { filter: invert(1); }
html.inverted #shaderBg { filter: invert(1) !important; }
html.inverted .works-card img { filter: brightness(0.85) invert(1); }
html.inverted .works-cycle-item img { filter: grayscale(1) invert(1) !important; }
html.inverted .works-cycle-item.is-active img { filter: invert(1) !important; }
/* Project-page photos + the video lightbox are counter-inverted so they
   stay true-color when the rest of the page is inverted. */
html.inverted .case-bleed img,
html.inverted .case-grid-two img,
html.inverted .case-grid-two video,
html.inverted .case-video video,
html.inverted .case-film-thumb img,
html.inverted .menu-submenu-preview img,
html.inverted .case-embed iframe,
html.inverted .case-reels video,
html.inverted .ai-works-card img { filter: invert(1) !important; }
html.inverted .video-lightbox { filter: invert(1) !important; }

/* ============ MENU TRIGGER (two-line hamburger → X) ============ */
.menu-trigger {
  width: 26px; height: 26px;
  background: transparent;
  border: none; padding: 0; cursor: none;
  color: var(--ash);
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  transition: color 0.3s ease;
  position: relative;
}
/* Hover: brighten to the bright theme ink + thicken the hairlines so the icon
   reads clearly inside the framing cursor ring (the cursor no longer covers it). */
.menu-trigger:hover { color: var(--ink); transform: scale(1.08); }
.menu-trigger { transition: color 0.3s ease, transform 0.3s ease; }
.menu-trigger:hover .menu-trigger-dot::before,
.menu-trigger:hover .menu-trigger-dot::after { height: 2px; }
/* Two 1px hairlines stacked — same hairline weight as the invert dot's
   stroke and the site's 1px borders, so the icon shares the design
   language. On open, the lines collapse to center and cross into a
   matching X (same line weight, same easing). */
.menu-trigger-dot {
  display: block;
  position: relative;
  width: 22px;
  height: 9px;
}
.menu-trigger-dot::before,
.menu-trigger-dot::after {
  content: '';
  position: absolute;
  left: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transition:
    top 0.4s cubic-bezier(0.65, 0, 0.35, 1),
    transform 0.4s cubic-bezier(0.65, 0, 0.35, 1),
    height 0.3s ease;
}
.menu-trigger-dot::before { top: 0; }
.menu-trigger-dot::after  { top: calc(100% - 1px); }
.menu-trigger.is-open .menu-trigger-dot::before {
  top: calc(50% - 0.5px);
  transform: rotate(45deg);
}
.menu-trigger.is-open .menu-trigger-dot::after {
  top: calc(50% - 0.5px);
  transform: rotate(-45deg);
}

/* When the menu is open, lift the header above the overlay so the morphed
   X stays visible at the exact spot the hamburger was. Hide the rest of
   the header content so only the X is interactive. */
body.menu-open .header {
  z-index: 9500;
  pointer-events: none;
}
body.menu-open .header .menu-trigger { pointer-events: auto; }
body.menu-open .header-logo,
body.menu-open .header-center-name,
body.menu-open .invert-dot {
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
}

/* ============ FULL-SCREEN MENU OVERLAY ============ */
.menu-overlay {
  position: fixed; inset: 0;
  z-index: 9000;
  background: transparent;
  opacity: 0;
  pointer-events: none;
  display: flex; flex-direction: column;
  justify-content: center;
  padding: 8rem var(--pad) 4rem;
  transition: opacity 0.6s ease 0.4s; /* close: wait for items to dissolve, then fade overlay (smoke already receded in parallel during relief retreat) */
  overflow: hidden;
}
/* Living shader canvas — fills the overlay. Its visibility rides on the
   overlay's own opacity transition, so as the menu opens the field is
   what fades in and fills the screen (not a flat paper background that
   pops first). The nav links are delayed to materialize after the field
   has landed. */
.menu-shader-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
  opacity: 0.97;
  z-index: 0;
}
.menu-overlay.is-open {
  opacity: 1;
  pointer-events: auto;
  transition: opacity 1.2s cubic-bezier(0.25, 1, 0.5, 1); /* open: no delay */
}
/* Plaster wipe — page-transition curtain for non-menu internal navs (pill
   buttons, work cards, etc.). A single persistent <div.page-wipe> injected
   by the router slides up from below, fully covers at midpoint (the swap
   moment), then continues up off the top. Matches the wall color so it
   reads as the wall briefly stepping in front of itself. Distinct from
   the menu's smoke transition (smoke = "big moment"; wipe = everyday). */
.page-wipe {
  position: fixed;
  inset: 0;
  z-index: 8000;
  /* White source → pure black under the global invert, matching the near-black
     dark-mode wall (paper would invert to dark blue). */
  background: #fff;
  transform: translateY(100%);
  pointer-events: none;
  will-change: transform;
}
.page-wipe.is-running {
  animation: page-wipe-up 1.2s cubic-bezier(0.65, 0, 0.35, 1) forwards;
}
@keyframes page-wipe-up {
  0%   { transform: translateY(100%); }
  50%  { transform: translateY(0); }
  100% { transform: translateY(-100%); }
}

.menu-overlay-list {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column;
  align-items: flex-start;
  gap: clamp(1rem, 2.5vh, 2.2rem);
  /* Box = nav text + reserved space for the submenu/preview that fly out to
     the right of "Brand Work". Centering this padded box centers the whole
     composition (nav + submenu + image) as one cell on the page. */
  width: fit-content;
  margin-inline: auto;
  padding-right: calc(clamp(2rem, 4vw, 4rem) + 27rem + clamp(16rem, 22vw, 26rem));
  position: relative;
  z-index: 1;
}
.menu-overlay-list li {
  opacity: 0;
  transition: opacity 0.4s ease-out; /* close: fast dissolve-out */
}
/* All four nav links dissolve in together, after the smoke has filled. */
.menu-overlay.is-open .menu-overlay-list li {
  opacity: 1;
  transition: opacity 1.0s ease-out 0.45s;
}

/* When a menu item is clicked, fade the words and submenu out while the
   smoke holds at full, then the page navigates. Drives the "zoom out
   into the new page" transition cleanly out of the menu. */
.menu-overlay.is-navigating .menu-overlay-list > li,
.menu-overlay.is-navigating .menu-submenu-wrap {
  opacity: 0 !important;
  transition: opacity 0.5s ease-out !important;
}

.menu-overlay-list a {
  display: inline-flex;
  align-items: baseline;
  gap: 2.5rem;
  color: var(--ink);
  text-decoration: none;
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(3rem, 7vw, 6rem);
  line-height: 1;
  letter-spacing: -0.02em;
}

/* Submenu — appears to the right of "Work" on hover, listing every
   project vertically. Hovering a project shows its hero image to the
   right of the list. Injected by js/menu-shader.js so the markup stays
   a single source of truth across all pages. */
.menu-overlay-list li.has-submenu {
  align-self: flex-start;   /* shrink to text width so submenu sits next to it */
  position: relative;
}
/* Wrap holds the project list + hero preview, sitting just right of "Brand
   Work" and vertically centered on it. */
.menu-submenu-wrap {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  left: 100%;
  padding-left: clamp(2rem, 4vw, 4rem);  /* doubles as the hover bridge */
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.45s ease;
  display: flex;
  align-items: center;
  gap: 3rem;
}
.menu-overlay-list li.has-submenu:hover .menu-submenu-wrap,
.menu-overlay-list li.has-submenu:focus-within .menu-submenu-wrap {
  opacity: 1;
  pointer-events: auto;
}
.menu-submenu {
  list-style: none;
  margin: 0;
  padding: 0;
  min-width: 22rem;
  display: flex;
  flex-direction: column;
  gap: clamp(0.4rem, 1vh, 0.75rem);
}
/* Submenu items don't inherit the outer list's dissolve. */
.menu-submenu li {
  opacity: 1 !important;
  transition: none !important;
}
.menu-submenu a {
  display: inline-flex;
  align-items: baseline;
  gap: 1rem;
  text-decoration: none;
  color: var(--ash);
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1rem, 1.3vw, 1.2rem);
  line-height: 1.3;
  letter-spacing: 0;
  transition: color 0.3s ease;
}
.menu-submenu a:hover { color: var(--ink); }
.menu-submenu-num {
  font-family: var(--font-sans);
  font-style: normal;
  font-size: 0.6rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--stone);
  width: 1.8rem;
  flex: none;
  font-feature-settings: "tnum" 1;
}
.menu-submenu-name { flex: 1; }

/* Hero preview — fades in when a project is hovered. */
.menu-submenu-preview {
  flex: none;
  width: clamp(16rem, 22vw, 26rem);
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border-radius: 2px;
  background: rgba(23, 21, 18, 0.04);
  opacity: 0;
  transition: opacity 0.4s ease;
}
.menu-submenu-preview.is-active { opacity: 1; }
.menu-submenu-preview img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}

/* Responsive: tighten then drop the preview, then hide the whole thing on
   narrow viewports where it doesn't fit. */
@media (max-width: 1280px) {
  .menu-submenu-wrap { padding-left: clamp(1.5rem, 3vw, 3rem); }
  .menu-submenu-preview { display: none; }
}
@media (max-width: 900px) {
  .menu-submenu-wrap { display: none; }
  /* Submenu is gone here — drop its reserved space (else the desktop padding-right
     shoves the nav off-canvas). Keep the items left-aligned, matching desktop. */
  .menu-overlay-list { padding-right: 0; width: auto; align-items: flex-start; text-align: left; margin-inline: 0; padding-left: 0.7rem; }
  .menu-overlay-list li.has-submenu { align-self: flex-start; }
  /* The sticky 3-column works-cycle frame is cramped at this width. */
  .works-cycle-frame { display: none; }
  /* Keep each word's glyphs together so split-char headings never break
     mid-word on narrow screens (desktop keeps the .cw unstyled = no-op). */
  .split-chars .cw { white-space: nowrap; }
  /* Promote the shader canvas to its own compositor layer so iOS keeps it
     pinned as a fixed background during scroll (paired with the JS render-pause
     that leaves it a static layer). */
  #shaderBg { transform: translateZ(0); will-change: transform; backface-visibility: hidden; }
}
@media (pointer: coarse) {
  .menu-submenu-wrap { display: none; }
  .menu-overlay-list { padding-right: 0; width: auto; align-items: flex-start; text-align: left; margin-inline: 0; padding-left: 0.7rem; }
  .menu-overlay-list li.has-submenu { align-self: flex-start; }
  #shaderBg { transform: translateZ(0); will-change: transform; backface-visibility: hidden; }
}

/* Mobile/tablet inner scroll container: the page content scrolls inside
   #scroll-root so the document/body never scrolls — keeping the fixed WebGL
   canvas truly pinned (no iOS drift) while the shader camera follows the
   container's scroll for parallax. Desktop sets nothing on #scroll-root, so it
   stays an inert passthrough div and the window scrolls exactly as before. */
@media (max-width: 900px), (pointer: coarse) {
  html, body { height: 100%; overflow: hidden; }
  #scroll-root {
    height: 100dvh;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: none;
  }
  /* The menu lock must target the wrapper, since body no longer scrolls here. */
  body.menu-open #scroll-root { overflow: hidden; }
  /* (Client-logo mobile swipe override lives AFTER the base .logo-ticker rules
     so it wins the cascade — see the block just below the tickerScroll keyframe.) */
}

@media (prefers-reduced-motion: reduce) {
}
.menu-overlay-num { display: none; }

.menu-overlay-footer { display: none; }

body.menu-open { overflow: hidden; }

/* Menu is now visually transparent — its background was the only thing
   hiding page content. Fade main/footer out when the menu opens so the
   user sees only the plaster wall (shaderBg) + smoke + menu items. */
main, footer {
  transition: opacity 0.25s ease;
}
body.menu-open main,
body.menu-open footer {
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  .menu-overlay,
  .menu-overlay-list li,
  .menu-overlay-footer { transition-duration: 0.01ms !important; transform: none !important; }
  .menu-shader-canvas { display: none; }
}

/* ============ HERO ============ */
.hero {
  min-height: 100vh;
  display: flex; flex-direction: column;
  justify-content: flex-end;
  padding: 8rem var(--pad) var(--pad);
  position: relative;
}
.hero-headline { margin-top: auto; padding-bottom: 1rem; }
.hero-headline h1 {
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(3rem, 7vw, 6.5rem);
  line-height: 1.05; letter-spacing: -0.02em;
}
.hero-headline em { color: var(--orange); }
.hero-meta {
  position: absolute; bottom: var(--pad); right: var(--pad);
  text-align: right;
  font-size: 0.65rem; text-transform: uppercase;
  letter-spacing: 0.12em; color: var(--gray);
  display: flex; flex-direction: column; gap: 0.15rem;
}
.hero-meta .line-mask { display: block; }
.hero-meta .line-inner { display: block; text-align: right; }

/* ============ SECTION LABEL ============ */
.section-label {
  font-size: 0.7rem; text-transform: uppercase;
  letter-spacing: 0.2em; color: var(--gray);
  margin-bottom: 3rem;
}

/* ============ INTRO ============ */
.intro { padding: clamp(16rem, 32vh, 26rem) var(--pad) 11rem; }
.intro-head { margin-bottom: 1.25rem; }
.intro-eyebrow {
  font-family: var(--font-sans);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ash);
}
.intro-rule {
  border-top: 1px solid var(--line);
  margin: 0 0 2.75rem;
}
.intro-content h2 {
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(1.8rem, 3.5vw, 2.8rem);
  line-height: 1.35; margin-bottom: 2rem;
  max-width: 1100px;
}
.intro-content h2 em { color: var(--orange); }
.intro-sub {
  font-family: var(--font-sans); font-weight: 400;
  font-size: clamp(0.95rem, 1.2vw, 1.05rem);
  line-height: 1.85; color: var(--gray-light);
  max-width: 760px; margin-bottom: 2.5rem;
}

/* ============ PILL BUTTON ============ */
.pill-btn {
  display: inline-block;
  border: 1px solid var(--border-light);
  padding: 0.5rem 1.5rem; border-radius: 100px;
  font-size: 0.7rem; text-transform: uppercase;
  letter-spacing: 0.12em; font-weight: 500;
  margin-top: 1rem; color: var(--white);
  transition: border-color 0.3s, background 0.3s, color 0.3s;
}
.pill-btn:hover { border-color: var(--ink); background: var(--ink); color: var(--paper); }

/* ============ STATS ============ */
.stats {
  padding: 6rem var(--pad);
}
.stats-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 3rem; max-width: 1200px; margin: 0 auto;
}
.stat { text-align: center; }
.stat-number {
  display: block; font-family: var(--font-serif);
  font-size: clamp(2.5rem, 5vw, 4rem);
  font-weight: 400; color: var(--orange);
  margin-bottom: 0.5rem; line-height: 1;
}
.stat-label { font-size: 0.8rem; color: var(--gray); line-height: 1.5; }

/* ============ SELECTED WORK — Vertical scroll-through (obys-style) ===
   The image rail and the sticky frame share the same grid cell so the
   sticky frame stays pinned at viewport top while the image column
   scrolls through it. Active item is the one nearest viewport center. */
.works-cycle {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  padding: 0 var(--pad);
}
.works-cycle-head {
  position: absolute;
  top: 10rem;
  left: var(--pad);
  right: var(--pad);
  z-index: 3;
}
.works-cycle-label {
  margin-bottom: 0.85rem;
}
.works-cycle-rule {
  border-top: 1px solid var(--line);
}

/* Sticky frame — left names, right meta, with the middle column reserved
   as the gap the image rail flows through. Pinned at the viewport top.
   align-items: start + padding-top puts names/meta at the same y as the
   first image's entry point, so the three columns read as one row. */
.works-cycle-frame {
  grid-column: 1; grid-row: 1;
  position: sticky; top: 0;
  height: 100vh;
  display: grid;
  grid-template-columns: 1fr clamp(420px, 50vw, 760px) 1fr;
  align-items: start;
  padding-top: 45vh;
  pointer-events: none;
  z-index: 2;
}
.works-cycle-frame > * { pointer-events: auto; }

.works-cycle-names {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 0.35rem;
  font-family: var(--font-sans);
  font-size: 0.95rem;
}
.works-cycle-names a {
  color: var(--stone);
  text-decoration: none;
  transition: color 0.35s ease;
  cursor: none;
}
.works-cycle-names a.is-active { color: var(--ink); }

.works-cycle-meta {
  grid-column: 3;
  display: flex; flex-direction: column; align-items: flex-end; gap: 0.5rem;
  font-family: var(--font-sans);
  font-size: 0.95rem;
  color: var(--ink);
  text-align: right;
}
.works-cycle-tags { color: var(--ink); }
.works-cycle-index {
  font-variant-numeric: tabular-nums;
  color: var(--ash);
}

/* Image rail — vertical column scrolling through the sticky frame */
.works-cycle-rail {
  grid-column: 1; grid-row: 1;
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column;
  align-items: center;
  /* Top/bottom padding so first and last image can reach viewport center.
     Top matches the frame's padding so first image lines up with names/meta. */
  padding: 45vh 0 35vh;
  gap: 25vh;
  z-index: 1;
}
.works-cycle-item {
  width: clamp(220px, 22vw, 360px);
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border-radius: 2px;
  transition: transform 0.6s cubic-bezier(0.16,1,0.3,1);
}
.works-cycle-item a {
  display: block;
  width: 100%; height: 100%;
  cursor: none;
  position: relative;
}
.works-cycle-item img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  filter: grayscale(1);
  transition: filter 0.55s ease, transform 0.7s cubic-bezier(0.16,1,0.3,1);
}
.works-cycle-item.is-active img { filter: grayscale(0); }
/* Hover: the img's transform/filter are rewritten inline every frame, so lift the
   WRAPPER instead — scale it up. Pairs with the cursor's ring + "View" label.
   (No frame/border — relies on the cursor ring for the affordance.) */
.works-cycle-item:hover { transform: scale(1.05); }

/* ============ SERVICES ============ */
.services { padding: 10rem var(--pad); border-top: 1px solid var(--border); }
.services-headline {
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(1.8rem, 3.5vw, 2.8rem);
  line-height: 1.35; max-width: 650px; margin-bottom: 6rem;
}
.services-headline em { font-style: italic; }
.services-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 3rem; max-width: 1200px;
}
.service-pill {
  display: inline-block;
  min-width: 150px; text-align: center;
  border: 1px solid var(--accent); color: var(--accent);
  padding: 0.3rem 1rem; border-radius: 100px;
  font-family: var(--font-sans); font-size: 0.7rem;
  text-transform: uppercase; letter-spacing: 0.12em; font-weight: 500;
  text-decoration: none; cursor: pointer;
  transition: background 0.3s, color 0.3s;
}
.service-col:hover .service-pill { background: var(--ink); color: var(--paper); }
.service-col-title { margin-bottom: 1.5rem; }
.service-col ul { list-style: none; }
.service-col li {
  padding: 0.55rem 0; font-size: 0.9rem; color: var(--ash);
  border-bottom: 1px solid var(--line);
  transition: color 0.3s, padding-left 0.3s;
}
.service-col li:hover { color: var(--ink); padding-left: 0.5rem; }

/* ============ PROCESS ============ */
.process { padding: 10rem var(--pad); border-top: 1px solid var(--border); }
.process-title {
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(2.5rem, 5vw, 4.5rem); margin-bottom: 0.75rem;
}
.process-subtitle {
  font-size: 0.95rem; color: var(--gray);
  margin-bottom: 6rem; max-width: 450px;
}
.process-steps {
  display: grid; grid-template-columns: repeat(5, 1fr);
  gap: 1.5rem; max-width: 1200px;
}
.process-step { padding: 1.5rem 0; border-top: 2px solid var(--accent); }
.step-number {
  display: block; font-size: 0.65rem; color: var(--orange);
  letter-spacing: 0.1em; margin-bottom: 1.25rem;
}
.process-step h3 {
  font-family: var(--font-serif); font-size: 1.2rem;
  font-weight: 400; margin-bottom: 0.75rem;
}
.process-step p { font-size: 0.8rem; color: var(--gray); line-height: 1.6; }

/* ============ LOGO TICKER ============ */
.logo-ticker {
  overflow: hidden; padding: 3rem 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.logo-ticker-inner {
  display: flex; gap: 4rem;
  animation: tickerScroll 30s linear infinite;
  width: max-content; align-items: center;
}
.logo-ticker-inner img {
  height: 35px; width: auto; opacity: 0.4;
  filter: grayscale(100%) brightness(2);
  transition: opacity 0.3s; flex-shrink: 0;
}
.logo-ticker-inner img:hover { opacity: 0.8; }
/* Charles Schwab is white-on-blue; the default brightness(2) wash makes it
   invisible. Invert instead so the wordmark reads on the cream background. */
.logo-ticker-inner img.logo-schwab { filter: grayscale(100%) invert(1); }
@keyframes tickerScroll {
  0% { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}
/* Client logos on mobile/tablet: the CSS transform marquee both slid logos off
   ("cutoff/disappear") and blocked touch. Instead make the row a real scroller
   (swipeable) and drive an infinite auto-loop in JS via scrollLeft (see
   initLogoTicker in main.js) — that coexists with manual dragging. The two
   duplicated logo sets stay (the loop wraps seamlessly between them). Placed
   AFTER the base rules so it wins the cascade. */
@media (max-width: 900px), (pointer: coarse) {
  .logo-ticker {
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    touch-action: pan-x;
  }
  .logo-ticker::-webkit-scrollbar { display: none; }
  .logo-ticker-inner {
    animation: none;
    transform: none;
    padding: 0 var(--pad);
  }
  .logo-ticker-inner img { opacity: 0.5; }
}

/* ============ CONTACT ============ */
.contact { padding: 10rem var(--pad) 6rem; }
.contact-info-row { display: flex; gap: 6rem; margin-bottom: 6rem; }
.contact-block { display: flex; flex-direction: column; gap: 0.6rem; }
.contact-label-pill {
  display: inline-block;
  color: var(--accent);
  padding: 0.25rem 0; border-radius: 0;
  font-size: 0.65rem; text-transform: uppercase;
  letter-spacing: 0.12em; width: fit-content;
  font-weight: 500;
}
.contact-detail { font-size: 0.9rem; color: var(--gray-light); }
.contact-cta { position: relative; }
.contact-dot {
  width: 12px; height: 12px;
  background: var(--accent); border-radius: 50%;
  margin-bottom: 2rem;
}
.contact-cta h2 {
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(2rem, 4.5vw, 4rem); line-height: 1.2;
}
.contact-cta h2 em { color: var(--orange); }
.email-link {
  text-decoration: underline;
  text-underline-offset: 6px;
  text-decoration-color: var(--orange);
}
.email-link:hover { text-decoration-color: var(--white); color: var(--white); }

/* ============ FOOTER ============ */
.footer { padding: 1.5rem var(--pad); border-top: 1px solid var(--border); }
.footer-row {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 0.65rem; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--gray);
}
.footer-row a { color: var(--gray); }
.footer-row a:hover { color: var(--white); }
.footer-divider { margin: 0 0.6rem; opacity: 0.3; }
.footer-center { display: flex; align-items: center; }

/* ============ PAGE HERO (inner pages) ============ */
.page-hero {
  min-height: 55vh;
  display: flex; flex-direction: column;
  justify-content: flex-end;
  padding: 8rem var(--pad) 3rem;
}
.page-hero-title {
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(3.5rem, 9vw, 8rem);
  line-height: 1; letter-spacing: -0.03em;
  margin-bottom: 1.25rem;
}
.page-hero-title em { color: var(--orange); }
.page-hero-sub {
  font-size: 1.05rem; color: var(--gray);
  max-width: 500px; line-height: 1.7;
}

/* ============ WORKS SPLIT PAGE (375-style) ============ */
/* ---- Works page: split layout ---- */
.works-split {
  display: grid; grid-template-columns: 1.1fr 0.9fr;
  height: 100vh; overflow: hidden;
}
.works-left {
  position: relative; height: 100vh;
  display: flex; flex-direction: column;
  justify-content: center;
  padding: 3rem var(--pad);
}
.works-left-title {
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(2rem, 3.2vw, 3.5rem);
  line-height: 1.1; letter-spacing: -0.01em;
}
.works-left-title em { color: var(--orange); }

/* ---- Works right: scrolling image column ---- */
.works-right {
  position: relative; height: 100vh;
  overflow: hidden;
}

/* Purple atmospheric glow — bottom */
.works-right::after {
  content: '';
  position: absolute;
  bottom: -20px; left: -10%; right: -10%;
  height: 120px;
  background: radial-gradient(
    ellipse 80% 100% at 50% 100%,
    rgba(23, 21, 18, 0.12) 0%,
    rgba(23, 21, 18, 0.04) 50%,
    transparent 100%
  );
  filter: blur(20px);
  pointer-events: none;
  z-index: 2;
}

/* Purple atmospheric glow — top */
.works-right::before {
  content: '';
  position: absolute;
  top: -20px; left: -10%; right: -10%;
  height: 120px;
  background: radial-gradient(
    ellipse 80% 100% at 50% 0%,
    rgba(23, 21, 18, 0.12) 0%,
    rgba(23, 21, 18, 0.04) 50%,
    transparent 100%
  );
  filter: blur(20px);
  pointer-events: none;
  z-index: 2;
}

.works-scroll {
  display: flex; flex-direction: column;
  gap: 1.25rem;
  padding: 0;
  will-change: transform;
}

/* ---- Individual project cards ---- */
.works-card {
  display: block; position: relative;
  overflow: hidden; cursor: none;
  will-change: transform, filter;
  transform-origin: center center;
  backface-visibility: hidden;
}
.works-card img {
  width: 100%; aspect-ratio: 16/9;
  object-fit: cover;
  filter: brightness(0.85);
  will-change: transform, filter;
  backface-visibility: hidden;
}
.works-card h3 {
  position: absolute; bottom: 1.25rem; left: 1.25rem;
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(1.5rem, 2.5vw, 2.2rem);
  color: #fff;
  text-shadow: 0 2px 20px rgba(0,0,0,0.6);
  transition: opacity 0.4s ease;
}
/* Hover: brighten the title only. Pairs with the cursor's ring + "View" label.
   (No box-shadow frame — the bright border read as a glowing outline.) */
.works-card:hover h3 { color: #fff; }

/* ---- Brand Work cards on mobile ----
   Match the homepage / AI work cards: a normal vertical stack of 4:5 rounded
   tiles with the project name beneath each (no desktop infinite-loop scroll).
   Greyscale by default → full colour when scroll-focused (is-active); scale is
   driven per-frame in JS (initWorksScrollMobileFocus), so no transition on it. */
@media (max-width: 900px), (pointer: coarse) {
  /* Taller top padding so there's a larger gap between the top nav and the
     BRAND WORK section label. Scoped via .works-split to outrank the
     max-width:1024px padding shorthand that comes later in the file. */
  .works-split .works-left { padding-top: 13rem; border-bottom: none; }
  /* Divider line re-added as a pseudo-element so it can fade in with the
     entrance sequence (instead of the static border popping in instantly).
     Revealed via .revealed, toggled in initWorksSplitEntrance after the
     sculpture emerges. */
  .works-split .works-left::after {
    content: '';
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 1px;
    background: var(--border);
    opacity: 0;
    /* 0.7s delay = the next step in the hero's 0.35s stagger (label 0s, title
       0.35s), so the line fades in last, after the "We partner" title. */
    transition: opacity 0.9s ease 0.7s;
  }
  .works-split .works-left.revealed::after { opacity: 1; }
  .works-right::before { display: none; }
  .works-scroll {
    flex-direction: column;
    align-items: center;
    gap: 5rem;
    padding: 0 0 4rem;
    transform: none !important;
  }
  .works-card {
    width: min(80vw, 360px);
    overflow: visible;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    text-align: left;
    cursor: pointer;
  }
  .works-card img {
    order: 0;
    width: 100%;
    height: auto;          /* show each image at its natural aspect — no crop */
    aspect-ratio: auto;
    object-fit: contain;
    border-radius: 2px;
    filter: grayscale(1);
    transition: filter 0.5s ease;
    transform-origin: center;
  }
  .works-card.is-active img { filter: grayscale(0); }
  .works-card h3 {
    order: 1;
    position: static;
    margin: 1.5rem 0 0;
    font-family: var(--font-sans);
    font-weight: 500;
    font-size: 0.9rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink);
    text-shadow: none;
  }
  .works-card[data-tags]::after {
    order: 2;
    content: attr(data-tags);
    margin-top: 0.4rem;
    font-family: var(--font-sans);
    font-size: 0.75rem;
    font-weight: 300;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ash);
  }
  /* When the real caption span is injected, switch off the data-attr pseudo. */
  .works-card[data-tags].has-cap::after { content: none; }
  .works-card .card-cap-tags { display: block; }
}

/* ============ ABOUT DETAIL ============ */
.about-detail {
  padding: 8rem var(--pad) 10rem;
  border-top: 1px solid var(--border);
}
.about-detail-grid {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 6rem; max-width: 1200px; margin: 0 auto;
}
.about-detail-left h2 {
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(2rem, 3.5vw, 3rem); line-height: 1.3;
}
.about-detail-left h2 em { color: var(--orange); }
.about-detail-right p {
  font-size: 1rem; line-height: 1.85;
  color: var(--gray-light); margin-bottom: 1.5rem;
}

/* ============ ABOUT PHILOSOPHY ============ */
.about-philosophy {
  padding: 8rem var(--pad) 10rem;
  border-top: 1px solid var(--border);
}
.about-philosophy-content {
  max-width: 900px; margin: 0 auto; text-align: center;
}
.about-philosophy h2 {
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(2.5rem, 5vw, 4.5rem);
  line-height: 1.15; margin-bottom: 3rem;
}
.about-philosophy h2 em { color: var(--orange); }
.about-philosophy-text { max-width: 650px; margin: 0 auto; }
.about-philosophy-text p {
  font-size: 1rem; line-height: 1.85;
  color: var(--gray-light); margin-bottom: 1.5rem;
}

/* ============ ABOUT APPROACH ============ */
.about-approach {
  padding: 8rem var(--pad) 10rem;
  border-top: 1px solid var(--border);
}
.about-approach-title {
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(2.5rem, 5vw, 4.5rem); margin-bottom: 1rem;
}
.about-approach-title em { color: var(--orange); }
.about-approach-desc {
  font-size: 1rem; color: var(--gray);
  max-width: 550px; margin-bottom: 6rem; line-height: 1.7;
}
.about-approach-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 1.5rem; max-width: 1200px;
}
.approach-card { padding: 1.5rem 0; border-top: 2px solid var(--accent); }
.approach-number {
  display: block; font-size: 0.65rem;
  color: var(--orange); letter-spacing: 0.1em;
  margin-bottom: 1.25rem;
}
.approach-card h3 {
  font-family: var(--font-serif); font-size: 1.2rem;
  font-weight: 400; margin-bottom: 0.75rem;
}
.approach-card p { font-size: 0.8rem; color: var(--gray); line-height: 1.6; }

/* ============ ABOUT SERVICES ============ */
.about-services-full {
  padding: 8rem var(--pad) 10rem;
  border-top: 1px solid var(--border);
}
.about-services-title {
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(2.5rem, 5vw, 4.5rem); margin-bottom: 6rem;
}
.about-services-title em { color: var(--orange); }

/* ============ CONTACT PAGE ============ */
.contact-page { padding: 3rem var(--pad) 10rem; }
.contact-page-grid {
  display: grid; grid-template-columns: 1fr 1.5fr;
  gap: 6rem; max-width: 1200px; margin: 0 auto;
}
.contact-page-info { display: flex; flex-direction: column; gap: 2rem; }
.contact-detail-lg { font-size: 1.05rem; }
.contact-socials { display: flex; gap: 0.75rem; margin-top: 1rem; }
.contact-social-link {
  font-size: 0.7rem;
  border: 1px solid var(--accent); color: var(--accent);
  padding: 0.35rem 1rem; border-radius: 100px;
  text-transform: uppercase; letter-spacing: 0.08em;
  font-weight: 500;
  transition: border-color 0.3s, background 0.3s, color 0.3s;
}
.contact-social-link:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.contact-form { display: flex; flex-direction: column; gap: 1.5rem; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; }
.form-group { display: flex; flex-direction: column; gap: 0.4rem; }
.form-group label {
  font-size: 0.7rem; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--gray);
}
.form-group input,
.form-group textarea {
  background: transparent; border: none;
  border-bottom: 1px solid var(--border-med);
  color: var(--white); font-family: var(--font-sans);
  font-size: 0.95rem; padding: 0.75rem 0;
  outline: none; resize: none; cursor: none;
  transition: border-color 0.3s;
}
.form-group input:focus,
.form-group textarea:focus { border-color: var(--orange); }
.form-group textarea {
  border: 1px solid var(--border-med);
  padding: 1rem; margin-top: 0.25rem;
}
.form-group textarea:focus { border-color: var(--orange); }
.form-submit {
  align-self: flex-start;
  background: var(--ink); color: var(--paper);
  border: none; padding: 0.9rem 2.5rem;
  font-family: var(--font-sans); font-size: 0.75rem;
  text-transform: uppercase; letter-spacing: 0.12em;
  font-weight: 500; cursor: none;
  transition: background 0.3s, transform 0.3s;
}
.form-submit:hover { background: var(--ash); transform: translateY(-2px); }

/* ============ CASE STUDY PAGES — editorial long-form ============ */
/* All sections share one content column so the page reads as one
   continuous, easy-to-skim flow. Images display whole at their natural
   aspect ratio — never cropped. */
.case-eyebrow {
  font-family: var(--font-sans);
  font-size: 0.65rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ash);
  display: block;
  margin-bottom: 1rem;
}
.case-eyebrow em {
  font-family: var(--font-serif);
  font-style: italic;
  letter-spacing: 0;
  text-transform: none;
  font-size: 0.85rem;
  color: var(--ink);
  margin-right: 0.35rem;
}

/* Back to all projects — sits above the project eyebrow */
.case-back {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin-bottom: 1.6rem;
  font-family: var(--font-sans);
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ash);
  transition: color 0.3s ease;
}
.case-back:hover { color: var(--ink); }
.case-back-arrow {
  display: inline-block;
  font-size: 0.8rem;
  transition: transform 0.3s ease;
}
.case-back:hover .case-back-arrow { transform: translateX(-4px); }

/* Hero — eyebrow, title, tagline. Compact. */
.case-hero {
  padding: 9rem var(--pad) 0;
  max-width: 1100px;
  margin: 0 auto;
}
.case-title {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(3rem, 7vw, 6rem);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0 0 1.25rem;
}
.case-tagline {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(1.05rem, 1.5vw, 1.35rem);
  line-height: 1.45;
  max-width: 30em;
  color: var(--ash);
  margin: 0;
}
.case-play-btn {
  display: inline-flex; align-items: center; gap: 0.6rem;
  margin-top: 1.75rem; padding: 0.65rem 1.3rem;
  background: transparent; border: 1px solid var(--line-strong);
  color: var(--ink); font-family: var(--font-sans);
  font-size: 0.68rem; text-transform: uppercase;
  letter-spacing: 0.18em;
  border-radius: 100px; cursor: pointer;
  transition: background 0.3s, color 0.3s, border-color 0.3s;
}
.case-play-btn:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.case-play-btn svg { width: 11px; height: 11px; }
/* "Visit site" external-link buttons in the case hero — same pill as the play
   button; sits in a wrapping row so multiple links flow on narrow screens. */
.case-links { display: flex; flex-wrap: wrap; gap: 0.85rem; margin-top: 1.75rem; }
.case-links .case-play-btn, .case-links .case-link-btn { margin-top: 0; }
.case-link-btn {
  display: inline-flex; align-items: center; gap: 0.6rem;
  padding: 0.65rem 1.3rem;
  background: transparent; border: 1px solid var(--line-strong);
  color: var(--ink); font-family: var(--font-sans);
  font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.18em;
  text-decoration: none; border-radius: 100px;
  transition: background 0.3s, color 0.3s, border-color 0.3s;
}
.case-link-btn:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.case-link-btn svg { width: 12px; height: 12px; }

/* Meta strip */
.case-meta {
  max-width: 1100px;
  margin: 2.5rem auto 3rem;
  padding: 0 var(--pad);
  border-top: 1px solid var(--line);
}
.case-meta-row {
  display: grid;
  grid-template-columns: 160px 1fr;
  gap: 2rem;
  padding: 1rem 0;
  border-bottom: 1px solid var(--line);
  align-items: baseline;
}
.case-meta-label {
  font-family: var(--font-sans);
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ash);
}
.case-meta-value {
  font-family: var(--font-sans);
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--ink);
}

/* Images — contained to the content column, shown WHOLE at their
   natural aspect ratio. No cropping, no forced heights. */
.case-bleed {
  max-width: 1100px;
  margin: 3.5rem auto;
  padding: 0 var(--pad);
}
.case-bleed img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 2px;
}
.case-bleed figcaption {
  margin-top: 0.85rem;
  font-family: var(--font-sans);
  font-size: 0.65rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ash);
}
/* Portrait / tall screenshots — shown whole at a reduced, centered width so
   they read intentionally instead of running the full column height. */
.case-bleed.is-portrait img,
.case-grid-two figure.is-portrait img { max-width: min(460px, 82vw); }
.case-bleed.is-portrait { text-align: center; }
.case-bleed.is-portrait img { margin-inline: auto; }
.case-bleed.is-portrait figcaption { text-align: center; }

/* Two-up image grid — natural aspect, top-aligned */
.case-grid-two {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
  max-width: 1100px;
  margin: 3.5rem auto;
  padding: 0 var(--pad);
  align-items: start;
}
.case-grid-two figure { margin: 0; }
.case-grid-two img {
  width: 100%; height: auto;
  display: block;
  border-radius: 2px;
}

/* Video — full-width, natural aspect, rounded like images */
.case-video {
  max-width: 1100px;
  margin: 3.5rem auto;
  padding: 0 var(--pad);
}
.case-video figure { margin: 0; }
.case-video video,
.case-grid-two video {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 2px;
}
/* Row of vertical social reels (e.g. LuxxEV Dashies) — 4-up on desktop, 2-up on
   narrow screens. */
.case-reels {
  max-width: 1100px;
  margin: 3.5rem auto;
  padding: 0 var(--pad);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.85rem;
}
.case-reels video {
  width: 100%;
  height: auto;
  display: block;
  aspect-ratio: 9 / 16;
  object-fit: cover;
  border-radius: 2px;
  background: #000;
}
.case-reels-caption {
  grid-column: 1 / -1;
  margin: 0.85rem 0 0;
  font-family: var(--font-sans);
  font-size: 0.65rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ash);
}
@media (max-width: 700px) {
  .case-reels { grid-template-columns: repeat(2, 1fr); }
}
/* Inline embedded player (e.g. a YouTube spot) — responsive 16:9 box. */
.case-embed {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 2px;
  overflow: hidden;
}
.case-embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.case-video figcaption {
  margin-top: 0.85rem;
  font-family: var(--font-sans);
  font-size: 0.65rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ash);
}

/* Story sections — sticky label + body, tight rhythm */
.case-story {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 var(--pad);
}
.case-story-block {
  display: grid;
  grid-template-columns: 160px 1fr;
  gap: 3rem;
  padding: 3rem 0;
  border-top: 1px solid var(--line);
}
.case-story-block:first-child { border-top: none; padding-top: 1.5rem; }
.case-story-label {
  font-family: var(--font-sans);
  font-size: 0.65rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ash);
  position: sticky;
  top: 7rem;
  align-self: start;
}
.case-story-body p {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(1.05rem, 1.25vw, 1.2rem);
  line-height: 1.65;
  color: var(--ink);
  margin: 0 0 1.1rem;
  max-width: 40em;
}
.case-story-body p:last-child { margin-bottom: 0; }

/* Impact — vertical numbered list */
.case-impact {
  max-width: 1100px;
  margin: 4.5rem auto;
  padding: 0 var(--pad);
}
.case-impact-list {
  list-style: none;
  padding: 0;
  margin: 0;
  border-top: 1px solid var(--line);
}
.case-impact-list li {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: 2rem;
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--line);
  align-items: baseline;
}
.case-impact-num {
  font-family: var(--font-sans);
  font-size: 0.65rem;
  letter-spacing: 0.22em;
  color: var(--ash);
  font-feature-settings: "tnum" 1;
}
.case-impact-text {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.2rem, 1.9vw, 1.7rem);
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--ink);
}

/* Pull quote */
.case-quote {
  max-width: 1100px;
  margin: 4.5rem auto;
  padding: 0 var(--pad);
}
.case-quote blockquote {
  margin: 0;
  padding-top: 2rem;
  border-top: 1px solid var(--line);
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.45rem, 2.9vw, 2.3rem);
  line-height: 1.38;
  letter-spacing: -0.01em;
  color: var(--ink);
  max-width: 24em;
}
.case-quote cite {
  display: block;
  margin-top: 1.5rem;
  font-family: var(--font-sans);
  font-style: normal;
  font-size: 0.65rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ash);
}

/* Films — video thumbnail grid */
.case-films {
  max-width: 1100px;
  margin: 4.5rem auto;
  padding: 0 var(--pad);
}
.case-films-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
  margin-top: 1.25rem;
}
.case-films-grid.is-single { grid-template-columns: 1fr; }
.case-film {
  display: block;
  width: 100%;
  padding: 0;
  margin: 0;
  border: none;
  background: none;
  cursor: pointer;
}
.case-film-thumb {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: 2px;
}
.case-film-thumb img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  transition: transform 0.6s ease;
}
.case-film:hover .case-film-thumb img { transform: scale(1.04); }
.case-film-play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.case-film-play svg {
  width: 22px;
  height: 22px;
  color: #fff;
  position: relative;
  left: 2px;
}
.case-film-play::before {
  content: "";
  position: absolute;
  width: 68px;
  height: 68px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.7);
  background: rgba(0, 0, 0, 0.35);
  transition: background 0.3s ease, transform 0.3s ease;
}
.case-film:hover .case-film-play::before {
  background: rgba(0, 0, 0, 0.6);
  transform: scale(1.08);
}
.case-films-caption {
  margin: 0.85rem 0 0;
  font-family: var(--font-sans);
  font-size: 0.65rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ash);
}

/* Results — stat / description rows */
.case-results {
  max-width: 1100px;
  margin: 4.5rem auto;
  padding: 0 var(--pad);
}
.case-results-list {
  list-style: none;
  padding: 0;
  margin: 1.25rem 0 0;
  border-top: 1px solid var(--line);
}
.case-results-list li {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 2.5rem;
  padding: 1.75rem 0;
  border-bottom: 1px solid var(--line);
  align-items: baseline;
}
.case-stat-num {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(1.9rem, 3.5vw, 2.9rem);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ink);
  font-feature-settings: "tnum" 1;
}
.case-stat-label {
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--ash);
  max-width: 34em;
}

/* Awards — source / detail rows */
.case-awards {
  max-width: 1100px;
  margin: 4.5rem auto;
  padding: 0 var(--pad);
}
.case-awards-list {
  list-style: none;
  padding: 0;
  margin: 1.25rem 0 0;
  border-top: 1px solid var(--line);
}
.case-awards-list li {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 2.5rem;
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--line);
  align-items: baseline;
}
.case-award-source {
  font-family: var(--font-sans);
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ash);
  line-height: 1.5;
}
.case-award-detail {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(1.05rem, 1.4vw, 1.25rem);
  line-height: 1.5;
  color: var(--ink);
}

/* Previous / next project navigation */
.case-next {
  max-width: 1100px;
  margin: 4.5rem auto 4rem;
  padding: 2.5rem var(--pad) 0;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
}
.case-next-link {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  text-decoration: none;
  color: var(--ink);
}
.case-next-next { text-align: right; }
.case-next-text {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.case-next-label {
  font-family: var(--font-sans);
  font-size: 0.6rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ash);
  transition: color 0.3s ease;
}
.case-next-name {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(1.15rem, 1.8vw, 1.6rem);
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.case-next-arrow {
  flex: none;
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1;
  color: var(--ink);
  transition: background 0.35s ease, color 0.35s ease, transform 0.35s ease;
}
.case-next-prev:hover .case-next-arrow {
  background: var(--ink);
  color: var(--paper);
  transform: translateX(-4px);
}
.case-next-next:hover .case-next-arrow {
  background: var(--ink);
  color: var(--paper);
  transform: translateX(4px);
}
.case-next-link:hover .case-next-label { color: var(--ink); }

/* Video Lightbox (CLIF KID) */
.video-lightbox {
  position: fixed; inset: 0; z-index: 10000;
  background: rgba(23, 21, 18, 0.92);
  display: flex; align-items: center; justify-content: center;
  opacity: 0; pointer-events: none;
  transition: opacity 0.4s ease;
}
.video-lightbox.active { opacity: 1; pointer-events: all; }
.lightbox-inner {
  width: 85vw; max-width: 1100px;
  aspect-ratio: 16 / 9;
}
.lightbox-inner iframe,
.lightbox-inner video { width: 100%; height: 100%; border-radius: 4px; }
.lightbox-inner video { background: #000; object-fit: contain; }
.lightbox-close {
  position: absolute; top: 1.5rem; right: 1.5rem;
  background: none; border: none; color: var(--white);
  font-size: 2rem; cursor: none; line-height: 1;
  transition: color 0.3s;
}
.lightbox-close:hover { color: var(--ash); }

/* ============ SCULPTURE INFO CARD (relief-info.js) ============ */
/* Blur the DOM content layers while a card is open; #shaderBg (the sculpture +
   wall) is deliberately excluded, and since those layers are transparent over
   the canvas, the sculpture reads sharp behind the blurred content. */
html.relief-zoom-open #header,
html.relief-zoom-open #scroll-root,
html.relief-zoom-open #menuOverlay {
  filter: blur(7px);
  transition: filter 0.45s ease;
  pointer-events: none;
}
/* Scroll-lock while open. Desktop scrolls window; mobile scrolls #scroll-root. */
html.relief-zoom-open,
html.relief-zoom-open body { overflow: hidden; }
html.relief-zoom-open #scroll-root { overflow: hidden !important; }

/* Card entrance — the site's own motion language rather than a literal prop.
   The panel settles in with a restrained fade + lift + faint focus-pull (blur),
   and the fields cascade top→bottom (title first), echoing the statue-first
   hero cascades elsewhere. Closing reverses with no stagger (a clean fade-out). */
.relief-card {
  --card-ease: cubic-bezier(0.16, 1, 0.3, 1);
  position: fixed;
  z-index: 10001;
  width: min(300px, calc(100vw - 32px));
  pointer-events: none;
  outline: none;
  opacity: 0;
  transform: translateY(14px) scale(0.985);
  filter: blur(6px);
  transition: opacity 0.5s ease, transform 0.7s var(--card-ease), filter 0.5s ease;
  will-change: opacity, transform, filter;
}
.relief-card.active {
  pointer-events: auto;
  opacity: 1;
  transform: none;
  filter: blur(0);
}

.relief-card-paper {
  position: relative;
  padding: 1.4rem 1.5rem 1.5rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 4px;
  box-shadow: 0 24px 60px -12px rgba(23, 21, 18, 0.35),
              0 4px 14px rgba(23, 21, 18, 0.18);
}

/* Fields cascade in after the panel settles. Each row lifts + fades, staggered
   top→bottom. The × fades with the panel (no stagger of its own). */
.relief-row {
  opacity: 0;
  transform: translateY(9px);
  transition: opacity 0.55s var(--card-ease), transform 0.55s var(--card-ease);
}
.relief-card.active .relief-row { opacity: 1; transform: none; }
.relief-card.active .relief-row:nth-child(1) { transition-delay: 0.16s; }
.relief-card.active .relief-row:nth-child(2) { transition-delay: 0.24s; }
.relief-card.active .relief-row:nth-child(3) { transition-delay: 0.32s; }
.relief-card.active .relief-row:nth-child(4) { transition-delay: 0.40s; }
.relief-card.active .relief-row:nth-child(5) { transition-delay: 0.48s; }

.relief-card-close:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* Phones: a smaller, tighter card. */
@media (max-width: 600px) {
  .relief-card { width: min(220px, calc(100vw - 48px)); }
  .relief-card-paper { padding: 1rem 1.1rem 1.1rem; }
  .relief-card-fields { gap: 0.4rem; }
  .relief-row { padding-bottom: 0.4rem; }
  .relief-row dt { font-size: 0.56rem; letter-spacing: 0.1em; }
  .relief-row dd { font-size: 0.92rem; }
  .relief-row:first-child dd { font-size: 1.15rem; }
  .relief-card-close { font-size: 1.3rem; top: 0.35rem; right: 0.5rem; }
}

.relief-card-fields { display: flex; flex-direction: column; gap: 0.55rem; margin: 0; }
.relief-row {
  display: flex; flex-direction: column; gap: 0.1rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--line);
}
.relief-row:last-child { padding-bottom: 0; border-bottom: none; }
.relief-row dt {
  font-family: var(--font-sans); font-size: 0.62rem; font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.12em; color: var(--ash);
}
.relief-row dd {
  margin: 0;
  font-family: var(--font-serif); font-size: 1.05rem; line-height: 1.3; color: var(--ink);
}
/* Name = the headline field — larger italic, echoing the page-hero <em>. */
.relief-row:first-child dd { font-size: 1.35rem; font-style: italic; }

.relief-card-close {
  position: absolute; top: 0.5rem; right: 0.65rem;
  background: none; border: none; color: var(--ash);
  font-size: 1.5rem; line-height: 1; cursor: none;
  transition: color 0.3s;
}
.relief-card-close:hover { color: var(--ink); }
@media (pointer: coarse) { .relief-card-close { cursor: auto; } }

/* Inverted mode: let the card ride the page invert so it adopts a dark theme
   consistent with the rest of the inverted UI (paper→near-black, ink→light).
   The drop shadow inverts to a soft light halo, which suits the dark backdrop. */

@media (prefers-reduced-motion: reduce) {
  .relief-card { opacity: 0; transform: none; filter: none; transition: opacity 0.2s ease; }
  .relief-card.active { opacity: 1; }
  .relief-row { opacity: 1; transform: none; transition: none; transition-delay: 0s; }
  html.relief-zoom-open #header,
  html.relief-zoom-open #scroll-root,
  html.relief-zoom-open #menuOverlay { transition: none; }
}

/* ============ SCROLL ANIMATIONS ============ */
.reveal {
  opacity: 0; transform: translateY(30px);
  transition: opacity 0.8s cubic-bezier(0.16,1,0.3,1),
              transform 0.8s cubic-bezier(0.16,1,0.3,1);
}
.reveal.visible { opacity: 1; transform: translateY(0); }

/* ============ STUDIO / ABOUT PAGE ============ */
.studio-hero {
  min-height: 100vh;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: 8rem var(--pad) 4rem;
  text-align: center;
  position: relative;
}
.studio-badge {
  display: inline-block;
  border: 2px solid var(--white);
  border-radius: 29px;
  padding: 0.3rem 1rem;
  font-size: 0.8rem; font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-bottom: 3rem;
}
.studio-heading {
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(2.5rem, 5vw, 4.5rem);
  line-height: 1.2; max-width: 900px;
}
.studio-heading em { color: var(--orange); }

/* Tagline Section */
.studio-tagline {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: 6rem var(--pad);
  border-top: 1px solid var(--border);
}
.studio-tagline-text { text-align: center; max-width: 1000px; }
.studio-tagline-h2 {
  font-size: clamp(3rem, 7vw, 6.5rem);
  line-height: 1.1; margin-bottom: 3rem;
}
.tagline-line { display: block; }
.font-serif { font-family: var(--font-serif); font-weight: 400; }
.font-sans { font-family: var(--font-sans); }
.font-bold { font-weight: 600; text-transform: uppercase; }
.tag-italic { font-style: italic; }
.studio-tagline-sub {
  font-size: 1.1rem; font-weight: 400;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--gray-light);
  max-width: 700px; margin: 0 auto 3rem;
  line-height: 1.7;
}
.studio-tagline-pills { display: flex; gap: 1rem; justify-content: center; }
.studio-pill {
  border: 2px solid var(--white);
  border-radius: 29px;
  padding: 0.4rem 1.2rem;
  font-size: 0.8rem; font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.08em;
  transition: background 0.3s, color 0.3s, border-color 0.3s;
  color: var(--white);
}
.studio-pill:hover {
  background: var(--ink); border-color: var(--ink);
  color: var(--paper);
}

/* Agency Description */
.studio-about {
  padding: 10rem var(--pad) 6rem;
  min-height: 100vh;
  /* desktop: sit the hero block lower (vertically centered) rather than
     top-aligned. Mobile re-anchors it to the bottom in the 768px block. */
  display: flex; flex-direction: column; justify-content: center;
}
.studio-about-main {
  max-width: 1100px;
}
/* "Info" eyebrow above the lead paragraph (mirrors the homepage intro). The
   divider line below it shows on mobile only — see the max-width:768px block. */
.studio-about-eyebrow {
  font-family: var(--font-sans);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ash);
  margin-bottom: 1.25rem;
}
.studio-about-rule { display: none; }   /* desktop: label only, no line */
.studio-about-large {
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(2rem, 4vw, 3.8rem);
  line-height: 1.3;
}
.studio-about-large em { font-style: italic; color: var(--orange); }
.studio-about-sub {
  font-family: var(--font-sans); font-weight: 300;
  font-size: clamp(1rem, 1.4vw, 1.2rem);
  line-height: 1.85; color: var(--gray-light);
  max-width: 760px; margin-top: 2.25rem;
}
/* Editorial statement — its own centered section between the lead and "What We Do". */
.studio-statement {
  padding: 7rem var(--pad);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.studio-statement-heading {
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(2.5rem, 5vw, 4rem);
  text-align: center; margin-bottom: 2.5rem;
}
.studio-statement-heading em { color: var(--orange); }
.studio-statement-body { max-width: 1040px; margin: 0 auto; text-align: center; }
.studio-statement-body p {
  font-family: var(--font-sans); font-weight: 300;
  font-size: clamp(1.05rem, 1.5vw, 1.3rem);
  line-height: 1.85; color: var(--gray-light);
  margin-bottom: 1.75rem;
}
.studio-statement-body p:last-child { margin-bottom: 0; }

/* Client Logo Grid */
.studio-logos {
  padding: 6rem var(--pad);
}
.studio-logos-label {
  display: block;
  font-size: 0.7rem; font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.15em;
  color: var(--gray); margin-bottom: 3rem;
}
.studio-logos-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 0;
  max-width: 1200px;
}
.logo-cell {
  aspect-ratio: 1;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border);
  padding: 1.5rem;
  transition: border-color 0.3s;
}
.logo-cell:hover { border-color: var(--accent); }
.logo-cell img {
  width: 100%; height: 100%;
  object-fit: contain;
  filter: grayscale(100%) brightness(2);
  opacity: 0.5;
  transition: opacity 0.3s, filter 0.3s;
}
.logo-cell:hover img { opacity: 0.9; }

/* Studio Approach */
.studio-approach {
  padding: 10rem var(--pad);
}
.studio-section-heading {
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(3rem, 7vw, 6rem);
  margin-bottom: 2rem;
}
.studio-section-heading em { color: var(--orange); }
.studio-approach-sub {
  font-size: 1rem; color: var(--gray);
  max-width: 600px; margin-bottom: 6rem;
  line-height: 1.7;
}
.studio-services .studio-approach-sub { max-width: none; }
.studio-services .studio-section-heading { margin-bottom: 1rem; }
.studio-approach-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 1.5rem; max-width: 1200px;
}

/* Studio Services */
.studio-services {
  padding: 10rem var(--pad);
}

/* ============ TEXT ANIMATIONS ============ */

/*
 * Line-mask reveal system (Studio375-style)
 * Each line is wrapped in .line-mask (overflow:hidden)
 * containing .line-inner which slides up from below.
 * Stagger is applied via CSS custom property --line-i
 * set in JS. The motion is tight: short distance,
 * smooth easing, slight opacity fade.
 */

/* Mask container: no overflow hidden needed with clip-path approach */
.line-mask {
  display: block;
  position: relative;
}

/*
 * The text line uses clip-path to reveal from bottom to top.
 * The text never moves — only the clipping rectangle animates,
 * so it feels like an unveiling, not a float.
 * A very subtle translateY (8px) adds just enough settling motion.
 */
.line-inner {
  display: block;
  clip-path: inset(100% 0 0 0);
  transform: translateY(8px);
  transition:
    clip-path 0.7s cubic-bezier(0.25, 1, 0.5, 1) calc(var(--line-i, 0) * 0.1s),
    transform 0.7s cubic-bezier(0.25, 1, 0.5, 1) calc(var(--line-i, 0) * 0.1s);
}

/* Revealed: fully unclipped, settled into place */
.line-inner.revealed {
  clip-path: inset(0 0 0 0);
  transform: translateY(0);
}

/* Split chars - hidden until animated */
.split-chars .char {
  display: inline-block;
  opacity: 0;
}

/* When .animated is added, each char plays the float-up keyframe */
.split-chars.animated .char {
  animation: charFloat 2s cubic-bezier(0.25,1,0.5,1) forwards;
  animation-delay: var(--char-delay, 0s);
}

@keyframes charFloat {
  0% { opacity: 0; transform: translateY(60px); }
  100% { opacity: 1; transform: translateY(0); }
}

/* Hero headline: a single, unified fade-in. Hidden from first paint (so there's
   no flash of raw text before the chars split, and no per-character flicker),
   then faded in as one unit by initHero once the goat relief has emerged. */
.hero .hero-headline h1.split-chars { opacity: 0; transition: opacity 2.8s ease; }
.hero .hero-headline h1.split-chars .char { transform: none; opacity: 1; }
.hero .hero-headline h1.split-chars.hero-revealed { opacity: 1; }
@keyframes heroHeadlineFade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Split words - word-by-word animation */
.split-words .word {
  display: inline-block;
  opacity: 0;
  transform: translateY(40px);
  transition: opacity 0.7s cubic-bezier(0.25,1,0.5,1),
              transform 0.7s cubic-bezier(0.25,1,0.5,1);
}
.split-words.animated .word {
  opacity: 1;
  transform: translateY(0);
}

/* Line reveal - slide up from mask (services, approach cards, etc.) */
.line-reveal {
  overflow: hidden;
}
.line-reveal-inner {
  transform: translateY(105%);
  transition: transform 0.8s cubic-bezier(0.25,1,0.5,1);
}
.line-reveal.revealed .line-reveal-inner {
  transform: translateY(0);
}

/* Scroll-triggered line-mask reveals use same clip-path system */

/* General scroll reveal for non-line-mask elements */
.reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.7s cubic-bezier(0.25,1,0.5,1),
              transform 0.7s cubic-bezier(0.25,1,0.5,1);
}
.reveal.visible {
  opacity: 1;
  transform: translateY(0);
}

/* Intro section fades in like the hero headline — pure opacity, no slide,
   paced at 2.8s ease. */
.intro .reveal {
  transform: none;
  transition: opacity 2.8s ease;
}
.intro .reveal.visible { transform: none; }

/* ===== Unified hero-style fade-in for Work / About / AI / Contact pages =====
   On .page-fade pages, every reveal/split/line animation collapses to a single
   pure opacity fade (2.8s ease) — no slide, no per-word/char stagger. */
.page-fade .reveal { transform: none; transition: opacity 2.8s ease; }
.page-fade .reveal.visible { transform: none; opacity: 1; }

.page-fade .split-words .word {
  transform: none;
  transition: opacity 2.8s ease;
  transition-delay: 0s !important;
}
.page-fade .split-words.animated .word { transform: none; opacity: 1; }

.page-fade .split-chars .char { transform: none; }
.page-fade .split-chars.animated .char {
  animation: heroHeadlineFade 2.8s ease forwards;
}

.page-fade .line-reveal { overflow: visible; }
.page-fade .line-reveal-inner {
  transform: none;
  opacity: 0;
  transition: opacity 2.8s ease;
}
.page-fade .line-reveal.revealed .line-reveal-inner { transform: none; opacity: 1; }

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .line-inner,
  .split-chars .char,
  .split-words .word,
  .line-reveal-inner,
  .reveal,
  .hero .hero-headline h1.split-chars {
    transition-duration: 0.01ms !important;
    transform: none !important;
    opacity: 1 !important;
  }
}

/* ============ RESPONSIVE ============ */
/* Laptop / tablet-landscape — ease the densest desktop grids before the
   full single-column collapse at 1024px. */
@media (max-width: 1280px) {
  .process-steps { grid-template-columns: repeat(4, 1fr); }
}

@media (max-width: 1024px) {
  .services-grid { grid-template-columns: repeat(2, 1fr); }
  .process-steps { grid-template-columns: repeat(3, 1fr); }
  .stats-grid { grid-template-columns: repeat(2, 1fr); }
  .about-approach-grid { grid-template-columns: repeat(2, 1fr); }
  .studio-approach-grid { grid-template-columns: repeat(2, 1fr); }
  .studio-logos-grid { grid-template-columns: repeat(4, 1fr); }
  .contact-page-grid { grid-template-columns: 1fr; gap: 3rem; }
  .about-detail-grid { grid-template-columns: 1fr; gap: 3rem; }
  .works-split { grid-template-columns: 1fr; height: auto; overflow: visible; }
  .works-left {
    position: relative; height: auto;
    padding: 8rem var(--pad) 3rem;
    border-right: none; border-bottom: 1px solid var(--border);
  }
  .works-right { padding-top: 2rem; height: auto; overflow: visible; }
  .works-right::after { display: none; }
  .works-scroll { transform: none !important; }
}

@media (max-width: 768px) {
  /* Keep the desktop header design on mobile — center wordmark stays visible. */
  .header-logo-img { height: 24px; }
  .header-logo { margin-left: -2px; }
  .header { padding: 1rem var(--pad); }

  /* Top-align the hero and give it clearance below the fixed header (the big
     headline was colliding with the logo), and shrink the display type so long
     words fit the column. */
  /* Fill the viewport; headline anchored to the bottom (clears the fixed
     header) so the goat relief owns the upper area. */
  .hero { min-height: 100dvh; justify-content: flex-end; padding: 7rem var(--pad) 3rem; }
  .hero-headline { margin-top: 0; }
  .hero-headline h1 { font-size: clamp(2.05rem, 9vw, 3.2rem); }
  .hero-meta {
    position: relative; bottom: auto; right: auto;
    text-align: left; margin-top: 2rem;
    font-size: 0.96rem;
  }
  /* Info section fills the viewport (content keeps its spacing at the top; the
     oceanus relief sits in the lower area). */
  .intro { min-height: 100dvh; }
  /* Drop forced full-viewport heights so phone content isn't cramped. */
  .studio-hero { min-height: auto; padding: 7rem var(--pad) 3rem; }
  /* Mirror the homepage hero: athena owns the negative space up top, and the
     headline + sub-paragraph sit together as one tight statement anchored to the
     bottom third of the viewport. */
  .studio-about {
    min-height: 100dvh;
    display: flex; flex-direction: column; justify-content: flex-end;
    padding: 7rem var(--pad) 3rem;
  }
  .studio-about-rule {                        /* mobile only: divider line under "Info" */
    display: block;
    border-top: 1px solid var(--line);
    margin: 0 0 1.75rem;
  }
  .studio-about-large {
    font-size: clamp(1.5rem, 6.2vw, 2rem);    /* lower the header font on mobile */
  }
  .studio-about-sub {
    margin-top: 1.25rem;                      /* tight to the header — part of the same conversation */
  }
  /* Quicker fade for the sequenced hero text (page-fade default is 2.8s, which
     dragged after the staggered start). Later + equal specificity wins. */
  .page-fade .studio-about-large .word,
  .page-fade .studio-about-sub .word { transition-duration: 1.4s; }
  .studio-statement { min-height: auto; padding: 5rem var(--pad); }
  /* "What is A Measured Force?" — left-align the whole section on mobile and
     tighten the gaps between the heading and the paragraphs. */
  .studio-statement-heading,
  .studio-statement-body,
  .studio-statement-body p { text-align: left; }
  .studio-statement-heading { margin-bottom: 1.5rem; }
  .studio-statement-body p { margin-bottom: 1rem; }
  /* Divider between the "A Measured Force?" statement and "Core Capabilities"
     (mobile only). Sits at the top of the services section, inset to content
     width by the section's var(--pad) padding. */
  .studio-services::before {
    content: '';
    display: block;
    border-top: 1px solid var(--line);
    margin: 0 0 4.5rem;
  }
  /* "Core Capabilities" — close the big gap between the sub-line and the lists
     so the lists sit up near the subheader (desktop keeps the 6rem). */
  .studio-services .studio-approach-sub { margin-bottom: 1.75rem; }
  /* Bottom CTA email: shrink so the full address stays on one line on phones.
     Scoped to .ai-big-cta (the CTA wrapper on both About and AI pages) for
     specificity over the later base .ai-cta-display rule. */
  .ai-big-cta .ai-cta-display { font-size: clamp(1.5rem, 7.4vw, 2rem); white-space: nowrap; word-break: normal; }
  /* Rein in the largest display headings so they don't dominate the phone. */
  .page-hero-title { font-size: clamp(2.4rem, 11vw, 4rem); }
  .case-title,
  .studio-heading,
  .studio-tagline-h2,
  .studio-section-heading,
  .studio-statement-heading,
  .process-title,
  .about-philosophy h2,
  .about-approach-title,
  .about-services-title { font-size: clamp(1.9rem, 7.5vw, 3rem); }

  .intro, .services, .process, .contact,
  .about-detail, .about-philosophy, .about-approach,
  .about-services-full, .contact-page {
    padding: 6rem var(--pad);
  }

  .page-hero { padding: 6rem var(--pad) 1.5rem; min-height: 42vh; }
  /* Contact page: tighten the "Contact" → "Let's Talk" gap, but keep a clear gap
     between the sub-line and the contact info (email/phone/location) below. */
  .page-hero .section-label { margin-bottom: 1rem; }
  .contact-page { padding-top: 3.5rem; }
  .services-grid { grid-template-columns: 1fr; }
  /* Mobile: pull the services headline in from the right edge while keeping 3 lines */
  .services-headline { font-size: 1.55rem; max-width: 16rem; }
  .process-steps { grid-template-columns: 1fr; }
  .stats-grid { grid-template-columns: 1fr 1fr; }
  .about-approach-grid { grid-template-columns: 1fr; }
  .studio-approach-grid { grid-template-columns: 1fr; }
  .studio-logos-grid { grid-template-columns: repeat(3, 1fr); }
  .studio-tagline { min-height: auto; padding: 4rem var(--pad); }
  .studio-tagline-pills { flex-wrap: wrap; }
  .form-row { grid-template-columns: 1fr; }
  .contact-info-row { flex-direction: column; gap: 2rem; }
  .footer-row { flex-direction: column; gap: 0.75rem; text-align: center; }
  .lightbox-close { padding: 0.5rem; font-size: 2.4rem; top: 1rem; right: 1rem; }

  /* Mobile: drop the sticky frame and lay the section out as a normal BLOCK so
     the header sits at the TOP (DOM order), then images stack below it with the
     project name + tags under each. (The desktop grid put the static header in a
     later grid cell = bottom; block flow fixes that.) */
  .works-cycle { display: block; padding-top: 5rem; }
  .works-cycle-frame { display: none; }
  .works-cycle-head {
    position: static; top: auto; left: auto; right: auto;
    margin-bottom: 3rem;
  }
  .works-cycle-rail {
    padding: 0 0 5rem;
    gap: 6rem;            /* generous space between cards */
  }
  /* Let the item grow past the image so the caption below isn't clipped; the
     image link keeps the 4:5 tile shape + rounded clip. Flex column with `order`
     lets both pseudo-element caption lines sit BELOW the image, left-aligned to
     the card: ::before = project name (bolder), ::after = context (lighter). */
  .works-cycle-item {
    width: min(80vw, 360px);
    aspect-ratio: auto;
    height: auto;
    overflow: visible;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    text-align: left;
  }
  .works-cycle-item a {
    order: 0;
    width: 100%;
    aspect-ratio: 4 / 5;
    overflow: hidden;
    border-radius: 2px;
    /* Scale is driven continuously per-frame in JS (initWorksCycle tick) from
       each card's distance to viewport center, so it grows/shrinks fluidly as
       you scroll. transform-origin centered; no CSS transition so the per-frame
       updates stay smooth (a transition would lag them). */
    transform-origin: center;
  }
  .works-cycle-item::before {
    order: 1;
    content: attr(data-name);
    margin-top: 1.5rem;
    font-family: var(--font-sans);
    font-size: 0.9rem;
    font-weight: 500;        /* project name — slightly bolder */
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink);
  }
  .works-cycle-item::after {
    order: 2;
    content: attr(data-tags);
    margin-top: 0.4rem;
    font-family: var(--font-sans);
    font-size: 0.75rem;
    font-weight: 300;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ash);
  }
  /* Real injected captions replace the data-attr pseudo versions on mobile. */
  .works-cycle-item.has-cap::before,
  .works-cycle-item.has-cap::after { content: none; }
  .works-cycle-item .card-cap-name,
  .works-cycle-item .card-cap-tags { display: block; }

  /* Case study — editorial layout collapses to single column */
  .case-hero { padding: 8rem var(--pad) 2rem; }
  .case-meta-row { grid-template-columns: 1fr; gap: 0.5rem; padding: 1rem 0; }
  .case-story-block { grid-template-columns: 1fr; gap: 1rem; padding: 3rem 0; }
  .case-story-label { position: static; margin-bottom: 1rem; }
  .case-impact-list li { grid-template-columns: 50px 1fr; gap: 1.5rem; padding: 1.5rem 0; }
  .case-bleed { margin: 3rem 0; }
  .case-grid-two { grid-template-columns: 1fr; }
  .case-films-grid { grid-template-columns: 1fr; }
  .case-results-list li,
  .case-awards-list li { grid-template-columns: 1fr; gap: 0.6rem; }
  .case-next { padding-top: 2rem; gap: 1rem; }
  .case-next-link { gap: 0.75rem; }
  .case-next-arrow { width: 40px; height: 40px; }
  .case-next-name { font-size: 0.95rem; }
}

@media (max-width: 600px) {
  .intro, .services, .process, .contact,
  .about-detail, .about-philosophy, .about-approach,
  .about-services-full, .contact-page,
  .studio-approach, .studio-services { padding: 4.5rem var(--pad); }
  /* .studio-about manages its own padding (two-screen hero); excluded above. */
  .contact-page { padding-top: 3.5rem; }  /* clear gap between sub-line and contact info */
  .logo-ticker-inner { gap: 2.75rem; }
  .logo-ticker-inner img { height: 32px; }
  .case-hero { padding-top: 7rem; }
  .contact-info-row { gap: 1.5rem; }
}

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

@media (max-width: 400px) {
  .header-logo-img { height: 17px; }
  .header-logo { margin-left: 0; }
  .menu-trigger { width: 22px; height: 22px; }
  .menu-trigger-dot { width: 18px; height: 7px; }
  .menu-overlay { padding: 7rem var(--pad) 3rem; }
}

/* ============ SYSTEM DIAGRAM (AI page centerpiece) ============
   Scoped under .system-diagram. Tokens mapped to AMF palette:
   --bg → --paper, --mute-strong → --ash, --serif/--sans → AMF fonts.
   Section bg left transparent so the warm shader bleeds through. */

.system-diagram {
  color: var(--ink);
  padding: clamp(120px, 16vh, 200px) clamp(20px, 4vw, 64px)
           clamp(80px, 12vh, 160px);
}

.system-diagram .diagram-wrap {
  max-width: 1480px;
  margin: 0 auto;
  position: relative;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.system-diagram .diagram-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 18px 0;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.system-diagram .state-label {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(15px, 1.4vw, 20px);
  color: var(--ink);
  flex: 1 1 auto;
  min-width: 0;
}
.system-diagram .state-label .change {
  display: inline-block;
  min-width: 7ch;
  transition: opacity .35s ease;
}

.system-diagram .toggle {
  display: inline-flex;
  background: transparent;
  border: 1px solid var(--ink);
  border-radius: 999px;
  padding: 4px;
}
.system-diagram .toggle button {
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 8px 18px;
  border-radius: 999px;
  color: var(--ink);
  white-space: nowrap;
  background: none;
  border: 0;
  cursor: none;
  transition: background .25s ease, color .25s ease;
}
.system-diagram .toggle button[aria-pressed="true"] {
  background: var(--ink);
  color: var(--paper);
}

.system-diagram .diagram {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 10;
  max-height: 720px;
}
.system-diagram .diagram svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* SVG element theming — classes referenced by JS-created nodes */
.system-diagram .diagram svg text { fill: var(--ink); }
.system-diagram .diagram svg .signal-fill { fill: var(--ink); }
.system-diagram .diagram svg .line-stroke { stroke: var(--ink); }
.system-diagram .diagram svg .sub-fill { fill: var(--ash); }

.system-diagram .legend {
  display: flex;
  justify-content: space-between;
  gap: 24px;
  padding: 18px 0;
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ash);
  border-top: 1px solid var(--line);
  flex-wrap: wrap;
}
.system-diagram .legend .item {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.system-diagram .legend .swatch {
  display: inline-block;
  width: 22px;
  height: 1px;
  background: var(--ink);
}
.system-diagram .legend .swatch.dashed {
  background: repeating-linear-gradient(
    to right,
    var(--ink) 0 3px,
    transparent 3px 6px
  );
}

@media (prefers-reduced-motion: reduce) {
  .system-diagram *,
  .system-diagram *::before,
  .system-diagram *::after {
    transition-duration: 0.001ms !important;
  }
}

@media (max-width: 900px) {
  .system-diagram .diagram { aspect-ratio: 4 / 5; }
}

/* ============ AI SERVICE PAGE — Long-scroll conversational ============ */

/* HERO — sibling to homepage hero: same scale, bottom-aligned, left */
.ai-hero {
  position: relative;
  min-height: 100vh;
  display: flex; flex-direction: column;
  justify-content: flex-end; align-items: flex-start;
  padding: 8rem var(--pad) var(--pad);
  text-align: left;
}
.ai-hero-inner {
  width: 100%;
  margin-top: auto;
  padding-bottom: 1rem;
}
.ai-hero-headline {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(3rem, 7vw, 6.5rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--ink);
  will-change: transform;
  margin: 0;
}
.ai-hero-headline em {
  color: var(--ink);
  font-style: italic;
}

/* APHORISM BEATS — each its own breathing viewport */
.ai-beat {
  min-height: 85vh;
  display: flex;
  align-items: center;
  padding: 6rem var(--pad);
  position: relative;
}
.ai-beat-inner {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
}
.ai-beat--left  .ai-beat-inner { margin-left: 0; padding-right: 30%; }
.ai-beat--right .ai-beat-inner { margin-right: 0; margin-left: auto; padding-left: 30%; text-align: right; margin-top: 6rem; }
.ai-beat--center .ai-beat-inner { text-align: center; max-width: 900px; }
.ai-beat-line {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(1.8rem, 4.2vw, 3.8rem);
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: var(--ink);
  max-width: 22ch;
}
.ai-beat--right .ai-beat-line { margin-left: auto; }
.ai-beat--center .ai-beat-line { margin: 0 auto; }
.ai-beat-line em {
  font-style: italic;
  font-family: var(--font-serif);
}
.ai-beat-label {
  display: block;
  font-family: var(--font-sans);
  font-size: 0.65rem; letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ash);
  margin-bottom: 1.5rem;
  will-change: transform;
}
/* Reverted: the "I" in "AI" renders as the normal sans letter (no special
   treatment). The .serif-i spans remain in the markup but are unstyled. */

/* Real caption spans injected on mobile (injectCardCaptions) to replace the
   data-attr ::before/::after captions — needed so the serif "I" can be applied.
   Hidden by default; each card system flips them to `display:block` inside its
   own mobile breakpoint (and switches off its pseudo captions via .has-cap). */
.card-cap-name, .card-cap-tags { display: none; }
.card-cap-name {
  order: 1; margin-top: 1.5rem;
  font-family: var(--font-sans); font-size: 0.9rem; font-weight: 500;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink);
}
.card-cap-tags {
  order: 2; margin-top: 0.4rem;
  font-family: var(--font-sans); font-size: 0.75rem; font-weight: 300;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--ash);
}

/* PRINCIPLES — each principle is its own ~100vh block with sticky left rail */
/* Principles — sticky stage; each principle crossfades through a single
   pinned viewport. Cards alternate left/right horizontal alignment so
   the reader's eye moves across as they read down. */
.ai-principles {
  position: relative;
  height: 360vh;
}
.ai-principles-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 0 var(--pad);
  overflow: hidden;
}
.ai-principles-eyebrow {
  position: absolute;
  top: 11rem;
  left: var(--pad);
  font-family: var(--font-sans);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ash);
  z-index: 3;
}
.ai-principle-card {
  position: absolute;
  top: 8vh;
  bottom: 14vh;
  width: min(620px, 50%);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1.5rem;
  opacity: 0;
  pointer-events: none;
  /* JS drives opacity + translateY per frame for a continuous parallax
     ride; no CSS transition so the inline updates apply 1:1 with scroll. */
}
.ai-principle-card.is-active {
  pointer-events: auto;
}
/* Alternate: 01 left, 02 right, 03 left. */
.ai-principle-card[data-index="0"] { left: var(--pad);  right: auto; text-align: left; }
.ai-principle-card[data-index="1"] { right: var(--pad); left: auto;  text-align: right; }
.ai-principle-card[data-index="2"] { left: var(--pad);  right: auto; text-align: left; }
.ai-principle-num {
  font-family: var(--font-sans);
  font-feature-settings: "tnum" 1;
  font-size: clamp(0.85rem, 1.2vw, 1.05rem);
  letter-spacing: 0.16em;
  color: var(--ash);
}
.ai-principle-title {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(2rem, 4.2vw, 3.4rem);
  line-height: 1.1;
  letter-spacing: -0.015em;
  color: var(--ink);
  max-width: 18ch;
  margin: 0;
}
.ai-principle-card[data-index="1"] .ai-principle-title { margin-left: auto; }
.ai-principle-body {
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: clamp(1.05rem, 1.4vw, 1.25rem);
  line-height: 1.7;
  color: var(--ink);
  max-width: 56ch;
  margin: 0;
}
.ai-principle-card[data-index="1"] .ai-principle-body { margin-left: auto; }
.ai-principle-body em {
  font-family: var(--font-serif);
  font-style: italic;
}
.ai-principles-progress {
  position: absolute;
  bottom: 6vh;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 1.5rem;
  z-index: 1;
}
.ai-principles-progress span {
  display: block;
  width: 24px;
  height: 1px;
  background: var(--line-med);
  transition: width 0.6s cubic-bezier(0.25, 1, 0.5, 1),
              background 0.4s ease;
}
.ai-principles-progress span.is-active {
  width: 56px;
  background: var(--ink);
}

@media (prefers-reduced-motion: reduce) {
  .ai-principles { height: auto; }
  .ai-principles-stage { position: static; height: auto; display: block; padding: 6rem var(--pad); overflow: visible; }
  .ai-principle-card {
    position: static; inset: auto; opacity: 1; transform: none;
    padding: 6rem 0; pointer-events: auto; max-width: 760px;
    margin: 0 auto;
  }
  .ai-principles-progress { display: none; }
}
/* Mobile: same static stack as the reduced-motion fallback. The JS guard in
   initAiPrinciplesStage stops the per-frame inline opacity/transform writes so
   these rules win. */
@media (max-width: 768px) {
  .ai-principles { height: auto; }
  .ai-principles-stage { position: static; height: auto; display: block; padding: 5rem var(--pad); overflow: visible; }
  .ai-principle-card {
    position: static; inset: auto; width: auto; max-width: 100%;
    opacity: 1; transform: none; padding: 3.5rem 0;
    pointer-events: auto; text-align: left; margin: 0;
  }
  .ai-principle-card[data-index="0"],
  .ai-principle-card[data-index="1"],
  .ai-principle-card[data-index="2"] { left: auto; right: auto; text-align: left; }
  .ai-principle-card[data-index="1"] .ai-principle-title,
  .ai-principle-card[data-index="1"] .ai-principle-body { margin-left: 0; }
  .ai-principles-eyebrow { position: static; top: auto; left: auto; margin-bottom: 2rem; }
  .ai-principles-progress { display: none; }
}

/* AI WORKS — full-width horizontal travel
   .ai-works-pin is a tall outer container. Inside, the .ai-works-stage
   sticks to the viewport while the rail of 5 cards translates from
   off-screen-right to off-screen-left. Each card has a distinct moment at
   viewport center; the name label (above) and index+tag (below) only
   appear when their card is centered, fading out between cards.

   To populate a card with a real image:
     <div class="ai-works-card" data-aspect="square" data-index="02" ...>
       <img src="../../assets/ai-projects/02-sales-dashboard.jpg" alt="">
     </div>
   Card keeps its [data-aspect] sizing; <img> fills via object-fit. */
.ai-works-pin {
  position: relative;
  height: 380vh;
  margin-top: 2rem;
}
.ai-works-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
}
.ai-works-eyebrow {
  position: absolute;
  top: 9rem;
  left: var(--pad);
  font-family: var(--font-sans);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ash);
  z-index: 3;
}

/* Track spans the full viewport. Rail translates inside via JS. */
.ai-works-track {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
}
.ai-works-rail {
  position: absolute;
  left: 0;
  top: 50%;
  display: flex;
  align-items: center;
  gap: min(32vw, 380px);
  transform: translate3d(100vw, -50%, 0);
  will-change: transform;
}
.ai-works-card {
  flex: 0 0 auto;
  position: relative;
  background: rgba(23, 21, 18, 0.04);
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  height: min(44vh, 420px);
  max-width: min(34vw, 460px);
}
.ai-works-card[data-aspect="portrait"]    { aspect-ratio: 4 / 5; }
.ai-works-card[data-aspect="square"]      { aspect-ratio: 1 / 1; }
.ai-works-card[data-aspect="tall"]        { aspect-ratio: 3 / 5; }
.ai-works-card[data-aspect="landscape"]   { aspect-ratio: 16 / 10; }
.ai-works-card[data-aspect="square-wide"] { aspect-ratio: 6 / 5; }
.ai-works-card[data-aspect="standard"]    { aspect-ratio: 4 / 3; max-width: min(46vw, 600px); }
.ai-works-card[data-aspect="wide"]        { aspect-ratio: 3 / 2; max-width: min(52vw, 640px); }
.ai-works-card[data-aspect="phone"]       { aspect-ratio: 3 / 4; }
.ai-works-card::after {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-size: 0.6rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--stone);
}
.ai-works-card[data-aspect="portrait"]::after    { content: "image · 4 : 5"; }
.ai-works-card[data-aspect="square"]::after      { content: "image · 1 : 1"; }
.ai-works-card[data-aspect="tall"]::after        { content: "image · 3 : 5"; }
.ai-works-card[data-aspect="landscape"]::after   { content: "image · 16 : 10"; }
.ai-works-card[data-aspect="square-wide"]::after { content: "image · 6 : 5"; }
.ai-works-card img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.ai-works-card:has(img)::after { display: none; }

/* Labels — centered horizontally, above and below the active card.
   Opacity is driven by JS based on the nearest card's distance from center. */
.ai-works-label-top,
.ai-works-label-bottom {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
  pointer-events: none;
  opacity: 0;
  z-index: 4;
  max-width: 80vw;
}
.ai-works-label-top {
  top: calc(50% - min(22vh, 230px) - 3rem);
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.2rem, 2vw, 1.7rem);
  line-height: 1.2;
  color: var(--ink);
}
.ai-works-label-bottom {
  top: calc(50% + min(22vh, 230px) + 1.25rem);
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-family: var(--font-sans);
  font-size: 0.85rem;
  color: var(--ash);
  letter-spacing: 0.04em;
}
.ai-works-label-index {
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.ai-works-label-tag {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 0.95rem;
  color: var(--ash);
  letter-spacing: 0;
}

@media (prefers-reduced-motion: reduce) {
  .ai-works-pin { height: auto; margin-top: 0; }
  .ai-works-stage {
    position: static;
    height: auto;
    overflow: visible;
    padding: 6rem var(--pad);
  }
  .ai-works-eyebrow { position: static; margin-bottom: 3rem; }
  .ai-works-track { position: static; display: block; }
  .ai-works-rail {
    position: static;
    flex-direction: column;
    align-items: flex-start;
    gap: 3rem;
    transform: none !important;
  }
  .ai-works-card {
    width: min(100%, 480px) !important;
    max-width: 100% !important;
    height: auto !important;
  }
  .ai-works-label-top,
  .ai-works-label-bottom { display: none; }
}

@media (max-width: 900px) {
  .ai-works-pin { height: auto; margin-top: 0; }
  .ai-works-stage {
    position: static;
    height: auto;
    overflow: visible;
    padding: 5rem var(--pad);
  }
  .ai-works-eyebrow { position: static; margin-bottom: 2.5rem; }
  .ai-works-track { position: static; display: block; }
  .ai-works-rail {
    position: static;
    flex-direction: column;
    align-items: center;
    gap: 5rem;
    transform: none !important;
  }
  /* Match the homepage work cards: a 4:5 rounded tile with the project name
     (bold) and tags (light) stacked beneath each, instead of the desktop
     pinned scroll-track + shared labels. */
  .ai-works-card {
    width: min(80vw, 360px) !important;
    max-width: 100% !important;
    height: auto !important;
    aspect-ratio: auto !important;
    background: none;
    border: none;
    border-radius: 0;
    overflow: visible;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    text-align: left;
  }
  .ai-works-card img {
    position: static;
    order: 0;
    width: 100%;
    height: auto;          /* show each image at its natural aspect — no crop */
    border-radius: 2px;
    /* Scroll-focus like the homepage work cards: greyscale by default, full colour
       when highlighted; scale is driven per-frame in JS (no transition on it). */
    filter: grayscale(1);
    transition: filter 0.5s ease;
    transform-origin: center;
  }
  .ai-works-card.is-active img { filter: grayscale(0); }
  .ai-works-card::before {
    order: 1;
    content: attr(data-name);
    margin-top: 1.5rem;
    font-family: var(--font-sans);
    font-size: 0.9rem;
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink);
  }
  /* [data-aspect] raises specificity above the per-aspect "image · 4:5"
     placeholder rules so the real tag shows (portrait card was showing the
     placeholder). */
  .ai-works-card[data-aspect]:has(img)::after {
    display: block;
    position: static;
    inset: auto;
    order: 2;
    content: attr(data-tag);
    margin-top: 0.4rem;
    font-family: var(--font-sans);
    font-size: 0.75rem;
    font-weight: 300;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ash);
  }
  /* Real injected captions replace the data-attr pseudo versions on mobile.
     The ::after selector needs [data-aspect]…:has(img) to outrank the rule above. */
  .ai-works-card.has-cap::before { content: none; }
  .ai-works-card[data-aspect].has-cap:has(img)::after { content: none; }
  .ai-works-card .card-cap-name,
  .ai-works-card .card-cap-tags { display: block; }
  .ai-works-label-top,
  .ai-works-label-bottom { display: none; }
}

/* BIG EMAIL CTA — kept; padded heavily for breathing room */
.ai-big-cta {
  padding: 14rem 0 10rem;
}
/* When reused at the bottom of the home/about contact section, the section
   already provides outer padding — drop the CTA's own vertical padding. */
.contact .ai-big-cta { padding: 5rem 0 3rem; }
/* The .contact section already supplies var(--pad); drop the CTA elements'
   own horizontal padding so they left-align with the content above. */
.contact .ai-cta-pretitle,
.contact .ai-cta-display,
.contact .ai-cta-sub { padding-left: 0; padding-right: 0; }
.ai-cta-pretitle {
  padding: 0 var(--pad);
  font-family: var(--font-sans);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash);
  margin-bottom: 4rem;
}
.ai-cta-display {
  display: block;
  padding: 0 var(--pad);
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(2.2rem, 8.2vw, 7.8rem);
  line-height: 0.95;
  letter-spacing: -0.035em;
  color: var(--stone);
  text-decoration: none;
  transition: color 0.5s ease;
  word-break: break-word;
}
.ai-cta-display:hover { color: var(--ink); opacity: 1; }
.ai-cta-sub {
  padding: 4rem var(--pad) 0;
  display: flex; gap: 1rem;
  align-items: center;
}

/* Reduced-motion guard: disable parallax, keep content flowing */
@media (prefers-reduced-motion: reduce) {
  .ai-hero-headline,
  .ai-beat-label,
  .ai-build-num {
    transform: none !important;
    will-change: auto;
  }
}

@media (max-width: 1024px) {
  .ai-hero { min-height: 100vh; }
  .ai-beat { min-height: 70vh; padding: 5rem var(--pad); }
  .ai-beat--left .ai-beat-inner,
  .ai-beat--right .ai-beat-inner { padding-left: 0; padding-right: 0; }
  .ai-build-beat { grid-template-columns: 1fr; gap: 2rem; min-height: auto; padding: 5rem var(--pad); }
  .ai-build-beat:nth-child(even) { direction: ltr; }
  .ai-big-cta { padding: 8rem 0 6rem; }
}
@media (max-width: 768px) {
  .ai-hero { padding: 7rem var(--pad) 4rem; min-height: auto; }
  /* Keep each aphorism its own "breathing moment" on phones (don't collapse the
     beats into one another) — restore a tall, centered block per beat. */
  /* Even rhythm: after the opening beat, each beat is a fixed slot so the gaps
     On approach → Failure mode → Our way → diagram stay equal (~the gap the
     centered opening beat creates to the failure-mode line). */
  .ai-beat { min-height: 70vh; padding: 4rem var(--pad); }
  /* Match the home hero headline size on mobile. */
  .ai-beat-line { font-size: clamp(2.05rem, 9vw, 3.2rem); }
  /* First beat ("On approach") fills the opening viewport; the copy sits a little
     below centre so its gap to the failure-mode line matches Failure → Our way. */
  .ai-beat--left { min-height: 100dvh; align-items: flex-start; padding-top: calc(50dvh + 64px); }
  /* Second beat ("failure mode"): top-anchored, right-aligned to the right side.
     Tighter slot so failure mode sits closer to "Our way" with the dog between.
     Extra top padding nudges it down so the whitespace above/below it is even
     (its block is shorter than the neighbours, which skewed the visual gaps). */
  .ai-beat--right { min-height: 50vh; align-items: flex-start; padding-top: 5.3rem; }
  .ai-beat--right .ai-beat-inner { text-align: right; margin-top: 0; }
  .ai-beat--right .ai-beat-line { margin-left: auto; margin-right: 0; }
  /* Third beat ("Our way"): top-anchored, left-aligned on the left side, same slot
     height as the failure mode so the gap down to the Built-In section matches. */
  .ai-beat--center { min-height: 50vh; align-items: flex-start; }
  .ai-beat--center .ai-beat-inner { text-align: left; max-width: none; }
  .ai-beat--center .ai-beat-line { margin: 0; }
  .ai-build-beat { padding: 4rem var(--pad); }
  .ai-big-cta { padding: 5rem 0 3rem; }
  .ai-cta-pretitle { margin-bottom: 2rem; }
  .ai-cta-sub { padding-top: 2rem; }
}

/* ============ WIRED-IN HEXAGONAL DIAGRAM ============ */
/* Self-contained editorial panel that replaces the old system-diagram. All
   class names are BEM-scoped so nothing collides with the rest of the site. */
.amf-wired-in {
  --ink: #1F1F1F;
  --ink-muted: #7A7565;
  --ink-brand: #6B6555;
  --hairline: rgba(31, 31, 31, 0.18);
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Inter", Arial, sans-serif;
  position: relative;
  /* Tight vertical rhythm — let the plaster wall show through and don't
     leave a dead band between this section and the principles below.
     Letting the SVG span nearly the full viewport so the hexagon reads
     as a presence rather than a small badge. */
  padding: clamp(80px, 10vh, 140px) clamp(12px, 2vw, 32px) clamp(20px, 3vh, 40px);
  max-width: 1900px;
  margin: 0 auto;
}
.amf-wired-in__header {
  text-align: center;
  padding: 8px 36px 4px;
}
.amf-wired-in__diagram {
  width: 100%;
  display: block;
  padding: 0;
}
.amf-wired-in__stamp {
  display: inline-flex;
  align-items: center;
  margin-bottom: 10px;
}
.amf-wired-in__stamp-tag {
  font-family: var(--font-sans);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ash);
  font-weight: 400;
}
.amf-wired-in__claim {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(2rem, 4.2vw, 3.4rem);
  color: var(--ink);
  line-height: 1.15;
}

/* Reduced motion: freeze all SMIL animations to their fully-drawn state. */
@media (prefers-reduced-motion: reduce) {
  .amf-wired-in__diagram [stroke-dashoffset] { stroke-dashoffset: 0 !important; }
  .amf-wired-in__diagram animate { display: none; }
}

/* Narrow viewports: shrink padding so the diagram + labels breathe. */
@media (max-width: 768px) {
  .amf-wired-in__header { padding: 6px 20px 4px; }
  /* Claim as large as the other section headers (home/beat headline size). */
  .amf-wired-in__claim { font-size: clamp(2.05rem, 9vw, 3.2rem); line-height: 1.1; }
  /* Enlarge the SVG text (in viewBox units) so it's readable on a phone. Targeted
     by their presentation font-size so labels and the AI centre scale separately;
     mobile-only via the media query (desktop SVG attributes untouched). */
  .amf-wired-in__diagram text[font-size="8.5"] { font-size: 19px; }
  .amf-wired-in__diagram text[font-size="78"] { font-size: 88px; }
  /* The hexagon sits in the middle ~third of a wide 1300x720 viewBox, so at full
     container width it reads small. Trim the dead vertical band and let the SVG
     run wider than the column (empty side-margins of the viewBox spill off-screen)
     so the hexagon itself reads as a presence. */
  /* Top padding offsets the diagram header to where a beat line sits (beats have
     a label above their line, the diagram doesn't) so the Our way → diagram gap
     matches the beat-to-beat rhythm. */
  .amf-wired-in { padding: 5.3rem 0 clamp(16px, 3vh, 28px); overflow: hidden; }
  .amf-wired-in__diagram { width: 160%; margin-left: -30%; }
}
