Diez años de app, dos plataformas y ningún lenguaje común. El sistema empezó por contar lo que había antes de decidir nada.
ClienteTextPlus
RolProduct Designer
Año2026
EstadoEntregado
01 El problema
text+ es una app de mensajería y llamadas con más de diez años en iOS y Android. Nunca tuvo un sistema de diseño formal: los estilos vivían en el código, cada plataforma hacía lo suyo y las inconsistencias crecían con cada release. La reescritura de la app en Flutter ya estaba en marcha cuando entré.
Antes de definir un solo token hice un inventario completo de la interfaz: ocho flujos, 216 pantallas en las dos plataformas, 571 elementos clasificados por lo que hacen y no por cómo se ven. Agrupar por función y no por color fue la decisión que dio sentido a todo lo demás: dos botones “Continuar”, uno amarillo y otro verde, son el mismo botón mal implementado dos veces, no dos componentes.
Frecuencia por varianza: lo más usado y más inconsistente es lo primero que se construye.La fila de lista es el esqueleto de la app: chats, llamadas, contactos y ajustes son la misma pieza con distinto contenido.
Mi papel
Fui el único diseñador del proyecto, en un equipo de tres: el CEO, que fijaba prioridades; un desarrollador Flutter, mi interlocutor técnico en cada decisión; y yo. Dos restricciones: un equipo así no puede mantener un sistema complejo, y el desarrollador iba a construir pantallas a partir de él sin que yo revisara cada una, así que nada podía quedar implícito.
Auditoría de 216 pantallas y 571 elementos
Arquitectura de tokens en tres modos
Kit de 15 componentes con auto layout
Reglas de uso escritas con su razón
Documentación del sistema
Handoff al theme de Flutter
02 Las decisiones
Un sistema para un equipo de tres obliga a decidir pocas cosas y dejarlas por escrito. Estas seis son la base del gobierno del sistema; cada una está documentada con su razón, para discutirla en vez de reinventarla.
01
Los tokens describen roles, nunca colores
brand/action, no brand/tangerine. Si el nombre es un color, el nombre está mal. El grupo de marca tiene exactamente dos tokens, acción y énfasis, y no admite un tercero.
Un color cambia en un sitio y ningún nombre se queda obsoleto.
02
Dos niveles en vez de tres
Primitivos y semánticos. Los tokens de componente añaden un mantenimiento que un equipo pequeño no puede pagar. En su lugar, cada componente lleva una descripción con la intención y los tokens que consume.
El sistema crece sin que crezca su mantenimiento.
03
OKLCH para que los modos sean configuración
Ocho paletas en un espacio perceptualmente uniforme: la misma luminosidad se percibe igual en cualquier tono. El modo oscuro deja de ser un proyecto de diseño y pasa a ser un cambio de modo en una variable. El contraste AA se comprueba en el par de tokens y se corrige en la variable.
Tres modos desde los mismos 67 tokens, sin repintar.
04
El amarillo actúa, el verde confirma
Nunca compiten en la misma pantalla. En los modos oscuros el amarillo se sustituye por lima de forma automática, porque el token de acción resuelve a otro valor. Todo lo que no es la acción principal es secundario o un enlace.
Una sola acción primaria por pantalla, también en oscuro.
05
Material 3 nativo, sin widgets propios
El contrato es simple: ThemeData y ThemeExtension, sin clases de widget propias. Por eso el sistema se apoya en los widgets nativos de Material 3, y los estados hover y pressed no se exportan: los gestiona Flutter, no Figma.
El desarrollador consume tokens desde el theme, sin traducción.
06
Un suelo de dispositivo real
Anchura mínima de 360 dp, de los datos de Android; altura mínima de 667 pt, del tráfico real en iPhone 7 y 8. Por debajo, un breakpoint de Flutter oculta o recoloca: comportamiento definido, no un bug. Tablet y escritorio esperan a tener datos.
Todo componente cabe en 360 × 667 y lo demás queda fuera de alcance.
Los mismos 67 tokens semánticos en Light, Carbon y Navy. El token no cambia; cambia el valor.
03 El sistema
Cinco capas, de abajo arriba. Cada una se apoya en la anterior y ninguna se salta a la siguiente: un componente nunca toca un primitivo, y una regla nunca nombra un color.
Las capas del sistema
01Primitivos83 variablesOcho paletas OKLCH con la misma luminosidad en cada paso
03Escalas13 espaciados · 7 radios · 107 tipográficosZilla Slab en los titulares grandes, Inter en todo lo demás
04Componentes15 setsAuto layout, cada relleno vinculado a una variable, contratos cerrados
05Reglas y themeGuías de uso · ThemeDataCuándo se usa cada cosa, y el mismo token en Figma y en Flutter
Tokens. 277 variables en Figma, la única fuente de verdad del sistema. El espaciado funciona por bandas: de 4 a 8 dentro de un componente, de 12 a 20 como padding, de 24 a 40 entre secciones. Cruzar de banda rompe el ritmo, y está escrito.
La escala se nombra por su valor y se usa por bandas. Nunca se salta de una a otra.
Kit de componentes. Quince sets construidos sobre los tokens: botón, botón social, fila de lista, campo de texto, switch, radio, checkbox, control segmentado, tarjeta de acción, avatar, badge, selector de plan, tabs, barra inferior y barra superior. Cada set lleva su descripción con la arquitectura de capas, los tokens que consume y las notas de entrega para Flutter.
Dieciocho variantes. Hover y pressed no están: los resuelve el theme de Flutter.
La fila de lista como contrato. Es el componente que más pantallas desbloquea, así que tiene un contrato cerrado que funciona como su API: el elemento izquierdo puede ser nada, icono o avatar; el derecho es una lista fija de nueve opciones, de chevron a switch, badge o valor. No entra un tipo nuevo sin actualizar la especificación primero. En Flutter ese contrato es una enumeración, no un widget libre.
Una fila, tres slots. Las 47 versiones de la app caben aquí.El chrome de la app: barra superior neutra, tabs y barra inferior atadas a los tokens.
Cambio de tema en un clic. Las pantallas de referencia están duplicadas cambiando solo el modo de la variable en la sección. Sin repintar nada.
Arriba Light, abajo Carbon. La única diferencia es el modo seleccionado en la sección.
Iconografía. La app mezclaba iconos de varias épocas y pesos. En vez de comprar un set nuevo, consolidé el que ya existía en la empresa: una sola librería, trazo 1.5, línea, 24 px de base, y la regla de que ningún icono se dibuja a mano.
04 Resultados
AntesDespués
Botón primario44 versiones repartidas por la appUn set de 18 variantes con reglas de uso: cuándo primario, cuándo secundario, qué pasa con dos acciones
Fila de lista47 implementaciones distintas, ninguna como componenteUn componente con contrato cerrado, que en Flutter es una enumeración
Color y temaEstilos sueltos en el código, un modo277 variables como única fuente de verdad y tres modos desde los mismos tokens, comprobados en flujos reales
EntregaHandoff conversacional, pantalla a pantallaQuince componentes con notas de handoff, consumidos desde el theme de Flutter sin traducción intermedia
DocumentaciónDecisiones en la cabeza de quien las tomóCada decisión publicada con su razón en un sitio propio, el siguiente caso de este portfolio
05 Aprendizajes
01
Auditar antes de tokenizar.
El inventario no fue trabajo previo: fue la decisión de diseño más importante del proyecto. Sacó a la luz el componente que más pantallas resolvía y que nadie había pedido.
02
Las reglas valen más que las piezas.
Un kit sin reglas produce decisiones a ojo en cada pantalla. Escribir cuándo se usa cada cosa, y por qué, es lo que convierte una librería en un sistema y lo que permite que otros decidan sin preguntarme.
03
Diseñar para que lo lea una máquina.
Nombres por rol, intención documentada, contratos cerrados. Es lo que permite que el desarrollador, o quien llegue nuevo, construya una pantalla y salga parecida a lo que el sistema pretende.
Un sistema de diseño no es un entregable. Es una decisión sobre quién puede cambiar qué sin pedir permiso.
216pantallas auditadas8 flujos en iOS y Android, antes de definir un solo token
3modos desde un solo tokenLight, Carbon y Navy: cambiar de tema es cambiar un modo
15sets de componentesauto layout, cada relleno vinculado a una variable, notas para Flutter
47 → 1versiones de la fila de listaun contrato cerrado con slots sustituye a todas
¿Tienes un producto que necesita escalar con criterio?