/*
   theme-animate.css — Optimized in 2026
   Author: Tymchenko Serhii (https://github.com/ts03-coder) 
*/

/* ──────────────────────────────────────────────────────────
   ANIMATION TOKENS
   ────────────────────────────────────────────────────────── */
:root {
	--animate-duration: 1s;
	--animate-delay: 0s;
	--animate-repeat: 1;
	--animate-offset-sm: 20px;
	--animate-offset-lg: 2000px; /* Big variants — але краще 150vh/150vw */

	/* Easing */
	--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
	--ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
	--ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
}

/* ──────────────────────────────────────────────────────────
   ACCESSIBILITY: Reduced Motion — WCAG 2.1 SC 2.3.3
   ────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
	.animated,
	.appear-animation {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}

	.appear-animation {
		opacity: 1 !important;
	}
}

/* ──────────────────────────────────────────────────────────
   BASE CLASSES
   ────────────────────────────────────────────────────────── */
.appear-animation {
	opacity: 0;
}

.appear-animation-visible {
	opacity: 1;
}

.animated,
.appear-animation {
	animation-fill-mode: both;
	animation-duration: var(--animate-duration);
	animation-delay: var(--animate-delay);
	animation-iteration-count: var(--animate-repeat);
	will-change: transform, opacity;
}

/* Звільнення GPU пам'яті після завершення */
.animated {
	animation-fill-mode: both;
}

/* ──────────────────────────────────────────────────────────
   UTILITY MODIFIERS
   Замість hardcode через JS — використовуй CSS змінні:
   <div class="animated fadeIn" style="--animate-duration: 0.5s; --animate-delay: 0.3s">
   ────────────────────────────────────────────────────────── */
.animated.infinite {
	animation-iteration-count: infinite;
}
.animated.hinge {
	animation-duration: calc(var(--animate-duration) * 2);
}

/* ══════════════════════════════════════════════════════════
   ATTENTION SEEKERS
   ══════════════════════════════════════════════════════════ */

/* flash */
@keyframes flash {
	0%,
	50%,
	100% {
		opacity: 1;
	}
	25%,
	75% {
		opacity: 0;
	}
}
.flash {
	animation-name: flash;
}

/* shake */
@keyframes shake {
	0%,
	100% {
		transform: translateX(0);
		opacity: 1;
	}
	10%,
	30%,
	50%,
	70%,
	90% {
		transform: translateX(-10px);
	}
	20%,
	40%,
	60%,
	80% {
		transform: translateX(10px);
	}
}
.shake {
	animation-name: shake;
}

/* bounce */
@keyframes bounce {
	0%,
	20%,
	50%,
	80%,
	100% {
		transform: translateY(0);
		opacity: 1;
	}
	40% {
		transform: translateY(-30px);
	}
	60% {
		transform: translateY(-15px);
	}
}
.bounce {
	animation-name: bounce;
}

/* tada */
@keyframes tada {
	0% {
		transform: scale(1);
	}
	10%,
	20% {
		transform: scale(0.9) rotate(-3deg);
	}
	30%,
	50%,
	70%,
	90% {
		transform: scale(1.1) rotate(3deg);
	}
	40%,
	60%,
	80% {
		transform: scale(1.1) rotate(-3deg);
	}
	100% {
		transform: scale(1) rotate(0);
		opacity: 1;
	}
}
.tada {
	animation-name: tada;
}

/* swing */
@keyframes swing {
	20% {
		transform: rotate(15deg);
	}
	40% {
		transform: rotate(-10deg);
	}
	60% {
		transform: rotate(5deg);
	}
	80% {
		transform: rotate(-5deg);
	}
	100% {
		transform: rotate(0deg);
		opacity: 1;
	}
}
.swing {
	transform-origin: top center;
	animation-name: swing;
}

/* wobble */
@keyframes wobble {
	0% {
		transform: translateX(0%);
	}
	15% {
		transform: translateX(-25%) rotate(-5deg);
	}
	30% {
		transform: translateX(20%) rotate(3deg);
	}
	45% {
		transform: translateX(-15%) rotate(-3deg);
	}
	60% {
		transform: translateX(10%) rotate(2deg);
	}
	75% {
		transform: translateX(-5%) rotate(-1deg);
	}
	100% {
		transform: translateX(0%);
		opacity: 1;
	}
}
.wobble {
	animation-name: wobble;
}

/* wiggle */
@keyframes wiggle {
	0% {
		transform: skewX(9deg);
	}
	10% {
		transform: skewX(-8deg);
	}
	20% {
		transform: skewX(7deg);
	}
	30% {
		transform: skewX(-6deg);
	}
	40% {
		transform: skewX(5deg);
	}
	50% {
		transform: skewX(-4deg);
	}
	60% {
		transform: skewX(3deg);
	}
	70% {
		transform: skewX(-2deg);
	}
	80% {
		transform: skewX(1deg);
	}
	90% {
		transform: skewX(0deg);
	}
	100% {
		transform: skewX(0deg);
		opacity: 1;
	}
}
.wiggle {
	animation-name: wiggle;
	animation-timing-function: ease-in;
}

/* pulse */
@keyframes pulse {
	0% {
		transform: scale(1);
	}
	50% {
		transform: scale(1.1);
	}
	100% {
		transform: scale(1);
		opacity: 1;
	}
}
.pulse {
	animation-name: pulse;
}

/* ══════════════════════════════════════════════════════════
   FADE IN
   ══════════════════════════════════════════════════════════ */

@keyframes fadeIn {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}
.fadeIn {
	animation-name: fadeIn;
}

@keyframes fadeInUp {
	from {
		opacity: 0;
		transform: translateY(var(--animate-offset-sm));
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}
.fadeInUp {
	animation-name: fadeInUp;
}

@keyframes fadeInDown {
	from {
		opacity: 0;
		transform: translateY(calc(var(--animate-offset-sm) * -1));
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}
.fadeInDown {
	animation-name: fadeInDown;
}

@keyframes fadeInLeft {
	from {
		opacity: 0;
		transform: translateX(calc(var(--animate-offset-sm) * -1));
	}
	to {
		opacity: 1;
		transform: translateX(0);
	}
}
.fadeInLeft {
	animation-name: fadeInLeft;
}

@keyframes fadeInRight {
	from {
		opacity: 0;
		transform: translateX(var(--animate-offset-sm));
	}
	to {
		opacity: 1;
		transform: translateX(0);
	}
}
.fadeInRight {
	animation-name: fadeInRight;
}

/* Big variants — translateX/Y(2000px) замінено на 150vw/150vh
   щоб уникнути величезних layout repaints на будь-якому екрані */
@keyframes fadeInUpBig {
	from {
		opacity: 0;
		transform: translateY(150vh);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}
.fadeInUpBig {
	animation-name: fadeInUpBig;
}

@keyframes fadeInDownBig {
	from {
		opacity: 0;
		transform: translateY(-150vh);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}
.fadeInDownBig {
	animation-name: fadeInDownBig;
}

@keyframes fadeInLeftBig {
	from {
		opacity: 0;
		transform: translateX(-150vw);
	}
	to {
		opacity: 1;
		transform: translateX(0);
	}
}
.fadeInLeftBig {
	animation-name: fadeInLeftBig;
}

@keyframes fadeInRightBig {
	from {
		opacity: 0;
		transform: translateX(150vw);
	}
	to {
		opacity: 1;
		transform: translateX(0);
	}
}
.fadeInRightBig {
	animation-name: fadeInRightBig;
}

/* ══════════════════════════════════════════════════════════
   BOUNCE IN
   ══════════════════════════════════════════════════════════ */

@keyframes bounceIn {
	0% {
		opacity: 0;
		transform: scale(0.3);
	}
	50% {
		opacity: 1;
		transform: scale(1.05);
	}
	70% {
		transform: scale(0.9);
	}
	100% {
		transform: scale(1);
		opacity: 1;
	}
}
.bounceIn {
	animation-name: bounceIn;
}

@keyframes bounceInUp {
	0% {
		opacity: 0;
		transform: translateY(150vh);
	}
	60% {
		opacity: 1;
		transform: translateY(-30px);
	}
	80% {
		transform: translateY(10px);
	}
	100% {
		transform: translateY(0);
		opacity: 1;
	}
}
.bounceInUp {
	animation-name: bounceInUp;
}

@keyframes bounceInDown {
	0% {
		opacity: 0;
		transform: translateY(-150vh);
	}
	60% {
		opacity: 1;
		transform: translateY(30px);
	}
	80% {
		transform: translateY(-10px);
	}
	100% {
		transform: translateY(0);
		opacity: 1;
	}
}
.bounceInDown {
	animation-name: bounceInDown;
}

@keyframes bounceInLeft {
	0% {
		opacity: 0;
		transform: translateX(-150vw);
	}
	60% {
		opacity: 1;
		transform: translateX(30px);
	}
	80% {
		transform: translateX(-10px);
	}
	100% {
		transform: translateX(0);
		opacity: 1;
	}
}
.bounceInLeft {
	animation-name: bounceInLeft;
}

@keyframes bounceInRight {
	0% {
		opacity: 0;
		transform: translateX(150vw);
	}
	60% {
		opacity: 1;
		transform: translateX(-30px);
	}
	80% {
		transform: translateX(10px);
	}
	100% {
		transform: translateX(0);
		opacity: 1;
	}
}
.bounceInRight {
	animation-name: bounceInRight;
}

/* ══════════════════════════════════════════════════════════
   ROTATE IN
   ══════════════════════════════════════════════════════════ */

@keyframes rotateIn {
	from {
		transform-origin: center center;
		transform: rotate(-200deg);
		opacity: 0;
	}
	to {
		transform-origin: center center;
		transform: rotate(0);
		opacity: 1;
	}
}
.rotateIn {
	animation-name: rotateIn;
}

@keyframes rotateInUpLeft {
	from {
		transform-origin: left bottom;
		transform: rotate(90deg);
		opacity: 0;
	}
	to {
		transform-origin: left bottom;
		transform: rotate(0);
		opacity: 1;
	}
}
.rotateInUpLeft {
	animation-name: rotateInUpLeft;
}

@keyframes rotateInDownLeft {
	from {
		transform-origin: left bottom;
		transform: rotate(-90deg);
		opacity: 0;
	}
	to {
		transform-origin: left bottom;
		transform: rotate(0);
		opacity: 1;
	}
}
.rotateInDownLeft {
	animation-name: rotateInDownLeft;
}

@keyframes rotateInUpRight {
	from {
		transform-origin: right bottom;
		transform: rotate(-90deg);
		opacity: 0;
	}
	to {
		transform-origin: right bottom;
		transform: rotate(0);
		opacity: 1;
	}
}
.rotateInUpRight {
	animation-name: rotateInUpRight;
}

@keyframes rotateInDownRight {
	from {
		transform-origin: right bottom;
		transform: rotate(90deg);
		opacity: 0;
	}
	to {
		transform-origin: right bottom;
		transform: rotate(0);
		opacity: 1;
	}
}
.rotateInDownRight {
	animation-name: rotateInDownRight;
}
