Flow Design System

Guía de Motion & Animación

Sistema de movimiento de 3 niveles con curvas de aceleración intencionales. El motion en Flow es funcional, no decorativo.

01 — Principios

Filosofía de movimiento

En Flow, el motion cumple una función: guiar la atención, confirmar acciones y comunicar jerarquía. Nunca es decorativo.

Regla fundamental: Cada animación debe responder a una pregunta — ¿qué acaba de cambiar? ¿dónde estoy? ¿mi acción fue exitosa? Si la animación no responde ninguna de estas preguntas, elimínala.

Los 4 pilares

✓ Funcional

El movimiento guía, no distrae. Cada transición tiene un propósito: indicar que algo cambió, confirmar una acción, o revelar contenido.

✓ Rápido

La interfaz debe sentirse inmediata. Los elementos pequeños responden en 150ms, los cambios de contenido en 300ms. Nada debería tardar más de 500ms.

✓ Consistente

Usa solo las 3 duraciones y 3 curvas del sistema. Un botón siempre reacciona igual, un modal siempre entra igual.

✓ Respetuoso

Siempre respeta prefers-reduced-motion. Ningún motion debe causar incomodidad o accesibilidad reducida.

Cuándo usar (y cuándo no)

✓ Usar motion

Hover en botones y cards. Apertura/cierre de modales y dropdowns. Cambio entre estados (toggle, tabs). Feedback visual de acciones (submit, delete). Entrada de elementos nuevos en la página.

✗ No usar motion

Decoración de fondo (partículas, gradientes animados). Animaciones infinitas en loop. Parallax excesivo. Transiciones entre páginas completas (excepto SPA). Micro-bounces o spring effects.

02 — Duraciones

Sistema de 3 niveles

Solo existen 3 duraciones en Flow. Elige según el tamaño del cambio visual.

Fast
150ms
Default
300ms
Slow
500ms

Pasa el mouse sobre cada barra para ver la duración en acción

Token Valor Uso Ejemplos
motion.duration.fast 150ms Micro-interacciones, cambios de color, hover Hover en botón, cambio de color en link, border-color en input focus
motion.duration.default 300ms Transiciones de contenido, cambios de layout Apertura de dropdown, cambio de tab, card hover lift, toggle switch
motion.duration.slow 500ms Cambios grandes, overlays, transiciones complejas Apertura de modal, fade de overlay, transición de página (SPA)
Regla de selección: ¿El cambio es de color/opacidad? → Fast. ¿El cambio mueve o revela contenido? → Default. ¿El cambio afecta la estructura completa de la vista? → Slow. Nunca inventes duraciones intermedias como 200ms o 400ms.
03 — Curvas de Aceleración

3 curvas, 3 propósitos

Cada curva tiene una personalidad diferente. Standard para ida y vuelta, Entrance para lo que aparece, Exit para lo que desaparece.

Standard
cubic-bezier(0.4, 0, 0.2, 1)

Hover, toggle, cualquier cambio reversible

Entrance
cubic-bezier(0, 0, 0.2, 1)

Modal abriendo, dropdown entrando, toast apareciendo

Exit
cubic-bezier(0.4, 0, 1, 1)

Modal cerrando, elemento saliendo, overlay fade-out

Pasa el mouse sobre cada tarjeta para ver la curva en acción

Token Valor Cuándo usar
motion.easing.standard cubic-bezier(0.4, 0, 0.2, 1) Transiciones reversibles — hover, toggle, tab switch, color change
motion.easing.entrance cubic-bezier(0, 0, 0.2, 1) Elementos que aparecen — modal abriendo, dropdown, toast, fade-in
motion.easing.exit cubic-bezier(0.4, 0, 1, 1) Elementos que desaparecen — modal cerrando, overlay fade-out, collapse
04 — Componentes Interactivos

Motion por componente

Cada componente tiene sus propiedades animables y configuración exacta. Los demos son interactivos — pruébalos.

Botones

PropiedadDuraciónCurvaDetalles
background-color fast (150ms) standard Hover: green-500 → green-600
transform fast (150ms) standard Hover: translateY(-1px) · Active: translateY(0)
box-shadow fast (150ms) standard Hover: elevation.md · Active: none
border-color (secondary) fast (150ms) standard Hover: border → green-500

Cards

Proyecto Alpha
Hover para ver la elevación y el borde verde.
Proyecto Beta
El lift es de 4px — suficiente sin ser exagerado.
PropiedadDuraciónCurvaDetalles
transform default (300ms) standard Hover: translateY(-4px)
box-shadow default (300ms) standard Hover: elevation.lg
border-color default (300ms) standard Hover: border → green-500

Inputs & Focus

PropiedadDuraciónCurvaDetalles
border-color fast (150ms) standard Focus: border → green-500
box-shadow (focus ring) fast (150ms) standard Focus: 0 0 0 3px rgba(59,235,100, 0.12)

Toggle Switch

Haz clic para activar/desactivar
PropiedadDuraciónCurvaDetalles
background (track) default (300ms) standard border → green-500
transform (knob) default (300ms) standard translateX(0) → translateX(20px)
05 — Transiciones de Contenido

Patrones de entrada y salida

Cómo aparece y desaparece el contenido — modales, dropdowns, toasts, y tooltips.

Modal / Dialog

ElementoEntradaSalida
Overlay (backdrop) opacity 0→0.9 · slow · entrance opacity 0.9→0 · default · exit
Panel (contenido) opacity 0→1, translateY(16px→0) · slow · entrance opacity 1→0, translateY(0→8px) · default · exit

Dropdown / Popover

PropiedadEntradaSalida
opacity 0→1 · default · entrance 1→0 · fast · exit
transform translateY(-4px)→translateY(0) · default · entrance Ninguno — solo fade out
transform-origin Según posición: top para dropdown, bottom para popup, center para tooltip

Toast / Notification

PropiedadEntradaAuto-dismiss
opacity + translateY 0→1, translateY(12px→0) · default · entrance 1→0, translateY(0→-8px) · default · exit
Duración visible Success: 3s · Error: 5s (o manual dismiss) · Info: 4s

Tooltip

PropiedadEntradaSalida
opacity 0→1 · fast · entrance 1→0 · fast · exit
Delay Entrada: 200ms delay · Salida: inmediata
06 — Transiciones de Página

Navegación y cambios de vista

Para aplicaciones SPA o secciones con cambio de contenido dinámico.

Dashboard

Vista principal con métricas y acceso rápido.

Proyectos

Lista de proyectos activos del equipo.

Configuración

Preferencias y ajustes de la cuenta.

Haz clic en los dots del sidebar para ver la transición entre páginas

PatrónTransiciónCuándo usar
Fade + Slide Up opacity 0→1, translateY(12px→0) · default · entrance Cambio de tab, navegación entre vistas en SPA
Cross-fade Salida: opacity 1→0 · Entrada: opacity 0→1 · default Cambio entre contenidos del mismo nivel jerárquico
Slide lateral translateX(100%→0) · slow · entrance Panel lateral, drawer, step wizard
Expand/Collapse max-height 0→auto, opacity 0→1 · default · standard Accordions, secciones expandibles, FAQs
07 — Mapa de Transiciones

Referencia rápida por componente

Tabla completa de qué propiedades animar en cada componente, con duración y curva exactas.

Componente
Propiedades
Duración
Curva
Button (primary)
background, transform, box-shadow
fast
standard
Button (secondary)
border-color, color, background
fast
standard
Card
transform, box-shadow, border-color
default
standard
Input focus
border-color, box-shadow
fast
standard
Toggle switch
background, transform (knob)
default
standard
Link / Nav item
color, border-bottom-color
fast
standard
Modal (entrada)
opacity, transform (translateY)
slow
entrance
Modal (salida)
opacity, transform
default
exit
Dropdown
opacity, transform (translateY)
default / fast
entrance / exit
Toast
opacity, transform (translateY)
default
entrance / exit
Tooltip
opacity
fast
entrance / exit
Overlay (backdrop)
opacity
slow / default
entrance / exit
Accordion
max-height, opacity
default
standard
Page transition
opacity, transform (translateY)
default
entrance
Sidebar / Drawer
transform (translateX)
slow
entrance / exit
08 — Movimiento Reducido

Accesibilidad de motion

Flow respeta la preferencia del sistema operativo. Si el usuario tiene activada la reducción de movimiento, todas las animaciones se desactivan o simplifican.

Regla obligatoria: Todo archivo CSS o componente que incluya transiciones debe incluir el media query prefers-reduced-motion: reduce.

Los elementos con prefers-reduced-motion activo reemplazan todas las transiciones con cambios instantáneos (duration: 0ms) o transiciones mínimas (opacity only, fast).

/* Reduced Motion — obligatorio en todo proyecto Flow */ @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; } } /* Alternativa granular — mantiene fade pero elimina movimiento */ @media (prefers-reduced-motion: reduce) { .modal-panel { transition: opacity 150ms ease; transform: none !important; } .card:hover { transform: none; /* Mantiene el cambio de border-color como feedback visual */ } }
✓ Correcto

Eliminar translateY, translateX, scale. Reducir duraciones a instantáneo. Mantener cambios de color/opacity como feedback mínimo. Usar opacity como fallback de transiciones complejas.

✗ Incorrecto

Ignorar la preferencia del usuario. Usar !important para forzar animaciones. Dejar scroll-behavior: smooth sin override. Depender del motion como único indicador de estado.

09 — Código de Referencia

Custom properties y mixins

Variables CSS listas para copiar. Todas las animaciones del sistema se construyen con estas 6 custom properties.

/* ── Flow Motion Tokens ── */ :root { /* Duraciones */ --flow-motion-duration-fast: 150ms; --flow-motion-duration-default: 300ms; --flow-motion-duration-slow: 500ms; /* Curvas */ --flow-motion-easing-standard: cubic-bezier(0.4, 0, 0.2, 1); --flow-motion-easing-entrance: cubic-bezier(0, 0, 0.2, 1); --flow-motion-easing-exit: cubic-bezier(0.4, 0, 1, 1); }

Shorthand patterns

/* ── Patrones comunes — copiar y adaptar ── */ /* Botón hover */ .btn { transition: background var(--flow-motion-duration-fast) var(--flow-motion-easing-standard), transform var(--flow-motion-duration-fast) var(--flow-motion-easing-standard), box-shadow var(--flow-motion-duration-fast) var(--flow-motion-easing-standard); } /* Card lift */ .card { transition: transform var(--flow-motion-duration-default) var(--flow-motion-easing-standard), box-shadow var(--flow-motion-duration-default) var(--flow-motion-easing-standard), border-color var(--flow-motion-duration-default) var(--flow-motion-easing-standard); } /* Modal entrada */ .modal-overlay { transition: opacity var(--flow-motion-duration-slow) var(--flow-motion-easing-entrance); } .modal-panel { transition: opacity var(--flow-motion-duration-slow) var(--flow-motion-easing-entrance), transform var(--flow-motion-duration-slow) var(--flow-motion-easing-entrance); } /* Modal salida (clase .is-closing) */ .modal-overlay.is-closing { transition: opacity var(--flow-motion-duration-default) var(--flow-motion-easing-exit); } .modal-panel.is-closing { transition: opacity var(--flow-motion-duration-default) var(--flow-motion-easing-exit), transform var(--flow-motion-duration-default) var(--flow-motion-easing-exit); } /* Input focus */ .input { transition: border-color var(--flow-motion-duration-fast) var(--flow-motion-easing-standard), box-shadow var(--flow-motion-duration-fast) var(--flow-motion-easing-standard); } /* Page transition (SPA) */ .page-enter { opacity: 0; transform: translateY(12px); } .page-enter-active { opacity: 1; transform: translateY(0); transition: opacity var(--flow-motion-duration-default) var(--flow-motion-easing-entrance), transform var(--flow-motion-duration-default) var(--flow-motion-easing-entrance); } /* Toast notification */ @keyframes toastIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } } .toast { animation: toastIn var(--flow-motion-duration-default) var(--flow-motion-easing-entrance); }
Checklist antes de entregar:

① ¿Usas solo las 3 duraciones del sistema? (150 / 300 / 500ms)
② ¿Cada transición usa la curva correcta? (standard / entrance / exit)
③ ¿Incluiste el media query prefers-reduced-motion?
④ ¿Las transiciones de hover usan fast?
⑤ ¿Los modales usan slow para entrada y default para salida?
⑥ ¿El motion comunica algo? Si no, elimínalo.