/* ==========================================================================
   PASTED — Immersive Gateway
   Design system tokens are pulled directly from pastedseries.com's compiled
   CSS so this site reads as the same brand family, not a separate agency.

   Visual direction, v2: shifted from bold/cinematic toward the client's
   "quiet luxury" reference set (Aesop, Chanel, Vogue, Burberry) — Krylon
   (self-hosted, Regular weight only) replaces both former display faces as
   the single serif voice for headlines AND pull-quotes (italic is Chromium's
   synthetic oblique on Krylon — checked at pull-quote size, reads cleanly).
   The base stays void-black per direction ("stay dark, just quieter"); the
   change is restraint — accent color pulled out of headline copy entirely,
   graphic frame/box devices removed, buttons become underline text-links.
   ========================================================================== */

@font-face {
  font-family: 'Krylon';
  src: url('../fonts/Krylon-Regular.woff2') format('woff2'),
       url('../fonts/Krylon-Regular.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  /* color — brand palette: black #141111, cream/off-white #edeae6, red
     accent #ed1c24. --dark/--charcoal/--warm-dark/--warm-bg stay as relative
     depth steps off the new black (they were already close to it) for card/
     placeholder layering; --stone/--ash stay as in-between neutrals since no
     replacement was given for those. */
  --void: #141111;
  --black: #141111;
  --dark: #171413;
  --charcoal: #211d1c;
  --warm-dark: #2b2624;
  --warm-bg: #252120;
  --stone: #a09890;
  --ash: #6b665d;
  --cream: #edeae6;
  --white: #edeae6;
  --accent: #ed1c24;
  --error: #e05252;

  --border-faint: rgba(237, 234, 230, .06);
  --border-subtle: rgba(237, 234, 230, .08);
  --border-light: rgba(237, 234, 230, .15);
  --border-mid: rgba(237, 234, 230, .25);
  --border-strong: rgba(237, 234, 230, .4);
  --overlay-nav: rgba(20, 17, 17, .6);
  --overlay-dark: rgba(20, 17, 17, .45);
  --overlay-dim: rgba(0, 0, 0, .7);
  --overlay-medium: rgba(20, 17, 17, .4);
  --white-faded: rgba(237, 234, 230, .4);
  --white-muted: rgba(237, 234, 230, .5);

  /* type — Krylon carries both display headlines and italic pull-quotes now;
     Archivo remains the one quiet sans for nav/labels/body. */
  --display: "Krylon", Georgia, serif;
  --sans: "Archivo", system-ui, sans-serif;
  --serif: "Krylon", Georgia, serif;

  --text-hero: clamp(2.75rem, 7.8vw, 6.75rem);
  --text-display-xxl: clamp(2.3rem, 11vw, 8rem);
  --text-display-xl: clamp(2rem, 8vw, 5.5rem);
  --text-display-lg: clamp(1.8rem, 6.5vw, 4rem);
  --text-display-md: clamp(1.7rem, 3.4vw, 2.6rem);
  --text-section-title: clamp(1.5rem, 2.5vw, 2.25rem);
  --text-quote: clamp(1.6rem, 3.2vw, 2.6rem);
  --text-stat: clamp(2.25rem, 4.5vw, 4rem);
  --text-body-lg: .85rem;
  --text-body-md: .75rem;
  --text-body-sm: .7rem;
  --text-body-xs: .65rem;
  --text-label-md: .58rem;
  --text-label-sm: .52rem;
  --text-label-xs: .46rem;

  /* space */
  --space-section: 10rem;
  --space-section-sm: 6rem;
  --space-gap-xl: 8rem;
  --space-gap-lg: 6rem;
  --space-gap-md: 4rem;
  --space-gap-sm: 3rem;
  --space-gap-xs: 2rem;
  --space-gap-xxs: 1rem;

  /* motion */
  --ease-spring: cubic-bezier(.16, 1, .3, 1);
  --ease-smooth: cubic-bezier(.25, 1, .5, 1);
  --dur-fast: .3s;
  --dur-mid: .55s;
  --dur-slow: .9s;
  --dur-long: 1.2s;

  /* layout */
  --max-w: 1400px;
  --gutter: 4rem;

  --z-nav: 1100;
  --z-cursor: 9998;
  --z-modal: 9999;
  --z-preloader: 99999;
}

@media (max-width: 968px) { :root { --gutter: 2rem; } }
@media (max-width: 640px) { :root { --gutter: 1.5rem; } }

/* ---------- reset ---------- */
* { margin: 0; padding: 0; box-sizing: border-box; }
html { background: var(--void); }
html.lenis { height: auto; }
body {
  background: var(--void);
  color: var(--white);
  font-family: var(--sans);
  font-weight: 300;
  overflow-x: hidden;
  cursor: default;
  -webkit-font-smoothing: antialiased;
}
img, video { max-width: 100%; display: block; }
a { color: inherit; }
::selection { background: var(--accent); color: var(--void); }

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.02;
}

.italic-accent { font-family: var(--serif); font-style: italic; font-weight: 300; text-transform: none; letter-spacing: 0; }
.hot { color: var(--accent); }
/* quiet-luxury pass: accent color is a rare, deliberate flourish, not a
   default headline treatment — no color trick, no outline. Emphasis inside
   headline copy now reads in the same tone as the rest of the line; weight
   comes from scale and space, not color. */
h1 .hot, h2 .hot, h3 .hot, h4 .hot, .hero-line .hot, .cta-title .hot, .kinetic .hot, .legacy-quote .hot {
  color: inherit;
}
/* ---------- layout ---------- */
.wrap { width: 100%; max-width: var(--max-w); margin: 0 auto; padding: 0 var(--gutter); flex-shrink: 0; }

section { position: relative; padding: var(--space-section) 0 var(--space-gap-sm); }
section.chapter { min-height: 100vh; display: flex; flex-direction: column; justify-content: center; }
/* Tablet + mobile share one reduced tier — 968px matches isMobile() in
   animations.js and every other responsive gate in this file, so tablet
   widths (e.g. 768–968px) get this instead of silently falling through
   to the desktop 160px/48px values above. */
@media (max-width: 968px) {
  section { padding: var(--space-gap-sm) 0 var(--space-gap-sm); }
  /* The real source of the remaining "huge gap" screenshots: .chapter
     forces min-height:100vh and vertically centers its content. On a
     tall phone screen with short content (a heading + one line + a
     3-row list), centering leaves a large empty band above the heading
     before it even appears — that band reads as inter-section dead
     space, even though no padding/margin value is actually that big.
     Letting the section size to its own content instead removes it. */
  section.chapter { min-height: 0; justify-content: flex-start; }
}

.section-head { display: flex; flex-direction: column; align-items: flex-start; gap: 1.2rem; margin-bottom: var(--space-gap-lg); }
.section-head h2 { font-size: var(--text-display-xl); }
.section-head p { max-width: 480px; font-size: var(--text-body-md); color: var(--stone); line-height: 1.8; font-weight: 300; }
.section-head.center { align-items: center; text-align: center; }
/* same 968px tier as the section padding rule above — this margin was
   still a flat 96px (--space-gap-lg) on every screen size, so it was
   compounding with section padding into the "huge gap" on mobile/tablet
   even after the section padding itself was reduced. */
@media (max-width: 968px) {
  .section-head { margin-bottom: var(--space-gap-sm); }
}

/* ---------- reveal / motion utilities ---------- */
.reveal { opacity: 0; transform: translateY(34px); transition: opacity var(--dur-slow) var(--ease-spring), transform var(--dur-slow) var(--ease-spring); }
.reveal.in { opacity: 1; transform: translateY(0); }
.reveal-d1 { transition-delay: .08s; } .reveal-d2 { transition-delay: .16s; }
.reveal-d3 { transition-delay: .24s; } .reveal-d4 { transition-delay: .32s; }

.kinetic .ch { display: inline-block; opacity: 0; transform: translateY(.5em); transition: opacity .7s var(--ease-spring), transform .7s var(--ease-spring); }
.kinetic.in .ch { opacity: 1; transform: translateY(0); }

/* character-rise text reveal: GSAP animates .cr-char's transform directly
   (yPercent 100 -> 0), so there's no CSS hidden-state here — if GSAP never
   loads, the text just sits at rest, fully visible. The padding/negative-
   margin pair on .cr-wrap only gives the clip box vertical headroom so
   ascenders/descenders never get cut at rest; it nets to zero added space
   in the line so nothing shifts. */
.cr-word { display: inline-block; white-space: nowrap; }
.cr-wrap { display: inline-block; overflow: hidden; padding: .16em 0; margin: -.16em 0; }
.cr-char { display: inline-block; will-change: transform; }

.reduce-motion *, .reduce-motion *::before, .reduce-motion *::after {
  animation-duration: .01ms !important; animation-iteration-count: 1 !important;
  transition-duration: .2s !important; scroll-behavior: auto !important;
}
.reduce-motion .reveal { opacity: 1; transform: none; }
.reduce-motion .kinetic .ch { opacity: 1; transform: none; }

/* ---------- wistia-player (custom elements default to display:inline,
   which ignores width/height — every .scene-player rule below sets
   width:100%/height:100%, so without this the player never sizes at all) ---------- */
wistia-player { display: block; }
/* Every ambient/inline slot (hero, Production flagship, Pasted India)
   mounts its player via mountWistia(..., {chromeless:true}) — see
   js/components.js — which adds this class. pointer-events:none lets a
   click fall through to the section's own data-screening handler instead
   of the (invisible-but-still-there) player intercepting it. */
.wistia-chromeless { pointer-events: none; }

/* ---------- media placeholder (no footage/photography supplied yet) ---------- */
.media-placeholder {
  position: absolute; inset: 0;
  background: radial-gradient(130% 130% at 22% 0%, var(--warm-dark) 0%, var(--charcoal) 45%, var(--black) 100%);
}
.media-placeholder::after {
  content: ''; position: absolute; inset: 0; opacity: .5; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
.media-placeholder-mark {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 46px; height: 46px; border-radius: 50%; border: 1px solid var(--border-mid);
  display: flex; align-items: center; justify-content: center;
}
.media-placeholder-mark::after { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--border-strong); }
.media-placeholder-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.media-placeholder.has-poster .media-placeholder-mark { display: none; }

/* ---------- grain ---------- */
.grain {
  position: fixed; inset: 0; z-index: 10000; pointer-events: none; opacity: .045;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; gap: .6rem; padding: 1rem 2.2rem;
  font-family: var(--sans); font-weight: 500; font-size: var(--text-body-xs);
  letter-spacing: .12em; text-decoration: none;
  border-radius: 0; transition: background var(--dur-fast), border-color var(--dur-fast), color var(--dur-fast);
}
.btn-solid { background: var(--white); color: var(--void); border: 1px solid var(--white); }
.btn-solid:hover { background: transparent; color: var(--white); }
.btn-outline { border: 1px solid var(--border-cta, rgba(237,234,230,.35)); color: var(--white); }
.btn-outline:hover { border-color: var(--white); background: rgba(237, 234, 230, .06); }

/* ---------- progress + reel dots ---------- */
#progress { position: fixed; top: 0; left: 0; height: 2px; background: var(--accent); z-index: var(--z-nav); width: 0%; }

/* ---------- preloader ---------- */
.preloader {
  position: fixed; inset: 0; z-index: var(--z-preloader); background: var(--void);
  display: flex; align-items: center; justify-content: center;
  transition: opacity var(--dur-slow) var(--ease-spring), visibility var(--dur-slow) var(--ease-spring);
}
.preloader.leaving { opacity: 0; visibility: hidden; pointer-events: none; }
.preloader-content { text-align: center; display: flex; flex-direction: column; align-items: center; gap: 1.1rem; }
.preloader-rule { width: 0; height: 1px; background: var(--border-light); animation: preloaderRule 1s var(--ease-spring) .15s forwards; }
@keyframes preloaderRule { to { width: 160px; } }
.preloader-label { font-size: var(--text-label-sm); letter-spacing: .18em; color: var(--ash); opacity: 0; animation: preloaderFade var(--dur-slow) var(--ease-spring) .4s forwards; }
.preloader-title { font-family: var(--display); font-size: clamp(2.2rem, 7vw, 5rem); color: var(--white); opacity: 0; animation: preloaderFade 1s var(--ease-spring) .6s forwards; }
.preloader-presents { font-size: var(--text-label-md); letter-spacing: .2em; color: var(--ash); opacity: 0; animation: preloaderFade var(--dur-slow) var(--ease-spring) .85s forwards; }
@keyframes preloaderFade { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }
.reduce-motion .preloader { display: none; }

/* ---------- header / nav ---------- */
header {
  position: fixed; top: 0; left: 0; right: 0; z-index: var(--z-nav);
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; column-gap: 2rem;
  padding: 1.5rem var(--gutter);
  background: var(--overlay-nav); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--border-faint);
}
.logo { grid-column: 2; display: flex; align-items: center; justify-self: center; text-decoration: none; }
.logo img { height: 24px; width: auto; }

nav.top-links { display: flex; align-items: center; gap: 2rem; }
.top-links-left { grid-column: 1; justify-self: start; }
.top-links-right { grid-column: 3; justify-self: end; }
nav.top-links a {
  font-family: var(--sans); font-size: var(--text-body-xs); letter-spacing: .1em;
  color: var(--white); opacity: .62; text-decoration: none; transition: opacity var(--dur-fast);
}
nav.top-links a:hover { opacity: 1; }
@media (max-width: 940px) { nav.top-links.top-links-left, nav.top-links.top-links-right { display: none; } }

.nav-contact { font-size: var(--text-body-xs); letter-spacing: .1em; color: var(--white); text-decoration: none; opacity: 1; }
.nav-contact:hover { opacity: .7; }

.nav-hamburger {
  display: none; grid-column: 3; justify-self: end; position: relative; width: 34px; height: 34px; z-index: 1100;
  background: none; border: none; cursor: pointer; flex-direction: column; justify-content: center; gap: 5px;
}
@media (max-width: 940px) {
  .nav-hamburger { display: flex; }
  .logo { grid-column: 1; justify-self: start; }
}
.nav-hamburger span { display: block; width: 22px; height: 1px; background: var(--white); transition: all .45s var(--ease-spring); transform-origin: 50%; }
.nav-hamburger.active span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-hamburger.active span:nth-child(2) { opacity: 0; transform: scaleX(0); }
.nav-hamburger.active span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.nav-mobile {
  position: fixed; inset: 0; z-index: 1050; background: var(--void);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  opacity: 0; pointer-events: none; transition: opacity var(--dur-mid) var(--ease-spring);
}
.nav-mobile.active { opacity: 1; pointer-events: auto; }
.nav-mobile-menu { list-style: none; display: flex; flex-direction: column; align-items: center; gap: var(--space-gap-xs); text-align: center; }
.nav-mobile-menu a {
  font-family: var(--display); font-size: clamp(1.8rem, 8vw, 3rem);
  color: var(--white); text-decoration: none; opacity: 0; transform: translateY(16px);
  transition: opacity var(--dur-mid) var(--ease-spring), transform var(--dur-mid) var(--ease-spring);
}
.nav-mobile.active .nav-mobile-menu a { opacity: 1; transform: translateY(0); }

.nav-mobile.active .nav-mobile-menu li:nth-child(1) a { transition-delay: .08s; }
.nav-mobile.active .nav-mobile-menu li:nth-child(2) a { transition-delay: .13s; }
.nav-mobile.active .nav-mobile-menu li:nth-child(3) a { transition-delay: .18s; }
.nav-mobile.active .nav-mobile-menu li:nth-child(4) a { transition-delay: .23s; }
.nav-mobile.active .nav-mobile-menu li:nth-child(5) a { transition-delay: .28s; }
.nav-mobile.active .nav-mobile-menu li:nth-child(6) a { transition-delay: .33s; }
.nav-mobile.active .nav-mobile-menu li:nth-child(7) a { transition-delay: .38s; }

/* ==========================================================================
   HERO — full-bleed scene, framed at rest, chrome recedes as headline clears
   ========================================================================== */
#hero { padding: 0; min-height: 100vh; }
.hero-stage { position: relative; width: 100%; height: 100vh; overflow: hidden; background: var(--void); }

.hero-mask { position: absolute; inset: 0; will-change: clip-path; }
.hero-media { position: absolute; inset: 0; }
.hero-media img, .hero-media .scene-player { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.hero-media::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to top, var(--void) 0%, rgba(20,17,17,.55) 22%, rgba(20,17,17,.15) 55%, transparent 100%),
              linear-gradient(to right, rgba(20,17,17,.55) 0%, transparent 45%);
}
.hero-veil { position: absolute; inset: 0; background: var(--overlay-dark); opacity: 0; pointer-events: none; }

/* the graphic viewfinder-frame box was dropped — a single quiet corner
   label is enough of a cinematic nod without reading as production HUD */
.hero-frame-chrome { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
.hero-chrome-meta { position: absolute; bottom: calc(3.4vw + 1.8rem); right: calc(3.4vw + 1.8rem); font-size: var(--text-label-sm); letter-spacing: .12em; color: var(--white-muted); text-align: right; line-height: 1.7; }
@media (max-width: 720px) {
  .hero-chrome-meta { bottom: calc(6vw + 1.4rem); right: calc(6vw + 1.4rem); }
}

.hero-content { position: absolute; left: calc(var(--gutter) + 1.5rem); right: calc(var(--gutter) + 1.5rem); bottom: calc(8vw + 3.6rem); z-index: 5; }
@media (max-width: 640px) { .hero-content { left: calc(var(--gutter) + .5rem); right: calc(var(--gutter) + .5rem); } }
.hero-stack { position: relative; }
.hero-line { line-height: .96; will-change: transform, opacity; }
.hero-line-fit {
  display: inline-block; font-family: var(--display); font-size: var(--text-hero); color: var(--white);
  line-height: .96; letter-spacing: -.01em; white-space: nowrap; transform-origin: left center;
}
.hero-sub-row { display: flex; flex-direction: column; align-items: flex-start; gap: 2.2rem; margin-top: 2rem; }
.hero-desc { max-width: 400px; font-size: var(--text-body-md); line-height: 1.9; color: var(--stone); }
.hero-cta-row { display: flex; gap: 2.2rem; flex-wrap: wrap; }

.hero-scroll-cue {
  position: absolute; left: 50%; bottom: 2.2rem; transform: translateX(-50%); z-index: 5;
  display: flex; flex-direction: column; align-items: center; gap: .6rem;
  font-size: var(--text-label-xs); letter-spacing: .18em; color: var(--white-muted);
}
.hero-scroll-cue::after { content: ''; width: 1px; height: 30px; background: linear-gradient(var(--white-muted), transparent); }
@media (max-width: 720px) { .hero-scroll-cue { display: none; } }

.marquee-wrap { padding: 1.4rem 0; overflow: hidden; white-space: nowrap; border-top: 1px solid var(--border-faint); }
.marquee { display: inline-block; animation: scrollLeft 34s linear infinite; }
.marquee span { font-family: var(--display); font-size: 1rem; color: var(--ash); padding: 0 2rem; letter-spacing: .02em; }
@keyframes scrollLeft { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ==========================================================================
   ROW LISTS — market / offer / event / partner rows share one pattern
   ========================================================================== */
.row-list { display: flex; flex-direction: column; }

.offer-row, .event-item {
  display: grid; grid-template-columns: 60px 1fr auto; align-items: center; gap: 1.4rem;
  padding: 1.6rem 0; border-bottom: 1px solid var(--border-faint); transition: padding-left var(--dur-fast) var(--ease-smooth);
}
.offer-row:first-child, .event-item:first-child { border-top: 1px solid var(--border-faint); }
.offer-row:hover, .event-item:hover { padding-left: .7rem; }
.o-num, .ev-num { font-family: var(--sans); color: var(--ash); font-size: var(--text-body-sm); }
.offer-name, .ev-name { font-family: var(--display); font-size: var(--text-display-md); transition: color var(--dur-fast); }
.offer-row:hover .offer-name, .event-item:hover .ev-name { color: var(--accent); }
.offer-desc, .ev-loc { font-size: var(--text-body-sm); color: var(--ash); max-width: 230px; text-align: right; font-family: var(--sans); letter-spacing: .02em; }
@media (max-width: 760px) {
  .offer-row, .event-item { grid-template-columns: 34px 1fr; }
  .offer-desc, .ev-loc { display: none; }
}

/* ==========================================================================
   PROCESS SCENE — Intersection section's pinned cinematic card sequence.
   .process-scene is both the ScrollTrigger trigger AND the pinned element:
   a fixed 100vh box (GSAP's own `end` distance supplies the scroll runway,
   not the element's own layout height, so — unlike .film-scene/#phstudio-
   scene elsewhere in this file — it needs no tall CSS height of its own).
   Two stacked layers inside: .process-intro (the heading — static, GSAP
   never touches it, it just sits there for the whole sequence) and
   .process-cards (the four cards, GSAP-driven, stacked above it). Each
   card lives inside a .process-card-slot that owns its STATIC right-side
   position and vertical centering via flexbox; the card itself is the
   only thing GSAP ever transforms (yPercent + opacity) — one owner per
   transform, never a CSS transform and a GSAP transform on the same
   element (see initFilmScene's own notes on that same principle).
   ========================================================================== */
.process-scene { position: relative; width: 100%; height: 100vh; overflow: hidden; background: var(--void); z-index: 20; }
.process-intro { position: absolute; inset: 0; display: flex; align-items: center; z-index: 1; }

.process-cards { position: absolute; inset: 0; z-index: 3; max-width: var(--max-w); margin: 0 auto; padding: 0 var(--gutter); }
.process-card-slot {
  position: absolute; top: 0; bottom: 0; right: var(--gutter); width: clamp(320px, 34vw, 480px);
  display: flex; align-items: center; justify-content: flex-end; pointer-events: none;
}

.process-card {
  width: 100%; background: var(--warm-bg); border: 1px solid var(--border-light);
  box-shadow: 0 30px 70px rgba(0,0,0,.45); padding: 2.6rem 2.4rem; pointer-events: auto;
}
.process-card-tag { display: block; margin-bottom: 1.6rem; font-family: var(--sans); font-size: var(--text-label-sm); letter-spacing: .12em; text-transform: uppercase; color: var(--stone); }
.process-card-title { font-family: var(--display); font-weight: 400; font-size: var(--text-display-md); margin-bottom: 1.2rem; }
.process-card-desc { font-size: var(--text-body-sm); color: var(--stone); line-height: 1.9; max-width: 34ch; }

@media (max-width: 720px) {
  .process-card { padding: 2rem 1.8rem; }
}

/* static fallback — mobile / reduced-motion: no pin, normal stacked flow.
   .static is added by initProcessScene() (js/animations.js) itself, inside
   the same gsap.matchMedia() branch that skips creating the pinned
   timeline entirely — not a separate CSS breakpoint that could drift out
   of sync with it (matches #phstudio-scene's own established pattern). */
.process-scene.static { height: auto; overflow: visible; padding: var(--space-gap-lg) 0; }
.process-scene.static .process-intro { position: relative; inset: auto; display: block; margin-bottom: var(--space-gap-md); }
.process-scene.static .process-cards { position: relative; inset: auto; display: flex; flex-direction: column; gap: 1.2rem; }
.process-scene.static .process-card-slot { position: static; width: auto; display: block; }
/* .static is what actually renders on mobile/tablet (see comment above) —
   96px top+bottom here was the same flat value as desktop, so it's part
   of the "96px inner padding on mobile" the section-level fix didn't
   reach. Matches the 968px tier used for section padding elsewhere. */
@media (max-width: 968px) {
  .process-scene.static { padding: var(--space-gap-sm) 0; }
  .process-scene.static .process-intro { margin-bottom: var(--space-gap-sm); }
}

/* ==========================================================================
   WORLD MAP — bespoke interactive dotted map (Markets section)
   Dots are SVG (square, on a straight grid — not circles/hexagons); markers
   are real buttons (keyboard + touch friendly) positioned by percentage
   against the map's own viewBox aspect-ratio, so they stay pixel-aligned
   with the SVG beneath them at any width. Geometry comes from
   js/map-geometry.js (generated — see tools/generate-map-data.cjs), never
   hand-placed CSS positions.
   ========================================================================== */
.world-map-wrap { margin-top: var(--space-gap-md); }
/* .world-map's aspect-ratio is fixed by JS (world-map.js, matching the
   dot-grid's own viewBox) at whatever the container's current width is —
   bleeding the wrapper past .wrap's gutter on narrow screens is what
   actually grows the map (the SVG scales off container width, so more
   width directly means bigger dots/markers), not touching the ratio
   itself, which would either letterbox (no size gain) or distort the
   geography if forced non-uniform. .world-map-detail gets its own inset
   back so its text doesn't bleed with it. */
@media (max-width: 640px) {
  .world-map-wrap { margin-left: calc(-1 * var(--gutter)); margin-right: calc(-1 * var(--gutter)); }
  .world-map-detail { padding: 0 var(--gutter); }
}
.world-map { position: relative; width: 100%; user-select: none; }
.world-map-dots { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* dots sit at a constant .55 opacity; the entrance reveal animates the
   parent <g> band (opacity 0→1) instead of each individual rect — opacity
   is multiplicative through nesting, so band(1) × rect(.55) still lands on
   .55 at rest, while keeping ~3000 rects out of the transition entirely. */
.world-map-dots rect { fill: var(--stone); opacity: .55; transition: opacity .5s, fill .6s; }
.world-map-dots g { opacity: 0; transition: opacity .9s var(--ease-spring); }

/* soft frame vignette — fades the map's own edges into the section
   background rather than ending in a hard rectangle. Deliberately faint: a
   narrow band and a partial (not fully opaque) endpoint, so it reads as a
   quiet, intentional edge treatment rather than a visible frame. Kept
   narrow enough that markers near the edge, like Sydney, stay fully legible. */
.world-map::after {
  content: '';
  position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(to right, var(--overlay-dark) 0%, transparent 4%, transparent 96%, var(--overlay-dark) 100%),
    linear-gradient(to bottom, var(--overlay-dark) 0%, transparent 6%, transparent 94%, var(--overlay-dark) 100%);
}

.world-map-markers { position: absolute; inset: 0; }
.wm-marker {
  position: absolute; transform: translate(-50%, -50%);
  width: 34px; height: 34px; padding: 0; margin: 0; border: none; background: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.wm-marker-mark {
  position: absolute; width: 11px; height: 11px; border: 1px solid var(--stone); background: transparent;
  transition: border-color var(--dur-fast), transform var(--dur-mid) var(--ease-smooth), box-shadow var(--dur-mid);
}
.wm-marker-mark::after {
  content: ''; position: absolute; inset: 3px; background: var(--stone); transition: background var(--dur-fast);
}
.wm-marker:hover .wm-marker-mark, .wm-marker:focus-visible .wm-marker-mark, .wm-marker.active .wm-marker-mark {
  border-color: var(--accent); transform: scale(1.5);
}
.wm-marker:hover .wm-marker-mark::after, .wm-marker:focus-visible .wm-marker-mark::after, .wm-marker.active .wm-marker-mark::after { background: var(--accent); }
.world-map-markers.has-active .wm-marker:not(.active):not(:hover):not(:focus-visible) { opacity: .38; }

/* ambient "blip" — one marker at a time, quiet and slow (see world-map.js
   startBlipCycle) so the map reads as alive without ever feeling busy.
   The label rides along (see .blip additions below) so each blip actually
   announces the market, not just an abstract pulse. */
@keyframes wmBlipRing { 0%, 100% { border-color: var(--stone); transform: scale(1); box-shadow: none; } 12%, 88% { border-color: var(--accent); transform: scale(1.7); box-shadow: 0 0 7px rgba(237, 28, 36, .5); } }
@keyframes wmBlipFill { 0%, 100% { background: var(--stone); } 12%, 88% { background: var(--accent); } }
.wm-marker.blip .wm-marker-mark { animation: wmBlipRing 2.6s var(--ease-smooth); }
.wm-marker.blip .wm-marker-mark::after { animation: wmBlipFill 2.6s var(--ease-smooth); }

.wm-marker-label {
  position: absolute; white-space: nowrap; pointer-events: none;
  opacity: 0; transition: opacity var(--dur-mid) var(--ease-smooth), transform var(--dur-mid) var(--ease-smooth);
}
.wm-marker:hover .wm-marker-label, .wm-marker:focus-visible .wm-marker-label, .wm-marker.active .wm-marker-label, .wm-marker.blip .wm-marker-label { opacity: 1; }
.wm-marker-label .wml-name { display: block; font-family: var(--display); font-size: .9rem; color: var(--white); letter-spacing: .02em; }
.wm-marker-label .wml-meta { display: block; font-family: var(--sans); font-size: var(--text-label-sm); letter-spacing: .06em; color: var(--ash); margin-top: .2rem; }

/* label anchor directions keep labels from running off the map edge */
.wm-marker[data-anchor="top"] .wm-marker-label { bottom: 100%; left: 50%; transform: translate(-50%, 10px); margin-bottom: 10px; text-align: center; }
.wm-marker[data-anchor="top"]:hover .wm-marker-label, .wm-marker[data-anchor="top"]:focus-visible .wm-marker-label, .wm-marker[data-anchor="top"].active .wm-marker-label, .wm-marker[data-anchor="top"].blip .wm-marker-label { transform: translate(-50%, 0); }
.wm-marker[data-anchor="bottom"] .wm-marker-label { top: 100%; left: 50%; transform: translate(-50%, -10px); margin-top: 10px; text-align: center; }
.wm-marker[data-anchor="bottom"]:hover .wm-marker-label, .wm-marker[data-anchor="bottom"]:focus-visible .wm-marker-label, .wm-marker[data-anchor="bottom"].active .wm-marker-label, .wm-marker[data-anchor="bottom"].blip .wm-marker-label { transform: translate(-50%, 0); }
.wm-marker[data-anchor="left"] .wm-marker-label { right: 100%; top: 50%; transform: translate(10px, -50%); margin-right: 10px; text-align: right; }
.wm-marker[data-anchor="left"]:hover .wm-marker-label, .wm-marker[data-anchor="left"]:focus-visible .wm-marker-label, .wm-marker[data-anchor="left"].active .wm-marker-label, .wm-marker[data-anchor="left"].blip .wm-marker-label { transform: translate(0, -50%); }
.wm-marker[data-anchor="right"] .wm-marker-label { left: 100%; top: 50%; transform: translate(-10px, -50%); margin-left: 10px; text-align: left; }
.wm-marker[data-anchor="right"]:hover .wm-marker-label, .wm-marker[data-anchor="right"]:focus-visible .wm-marker-label, .wm-marker[data-anchor="right"].active .wm-marker-label, .wm-marker[data-anchor="right"].blip .wm-marker-label { transform: translate(0, -50%); }

.wm-marker:focus-visible { outline: none; }
.wm-marker:focus-visible .wm-marker-mark { box-shadow: 0 0 0 3px rgba(237, 28, 36, .25); }

/* city detail strip — appears only once a market is clicked; carries real
   information (its actual cities), not a restatement of the pin's own
   label, so it earns the space it takes. */
.world-map-detail.filled {
  margin-top: var(--space-gap-md); padding-top: 1.8rem; border-top: 1px solid var(--border-faint);
}
.wmd-content { display: flex; flex-direction: column; gap: .6rem; }
.wmd-name { font-family: var(--display); font-size: var(--text-display-md); }
.wmd-cities { font-family: var(--sans); font-size: var(--text-body-sm); letter-spacing: .04em; color: var(--stone); }

@media (prefers-reduced-motion: reduce) {
  .world-map-dots rect, .world-map-dots g, .wm-marker-mark, .wm-marker-mark::after, .wm-marker-label { transition: none !important; }
}

/* ---------- finder: "The Brief" — a blueprint-to-built numeral grid.
   Ghost-outline numerals (transparent fill, hairline stroke) fill solid gold
   on choice — the question rendered as an unbuilt outline becoming a built,
   solid mark. No boxes: every division is a hairline rule. ---------- */
.finder-q { font-family: var(--display); font-size: var(--text-display-xl); max-width: 820px; margin-bottom: var(--space-gap-xl); }

.finder-list {
  display: grid; grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--border-light); border-bottom: 1px solid var(--border-faint);
}
.finder-row {
  position: relative; display: flex; flex-direction: column;
  padding: 3rem 1.75rem 2.5rem; border-left: 1px solid var(--border-faint); cursor: pointer;
}
.finder-row:first-child { border-left: none; padding-left: 0; }
.finder-row:last-child { padding-right: 0; }
.finder-list:has(.finder-row.active) .finder-row:not(.active) {
  opacity: .4; transition: opacity var(--dur-mid) var(--ease-smooth);
}

.fr-num {
  display: block; font-family: var(--sans); font-weight: 300; line-height: 1;
  font-size: clamp(3.5rem, 9vw, 7rem); font-variant-numeric: tabular-nums; color: var(--border-strong);
  transition: color var(--dur-mid) var(--ease-smooth), -webkit-text-stroke-color var(--dur-mid) var(--ease-smooth);
}
@supports (-webkit-text-stroke: 1px black) {
  .fr-num { color: transparent; -webkit-text-stroke: 1px var(--border-strong); }
  .finder-row:hover .fr-num { -webkit-text-stroke-color: var(--cream); }
}
.finder-row.active .fr-num { color: var(--accent); -webkit-text-stroke: 0; }

.fr-mark { position: absolute; top: 3.2rem; right: 1.75rem; width: 12px; height: 12px; transition: transform var(--dur-fast) var(--ease-smooth); }
.fr-mark::before, .fr-mark::after { content: ''; position: absolute; background: var(--border-strong); transition: background var(--dur-fast); }
.fr-mark::before { left: 5px; top: 0; width: 1px; height: 12px; }
.fr-mark::after { top: 5px; left: 0; width: 12px; height: 1px; }
.finder-row.active .fr-mark { transform: rotate(45deg); }
.finder-row.active .fr-mark::before, .finder-row.active .fr-mark::after { background: var(--accent); }

.fr-title { display: block; font-family: var(--display); font-size: clamp(1.3rem, 1.8vw, 1.7rem); margin-top: 1.75rem; color: var(--cream); }
.fr-sub { display: block; font-size: var(--text-body-sm); color: var(--ash); margin-top: .5rem; max-width: 90%; font-family: var(--sans); }

.finder-row::after {
  content: ''; position: absolute; left: 1.75rem; right: 1.75rem; bottom: -1px; height: 1px; background: var(--accent);
  transform: scaleX(0); transform-origin: left; transition: transform var(--dur-mid) var(--ease-spring);
}
.finder-row.active::after { transform: scaleX(1); }

@media (max-width: 900px) {
  .finder-list { grid-template-columns: repeat(2, 1fr); }
  .finder-row { border-left: none; border-top: 1px solid var(--border-faint); padding-right: 1.75rem; }
  .finder-row:nth-child(odd) { border-right: 1px solid var(--border-faint); }
  .finder-row:nth-child(-n+2) { border-top: none; }
}
@media (max-width: 640px) {
  .finder-list { grid-template-columns: 1fr; }
  .finder-row { border-left: none !important; border-right: none !important; padding: 1.8rem 0; }
  .finder-row:first-child { border-top: none; }
  .fr-num { font-size: clamp(2.5rem, 14vw, 3.5rem); }
  .fr-sub { max-width: 100%; }
}

.finder-answer {
  max-height: 0; overflow: hidden; opacity: 0;
  font-family: var(--display); font-style: italic; font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  color: var(--stone); line-height: 1.85;
  transition: max-height var(--dur-slow) var(--ease-spring), opacity var(--dur-slow) var(--ease-smooth),
    margin-top var(--dur-slow) var(--ease-smooth), padding-top var(--dur-slow) var(--ease-smooth);
}
.finder-answer.show { max-height: 280px; opacity: 1; margin-top: 2.5rem; padding-top: 2rem; }
.finder-answer strong { font-weight: 500; color: inherit; }
@media (min-width: 641px) { .finder-answer { max-width: 50%; } }

@media (prefers-reduced-motion: reduce) {
  .fr-num, .fr-mark, .fr-mark::before, .fr-mark::after, .finder-row::after, .finder-answer { transition: none !important; }
}

/* ==========================================================================
   FILM SCENE — Production section's cinematic reveal, built on native CSS
   sticky positioning rather than a ScrollTrigger pin. .film-scene is the
   scroll runway: a tall block (100vh stage + 200vh of scrub distance) that
   exists purely to give .film-stage room to be sticky. .film-stage
   (position:sticky, top:0, height:100vh) never changes positioning scheme —
   the browser's own sticky mechanics carry it from normal flow into "stuck"
   and back out again, so there is no relative->fixed handoff for
   ScrollTrigger (or the user) to notice. GSAP's only job is scrubbing
   .film-frame's transform:scale() from a responsively computed "open"
   factor down to 1 (initFilmScene, js/animations.js, sets this deterministically
   via gsap.set() before any scroll happens, so the very first frame already
   reads as its cinematic near-fullscreen state — nothing to jump into).
   .film-info stays opacity:0 until the scale finishes, so text is never
   visible while the frame's own transform would otherwise distort it.
   ========================================================================== */
.scene-pin { position: relative; isolation: isolate; z-index: 20; }

.film-scene {
  position: relative;
  /* 100vh for .film-stage itself + 200vh of scrub distance — matches the
     scroll-distance-to-progress pacing the cinematic reveal originally used
     under ScrollTrigger's pin (end:'+=200%'), so the timing reads the same. */
  height: 300vh;
}

.film-stage {
  position: sticky; top: 0; width: 100%; height: 100vh; overflow: hidden; background: var(--void);
  display: flex; align-items: center; justify-content: center;
}

/* The sticky+scrub zoom now runs at every width (js/animations.js,
   initFilmScene) — only prefers-reduced-motion skips it, since that's the
   one condition where initFilmScene() never creates a ScrollTrigger and
   nothing should be reserving 200vh of scroll runway for it. .film-stage's
   height/padding fallback lives in the same query so the two paths (JS
   "skip the animation" and CSS "collapse the scroll runway") can't drift
   out of sync the way a separate width-keyed rule risked. */
@media (prefers-reduced-motion: reduce) {
  .film-scene { height: auto; }
  .film-stage { position: static; height: auto; padding: var(--space-gap-md) 0; }
}

.film-frame {
  position: relative; overflow: hidden; transform-origin: center center; will-change: transform;
  width: min(100% - 2 * var(--gutter), 1400px - 2 * var(--gutter));
  height: min(70vh, 760px); min-height: 380px;
  cursor: pointer; /* data-screening (index.html) — click opens the full player in the screening modal */
}
@media (max-width: 720px) { .film-frame { height: auto; aspect-ratio: 4/5; } }

.film-media { position: absolute; inset: 0; }
.film-media img, .film-media .scene-player { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.film-veil { position: absolute; inset: 0; background: linear-gradient(rgba(20,17,17,.4) 0%, transparent 22%, transparent 55%, rgba(20,17,17,.8) 100%); pointer-events: none; }

.film-info { position: absolute; inset: 0; z-index: 3; padding: 3.4vw; display: flex; flex-direction: column; justify-content: flex-end; pointer-events: none; will-change: opacity, transform; }
.film-tag { display: block; font-size: var(--text-label-sm); letter-spacing: .12em; color: var(--stone); margin-bottom: .6rem; }
.film-title { display: block; margin: 0; font-family: var(--display); font-weight: 400; font-size: var(--text-display-lg); max-width: 14ch; }
.film-duration { display: block; font-family: var(--sans); font-size: var(--text-body-sm); color: var(--white-faded); margin-top: .6rem; }
@media (max-width: 720px) { .film-info { padding: 6vw; } .film-title { font-size: var(--text-display-md); } }

.film-chrome { position: absolute; inset: 0; z-index: 4; pointer-events: none; will-change: opacity, transform; }
.film-chrome-bottom { position: absolute; bottom: 2.4rem; right: 2.4rem; font-family: var(--sans); font-size: var(--text-label-sm); letter-spacing: .06em; color: var(--stone); text-align: right; }
@media (max-width: 720px) { .film-chrome-bottom { display: none; } }

/* production reel grid — the 3 supporting cards; the film scene (sticky, not pinned) is its own stage above */
.reel-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; margin-top: var(--space-gap-lg); }
@media (max-width: 760px) { .reel-grid { grid-template-columns: 1fr; } }
@media (max-width: 968px) { .reel-grid { margin-top: var(--space-gap-sm); } }

.film-card { aspect-ratio: 3/4; cursor: pointer; background: var(--charcoal); position: relative; overflow: hidden; }
.film-card-overlay {
  position: absolute; inset: 0; padding: 1.5rem; display: flex; flex-direction: column; justify-content: flex-end;
  background: linear-gradient(transparent 0%, rgba(20,17,17,.25) 55%, rgba(20,17,17,.92) 100%);
}
.film-card-category { font-size: var(--text-label-sm); letter-spacing: .12em; color: var(--stone); margin-bottom: .4rem; }
.film-card-title { font-family: var(--display); font-size: 1.15rem; color: var(--white); line-height: 1.15; }
.film-card-duration { font-size: var(--text-label-md); letter-spacing: .06em; color: var(--ash); margin-top: .4rem; }
.film-card-play {
  position: absolute; top: 1.4rem; right: 1.4rem; width: 32px; height: 32px; border-radius: 50%;
  border: 1px solid var(--border-mid); display: flex; align-items: center; justify-content: center;
  font-size: .6rem; color: var(--white); opacity: 0; transform: scale(.8); transition: all var(--dur-mid) var(--ease-spring);
}
.film-card:hover .film-card-play { opacity: 1; transform: scale(1); }
.film-card.coming-soon { cursor: default; }
.film-card.coming-soon .film-card-overlay { background: linear-gradient(rgba(20,17,17,.35) 0%, rgba(20,17,17,.94) 100%); }
.film-card.coming-soon::before { content: ''; position: absolute; inset: 0; backdrop-filter: blur(3px); }

/* production section outro — points to the full pastedseries.com catalog */
.film-outro { margin-top: var(--space-gap-md); padding-top: var(--space-gap-sm); border-top: 1px solid var(--border-faint); }
.film-outro-eyebrow { display: block; font-size: var(--text-label-sm); letter-spacing: .12em; text-transform: uppercase; color: var(--stone); margin-bottom: 1rem; }
.film-outro-row { display: flex; align-items: center; justify-content: space-between; gap: 2.4rem; flex-wrap: wrap; }
.film-outro-line { font-size: var(--text-body-md); color: var(--stone); line-height: 1.8; font-weight: 300; max-width: 560px; flex: 1 1 360px; }
.film-outro .btn { flex-shrink: 0; white-space: nowrap; }
@media (max-width: 640px) {
  .film-outro-row { flex-direction: column; align-items: flex-start; }
  /* flex:1 1 360px on .film-outro-line was written for the row layout,
     where 360px is a sane flex-basis WIDTH. Flipping to column above
     puts flex-basis on the main axis instead, which is now vertical —
     so it silently became a forced 360px MINIMUM HEIGHT on a 3-line
     paragraph, leaving a huge empty box under the text before the
     button. Reset to content-sized now that the axis has changed. */
  .film-outro-line { flex: none; }
  .film-outro .btn { width: 100%; justify-content: center; }
}

/* ---------- screening modal (click-to-open, reused pastedseries.com pattern) ---------- */
.screening {
  position: fixed; inset: 0; z-index: var(--z-modal); background: #000;
  display: flex; flex-direction: column; opacity: 0; pointer-events: none;
  transition: opacity .6s var(--ease-spring);
}
.screening.active { opacity: 1; pointer-events: auto; }
.screening-bar { width: 100%; height: 8vh; background: #000; flex-shrink: 0; transform: scaleY(0); transition: transform var(--dur-mid) var(--ease-spring); }
.screening-bar.top { transform-origin: top; }
.screening-bar.bottom { transform-origin: bottom; }
.screening.active .screening-bar { transform: scaleY(1); }
.screening-body { flex: 1; display: flex; align-items: center; justify-content: center; position: relative; }
.screening-inner {
  position: relative; width: min(90vw, 1200px); aspect-ratio: 16/9;
  transform: scale(.96) translateY(10px); transition: transform .65s var(--ease-spring);
}
.screening.active .screening-inner { transform: scale(1) translateY(0); }
.screening-inner iframe, .screening-inner .scene-player { position: absolute; inset: 0; width: 100%; height: 100%; border: none; }
.screening-close {
  position: absolute; top: 2rem; right: 2rem; width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid var(--border-light); background: var(--border-faint); color: var(--white);
  display: flex; align-items: center; justify-content: center; font-size: 1rem; cursor: pointer;
  transition: background var(--dur-fast), border-color var(--dur-fast); z-index: 2;
}
.screening-close:hover { border-color: var(--border-strong); background: rgba(237,234,230,.16); }

/* ---------- custom cursor (video hover only) ---------- */
.hero-cursor {
  position: fixed; top: -50px; left: -50px; z-index: var(--z-cursor); width: 100px; height: 100px;
  border-radius: 50%; border: 1px solid rgba(237,234,230,.5); background: rgba(20,17,17,.15);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  pointer-events: none; opacity: 0;
}
.hero-cursor span { font-size: var(--text-label-xs); letter-spacing: .12em; color: var(--white); }
@media (max-width: 940px), (hover: none) { .hero-cursor { display: none; } }

/* ==========================================================================
   PASTED INDIA — full-bleed video occupying the left portion of the
   section (edge-to-edge, no gutter/max-width — same #hero {padding:0}
   pattern below it, not the boxed/aspect-ratio card treatment .film-card
   or .founder-profile-media use), dissolving into the section's own
   background color via .india-media-fade rather than ending at a hard
   vertical seam, with the copy sitting in the plain remaining space —
   pastedseries.com's own "Library" section layout (per reference), rebuilt
   with this site's own type/color system rather than its visual styling.
   Flex, not grid: a hard column split would leave a visible edge where
   the fade should be dissolving into flat background instead — .india-
   media's own right edge already reaches 100% --void by the time it gets
   there, so .india-copy picks up on the same color with nothing to seam
   against. .india-media-info reuses .film-tag/.film-title's own type
   treatment (Production's video-overlay pattern) instead of a new pair of
   styles doing the same job. */
#india { position: relative; display: flex; align-items: center; overflow: hidden; padding: 0; min-height: min(80vh, 720px); }
/* Ambient placeholder footage only, not a real trailer worth opening
   bigger — no data-screening here (unlike .film-frame), so this stays
   a plain autoplay-muted-loop background with no click affordance. */
.india-media { position: relative; flex: 0 0 58%; align-self: stretch; overflow: hidden; background: var(--charcoal); }
.india-video { position: absolute; inset: 0; }
.india-video .scene-player { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.india-media-fade { position: absolute; inset: 0; background: linear-gradient(to right, transparent 0%, transparent 45%, var(--void) 100%); pointer-events: none; }
.india-media-info { position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; padding: 3.4vw; pointer-events: none; }
.india-media-tag { display: block; font-size: var(--text-label-sm); letter-spacing: .12em; color: var(--stone); margin-bottom: .6rem; }
.india-media-title { display: block; font-family: var(--display); font-weight: 400; font-size: var(--text-display-lg); }

.india-copy { flex: 1; padding: 0 var(--gutter) 0 clamp(2rem, 4vw, 4rem); }
/* Eyebrow replaces the old "Request Access" CTA — #education used to be
   a separate section with its own "See Pasted India" link pointing here;
   now that its content lives in this same column, a link back to itself
   is circular, so both collapsed into one plain section-identifying
   label instead of staying a clickable CTA. */
.india-copy-eyebrow { display: block; font-size: var(--text-label-sm); letter-spacing: .12em; color: var(--stone); margin-bottom: 1rem; }
/* --text-display-xl's 8vw clamp is tuned for a full-width .section-head
   heading — in .india-copy's narrower flex column (roughly 40% of the
   viewport, not the whole thing) that read oversized. --text-display-lg
   is the next step down, and also what .india-media-title (the video
   overlay right beside it) already uses, so the two now match in scale. */
.india-copy h2 { font-size: var(--text-display-lg); margin-bottom: 1.2rem; }
.india-copy p { max-width: 480px; font-size: var(--text-body-md); color: var(--stone); line-height: 1.8; font-weight: 300; margin-bottom: 2rem; }
.india-copy-divider { padding-top: 1.6rem; border-top: 1px solid var(--border-faint); }
.india-copy-divider strong { color: var(--white); font-weight: 500; }
/* .india-copy p already carries margin-bottom:2rem, so the CTA below it
   picks up the same rhythm as every other paragraph-to-next-element gap
   in this column for free. */

@media (max-width: 900px) {
  #india { flex-direction: column; align-items: stretch; min-height: 0; }
  .india-media { flex: none; align-self: auto; width: 100%; aspect-ratio: 4/3; }
  .india-media-fade { background: linear-gradient(to bottom, transparent 0%, transparent 45%, var(--void) 100%); }
  /* #india zeroes out the base `section` padding for the desktop split
     (min-height + centering supplies its breathing room there instead) —
     stacked on mobile there's no such min-height cushion, so .india-copy
     has to supply real top/bottom spacing itself, matching the same
     --space-gap-sm tier every other section uses at this width. */
  .india-copy { padding: var(--space-gap-sm) var(--gutter); }
}
@media (max-width: 720px) {
  .india-media-info { padding: 6vw; }
  .india-media-title { font-size: var(--text-display-md); }
}

/* ==========================================================================
   LEGACY / founders — matches pastedseries.com's own founders section:
   name/role plates are overlaid on the portrait itself (name tag hugs its
   own width, role plate spans the full image width beneath it), the grid
   is capped at 1000px so the cards never blow up to hero size, and the
   portrait keeps a true 3/4 crop with a max-height safety cap instead of
   stretching wide and cropping the (square) source photos oddly.
   ========================================================================== */
.legacy-quote { font-family: var(--serif); font-style: italic; font-weight: 400; font-size: var(--text-quote); line-height: 1.24; }

.founders-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-gap-sm); max-width: 1000px; margin: 0 auto; }
@media (max-width: 640px) { .founders-grid { grid-template-columns: 1fr; gap: var(--space-gap-md); } }

.founder-card { display: flex; flex-direction: column; text-decoration: none; color: inherit; }
.founder-portrait { position: relative; aspect-ratio: 3/4; max-height: 540px; overflow: hidden; background: var(--charcoal); filter: grayscale(1); }
.founder-portrait img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform var(--dur-slow) var(--ease-smooth); }
.founder-card:hover .founder-portrait img { transform: scale(1.035); }

.founder-name-bar { position: absolute; bottom: 0; left: 0; right: 0; display: flex; flex-direction: column; }
.founder-name-row { background: var(--void); align-self: flex-start; padding: 1rem 1.5rem; }
.founder-name { font-family: var(--display); font-size: var(--text-section-title); color: var(--white); font-weight: 400; line-height: 1.1; transition: color var(--dur-fast); }
.founder-card:hover .founder-name { color: var(--accent); }
.founder-role-row { background: var(--warm-bg); width: 100%; box-sizing: border-box; padding: .65rem 1.5rem; }
.founder-role { display: block; font-family: var(--sans); font-size: var(--text-label-sm); letter-spacing: .3em; text-transform: uppercase; color: var(--stone); }

.founder-info { padding-top: 1.5rem; }
.founder-line { font-size: var(--text-body-sm); color: var(--stone); line-height: 1.9; margin-bottom: 1rem; }
.founder-quote { font-family: var(--serif); font-style: italic; font-weight: 400; color: var(--stone); font-size: 1.1rem; line-height: 1.6; border-left: 1px solid var(--border-light); padding-left: 1.5rem; }

/* ==========================================================================
   FOUNDER DETAIL — alan-clarke.html / zac-orender.html, each a dedicated
   full-bio page structured like a personal letter: one bordered card holds
   portrait + copy together, a small quote mark at the top stands in for
   "this is their own words," and the page closes with a signature block
   (name + role again, socials alongside it) rather than a stranded link
   row earlier in the page. .reverse flips the image to the right so the
   two founders' pages read as a matched pair, not identical templates.
   ========================================================================== */
.founder-card-frame { border: 1px solid var(--border-light); padding: var(--space-gap-lg); }
.founder-profile-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-gap-xl); align-items: start; }
.founder-profile.reverse .founder-profile-media { order: 2; }
.founder-profile.reverse .founder-profile-copy { order: 1; }
.founder-profile-media { position: relative; aspect-ratio: 4/5; overflow: hidden; background: var(--charcoal); }
.founder-profile-media img { width: 100%; height: 100%; object-fit: cover; filter: saturate(.92) contrast(1.02); }

.founder-profile-role { display: block; font-family: var(--sans); font-size: var(--text-label-sm); letter-spacing: .12em; text-transform: uppercase; color: var(--stone); margin-bottom: 1rem; }
.founder-profile-name { font-size: var(--text-display-xl); margin-bottom: 1.8rem; }
.founder-profile-line { font-size: var(--text-body-lg); color: var(--white); line-height: 1.7; max-width: 640px; margin-bottom: 2rem; }

@media (max-width: 900px) {
  .founder-card-frame { padding: var(--space-gap-sm); }
  .founder-profile-grid { grid-template-columns: 1fr; gap: var(--space-gap-md); }
  .founder-profile.reverse .founder-profile-media, .founder-profile.reverse .founder-profile-copy { order: initial; }
}
.founder-line { margin-top: 1.3rem; font-size: var(--text-body-sm); color: var(--ash); line-height: 1.9; }

.founder-detail-body { max-width: 640px; }
.founder-detail-body p { font-size: var(--text-body-lg); color: var(--stone); line-height: 2; margin-bottom: 1.7rem; }

/* closing line breaks out of the two-column grid entirely (a sibling of
   .founder-profile-grid, not nested inside its copy column) so it can run
   the full width of the card — the mark that used to sit at the top of the
   card now sits here instead, right above the line it's actually marking */
.founder-detail-close-wrap { margin-top: var(--space-gap-md); }
.founder-quote-mark { display: block; font-family: var(--display); font-style: normal; font-size: 4rem; line-height: .6; color: var(--stone); margin-bottom: 1rem; }
.founder-detail-close { font-family: var(--serif); font-style: italic; font-weight: 400; color: var(--white); font-size: var(--text-quote); line-height: 1.4; }

/* signature — closes the letter: a divider, then name + role again, with
   the (placeholder-for-now) social links sitting beside it. Also a sibling
   of the grid now, so it spans the full card width to match the close line
   above it rather than snapping back to half-width. */
.founder-signature { margin-top: var(--space-gap-md); padding-top: 1.8rem; border-top: 1px solid var(--border-faint); display: flex; justify-content: space-between; align-items: flex-end; flex-wrap: wrap; gap: 1.5rem; }
.founder-signature-name { font-family: var(--display); font-size: 1.15rem; color: var(--white); }
.founder-signature-role { font-size: var(--text-body-xs); letter-spacing: .08em; text-transform: uppercase; color: var(--ash); margin-top: .3rem; }
.founder-detail-socials { display: flex; gap: 1.8rem; }
.founder-detail-socials a {
  font-family: var(--sans); font-size: var(--text-body-xs); letter-spacing: .1em; text-transform: uppercase;
  color: var(--stone); text-decoration: none; transition: color var(--dur-fast);
}
.founder-detail-socials a:hover { color: var(--accent); }

.founder-footer-section { padding-top: 0; }
/* .footer-ticker's own top margin exists to separate it from the CTA block
   that normally precedes it (see #contact) — here it's the section's first
   child, so that margin was just dead space at the very top of an
   otherwise-empty section */
.founder-footer-section .footer-ticker { margin-top: 0; }

/* ==========================================================================
   PH STUDIO — consolidating mosaic roster. Same architecture as the Production
   film scene (js/animations.js, initFilmScene): a tall #phstudio-scene runway
   + position:sticky #phstudio-stage, no ScrollTrigger pin — the browser owns
   the stage's positioning throughout, so there's no relative->fixed handoff
   at engage or release for ScrollTrigger (or the user) to notice.
   ========================================================================== */
/* No overflow:hidden here (there was one; removed). It's harmless under a
   ScrollTrigger pin (position:fixed ignores ancestor overflow entirely) but
   it silently breaks position:sticky on a descendant — any ancestor that
   restricts overflow becomes sticky's containing scroll box, and #phstudio
   itself doesn't scroll independently, so #phstudio-stage's stickiness was
   computed against a box that can't ever satisfy it and just never stuck.
   #phstudio-stage already has its own overflow:hidden to contain the
   scattered roster cards within its own 100vh box, so nothing here relied
   on the section-level rule for actual clipping. */
#phstudio-scene {
  position: relative; margin-top: 2.5rem;
  /* 100vh for #phstudio-stage + 180vh of scrub distance — matches the
     original ScrollTrigger pin's end:'+=180%' pacing. */
  height: 280vh;
}
/* .static is added by initPHStudioRoster() (js/animations.js) itself, in
   lockstep with the same reducedMotion()/isMobile() check that skips
   creating the ScrollTrigger entirely — not a separate CSS breakpoint that
   could drift out of sync with it. */
#phstudio-scene.static { height: auto; }
#phstudio-stage { position: sticky; top: 0; width: 100%; height: 100vh; overflow: hidden; background: var(--void); z-index: 20; }
#phstudio-cards { position: absolute; inset: 0; }
.roster-card {
  position: absolute; left: 50%; top: 50%; width: 168px; height: 236px; margin: -118px 0 0 -84px;
  border-radius: 4px; overflow: hidden; background: var(--charcoal); border: 1px solid var(--border-light);
  box-shadow: 0 20px 50px rgba(0,0,0,.4); will-change: transform, opacity;
}
.roster-card img { width: 100%; height: 100%; object-fit: cover; display: block; }
@media (max-width: 720px) { .roster-card { width: 116px; height: 164px; margin: -82px 0 0 -58px; } }

#phstudio-seat-text { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); text-align: center; opacity: 0; z-index: 3; width: 90%; pointer-events: none; }
.st-title { font-family: var(--display); font-size: var(--text-display-xxl); color: var(--white); line-height: .96; }

/* static fallback — mobile / reduced-motion: normal grid, no pin, no absolute scatter */
#phstudio-stage.static { position: static; height: auto; overflow: visible; }
#phstudio-cards.static {
  position: relative; inset: auto; display: grid; grid-template-columns: repeat(4, 1fr); gap: .6rem; padding: 0 var(--gutter) var(--space-gap-md);
}
@media (max-width: 640px) { #phstudio-cards.static { grid-template-columns: repeat(3, 1fr); } }
#phstudio-cards.static .roster-card { position: static; margin: 0; width: 100%; height: auto; aspect-ratio: 3/4; opacity: 1; transform: none; }
#phstudio-seat-text.static { position: relative; left: auto; top: auto; transform: none; opacity: 1; padding: var(--space-gap-md) var(--gutter) 0; }

/* ==========================================================================
   CONTACT / FOOTER
   ========================================================================== */
#contact { text-align: center; padding-top: var(--space-section); }
.cta-title { font-family: var(--display); font-size: var(--text-display-xl); }
.cta-sub { margin: 1.6rem auto 2.8rem; max-width: 480px; font-size: var(--text-body-md); color: var(--stone); line-height: 1.9; }

/* Real gaps, not the hairline-background trick some other grids on this
   page used to use (reel-grid was already moved off it). .partner-card
   itself is deliberately styled to match .process-card (Intersection
   section) exactly — same warm-bg/border/shadow container, same
   --text-display-md heading size and --stone/1.9 body treatment — so the
   two card patterns read as one consistent card language, not two. */
.partner-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; margin-top: var(--space-gap-lg); text-align: left; }
@media (max-width: 820px) { .partner-grid { grid-template-columns: 1fr; } }
@media (max-width: 968px) { .partner-grid { margin-top: var(--space-gap-sm); } }
.partner-card {
  display: flex; flex-direction: column; align-items: flex-start;
  background: var(--warm-bg); border: 1px solid var(--border-light);
  box-shadow: 0 30px 70px rgba(0,0,0,.45); padding: 2.6rem 2.4rem;
}
.partner-card h3 { font-size: var(--text-display-md); margin-bottom: 1.2rem; }
.partner-card p { font-size: var(--text-body-sm); color: var(--stone); line-height: 1.9; max-width: 34ch; }
.partner-card .btn { margin-top: 1.8rem; width: 100%; justify-content: center; }
@media (max-width: 720px) {
  .partner-card { padding: 2rem 1.8rem; }
}

.footer-ticker { margin-top: var(--space-gap-xl); border-top: 1px solid var(--border-faint); padding: 1.4rem 0; overflow: hidden; white-space: nowrap; }

footer { padding: var(--space-section-sm) var(--gutter) var(--space-gap-md); background: var(--void); text-align: center; }
.footer-inner { max-width: var(--max-w); margin: 0 auto; }
.footer-logo { width: 72px; height: 72px; margin: 0 auto 1.8rem; }
.footer-tagline { font-size: var(--text-body-lg); letter-spacing: .04em; color: var(--stone); line-height: 1.9; margin-bottom: var(--space-gap-md); }
.footer-nav { display: flex; justify-content: space-between; gap: 6rem; margin-bottom: var(--space-gap-md); flex-wrap: wrap; }
@media (max-width: 640px) { .footer-nav { flex-direction: column; align-items: center; gap: 2.4rem; } }
.footer-col { text-align: center; }
.footer-col h4 { font-family: var(--sans); font-weight: 500; font-size: var(--text-body-md); letter-spacing: .1em; color: var(--ash); margin-bottom: 1rem; }
.footer-col a { display: block; font-size: var(--text-body-lg); color: var(--white-faded); text-decoration: none; margin-bottom: .6rem; letter-spacing: .01em; }
.footer-col a:hover { color: var(--white); }
.footer-divider { max-width: var(--max-w); background: var(--border-subtle); height: 1px; margin: 0 auto 1.6rem; }
.footer-bottom { max-width: var(--max-w); margin: 0 auto; display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; font-size: var(--text-body-sm); color: var(--ash); letter-spacing: .06em; }
@media (max-width: 640px) { .footer-bottom { flex-direction: column; align-items: center; text-align: center; gap: .6rem; } }
.footer-coords { font-family: monospace; letter-spacing: .1em; }

/* ---------- prefers-reduced-motion (final override, highest specificity) ---------- */
@media (prefers-reduced-motion: reduce) {
  .preloader { display: none; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .kinetic .ch { opacity: 1; transform: none; transition: none; }
  .hero-mask, .scene-mask { clip-path: none !important; }
  .grain { display: none; }
}
