/* Cinematic project chapters
   One object, one film, one live record at a time. The film carries atmosphere;
   every name, claim, proof point, and action remains semantic HTML. */

:root {
  --cinema-black: var(--ivory, #FAF4E8);
  --cinema-soot: #F1E8D8;
  --cinema-ivory: var(--ink, #2B1F14);
  --cinema-muted: rgba(43, 31, 20, .72);
  --cinema-line: rgba(43, 31, 20, .14);
  --cinema-amber: var(--amber, #C46A2B);
  /* Amber as small text on the ivory cinema ground fails AA (3.2:1); this is
     the darker text cut that clears 4.5:1. Keep raw amber for graphics. */
  --cinema-amber-text: var(--amber-text, #9E5115);
  --cinema-steel: #7A6959;
}

/* The legacy paper rooms give the persistent header a cream ground. Inside the
   cinema the same controls ride a dark neutral veil, preserving contrast
   without introducing a bright band above the film. */
body.cinematic-surface-active header,
body.cinematic-surface-active header.on-light {
  color: var(--cinema-ivory);
}

body.cinematic-surface-active header::before,
body.cinematic-surface-active header.on-light::before {
  background: linear-gradient(to bottom, rgba(7, 7, 6, .96) 0%, rgba(7, 7, 6, .82) 46%, rgba(7, 7, 6, 0) 100%);
}

body.cinematic-surface-active header .hx-num,
body.cinematic-surface-active header.on-light .hx-num {
  color: var(--cinema-amber);
}

body.cinematic-surface-active #project-assistant {
  opacity: 0;
  transform: translate3d(0, .75rem, 0);
  pointer-events: none;
}

/* ---------- Project Selector ----------
   Replaces the legacy intro text and horizontal chapter rail with a
   selector-first experience. */

.cinematic-selector {
  padding: clamp(7rem, 14vh, 10rem) clamp(1.2rem, 5vw, 4rem) clamp(5rem, 10vh, 8rem);
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: clamp(2.8rem, 7vh, 5rem);
}

.cinematic-selector-header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(18rem, 32rem);
  gap: 1rem clamp(2rem, 8vw, 9rem);
  width: 100%;
  max-width: none;
  align-items: end;
}

.cinematic-selector-header .cinematic-kicker {
  grid-column: 1 / -1;
  color: var(--cinema-amber-text);
  font: 600 .75rem/1 var(--sans);
  letter-spacing: .12em;
  text-transform: uppercase;
  margin: 0 0 1rem;
}

.cinematic-selector-header h2 {
  max-width: 12ch;
  color: var(--cinema-ivory);
  font: 400 clamp(2.4rem, 6vw, 4.2rem)/1.05 var(--serif);
  letter-spacing: -.02em;
  margin: 0 0 1.6rem;
}

.cinematic-selector-header .cinematic-intro-note {
  align-self: end;
  color: var(--cinema-muted);
  font: 400 clamp(1rem, 1.8vw, 1.15rem)/1.5 var(--sans);
  max-width: 38rem;
}

.cinematic-selector-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(2rem, 4vw, 4rem) clamp(1.5rem, 3vw, 3rem);
  width: 100%;
}

@media (min-width: 641px) {
  .cinematic-card[data-featured="true"] {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: minmax(0, 1.55fr) minmax(16rem, .45fr);
    align-items: end;
    gap: clamp(1.5rem, 4vw, 4rem);
  }

  .cinematic-card:nth-child(even) {
    margin-top: clamp(4rem, 12vw, 10rem);
  }
}

.cinematic-card {
  display: flex;
  flex-direction: column;
  gap: 1.2rem;
  background: transparent;
  border: none;
  padding: 0;
  text-align: left;
  cursor: pointer;
  color: var(--cinema-ivory);
  /* Keep vertical trackpad/touch scrolling while the cursor is over cards. */
  touch-action: pan-y;
  transition: transform .4s cubic-bezier(0.16, 1, 0.3, 1);
}

.cinematic-card:focus-visible {
  outline: 2px solid var(--cinema-amber);
  outline-offset: 6px;
}

.cinematic-card[aria-selected="true"] .cinematic-card-title {
  color: var(--cinema-amber-text);
}

.cinematic-card-bg {
  position: relative;
  width: 100%;
  aspect-ratio: 16/9;
  border-radius: 16px;
  overflow: hidden;
  background: var(--cinema-soot);
}

.cinematic-card-bg video {
  position: absolute;
  top: -10%;
  left: 0;
  width: 100%;
  height: 120%;
  object-fit: cover;
  transition: transform 1s cubic-bezier(0.16, 1, 0.3, 1);
}

.cinematic-card:hover .cinematic-card-bg video,
.cinematic-card:focus-visible .cinematic-card-bg video {
  transform: scale(1.05);
}

.cinematic-card-bg i {
  display: none; /* No scrim needed since text is below */
}

.cinematic-card-content {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  width: 100%;
}

.cinematic-card-cat {
  font: 500 .75rem/1.3 var(--sans);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--cinema-muted);
}

.cinematic-card-proof {
  display: block;
  margin-top: .4rem;
  color: var(--cinema-muted);
  font: 500 clamp(.76rem, .9vw, .88rem)/1.45 var(--sans);
}

.cinematic-card-start {
  display: none;
  width: max-content;
  margin-bottom: .35rem;
  padding: .35rem .55rem;
  color: var(--ivory);
  background: var(--cinema-amber-text);
  font: 600 .65rem/1 var(--sans);
  letter-spacing: .09em;
  text-transform: uppercase;
}

.cinematic-card[data-featured="true"] .cinematic-card-start {
  display: inline-flex;
}

.cinematic-card-title {
  font: 400 clamp(2rem, 3vw, 2.8rem)/1.1 var(--sans); /* Reference uses sans-serif for title */
  letter-spacing: -0.02em;
  margin: 0;
}

.cinematic-card-num {
  display: none; /* Hide number to match reference cleanly */
}

/* ---------- State Visibility ---------- */
#projects:not(.is-project-active) #cinematic-active-stage {
  display: none;
}

#projects.is-project-active .cinematic-selector {
  display: none;
}

/* ---------- Active Stage Full-Screen Takeover ---------- */
/* When a project is open, #projects becomes a full-viewport fixed panel
   sitting above the paper sheet (z-index 3), header (z-index 50), and
   everything else. Body scroll is locked by JS. */
#projects.is-project-active {
  position: fixed !important;
  inset: 0 !important;
  z-index: 200 !important;
  width: 100vw !important;
  height: 100vh !important;
  overflow: hidden !important;
  touch-action: none;
  min-height: unset !important;
}

/* ---------- Active Stage UI ---------- */
#cinematic-active-stage {
  position: relative;
  width: 100%;
  height: 100vh !important;
  overflow: hidden !important;
}

.cinematic-stage-controls {
  position: fixed;
  top: clamp(1.2rem, 4vh, 2.5rem);
  left: 50%;
  transform: translateX(-50%);
  z-index: 9999 !important;
  pointer-events: none;
}

.cinematic-return-control {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: .6rem;
  min-height: 44px;
  background: rgba(250, 244, 232, .9);
  backdrop-filter: blur(12px) saturate(.85);
  -webkit-backdrop-filter: blur(12px) saturate(.85);
  border: 1px solid rgba(43, 31, 20, .22);
  color: var(--cinema-ivory);
  font: 500 .8rem/1 var(--sans);
  padding: .7rem 1rem;
  border-radius: 2rem;
  box-shadow: 0 12px 30px -20px rgba(43, 31, 20, .65);
  cursor: pointer;
  transition: background .2s, border-color .2s, transform .2s;
  text-decoration: none;
}

.cinematic-return-control:hover,
.cinematic-return-control:focus-visible {
  background: var(--ivory);
  border-color: var(--cinema-amber-text);
  transform: translateY(-1px);
  outline: 2px solid var(--cinema-amber);
  outline-offset: 3px;
}

.cinematic-return-control i::before {
  content: "←";
}

@media (max-width: 640px) {
  .cinematic-selector {
    padding-top: 6.5rem;
  }

  .cinematic-selector-header {
    grid-template-columns: 1fr;
  }

  .cinematic-selector-grid {
    grid-template-columns: 1fr;
    min-width: 0;
  }
  .cinematic-card {
    width: 100%;
    min-width: 0;
  }
}


#projects.cinematic-projects {
  position: relative;
  z-index: 2;
  min-height: 100svh;
  margin: 0;
  padding: 0;
  color: var(--cinema-ivory);
  background: var(--cinema-black);
  overflow: clip;
}

#projects.cinematic-projects::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: .18;
  background:
    radial-gradient(circle at 80% 8%, rgba(223, 140, 66, .16), transparent 22rem),
    linear-gradient(90deg, transparent 0 7%, rgba(255, 255, 255, .025) 7.05%, transparent 7.1% 92%, rgba(255, 255, 255, .025) 92.05%, transparent 92.1%);
}


.cinematic-project {
  --chapter-progress: 0;
  --film-opacity: 1;
  position: relative;
  height: 220svh;
  min-height: 1120px;
  background: var(--cinema-black);
  isolation: isolate;
}

#projects.is-project-active .cinematic-project,
#projects.is-project-active .cinematic-project-stage {
  height: 100vh !important;
  min-height: 100vh !important;
  max-height: 100vh !important;
  overflow: hidden !important;
}

.cinematic-project + .cinematic-project {
  margin-top: -1px;
}

.cinematic-project-stage {
  position: sticky;
  top: 0;
  height: 100svh;
  min-height: 620px;
  overflow: hidden;
  background: var(--cinema-soot);
}

.cinematic-project-media,
.contact-passage-media {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #090908;
}

.cinematic-project-media img,
.cinematic-project-media video,
.contact-passage-media img,
.contact-passage-media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cinematic-project-media img,
.contact-passage-media img {
  opacity: 1;
  transition: opacity .45s ease;
}

.cinematic-project.is-video-ready .cinematic-project-media img,
.contact-passage.is-video-ready .contact-passage-media img {
  opacity: 0;
}

.cinematic-project-media video,
.contact-passage-media video {
  opacity: var(--film-opacity);
  transform: translateZ(0);
  backface-visibility: hidden;
}

.cinematic-project-scrim,
.contact-passage-scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(90deg, rgba(250, 244, 232, .96) 0%, rgba(250, 244, 232, .86) 28%, rgba(250, 244, 232, .32) 58%, rgba(250, 244, 232, .12) 80%, rgba(250, 244, 232, .36) 100%),
    linear-gradient(0deg, rgba(250, 244, 232, .9), transparent 26% 74%, rgba(250, 244, 232, .55));
}

.cinematic-project-grain,
.contact-passage-grain {
  position: absolute;
  inset: -30%;
  pointer-events: none;
  opacity: .045;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.88' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.8'/%3E%3C/svg%3E");
  transform: translate3d(calc(var(--chapter-progress) * -2%), calc(var(--chapter-progress) * 1.5%), 0);
  will-change: transform;
}

.cinematic-project-copy {
  --beat-position: 0;
  position: relative;
  z-index: 3;
  width: min(44rem, 48vw);
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(6.5rem, 13vh, 9rem) 0 clamp(5.5rem, 9vh, 7rem) clamp(1.25rem, 6vw, 6.5rem);
  transform: translate3d(0, calc(var(--chapter-progress) * -45px), 0);
  will-change: transform;
}

.cinematic-project-meta {
  display: flex;
  align-items: center;
  gap: .9rem;
  margin-bottom: clamp(1rem, 2.4vh, 1.8rem);
  color: var(--cinema-amber);
}

.cinematic-project-meta span:last-child {
  color: var(--cinema-muted);
}

.cinematic-project-meta::before {
  content: "";
  width: 2.4rem;
  height: 1px;
  background: var(--cinema-amber);
}

.cinematic-project h3 {
  max-width: 9.5ch;
  font: 600 clamp(3rem, 6vw, 6rem)/.86 var(--serif);
  letter-spacing: -.04em;
  text-wrap: balance;
}

.cinematic-project-lede {
  max-width: 33rem;
  margin-top: clamp(1.3rem, 3vh, 2.2rem);
  font: 400 clamp(1rem, 1.2vw, 1.16rem)/1.5 var(--sans);
  color: var(--cinema-muted);
}

/* The beats are stacked in one grid cell rather than positioned absolutely, so
   the container reserves the height of the TALLEST beat instead of a fixed
   min-height. With a fixed one, a beat whose paragraph wrapped to three lines
   on a narrow phone overflowed and printed straight over the proof row below —
   44-70px of text on text at 360-390px wide. Grid keeps the crossfade (every
   beat still shares the same cell) and the rail below stays absolute. */
.cinematic-beats {
  position: relative;
  display: grid;
  /* The copy column is a flex column; without this the beats box is allowed to
     shrink below its own content and spill over the proof row again at 360px. */
  flex-shrink: 0;
  min-height: 7.5rem;
  max-width: 34rem;
  margin-top: clamp(2rem, 5vh, 3.75rem);
  padding-left: 2.8rem;
}

.cinematic-beats::before,
.cinematic-beats::after {
  content: "";
  position: absolute;
  left: .35rem;
  pointer-events: none;
}

.cinematic-beats::before {
  top: .35rem;
  bottom: .35rem;
  width: 1px;
  background: var(--cinema-line);
}

.cinematic-beats::after {
  top: .35rem;
  width: .55rem;
  height: .55rem;
  border: 2px solid var(--cinema-black);
  border-radius: 50%;
  background: var(--cinema-amber);
  transform: translate3d(-.25rem, calc(var(--beat-position) * 6.25rem), 0);
  transition: transform .52s cubic-bezier(.16, 1, .3, 1);
  box-shadow: 0 .18rem .7rem rgba(122, 55, 14, .24);
}

.cinematic-project[data-beat="1"] .cinematic-project-copy {
  --beat-position: .5;
}

.cinematic-project[data-beat="2"] .cinematic-project-copy {
  --beat-position: 1;
}

.cinematic-beat {
  grid-area: 1 / 1;
  opacity: 0;
  clip-path: inset(0 0 100% 0);
  transform: translate3d(0, .8rem, 0);
  transition:
    opacity .26s ease,
    clip-path .5s cubic-bezier(.16, 1, .3, 1),
    transform .5s cubic-bezier(.16, 1, .3, 1);
  pointer-events: none;
}

.cinematic-project[data-beat="0"] .cinematic-beat:nth-child(1),
.cinematic-project[data-beat="1"] .cinematic-beat:nth-child(2),
.cinematic-project[data-beat="2"] .cinematic-beat:nth-child(3) {
  opacity: 1;
  clip-path: inset(0 0 0 0);
  transform: translate3d(0, 0, 0);
}

.cinematic-beat-index {
  display: block;
  margin-bottom: .75rem;
  color: var(--cinema-amber);
  font: 600 .66rem/1 var(--sans);
  letter-spacing: .13em;
}

.cinematic-beat h4 {
  margin-bottom: .55rem;
  font: 500 clamp(1.3rem, 1.8vw, 1.7rem)/1.08 var(--serif);
  letter-spacing: -.03em;
  text-wrap: balance;
}

.cinematic-beat p {
  max-width: 31rem;
  font: 400 clamp(.9rem, 1vw, .98rem)/1.5 var(--sans);
  color: var(--cinema-muted);
}

.cinematic-project-proof {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  max-width: 39rem;
  gap: 1rem;
  margin-top: auto;
  padding-top: 1.3rem;
  border-top: 1px solid var(--cinema-line);
  opacity: .72;
  transition: opacity .4s ease;
}

.cinematic-project.is-final .cinematic-project-proof {
  opacity: 1;
}

.cinematic-project-proof div {
  min-width: 0;
}

.cinematic-project-proof dt {
  margin-bottom: .45rem;
  color: var(--cinema-steel);
}

.cinematic-project-proof dd {
  font: 500 .83rem/1.35 var(--sans);
  color: var(--cinema-ivory);
}

/* Proof links stay reachable from the first beat — a scanning visitor should
   never have to finish the film to reach the App Store. The final beat only
   brightens them. */
.cinematic-project-actions {
  display: flex;
  align-items: center;
  gap: .8rem;
  margin-top: 1.35rem;
  opacity: .88;
  transition: opacity .35s ease;
}

.cinematic-project.is-final .cinematic-project-actions {
  opacity: 1;
}

.cinematic-project-actions a {
  display: inline-flex;
  min-height: 2.8rem;
  align-items: center;
  justify-content: center;
  padding: .75rem 1rem;
  border: 1px solid var(--cinema-line);
  color: var(--cinema-ivory);
  font: 600 .72rem/1 var(--sans);
  letter-spacing: .12em;
  text-decoration: none;
  text-transform: uppercase;
  transition: color .2s ease, border-color .2s ease, background-color .2s ease;
}

.cinematic-project-actions a:first-child {
  color: #130d08;
  border-color: var(--cinema-amber);
  background: var(--cinema-amber);
}

.cinematic-project-actions a:hover,
.cinematic-project-actions a:focus-visible {
  color: #130d08;
  border-color: var(--cinema-ivory);
  background: var(--cinema-ivory);
}

.cinematic-project-progress {
  position: absolute;
  z-index: 4;
  right: clamp(1.25rem, 3vw, 3.5rem);
  bottom: clamp(1.25rem, 4vh, 2.6rem);
  left: clamp(1.25rem, 6vw, 6.5rem);
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 1rem;
  align-items: center;
  color: var(--cinema-muted);
  font: 600 .62rem/1 var(--sans);
  letter-spacing: .14em;
  text-transform: uppercase;
}

.cinematic-project-progress i {
  height: 1px;
  overflow: hidden;
  background: var(--cinema-line);
}

.cinematic-project-progress i::after {
  content: "";
  display: block;
  width: 100%;
  height: 100%;
  background: var(--cinema-amber);
  transform: scaleX(var(--chapter-progress));
  transform-origin: left center;
  will-change: transform;
}

.cinematic-project.is-active .cinematic-project-progress {
  color: var(--cinema-ivory);
}

.contact-passage {
  --chapter-progress: 0;
  --film-opacity: 1;
  position: relative;
  z-index: 5;
  height: 115svh;
  min-height: 700px;
  padding: 0;
  color: var(--cinema-ivory);
  background: var(--cinema-black);
}

.contact-passage-stage {
  position: sticky;
  top: 0;
  height: 100svh;
  min-height: 620px;
  overflow: hidden;
}

.contact-passage-scrim {
  background:
    linear-gradient(90deg, rgba(5, 5, 4, .88), rgba(5, 5, 4, .62) 35%, rgba(5, 5, 4, .08) 68%),
    linear-gradient(0deg, rgba(5, 5, 4, .86), transparent 34%);
}

.contact-passage-copy {
  position: relative;
  z-index: 3;
  height: 100%;
  width: min(42rem, 52vw);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 7rem 0 6rem clamp(1.25rem, 6vw, 6.5rem);
}

.contact-passage-kicker {
  margin-bottom: 1.3rem;
  color: var(--cinema-amber);
}

.contact-passage h2 {
  max-width: 9ch;
  font: 600 clamp(3.4rem, 7vw, 6rem)/.88 var(--serif);
  letter-spacing: -.04em;
  text-wrap: balance;
}

.contact-passage-copy p {
  max-width: 31rem;
  margin-top: 1.5rem;
  color: var(--cinema-muted);
  font: 400 clamp(1rem, 1.3vw, 1.2rem)/1.5 var(--sans);
}

.contact-passage-continuation {
  position: absolute;
  z-index: 4;
  right: clamp(1.25rem, 4vw, 4rem);
  bottom: clamp(1.5rem, 5vh, 3.5rem);
  color: var(--cinema-ivory);
  font: 600 .68rem/1 var(--sans);
  letter-spacing: .16em;
  text-transform: uppercase;
}

/* Text exit: copy and continuation slide up and fade as --passage-text-exit → 1.
   A cubic easing is built into the calc: the first 60% of the variable travels
   through the initial ease, snapping fully gone before the film takes over. */
.contact-passage-copy,
.contact-passage-continuation {
  will-change: transform, opacity;
  transform: translateY(calc(var(--passage-text-exit, 0) * -52px));
  opacity: calc(1 - var(--passage-text-exit, 0));
  transition: none; /* driven by scroll, not by CSS transition */
}

.contact-passage-seal {
  position: absolute;
  z-index: 4;
  right: clamp(1.25rem, 6vw, 6.5rem);
  top: 50%;
  transform: translateY(-50%);
  width: 54px;
  height: 54px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--cinema-amber);
  color: #0d0905;
  font: 700 .75rem/1 var(--sans);
  letter-spacing: .14em;
  text-transform: uppercase;
  opacity: calc(var(--passage-text-exit, 0) * (1 - var(--passage-text-exit, 0)) * 4);
  pointer-events: none;
  transition: none;
}

@media (max-width: 820px) {
  .cinematic-projects-intro {
    min-height: 70svh;
    grid-template-columns: 1fr;
    gap: 2.4rem;
    padding-top: 8rem;
  }

  .cinematic-projects-intro h2 {
    font-size: clamp(3.4rem, 15vw, 6.4rem);
  }

  .cinematic-project {
    /* Mobile changes the film scrim from ivory to near-black so the frame can
       carry the full viewport. Give that surface its own foreground tokens;
       inheriting the desktop ink palette made every record unreadable. */
    --cinema-black: #050504;
    --cinema-soot: #090908;
    --cinema-ivory: #FAF4E8;
    --cinema-muted: rgba(250, 244, 232, .78);
    --cinema-line: rgba(250, 244, 232, .22);
    --cinema-steel: #D4C8B6;
    color: var(--cinema-ivory);
    height: 165svh;
    min-height: 920px;
  }

  .cinematic-project-stage,
  .contact-passage-stage {
    min-height: 560px;
  }

  .cinematic-project-media img,
  .cinematic-project-media video,
  .contact-passage-media img,
  .contact-passage-media video {
    object-position: 61% center;
  }

  .cinematic-project-scrim {
    background:
      linear-gradient(0deg, rgba(5, 5, 4, .96) 0%, rgba(5, 5, 4, .78) 42%, rgba(5, 5, 4, .12) 74%),
      linear-gradient(90deg, rgba(5, 5, 4, .66), transparent 80%);
  }

  .cinematic-project-copy {
    width: 100%;
    justify-content: flex-end;
    padding: 5.5rem 1.25rem 5.2rem;
  }

  .cinematic-project h3 {
    max-width: 11ch;
    font-size: clamp(2.85rem, 13vw, 5.6rem);
  }

  .cinematic-project-lede {
    max-width: 34rem;
    margin-top: 1rem;
    font-size: .96rem;
  }

  .cinematic-beats {
    min-height: 7.2rem;
    margin-top: 1.35rem;
    padding-left: 2.35rem;
  }

  .cinematic-beat h4 {
    font-size: clamp(1.25rem, 5.8vw, 1.65rem);
  }

  .cinematic-beat p {
    max-width: 29rem;
    font-size: .86rem;
  }

  .cinematic-project-proof {
    max-width: none;
    gap: .75rem;
    margin-top: 1.15rem;
  }

  .cinematic-project-progress {
    right: 1.25rem;
    bottom: 1.2rem;
    left: 1.25rem;
  }

  /* The copy is bottom-aligned on a phone, so the return pill takes the free
     top-left gutter rather than floating over the title. */
  .cinematic-stage-controls {
    top: 1.2rem;
    left: 1.25rem;
    transform: none;
  }

  .contact-passage {
    height: 160svh;
    min-height: 880px;
  }

  .contact-passage-scrim {
    background: linear-gradient(0deg, rgba(5, 5, 4, .94), rgba(5, 5, 4, .48) 60%, rgba(5, 5, 4, .1));
  }

  .contact-passage-copy {
    width: 100%;
    justify-content: flex-end;
    padding: 5rem 1.25rem 7rem;
  }
}

@media (max-width: 520px) {
  /* On a short, narrow phone the copy column is taller than the viewport, and a
     flex-end column overflows past its own padding — so the chapter meta line
     rides up into the top band. Collapse the return control to its arrow there:
     44px square in the right gutter clears the meta text at every beat, and the
     button keeps its aria-label so the affordance is unchanged. */
  .cinematic-stage-controls {
    left: auto;
    right: 1.25rem;
  }

  .cinematic-return-control {
    justify-content: center;
    gap: 0;
    min-width: 44px;
    padding: .7rem;
  }

  .cinematic-return-control span {
    display: none;
  }

  .cinematic-project-proof dd {
    font-size: .72rem;
  }

  .cinematic-project-actions {
    gap: .55rem;
  }

  .cinematic-project-actions a {
    min-height: 2.55rem;
    padding: .65rem .75rem;
    font-size: .6875rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cinematic-projects-intro {
    min-height: auto;
  }

  .cinematic-project,
  .contact-passage {
    height: auto;
    min-height: auto;
  }

  .cinematic-project-stage,
  .contact-passage-stage {
    position: relative;
    top: auto;
    height: auto;
    min-height: 760px;
  }

  .cinematic-project-media video,
  .contact-passage-media video {
    display: none;
  }

  .cinematic-project-grain,
  .contact-passage-grain {
    transform: none;
  }

  .cinematic-beats {
    position: static;
    display: grid;
    gap: 1rem;
    min-height: auto;
  }

  .cinematic-beat {
    grid-area: auto;
    position: static;
    opacity: 1;
    clip-path: none;
    transform: none;
    pointer-events: auto;
  }

  #projects.is-project-active .cinematic-project-stage {
    overflow-y: auto !important;
  }

  #projects.is-project-active .cinematic-project-copy {
    height: auto;
    min-height: 100%;
    justify-content: flex-start;
  }

  .cinematic-beats::before,
  .cinematic-beats::after {
    display: none;
  }

  .cinematic-project-actions {
    opacity: 1;
    visibility: visible;
    transform: none;
    pointer-events: auto;
  }

  .cinematic-project-progress {
    display: none;
  }
}

/* Deterministic capture/QA route: `?motion=reduce` mirrors the operating-system
   preference without changing the default experience. */
html.cinematic-reduced .cinematic-projects-intro {
  min-height: auto;
}

html.cinematic-reduced .cinematic-project,
html.cinematic-reduced .contact-passage {
  height: auto;
  min-height: auto;
}

html.cinematic-reduced .cinematic-project-stage,
html.cinematic-reduced .contact-passage-stage {
  position: relative;
  top: auto;
  height: auto;
  min-height: 760px;
}

html.cinematic-reduced .cinematic-project-media video,
html.cinematic-reduced .contact-passage-media video {
  display: none;
}

html.cinematic-reduced .cinematic-project-grain,
html.cinematic-reduced .contact-passage-grain {
  transform: none;
}

html.cinematic-reduced .cinematic-beats {
  position: static;
  display: grid;
  gap: 1rem;
  min-height: auto;
}

html.cinematic-reduced .cinematic-beat {
  grid-area: auto;
  position: static;
  opacity: 1;
  clip-path: none;
  transform: none;
  pointer-events: auto;
}

html.cinematic-reduced #projects.is-project-active .cinematic-project-stage {
  overflow-y: auto !important;
}

html.cinematic-reduced #projects.is-project-active .cinematic-project-copy {
  height: auto;
  min-height: 100%;
  justify-content: flex-start;
}

html.cinematic-reduced .cinematic-beats::before,
html.cinematic-reduced .cinematic-beats::after {
  display: none;
}

html.cinematic-reduced .cinematic-project-actions {
  opacity: 1;
  visibility: visible;
  transform: none;
  pointer-events: auto;
}

html.cinematic-reduced .cinematic-project-progress {
  display: none;
}

/* ---------- Horizontal Slide: article transition inside fixed overlay ---------- */
/* Articles flow normally inside the fixed #projects scroll container.
   During a slide, GSAP translates them on the X axis. We need to clip
   the overflow so the outgoing article doesn't show outside the panel. */
#projects.is-project-active #cinematic-active-stage {
  overflow: hidden;
  /* Give the stage a defined height so absolute-positioned slide twins work */
  position: relative;
}

/* Body scroll lock when project is fullscreen */
body.project-open {
  overflow: hidden;
}

/* An open record is a fullscreen mode with page scroll locked, so the persistent
   header's in-page anchors cannot go anywhere — and because it is a full-width
   band pinned over the film, its contact link sat on top of the "All projects"
   pill and swallowed the tap on a phone, leaving no way out of the reel. Retire
   it for the duration and let the return control own the top band. Uses
   visibility, not just opacity, so its links leave the tab order too — a
   keyboard visitor must not be able to focus a header they cannot see. */
body.project-open header {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .3s ease, visibility .3s ease;
}
