/** * Animations & Micro-interactions - Cursor-Inspired * Smooth, fast animations with 200ms duration * Version: 1.0.0 */ /* ============================================ KEYFRAME ANIMATIONS ============================================ */ /* Fade In */ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } /* Fade In Up */ @keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } /* Fade In Down */ @keyframes fadeInDown { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } } /* Fade In Left */ @keyframes fadeInLeft { from { opacity: 0; transform: translateX(-20px); } to { opacity: 1; transform: translateX(0); } } /* Fade In Right */ @keyframes fadeInRight { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: translateX(0); } } /* Scale In */ @keyframes scaleIn { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } } /* Slide In Right */ @keyframes slideInRight { from { transform: translateX(100%); } to { transform: translateX(0); } } /* Slide In Left */ @keyframes slideInLeft { from { transform: translateX(-100%); } to { transform: translateX(0); } } /* Slide Out Right */ @keyframes slideOutRight { from { transform: translateX(0); } to { transform: translateX(100%); } } /* Slide Out Left */ @keyframes slideOutLeft { from { transform: translateX(0); } to { transform: translateX(-100%); } } /* Pulse */ @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } /* Spin */ @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } /* Bounce */ @keyframes bounce { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } } /* Shake */ @keyframes shake { 0%, 100% { transform: translateX(0); } 10%, 30%, 50%, 70%, 90% { transform: translateX(-4px); } 20%, 40%, 60%, 80% { transform: translateX(4px); } } /* Glow */ @keyframes glow { 0%, 100% { box-shadow: 0 0 10px var(--accent-purple-glow); } 50% { box-shadow: 0 0 20px var(--accent-purple-glow); } } /* Shimmer */ @keyframes shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } } /* Progress Indeterminate */ @keyframes progressIndeterminate { 0% { left: -35%; right: 100%; } 60% { left: 100%; right: -90%; } 100% { left: 100%; right: -90%; } } /* ============================================ ANIMATION UTILITY CLASSES ============================================ */ /* Fade Animations */ .animate-fade-in { animation: fadeIn var(--duration-normal) var(--ease-in-out); } .animate-fade-in-up { animation: fadeInUp var(--duration-normal) var(--ease-in-out); } .animate-fade-in-down { animation: fadeInDown var(--duration-normal) var(--ease-in-out); } .animate-fade-in-left { animation: fadeInLeft var(--duration-normal) var(--ease-in-out); } .animate-fade-in-right { animation: fadeInRight var(--duration-normal) var(--ease-in-out); } /* Scale Animation */ .animate-scale-in { animation: scaleIn var(--duration-normal) var(--ease-in-out); } /* Slide Animations */ .animate-slide-in-right { animation: slideInRight var(--duration-medium) var(--ease-in-out); } .animate-slide-in-left { animation: slideInLeft var(--duration-medium) var(--ease-in-out); } .animate-slide-out-right { animation: slideOutRight var(--duration-medium) var(--ease-in-out); } .animate-slide-out-left { animation: slideOutLeft var(--duration-medium) var(--ease-in-out); } /* Utility Animations */ .animate-pulse { animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; } .animate-spin { animation: spin 1s linear infinite; } .animate-bounce { animation: bounce 1s ease-in-out infinite; } .animate-shake { animation: shake 0.5s ease-in-out; } .animate-glow { animation: glow 2s ease-in-out infinite; } .animate-shimmer { background: linear-gradient( 90deg, transparent 0%, rgba(255, 255, 255, 0.05) 50%, transparent 100% ); background-size: 200% 100%; animation: shimmer 2s linear infinite; } /* ============================================ STAGGER ANIMATIONS ============================================ */ .stagger-fade-in > * { animation: fadeInUp var(--duration-normal) var(--ease-in-out) backwards; } .stagger-fade-in > *:nth-child(1) { animation-delay: 0ms; } .stagger-fade-in > *:nth-child(2) { animation-delay: 50ms; } .stagger-fade-in > *:nth-child(3) { animation-delay: 100ms; } .stagger-fade-in > *:nth-child(4) { animation-delay: 150ms; } .stagger-fade-in > *:nth-child(5) { animation-delay: 200ms; } .stagger-fade-in > *:nth-child(6) { animation-delay: 250ms; } .stagger-fade-in > *:nth-child(7) { animation-delay: 300ms; } .stagger-fade-in > *:nth-child(8) { animation-delay: 350ms; } .stagger-fade-in > *:nth-child(9) { animation-delay: 400ms; } .stagger-fade-in > *:nth-child(10) { animation-delay: 450ms; } /* ============================================ HOVER EFFECTS - Cursor-style ============================================ */ .hover-lift { transition: transform var(--duration-normal) var(--ease-in-out); } .hover-lift:hover { transform: translateY(-2px); } .hover-scale { transition: transform var(--duration-normal) var(--ease-in-out); } .hover-scale:hover { transform: scale(1.02); } .hover-glow { transition: box-shadow var(--duration-normal) var(--ease-in-out); } .hover-glow:hover { box-shadow: var(--shadow-purple); } .hover-brightness { transition: filter var(--duration-normal) var(--ease-in-out); } .hover-brightness:hover { filter: brightness(1.1); } /* ============================================ ACTIVE/CLICK EFFECTS ============================================ */ .active-scale { transition: transform var(--duration-fast) var(--ease-in-out); } .active-scale:active { transform: scale(0.98); } /* Ripple Effect */ .ripple { position: relative; overflow: hidden; } .ripple::after { content: ''; position: absolute; top: 50%; left: 50%; width: 0; height: 0; border-radius: 50%; background: rgba(255, 255, 255, 0.3); transform: translate(-50%, -50%); transition: width var(--duration-medium) var(--ease-out), height var(--duration-medium) var(--ease-out), opacity var(--duration-medium) var(--ease-out); pointer-events: none; opacity: 0; } .ripple:active::after { width: 200px; height: 200px; opacity: 1; } /* ============================================ LOADING STATES ============================================ */ .loading { position: relative; pointer-events: none; opacity: 0.6; } .loading::after { content: ''; position: absolute; top: 50%; left: 50%; width: 20px; height: 20px; margin: -10px 0 0 -10px; border: 2px solid var(--accent-purple); border-top-color: transparent; border-radius: 50%; animation: spin 0.8s linear infinite; } /* Spinner */ .spinner { width: 20px; height: 20px; border: 2px solid var(--surface-tertiary); border-top-color: var(--accent-purple); border-radius: 50%; animation: spin 0.8s linear infinite; } .spinner-sm { width: 16px; height: 16px; border-width: 2px; } .spinner-lg { width: 32px; height: 32px; border-width: 3px; } /* Dots Loader */ .dots-loader { display: inline-flex; gap: 6px; } .dots-loader span { width: 8px; height: 8px; background: var(--accent-purple); border-radius: 50%; animation: dotsLoader 1.4s ease-in-out infinite; } .dots-loader span:nth-child(1) { animation-delay: 0s; } .dots-loader span:nth-child(2) { animation-delay: 0.2s; } .dots-loader span:nth-child(3) { animation-delay: 0.4s; } @keyframes dotsLoader { 0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); } 40% { opacity: 1; transform: scale(1); } } /* ============================================ PROGRESS ANIMATIONS ============================================ */ .progress-indeterminate { position: relative; overflow: hidden; } .progress-indeterminate::before { content: ''; position: absolute; top: 0; left: 0; bottom: 0; background: var(--accent-purple-gradient); animation: progressIndeterminate 2s cubic-bezier(0.4, 0, 0.2, 1) infinite; } /* ============================================ PAGE TRANSITIONS ============================================ */ .page-transition-enter { animation: fadeInUp var(--duration-normal) var(--ease-in-out); } .page-transition-exit { animation: fadeOut var(--duration-fast) var(--ease-in-out); } @keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } } /* ============================================ SCROLL ANIMATIONS ============================================ */ .scroll-reveal { opacity: 0; transform: translateY(30px); transition: opacity var(--duration-medium) var(--ease-in-out), transform var(--duration-medium) var(--ease-in-out); } .scroll-reveal.revealed { opacity: 1; transform: translateY(0); } /* ============================================ SKELETON ANIMATIONS ============================================ */ .skeleton-wave { position: relative; overflow: hidden; background: var(--surface-secondary); } .skeleton-wave::after { content: ''; position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: linear-gradient( 90deg, transparent 0%, var(--surface-tertiary) 50%, transparent 100% ); background-size: 200% 100%; animation: shimmer 1.5s linear infinite; } /* ============================================ NUMBER COUNTER ANIMATION ============================================ */ .counter { display: inline-block; } .counter.counting { animation: countPulse 0.3s ease-in-out; } @keyframes countPulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } } /* ============================================ NOTIFICATION ANIMATIONS ============================================ */ .notification-enter { animation: slideInRight var(--duration-medium) var(--ease-in-out); } .notification-exit { animation: slideOutRight var(--duration-medium) var(--ease-in-out); } /* ============================================ MODAL ANIMATIONS ============================================ */ .modal-backdrop-enter { animation: fadeIn var(--duration-normal) var(--ease-in-out); } .modal-backdrop-exit { animation: fadeOut var(--duration-normal) var(--ease-in-out); } .modal-enter { animation: scaleIn var(--duration-normal) var(--ease-in-out); } .modal-exit { animation: fadeOut var(--duration-fast) var(--ease-in-out); } /* ============================================ DROPDOWN ANIMATIONS ============================================ */ .dropdown-enter { animation: fadeInDown var(--duration-fast) var(--ease-out); } .dropdown-exit { animation: fadeOut var(--duration-fast) var(--ease-in); } /* ============================================ TOOLTIP ANIMATIONS ============================================ */ .tooltip-enter { animation: scaleIn var(--duration-fast) var(--ease-out); } .tooltip-exit { animation: fadeOut var(--duration-fast) var(--ease-in); } /* ============================================ PARALLAX EFFECTS ============================================ */ .parallax { transition: transform var(--duration-slow) var(--ease-out); } .parallax[data-speed="slow"] { transition-duration: var(--duration-slower); } .parallax[data-speed="fast"] { transition-duration: var(--duration-normal); } /* ============================================ SMOOTH SCROLL ============================================ */ html { scroll-behavior: smooth; } @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } } /* ============================================ INTERSECTION OBSERVER ANIMATIONS ============================================ */ [data-animate]:not(.animated) { opacity: 0; } [data-animate="fade"].animated { animation: fadeIn var(--duration-medium) var(--ease-in-out); } [data-animate="fade-up"].animated { animation: fadeInUp var(--duration-medium) var(--ease-in-out); } [data-animate="fade-down"].animated { animation: fadeInDown var(--duration-medium) var(--ease-in-out); } [data-animate="fade-left"].animated { animation: fadeInLeft var(--duration-medium) var(--ease-in-out); } [data-animate="fade-right"].animated { animation: fadeInRight var(--duration-medium) var(--ease-in-out); } [data-animate="scale"].animated { animation: scaleIn var(--duration-medium) var(--ease-in-out); } /* Animation Delays */ [data-delay="100"].animated { animation-delay: 100ms; } [data-delay="200"].animated { animation-delay: 200ms; } [data-delay="300"].animated { animation-delay: 300ms; } [data-delay="400"].animated { animation-delay: 400ms; } [data-delay="500"].animated { animation-delay: 500ms; } /* ============================================ PERFORMANCE OPTIMIZATIONS ============================================ */ /* GPU Acceleration */ .will-change-transform { will-change: transform; } .will-change-opacity { will-change: opacity; } /* Disable animations for reduced motion preference */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } }