Tendências de Design

Cor em Design Systems em Escala: Lições da Shopify, GitHub e Atlassian

11 min de leitura

Todo design system eventualmente enfrenta uma crise de cores. Geralmente começa pequeno: uma nova superfície de produto precisa de um tom que não existe na paleta, um requisito de modo escuro expõe inconsistências na forma como a cor é usada entre componentes, ou um rebranding revela que os tokens de cor estão espalhados por dezenas de arquivos sem hierarquia clara. As equipes que resolveram esses problemas de forma mais pública — Shopify, GitHub e Atlassian — documentaram suas abordagens com detalhes suficientes para que possamos comparar padrões e extrair princípios aplicáveis a qualquer sistema de qualquer tamanho.

Este não é um resumo da documentação deles. É uma análise das decisões que tomaram, dos problemas que essas decisões resolveram, e do que você pode aproveitar para o seu próprio sistema.


Shopify Polaris: O Modelo de Camadas de Tokens

O Polaris é um dos design systems públicos mais maduros existentes. A Shopify vem iterando sobre ele desde 2017, e ele serve milhares de lojistas, desenvolvedores de aplicativos e equipes internas de produto. A cor tem sido um dos problemas mais complexos que eles precisaram resolver — não porque a paleta de marca da Shopify seja complicada, mas porque o enorme número de superfícies, aplicativos e contextos que devem todos parecer coesamente "Shopify" é gigantesco.

De Cores Nomeadas a Tokens Baseados em Função

As primeiras versões do Polaris usavam uma paleta relativamente direta de cores nomeadas. As equipes podiam referenciar --p-color-green-400 diretamente nos componentes. Isso funcionou até parar de funcionar: o modo escuro era impossível de implementar sem lógica condicional em cada componente, desenvolvedores de aplicativos usando tokens do Polaris construíam componentes que quebravam durante atualizações do admin Shopify, e não havia regra clara para quando um novo primitivo era justificado versus quando uma atribuição semântica deveria ser reutilizada.

O Polaris v12 introduziu um modelo de token de três camadas que resolveu esses problemas:

Camada 1 — Escala de Cores: Uma escala numérica de todas as cores disponíveis, nomeadas por matiz e passo de luminosidade. Estes são os primitivos de fonte de verdade. A Shopify usa uma escala de 13 passos para a maioria dos matizes (do muito claro ao muito escuro) e reserva esses tokens apenas para definições internas de tokens — desenvolvedores de aplicativos não devem utilizá-los diretamente.

Camada 2 — Tokens de Função: Tokens com nomes de propósito que referenciam valores da camada 1. São esses que os autores de componentes utilizam. Nomes como --p-color-bg-surface, --p-color-text-critical, --p-color-border-interactive descrevem o que uma cor faz, não como ela é.

Camada 3 — Tokens de Componente: Tokens com escopo de componente que referenciam tokens de função. O fundo de um botão é --p-color-bg-fill-brand, que mapeia para --p-color-green-600 no modo claro e --p-color-green-400 no modo escuro. O componente nunca "sabe" qual valor de verde está usando.

Como o Polaris Lida com o Modo Escuro

O Polaris gera dois conjuntos completos de tokens — claro e escuro — com os mesmos nomes de tokens de função. Os arquivos de atribuição se leem como configuração:

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

O resultado são dois arquivos CSS com nomes de variáveis idênticos, mas valores diferentes. O modo escuro é aplicado carregando o arquivo de tokens escuro (ou alternando um atributo data-polaris-color-scheme no elemento raiz) — não escrevendo sobreposições de modo escuro nas folhas de estilo dos componentes.

Esse é o insight arquitetônico: o modo escuro não é um conjunto de exceções de componentes. É um conjunto diferente de atribuições semânticas.

O Que Aproveitar do Polaris

A separação entre "quem define as cores" e "quem usa as cores" é o padrão mais importante do Polaris. As decisões sobre a escala de cores são tomadas por um pequeno grupo com profundo conhecimento em cor. As atribuições de tokens de função são feitas por designers de sistema que entendem o propósito. O uso em componentes é tratado por qualquer desenvolvedor de produto, que fica protegido tanto das decisões de escala quanto das de atribuição. O controle de acesso às decisões de cor — por meio de arquitetura, não de política — é como grandes equipes mantêm consistência.


GitHub Primer: Modos de Cor Sem Duplicação

O design system Primer do GitHub enfrenta um desafio que a maioria dos sistemas não tem: ele deve servir a mesma interface em modo claro, modo escuro, modo escuro esmaecido, modo escuro de alto contraste e modo claro de alto contraste. São cinco modos completos de cor que devem todos parecer GitHub.

O Problema com Sobreposições por Modo

Uma abordagem ingênua para cinco modos de cor escreve cinco conjuntos de sobreposições CSS — uma para cada modo. O resultado são milhares de linhas de CSS repetitivo, uma superfície de testes que cresce exponencialmente, e uma quase certeza de inconsistência à medida que o sistema evolui. Mude uma cor em um modo, e não há forma sistemática de saber se o valor correspondente nos outros modos agora é inconsistente.

O Primer resolve isso tratando todos os cinco modos como instâncias do mesmo esquema semântico. Cada função semântica tem cinco valores — um por modo — armazenados em uma única estrutura de dados. O sistema de build gera CSS específico por modo a partir dessa única fonte de verdade.

O Vocabulário Funcional de Cores do Primer

O Primer organiza seus tokens semânticos em categorias funcionais com nomes previsíveis:

fg.default          — Texto primário, ícones, bordas
fg.muted            — Texto secundário, ícones sutis
fg.subtle           — Texto de placeholder, ícones desabilitados

canvas.default      — Fundo da página
canvas.overlay      — Fundo de dropdown e modal
canvas.inset        — Superfícies recuadas, blocos de código

border.default      — Bordas padrão
border.muted        — Divisores sutis
border.subtle       — Separadores de linha fina

accent.fg           — Texto interativo (links)
accent.emphasis     — Elementos interativos preenchidos (aba selecionada)
accent.muted        — Fundos de destaque
accent.subtle       — Tons de destaque muito claros

success.fg          — Texto de sucesso
success.emphasis    — Preenchimento de sucesso (badges verdes)
success.muted       — Tom de fundo de sucesso
success.subtle      — Tom de sucesso muito claro

Este vocabulário se aplica identicamente entre os modos. success.emphasis no modo claro é #1F883D. No modo escuro é #3FB950. No modo escuro de alto contraste é #56D364. O significado semântico — "indicador de sucesso preenchido" — é preservado em todos os modos; apenas o valor muda para manter a acessibilidade no contexto de fundo de cada modo.

Transparência da Escala

O Primer publica sua escala de cores completa publicamente. Cada primitivo — de blue-000 #DBF4FF a blue-900 #0A192F — está documentado. A escala pública serve dois propósitos: permite que desenvolvedores de aplicativos construindo sobre a API do GitHub entendam o vocabulário visual, e responsabiliza a equipe do Primer pela completude da escala antes que as atribuições semânticas sejam feitas.

Um modo de falha comum em design systems é criar tokens semânticos que não têm um bom primitivo para referenciar — a escala não possui o tom certo, então alguém adiciona um valor hex único que fica fora da escala. A abordagem do Primer torna isso visível: se uma atribuição semântica precisar de uma cor que não está na escala, a escala precisa ser estendida, não contornada.

Acessibilidade de Cor Incorporada na Geração de Modos

O Primer executa verificações de contraste WCAG como parte de seu pipeline de geração de tokens. Cada modo gerado deve passar pelos limites mínimos de contraste para combinações de texto-sobre-fundo e ícone-sobre-fundo antes que o modo seja aceito. Isso significa que o teste de regressão de acessibilidade é estrutural, não manual — um desenvolvedor não pode publicar um novo modo ou uma mudança de escala que quebre o contraste sem que o build falhe.

Vale a pena replicar isso em qualquer sistema. Uma verificação de contraste como etapa de build, não de revisão de design, significa que a acessibilidade não pode escorregar durante ciclos de entrega sob alta pressão.


Atlassian Design System: Tokens como API

O design system da Atlassian serve o Jira, Confluence, Trello, Bitbucket e um crescente ecossistema de aplicativos Forge. Seu modelo de tokens é explicitamente enquadrado como uma API estável da qual equipes de produto e desenvolvedores terceirizados podem depender — alterar o valor de um token sem alterar seu nome não deve quebrar o design visual de nenhum produto de forma significativa.

Contratos Explícitos de Token

A Atlassian publica descrições de tokens que equivalem a contratos. Um token como color.background.neutral não é apenas documentado como "fundo neutro" — é documentado com garantias explícitas: este token sempre será uma cor de fundo neutra (acromática ou quase acromática); ele sempre atenderá ao contraste WCAG AA em relação ao color.text colocado sobre ele; ele sempre estará disponível nos modos claro e escuro.

Essas garantias significam que as equipes de produto podem usar o token sem testar cada nova versão de tema. A equipe do sistema absorve a carga de testes em troca dessa promessa.

Este modelo de contrato explícito tem uma implicação significativa para a nomenclatura de tokens: um token que promete sempre ter contraste suficiente contra certas cores de texto não pode ser redirecionado para usos decorativos onde o contraste é irrelevante. O nome deve ser específico o suficiente para que o contrato seja compreensível.

Taxonomia de Nomenclatura da Atlassian

A Atlassian usa uma taxonomia de nomenclatura estruturada com quatro segmentos:

color . {categoria} . {variante} . {estado}

color.text.subtle               Texto discreto (sem estado = padrão)
color.text.subtle.[hovered]     Sobreposição do estado hover
color.background.selected       Superfície selecionada
color.border.focused            Cor do anel de foco
color.icon.danger               Cor do ícone de perigo

A notação entre colchetes [hovered] indica que um token de estado é opcional — os componentes podem ou não optar por aplicá-lo. Os tokens base obrigatórios não têm colchetes.

Estratégia de Migração: Destacando as Costuras

A Atlassian precisou migrar produtos legados de valores hex brutos para tokens. Sua estratégia de migração documentada publicamente envolve o que eles chamam de "destacar as costuras" — tornar os limites dos tokens visíveis durante a migração em vez de tentar refatorar silenciosamente.

Suas ferramentas geram um modo de auditoria visual que destaca cada região de token com uma sobreposição codificada por cores mostrando se o elemento está usando um token (verde), usando um valor legado codificado (amarelo) ou usando um token obsoleto (vermelho). As equipes de produto executam essa auditoria antes de cada lançamento para acompanhar o progresso da migração.

A lição prática: migrações de design system têm sucesso quando o progresso é mensurável e visível. Tokens de cor são particularmente adequados para ferramentas de auditoria visual porque os dados são literalmente visíveis na tela.


Padrões Comuns em Todos os Três Sistemas

Comparar o Polaris, o Primer e o Atlassian revela decisões consistentes que parecem ser descobertas independentes das mesmas melhores práticas:

Separação das Camadas Primitiva e Semântica

Os três sistemas mantêm um limite rígido entre valores de cores brutos (primitivos) e tokens com nomes de propósito (semânticos). O código de componentes nunca referencia primitivos. Essa separação possibilita temas, modo escuro e rebranding sem tocar no código dos componentes.

Nomes Semânticos São Descrições de Função, Não de Matiz

Nenhum dos três sistemas usa palavras de matiz em seus nomes de tokens semânticos. "Emphasis," "subtle," "muted," "critical," "surface," "canvas" — essas palavras descrevem o que uma cor faz. O matiz real é um detalhe de implementação que vive na camada primitiva.

Acessibilidade é uma Restrição de Build

Os três sistemas aplicam requisitos de acessibilidade em seus pipelines de ferramentas, não apenas em sua documentação. Os limiares de contraste são verificados automaticamente. Isso move a acessibilidade de uma boa intenção para uma garantia mecânica.

Suporte a Múltiplos Modos é Arquitetônico

O modo escuro (e no caso do Primer, cinco modos) é tratado gerando múltiplos conjuntos de valores de tokens a partir do mesmo esquema semântico. Não é tratado escrevendo sobreposições prefers-color-scheme no código dos componentes. Essa separação arquitetônica é o que torna possível que os autores de componentes sejam completamente alheios ao modo que o usuário selecionou.


Escalando Decisões de Cor para Grandes Equipes

A dimensão organizacional da cor em escala é tão importante quanto a técnica. Grandes equipes precisam de estruturas claras de propriedade para decisões de cor, e essas estruturas devem ser codificadas na própria arquitetura de tokens.

Três Níveis de Tomada de Decisão de Cor

Decisões de escala (quais cores existem na paleta primitiva) requerem mais expertise — conhecimento de ciência das cores, expertise de marca e testes de acessibilidade. Essas decisões são tomadas com pouca frequência e afetam todo o sistema. Propriedade: equipe central do design system.

Decisões de atribuição semântica (qual propósito este primitivo serve) requerem compreensão dos contextos de produto e das expectativas dos usuários. Essas decisões acontecem quando novas superfícies de produto são adicionadas ou quando há mudanças significativas na direção de design. Propriedade: design system com input dos líderes de design de produto.

Decisões de uso (qual token semântico se aplica a este elemento específico neste contexto específico) devem exigir o mínimo de expertise e nenhum acesso especial. Qualquer designer ou desenvolvedor deve ser capaz de tomar essas decisões com confiança lendo os nomes dos tokens. Propriedade: equipes de produto individuais.

A arquitetura de tokens codifica essa hierarquia. Tokens primitivos que aparecem apenas em arquivos de atribuição semântica são arquiteturalmente protegidos contra uso indevido. Tokens semânticos com nomes claros são self-service. Isso não é um controle de política — é uma orientação arquitetônica.

Quando um Novo Token é Justificado

Os três sistemas desenvolveram critérios para quando adicionar novos tokens versus reutilizar os existentes. Um novo token semântico é justificado quando:

  • Um novo propósito genuinamente existe e nenhum token atual o cobre
  • O novo propósito aparecerá em pelo menos três componentes distintos
  • O propósito não pode ser expresso como uma composição de tokens existentes (por exemplo, um token usado com opacidade)
  • A adição foi revisada em relação ao vocabulário de tokens existente para confirmar que não duplica um token com um nome diferente

O limite de "três componentes" evita que o vocabulário de tokens cresça ilimitadamente com tokens únicos para cada caso especial. Ele força a consolidação de propósitos similares e mantém a camada semântica compreensível.


O Que Implementar Hoje

Se você está construindo ou refatorando uma camada de cor de design system, aqui está uma sequência prática de início, independente do tamanho da equipe:

  1. Defina sua paleta primitiva completamente antes de atribuir funções semânticas. Use uma escala numérica ou nomeada que cubra toda a faixa de luminosidade para cada matiz.

  2. Audite o código de componentes existente para descobrir as funções de cor reais em uso — não o que você pretendia, mas o que está realmente acontecendo. Agrupe as cores por propósito entre os componentes.

  3. Esboce nomes de tokens semânticos a partir de sua auditoria, usando linguagem de função (surface, text, border, feedback) em vez de linguagem de matiz.

  4. Mapeie primitivos para semânticos. Se um mapeamento requer um primitivo que não existe, estenda a escala em vez de usar um valor fora da escala.

  5. Adicione verificação automática de contraste para suas combinações mais comuns de texto-sobre-fundo.

  6. Migre um componente de cada vez, usando valores baseados em tokens, mantendo os primitivos disponíveis para código legado durante a transição.

Os sistemas descritos aqui não foram construídos em um sprint. Eles evoluíram através exatamente desse tipo de trabalho iterativo, absorvendo lições de falhas reais de produto. O que eles compartilham — e o que torna suas abordagens transferíveis — é o princípio central de que as decisões de cor devem ser separadas por expertise e expressas como arquitetura, não como convenção.

Cores relacionadas

Marcas relacionadas

Ferramentas relacionadas