/* Inline motion: pre-animation state.
   Before the runtime starts, animated blocks wait hidden (no flash of content that then jumps).
   If the runtime never starts (blocked script, error), a fail-safe reveals them after 2.5s.
   Once the runtime is live it owns the state, so this CSS steps aside. */

@keyframes inline-motion-failsafe { to { opacity: 1; } }

html.inline-motion:not(.inline-motion-live) [data-motion]:is([data-motion="fade-up"], [data-motion="fade-in"], [data-motion="zoom-in"], [data-motion="slide-left"], [data-motion="slide-right"]),
html.inline-motion:not(.inline-motion-live) [data-motion="stagger"] > * {
	opacity: 0;
	animation: inline-motion-failsafe .5s ease .8s forwards;
}

/* word-by-word reveal keeps words on one baseline while they fade */
[data-motion="words"] .inline-w { display: inline-block; }

@media (prefers-reduced-motion: reduce) {
	[data-motion], [data-motion] > * { opacity: 1 !important; transform: none !important; animation: none !important; }
}

/* pre-animation states for the newer effects (same fail-safe) */
html.inline-motion:not(.inline-motion-live) :is([data-motion="shutter"], [data-motion="flip"] > *, [data-motion="rise"]) {
	opacity: 0;
	animation: inline-motion-failsafe .5s ease .8s forwards;
}
.inline-mask { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: .08em; margin-bottom: -.08em; }
.inline-mask > .inline-w { display: inline-block; }
