Saltar al contenido

Product design, liderazgo y la serie Harness Design

Serie Harness DesignArtículo n.º 08

El rollout de los tokens con una capa de Harness Design

John Morais, .

Un escritorio visto desde arriba con dos hojas de la misma pantalla lado a lado bajo la luz, una lupa entre ellas y una mano con una muestra de color; en un gancho, dos llaves casi iguales, una verde y una gris

Cerré el Hito 1 y el Hito 2 del Proyecto Harness Design System en los artículos anteriores. La base de tokens está lista, la gobernanza está definida, el schema de harness está aplicado en Figma. Lo que faltaba era la parte que ningún artículo técnico suele contar bien: sacar todo eso del ambiente controlado y ponerlo frente al código que nuestros clientes usan todos los días.

Eso ocurrió. El React web está en producción con los tokens nuevos. Y lo que aprendí en el proceso importa más que la confirmación de que funcionó.

El rollout ocurrió, con deuda técnica comprada a conciencia

Hicimos el rollout de React en producción. La decisión de hacerlo un sábado no fue casualidad. Cambiar color y tipografía de una cantidad grande de pantallas al mismo tiempo, en producción, exige una ventana en la que la menor cantidad posible de personas esté tocando el sistema.

Antes de eso vino la validación. Y aquí apareció un problema práctico que no habíamos dimensionado bien: cómo validar un cambio que afecta el color y la tipografía de prácticamente todas las pantallas del sistema, sin abrirlas una por una a mano. La respuesta que trajeron los devs (aquí el trabajo de Front-End React de Rodofo Ferreira fue excepcional) fue armar, a partir de una base ya existente llamada Argos CI, un sistema que muestra la pantalla actual al lado de la pantalla después de aplicar los tokens nuevos. Sin eso, validar habría significado recorrer pantalla por pantalla, ambiente por ambiente, esperando no dejar pasar nada.

Incluso con Argos, la validación no salió perfecta. Y eso ya se esperaba. Hicimos el rollout sabiendo que iba a sobrar deuda técnica: lugares con color hardcoded que el proceso automático no detectó, componentes que no están en el flujo principal y por eso quedaron fuera del alcance, tipografía que no migró en algún rincón específico. Comprar ese riesgo fue una decisión consciente, no un imprevisto que apareció después. La alternativa habría sido no hacer el rollout hasta que todo estuviera perfecto, y eso significaría postergar indefinidamente el momento en que la base empieza a valer algo en producción.

La divergencia que la base ya había previsto

En "Antes de AI-first, human-first" escribí sobre el riesgo de publicar tokens nuevos en Figma mientras el código todavía corre con los antiguos. Eso se confirmó en la práctica, solo que de una forma más específica de lo que esperaba.

React migró primero. Flutter todavía no. Eso creó una situación concreta: los designers que trabajan en pantallas de app tienen que seguir prototipando a partir de la versión antigua de Glorp, nuestro design system en Figma, mientras quienes trabajan en pantallas web ya consumen la versión nueva. Tuvimos que mantener las dos versiones de la biblioteca disponibles al mismo tiempo, una activa para quienes migraron y otra como respaldo para quienes todavía no.

Publicar la biblioteca entera de una vez también expuso un problema estructural que estaba escondido: no todos los componentes tenían una distinción clara entre la variante usada en mobile y la usada en web. Un mismo nombre de componente, dos contextos distintos, sin separación explícita en el archivo. Eso no apareció como un bug del rollout. Apareció porque el rollout obligó a todos a mirar el archivo de una manera en que nadie lo había mirado antes.

Hubo también el efecto colateral más molesto: pantallas que ya estaban listas con los tokens antiguos y tuvieron que rehacerse a mano para acompañar el cambio, porque si no Figma mostraría una cosa y el código otra. Es trabajo real, hecho después del hecho, que no estaba en el plan original.

Para el cliente, casi nada cambia. Por ahora

Este es el punto que más vale la pena nombrar con honestidad. Internamente, este fue un cambio grande: dos semanas de dedicación casi total, una capa de infraestructura entera creada desde cero para volver semiautomática la actualización de tokens, un plugin de bind construido y ajustado a lo largo de varias iteraciones, pruebas de validación que cubrieron decenas de componentes.

Para quien usa el producto, el impacto visible es pequeño. Algunas personas notarán que un texto quedó un poco más legible, o que un color de aviso quedó un poco distinto. La mayoría no notará nada.

Eso no es una falla de ejecución. Es la naturaleza de esta capa del proyecto. La ganancia real que el cliente va a percibir no vive en los tokens, vive en los componentes que la próxima fase del proyecto va a producir con más velocidad y más consistencia gracias a esta base. Los tokens son lo que hace posible esa ganancia, no lo que la entrega directamente. Les expliqué esto a los stakeholders internos varias veces a lo largo del proyecto, y todavía me parece raro tener que defender tiempo del equipo en algo que, visto desde afuera, parece solo un cambio de paleta de colores.

Lo que de hecho cambió

Vale la pena desglosar lo que esta base lleva consigo, porque en conjunto es más de lo que parece.

En accesibilidad, los números confirman la mejora, con una salvedad importante: no todo mejoró por igual. El contraste del texto terciario, que es el tono más usado en todo el sistema, pasó de aproximadamente 4,3:1 a 8,0:1. El ícono neutro secundario pasó de 2,70:1, que reprobaba, a 10,00:1.

La familia de rojo de error es el caso que exige más contexto. Cuando planificamos los tokens nuevos, notamos que el rojo antiguo se parecía demasiado a tonos de amarillo y naranja en algunas variaciones, lo que dificultaba diferenciar los tres colores en ciertos contextos de la interfaz. La decisión fue desplazar el rojo en dirección al magenta, más rosado, para abrir una distancia clara entre las tres familias. Eso resolvió el problema de diferenciación, pero tuvo un costo que solo apareció después, en la medición de contraste: el rojo quedó más claro en esa nueva posición, y el par más crítico de esa familia pasó a reprobar por poco. Ya identificamos el punto y está en la fila para ser refinado, sin perder la distancia que ganamos respecto del amarillo y del naranja.

El naranja usado en links y acciones también sigue reprobando, tanto antes como después: 3,31 a 3,24. Es un caso distinto del rojo. El tono no cambió porque es el color de la identidad visual de la marca, y tocarlo no era una decisión que cupiera dentro del alcance de los tokens. Pero ya entendemos el camino: para uso en interfaz, en botones y en links, vamos a tener que aplicar un tono un nivel más oscuro dentro de la misma escala de naranja, manteniendo reconocible el color de la marca y resolviendo el contraste. Todavía no está hecho.

Y el indicador de foco sigue siendo prácticamente invisible sobre fondo blanco, en torno a 1,18:1, cuando el mínimo recomendado es 3:1. Ganamos terreno real en texto e íconos. Error, link y foco siguen siendo pendientes abiertos, no victorias que esté inflando.

En tipografía, cambiamos la fuente usada en los párrafos de Prompt por Figtree. Ese cambio ya se había decidido meses atrás, en una revisión anterior de la identidad visual de la marca, pero nunca había llegado al design system. O sea, el sistema estaba desfasado respecto de la propia marca, no solo respecto de las buenas prácticas de accesibilidad. Figtree es cerca de 5,6% más angosta que Prompt al mismo tamaño, y el peso del cuerpo del texto subió de 300 a 400, lo que ayuda a quien tiene baja visión a leer un texto que antes era demasiado delgado. En buena parte de los casos esto ahorra una línea entera de altura en el párrafo, lo que importa en pantallas pequeñas. La contrapartida es que los títulos más grandes, que siguen usando la fuente antigua, quedaron proporcionalmente más altos después del cambio de leading. La ganancia de espacio no es uniforme en toda la pantalla.

Además de color y tipografía, ampliamos el conjunto de tokens en varios frentes que antes no tenían cobertura: bordes, grosor de stroke, sombra, espaciado. Cada una de esas familias ganó variantes que simplemente no existían, lo que reduce la cantidad de valores sueltos digitados a mano que todavía quedaban en el sistema.

Lo que esta base dejó listo

Hay una ganancia que no aparece en ninguna pantalla, y que tal vez sea la más importante de las tres: ahora existe una forma de gestionar y actualizar tokens que antes no existía. Antes, cambiar un token significaba que alguien entrara manualmente en cada lugar donde se usaba ese valor. Ahora, el flujo pasa por Figma, por un plugin de export y bind, y por una capa de infraestructura que distribuye la actualización a React y Flutter. Eso hace que probar, ajustar y mejorar un proceso sea mucho más barato de lo que era hace dos meses.

El rollout de React ocurrió. El de Flutter sigue en marcha, sin fecha cerrada. La divergencia entre Figma y código, que sabíamos que iba a aparecer, apareció, y se está resolviendo poco a poco. No es una migración perfecta. Es la migración que se pudo hacer, con el riesgo que decidimos comprar, y con el cimiento que el próximo paso del proyecto va a necesitar.