Design System
v2.3 · Índigo + Linha de luz · Geist

Escuro e calmo, com luz só onde há ação

Base única para apps no Lovable, extensões de Chrome, front-ends e blogs. Neutros levemente frios, índigo como cor de marca, um fio de luz como assinatura e brilho que só aparece quando você interage.

Comece pelo arquivo do seu projeto
Lovable / React + shadcn

shadcn-globals.css + tailwind.config.js

Classes da assinatura: lit, btn-glow, card-glow, nav-active, input-glow. Movimento: motion.ts.

Extensão, blog, HTML

tokens.css

Variáveis --color-*, --space-*, --radius-* e classes .ds-lit, .ds-btn-primary, .ds-card-interactive.

IA e outras ferramentas

llms.txt + tokens.json

A IA consulta as páginas pelo llms.txt. O JSON alimenta scripts e Figma (Tokens Studio).

Como usar
// Regra: componentes usam só tokens semânticos. Nunca hex direto.

// Lovable / React + shadcn
<html class="dark">
<Card className="lit">              {/* linha de luz: 1 por tela */}
  <Button className="btn-glow">Criar monitor</Button>
</Card>

<!-- CSS puro (tokens.css) -->
<div class="ds-lit ds-card-interactive">
  <button class="ds-btn-primary">Criar monitor</button>
</div>

Como ler esta página: Fundamentos definem os tokens; Componentes mostram variantes, estados e regras de uso, cada um com uma nota "Movimento"; Cards e Páginas mostram como compor telas. Clique em cores e escalas para copiar o hex.

Fundamentos

Cores semânticas

Profundidade vem de camadas de superfície e bordas de 1px, sem sombra. Componentes usam só estes tokens; clique em uma cor para copiar o hex do tema atual.

1 · Superfícies e texto
2 · Marca e status
3 · Quando usar cada camada
Fundo--color-bg

Página inteira e área atrás de cards. Nunca dentro de um card.

Superfície--color-surface

Cards, menu lateral, modal, menus suspensos.

Elevada--color-surface-raised

Dentro da superfície: hover de linha, item ativo, botão secundário, badge neutro.

Afundada--color-surface-sunken

Campos, blocos de código, cabeçalho de tabela, rodapé de modal.

  • Texto: principal para conteúdo, secundário para descrições, apagado para legendas e metadados. Desativado só em controle desativado.
  • Borda (--color-border) separa áreas; borda forte contorna controles (campo, botão secundário, menu).
  • Índigo só em ação principal, link, foco e seleção. Ícone decorativo e título ficam neutros.
  • Status nunca vem só pela cor: sempre com ícone ou texto ("Erro", "Ativo").
Fundamentos

Escalas

Primitivos gerados em OKLCH. Componentes não usam a escala direto: ela serve para criar tokens semânticos, gráficos e ilustrações. Índigo 500 (contornado) é a cor de marca.

1 · Primitivos · clique para copiar
2 · De onde vem cada token semântico
TokenEscuroClaro
Fundo · superfície · elevadaneutro 950 · 900 · 800neutro 50 · branco · 100
Borda · borda forteneutro 800 · 700neutro 200 · 300
Texto · secundário · apagadoneutro 100 · 300 · 400neutro 900 · 700 · 600
Primário · hoveríndigo 500 · 600índigo 500 · 600
Texto índigo · focoíndigo 300 · 400índigo 600 · 500
Status (texto e ícone)400700
Destrutivo sólidovermelho 600vermelho 600

Regra para criar um token novo: no escuro use passos claros (300–400) para texto; no claro, passos escuros (600–700). Confira o contraste antes de usar.

Fundamentos

Contraste

Razões WCAG sobre o fundo de cada tema. Texto pede 4,5:1 (AA); anel de foco e ícones que transmitem informação pedem 3:1.

ParEscuroClaroNível
Texto principal / fundo16,8 : 117,3 : 1AAA
Texto secundário / fundo11,3 : 111,3 : 1AAA
Texto apagado / fundo7,2 : 17,5 : 1AAA
Texto índigo, links / fundo9,8 : 16,5 : 1AA
Status / fundo7,0–7,8 : 16,8–7,7 : 1AA
Branco / botão índigo5,1 : 15,1 : 1AA
Branco / destrutivo sólido5,7 : 15,7 : 1AA
Anel de foco / fundo7,0 : 14,9 : 13:1 ok
Texto desativado / fundo2,5 : 12,6 : 1Isento

Meça no pior caso: sobre a superfície elevada o texto apagado cai para 5,9:1 (escuro) e o texto índigo para 5,9:1 (claro), ainda AA. Texto desativado é isento pela WCAG, por isso o motivo do bloqueio vai em texto normal ao lado.

Fundamentos

Assinatura

Parada, a tela é calma: só um fio de luz no topo do herói e de um card de destaque. O brilho aparece como resposta, ao passar o mouse, focar ou marcar o item ativo.

MovimentoLinha de luz parada; ao carregar a página, uma varredura atravessa o herói uma única vez (veja o topo desta página). Brilho só em hover, foco e item ativo.
900ms · ease-in-out · 1×glow · base
1 · Os quatro elementos
Linha de luz

Card em destaque

No máximo um por tela, além do herói.

Hover

Card interativo

Passe o mouse: borda índigo e halo suave.

Botão e foco
Marca e ativo
Seu produto
2 · Classes por projeto
ElementoReact + shadcnCSS puro
Linha de luzlit.ds-lit
Brilho do primáriobtn-glow.ds-btn-primary
Card interativocard-glow.ds-card-interactive
Foco de campoinput-glow.ds-input
Item ativo do menunav-active.ds-nav-active
Marcabrand-mark.ds-mark
3 · Uso
Um card com linha de luz: o olho sabe onde começar.
Se tudo brilha, nada se destaca. Brilho em repouso também não.
Fundamentos

Tipografia

Geist para interface e títulos, Geist Mono para números, código e rótulos técnicos. Interface em 14px, leitura longa em 16px.

1 · Famílias
Sans · UI e títulosAa Gg 123

Geist · 400, 500, 600, 700

Mono · dados e códigoR$ 1.284,90

Geist Mono · 400, 500 · números tabulares

2 · Escala
3 · Regras
  • Peso: 400 para texto, 500 para rótulos e botões, 600 para títulos, 700 só a partir de 36px.
  • Espaçamento entre letras negativo só em títulos de 20px para cima; quanto maior o título, mais negativo.
  • Altura de linha: 1,2 em títulos, 1,5 na interface, 1,7 em texto de leitura (até 66 caracteres por linha).
  • Valores, datas, IDs e preços em Geist Mono com font-variant-numeric: tabular-nums, alinhados à direita em tabelas.
  • Caixa alta só em rótulos de 12px com espaçamento .08em. Nunca em títulos ou botões.
Fundamentos

Espaço, raio e sombra

Todo espaço é múltiplo de 4px. Quanto mais relacionados dois elementos, menor o espaço entre eles. Profundidade vem de borda e superfície; sombra só no que flutua.

Espaçamento · base 4px

4–8 dentro do componente (ícone e texto) · 12–16 entre campos e padding de card · 24–32 entre grupos · 48–64 entre seções.

Raio

4 · badge
8 · botão, campo
12 · card
14 · modal
full · chip, avatar

Elemento dentro de outro usa raio menor que o do pai.

Elevação

0 · borda (padrão)
1 · superfície elevada
2 · sombra (modal, menu, toast)

Camadas (--z-*): menu 50 · fixo 100 · overlay 200 · modal 300 · toast 400.

Fundamentos

Ícones

Traço de 1,75px, cantos arredondados, cor herdada do texto. No Lovable/React use lucide-react, que segue este estilo; não misture com outra biblioteca.

1 · Conjunto · passe o mouse para ver o nome

Os nomes são do sprite desta página. No Lucide: okc = CircleCheck, xc = CircleX, warn = TriangleAlert, gear = Settings, more = Ellipsis, tup/tdown = TrendingUp/TrendingDown, down/up = Download/Upload, ext = ExternalLink, out = LogOut, msg = MessageSquare, cal = Calendar, spark = Sparkle.

2 · Tamanho e uso
  • 14px em botão pequeno, tabela e badge; 16px no padrão da interface; 20px em destaque, estado vazio e cabeçalho de card.
  • strokeWidth 1,75 em todos os tamanhos (medido no viewBox de 24).
  • Ícone ao lado de texto é decorativo: aria-hidden. Ícone sozinho em botão leva aria-label e tooltip.
  • Cor neutra por padrão (secundário ou apagado). Índigo só no item ativo; cor de status só em mensagem de status.
Icon.tsx
import { Bell } from "lucide-react";

// padrão: 16px, traço 1,75
<Bell size={16} strokeWidth={1.75} aria-hidden />
Fundamentos

Movimento

Movimento é resposta, nunca enfeite: se a animação não ajuda a entender o que mudou, ela sai. Cada componente desta página traz uma nota "Movimento" com o comportamento e os tokens que usa.

1 · Tokens e regras
TokenValorUso
--duration-fast120mscor e fundo no hover, clique, sair, tooltip, menu
--duration-base200msbrilho e elevação no hover, foco, abrir, abas, toast
--duration-slow320mspainéis, gaveta, reorganizar lista, switch
--stagger40msentre itens de lista; do 7º em diante entram juntos
--ease-out.2, 0, 0, 1entrar e reposicionar (lista, indicador)
--ease-in.4, 0, 1, 1sair
--ease-in-out.4, 0, .2, 1atravessar a tela inteira (varredura)
--ease-spring.34, 1.4, .64, 1só peças pequenas que confirmam clique: switch, check, radio, ícone, contador
Mola (JS)k 380 · c 30o que o dedo arrasta: gaveta, cards; layout no React

No CSS desta página os mesmos valores se chamam --d-fast, --d-base, --d-slow e --ease-io. Ao copiar CSS daqui, troque pelos nomes de tokens.css.

Regras

  • Anime só transform e opacity. Exceções documentadas: altura do acordeão, do alerta ao fechar e do grupo do menu; largura do menu ao recolher.
  • Sair é mais rápido que entrar.
  • Nada acima de 400ms. Exceções: contagem de KPI (800ms), varredura do herói (900ms, 1×) e destaque de item novo (1,2s, só a cor de fundo se apagando).
  • Loop só em loading, esqueleto e indicador "ao vivo".
  • Animação nunca bloqueia: o usuário clica, digita ou rola durante ela, e uma nova ação interrompe a anterior.
  • A tela fica completa mesmo se a animação não rodar.
2 · Curvas · clique para repetir
3 · Quando não animar e acessibilidade

Não anime

  • Ações repetidas o dia todo: digitar, atalhos de teclado, trocar linha com as setas.
  • Dados que se atualizam sozinhos. A contagem de KPI roda só na primeira entrada; depois o número troca direto.
  • Listas longas: sem sequência acima de 6 itens e sem deslizar linhas em tabela virtualizada.
  • Texto que precisa ser lido na hora: erro crítico, 404, conteúdo de artigo ao rolar.
  • Abertura de popup de extensão e de páginas inteiras: o navegador já anima.

Reduzir movimento

  • Com prefers-reduced-motion ativo, deslocamento, escala, mola, varredura e contagem viram troca instantânea.
  • O que continua: mudança de cor, foco e a barra de leitura (ela segue a rolagem do próprio usuário).
  • Spinner parado não comunica nada sozinho: mantenha o texto ao lado ("Salvando…").
  • Nada pisca mais de 3 vezes por segundo. Loop que dura mais de 5s precisa ser pequeno ou ter como pausar.
  • O foco vai para o destino quando a animação termina (veja Card → detalhe e a gaveta).
4 · Bibliotecas por tipo de projeto
ProjetoUsePor quê
Lovable / Reactmotion (import de motion/react)Entrada e saída (AnimatePresence), layout, mola. Sucessor do Framer Motion.
Extensão de Chrome, blog, HTMLCSS nativo + View Transitions0 KB. @starting-style, popover, animation-timeline.
Landing com narrativa de rolagemGSAP + ScrollTriggerSó se a página for "contada" pela rolagem. Gratuito. Fora disso, CSS basta.
App mobile (React Native)Reanimated + MotiAnima na thread nativa, não trava.
5 · Código
tokens.css
--duration-fast: 120ms;
--duration-base: 200ms;
--duration-slow: 320ms;
--stagger: 40ms;
--ease-out: cubic-bezier(.2, 0, 0, 1);
--ease-in: cubic-bezier(.4, 0, 1, 1);
--ease-in-out: cubic-bezier(.4, 0, .2, 1);
--ease-spring: cubic-bezier(.34, 1.4, .64, 1);

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0ms !important;
    animation-duration: 0ms !important;
  }
}
App.tsx
import { motion, AnimatePresence, MotionConfig } from "motion/react";
// presets prontos em motion.ts (modal, menu, toast, list, item…)
import { modal, spring } from "@/lib/motion";

// "user" respeita o reduzir movimento do sistema
<MotionConfig reducedMotion="user">
  <AnimatePresence>
    {open && <motion.div {...modal} />}
  </AnimatePresence>
  <motion.li layout transition={spring} />
</MotionConfig>
Movimento

Técnicas modernas

Seis técnicas que ajudam a acompanhar o que mudou. Use cada uma só no caso descrito na tabela abaixo das demos. As que dependem do navegador mostram se ele tem suporte nativo ou se está usando a reserva.

Card → detalhe View Transitions

Clique num produto: a imagem e o título viajam até a tela de detalhe. Volte para ver o caminho inverso.

slow × 1,15 · ease-out

Gaveta com mola Spring

Arraste a alça para baixo e solte. Funciona com mouse e dedo.

Tela do app
mola k 380 · c 30

Lista que se reorganiza Layout / FLIP

Filtre e ordene: quem fica desliza para o novo lugar, quem sai some primeiro.

slow · translate only

Paleta de comandos Só CSS

Abre e fecha sem biblioteca: popover nativo + @starting-style. Fundo com vidro fosco.

Esc ou clique fora para fechar
base · 0 KB de JS

Progresso de leitura Scroll-driven

Role o texto: a barra acompanha e o cabeçalho ganha vidro fosco.

Blog6 min

Comece pelos cinzas

Num tema escuro, quase tudo na tela é cinza. Escolha um fundo, duas superfícies e duas bordas com um leve tom frio, e a interface já parece intencional antes de qualquer cor de marca.

Uma cor de marca

O índigo marca ação: botão principal, links e foco. Status continua em verde, âmbar e vermelho, sempre com texto ao lado.

A assinatura

A linha de luz aparece no herói e em um card de destaque. O brilho maior só surge como resposta ao mouse ou ao foco.

Movimento

Três durações, quatro curvas e uma regra: se a animação não ajuda a entender o que mudou, ela sai.

linear · ligado à rolagem

Interface otimista + desfazer Percepção de velocidade

A ação acontece na hora; o servidor confirma depois. Arquive um alerta e use "Desfazer", ou favorite um item.

fast saída · 5s para desfazer
Quando usar cada técnica
TécnicaUse quandoEvite quandoCusto e suporte
View TransitionsCard abre o detalhe e o usuário precisa saber de onde veio.Muitos elementos com nome na mesma tela; troca de aba simples.0 KB. Mesma página: navegadores atuais. Entre páginas: ainda sem Firefox. Reserva: troca direta.
MolaO dedo arrasta: gaveta no celular, card que se descarta.Modal e menu no desktop; use a curva com duração fixa.JS a cada quadro. No React, já vem no motion. Funciona em todo navegador.
Layout / FLIPFiltrar ou ordenar uma lista curta em que o usuário segue um item.Mais de ~50 linhas, tabela virtualizada ou dados que mudam sozinhos.Mede a posição antes e depois. No React, layout do motion; sem framework, ~30 linhas.
Popover + @starting-stylePaleta, menu e popover em extensão ou HTML puro.Diálogo que precisa prender o foco: use <dialog>. No React, use o componente da biblioteca.0 KB. Navegadores atuais; no Firefox a saída é instantânea. Reserva: abre sem animar.
Scroll-drivenProgresso de leitura e cabeçalho que muda ao rolar.Parallax, rolagem sequestrada, texto que só aparece ao rolar.0 KB. Chrome, Edge e Safari 26; Firefox ainda não. Reserva: ouvinte de rolagem passivo.
Interface otimistaAção reversível que quase nunca falha: arquivar, favoritar, marcar como lida.Pagamento, exclusão definitiva, envio de e-mail.Precisa desfazer a mudança e avisar se o servidor falhar. React: useOptimistic ou onMutate do TanStack Query.
Componentes

Botões

Um botão primário por tela. A hierarquia diz qual ação importa; o texto diz exatamente o que vai acontecer.

MovimentoHover acende o brilho (só no primário); clique afunda 3% (scale(.97)). Carregando troca o texto por spinner e depois por check, sem mudar a largura. Alternar dá um pulo no ícone. Desativado e destrutivo não brilham.
hover · fastglow · basepress · fasttexto · y ±6alternar · spring
1 · Hierarquia
Primário

A ação principal. Um por tela ou por modal.

Secundário

Ações de apoio ao lado do primário.

Contorno

Ações neutras em áreas cheias de cards.

Fantasma

Barras de ferramentas, cancelar, ações terciárias.

Link

Dentro de texto ou para navegar. Se leva a outra página, use <a>.

2 · Destrutivo
Destrutivo suave · uso padrão

Em listas, cards e configurações. Abre a confirmação ou permite Desfazer.

Destrutivo sólido · só na confirmação

Aparece apenas no modal que confirma a exclusão. Branco sobre #B1403E: 5,7:1.

3 · Tamanhos
sm · 32px · ícone 14 · tabelas e barras
md · 36px · ícone 16 · padrão
lg · 44px · ícone 16 · celular e landing

No celular, todo alvo de toque tem no mínimo 44px de altura, mesmo que o botão pareça menor.

4 · Estados
NormalHoverFoco (teclado)PressionadoCarregandoDesativado
Primário
Secundário
Fantasma—
Destrutivo

Foco usa anel de 2px com folga de 2px, sempre visível no teclado e nunca no clique do mouse (:focus-visible). Carregando mantém a largura e bloqueia novos cliques.

5 · Variações
Com ícone

Ícone à esquerda para ação; seta à direita para avançar.

Só ícone
ConfiguraçõesMais opçõesCopiar link

Sempre com tooltip e aria-label. Passe o mouse.

Dividido

Ação mais comum à esquerda; alternativas no menu.

Alternar

Liga/desliga com aria-pressed. Clique em Favoritar.

Com contador e atalho

Contador para pendências; atalho só em ações frequentes.

Grupo e carregando

Clique em Salvar para ver carregando → sucesso.

6 · Em contexto
Rodapé de modalprimário à direita
Excluir "Monitor de fretes"?Os 128 produtos e o histórico serão apagados.
Rodapé de formuláriostatus à esquerda
Alterações não salvas
Barra de ferramentasfantasma + 1 primário
FiltrosAtualizarBaixar
Celularlargura total, empilhado
Ativar alertas no WhatsApp?Avisamos quando o preço cair.
7 · Texto e uso
Verbo + objeto. A pessoa sabe o que vai acontecer sem ler o resto.
"Sim", "OK" e "Confirmar" obrigam a reler a pergunta.
Preencha o nome do projeto para continuar.
Desativado sempre com o motivo ao lado.
Três primários competem; nenhum se destaca.
  • Em rodapés e modais, primário à direita, secundário à esquerda dele. Destrutivo suave fica separado, no lado oposto.
  • Largura total só no celular ou em formulários estreitos (login, popup de extensão).
  • Texto em uma linha, até 3 palavras, sem ponto final. Primeira letra maiúscula, resto minúsculo.
  • <button> executa ação; <a> leva a outra página, mesmo que pareça botão.
Componentes

Badges e status

Badge mostra um estado ou atributo e não é clicável. Status sempre com texto; a cor só reforça. Índigo marca novidade e destaque, nunca estado.

MovimentoO contador pula quando o número muda (clique em Notificações). O ponto de "Ao vivo" pulsa: é o único loop desta seção e só vale para dado em tempo real. Chips encolhem 4% no clique; badge não reage.
contador · spring 320pulso · loop 1,8schip · fast
1 · Status
AtivoSucesso

Ativo, pago, concluído.

PendenteAtenção

Pede ação em breve, sem bloquear nada.

FalhouErro

Falhou ou está bloqueado. O motivo aparece no detalhe.

Em filaInformação

Em andamento ou aguardando o sistema.

RascunhoNeutro

Inativo, arquivado, rascunho. Sem ponto.

2 · Marca e variações
Destaque
IANovoPro

Novidade, recurso de IA, plano. Sólido só para o plano pago, no máximo um por tela.

Técnico
v1.4.2#1284

Versão, ID, código. Sempre em Geist Mono.

Ao vivo
Ao vivo

Só para dado que atualiza sozinho agora. Um por tela.

3 · Contador, chip e tag
Contador

Pendências não vistas. Acima de 99 mostra "99+"; com zero, some.

Chip de filtro

Clicável, liga e desliga. Fica em Seleção, acima de listas.

Tag removível
SantosParanaguá

Valor escolhido. Só o X é botão, com aria-label.

4 · Uso
PagoRecusadoVencendo
Cor + texto. Funciona para quem não distingue cores e no leitor de tela.
Só a cor: vermelho e verde viram o mesmo ponto para 1 em cada 12 homens.
  • Texto de 1 ou 2 palavras, sem ponto final: "Pago", "Em fila", "Vence hoje".
  • Badge não tem hover nem cursor de mão. Se a pessoa pode clicar, use chip ou botão.
  • No celular, o badge não quebra linha. Se faltar espaço, corte o título do item, nunca o status.
Componentes

Campos

Rótulo sempre visível acima, ajuda abaixo. Placeholder só dá exemplo e nunca substitui o rótulo. O erro diz como corrigir.

MovimentoFoco: borda e halo entram juntos. Erro: uma tremida curta de 6px e a mensagem entra com fade (clique em Validar). O ícone de mostrar senha troca com impulso. Arraste um arquivo sobre o upload para ver o estado ativo.
foco · baseerro · 320 · 1 cicloolho · springsoltar · base
1 · Estados
Normal
Aparece no topo do painel.
Foco
Borda índigo + halo de 3px.
Erro
Digite um e-mail completo, como nome@empresa.com.
Desativado
Disponível no plano Pro.
Somente leitura
Dá para selecionar e copiar. Sem halo de edição.
Opcional

Marque o opcional, não o obrigatório. Sem asterisco.

Desativado sempre com o motivo ao lado. Somente leitura é para dado que a pessoa vê mas não edita aqui; desativado é para algo que ela poderá editar depois.

2 · Tipos
Busca
⌘K

Ícone à esquerda. Atalho só no desktop.

Prefixo
https://

Parte fixa fica fora do valor: domínio, moeda, unidade.

Senha

Botão de mostrar com aria-pressed. Não bloqueie colar.

Texto longo
82 / 280

Contador só quando há limite.

Código
Código de verificação

Colar preenche tudo; o foco avança sozinho.

Upload
Planilha de produtos
3 · Uso
Rótulo fixo acima; placeholder mostra o formato.
Placeholder como rótulo some ao digitar; a pessoa esquece o que o campo pedia.
  • Valide ao sair do campo ou ao enviar, nunca a cada tecla. O erro some assim que a pessoa corrige.
  • Erro ligado ao campo com aria-invalid e aria-describedby. Ao enviar com erro, o foco vai para o primeiro campo errado.
  • No celular: campo com 44px de altura e fonte de 16px (abaixo disso o iOS dá zoom). type e inputmode certos abrem o teclado certo.
  • A largura do campo sugere o tamanho do dado: CEP curto, descrição larga. Em formulário, uma coluna.
Componentes

Seleção

Escolha o controle pelo número de opções e pelo momento do efeito. Switch aplica na hora; checkbox e radio esperam o Salvar.

MovimentoSwitch desliza com impulso e alonga ao pressionar. Check e ponto do radio surgem com impulso. Select nativo não anima.
switch · slow · springcheck · base · spring
1 · Qual usar
Switch
Notificações

Liga ou desliga com efeito imediato. Sem botão Salvar.

Checkbox
Canais de alerta

Várias opções independentes, ou um aceite. Vale ao salvar.

Radio
Frequência

Uma entre 2 e 5 opções, todas à vista. Sempre com uma marcada.

Select

Uma entre 6 ou mais, ou quando falta espaço. Acima de 15, select com busca. Até 4 opções que mudam a tela na hora: segmentado (em Abas).

Intervalo

Valor aproximado numa faixa. Mostre o número; para valor exato, use campo.

Chips de filtro

Filtros que se somam, acima de listas e tabelas. Aplicam na hora.

2 · Estados
DesmarcadoMarcadoMistoFocoErroDesativado
Checkbox
Radio—
Switch——

Misto aparece no "selecionar todos" quando só parte da lista está marcada. Erro de grupo (nenhuma opção escolhida) mostra a mensagem abaixo do grupo, não em cada item. Contorno desmarcado em --muted para ter 3:1 contra o fundo.

3 · Uso
Switch sozinho, vale na hora. O rótulo diz o que fica ligado.
Switch que espera o Salvar engana: parece ligado e não está. Aqui é checkbox.
  • O rótulo inteiro é clicável. No celular, cada linha tem 44px de altura.
  • Grupos usam fieldset + legend; switch usa role="switch".
  • Opção desativada mostra o motivo ao lado ("plano Pro").
  • Use o select nativo: no celular ele abre o seletor do sistema. Customizado só quando precisa de busca, ícone ou várias escolhas.
Componentes

Abas e navegação

Abas trocam a visão dentro da mesma página, sem navegar. Segmentado troca o formato do mesmo conteúdo. Breadcrumb e paginação dizem onde a pessoa está.

MovimentoO indicador desliza até a aba (translate + scaleX, nunca left/width). O painel novo entra com fade e 4px. No segmentado, o fundo da opção desliza.
indicador · basepainel · base · y 4
1 · Abas sublinhadas
Resumo do projeto com métricas do mês.

Seções do mesmo objeto, uma de cada vez. De 2 a 6 abas; com mais, use navegação lateral. A aba vai para a URL (?aba=historico) para o link e o voltar funcionarem. No celular, a barra rola na horizontal e nunca quebra linha.

2 · Segmentado

De 2 a 4 opções curtas que mudam o formato ou o período na hora, sem painel novo. Com 5 ou mais, use select.

3 · Breadcrumb e paginação

Breadcrumb a partir de 3 níveis; o último item é a página atual, sem link. No celular, mostre só o nível anterior. Paginação em tabelas com total conhecido: primeira, última e vizinhas. Em feeds, prefira "Carregar mais".

4 · Uso
Segmentado muda o mesmo gráfico. Abas separam conteúdos diferentes.
Passos de um fluxo em abas deixam pular etapas. Use o stepper.
  • Teclado nas abas: Tab entra na aba ativa, setas trocam de aba, Tab de novo vai para o painel.
  • Rótulo de 1 ou 2 palavras. Contador opcional à direita, em badge neutro.
  • Aba nunca desativada sem motivo: se o conteúdo não existe, esconda a aba.
Componentes

Acordeão

Esconde respostas e detalhes secundários para a página caber numa olhada. Se a pessoa precisa ler tudo, não esconda.

MovimentoSeta gira 180°. A altura anima ao abrir (200ms) e fecha mais rápido (120ms).
Exceção à regra de só animar transform: altura em conteúdo curto. Em React use motion com height: "auto".
abrir · basefechar · fast
1 · Perguntas frequentes
Como o preço é atualizado?
A cada 15 minutos verificamos cada link. Quando o valor muda, o histórico registra e o alerta dispara se cruzar a meta.
Posso exportar os dados?
Sim, em CSV ou XLSX pela tela de relatórios.
Quantos produtos posso monitorar?
50 no plano grátis e sem limite no Pro.

Feito com <details> e <summary>: teclado (Enter e Espaço) e leitor de tela funcionam sem JS. A linha toda é o alvo, com pelo menos 48px. Vários podem ficar abertos ao mesmo tempo.

2 · Quando usar
Acordeão

Perguntas frequentes e opções avançadas que a maioria não abre. O título é a pergunta inteira.

Abas

Conteúdos do mesmo nível que a pessoa compara ou alterna. Ver Abas e navegação.

Mostrar mais

Um texto longo só. Mostre as primeiras linhas e um link para expandir.

  • Primeiro item aberto quando ele responde a dúvida mais comum.
  • Não aninhe acordeão dentro de acordeão, nem esconda campos obrigatórios.
Componentes

Avatar

Identifica quem fez ou quem participa. Redondo é pessoa, quadrado é empresa ou projeto. Sem foto, iniciais com uma cor fixa por nome.

MovimentoPasse o mouse na pilha: os avatares se afastam para mostrar quem está ali. Status não anima.
afastar · base
1 · Tamanhos e forma
sm · 24 · listas densas, menções
md · 32 · padrão
lg · 44 · perfil, cabeçalho
quadrado · empresa, projeto

Ordem de exibição: foto, depois iniciais, depois ícone de pessoa. A cor vem do nome (mesmo nome, mesma cor) e as 6 opções têm texto branco com contraste de 4,9:1 ou mais.

2 · Status, grupo e nome
Status
DJOnline
ACAusente
MSOffline

O ponto não basta sozinho: o status vai no aria-label e em texto onde houver espaço.

Pilha
DJACMS+5

Até 3 rostos e um contador. Clicar abre a lista completa.

Com nome
Ana Costa
ana@empresa.com

Com o nome ao lado, o avatar é decorativo (aria-hidden ou alt="").

Componentes

Tooltip e menu

Tooltip nomeia ou completa em poucas palavras e nunca guarda informação essencial. Menu reúne ações sobre um item; cada item começa com verbo.

MovimentoTooltip espera 300ms para aparecer e some na hora. Menu cresce de 96% a partir do botão que o abriu e fecha mais rápido do que abre.
tooltip · delay 300 · fastmenu · fast · origem no gatilho
1 · Tooltip
Copiar link Atualizado há 4 min13 out 2026, 14:32

Nome de botão só de ícone (repete o aria-label) ou o dado completo de algo resumido, como a data exata. Abre no hover e no foco do teclado; em produção, Esc fecha. Só texto, sem link nem botão dentro. No celular não há hover: o que importa fica visível.

2 · Menu de ações

Destrutivo por último, depois de uma divisória, em vermelho; ele abre a confirmação. Atalho à direita. Teclado: setas movem, Enter escolhe, Esc fecha e devolve o foco ao botão. No celular, menu com mais de 5 itens vira folha inferior.

3 · Qual usar
Tooltip

Rótulo curto no hover ou foco. Só texto.

Popover

Abre no clique e pode ter link, botão ou formulário curto. Fecha com Esc ou clique fora.

Menu

Lista de ações sobre um item: "Mais opções", botão dividido.

Select

Escolher um valor de uma lista. Ver Seleção.

Mínimo de 8 caracteres.
Regra que a pessoa precisa seguir fica visível, como ajuda do campo.
Mínimo de 8 caracteres
Regra escondida no tooltip: no celular ninguém vê, e o ícone nem recebe foco.
Componentes

Stepper

Mostra onde a pessoa está num fluxo linear de 3 a 5 passos. Se as partes podem ser visitadas em qualquer ordem, use abas.

MovimentoAo concluir um passo, a linha se preenche (scaleX) e o check aparece com impulso. Voltar desfaz na hora. Com movimento reduzido, tudo troca sem animação.
linha · slowcheck · base · spring
1 · Padrão · use Avançar e Voltar
  1. ContaE-mail e senha
  2. EmpresaDados básicos
  3. 3PreferênciasAlertas e metas
  4. 4ProntoPrimeiro projeto
2 · Estados do passo
Concluído

Clicável para voltar e revisar. Os dados continuam preenchidos.

3Atual

Anel índigo. No HTML, aria-current="step".

4Próximo

Apagado e não clicável. Avançar valida só o passo atual.

Com erro

Passo já visitado que ficou inválido. A descrição diz o que corrigir.

3 · Celular e regras
Celularpasso X de Y + barra
Passo 3 de 4Próximo: Pronto
Preferências
Como você quer ser avisado?
  • No celular, troque a lista de passos por "Passo 3 de 4", o nome do passo e uma barra. A lista completa vira coluna só se couber sem empurrar o formulário para baixo.
  • Título do passo com 1 ou 2 palavras. A descrição é opcional e some no celular.
  • Marque com <ol>: a ordem faz parte do significado.
  • O último botão diz o que acontece no fim ("Criar projeto"), nunca "Avançar".
Componentes

Progresso e loading

Escolha pelo tempo de espera e pelo que se sabe do progresso. Sempre diga o que está carregando.

MovimentoBarras preenchem ao entrar na tela e mudam de valor deslizando. Barra indeterminada, spinner e brilho do esqueleto são os únicos loops permitidos. O conteúdo substitui o esqueleto com fade, sem pular de lugar.
preencher · slowesqueleto · loop 1,6strocar · base
1 · Qual usar
EsperaUse
Até 300msNada. Mostrar loader nesse tempo só causa uma piscada.
300ms a 3sSpinner no lugar da ação (botão, linha) ou esqueleto no lugar do conteúdo.
Mais de 3s, progresso conhecidoBarra determinada com número: "312 de 480" ou porcentagem.
Mais de 3s, sem previsãoBarra indeterminada e um texto do que está acontecendo. Acima de 10s, ofereça Cancelar ou deixe seguir em segundo plano com aviso no fim.
2 · Barras
Importando produtos312 de 480
Uso do plano68%
Cota de API87%
Importação concluída100%
Gerando relatório de fretes…—

Brilho só na barra em andamento. Cor por faixa: índigo até 79%, âmbar de 80% a 99%, vermelho ao estourar o limite. Verde só quando um processo termina.

3 · Spinner, esqueleto e anel
Spinner

Espera curta num ponto só. Dentro de botão, segue as regras de Botões. Sozinho, leva role="status" e rótulo.

Esqueleto

Primeira carga de conteúdo com forma conhecida. Copie o layout real para nada pular quando os dados chegarem.

Anel
Meta do mêsR$ 680 de R$ 1.000

Mostra proporção em cards de métrica (meta, uso). Não serve para indicar carregamento.

Componentes

Alertas e toasts

Escolha pelo alcance e pela urgência. Banner fala do produto todo, alerta fala de uma área, toast confirma o que a pessoa acabou de fazer.

MovimentoToast sobe 12px ao entrar e desce mais rápido ao sair. Máximo de 3 empilhados; o mais antigo sai primeiro. Alerta fechado faz fade e depois recolhe a altura. No celular, arrastar o toast para o lado dispensa.
toast · entra base · sai fastfechar alerta · base
1 · Qual usar
Banner

Vale para o produto inteiro: novidade, manutenção, pagamento pendente. Fica no topo, um por vez, até a pessoa dispensar ou o problema acabar.

Alerta

Situação de uma página ou área. Fica perto do que afeta e só sai quando resolvido ou dispensado.

Toast

Resultado de uma ação da pessoa. Some sozinho; nada importante pode depender dele.

Modal

Decisão obrigatória antes de seguir. É o mais caro: use pouco. Veja Modal.

2 · Banner
3 · Alertas na página
Importação concluída480 produtos adicionados ao projeto.
Manutenção programadaSábado, das 2h às 3h. Os alertas continuam ativos.
Cota em 85%Faltam 1.500 requisições este mês.
Falha na sincronizaçãoO acesso à Loja A expirou. Os preços dessa loja pararam de atualizar.

Erro não tem fechar: fica até ser resolvido e traz o botão que resolve. Os outros podem ser dispensados. Alerta que aparece depois de uma ação usa role="alert" (erro) ou role="status" (demais).

4 · Toasts · clique para disparar
  • Texto curto no passado: "Produto removido". Detalhe opcional em uma linha.
  • No máximo uma ação, sempre um verbo: Desfazer, Ver, Tentar de novo.
  • Fica 4s; com ação, 8s. Pausa enquanto o mouse ou o foco está nele.
  • Canto inferior direito. No celular, embaixo em largura total, acima da barra de navegação.
  • A área de toasts usa aria-live="polite"; toast de erro usa role="alert".
5 · Erro: onde mostrar
Falha na sincronizaçãoReconecte a Loja A para voltar a atualizar.
Erro que pede ação fica na página, perto do que afeta, até ser resolvido.
Falha na sincronização
Reconecte a Loja A
Toast some em segundos. Quem piscou perdeu o aviso e não sabe onde resolver.
Componentes

Bloco de código

Para trechos que a pessoa vai copiar: comandos, configurações, tokens. Dentro de uma frase, use <code> inline.

MovimentoCopiar troca o ícone por check com impulso, confirma com toast e volta ao normal depois de 1,4s.
ícone · spring
Trecho de código
tsx · botão primário
<Button className="btn-glow">
  <Plus className="h-4 w-4" /> Novo projeto
</Button>

/* hover: halo índigo */
box-shadow: 0 0 0 1px rgb(99 87 240 / .6), 0 6px 22px rgb(99 87 240 / .35);
Comando de terminal
terminal
npm install lucide-react

O $ vem do CSS (::before) e fica fora da cópia. Cabeçalho diz a linguagem ou o nome do arquivo. Linhas longas rolam na horizontal e nunca quebram no meio. Cores de sintaxe usam só os tokens de texto: índigo, verde, âmbar e apagado.

Componentes

Tabela

Para comparar muitos itens pelos mesmos campos. Números em mono e alinhados à direita; texto à esquerda.

MovimentoHover e seleção mudam o fundo em 120ms. Ordenar reorganiza as linhas deslizando. Linha nova entra com destaque índigo que se apaga em 1,2s. Remover é otimista, com Desfazer.
hover · fastreorganizar · slowdestaque · 1,2s
1 · Padrão · filtre, ordene, selecione
LojaStatusAções
Monitor 27" 4KLoja AR$ 1.899,00−12,0%Abaixo da meta
Teclado mecânicoLoja BR$ 459,900,0%Monitorando
SSD NVMe 2TBLoja AR$ 799,00+6,5%Subiu
Cadeira ergonômicaLoja CR$ 1.249,00—Link quebrado
1 de 128 selecionados

Digite "fone" no filtro para ver a tabela sem resultado: cabeçalho e busca continuam no lugar. Em preço, queda é boa notícia: verde para queda, vermelho para alta, sempre com o sinal.

2 · Carregando e celular
Carregandoesqueleto nas colunas reais
Celularvira lista
  • Monitor 27" 4KLoja A · Abaixo da meta
    R$ 1.899,00−12,0%
  • Teclado mecânicoLoja B · Monitorando
    R$ 459,900,0%
  • SSD NVMe 2TBLoja A · Subiu
    R$ 799,00+6,5%
  • Cabeçalho ordenável é <button> dentro do <th>, com aria-sort. Uma coluna ordena por vez; o primeiro clique ordena do menor para o maior.
  • Densidade compacta só para listas longas de trabalho diário. Linha de toque no celular tem no mínimo 44px.
  • Carregando: mantém cabeçalho e mostra 3 a 5 linhas de esqueleto. Ao recarregar com dados na tela, não apague as linhas: use uma barra fina no topo.
  • Celular: até 4 colunas, a tabela rola na horizontal dentro do contêiner. Com mais, vira lista com nome à esquerda e número à direita.
  • Ações da linha ficam no menu ⋯ com aria-label que nomeia o item. Tabela vazia de verdade usa o estado vazio de primeiro uso.
Componentes

Estados vazios

Todo lugar que pode ficar vazio precisa de um. Diga por que está vazio e qual é o próximo passo, com um botão só.

MovimentoO estado vazio entra com fade e 8px quando a lista esvazia. "Tentar de novo" vira spinner enquanto carrega, como em Botões.
entrar · base · y 8
1 · Os três motivos
Primeiro uso

Nenhum produto ainda

Cole o link de um produto para começar a monitorar o preço.

Sem resultado

Nada encontrado

Nenhum resultado para "teclado sem fio". Tente outro termo ou limpe os filtros.

Erro

Não foi possível carregar

A conexão caiu durante a busca. Seus dados estão salvos.

Primeiro uso convida: ícone índigo e botão primário. Sem resultado repete o termo buscado e oferece limpar. Erro diz o que houve, tranquiliza sobre os dados e oferece tentar de novo; nunca mostre código técnico.

2 · Dentro de um card
Alertas recentesÚltimos 7 dias
Nenhum preço caiu nos últimos 7 dias. Avisamos assim que algum ficar abaixo da meta.
  • Em áreas pequenas (card, painel, coluna), use uma linha de texto sem ícone grande e sem botão.
  • Vazio por estar tudo em dia é boa notícia: diga isso e quando algo vai aparecer.
  • Enquanto carrega, mostre esqueleto. Estado vazio só depois da resposta, para não piscar "Nenhum produto" antes dos dados.
Gráficos

Cores, anatomia e escolha

Escolha o tipo pela pergunta que o gráfico responde, use a paleta de dados na ordem fixa e deixe o número exato a um passar de mouse.

MovimentoEntrada única ao aparecer na tela: barras crescem da base em sequência, linhas se revelam da esquerda, rosca abre no sentido horário. Mudança de filtro ou série transiciona em 200ms. Nunca animação contínua; com "reduzir movimento", o gráfico aparece pronto.
entrada · slow + stagger 40linha · 600 · 1×atualizar · base
1 · Paleta de dados
Categórica
123456

Séries diferentes, sempre nesta ordem. Máx. 6; o resto vira "Outros" em cinza.

Sequencial

Intensidade de um valor: mapa de calor, mapa. Mais claro = mais.

Divergente

Desvio em torno de um centro: variação %, meta vs. real.

Status

Só quando a série É um status (no prazo, atrasado, crítico). Nunca como cor de categoria.

Todas as cores têm 3:1 ou mais sobre a superfície nos dois temas. A série principal é sempre a índigo (--chart-1); comparações e períodos anteriores ficam em cinza ou tracejado.

2 · Anatomia
  • Título é o nome do indicador: "Frete Ásia → Santos". Conclusão não vai no título; se precisar, use um badge de variação ao lado.
  • Subtítulo com unidade e período: "US$ por TEU · últimos 12 meses".
  • Grade só horizontal, tênue. Sem bordas no gráfico, sem fundo.
  • Eixo Y em zero sempre em barras e áreas. Linhas podem cortar, com o corte visível.
  • Rótulo direto no fim da linha quando há até 3 séries; legenda só acima disso.
  • Tooltip com todas as séries do ponto, na ordem da legenda, valor em Geist Mono. Séries levam a cor; valores derivados (total, %, variação) ficam sem cor, abaixo de uma linha.
  • Números em pt-BR e abreviados no eixo (12 mil, 1,2 mi); completos no tooltip.
  • Legenda acima do gráfico e clicável; veja os 6 formatos abaixo.
3 · Legendas
Clicável no topo · padrão
20252024Meta

2 a 6 séries. Fica acima do gráfico, na ordem das cores. Clique liga/desliga a série; a última não pode ser desligada.

Rótulo direto

Até 3 linhas: o nome vai na ponta da linha, na cor dela. Dispensa a legenda e o olho não vai e volta.

Com valores
Marítimo72%
Rodoviário17%
Aéreo8%
Outros3%

Rosca e composição: a legenda vira a tabela de valores ao lado do gráfico.

Escala
MenosMais

Mapa de calor e mapas: mostra o que cada tom significa, com o intervalo real ("0–30 navios").

Referências
MédiaLimite 7%Alvo

Linhas de média, limite e alvo entram na legenda com o mesmo traço usado no gráfico.

Sem legenda
uma série só

Uma série só não leva legenda: o título e o subtítulo já dizem o que é.

4 · Qual gráfico usar
PerguntaUseEvite
Como mudou ao longo do tempo?Linha · área (volume)Barras com mais de ~20 períodos
Qual é maior? Qual o ranking?Barras horizontais ordenadasPizza, radar
Como se compara com o período anterior?Barras agrupadas · linha com tracejadoDuas pizzas lado a lado
Do que é feito o total?Rosca (até 5 partes) · barra empilhada 100%Pizza com 6+ fatias
Uma coisa influencia a outra?DispersãoDuas linhas com eixos diferentes
Volume e taxa juntos?Combinado (barras + linha)Dois gráficos separados sem eixo comum
Quando acontece mais?Mapa de calor (dia × hora)Linha com 168 pontos
Onde as pessoas desistem?FunilRosca
Estamos perto da meta?Bullet (barra com alvo)Velocímetro
Gráficos

Tipos principais

Os gráficos que cobrem quase todo painel. Passe o mouse para ver o tooltip; clique na legenda para ligar e desligar séries.

Frete Ásia → Santos

US$ por TEU · últimos 12 meses vs. ano anterior

Linha
Use paraTendência no tempo, até 4 séries.
EviteCategorias sem ordem (use barras).

Volume importado por modal

Mil toneladas por mês · últimos 12 meses

Área empilhada
Use paraTotal no tempo e quanto cada parte contribui.
EviteMais de 4 camadas; comparar camadas do meio.

Alertas por dia da semana

Alertas disparados · outubro

Barras
Use paraComparar poucas categorias; destaque a que importa.
EviteEixo que não começa em zero.

Embarques por porto

Mil embarques · 2024 vs. 2025

Barras agrupadas
Use paraMesmas categorias em 2 ou 3 grupos.
EviteMais de 3 barras por grupo.

Valor importado por capítulo NCM

Top 6 · US$ bilhões · 2025

Barras horizontais
Use paraRanking e rótulos longos. Ordene do maior para o menor.
EviteOrdem alfabética.

Status dos embarques por porto

% do total · outubro

Empilhada 100%
Use paraComposição comparada entre categorias.
EviteMais de 4 partes por barra.

Participação por modal

% das toneladas · 2025

Rosca
Use paraParte do todo com até 5 partes. Total no centro.
EviteComparar duas roscas; fatias parecidas.

Embarques e taxa de atraso

Barras: mil embarques · linha: % atrasados · 12 meses

Combinado
Use paraVolume e taxa da mesma coisa. Eixo da taxa à direita, na cor da linha.
EviteDuas grandezas sem relação.

Tempo de liberação × valor da carga

Dias × US$ mil · por canal de parametrização

Dispersão
Use paraRelação entre duas medidas e pontos fora da curva.
EviteMilhares de pontos em SVG (use canvas/ECharts).

Chegadas por dia e horário

Navios atracados · faixas de 2h · últimos 90 dias

Mapa de calor
Use paraPadrões em duas dimensões (dia × hora).
EviteComparar valores exatos (mostre no tooltip).

Funil de ativação

Pessoas por etapa · outubro

Funil
Use paraEtapas em sequência; mostre a conversão entre elas.
EviteEtapas que não são subconjunto da anterior.

Metas do trimestre

Valor atual, faixas ruim/ok/bom e alvo

Bullet
Use paraValor vs. meta com contexto, em pouco espaço.
EviteVelocímetro/gauge: ocupa muito e lê mal.
Gráficos

Estados, erros comuns e código

Todo gráfico precisa de três estados além do normal, e de uma biblioteca que respeite os tokens de cor.

1 · Estados
Carregando: esqueleto com a forma do gráfico, título já visível se for conhecido.
Sem dados no período

Nenhum alerta entre 1 e 13 de outubro.

Não foi possível carregar

A fonte de dados não respondeu. O resto do painel continua funcionando.

2 · Erros comuns
MarítimoRodoviárioAéreoFerroviárioOutros
Barras ordenadas: a diferença entre 5 partes fica óbvia.
Pizza com 8 fatias parecidas: ninguém compara ângulos.
0
Eixo em zero: 412 contra 438 parece o que é, +6%.
400
Eixo começando em 400: +6% parece 4 vezes maior.
  • Sem 3D, sem sombra em barras, sem gradiente colorido entre séries. A área leva só um degradê da própria cor até transparente.
  • Cor nunca é a única pista: status também aparece no tooltip e na legenda com texto; linhas de comparação são tracejadas.
  • Acessibilidade: cada gráfico tem role="img" e um aria-label com a conclusão; para dados críticos, ofereça "Ver como tabela".
  • No celular: no máximo 6 rótulos no eixo X, legenda acima do gráfico, tooltip ao tocar; barras horizontais no lugar de verticais quando os nomes são longos.
3 · Bibliotecas
ProjetoUsePor quê
Lovable / React + shadcnshadcn/ui chart (Recharts v3)Padrão de mercado para dashboards; cores via var(--chart-1…6), tema claro/escuro automático. Bom até ~5 mil pontos.
Muitos dados, tempo real, mapasApache EChartsRenderiza em canvas; aguenta dezenas de milhares de pontos e tem Sankey, treemap, mapas. Aplique os tokens no tema.
Extensão de Chrome, HTML puroSVG próprio ou uPlotSparkline e barra simples em SVG (como nesta página); uPlot para séries temporais grandes com poucos KB.
App mobileVictory Native ou EChartsMesmos tokens; tooltip por toque.
4 · Código
globals.css · tokens de gráfico
:root {            /* claro */
  --chart-1: #5246cd; --chart-2: #098585;
  --chart-3: #be7204; --chart-4: #c4334f;
  --chart-5: #2382ba; --chart-6: #61911c;
}
.dark {            /* escuro */
  --chart-1: #8d92f9; --chart-2: #49c7c0;
  --chart-3: #eeb154; --chart-4: #f2798f;
  --chart-5: #7ac8f5; --chart-6: #afd46a;
}
FreteChart.tsx · shadcn + Recharts
const config = {
  atual:    { label: "2025", color: "var(--chart-1)" },
  anterior: { label: "2024", color: "var(--chart-other)" },
} satisfies ChartConfig;

<ChartContainer config={config} className="h-56 w-full">
  <LineChart data={data}>
    <CartesianGrid vertical={false} />
    <XAxis dataKey="mes" tickLine={false} axisLine={false} />
    <ChartTooltip content={<ChartTooltipContent />} />
    <Line dataKey="anterior" stroke="var(--color-anterior)" strokeDasharray="5 4" dot={false} />
    <Line dataKey="atual" stroke="var(--color-atual)" strokeWidth={2.25} dot={false} />
  </LineChart>
</ChartContainer>
Cards

Dados e métricas

Para painéis e dashboards. O número é o protagonista, em Geist Mono; a variação vem com seta e cor de status. As regras de anatomia abaixo valem para todas as seções de cards.

MovimentoNúmeros contam até o valor ao entrar na tela. Sparklines se desenham, barras crescem em sequência e barras de meta se preenchem, uma vez só. Só card clicável sobe 2px no hover.
contagem · 800barras · slow + stagger 40hover · base · −2px
1 · Anatomia comum

Título do card

Contexto ou período
Statuscard-h · 14/18
R$ 1.284Conteúdo principal, com gap de 12px.card-b · 18
Apoiocard-f · 12/18
  • Dois modos. .card.pad (20px, gap 12) para card simples sem divisórias. .card-h/.card-b/.card-f quando há título com ação, lista ou rodapé. Card em linha (arquivo, opção, integração): 14/16px.
  • Posições fixas. Rótulo em cima, valor, depois apoio (variação, descrição). Badge de status e menu ⋯ no canto superior direito. Ações no rodapé, à direita.
  • Números. 28px Mono no valor principal; 22px em card compacto ou secundário. Variação em 12px: a cor diz se é bom ou ruim, a seta diz a direção.
  • Superfície. Borda 1px padrão. Borda colorida só para estado (selecionado, perigo). Tracejada só para "adicionar". Linha de luz em no máximo 1 card por tela.
  • Clique. Card com um destino é um <a> inteiro com .hov. Card com várias ações fica parado e cada ação é um botão. Sem .hov em card que não abre nada.
2 · KPI · simples, clicável, ao vivo, com meta
Economia no mêsR$ 342,10+18% vs. setembro
Monitorados
128+12 esta semana
Preço médioAo vivo
R$ 86,40
Meta de economia
68%R$ 342 / R$ 500
Faltam R$ 157,90 · 18 dias
3 · Gráfico e ranking

Alertas disparados

Últimos 12 meses
1.284+24,6%
NDJFMAMJJASO

Top portos por volume

TEUs · setembro
Ver todos
Santos (BRSSZ)412.380
Paranaguá (BRPNG)168.920
Itajaí (BRITJ)121.044
Rio de Janeiro (BRRIO)98.310
Manaus (BRMAO)54.702
4 · Comparativo e status com tendência
Frete Ásia → Santos
Hoje
US$ 2.140
30 dias atrás
US$ 2.610
−18,0% no período
SLA de entrega
97,8%
Tempo médio de liberação
6,1 dias
+1,4 dia vs. meta

No frete, a seta desce e a cor é verde porque cair é bom. No tempo de liberação, a seta sobe e a cor é vermelha.

Cards

Conteúdo

Para blogs, catálogos, projetos e pessoas. Se o card leva a um lugar só, ele inteiro é o link e acende no hover. Se tem várias ações, ele fica parado e cada ação é um botão.

MovimentoCard clicável sobe 2px e acende a borda; no teclado, ganha o anel de foco. Ao abrir, use View Transition para a imagem e o título viajarem até o detalhe (veja Técnicas modernas).
hover · base · −2pxfoco · anel 2+2detalhe · view transition
1 · Tipos
Tutorial
12 out 2026 · 6 min de leitura

Como montar um design system pessoal em uma tarde

Tokens, tipografia e uma assinatura visual que funciona do Lovable à extensão de Chrome.

DJDarci Junior

Monitor de fretes

Sistema web · Lovable

Acompanha cotações de frete marítimo e avisa quando a rota fica abaixo da meta.

Progresso do MVP7 / 10 tarefas
DJACMS
Em produção
−12%
Loja A · atualizado há 4 min

Monitor 27" 4K IPS

R$ 1.899R$ 2.159
Meta R$ 1.950 · atingidaAbrir na loja
AC

Ana Costa

Engenheira de dados · São Paulo
PythonSQLAirflow

Alertas em tempo real

Notificação no navegador em segundos quando o preço cruza a sua meta.

Ver como funciona
relatorio_q3.pdf
PDF · 2,4 MB · ontem
Documentação da API
docs.meuapp.dev

Arquivo tem ação interna (baixar): card parado. Link leva a um lugar só: card inteiro clicável.

2 · Card clicável
Monitor de fretes
Título é o link; o card inteiro clica
Com uma ação extra, use link esticado: o <a> do título cobre o card com ::after e o botão fica por cima (z-index).
Monitor de fretes
Card inteiro dentro de um <a>
Botão ou link dentro de <a> é HTML inválido e o leitor de tela lê tudo como um link só.
Cards

Ação e escolha

Cards que pedem uma decisão: plano, opção, integração ou próximo passo. Cada card tem uma ação clara; o plano recomendado leva a linha de luz.

MovimentoTroque Mensal/Anual: os preços saem para cima e entram por baixo. Opção selecionável acende a borda e afunda 1% no clique; integrações usam o switch com impulso. A barra do checklist acompanha cada item marcado.
preço · fast/baseseleção · basechecklist · slow
1 · Planos

Grátis

Para testar e uso pessoal.

R$ 0 /mês
  • 50 produtos
  • Alertas por e-mail
  • Histórico completo
  • API

Pro

Recomendado

Para quem vende ou monitora muito.

R$ 29 /mês
  • Produtos ilimitados
  • E-mail, navegador e WhatsApp
  • Histórico completo
  • API e webhooks

Equipe

Para times e empresas.

R$ 99 /mês
  • Tudo do Pro
  • 10 usuários
  • SSO e auditoria
  • Suporte prioritário

Um primário só, no plano recomendado. Os outros usam secundário e contorno. No celular, o recomendado vem primeiro.

2 · Opções selecionáveis

O card inteiro é o <label> do rádio: clique e setas do teclado funcionam sem JS.

3 · Integrações
WhatsAppAlertas no número (11) 9••••-4421
E-mailResumo diário às 8h
WebhookEnvie eventos para o seu sistema

Já conectada: switch liga e desliga. Ainda não conectada: botão Conectar.

4 · Chamada e próximo passo
Pro

Libere alertas por WhatsApp e histórico completo

7 dias grátis. Cancele quando quiser.

Comece seu primeiro projeto

3 de 5 passos concluídos
Cards

Listas e atividade

Para feeds curtos dentro de um painel. As linhas vão de borda a borda, sem .card-b; título à esquerda e ação em texto à direita no cabeçalho. Mostre até 5 itens e leve o resto para "Ver todas".

MovimentoItens entram em sequência (40ms) ao aparecer. "Marcar como lidas" apaga os pontos um a um. Convite enviado entra na lista na hora, antes da resposta do servidor.
stagger · 40ponto · base

Atividade

Hoje
Deploy v1.4.2 publicado
14:32
Meta do SSD alterada para R$ 650
11:08
3 produtos adicionados
09:41
Ana Costa entrou no projeto
08:15

Equipe

DJ
Darci Junior
Você
Dono
AC
Ana Costa
ana@empresa.com
Editor
MS
Maria Silva
maria@empresa.com
Leitor
?
pedro@empresa.com
Convite enviado
Pendente

Linha que abre algo é um <a> e acende no hover (Notificações). Linha que só informa não reage ao mouse (Equipe). Não lidas: texto em --text e ponto índigo; lidas: texto em --text-2.

Cards

Sistema e estados

Status de serviço, configuração e perigo, mais os estados que todo card de dados precisa ter: carregando, erro, vazio e bloqueado. Cada estado ocupa o mesmo tamanho do card pronto, para a tela não pular.

MovimentoPonto de status ao vivo pulsa (único loop permitido). Rodapé de salvar aparece só quando há alteração, subindo 8px. Esqueleto troca para o conteúdo com fade.
pulse · looprodapé · base · y 8esqueleto → conteúdo · base
1 · Status, configuração e perigo

Status dos serviços

Instável
API99,99%OK
Coleta de preços99,2%Lenta
Envio de alertas100%OK

Meta de preço

Avisamos quando o preço ficar abaixo.
R$
Alterações não salvas

Zona de perigo

Excluir o projeto apaga os 128 produtos e todo o histórico. Não dá para desfazer.

O badge do cabeçalho mostra o pior status da lista. Zona de perigo fica no fim da página de configurações e abre a confirmação (veja Modal).

2 · Estados de um card
Carregando dados…

Recurso do plano Pro

Histórico além de 30 dias

Erro fica dentro do card que falhou, nunca derruba a tela. Espaço vazio que adiciona algo é um <button> tracejado.

Páginas

Login

Duas colunas: formulário à esquerda, mensagem do produto à direita com a linha de luz. O formulário é a tela inteira; a coluna da marca é opcional e some no celular.

MovimentoEntrar vira spinner e depois check (clique em Entrar). Erro de senha usa a mesma tremida do campo. A coluna da marca fica parada.
botão · fasterro · slow
app.orbita.dev/entrar
Órbita

Entrar na sua conta

Use o e-mail da sua conta Órbita.

ou

Não tem conta? Criar conta grátis

© 2026 Órbita · Termos · Privacidade
Novo · alertas por WhatsApp

Seus preços monitorados em tempo real

Economia no mês+18%
R$ 342,10
Grade e larguras

Duas colunas iguais. Na do formulário, marca no topo, formulário no meio e rodapé legal embaixo. Formulário com até 340px.

Celular · até 900px

A coluna da marca some. O formulário ocupa a largura com margem de 16px, botões em btn-lg (44px).

Erros e acesso

Uma mensagem só, acima de Entrar: "E-mail ou senha incorretos." Use <form>, type="email" e autocomplete para Enter e gerenciador de senhas funcionarem.

Páginas

Onboarding

Um passo por tela, stepper no topo, opções como cards selecionáveis. Voltar e Continuar ficam no mesmo lugar em todos os passos.

MovimentoAvançar desliza o conteúdo para a esquerda; voltar, para a direita. O stepper preenche junto. Use Continuar e Voltar.
sai · fast · x −16entra · base · x 16
app.orbita.dev/comecar
Órbita
Conta
Empresa
3Alertas
4Pronto

Como você quer ser avisado?

Dá para mudar depois em Configurações.

%
Grade e larguras

Coluna única centralizada de até 620px, sem menu lateral. Topo só com marca e Pular. Ações num rodapé com divisória: Voltar à esquerda, Continuar à direita.

Celular · até 640px

Stepper vira texto "Passo 3 de 4" com barra de progresso. Cards empilham. Rodapé de ações fica preso no fim da tela, com Continuar em largura total.

Fluxo e acesso

No máximo 4 passos, cada um com uma pergunta. Ao avançar, o foco vai para o título do passo. Pular sempre visível; nada aqui deve ser obrigatório para usar o produto.

Páginas

Dashboard

Menu lateral na variante app de Navegação lateral, barra superior com busca, cabeçalho da página com o único primário, KPIs (um com linha de luz), gráfico e lista.

MovimentoAo abrir: KPIs contam, barras crescem e alertas entram em sequência. O indicador do item ativo cresce ao trocar de item (clique no menu).
contagem · 800barras · staggermenu · base
app.orbita.dev/visao-geral
⌘K

Visão geral

Atualizado há 4 min
EconomiaR$ 342,10+18%
Monitorados128+12
Alertas32 sem resposta
Abaixo da meta1713% do total

Economia por semana

S1S2S3S4S5S6S7S8

Alertas recentes

Ver todos
Monitor 27" −12%
4 min
SSD 2TB +6,5%
1 h
Link quebrado
ontem
Grade e larguras

Menu de 260px (64px recolhido) + conteúdo fluido. Barra superior de 56px. Corpo com 24px de margem: KPIs em 4 colunas, gráfico 1,6fr ao lado da lista 1fr. Acima de 1440px o conteúdo para de crescer e centraliza.

Celular · até 900px

O menu vira gaveta, aberta por um botão na barra superior. KPIs em 2×2; gráfico e lista empilham. No cabeçalho fica só o primário; o filtro de período vai para um menu.

Regras da tela

Um primário, no cabeçalho da página. Linha de luz só no KPI principal; KPIs não são clicáveis, então não têm hover. Perfil e plano ficam no rodapé do menu, como em Navegação lateral.

Páginas

Landing page

Herói com linha de luz, prova em números, recursos em cards e chamada final. A ação principal repete com o mesmo texto; só o herói e a chamada final a mostram como primário.

MovimentoVarredura da linha de luz no herói, uma vez. Números contam e cards de recursos entram em sequência ao rolar até eles. Nada de parallax.
varredura · 900 · 1×recursos · stagger 40
orbita.dev
NovoAlertas por WhatsApp

Pare de atualizar a página do produto

A Órbita monitora preços em qualquer loja e avisa no segundo em que cai abaixo da sua meta.

Sem cartão · 50 produtos grátis
2,3 mi
preços verificados por dia
15 min
intervalo entre checagens
R$ 186
economia média por usuário/mês

Cole o link

Funciona com as principais lojas do Brasil.

Defina a meta

Escolha o preço que vale a compra.

Receba o alerta

No navegador, por e-mail ou WhatsApp.

Comece a economizar hoje

Leva menos de um minuto.

Criar conta grátis
Grade e larguras

Contêiner de até 1120px. Herói centralizado: título com até 13ch, texto com até 46ch. Blocos separados por 48–72px; números em faixa de 3 colunas, recursos em 3 cards.

Celular · até 640px

Links do topo viram menu; ficam a marca e Entrar. Título de 54 para 36px. Botões do herói empilham em largura total. Números e recursos em 1 coluna.

Regras da página

Linha de luz só no herói e na chamada final. No topo, a mesma ação fica secundária para não competir com o herói. Tudo que leva a outra página é <a>, mesmo com cara de botão. Cards informativos não têm hover.

Páginas

Configurações

Abas no topo, cada grupo com título à esquerda e card à direita, zona de perigo no fim. Campos de texto salvam pelo rodapé do card; switch e segmentado salvam na hora.

MovimentoIndicador das abas desliza; o segmentado de tema desliza o fundo. Salvar mostra o progresso e confirma (clique nele).
abas · basesalvar · fast
app.orbita.dev/configuracoes

Configurações

Perfil

Como você aparece para a equipe.

DJ
Alterações não salvas

Preferências

Aparência e e-mails. Salva na hora e avisa com um toast.

Tema
Escuro é o padrão
Toda segunda às 8h

Zona de perigo

Ações que não dá para desfazer.

Excluir conta

Apaga todos os projetos e dados.

Grade e larguras

Conteúdo de até 960px. Grade de 240px (título e explicação) + card. Dentro do app, ocupa a área de conteúdo do Dashboard com Configurações ativo no menu; aqui aparece sem o menu.

Celular · até 640px

Abas rolam na horizontal. O título de cada grupo sobe para cima do card. Campos em 1 coluna; no rodapé, Salvar ocupa a largura e o status fica acima.

Salvar e excluir

Rodapé do card: status à esquerda, Descartar e Salvar à direita, ativos só com alteração pendente. Excluir conta é destrutivo suave; o sólido aparece só no modal que confirma.

Páginas

Artigo de blog

Coluna de leitura com cerca de 65 caracteres, corpo em 17px, sumário lateral fixo e código no mesmo estilo do sistema. O texto é o produto: nada de primário na página.

MovimentoBarra de progresso de leitura ligada à rolagem (CSS animation-timeline, demo em Técnicas modernas) e cabeçalho com vidro fosco ao rolar. O sumário destaca a seção atual. O texto não anima.
leitura · linear · scroll
blog.orbita.dev/design-system-pessoal
Tutorial12 out 2026 · 6 min

Como montar um design system pessoal em uma tarde

Cada projeto novo começava do zero. Uma base fixa resolve isso e deixa o tempo para o problema que o produto resolve.

DJ
Darci Junior
Engenharia e produto

1. Comece pelos cinzas

Num tema escuro, quase tudo na tela é cinza. Escolha um fundo, duas superfícies e duas bordas com um leve tom frio, e a interface já parece intencional antes de qualquer cor de marca.

tokens.css
--bg: #0e0e14;
--surface: #16161d;
--primary: #6357f0;
Se tudo brilha, nada se destaca.
Grade e larguras

Contêiner de 960px: artigo de até 640px (cerca de 65 caracteres em 17px) + sumário de 200px preso ao rolar. Corpo 17/1,7; título de seção 22px com respiro extra acima.

Celular · até 900px

O sumário sai da lateral e vira "Nesta página" recolhível acima do texto. Título de 40 para 30px, margens de 16px. Código rola dentro do bloco, nunca a página.

Leitura e acesso

Um h1 por artigo e níveis sem pular. Links no corpo sublinhados. Assinar é secundário; a única chamada forte, se houver, vai no fim do artigo.

Páginas

Popup de extensão

360px de largura, cabeçalho compacto, ação principal visível sem rolar. Ao lado, o estado vazio do mesmo popup.

MovimentoO popup abre já completo, sem entrada nem contagem (o Chrome já anima a janela). Só o item recém-adicionado anima: entra no topo da lista com fundo índigo que some em seguida.
item novo · base · y 8destaque · slow
Órbita
3 alertas
Nesta páginaTeclado mecânico TKL
R$ 459,90Sem histórico
R$
MonitorandoVer todos (128)
Monitor 27" 4K
R$ 1.899
−12%
SSD NVMe 2TB
R$ 799
+6,5%
Órbita
Nenhum produto nesta página

Abra a página de um produto em uma loja para monitorar o preço.

Ver lojas compatíveis
Grade e larguras

Largura fixa de 360px (o Chrome aceita até 800×600). Cabeçalho de 48px; corpo com 14px de margem e 12px entre blocos. Tudo em uma coluna.

Altura e rolagem

Produto atual, meta e Monitorar ficam sempre visíveis. Se a lista passar do limite de 600px, só ela rola. Itens que abrem a página do produto são <a>.

Estados obrigatórios

Produto encontrado, vazio (ao lado), carregando (esqueleto do card, não spinner) e sem acesso à página, com o botão que pede a permissão.

Páginas

Página 404

Diz o que aconteceu em uma frase, sem culpar a pessoa, e oferece o caminho de volta. Dentro do app, mantenha o menu lateral para ninguém ficar perdido.

MovimentoSem animação, de propósito: a mensagem precisa ser lida na hora.
app.orbita.dev/produto/9f2a

Esta página não existe mais

O produto pode ter sido removido ou o link está incompleto.

Grade e larguras

Uma coluna centralizada na altura da tela, texto com até 42ch. No app, ocupa só a área de conteúdo, com menu e barra superior no lugar.

Celular · até 640px

Número de 88 para 64px. Botões empilham em largura total (btn-lg), primário em cima.

Regras

Responda com status HTTP 404 de verdade, sem redirecionar. Mantenha a URL errada na barra. Ir para o início é o único primário; Buscar é secundário.

Referência

Para IA: consulte o design system

Ferramentas de IA não precisam de um prompt colado: elas leem as páginas do design system direto da web. Aponte a IA para o índice e ela busca só o que a tarefa pede. Os arquivos de tokens continuam sendo a fonte da verdade.

O que consultar
Índice

https://design.mypersonalhub.com.br/llms.txt lista as páginas da camada IA (fundamentos, movimento, tokens, componentes) com um resumo de cada uma.

Tudo de uma vez

https://design.mypersonalhub.com.br/llms-full.txt reúne todas as páginas em um só texto, para ferramentas que não navegam por links.

Tokens

Para o código, use tokens.css, shadcn-globals.css, tailwind.config.js e motion.ts. As páginas explicam o porquê; os arquivos trazem os valores.

Como usar
Lovable

Na primeira mensagem ou no conhecimento do projeto (Knowledge), peça para seguir o design system em llms.txt. Depois peça para aplicar shadcn-globals.css e tailwind.config.js.

Cursor ou Claude Code

Adicione uma linha ao arquivo de regras (.cursor/rules ou CLAUDE.md) apontando para o llms.txt, ao lado dos arquivos de tokens.

Chat avulso

Envie o link do llms.txt (ou do llms-full.txt) e peça para consultá-lo antes de montar a tela.

regra-para-ia.txt
Siga o design system "Índigo + Linha de luz".
Antes de montar qualquer tela, consulte https://design.mypersonalhub.com.br/llms.txt
e leia as páginas relevantes (use llms-full.txt se não conseguir navegar pelos links).
No código use SEMPRE os tokens/classes (bg-primary, var(--color-primary)…), nunca hex solto.
Esc
Ações
Ir para