UI

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

TokenQuando usar
background / foregroundFundo da página e texto principal.
card / card-foregroundCartões e painéis.
popover / popover-foregroundMenus, popovers, listas suspensas.
surfaceSeções alternadas da página.
surface-elevatedConteúdo que fica acima de uma surface.

Ação

TokenQuando usar
primary / primary-foregroundA ação principal da tela. Uma por contexto.
secondary / secondary-foregroundAções de apoio. Com --secondary, é a segunda cor da marca; sem ela, um neutro.
accent / accent-foregroundHover e seleção sutis em listas e menus.
muted / muted-foregroundFundos discretos e texto secundário (legendas, ajuda).
linkA cor da marca usada como texto: links, ícones de destaque.

Estados

TokenQuando usar
destructive / destructive-foregroundErro, exclusão, ação irreversível.
success / success-foregroundConfirmação, operação concluída.
warning / warning-foregroundAlerta que pede atenção.
info / info-foregroundInformação neutra.

Linhas e foco

TokenQuando usar
borderBordas e divisores.
inputBorda de campos de formulário.
ringAnel de foco por teclado.
focusMarca de foco da identidade (o ciano Lens). Nunca como cor de texto.
overlayVéu atrás de modais e sheets.

Dados

TokenQuando usar
chart-1 … chart-5Séries de gráficos, na ordem.
TokenQuando usar
sidebar / sidebar-foregroundFundo e texto da navegação lateral de sistemas.
sidebar-primary / sidebar-primary-foregroundItem ativo.
sidebar-accent / sidebar-accent-foregroundHover de item.
sidebar-border, sidebar-ringDivisores 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.

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-primary sobre fundo neutro.

Fontes e raio

Estes tokens não mudam entre claro e escuro.

TokenUtilitárioUso
--font-bodyfont-sansTexto corrido e interface.
--font-displayfont-headingTítulos (h1 a h4 já recebem).
--font-codefont-monoCódigo e números. Em painéis, use com tabular-nums.
--radiusrounded-sm … rounded-2xlRaio 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

AmostraTokenValor atual
--background…
--foreground…
--card…
--card-foreground…
--popover…
--popover-foreground…
--surface…
--surface-elevated…

Ação

AmostraTokenValor atual
--primary…
--primary-foreground…
--secondary…
--secondary-foreground…
--accent…
--accent-foreground…
--muted…
--muted-foreground…
--link…

Estados

AmostraTokenValor atual
--destructive…
--destructive-foreground…
--success…
--success-foreground…
--warning…
--warning-foreground…
--info…
--info-foreground…

Linhas e foco

AmostraTokenValor atual
--border…
--input…
--ring…
--focus…
--overlay…

Dados

AmostraTokenValor atual
--chart-1…
--chart-2…
--chart-3…
--chart-4…
--chart-5…

Sidebar

AmostraTokenValor 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çãoO que faz
--nameObrigatória. Slug do tema. Vira data-theme="<name>" e o item theme-<name> no registry.
--primaryObrigatória em tema novo. Cor principal: hex, rgb(), hsl() ou oklch().
--labelNome legível, exibido no seletor de temas.
--descriptionDescrição do tema no registry.
--secondarySegunda cor da marca. Sem ela, secondary é um neutro.
--accentCor de hover e seleção. Padrão: derivada da primária.
--neutralBase dos cinzas. Padrão: cinza levemente tingido pela primária.
--neutral-chromaIntensidade do tingimento dos cinzas quando não há --neutral. Padrão 0.012; 0 é cinza puro.
--focusMarca de foco. Padrão: a primária clareada.
--radiusRaio base. Padrão 0.625rem.
--font-body, --font-display, --font-codePilhas de fonte do texto, dos títulos e do código.
--dry-runMostra 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.

packages/tokens/themes/clinica-sorriso.theme.json
{
  "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:build

Overrides 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

ArquivoConteúdo
packages/tokens/themes/<name>.cssVariáveis do tema em claro e escuro.
packages/tokens/themes/index.css e manifest.jsonLista de todos os temas (usada pelo seletor deste site).
packages/tokens/themes/CONTRAST.mdRelatório de contraste de todos os temas.
packages/tokens/css/theme.cssMapeamento dos tokens para o Tailwind.
packages/registry/registry/lenstech/_items/tokens.jsonItens 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:

ElementoMínimoPares verificados
Texto4.5:1foreground, muted-foreground e link sobre background; link sobre card; cada X-foreground sobre X
Foco3:1ring sobre background
Borda de campo1.5:1input 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 link até 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.

On this page