/* ============================================================
   charliehane.com
   landing = portal → forest scroll → bicycle world (with bricks)
   inner pages = editorial works lists with bicycle cursor
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; background: none; border: 0; padding: 0; }

:root {
  --ink:       #1a1614;
  --ink-2:     #2a2420;
  --cream:     #f3ebe0;
  --cream-2:   #e9dfd0;
  --paper:     #fffaf2;
  --rust:      #b94a2a;
  --rust-2:    #d96a3a;
  --moss:      #2f4730;
  --moss-2:    #5a7556;
  --hairline:  rgba(26,22,20,0.16);

  --serif: 'Fraunces', 'Times New Roman', serif;
  --sans:  'Inter', system-ui, sans-serif;
  --mono:  'JetBrains Mono', ui-monospace, monospace;
}

body {
  font-family: var(--sans);
  background: var(--cream);
  color: var(--ink);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection { background: var(--rust); color: var(--paper); }


/* ============================================================
   nav (shared)
   ============================================================ */

.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 24px 32px;
  font-family: var(--mono);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  pointer-events: none;
}
.nav a, .nav .nav-mark { pointer-events: auto; }
.nav-mark { font-weight: 600; letter-spacing: 0.14em; }
.nav-sections {
  list-style: none;
  display: flex;
  gap: 26px;
  margin: 0; padding: 0;
}
.nav-sections a { position: relative; }
.nav-sections a::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  bottom: -5px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.4s cubic-bezier(.2,.8,.2,1);
}
.nav-sections a:hover::after,
.nav-sections a.is-current::after {
  transform: scaleX(1);
  transform-origin: left;
}
/* invert nav over varying section backgrounds */
.nav--blend {
  color: #ffffff;
  mix-blend-mode: difference;
}


/* ============================================================
   landing — base
   ============================================================ */

.page-landing { cursor: none; overflow-x: hidden; }
.page-landing a, .page-landing button { cursor: none; }


/* ============================================================
   PORTAL hero
   ============================================================ */

.portal {
  min-height: 220vh;
  padding: 0;
  position: relative;
  background: var(--cream);
}
.portal-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 60px 8vw 80px;
  overflow: hidden;
}
.portal-eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  margin: 0 0 32px;
  opacity: 0.6;
}
.portal-name {
  font-family: var(--serif);
  font-weight: 350;
  font-variation-settings: "opsz" 144, "SOFT" 100, "WONK" 1;
  font-size: clamp(36px, 8.5vw, 130px);     /* halved from clamp(72,17vw,260) */
  line-height: 0.86;
  margin: 0 0 36px;
  letter-spacing: -0.04em;
}
.portal-name em {
  font-style: italic;
  color: var(--rust);
  font-variation-settings: "opsz" 144, "SOFT" 100, "WONK" 1;
}
.portal-blurb {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 350;
  font-size: clamp(20px, 2.4vw, 30px);
  margin: 0 0 36px;
  max-width: 32ch;
  opacity: 0.82;
}
.portal-cue {
  position: absolute;
  bottom: 36px; left: 8vw;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  opacity: 0.55;
  animation: cueBob 2.2s ease-in-out infinite;
}
@keyframes cueBob {
  0%, 100% { transform: translateY(0); opacity: 0.55; }
  50%      { transform: translateY(8px); opacity: 1; }
}


/* ============================================================
   FOREST SCROLL — first-person walk forward
   things start tiny near the horizon and scale up + drift to the
   sides as the user scrolls "forward" through the woods.
   ============================================================ */

.forest {
  position: relative;
  height: 700vh;
  background: #0a140a;
}
.forest-pin {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  background: #0a140a;   /* fallback dark forest so no light leaks */
}

/* ============================================================
   FOREST CINEMA — scroll-scrubbed AE render with sign hotspots
   ============================================================ */

/* The pre-rendered video fills the pinned viewport — no bars. When the
   viewer's aspect ratio doesn't match 16:9, the video gets cropped to
   fit; object-position keeps the upper-mid portion of the frame anchored
   so signs that live near the top of the comp stay visible on taller
   (MacBook 16:10) and wider (ultrawide) screens alike. */
.forest-cine-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Source video is 1.89:1 — wider than most viewports, so cropping
     (when it happens) is on the sides. Centered position works well. */
  object-position: center;
  display: block;
  z-index: 1;
  pointer-events: none;
  background: #0a140a;
}

/* "Forest sequence loading..." placeholder — visible while video buffers
   or while videoSrc is empty during development. Fades out via .is-hidden
   once the video reports loadedmetadata. */
.forest-cine-pending {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.4em;
  z-index: 2;
  color: rgba(220, 215, 195, 0.55);
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: lowercase;
  pointer-events: none;
  transition: opacity 0.4s ease;
}
.forest-cine-pending p { margin: 0; }
.forest-cine-pending-hint { opacity: 0.6; font-size: 0.75rem; }
.forest-cine-pending.is-hidden { opacity: 0; }

/* Hotspot container fills the pin. Individual buttons inside are
   positioned absolutely from the sign data in content.json. */
.forest-hotspots {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;   /* container passes clicks through */
}

/* The hotspot button — invisible until its scroll window is active.
   Hit area is generous; users don't need pixel accuracy. */
.sign-hotspot {
  position: absolute;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.35s ease, transform 0.35s ease;
  pointer-events: none;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  /* Subtle inner glow during dev so you can see where the hit areas are.
     Comment this out for production polish. */
  /* box-shadow: inset 0 0 0 1px rgba(255,210,140,0.25); */
}
.sign-hotspot.is-active {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.sign-hotspot:focus { outline: none; }
.sign-hotspot:focus-visible .sign-hotspot-pill {
  box-shadow: 0 0 0 2px rgba(255,210,140,0.7), 0 6px 24px rgba(0,0,0,0.5);
}
.sign-hotspot:hover .sign-hotspot-pill {
  background: rgba(255,210,140,0.95);
  color: #1a1208;
  transform: translateY(-2px);
}

/* Tiny pill at the bottom of the hotspot that says "tap to read" */
.sign-hotspot-pill {
  display: inline-block;
  margin-bottom: 6%;
  padding: 0.5em 0.95em;
  background: rgba(20, 14, 8, 0.85);
  color: rgba(255, 230, 190, 0.95);
  border: 1px solid rgba(255, 210, 140, 0.4);
  border-radius: 999px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: lowercase;
  white-space: nowrap;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  transition: background 0.2s, color 0.2s, transform 0.2s, box-shadow 0.2s;
}

/* ============================================================
   SIGN MODAL — opens when a hotspot is clicked
   ============================================================ */

.sign-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.22s ease;
}
.sign-modal.is-open { opacity: 1; }
.sign-modal[hidden] { display: none; }

.sign-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(8, 14, 8, 0.78);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  cursor: pointer;
}

.sign-modal-card {
  position: relative;
  z-index: 1;
  max-width: min(720px, 92vw);
  max-height: 86vh;
  overflow-y: auto;
  padding: clamp(1.5rem, 4vw, 3rem);
  background: #efe7d8;          /* cream paper, matches the original sign */
  color: #1a1208;
  border-radius: 4px;
  box-shadow: 0 30px 80px rgba(0,0,0,0.6),
              0 0 0 1px rgba(0,0,0,0.1);
  /* Subtle paper texture via gradient — looks like a posted sign */
  background-image:
    radial-gradient(ellipse at 20% 10%, rgba(120,80,40,0.06) 0%, transparent 60%),
    radial-gradient(ellipse at 80% 90%, rgba(120,80,40,0.05) 0%, transparent 60%);
  transform: translateY(20px) scale(0.96);
  transition: transform 0.3s cubic-bezier(0.2, 0.9, 0.3, 1);
}
.sign-modal.is-open .sign-modal-card {
  transform: translateY(0) scale(1);
}

.sm-role {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.75rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #5a4126;
  margin: 0 0 1rem;
}

.sm-quote {
  font-family: 'Fraunces', serif;
  font-weight: 400;
  font-style: italic;
  font-size: clamp(1.25rem, 2.6vw, 1.85rem);
  line-height: 1.4;
  margin: 0 0 1.25rem;
  color: #1a1208;
}
.sm-quote::before { content: '“'; }
.sm-quote::after  { content: '”'; }

.sm-cite {
  display: block;
  font-family: 'Inter', sans-serif;
  font-size: 0.95rem;
  font-style: normal;
  color: #3a2a14;
  margin-bottom: 1.5rem;
}
.sm-cite em {
  font-style: italic;
  color: #5a4126;
}

.sm-video {
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #1a1208;
  border-radius: 2px;
  overflow: hidden;
  display: none;  /* hidden until populated */
}
.sm-video:not(:empty) { display: block; }
.sm-video iframe,
.sm-video video {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* ============================================================
   BIO SIGN MODAL — bigger card, columnar paragraphs, no quote marks
   ============================================================ */

.sign-modal-card--bio {
  max-width: min(820px, 94vw);
  max-height: 90vh;
}

.sm-title {
  font-family: 'Fraunces', serif;
  font-weight: 400;
  font-size: clamp(1.85rem, 4vw, 2.75rem);
  line-height: 1.1;
  margin: 0 0 1.5rem;
  color: #1a1208;
  letter-spacing: -0.01em;
}

.sm-body {
  font-family: 'Inter', sans-serif;
  font-size: clamp(0.95rem, 1.4vw, 1.05rem);
  line-height: 1.65;
  color: #2a1f12;
}
.sm-body p {
  margin: 0 0 1.15em;
}
.sm-body p:last-child { margin-bottom: 0; }
.sm-body em {
  font-style: italic;
  color: #5a4126;
  font-weight: 500;
}

/* Bio sign — full-viewport invisible click target with a plain-text
   "CLICK THE SIGN" label anchored in the bottom-right corner. Lower
   z-index than the quote hotspots so that during the 0.24→0.38 overlap
   window, clicking a quote sign opens that quote (the discrete hotspot
   wins in its rect) while clicking anywhere else opens the bio. */
.sign-hotspot--bio {
  align-items: flex-end;
  justify-content: flex-end;
  padding: 0 5vw 4vh 0;
  z-index: 1;
}
/* Quote hotspots sit above the bio's fullscreen click area so their
   discrete click rects win during overlap. */
.forest-hotspots .sign-hotspot:not(.sign-hotspot--bio) {
  z-index: 2;
}
/* CLICK THE SIGN — the gentle pulse + small blinking caret makes the
   affordance read as "interactive" without being garish. The text-shadow
   stack keeps it legible over any video frame. */
.sign-hotspot--bio .sign-hotspot-pill {
  background: transparent;
  color: rgba(255, 248, 230, 1);
  border: 0;
  text-transform: uppercase;
  letter-spacing: 0.30em;
  /* Bigger than before — scales 1.7rem on phones up to ~3rem on big displays */
  font-size: clamp(1.7rem, 3vw, 3rem);
  font-weight: 700;
  padding: 0.4em 0.7em;
  margin-bottom: 0;
  border-radius: 4px;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  /* Continuous gentle pulse so the eye catches movement */
  animation: clickSignPulse 2.4s ease-in-out infinite;
  transition: color 0.2s, transform 0.2s;
  /* Subtle outline + glow that pulses with the keyframes below */
  text-shadow:
    0 0 1px rgba(255, 235, 180, 0.85),
    0 2px 4px rgba(0, 0, 0, 0.95),
    0 4px 24px rgba(0, 0, 0, 0.85),
    0 0 6px rgba(0, 0, 0, 0.7);
}
/* Tiny blinking attention mark after the text — universal "look here" cue */
.sign-hotspot--bio .sign-hotspot-pill::after {
  content: '!';
  display: inline-block;
  margin-left: 0.35em;
  animation: clickSignBlink 1.1s steps(1, end) infinite;
}
.sign-hotspot--bio:hover .sign-hotspot-pill {
  background: rgba(20, 14, 8, 0.55);
  color: #fff5cd;
  transform: translateY(-2px) scale(1.02);
  animation-play-state: paused;
}
@keyframes clickSignPulse {
  0%, 100% {
    opacity: 0.78;
    text-shadow:
      0 0 1px rgba(255, 235, 180, 0.65),
      0 2px 4px rgba(0, 0, 0, 0.95),
      0 4px 22px rgba(0, 0, 0, 0.85),
      0 0 6px rgba(0, 0, 0, 0.7);
  }
  50% {
    opacity: 1;
    text-shadow:
      0 0 2px rgba(255, 235, 180, 1),
      0 2px 4px rgba(0, 0, 0, 0.95),
      0 4px 28px rgba(255, 230, 170, 0.35),
      0 4px 22px rgba(0, 0, 0, 0.85),
      0 0 16px rgba(255, 230, 170, 0.5);
  }
}
@keyframes clickSignBlink {
  0%, 50% { opacity: 1; }
  51%, 100% { opacity: 0; }
}

.sign-modal-close {
  position: absolute;
  top: 1rem;
  right: 1.5rem;
  z-index: 2;
  background: rgba(20, 14, 8, 0.7);
  color: #efe7d8;
  border: 0;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  font-size: 1.75rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.2s, transform 0.2s;
}
.sign-modal-close:hover {
  background: rgba(20, 14, 8, 0.95);
  transform: scale(1.05);
}



/* ============================================================
   BICYCLE WORLD (horizontal pin-and-pan + bricks + bike)
   ============================================================ */

.world-section {
  position: relative;
  height: 500vh;
  background: var(--ink);
}
.world-pin {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  align-items: center;
  overflow: visible;
}
.world-track-clip {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
.world-bike-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  margin-top: -100vh;
  pointer-events: none;
  z-index: 6;
}
.world-track {
  display: flex;
  height: 100%;
  width: max-content;
  will-change: transform;
}
.scene {
  flex: 0 0 78vw;
  height: 100%;
  position: relative;
  display: flex;
  align-items: flex-end;
  padding: 56px;
  border-right: 1px dashed rgba(255,255,255,0.12);
}
.scene-num {
  position: absolute;
  top: 56px; left: 56px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.22em;
  color: var(--cream);
  opacity: 0.5;
  z-index: 2;
}
.scene-name {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 350;
  font-variation-settings: "opsz" 144, "SOFT" 100, "WONK" 1;
  font-size: clamp(60px, 12vw, 220px);
  letter-spacing: -0.04em;
  color: var(--cream);
  line-height: 0.9;
  position: relative;
  z-index: 1;
}
/* Scene atmospheres — match the time-of-day arc in the films array.
   01 Forest at night → deep moonlit greens
   02 Mountains at blue hour → cold cobalt sky into navy silhouette
   03 Coast at sunrise → peach/orange sky into cool reflective water
   04 Hilly Town at midday → warm pale sky into sunlit grass
   05 City at midday → bright urban sky into glass and concrete */
.scene--01 { background: linear-gradient(180deg, #14342a 0%, #0e2818 55%, #061a0e 100%); }
.scene--02 { background: linear-gradient(180deg, #3a567c 0%, #1f3358 55%, #0a1428 100%); }
.scene--03 { background: linear-gradient(180deg, #f6c5a8 0%, #ea8a5c 50%, #7a98b0 100%); }
.scene--04 { background: linear-gradient(180deg, #c8e0e6 0%, #a8c878 60%, #d4b878 100%); }
.scene--05 { background: linear-gradient(180deg, #b8d8ec 0%, #c8d2da 55%, #88909a 100%); }

/* ----- bricks (Mario ?-block) ----- */
.brick {
  position: absolute;
  width: 88px;
  height: 88px;
  background: linear-gradient(180deg, #f4b53c 0%, #d49328 100%);
  border: 4px solid #1a1614;
  font-family: var(--mono);
  font-size: 38px;
  font-weight: 800;
  color: #1a1614;
  cursor: none;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow:
    inset 5px 5px 0 #f8d885,
    inset -5px -5px 0 #b06d20,
    5px 5px 0 #1a1614;
  animation: brickBob 3.4s ease-in-out infinite;
  z-index: 4;
  line-height: 1;
}
.brick-mark { display: block; transform: translateY(-3px); pointer-events: none; }
.brick-rivets {
  position: absolute;
  inset: 6px;
  pointer-events: none;
  background:
    radial-gradient(circle at 4px 4px, #1a1614 0 2px, transparent 3px),
    radial-gradient(circle at calc(100% - 4px) 4px, #1a1614 0 2px, transparent 3px),
    radial-gradient(circle at 4px calc(100% - 4px), #1a1614 0 2px, transparent 3px),
    radial-gradient(circle at calc(100% - 4px) calc(100% - 4px), #1a1614 0 2px, transparent 3px);
}
@keyframes brickBob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}
.brick[data-exploded="1"] { visibility: hidden; }

.brick-piece {
  position: fixed;
  pointer-events: none;
  z-index: 9998;
  background: linear-gradient(180deg, #f4b53c 0%, #d49328 100%);
  border: 3px solid #1a1614;
  will-change: transform, opacity;
}
.brick-piece--tl { animation: pieceTL 1.0s cubic-bezier(.3,.7,.6,1) forwards; }
.brick-piece--tr { animation: pieceTR 1.0s cubic-bezier(.3,.7,.6,1) forwards; }
.brick-piece--bl { animation: pieceBL 1.0s cubic-bezier(.3,.7,.6,1) forwards; }
.brick-piece--br { animation: pieceBR 1.0s cubic-bezier(.3,.7,.6,1) forwards; }
@keyframes pieceTL {
  0%   { transform: translate(0,0)        rotate(0);       opacity: 1; }
  35%  { transform: translate(-50px,-70px) rotate(-200deg); opacity: 1; }
  100% { transform: translate(-110px,220px) rotate(-540deg); opacity: 0; }
}
@keyframes pieceTR {
  0%   { transform: translate(0,0)         rotate(0);      opacity: 1; }
  35%  { transform: translate(50px,-70px)  rotate(200deg);  opacity: 1; }
  100% { transform: translate(110px,220px) rotate(540deg);  opacity: 0; }
}
@keyframes pieceBL {
  0%   { transform: translate(0,0)         rotate(0);      opacity: 1; }
  35%  { transform: translate(-65px,-30px) rotate(-100deg); opacity: 1; }
  100% { transform: translate(-130px,250px) rotate(-360deg); opacity: 0; }
}
@keyframes pieceBR {
  0%   { transform: translate(0,0)         rotate(0);     opacity: 1; }
  35%  { transform: translate(65px,-30px)  rotate(100deg); opacity: 1; }
  100% { transform: translate(130px,250px) rotate(360deg); opacity: 0; }
}

.scene--01 .brick { top: 32%; left: 60%; }
.scene--02 .brick { top: 32%; left: 56%; }
.scene--03 .brick { top: 36%; left: 64%; }
.scene--04 .brick { top: 32%; left: 52%; }
.scene--05 .brick { top: 32%; left: 60%; }

.brick-popup {
  position: absolute;
  width: 280px;
  background: var(--cream);
  color: var(--ink);
  border: 4px solid var(--ink);
  padding: 22px;
  box-shadow: 8px 8px 0 var(--ink);
  opacity: 0;
  pointer-events: none;
  transform: translateY(0) scale(0.94);
  transition: opacity 0.35s ease, transform 0.35s cubic-bezier(.3,1.5,.5,1);
  z-index: 5;
}
.brick-popup.is-shown {
  opacity: 1;
  transform: translateY(-30px) scale(1);
}
.scene--01 .brick-popup { top: 18%; left: 38%; }
.scene--02 .brick-popup { top: 10%; left: 32%; }
.scene--03 .brick-popup { top: 22%; left: 42%; }
.scene--04 .brick-popup { top: 12%; left: 28%; }
.scene--05 .brick-popup { top: 18%; left: 38%; }

.popup-tag {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin: 0 0 12px;
  color: var(--rust);
  font-weight: 600;
}
.popup-title {
  font-family: var(--serif);
  font-weight: 380;
  font-variation-settings: "opsz" 96, "SOFT" 60, "WONK" 1;
  font-size: 28px;
  line-height: 1.05;
  margin: 0 0 10px;
  letter-spacing: -0.02em;
}
.popup-meta {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  margin: 0;
  opacity: 0.7;
}

/* ----- bike rider (placeholder) ----- */
.world-bike {
  position: absolute;
  bottom: 9%;
  left: 50%;
  width: 140px;
  transform: translateX(-50%);
  z-index: 3;
  pointer-events: none;
  filter: drop-shadow(0 8px 18px rgba(0,0,0,0.35));
}
.world-bike svg { width: 100%; height: auto; }
.world-bike.is-jumping {
  animation: bikeJump 0.75s cubic-bezier(.3,-0.4,.5,1.5) 1;
}
@keyframes bikeJump {
  0%   { transform: translateX(-50%) translateY(0)     rotate(0deg); }
  35%  { transform: translateX(calc(-50% + var(--aimX, 0px))) translateY(-44vh) rotate(-10deg); }
  55%  { transform: translateX(calc(-50% + var(--aimX, 0px))) translateY(-44vh) rotate(10deg); }
  100% { transform: translateX(-50%) translateY(0)     rotate(0deg); }
}

/* outer wrapper handles "drive off right" drift; inner bike handles jump */
.world-bike-pos {
  position: absolute;
  bottom: 8%;
  left: 50%;
  width: 0;
  height: 0;
  z-index: 5;
  transform: translateX(var(--exitX, 0px));
  will-change: transform;
}
.world-bike-pos .world-bike {
  position: absolute;
  bottom: 0;
  left: 0;
}
.bike-wheel { transform-box: fill-box; transform-origin: center; }

.world-progress {
  position: absolute;
  bottom: 28px; left: 56px; right: 56px;
  height: 1px;
  background: rgba(255,255,255,0.18);
  z-index: 5;
}
.world-progress-bar {
  height: 100%;
  background: var(--cream);
  width: 0%;
  will-change: width;
}
.world-caption {
  position: absolute;
  bottom: 56px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--cream);
  opacity: 0.6;
  margin: 0;
  z-index: 5;
  white-space: nowrap;
}


/* ============================================================
   big section links
   ============================================================ */

.lander-sections {
  padding: 140px 8vw 60px;
  background: var(--cream);
}
.sections-eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  margin: 0 0 56px;
  opacity: 0.55;
}
.big-link {
  display: grid;
  grid-template-columns: 80px 1fr 60px;
  align-items: baseline;
  gap: 28px;
  padding: 36px 0;
  border-top: 1px solid var(--hairline);
  transition: padding-left 0.45s cubic-bezier(.2,.8,.2,1), color 0.3s ease;
  position: relative;
}
.lander-sections > .big-link:last-of-type { border-bottom: 1px solid var(--hairline); }
.big-link:hover { padding-left: 22px; color: var(--rust); }

.bl-num {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.2em;
  opacity: 0.5;
  align-self: center;
}
.bl-label {
  font-family: var(--serif);
  font-weight: 350;
  font-variation-settings: "opsz" 144, "SOFT" 100, "WONK" 1;
  font-size: clamp(56px, 10vw, 156px);
  line-height: 0.95;
  letter-spacing: -0.03em;
  transition: font-style 0.3s ease;
}
.big-link:hover .bl-label { font-style: italic; }
.bl-arrow {
  font-family: var(--mono);
  font-size: 22px;
  text-align: right;
  align-self: center;
  transition: transform 0.4s cubic-bezier(.2,.8,.2,1);
}
.big-link:hover .bl-arrow { transform: translate(8px, -8px); }

.lander-footer {
  padding: 60px 8vw;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  background: var(--cream);
  border-top: 1px solid var(--hairline);
}


/* ============================================================
   90s arrow cursor (DOM-rendered, sized freely)
   ============================================================ */
.cursor-90s {
  position: fixed;
  top: 0; left: 0;
  width: 56px; height: 72px;
  pointer-events: none;
  z-index: 9999;
  transform: translate3d(-200px, -200px, 0);
  will-change: transform;
  opacity: 1;
}
.cursor-90s svg { width: 100%; height: 100%; image-rendering: pixelated; }
.cursor-90s.is-down svg { transform: scale(0.92); transform-origin: 4px 4px; }


/* ============================================================
   INNER PAGES
   ============================================================ */

.page-inner {
  background: var(--cream);
  color: var(--ink);
  cursor: none;
  overflow-x: hidden;
}
.page-inner a, .page-inner button { cursor: none; }

.page-header {
  padding: 160px 8vw 60px;
  max-width: 1500px;
  margin: 0 auto;
}
.page-eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  margin: 0 0 28px;
  opacity: 0.55;
}
.page-title {
  font-family: var(--serif);
  font-weight: 350;
  font-size: clamp(80px, 16vw, 240px);
  font-variation-settings: "opsz" 144, "SOFT" 100, "WONK" 1;
  line-height: 0.9;
  margin: 0 0 32px;
  letter-spacing: -0.03em;
}
.page-title em { color: var(--rust); font-style: italic; }
.page-lede {
  font-family: var(--serif);
  font-weight: 350;
  font-style: italic;
  font-size: clamp(20px, 2.4vw, 30px);
  line-height: 1.35;
  max-width: 32ch;
  margin: 0;
  opacity: 0.78;
}

.works {
  padding: 60px 8vw 120px;
  max-width: 1500px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 120px;
}
.work {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: 6vw;
  align-items: center;
}
.work:nth-child(even) { direction: rtl; }
.work:nth-child(even) > * { direction: ltr; }

.work-thumb {
  aspect-ratio: 4 / 3;
  background: var(--ink);
  position: relative;
  overflow: hidden;
  transition: transform 0.7s cubic-bezier(.2,.8,.2,1);
}
.work-thumb::after {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(circle at 30% 30%, rgba(255,255,255,0.08), transparent 60%);
}
.work:hover .work-thumb { transform: scale(1.025); }

.work-thumb--01 { background: linear-gradient(135deg, #2a2419 0%, #5e4a32 100%); }
.work-thumb--02 { background: linear-gradient(135deg, #d99a5b 0%, #b94a2a 100%); }
.work-thumb--03 { background: linear-gradient(135deg, #8aa9b8 0%, #2c4452 100%); }
.work-thumb--04 { background: linear-gradient(135deg, #5e5a4a 0%, #1c1812 100%); }
.work-thumb--05 { background: linear-gradient(135deg, #3a5e7a 0%, #0e1d2e 100%); }
.work-thumb--06 { background: linear-gradient(135deg, #4a5d3a 0%, #1a2412 100%); }
.work-thumb--07 { background: linear-gradient(135deg, #c9a273 0%, #6e4f2a 100%); }
.work-thumb--08 { background: linear-gradient(135deg, #b9b9c9 0%, #4a4a5a 100%); }
.work-thumb--09 { background: linear-gradient(135deg, #6e7a6c 0%, #1f2a1c 100%); }
.work-thumb--10 { background: linear-gradient(135deg, #e0c39a 0%, #7a5a3a 100%); }
.work-thumb--11 { background: linear-gradient(135deg, #c2b39a 0%, #5a4a32 100%); }
.work-thumb--12 { background: linear-gradient(135deg, #2a2a3a 0%, #0a0a14 100%); }

.work-tag {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  margin: 0 0 18px;
  opacity: 0.55;
}
.work-title {
  font-family: var(--serif);
  font-weight: 380;
  font-variation-settings: "opsz" 96, "SOFT" 60, "WONK" 1;
  font-size: clamp(34px, 5vw, 64px);
  line-height: 1.04;
  margin: 0 0 14px;
  letter-spacing: -0.02em;
}
.work-credit {
  font-family: var(--mono);
  font-size: 13px;
  margin: 0 0 18px;
  opacity: 0.7;
}
.work-blurb {
  font-family: var(--serif);
  font-weight: 350;
  font-size: 19px;
  line-height: 1.5;
  margin: 0;
  max-width: 38ch;
}

.page-footer {
  padding: 60px 8vw;
  max-width: 1500px;
  margin: 0 auto;
  font-family: var(--mono);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  border-top: 1px solid var(--hairline);
}

/* ============================================================
   EDITOR — DIG-DUG style page
   ============================================================ */

.page-editor-dig {
  background: #0a0604;
  color: var(--cream);
  cursor: none;
  overflow-x: hidden;
}
.page-editor-dig a, .page-editor-dig button { cursor: none; }

.dig-header {
  background: linear-gradient(180deg, #f3ebe0 0%, #e9dfd0 100%);
  color: var(--ink);
  padding: 160px 8vw 60px;
  position: relative;
  z-index: 2;
}
.dig-header .page-title em { color: var(--rust); }

.dig-world {
  position: relative;
  height: 320vh;
  overflow: hidden;
}

.dig-sky {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 11%;
  background: linear-gradient(180deg, #c97e54 0%, #d4a878 60%, #e2c89a 100%);
}

.dig-grass {
  position: absolute;
  top: 11%; left: 0; right: 0;
  height: 18px;
  background: linear-gradient(180deg, #4a6a3a 0%, #2a4520 100%);
  z-index: 3;
  border-bottom: 2px solid #1a2f10;
}
.dig-grass::after {
  content: "";
  position: absolute;
  bottom: 14px;
  left: 0; right: 0;
  height: 14px;
  background:
    radial-gradient(circle at 4%,  #2a4520 0 5px, transparent 6px),
    radial-gradient(circle at 11%, #2a4520 0 4px, transparent 5px),
    radial-gradient(circle at 18%, #2a4520 0 6px, transparent 7px),
    radial-gradient(circle at 26%, #2a4520 0 4px, transparent 5px),
    radial-gradient(circle at 34%, #2a4520 0 5px, transparent 6px),
    radial-gradient(circle at 42%, #2a4520 0 6px, transparent 7px),
    radial-gradient(circle at 50%, #2a4520 0 4px, transparent 5px),
    radial-gradient(circle at 58%, #2a4520 0 5px, transparent 6px),
    radial-gradient(circle at 66%, #2a4520 0 6px, transparent 7px),
    radial-gradient(circle at 74%, #2a4520 0 4px, transparent 5px),
    radial-gradient(circle at 82%, #2a4520 0 5px, transparent 6px),
    radial-gradient(circle at 90%, #2a4520 0 6px, transparent 7px),
    radial-gradient(circle at 96%, #2a4520 0 4px, transparent 5px);
}

.dig-underground {
  position: absolute;
  top: calc(11% + 18px);
  left: 0; right: 0;
  bottom: 0;
  background: linear-gradient(180deg,
    #6a4a2a 0%,
    #5a3a20 12%,
    #4a3018 28%,
    #3a2516 44%,
    #2a1810 60%,
    #1a0e08 78%,
    #050302 100%
  );
  overflow: hidden;
}
.dig-underground::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 12% 6%,  rgba(0,0,0,0.35) 0 7px, transparent 9px),
    radial-gradient(circle at 32% 11%, rgba(0,0,0,0.30) 0 5px, transparent 7px),
    radial-gradient(circle at 58% 8%,  rgba(0,0,0,0.35) 0 8px, transparent 10px),
    radial-gradient(circle at 82% 14%, rgba(0,0,0,0.30) 0 6px, transparent 8px),
    radial-gradient(circle at 22% 26%, rgba(0,0,0,0.35) 0 9px, transparent 11px),
    radial-gradient(circle at 70% 30%, rgba(0,0,0,0.30) 0 7px, transparent 9px),
    radial-gradient(circle at 44% 42%, rgba(0,0,0,0.30) 0 5px, transparent 7px),
    radial-gradient(circle at 10% 50%, rgba(0,0,0,0.35) 0 6px, transparent 8px),
    radial-gradient(circle at 88% 60%, rgba(0,0,0,0.30) 0 8px, transparent 10px),
    radial-gradient(circle at 36% 70%, rgba(0,0,0,0.40) 0 7px, transparent 9px),
    radial-gradient(circle at 78% 86%, rgba(0,0,0,0.50) 0 6px, transparent 8px),
    radial-gradient(circle at 18% 92%, rgba(0,0,0,0.45) 0 8px, transparent 10px);
  pointer-events: none;
}

.dirt-clump {
  position: absolute;
  width: 28px;
  height: 18px;
  border-radius: 14px;
  background: radial-gradient(ellipse at 30% 30%, #5a3a20 0%, #2a1810 80%);
  opacity: 0.65;
  pointer-events: none;
}

.dig-worm {
  position: absolute;
  top: 32%;
  left: 0;
  width: 540px;
  height: 160px;
  animation: wormCrawl 28s linear infinite;
  filter: drop-shadow(0 6px 14px rgba(0,0,0,0.7));
  z-index: 3;
  pointer-events: none;
}
.dig-worm svg { width: 100%; height: 100%; }
/* worm always moves the direction its eyes point — right→left, no bobbing */
@keyframes wormCrawl {
  from { transform: translate(110vw, 0); }
  to   { transform: translate(-560px, 0); }
}

.casket {
  position: absolute;
  width: 320px;
  height: 92px;
  display: flex;
  align-items: stretch;
  z-index: 4;
  filter: drop-shadow(0 8px 22px rgba(0,0,0,0.8));
  transition: transform 0.4s cubic-bezier(.2,.8,.2,1);
}
.casket:hover { transform: translateY(-4px); }

.casket-handle {
  width: 18px;
  background: linear-gradient(180deg, #2a1408 0%, #4a3018 50%, #2a1408 100%);
  border-top: 2px solid #1a0a04;
  border-bottom: 2px solid #1a0a04;
  position: relative;
  flex-shrink: 0;
}
.casket-handle::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 22px; height: 8px;
  background: #5a4030;
  border: 2px solid #1a0a04;
  border-radius: 2px;
}

.casket-body {
  flex: 1;
  background:
    linear-gradient(180deg, rgba(20,12,4,0.72) 0%, rgba(10,6,2,0.85) 100%),
    repeating-linear-gradient(90deg, transparent 0 6px, rgba(255,255,255,0.04) 6px 7px);
  border-top: 3px solid #5a4030;
  border-bottom: 3px solid #5a4030;
  padding: 12px 22px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  position: relative;
  backdrop-filter: blur(2px);
}
.casket-body::before, .casket-body::after {
  content: "";
  position: absolute;
  width: 8px; height: 8px;
  background: #5a4030;
  border: 2px solid #1a0a04;
  border-radius: 50%;
}
.casket-body::before { top: 6px; left: 8px; }
.casket-body::after { bottom: 6px; left: 8px; }

.casket-tag {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  margin: 0 0 6px;
  color: #d4a878;
  font-weight: 700;
}
.casket-title {
  font-family: var(--serif);
  font-weight: 380;
  font-variation-settings: "opsz" 96, "SOFT" 60, "WONK" 1;
  font-size: 22px;
  line-height: 1.05;
  margin: 0 0 4px;
  color: #f3ebe0;
  letter-spacing: -0.01em;
}
.casket-credit {
  font-family: var(--mono);
  font-size: 11px;
  margin: 0;
  color: rgba(243, 235, 224, 0.7);
  letter-spacing: 0.04em;
}

.casket--04 { filter: drop-shadow(0 8px 22px rgba(0,0,0,0.95)) brightness(0.85); }

.page-editor-dig .page-footer {
  border-top: 1px solid rgba(243,235,224,0.15);
  background: #050302;
  color: rgba(243,235,224,0.7);
}


@media (max-width: 760px) {
  .work { grid-template-columns: 1fr; gap: 28px; }
  .work:nth-child(even) { direction: ltr; }
  .nav { padding: 16px 20px; }
  .portal, .page-header { padding-left: 24px; padding-right: 24px; }
  .lander-sections, .lander-footer, .works, .page-footer { padding-left: 24px; padding-right: 24px; }
  .scene { flex-basis: 92vw; padding: 32px; }
  .scene-num { top: 32px; left: 32px; }
  .world-caption { bottom: 44px; }
  .big-link { grid-template-columns: 50px 1fr 40px; gap: 16px; padding: 24px 0; }
  .portal-cue { left: 24px; }
  .brick { width: 64px; height: 64px; font-size: 28px; }
  .brick-popup { width: 220px; padding: 16px; }
  .world-bike { width: 110px; }
  .portal-foot { width: 140px; height: 140px; }
  .portal-stage { gap: 12px; }
  .coffin { width: 130px; height: 220px; }
  .dig-tree-bike { transform: scale(0.7); transform-origin: top right; }
  .dig-sky-text .page-title { font-size: 80px !important; }
}


/* ============================================================
   PRODUCER PAGE — owns the bike-hits-bricks horizontal world
   ============================================================ */

.page-producer-ride { background: var(--ink); }
.page-producer-ride .world-section { height: 2000vh; }
.page-producer-ride .scene { flex: 0 0 100vw; }
.page-producer-ride .scene--night { flex-basis: 200vw; }
.page-producer-ride .scene--night .brick { left: 25%; }
.page-producer-ride .scene--night .brick-popup { left: 8%; top: 14%; }
.scene-car {
  position: absolute;
  bottom: 8%;
  left: 60%;
  width: 240px;
  pointer-events: none;
  z-index: 3;
  filter: drop-shadow(0 8px 18px rgba(0,0,0,0.5));
}
.scene-car > svg { width: 100%; height: auto; }

.page-producer-ride .page-header {
  padding: 140px 8vw 60px;
  background: var(--ink);
  color: var(--cream);
  position: relative;
  z-index: 2;
}
.page-producer-ride .page-title { color: var(--cream); }
.page-producer-ride .page-title em { color: var(--rust); }
.page-producer-ride .page-lede { color: rgba(243,235,224,0.78); }

.page-producer-ride .world-bike {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 160px;
  transform: translateX(-50%) rotate(var(--crashRot, 0deg));
  transition: transform 0.45s cubic-bezier(.3,.6,.4,1.2);
  filter: drop-shadow(0 8px 18px rgba(0,0,0,0.4));
  z-index: 3;
}
.page-producer-ride .world-bike svg { width: 100%; height: auto; }
.page-producer-ride .world-bike .bike-rider {
  transition: opacity 0.25s ease;
}
.page-producer-ride .world-bike.is-jumping {
  animation: bikeJump 0.75s cubic-bezier(.3,-0.4,.5,1.5) 1;
  transition: none;
}

/* GIF-driven bike: 14-frame horizontal sprite. Frame width 240, total 3360.
   Display width 240px keeps frames pixel-perfect. JS sets background-position
   based on accumulated scroll velocity so faster scroll = faster pedaling. */
.page-producer-ride .world-bike--sprite {
  width: 240px;
  height: 135px;
  background-image: url('../../assets/bike-sprite.png');
  background-repeat: no-repeat;
  background-size: 3360px 135px;
  background-position: 0 0;
  filter: drop-shadow(0 8px 16px rgba(0,0,0,0.3));
}

/* car drives in from the right and crashes into the bike */
.world-car {
  position: absolute;
  bottom: 8%;
  left: 0;
  width: 220px;
  pointer-events: none;
  z-index: 4;
  filter: drop-shadow(0 8px 18px rgba(0,0,0,0.45));
  will-change: transform;
}
.world-car svg { width: 100%; height: auto; }

/* launched stick figure (post-crash, flies through the air) */
.launched-figure {
  position: fixed;
  top: 0;
  left: 0;
  width: 80px;
  height: 110px;
  pointer-events: none;
  z-index: 7;
  opacity: 0;
  transition: opacity 0.3s ease;
  will-change: transform, opacity;
  filter: drop-shadow(0 6px 14px rgba(0,0,0,0.45));
}
.launched-figure svg { width: 100%; height: 100%; }


/* ============================================================
   STICK FIGURE CURSOR (director page)
   ============================================================ */

.stick-cursor {
  position: fixed;
  top: 0; left: 0;
  width: 80px;
  height: 110px;
  pointer-events: none;
  z-index: 9999;
  transform: translate3d(-200px, -200px, 0);
  will-change: transform;
  filter: drop-shadow(0 4px 10px rgba(0,0,0,0.35));
  perspective: 600px;
}
/* wind-streak Lottie wrapper — positioned just below the spinning figure.
   Contains either the fallback inline SVG or the Lottie player's SVG. */
.stick-cursor .stick-wind-lottie {
  position: absolute;
  top: 100%;
  left: 0;
  width: 80px;
  height: 70px;
  overflow: visible;
  pointer-events: none;
}
.stick-cursor .stick-wind-lottie > svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  display: block;
}
/* The cursor wrapper renders head-down (rotated 180° via JS), so anything
   inside it gets flipped. When a real Lottie is loaded, counter-rotate it
   so the AE comp plays in its natural orientation on screen.
   The inline-SVG fallback keeps the original (rotated) orientation since
   its CSS animation was designed knowing about the parent rotation. */
.stick-cursor .stick-wind-lottie[data-lottie-loaded="1"] {
  transform: rotate(180deg);
  transform-origin: center;
}
.stick-cursor .wind-line {
  animation: windPulse 0.45s linear infinite;
  transform-box: fill-box;
  transform-origin: center;
}
.stick-cursor .wind-line--1 { animation-delay: 0s; }
.stick-cursor .wind-line--2 { animation-delay: 0.10s; }
.stick-cursor .wind-line--3 { animation-delay: 0.20s; }
.stick-cursor .wind-line--4 { animation-delay: 0.30s; }
.stick-cursor .wind-line--5 { animation-delay: 0.40s; }
@keyframes windPulse {
  0%   { opacity: 0; transform: translateY(-8px); }
  35%  { opacity: 1; transform: translateY(0); }
  70%  { opacity: 1; transform: translateY(8px); }
  100% { opacity: 0; transform: translateY(16px); }
}

/* Cursor figure is now a 10-frame photo sprite (assets/you-sprite.png).
   Each frame is 200x275 in the source; we display the cursor at 80x110,
   so the full sprite scales to 800x110. The steps(10) animation ticks
   the background-position through 10 discrete frames per loop, creating
   the illusion of you rotating in 3D. */
.stick-cursor .stick-spin {
  width: 100%;
  height: 100%;
  background-image: url('../../assets/you-sprite.png');
  background-size: 800px 110px;
  background-repeat: no-repeat;
  background-position: 0 0;
  animation: spriteRotate 0.9s steps(10) infinite;
}
.stick-cursor svg { width: 100%; height: 100%; overflow: visible; }
@keyframes spriteRotate {
  from { background-position: 0 0; }
  to   { background-position: -800px 0; }
}


/* ============================================================
   SHOVEL CURSOR (editor page)
   ============================================================ */

.shovel-cursor {
  position: fixed;
  top: 0; left: 0;
  width: 50px;
  height: 90px;
  pointer-events: none;
  z-index: 9999;
  transform: translate3d(-200px, -200px, 0);
  will-change: transform;
  filter: drop-shadow(0 6px 12px rgba(0,0,0,0.55));
}
.shovel-cursor svg { width: 100%; height: 100%; }


/* ============================================================
   SKY-BACKGROUND PAGES (director — and reused on editor sky)
   ============================================================ */

.page-sky {
  background: linear-gradient(180deg, #cfe6f0 0%, #a8cfe2 50%, #d4e6ee 100%);
  cursor: none;
  overflow-x: hidden;
}
.page-sky a, .page-sky button { cursor: none; }

.sky-bg {
  position: fixed;
  inset: 0;
  background: linear-gradient(180deg, #cfe6f0 0%, #a8cfe2 50%, #d4e6ee 100%);
  z-index: -2;
}

.sky-clouds, .sky-birds {
  position: fixed;
  top: 0; left: 0; right: 0;
  /* Constrain to top half of viewport — clouds + birds drift here only,
     never reach the lower-half building/concrete area. */
  height: 50vh;
  pointer-events: none;
  z-index: -1;
  overflow: hidden;
}

.sky-cloud {
  position: absolute;
  left: -260px;
  width: 220px;
  height: 110px;
  animation-name: cloudDrift;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  filter: drop-shadow(0 6px 12px rgba(60, 80, 120, 0.18));
}
.sky-cloud svg { width: 100%; height: 100%; }

/* Puffy PNG clouds (production page) — bigger and let the source image's
   aspect ratio flow naturally rather than forcing 220x110 */
.sky-cloud--puffy {
  width: 360px;
  height: auto;
}
.sky-cloud--puffy img {
  width: 100%;
  height: auto;
  display: block;
  user-select: none;
  -webkit-user-drag: none;
}
@keyframes cloudDrift {
  from { transform: translateX(0) scale(1); }
  to   { transform: translateX(calc(100vw + 260px)) scale(1); }
}

.sky-bird {
  position: absolute;
  left: -80px;
  width: 60px;
  height: 28px;
  animation-name: birdGlide;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
.sky-bird svg { width: 100%; height: 100%; }
@keyframes birdGlide {
  from { transform: translate(0, 0); }
  50%  { transform: translate(50vw, -22px); }
  to   { transform: translate(calc(100vw + 80px), 6px); }
}

.page-director .page-header,
.page-director .works,
.page-director .page-footer {
  position: relative;
  z-index: 1;
}


/* ============================================================
   EDITOR DIG — sky-to-bottom, sky text, tree+bike, hex coffins
   ============================================================ */

.page-editor-dig {
  background: linear-gradient(180deg, #cfe6f0 0%, #a8cfe2 18%, #d4e6ee 24%, #4a6a3a 24.6%, #6a4a2a 25.2%, #050302 100%);
  background-attachment: fixed;
  color: var(--cream);
  cursor: none;
  overflow-x: hidden;
}
.page-editor-dig a, .page-editor-dig button { cursor: none; }

.dig-world {
  position: relative;
  height: 380vh;
  overflow: hidden;
}

.dig-sky {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 75vh;
  background: linear-gradient(180deg, #cfe6f0 0%, #a8cfe2 70%, #d4e6ee 100%);
  z-index: 1;
}

.dig-sky-text-wrap {
  /* the wrapper is just a container; the text inside is fixed */
  position: absolute;
  top: 0;
  left: 0; right: 0;
  height: 100vh;
  pointer-events: none;
  z-index: 2;
}
.dig-sky-text {
  /* fixed in viewport — stays put as the user scrolls; the dirt
     (z-index higher) rises up and visually covers it */
  position: fixed;
  top: 14vh;
  left: 0; right: 0;
  text-align: center;
  padding: 0 8vw;
  color: var(--ink);
  pointer-events: none;
  z-index: 2;
}
.dig-sky-text .page-lede {
  max-width: 56ch;
  margin: 24px auto 0;
}
/* dirt + grass + tree all sit ABOVE the sky text so they cover it */
.dig-grass { z-index: 7; }
.dig-tree-bike { z-index: 6; }
.dig-underground { z-index: 5; }
.dig-sky-text .page-eyebrow { color: rgba(26,22,20,0.55); }
.dig-sky-text .page-title {
  font-family: var(--serif);
  font-weight: 350;
  font-variation-settings: "opsz" 144, "SOFT" 100, "WONK" 1;
  font-size: clamp(80px, 14vw, 200px);
  line-height: 0.9;
  margin: 8px 0 16px;
  letter-spacing: -0.03em;
  color: var(--ink);
}
.dig-sky-text .page-lede {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(15px, 1.6vw, 18px);
  line-height: 1.4;
  max-width: 36ch;
  margin: 0 auto;
  color: rgba(26,22,20,0.75);
}

.dig-clouds {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 75vh;
  pointer-events: none;
  z-index: 3;
  overflow: hidden;
}

.dig-tree-bike {
  position: absolute;
  top: calc(75vh - 440px);   /* anchored just above the grass */
  right: 3%;
  width: 300px;
  height: 440px;
  z-index: 8;
  pointer-events: none;
  filter: drop-shadow(0 14px 24px rgba(0, 0, 0, 0.35));
}
.dig-tree { position: absolute; bottom: 0; left: 0; width: 100%; height: 100%; z-index: 1; }

/* ============================================================
   POSTPRODUCTION — deep-background scenery (hills + forest)
   Each layer parallaxes on scroll via [data-parallax="<speed>"].
   Lower speed = appears further back (lags behind scroll more).
   ============================================================ */

.dig-hills {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 75vh;             /* lives only in the sky portion */
  pointer-events: none;
  overflow: hidden;
  z-index: 2;
}
.dig-hills .hill {
  position: absolute;
  left: 50%;
  width: 130vw;             /* wider than viewport so parallax doesn't expose edges */
  height: auto;
  transform: translateX(-50%) translateY(var(--py, 0));
  will-change: transform;
}
.dig-hills .hill-back  { bottom: -2vh; opacity: 0.55; filter: blur(0.6px) brightness(1.05); z-index: 1; }
.dig-hills .hill-mid   { bottom: -3vh; opacity: 0.80; filter: brightness(0.95);              z-index: 2; }
.dig-hills .hill-front { bottom: -4vh; opacity: 0.95; filter: brightness(0.88);              z-index: 3; }

.dig-forest {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 75vh;
  pointer-events: none;
  overflow: visible;
  z-index: 3;               /* BEHIND .dig-underground (z:5) so dirt covers
                               trees as they scroll past the horizon */
}
.dig-forest .bg-tree {
  position: absolute;
  bottom: -60px;            /* roots tucked into the ground — grass + dirt
                               strip covers the base so no roots are visible */
  width: auto;
  height: auto;
  transform: translateY(var(--py, 0));
  will-change: transform;
  filter: drop-shadow(0 12px 18px rgba(0, 0, 0, 0.35));
}
/* tree-tall-1.png and tree-tall-2.png have visible spreading roots painted
   into the bottom of the PNG. For trees on the back hill (e.g. --far-right)
   there's no dirt strip to bury them in, so simply pushing the tree down
   doesn't help. Instead, crop the root portion out of the rendered image so
   the trunk ends cleanly at the grass and no roots show regardless of where
   the tree is positioned. */
.dig-forest .bg-tree[src$="tree-tall-1.png"],
.dig-forest .bg-tree[src$="tree-tall-2.png"] {
  clip-path: inset(0 0 15% 0);
}
/* mirrored tree keeps its flip + still receives parallax */
.dig-forest .bg-tree--mirror,
.dig-forest .bg-tree--far-right { transform: scaleX(-1) translateY(var(--py, 0)); }

/* Forest tree placements — flanking the gravestone, varying scales for depth.
   Three depth bands: distant (~150-180px wide, dimmer), mid (~200-240px),
   near (~260-300px, fully opaque). Mix scales + flip mirroring for variety. */

/* DISTANT layer (sit furthest back, smaller, faded) */
.dig-forest .bg-tree--far-left   { left: 1%;   width: 200px; opacity: 0.78; z-index: 1; }
.dig-forest .bg-tree--far-right  { right: 1%;  width: 200px; opacity: 0.78; z-index: 1; }
.dig-forest .bg-tree--far-l2     { left: 9%;   width: 160px; opacity: 0.70; z-index: 1; }
.dig-forest .bg-tree--far-r2     { right: 9%;  width: 160px; opacity: 0.70; z-index: 1; }
.dig-forest .bg-tree--far-deep-l { left: 38%;  width: 140px; opacity: 0.62; z-index: 1; bottom: -40px; }
.dig-forest .bg-tree--far-deep-r { right: 38%; width: 140px; opacity: 0.62; z-index: 1; bottom: -40px; }

/* MID layer */
.dig-forest .bg-tree--mid-left   { left: 16%;  width: 220px; opacity: 0.90; z-index: 2; }
.dig-forest .bg-tree--mid-right  { right: 16%; width: 220px; opacity: 0.90; z-index: 2; }
.dig-forest .bg-tree--mid-l2     { left: 24%;  width: 190px; opacity: 0.85; z-index: 2; }
.dig-forest .bg-tree--mid-r2     { right: 24%; width: 190px; opacity: 0.85; z-index: 2; }

/* NEAR layer (closest, largest, fully opaque) */
.dig-forest .bg-tree--near-left  { left: 30%;  width: 280px; opacity: 1.0;  z-index: 3; }
.dig-forest .bg-tree--near-right { right: 30%; width: 260px; opacity: 1.0;  z-index: 3; }

/* fallen tree as foreground decoration — slightly more rooted */
.dig-forest .bg-tree--fallen     { left: 44%;  width: 260px; opacity: 0.95; z-index: 4; bottom: -30px; }

/* On narrow screens, simplify: hide the smaller mid trees so the
   scene doesn't get crowded */
@media (max-width: 760px) {
  .dig-forest .bg-tree--mid-left,
  .dig-forest .bg-tree--mid-right,
  .dig-forest .bg-tree--fallen { display: none; }
  .dig-forest .bg-tree--far-left,
  .dig-forest .bg-tree--far-right { width: 160px; }
  .dig-tree-bike { width: 200px; height: 293px; top: calc(75vh - 293px); }
}
.dig-gravestone-center {
  position: absolute;
  top: calc(75vh - 90px);
  left: 50%;
  transform: translateX(-50%);
  width: 72px;
  height: 90px;
  z-index: 6;
  pointer-events: none;
}

.dig-grass {
  position: absolute;
  top: 75vh;
  left: 0; right: 0;
  height: 32px;
  z-index: 6;
  background: linear-gradient(180deg, #4a6a3a 0%, #2a4520 100%);
  border-bottom: 2px solid #1a2f10;
}
.dig-grass::after {
  content: "";
  position: absolute;
  bottom: 22px;
  left: 0; right: 0;
  height: 16px;
  background:
    radial-gradient(circle at 4%,  #2a4520 0 5px, transparent 6px),
    radial-gradient(circle at 11%, #2a4520 0 4px, transparent 5px),
    radial-gradient(circle at 18%, #2a4520 0 6px, transparent 7px),
    radial-gradient(circle at 26%, #2a4520 0 4px, transparent 5px),
    radial-gradient(circle at 34%, #2a4520 0 5px, transparent 6px),
    radial-gradient(circle at 42%, #2a4520 0 6px, transparent 7px),
    radial-gradient(circle at 50%, #2a4520 0 4px, transparent 5px),
    radial-gradient(circle at 58%, #2a4520 0 5px, transparent 6px),
    radial-gradient(circle at 66%, #2a4520 0 6px, transparent 7px),
    radial-gradient(circle at 74%, #2a4520 0 4px, transparent 5px),
    radial-gradient(circle at 82%, #2a4520 0 5px, transparent 6px),
    radial-gradient(circle at 90%, #2a4520 0 6px, transparent 7px),
    radial-gradient(circle at 96%, #2a4520 0 4px, transparent 5px);
}
.dig-grass-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 1;
}

.dig-underground {
  position: absolute;
  top: calc(75vh + 32px);
  left: 0; right: 0;
  bottom: 0;
  background: linear-gradient(180deg,
    #6a4a2a 0%,
    #5a3a20 12%,
    #4a3018 28%,
    #3a2516 44%,
    #2a1810 60%,
    #1a0e08 78%,
    #050302 100%
  );
  overflow: hidden;
  z-index: 4;
}

/* hexagonal coffins, top-down view */
.coffin {
  position: absolute;
  width: 200px;
  height: 320px;
  transform: rotate(var(--rot, 0deg));
  z-index: 5;
}
.coffin-shape {
  width: 100%;
  height: 100%;
  position: absolute;
  inset: 0;
  filter: drop-shadow(0 10px 22px rgba(0,0,0,0.7));
}
.coffin-content {
  position: absolute;
  top: 28%;
  left: 14%;
  right: 14%;
  bottom: 28%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: center;
  font-family: var(--mono);
  z-index: 2;
}
.coffin-content--bottom {
  top: auto;
  bottom: 14%;
}
.coffin-tag {
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #d4a878;
  margin: 0 0 6px;
  font-weight: 700;
}
.coffin-title {
  font-family: var(--serif);
  font-weight: 380;
  font-style: italic;
  font-size: 17px;
  line-height: 1.05;
  margin: 0 0 6px;
  color: #f3ebe0;
  letter-spacing: -0.01em;
}
.coffin-credit {
  font-size: 9.5px;
  margin: 0;
  color: rgba(243,235,224,0.65);
  letter-spacing: 0.04em;
  font-family: var(--mono);
}

.coffin-skeleton {
  position: absolute;
  inset: 12% 16% 12% 16%;
  width: auto !important;
  height: auto !important;
  z-index: 3;
}
.skull-eye { transition: fill 0.25s ease; }

.coffin-charlie {
  position: absolute;
  inset: 8% 18% 8% 18%;
  z-index: 3;
}
.charlie-fig {
  width: 100%;
  height: 100%;
  display: block;
}
.charlie-scratches {
  position: absolute;
  top: 8px;
  left: 18%;
  right: 18%;
  height: 36px;
  opacity: 0;
  transition: opacity 0.4s ease;
  z-index: 4;
}

.coffin--charlie .coffin-content {
  top: auto;
  bottom: -38px;
  left: 50%;
  transform: translateX(-50%);
  width: 200%;
  display: block;
}
.coffin--charlie .coffin-tag,
.coffin--charlie .coffin-title {
  text-align: center;
  color: var(--cream);
}


/* ============================================================
   HELL — fiery wasteland with smashed Charlie coffin + menu
   ============================================================ */

.hell {
  position: relative;
  height: 110vh;
  background: radial-gradient(ellipse at 50% 0%, #c41818 0%, #6a0606 25%, #2a0a08 60%, #0a0202 100%),
              linear-gradient(180deg, #c41818 0%, #5a0606 30%, #1a0a04 100%);
  background-blend-mode: screen, normal;
  overflow: visible;
  border-top: 4px solid #1a0a04;
  color: #f3ebe0;
  z-index: 10;
}

/* Charlie coffin straddles dirt/hell boundary */
.hell .coffin--charlie {
  position: absolute;
  top: -110px;
  right: 22%;
  width: 200px;
  height: 200px;
  z-index: 12;
  filter: drop-shadow(0 10px 26px rgba(0,0,0,0.85));
  transform: rotate(-2deg);
}
.hell .coffin--charlie .coffin-shape--smashed {
  position: absolute;
  top: 0; left: 0;
  width: 100%;
  height: 100%;
}
.hell .coffin--charlie .charlie-fig {
  position: absolute;
  top: 14%;
  left: 16%;
  width: 68%;   /* matches the inner width of the hexagonal coffin */
  height: auto; /* preserve the figure's proportions (80×110) */
  overflow: visible;
}
/* let the inlined charlie SVG overflow its viewBox so the kicking legs
   stick out below — the [data-art-fit="aspect"] attribute already keeps
   width:100% / height:auto, this just adds visible overflow */
.hell .coffin--charlie .charlie-fig > svg { overflow: visible; }

.hell-fire {
  position: absolute;
  bottom: 0;
  left: 0; right: 0;
  height: 60%;
  pointer-events: none;
}
.flame {
  position: absolute;
  bottom: 0;
  width: 80px;
  height: 200px;
  background: linear-gradient(180deg,
    rgba(255, 220, 80, 0) 0%,
    rgba(255, 180, 40, 0.6) 30%,
    #c41818 70%,
    #6a0606 100%);
  border-radius: 50% 50% 30% 30% / 70% 70% 30% 30%;
  filter: blur(6px);
  animation: flicker 1.6s ease-in-out infinite;
  transform-origin: bottom center;
}
.flame--1 { left: 4%;  height: 240px; animation-delay: 0s;   }
.flame--2 { left: 14%; height: 180px; animation-delay: 0.4s; }
.flame--3 { left: 26%; height: 280px; animation-delay: 0.2s; }
.flame--4 { left: 38%; height: 220px; animation-delay: 0.6s; }
.flame--5 { left: 52%; height: 260px; animation-delay: 0.1s; }
.flame--6 { left: 64%; height: 200px; animation-delay: 0.5s; }
.flame--7 { left: 78%; height: 240px; animation-delay: 0.3s; }
.flame--8 { left: 90%; height: 180px; animation-delay: 0.7s; }
@keyframes flicker {
  0%, 100% { transform: scaleY(1)    scaleX(1); opacity: 0.85; }
  25%      { transform: scaleY(1.15) scaleX(0.92); opacity: 1; }
  50%      { transform: scaleY(0.92) scaleX(1.08); opacity: 0.7; }
  75%      { transform: scaleY(1.08) scaleX(0.96); opacity: 0.95; }
}

.hell-smoke {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.4;
}
.hell-smoke span {
  position: absolute;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(40, 20, 16, 0.55) 0%, transparent 70%);
  filter: blur(20px);
  animation: smokeRise 12s linear infinite;
}
.hell-smoke span:nth-child(1) { left: 10%; bottom: 10%; animation-delay: 0s;    }
.hell-smoke span:nth-child(2) { left: 35%; bottom: 5%;  animation-delay: -3s;   }
.hell-smoke span:nth-child(3) { left: 60%; bottom: 15%; animation-delay: -6s;   }
.hell-smoke span:nth-child(4) { left: 85%; bottom: 8%;  animation-delay: -9s;   }
@keyframes smokeRise {
  from { transform: translateY(0)     scale(1);   opacity: 0; }
  20%  { opacity: 0.6; }
  to   { transform: translateY(-80vh) scale(2.5); opacity: 0; }
}

.hell-menu {
  position: relative;
  z-index: 5;
  padding: 60px 8vw;
  max-width: 1100px;
  margin: 0 auto;
}
.hell-eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  margin: 0 0 32px;
  opacity: 0.85;
  color: #f4a26b;
}
.hell .big-link {
  display: grid;
  grid-template-columns: 64px 1fr 50px;
  gap: 22px;
  align-items: baseline;
  padding: 26px 0;
  border-top: 1px solid rgba(243, 235, 224, 0.25);
  color: #f3ebe0;
  transition: padding-left 0.4s ease, color 0.3s ease;
  position: relative;
}
.hell .big-link:last-of-type { border-bottom: 1px solid rgba(243, 235, 224, 0.25); }
.hell .big-link:hover { padding-left: 18px; color: #f4a26b; }
.hell .bl-num {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.2em;
  opacity: 0.6;
  align-self: center;
}
.hell .bl-label {
  font-family: var(--serif);
  font-weight: 350;
  font-style: italic;
  font-variation-settings: "opsz" 144, "SOFT" 100, "WONK" 1;
  font-size: clamp(48px, 8vw, 110px);
  line-height: 0.95;
  letter-spacing: -0.03em;
}
.hell .bl-arrow {
  font-family: var(--mono);
  font-size: 22px;
  text-align: right;
  align-self: center;
  transition: transform 0.4s ease;
}
.hell .big-link:hover .bl-arrow { transform: translate(8px, -8px); }

.page-footer--hell {
  background: #050202;
  color: rgba(243, 235, 224, 0.55);
  border-top: 1px solid rgba(243, 235, 224, 0.18);
}


/* ============================================================
   PORTAL BLOOD — splat pool (revised: pool, not vertical streams)
   ============================================================ */

.portal-blood {
  position: absolute;
  bottom: -8px;
  /* Centered directly under "Hane." — the portal-name-wrap is itself
     centered by the parent stage, so `left: 50%` is its center, which
     is the page center. translateX(-50%) pulls blood back by half its
     own width. */
  left: 50%;
  width: 350px;
  transform: translateX(-50%);
  pointer-events: none;
  z-index: 5;
  height: 0;
  overflow: visible;
}
.portal-blood-pool {
  position: absolute;
  bottom: -8px;
  left: -4%;
  right: -4%;
  height: 0;
  background: radial-gradient(ellipse at 50% 100%, #c41818 0%, #8a0808 50%, #5a0404 80%, transparent 100%);
  border-radius: 50% 50% 50% 50% / 60% 60% 100% 100%;
  filter: blur(2px);
  transition: height 0.7s cubic-bezier(.4,0,.4,1);
}
.portal-blood.is-bleeding .portal-blood-pool { height: 80px; }

.portal-blood-splat {
  position: absolute;
  bottom: -16px;
  left: 0;
  right: 0;
  height: 0;
  width: 100%;
  pointer-events: none;
  transition: height 0.8s cubic-bezier(.4,0,.4,1), opacity 0.5s ease;
  opacity: 0;
}
.portal-blood-splat svg {
  width: 100%;
  height: 100%;
  display: block;
}
.portal-blood.is-bleeding .portal-blood-splat {
  height: 70px;
  opacity: 1;
}

.portal-blood-drip {
  position: absolute;
  top: 0;
  width: 14px;
  height: 0;
  background: linear-gradient(180deg, transparent 0%, #c41818 12%, #8a0808 80%, #5a0404 100%);
  border-radius: 50% 50% 90% 90% / 0 0 80% 80%;
  filter: blur(0.5px);
  transition: height 0.8s cubic-bezier(.4,0,.4,1);
  transform: translateX(-50%);
}
.portal-blood-drip::after {
  content: "";
  position: absolute;
  bottom: -10px;
  left: 50%;
  transform: translateX(-50%) scale(0);
  width: 22px;
  height: 22px;
  background: radial-gradient(circle at 40% 35%, #c41818 0%, #6a0606 100%);
  border-radius: 50% 50% 60% 60% / 60% 60% 40% 40%;
  filter: blur(0.5px);
  transition: transform 0.4s cubic-bezier(.5,1.5,.5,1);
  transition-delay: inherit;
}
.portal-blood.is-bleeding .portal-blood-drip { height: 70px; }
.portal-blood.is-bleeding .portal-blood-drip::after { transform: translateX(-50%) scale(1); }


/* ============================================================
   POST-RIDE MENU (producer page below the world section)
   DIRECTOR concrete floor + smush
   ============================================================ */

.post-ride-menu, .post-floor-menu {
  position: relative;
  z-index: 4;
  padding: 100px 8vw 60px;
  background: var(--cream);
  color: var(--ink);
}
.post-ride-menu .sections-eyebrow,
.post-floor-menu .sections-eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  margin: 0 0 56px;
  opacity: 0.55;
}
.post-ride-menu .big-link,
.post-floor-menu .big-link {
  display: grid;
  grid-template-columns: 80px 1fr 60px;
  gap: 28px;
  align-items: baseline;
  padding: 36px 0;
  border-top: 1px solid var(--hairline);
  transition: padding-left 0.45s cubic-bezier(.2,.8,.2,1), color 0.3s ease;
  color: inherit;
}
.post-ride-menu > .big-link:last-of-type,
.post-floor-menu > .big-link:last-of-type { border-bottom: 1px solid var(--hairline); }
.post-ride-menu .big-link:hover,
.post-floor-menu .big-link:hover { padding-left: 22px; color: var(--rust); }
.post-ride-menu .bl-num,
.post-floor-menu .bl-num {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.2em;
  opacity: 0.5;
  align-self: center;
}
.post-ride-menu .bl-label,
.post-floor-menu .bl-label {
  font-family: var(--serif);
  font-weight: 350;
  font-variation-settings: "opsz" 144, "SOFT" 100, "WONK" 1;
  font-size: clamp(56px, 10vw, 156px);
  line-height: 0.95;
  letter-spacing: -0.03em;
}
.post-ride-menu .big-link:hover .bl-label,
.post-floor-menu .big-link:hover .bl-label { font-style: italic; }
.post-ride-menu .bl-arrow,
.post-floor-menu .bl-arrow {
  font-family: var(--mono);
  font-size: 22px;
  text-align: right;
  align-self: center;
  transition: transform 0.4s ease;
}
.post-ride-menu .big-link:hover .bl-arrow,
.post-floor-menu .big-link:hover .bl-arrow { transform: translate(8px, -8px); }

/* Empty stretch of sky between the last work and the concrete strip,
   so buildings only ever appear AFTER the works content. */
.director-sky-buffer {
  height: 50vh;
  pointer-events: none;
}

/* ============================================================
   CITY SKYLINE — fixed-position layer with overflow:hidden whose
   bottom edge is anchored to the concrete strip's top in the
   viewport. Buildings can translate freely INSIDE — anything that
   moves past the clip bottom is hidden by the concrete line.
   Vertical parallax: closer buildings translate more than far.
   Sits at z-index: -1 so non-positioned text/works stack above.
   ============================================================ */
.director-skyline {
  position: fixed;
  top: 0; left: 0; right: 0;
  /* SAFE default before JS runs: park the skyline far below the viewport
     so any momentary flicker before the first updateSkyline() call shows
     nothing. JS will override `bottom` per frame once it's running. */
  bottom: -200vh;
  overflow: hidden;
  z-index: -1;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.12s ease;   /* faster fade-in so fast scrolls catch it */
}
.director-skyline.is-visible { opacity: 1; }

.director-skyline .building {
  position: absolute;
  bottom: -120px;       /* feet pushed WELL below clip bottom — guaranteed
                            hidden behind concrete at rest AND when sinking */
  height: auto;
  /* `--py` is the vertical parallax offset set by JS (positive = down).
     `left: X%` is the building's CENTER thanks to translateX(-50%). */
  transform: translateX(-50%) translateY(var(--py, 0px));
  transform-origin: bottom center;
  will-change: transform;
  user-select: none;
  -webkit-user-drag: none;
  filter: drop-shadow(0 8px 16px rgba(0, 0, 0, 0.3));
}
.director-skyline .building.is-flipped {
  transform: translateX(-50%) scaleX(-1) translateY(var(--py, 0px));
}
/* Buildings are FULLY OPAQUE in their natural color. Depth comes from
   SIZE (smaller = far), the FOG layers between bands, the SLIGHT blur
   on the far band (out-of-focus distance), and SHADOW depth on the near
   band. No brightness/contrast tinting — buildings stay their real color. */
.director-skyline .building--far  {
  z-index: 1;
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.15)) blur(0.5px);
}
.director-skyline .building--mid  {
  z-index: 3;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.22));
}
.director-skyline .building--near {
  z-index: 5;
  filter: drop-shadow(0 14px 22px rgba(0, 0, 0, 0.4));
}

/* Atmospheric fog layers behind the front buildings — pure CSS
   gradients (no images, no blend modes). Each fog div sits between
   bands and softly hazes everything behind it, fading from denser at
   the bottom horizon to fully transparent up high. */
.director-skyline .fog-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    0deg,
    rgba(225, 240, 248, 0.55) 0%,
    rgba(225, 240, 248, 0.30) 30%,
    rgba(225, 240, 248, 0.10) 65%,
    rgba(225, 240, 248, 0)    100%
  );
}
.director-skyline .fog-layer--far { z-index: 2; opacity: 0.85; }
.director-skyline .fog-layer--mid { z-index: 4; opacity: 0.55; }

.director-concrete {
  position: relative;
  height: 12px;
  background: linear-gradient(180deg, #8a8884 0%, #6a6864 50%, #5a5854 100%);
  border-top: 4px solid #5a5854;
  border-bottom: 4px solid #4a4844;
  z-index: 2;
  overflow: visible;
}
.concrete-cracks { display: none; }
.smushed-body {
  position: fixed;
  width: 100px;
  height: 38px;
  display: none;
  pointer-events: none;
  z-index: 9998;
  transform: translate(-50%, -100%);
}
.smushed-body.is-shown { display: block; }
.smushed-body svg { width: 100%; height: 100%; overflow: visible; }
.post-floor-menu {
  background: linear-gradient(180deg, #6a6864 0%, #5a5854 50%, #4a4844 100%);
  color: #f3ebe0;
  position: relative;
}
.post-floor-menu .sections-eyebrow { color: rgba(243,235,224,0.65); }
.post-floor-menu .big-link {
  color: #f3ebe0;
  border-top-color: rgba(243,235,224,0.2);
}
.post-floor-menu > .big-link:last-of-type {
  border-bottom-color: rgba(243,235,224,0.2);
}
.post-floor-menu .big-link:hover { color: #d4a878; }
.page-director .page-footer {
  background: #4a4844;
  color: rgba(243,235,224,0.5);
  border-top-color: rgba(243,235,224,0.18);
  /* page-footer normally has max-width:1500px which lets the body's
     sky background bleed in on wide screens. On the director page we
     want the concrete-grey to extend edge-to-edge instead. */
  max-width: none;
}


/* ============================================================
   STICK CURSOR — face-pointing-right horizontal pose tweaks
   ============================================================ */
.stick-cursor.is-falling { /* upside down — feet up, head down */ }
.stick-cursor.is-stuck { display: none; }


/* ============================================================
   DIRECTOR — sky overlay throughout the page (not just top)
   ============================================================ */
.page-director .sky-clouds,
.page-director .sky-birds {
  position: absolute !important;
  top: 0;
  height: 100%;
}
.page-director {
  position: relative;
  background: linear-gradient(180deg, #cfe6f0 0%, #a8cfe2 50%, #d4e6ee 100%);
  background-attachment: fixed;
}
.page-director .sky-bg { display: none; }


/* ============================================================
   PORTAL — name + foot crush + blood (scroll-driven)
   ============================================================ */

.portal-stage {
  display: flex;
  flex-direction: column;
  align-items: center;          /* CENTERED — was flex-start */
  position: relative;
  margin-bottom: 36px;
  text-align: center;           /* center text inside name/blurb */
}
.portal-foot {
  width: 280px;
  height: 200px;
  margin-bottom: 8px;
  pointer-events: none;
  position: relative;
  z-index: 2;
}
.portal-foot svg { width: 100%; height: 100%; }

/* 4-frame foot sprite (replaces the boot SVG). Each source frame is
   280×174 (side-view foot). Each frame holds for ~0.5s before stepping
   to the next — a slow, restful cadence that feels alive without the
   "wobble" of a fast cycle. Animation loops independently of scroll. */
/* Static foot — single frame, no animation. */
.portal-foot--sprite {
  width: 350px;
  height: 215px;
  background-image: url('../../assets/foot-sprite.png');
  background-repeat: no-repeat;
  background-size: 350px 215px;
  background-position: 0 0;
  transition: filter 0.15s ease-out;   /* smooth fade on motion blur */
}

/* Foot-area is a positioned wrapper sized exactly to the foot. The
   foot's horizontal CENTER is therefore the wrapper's center, and the
   wrapper is itself centered horizontally on the page via the parent's
   `align-items: center`. The C is absolutely positioned inside this
   wrapper so it overlays the foot's upper-left negative space and does
   NOT push the foot's center off-axis. */
.portal-foot-area {
  position: relative;
  width: 350px;
  height: 215px;       /* matches new foot aspect (1400:862) */
  margin-bottom: 8px;
}
.portal-foot-area .portal-foot { margin: 0; }

/* 4-frame C sprite — sits next to the foot, cycles on its own loop.
   Each source frame: 280×293 with each C centered + padded so nothing
   ever clips at the edge. Display sized smaller to feel like a
   complement, not a competitor with the foot. */
/* The C sits OVER the foot — covering the toes (left portion) and
   bridge (mid-upper). Inset from the foot's left edge, top-aligned. */
.portal-c--sprite {
  position: absolute;
  top: -12px;
  left: -22px;           /* sits over the toes with slight overhang */
  width: 145px;
  height: 145px;         /* slight Y squish from native ~0.9 aspect */
  background-image: url('../../assets/c-sprite.png');
  background-repeat: no-repeat;
  background-size: 580px 145px;   /* 4 frames × 145 wide */
  background-position: 0 0;
  animation: cStep 0.6s steps(4) infinite;
  pointer-events: none;
  z-index: 3;            /* on top of the foot */
}
@keyframes cStep {
  from { background-position: 0 0; }
  to   { background-position: -580px 0; }
}

/* Any element using the [data-art] swap pattern: make the inlined SVG fill
   the placeholder so the container's width/height controls render size.
   Page-specific rules above (e.g. .world-bike svg { height:auto; }) win
   via specificity for cases that need different behavior. */
[data-art] > svg { width: 100%; height: 100%; display: block; }
/* opt-out: containers whose parent has no fixed height — let the SVG keep
   its intrinsic aspect ratio. Add the `data-art-fit="aspect"` attribute on
   the placeholder to use this. (Bike + car set this in their HTML.) */
[data-art][data-art-fit="aspect"] > svg { height: auto; }

.portal-name-wrap {
  position: relative;
  width: 100%;
}
.portal-name {
  margin: 0;
  transform-origin: center bottom;
  will-change: transform;
}
.portal-foot {
  will-change: transform;
}

.portal-blood {
  position: absolute;
  /* Centered under "Hane." — same anchoring as the earlier rule but
     overridden HERE because this rule comes later and was previously
     pushing blood off to left:6%, which broke the centering. */
  left: 50%;
  width: 350px;
  transform: translateX(-50%);
  bottom: -10px;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  pointer-events: none;
  height: 0;
  overflow: visible;
  z-index: 5;
}
.portal-blood span {
  display: block;
  width: 16px;
  height: 0;
  background: linear-gradient(180deg, transparent 0%, #c41818 8%, #8a0808 60%, #5a0404 100%);
  border-radius: 50% 50% 60% 60% / 6% 6% 100% 100%;
  filter: blur(0.6px);
  transform-origin: top center;
  transition: height 0.9s cubic-bezier(.4,0,.4,1);
  position: relative;
}
.portal-blood span::after {
  content: "";
  position: absolute;
  bottom: -8px;
  left: 50%;
  transform: translateX(-50%) scale(0);
  width: 24px;
  height: 28px;
  background: radial-gradient(circle at 40% 35%, #c41818 0%, #6a0606 100%);
  border-radius: 60% 60% 50% 50% / 70% 70% 40% 40%;
  filter: blur(0.5px);
  transition: transform 0.4s cubic-bezier(.5,1.5,.5,1);
  transition-delay: inherit;
}
.portal-blood.is-bleeding span::after {
  transform: translateX(-50%) scale(1);
}
.portal-blood span:nth-child(1)  { transition-delay: 0.02s; }
.portal-blood span:nth-child(2)  { transition-delay: 0.18s; }
.portal-blood span:nth-child(3)  { transition-delay: 0.08s; }
.portal-blood span:nth-child(4)  { transition-delay: 0.24s; }
.portal-blood span:nth-child(5)  { transition-delay: 0.12s; }
.portal-blood span:nth-child(6)  { transition-delay: 0.20s; }
.portal-blood span:nth-child(7)  { transition-delay: 0.05s; }
.portal-blood span:nth-child(8)  { transition-delay: 0.28s; }
.portal-blood span:nth-child(9)  { transition-delay: 0.16s; }
.portal-blood span:nth-child(10) { transition-delay: 0.10s; }
.portal-blood span:nth-child(11) { transition-delay: 0.22s; }
.portal-blood span:nth-child(12) { transition-delay: 0.06s; }
.portal-blood.is-bleeding span:nth-child(1)  { height: 160px; width: 14px; }
.portal-blood.is-bleeding span:nth-child(2)  { height: 220px; width: 22px; }
.portal-blood.is-bleeding span:nth-child(3)  { height: 130px; width: 16px; }
.portal-blood.is-bleeding span:nth-child(4)  { height: 260px; width: 24px; }
.portal-blood.is-bleeding span:nth-child(5)  { height: 180px; width: 16px; }
.portal-blood.is-bleeding span:nth-child(6)  { height: 210px; width: 18px; }
.portal-blood.is-bleeding span:nth-child(7)  { height: 150px; width: 14px; }
.portal-blood.is-bleeding span:nth-child(8)  { height: 240px; width: 20px; }
.portal-blood.is-bleeding span:nth-child(9)  { height: 170px; width: 16px; }
.portal-blood.is-bleeding span:nth-child(10) { height: 250px; width: 22px; }
.portal-blood.is-bleeding span:nth-child(11) { height: 140px; width: 14px; }
.portal-blood.is-bleeding span:nth-child(12) { height: 200px; width: 18px; }
