/* ======================================================
   Sayonara_Alice.exe — v72.06
   Fluid video engine layer.
   ------------------------------------------------------
   Geometry, typography and composition of v72.05 are left
   untouched. This file only fixes what made playback stutter:
   slot visibility, crossfade compositing and continuous repaints.
====================================================== */

/* ------------------------------------------------------
   1. Deterministic slot visibility — the core fix.

   v72_opening.css:820 declares
     .v72-opening.has-living-video .v72-opening-video { opacity: 1 }
   with specificity 0-3-0, which outranked
     .v72-opening-video.is-visible { opacity: 1 }        (0-2-0)
   and the 0-1-0 base rule that set opacity: 0.

   Result before this file: every pooled <video> was opaque at the
   same time, and the buffer element — later in the DOM, absolutely
   positioned in the same portal — covered the one actually playing.
   The next clip's poster therefore appeared on top of the running
   memory as soon as it was preloaded.

   The two rules below are now the single source of truth for what
   is on screen. They carry !important so no earlier layer can
   reintroduce the conflict.
------------------------------------------------------ */
.v72-opening .v72-opening-video {
  opacity: 0 !important;
  z-index: 1;
  pointer-events: none;
  transform: translateZ(0) !important;
  transform-style: flat !important;
  filter: none !important;
  will-change: opacity;
  transition: opacity .9s cubic-bezier(.36, 0, .18, 1) !important;
}

.v72-opening .v72-opening-video.is-visible {
  opacity: 1 !important;
}

/* ------------------------------------------------------
   2. Crossfade without an alpha dip.

   A symmetrical dissolve (one element fading out while the other
   fades in) drops the composite alpha to about .75 at mid point,
   which let the static portal poster show through the hand-off.

   Here the incoming memory is lifted above the outgoing one and
   fades in alone; the outgoing stays fully opaque underneath until
   it is completely covered, then is hidden. Composite alpha never
   leaves 1, so no poster, no background and no black frame can
   appear between two memories.
------------------------------------------------------ */
.v72-opening .v72-opening-video.is-incoming {
  z-index: 2;
}

/* ------------------------------------------------------
   3. No filter on the container that wraps both videos.

   .v72-dual-memory-stage carried filter: saturate() contrast(),
   which forces both video layers into an intermediate surface that
   has to be re-filtered on every frame. The grade was subtle enough
   that removing it is imperceptible; the cost was not.
------------------------------------------------------ */
.v72-opening .v72-dual-memory-stage {
  filter: none !important;
  will-change: transform;
}

.v72-opening .v72-video-portal {
  filter: none !important;
  will-change: auto;
}

.v72-opening.is-memory-switching .v72-dual-memory-stage,
.v72-opening.is-memory-switching .v72-video-portal,
.v72-opening.is-memory-switching .v72-memory-lane {
  filter: none !important;
}

/* ------------------------------------------------------
   4. Ambient fields: dim with opacity, not with filter.

   Two layers larger than the viewport (inset: -12%, scale 1.18)
   carried blur(44px) plus brightness(var(--v72-adaptive-*)).
   Every readability update forced a full re-rasterisation of both
   blurs. The blur is now static — rasterised once — and the
   adaptive dimming rides on opacity, which is compositor only.
------------------------------------------------------ */
.v72-opening .v72-opening-ambient {
  filter: blur(44px) saturate(1.3) contrast(1.08) !important;
  opacity: var(--v72-adaptive-ambient-opacity, .62) !important;
  transition: opacity .6s ease !important;
  will-change: opacity;
}

/* ------------------------------------------------------
   5. Background breath: transform only.

   v72OpeningBreath animated filter: brightness()/contrast()/saturate()
   on a full-viewport image, 15s on infinite alternate. Animating a
   filter repaints the whole layer on every frame for as long as the
   opening is visible. The movement is preserved, the animated filter
   is not; the static grade from .v72-opening-fallback applies instead.
------------------------------------------------------ */
.v72-opening .v72-opening-image {
  animation-name: v72OpeningBreathFluid !important;
  will-change: transform;
}

@keyframes v72OpeningBreathFluid {
  0%   { transform: scale(1.055) translate3d(0, 0, 0); }
  100% { transform: scale(1.09) translate3d(-.5%, -.4%, 0); }
}

/* ------------------------------------------------------
   6. Static paths.

   Reduced motion, Save-Data and blocked autoplay never assign a
   source, so nothing is revealed and the portal poster is the
   picture. These rules come last so they win over .is-visible.
------------------------------------------------------ */
.v72-opening.is-video-poster .v72-opening-video,
.v72-opening.is-video-fallback .v72-opening-video {
  opacity: 0 !important;
}

@media (prefers-reduced-motion: reduce) {
  .v72-opening .v72-opening-image {
    animation: none !important;
  }

  .v72-opening .v72-opening-video {
    transition: none !important;
  }
}
