Apostila completa de Design Systems & Design Tokens
Um design system é a fonte compartilhada de decisões de design e código que mantém muitos produtos e times coerentes. Esta apostila cobre o que ele é e não é, design tokens (o conceito, a spec do W3C, as três camadas), temas e modos, o pipeline de token para código com Style Dictionary, a anatomia e a API de componentes, contribuição e governança, a ponte com o Figma, e como escalar — com o olho no que empresas pedem de quem trabalha com design systems.
O que é (e não é) um design system
Objetivo: separar design system de UI kit, biblioteca de componentes e style guide; conhecer as partes que o compõem; e entender por que ele existe.
1.1 As definições que confundem
| Termo | O que é |
|---|---|
| Style guide | Documento com as regras visuais e de conteúdo (cor, tipografia, voz). Estático. |
| UI kit | Um arquivo de design (Figma/Sketch) com telas e elementos para copiar. Só do lado do design. |
| Biblioteca de componentes | Pacote de código com componentes reutilizáveis (React, Web Components…). Só do lado do código. |
| Design system | O conjunto conectado: tokens + componentes (design e código sincronizados) + padrões + guidelines + ferramentas + as pessoas e o processo que mantêm tudo. Vivo. |
Um design system é um produto cujos usuários são times de produto. Isso muda tudo: tem roadmap, versionamento, changelog, suporte, métricas de adoção e uma decisão constante entre "resolver isso no sistema" e "deixar o produto resolver". Sem esse enquadramento, vira uma pasta de componentes que ninguém mantém.
1.2 As partes de um design system
- Fundamentos / tokens: cor, tipografia, espaçamento, grade, raios, sombras, motion, z-index — as decisões atômicas (Módulos 2–3).
- Componentes: botão, campo, modal, tabela… em design e código, com a mesma API e o mesmo comportamento (Módulo 6).
- Padrões (patterns): composições recorrentes — formulário, página de detalhe, estado vazio, paginação, fluxo de confirmação destrutiva.
- Guidelines: conteúdo/UX writing, acessibilidade, uso de cor, do's & don'ts.
- Ferramentas: site de documentação, Storybook, plugins de lint, o pipeline de tokens.
- Governança: time, processo de contribuição, versionamento, suporte, medição.
1.3 Por que existe
- Consistência: a mesma coisa parece e se comporta igual em todo lugar — confiança do usuário, menos carga cognitiva.
- Velocidade: não redesenhar/reimplementar um botão a cada tela; times focam no problema do produto.
- Qualidade: acessibilidade, estados, responsivo e edge cases resolvidos uma vez, bem.
- Escala: muitos produtos, plataformas e times sem divergir.
- Manutenção: mudar a cor de marca ou o raio padrão em um lugar, não em 400.
1.4 Quando NÃO fazer (ou adiar)
Um produto único, pequeno, em fase de descoberta, com um time — um design system formal é custo sem retorno. Comece com uma escala de tokens e alguns componentes compartilhados; invista em sistema quando há múltiplos produtos/times e a divergência já dói. Design system é resposta a um problema de escala, não um troféu.
Perguntas de abertura: "Qual a diferença entre um design system e uma biblioteca de componentes?" (o sistema conecta design + código + processo + pessoas; a lib é só código), "Quais as partes de um design system?", "Por que uma empresa investe num?" (consistência, velocidade, qualidade, escala), "Quando você não faria um?".
✏️ Exercício 1 — Classifique
Para cada item, diga se é style guide, UI kit, biblioteca de componentes ou design system, e o que falta para ser um design system: (a) um PDF com a paleta e as fontes da marca; (b) um pacote npm com 40 componentes React; (c) um arquivo Figma com todos os componentes e telas; (d) o item (b) + o item (c) com os mesmos nomes, um site de documentação, um time responsável e um processo de contribuição.
Gabarito: (a) style guide — falta código, componentes, sincronia e processo. (b) biblioteca de componentes — falta o lado do design, tokens compartilhados, documentação e governança. (c) UI kit — falta o código sincronizado e o processo. (d) design system — tem tokens/componentes em design e código com paridade, documentação, time e governança; o "vivo" está presente.
Design tokens: o conceito
Objetivo: entender o que é um token, por que nomear decisões, o formato e os tipos, e a especificação do W3C Design Tokens Community Group.
2.1 O que é um token
Um design token é uma decisão de design nomeada, guardada como dado, e não como valor solto no código. Em vez de #0E7C6B espalhado, você tem color.action.default = #0E7C6B. O nome carrega a intenção; o valor pode mudar (tema, marca, plataforma) sem tocar em quem o usa.
Tokens são a menor unidade compartilhável de um design system e a peça que viaja melhor entre plataformas: o mesmo space.4 vira 1rem na web, 16pt no iOS, 16dp no Android.
2.2 Formato: nome, valor, tipo
// spec do Design Tokens Community Group (W3C DTCG) — arquivo .tokens.json
{
"color": {
"brand": {
"$type": "color",
"500": { "$value": "#0E7C6B" },
"600": { "$value": "#0A5A4E" }
}
},
"space": {
"$type": "dimension",
"4": { "$value": "16px" }
},
"radius": {
"$type": "dimension",
"2": { "$value": "8px" }
}
}
$value: o valor bruto ou uma referência a outro token ("{color.brand.500}").$type:color,dimension,fontFamily,fontWeight,duration,cubicBezier,number,shadow,typography,border,gradient,transition… (a spec define o conjunto).$description: para que serve — vira documentação.
2.3 Tokens compostos (composite)
{
"typography": {
"heading-1": {
"$type": "typography",
"$value": {
"fontFamily": "{font.family.sans}",
"fontSize": "{font.size.800}",
"fontWeight": "{font.weight.bold}",
"lineHeight": "1.15",
"letterSpacing": "-0.02em"
}
}
},
"shadow": {
"raised": {
"$type": "shadow",
"$value": { "offsetX": "0", "offsetY": "1px", "blur": "3px", "spread": "0", "color": "#0000001f" }
}
}
}
Compostos agrupam vários valores numa decisão só (um "estilo de texto", uma "elevação") — o mesmo conceito de "type style" da apostila Tipografia.
2.4 Por que a spec importa
Antes do DTCG, cada ferramenta tinha seu formato e a interoperabilidade era zero. A spec do W3C dá um formato comum (.tokens.json) que Figma, Style Dictionary, Tokens Studio, Storybook e afins podem ler e escrever — o token deixa de ser refém de uma ferramenta. Ainda está evoluindo; acompanhe.
Perguntas: "O que é um design token e por que não usar o valor direto?" (nome carrega intenção; valor troca por tema/plataforma sem tocar no consumidor), "O que é o DTCG / a spec de design tokens do W3C?", "O que é um token composto?" (typography, shadow — várias propriedades numa decisão), "Como um token vira valor em iOS e Android?" (transforms no pipeline — Módulo 5).
✏️ Exercício 2 — Escreva os tokens
Modele em JSON (estilo DTCG) os tokens para: dois tons de uma cor primária, três degraus de espaçamento, um raio, e um token de tipografia composto "body". Use referências onde fizer sentido.
Gabarito (uma boa resposta): color.primary com $type: color e chaves 500/600; space com $type: dimension e 2/3/4 = 8px/12px/16px; radius.2 = 8px; typography.body com $type: typography e $value objeto: fontFamily: "{font.family.sans}", fontSize: "{font.size.300}", fontWeight: "{font.weight.regular}", lineHeight: "1.55". A referência {font.family.sans} evita repetir a stack de fontes.
As três camadas de token
Objetivo: estruturar tokens em primitivos, semânticos e de componente — e entender por que os componentes só devem consumir a camada semântica.
3.1 As camadas
| Camada | Também chamada | O que é | Exemplo |
|---|---|---|---|
| Primitivo | option, global, core, tier-1 | o valor cru, sem significado de uso; a paleta completa, a escala inteira | color.blue.500, space.4, font.size.300 |
| Semântico | alias, decision, system, tier-2 | um papel; aponta para um primitivo; é o que muda entre temas | color.action, color.text.muted, space.inset.card |
| Componente | scoped, tier-3 | específico de um componente; aponta para um semântico; opcional | button.primary.background, card.padding |
/* PRIMITIVO */ --blue-500: oklch(64% 0.17 254); --gray-900: oklch(22% 0.012 260); --space-4: 1rem; /* SEMÂNTICO — os componentes usam SÓ estes */ --color-action: var(--blue-500); --color-text: var(--gray-900); --space-inset-md: var(--space-4); /* COMPONENTE (opcional) — quando um componente precisa desviar do semântico */ --button-primary-bg: var(--color-action); --button-padding-x: var(--space-inset-md);
3.2 Por que componentes só consomem semânticos
- Temas funcionam: trocar dark mode / marca = redefinir a camada semântica; se o botão aponta para
blue-500direto, ele não acompanha. - Intenção fica explícita:
color-actiondiz por que aquela cor está ali;blue-500não. - Refatorar é seguro: mudar qual primitivo o semântico aponta não quebra nada a jusante.
3.3 Quando criar tokens de componente
Só quando um componente precisa legitimamente desviar do semântico ou quando expor um "gancho" de customização é o objetivo (theming por componente). Criar button.text.color = color.text.on-action só para "ter simetria" incha o sistema. Regra: comece sem a camada de componente; adicione um token só quando a dor aparece.
3.4 Nomenclatura
- Primitivos por escala (
blue-500,space-4) — descritivo, sem uso. - Semânticos por papel, num padrão consistente:
categoria.papel.variante.estado→color.text.muted,color.border.focus,color.bg.danger.subtle. - Evite números em semânticos (
color-text-2não diz nada); evite acoplar ao valor (color-action-bluemente quando a marca vira roxa). - Documente o padrão de nomes — é o contrato mais usado do sistema.
Só uma camada (primitivos usados direto nos componentes) — o tema quebra. Semânticos demais, um por cor de cada canto — vira dicionário sinônimo. Nome semântico acoplado ao valor (color-primary-green). Camada de componente para tudo, sem necessidade. Referências circulares. Mudar o valor de um primitivo quando na verdade era preciso um novo (e aí toda a UI muda sem querer).
Perguntas: "Explique as três camadas de token" (primitivo/opção → semântico/papel → componente), "Por que um componente não deve usar um primitivo direto?" (temas, intenção, refatoração), "Como você nomeia tokens semânticos?" (por papel, padrão categoria.papel.variante.estado, sem acoplar ao valor), "Quando criar um token de componente?".
✏️ Exercício 3 — Refatore para camadas
Um projeto tem, no CSS dos componentes: background:#0E7C6B no botão primário, color:#44555F em textos "secundários" em 12 lugares, border:1px solid #DCE4E8 em inputs e cards. Reescreva com as três camadas e diga o que muda ao adicionar dark mode.
Gabarito (uma boa resposta): Primitivos: --teal-600:#0E7C6B, --gray-600:#44555F, --gray-200:#DCE4E8. Semânticos: --color-action: var(--teal-600), --color-text-muted: var(--gray-600), --color-border: var(--gray-200). Componentes usam var(--color-action), var(--color-text-muted), var(--color-border). Dark mode: um bloco @media (prefers-color-scheme: dark) (ou [data-theme=dark]) redefine só os três semânticos (ex.: --color-action mais claro e menos saturado, --color-border com alpha maior) — nenhum componente muda.
Temas e modos
Objetivo: modelar light/dark, densidade, marca (white-label) e alto contraste como reconfigurações da camada semântica — não como forks.
4.1 Um tema é a camada semântica trocada
Se a arquitetura de token estiver certa (Módulo 3), um tema é só outro conjunto de valores para os mesmos nomes semânticos. Os primitivos podem até ser os mesmos; o que muda é para onde color.surface, color.text, color.action apontam.
:root{ /* tema claro (default) */
--color-surface: var(--gray-50);
--color-text: var(--gray-900);
--color-action: var(--blue-600);
}
[data-theme="dark"]{
--color-surface: var(--gray-950);
--color-text: var(--gray-50);
--color-action: var(--blue-400); /* +L, -C no escuro */
}
@media (prefers-color-scheme: dark){
:root:not([data-theme="light"]){ /* mesmos overrides do dark */ }
}
4.2 Modos independentes
- Aparência (light/dark) e densidade (confortável/compacto) e contraste (normal/alto) são eixos ortogonais — combináveis. Modele cada um como um conjunto de overrides próprio, aplicável por atributo/classe num escopo.
- Densidade: um
--densityque multiplica a escala de espaçamento e reduz alturas de linha (ver Layout, Grade & Espaçamento). @media (prefers-contrast: more)e(forced-colors: active): ofereça a variante de alto contraste e teste o modo do SO (ver Acessibilidade Digital & WCAG).
4.3 Multi-brand / white-label
- Cada marca é um token set que sobrescreve os semânticos (e às vezes alguns primitivos: a paleta de marca, a fonte).
- Padrão robusto: o cliente fornece poucas entradas (cor de marca, talvez a fonte e o raio) e o sistema deriva o resto — rampa via OKLCH, estados, semânticas (ver Cor, Módulo 7).
- Fixe as semânticas de status — o cliente não pode tornar "erro" verde.
- Valide contraste automaticamente para qualquer entrada e ajuste (texto sobre a cor de marca vira preto ou branco conforme a luminosidade dela).
4.4 Onde os temas vivem em runtime
- CSS custom properties são a melhor sede: trocar tema é mudar um atributo no
<html>, sem rebuild, sem recarregar, com transição possível. - Evite gerar um CSS por tema e trocar o arquivo (flash, cache, mais bytes). Um CSS com os blocos de override é mais simples.
- Persistir a escolha do usuário (localStorage) + respeitar
prefers-color-schemecomo default + evitar o "flash" de tema errado (script inline no<head>).
Adicione um tema novo (ou o dark mode) sem abrir nenhum arquivo de componente. Se você conseguiu, a arquitetura está certa. Se precisou caçar cores dentro de componentes, faltam semânticos — algum componente está falando com um primitivo (ou um valor cru) direto.
Perguntas: "Como você implementa dark mode num design system?" (redefinir só a camada semântica; CSS custom properties; respeitar prefers-color-scheme + escolha do usuário + anti-flash), "Como suportar white-label sem forks?" (token set por marca, poucas entradas → derivar, status fixo, validar contraste), "Aparência e densidade são o mesmo eixo?" (não — ortogonais, combináveis).
✏️ Exercício 4 — Modele os modos
Especifique como você suportaria, ao mesmo tempo: (a) claro/escuro; (b) confortável/compacto; (c) três marcas. Diga o que cada modo sobrescreve, onde isso vive, e como evitar o flash de tema errado no carregamento.
Gabarito (uma boa resposta): (a) [data-theme] no <html> sobrescreve os semânticos de cor; default segue prefers-color-scheme. (b) [data-density] sobrescreve --density (multiplicador da escala de espaço) e alturas de componente. (c) [data-brand] sobrescreve os primitivos da paleta de marca + a fonte + o raio, e os semânticos derivados se recalculam (via oklch(from …)/color-mix) — status fica fixo. Tudo em CSS custom properties, combinável (os três atributos coexistem). Anti-flash: um <script> inline no <head> que lê o localStorage e o matchMedia e seta os atributos antes do primeiro paint.
Do token ao código: o pipeline
Objetivo: transformar um arquivo de tokens numa saída para cada plataforma com Style Dictionary / Tokens Studio, incluindo transforms, referências, build no CI e versionamento.
5.1 O problema
Você tem os tokens em .tokens.json. Precisa deles como: CSS custom properties (web), objeto JS/TS (para lógica e RN), .xml/Compose (Android), .swift/asset catalog (iOS), variáveis do Figma. Mantê-los à mão em 5 formatos = divergência garantida. A resposta é uma fonte, muitas saídas, geradas.
5.2 Style Dictionary
// style-dictionary config (resumo)
{
"source": ["tokens/**/*.tokens.json"],
"platforms": {
"css": {
"transformGroup": "css",
"buildPath": "dist/css/",
"files": [{ "destination": "tokens.css", "format": "css/variables",
"options": { "outputReferences": true } }]
},
"ts": {
"transformGroup": "js",
"buildPath": "dist/ts/",
"files": [{ "destination": "tokens.ts", "format": "javascript/es6" }]
},
"android": { "transformGroup": "android", "buildPath": "dist/android/",
"files": [{ "destination": "tokens.xml", "format": "android/resources" }] }
}
}
- Parsers leem o formato DTCG; transforms convertem valores (
16px→16.00dp,#RRGGBBAA→UIColor, nomecolor.text.muted→--color-text-muted/colorTextMuted); formats montam o arquivo final. outputReferences: preservavar(--blue-500)em vez de "achatar" para o hex — mantém a cascata e o tema no CSS gerado.- Compostos (typography, shadow) têm formats próprios ou transforms custom.
5.3 Tokens Studio
Plugin do Figma para criar e editar tokens dentro do Figma (com temas/sets), exportando o JSON DTCG para o repositório. Fecha o loop "designer edita token → PR → pipeline gera código". Alternativa/complemento: as Variables nativas do Figma (Módulo 8).
5.4 O build no CI
- O repositório de tokens roda o pipeline a cada PR: valida o JSON (schema DTCG), checa referências quebradas e ciclos, roda testes de contraste nos pares semânticos, gera as saídas e publica um pacote versionado.
- Os produtos consomem o pacote (
@empresa/tokens) por versão — não copiam arquivos.
5.5 Versionamento
- SemVer: patch = ajuste de valor sem mudança perceptível/renome; minor = token novo; major = remoção/renome de token ou mudança de valor com impacto visual grande.
- Changelog humano por versão; codemods/mapa de renome para majors.
- Deprecação antes de remover: marcar
$deprecated, manter um release, avisar.
Perguntas (DS engineer): "Como um token vira CSS, iOS e Android a partir de uma fonte?" (Style Dictionary: parsers → transforms → formats), "O que outputReferences resolve?" (mantém var() e a cascata/tema no CSS gerado), "Como você versiona tokens?" (SemVer; major para renome/remoção/mudança visual; changelog + codemods; deprecação antes), "Onde entra o Tokens Studio?".
✏️ Exercício 5 — Desenhe o pipeline
Descreva o fluxo completo de uma mudança: o designer precisa escurecer levemente o color.action para melhorar contraste. Da edição à chegada nos produtos web e mobile — incluindo o que roda no CI e como isso é versionado.
Gabarito (uma boa resposta): designer edita o token no Tokens Studio/Figma Variables → exporta o .tokens.json → abre PR no repo de tokens. CI: valida schema DTCG, checa referências/ciclos, roda teste de contraste (agora color.action vs texto passa), gera tokens.css, tokens.ts, tokens.xml, asset iOS. Como é só um ajuste de valor sem impacto visual grande nem renome → bump patch (ou minor se a política considerar mudança de cor perceptível como minor); entrada no changelog. Publica @empresa/tokens@x.y.z. Produtos web e mobile atualizam a dependência (Renovate/Dependabot) e recebem o novo valor sem tocar em componentes.
Componentes
Objetivo: projetar a anatomia e a API de um componente de sistema, suas variantes e estados, a acessibilidade embutida, e a paridade design ↔ código.
6.1 Anatomia e API
- Anatomia: as partes nomeadas (um Button tem: container, label, ícone opcional à esquerda/direita, spinner de loading). O mesmo mapa de partes existe no design e no código.
- Props / API: poucas, ortogonais, previsíveis. Para o Button:
variant(primary/secondary/ghost/danger),size(sm/md/lg),statederivado (hover/active/focus/disabled/loading),iconStart/iconEnd,fullWidth. - Configuração vs composição: props para o que é finito e padronizado (variant, size); slots/children para o que varia livremente (o conteúdo de um Card, as ações de um Dialog). Evite a "prop explosion".
6.2 Variantes, tamanhos, estados
- Defina a matriz: variant × size × state. Nem toda célula precisa existir, mas as que existem são especificadas (tokens de cada parte em cada combinação).
- Estados obrigatórios em todo componente interativo: default, hover, active/pressed, focus-visible, disabled, e quando aplicável loading, error, selected, read-only.
- Estados são derivados de tokens semânticos (ex.: hover =
color.action−8% L), não cores novas à mão.
6.3 Acessibilidade embutida
- O componente já vem acessível: papel/ARIA correto, foco visível e gerenciado, navegação por teclado,
aria-label/associações, respeito aprefers-reduced-motion, alvo de toque ≥ 24–44px. - Padrões complexos (menu, combobox, dialog, tabs) seguem o APG (ARIA Authoring Practices) — não reinvente.
- Isso é metade do valor de um design system: acessibilidade resolvida uma vez, bem. Ver Acessibilidade Digital & WCAG.
6.4 Headless + estilo
Separar comportamento/acessibilidade (headless: Radix, React Aria, Ark, Headless UI) do estilo (seus tokens) é o padrão atual: você herda anos de edge cases de teclado/ARIA e aplica a sua skin. Para multi-framework, um core headless em Web Components ou lógica compartilhada + camadas finas por framework.
6.5 Documentação do componente
- Visão geral: o que é, quando usar, quando não usar (e o que usar no lugar).
- Anatomia ilustrada; props tabeladas; variantes/estados renderizados (Storybook).
- Do's & don'ts visuais; acessibilidade (o que o componente garante e o que cabe a quem usa); conteúdo (como escrever o label).
- Código e design lado a lado; link para o componente no Figma (Code Connect — Módulo 8).
API com 30 props booleanas em vez de variant/size. Cor/spacing cru no CSS do componente (não token semântico). Sem estado :focus-visible. Reimplementar um combobox do zero em vez de usar um headless + APG. Componente que só existe no código (ou só no Figma). Documentação sem "quando não usar". Variante nova adicionada sem passar por revisão de acessibilidade.
Perguntas: "Como você projeta a API de um componente de sistema?" (poucas props ortogonais; variant/size para o finito, slots para o livre; evitar prop explosion), "Configuração vs composição?", "O que significa 'acessibilidade embutida'?", "O que é um componente headless e por que usar?" (herdar comportamento/ARIA, aplicar sua skin), "O que uma boa doc de componente tem?".
✏️ Exercício 6 — Especifique um componente
Projete a especificação de sistema de um componente Alert/Callout: anatomia, props, variantes, estados, acessibilidade e "quando não usar".
Gabarito (uma boa resposta): Anatomia: container, ícone de status, título opcional, conteúdo, ações opcionais, botão de fechar opcional. Props: tone (info/success/warning/danger), title?, dismissible?, icon? (override), children (conteúdo), actions? (slot). Variantes visuais: por tone, cada um com fundo sutil + borda + cor de ícone vindos de tokens semânticos (color.bg.danger.subtle etc.); talvez emphasis (subtle/solid). Estados: estático; se dismissible, o botão fechar tem hover/focus-visible. Acessibilidade: role="status" (info/success) ou role="alert" (warning/danger, se urgente); o ícone é decorativo (aria-hidden) e o sentido vem do texto (não só da cor — volta ao 1.4.1); foco não é roubado; contraste do texto ≥ 4.5:1 sobre o fundo do tone. Quando não usar: para feedback efêmero de uma ação → use Toast; para erro de um campo → use a mensagem inline do Field; para bloquear o fluxo → use Dialog.
Contribuição e governança
Objetivo: o modelo de time, o processo de proposta e contribuição, versionamento de breaking changes, deprecação e as métricas de adoção que provam o valor.
7.1 Modelos de time
| Modelo | Como | Trade-off |
|---|---|---|
| Centralizado (solitary) | um time dedicado faz tudo | consistência alta; vira gargalo; distante dos produtos |
| Federado / distribuído | representantes de vários times mantêm juntos | perto dos produtos; exige coordenação forte; risco de inconsistência |
| Híbrido (core + contribuição) | um time core pequeno + contribuições revisadas dos produtos | o mais comum em escala; precisa de processo claro de contribuição |
7.2 "Resolvido, não resolvido, não vamos resolver"
Todo elemento do sistema tem um status explícito: resolvido (use), em progresso (RFC aberto), não resolvido (ainda faça no produto, mas siga a convenção X), fora de escopo. Isso evita que times esperem por algo que nunca virá e que reinventem o que já existe.
7.3 O processo de contribuição
- Intake: um canal único para pedidos/ideias, triados regularmente.
- RFC / proposal: problema, casos de uso, alternativas, proposta de API — revisado por design + eng + acessibilidade antes de escrever código.
- Definição de pronto: design + código + testes + a11y + docs + entrada no Figma + changelog. Um componente não "existe" sem todos.
- Revisão: checklist (tokens, estados obrigatórios, APG, responsivo, RTL, dark mode).
7.4 Breaking changes e deprecação
- Deprecar antes de remover: marcar como deprecated, manter funcionando ≥ 1 ciclo, avisar, oferecer a alternativa e um codemod.
- Major agrupa breaking changes; changelog detalhado; guia de migração; ferramentas automáticas onde possível (oasdiff-style para APIs de componente, jscodeshift para props).
- Janela de suporte: quanto tempo a versão N-1 recebe correções.
7.5 Adoção: as métricas que importam
- Cobertura: % dos componentes de UI em produção que vêm do design system (via análise estática / scanners como a "component analytics" do próprio DS).
- Adoção por produto/time ao longo do tempo; nº de detached/overrides no Figma.
- Velocidade: tempo para montar uma tela nova antes/depois; nº de bugs de a11y/visual reportados.
- Saúde: issues abertas, tempo de resposta, NPS interno do sistema.
- Essas métricas são como o time de DS justifica orçamento — trate-as como parte do produto.
Perguntas: "Modelos de time de design system e trade-offs?" (centralizado/federado/híbrido), "Como funciona a contribuição de um produto para o sistema?" (intake → RFC → definição de pronto → revisão), "Como você conduz um breaking change?" (deprecar → avisar → codemod → major com guia), "Como você mede o sucesso de um design system?" (cobertura, adoção, velocidade, saúde).
✏️ Exercício 7 — Escreva o processo
Um time de produto quer um componente novo (um "Stepper" numérico) que não existe no sistema. Descreva o caminho desde o pedido até o componente publicado, incluindo os gates e quem revisa o quê.
Gabarito (uma boa resposta): pedido entra pelo intake → triagem marca como "não resolvido, candidato" e pede um RFC (problema, casos de uso reais, alternativas — dá pra resolver com Input + botões?, proposta de API: value, min, max, step, onChange, tamanhos). Revisão do RFC por: design (encaixa nos padrões?), eng (API sustentável? headless disponível?), a11y (é o padrão APG de spinbutton — teclado ↑↓, role="spinbutton", aria-valuenow/min/max). Aprovado → implementação (headless + tokens), testes, story, doc com "quando não usar", componente no Figma com as mesmas props, entrada no changelog (minor — token/componente novo). Gate final: checklist (estados obrigatórios, dark mode, RTL, responsivo, a11y) antes de publicar @empresa/components@x.(y+1).0.
Figma e a ponte design ↔ código
Objetivo: usar Variables e modes, component properties e bibliotecas publicadas no Figma; manter paridade com o código; e detectar divergência com Code Connect e design lint.
8.1 Variables e modes
- Variables do Figma = tokens: tipos color, number, string, boolean; organizadas em collections; com modes (ex.: a collection "theme" tem modes Light/Dark; "density" tem Comfortable/Compact).
- Aliases: uma variable aponta para outra — as três camadas do Módulo 3 reproduzidas no Figma (primitivos numa collection, semânticos noutra que referencia a primeira).
- Aplicar um mode a um frame troca todos os valores de uma vez — o "dark mode" do protótipo.
8.2 Component properties
- Variant (a matriz variant/size/state), boolean (mostrar ícone?), instance swap (qual ícone), text (o label) — o equivalente visual das props do componente de código.
- Os nomes das properties devem bater com os nomes das props no código.
variant=primaryno Figma ↔variant="primary"no React.
8.3 Bibliotecas e publicação
- O DS vive numa ou mais bibliotecas publicadas; produtos as habilitam e recebem updates com aviso de mudança.
- Versione as libs em paralelo aos pacotes de código; comunique breaking changes de componente do Figma como você comunica os do código.
8.4 Code Connect
Code Connect liga um componente do Figma ao seu componente de código real: no Dev Mode, quem for implementar vê o seu snippet (import certo, props mapeadas), não um CSS genérico. Mantém a ponte viva e reduz o "traduzi errado do design".
8.5 Divergência: o inimigo
- Sintomas: a cor no Figma não é a do CSS; um espaçamento "18" solto; um componente detached; uma variante que só existe de um lado.
- Prevenção: tokens como fonte única (Tokens Studio ou Variables exportadas para o pipeline), paridade de nomes, Code Connect, e design lint (plugins que apontam valores fora dos tokens, camadas soltas, uso de estilos locais).
- Detecção: auditorias periódicas (component analytics do Figma: quantas instâncias, quantos overrides, quantos detached por arquivo).
O erro mais caro é manter os tokens à mão nos dois lados (Figma e código). Escolha uma direção: ou o repositório (JSON DTCG) é a fonte e as Figma Variables são importadas dele, ou o Figma/Tokens Studio é a fonte e o JSON é exportado para o pipeline. As duas funcionam; ter duas fontes não funciona.
Perguntas: "O que são Figma Variables e modes, e como mapeiam para tokens?" (collections + aliases = as três camadas; modes = temas), "Como você garante paridade entre o componente do Figma e o do código?" (nomes de property = nomes de prop; Code Connect), "Como você detecta e previne divergência de tokens?" (fonte única, design lint, component analytics), "O que o Code Connect faz?".
✏️ Exercício 8 — Ligue os dois lados
Você tem tokens no repositório (JSON DTCG, fonte da verdade) e uma biblioteca no Figma. Descreva como manter os dois em sincronia: tokens, um componente Button, e o dark mode. Cite duas verificações automáticas.
Gabarito (uma boa resposta): Tokens: pipeline gera, além do CSS/TS, um arquivo que um plugin (ou a API do Figma) importa para as Variables — collections "primitives" e "semantic" com aliases, e uma collection "theme" com modes Light/Dark refletindo os overrides do JSON. Button: component properties variant/size com os mesmos valores das props; Code Connect mapeando para <Button variant size> real, para o Dev Mode mostrar o snippet certo. Dark mode: é o mode "Dark" da collection theme — aplicar num frame troca os semânticos; no código é [data-theme=dark] gerado do mesmo JSON. Verificações: (1) CI do repo de tokens falha se o export para Figma diverge do JSON; (2) design lint no Figma sinaliza qualquer cor/spacing que não seja uma Variable, e um relatório de component analytics acusa detached/overrides acima de um limite.
Escala e ROI
Objetivo: arquitetura para muitos produtos e plataformas, camadas de sistema, performance, migração de legado, e como medir (e defender) o retorno.
9.1 Multi-produto: core + extensões
- Core: tokens e componentes verdadeiramente comuns a todos os produtos.
- Camadas de produto: cada produto pode ter um conjunto de tokens semânticos e componentes próprios que estendem o core, sem forká-lo.
- Evite o "sistema que serve a todos e a ninguém": o core resolve o comum; a variação legítima mora nas camadas.
9.2 Arquitetura de token em grande escala
- Alguns sistemas usam 4 tiers: tier-0 (constantes brutas) → tier-1 (primitivos/opções) → tier-2 (semânticos/sistema) → tier-3 (componente). A profundidade extra ajuda quando há muitas marcas e plataformas; em sistemas menores, 2–3 camadas bastam — não adicione tiers por estética.
- Namespacing:
empresa.core.color.actionvsempresa.produtoX.color.action. - Ferramentas de resolução de referência e detecção de ciclo tornam-se críticas.
9.3 Performance
- CSS de tokens: centenas de custom properties é barato; milhares por tema × modo × marca, todos sempre carregados, não. Carregue só os modes ativos; considere escopar.
- Componentes: tree-shaking real (imports por componente), CSS por componente, evitar um bundle monolítico.
- Medir o custo do DS no LCP/CLS/JS transferido dos produtos que o consomem.
9.4 Migração de um sistema legado
- Inventário: quantos botões diferentes existem hoje? (scanners de código e de Figma). O número costuma chocar e vender o projeto.
- Ponte: uma camada de compatibilidade (tokens antigos apontando para os novos) para migrar incremental, tela a tela, sem "big bang".
- Ordem: tokens primeiro (ganho rápido, baixo risco) → componentes de alta frequência (botão, campo, tipografia) → padrões.
- Codemods e um "modo estrito" opcional que falha o build em uso de padrão antigo.
9.5 ROI e quando parar
- Custo: o time de DS, o tempo de adoção dos produtos, a manutenção.
- Retorno: horas não gastas reimplementando, bugs de a11y/visual evitados, velocidade de novas telas, consistência (mais difícil de quantificar, mas real).
- Anti-padrões de escala: gold-plating (componentes que ninguém pede), governança tão pesada que ninguém contribui, sistema que trava a inovação dos produtos. Um DS existe para acelerar — se está freando, ajuste o escopo.
Em maturidade alta, o design system deixa de ser "componentes" e vira uma plataforma: CLI para scaffolding de componentes, testes visuais automáticos (Chromatic/Playwright), documentação gerada, analytics de uso embutido, RFCs versionados, canais de suporte, e um contrato de SLA com os produtos. As decisões passam a ser de produto e de operação, não só de design.
Perguntas (staff / lead de DS): "Como você arquiteta um DS para 6 produtos e 3 plataformas?" (core + camadas de produto; namespacing; não forkar o core), "Quantos tiers de token?" (2–3 na maioria; 4 só com muitas marcas/plataformas — não por estética), "Como migrar de um sistema legado sem big bang?" (inventário → camada de compatibilidade → tokens → componentes de alta frequência → codemods), "Como você defende o orçamento do DS?" (cobertura, velocidade, bugs evitados, custo vs retorno).
✏️ Exercício 9 — Plano de adoção
Uma empresa tem 4 produtos web, cada um com seu próprio CSS e componentes, muita inconsistência. Você foi contratado para criar o design system. Descreva os 3 primeiros trimestres: o que entregar, em que ordem, e como medir progresso.
Gabarito (uma boa resposta): T1 — fundação e prova de valor: inventário automatizado (quantos botões/cores/spacings distintos existem — o número vende o projeto); definir a arquitetura de token (3 camadas) e publicar @empresa/tokens com pipeline no CI; migrar um produto piloto para os tokens (cor, tipografia, espaçamento) — ganho rápido, baixo risco. Métrica: % do CSS do piloto usando tokens. T2 — componentes de alta frequência: Button, Input/Field, Typography, Link, Icon, Stack/Grid (primitivas de layout) com headless + a11y + Storybook + Figma com paridade; camada de compatibilidade para migração incremental; adoção no piloto + começar no 2º produto. Métrica: cobertura de componentes do DS nos dois produtos. T3 — padrões e expansão: formulário, modal, tabela, toast, estados vazios; processo de contribuição (intake + RFC + definição de pronto); site de documentação; onboarding dos produtos 3 e 4. Métrica: cobertura agregada, tempo para montar uma tela nova, nº de bugs de a11y reportados (deve cair), NPS interno do sistema.
Mercado de trabalho: roadmap, entrevistas e portfólio
Objetivo: converter o conteúdo dos módulos em contratação — os cargos, um plano de estudo, um banco de perguntas com respostas e projetos que geram entrevista.
10.1 Os cargos
- Design Systems Designer: tokens, componentes no Figma, padrões, guidelines, documentação, contribuição do lado do design.
- Design Systems Engineer / Design Technologist: a biblioteca de código, o pipeline de tokens, Storybook, testes visuais, a ponte Figma↔código, performance.
- DS Product Manager / Lead: roadmap, governança, adoção, stakeholders, ROI.
- Accessibility specialist frequentemente dedicado ou muito próximo.
- Em times menores, uma pessoa acumula design + engenharia do sistema — o "design engineer".
10.2 Roadmap de estudo (6–8 semanas)
| Semanas | Foco | Prática |
|---|---|---|
| 1 | O que é um DS; anatomia (Módulo 1) | Estudar 3 design systems públicos (Polaris, Primer, Material, Carbon) e mapear as partes de cada |
| 2 | Tokens: conceito e spec (Módulo 2) | Modelar um conjunto de tokens em JSON DTCG (cor, espaço, tipo, raio, sombra, motion) |
| 3 | As três camadas (Módulo 3) | Refatorar um CSS real para primitivos → semânticos; nomear com um padrão |
| 4 | Temas e pipeline (Módulos 4–5) | Style Dictionary: gerar CSS + TS + (mock) Android; adicionar dark mode e um 2º "brand" só via overrides |
| 5 | Componentes (Módulo 6) | Construir um Button e um Field completos (headless + tokens + estados + a11y + Storybook) |
| 6 | Figma ↔ código (Módulo 8) | Recriar os tokens como Figma Variables com modes; component properties com paridade de nomes; Code Connect |
| 7 | Governança e escala (Módulos 7, 9) | Escrever um RFC template, uma definição de pronto, uma política de versionamento e um plano de adoção |
| 8 | Portfólio | Publicar um mini-DS com site de documentação e os estudos de caso escritos |
10.3 Banco de perguntas de entrevista (com a resposta que aprova)
Júnior/pleno — "O que é um design token?"
Uma decisão de design nomeada e guardada como dado, não como valor solto: color.action.default em vez de #0E7C6B espalhado. O nome carrega a intenção; o valor pode mudar por tema/marca/plataforma sem tocar em quem consome. É a menor unidade compartilhável do sistema e a que viaja melhor entre plataformas.
Pleno — "Explique as três camadas de tokens."
Primitivos (opção/global): valores crus sem uso — a paleta e as escalas inteiras (blue-500, space-4). Semânticos (alias/decisão): papéis que apontam para primitivos e mudam entre temas (color-action, color-text-muted). Componente (scoped, opcional): específicos de um componente, apontando para semânticos. Regra: componentes consomem só a camada semântica — assim temas funcionam e a intenção fica explícita.
Pleno — "Como você implementa dark mode?"
Redefinindo apenas a camada de tokens semânticos num escopo ([data-theme=dark] / prefers-color-scheme), em CSS custom properties, sem tocar em nenhum componente. Cores de destaque ganham +L e −C no escuro; superfícies escuras temperadas, não #000; revalidar todos os contrastes. Persistir a escolha do usuário e evitar o flash com um script inline no head.
Pleno/eng — "Como um token vira código em várias plataformas?"
Uma fonte (.tokens.json DTCG) + Style Dictionary: parsers leem o formato, transforms convertem valores e nomes por plataforma (16px→16dp, hex→UIColor, color.text.muted→--color-text-muted), formats montam o arquivo (CSS vars, ES module, XML, Swift). Roda no CI, publica um pacote versionado que os produtos consomem. outputReferences mantém var() e a cascata no CSS.
Sénior — "Como você projeta a API de um componente de sistema?"
Poucas props ortogonais e previsíveis: variant/size para o que é finito e padronizado; slots/children para o que varia livre; evitar a explosão de booleanas. Estados obrigatórios (default/hover/active/focus-visible/disabled + loading/error onde couber) derivados de tokens semânticos. Acessibilidade embutida (APG para padrões complexos), idealmente sobre um headless. Paridade de nomes com o componente do Figma.
Sénior — "Como você conduz um breaking change nos componentes?"
Deprecar antes de remover (marcar, manter ≥ 1 ciclo, avisar, oferecer alternativa e codemod). Agrupar breaking changes num major com changelog detalhado e guia de migração; automação (jscodeshift para props). Definir a janela de suporte da versão N-1. Comunicar pelos canais do DS, não só no release notes.
Sénior/lead — "Como você mede o sucesso de um design system?"
Cobertura (% da UI em produção que vem do DS, via scanners), adoção por produto ao longo do tempo, nº de detached/overrides no Figma, velocidade (tempo para uma tela nova, antes/depois), qualidade (bugs de a11y/visual reportados devem cair), saúde (tempo de resposta a issues, NPS interno). São os números que sustentam o orçamento.
Armadilha — "O design system é a pasta de componentes no repo"
Isso é uma biblioteca de componentes. Um design system conecta tokens + componentes em design e código com paridade + padrões + guidelines + ferramentas + o time e o processo que mantêm tudo, com roadmap, versionamento e métricas de adoção. Sem o "produto que serve produtos", a pasta apodrece.
10.4 Projetos de portfólio que geram entrevista
- Pipeline de tokens (âncora): um
.tokens.jsonDTCG completo → Style Dictionary → CSS + TS + (mock) mobile, com dark mode e um 2º brand só por overrides, rodando no CI, com contraste testado. README explicando a arquitetura de camadas. - Um componente completo cross design+código: Button ou Field com headless + tokens + todos os estados + a11y (APG) + Storybook + o mesmo componente no Figma com component properties de nomes idênticos + Code Connect.
- Tema / white-label: um gerador que recebe uma cor de marca e deriva a paleta e os semânticos, com validação de contraste e status fixo.
- Estudo de migração: pegar um projeto open source com CSS inconsistente, fazer o inventário (quantos botões/cores distintas), propor a camada de compatibilidade e migrar 2–3 telas, documentando o antes/depois.
- Site de documentação: um mini-DS documentado como produto — visão geral, tokens visualizados, componentes com do's/don'ts, changelog, guia de contribuição.
10.5 Fontes para continuar
- Livros: Design Systems (Alla Kholmatova); Expressive Design Systems (Yesenia Perez-Cruz); Atomic Design (Brad Frost); Laying the Foundations (Andrew Couldwell).
- Web: designsystems.com (Figma); os artigos de Nathan Curtis / EightShapes (tokens, contribuição, medição); the-elements-of-typographic-style-applied… — e sobretudo os design systems públicos com código aberto: Polaris (Shopify), Primer (GitHub), Carbon (IBM), Spectrum (Adobe), Material, Atlassian, Base (Uber).
- Tokens: a spec do Design Tokens Community Group (W3C); a documentação do Style Dictionary e do Tokens Studio; os Figma Variables docs.
- Componentes/a11y: ARIA Authoring Practices Guide (APG); Radix Primitives, React Aria, Ark UI; Storybook docs.
- Nesta trilha: Tipografia, Cor, Layout, Grade & Espaçamento, Logótipos & Lettering; e Figma, Guia de Elementos de Interface, Acessibilidade Digital & WCAG, CSS, Tailwind CSS, Full Stack com TypeScript & Next.js.
Cinco ideias sustentam design systems: (1) é um produto que serve produtos — roadmap, versionamento, suporte, métricas de adoção; (2) tokens em três camadas (primitivo → semântico → componente) são a fundação — componentes só falam com a camada semântica; (3) temas e marcas são a camada semântica reconfigurada, nunca forks; (4) uma fonte de tokens, muitas saídas geradas por um pipeline no CI, e paridade de nomes entre Figma e código; (5) o sistema vence quando acelera os times — se a governança freia mais do que a consistência ajuda, o escopo está errado.