/* ============================================================ GLASSGRID — ANIMATIONS & MOTION All durations/easings reference tokens. ============================================================ */ /* ── Page Transition ── */ @keyframes fadeInUp { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes slideUp { from { transform: translateY(100%); } to { transform: translateY(0); } } @keyframes slideDown { from { transform: translateY(-100%); } to { transform: translateY(0); } } @keyframes scaleIn { from { opacity: 0; transform: scale(0.92); } to { opacity: 1; transform: scale(1); } } /* ── Like Heart Pop ── */ @keyframes heartPop { 0% { transform: scale(1); } 30% { transform: scale(1.35); } 60% { transform: scale(0.9); } 100% { transform: scale(1); } } /* ── Toast ── */ @keyframes toastIn { from { opacity: 0; transform: translateY(10px) translateX(-50%) scale(0.95); } to { opacity: 1; transform: translateY(0) translateX(-50%) scale(1); } } @keyframes toastOut { from { opacity: 1; transform: translateY(0) translateX(-50%) scale(1); } to { opacity: 0; transform: translateY(-6px) translateX(-50%) scale(0.95); } } /* ── Shimmer Skeleton ── */ @keyframes shimmer { 0% { background-position: -200% center; } 100% { background-position: 200% center; } } /* ── Spin ── */ @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } /* ── Pulse ── */ @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } /* ── Float ── */ @keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } } /* ─── Animation Utility Classes ─── */ .animate-fadeInUp { animation: fadeInUp var(--duration-normal) var(--ease-out) both; } .animate-fadeIn { animation: fadeIn var(--duration-normal) var(--ease-out) both; } .animate-scaleIn { animation: scaleIn var(--duration-normal) var(--ease-spring) both; } .animate-slideUp { animation: slideUp var(--duration-slow) var(--ease-out) both; } .animate-heartPop { animation: heartPop var(--duration-slow) var(--ease-spring); } .animate-toastIn { animation: toastIn var(--duration-normal) var(--ease-spring) both; } .animate-spin { animation: spin 1s linear infinite; } .animate-pulse { animation: pulse 2s ease-in-out infinite; } .animate-float { animation: float 3s ease-in-out infinite; } /* ─── Skeleton Loader ─── */ .skeleton { background: linear-gradient( 90deg, var(--color-glass-fill) 25%, var(--color-glass-fill-md) 50%, var(--color-glass-fill) 75% ); background-size: 200% 100%; animation: shimmer 1.5s linear infinite; border-radius: var(--radius-md); } /* ─── Staggered Children ─── */ .stagger > *:nth-child(1) { animation-delay: 0ms; } .stagger > *:nth-child(2) { animation-delay: 60ms; } .stagger > *:nth-child(3) { animation-delay: 120ms; } .stagger > *:nth-child(4) { animation-delay: 180ms; } .stagger > *:nth-child(5) { animation-delay: 240ms; } .stagger > *:nth-child(6) { animation-delay: 300ms; } .stagger > *:nth-child(7) { animation-delay: 360ms; } .stagger > *:nth-child(8) { animation-delay: 420ms; } /* ─── Reduced Motion ─── */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } }