/* reel.css: the fixed full-screen film behind everything (#stage, owned by reel.js). Replaces film.css on the page. */

#stage {
  position: fixed;
  top: 0; right: 0; bottom: 0; left: 0; inset: 0;
  z-index: 0;
  overflow: hidden;
  background: var(--night-deep, #1c0a0d);
  pointer-events: none;
}

/* Phones: the stage keeps the large-viewport height, so the collapsing browser toolbar never rescales the film. */
@supports (height: 100lvh) {
  #stage { bottom: auto; height: 100lvh; }
}

/* Poster: the first stop's still, shown before the script runs (and without it). */
.stage__poster,
.stage__poster img {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0; inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
}

/* Film layers: three video slots and two still layers, stacked. Only .is-front is seen; the video slots under it stay
   rendered (so a primed clip's first frame is decoded and presented) and the still layers under it are hidden.
   The transform is the opening push (reel.js), about the parchment centre. */
.reel__layer {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  transform-origin: 0 0;
  will-change: transform;
  z-index: 0;
  pointer-events: none;
}

.reel__layer.is-front { z-index: 2; }
.reel__still:not(.is-front) { visibility: hidden; }
/* A cut dissolves (reel.js, 220 ms): the layer it replaces stays drawn just under the new front until then. */
.reel__layer.is-leaving { z-index: 1; }
.reel__still.is-leaving { visibility: visible; }

.stage__grade,
.stage__vignette,
.stage__grain {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0; inset: 0;
  z-index: 2;
  pointer-events: none;
}

/* Two grade layers crossfade (reel.js flips is-on and data-grade). */
.stage__grade {
  opacity: 0;
  transition: opacity 1.2s ease;
}

.stage__grade.is-on { opacity: 1; }

.stage__grade[data-grade="candle"] {
  background: radial-gradient(120% 90% at 50% 35%, rgba(217, 191, 138, 0.10), rgba(28,10,13, 0.12));
  mix-blend-mode: soft-light;
}

.stage__grade[data-grade="moon"] {
  background: linear-gradient(180deg, rgba(236, 210, 204, 0.08), rgba(110,26,40, 0.12));
  mix-blend-mode: soft-light;
}

.stage__grade[data-grade="marigold"] {
  background: linear-gradient(180deg, rgba(217, 191, 138, 0.12), rgba(196,138,134, 0.08));
  mix-blend-mode: soft-light;
}

.stage__grade[data-grade="dawn"] {
  background: linear-gradient(0deg, rgba(236, 210, 204, 0.12), rgba(236, 210, 204, 0) 60%);
  mix-blend-mode: screen;
}

.stage__grade[data-grade="lanterns"] {
  background: radial-gradient(120% 100% at 50% 100%, rgba(217, 191, 138, 0.12), rgba(28,10,13, 0.12));
  mix-blend-mode: soft-light;
}

.stage__vignette {
  background: radial-gradient(ellipse at 50% 50%, rgba(28,10,13, 0) 60%, rgba(28,10,13, 0.45) 100%);
}

/* Reply rest: the held hall frame goes soft (depth of field) and the vignette deepens, so the parchment sheets read
   clearly. reel.js toggles .stage--rest on #stage. */
.stage__vignette::after {
  content: "";
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0; inset: 0;
  background: radial-gradient(ellipse at 50% 50%, rgba(28,10,13, 0) 35%, rgba(28,10,13, 0.6) 100%);
  opacity: 0;
  transition: opacity 1.2s ease;
}

/* Only the layer in front is filtered (the others are covered); the radius is not animated (a 1.2 s blur animation over a
   full-screen film layer is per-frame compositor work on a phone), the vignette below fades in instead. */
#stage.stage--rest .reel__layer.is-front {
  filter: blur(2.5px) brightness(0.78) saturate(1.05);
}

#stage.stage--rest .stage__vignette::after { opacity: 1; }

/* Film grain: SVG turbulence tile, jittered in 8 steps about every 0.5 s (desktop only, see below). */
.stage__grain {
  opacity: 0.07;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size: 240px 240px;
  animation: hn-grain 0.5s steps(8) infinite;
}

@keyframes hn-grain {
  0% { background-position: 0 0; }
  12% { background-position: -24px 16px; }
  25% { background-position: 12px -28px; }
  37% { background-position: -36px 8px; }
  50% { background-position: 20px 32px; }
  62% { background-position: -8px -20px; }
  75% { background-position: 30px -12px; }
  87% { background-position: -16px 26px; }
  100% { background-position: 0 0; }
}

/* Phones: static grain. Moving background-position repaints the full-screen layer 16 times a second. */
@media (pointer: coarse) {
  .stage__grain { animation: none; }
}

/* A move waiting for its clip to buffer (after 250 ms): the progress cursor, and for touch screens, which have no
   cursor, a small soft gold dot pulsing near the bottom edge. */
html.reel-wait,
html.reel-wait body { cursor: progress; }

html.reel-wait .stage__vignette::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: calc(28px + env(safe-area-inset-bottom, 0px));
  width: 6px;
  height: 6px;
  margin-left: -3px;
  border-radius: 50%;
  background: rgba(217, 191, 138, 0.85);
  box-shadow: 0 0 10px rgba(217, 191, 138, 0.6);
  animation: reel-wait-pulse 0.9s ease-in-out infinite;
}

@keyframes reel-wait-pulse {
  0%, 100% { opacity: 0.25; transform: scale(0.8); }
  50% { opacity: 1; transform: scale(1.25); }
}

html.still .reel__layer,
html.still .stage__vignette::after,
html.still .stage__grade { transition: none; }

html.still .stage__grain { animation: none; }
