Tematização
Como o tema está montado — componentes próprios, uma camada de tokens e um modo escuro que comuta por classe.
O tema não é uma dependência que se configura. É um conjunto de ficheiros que a camada possui, construído sobre shadcn-vue e Tailwind 4 — e a razão dessa forma decide quanto te custa substituir algo.
Alterar algo é Substituir o tema. Esta página explica por que as costuras estão onde estão.
Os componentes são copiados, não importados
O shadcn-vue não é uma biblioteca de componentes que se instala. A sua CLI escreve
o código-fonte de um componente no teu projeto e, a partir daí, o ficheiro é teu. A
camada guarda as suas primitivas em app/components/ui/, e o components.json
aponta a CLI para esse alias, portanto acrescentar uma é um único comando.
Seguem-se duas consequências, e vão em direções opostas:
- Podes alterar tudo, sem bifurcar. Um componente que queres diferente é um ficheiro que editas — não há um upstream contra o qual lutar, nem uma API de tema onde procurar uma brecha.
- Nada se atualiza sozinho. Uma correção a montante numa primitiva chega-te quando voltas a correr a CLI para ela, não quando uma dependência sobe de versão. A camada assume esse custo pelas suas próprias primitivas; um componente que substituis no teu projeto, assumes tu.
Essa troca é toda a razão do terceiro nível do guia de substituição: a alteração mais pequena que resolve a tarefa é a certa, porque um componente que substituis é um componente que passas a manter.
Por que shadcn-vue em vez de um tema de documentação já feito está registado no ADR 0008.
Uma camada de tokens, duas folhas de estilo
A paleta são propriedades personalizadas de CSS em oklch, definidas uma vez em
:root e redefinidas em .dark. Cada componente lê um token; nenhum guarda uma
cor. É isso que torna possível uma substituição de uma linha — redefines
--primary na tua própria folha de estilo e todas as superfícies que o usam
acompanham.
Dois ficheiros a sustentam, e não são intermutáveis:
| Ficheiro | Contém |
|---|---|
app/assets/css/duxt.css | A paleta, a entrada do Tailwind, a predefinição da camada — o ficheiro que lês |
app/assets/css/typeset.css | O typeset do shadcn, copiado tal e qual — o ficheiro que não editas |
Atrás de typeset.css não há entrada de registo, por isso a CLI não o consegue
obter nem atualizar. Atualizar significa descarregar o ficheiro outra vez, e é por
isso que as alterações locais pertencem à predefinição de duxt.css: uma edição
feita em typeset.css é uma que a próxima atualização descarta em silêncio.
O modo escuro é uma classe, não uma media query
@custom-variant dark (&:is(.dark *)) — o tema comuta com uma classe dark, e o
@nuxtjs/color-mode põe exatamente essa classe porque a camada o configura com
classSuffix: ''.
Este é o pormenor em que se tropeça ao substituir uma cor. Um token definido apenas
sob @media (prefers-color-scheme: dark) nunca é lido, e um token definido uma vez
em :root serve nos dois modos — ou seja, está errado num deles. Redefine nos dois
blocos, ou aceita que um dos modos fique com o valor da camada.
A paleta afasta-se do padrão do shadcn, de propósito
--muted-foreground é aqui mais escuro do que o conjunto neutro do shadcn o
entrega. Esse token leva as descrições de página, o índice e a navegação estrutural,
e com o valor do shadcn mede abaixo dos 4,5:1 que a WCAG AA pede nas superfícies em
que realmente assenta.
Nenhuma verificação feita num navegador o apanha: uma passagem de acessibilidade
sobre as páginas construídas não tem cor calculada para medir. A camada mede, por
isso, os próprios tokens, em tests/contrast.test.ts, emparelhando cada cor de
primeiro plano com os fundos em que é de facto usada. Se substituíres um token de
primeiro plano, assumes essa garantia — o teste lê o ficheiro da camada, não o teu.
É preciso dizer ao Tailwind onde está a camada
@source '../../../app' está no início de duxt.css e não é enfeite. O Tailwind
procura nomes de classe a partir da raiz de compilação, que é a diretoria do
projeto consumidor. A camada vive fora dela, em node_modules, portanto sem essa
linha faltaria no CSS gerado cada utilitário usado por um componente da camada: um
site que apresenta sem estilo nenhum.
O caminho é relativo à folha de estilo, pelo que vale onde quer que o pacote esteja instalado.
O que isto significa para ti
- Uma cor, um raio, um tipo de letra: redefine o token na tua folha de estilo.
- Uma disposição errada para o teu site: sombreia o componente pelo nome.
- Uma primitiva que a camada não traz: acrescenta-a com a CLI.
Cada degrau para baixo custa mais manutenção do que o anterior. O guia de substituição percorre os três, e Dá identidade ao teu site cobre a parte que é identidade e não tema — o nome, a marca e os ícones.