/* Poster + video, stacked.
 *
 * The poster <img> stays in flow and defines the box; the video is absolutely
 * positioned to fill whatever box the poster establishes. That keeps the
 * existing .demo-video__player sizing (height: 52vh, aspect-ratio: 16/9) as the
 * single source of truth for how big the clip is -- both elements carry that
 * class, so there is no second set of dimensions to keep in sync.
 */
.demo-clip {
  position: relative;
  display: inline-block;
  margin: 0;
  /* Kills the inline-block descender gap under the poster. */
  line-height: 0;
}

.demo-clip__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* Transparent until demo-clip.js adds .is-ready on canplaythrough. The poster
   * shows through until then, so the visitor never sees an empty element, a
   * dark rectangle, or a pop as the first frame arrives -- the poster is frame
   * 0 of this exact encode, so the crossfade lands on an identical image.
   */
  opacity: 0;
  transition: opacity var(--duration-slow, .6s) var(--ease-out, ease);
}

.demo-clip__video.is-ready {
  opacity: 1;
}

/* demo-clip.js already returns before requesting the file under reduced motion,
 * so nothing is downloaded. This is belt and braces for the case where the
 * element is somehow populated anyway.
 */
@media (prefers-reduced-motion: reduce) {
  .demo-clip__video {
    display: none;
  }
}
