Home / Uncategorized / Como nomear design tokens: a taxonomia de níveis que impede o sistema de virar bagunça

Como nomear design tokens: a taxonomia de níveis que impede o sistema de virar bagunça

Em 6 de outubro de 2026, Vitaly Friedman publicou na Smashing Magazine um guia prático chamado A Practical Guide To Naming Things, reunindo recursos para nomear classes CSS, cores, tokens, variáveis, features e componentes de UI. O artigo é essencialmente uma curadoria, apontando para trabalhos como o de Nathan Curtis (EightShapes) sobre taxonomia de tokens e o estudo de caso de Nate Baldwin sobre o Intuit Design System.

Em vez de resumir a curadoria, vou pegar a parte mais densa dela, a nomenclatura de design tokens, e explicar o mecanismo que está por trás. Nomear token não é escolha estética. É escolha de API. Quando você escreve color.text.default, você está publicando um contrato que outro time vai consumir e que vai aparecer dentro do Figma truncado na metade. O nome é o único lugar onde a semântica mora.

O mecanismo: por que um token precisa de níveis

Um design token é um apelido para um valor. Em vez de usar HEX ou valores em px diretamente, você se refere a um token cujo nome descreve como e onde o valor é usado, o que torna muito mais simples atualizar o design mudando um valor em um lugar sem quebrar o resto. Isso é a parte fácil. A parte difícil é que #B90000 pode ser, ao mesmo tempo, a cor de borda de um input inválido, o fundo de um toast de erro e o ícone de alerta no header. Três intenções, um valor. Se você der um nome só, perde a intenção. Se der três nomes totalmente desconexos, perde o fato de que compartilham o valor.

Pensa num endereço postal. “Rua das Flores, 123” sozinho não serve para nada: existem mil Ruas das Flores no Brasil. Você precisa de bairro, cidade, estado, CEP. Cada nível reduz a ambiguidade do anterior. E a ordem importa: você escreve do mais específico ao mais genérico (ou o contrário, como no padrão japonês), mas nunca embaralhado. Taxonomia de token é exatamente isso. Cada nível é uma pergunta que o nome responde, e a ordem dos níveis é parte da gramática. A analogia quebra num ponto: endereço só precisa levar você a um lugar. Token precisa também permitir que você troque o lugar sem reescrever o nome.

Os níveis de Nathan Curtis

Curtis, da EightShapes, propôs um modelo que virou referência. Ele separa o nome do token em quatro famílias de níveis. Os níveis base são o esqueleto do token e combinam categoria (por exemplo, color), concept (action) e property (size). Os níveis modifier se referem a variant (primary), state (hover), scale (100) e mode (on-dark). Os níveis object se referem a um component (button), element dentro de um componente (left-icon) ou component group (forms). Acima disso tudo pode existir um namespace, que identifica o sistema ou a marca.

Na prática isso resulta em nomes de comprimento variável. O token $esds-color-neutral-42 combina quatro níveis, namespace (esds, de EightShapes Design System), category, variant e scale, para mapear para #6B6B6B. E quando a decisão é mais específica, mais níveis entram: $esds-color-feedback-background-error representa #B90000 propositalmente, e $esds-marquee-space-inset-2-x-media-query-s incorpora um nome de componente e inclui dois pares de category/scale.

Repare na ordem. Curtis escreve do mais genérico ao mais específico. Isso é importante porque o nome ordenado dessa forma agrupa automaticamente quando você lista alfabeticamente. Todos os color-feedback-* ficam juntos. Todos os color-neutral-* ficam juntos. O autocompletar do seu editor passa a funcionar como um menu de navegação, e não como uma loteria.

As três camadas: primitive, semantic, component

Em cima dos níveis existe outra decisão, independente: em que camada esse token vive. A convenção que foi se consolidando separa três. Primitive (ou global, ou base) é o valor cru sem contexto: blue-500 diz que um azul existe e qual é o valor dele, mas não diz onde usar. Semantic (ou alias) é a intenção: color-text-default aponta para um primitive e diz para que serve o valor. Component é ligado a um componente só: button-background-hover aponta para um semantic e existe para que um componente possa divergir por conta própria.

A regra prática que caiu bem no meu dia a dia: nunca referencie primitive direto no componente. Sempre passe por semantic. Isso é o que permite trocar o tema inteiro sem tocar nos componentes. E é também o que o time da Intuit descobriu, da forma dura, que faltava. O conjunto antigo de tokens era composto principalmente de primitives e tokens específicos de componente, com poucos tokens semânticos. Um set semântico fraco significava que primitives acabavam mapeados direto para tokens de componente sem contexto sistemático claro por trás da escolha de cor.

O que isso significa na prática

Vou mostrar como as três camadas se combinam em CSS Custom Properties, que é o jeito mais direto de implementar hoje:

:root {
 /* Camada 1: primitives. Valor cru, sem intenção. */
 --yk-color-red-500: #b90000;
 --yk-color-red-600: #8f0000;
 --yk-color-neutral-0: #ffffff;
 --yk-color-neutral-900: #111111;

 /* Camada 2: semantic. Intenção, aponta para primitive. */
 --yk-color-feedback-error: var(--yk-color-red-500);
 --yk-color-feedback-error-strong: var(--yk-color-red-600);
 --yk-color-text-default: var(--yk-color-neutral-900);
 --yk-color-surface-default: var(--yk-color-neutral-0);
}

[data-theme="dark"] {
 /* Trocar tema é reescrever semantic, nunca primitive. */
 --yk-color-text-default: var(--yk-color-neutral-0);
 --yk-color-surface-default: var(--yk-color-neutral-900);
}

.yk-input--invalid {
 /* Camada 3: component usa semantic, nunca primitive. */
 border-color: var(--yk-color-feedback-error);
}

O que esse código impõe: quando o modo escuro muda --yk-color-text-default, nenhum componente precisa ser reescrito. Quando o rebranding muda o vermelho da marca de #b90000 para outro vermelho, você edita o primitive e todos os semantics se ajustam. Se um componente precisa de uma cor que nenhum semantic descreve, isso é um sinal: ou falta um semantic no sistema, ou a decisão é genuinamente local e merece um token de component dedicado. Dificilmente é “vou puxar o primitive direto, só dessa vez”.

Em projetos onde publiquei design system e style guide de interface, o que mais fez diferença não foi o conjunto de componentes, foi essa disciplina de camadas. É quase nenhum engenheiro de IA que tem isso montado, e é por isso que quase toda interface de produto com agente hoje é feia: não tem onde ancorar as decisões, cada tela é uma decisão nova.

A ordem dos níveis dentro do nome

Curtis defende do mais genérico ao mais específico. A Intuit também. A convenção de nomenclatura derivada da taxonomia é ordenada da categoria mais genérica para a mais específica, uma forma intencional de ordenar cada categoria para construir uma sobre a outra, resultando em tokens que têm nomes naturais e humanos. O ponto de ter uma regra, qualquer regra, é que o próximo token a ser criado tem um lugar óbvio. Sem regra, cada pessoa escolhe uma ordem, e no fim do trimestre você tem button-hover-background e background-primary-button apontando para a mesma intenção.

Onde quebra

A taxonomia tem custo. O primeiro é cognitivo: um nome como yk-color-feedback-background-error-hover é longo. Nos problemas levantados pela Intuit: os nomes de token de componente eram difíceis de entender, eram longos e ficavam truncados na UI do Figma, havia tokens demais para escolher, e os times tinham dificuldade de identificar o racional por trás do uso. O Figma trunca. O autocompletar do VS Code mostra os primeiros caracteres, e se dez tokens começam igual, você passa a comparar sufixos. Isso é real e precisa ser desenhado contra.

O segundo custo é político. Design system só se paga quando tem mais de um time consumindo. Em time único, uma planilha com dez cores resolve. A taxonomia de quatro níveis é overkill. O investimento de nomear direito só retorna quando aparecem o segundo e o terceiro consumidor, e quando aparece o rebranding, o dark mode, o white label. Aí a economia aparece de uma vez.

O terceiro custo é que a disciplina só se mantém se o próprio tooling impõe. Num construtor de landing page que montei para tirar a criação de página da fila da engenharia, a redução de esforço de desenvolvimento por página passou de 70%, mas o preço foi aceitar que o marketing conseguisse montar página fora do design system, a menos que o próprio builder impusesse o limite. A lição vale aqui: se o pipeline de tokens não valida nomes contra a taxonomia (via linter, via schema JSON, via check de CI), a taxonomia vai erodir em três sprints. Documento não segura, código segura.

O quarto ponto é que taxonomia não resolve naming de feature voltada ao usuário. O artigo de Curtis expande como pensar em naming de token com uma base sólida estendida por modifiers, objects e namespaces, e aprofunda em princípios como completude, ordem e polihierarquia. Nada disso ajuda a decidir se o botão da sua ferramenta de IA se chama “Resumir”, “Sintetizar” ou “Gerar sumário”. Essa decisão vem de pesquisa com usuário, não de taxonomia.

O que não dá para afirmar ainda

A curadoria da Smashing junta trabalhos de contextos muito diferentes, EightShapes, Intuit, Vodafone UK, sem comparar resultados mensuráveis. Não há no material número de adoção, tempo até primeiro token útil, taxa de erro de uso. Então quando o artigo sugere que taxonomia melhora a vida do time, isso é consenso da prática, não resultado controlado. É possível que, em contextos de time pequeno e único produto, a camada semantic adicione fricção sem retorno proporcional. Eu não testei abaixo de dois consumidores.

Também não está claro no material como esses sistemas lidam com conflitos entre a convenção global e necessidades específicas de plataforma (iOS, Android, web têm restrições diferentes de nome, caracteres, tamanho). O artigo de Curtis trata disso em profundidade, mas é um tópico à parte.

Como testar isso você mesmo

Pega um projeto pequeno que você já tem e faz o seguinte, em uma hora:

  1. Lista todas as cores que aparecem no CSS. Se forem mais de dez repetições do mesmo HEX, você já tem primitive implícito.
  2. Para cada HEX, escreve ao lado qual é a intenção. Se o mesmo HEX serve a duas intenções, anota as duas.
  3. Cria um arquivo tokens.css com três blocos comentados: primitives, semantics, components. Preenche só os primitives (--brand-blue-500) e os semantics que você consegue nomear sem hesitar (--color-text-default, --color-surface-default, --color-feedback-error).
  4. Substitui no CSS existente, começando pelos componentes mais estáveis, as referências diretas por var(--...). Nunca referencia primitive dentro do componente.
  5. Adiciona um bloco [data-theme="dark"] e redefine só os semantics. Toggle no HTML e vê se a interface vira sem você tocar em nenhum componente.

Se o passo 5 funcionar sem reescrever componente, a camada semantic está fazendo o trabalho dela. Se não funcionar, provavelmente algum componente ainda está puxando primitive direto, e esse é exatamente o tipo de dívida que a taxonomia existe para evitar.

Deixe um Comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *