/**
 * EduBox Animations – Effekt-Styles.
 *
 * Der versteckte Ausgangszustand ist doppelt abgesichert:
 * - Er greift nur unter html.edu-reveal-ready (setzt view.js — ohne JS
 *   bleibt also alles sichtbar).
 * - Er liegt komplett in @media (prefers-reduced-motion: no-preference).
 *
 * Bei data-edu-stagger wird nicht der Block selbst versteckt, sondern
 * seine direkten Kinder — sie blenden nacheinander ein (Delay via JS).
 * Nach Abschluss entfernt .edu-reveal--done unsere transition-Regel,
 * damit Theme-Hover-Transitions wieder normal funktionieren.
 *
 * Es gibt zwei Effekt-Gruppen:
 * - data-edu-animation: einmaliges Einblenden beim Sichtbarwerden.
 * - data-edu-loop: Dauer-Effekt, der erst NACH dem Einblenden startet
 *   (Selektor .edu-reveal--done) und dann endlos läuft. Getrennte
 *   Zeitpunkte, damit sich nie zwei Regeln um dieselbe transform-
 *   Eigenschaft streiten.
 */

@media (prefers-reduced-motion: no-preference) {

	/*
	 * Standard-Kurve für alle Einblend-Effekte (easeOutQuad).
	 *
	 * Bewusst KEIN starkes Ease-out wie cubic-bezier(0.22, 1, 0.36, 1):
	 * das legt ~80 % der Strecke in die ersten ~25 % der Zeit, wodurch
	 * eine eingestellte Dauer von 2000 ms wie 500 ms wirkt und der Rest
	 * ein unsichtbares Nachkriechen ist. Mit dieser Kurve sind nach der
	 * halben Zeit erst ~75 % erledigt — die Dauer ist damit spürbar.
	 */
	html.edu-reveal-ready {
		--edu-ease: cubic-bezier(0.25, 0.46, 0.45, 0.94);
	}

	/* Seitliche Effekte starten außerhalb des Viewports und dürfen dabei
	   keinen horizontalen Scrollbalken erzeugen. */
	html.edu-reveal-ready body {
		overflow-x: clip;
	}

	/* Übergang auf dem Animationsziel (Block oder dessen direkte Kinder). */
	html.edu-reveal-ready .edu-reveal:not([data-edu-stagger]):not(.edu-reveal--done),
	html.edu-reveal-ready .edu-reveal[data-edu-stagger] > :not(.edu-reveal--done) {
		transition:
			opacity 1.4s var(--edu-ease),
			transform 1.4s var(--edu-ease),
			filter 1.4s var(--edu-ease);
	}

	/* Ausgangszustand: unsichtbar, bis der Observer .edu-reveal--in setzt. */
	html.edu-reveal-ready .edu-reveal:not(.edu-reveal--in):not([data-edu-stagger]),
	html.edu-reveal-ready .edu-reveal[data-edu-stagger]:not(.edu-reveal--in) > * {
		opacity: 0;
	}

	html.edu-reveal-ready .edu-reveal[data-edu-animation="up"]:not(.edu-reveal--in):not([data-edu-stagger]),
	html.edu-reveal-ready .edu-reveal[data-edu-animation="up"][data-edu-stagger]:not(.edu-reveal--in) > * {
		transform: translateY(4rem);
	}

	html.edu-reveal-ready .edu-reveal[data-edu-animation="down"]:not(.edu-reveal--in):not([data-edu-stagger]),
	html.edu-reveal-ready .edu-reveal[data-edu-animation="down"][data-edu-stagger]:not(.edu-reveal--in) > * {
		transform: translateY(-4rem);
	}

	/*
	 * „Von links"/„Von rechts" starten komplett außerhalb des Viewports.
	 * Wichtig: Das darf nicht über den versteckten Ausgangszustand
	 * (transform) passieren — der IntersectionObserver misst die
	 * transformierte Position, ein voll ausgelagertes Element würde also
	 * nie als sichtbar erkannt und nie animiert. Deshalb bleiben diese
	 * Effekte im Ausgangszustand nur per opacity versteckt und fliegen
	 * beim Auslösen über eine Keyframe-Animation herein (Dauer/Delay
	 * setzt view.js inline, 50vw + halbe Elementbreite reicht für mittig
	 * platzierte Elemente wie für volle Breite).
	 */
	html.edu-reveal-ready .edu-reveal[data-edu-animation="left"].edu-reveal--in:not([data-edu-stagger]):not(.edu-reveal--done),
	html.edu-reveal-ready .edu-reveal[data-edu-animation="left"][data-edu-stagger].edu-reveal--in > :not(.edu-reveal--done) {
		animation: edu-slide-from-left 1.4s var(--edu-ease) both;
	}

	html.edu-reveal-ready .edu-reveal[data-edu-animation="right"].edu-reveal--in:not([data-edu-stagger]):not(.edu-reveal--done),
	html.edu-reveal-ready .edu-reveal[data-edu-animation="right"][data-edu-stagger].edu-reveal--in > :not(.edu-reveal--done) {
		animation: edu-slide-from-right 1.4s var(--edu-ease) both;
	}

	@keyframes edu-slide-from-left {
		from {
			transform: translateX(calc(-50vw - 50%));
		}

		to {
			transform: none;
		}
	}

	@keyframes edu-slide-from-right {
		from {
			transform: translateX(calc(50vw + 50%));
		}

		to {
			transform: none;
		}
	}

	html.edu-reveal-ready .edu-reveal[data-edu-animation="zoom"]:not(.edu-reveal--in):not([data-edu-stagger]),
	html.edu-reveal-ready .edu-reveal[data-edu-animation="zoom"][data-edu-stagger]:not(.edu-reveal--in) > * {
		transform: scale(0.92);
	}

	/* „Weichzeichnen": kommt aus der Unschärfe scharf — läuft wie fade/up
	   über die transition-Regel oben (filter ist dort mit aufgeführt). */
	html.edu-reveal-ready .edu-reveal[data-edu-animation="blur"]:not(.edu-reveal--in):not([data-edu-stagger]),
	html.edu-reveal-ready .edu-reveal[data-edu-animation="blur"][data-edu-stagger]:not(.edu-reveal--in) > * {
		filter: blur(14px);
		transform: scale(1.06);
	}

	/*
	 * Keyframe-Effekte. Wie bei „von links"/„von rechts" braucht es hier
	 * Zwischenschritte (Überschwingen, Pendeln, Wischen), die sich mit
	 * einer reinen transition nicht abbilden lassen. Dauer/Delay setzt
	 * view.js inline; die Deckkraft übernimmt weiterhin die transition,
	 * beide laufen dank identischer Werte synchron.
	 */
	html.edu-reveal-ready .edu-reveal[data-edu-animation="pop"].edu-reveal--in:not([data-edu-stagger]):not(.edu-reveal--done),
	html.edu-reveal-ready .edu-reveal[data-edu-animation="pop"][data-edu-stagger].edu-reveal--in > :not(.edu-reveal--done) {
		animation: edu-pop 1.4s cubic-bezier(0.34, 1.56, 0.64, 1) both;
	}

	html.edu-reveal-ready .edu-reveal[data-edu-animation="flip"].edu-reveal--in:not([data-edu-stagger]):not(.edu-reveal--done),
	html.edu-reveal-ready .edu-reveal[data-edu-animation="flip"][data-edu-stagger].edu-reveal--in > :not(.edu-reveal--done) {
		animation: edu-flip 1.4s var(--edu-ease) both;
		backface-visibility: hidden;
	}

	html.edu-reveal-ready .edu-reveal[data-edu-animation="spin"].edu-reveal--in:not([data-edu-stagger]):not(.edu-reveal--done),
	html.edu-reveal-ready .edu-reveal[data-edu-animation="spin"][data-edu-stagger].edu-reveal--in > :not(.edu-reveal--done) {
		animation: edu-spin 1.4s var(--edu-ease) both;
	}

	/* Pendelt an der Oberkante aus, als hinge das Element an einem Nagel. */
	html.edu-reveal-ready .edu-reveal[data-edu-animation="swing"].edu-reveal--in:not([data-edu-stagger]):not(.edu-reveal--done),
	html.edu-reveal-ready .edu-reveal[data-edu-animation="swing"][data-edu-stagger].edu-reveal--in > :not(.edu-reveal--done) {
		animation: edu-swing 1.4s ease-out both;
		transform-origin: top center;
	}

	html.edu-reveal-ready .edu-reveal[data-edu-animation="wipe"].edu-reveal--in:not([data-edu-stagger]):not(.edu-reveal--done),
	html.edu-reveal-ready .edu-reveal[data-edu-animation="wipe"][data-edu-stagger].edu-reveal--in > :not(.edu-reveal--done) {
		animation: edu-wipe 1.4s cubic-bezier(0.65, 0, 0.35, 1) both;
	}

	@keyframes edu-pop {
		from {
			transform: scale(0.4);
		}

		to {
			transform: none;
		}
	}

	@keyframes edu-flip {
		from {
			transform: perspective(900px) rotateY(-90deg);
		}

		to {
			transform: perspective(900px) rotateY(0);
		}
	}

	@keyframes edu-spin {
		from {
			transform: rotate(-270deg) scale(0.3);
		}

		to {
			transform: none;
		}
	}

	@keyframes edu-swing {
		0% {
			transform: rotate(-14deg);
		}

		35% {
			transform: rotate(9deg);
		}

		60% {
			transform: rotate(-5deg);
		}

		80% {
			transform: rotate(2deg);
		}

		100% {
			transform: none;
		}
	}

	@keyframes edu-wipe {
		from {
			clip-path: inset(0 100% 0 0);
		}

		to {
			clip-path: inset(0);
		}
	}

	/* ---------------------------------------------------------------
	   Dauer-Effekte (data-edu-loop). Greifen erst ab .edu-reveal--done,
	   also nachdem das Einblenden fertig ist und view.js die Inline-
	   Styles entfernt hat. Bei data-edu-stagger tragen die Kinder das
	   --done, deshalb je zwei Selektoren.
	   --------------------------------------------------------------- */

	html.edu-reveal-ready .edu-reveal--done[data-edu-loop="float"],
	html.edu-reveal-ready .edu-reveal[data-edu-stagger][data-edu-loop="float"] > .edu-reveal--done {
		animation: edu-float 6s ease-in-out infinite;
	}

	html.edu-reveal-ready .edu-reveal--done[data-edu-loop="pulse"],
	html.edu-reveal-ready .edu-reveal[data-edu-stagger][data-edu-loop="pulse"] > .edu-reveal--done {
		animation: edu-pulse 3.2s ease-in-out infinite;
	}

	/* Leuchten nutzt die Theme-Primärfarbe, fällt ohne edubox auf Blau
	   zurück. drop-shadow statt box-shadow, damit auch freigestellte
	   Logo-PNGs/SVGs an ihrer Silhouette leuchten statt im Rechteck. */
	html.edu-reveal-ready .edu-reveal[data-edu-loop="glow"] {
		--ebx-glow: var(--theme-primary, #2b6cb0);
	}

	html.edu-reveal-ready .edu-reveal--done[data-edu-loop="glow"],
	html.edu-reveal-ready .edu-reveal[data-edu-stagger][data-edu-loop="glow"] > .edu-reveal--done {
		animation: edu-glow 3.6s ease-in-out infinite;
	}

	/*
	 * Glanzlicht: wandert als Pseudo-Element über den Block. Läuft auf
	 * dem Wurzelelement (auch bei Stagger) und kollidiert deshalb mit
	 * keiner transform-Regel. overflow: hidden hält den Streifen im
	 * Element — bei Blöcken mit Schlagschatten oder Überstand daher
	 * lieber einen der anderen Dauer-Effekte wählen.
	 */
	html.edu-reveal-ready .edu-reveal[data-edu-loop="shine"] {
		position: relative;
		overflow: hidden;
	}

	html.edu-reveal-ready .edu-reveal[data-edu-loop="shine"]::after {
		content: "";
		position: absolute;
		inset: 0;
		background: linear-gradient(
			105deg,
			rgba(255, 255, 255, 0) 40%,
			rgba(255, 255, 255, 0.55) 50%,
			rgba(255, 255, 255, 0) 60%
		);
		transform: translateX(-130%);
		pointer-events: none;
	}

	html.edu-reveal-ready .edu-reveal--in[data-edu-loop="shine"]::after {
		animation: edu-shine 5s ease-in-out 1s infinite;
	}

	@keyframes edu-float {
		0%,
		100% {
			transform: translateY(0);
		}

		50% {
			transform: translateY(-0.75rem);
		}
	}

	@keyframes edu-pulse {
		0%,
		100% {
			transform: scale(1);
		}

		50% {
			transform: scale(1.04);
		}
	}

	@keyframes edu-glow {
		0%,
		100% {
			filter: drop-shadow(0 0 0 transparent);
		}

		50% {
			filter: drop-shadow(0 0 1.25rem var(--ebx-glow));
		}
	}

	@keyframes edu-shine {
		0% {
			transform: translateX(-130%);
		}

		/* Nach einem Drittel ist der Streifen durch, der Rest ist Pause. */
		35%,
		100% {
			transform: translateX(130%);
		}
	}
}
