Tailwind CSS
Use o Camaleo junto com o Tailwind CSS v4. Ponha as camadas na ordem certa, transforme os tokens em utilitários e deixe o estilo fazer o trabalho dele.
// você vai aprender
- Onde as camadas do Camaleo entram entre as do Tailwind, e por que a ordem importa
- Como usar os tokens
--cml-*como valores do tema do Tailwind - Como chegar a uma parte de um componente pelo
data-slot - O que estilizar com utilitários e o que deixar para o estilo
O Camaleo não precisa do Tailwind: os estilos são CSS puro. Se o seu app já usa o Tailwind v4, os dois funcionam juntos com poucas linhas na folha de estilo principal. Não há plugin nem preset para instalar.
Ordene as camadas
Todo o CSS do Camaleo fica em quatro camadas: cml.tokens, cml.components, cml.style e cml.preferences. O Tailwind v4 usa theme, base, components e utilities. A camada declarada primeiro perde, então declare a ordem inteira uma vez, antes dos imports:
@layer theme, base, cml, components, utilities;
@import "tailwindcss";
@import "@camaleo/styles/base.css";
@import "@camaleo/styles/glass.css";Com essa ordem:
- O reset do Tailwind (Preflight, em
base) fica abaixo do Camaleo, então nunca achata os botões ou campos de um estilo. - Os seus utilitários ficam acima do Camaleo, então
className="mt-6 w-full"num componente vence o espaçamento e a largura dele. - O CSS sem camada que você escreve continua vencendo tudo.
Sem a primeira linha, quem decide é a ordem dos imports: as camadas do Camaleo vêm depois das do Tailwind e vencem até os seus utilitários, e um className="w-full" num Button parece não fazer nada.
Transforme tokens em valores do tema
Mapeie os tokens que você quer como utilitários num bloco @theme inline. Os nomes abaixo usam o prefixo cml- para nunca colidir com a paleta do Tailwind:
@theme inline {
--color-cml-surface: var(--cml-surface);
--color-cml-raised: var(--cml-surface-raised);
--color-cml-fg: var(--cml-fg);
--color-cml-fg-secondary: var(--cml-fg-secondary);
--color-cml-border: var(--cml-border);
--color-cml-accent: var(--cml-accent);
--color-cml-accent-fg: var(--cml-accent-fg);
--color-cml-accent-text: var(--cml-accent-text);
--color-cml-danger: var(--cml-danger);
--radius-cml-control: var(--cml-radius-control);
--radius-cml-surface: var(--cml-radius-surface);
--font-cml-body: var(--cml-font-body);
--font-cml-display: var(--cml-font-display);
}Agora existem bg-cml-surface, text-cml-fg-secondary, border-cml-border, rounded-cml-surface e font-cml-display, e cada um segue o estilo, o modo e a marca do StyleProvider mais próximo:
<aside className="rounded-cml-surface border border-cml-border bg-cml-raised p-6">
<h2 className="font-cml-display text-cml-fg">Seu plano</h2>
<p className="text-cml-fg-secondary">Renova em 12 de novembro.</p>
</aside>
O inline faz diferença. Sem ele, o Tailwind declara --color-cml-surface no :root, onde ele é resolvido uma vez, com o estilo da raiz. Com inline, o utilitário escreve o próprio var(--cml-surface), e uma ilha em outro estilo ganha o valor dela.
Estilize as partes pelo data-slot
Toda parte de todo componente tem um data-slot estável, e o estado vem em atributos de dados (data-active, data-checked, data-disabled…). As variantes de dados do Tailwind chegam neles direto:
{/* Um estado do próprio elemento */}
<Tab value="billing" className="data-active:font-semibold">Cobrança</Tab>
{/* Uma parte dentro do componente */}
<Card className="[&_[data-slot=card-title]]:text-lg">…</Card>
{/* Um token, só para este elemento */}
<Button className="[--cml-radius-control:0px]">Exportar</Button>
Cada página de componente lista slots, atributos de estado e tokens na seção Styling hooks.
Não brigue com o estilo
Utilitários são para o seu layout: margens, larguras, posição no grid, espaçamentos e a página em volta dos componentes. Isso não muda de um estilo para outro.
A aparência de um componente (cores, raio, bordas, sombras, fontes) é do estilo. Se você pinta um Button com bg-blue-600 rounded-full shadow-lg, ele para de mudar com o estilo, ignora a marca e o modo escuro, e o contraste dele deixa de ser conferido pelos testes da biblioteca.
| Quer | Em vez de | Use |
|---|---|---|
| Um controle mais redondo | rounded-full | [--cml-radius-control:999px] |
| A cor da marca | bg-blue-600 text-white | bg-cml-accent text-cml-accent-fg |
| Texto mais apagado | text-gray-500 | text-cml-fg-secondary |
| Mudar só um estilo | in-data-[style=retro]:… | uma regra @scope no CSS |
O guia Sobrescritas com escopo mostra como escrever essas regras.
Uma variante como in-data-[style=retro]:uppercase vale para qualquer ancestral retro, inclusive um que fica fora de uma ilha aninhada em outro estilo. As regras de estilo do próprio Camaleo usam @scope ([data-style="retro"]) to ([data-style]), que para na ilha seguinte.
Modo escuro
Os tokens já trocam com o modo (usam light-dark()), então bg-cml-surface não precisa da variante dark:. O dark: do Tailwind segue o sistema por padrão. Se você define o mode e precisa do dark: para as suas cores, aponte a variante para o data-mode:
@custom-variant dark (&:where([data-mode=dark], [data-mode=dark] *));Essa variante só enxerga um mode="dark" explícito. Com mode="system" ou sem modo, mantenha o padrão do Tailwind, ou use tokens.
Antes de publicar
@layer theme, base, cml, components, utilities;vem antes de qualquer@import- Os tokens são mapeados com
@theme inline, não com@themesimples - Utilitários em componentes só cuidam de layout e espaçamento
- Mudanças de um estilo só ficam em regras
@scope, não em variantesin-data-[style=…] - As cores que você acrescenta vêm de tokens, então seguem o modo e a marca