El hero del dashboard. Muestra el portafolio del usuario: valorización total en COP (referencia, no saldo gastable) y los saldos cripto reales de BTC, ETH y USDT. En MiCapi no existe "saldo COP" — el peso solo existe en tránsito durante una compra. Este card es donde se decide si la app parece exchange profesional o neobank claro.
Siete elementos. La jerarquía es deliberada: valorización arriba grande, saldos cripto abajo como la verdad operativa. La COP es referencia; el cripto es lo que el usuario realmente tiene.
"Valor estimado en COP" — el copy es explícito: no es saldo, es una estimación. Ícono trending-up refuerza que es valorización de mercado. Nunca "Saldo COP".
Icono eye / eye-off en la esquina superior derecha. Tap → oculta todos los montos del card. Estado persiste vía SharedPreferences.
Mono tabular, 32dp, peso 600. Sufijo COP en peso menor. Es lo más grande del card, pero no es saldo gastable — solo referencia.
Chip semántico — verde success si sube, rojo error si baja. Flecha direccional + porcentaje tabular. Sufijo 24h aparte.
Hairline #F0F4F3 separa la valorización (referencia) de los saldos cripto (operativos). Es la frontera conceptual del card.
Icono 40dp con color de marca · nombre + símbolo · saldo cripto + equivalente COP. Cada fila es InkWell → detalle del activo. Page transition slide+fade.
Mono JetBrains Mono con FontFeature.tabularFigures() — los dígitos se alinean verticalmente entre filas para que el ojo compare montos sin ruido.
Galería a ancho real (328dp). Cada variante es el mismo componente; lo que cambia es el contenido y, en algunos casos, el estado de visibilidad.
components-skeleton. Bordes/labels reales para no perder estructura.clock warning. Tap → bottom sheet explicativo.eye-off activo. Montos enmascarados; nombres e iconos visibles. Estado persistente.La decisión de diseño más importante del card. Cuando el cripto recién comprado todavía está liquidando, el usuario tiene dos saldos. Los mostramos juntos en la misma fila — no en cards separados, no en tabs. El usuario ve ambos de un vistazo.
No mostrar la línea "disponible" — no agregar ruido cuando los dos números son iguales. Solo el saldo principal y su equivalente COP.
Mostrar el total arriba (peso 600) y debajo, en caption muted color warning, el disponible con icono clock. Tap → tooltip o bottom sheet.
El card como unidad no es tappable. Las filas y los controles internos sí. Cada interacción se conecta a tokens ya definidos en foundations-motion.
Navega a la pantalla de detalle del activo. PageRouteBuilder con SlideTransition + FadeTransition, duration-slow · ease-standard.
Toggle privacy mode. Crossfade del valor a •••••• en 200ms. Haptic selectionClick(). Persiste vía SharedPreferences.
Abre showModalBottomSheet con la explicación de los 24 horas hábiles. duration-modal + ease-drawer.
En el dashboard (no en el card aislado). RefreshIndicator dispara crossfade a skeletons mientras el provider revalida la data.
Vuelve a estado loading (skeleton) y dispara el fetch. Si falla otra vez, mantiene el estado de error sin loops infinitos visibles.
"Compra tu primer Bitcoin" navega al flujo de compra con BTC preseleccionado. Haptic lightImpact() al iniciar la transición.
Misma jerarquía, misma estructura. En oscuro el card vive sobre --color-surface-dark con su propio fill ligeramente elevado. Los colores de marca de los activos se mantienen — la identidad del BTC es naranja, sí o sí.
El card debe funcionar desde Android económico (320dp) hasta iPhone 15 Pro Max (428dp). El padding interno y la tipografía se mantienen; lo que cambia es el ancho útil. Saldos cripto muy largos se truncan con ellipsis.
A 320dp el saldo del BTC del primer ejemplo está al límite. Saldos micro como 0,00000001 BTC se truncan con ellipsis (ver Pixel 8) — el valor completo se muestra en el detalle del activo.
El dashboard no usa tarjetas. Aplicando §4.7b (canvas-first): el balance y las transacciones viven directamente sobre el lienzo blanco, separados por hairlines y espacio — no por cajas. El hero gana presencia con peso tipográfico (36dp), no con chrome. El único contenedor en pantalla es el bottom nav flotante, que como componente flotante sí conserva elevación.
Lienzo blanco continuo. El fondo es --surface-canvas (#FFFFFF). No hay contraste fondo↔tarjeta que crear: el balance es lo primero que el usuario ve, sin caja que lo enmarque.
El hero gana con tipografía. Sin borde, sin sombra, sin radio. La valorización sube a 36dp y domina la pantalla por peso y escala, no por chrome.
Hairlines en vez de cards. Filas de activo y de transacción se separan con --divider-hairline indentado bajo el ícono — lenguaje de lista densa, no de contenedores apilados.
"Recientes" es un label micro-cap. Mismo lenguaje que el label del balance. El grupo se anuncia con tipografía + espacio, no con un contenedor con su propio borde.
El bottom nav flotante se queda. Es la única "caja" legítima en pantalla: §4.7b permite a los componentes flotantes conservar elevación y borde para despegarse del lienzo.
Container con BoxDecoration (borderRadius: 16, color: surface, boxShadow: elev.1) — preferible al Card Material para tener control fino sobre el shadow.
InkWell envolviendo un Row custom (no ListTile — su default padding no encaja). Ripple Material nativo + scale opcional via AnimatedScale si la fila es CTA primaria.
TextStyle(fontFeatures: [FontFeature.tabularFigures()]) en todos los montos. Garantiza que 0,00109 BTC y 0,01548 BTC alineen dígitos verticalmente entre filas.
ValueNotifier<bool> (o Riverpod provider) que persiste en SharedPreferences. El widget escucha y reemplaza los Text de montos por "••••••" manteniendo todo lo demás.
El skeleton del card usa el mismo AnimationController del SkeletonScope de la pantalla — no crear un controller propio. Misma fuente de verdad que el resto de skeletons visibles.
RefreshIndicator envuelve el ListView del dashboard. El onRefresh revalida el provider de portafolio, lo que repinta el card en estado skeleton durante el fetch.