/* REV030 — page 01 opens through the telescope's sea/sky aperture.
   Measured in the 3840×2160 source: centre (1920,1080), inner radius ~700px;
   the sea label sits at (1920,1512). Both use the same source/crop transform.
   REV048 supplies those points from the actual displayed film transform, with
   cover-safe native45% fallbacks before the first controller presentation.
   These properties never alter the film or the existing hero geometry. */
#stage {
  --opening-source-width: var(--reel-film-width, max(min(120vw, 1728px), 100vw, calc(100vh * 1.7777777778)));
  --opening-source-height: var(--reel-film-height, max(min(67.5vw, 972px), 56.25vw, 100vh));
  --opening-aperture-x: calc(100vw - var(--opening-source-width) * .5);
  --opening-aperture-y: 50vh;
  --opening-aperture-radius: calc(var(--opening-source-width) * .1822916667);
  --opening-sea-y: calc(var(--opening-aperture-y) + var(--opening-source-height) * .2);
}

/* One black radial field, with a clear optical core and a broad smooth falloff
   across the lens rim. Existing app-owned grade opacity is the reveal: grade0
   fades continuously to zero while page02's original grade comes into view. */
#shade .scene-grade[data-grade="0"] {
  background: none;
}
#shade .scene-grade[data-grade="0"]::before {
  content: "";
  background: radial-gradient(circle var(--opening-aperture-radius)
    at var(--opening-aperture-x) var(--opening-aperture-y),
    transparent 0% 80%,
    rgb(0 0 0 / .08) 90%,
    rgb(0 0 0 / .38) 98%,
    rgb(0 0 0 / .90) 108%,
    rgb(0 0 0 / .985) 120%,
    rgb(0 0 0 / .997) 135%);
  -webkit-mask-image: none;
  mask-image: none;
}
#shade .scene-grade[data-grade="0"]::after {
  content: none;
  background: none;
  -webkit-mask-image: none;
  mask-image: none;
}

#stage[data-opening-revision="true"] #copy-one .scene-subtitle {
  --opening-statement-width: min(calc(100vw - 48px), calc(var(--opening-aperture-x) * 2 - 48px), calc(var(--opening-aperture-radius) * 1.85));
  position: absolute;
  inset: var(--opening-sea-y) auto auto var(--opening-aperture-x);
  width: max-content;
  max-width: var(--opening-statement-width);
  margin: 0;
  padding: 0;
  transform: translate(-50%, -50%);
  text-align: center;
  font-size: min(clamp(20px, 2.2vw, 34px), calc(var(--opening-statement-width) / 10.5));
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: -.04em;
  white-space: nowrap;
  background: none;
  text-shadow: 0 1px 6px rgb(0 0 0 / .45);
}
#stage[data-opening-revision="true"] #copy-one .scene-subtitle > span {
  display: block;
}

/* REV031: the controller reveals the telescope completely before the next
   hero, then its whole paragraph. Opacity alone changes; approved geometry
   and every non-opening transition retain their existing composition. */
#stage[data-opening-revision="true"] #copy-two .hero {
  opacity: var(--opening-meeting-hero-opacity, 1);
}
#stage[data-opening-revision="true"] #copy-two > [data-opening-content] {
  opacity: var(--opening-meeting-body-opacity, 1);
}

/* Mobile's film box is the viewport, but the underlying 16:9 source is cover
   cropped at focusX=.52/focusY=.5. Recover that uncropped size before locating
   the native aperture; portrait and short landscape therefore share one rule. */
@media (max-width: 760px) {
  #stage {
    --opening-source-width: max(var(--reel-film-width, 100vw), calc(var(--reel-film-height, 100vh) * 1.7777777778));
    --opening-source-height: max(var(--reel-film-height, 100vh), calc(var(--reel-film-width, 100vw) * .5625));
    --opening-aperture-x: calc(var(--reel-film-width, 100vw) * .52 - var(--opening-source-width) * .02);
  }
  #stage[data-opening-revision="true"] #copy-one .scene-subtitle {
    font-size: min(clamp(20px, 6.8vw, 28px), calc(var(--opening-statement-width) / 10.5));
  }
}
@media (max-width: 760px) and (orientation: landscape) {
  #stage[data-opening-revision="true"] #copy-one .scene-subtitle {
    font-size: min(20px, calc(var(--opening-statement-width) / 10.5));
  }
}
