mateusfb.aibrand.mateusfb.com
Design system

Duas cores e uma escala.

A régua da marca mateusfb.ai, dos tokens aos componentes: o que vale no site, no carrossel e em qualquer peça nova. Os valores desta página saem dos arquivos do projeto no momento do build, e os componentes são os mesmos que o site usa, então ela não tem como atrasar em relação ao código.

Preto e branco estritoGeistCanto vivoBorda tracejada
01Cor

Duas, e elas trocam de lugar.

Não existe azul de link, vermelho de erro nem verde de sucesso. Estado se mostra por inversão, por peso ou por posição. Cinza é opacidade de fg, nunca cor nova.

bg
#000
tema
escuro, o site inteiro
fg
#fff
contraste
21,0 : 1
A escada de cinza
fg21,0
fg/8514,8
fg/7010,0
fg/607,4
fg/454,4
fg/403,7
fg/252,0
fg/201,7
fg/151,4
fg/101,2

O piso escrito: corpo de texto nunca abaixo de 60%, metadado nunca abaixo de 40%. O fg/45 dá 4,4 para 1, logo abaixo dos 4,5 da WCAG AA, e fica assim de propósito, porque nada que se leia como texto corrido usa esse degrau. O fg/15 dá 1,4 para 1 porque a borda tracejada é textura: quem ancora o cartão para o olho são as marcas de canto, em fg cheio.

O que a cor NÃO faz aqui
Selecionado

Inverte: fundo fg, letra bg.

Erro

Borda em fg cheio, ícone de alerta e a palavra. Nunca só um tom.

Situação

Ícone mais palavra. A bolinha verde não existe neste sistema.

02Tipografia

Geist, e oito degraus.

Duas famílias, as duas do projeto. Tamanho cru no className reprova na catraca: a hierarquia sai da escala, não de um número escolhido na hora.

A escala
Construindo com agentes
text-display54pxaltura 1.1letra -2pxpeso 400
O que estou construindo
text-subhead48pxaltura 1.1letra -1pxpeso 400
Todo mundo prompta. Eu entrego.
text-pullquote36pxaltura 1.1letra -.5pxpeso 400
O gate que não sabe se provar
text-post-title36pxaltura 1.1letra -.6pxpeso 500
Ferramentas e produtos, entregues em público.
text-body24pxaltura 1.2peso 400
Notas curtas e práticas sobre construir com agentes.
text-caption14pxaltura 1.5peso 400
Ver projetos
text-button14pxaltura 1.5peso 500
seu@email.com
text-field16pxaltura 1.5peso 500
01 · Projetos
text-eyebrow10pxaltura 1letra 1pxpeso 400mono
Abaixo de 768px
text-display
40px
text-subhead
34px
text-pullquote
28px
text-post-title
26px
text-body
18px

Cinco degraus encolhem no telefone. Caption, button, field e eyebrow não mudam: eles já são o piso. O text-field existe por causa do Safari do iPhone, que dá zoom ao focar um campo abaixo de 16px.

As duas famílias
Geist, peso 400 e 500Sans: tudo que se lê
Geist Mono, peso 400Mono: eyebrow, etiqueta, número, código e o corpo do post

Geist e Geist Mono vêm do pacote do projeto e são servidas junto com a página. Nunca puxe uma fonte do Google Fonts no site.

Sem linha órfã
O defeito

Frase que quebra em duas linhas e deixa UMA palavra sozinha embaixo. Ele não aparece no código: aparece na largura da tela de quem lê, e some quando a janela muda de tamanho, que é o que o faz passar despercebido.

A regra

Título distribui as linhas com `text-wrap: balance`; texto corrido puxa a última palavra para cima com `text-wrap: pretty`. Os dois valem para o site inteiro, na folha global. Onde a quebra é decisão editorial, como a manchete de um post aprovada palavra por palavra, ela continua explícita no conteúdo.

título
text-wrap: balance
texto corrido
text-wrap: pretty
medida do apoio
448px, cerca de 70 caracteres
medida do post
630px, cerca de 70 caracteres em mono
copy aprovada
quebra explícita no conteúdo

A medida do texto de apoio é o token `medida-nota`, 448px, e não um valor em `ch`: o `ch` do CSS é a largura do ALGARISMO ZERO, 9,3px nesta fonte, enquanto a letra média mede 6,4px. Com 58ch as notas saíam com 84 caracteres por linha. Medido no navegador, contando caractere por linha.

Texto longo: o bloco de notas

O gate que não sabe se provar

Todo gate nasce com a mutação declarada: um defeito real, injetado no código de verdade, que ele tem que pegar. Gate que fica verde com o defeito dentro é um gate quebrado, e quem acusa isso é o meta-gate.

A pauta passa embaixo do texto sem cortar letra nenhuma.
pauta
28px
medida
630px
corpo
15px mono
cor do corpo
fg/85

A regra que faz funcionar é uma só: todo espaçamento vertical é múltiplo da pauta. Um margin fora do múltiplo desalinha todo o texto abaixo, e o efeito de papel pautado morre.

03Espaço

Medidas com nome, não uma escala de oito.

Cada uma tem um trabalho, e juntas cobrem o site inteiro. Estão todas em app/tokens.css, e esta página lê de lá.

As medidas
container
1512px
gutter
120px
frame
30px
cell-gap
9px
nav-h
46px
radius-campo
10px
Para que serve cada uma
container

Largura máxima do conteúdo.

gutter

Respiro lateral em desktop. No telefone, 24px.

frame

Declarado e não usado em lugar nenhum hoje.

cell-gap

O vão entre linhas de post: coladas, elas leem como pilha.

nav-h

Altura da navegação, usada em calc para centrar página.

radius-campo

O único raio que não é pílula nem zero: o canto da área de texto.

A grade
1
2
3
4
5
6
7
8

Uma coluna no telefone, duas no tablet, três ou quatro no desktop. O conteúdo passa sempre pelo Container, e o respiro lateral é o gutter: nenhuma peça encosta no corte da tela.

04Traço

Canto vivo, e uma linha tracejada.

O padrão é raio zero. Arredondar é exceção, e cada exceção tem motivo. Separar é trabalho da borda tracejada, nunca de sombra.

Raio
0o padrão
radius-campoárea de texto
fullbotão e pílula
Traço e sombra
1px tracejado fg/15: superfície
1px cheio fg/20: controle
1px cheio fg/15: divisor

A única sombra do sistema é o brilho interno da pílula de vidro, e ela existe para dar volume ao vidro, não para separar objeto.

05Movimento

Duas curvas, quatro durações.

Easing e duração saem de lib/motion.ts, nunca inventados na hora. Com movimento reduzido tudo cai para quase zero, e a peça continua legível e no mesmo lugar.

EASE_OUT_QUINTcubic-bezier(0.22, 1, 0.36, 1)Entrada de qualquer coisa. O padrão.
EASE_IN_OUTcubic-bezier(0.65, 0, 0.35, 1)O que sai e volta, como a respiração da marca.
Tocando
Entrada de seção700ms · ease-out-quint
Troca de estado360ms · ease-out-quint
Hover e foco200ms · ease-out-quint
A marca respirandoA marca respira em 8s, sem parar.

A entrada escalona por delay de 80ms, nunca por duração diferente: duas coisas que entram juntas têm a mesma curva, e o que muda é quando cada uma começa.

Durações
200ms
0.2s · hover, foco, troca de cor
360ms
0.36s · menu, troca de estado
600ms
0.6s · marca voltando ao lugar
700ms
0.7s · entrada de seção

A entrada de seção é o Reveal: opacidade 0 para 1 com y de 12px para 0, disparando com margem de -10% e uma vez só. Rolar para cima e descer de novo não re-anima nada. Botão não se move no hover: quem muda é a cor, e as letras embaralham.

06Ícones

132 ícones, um traço só.

Grade de 24 e traço 1,5, o mesmo dos planos da marca. Três formas de tinta, e só três: contorno, preenchido para o glifo que só existe como massa, e o ponto de ênfase onde o traço não faz pingo.

Marca e forma · 6
losangolosango
losango-vaziolosango-vazio
pilhapilha
quadradoquadrado
circulocirculo
triangulotriangulo
Direção · 20
seta-direitaseta-direita
seta-esquerdaseta-esquerda
seta-cimaseta-cima
seta-baixoseta-baixo
seta-diagonalseta-diagonal
chevron-direitachevron-direita
chevron-esquerdachevron-esquerda
chevron-cimachevron-cima
chevron-baixochevron-baixo
primeiraprimeira
ultimaultima
desfazerdesfazer
refazerrefazer
atualizaratualizar
sincronizarsincronizar
expandirexpandir
recolherrecolher
tela-cheiatela-cheia
movermover
arrastararrastar
Interface · 17
menumenu
fecharfechar
maismais
menosmenos
conferidoconferido
opcoesopcoes
opcoes-verticalopcoes-vertical
gradegrade
listalista
barra-lateralbarra-lateral
colunascolunas
filtrarfiltrar
ordenarordenar
buscabusca
externoexterno
olhoolho
olho-fechadoolho-fechado
Ação · 13
editareditar
apagarapagar
copiarcopiar
cortarcortar
anexaranexar
enviarenviar
compartilharcompartilhar
baixarbaixar
subirsubir
imprimirimprimir
marcadormarcador
etiquetaetiqueta
favoritofavorito
Estado · 15
alertaalerta
informacaoinformacao
perguntapergunta
sucessosucesso
erroerro
proibidoproibido
carregandocarregando
sinosino
sino-mudosino-mudo
atividadeatividade
raioraio
escudoescudo
cadeadocadeado
cadeado-abertocadeado-aberto
chavechave
Tempo e lugar · 7
relogiorelogio
historicohistorico
calendariocalendario
ampulhetaampulheta
locallocal
mundomundo
bussolabussola
Conteúdo · 11
notanota
pastapasta
imagemimagem
videovideo
cameracamera
somsom
mudomudo
microfonemicrofone
livrolivro
caixacaixa
cartaocartao
Dado · 5
grafico-linhagrafico-linha
grafico-barrasgrafico-barras
grafico-radargrafico-radar
tabelatabela
painelpainel
Pessoas · 9
pessoapessoa
pessoaspessoas
adicionar-pessoaadicionar-pessoa
balaobalao
baloesbaloes
emailemail
telefonetelefone
respostaresposta
instagraminstagram
Mídia · 7
tocartocar
pausarpausar
pararparar
anterioranterior
proximoproximo
repetirrepetir
aleatorioaleatorio
Construção · 14
codigocodigo
terminalterminal
repositoriorepositorio
commitcommit
bugbug
engrenagemengrenagem
ferramentaferramenta
servidorservidor
banco-de-dadosbanco-de-dados
cpucpu
nuvemnuvem
nuvem-sobenuvem-sobe
wifiwifi
bateriabateria
Texto · 8
negritonegrito
italicoitalico
sublinhadosublinhado
lista-marcadalista-marcada
citacaocitacao
linklink
titulotitulo
alinhar-esquerdaalinhar-esquerda
Tamanhos
seta a 16px16
seta a 20px20
seta a 24px24
seta a 32px32
07Poeira

O jeito desta marca desenhar objeto.

Sólido isométrico branco, sem contorno nenhum, existindo só pela densidade do ponto, com a aresta de cima acesa e a borda se desfazendo em pó. É a mesma linguagem no hero, nos tópicos de projeto e na capa de cada post, e até aqui ela não tinha nome.

As composições que já existem no site
web.ai · o design e a página
monitorpilot · três telas, uma acesa
cove · a tampa e a ilha
kit · a grade dos agentes

São os sólidos DE VERDADE, lidos de social/instagram/capa.mjs, e o movimento é o DO HERO, com os números dele: cada ponto cintila sozinho, o campo respira a cada 6s, e o cursor empurra quem está num raio de 140px com um redemoinho de 20°, que volta com inércia (0,10 entrando, 0,05 soltando, então o rastro dura mais que a ida). Passe o cursor devagar por cima. Com movimento reduzido, fica um quadro parado.

A rendição e a peça
a rendição, viva
Capa publicada do carrossel do web.ai
A peça, em PNG

À esquerda, o que esta folha desenha: o mesmo campo de tons da capa, ditherizado em canvas e animado com a física do hero. À direita, o PNG publicado. A diferença que sobra é o grão: a capa de verdade ditheriza com célula de 2,2px num quadro de 918, e aqui a célula é de 3px numa peça três vezes menor.

As quatro regras
Projeção 2:1, sempre

A mesma dos planos da marca. Nada de perspectiva e nada de ponto de fuga: a laje é vista de cima e de lado ao mesmo tempo.

Sem contorno

A forma existe só pela densidade do ponto: topo claro, lateral direita no meio, lateral esquerda escura. Desenhar a silhueta com um traço vira ícone com textura dentro.

Aresta acesa

A quina do topo ganha uma faixa mais densa. É ela que faz o volume ler como volume, e não como mancha.

Poeira na borda

O objeto não termina numa linha: ele se desfaz em pontos soltos que somem. É daí que vem o nome.

Onde ela vive, e como é feita em cada lugar
hero do site
PNG de 1 bit lido pixel a pixel, cada ponto branco vira partícula em WebGL
tópico de projeto
malha em three.js passada por um shader de dither, girando 0,25 rad/s
capa do post
geometria em canvas, ditherizada na hora de rasterizar o slide
formato da capa
918 por 540, dentro da moldura do slide
esta página
padrão de pontos em CSS, uma rendição
Por que três implementações

Cada lugar tem uma restrição diferente. O hero precisa de movimento contínuo sem custar processamento por quadro, então lê uma imagem pronta. O tópico precisa girar de verdade, então é geometria em 3D. A capa precisa virar PNG num navegador sem cabeça e custar R$0, então nasce em canvas.

Esta folha desenha a quarta versão, em CSS, porque especificação não carrega WebGL e não vale 40 KB de círculos em SVG.

O que as três preservam é o que decide: projeção, ordem dos tons, aresta acesa e dispersão. O resto é o meio: partícula viva no hero, giro lento no tópico, pixel congelado na capa.

08Botão

Dois, e nada mais.

Sólido para a ação principal, contorno para a secundária. Um sólido por tela, no máximo. O rótulo diz o que acontece ao clicar, nunca clique aqui.

Variantes e estados
desabilitado
botão de texto

Passe o cursor: o sólido inverte em 200ms e as letras embaralham da esquerda para a direita. O contorno não muda nada além das letras. Navegue por tab: o foco é um contorno de 1px em fg, afastado 4px, e ele é o mesmo em todo o sistema.

Medidas
altura
40px (10px de respiro vertical)
respiro lateral
20px
raio
full
texto
text-button, peso 500
transição
cor, 200ms
O que ele vira

Com href interno sai um Link do Next. Com http, mailto ou tel sai um a, e só http abre em aba nova. Sem href sai um button, cujo tipo padrão é button e não envia formulário.

A borda existe sempre, inclusive no sólido, onde é branca sobre branco. Se nascesse no hover, 1px empurraria o layout naquele instante.

09Campo

Um campo, e o erro sem cor.

A mesma linha de classes que o formulário da comunidade, a senha do painel e o editor de notas escreviam cada um à sua maneira. Erro se marca por borda cheia, ícone e palavra, porque vermelho não existe aqui.

Estados
Só para mandar o convite. Nada de lista.
Esse endereço não parece completo.
Área de texto

A área de texto é a única coisa do sistema com raio que não é pílula nem zero: radius-campo, 10px. Ela é mono porque o que se escreve ali é Markdown.

10Escolha

Marcar, escolher, ligar.

Os três usam o controle nativo escondido com sr-only, nunca display none: foco, toque, tecla de espaço e leitor de tela continuam sendo os do navegador, e só a aparência é nossa.

Marcar e escolher
11Etiqueta

Filtro, situação e progresso.

Selecionado é inversão. Situação é ícone mais palavra, porque a bolinha colorida não existe neste sistema e não fazia falta.

Etiqueta
TodosEntreguesEm construçãoKits
Situação
EntregueEm andamentoParadoA capa não bate com o gerador
Progresso
Gates verdes13/13
Mutações provadas20/20
Rotas dentro da catraca de peso24/26

Trilho em fg/15, preenchimento em fg cheio. O número vai em mono com tabular-nums, senão a coluna dança a cada atualização.

12Marca

Três planos empilhados.

Projeção isométrica: o de cima sólido, os dois de baixo só contorno. Desenho 2D que lê como 3D, e que abstrai camadas construindo alguma coisa.

Tamanhos
Marca a 16px16px
Marca a 32px32px
Marca a 128px128px
Marca animadarespirando
Assinatura
mateusfb.aimateusfb.aimateusfb.ai
A geometria
viewBox
32 x 32
centros
cy 10,5 / 16 / 21,5
meia largura
10
meia altura
5
traço
1,5
tamanho mínimo
16px
respiro
a altura de um plano

Nunca: mudar a proporção 2 para 1 do losango, preencher os planos de baixo, acrescentar arestas laterais, rotacionar, inclinar, aplicar cor, gradiente ou sombra, ou juntar a marca a uma letra.

Os arquivos
14Mensagem

Aviso, estado vazio e tabela.

Três peças que só aparecem quando algo sai do caminho feliz, e por isso costumam ser as menos cuidadas de um sistema. Aqui elas usam o mesmo cartão tracejado do resto.

Aviso

O grupo abre em breve.

Mando o convite no seu e-mail assim que abrir.

Travessão no texto.

O repositório não aceita travessão. Duas linhas precisam de troca.

Nota no repositório.

O site atualiza em cerca de um minuto.
Estado vazio

Ainda sem notas.

Quando a primeira sair, ela aparece aqui e no feed em português e em inglês.

15Cabeçalho

Como uma seção começa.

Número, eyebrow, título e um parágrafo de apoio na coluna ao lado. É o que dá ritmo à home inteira, e o número é âncora, não enfeite.

SectionHeader
03Bloco de notas

Notas de quem constrói

Notas curtas e práticas sobre construir com agentes.

Eyebrow
01Projetos
04Comunidade
Superfície
RepousoDashedCard
AtivoInverte, não escurece
16Gráficos

Dado sem cor nenhuma.

Série não se distingue por cor aqui, porque não há cor: se distingue por traço e por rótulo direto. O que parece limitação é a versão que funciona impressa, no escuro e para quem não separa matiz.

Linha: o peso do JS das rotas de texto
07941494antesdepois do perfhojemedidoantes: 14941494depois do perf: 772772hoje: 794794teto

Três medições reais do mesmo dia: 1494 KB quando o three.js entrava no bundle inicial de toda rota, 772 depois que ele saiu, 794 depois que a main trouxe o next/image no bloco de retrato. O teto é a catraca, em traço apagado porque é referência, não medida.

Barras: as rotas mais pesadas
  • en852 KB
  • en/about828 KB
  • en/projects817 KB
  • en/brand814 KB
  • marca739 KB
  • _not-found699 KB

Horizontal porque rótulo de categoria é texto, e texto deitado se lê. O valor vai na ponta da barra, nunca num eixo que obriga a medir com o olho.

Malha: frequência
0251003862014973002511610374295
há 30 diashoje
menosmais

Uma célula por dia, cinco degraus de tinta. É o gráfico mais honesto que um sistema sem cor tem para frequência, porque densidade é exatamente o que a escada de cinza sabe dizer, e é a mesma linguagem do dither das capas. Os dados aqui são um exemplo.

Radar: o perfil de cada camada desta página
Fundamentos: 21Fundamentos 21Átomos: 13Átomos 13Moléculas: 9Moléculas 9Dados: 15Dados 15Organismos: 9Organismos 9Padrões: 5Padrões 5FundamentosÁtomosMoléculasDadosOrganismosPadrões

Radar compara PERFIL, não valor: o olho compara área e formato bem, e ângulo mal. Se a pergunta é quanto vale um eixo, isso é barra. Até dois perfis no mesmo desenho, e o segundo entra tracejado e sem preenchimento, senão uma área esconde a outra. Os números aqui são contados dos arquivos que compõem esta página.

Colunas: a escala tipográfica
544836241414163610
text-displaytext-eyebrow

A última coluna em fg cheio e o resto em fg/25: a cheia é o agora, ou o degrau em foco, e é a única coisa que precisa saltar. Sem eixo vertical, porque o valor que importa vai escrito. Aqui as colunas são os tamanhos da escala, lidos de app/globals.css.

Distribuição: o JS por família de rota
notas · 32%home · 11%about · 11%projects · 11%brand · 11%ds · 11%erro e 404 · 8%design system · 5%
  • notas32%
  • home11%
  • about11%
  • projects11%
  • brand11%
  • ds11%
  • erro e 4048%
  • design system5%

Uma barra de 100% com as partes em degraus de tinta, e a legenda logo abaixo NA MESMA ORDEM, com o número junto. É a exceção da regra de rotular direto: parte pequena não cabe rótulo dentro. O que continua proibido é a legenda que só dá a cor e manda você adivinhar o tamanho.

Mapa de calor: quando as coisas acontecem
seg
seg · 0seg · 1seg · 4seg · 9seg · 6seg · 2
ter
ter · 0ter · 0ter · 3ter · 7ter · 8ter · 3
qua
qua · 1qua · 2qua · 6qua · 11qua · 5qua · 1
qui
qui · 0qui · 1qui · 2qui · 5qui · 9qui · 4
sex
sex · 0sex · 0sex · 1sex · 3sex · 2sex · 0
0h8h16h24h
menosmais

Uma linha por dia, uma célula por faixa de hora. Serve para achar PADRÃO, a hora em que sempre acontece, e nunca para ler o valor de uma célula: para isso existe a tabela. Os dados aqui são um exemplo.

A régua dos gráficos
Série sem cor

Cheio, tracejado, pontilhado, e o nome no fim da linha. Legenda com quadradinho obriga o olho a ir e voltar.

No máximo três séries

Acima disso, vários gráficos pequenos lado a lado, e não mais um traço no mesmo.

Comparação em fg/25

O período anterior e a meta ficam apagados. O agora fica em fg cheio.

Ênfase no último ponto

Ponto cheio no fim, que é onde o olho procura o agora.

Rótulo que existe

Todo valor no eixo é um valor que o gráfico alcança de verdade.

Hachura é estimativa

Número que ninguém mediu não pode parecer medido.

17Tabela

Coluna que não dança.

Número alinha à direita e usa tabular-nums. Sem isso a coluna se mexe a cada dígito, e a comparação vertical, que é o único motivo de existir uma tabela, deixa de funcionar.

Com total e coluna de número
O teto de cada rota de texto, lido de scripts/gates/peso-por-rota.txt.
RotaSituaçãoJS
en/aboutacima da média828 KB
en/notasacima da média814 KB
en/notas/building-with-agentsacima da média814 KB
en/notas/hello-worldacima da média814 KB
pt/aboutacima da média828 KB
pt/notasacima da média814 KB
pt/notas/building-with-agentsacima da média814 KB
pt/notas/hello-worldacima da média814 KB
Média de todas as rotas796 KB
Compacta
GateProva
so-preto-e-brancocor cromática injetada
escala-tipograficatamanho cru novo
peso-do-bundleimport estático de biblioteca pesada
Sem linha nenhuma

Nenhuma rota acima do teto.

Quando alguma passar, ela aparece aqui com o excesso em KB.

Tabela vazia continua sendo superfície do sistema, não um vão. O estado vazio diz o que fazer, e não só que não há nada.

A régua da tabela
cabeçalho
eyebrow mono, fg/60, peso 400
primeira coluna
fg cheio: é ela que identifica a linha
número
à direita, tabular-nums
divisória
tracejada fg/15, a mesma dos cartões
total
linha contínua fg/40 e texto em fg
rolagem
no container da tabela, nunca no corpo da página
18Painel

Lido de relance, não de cima a baixo.

Painel não é página de leitura: o resumo vem antes do detalhe, o que precisa de atenção se enxerga sem contar número, e todo bloco tem o mesmo topo, o mesmo respiro e a ação no mesmo canto.

O indicador, e as quatro formas dele
Gatesrodam todos, sempre
Verdes
32/32
  • com mutação declarada32
  • rodam em paralelo31
  • exclusivos, em série1
JS das rotas de textomedido hoje
Hoje+22 KBdesde a manhã
794 KB
Subiu porque a main trouxe o next/image no bloco de retrato. A catraca acompanhou, com a causa escrita.
Rotascom teto registrado
catraca
Na catraca
19 rotas
554699739814814814814814814814814814814817817828828852852
Média de 796 KB de JS entre elas. Rota sem linha na catraca não reprova por peso, só pela lista de bibliotecas pesadas.
Situaçãoo que precisa de atenção
Aberto
1 pendência
Build, testes e preto e brancoEscala tipográfica18 níveis de cinza, sem catraca

Rótulo e período em cima, número grande, e embaixo o detalhe: a lista que abre o número, a série que mostra a forma, ou a situação. A variação NÃO TEM COR. Num painel colorido, verde e vermelho dizem bom e ruim sem ninguém escrever nada, e isso é falso metade das vezes: erro que sobe é ruim, custo que desce é bom, e o mesmo verde estaria nos dois. A seta diz a direção; o rótulo diz o que ela significa.

O painel montado
Peso por rotauma rota por valor distinto
  • en852 KB
  • en/about828 KB
  • en/projects817 KB
  • en/brand814 KB
  • marca739 KB
  • _not-found699 KB
DistribuiçãoJS por família de rota
notas · 32%home · 11%about · 11%projects · 11%brand · 11%ds · 11%erro e 404 · 8%design system · 5%
  • notas32%
  • home11%
  • about11%
  • projects11%
  • brand11%
  • ds11%
  • erro e 4048%
  • design system5%
TendênciaJS das rotas de texto
Ver o gráfico
794 KB
Frequênciaexemplo, para mostrar a malha
0251003862014973002511610374295

Os mesmos blocos numa grade de duas colunas, com o gráfico largo ocupando as duas. Todo número aqui sai de um arquivo do repositório; onde entra exemplo, a legenda diz que é exemplo.

A régua do painel
Resumo antes do detalhe

O número que responde a pergunta vem primeiro; o gráfico que explica vem depois.

Estado na forma

Ícone e palavra, nunca um tom. Quem precisa de atenção se enxerga sem ler o número.

Densidade constante

Todo bloco com o mesmo topo, o mesmo respiro e a ação no mesmo canto.

Ação em texto

A ação de um bloco é um link em eyebrow, não um botão: botão cheio compete com o número, que é o que a pessoa veio ver.

Grade de duas colunas

Uma no telefone. O gráfico de linha ocupa duas, senão vira garrancho.

Nada pisca

Atualização não se anuncia com animação: o painel fica parado e o número troca.

Número com fonte

Todo valor sai de um arquivo do repositório, e o exemplo que não sai diz que é exemplo.

19Listagem

Cartão de projeto e linha de post.

As duas listagens do site. O cartão é uma grade de objetos iguais; a linha de post é uma pilha, e por isso o vão entre elas é o cell-gap, e não o respiro de um cartão.

Cartão de projeto
TypeScript

web.ai

Uma página que se monta sozinha.

12 estrelas
SwiftEm andamento

monitorpilot

Três telas, uma rampa de brilho.

12 estrelas
Swift

cove

O notch vira console de música.

12 estrelas

components/sections/ProjectCard.tsx é o componente real. O cartão inteiro é o link, e a etiqueta de em construção é a inversão, no alto à direita.

Linha de post
18 set 2026O gate que não sabe se provarToda cerca nasce com o defeito que ela promete pegar.Ler
12 set 2026Cobertura é globalPor que a capa virou névoa quando eu mirei mais pontos.Ler

components/sections/PostRow.tsx é o componente real. Uma só coisa domina: o título. Data e resumo são apoio, resolvido por tamanho, peso e opacidade, nunca por cor, e o Ler é metadado, porque o link é a linha inteira.

20Formulário

O formulário inteiro, do rótulo ao erro.

Rótulo em eyebrow, campo, dica ou erro embaixo. A ação principal é sólida e fica à esquerda; a saída é um botão de texto em fg/45, não um segundo botão disputando atenção.

Entrar na comunidade

Entrar na comunidade

Preencha e eu te levo pro Vibe100Coding Club.

Seus dados estão seguros e não são compartilhados.

21Post

A mesma marca, em 1080 por 1440.

Um carrossel por projeto, quatro slides: capa, dois de como funciona com dois itens cada, e a chamada. Mais uma peça estática, para quando o post é um só.

As peças de verdade, como saem do gerador
01 capa do carrossel do web.ai
01 capa
02 como funciona do carrossel do web.ai
02 como funciona
03 como funciona do carrossel do web.ai
03 como funciona
04 chamada do carrossel do web.ai
04 chamada
peça única do carrossel do web.ai
peça única

Estes são os PNGs publicados, servidos de /social/, byte a byte iguais aos que o render.sh produz. Uma folha de especificação que redesenha a peça à mão nunca fica igual e envelhece sozinha: a peça é a peça.

A mesma peça, nos dois fundos
capa do web.ai, fundo escurocapa do web.ai, fundo claro

Cada peça é renderizada nos dois fundos, o que dá 40 PNGs: quatro projetos, cinco peças, dois temas. O fundo é escolhido por post, e é isso que dá xadrez na grade do perfil.

O esqueleto anotado
web.aiTypeScript01 / 04

Seu design ou o seusite transformado emJSON do Elementor,nativo e editável.

mateusfb.aiArrasta →
fundo
grade de 4 por 6, só na capa e na peça única
cantos
as quatro marcas, 16px, traço 1,6
topo
projeto e linguagem à esquerda, contador à direita
artefato
a Poeira do projeto, 918 por 540
manchete
subhead 84px, quebra explícita, 84px de respiro
sobra
vai toda para o pé, e não para o meio
rodapé
assinatura à esquerda, o que fazer à direita

Isto NÃO é a peça, é o diagrama dela: os blocos que o gerador monta, na ordem em que ele monta, com a copy real lida de dados.mjs. Serve para dizer o que entra em cada faixa, e a peça ao lado é que diz como fica.

A linha cai no fundo claro
moldura, fundo escuro
15%
moldura, fundo claro
11%
linha forte
30% e 22%
grade
50% e 38%

Medido no PNG, não estimado: preto a 15% sobre branco pesa mais que branco a 15% sobre preto, e a moldura tem que sussurrar nos dois fundos. É a única coisa que o tema claro NÃO faz por inversão simples.

A capa
A cena do hero: pilha isométrica desenhada só por densidade de pontos

A arte nasce em canvas no mesmo navegador sem cabeça que já rasteriza os slides: o PNG do slide é a única saída, sem arquivo intermediário, sem ferramenta externa e sem binário novo no repositório.

Herda o TRATAMENTO do hero (sólido isométrico ditherizado, aresta acesa, poeira nas bordas) e troca o ASSUNTO: cada projeto tem o seu sólido. Não é a cena do hero repetida quatro vezes, nem o print da interface.

22Rodapé

Onde a página termina.

Assinatura, situação e o que mais existe. O rodapé é o único lugar onde a marca aparece de novo depois do topo.

Rodapé
mateusfb.ai

Ferramentas, agentes e conteúdo. Entregues em público.

SiteProjetosBloco de notasSobre
SocialInstagramRepositório
Tudo funcionando
Feito no Brasil2026 mateusfb.ai
23Diagramação

Como uma página se monta.

Seções numeradas, uma medida de leitura curta e muito respiro. O que dá ritmo não é linha divisória, é espaço, e o que dá orientação é o número da seção.

O ritmo
entre seções
96px no desktop, 64px no telefone
dentro da seção
40px
rótulo e conteúdo
24px
linhas de uma pilha
9px (cell-gap)
medida de leitura
cerca de 70 caracteres
As três larguras
telefone
uma coluna, respiro de 24px
tablet
duas colunas
desktop
três ou quatro, respiro de 120px
teto
1512px, e o conteúdo centra
O que não fazemos
Cartão para tudo

Borda, fundo e raio dizem objeto separado. Gastar nos três achata a hierarquia.

Centralizar tudo

O texto nasce alinhado à esquerda, onde o olho volta.

Linha para separar

Primeiro o espaço. A linha entra quando o espaço não bastou.

Todo recurso estrutural precisa dizer algo verdadeiro sobre o conteúdo. Numerar uma seção é dizer que existe ordem; se não existe, o número é enfeite.

24Acessibilidade

O que não é negociável.

Um sistema sem cor precisa acertar o resto. Foco visível, alvo grande, controle nativo e movimento que se desliga de verdade.

Foco

Contorno de 1px em fg, afastado 4px, declarado uma vez na folha global. Nenhum componente redefine o dele.

Alvo de toque

44px de altura em qualquer coisa que se clique com o dedo, mesmo quando o desenho é menor.

Controle nativo

Marcar, escolher e ligar usam o input do navegador escondido com sr-only. display none tira do teclado.

Movimento reduzido

Animação e transição caem para 0,01ms e a árvore renderizada é a mesma, para não haver diferença entre servidor e cliente.

Cor nunca sozinha

Erro e situação carregam ícone e palavra. Aqui não há escolha: não existe cor para carregar sentido.

Imagem

Alt que descreve o que a imagem faz na página. Decoração vai com aria-hidden, sem texto nenhum.

25Voz

As palavras também são o design.

pt-BR direto, sem jargão, o número antes do adjetivo. Três destas regras têm catraca, então não são preferência: reprovam o commit.

Em vez de, escreva
RegraEm vez deEscreva
TravessãoUma coisa — e outraUma coisa, e outra
PromessaO melhor kit de agentesO kit que eu uso todo dia
NúmeroCentenas de commits31 commits, medidos hoje
JargãoConfigure o webhookReceber aviso de nota nova
26Catracas

O que defende tudo isto.

O sistema não se sustenta por disciplina, se sustenta por gate. Cada regra que podia ser furada em silêncio virou um programa que reprova o commit.

32 catracas, todas rodam sempre
CatracaO que reprova
sem-travessaoTravessão em texto que uma pessoa lê.
lista-de-gatesGate que existe no arquivo e não roda.
sessao-abre-arvoreO comando que abre a árvore de trabalho parando de funcionar.
checkeslint, tsc e os testes.
buildO build do Next.
sem-hypePromessa sem base na copy: garantido, vagas limitadas, o melhor.
numero-com-fonteNúmero em copy que não existe em content/.
grafico-com-serie-realSem descrição nesta página.
so-preto-e-brancoQualquer cor cromática em app/ ou components/, por hex, rgb, hsl ou nome.
botao-visivel-no-invertidoSem descrição nesta página.
escala-tipograficaTamanho de fonte cru fora da escala e fora da lista de exceções.
frase-com-maiusculaSem descrição nesta página.
repo-urlURL de repositório montada a partir do slug.
links-vivosLink morto na documentação.
palavra-chaveCódigo de projeto fora do formato, repetido entre projetos, ou ausente da legenda ou da arte do CTA.
peso-do-bundleBiblioteca pesada entrando no JS inicial de uma rota.
artes-servidasSem descrição nesta página.
personagem-sem-donoSem descrição nesta página.
acesso-em-camadasSem descrição nesta página.
painel-fechadoSem descrição nesta página.
dominio-com-cookieSem descrição nesta página.
hosts-exclusivosSem descrição nesta página.
marca-sem-fonteSem descrição nesta página.
previa-sem-vazamentoSem descrição nesta página.
ramo-com-marcaSem descrição nesta página.
sem-jargaoSem descrição nesta página.
tela-fala-os-dois-idiomasSem descrição nesta página.
secao-com-elementoSem descrição nesta página.
faixa-alternadaSem descrição nesta página.
painel-que-respondeSem descrição nesta página.
destaque-do-kitSem descrição nesta página.
passo-sem-vazioSem descrição nesta página.

E a regra que faz um gate valer alguma coisa: gate que não sabe dizer como se prova não protege nada. Cada um nasce com a mutação declarada, um defeito real injetado no código, e o meta-gate exige vermelho em cada uma antes de aceitar que a cerca existe.