/* @utilities/animations */ @keyframes pulsate { 0% { box-shadow: 0 0 0 0 var(--accent); transform: scale(0.9); } 50% { transform: scale(1); } 100% { box-shadow: 0 0 20px 10px transparent; transform: scale(0.9); } } @keyframes fadeInOpacity { from { opacity: 0; } to { opacity: 1; } } @keyframes fadeInTranslate { from { transform: translateY(0.75vh); } to { transform: translateY(0vh); } } @keyframes aurora { from { background-position: 50% 50%, 50% 50%; } to { background-position: 350% 50%, 350% 50%; } } @keyframes spin-slow { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @keyframes spin-reverse { from { transform: rotate(0deg); } to { transform: rotate(-360deg); } } @keyframes marquee-vertical { from { transform: translateY(0); } to { transform: translateY(-50%); } } @keyframes marquee-vertical-reverse { from { transform: translateY(-50%); } to { transform: translateY(0); } } @keyframes marquee-horizontal { from { transform: translateX(0); } to { transform: translateX(-50%); } } @keyframes marquee-horizontal-reverse { from { transform: translateX(-50%); } to { transform: translateX(0); } } @keyframes orbit { from { transform: rotate(var(--initial-position, 0deg)) translateX(var(--translate-position, 120px)) rotate(calc(-1 * var(--initial-position, 0deg))); } to { transform: rotate(calc(var(--initial-position, 0deg) + 360deg)) translateX(var(--translate-position, 120px)) rotate(calc(-1 * (var(--initial-position, 0deg) + 360deg))); } } @keyframes map-dot-pulse { 0%, 100% { transform: scale(0.4); opacity: 0.6; } 50% { transform: scale(1.4); opacity: 1; } } /* Animation classes */ .animate-pulsate { animation: pulsate 1.5s infinite; } .animation-container { animation: fadeInOpacity 0.8s ease-in-out forwards, fadeInTranslate 0.6s forwards; } .animation-container-fade { animation: fadeInOpacity 0.8s ease-in-out forwards; } .animate-spin-slow { animation: spin-slow 15s linear infinite; } .animate-spin-reverse { animation: spin-reverse 10s linear infinite; } .animate-marquee-vertical { animation: marquee-vertical 40s linear infinite; } .animate-marquee-vertical-reverse { animation: marquee-vertical-reverse 40s linear infinite; } .animate-marquee-horizontal { animation: marquee-horizontal 15s linear infinite; } .animate-marquee-horizontal-reverse { animation: marquee-horizontal-reverse 15s linear infinite; } @keyframes gradient-shift { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } .animated-gradient-button:hover { animation: gradient-shift 4s ease infinite; } @keyframes fade-in-up { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } @keyframes slide-in-left { from { opacity: 0; transform: translateX(-20px); } to { opacity: 1; transform: translateX(0); } } .animate-on-scroll { opacity: 0; } .animate-on-scroll.is-visible { animation: fade-in-up 0.8s ease-out forwards; } /* Hover effects */ .card, .primary-button, .secondary-button { transition: transform 0.3s ease-out, box-shadow 0.3s ease-out; } .card:hover { transform: translateY(-5px); box-shadow: color-mix(in srgb, var(--color-foreground) 8%, transparent) 0px 8px 40px 0px; } .primary-button:hover { transform: translateY(-2px); box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-accent) 60%, transparent), 0 8px 16px -4px color-mix(in srgb, var(--color-accent) 45%, transparent), inset 0 1px 0 0 color-mix(in srgb, var(--color-foreground) 20%, transparent); } .secondary-button:hover { transform: translateY(-2px); box-shadow: 0 4px 8px 0 rgb(0 0 0 / 0.08); }