Use isto quando você está ensinando as convenções de um sistema: os tokens nomeados de cor e espaçamento, como os nomes são construídos e a forma certa vs. errada de usá-los.
Este é um exemplar copiável. Pegue as <section>s de demo abaixo e leve para uma lição construída a partir de assets/lesson-template.html — mantenha os design tokens e a paleta neutra-quente na íntegra.
Um design system é um pequeno dicionário compartilhado para a aparência de um produto. Em vez de escrever uma cor crua como #D97757 em cinquenta lugares, você dá a ela um único nome acordado — --clay — e todo mundo usa esse nome. Mude o valor do nome uma vez e cada botão, link e selo se atualiza junto.
Esta página ensina os três hábitos pelos quais um design system vive ou morre: as amostras (o que os valores nomeados realmente são), a tabela de nomenclatura (como o nome de um token é construído para que qualquer um adivinhe o certo) e os pares faça / não faça (os pequenos erros que silenciosamente quebram o sistema).
Pense como… uma cozinha com potes rotulados. Ninguém serve de um saco sem marca de pó branco torcendo para ser açúcar — pega o pote que diz “Açúcar”. Os tokens são os rótulos; esta página é a regra que diz sempre pegue o pote, nunca o saco cru.
Os tokens aqui são propriedades customizadas de CSS declaradas uma vez em :root e consumidas com var(--token). Como a resolução da cascata é ao vivo, sobrescrever um token em um escopo (uma classe de tema, prefers-color-scheme, a raiz de um componente) re-tematiza cada descendente com zero mudanças de marcação — a única fonte de verdade é a declaração, não o local de uso.
Duas camadas valem a pena separar em um sistema maduro: tokens primitivos (valores crus de escala como --clay: #D97757) e tokens semânticos que os apelidam por papel (--btn-bg: var(--clay)). Os componentes consomem apenas tokens semânticos, então re-skinnar significa re-apontar o apelido, nunca tocar no componente.
Cada token nomeado, mostrado como uma amostra com seu valor real. Esta é a página que um designer ou desenvolvedor escaneia para achar “o laranja certo” em vez de adivinhar um código hexadecimal.
Os tokens de espaçamento seguem uma escala de passos fixos (uma base de 4px: 4 · 8 · 12 · 16 · 24 · 52). Restringir o espaçamento a uma escala elimina a discussão fútil “é 13px ou 14px?” e garante o ritmo vertical — cada folga no produto é um múltiplo sobre o qual você consegue raciocinar. As cores são igualmente fechadas: dez nomes, nenhum hex fora do elenco.
Todos eles vivem em um único bloco :root no topo da folha de estilos, p.ex. --clay:#D97757; e --space-4:16px;. Um componente nunca repete um hex — ele escreve color:var(--clay) ou padding:var(--space-3) var(--space-4).
Um bom nome de token se lê como uma frase: categoria, depois papel, depois estado. Uma vez que você conhece a forma, consegue adivinhar um token que nunca viu.
btn, papel bg, estado hover → resolve para um token primitivo.O contrato em uma só tabela. Cada linha é um token semântico: seu nome, o primitivo para o qual aponta e exatamente onde recorrer a ele.
| Token | Valor | Use para |
|---|---|---|
| --btn-bg categoria · papel |
var(--clay) |
Preenchimento de um botão primário — a única ação principal de uma tela. |
| --btn-bg-hover categoria · papel · estado |
var(--clay-d) |
Fundo do botão primário enquanto o ponteiro está sobre ele. |
| --btn-fg categoria · papel |
#FFFFFF |
Texto do rótulo em um botão primário preenchido. |
| --btn-bg-success categoria · papel · intenção |
var(--olive) |
Ações de confirmar / salvar onde o verde sinaliza “seguro prosseguir”. |
| --btn-bg-danger categoria · papel · intenção |
var(--rust) |
Apenas ações destrutivas — excluir, remover, cancelar-de-verdade. |
| --space-3 passo de escala |
12px |
Padding vertical dentro de um controle. Combina com --space-4 na horizontal. |
| --radius-row categoria · papel |
9px |
Raio de canto em botões, inputs, chips — qualquer coisa do tamanho de uma linha. |
Note que cada token --btn-* apelida um primitivo (--clay, --olive…). Os componentes referenciam --btn-bg, nunca --clay diretamente. Essa indireção é o que permite entregar um tema de “alto contraste” ou “escuro”: você re-aponta os sete apelidos --btn-* em um escopo e a marcação fica intocada.
/* escala primitiva */ --clay: #D97757; --clay-d: #B85C3E; /* apelidos semânticos — os componentes usam ESTES */ --btn-bg: var(--clay); --btn-bg-hover: var(--clay-d); --btn-fg: #FFFFFF;
O mesmo botão, de duas formas. A coluna da esquerda mantém o sistema intacto; a coluna da direita silenciosamente o quebra.
Use o token nomeado. Se o laranja da marca um dia mudar, este botão muda junto — de graça.
.btn-primary {
background: var(--btn-bg);
color: var(--btn-fg);
padding: var(--space-3) var(--space-4);
border-radius: var(--radius-row);
}
Um hex cru e números mágicos. Invisível a uma mudança de tema, e a próxima pessoa não tem como saber qual laranja este deveria ser.
.btn-primary {
background: #D97757; /* qual laranja? */
color: #fff;
padding: 11px 15px; /* fora da escala */
border-radius: 8px; /* não é 9px */
}
O token de perigo diz para que serve. Qualquer um que lê o código sabe que este botão exclui algo.
/* confirmação de exclusão */ .btn-delete { background: var(--btn-bg-danger); }
Nomeado pela cor, não pela função. Renomeie o vermelho da marca e o token --red-button vira uma mentira.
/* para que serve isto? */ .btn-delete { background: var(--red-button); }
Escolha uma intenção e um tamanho abaixo. O botão de pré-visualização é estilizado apenas a partir de tokens — o trecho de código se atualiza para mostrar os tokens exatos em jogo.
Intenção
Tamanho
.btn { }
O botão não carrega nenhuma classe CSS por intenção. Cada controle segmentado escreve os tokens semânticos (--btn-bg, --btn-px, …) no style inline do elemento como propriedades customizadas. A única regra .ds-btn os lê com var(). É exatamente assim que um componente real orientado a tokens se comporta: troque os valores dos tokens, o componente re-renderiza, sem novos seletores.