/* Controlled Velocity: shared timing, with the authored layout as the rest state. */
:root {
  --motion-ease-out: cubic-bezier(.23, 1, .32, 1);
  --motion-ease-in-out: cubic-bezier(.77, 0, .175, 1);
  --motion-press: 120ms;
  --motion-fast: 160ms;
  --motion-ui: 220ms;
  --motion-copy: 460ms;
  --motion-group: 540ms;
  --motion-media: 760ms;
  --motion-hero: 900ms;
  --motion-stagger: 45ms;
}

/* No script, blocked script, or expired bootstrap: all content is visible.
   The independent CSS deadline also covers a bootstrap/runtime exception. */
html[data-motion-boot] :is([data-motion="hero-media"], [data-motion="line-mask"], [data-motion="hero-copy"], [data-motion="header-item"]) {
  opacity: 0;
  animation: motion-bootstrap-release 1ms 1150ms forwards;
}
@keyframes motion-bootstrap-release { to { opacity: 1; } }

.home-hero h1 .motion-line-mask,
.home-hero h1 .motion-line-mask > span { display: block; }
.home-hero h1 .motion-line-mask { overflow: clip; }

/* Keep inline text in the same coordinate context when its entrance ends.
   A 2D identity avoids a permanent GPU-layer hint and preserves every rest box. */
.editorial-card > [data-motion="copy"],
.home-store-card[data-motion="media-pane"] { transform: translate(0, 0); }

/* Only offscreen groups are armed; focus and direct input reveal them at once.
   These states are installed after every observer and recovery handler exists. */
html[data-motion-ready] [data-motion-pending] { opacity: 0; }
html[data-motion-ready] [data-motion-pending]:focus-within { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  html[data-motion-ready] [data-motion-pending] { opacity: 1; }
  .home-hero h1 .motion-line-mask { overflow: visible; }
}
