vx-scene {
  /* Authored surface. --vx-screens sets how long the opening runs; --vx-fit, --vx-focus and
     --vx-matte art-direct how the frame sits in the stage at each breakpoint; --vx-scrim is
     any background that darkens the held frame for copy. */
  --vx-screens: 2;
  --vx-fit: cover;
  --vx-focus: 50% 50%;
  --vx-matte: #000;
  --vx-scrim: none;
  /* Published by the runtime: the real media band inside the stage. */
  --vx-media-top: 0px;
  --vx-media-height: 100%;
  --vx-progress: 0;
  display: block;
  /* Clipping keeps the media inside its own scene without creating a scroll container. */
  overflow: clip;
  position: relative;
}

vx-scene > .vx-hold {
  /* The runtime sizes this so the opening runs for --vx-screens viewport heights. */
  pointer-events: none;
}

vx-scene > .vx-stage {
  height: 100svh;
  isolation: isolate;
  /* The stage holds the sticky position without consuming flow, so authored content
     starts at the top of the scene and scrolls over the frame. */
  margin-bottom: -100svh;
  position: sticky;
  top: 0;
  z-index: 0;
}

vx-scene > .vx-stage > * {
  display: block;
  left: 0;
  position: absolute;
  top: 0;
  width: 100%;
  /* Large-viewport height covers the screen in both mobile toolbar states while the
     stage keeps its stable small-viewport layout height. */
  height: 100lvh;
}

/* The scrim stays on the held frame, so it never scrolls away and leaves a hard edge over it. */
vx-scene > .vx-stage::after {
  background: var(--vx-scrim);
  content: "";
  height: 100lvh;
  left: 0;
  pointer-events: none;
  position: absolute;
  top: 0;
  width: 100%;
}

vx-scene > .vx-stage > .vx-poster {
  object-fit: cover;
  transition: opacity 600ms cubic-bezier(.22, 1, .36, 1), visibility 0s linear 600ms;
}

vx-scene[data-vx-state="ready"] > .vx-stage > .vx-poster {
  opacity: 0;
  visibility: hidden;
}

vx-scene > :not(.vx-stage) {
  position: relative;
  z-index: 1;
}

vx-scene [data-vx-at] {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 420ms cubic-bezier(.22, 1, .36, 1), transform 420ms cubic-bezier(.22, 1, .36, 1);
  will-change: opacity, transform;
}

vx-scene [data-vx-at][data-vx-on] {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  vx-scene > .vx-stage > .vx-canvas {
    display: none;
  }

  vx-scene [data-vx-at] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
