Cómo se mueve MiCapi. La app se construye en Flutter para Android (90% del tráfico) e iOS — toda la spec usa Duration y Curves nativos, no cubic-bezier de CSS. El motion en fintech acompaña — nunca bloquea ni adorna acciones que mueven dinero.
Si una animación no cumple uno de estos cinco principios, no debe existir. La estética es consecuencia, no objetivo.
Si quitar la animación no pierde información ni orientación, no debe existir.
Confirmar compra ejecuta inmediato. La animación acompaña — el usuario nunca espera a que termine.
Si MediaQuery.disableAnimationsOf(context), reemplazar por crossfade o corte.
La misma transición para el mismo tipo de acción. No inventamos motion por pantalla.
Baseline Material 3. iOS debe sentirse nativo, pero no diseñamos dos sistemas paralelos.
Cuatro duraciones canónicas. La barra recorre su duración real, luego se mantiene, retorna y se mantiene — todas comparten el mismo ciclo de 1.8s para que veas la diferencia relativa.
Las cuatro barras corren sincronizadas en un ciclo de 1800ms. Mismo punto de arranque · velocidades reales.
Tres curvas canónicas, mapeadas directamente a Curves de Flutter. La gráfica muestra tiempo (x) contra progreso (y). Si un patrón necesita una curva custom (spring, overshoot), se define inline — no se agrega al sistema.
CurveTween custom ni curvas con overshoot (spring, elastic, bounceOut). El motion fintech no rebota: en una pantalla de confirmación de compra, un overshoot lee como inestabilidad. Si un patrón necesita una curva no canónica, se justifica caso por caso — nunca como token global.Seis patrones canónicos. Cada mockup se renderiza a ancho de Android (360dp) — el formato real en el que vivirán. La barra de estado y la barra de navegación gestual son referencia visual de encuadre, no chrome obligatorio.
Cuándo vibra el dispositivo. El haptic es feedback táctil — no es decoración, no es premio. Reservado para acciones financieras confirmatorias y para confirmar que algo se copió o seleccionó.
| Momento | Tipo (Flutter) | Por qué |
|---|---|---|
| Confirmar compra de cripto | HapticFeedback.mediumImpact() | Acción financiera irreversible confirmada |
| Confirmar retiro a banco | HapticFeedback.mediumImpact() | Acción financiera confirmada |
| Confirmar retiro a wallet externa | HapticFeedback.heavyImpact() | Acción irreversible on-chain — el impacto refuerza la finalidad |
| Copiar dirección · hash · referencia | HapticFeedback.lightImpact() | Feedback de acción completada |
| Toggle · switch · segmented control | HapticFeedback.selectionClick() | Feedback sutil de selección |
| Momento | Tipo (Flutter) | Nota |
|---|---|---|
| Error de validación (shake del input) | HapticFeedback.lightImpact() | Puede reforzar el error visual, pero evaluar si se siente excesivo en uso repetido. Probar con usuarios reales antes de fijarlo como regla. |
No usar haptic en scroll, navegación normal, aparición de modales, animaciones de carga, ni cambios de estado pasivos (precio actualizándose, balance refrescando). El haptic gratuito desgasta su valor — cuando llega el haptic importante, el usuario ya lo ignora.
Comparación lado a lado. Cuando MediaQuery.disableAnimationsOf(context) es true, el movimiento se reemplaza por crossfade o corte directo. Los haptics se mantienen — son feedback táctil, no visual.
Cheat sheet final. Si no estás seguro de qué hacer, esta es la regla.
InkWell con ripple en todo elemento tappable (botones, cards, list tiles).CupertinoPageRoute ni transiciones iOS-only como default.