/**
 * Entrance animations.
 *
 * The hidden initial state is scoped to `.ractro-anim-on`, a class the driver
 * (assets/js/ractro-anim.js) puts on <html> as its very first statement. That
 * indirection is the whole safety design: if the script fails to load, is blocked,
 * or errors, the class never appears and NOTHING is hidden — the page reads
 * exactly as if animations were never configured. Hiding on the attribute alone
 * would mean one broken request leaves a blank page with content that never
 * arrives.
 *
 * The driver is enqueued in the HEAD for the same reason the class exists: loaded
 * in the footer it would set the class after first paint, so every animated
 * element would flash visible, disappear, then animate back in.
 */

.ractro-anim-on [data-ractro-anim]:not(.ractro-anim-in) {
	opacity: 0;
}

/* THE END STATE IS THE AUTHOR'S STATE, NOT `none`.
 *
 * `animation-fill-mode: both` keeps the LAST keyframe forever, so whatever the
 * `to` block writes wins over the element's own rules for good. The keyframes
 * used to end at `transform: none`, which silently deleted the Skew X / Skew Y
 * the author had set two controls higher up in the same Motion group: measured
 * on an element with Skew X 12deg + Fade up, the finished animation left
 * `transform: matrix(1, 0, 0, 1, 0, 0)` — flat. Every keyframe below therefore
 * ends at exactly what the skew controls emit, so a finished animation restores
 * the element's own transform instead of erasing it.
 *
 * Move X/Y, Rotate and Scale are individual transform PROPERTIES (`translate`,
 * `rotate`, `scale`), which is why they already survived: the animation drives
 * `transform`, and per spec the individual properties apply on top of it. That
 * separation is deliberate — keep animations on `transform` and static motion on
 * the individual properties, and the two compose instead of overwriting.
 */
.ractro-anim-in {
	animation-duration: var(--ractro-anim-duration, 600ms);
	animation-delay: var(--ractro-anim-delay, 0ms);
	animation-fill-mode: both;
	animation-timing-function: cubic-bezier(0.22, 0.61, 0.36, 1);
}

.ractro-anim-in[data-ractro-anim="fade"]        { animation-name: ractro-anim-fade; }
.ractro-anim-in[data-ractro-anim="fade-up"]     { animation-name: ractro-anim-fade-up; }
.ractro-anim-in[data-ractro-anim="fade-down"]   { animation-name: ractro-anim-fade-down; }
.ractro-anim-in[data-ractro-anim="fade-left"]   { animation-name: ractro-anim-fade-left; }
.ractro-anim-in[data-ractro-anim="fade-right"]  { animation-name: ractro-anim-fade-right; }
.ractro-anim-in[data-ractro-anim="zoom-in"]     { animation-name: ractro-anim-zoom-in; }
.ractro-anim-in[data-ractro-anim="zoom-out"]    { animation-name: ractro-anim-zoom-out; }
.ractro-anim-in[data-ractro-anim="flip-up"]     { animation-name: ractro-anim-flip-up; }

@keyframes ractro-anim-fade {
	from { opacity: 0; }
	to   { opacity: 1; }
}
@keyframes ractro-anim-fade-up {
	from { opacity: 0; transform: translateY(var(--ractro-anim-distance, 28px)) skew(var(--ractro-skx, 0deg), var(--ractro-sky, 0deg)); }
	to   { opacity: 1; transform: skew(var(--ractro-skx, 0deg), var(--ractro-sky, 0deg)); }
}
@keyframes ractro-anim-fade-down {
	from { opacity: 0; transform: translateY(calc(-1 * var(--ractro-anim-distance, 28px))) skew(var(--ractro-skx, 0deg), var(--ractro-sky, 0deg)); }
	to   { opacity: 1; transform: skew(var(--ractro-skx, 0deg), var(--ractro-sky, 0deg)); }
}
@keyframes ractro-anim-fade-left {
	from { opacity: 0; transform: translateX(var(--ractro-anim-distance, 28px)) skew(var(--ractro-skx, 0deg), var(--ractro-sky, 0deg)); }
	to   { opacity: 1; transform: skew(var(--ractro-skx, 0deg), var(--ractro-sky, 0deg)); }
}
@keyframes ractro-anim-fade-right {
	from { opacity: 0; transform: translateX(calc(-1 * var(--ractro-anim-distance, 28px))) skew(var(--ractro-skx, 0deg), var(--ractro-sky, 0deg)); }
	to   { opacity: 1; transform: skew(var(--ractro-skx, 0deg), var(--ractro-sky, 0deg)); }
}
@keyframes ractro-anim-zoom-in {
	from { opacity: 0; transform: scale(0.9) skew(var(--ractro-skx, 0deg), var(--ractro-sky, 0deg)); }
	to   { opacity: 1; transform: skew(var(--ractro-skx, 0deg), var(--ractro-sky, 0deg)); }
}
@keyframes ractro-anim-zoom-out {
	from { opacity: 0; transform: scale(1.1) skew(var(--ractro-skx, 0deg), var(--ractro-sky, 0deg)); }
	to   { opacity: 1; transform: skew(var(--ractro-skx, 0deg), var(--ractro-sky, 0deg)); }
}
@keyframes ractro-anim-flip-up {
	from { opacity: 0; transform: perspective(800px) rotateX(28deg) skew(var(--ractro-skx, 0deg), var(--ractro-sky, 0deg)); }
	to   { opacity: 1; transform: skew(var(--ractro-skx, 0deg), var(--ractro-sky, 0deg)); }
}

/* Motion sensitivity is an accessibility requirement, not a preference we get to
   weigh: reveal everything immediately and run nothing. */
@media (prefers-reduced-motion: reduce) {
	.ractro-anim-on [data-ractro-anim],
	.ractro-anim-on [data-ractro-anim]:not(.ractro-anim-in) {
		opacity: 1;
	}
	.ractro-anim-in {
		animation: none !important;
	}
}
