/* ============================================================
   GNEMO Studio — Global Styles
   Pin + Scroll-driven Cards layout
   ============================================================ */

:root {
  --bg: #0b0b0b;
  --bg-2: #111111;
  --ink: #f5f4ef;
  --ink-dim: rgba(245, 244, 239, 0.62);
  --paper: #f5f4ef;
  --paper-2: #ece9df;
  --paper-ink: #0e0e0e;
  --accent: #CBFC05;
  --line: rgba(245, 244, 239, 0.16);
  --line-dark: rgba(14, 14, 14, 0.12);

  --serif: "Playfair Display", "DM Serif Display", "Times New Roman", serif;
  --sans: "Space Grotesk", "Inter", system-ui, -apple-system, "Helvetica Neue",
    Arial, sans-serif;

  --max: 1320px;
  --gut: clamp(20px, 4vw, 56px);
  --radius: 18px;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --hero-title-size: clamp(52px, 10.5vw, 168px);

  /* number of cards + 1 (the leading hero buffer) */
  --stage-vh: 500;
}

* { box-sizing: border-box; }
html {
  scroll-behavior: smooth; 
  overflow-anchor: none;
  -ms-overflow-style: none;  /* IE and Edge */
  scrollbar-width: none;  /* Firefox */
}
html.is-restoring { scroll-behavior: auto; }
html::-webkit-scrollbar { 
  display: none; 
}
body {
  margin: 0;
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
  color: var(--paper-ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  -ms-overflow-style: none; /* IE and Edge */
  scrollbar-width: none; /* Firefox */
}
body::-webkit-scrollbar {
  display: none; /* Chrome, Safari and Opera */
}

a { color: inherit; text-decoration: none; }

/* ----------------------------------------------------------------
   Asset protection — discourage casual right-click / drag / save
   on every image and the hero video.
   This is a deterrent only (DevTools can always pull source) but
   stops 99% of accidental "save image as" actions.
---------------------------------------------------------------- */
img, video {
  display: block;
  max-width: 100%;
  -webkit-user-drag: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;     /* iOS long-press save sheet */
  pointer-events: none;            /* dead to mouse — wrappers handle clicks */
}

/* Block text selection across the whole page (the entire site is
   visual / decorative copy — nothing here should be selected). */
body {
  -webkit-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

html.is-loading,
html.is-loading body {
  overflow: hidden;
}

button { font: inherit; cursor: pointer; border: 0; background: transparent; color: inherit; }

/* ============================================================
   Entry loader
   ============================================================ */
.page-loader {
  position: fixed;
  inset: 0;
  z-index: 10000;
  /* Stack the wordmark and the progress group as a single
     vertically-centered unit so the brand mark and progress feedback
     read as one composition instead of two disconnected pieces. */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(28px, 4.4vh, 46px);
  padding: 0 24px;
  overflow: hidden;
  background:
    radial-gradient(circle at 50% 45%, rgba(245, 244, 239, 0.055), rgba(245, 244, 239, 0) 28%),
    #090909;
  color: var(--ink);
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transition:
    opacity 0.72s var(--ease),
    visibility 0s linear 0.72s;
}
html.is-loading .page-loader {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
  transition: opacity 0.42s var(--ease);
}
html.is-loading.is-loader-ready .page-loader {
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transition:
    opacity 0.72s var(--ease),
    visibility 0s linear 0.72s;
}
/* The new SVG is a horizontal wordmark (icon + "GNEMO" lockup).
   The wordmark gets a single subtle `loaderBreath` animation —
   gentle opacity + 1.5px lift so the mark "breathes" instead of
   feeling frozen. The progress bar below carries the actual
   loading-in-flight signal. */
.page-loader__mark {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: clamp(200px, 24vw, 300px);
}
.page-loader__mark img {
  width: 100%;
  height: auto;
  opacity: 0.97;
  filter: drop-shadow(0 14px 30px rgba(0, 0, 0, 0.48));
  animation: loaderBreath 2.6s ease-in-out infinite;
}
@keyframes loaderBreath {
  0%, 100% { opacity: 0.9;  transform: translateY(0); }
  50%      { opacity: 1;    transform: translateY(-1.5px); }
}

.page-loader__copy {
  position: relative;
  z-index: 1;
  /* Match the wordmark's clamp so the progress bar terminates at the
     same horizontal extents as the brand mark above it. */
  width: clamp(200px, 24vw, 300px);
  display: grid;
  gap: 12px;
}
.page-loader__meta {
  width: 100%;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 18px;
}
.page-loader__meta p,
.page-loader__meta span {
  margin: 0;
  color: rgba(245, 244, 239, 0.62);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  font-feature-settings: "tnum" 1;
}
.page-loader__meta span {
  min-width: 48px;
  color: rgba(203, 252, 5, 0.88);
  text-align: right;
  letter-spacing: 0.08em;
}
.page-loader__bar {
  position: relative;
  width: 100%;
  height: 1.5px;
  overflow: hidden;
  background: rgba(245, 244, 239, 0.14);
}
.page-loader__bar span {
  display: block;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, rgba(203, 252, 5, 0.82), rgba(245, 244, 239, 0.78));
  transform: scaleX(var(--loader-progress, 0));
  transform-origin: 0 50%;
  transition: transform 0.28s var(--ease);
}
/* ============================================================
   CUSTOM CURSOR
   - System cursor hidden on devices that have a real pointer.
   - Two layers: a tiny accent-orange dot that tracks 1:1 with the
     mouse, and a larger outline ring that follows on a lerp.
   - On hover over interactive things, the ring scales up and the
     dot dims, giving links and cards a satisfying magnetic feel.
   - On touch devices we leave the system cursor alone.
   ============================================================ */
@media (hover: hover) and (pointer: fine) {
  /* Hide the system cursor everywhere — including on <video>, <img>,
     <iframe>, the body padding, etc., where some browsers re-show it
     even when html/body have cursor:none. The custom .cursor element
     uses pointer-events:none so it never intercepts hits. */
  html, body, * { cursor: none !important; }
}

/* ============================================================
   Custom cursor — "Liquid bead" with velocity squash & stretch,
   neon trail, and hover/press states.

   Layers (back → front):
     .cursor__trail  : soft accent-green glow that lags behind
     .cursor__bubble : 14px glass bead, stretches along motion vector
     .cursor__core   : 4px neon-green nucleus, snaps to pointer

   All layers are translated each frame by JS via inline transforms.
   CSS only handles size / color / opacity tweens (entrance, hover,
   press) so the tracking itself stays at 60 fps regardless of the
   transition timings.
   ============================================================ */
.cursor {
  position: fixed;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  pointer-events: none;
  z-index: 9999;
  opacity: 0;
  transition: opacity 0.25s var(--ease);
}
.cursor[data-ready="1"] { opacity: 1; }

@media (hover: none), (pointer: coarse) {
  .cursor { display: none !important; }
}

.cursor__trail,
.cursor__bubble,
.cursor__core {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  will-change: transform;
}

/* ---- Trail ---- a soft accent halo that lags behind the bead.
   Hidden at rest; faded in while moving (.is-moving). */
.cursor__trail {
  width: 64px;
  height: 64px;
  margin: -32px 0 0 -32px;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    rgba(203, 252, 5, 0.55) 0%,
    rgba(203, 252, 5, 0.22) 38%,
    rgba(203, 252, 5, 0)   72%
  );
  filter: blur(6px);
  opacity: 0;
  transition: opacity 0.28s var(--ease);
}
.cursor.is-moving .cursor__trail { opacity: 0.55; }
.cursor.is-hover  .cursor__trail { opacity: 0.85; }

/* ---- Liquid glass bead ---- main visible body. Background is a
   layered radial+linear gradient that fakes a real glass sphere
   without needing backdrop-filter (so it stays cheap to redraw at
   60 fps over the whole viewport). Stretches along the motion
   vector via JS-set transform. */
.cursor__bubble {
  width: 16px;
  height: 16px;
  margin: -8px 0 0 -8px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 32% 28%, rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.05) 55%),
    linear-gradient(160deg, rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0.04));
  border: 0.6px solid rgba(255, 255, 255, 0.55);
  box-shadow:
    inset 0 0 0 0.5px rgba(255, 255, 255, 0.18),
    inset 0 -1px 1px rgba(0, 0, 0, 0.25),
    0 1px 2px rgba(0, 0, 0, 0.4),
    0 0 0 rgba(203, 252, 5, 0);
  transition:
    width 0.42s var(--ease),
    height 0.42s var(--ease),
    margin 0.42s var(--ease),
    background 0.32s var(--ease),
    border-color 0.32s var(--ease),
    box-shadow 0.32s var(--ease);
}
.cursor__bubble-glare {
  position: absolute;
  top: 12%;
  left: 22%;
  width: 36%;
  height: 28%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.92), rgba(255, 255, 255, 0) 70%);
  pointer-events: none;
  opacity: 0.85;
  transition: opacity 0.32s var(--ease);
}

/* ---- Neon nucleus ---- snaps tighter to pointer, gives a sharp
   focal point even while the bead is mid-stretch. */
.cursor__core {
  width: 4px;
  height: 4px;
  margin: -2px 0 0 -2px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow:
    0 0 6px rgba(203, 252, 5, 0.9),
    0 0 14px rgba(203, 252, 5, 0.45);
  transition:
    width 0.3s var(--ease),
    height 0.3s var(--ease),
    margin 0.3s var(--ease),
    opacity 0.3s var(--ease);
}

/* ---- Hover state ---- bead grows to a 56 px lime puck and
   the glare fades; nucleus grows along with it. */
.cursor.is-hover .cursor__bubble {
  width: 56px;
  height: 56px;
  margin: -28px 0 0 -28px;
  background:
    radial-gradient(circle at 32% 28%, rgba(255, 255, 255, 0.55), rgba(203, 252, 5, 0.0) 55%),
    radial-gradient(circle at 50% 50%, rgba(203, 252, 5, 0.32), rgba(203, 252, 5, 0.10) 70%);
  border-color: rgba(203, 252, 5, 0.7);
  box-shadow:
    inset 0 0 0 0.5px rgba(255, 255, 255, 0.35),
    0 0 28px rgba(203, 252, 5, 0.45),
    0 8px 22px rgba(0, 0, 0, 0.38);
}
.cursor.is-hover .cursor__bubble-glare { opacity: 0.4; }
.cursor.is-hover .cursor__core {
  width: 5px;
  height: 5px;
  margin: -2.5px 0 0 -2.5px;
  opacity: 0;
}

/* ---- Press state ---- bead snaps small + solid neon, simulating
   a click pop. JS still sets transform so the squash is preserved. */
.cursor.is-press .cursor__bubble {
  width: 12px;
  height: 12px;
  margin: -6px 0 0 -6px;
  background: rgba(203, 252, 5, 0.55);
  border-color: rgba(203, 252, 5, 0.95);
  box-shadow:
    inset 0 0 0 0.5px rgba(255, 255, 255, 0.45),
    0 0 18px rgba(203, 252, 5, 0.6);
}
.cursor.is-press .cursor__bubble-glare { opacity: 0.2; }
.cursor.is-press .cursor__core {
  width: 6px;
  height: 6px;
  margin: -3px 0 0 -3px;
  opacity: 1;
}

.container {
  max-width: var(--max);
  margin: 0 auto;
  padding: 0 var(--gut);
}

.eyebrow {
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-dim);
  margin: 0 0 6px;
}

/* ============================================================
   NAV — compact smoked glass
   A darker rail keeps the menu readable on moving imagery without
   becoming the brightest object in the first viewport.
   ============================================================ */

.nav {
  --nav-spec-x: 0.52;
  --nav-spec-y: 0.28;
  position: fixed;
  top: 18px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 8px;
  isolation: isolate;
  overflow: hidden;
  padding: 5px;
  border-radius: 999px;
  background:
    radial-gradient(120% 140% at calc(var(--nav-spec-x) * 100%) -20%,
      rgba(203, 252, 5, 0.13),
      rgba(255, 255, 255, 0.04) 36%,
      transparent 68%),
    linear-gradient(180deg,
      rgba(17, 20, 18, 0.76) 0%,
      rgba(8, 10, 9, 0.66) 100%);
  border: 1px solid rgba(245, 244, 239, 0.15);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.16),
    inset 0 -1px 0 rgba(0, 0, 0, 0.38),
    0 16px 42px rgba(0, 0, 0, 0.34),
    0 2px 8px rgba(0, 0, 0, 0.18);
  transition: transform 0.5s var(--ease), opacity 0.4s var(--ease),
    box-shadow 0.45s var(--ease), border-color 0.35s ease, background 0.35s ease;
  backdrop-filter: blur(20px) saturate(105%) brightness(0.82);
  -webkit-backdrop-filter: blur(20px) saturate(105%) brightness(0.82);
}

.nav::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 0;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.14), transparent 46%),
    radial-gradient(
      95% 90% at calc(var(--nav-spec-x) * 100%) calc(var(--nav-spec-y) * 100%),
      rgba(203, 252, 5, 0.10) 0%,
      transparent 58%
    );
  opacity: 0.76;
}

.nav::after {
  content: "";
  position: absolute;
  pointer-events: none;
  z-index: 0;
  inset: auto 18px 0;
  height: 1px;
  border-radius: 0;
  background: linear-gradient(90deg, transparent, rgba(203, 252, 5, 0.32), transparent);
  opacity: 0.62;
}

@supports (backdrop-filter: url("#x")) or (-webkit-backdrop-filter: url("#x")) {
  .nav {
    background:
      radial-gradient(120% 140% at calc(var(--nav-spec-x) * 100%) -20%,
        rgba(203, 252, 5, 0.11),
        rgba(255, 255, 255, 0.04) 38%,
        transparent 70%),
      rgba(8, 10, 9, 0.62);
    -webkit-backdrop-filter:
      blur(20px) saturate(105%) brightness(0.82);
            backdrop-filter:
      blur(20px) saturate(105%) brightness(0.82);
  }
}

.nav:hover {
  transform: translateX(-50%) translateY(-1px);
  border-color: rgba(203, 252, 5, 0.28);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.18),
    inset 0 -1px 0 rgba(0, 0, 0, 0.38),
    0 18px 46px rgba(0, 0, 0, 0.38),
    0 0 26px rgba(203, 252, 5, 0.08);
}

@supports (backdrop-filter: url("#x")) or (-webkit-backdrop-filter: url("#x")) {
  .nav:hover {
    -webkit-backdrop-filter:
      blur(22px) saturate(112%) brightness(0.86);
            backdrop-filter:
      blur(22px) saturate(112%) brightness(0.86);
  }
}

@media (prefers-reduced-motion: reduce) {
  .nav,
  .nav:hover {
    transition: none;
  }
}

.nav__toggle {
  display: none;
}

.nav__toggle-icon { position: relative; width: 16px; height: 14px; }
.nav__toggle-icon span {
  position: absolute;
  left: 0; right: 0; top: 50%;
  height: 1.5px;
  background: #fff;
  border-radius: 2px;
  transform-origin: center;
  transition: transform 0.4s var(--ease);
}
.nav__toggle-icon span:nth-child(1) { transform: translateY(calc(-50% - 4px)); }
.nav__toggle-icon span:nth-child(2) { transform: translateY(calc(-50% + 4px)); }

body.menu-open .nav__toggle { background: var(--accent); }
body.menu-open .nav__toggle-icon span:nth-child(1) { transform: translateY(-50%) rotate(45deg); }
body.menu-open .nav__toggle-icon span:nth-child(2) { transform: translateY(-50%) rotate(-45deg); }

.nav__track {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  border-radius: inherit;
}

/* Selected tab */
.nav__pill {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  border-radius: 999px;
  pointer-events: none;
  z-index: 0;
  opacity: 0;
  background:
    linear-gradient(180deg, rgba(203, 252, 5, 0.22), rgba(203, 252, 5, 0.10)),
    rgba(4, 6, 5, 0.58);
  border: 1px solid rgba(203, 252, 5, 0.48);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.18),
    inset 0 -1px 0 rgba(0, 0, 0, 0.36),
    0 0 18px rgba(203, 252, 5, 0.16);
  backdrop-filter: blur(18px) saturate(115%);
  -webkit-backdrop-filter: blur(18px) saturate(115%);
  will-change: transform, width, height;
  transition:
    transform 0.36s cubic-bezier(0.25, 0.1, 0.25, 1),
    width 0.36s cubic-bezier(0.25, 0.1, 0.25, 1),
    height 0.36s cubic-bezier(0.25, 0.1, 0.25, 1),
    opacity 0.2s ease;
}
@media (prefers-reduced-motion: reduce) {
  .nav__pill { transition: none; }
}

.nav__list {
  list-style: none;
  margin: 0;
  padding: 0 4px;
  display: flex;
  gap: 2px;
  position: relative;
  z-index: 1;
}
.nav__link {
  display: inline-block;
  padding: 9px 17px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: rgba(245, 244, 239, 0.74);
  position: relative;
  z-index: 1;
  background: transparent;
  border: 1px solid transparent;
  -webkit-font-smoothing: antialiased;
  transition:
    color 0.3s cubic-bezier(0.22, 1, 0.32, 1),
    background 0.28s ease,
    border-color 0.28s ease,
    box-shadow 0.28s ease;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.42);
}
.nav__link:hover:not(.is-active) {
  background: rgba(245, 244, 239, 0.08);
  border-color: rgba(245, 244, 239, 0.14);
  color: rgba(245, 244, 239, 0.96);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.08) inset,
    0 8px 18px rgba(0, 0, 0, 0.16);
  backdrop-filter: blur(12px) saturate(110%);
  -webkit-backdrop-filter: blur(12px) saturate(110%);
}
.nav__link.is-active {
  color: var(--accent);
  text-shadow:
    0 0 16px rgba(203, 252, 5, 0.26),
    0 1px 8px rgba(0, 0, 0, 0.42);
}

@media (max-width: 720px) {
  .nav {
    top: 16px;
    left: auto;
    right: var(--gut);
    transform: none;
    max-width: calc(100vw - 32px);
    padding: 5px;
    gap: 0;
    background:
      radial-gradient(120% 140% at calc(var(--nav-spec-x) * 100%) -20%,
        rgba(203, 252, 5, 0.12),
        rgba(255, 255, 255, 0.04) 42%,
        transparent 72%),
      rgba(8, 10, 9, 0.68);
  }
  .nav:hover {
    transform: none;
  }
  .nav__toggle {
    position: relative;
    z-index: 2;
    width: 42px;
    height: 42px;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #fff;
  }
  .nav__track {
    display: none;
  }
}

/* ============================================================
   FULLSCREEN MENU
   ============================================================ */

.menu {
  position: fixed;
  inset: 0;
  z-index: 55;
  background: #0b0b0b;
  color: var(--ink);
  clip-path: circle(0% at calc(50% - 0px) 30px);
  transition: clip-path 0.7s var(--ease);
  pointer-events: none;
}
body.menu-open .menu {
  clip-path: circle(150% at 50% 30px);
  pointer-events: auto;
}

.menu__inner {
  height: 100%;
  display: grid;
  grid-template-rows: 1fr auto;
  padding: 110px var(--gut) 40px;
}

.menu__list { list-style: none; margin: 0; padding: 0; align-self: center; }
.menu__list li { border-top: 1px solid var(--line); overflow: hidden; }
.menu__list li:last-child { border-bottom: 1px solid var(--line); }
.menu__list a {
  display: flex;
  align-items: baseline;
  gap: 24px;
  padding: 20px 0;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 700;
  font-size: clamp(40px, 8vw, 110px);
  line-height: 1;
  letter-spacing: -0.01em;
  transition: transform 0.4s var(--ease), color 0.3s ease, padding 0.4s var(--ease);
}
.menu__list a span {
  font-family: var(--sans);
  font-style: normal;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.2em;
  color: var(--ink-dim);
}
.menu__list a:hover { color: var(--accent); padding-left: 24px; }

.menu__meta {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 30px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  font-size: 13px;
  color: var(--ink-dim);
}
.menu__meta a:hover { color: var(--ink); }
@media (max-width: 700px) {
  .menu {
    clip-path: circle(0% at calc(100% - 38px) 38px);
  }
  body.menu-open .menu {
    clip-path: circle(150% at calc(100% - 38px) 38px);
  }
  .menu__inner {
    padding: 96px var(--gut) 28px;
  }
  .menu__list a {
    padding: 18px 0;
    font-size: clamp(42px, 15vw, 76px);
  }
  .menu__meta { grid-template-columns: 1fr; gap: 16px; }
}

/* ============================================================
   STAGE — pin + scroll-driven layer
   ============================================================ */

.stage {
  position: relative;
  /* (cards.length + 1) * 100vh = 5 viewports of scroll */
  height: calc(var(--stage-vh) * 1vh);
  height: calc(var(--stage-vh) * 1dvh);
  background: #000;
}

/* ARRIVAL CLOAK — applied by the inline <head> script in index.html
   when the page is opened with a hash (deep link from work.html).
   Hides only the cards + hero foreground (NOT the video itself), so
   the looping hero video stays visible while script.js measures the
   layout, fixes scrollY, scrubs the video to the right frame, and
   applies the correct --p / --ce on each card.

   Two-class state machine:
     html.is-restoring                 → cards + hero content cloaked
     html.is-restoring.is-ready        → fade transition kicks in
   After ~450ms script.js drops both classes and the runtime CSS
   (opacity: calc(1 - var(--ce))) takes back over without contention. */
html.is-restoring .card,
html.is-restoring .hero__content {
  opacity: 0 !important;
  transition: none !important;
}
html.is-restoring.is-ready .card {
  /* Restore card opacity on reveal (matches .card's natural CSS rule
     which now subtracts both --p (depth entry) and --ce (forward exit)
     from full opacity), then fade. */
  opacity: calc(1 - var(--p) - var(--ce)) !important;
  transition: opacity 0.35s var(--ease) !important;
}
html.is-restoring.is-ready .hero__content {
  /* hero__content opacity is set by the .hero scroll system; on
     reveal we just lift the cloak — the parent's --hp logic owns it. */
  opacity: 1 !important;
  transition: opacity 0.35s var(--ease) !important;
}

.stage__pin {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  /* Cover tall browser chrome / vh quirks so the pin never leaves a gap */
  min-height: 100svh;
  overflow: hidden;
  background: #000;
}

/* ============================================================
   HERO (pinned background, video scrubs with scroll)
   ============================================================ */

.hero {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  color: #fff;
  overflow: hidden;
  z-index: 1;

  /* 3D space for the parallax exit */
  perspective: 1400px;
  perspective-origin: 50% 42%;

  /* --hp drives the foreground's "fly-through" exit (0 = idle, 1 = fully gone).
     JS sets it as the user scrolls through the first ~1 second of video. */
  --hp: 0;
}

/* ----- 3D parallax exit of the hero foreground -----
   Each layer has its own --ly (Y drift) and --lz (Z push) factor.
   They all share the same --hp on .hero, so they zoom forward and fade
   together but at different velocities — that's the depth feel. */
.hero__eyebrow,
.hero__title .line,
.hero__sub,
.hero__cta-drift {
  transform-origin: 50% 50%;
  transform: translate3d(0, calc(var(--ly, 0px) * var(--hp)), calc(var(--lz, 0px) * var(--hp)));
  opacity: calc(1 - var(--hp));
  will-change: transform, opacity;
  /* No CSS transition — JS plays a fixed-duration tween per section event. */
}

/* Per-element depth tuning — front layers get the biggest --lz so they
   appear to rush past the camera; back layers move less. */
.hero__eyebrow             { --ly: -18px;  --lz: 380px; }
.hero__title .line:nth-child(1) { --ly:   2px;  --lz: 1000px; }
.hero__title .line:nth-child(2) { --ly:  24px;  --lz:  820px; }
.hero__sub                 { --ly:  46px;  --lz:  520px; }
.hero__cta-drift           { --ly:  68px;  --lz:  360px; }

/* When the foreground has fully exited, take it out of the hit-test stack
   so the (now-invisible) buttons can't be focused or clicked. */
.hero.is-exited .hero__eyebrow,
.hero.is-exited .hero__title,
.hero.is-exited .hero__sub,
.hero.is-exited .hero__cta-drift {
  pointer-events: none;
  visibility: hidden;
}

/* Mouse-driven 3D parallax variables. Lifted onto the hero parent so
   both the <video> and the <img class="hero__bg"> layers share the
   same transform — they must occupy exactly the same pixel rect, or
   the static fallback PNG would show seams against the video. */
.hero {
  --vpx: 0px;
  --vpy: 0px;
  --vrx: 0deg;
  --vry: 0deg;
}

/* Under the <video> during source swaps — same framing as .hero__bg */
.hero__poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  z-index: 0;
  opacity: 0;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
  transform-origin: 50% 50%;
  transform:
    perspective(1600px)
    translate3d(var(--vpx), var(--vpy), 0)
    rotateX(var(--vrx))
    rotateY(var(--vry))
    scale(1.07);
  will-change: transform, opacity;
  transition: none;
}
.hero__poster.hero__poster--on {
  opacity: 1;
}

.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  z-index: 1;
  pointer-events: none;
  /* Slight overscale (1.07) so the parallax shift never reveals edges. */
  transform-origin: 50% 50%;
  transform:
    perspective(1600px)
    translate3d(var(--vpx), var(--vpy), 0)
    rotateX(var(--vrx))
    rotateY(var(--vry))
    scale(1.07);
  will-change: transform;
}

/* Hide the <video> while the decoder is empty so the poster shows through */
.hero__video.hero__video--loading {
  opacity: 0;
  transition: none;
}

/* Settled section backgrounds: static image or loop video above the transition
   video when visible, below .hero__veil. */
.hero__bg,
.hero__bg-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  z-index: 0;
  opacity: 0;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
  transform-origin: 50% 50%;
  transform:
    perspective(1600px)
    translate3d(var(--vpx), var(--vpy), 0)
    rotateX(var(--vrx))
    rotateY(var(--vry))
    scale(1.07);
  will-change: transform;
  transition: opacity 0.45s var(--ease, ease);
}

.hero__bg.is-visible,
.hero__bg-video.is-visible {
  opacity: 1;
  z-index: 2;
}
.hero__bg.is-bridge,
.hero__bg-video.is-bridge {
  transition: none;
}

/* ------------------------------------------------------------
   Safari/WebKit — composite fix for hero video.
   Local perspective() + rotateX/Y on a <video> inside a
   position:sticky parent triggers an async-compositor bug on
   macOS Tahoe Safari: during scroll the video drifts right and
   reveals the black <stage__pin> underneath, then snaps back
   when scrolling stops. Strip the 3D bits on Safari only — keep
   the mouse parallax shift and a slightly bigger overscan.
   Chrome/Firefox keep the full 3D parallax above untouched.
   `@supports (-webkit-touch-callout: none)` would only catch iOS
   Safari, so we gate on the JS-driven [data-browser="safari"]
   attribute set on <html>.
   ------------------------------------------------------------ */
[data-browser="safari"] .hero__video,
[data-browser="safari"] .hero__bg,
[data-browser="safari"] .hero__bg-video,
[data-browser="safari"] .hero__poster {
  /* Safari repaints <video> source swaps a few pixels off when the layer
     is also transformed. Use real overscan geometry instead of transform
     scaling so the video and bridge image stay on the same pixel grid. */
  inset: auto;
  left: -9%;
  top: -9%;
  width: 118%;
  height: 118%;
  max-width: none;
  transform: none;
  will-change: auto;
}

.hero__veil {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background:
    radial-gradient(120% 80% at 50% 0%, rgba(0, 0, 0, 0) 30%, rgba(0, 0, 0, 0.5) 100%),
    linear-gradient(180deg, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0) 25%, rgba(0,0,0,0) 60%, rgba(0,0,0,0.55) 100%);
}

/* Brand mark — fixed top-left, sibling of the floating nav.
   Lives outside the hero so it stays anchored regardless of scroll
   or the hero's 3D parallax exit. */
.brand {
  position: fixed;
  top: 22px;
  left: var(--gut);
  z-index: 60;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: #fff;
  text-decoration: none;
  /* Mild shadow so the white mark stays legible over bright video frames */
  filter: drop-shadow(0 6px 18px rgba(0, 0, 0, 0.35));
  transition: opacity 0.35s var(--ease);
}
body.menu-open .brand {
  opacity: 0;
  pointer-events: none;
}
.brand__mark {
  /* PNG logo is 184x228 (≈4:5) and is white on transparent — a height
     of 38px renders the same visual weight as the old circular "G" mark. */
  display: block;
  height: 38px;
  width: auto;
  object-fit: contain;
  /* Don't let a stray drag pull the image out of the link */
  -webkit-user-drag: none;
  user-select: none;
}

/* Wordmark variant — the new SVG (644×151, ratio ≈ 4.26:1) is a
   horizontal lockup containing both the icon and the "GNEMO"
   letterforms, so it replaces the icon mark + GNEMO text combo.
   We pick a slightly shorter height than the old icon-only mark so
   the wordmark sits in proportion with the floating nav pill.
   The parent .brand already provides a drop-shadow for legibility
   over bright video frames, so we don't repeat it here. */
.brand__mark--wordmark {
  height: 32px;
}


.hero__content {
  position: relative;
  z-index: 4;
  margin-top: auto;
  padding: 0 var(--gut) 40px;
  will-change: transform, opacity;
  /* Pass the 3D perspective from .hero down to .hero__title .line, etc. */
  transform-style: preserve-3d;
}

.hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.85);
  margin: 0 0 18px;
  padding: 7px 14px 7px 10px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.18);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.hero__eyebrow span {
  width: 8px; height: 8px; border-radius: 50%; background: #fff;
}

.hero__title {
  font-family: var(--serif);
  font-weight: 900;
  font-style: italic;
  line-height: 0.86;
  letter-spacing: -0.02em;
  margin: 0;
  font-size: var(--hero-title-size);
  text-shadow: 0 6px 40px rgba(0, 0, 0, 0.35);
  /* Pass the 3D perspective down to each .line so they can fly forward
     at different velocities (giving the depth feel). */
  transform-style: preserve-3d;
}
.hero__title .line {
  display: block;
  /* overflow:hidden was clipping the per-line 3D transform — let the
     line draw freely so its translate3d(z) can scale it up visually */
  overflow: visible;
}
.hero__title em { font-style: italic; font-weight: 900; }
.hero__title .ital {
  font-style: italic;
  font-weight: 400;
  font-family: var(--serif);
  letter-spacing: -0.01em;
  opacity: 0.95;
}

.hero__sub {
  max-width: 560px;
  margin: 22px 0 28px;
  font-size: clamp(15px, 1.3vw, 18px);
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.92);
}

.hero__cta {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 10px;
}

/* Parallax lives on .hero__cta-drift so buttons are not transformed:
   nested transforms disable backdrop-filter in WebKit / Chromium. */
.hero__cta-drift {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 10px;
}

/* Frosted primary CTA — blur samples the hero video, not an empty layer */
.hero__cta .btn--solid {
  background: rgba(255, 255, 255, 0.19);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.38);
  backdrop-filter: blur(28px) saturate(1.15);
  -webkit-backdrop-filter: blur(28px) saturate(1.15);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.28),
    0 10px 28px rgba(0, 0, 0, 0.25);
}
.hero__cta .btn--solid:hover {
  background: rgba(255, 255, 255, 0.3);
  color: #fff;
}

.hero__cta .btn--ghost {
  background: rgba(0, 0, 0, 0.22);
  border: 1px solid rgba(255, 255, 255, 0.42);
  backdrop-filter: blur(20px) saturate(1.1);
  -webkit-backdrop-filter: blur(20px) saturate(1.1);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12);
}
.hero__cta .btn--ghost:hover {
  background: rgba(255, 255, 255, 0.92);
  color: #111;
  border-color: rgba(255, 255, 255, 0.92);
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 22px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: transform 0.25s var(--ease), background 0.25s ease, color 0.25s ease, border-color 0.25s ease;
  white-space: nowrap;
}
.btn--solid { background: #fff; color: #111; }
.btn--solid:hover { transform: translateY(-2px); background: var(--accent); color: #fff; }
.btn--ghost { border: 1px solid rgba(255, 255, 255, 0.5); color: #fff; }
.btn--ghost:hover { background: #fff; color: #111; transform: translateY(-2px); }

@media (max-width: 720px) {
  .brand { top: 16px; }
  /* Slim the wordmark on phones so it doesn't crowd the nav toggle. */
  .brand__mark--wordmark { height: 26px; }
}

/* ============================================================
   CARDS — slide up from below as scroll progresses
   ============================================================ */

.cards {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
}

.card {
  position: absolute;
  left: 50%;
  top: 50%;

  /* Centered card, smaller than viewport so hero shows around all four edges */
  width: min(86vw, 960px);
  height: min(78vh, 660px);

  border-radius: clamp(20px, 2.2vw, 32px);
  overflow: hidden;
  pointer-events: none;

  display: flex;
  flex-direction: column;
  gap: clamp(16px, 2.4vw, 36px);
  padding: clamp(22px, 3.2vw, 48px);

  background: var(--paper);
  color: var(--paper-ink);
  box-shadow:
    0 40px 100px rgba(0, 0, 0, 0.5),
    0 16px 40px rgba(0, 0, 0, 0.28),
    0 1px 0 rgba(255, 255, 255, 0.18) inset;

  /*
     Both the IN and OUT animations are depth-based so they read as a
     first-person "you're walking through train cars" experience that
     matches the hero video.

     --p drives the depth ENTRY ("from far → near"):
       1  → far away in front of the camera (translateZ = −1000px),
            scaled down + faded out
       0  → centered in the viewport, full size, fully opaque
     --ce drives the 3D fly-through EXIT ("past the camera"):
       0  → at rest
       1  → pushed past the camera (translateZ = +700px) + faded out
     The two never overlap (JS only animates one at a time), so we can
     just sum their contributions to translateZ / scale / opacity.
  */
  --p: 1;
  --ce: 0;
  transform:
    translate3d(-50%, -50%, 0)
    perspective(1400px)
    translateZ(calc(var(--ce) * 700px - var(--p) * 1000px))
    scale(calc(1 - var(--ce) * 0.08 - var(--p) * 0.18));
  opacity: calc(1 - var(--p) - var(--ce));
  will-change: transform, opacity;
}

/* When a card has fully landed at rest (--p === 0 && --ce === 0) JS adds
   `.is-settled`. We then drop the 3D bits of the transform — perspective()
   and translateZ() — so Safari/WebKit stops disabling backdrop-filter on
   the glass cards. The card is at idle here so the animation isn't
   affected; the 3D entry/exit transform is restored the moment a new
   tween starts (JS removes the class). */
.card.is-settled {
  transform: translate3d(-50%, -50%, 0);
}

.card.is-settled.is-tweening {
  transform:
    translate3d(-50%, -50%, 0)
    perspective(1400px)
    translateZ(calc(var(--ce) * 700px - var(--p) * 1000px))
    scale(calc(1 - var(--ce) * 0.08 - var(--p) * 0.18));
}

.card.is-interactive {
  pointer-events: auto;
}

/* While the card is busy exiting (or fully gone) it must not catch
   clicks / hover from the cards underneath or the video below. */
.card.is-before-entry {
  opacity: 0;
  pointer-events: none;
}
.card.is-exit-active { pointer-events: none; }

.card[data-i="0"] { z-index: 1; }
.card[data-i="1"] { z-index: 2; }
.card[data-i="2"] { z-index: 3; }
.card[data-i="3"] { z-index: 4; }

.card__head { max-width: 22ch; }
.card__head--center { max-width: none; text-align: center; margin: 0 auto; }

.card__num {
  display: inline-flex;
  align-items: center;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 18px;
}
.card__num::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  margin-right: 10px;
}
.card__num--light { color: var(--accent); }

.card__title {
  font-family: var(--serif);
  font-weight: 900;
  font-style: italic;
  font-size: clamp(28px, 4vw, 58px);
  line-height: 0.96;
  letter-spacing: -0.02em;
  margin: 0;
}
.card__title em { font-style: italic; font-weight: 400; color: var(--accent); }
.card__title--light { color: var(--ink); }
.card__title--giant { font-size: clamp(44px, 7.2vw, 110px); line-height: 0.9; }

.card__body { flex: 1; min-height: 0; }

/* ---- About card — Liquid-glass panel ---- */

/* ============================================================
   GLASS CARD — shared liquid-glass treatment used by both
   About (#about) and Services (#services). Each card opts in
   via the .card--glass modifier in the HTML.
   ============================================================ */
.card--glass {
  /* iOS 26 LIQUID GLASS — clear panel with real refraction.
     The body is mostly transparent; what you see is mostly the
     hero video bent through an SVG displacement filter, then
     gently frosted, with a thin tint and bright specular edges. */
  background:
    /* (a) bright top-rim specular spill that bleeds into the body */
    radial-gradient(140% 60% at 50% -10%,
      rgba(255, 255, 255, 0.34),
      rgba(255, 255, 255, 0) 65%),
    /* (b) thin off-axis caustic */
    radial-gradient(70% 90% at 110% 20%,
      rgba(255, 255, 255, 0.10),
      rgba(255, 255, 255, 0) 60%),
    /* (c) faint vertical sheen so the glass face reads as curved */
    linear-gradient(180deg,
      rgba(255, 255, 255, 0.16) 0%,
      rgba(255, 255, 255, 0.04) 30%,
      rgba(255, 255, 255, 0.02) 60%,
      rgba(255, 255, 255, 0.10) 100%),
    /* (d) studio brand whisper — keeps the olive identity, but at
            ~25% so the glass still reads as clear, not painted. */
    linear-gradient(155deg,
      rgba(58, 72, 42, 0.22) 0%,
      rgba(28, 38, 22, 0.30) 55%,
      rgba(16, 22, 14, 0.36) 100%);

  /* Plain frosting — applies everywhere as the universal fallback.
     The displacement-based refraction is layered on via @supports
     below for browsers that handle url() in backdrop-filter. */
          backdrop-filter: blur(20px) saturate(190%) brightness(1.06) contrast(1.05);
  -webkit-backdrop-filter: blur(20px) saturate(190%) brightness(1.06) contrast(1.05);

  border: 1px solid rgba(255, 255, 255, 0.20);
  border-top-color: rgba(255, 255, 255, 0.45);
  color: rgba(255, 255, 255, 0.96);

  /* Curved-glass edge: bright top rim, soft dark bottom inner shadow,
     plus an external drop so the slab feels like it's floating. */
  box-shadow:
    /* outer specular halo (very thin) */
    0 0 0 1px rgba(255, 255, 255, 0.06),
    /* top edge highlight */
    inset 0 1.5px 0 rgba(255, 255, 255, 0.55),
    /* bottom edge deep-cut */
    inset 0 -1px 0 rgba(0, 0, 0, 0.30),
    /* side highlights */
    inset 1px 0 0 rgba(255, 255, 255, 0.10),
    inset -1px 0 0 rgba(255, 255, 255, 0.10),
    /* interior glow at the top (light pouring in) */
    inset 0 24px 50px -10px rgba(255, 255, 255, 0.10),
    /* interior darkness at the bottom (lens curl) */
    inset 0 -50px 80px -20px rgba(0, 0, 0, 0.22),
    /* outer drop: floaty + grounded */
    0 50px 120px -20px rgba(0, 0, 0, 0.55),
    0 14px 34px rgba(0, 0, 0, 0.32);

  /* Slightly softer corners read more like "thick clear glass" */
  border-radius: clamp(28px, 3vw, 40px);

  /* Layout: flex column — content top-to-bottom inside the glass */
  display: flex !important;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  text-align: center;
  padding: clamp(22px, 2.6vw, 38px) clamp(22px, 2.6vw, 40px);
  gap: clamp(14px, 1.8vw, 22px);

  isolation: isolate;

  /* ---- 3D hover tilt + 3D depth entry/exit ----
     --rx / --ry / --tilt-z   → lerped by JS on hover (defaults flat).
     --p                      → depth entry (1 = far, 0 = at rest).
     --ce                     → 3D fly-through exit (0 = at rest, 1 =
                                pushed past the camera).
     We redeclare the .card transform here so the hover tilt stacks on
     top of the same depth animation. */
  --rx: 0deg;
  --ry: 0deg;
  --tilt-z: 0px;
  transform:
    translate3d(-50%, -50%, 0)
    perspective(1100px)
    rotateX(var(--rx))
    rotateY(var(--ry))
    translateZ(calc(var(--tilt-z) + var(--ce) * 700px - var(--p) * 1000px))
    scale(calc(1 - var(--ce) * 0.08 - var(--p) * 0.18));
  opacity: calc(1 - var(--p) - var(--ce));
}

.card--glass.is-settled.is-tweening {
  transform:
    translate3d(-50%, -50%, 0)
    perspective(1100px)
    rotateX(var(--rx))
    rotateY(var(--ry))
    translateZ(calc(var(--tilt-z) + var(--ce) * 700px - var(--p) * 1000px))
    scale(calc(1 - var(--ce) * 0.08 - var(--p) * 0.18));
}



/* About + Services share the same glass frame size so the two
   cards feel like a matched pair as you scroll between them. */
.card--about,
.card--services {
  width: min(82vw, 920px);
  height: min(74vh, 620px);
}

/* CAUSTIC SPOTLIGHT — large diffuse highlight that follows the cursor.
   This is the iOS 26 "light source dragging across the slab" feel.
   JS keeps --mx / --my as percentage coords of the card. */
.card--glass::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(
      360px 280px at var(--mx, 50%) var(--my, 50%),
      rgba(255, 255, 255, 0.34),
      rgba(255, 255, 255, 0.10) 38%,
      transparent 72%
    ),
    radial-gradient(
      120px 90px at var(--mx, 50%) var(--my, 50%),
      rgba(255, 255, 255, 0.55),
      rgba(255, 255, 255, 0.18) 45%,
      transparent 80%
    );
  opacity: 0;
  transition: opacity 0.45s var(--ease);
  filter: blur(2px);
}
.card--glass:hover::after { opacity: 1; }

/* INNER GLASS SHEEN — top-rim wash, off-axis caustics and a soft
   bottom darkening that together sell the curvature of the slab.
   Stays static (resting state); the cursor highlight (::after) is
   what reacts to interaction. */
.card--glass::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 0;
  background:
    /* upper specular wash */
    radial-gradient(120% 55% at 50% -8%,
      rgba(255, 255, 255, 0.22), transparent 60%),
    /* slim off-axis caustic streak */
    radial-gradient(45% 90% at 8% 24%,
      rgba(255, 255, 255, 0.10), transparent 60%),
    /* secondary highlight near the right shoulder */
    radial-gradient(35% 60% at 92% 18%,
      rgba(255, 255, 255, 0.07), transparent 60%),
    /* bottom interior darkening */
    radial-gradient(120% 50% at 50% 110%,
      rgba(0, 0, 0, 0.22), transparent 65%);
}

/* iOS-26 LIQUID GLASS REFRACTION — progressive enhancement.
   In browsers where backdrop-filter accepts url() (Chrome / Edge), we
   replace the plain CSS frost with an SVG turbulence-displacement pass
   + a lighter blur stack. The result is a real refraction of the hero
   video through the glass slab.

   macOS Safari (data-browser="safari") is excluded: it returns true to
   the `@supports` test for url() in backdrop-filter but in practice it
   silently fails to render the SVG filter — the entire backdrop-filter
   then evaluates to "no effect" and the glass goes transparent. By
   excluding Safari here, the base `backdrop-filter: blur(20px) ...`
   declaration on `.card--glass` survives and gives Safari a real frost. */
@supports (backdrop-filter: url("#x")) or (-webkit-backdrop-filter: url("#x")) {
  html:not([data-browser="safari"]) .card--glass {
            backdrop-filter:
              url(#liquid-glass)
              blur(10px)
              saturate(190%)
              brightness(1.06)
              contrast(1.05);
    -webkit-backdrop-filter:
              url(#liquid-glass)
              blur(10px)
              saturate(190%)
              brightness(1.06)
              contrast(1.05);
  }
  /* On hover, swap to a stronger displacement scale + a touch more
     vibrancy, so the slab visibly "flexes" under the pointer. */
  html:not([data-browser="safari"]) .card--glass:hover {
            backdrop-filter:
              url(#liquid-glass-hover)
              blur(8px)
              saturate(210%)
              brightness(1.10)
              contrast(1.06);
    -webkit-backdrop-filter:
              url(#liquid-glass-hover)
              blur(8px)
              saturate(210%)
              brightness(1.10)
              contrast(1.06);
  }
}
.card--glass > * {
  position: relative;
  z-index: 1;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  -webkit-font-smoothing: antialiased;
}

/* Chip — small glass pill at the top */
.card__chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.92);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.18),
    0 6px 18px rgba(0, 0, 0, 0.18);
}
.card__chip-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 2px rgba(255, 90, 31, 0.28);
  animation: blink 1.6s ease-in-out infinite;
}

/* Glass-card top kicker — minimal "0X — Section" label, no pill.
   Used by both About and Services.
   The .card--glass > * rule forces children to flex-direction: column,
   so we explicitly opt back into row direction here. */
.card__kicker {
  margin: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 12px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.78);
}
.card__kicker-num {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 0;
  color: var(--accent);
}
.card__kicker-line {
  width: 36px;
  height: 1px;
  background: rgba(255, 255, 255, 0.4);
}
.card__kicker-label {
  /* tracking inherited from .card__kicker */
}

/* (legacy) Top group inside About — kept for backwards compat */
.about__top {
  gap: 10px;
}
.about__eyebrow {
  margin: 0;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
  text-align: center;
  max-width: 90%;
}

/* Middle column: statement + lead + tags + stats */
.about__main {
  gap: clamp(12px, 1.4vw, 20px);
  flex: 1 1 auto;
  justify-content: center;
  min-height: 0;
}

/* Centered statement — same face + black italic as .hero__title; size/leading match .card__statement--compact */
.card__statement {
  font-family: var(--serif);
  font-weight: 900;
  font-style: italic;
  font-size: clamp(28px, 4vw, 58px);
  line-height: 0.96;
  letter-spacing: -0.02em;
  margin: 0;
  max-width: 22ch;
  color: #fff;
  text-shadow: 0 1px 14px rgba(0, 0, 0, 0.35);
  align-self: center;
}
.card__statement em {
  font-style: italic;
  font-weight: 900;
}

/* Secondary lead paragraph under the statement */
.about__lead {
  margin: 0;
  max-width: 56ch;
  font-family: var(--serif);
  font-weight: 400;
  font-style: normal;
  letter-spacing: -0.018em;
  font-size: clamp(12.5px, 0.95vw, 14.5px);
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.86);
}

/* "What we believe" mini-chip row — flat, no nested backdrop-filter */
.about__tags {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
}
.about__tags li {
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.88);
  padding: 5px 11px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 999px;
}

/* Stats row */
.about__stats {
  list-style: none;
  margin: 0;
  padding: clamp(10px, 1.4vw, 16px) 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: clamp(18px, 4vw, 54px);
  align-items: flex-start;
  justify-content: center;
  border-top: 1px solid rgba(255, 255, 255, 0.16);
  width: 100%;
  max-width: 640px;
}
.about__stats li {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.about__stats strong {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 700;
  font-size: clamp(24px, 2.8vw, 38px);
  line-height: 1;
  color: #fff;
  letter-spacing: -0.02em;
}
.about__stats sup {
  font-size: 0.45em;
  vertical-align: super;
  margin-left: 2px;
  color: var(--accent);
  font-style: normal;
}
.about__stats span {
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
  white-space: nowrap;
}

/* Logo marquee strip — outer container holds label + marquee viewport */
.logos {
  gap: 10px;
}
.logos__label {
  margin: 0;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.45);
  text-align: center;
}
.logos__viewport {
  width: 100%;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.logos__track {
  display: inline-flex;
  align-items: center;
  gap: clamp(34px, 5vw, 70px);
  white-space: nowrap;
  animation: marquee 36s linear infinite;
  will-change: transform;
}
.logo {
  color: rgba(255, 255, 255, 0.7);
  font-family: var(--sans), "PingFang SC", "Microsoft YaHei",
    "Noto Sans CJK SC", "Hiragino Sans GB", sans-serif;
  font-weight: 500;
  font-size: clamp(15px, 1.4vw, 22px);
  letter-spacing: 0.04em;
  line-height: 1;
}
.logo--serif {
  font-family: var(--serif), "Songti SC", "STSong", "Noto Serif CJK SC",
    "SimSun", serif;
  font-weight: 700;
  font-style: normal;
  letter-spacing: 0.06em;
}
.logo--bold {
  font-family: var(--sans), "PingFang SC", "Microsoft YaHei",
    "Noto Sans CJK SC", sans-serif;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.logo--mono {
  font-family: ui-monospace, "SF Mono", "Menlo", "PingFang SC",
    "Microsoft YaHei", monospace;
  font-weight: 600;
  letter-spacing: 0.2em;
}
.logo--script {
  font-family: var(--serif), "STKaiti", "Kaiti SC", "Songti SC", serif;
  font-style: italic;
  font-weight: 700;
  letter-spacing: 0.01em;
}

@media (max-width: 720px) {
  .card--about {
    padding: 24px 18px;
    gap: 14px;
  }
  .about__main { gap: 14px; }
  .about__eyebrow { font-size: 9.5px; letter-spacing: 0.18em; }
  .card__statement {
    max-width: 18ch;
    font-size: clamp(26px, 7.5vw, 40px);
  }
  .about__lead {
    font-size: 12.5px;
    line-height: 1.5;
    max-width: 38ch;
  }
  .about__tags { gap: 6px; }
  .about__tags li { font-size: 10px; padding: 5px 10px; letter-spacing: 0.1em; }
  .about__stats {
    gap: 14px 24px;
    padding-top: 14px;
  }
  .about__stats strong { font-size: 26px; }
  .about__stats span { font-size: 9px; letter-spacing: 0.18em; }
  .logos__label { font-size: 9px; letter-spacing: 0.22em; }
}

/* ============================================================
   SERVICES CARD CONTENT — sits inside .card--glass, mirrors
   About's tone (dark-glass + serif italic accents) but lays
   out 4 service tiles in a 2×2 grid.
   ============================================================ */

/* Main column: tagline on top, 2×2 grid filling the rest */
.services__main {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(14px, 2vw, 22px);
  min-height: 0;
}

/* Big serif statement above the 4 service tiles — same heavy italic
   typography as the Works card title (.card__title), so the two
   sections feel like a matched typographic family. */
.card__statement--compact {
  font-weight: 900;
  font-style: italic;
  font-size: clamp(28px, 4vw, 58px);
  line-height: 0.96;
  letter-spacing: -0.02em;
  max-width: 22ch;
}

/* 2×2 service grid */
.services__grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(10px, 1.4vw, 16px);
  width: 100%;
  max-width: 780px;
}

/* Individual service tile — frosted glass within glass */
.services__grid .srv {
  background: rgba(255, 255, 255, 0.045);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 14px;
  padding: clamp(12px, 1.6vw, 20px) clamp(14px, 1.8vw, 22px);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  gap: 6px;
  transition:
    background 0.3s var(--ease),
    border-color 0.3s var(--ease),
    transform 0.4s var(--ease);
}
.services__grid .srv:hover {
  background: rgba(255, 255, 255, 0.085);
  border-color: rgba(255, 255, 255, 0.24);
  transform: translateY(-2px);
}

.srv__num {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: 13px;
  color: var(--accent);
  letter-spacing: 0;
  margin: 0;
}
.srv__title {
  margin: 0;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 700;
  font-size: clamp(18px, 1.7vw, 24px);
  line-height: 1.05;
  letter-spacing: -0.01em;
  color: #fff;
}
.srv__copy {
  margin: 0;
  font-size: clamp(11.5px, 0.9vw, 13.5px);
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.78);
}

@media (max-width: 720px) {
  .card--services {
    width: min(88vw, 540px);
    height: auto;
    min-height: min(78vh, 620px);
    padding: 24px 18px;
    gap: 14px;
  }
  .services__main { gap: 14px; }
  .card__statement--compact { font-size: clamp(26px, 7.5vw, 40px); }
  .services__grid {
    grid-template-columns: 1fr;
    gap: 10px;
    max-width: 100%;
  }
  .services__grid .srv { padding: 14px 16px; gap: 4px; }
  .srv__title { font-size: 18px; }
  .srv__copy { font-size: 12.5px; line-height: 1.5; }
}

/* ============================================================
   WORKS CARD — frame-less. The "card" no longer has a paper panel:
   the centered title sits directly over the hero video and the four
   project tiles run as a single horizontal row underneath.
   ============================================================ */

.card--works {
  /* Full-bleed so horizontally scrolling tiles exit at the viewport edge. */
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  max-height: none;

  /* Strip the panel: no paper, no shadow, no rounded frame */
  background: transparent;
  box-shadow: none;
  border-radius: 0;
  overflow: visible;       /* let tile shadows + hover lift render */
  color: var(--ink);

  /* Title block + tile track stacked with comfortable rhythm */
  justify-content: center;
  gap: clamp(24px, 3.6vw, 48px);
  padding: clamp(8px, 2vw, 24px) 0;
}

/* Centered title block inherits .card__head--center; just bump the
   little bullet accent so it reads on dark video. */
.card--works .card__num {
  display: inline-flex;
  align-items: center;
  position: relative;
  z-index: 0;
  isolation: isolate;
  padding: 10px 22px 10px 15px;
  border-radius: 999px;
  background:
    linear-gradient(180deg, rgba(18, 21, 18, 0.78), rgba(5, 7, 6, 0.68)),
    rgba(6, 8, 7, 0.72);
  backdrop-filter: blur(30px) saturate(0.85) brightness(0.72);
  -webkit-backdrop-filter: blur(30px) saturate(0.85) brightness(0.72);
  border: 1px solid rgba(203, 252, 5, 0.22);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.12),
    inset 0 -1px 0 rgba(0, 0, 0, 0.42),
    0 0 0 1px rgba(0, 0, 0, 0.22),
    0 12px 34px rgba(0, 0, 0, 0.42);
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.78);
}
.card--works .card__num::before {
  box-shadow:
    0 0 0 7px rgba(203, 252, 5, 0.12),
    0 0 18px rgba(203, 252, 5, 0.42);
}
.card--works .card__title {
  /* drop a soft halo so big italic text sits cleanly on motion */
  text-shadow: 0 2px 24px rgba(0, 0, 0, 0.45);
}

/* HORIZONTAL TRACK — many tiles, single row, JS-driven.
   The track is *not* user-scrollable (overflow hidden). Instead
   script.js absorbs page scroll while the user is on the Works
   section and applies it to .scrollLeft, sliding tiles to the left.
   We still keep scrollLeft as the transport so we can use the native
   layout/measurement for tile widths and total width. */
.card__body--works {
  --works-edge-fade: clamp(56px, 7vw, 140px);
  --works-side-gutter: clamp(28px, 8vw, 180px);
  counter-reset: work-card;

  display: flex;
  flex-wrap: nowrap;
  gap: clamp(14px, 1.4vw, 22px);
  align-self: stretch;
  flex: 0 0 auto;

  overflow-x: hidden;
  overflow-y: hidden;
  scroll-behavior: auto;            /* JS sets scrollLeft directly */
  user-select: none;
  cursor: grab;
  touch-action: pan-y;

  /* Bleed a bit of vertical room for hover lift / shadow */
  padding: 10px var(--works-side-gutter) 14px;

  /* Right-side feathering hints that the track continues. The left edge
     stays hard so tiles exit cleanly at the page edge. */
  -webkit-mask-image: linear-gradient(
    90deg,
    rgba(0, 0, 0, 1) 0,
    rgba(0, 0, 0, 1) calc(100% - var(--works-edge-fade)),
    rgba(0, 0, 0, 0) 100%
  );
          mask-image: linear-gradient(
    90deg,
    rgba(0, 0, 0, 1) 0,
    rgba(0, 0, 0, 1) calc(100% - var(--works-edge-fade)),
    rgba(0, 0, 0, 0) 100%
  );

  scrollbar-width: none;
}
.card__body--works.is-dragging {
  cursor: grabbing;
}
.card__body--works::-webkit-scrollbar { display: none; height: 0; }

/* Works track arrows (desktop) */
.works__arrows {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 14px;
  pointer-events: auto;
}
.works__arrow {
  width: 44px;
  height: 44px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, 0.92);
  background: rgba(0, 0, 0, 0.22);
  border: 1px solid rgba(255, 255, 255, 0.22);
  -webkit-backdrop-filter: blur(10px);
          backdrop-filter: blur(10px);
  transition: transform 0.25s var(--ease), background 0.25s var(--ease), border-color 0.25s var(--ease);
  pointer-events: auto;
}
.works__arrow svg {
  color: var(--accent);
}
.works__arrow:hover {
  transform: translateY(-2px);
  background: rgba(0, 0, 0, 0.32);
  border-color: rgba(255, 255, 255, 0.34);
}
.works__arrow:hover svg {
  filter: brightness(1.08);
}
.works__arrow:active {
  transform: translateY(0);
}

/* Mobile: allow finger horizontal swipe, hide arrows */
@media (hover: none), (pointer: coarse), (max-width: 720px) {
  .card__body--works {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scroll-behavior: smooth;
    touch-action: pan-x pan-y;
  }
  .works__arrows { display: none; }
}

/* Full-bleed marketing-tile style: the entire card is the imagery,
   with title + meta overlaid at the bottom. The image gently scales
   on hover; the text stays put, anchored to a soft dark gradient. */
.work {
  counter-increment: work-card;
  display: block;
  flex: 0 0 auto;                          /* fixed-width track items */
  width: clamp(260px, 24vw, 320px);
  aspect-ratio: 5 / 6;                     /* slightly portrait, almost square */
  border-radius: 24px;
  overflow: hidden;
  background: #0e0e0e;
  border: 0;
  position: relative;
  isolation: isolate;
  -webkit-user-drag: none;

  /* JS-driven 3D hover state. Each variable is updated per-card by
     script.js so cards tilt, lift, and parallax independently. */
  --rx: 0deg;
  --ry: 0deg;
  --lift: 0px;
  --mx: 50%;
  --my: 50%;
  --cx: 0px;
  --cy: 0px;

  transform-style: preserve-3d;
  transform:
    perspective(900px)
    translate3d(0, var(--lift), 0)
    rotateX(var(--rx))
    rotateY(var(--ry));
  transition:
    transform 0.45s var(--ease),
    box-shadow 0.45s var(--ease);
  box-shadow:
    0 12px 32px rgba(0, 0, 0, 0.38),
    0 2px 6px rgba(0, 0, 0, 0.25);
}

.work:hover {
  --lift: -6px;
  box-shadow:
    0 26px 60px rgba(0, 0, 0, 0.55),
    0 4px 12px rgba(0, 0, 0, 0.35),
    0 0 0 1px rgba(203, 252, 5, 0.18),
    0 0 70px -12px rgba(203, 252, 5, 0.36);
}
/* Hover zoom moved off .work__media onto .work__cover so the rounded
   clip is owned by the (non-3D) .work__media wrapper. Safari fails to
   clip a scaled .work__media against its preserve-3d .work parent —
   you'd see the cover spill past the rounded corners on hover. By
   scaling the inner cover instead, .work__media's own overflow:hidden +
   border-radius reliably contains the zoom on every browser. */

/* Bottom-anchored dark gradient sitting BETWEEN the media and the
   text, so the title is always legible regardless of palette. */
.work::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  background: linear-gradient(
    180deg,
    rgba(0, 0, 0, 0)   0%,
    rgba(0, 0, 0, 0)   42%,
    rgba(0, 0, 0, 0.18) 60%,
    rgba(0, 0, 0, 0.55) 82%,
    rgba(0, 0, 0, 0.82) 100%
  );
  transition: opacity 0.4s var(--ease);
}

/* Diagonal shine sweep — fires once on hover, sliding from the
   left edge across the card. Uses overlay blend so it lifts mid-
   tones without blowing out highlights. */
.work::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  border-radius: inherit;
  background: linear-gradient(
    115deg,
    transparent 30%,
    rgba(255, 255, 255, 0.22) 50%,
    transparent 70%
  );
  transform: translate3d(-110%, 0, 0);
  opacity: 0;
  transition:
    transform 0.95s var(--ease),
    opacity 0.5s var(--ease);
  mix-blend-mode: overlay;
}
.work:hover::before {
  transform: translate3d(110%, 0, 0);
  opacity: 1;
}

.work__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--accent);
  overflow: hidden;
  border-radius: inherit;
  transition: transform 0.9s var(--ease);
  will-change: transform;
}
.work__media::before { content: ""; position: absolute; inset: 0; }

/* Safari WebKit fixes for the .work card.

   Issue 1 — square hover corners:
     `.work` uses `transform-style: preserve-3d` for the hover tilt.
     WebKit fails to clip transformed descendants (e.g. the scaled
     .work__cover on hover) against an ancestor's `overflow: hidden +
     border-radius`, so the corners go square mid-hover. clip-path is
     applied AT the .work box in screen space and reliably wins, even
     when the inner cover scales and 3D-tilts.

   Issue 2 — vertical "white strip" on the left of cards:
     `.work::before` is the diagonal hover-shine. At rest it has
     `mix-blend-mode: overlay`, `opacity: 0`, and is parked at
     `translate3d(-110%, 0, 0)`. Inside a preserve-3d ancestor, WebKit's
     blend-mode compositor leaks the shine band onto the card edge even
     while opacity is 0 — this is the displaced gradient visible as a
     pale strip at the left edge. Disabling the pseudo-element entirely
     in Safari removes the artifact; Chrome/Firefox still render the
     shine sweep on hover. */
[data-browser="safari"] .work {
  -webkit-clip-path: inset(0 round 24px);
          clip-path: inset(0 round 24px);
}
[data-browser="safari"] .work::before {
  display: none;
}

/* Cursor-follow lime halo. Reads --mx / --my (set per-card by JS)
   so the soft glow follows the pointer as it scans across the
   tile. Hidden until the card is hovered. */
.work__media::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    280px circle at var(--mx, 50%) var(--my, 50%),
    rgba(203, 252, 5, 0.22),
    transparent 70%
  );
  opacity: 0;
  transition: opacity 0.45s var(--ease);
  mix-blend-mode: screen;
}
.work:hover .work__media::after { opacity: 1; }

/* Real photographic cover for the 5 hero tiles (7850, PENGZHUA,
   LALEME, VOAGE, WILD VILLA). Sits inside .work__media so the
   parent's hover transform handles zoom + parallax automatically;
   only the bespoke filter pulse lives here. */
.work__cover {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  user-select: none;
  -webkit-user-drag: none;
  pointer-events: none;
  transition:
    transform 0.9s var(--ease),
    filter 0.6s var(--ease);
}
.work:hover .work__cover {
  transform: scale(1.08) translate3d(var(--cx), var(--cy), 0);
  filter: saturate(1.18) brightness(1.06) contrast(1.04);
}

/* Work tile gradient covers (pure CSS) */
.work__media--1 {
  background:
    radial-gradient(circle at 30% 30%, rgba(255,255,255,0.35), transparent 50%),
    radial-gradient(circle at 80% 70%, rgba(0,0,0,0.4), transparent 60%),
    linear-gradient(135deg, #ff7a45 0%, #c9341a 60%, #5a1a0c 100%);
}
.work__media--1::before {
  background: repeating-linear-gradient(45deg, rgba(255,255,255,0.06) 0 12px, transparent 12px 26px);
}
.work__media--2 {
  background:
    radial-gradient(circle at 70% 30%, rgba(255,255,255,0.25), transparent 50%),
    linear-gradient(160deg, #4d7a5a 0%, #1f3b2d 70%, #0d1f17 100%);
}
.work__media--2::before {
  background: radial-gradient(circle at 50% 110%, rgba(255,255,255,0.14) 0 22%, transparent 22.5%);
}
.work__media--3 {
  background:
    radial-gradient(circle at 20% 80%, rgba(255,255,255,0.3), transparent 50%),
    linear-gradient(135deg, #2a4d8f 0%, #142b58 70%, #060e22 100%);
}
.work__media--3::before {
  background:
    repeating-linear-gradient(0deg, rgba(255,255,255,0.05) 0 1px, transparent 1px 14px),
    repeating-linear-gradient(90deg, rgba(255,255,255,0.05) 0 1px, transparent 1px 14px);
}
.work__media--4 {
  background:
    radial-gradient(circle at 30% 30%, rgba(255,255,255,0.4), transparent 50%),
    linear-gradient(160deg, #d6b56e 0%, #8c6a2d 70%, #3b2a10 100%);
}
.work__media--4::before {
  background:
    radial-gradient(circle at 50% 50%, rgba(255,255,255,0.18) 0 12%, transparent 13%),
    radial-gradient(circle at 50% 50%, rgba(255,255,255,0.0) 0 28%, rgba(0,0,0,0.18) 28.5% 30%, transparent 31%);
}

/* 5. Plum / violet — editorial */
.work__media--5 {
  background:
    radial-gradient(circle at 70% 25%, rgba(255,255,255,0.32), transparent 55%),
    linear-gradient(140deg, #6b3a8e 0%, #3a1c52 65%, #14081f 100%);
}
.work__media--5::before {
  background: repeating-linear-gradient(115deg, rgba(255,255,255,0.05) 0 14px, transparent 14px 32px);
}

/* 6. Teal / aqua — type foundry */
.work__media--6 {
  background:
    radial-gradient(circle at 30% 75%, rgba(255,255,255,0.28), transparent 55%),
    linear-gradient(160deg, #2e9989 0%, #145e57 65%, #052424 100%);
}
.work__media--6::before {
  background:
    radial-gradient(circle at 75% 30%, rgba(255,255,255,0.16) 0 10%, transparent 11%),
    radial-gradient(circle at 25% 30%, rgba(0,0,0,0.20) 0 8%, transparent 9%);
}

/* 7. Slate — identity */
.work__media--7 {
  background:
    radial-gradient(circle at 50% 30%, rgba(255,255,255,0.30), transparent 55%),
    linear-gradient(155deg, #8e9aa6 0%, #4a5664 60%, #1a222b 100%);
}
.work__media--7::before {
  background:
    repeating-linear-gradient(0deg, rgba(255,255,255,0.06) 0 1px, transparent 1px 18px);
}

/* 8. Olive — brand */
.work__media--8 {
  background:
    radial-gradient(circle at 25% 25%, rgba(255,255,255,0.28), transparent 55%),
    linear-gradient(155deg, #95995e 0%, #4f5532 65%, #1d2010 100%);
}
.work__media--8::before {
  background: repeating-linear-gradient(60deg, rgba(0,0,0,0.18) 0 8px, transparent 8px 22px);
}

/* 9. Brick / coral — web */
.work__media--9 {
  background:
    radial-gradient(circle at 70% 70%, rgba(255,255,255,0.30), transparent 55%),
    linear-gradient(150deg, #e87b5b 0%, #a8412a 60%, #4a1810 100%);
}
.work__media--9::before {
  background:
    radial-gradient(circle at 30% 30%, rgba(255,255,255,0.18) 0 14%, transparent 15%);
}

/* 10. Midnight blue — sound */
.work__media--10 {
  background:
    radial-gradient(circle at 50% 90%, rgba(255,255,255,0.18), transparent 60%),
    linear-gradient(180deg, #18233a 0%, #0a1124 70%, #04060f 100%);
}
.work__media--10::before {
  background:
    repeating-linear-gradient(90deg, rgba(255,255,255,0.06) 0 2px, transparent 2px 9px);
}

/* 11. Cream / sand — packaging */
.work__media--11 {
  background:
    radial-gradient(circle at 40% 30%, rgba(255,255,255,0.45), transparent 55%),
    linear-gradient(160deg, #e7d5b4 0%, #b89a73 60%, #5c4626 100%);
}
.work__media--11::before {
  background:
    radial-gradient(circle at 50% 50%, rgba(0,0,0,0.0) 0 32%, rgba(0,0,0,0.18) 32.5% 35%, transparent 36%);
}

/* 12. Charcoal / type — letterforms */
.work__media--12 {
  background:
    radial-gradient(circle at 30% 30%, rgba(255,255,255,0.18), transparent 55%),
    linear-gradient(160deg, #353535 0%, #1c1c1c 70%, #050505 100%);
}
.work__media--12::before {
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,0.05) 0 1px, transparent 1px 16px),
    repeating-linear-gradient(-45deg, rgba(255,255,255,0.05) 0 1px, transparent 1px 16px);
}

/* 13. Sage — brand */
.work__media--13 {
  background:
    radial-gradient(circle at 30% 70%, rgba(255,255,255,0.28), transparent 55%),
    linear-gradient(150deg, #9bb59a 0%, #547055 60%, #1c2c1d 100%);
}
.work__media--13::before {
  background:
    radial-gradient(circle at 80% 20%, rgba(255,255,255,0.18) 0 12%, transparent 13%),
    radial-gradient(circle at 80% 20%, rgba(0,0,0,0.0) 0 24%, rgba(0,0,0,0.16) 24.5% 26%, transparent 27%);
}

/* 14. Indigo — editorial */
.work__media--14 {
  background:
    radial-gradient(circle at 70% 30%, rgba(255,255,255,0.28), transparent 55%),
    linear-gradient(150deg, #5a55c2 0%, #2b2776 65%, #0c0a2a 100%);
}
.work__media--14::before {
  background:
    repeating-linear-gradient(0deg, rgba(255,255,255,0.05) 0 1px, transparent 1px 14px),
    repeating-linear-gradient(90deg, rgba(255,255,255,0.05) 0 1px, transparent 1px 14px);
}

/* 15. Terracotta — wellness / clinic */
.work__media--15 {
  background:
    radial-gradient(circle at 35% 30%, rgba(255,255,255,0.30), transparent 55%),
    linear-gradient(155deg, #c87856 0%, #7a3e26 65%, #2a130a 100%);
}

/* 16. Magenta — match / dating */
.work__media--16 {
  background:
    radial-gradient(circle at 70% 25%, rgba(255,255,255,0.28), transparent 55%),
    linear-gradient(150deg, #d44a7e 0%, #75183d 65%, #270613 100%);
}

/* 17. Coral sunset — voice rooms */
.work__media--17 {
  background:
    radial-gradient(circle at 30% 70%, rgba(255,255,255,0.32), transparent 55%),
    linear-gradient(155deg, #ee9c7b 0%, #b06148 60%, #3a1d12 100%);
}

/* 18. Cinema crimson — ticketing */
.work__media--18 {
  background:
    radial-gradient(circle at 50% 30%, rgba(255,255,255,0.22), transparent 55%),
    linear-gradient(160deg, #a1252e 0%, #5a1116 65%, #1a060a 100%);
}

/* 19. Warm amber — youth research / editorial */
.work__media--19 {
  background:
    radial-gradient(circle at 35% 25%, rgba(255,255,255,0.30), transparent 55%),
    linear-gradient(150deg, #f5b041 0%, #a86a18 60%, #2a1808 100%);
}

/* Bottom-overlaid title + caption. Sits ON the imagery, no glass
   panel — legibility comes from the .work::after gradient below. */
.work__meta {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-start;
  gap: 6px;
  padding: clamp(18px, 1.6vw, 26px) clamp(20px, 1.8vw, 28px) clamp(20px, 1.8vw, 28px);
  color: #fff;
  pointer-events: none;             /* let the parent <a> own clicks */
}

.work__meta::before {
  content: counter(work-card, decimal-leading-zero);
  position: absolute;
  top: clamp(12px, 1.2vw, 16px);
  right: clamp(12px, 1.2vw, 16px);
  z-index: 5;
  color: var(--accent);
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  line-height: 1;
  text-shadow:
    0 1px 8px rgba(0, 0, 0, 0.62),
    0 0 14px rgba(203, 252, 5, 0.22);
}

.work__meta h3 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  font-style: italic;
  font-size: clamp(22px, 1.9vw, 28px);
  letter-spacing: -0.005em;
  line-height: 1.12;
  color: #fff;
  text-shadow: 0 2px 14px rgba(0, 0, 0, 0.45);
}

.work__meta p {
  margin: 0;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.78);
  white-space: nowrap;
}

/* ---- Contact card ---- */

.card--contact {
  color: var(--ink);
  text-align: center;
  align-items: center;
  justify-content: center;
}
.card__body--contact {
  display: flex;
  flex-direction: column;
  gap: 22px;
  align-items: center;
  justify-content: flex-start;
  width: 100%;
}
.card__sub {
  max-width: 50ch;
  margin: 0;
  font-size: clamp(14px, 1.2vw, 17px);
  color: var(--ink-dim);
  line-height: 1.55;
}
.card__mail {
  font-family: var(--serif);
  font-weight: 700;
  font-style: italic;
  font-size: clamp(28px, 4vw, 56px);
  letter-spacing: -0.01em;
  border-bottom: 1px solid var(--line);
  padding-bottom: 6px;
  transition: color 0.25s ease, border-color 0.25s ease, transform 0.3s var(--ease);
}
.card__mail:hover { color: var(--accent); border-color: var(--accent); transform: translateY(-2px); }

.card__meta-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
  margin-top: clamp(20px, 4vw, 60px);
  text-align: left;
  border-top: 1px solid var(--line);
  padding-top: 20px;
  width: 100%;
  max-width: 1100px;
}
.card__meta-grid p { margin: 0; font-size: 13px; color: var(--ink-dim); line-height: 1.55; }
.card__meta-grid .eyebrow { color: var(--accent); margin-bottom: 6px; font-size: 10.5px; }
@media (max-width: 720px) { .card__meta-grid { grid-template-columns: 1fr 1fr; gap: 16px; } }

/* Contact card meta: single-line + centered */
.card--contact .card__meta-grid {
  display: flex;
  justify-content: center;
  text-align: center;
  max-width: none;
}
.card--contact .card__meta-grid > div {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
}
.card--contact .card__meta-grid p {
  white-space: nowrap;
}
@media (max-width: 520px) {
  .card--contact .card__meta-grid p {
    white-space: normal;
  }
}

/* ---- Card responsive ---- */
@media (max-width: 720px) {
  .card {
    width: 92vw;
    height: 80vh;
    padding: 22px;
    gap: 16px;
    border-radius: 20px;
  }
  .card__head { max-width: none; }
  .card__title { font-size: clamp(26px, 7.5vw, 40px); }
  .card__title--giant { font-size: clamp(40px, 12vw, 64px); }
  .card--works {
    width: 100vw;
    height: 100vh;
    height: 100svh;
    padding: clamp(8px, 2vw, 24px) 0;
  }
}

/* ============================================================
   MARQUEE
   ============================================================ */

.marquee {
  background: var(--paper);
  color: var(--paper-ink);
  border-top: 1px solid var(--line-dark);
  border-bottom: 1px solid var(--line-dark);
  overflow: hidden;
  padding: 22px 0;
}
.marquee__track {
  display: inline-flex;
  align-items: center;
  gap: 32px;
  white-space: nowrap;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 700;
  font-size: clamp(28px, 4vw, 56px);
  line-height: 1;
  animation: marquee 28s linear infinite;
}
.marquee__track .dot { font-size: 0.5em; opacity: 0.55; }
@keyframes marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

/* ============================================================
   FOOTER
   ============================================================ */

.footer {
  background: var(--bg);
  color: var(--ink);
  padding: 0 0 30px;
  border-top: 1px solid var(--line);
}
.footer__giant {
  font-family: var(--serif);
  font-weight: 900;
  font-style: italic;
  font-size: clamp(96px, 18vw, 300px);
  line-height: 0.9;
  letter-spacing: -0.055em;
  text-align: center;
  margin: 30px 0 30px;
  white-space: nowrap;
  background: linear-gradient(180deg, #ffffff 0%, rgba(255,255,255,0.18) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.footer__row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 14px;
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-dim);
  border-top: 1px solid var(--line);
  padding-top: 24px;
}
.footer__back {
  color: var(--ink);
  font-weight: 600;
  transition: color 0.25s ease;
}
.footer__back:hover { color: var(--accent); }

/* ============================================================
   REDUCED MOTION
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
  html { scroll-behavior: auto; }
  /* Show every card stacked statically (last on top) */
  .card {
    transform: none !important;
    position: relative !important;
    inset: auto !important;
    left: auto !important;
    top: auto !important;
    width: auto !important;
    height: auto !important;
    max-width: 1100px;
    margin: 24px auto;
  }
  .stage { height: auto !important; }
  .stage__pin { position: relative !important; height: auto !important; }
  .hero { position: relative !important; height: 100vh; }
}

/* ============================================================
   PROJECT DETAIL PAGE  (work.html)
   --------------------------------------------------------------
   A normal scrollable page (no scroll-jack, no pinned stage). It
   reuses the studio's brand / nav / menu / cursor / footer chrome
   and adds:
     .wd            — main container, vertical rhythm
     .wd__topbar    — sticky back-link + 01 / 14 counter
     .wd__hero      — full-bleed gradient banner (per-project tile)
     .wd__meta      — liquid-glass slab with Client / Year / Role
     .wd__intro     — generous serif/sans intro paragraph
     .wd__chapters  — alternating media + text rows
     .wd__next      — large clickable "next case" tile

   The detail body opts back into a normal cursor-friendly layout:
   the global rule  body { overflow-x: hidden; cursor: none; }
   already covers it. We only need to switch background + text
   color into the dark studio palette.
   ============================================================ */
.wd-body {
  background: var(--bg);
  color: var(--ink);
  /* Allow regular vertical scroll; .wd contents are tall. */
  overflow-x: hidden;
  /* The detail page should never see a horizontal scrollbar even
     when the hero cover scales slightly past 100vw. */
}

/* The detail page hides .marquee's bottom border since it's now the
   transition between body content and the footer block. */
.wd-body .marquee { border-top-color: rgba(255,255,255,0.08); }

/* The project detail page hides the primary site nav (the centered
   pill with the section links and the menu toggle) and the fullscreen
   menu drawer it opens. The brand mark and the wd__topbar Back button
   remain as the only chrome — focused, project-first reading. */
.wd-body .nav,
.wd-body .menu {
  display: none !important;
}

/* ----------------------------------------------------------------
   Top bar — fixed ribbon for detail-page navigation. It stays pinned
   to the viewport so the Back action is always available.
---------------------------------------------------------------- */
.wd {
  position: relative;
  width: 100%;
}

.wd__topbar {
  position: fixed;
  top: 86px;
  left: 0;
  right: 0;
  z-index: 58;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 clamp(20px, 5vw, 56px);
  background: transparent;
  pointer-events: none;
}
.wd__topbar > * { pointer-events: auto; }

.wd__back {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  padding: 10px 18px 10px 14px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  -webkit-backdrop-filter: blur(8px);
          backdrop-filter: blur(8px);
  transition: border-color 0.25s var(--ease),
              background 0.25s var(--ease),
              transform 0.25s var(--ease);
}
.wd__back:hover {
  border-color: rgba(255, 255, 255, 0.45);
  background: rgba(255, 255, 255, 0.12);
  transform: translateX(-3px);
}
.wd__back span:first-child {
  font-size: 14px;
  letter-spacing: 0;
  transform: translateY(-1px);
}

.wd__counter {
  font-family: var(--sans);
  font-size: 11.5px;
  letter-spacing: 0.22em;
  font-variant-numeric: tabular-nums;
  color: rgba(245, 244, 239, 0.55);
}

@media (max-width: 720px) {
  .wd__topbar {
    top: 74px;
    padding: 0 18px;
  }
}

@media (max-width: 520px) {
  .wd__topbar { top: 68px; }
}

/* ----------------------------------------------------------------
   HERO — full-bleed gradient banner. The cover element gets the
   `.work__media` + `.work__media--N` class assigned by JS, so it
   inherits the same gradient as the project's tile on the home
   page — clicking the tile feels like falling *into* it.
---------------------------------------------------------------- */
.wd__hero {
  position: relative;
  min-height: 46vh;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: clamp(54px, 7vh, 84px) clamp(20px, 5vw, 56px) clamp(48px, 7vh, 76px);
  overflow: hidden;
  isolation: isolate;
}

.wd__hero::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: clamp(120px, 18vh, 220px);
  z-index: 0;
  background: linear-gradient(180deg, rgba(11, 11, 11, 0) 0%, rgba(11, 11, 11, 0.72) 62%, var(--bg) 100%);
  pointer-events: none;
}

/* Per-project hero gradient — work.js sets CSS vars from the same stops as
   the home tile palette (with slug overrides when the cover diverges). */
.wd__hero > .wd__hero-cover.wd__hero-cover--custom {
  background:
    radial-gradient(circle at 30% 30%, var(--wd-hero-hi, rgba(255, 255, 255, 0.35)), transparent 50%),
    radial-gradient(circle at 80% 70%, rgba(0, 0, 0, 0.4), transparent 60%),
    linear-gradient(
      var(--wd-hero-angle, 150deg),
      var(--wd-hero-1) 0%,
      var(--wd-hero-2) 60%,
      var(--wd-hero-3) 100%
    );
}
.wd__hero > .wd__hero-cover.wd__hero-cover--custom::before {
  opacity: 0.42;
}

/* Hero uses the same cover image as the works card (see work.js COVERS_BY_SLUG). */
.wd__hero > .wd__hero-cover.wd__hero-cover--photo {
  background-color: #121212;
  background-image:
    linear-gradient(
      180deg,
      rgba(0, 0, 0, 0.12) 0%,
      rgba(0, 0, 0, 0.38) 52%,
      rgba(0, 0, 0, 0.58) 100%
    ),
    var(--wd-hero-photo);
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
}
.wd__hero > .wd__hero-cover.wd__hero-cover--photo::before {
  opacity: 0.06;
}
.wd__hero > .wd__hero-cover.wd__hero-cover--photo::after {
  background:
    radial-gradient(120% 85% at 50% 30%, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.32) 72%, rgba(0, 0, 0, 0.58) 100%),
    linear-gradient(180deg, rgba(11, 11, 11, 0) 22%, rgba(11, 11, 11, 0.48) 70%, rgba(11, 11, 11, 0.82) 100%);
}

.wd__hero-cover {
  position: absolute;
  inset: -6%;                  /* slight bleed for parallax wiggle */
  z-index: 0;
  /* Coverage and depth come from the work__media gradient classes;
     here we just add a touch of mouse-driven parallax via CSS vars
     written by work.js. */
  transform:
    translate3d(var(--vpx, 0px), var(--vpy, 0px), 0)
    rotateX(var(--vrx, 0deg))
    rotateY(var(--vry, 0deg))
    scale(1.04);
  transform-origin: 50% 50%;
  transition: transform 0.6s var(--ease);
  will-change: transform;
}
/* Vignette + fade-to-page so the banner reads as a hero, not a tile */
.wd__hero-cover::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 80% at 50% 30%, rgba(0,0,0,0) 0%, rgba(0,0,0,0.45) 75%, rgba(0,0,0,0.75) 100%),
    linear-gradient(180deg, rgba(11,11,11,0) 24%, rgba(11,11,11,0.82) 78%, rgba(11,11,11,1) 100%);
  pointer-events: none;
}

.wd__hero-text {
  position: relative;
  z-index: 1;
  max-width: 1180px;
  width: 100%;
  text-align: center;
  margin: 0 auto;
}

.wd__kicker {
  font-family: var(--sans);
  font-size: 11.5px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(245, 244, 239, 0.78);
  margin: 0 0 22px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 7px 14px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.22);
  -webkit-backdrop-filter: blur(8px);
          backdrop-filter: blur(8px);
}

.wd__title {
  font-family: var(--serif);
  font-weight: 900;
  font-size: clamp(56px, 11vw, 156px);
  line-height: 0.92;
  letter-spacing: -0.025em;
  color: var(--ink);
  margin: 0 0 28px;
  text-shadow:
    0 2px 10px rgba(0, 0, 0, 0.55),
    0 10px 36px rgba(0, 0, 0, 0.55),
    0 22px 90px rgba(0, 0, 0, 0.45);
}
.wd__title em {
  font-style: italic;
  font-weight: 900;
  color: #fff;
  text-shadow:
    0 2px 10px rgba(0, 0, 0, 0.62),
    0 12px 44px rgba(0, 0, 0, 0.55);
}

.wd__summary {
  font-family: var(--sans);
  font-size: clamp(16px, 1.45vw, 22px);
  line-height: 1.55;
  max-width: 760px;
  /* Small bottom spacer so the summary's last line never collides
     with the scroll hint or the meta slab below. */
  margin: 0 auto clamp(8px, 1.5vh, 16px);
  color: rgba(245, 244, 239, 0.85);
}

/* Tiny scroll-down hint at the bottom of the hero — a 1 px line that
   pulses to draw the eye into the meta slab below. */
.wd__hero-scroll {
  position: absolute;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  width: 1px;
  height: 56px;
  overflow: hidden;
  z-index: 2;
}
.wd__hero-scroll span {
  display: block;
  width: 100%;
  height: 100%;
  background: linear-gradient(180deg, transparent, rgba(255,255,255,0.55), transparent);
  animation: wdScroll 2.4s ease-in-out infinite;
}
@keyframes wdScroll {
  0%   { transform: translateY(-100%); }
  100% { transform: translateY(100%); }
}

/* ----------------------------------------------------------------
   META SLAB — liquid-glass card that reads "Client / Year / Role /
   Deliverables", overlapping the hero by ~60 px so it reads as the
   page's first piece of content rather than a sidebar.
---------------------------------------------------------------- */
.wd__meta {
  position: relative;
  z-index: 3;
  width: min(1180px, 92vw);
  /* Sit just under the hero with a small clear gap. The previous
     -64px overlap was eating the summary's last line on tighter
     viewports; a modest positive margin keeps both blocks legible
     while still reading as one continuous hero unit. */
  margin: clamp(20px, 3vh, 40px) auto 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 28px 48px;
  padding: clamp(24px, 3vw, 36px) clamp(24px, 3.5vw, 44px);
  border-radius: 22px;
  color: var(--ink);
  background:
    radial-gradient(140% 60% at 50% -20%, rgba(255,255,255,0.18), rgba(255,255,255,0) 60%),
    linear-gradient(180deg, rgba(255,255,255,0.10) 0%, rgba(255,255,255,0.03) 60%, rgba(255,255,255,0.06) 100%),
    rgba(20, 22, 18, 0.34);
  -webkit-backdrop-filter: blur(22px) saturate(180%) brightness(1.04) contrast(1.04);
          backdrop-filter: blur(22px) saturate(180%) brightness(1.04) contrast(1.04);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-top: 1px solid rgba(255, 255, 255, 0.32);
  box-shadow:
    inset 0 1.5px 0 rgba(255, 255, 255, 0.45),
    inset 0 -1px 0 rgba(0, 0, 0, 0.30),
    0 22px 48px rgba(0, 0, 0, 0.42);
}
@supports (backdrop-filter: url("#x")) or (-webkit-backdrop-filter: url("#x")) {
  .wd__meta {
    -webkit-backdrop-filter: url(#liquid-glass-meta) blur(14px) saturate(180%) brightness(1.04) contrast(1.04);
            backdrop-filter: url(#liquid-glass-meta) blur(14px) saturate(180%) brightness(1.04) contrast(1.04);
  }
}
.wd__meta-cell .eyebrow {
  margin: 0 0 8px;
  font-size: 10.5px;
  letter-spacing: 0.22em;
  color: rgba(245, 244, 239, 0.55);
}
.wd__meta-cell p:last-child {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
}
@media (max-width: 900px) {
  .wd__meta { grid-template-columns: repeat(2, 1fr); gap: 22px 28px; }
}
@media (max-width: 520px) {
  .wd__meta { grid-template-columns: 1fr; }
}

/* ----------------------------------------------------------------
   INTRO — single generous paragraph, sets the case for the chapters.
---------------------------------------------------------------- */
.wd__intro {
  max-width: 920px;
  margin: clamp(80px, 10vw, 140px) auto;
  padding: 0 clamp(20px, 5vw, 56px);
}
.wd__intro p {
  font-family: var(--sans);
  font-size: clamp(18px, 1.6vw, 26px);
  line-height: 1.55;
  letter-spacing: -0.005em;
  color: rgba(245, 244, 239, 0.92);
  margin: 0;
}
.wd__intro em,
.wd__intro p em {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 700;
}
.wd__intro--empty {
  display: none;
}

/* ----------------------------------------------------------------
   CHAPTERS — alternating left / right rows. Each chapter has a
   `.chapter__media` block (uses the project's gradient again, with
   a giant chapter number) and a `.chapter__text` column.
---------------------------------------------------------------- */
.wd__chapters {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 clamp(20px, 5vw, 56px);
  display: flex;
  flex-direction: column;
  gap: clamp(72px, 9vw, 128px);
}
.wd__chapters--images {
  width: min(1180px, 92vw);
  max-width: none;
  margin-top: clamp(48px, 6vw, 80px);
  padding: 0;
  gap: 0;
}
.project-image {
  margin: 0;
  overflow: hidden;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}
.project-image img {
  display: block;
  width: 100%;
  height: auto;
}
.wd__chapters--images .project-image:first-child {
  border-top-left-radius: 50px;
  border-top-right-radius: 50px;
}
.wd__chapters--images .project-image:last-child {
  border-bottom-right-radius: 50px;
  border-bottom-left-radius: 50px;
}
.chapter {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: clamp(32px, 5vw, 80px);
  align-items: center;
}
.chapter--reverse {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
}
.chapter--reverse .chapter__media { order: 2; }
.chapter--reverse .chapter__text  { order: 1; }

.chapter__media {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: 18px;
  overflow: hidden;
  isolation: isolate;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
  transition: transform 0.6s var(--ease), box-shadow 0.6s var(--ease);
}
.chapter:hover .chapter__media {
  transform: translateY(-4px);
  box-shadow: 0 28px 64px rgba(0, 0, 0, 0.55);
}
.chapter__media-num {
  position: absolute;
  left: clamp(18px, 2vw, 28px);
  bottom: clamp(14px, 2vw, 22px);
  font-family: var(--serif);
  font-style: italic;
  font-weight: 900;
  font-size: clamp(48px, 7vw, 96px);
  line-height: 1;
  letter-spacing: -0.02em;
  color: rgba(255, 255, 255, 0.85);
  text-shadow: 0 4px 18px rgba(0, 0, 0, 0.35);
  pointer-events: none;
}

.chapter__text { color: var(--ink); }
.chapter__num {
  margin: 0 0 16px;
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(245, 244, 239, 0.55);
}
/* Section headings — bumped from 26-40px to 36-60px so each chapter
   reads as a real H2 rather than a slightly-larger paragraph. */
.chapter__heading {
  font-family: var(--serif);
  font-weight: 700;
  font-size: clamp(36px, 3.6vw, 60px);
  line-height: 1.08;
  letter-spacing: -0.018em;
  margin: 0 0 22px;
}
.chapter__body {
  font-family: var(--sans);
  font-size: clamp(15px, 1.05vw, 17px);
  line-height: 1.7;
  color: rgba(245, 244, 239, 0.78);
  margin: 0;
}

@media (max-width: 760px) {
  .chapter,
  .chapter--reverse {
    grid-template-columns: 1fr;
    gap: 26px;
  }
  .chapter--reverse .chapter__media { order: 0; }
  .chapter--reverse .chapter__text  { order: 0; }
  .chapter__media { aspect-ratio: 16 / 11; }
}

/* ----------------------------------------------------------------
   NEXT PROJECT — single big tile with the next case. Inherits the
   work__media gradient of the next project so the navigation feels
   continuous: the page literally previews the color of the next
   one while the user is still finishing this one.
---------------------------------------------------------------- */
.wd__next {
  /* Two equal-width tiles side-by-side. Tighter outer max-width than
     the chapters section so the two cards feel compact rather than
     each one dominating the row. */
  max-width: 1080px;
  margin: clamp(96px, 12vw, 160px) auto clamp(80px, 10vw, 120px);
  padding: 0 clamp(20px, 5vw, 56px);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(18px, 2vw, 28px);
}
.wd__next-card {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  align-content: end;
  align-items: start;
  gap: 14px;
  /* Reduced padding + min-height since two cards now share the row */
  padding: clamp(24px, 3vw, 36px) clamp(22px, 2.6vw, 32px);
  min-height: 200px;
  border-radius: 20px;
  overflow: hidden;
  isolation: isolate;
  text-decoration: none;
  color: var(--ink);
  background: rgba(20, 22, 18, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.12);
  transition: transform 0.5s var(--ease), border-color 0.5s var(--ease);
}
.wd__next-card::before {
  /* The next project's tile gradient — assigned per-N via the
     .wd__next-card--N class set by work.js. Sits on a negative
     z-index so the eyebrow/title text always reads on top. */
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
}
.wd__next-card::after {
  /* Darkening vignette so any color gradient stays legible behind
     white type. */
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(110% 80% at 0% 100%, rgba(0,0,0,0.55), rgba(0,0,0,0) 60%),
    linear-gradient(180deg, rgba(0,0,0,0.0) 30%, rgba(0,0,0,0.55) 100%);
}
.wd__next-card:hover {
  transform: translateY(-4px);
  border-color: rgba(255, 255, 255, 0.28);
}
/* Per-N gradient backgrounds — mirror the .work__media--N stacks on
   the home page so navigating to "next case" feels like falling into
   the same color. Define explicitly rather than reusing the
   .work__media--N selector to avoid pulling in flex / aspect-ratio
   layout rules from .work__media. */
.wd__next-card--1::before {
  background:
    radial-gradient(circle at 30% 30%, rgba(255,255,255,0.32), transparent 50%),
    radial-gradient(circle at 80% 70%, rgba(0,0,0,0.4), transparent 60%),
    linear-gradient(135deg, #ff7a45 0%, #c9341a 60%, #5a1a0c 100%);
}
.wd__next-card--2::before {
  background:
    radial-gradient(circle at 70% 30%, rgba(255,255,255,0.25), transparent 50%),
    linear-gradient(160deg, #4d7a5a 0%, #1f3b2d 70%, #0d1f17 100%);
}
.wd__next-card--3::before {
  background:
    radial-gradient(circle at 20% 80%, rgba(255,255,255,0.3), transparent 50%),
    linear-gradient(135deg, #2a4d8f 0%, #142b58 70%, #060e22 100%);
}
.wd__next-card--4::before {
  background:
    radial-gradient(circle at 30% 30%, rgba(255,255,255,0.4), transparent 50%),
    linear-gradient(160deg, #d6b56e 0%, #8c6a2d 70%, #3b2a10 100%);
}
.wd__next-card--5::before {
  background:
    radial-gradient(circle at 70% 25%, rgba(255,255,255,0.32), transparent 55%),
    linear-gradient(140deg, #6b3a8e 0%, #3a1c52 65%, #14081f 100%);
}
.wd__next-card--6::before {
  background:
    radial-gradient(circle at 30% 75%, rgba(255,255,255,0.28), transparent 55%),
    linear-gradient(160deg, #2e9989 0%, #145e57 65%, #052424 100%);
}
.wd__next-card--7::before {
  background:
    radial-gradient(circle at 50% 30%, rgba(255,255,255,0.30), transparent 55%),
    linear-gradient(155deg, #8e9aa6 0%, #4a5664 60%, #1a222b 100%);
}
.wd__next-card--8::before {
  background:
    radial-gradient(circle at 25% 25%, rgba(255,255,255,0.28), transparent 55%),
    linear-gradient(155deg, #95995e 0%, #4f5532 65%, #1d2010 100%);
}
.wd__next-card--9::before {
  background:
    radial-gradient(circle at 70% 70%, rgba(255,255,255,0.30), transparent 55%),
    linear-gradient(150deg, #e87b5b 0%, #a8412a 60%, #4a1810 100%);
}
.wd__next-card--10::before {
  background:
    radial-gradient(circle at 50% 90%, rgba(255,255,255,0.18), transparent 60%),
    linear-gradient(180deg, #18233a 0%, #0a1124 70%, #04060f 100%);
}
.wd__next-card--11::before {
  background:
    radial-gradient(circle at 40% 30%, rgba(255,255,255,0.45), transparent 55%),
    linear-gradient(160deg, #e7d5b4 0%, #b89a73 60%, #5c4626 100%);
}
.wd__next-card--12::before {
  background:
    radial-gradient(circle at 30% 30%, rgba(255,255,255,0.18), transparent 55%),
    linear-gradient(160deg, #353535 0%, #1c1c1c 70%, #050505 100%);
}
.wd__next-card--13::before {
  background:
    radial-gradient(circle at 30% 70%, rgba(255,255,255,0.28), transparent 55%),
    linear-gradient(150deg, #9bb59a 0%, #547055 60%, #1c2c1d 100%);
}
.wd__next-card--14::before {
  background:
    radial-gradient(circle at 70% 30%, rgba(255,255,255,0.28), transparent 55%),
    linear-gradient(150deg, #5a55c2 0%, #2b2776 65%, #0c0a2a 100%);
}
.wd__next-card--15::before {
  background:
    radial-gradient(circle at 35% 30%, rgba(255,255,255,0.30), transparent 55%),
    linear-gradient(155deg, #c87856 0%, #7a3e26 65%, #2a130a 100%);
}
.wd__next-card--16::before {
  background:
    radial-gradient(circle at 70% 25%, rgba(255,255,255,0.28), transparent 55%),
    linear-gradient(150deg, #d44a7e 0%, #75183d 65%, #270613 100%);
}
.wd__next-card--17::before {
  background:
    radial-gradient(circle at 30% 70%, rgba(255,255,255,0.32), transparent 55%),
    linear-gradient(155deg, #ee9c7b 0%, #b06148 60%, #3a1d12 100%);
}
.wd__next-card--18::before {
  background:
    radial-gradient(circle at 50% 30%, rgba(255,255,255,0.22), transparent 55%),
    linear-gradient(160deg, #a1252e 0%, #5a1116 65%, #1a060a 100%);
}

.wd__next-eyebrow {
  display: inline-block;
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(245, 244, 239, 0.7);
  margin-bottom: 10px;
}
.wd__next-eyebrow #wdNextKicker,
.wd__next-eyebrow #wdPrevKicker {
  text-transform: uppercase;
  letter-spacing: 0.22em;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.92);
}
/* Half-width cards mean the title can't stay at 80px or it will run
   to 3+ lines on most viewports — scale it down to a desk size that
   still feels editorial. */
.wd__next-title {
  display: block;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 900;
  font-size: clamp(26px, 3vw, 44px);
  line-height: 1.02;
  letter-spacing: -0.02em;
  color: #fff;
  text-shadow: 0 6px 24px rgba(0, 0, 0, 0.45);
  max-width: 14ch;
}
.wd__next-title em { font-style: italic; }
.wd__next-cta {
  align-self: end;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 20px;
  border-radius: 999px;
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.32);
  -webkit-backdrop-filter: blur(8px);
          backdrop-filter: blur(8px);
  white-space: nowrap;
  transition: background 0.25s var(--ease), transform 0.25s var(--ease);
}
.wd__next-card:hover .wd__next-cta {
  background: rgba(255, 255, 255, 0.22);
  transform: translateX(4px);
}
@media (max-width: 720px) {
  /* Stack the two cards vertically — side-by-side is too tight on
     phones and the title would run to 3+ lines. */
  .wd__next {
    grid-template-columns: 1fr;
    gap: 18px;
  }
  .wd__next-card {
    align-items: stretch;
    min-height: 180px;
    padding: 28px 22px;
  }
  .wd__next-title { font-size: clamp(28px, 8vw, 44px); max-width: 18ch; }
  .wd__next-cta   { align-self: start; }
}

/* ----------------------------------------------------------------
   404 hero — used when ?p=<slug> is missing or unknown.
---------------------------------------------------------------- */
.wd__hero--empty {
  min-height: 70vh;
  align-items: center;
  background:
    radial-gradient(ellipse 90% 80% at 50% 30%, rgba(255, 90, 31, 0.22) 0%, transparent 60%),
    var(--bg);
}
.wd__hero--empty .wd__hero-text { max-width: 820px; }
.wd__hero--empty .wd__title { font-size: clamp(48px, 9vw, 110px); }

/* ----------------------------------------------------------------
   Reduced-motion fallbacks for the detail page.
---------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .wd__hero-cover,
  .wd__hero-scroll span,
  .chapter,
  .chapter__media,
  .wd__next-card { transition: none !important; animation: none !important; }
  .wd__hero-cover { transform: scale(1.04) !important; }
}
