Só existe um botão primário por tela.
Sem ela: a IA cria dois botões cheios disputando a atenção, os dois "certos" pelas cores do sistema, e ninguém sabe qual é a ação principal.
Este é o design system do próprio site, no formato DESIGN.md: o documento que captura cor, tipografia, espaçamento, componentes e o raciocínio, para uma pessoa nova e para a IA que constrói, manterem consistência. Não é vitrine, é o arquivo, renderizado. Troque o tema no topo e a página inteira re-tematiza a partir dos tokens.
Um canvas de papel quase branco ritmado por zonas full-bleed grafite e preto. A voltagem vem de um azul elétrico usado com restrição, contra tinta preta e uma voz técnica monoespaçada. A tipografia é uma família só, Switzer, em duas vozes: um display fino e um corpo humanista.
Não existe um segundo acento. O azul primary marca a ação principal e o estado ativo, nada além disso. As superfícies carregam o ritmo claro para escuro; o texto corre em três pesos de tinta. O tema escuro espelha cada token e é uma troca na raiz, não uma segunda versão de cada tela.
primary#2B49FF5,75:1 · texto sobre papelprimary-active#1E38D87,70:1 · texto sobre papelprimary-soft#EDEFFF17,34:1 · tinta sobre elecanvas#FAFAFA18,97:1 · tinta sobre elesurface-soft#F4F4F618,02:1 · tinta sobre elesurface-graphite#11111617,14:1 · claro sobre elesurface-black#06060818,43:1 · claro sobre eleink#0A0A0A18,97:1 · sobre papelbody#6E6E704,87:1 · sobre papelsuccess#107C415,05:1 · sobre papeldanger#CD2B315,05:1 · sobre papelO token vive em três camadas. A interface e a IA consomem o semântico, nunca o primitivo. É isso que faz o tema escuro ser uma troca na camada semântica, e não uma segunda versão de cada tela, e faz uma marca nova herdar o sistema trocando só a base.
O valor cru, sem opinião de uso.
O papel que o valor cumpre. Aponta para blue-600. É a camada que a interface consome.
O token amarrado a um lugar. Aponta para primary.
120ms · press, hover220ms · reveal, estado420ms · superfíciecubic-bezier(.32,.72,0,1)damping .82 · response .4≤16px · interrompívelSwitzer na interface inteira: um display fino em peso 200 com tracking negativo, e um corpo humanista em 400. Uma face monoespaçada carrega eyebrows, números e legendas, a voz de especificação.
A escala de espaçamento parte de 4px. O ritmo de seção e a goteira são fluidos (clamp), então respiram no desktop e apertam no mobile. O espaço em branco é estrutural, não sobra.
Conteúdo centralizado, máximo entre 1180 e 1680px. Corpo de texto limita em ~62ch. Uma coluna por padrão; múltiplas só onde a relação é real.
Goteira clamp(20px, 4.5vw, 64px), seção clamp(64px, 10vh, 120px). A densidade reduz nas telas menores, não encolhe por igual.
Bordas de fio mais sombras longas, suaves e de baixa opacidade. O peso do material codifica hierarquia: superfície maior, blur mais forte e sombra mais profunda. Nunca empilhe uma superfície translúcida sobre outra. Profundidade decorativa não existe, por regra.
1px hairlineshadow -22px / .28shadow -40px / .5O raio de borda cresce com o tamanho do elemento: apertado nos controles, generoso nos painéis, pílula na navegação. Chrome de produto real sobre ilustração abstrata; quando uma imagem não justifica o lugar, vira índice de texto.
Cada componente aparece renderizado, com a especificação em mono logo abaixo, referenciando o token. É o mesmo componente que roda no site, re-tematizado com o resto da página.
36px só em superfície de mouse. O alvo de toque mínimo continua 44px, e no celular a densidade compacta não se aplica.
.navmini{display:flex;align-items:center;gap:10px}
.navmini .pl{height:40px;border-radius:999px}
.navmini .ct{width:40px;height:40px;border-radius:50%}.b{min-height:44px;border-radius:10px;padding:11px 17px;
font:500 13.5px var(--f);
transition:background-color 120ms ease-out}
.b.primary{background:var(--acc);color:#fff}.fld label{display:block;font-size:12px;margin-bottom:7px}
.fld input{min-height:44px;border-radius:10px;padding:11px 14px}
.fld input:focus{border-color:var(--acc);
box-shadow:0 0 0 4px var(--acc-soft)}.badge{border-radius:999px;padding:5px 12px;
font:11px var(--mono);letter-spacing:.04em}
.badge.ok{color:var(--ok-ink);
background:color-mix(in srgb,var(--ok) 8%,transparent)}.seg{border-radius:999px;padding:3px}
.seg button{min-height:36px;font:10.5px var(--mono)}
.seg button[aria-pressed="true"]{background:var(--card);
box-shadow:0 2px 8px -4px rgba(10,10,40,.3)}.card{border:1px solid var(--line);border-radius:14px;
background:var(--card);padding:18px;
box-shadow:0 14px 34px -22px rgba(10,10,40,.28)}.toast{background:var(--ink);color:var(--paper);
border-radius:11px;padding:8px 12px;font-size:11.5px;
box-shadow:0 10px 26px -14px rgba(10,10,40,.5)}a{color:var(--acc);font-weight:500;text-decoration:none;
border-bottom:1px solid color-mix(in srgb,var(--acc) 40%,transparent);
padding-bottom:2px}.row{display:flex;justify-content:space-between;
padding:10px 14px;font-size:13px}
.row .v{font-variant-numeric:tabular-nums;
font-feature-settings:"tnum"}.win{background:#0B0B0F;border-radius:12px;
font:11.5px/1.7 var(--mono);color:#C9CBE0}
.win .k{color:#6E8BFF}| estado | token | valor | a regra |
|---|---|---|---|
| Repouso | {colors.primary} | #2B49FF · #6E8BFF no escuro | Branco sobre primary mede 6,0:1, acima do mínimo AA |
| Hover | {colors.primary-active} | #1E38D8 | Só a superfície muda. Sem deslocar e sem crescer |
| Foco | {colors.primary-soft} | anel de 4px | Visível ao teclado, sem depender do mouse |
| Desabilitado | opacidade | 45% · dessaturação 25% | Não recebe foco, e o rótulo continua legível |
| Altura padrão | alvo de toque | 44px | Vale em toda superfície. É a regra que a página publica |
| Altura compacta | alvo denso | 36px | Só em superfície de mouse. No celular não se aplica |
| Raio | raio de controle | 10px | O controle usa o raio menor da escala |
| Transição | duração curta | 120ms · ease-out | Só cor e anel. Transformação só quando o gesto pede |
Componente sem estado documentado empurra a decisão para quem implementa, e é onde a IA e o júnior mais erram. Todo componente interativo carrega a matriz; toda superfície de dado carrega os estados de tela. Ao vivo.
Os tokens dizem o que as coisas são. Estas regras dizem quando usar cada uma, em português claro, ao lado dos tokens. É a camada que um colega novo, ou uma IA montando uma tela, erra sem ser avisado. Cada regra elimina uma decisão errada; ao lado, a prova do que quebra sem ela.
Sem ela: a IA cria dois botões cheios disputando a atenção, os dois "certos" pelas cores do sistema, e ninguém sabe qual é a ação principal.
Sem ela: "Excluir conta" ganha o mesmo peso visual de "Salvar", e o erro irreversível fica a um toque de distância.
Sem ela: qualquer aviso rotineiro vira uma janela no meio da tela e interrompe quem estava no meio de uma tarefa.
O sistema documenta o contraste por par de token e não deixa texto significativo abaixo de AA (WCAG 4.5:1). A régua abaixo é o próprio sistema, medido.
ink sobre canvasprimary sobre canvasbody e faint sobre canvasbody e faint sobre a pílula, a superfície mais escura do tema clarobranco sobre primaryprimary do tema escuro sobre o canvas escurook sobre a superfície mais escura do tema clarodanger sobre a superfície mais escura do tema clarook do tema escuro sobre a superfície mais escuradanger do tema escuro sobre a superfície mais escurafaint-decorative sobre canvasA hierarquia do texto secundário vem do registro (mono, caixa alta, tracking), não de contraste abaixo de AA. O eyebrow lê como secundário porque muda de voz, não porque some. Os tokens de texto deixaram de ser opacidade e viraram hex: a opacidade resolvia em 4.48:1, meio ponto abaixo do mínimo, enquanto a documentação registrava a aproximação que passava. Medido e documentado passaram a ser o mesmo valor.
Foco visível obrigatório: anel de focus-ring, nunca só cor, via :focus-visible. Alvo de toque ≥44px no mobile. Reduced-motion troca slide e mola por cross-fade; reduced-transparency deixa os materiais sólidos.
A informação se adapta por breakpoint. No mobile e tablet, o meta lateral some, o grafo de conhecimento vira texto (ruído quando espremido), e a nav ganha uma borda de rolagem fosca para o conteúdo ler por baixo. Alvos de toque ficam sempre ≥44px.
Token antes de valor. Todo componente novo documenta a regra de comportamento, não só a aparência. Movimento é desenhado junto com os pixels. Quando um valor é questionado, ele é defensável a partir deste documento.