html { overflow-x: hidden; overflow-x: clip; }
body { max-width: 100%; overflow-x: hidden; overflow-x: clip; }
.home-story, .story-stage { position: relative; }
.home-story { isolation: isolate; overflow-anchor: none; }
.page-home .site-header nav a::after { display: none; }

/* lvh, not svh: the film fills the screen when mobile toolbars collapse (Risetex finding). */
#hero, #stage { height: 100lvh; min-height: 560px; }
#hero { position: relative; }
#stage { position: relative; overflow: hidden; background: var(--paper); }
.hero-poster, #film-canvas { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
#film-canvas { visibility: hidden; background: #fff; }
.film-ready #film-canvas { visibility: visible; }
.film-ready .hero-poster { visibility: hidden; }

/* While frames load: a blank white hold with only the progress bar, and no scrolling.
   The owner's call (2026-09-27), made knowing the cost: a blank screen is not content, so Lighthouse's
   largest paint waits for the film to start. Holding on the first frame instead scored 100 on mobile;
   do not change it back without asking. */
.film-loading { position: absolute; z-index: 4; right: var(--gutter); bottom: calc(100lvh - 100svh + 38px + env(safe-area-inset-bottom, 0px)); left: var(--gutter); height: 2px; background: rgba(47,47,47,.12); opacity: 0; transition: opacity .35s var(--ease); pointer-events: none; }
/* Scaled, not resized: a transform animates on the compositor, width re-lays out every frame. */
.film-loading-bar { display: block; width: 100%; height: 100%; background: linear-gradient(90deg, var(--red), var(--blue)); transform: scaleX(var(--film-progress, 0)); transform-origin: left; transition: transform .3s linear; }
html[data-film-state="loading"] .page-home .film-loading { opacity: 1; }
html[data-film-state="loading"]:has(.page-home) { overflow: hidden; }
html[data-film-state="loading"] .page-home { overflow: hidden; touch-action: none; }
html[data-film-state="loading"] .page-home .hero-poster,
html[data-film-state="loading"] .page-home .scroll-cue { visibility: hidden; }
html[data-film-state="loading"] .page-home #film-captions { display: none; }
/* The loading screen is blank white with only the progress bar; the menu fades in with the film. */
html[data-film-state="loading"] .page-home .site-header { visibility: hidden; opacity: 0; pointer-events: none; }
.film-ready .film-loading { opacity: 0; }

/* Captions sit in the white areas off the silks' diagonal: bottom-left on wide screens, right-aligned
   under the header on tall ones (the bottom of a phone screen can sit under Safari's toolbar).
   intro.js sets #stage[data-framing] to the frame set on screen. tools/film/check_captions.py measures
   these boxes against every frame at real screen shapes: change both together. */
.film-captions { position: absolute; inset: 0; pointer-events: none; }
.film-beat { position: absolute; opacity: 0; visibility: hidden; color: var(--ink); pointer-events: none; transition: opacity .35s var(--ease), visibility .35s; }
.film-beat[data-static] { opacity: 1; visibility: visible; }
/* With the film on, intro.js shows the end card when the film reaches it; until then it stays hidden,
   so it does not fade out over the first caption on every load. */
.cinematic .film-beat[data-static] { opacity: 0; visibility: hidden; }
.film-beat a { pointer-events: auto; }
.film-beat h1, .film-beat h2 { font-family: var(--display); font-weight: 400; line-height: 1.1; letter-spacing: -.005em; text-wrap: balance; }
:is(.beat-enter, .beat-pass, .beat-exit) { left: var(--gutter); bottom: 6%; max-width: 36%; }
:is(.beat-enter, .beat-pass, .beat-exit) :is(h1, h2) { font-size: clamp(30px, 3.3vw, 60px); }
#stage:is([data-framing="tablet-portrait"], [data-framing="phone"]) :is(.beat-enter, .beat-pass, .beat-exit) { top: max(9%, calc(var(--header) + 16px)); right: var(--gutter); bottom: auto; left: auto; max-width: 60%; text-align: right; }
#stage[data-framing="tablet-portrait"] :is(.beat-enter, .beat-pass, .beat-exit) :is(h1, h2) { font-size: clamp(30px, 4.4vw, 44px); }
#stage[data-framing="phone"] :is(.beat-enter, .beat-pass, .beat-exit) { top: max(9.5%, calc(var(--header) + 12px)); max-width: 70%; }
#stage[data-framing="phone"] :is(.beat-enter, .beat-pass, .beat-exit) :is(h1, h2) { font-size: clamp(26px, 7.4vw, 32px); }
.beat-end { left: 50%; top: 50%; width: min(88%, 760px); transform: translate(-50%, -50%); text-align: center; }
.end-logo { width: min(640px, 80vw); height: auto; margin: 0 auto; }
.end-line { margin-top: 18px; color: var(--muted); font-size: clamp(16px, 1.5vw, 20px); line-height: 1.5; }
.end-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 30px; }
.scroll-cue { position: absolute; z-index: 3; left: 50%; bottom: calc(100lvh - 100svh + 30px + env(safe-area-inset-bottom, 0px)); display: flex; align-items: center; gap: 14px; min-height: 44px; transform: translateX(-50%); color: var(--ink); font-size: 12px; letter-spacing: .14em; text-transform: uppercase; transition: opacity .3s var(--ease); }
.scroll-cue span { font-size: 18px; }
.scroll-cue[hidden] { display: none; }
html[data-film-started="yes"] .scroll-cue { opacity: 0; pointer-events: none; }

/* Fabric photos: three scenes stacked after the film and scrolled straight down (no sideways movement). */
.moodboard { scroll-margin-top: var(--header); background: var(--paper); }
.colour-scene { position: relative; height: clamp(560px, calc(100svh - var(--header)), 62vw); overflow: hidden; background: var(--paper); }
.colour-scene:nth-child(even) { background: var(--soft); }
.colour-scene h2 { position: absolute; z-index: 3; top: 8%; left: 5%; max-width: 9ch; font-family: var(--display); font-size: clamp(44px, 5.4vw, 96px); font-weight: 400; line-height: 1; }
.board-photo { position: absolute; z-index: 2; overflow: hidden; background: var(--soft); }
.board-photo > img { width: 100%; height: 100%; object-fit: cover; }
.scene-one .photo-main { top: 15%; right: 5%; width: 54%; height: 70%; }
.scene-one .photo-small { bottom: 7%; left: 8%; width: 20%; height: 36%; }
.scene-two .photo-main { top: 7%; left: 5%; width: 59%; height: 73%; }
.scene-two .photo-small { right: 5%; bottom: 8%; width: 26%; height: 46%; }
.scene-three .photo-main { top: 17%; left: 5%; width: 51%; height: 66%; }
.accent-rule { position: absolute; z-index: 1; width: 22%; height: 8px; }
.rule-red { background: var(--red); }
.rule-blue { background: var(--blue); }
.scene-one .accent-rule { left: 8%; bottom: 48%; }
.scene-two .accent-rule { right: 5%; top: 20%; }
.scene-three .accent-rule { left: 58%; top: 30%; }
.board-end-link { position: absolute; z-index: 3; right: 7%; bottom: 11%; display: inline-flex; gap: 24px; align-items: center; font-family: var(--display); font-size: clamp(25px, 3vw, 48px); }
.board-end-link span { transition: transform .25s var(--ease); }
.board-end-link:hover span { transform: translate(3px, -3px); }

.cinematic .home-story { height: var(--story-height, 600vh); }
.cinematic .story-stage { position: sticky; top: 0; height: 100lvh; overflow: hidden; }
.cinematic #hero, .cinematic #stage { height: 100%; min-height: 0; }
/* Without the film (reduced motion, ?film=off, slow or failed load) only the end card shows. */
html:not(.cinematic) .film-beat:not([data-static]) { display: none; }

@media (max-width: 660px) {
  .colour-scene { height: max(600px, calc(100svh - var(--header))); }
  .colour-scene h2 { top: 6%; left: 22px; font-size: clamp(42px, 13vw, 68px); }
  .scene-one .photo-main { top: 27%; right: 5%; width: 73%; height: 57%; }
  .scene-one .photo-small { bottom: 5%; left: 5%; width: 30%; height: 29%; }
  .scene-two .photo-main, .scene-three .photo-main { top: 8%; left: 5%; width: 90%; height: 58%; }
  .scene-two .photo-small { right: 5%; bottom: 7%; width: 58%; height: 38%; }
  .board-end-link { right: auto; bottom: 8%; left: 6%; font-size: 25px; }
  .film-loading { right: 20px; bottom: calc(100lvh - 100svh + 22px + env(safe-area-inset-bottom, 0px)); left: 20px; }
}
@media (max-height: 560px) {
  .scroll-cue { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .home-story { height: auto !important; }
  .story-stage { position: relative !important; height: auto !important; }
  .film-beat:not([data-static]) { display: none; }
}
