Tendencias de Diseño

Color en sistemas de diseño a escala: Lecciones de Shopify, GitHub y Atlassian

11 min de lectura

Todo sistema de diseño se enfrenta eventualmente a una crisis de color. Suele comenzar de forma pequeña: una nueva superficie de producto necesita un tono que no existe en la paleta, un requisito de modo oscuro expone inconsistencias en cómo se usa el color entre componentes, o un rebranding revela que los tokens de color están dispersos por docenas de archivos sin una jerarquía clara. Los equipos que han resuelto estos problemas de forma más pública —Shopify, GitHub y Atlassian— han documentado sus enfoques con suficiente detalle como para que podamos comparar patrones y extraer principios aplicables a cualquier sistema de cualquier tamaño.

Esto no es un resumen de su documentación. Es un análisis de las decisiones que tomaron, los problemas que esas decisiones resolvieron y lo que puedes tomar prestado para tu propio sistema.


Shopify Polaris: El modelo de niveles de tokens

Polaris es uno de los sistemas de diseño públicos más maduros que existen. Shopify ha estado iterando sobre él desde 2017, y sirve a miles de comerciantes de Shopify, desarrolladores de aplicaciones y equipos de productos internos. El color ha sido uno de los problemas más complejos que han tenido que resolver: no porque la paleta de marca de Shopify sea complicada, sino porque el enorme número de superficies, aplicaciones y contextos que deben sentirse coherentemente "Shopify" es enorme.

De colores con nombre a tokens basados en roles

Las primeras versiones de Polaris usaban una paleta de colores con nombre relativamente sencilla. Los equipos podían extraer --p-color-green-400 directamente en los componentes. Esto funcionó hasta que no lo hizo: el modo oscuro era imposible de implementar sin lógica condicional en cada componente, los desarrolladores de aplicaciones que usaban tokens de Polaris construían componentes que se rompían durante las actualizaciones del administrador de Shopify, y no existía una regla clara para cuándo un nuevo primitivo estaba justificado versus cuándo debía reutilizarse una asignación semántica.

Polaris v12 introdujo un modelo de tokens de tres niveles que abordó estos problemas:

Nivel 1 — Escala de color: Una escala numérica de cada color disponible, nombrado por tono y paso de luminosidad. Estos son los primitivos fuente de verdad. Shopify usa una escala de 13 pasos para la mayoría de los tonos (de muy claro a muy oscuro) y reserva estos tokens para las definiciones internas de tokens únicamente: los desarrolladores de aplicaciones no deben usarlos directamente.

Nivel 2 — Tokens de rol: Tokens con nombres de propósito que hacen referencia a los valores del nivel 1. Estos son los que usan los autores de componentes. Nombres como --p-color-bg-surface, --p-color-text-critical, --p-color-border-interactive describen lo que hace un color, no cómo se ve.

Nivel 3 — Tokens de componente: Tokens de ámbito de componente que hacen referencia a los tokens de rol. El fondo de un botón es --p-color-bg-fill-brand, que mapea a --p-color-green-600 en modo claro y a --p-color-green-400 en modo oscuro. El componente nunca "sabe" qué valor de verde está usando.

Cómo Polaris maneja el modo oscuro

Polaris genera dos conjuntos de tokens completos —claro y oscuro— con los mismos nombres de tokens de rol. Los archivos de asignación se leen como configuración:

bg-surface (claro): color-scale-neutral-50    → #F6F6F7
bg-surface (oscuro): color-scale-neutral-900  → #1A1A1A

El resultado son dos archivos CSS con nombres de variables idénticos pero valores diferentes. El modo oscuro se aplica cargando el archivo de tokens oscuros (o cambiando un atributo data-polaris-color-scheme en el elemento raíz), no escribiendo sobreescrituras de modo oscuro en las hojas de estilo de los componentes.

Esta es la perspectiva arquitectónica: el modo oscuro no es un conjunto de excepciones de componentes. Es un conjunto diferente de asignaciones semánticas.

Qué tomar prestado de Polaris

La separación de "quién define los colores" de "quién usa los colores" es el patrón más importante de Polaris. Las decisiones de escala de color son tomadas por un grupo pequeño con profunda experiencia en color. Las asignaciones de tokens de rol son realizadas por diseñadores de sistemas que entienden el propósito. El uso en componentes es manejado por cualquier desarrollador de productos, que está protegido de las decisiones de escala y asignación. El control de acceso sobre las decisiones de color —a través de la arquitectura, no de la política— es cómo los equipos grandes mantienen la coherencia.


GitHub Primer: Modos de color sin duplicación

El sistema de diseño Primer de GitHub se enfrenta a un desafío que la mayoría de los sistemas no tienen: debe servir la misma interfaz en modo claro, modo oscuro, modo oscuro atenuado, modo oscuro de alto contraste y modo claro de alto contraste. Son cinco modos de color completos que deben sentirse todos como GitHub.

El problema con las sobreescrituras por modo

Un enfoque ingenuo de cinco modos de color escribe cinco conjuntos de sobreescrituras CSS: uno por cada modo. El resultado son miles de líneas de CSS repetitivo, una superficie de pruebas que crece exponencialmente y una casi certeza de inconsistencia a medida que el sistema evoluciona. Cambia un color en un modo y no hay una forma sistemática de saber si el valor correspondiente en otros modos es ahora inconsistente.

Primer resuelve esto tratando los cinco modos como instancias del mismo esquema semántico. Cada rol semántico tiene cinco valores —uno por modo— almacenados en una única estructura de datos. El sistema de construcción genera CSS específico de modo desde esa única fuente de verdad.

El vocabulario funcional de color de Primer

Primer organiza sus tokens semánticos en categorías funcionales con nombres predecibles:

fg.default          — Texto primario, iconos, bordes
fg.muted            — Texto secundario, iconos sutiles
fg.subtle           — Texto de marcador de posición, iconos deshabilitados

canvas.default      — Fondo de página
canvas.overlay      — Fondo de desplegable, modal
canvas.inset        — Superficies hundidas, bloques de código

border.default      — Bordes predeterminados
border.muted        — Divisores sutiles
border.subtle       — Separadores de línea fina

accent.fg           — Texto interactivo (enlaces)
accent.emphasis     — Elementos interactivos rellenos (pestaña seleccionada)
accent.muted        — Fondos de acento
accent.subtle       — Tintes de acento muy claros

success.fg          — Texto de éxito
success.emphasis    — Relleno de éxito (insignias verdes)
success.muted       — Tinte de fondo de éxito
success.subtle      — Tinte de éxito muy claro

Este vocabulario se aplica de forma idéntica entre modos. success.emphasis en modo claro es #1F883D. En modo oscuro es #3FB950. En modo oscuro de alto contraste es #56D364. El significado semántico —"indicador de éxito relleno"— se preserva en todos los modos; solo el valor cambia para mantener la accesibilidad en el contexto de fondo de cada modo.

Transparencia de escala

Primer publica su escala de color completa públicamente. Cada primitivo —desde blue-000 #DBF4FF hasta blue-900 #0A192F— está documentado. La escala pública sirve dos propósitos: permite a los desarrolladores de aplicaciones que construyen sobre la API de GitHub entender el vocabulario visual, y responsabiliza al equipo de Primer de la completitud de la escala antes de realizar las asignaciones semánticas.

Un modo de fallo común en los sistemas de diseño es crear tokens semánticos que no tienen un buen primitivo al que hacer referencia: la escala no tiene el tono correcto, por lo que alguien añade un valor hex de uso único que cae fuera de la escala. El enfoque de Primer hace esto visible: si una asignación semántica necesita un color que no está en la escala, la escala debe extenderse, no eludirse.

Accesibilidad de color integrada en la generación de modos

Primer ejecuta comprobaciones de contraste WCAG como parte de su pipeline de generación de tokens. Cada modo generado debe pasar los umbrales mínimos de contraste para las combinaciones de texto sobre fondo e icono sobre fondo antes de que el modo sea aceptado. Esto significa que las pruebas de regresión de accesibilidad son estructurales en lugar de manuales: un desarrollador no puede enviar un nuevo modo o un cambio de escala que rompa el contraste sin que la construcción falle.

Esto vale la pena replicarlo en cualquier sistema. Una comprobación de contraste como paso de construcción, no como paso de revisión de diseño, significa que la accesibilidad no puede colarse durante los ciclos de entrega de alta presión.


Sistema de diseño Atlassian: Tokens como API

El sistema de diseño de Atlassian sirve a Jira, Confluence, Trello, Bitbucket y un ecosistema creciente de aplicaciones Forge. Su modelo de tokens está enmarcado explícitamente como una API estable de la que pueden depender los equipos de productos y los desarrolladores de terceros: cambiar el valor de un token sin cambiar su nombre no debe romper el diseño visual de ningún producto de forma significativa.

Contratos explícitos de tokens

Atlassian publica descripciones de tokens que equivalen a contratos. Un token como color.background.neutral no solo está documentado como "fondo neutro": está documentado con garantías explícitas: este token siempre será un color de fondo neutro (acromático o casi acromático); siempre cumplirá el contraste WCAG AA contra color.text colocado encima de él; siempre estará disponible en modos claro y oscuro.

Estas garantías significan que los equipos de productos pueden usar el token sin probar cada nueva versión del tema. El equipo del sistema absorbe la carga de prueba a cambio de esa promesa.

Este modelo de contrato explícito tiene una implicación significativa para el nombramiento de tokens: un token que promete siempre tener contraste suficiente contra ciertos colores de texto no puede reutilizarse para usos decorativos donde el contraste es irrelevante. El nombre debe ser suficientemente específico para que el contrato sea comprensible.

La taxonomía de nomenclatura de Atlassian

Atlassian usa una taxonomía de nomenclatura estructurada con cuatro segmentos:

color . {categoría} . {variante} . {estado}

color.text.subtle               Texto atenuado (sin estado = predeterminado)
color.text.subtle.[hovered]     Sobreescritura del estado al pasar el cursor
color.background.selected       Superficie seleccionada
color.border.focused            Color del anillo de enfoque
color.icon.danger               Color del icono de peligro

La notación entre corchetes [hovered] indica que un token de estado es opcional: los componentes pueden o no elegir aplicarlo. Los tokens de base requeridos no tienen corchetes.

Estrategia de migración: Haciendo visibles las costuras

Atlassian ha tenido que migrar productos heredados de valores hex en bruto a tokens. Su estrategia de migración documentada públicamente implica lo que llaman "hacer visibles las costuras": hacer que los límites de los tokens sean visibles durante la migración en lugar de intentar refactorizar en silencio.

Sus herramientas generan un modo de auditoría visual que resalta cada región de token con una superposición codificada por color que muestra si el elemento está usando un token (verde), usando un valor codificado heredado (amarillo) o usando un token obsoleto (rojo). Los equipos de productos ejecutan esta auditoría antes de cada lanzamiento para hacer seguimiento del progreso de la migración.

La lección práctica: las migraciones de sistemas de diseño tienen éxito cuando el progreso es medible y visible. Los tokens de color son particularmente adecuados para las herramientas de auditoría visual porque los datos son literalmente visibles en pantalla.


Patrones comunes en los tres sistemas

La comparación de Polaris, Primer y Atlassian revela decisiones coherentes que parecen ser descubrimientos independientes de las mismas mejores prácticas:

Separación de capas primitiva y semántica

Los tres sistemas mantienen un límite estricto entre los valores de color en bruto (primitivos) y los tokens con nombres de propósito (semánticos). El código de componentes nunca hace referencia a los primitivos. Esta separación permite la creación de temas, el modo oscuro y el rebranding sin tocar el código de los componentes.

Los nombres semánticos son descripciones de roles, no de tonos

Ninguno de los tres sistemas usa palabras de tono en sus nombres de tokens semánticos. "Énfasis", "sutil", "atenuado", "crítico", "superficie", "lienzo": estas palabras describen lo que hace un color. El tono real es un detalle de implementación que vive en la capa primitiva.

La accesibilidad es una restricción de construcción

Los tres sistemas hacen cumplir los requisitos de accesibilidad en sus pipelines de herramientas, no solo en su documentación. Los umbrales de contraste se verifican automáticamente. Esto convierte la accesibilidad de una buena intención a una garantía mecánica.

El soporte multi-modo es arquitectónico

El modo oscuro (y en el caso de Primer, cinco modos) se maneja generando múltiples conjuntos de valores de tokens desde el mismo esquema semántico. No se maneja escribiendo sobreescrituras de prefers-color-scheme en el código de los componentes. Esta separación arquitectónica es lo que hace posible que los autores de componentes sean completamente inconscientes del modo que el usuario ha seleccionado.


Escalando las decisiones de color para equipos grandes

La dimensión organizacional del color a escala es tan importante como la técnica. Los equipos grandes necesitan estructuras claras de propiedad para las decisiones de color, y esas estructuras deben codificarse en la propia arquitectura de tokens.

Tres niveles de toma de decisiones de color

Decisiones de escala (qué colores existen en la paleta primitiva) requieren la mayor experiencia: conocimiento de ciencia del color, experiencia de marca y pruebas de accesibilidad. Estas decisiones se toman con poca frecuencia y afectan a todo el sistema. Propiedad: equipo central del sistema de diseño.

Decisiones de asignación semántica (qué propósito sirve este primitivo) requieren comprensión de los contextos de producto y las expectativas de los usuarios. Estas decisiones ocurren cuando se añaden nuevas superficies de producto o se producen cambios significativos en la dirección de diseño. Propiedad: sistema de diseño con aportación de los líderes de diseño de producto.

Decisiones de uso (qué token semántico aplica a este elemento específico en este contexto específico) deben requerir la menor experiencia y sin acceso especial. Cualquier diseñador o desarrollador debe poder tomar estas decisiones con confianza leyendo los nombres de los tokens. Propiedad: equipos de productos individuales.

La arquitectura de tokens codifica esta jerarquía. Los tokens primitivos que solo aparecen en los archivos de asignación semántica están arquitectónicamente protegidos del mal uso. Los tokens semánticos con nombres claros son de autoservicio. Esto no es un control de políticas, es una guía arquitectónica.

Cuándo está justificado un nuevo token

Los tres sistemas han desarrollado criterios para cuándo añadir nuevos tokens versus reutilizar los existentes. Un nuevo token semántico está justificado cuando:

  • Existe genuinamente un nuevo propósito que ningún token actual cubre
  • El nuevo propósito aparecerá en al menos tres componentes distintos
  • El propósito no puede expresarse como una composición de tokens existentes (por ejemplo, un token usado con opacidad)
  • La adición ha sido revisada contra el vocabulario de tokens existente para confirmar que no duplica un token con un nombre diferente

El umbral de "tres componentes" evita que el vocabulario de tokens crezca sin límite con tokens de uso único para cada caso límite. Fuerza la consolidación de propósitos similares y mantiene la capa semántica comprensible.


Qué implementar hoy

Si estás construyendo o refactorizando una capa de color en un sistema de diseño, aquí tienes una secuencia de inicio práctica independientemente del tamaño de tu equipo:

  1. Define tu paleta primitiva completamente antes de asignar roles semánticos. Usa una escala numérica o nombrada que cubra el rango completo de luminosidad para cada tono.

  2. Audita el código de componentes existente para descubrir los roles de color realmente en uso: no lo que pretendías, sino lo que está ocurriendo realmente. Agrupa los colores por propósito entre componentes.

  3. Redacta nombres de tokens semánticos desde tu auditoría, usando lenguaje de roles (superficie, texto, borde, retroalimentación) en lugar de lenguaje de tonos.

  4. Mapea los primitivos a los semánticos. Si un mapeo requiere un primitivo que no existe, extiende la escala en lugar de usar un valor fuera de escala.

  5. Añade comprobaciones automáticas de contraste contra tus combinaciones más comunes de texto sobre fondo.

  6. Migra un componente a la vez, usando valores basados en tokens, manteniendo los primitivos disponibles para el código heredado durante la transición.

Los sistemas descritos aquí no se construyeron en un sprint. Evolucionaron a través exactamente de este tipo de trabajo iterativo, absorbiendo lecciones de fallos reales de productos. Lo que comparten —y lo que hace transferibles sus enfoques— es el principio central de que las decisiones de color deben separarse por experiencia y expresarse como arquitectura, no como convención.

Colores relacionados

Marcas relacionadas

Herramientas relacionadas