Temas
Tokens semânticos, o gerador de temas por cliente e a garantia de contraste AA.
Um tema é um conjunto de valores para os mesmos tokens, em claro e em escuro. Os componentes usam só os tokens
(bg-primary, text-link, border-border). Trocar o tema troca a marca inteira sem editar nenhum componente.
Experimente
Clique em um tema para aplicar ao site inteiro, inclusive a esta documentação. Os exemplos são temas reais do registry, gerados a partir de uma a três cores.
Como os tokens funcionam
Cada token é uma variável CSS (--primary) que o lenstech-base expõe como cor do Tailwind (bg-primary,
text-primary, border-primary, ring-primary…). Os nomes seguem o shadcn/ui, então qualquer componente shadcn
funciona com um tema Lens. Acrescentamos surface, link, os estados success, warning e info, focus e
overlay.
<div className="rounded-lg border bg-card p-6 text-card-foreground">
<h3 className="font-heading">Plano mensal</h3>
<p className="text-muted-foreground">Cobrança todo dia 10.</p>
<a className="text-link underline">Ver contrato</a>
</div>Superfícies
| Token | Quando usar |
|---|---|
background / foreground | Fundo da página e texto principal. |
card / card-foreground | Cartões e painéis. |
popover / popover-foreground | Menus, popovers, listas suspensas. |
surface | Seções alternadas da página. |
surface-elevated | Conteúdo que fica acima de uma surface. |
Ação
| Token | Quando usar |
|---|---|
primary / primary-foreground | A ação principal da tela. Uma por contexto. |
secondary / secondary-foreground | Ações de apoio. Com --secondary, é a segunda cor da marca; sem ela, um neutro. |
accent / accent-foreground | Hover e seleção sutis em listas e menus. |
muted / muted-foreground | Fundos discretos e texto secundário (legendas, ajuda). |
link | A cor da marca usada como texto: links, ícones de destaque. |
Estados
| Token | Quando usar |
|---|---|
destructive / destructive-foreground | Erro, exclusão, ação irreversível. |
success / success-foreground | Confirmação, operação concluída. |
warning / warning-foreground | Alerta que pede atenção. |
info / info-foreground | Informação neutra. |
Linhas e foco
| Token | Quando usar |
|---|---|
border | Bordas e divisores. |
input | Borda de campos de formulário. |
ring | Anel de foco por teclado. |
focus | Marca de foco da identidade (o ciano Lens). Nunca como cor de texto. |
overlay | Véu atrás de modais e sheets. |
Dados
| Token | Quando usar |
|---|---|
chart-1 … chart-5 | Séries de gráficos, na ordem. |
Sidebar
| Token | Quando usar |
|---|---|
sidebar / sidebar-foreground | Fundo e texto da navegação lateral de sistemas. |
sidebar-primary / sidebar-primary-foreground | Item ativo. |
sidebar-accent / sidebar-accent-foreground | Hover de item. |
sidebar-border, sidebar-ring | Divisores e foco dentro da sidebar. |
Pares de fundo e texto
Todo token com par -foreground funciona assim: o token sem sufixo é o fundo, o -foreground é o texto que vai
sobre ele. Use sempre os dois juntos.
<span className="bg-success text-success-foreground">Pago</span>O gerador garante contraste AA entre cada par. Misturar pares (bg-primary text-muted-foreground) não tem garantia.
A regra do link
primary foi feito para ser fundo. Uma primária clara, como um amarelo, passa com texto escuro por cima, mas
some como texto sobre branco. Por isso existe link: a cor da marca ajustada para ser lida sobre background e
card.
- Texto na cor da marca sobre fundo neutro:
text-link. - Nunca
text-primarysobre fundo neutro.
Fontes e raio
Estes tokens não mudam entre claro e escuro.
| Token | Utilitário | Uso |
|---|---|---|
--font-body | font-sans | Texto corrido e interface. |
--font-display | font-heading | Títulos (h1 a h4 já recebem). |
--font-code | font-mono | Código e números. Em painéis, use com tabular-nums. |
--radius | rounded-sm … rounded-2xl | Raio base. rounded-lg é o valor exato; os outros somam ou subtraem. |
Valores no tema ativo
Todos os tokens do contrato, com o valor calculado agora. Mude o tema ou o modo e a tabela acompanha.
Tema neutro, modo claro. Troque o tema acima ou no seletor do topo e os valores se atualizam.
Superfícies
| Amostra | Token | Valor atual |
|---|---|---|
| --background | … | |
| --foreground | … | |
| --card | … | |
| --card-foreground | … | |
| --popover | … | |
| --popover-foreground | … | |
| --surface | … | |
| --surface-elevated | … |
Ação
| Amostra | Token | Valor atual |
|---|---|---|
| --primary | … | |
| --primary-foreground | … | |
| --secondary | … | |
| --secondary-foreground | … | |
| --accent | … | |
| --accent-foreground | … | |
| --muted | … | |
| --muted-foreground | … | |
| --link | … |
Estados
| Amostra | Token | Valor atual |
|---|---|---|
| --destructive | … | |
| --destructive-foreground | … | |
| --success | … | |
| --success-foreground | … | |
| --warning | … | |
| --warning-foreground | … | |
| --info | … | |
| --info-foreground | … |
Linhas e foco
| Amostra | Token | Valor atual |
|---|---|---|
| --border | … | |
| --input | … | |
| --ring | … | |
| --focus | … | |
| --overlay | … |
Dados
| Amostra | Token | Valor atual |
|---|---|---|
| --chart-1 | … | |
| --chart-2 | … | |
| --chart-3 | … | |
| --chart-4 | … | |
| --chart-5 | … |
Sidebar
| Amostra | Token | Valor atual |
|---|---|---|
| --sidebar | … | |
| --sidebar-foreground | … | |
| --sidebar-primary | … | |
| --sidebar-primary-foreground | … | |
| --sidebar-accent | … | |
| --sidebar-accent-foreground | … | |
| --sidebar-border | … | |
| --sidebar-ring | … |
Criar o tema de um cliente
Temas são criados neste repositório, com o CLI do pacote @lenstech/tokens. Uma cor basta:
pnpm theme --name clinica-sorriso --primary "#0EA5E9"Com mais informações da marca:
pnpm theme --name clinica-sorriso --label "Clínica Sorriso" \
--primary "#0EA5E9" --secondary "#F97316" --neutral "#334155" \
--focus "#22D3EE" --radius 0.75rem --font-display "'Poppins', sans-serif"| Opção | O que faz |
|---|---|
--name | Obrigatória. Slug do tema. Vira data-theme="<name>" e o item theme-<name> no registry. |
--primary | Obrigatória em tema novo. Cor principal: hex, rgb(), hsl() ou oklch(). |
--label | Nome legível, exibido no seletor de temas. |
--description | Descrição do tema no registry. |
--secondary | Segunda cor da marca. Sem ela, secondary é um neutro. |
--accent | Cor de hover e seleção. Padrão: derivada da primária. |
--neutral | Base dos cinzas. Padrão: cinza levemente tingido pela primária. |
--neutral-chroma | Intensidade do tingimento dos cinzas quando não há --neutral. Padrão 0.012; 0 é cinza puro. |
--focus | Marca de foco. Padrão: a primária clareada. |
--radius | Raio base. Padrão 0.625rem. |
--font-body, --font-display, --font-code | Pilhas de fonte do texto, dos títulos e do código. |
--dry-run | Mostra os tokens gerados no terminal, sem gravar nada. |
Rodar de novo com o mesmo --name atualiza o tema e mantém o que não foi passado.
Ajustes finos no JSON
O comando grava packages/tokens/themes/<name>.theme.json. Para fixar um token específico, use overrides, por
modo. É assim que o tema lenstech segue o manual de marca.
{
"name": "clinica-sorriso",
"label": "Clínica Sorriso",
"primary": "#0EA5E9",
"secondary": "#F97316",
"radius": "0.75rem",
"fonts": { "display": "'Poppins', sans-serif" },
"overrides": {
"light": { "surface": "#F0F9FF" },
"dark": { "background": "#0B1220" }
}
}Depois de editar o JSON, gere de novo:
pnpm tokens:buildOverrides não são corrigidos
O gerador respeita o valor que você fixar, mesmo que ele reprove no contraste. Confira o relatório depois de cada ajuste.
O que é gerado
| Arquivo | Conteúdo |
|---|---|
packages/tokens/themes/<name>.css | Variáveis do tema em claro e escuro. |
packages/tokens/themes/index.css e manifest.json | Lista de todos os temas (usada pelo seletor deste site). |
packages/tokens/themes/CONTRAST.md | Relatório de contraste de todos os temas. |
packages/tokens/css/theme.css | Mapeamento dos tokens para o Tailwind. |
packages/registry/registry/lenstech/_items/tokens.json | Itens lenstech-base e theme-<name> do registry. |
Não edite esses arquivos à mão. Eles são sobrescritos a cada build.
Garantia de contraste
Todo tema precisa passar no nível AA da WCAG 2.2:
| Elemento | Mínimo | Pares verificados |
|---|---|---|
| Texto | 4.5:1 | foreground, muted-foreground e link sobre background; link sobre card; cada X-foreground sobre X |
| Foco | 3:1 | ring sobre background |
| Borda de campo | 1.5:1 | input sobre background |
Para chegar lá, o gerador:
- escolhe texto claro ou escuro para cada cor de fundo;
- ajusta a luminosidade da primária quando nenhum texto atinge 4.5:1, e avisa no terminal;
- escurece ou clareia
linkaté ele funcionar como texto.
Testamos o gerador com 500 cores primárias aleatórias: nenhuma falha de contraste. Tudo é calculado em OKLCH, então o ajuste muda a luminosidade e preserva o tom da marca.
O relatório não cobre texto sobre imagens, cores fora dos tokens e combinações novas (como bg-primary/10 com
text-link). Nesses casos, confira manualmente.
Entregar ao projeto do cliente
Envie o tema para a branch main. O deploy publica o item theme-<name> no registry (veja Registry).
No projeto do cliente:
npx shadcn@latest add @lenstech/lenstech-base @lenstech/theme-clinica-sorriso<html lang="pt-BR" data-theme="clinica-sorriso">O CLI grava as cores do tema no CSS do projeto, em :root (claro) e .dark (escuro). Carregue as fontes do tema como
na instalação.