/** * Reusable CSS @keyframes Animations * * Common animation patterns for Angular applications. * Import this file in your component styles or global styles. */ /* ============================================ FADE ANIMATIONS ============================================ */ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } } .fade-in { animation: fadeIn 0.3s ease-out; } .fade-out { animation: fadeOut 0.3s ease-in; } /* ============================================ SLIDE ANIMATIONS ============================================ */ @keyframes slideInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } @keyframes slideOutDown { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(20px); } } @keyframes slideInDown { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } } @keyframes slideOutUp { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(-20px); } } @keyframes slideInLeft { from { opacity: 0; transform: translateX(-20px); } to { opacity: 1; transform: translateX(0); } } @keyframes slideOutLeft { from { opacity: 1; transform: translateX(0); } to { opacity: 0; transform: translateX(-20px); } } @keyframes slideInRight { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: translateX(0); } } @keyframes slideOutRight { from { opacity: 1; transform: translateX(0); } to { opacity: 0; transform: translateX(20px); } } .slide-in-up { animation: slideInUp 0.3s ease-out; } .slide-out-down { animation: slideOutDown 0.3s ease-in; } .slide-in-down { animation: slideInDown 0.3s ease-out; } .slide-out-up { animation: slideOutUp 0.3s ease-in; } .slide-in-left { animation: slideInLeft 0.3s ease-out; } .slide-out-left { animation: slideOutLeft 0.3s ease-in; } .slide-in-right { animation: slideInRight 0.3s ease-out; } .slide-out-right { animation: slideOutRight 0.3s ease-in; } /* ============================================ SCALE ANIMATIONS ============================================ */ @keyframes scaleIn { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } } @keyframes scaleOut { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0.9); } } .scale-in { animation: scaleIn 0.2s ease-out; } .scale-out { animation: scaleOut 0.2s ease-in; } /* ============================================ UTILITY ANIMATIONS ============================================ */ /* Loading Spinner */ @keyframes spin { to { transform: rotate(360deg); } } .spin { animation: spin 1s linear infinite; } /* Skeleton Loading */ @keyframes shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } } .shimmer { background: linear-gradient( 90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75% ); background-size: 200% 100%; animation: shimmer 1.5s infinite; } /* Attention Pulse */ @keyframes attention-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.5); } 50% { box-shadow: 0 0 0 10px rgba(59, 130, 246, 0); } } .attention-pulse { animation: attention-pulse 2s ease-in-out infinite; } /* Shake (Error Feedback) */ @keyframes shake { 0%, 100% { transform: translateX(0); } 10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); } 20%, 40%, 60%, 80% { transform: translateX(5px); } } .shake { animation: shake 0.5s ease-in-out; } /* Breathing/Pulsing */ @keyframes breathe { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.7; transform: scale(1.05); } } .breathe { animation: breathe 2s ease-in-out infinite; } /* ============================================ TOAST/NOTIFICATION ANIMATIONS ============================================ */ @keyframes toastIn { from { opacity: 0; transform: translateY(100%) scale(0.9); } to { opacity: 1; transform: translateY(0) scale(1); } } @keyframes toastOut { from { opacity: 1; transform: translateY(0) scale(1); } to { opacity: 0; transform: translateY(100%) scale(0.9); } } .toast-in { animation: toastIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); } .toast-out { animation: toastOut 0.2s ease-in forwards; } /* ============================================ ACCESSIBILITY ============================================ */ /* Respect user's motion preferences */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } }