/*
 * GenerateBlocks Pro Animation Library
 * High-performance CSS animations using only transform and opacity
 * Zero dependencies | 60FPS mobile-optimized
 */

/* ============================================
   CSS VARIABLES
   ============================================ */
:root {
  /* Duration variables */
  --fx-duration: 0.4s;
  --fx-duration-fast: 0.2s;
  --fx-duration-slow: 0.6s;
  --fx-duration-slower: 0.8s;

  /* Easing variables */
  --fx-ease: ease-out;
  --fx-ease-in: ease-in;
  --fx-ease-in-out: ease-in-out;
  --fx-ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
  --fx-ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);

  /* Distance variables */
  --fx-distance: 20px;
  --fx-distance-large: 40px;
  --fx-distance-small: 10px;

  /* Delay variables */
  --fx-delay: 0s;
  --fx-delay-short: 0.1s;
  --fx-delay-medium: 0.2s;
  --fx-delay-long: 0.3s;
}


/* ============================================
   FADE ANIMATIONS
   ============================================ */

/* Fade In */
@keyframes fx-fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.fx-fade-in {
  animation: fx-fade-in var(--fx-duration) var(--fx-ease) var(--fx-delay) both;
}

/* Fade Out */
@keyframes fx-fade-out {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

.fx-fade-out {
  animation: fx-fade-out var(--fx-duration) var(--fx-ease) var(--fx-delay) both;
}


/* ============================================
   SLIDE ANIMATIONS
   ============================================ */

/* Slide In Up */
@keyframes fx-slide-in-up {
  from {
    opacity: 0;
    transform: translateY(var(--fx-distance));
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.fx-slide-in-up {
  animation: fx-slide-in-up var(--fx-duration) var(--fx-ease) var(--fx-delay) both;
}

/* Slide In Down */
@keyframes fx-slide-in-down {
  from {
    opacity: 0;
    transform: translateY(calc(var(--fx-distance) * -1));
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.fx-slide-in-down {
  animation: fx-slide-in-down var(--fx-duration) var(--fx-ease) var(--fx-delay) both;
}

/* Slide In Left */
@keyframes fx-slide-in-left {
  from {
    opacity: 0;
    transform: translateX(calc(var(--fx-distance) * -1));
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

.fx-slide-in-left {
  animation: fx-slide-in-left var(--fx-duration) var(--fx-ease) var(--fx-delay) both;
}

/* Slide In Right */
@keyframes fx-slide-in-right {
  from {
    opacity: 0;
    transform: translateX(var(--fx-distance));
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

.fx-slide-in-right {
  animation: fx-slide-in-right var(--fx-duration) var(--fx-ease) var(--fx-delay) both;
}


/* ============================================
   SCALE ANIMATIONS
   ============================================ */

/* Scale In */
@keyframes fx-scale-in {
  from {
    opacity: 0;
    transform: scale(0.9);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.fx-scale-in {
  animation: fx-scale-in var(--fx-duration) var(--fx-ease) var(--fx-delay) both;
}

/* Scale Out */
@keyframes fx-scale-out {
  from {
    opacity: 1;
    transform: scale(1);
  }
  to {
    opacity: 0;
    transform: scale(0.9);
  }
}

.fx-scale-out {
  animation: fx-scale-out var(--fx-duration) var(--fx-ease) var(--fx-delay) both;
}

/* Scale Up */
@keyframes fx-scale-up {
  from {
    opacity: 0;
    transform: scale(0.7);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.fx-scale-up {
  animation: fx-scale-up var(--fx-duration) var(--fx-ease-bounce) var(--fx-delay) both;
}

/* Scale Down */
@keyframes fx-scale-down {
  from {
    opacity: 0;
    transform: scale(1.3);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.fx-scale-down {
  animation: fx-scale-down var(--fx-duration) var(--fx-ease) var(--fx-delay) both;
}


/* ============================================
   ZOOM ANIMATIONS
   ============================================ */

/* Zoom In Up */
@keyframes fx-zoom-in-up {
  from {
    opacity: 0;
    transform: scale(0.9) translateY(var(--fx-distance));
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

.fx-zoom-in-up {
  animation: fx-zoom-in-up var(--fx-duration) var(--fx-ease) var(--fx-delay) both;
}

/* Zoom In Down */
@keyframes fx-zoom-in-down {
  from {
    opacity: 0;
    transform: scale(0.9) translateY(calc(var(--fx-distance) * -1));
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

.fx-zoom-in-down {
  animation: fx-zoom-in-down var(--fx-duration) var(--fx-ease) var(--fx-delay) both;
}

/* Zoom In Out Reverse (Infinite pulse effect) */
@keyframes fx-zoom-in-out-reverse {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.15);
  }
}

.fx-zoom-in-out-reverse {
  animation: fx-zoom-in-out-reverse 2s var(--fx-ease-in-out) var(--fx-delay) infinite alternate;
}

/* Zoom In Out (One-time entrance with bounce back) */
@keyframes fx-zoom-in-out {
  0% {
    opacity: 0;
    transform: scale(0.5);
  }
  60% {
    opacity: 1;
    transform: scale(1.1);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

.fx-zoom-in-out {
  animation: fx-zoom-in-out var(--fx-duration-slow) var(--fx-ease) var(--fx-delay) both;
}

/* Zoom Out In (Reverse entrance) */
@keyframes fx-zoom-out-in {
  0% {
    opacity: 0;
    transform: scale(1.5);
  }
  60% {
    opacity: 1;
    transform: scale(0.9);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

.fx-zoom-out-in {
  animation: fx-zoom-out-in var(--fx-duration-slow) var(--fx-ease) var(--fx-delay) both;
}


/* ============================================
   FLIP ANIMATIONS
   ============================================ */

/* Flip In X */
@keyframes fx-flip-in-x {
  from {
    opacity: 0;
    transform: perspective(400px) rotateX(90deg);
  }
  to {
    opacity: 1;
    transform: perspective(400px) rotateX(0);
  }
}

.fx-flip-in-x {
  animation: fx-flip-in-x var(--fx-duration-slow) var(--fx-ease) var(--fx-delay) both;
  backface-visibility: visible;
}

/* Flip In Y */
@keyframes fx-flip-in-y {
  from {
    opacity: 0;
    transform: perspective(400px) rotateY(90deg);
  }
  to {
    opacity: 1;
    transform: perspective(400px) rotateY(0);
  }
}

.fx-flip-in-y {
  animation: fx-flip-in-y var(--fx-duration-slow) var(--fx-ease) var(--fx-delay) both;
  backface-visibility: visible;
}


/* ============================================
   FLIP CARD ANIMATIONS (3D Card Effects)
   ============================================ */

/* Flip Card Container - Apply to parent wrapper */
.fx-flip-card {
  perspective: 1000px;
  position: relative;
}

.fx-flip-card-inner {
  position: relative;
  width: 100%;
  height: 100%;
  transition: transform var(--fx-duration-slow) var(--fx-ease-smooth);
  transform-style: preserve-3d;
}

/* Trigger flip on hover */
.fx-flip-card:hover .fx-flip-card-inner,
.fx-flip-card.fx-flipped .fx-flip-card-inner {
  transform: rotateY(180deg);
}

/* Front and back faces */
.fx-flip-card-front,
.fx-flip-card-back {
  position: absolute;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.fx-flip-card-back {
  transform: rotateY(180deg);
}

/* Vertical Flip Card */
.fx-flip-card-vertical:hover .fx-flip-card-inner,
.fx-flip-card-vertical.fx-flipped .fx-flip-card-inner {
  transform: rotateX(180deg);
}

.fx-flip-card-vertical .fx-flip-card-back {
  transform: rotateX(180deg);
}

/* Diagonal Flip Card */
.fx-flip-card-diagonal:hover .fx-flip-card-inner,
.fx-flip-card-diagonal.fx-flipped .fx-flip-card-inner {
  transform: rotate3d(1, 1, 0, 180deg);
}

.fx-flip-card-diagonal .fx-flip-card-back {
  transform: rotate3d(1, 1, 0, 180deg);
}

/* Flip Card with Scale */
.fx-flip-card-scale:hover .fx-flip-card-inner,
.fx-flip-card-scale.fx-flipped .fx-flip-card-inner {
  transform: rotateY(180deg) scale(1.1);
}

/* Animated Flip In (entrance animation) */
@keyframes fx-flip-card-in {
  from {
    opacity: 0;
    transform: perspective(400px) rotateY(-90deg);
  }
  to {
    opacity: 1;
    transform: perspective(400px) rotateY(0);
  }
}

.fx-flip-card-animate-in {
  animation: fx-flip-card-in var(--fx-duration-slow) var(--fx-ease) var(--fx-delay) both;
}

/* 3D Cube Flip */
@keyframes fx-cube-flip {
  0% {
    transform: rotateY(0deg);
  }
  100% {
    transform: rotateY(360deg);
  }
}

.fx-cube-flip {
  animation: fx-cube-flip 2s var(--fx-ease-smooth) var(--fx-delay) infinite;
  transform-style: preserve-3d;
}

/* Book Flip Animation */
@keyframes fx-book-flip {
  from {
    opacity: 0;
    transform: perspective(2000px) rotateY(-90deg);
    transform-origin: left center;
  }
  to {
    opacity: 1;
    transform: perspective(2000px) rotateY(0);
    transform-origin: left center;
  }
}

.fx-book-flip {
  animation: fx-book-flip var(--fx-duration-slower) var(--fx-ease) var(--fx-delay) both;
}


/* ============================================
   ROTATE ANIMATIONS
   ============================================ */

/* Rotate In */
@keyframes fx-rotate-in {
  from {
    opacity: 0;
    transform: rotate(-180deg) scale(0.9);
  }
  to {
    opacity: 1;
    transform: rotate(0) scale(1);
  }
}

.fx-rotate-in {
  animation: fx-rotate-in var(--fx-duration-slow) var(--fx-ease) var(--fx-delay) both;
}

/* Rotate In Down Left */
@keyframes fx-rotate-in-down-left {
  from {
    opacity: 0;
    transform: rotate(-45deg) translateY(calc(var(--fx-distance) * -1));
  }
  to {
    opacity: 1;
    transform: rotate(0) translateY(0);
  }
}

.fx-rotate-in-down-left {
  animation: fx-rotate-in-down-left var(--fx-duration) var(--fx-ease) var(--fx-delay) both;
}

/* Rotate In Up Right */
@keyframes fx-rotate-in-up-right {
  from {
    opacity: 0;
    transform: rotate(45deg) translateY(var(--fx-distance));
  }
  to {
    opacity: 1;
    transform: rotate(0) translateY(0);
  }
}

.fx-rotate-in-up-right {
  animation: fx-rotate-in-up-right var(--fx-duration) var(--fx-ease) var(--fx-delay) both;
}


/* ============================================
   BOUNCE ANIMATIONS
   ============================================ */

/* Bounce In */
@keyframes fx-bounce-in {
  0% {
    opacity: 0;
    transform: scale(0.3);
  }
  50% {
    opacity: 1;
    transform: scale(1.05);
  }
  70% {
    transform: scale(0.9);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

.fx-bounce-in {
  animation: fx-bounce-in var(--fx-duration-slow) var(--fx-ease) var(--fx-delay) both;
}

/* Bounce In Up */
@keyframes fx-bounce-in-up {
  0% {
    opacity: 0;
    transform: translateY(var(--fx-distance-large));
  }
  60% {
    opacity: 1;
    transform: translateY(calc(var(--fx-distance-small) * -1));
  }
  80% {
    transform: translateY(var(--fx-distance-small));
  }
  100% {
    transform: translateY(0);
  }
}

.fx-bounce-in-up {
  animation: fx-bounce-in-up var(--fx-duration-slow) var(--fx-ease) var(--fx-delay) both;
}


/* ============================================
   ATTENTION SEEKERS
   ============================================ */

/* Pulse */
@keyframes fx-pulse {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.05);
  }
}

.fx-pulse {
  animation: fx-pulse var(--fx-duration-slow) var(--fx-ease-in-out) var(--fx-delay) infinite;
}

/* Heartbeat */
@keyframes fx-heartbeat {
  0%, 100% {
    transform: scale(1);
  }
  14% {
    transform: scale(1.15);
  }
  28% {
    transform: scale(1);
  }
  42% {
    transform: scale(1.15);
  }
  70% {
    transform: scale(1);
  }
}

.fx-heartbeat {
  animation: fx-heartbeat var(--fx-duration-slower) var(--fx-ease-in-out) var(--fx-delay) infinite;
}

/* Shake */
@keyframes fx-shake {
  0%, 100% {
    transform: translateX(0);
  }
  10%, 30%, 50%, 70%, 90% {
    transform: translateX(-5px);
  }
  20%, 40%, 60%, 80% {
    transform: translateX(5px);
  }
}

.fx-shake {
  animation: fx-shake var(--fx-duration-slow) var(--fx-ease) var(--fx-delay) both;
}

/* Wobble */
@keyframes fx-wobble {
  0%, 100% {
    transform: translateX(0) rotate(0);
  }
  15% {
    transform: translateX(-10px) rotate(-5deg);
  }
  30% {
    transform: translateX(8px) rotate(3deg);
  }
  45% {
    transform: translateX(-8px) rotate(-3deg);
  }
  60% {
    transform: translateX(5px) rotate(2deg);
  }
  75% {
    transform: translateX(-3px) rotate(-1deg);
  }
}

.fx-wobble {
  animation: fx-wobble var(--fx-duration-slow) var(--fx-ease) var(--fx-delay) both;
}

/* Float */
@keyframes fx-float {
  0%, 100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-10px);
  }
}

.fx-float {
  animation: fx-float 2s var(--fx-ease-in-out) var(--fx-delay) infinite;
}


/* ============================================
   UTILITY MODIFIERS
   ============================================ */

/* Duration modifiers */
.fx-fast {
  animation-duration: var(--fx-duration-fast) !important;
}

.fx-slow {
  animation-duration: var(--fx-duration-slow) !important;
}

.fx-slower {
  animation-duration: var(--fx-duration-slower) !important;
}

/* Delay modifiers */
.fx-delay-short {
  animation-delay: var(--fx-delay-short) !important;
}

.fx-delay-medium {
  animation-delay: var(--fx-delay-medium) !important;
}

.fx-delay-long {
  animation-delay: var(--fx-delay-long) !important;
}

/* Infinite loop */
.fx-infinite {
  animation-iteration-count: infinite !important;
}

/* Reverse animation */
.fx-reverse {
  animation-direction: reverse !important;
}

/* Alternate animation */
.fx-alternate {
  animation-direction: alternate !important;
}

/* Pause animation */
.fx-paused {
  animation-play-state: paused !important;
}


/* ============================================
   PERFORMANCE OPTIMIZATIONS
   ============================================ */

/* Apply hardware acceleration to all animated elements */
[class*="fx-"] {
  will-change: transform, opacity;
  backface-visibility: hidden;
  perspective: 1000px;
}

/* Remove will-change after animation completes to free resources */
[class*="fx-"].fx-animated {
  will-change: auto;
}


/* ============================================
   STAGGER DELAYS (for sequential animations)
   ============================================ */

.fx-stagger-1 { animation-delay: calc(var(--fx-delay) + 0.1s) !important; }
.fx-stagger-2 { animation-delay: calc(var(--fx-delay) + 0.2s) !important; }
.fx-stagger-3 { animation-delay: calc(var(--fx-delay) + 0.3s) !important; }
.fx-stagger-4 { animation-delay: calc(var(--fx-delay) + 0.4s) !important; }
.fx-stagger-5 { animation-delay: calc(var(--fx-delay) + 0.5s) !important; }
.fx-stagger-6 { animation-delay: calc(var(--fx-delay) + 0.6s) !important; }
.fx-stagger-7 { animation-delay: calc(var(--fx-delay) + 0.7s) !important; }
.fx-stagger-8 { animation-delay: calc(var(--fx-delay) + 0.8s) !important; }


/* ============================================
   SCROLL-TRIGGERED ANIMATIONS (using Intersection Observer)
   Add .fx-on-scroll to elements for scroll-triggered animations
   ============================================ */

.fx-on-scroll {
  opacity: 0;
}

.fx-on-scroll.fx-in-view {
  opacity: 1;
}
