.fade-in { animation: fade .34s ease both; }
.slide-up { animation: slideUp .34s ease both; }
.scale-in { animation: scaleIn .2s ease both; }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes slideUp { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
@keyframes scaleIn { from { opacity: 0; transform: scale(.98); } to { opacity: 1; transform: scale(1); } }
@keyframes slideInRight { from { opacity: 0; transform: translateX(12px); } to { opacity: 1; transform: translateX(0); } }
@keyframes slideOutRight { to { opacity: 0; transform: translateX(12px); } }
@keyframes shimmer { to { transform: translateX(100%); } }
@keyframes spin { to { transform: rotate(360deg); } }
.ripple::after {
    content: ""; position: absolute; inset: auto; width: 0; height: 0; border-radius: 999px; background: rgba(255,255,255,.22);
    transform: translate(-50%, -50%); pointer-events: none;
}
.ripple.is-rippling::after { left: var(--ripple-x); top: var(--ripple-y); width: 180px; height: 180px; opacity: 0; transition: width .45s ease, height .45s ease, opacity .55s ease; }
