Motion
Sistema de animaciones y transiciones. Sutiles, funcionales, nunca decorativas.
Principios de motion
Funcional
Toda animación comunica un cambio de estado o guía la atención del usuario.
Sutil
Duraciones cortas (150-300ms). Si el usuario nota la animación, es demasiado larga.
Consistente
Mismas curvas y duraciones para acciones similares en toda la app.
Respetuosa
Respetar prefers-reduced-motion. Desactivar animaciones si el usuario lo pide.
Escala de duración
| Nombre | Duración | Uso |
|---|---|---|
| instant | 100ms | Hover de colores, opacity |
| fast | 150ms | Tooltips, micro-interacciones |
| normal | 200ms | Modals, toasts, accordions |
| slow | 300ms | Page transitions, complex layouts |
| slower | 500ms | Staggered animations, hero sections |
Curvas de easing
/* Estándar — la mayoría de transiciones */
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
/* Entrada — elementos que aparecen */
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
/* Salida — elementos que desaparecen */
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
/* En Tailwind: */
.transition-all /* → usa ease por defecto */
.ease-in /* → entrada */
.ease-out /* → salida */
.ease-in-out /* → estándar */Catálogo de animaciones
Fade In
Aparición de elementos: modals, toasts, dropdowns
200msScale Up
Hover en botones, cards interactivas
200msSlide Down
Menús desplegables, accordions
200msPulse
Indicadores de estado activo (badge dot)
2000msSpin
Loading spinners
1000msReduced motion
/* CSS — deshabilitar animaciones */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
/* Tailwind */
<div className="motion-safe:animate-pulse motion-reduce:animate-none">
/* iOS — UIAccessibility.isReduceMotionEnabled */
/* Android — Settings.Global.ANIMATOR_DURATION_SCALE */