ThemeForge: um sistema de temas CSS pronto para uso; um agente de IA o instala em apenas um passo

Publicado em
5 outubro 2026
Atualizado em
6 outubro 2026
Por
Jacob Lloyd — escrito com ajuda de IA, depois do projeto
Tempo de leitura
35 min de leitura

Em termos simples: O ThemeForge é uma pasta gratuita contendo CSS e um pequeno script que proporciona a qualquer aplicativo web um seletor de temas, dez temas de cores e um conjunto completo de botões, campos, cards e caixas de diálogo prontos para uso. Ele foi desenvolvido de forma que um agente de codificação da IA possa inseri-lo em um aplicativo com apenas uma linha de código: o agente segue as instruções contidas num arquivo no repositório, e o aplicativo ganha assim um seletor funcional, um padrão padrão que segue as convenções do sistema, além de “tokens” de design para servirem de base na criação de interfaces.

A maioria dos aplicativos web acaba tendo três temas, definidos em três lugares diferentes: um bloco :root no CSS principal, um segundo bloco sob @media (prefers-color-scheme: dark) e um terceiro inserido manualmente por algum desenvolvedor para que o seletor de temas funcione. O resultado é sempre o mesmo: um controle que tem uma aparência diferente na página inicial, outra na página de configurações; além disso, aparecem perguntas no sistema de rastreamento de problemas sobre por que o tema escuro torna o rodapé azul. Criei o ThemeForge justamente para impedir esse tipo de problema. Ele consiste em uma única pasta, ui-theme/, que contém o código de execução, uma camada base, as classes dos componentes, os tokens de todos os dez temas, um seletor de temas, adaptadores opcionais para Tailwind e Quasar, além de um pequeno arquivo AGENTS.md destinado a agentes de programação IA. Basta colocar essa pasta no projeto e adicionar quatro linhas ao cabeçalho da página; pronto: o aplicativo terá um seletor de temas funcional e um tema padrão que segue as preferências do sistema. O agente responsável pela instalação faz tudo com apenas um comando; o restante deste artigo é para quem quiser conhecer os detalhes internos.

Este artigo serve como um guia: o que realmente existe na pasta, os dez temas e suas finalidades, a história dos contrastes entre cores, além dos tokens de design e das classes dos componentes, fornecidos como referência. A segunda parte do texto foi elaborada para ser facilmente consultada: todos os tokens, componentes e métodos públicos estão listados, permitindo que um agente IA (ou você mesmo no futuro) os utilize diretamente.

Resumo rápido

  • Como obter: github.com/LaserLloyd/ThemeForge — licença MIT, gratuito; há também um zip com o código nos Downloads abaixo.
  • O que é: uma única pasta, ui-theme/, que pode ser inserida em qualquer aplicativo web e lhe fornece dez temas coloridos, um seletor de temas, cerca de 250 tokens de design, uma camada base de elementos, padrões de texto e um conjunto completo de classes para componentes (botões, campos, switches, cards, diálogos, toasts, tabelas, etc.). É apenas CSS simples e um pequeno script. Não exige compilação, Node ou dependências.
  • Instalação com um único comando (exatamente como no README): python3 -c "import urllib.request as u,sys;sys.argv=['update.py','--dest','static/ui-theme'];exec(u.urlopen('https://raw.githubusercontent.com/LaserLloyd/ThemeForge/main/ui-theme/update.py').read())"
  • Ordem de inclusão no cabeçalho (importante!): primeiro ui-theme.js (clássico, bloqueante; nunca use defer ou module), depois ui-theme-base.css e ui-components.css, em seguida o CSS do próprio aplicativo, e por fim ui-theme.css, para que os tokens dos temas tenham prioridade.
  • Seletor de temas: um único elemento: <select class="ui-select" data-ui-theme-picker aria-label="Theme"></select>. Ele se preenche automaticamente e permanece sincronizado entre abas.
  • Os dez temas: seis principais (Purple, Midnight Gold, Glacier, Forest, Paper, Daylight) e quatro opcionais (Electric Yellow, LaserLloyd, LaserLloyd Light, Night Red). Todos passam na auditoria de contraste sem nenhuma falha.
  • Contraste: texto principal 7:1, secundário 6:1; todos os níveis de texto em qualquer superfície têm contraste mínimo de 4,5:1; bordas e estados ativos dos controles exigem pelo menos 3:1. O estado “ativado” ou “selecionado” é identificado por forma e preenchimento, não apenas cor.
  • Desenvolvido para agentes IA: o arquivo AGENTS.md contém as instruções de instalação em formato textual; basta indicar esse arquivo a qualquer agente IA para que ele configure o seletor de temas automaticamente. O próprio repositório possui CI (GitHub Actions, três tarefas) que verifica clonagem do código, auditoria de contraste, executa node --check em todos os arquivos JS e roda testes via Chrome headless.

Onde obtê-lo

Trata-se de um único repositório sob licença MIT: github.com/LaserLloyd/ThemeForge. O arquivo AGENTS.md contém as instruções de instalação, enquanto o relatório de contraste detalha os resultados da auditoria. Prefere um arquivo zip? Na seção Downloads ao final desta página há o código completo; a página Downloads do site também disponibiliza esse pacote. Caso não tenha Python instalado, o README sugere alternativas como git clone –depth 1, npx degit ou um URL do jsDelivr (<script>) fixado na versão @v1.0.0, útil para protótipos rápidos.

O que você terá ao final

Em poucos passos, o aplicativo adquirirá a aparência desejada pelo usuário: um cabeçalho com seletor de temas já preenchido com todas as opções disponíveis, temas claro e escuro padrão que seguem as preferências do sistema operacional, além de uma única linha CSS no código-fonte, substituindo valores fixos como background: var(–surface-2) em vez de #1d1d39. Ao escolher um tema e recarregar a página, não há “piscar” visual algum — o script de execução roda sincronamente dentro do <head>, lê os parâmetros definidos no próprio código (data-*) e aplica o tema antes mesmo da primeira renderização. Abra o seletor em duas abas diferentes, mude o tema numa delas e a outra atualiza automaticamente (graças a um listener de eventos storage). Ao imprimir um tema escuro ou OLED, o sistema alterna temporariamente para um tema claro (ou oculta a navegação, conforme configuração em data-print-theme) para garantir que o papel fique legível; ao imprimir um tema claro, tudo permanece inalterado.

Notes

Inbox

3 notes, 1 unread

Quarterly review Pinned

Draft of the Q3 retrospective — looking for two more examples before Friday.

Trip packing list

Passport, charger, the small torch.

O exemplo acima foi criado usando ui-app, ui-card, ui-btn, ui-switch e os tokens --surface-*, --text-* e --accent. O seletor de temas é um simples <select data-ui-theme-picker>; o script de execução preenche e sincroniza automaticamente esse elemento.

O exemplo acima é uma demonstração direta na página; não se trata de um screenshot de arquivo externo. O conjunto completo — todos os componentes em cada tema — está disponível em specimen/index.html no repositório (basta rodar python3 -m http.server e acessar /specimen/).

Como tudo se integra

O código de execução é um pequeno script, ui-theme.js (aproximadamente 23 KB, 575 linhas) que executa três tarefas sequenciais. Primeiro, lê os atributos data-* do próprio <script> onde está inserido (assim as configurações viajam junto ao arquivo); em seguida, consulta o localStorage e as preferências de modo claro/escuro do sistema operacional. Com essas informações, escreve o tema escolhido em <html data-palette> e define o modo ativo em <html data-theme> (pode ser amoled, dark ou light) antes mesmo da primeira renderização. Depois, percorre o documento em busca de elementos <select data-ui-theme-picker> e preenche-os com a lista dos temas habilitados (além de monitorar eventuais novos elementos inseridos por frameworks). Por fim, expõe window.UITheme e, quando ui-components.js também é carregado, disponibiliza window.UIComponents; além disso, registra um listener de eventos storage para manter duas abas sincronizadas. O CSS é simples: ui-theme-base.css define padrões para texto, links, anéis de foco, barras de rolagem e animações reduzidas; ui-components.css desenha botões, campos, switches, cards, diálogos, toasts e tabelas; ui-theme.css é o único arquivo que varia conforme o tema — nele são definidos todos os tokens (cor, tipografia, espaçamento, raio, sombra, animação) para os dez temas, usando um seletor [data-palette=”…”] (o tema Purple usa :root, ou seja, não possui atributo data-palette). O script de execução seleciona o tema; o CSS então o exibe na tela.

O acompanhamento do tema do sistema operacional é o que surpreende as pessoas: data-default=”auto” lê prefers-color-scheme em cada carregamento da página; o runtime combina essa informação com a escolha salva pelo visitante (ou com data-default-dark e data-default-light) para definir o tema. Altere o tema do sistema operacional e atualize a página — ela se adapta. Escolha um tema explicitamente no seletor; essa escolha prevalece até que o usuário a limpe (ou chame UITheme.reset()). O runtime também conecta um evento storage para manter duas abas abertas do mesmo app sincronizadas, sem necessidade de comunicação com o servidor.

Instalação

O arquivo AGENTS.md no repositório contém todo o guia detalhado; a versão resumida é a linha abaixo e um bloco de quatro tags no cabeçalho. Na raiz do app:

python3 -c "import urllib.request as u,sys;sys.argv=['update.py','--dest','static/ui-theme'];exec(u.urlopen('https://raw.githubusercontent.com/LaserLloyd/ThemeForge/main/ui-theme/update.py').read())"

Esse comando baixa o instalador, que obtém a versão mais recente, verifica cada arquivo comparando-o à lista SHA-256 em files.json e escreve tudo na pasta correta. No Windows, use python ou py em vez de python3; a linha funciona tanto no PowerShell quanto no cmd e no bash. As quatro linhas a serem inseridas no <head> de cada página:

<script src="/static/ui-theme/ui-theme.js"
        data-themes="purple,midnight-gold,glacier,forest,paper,daylight"
        data-default="auto" data-default-dark="midnight-gold" data-default-light="daylight"
        data-storage-key="myapp.theme"></script>
<link rel="stylesheet" href="/static/ui-theme/ui-theme-base.css">
<link rel="stylesheet" href="/static/ui-theme/ui-components.css">
<!-- seus estilos -->
<link rel="stylesheet" href="/static/ui-theme/ui-theme.css">

Três regras, cada uma com seu motivo. O script ui-theme.js é clássico e bloqueante — nunca usa type=”module”, defer ou async — pois lê suas configurações diretamente da própria tag (document.currentScript, que é null para scripts do tipo módulo) e define o tema antes da primeira renderização. As camadas base e de componentes são carregadas antes do CSS do app, garantindo que as regras do próprio app tenham maior prioridade. O ui-theme.css é carregado por último, impedindo que variáveis antigas do app sobrescrevam os tokens do tema. O seletor de temas é uma única linha: <select class=”ui-select” data-ui-theme-picker aria-label=”Theme”></select>. Via script, há UITheme.set(‘glacier’), UITheme.current() e UITheme.onChange(fn). A instalação completa leva cerca de cinco minutos, conforme descrito no início do AGENTS.md.

O agente que realizou essa instalação num único passo, num app real, agiu assim: o humano pediu a um agente de codificação IA para adicionar modo escuro e seletor de temas ao app. O agente leu o AGENTS.md, executou o comando acima em static/ui-theme/, inseriu as quatro tags no cabeçalho do template base, substituiu duas referências de cor por var(–surface-2) e var(–text-secondary) e adicionou o seletor ao cabeçalho. Foram apenas seis linhas de alteração no código, sem novas dependências. A auditoria de contraste já cobre todas as combinações que os componentes podem gerar; o runtime acompanha automaticamente o tema do sistema operacional; a única coisa que a ferramenta de lint precisa verificar é se algum commit futuro incluirá cores codificadas diretamente.

Os temas

Os seis primeiros são os temas principais oferecidos por padrão; os quatro opcionais aparecem apenas quando listados pelo app. Todos passam na auditoria de contraste (docs/contrast-report.md): texto principal com razão de contraste 7:1, texto secundário 6:1 em qualquer superfície; demais níveis de texto 4,5:1; bordas e estados on/off 3:1; além disso, o formato também é usado para identificar estados selecionados/correntes em todos os temas. Lista completa:

Tema Conjunto Fundo Descrição
Purple básico escuro Acento violeta e texto lavanda suave sobre indigo profundo. É o tema base: seus valores são os padrões de :root.
Midnight Gold básico OLED Dourado quente sobre preto absoluto, ideal para telas OLED.
Glacier básico OLED Texto azul-gelo e detalhes característicos sobre preto absoluto, com acento verde-azulado intenso.
Forest básico OLED Verde-sage pálido e tons de casca sobre preto absoluto.
Paper básico claro Papel quente, texto marrom-escuro, fonte serif para textos longos e acento vermelho.
Daylight básico claro Branco limpo com acento azul.
Electric Yellow opcional escuro Amarelo ácido sobre grafite; bordas arredondadas e traços nítidos.
LaserLloyd opcional escuro Azul laser sobre grafite quase negro, inspirado no site do autor. Combina com LaserLloyd Light.
LaserLloyd Light opcional claro Versão clara de LaserLloyd.
Night Red opcional OLED Tema noturno com baixa emissão de luz azul: texto vermelho-âmbar sobre preto absoluto, estrutura vermelha e zero componente azul em qualquer cor.

Três dos quatro temas opcionais são intencionalmente chamativos. Electric Yellow é o que uso ao revisar CSS no escuro: quero que a página se destaque mais que meu editor; LaserLloyd mantém a coerência visual entre este site e um app que estou desenvolvendo nele; Night Red é um “perfil noturno” especial, cuja auditoria de contraste verifica uma lista ampliada de 171 linhas (as 147 padrão mais outras para condições de baixa luminosidade); nesse tema, todo token da paleta tem zero no canal azul (docs/contrast-report.md descreve a “auditoria de zero azul”; README.md menciona o §Night Red; docs/THEMES.md detalha o §Night Red).

Armadilhas

  • Uma cor codificada diretamente no seu CSS é o bug, não o tema. A auditoria verifica apenas os tokens; um color: #fff no código do app permanece branco em qualquer tema. O arquivo tools/lint_colors.py (no repositório) e o comando grep em AGENTS.md §8 detectam isso; porém, a verificação de lint no CI não executa essa etapa, então execute-a localmente antes de fazer o merge.
  • O ui-theme.js deve vir primeiro no <head>, da forma clássica, sem usar defer ou module. Um script do tipo module não possui o document.currentScript; o runtime lê seus próprios atributos data-* a partir da tag. O sintoma é um piscar temporário do tema errado, seguido pelo tema correto.
  • O ui-theme.css deve ser carregado após o CSS do app, e não antes. A ordem correta é: base, componentes, app, tokens. Uma regra do app com a mesma especificidade que seja carregada depois dos tokens acaba sendo ignorada.
  • O atributo data-themes controla o que o seletor de temas exibe. Um tema armazenado cujo “slug” não conste em data-themes é ignorado na próxima carga (o runtime volta ao tema padrão). Ao remover um tema, basta adicionar data-legacy-key e data-legacy-map uma única vez para que o valor armazenado seja migrado.
  • Os estilos rounded-md e font-sans do Tailwind mudam após a instalação. Isso é esperado: o tema define os tokens –radius- e –font-, cujos valores têm prioridade. Não tente alterar isso.
  • Aviso de “hydration” do Next.js. Adicione suppressHydrationWarning ao <html> e silencie a regra de lint no-sync-scripts no bloco head: o runtime define atributos no <html> antes da hidratação feita pelo React.
  • Outras bibliotecas leem o atributo data-theme no <html> (como daisyUI, Pico). O runtime escreve ali data-theme=”amoled|dark|light”; verifique se a biblioteca reage a isso. Caso reaja, use data-mirror-attr para definir um atributo diferente nela.
  • Não edite nada dentro da pasta ui-theme/. Essa pasta é substituída nas atualizações; a verificação de lint detecta alterações manuais e a instalação recusa sobrescrever arquivos modificados. Transfira as alterações para o CSS próprio do app.
  • As fontes mencionadas nos “stacks” não são embarcadas. Cada stack usa, como fallback, as fontes do sistema; se quiser usar Inter, JetBrains Mono, Space Grotesk ou Archivo, carregue-as você mesmo (o documento de integração traz um trecho <link> pronto para copiar).
  • O valor prefers-contrast: more aumenta a espessura das linhas e eleva o nível de contraste do texto. Não é necessário nenhum sinalizador de tema; o runtime detecta essa preferência e o CSS responde automaticamente. O grupo de tokens high-contrast é a forma legada de obter o mesmo efeito.

Onde isso me deixa

O que eu queria era uma maneira de dar a cada aplicativo que crio um sistema de temas decente, sem precisar criar um do zero a cada vez; o ThemeForge é exatamente essa solução que decidi manter. As pastas que coloco nos apps agora são ui-theme/ e mais o que for necessário para o funcionamento do app; as quatro tags de bloco principal e o seletor de temas são os mesmos em qualquer framework. O agente responsável pela instalação lê o arquivo AGENTS.md, e não uma mensagem no Slack. A auditoria de contraste, os testes com o Chrome headless e o comando node –check em todos os arquivos JS distribuídos são o que me dão confiança para continuar avançando. Está na versão 1.0.0 porque os tokens constituem a API pública; a renomeação de um token é considerada uma mudança de versão major. Cada release corresponde a uma tag Git, a pasta VERSION reflete essa versão, e os arquivos JSON são assinados com a mesma lista de checksums que o update.py utiliza para validação. O próprio CI do repositório passa sem problemas no Linux, Windows e Python 3.9; as mesmas verificações também são bem-sucedidas em um clone novo deste computador.

Referência (para agentes de IA)

O restante deste artigo é um card de referência que um agente de codificação (ou o meu eu do futuro) pode copiar textualmente. A primeira metade acima é texto narrativo; a segunda metade está estruturada, é fácil de escanear e foi criada para ser lida por uma ferramenta. Todos os tokens, todas as classes de componentes, todos os métodos públicos em window.UITheme e window.UIComponents, todos os temas, todas as configurações definidas em tags script, todos os adaptadores, o caminho completo de instalação, o contrato de contraste e o bloco de versão encontram-se abaixo.

Manifesto de arquivos

O repositório tem duas árvores que são importantes: o pacote pronto para uso que o aplicativo copia, e o design e as ferramentas usadas para criá-lo. O artigo trata do pacote.

Pacote de substituição — o que o aplicativo copia (ui-theme/):

Arquivo Tamanho Linhas O que é
ui-theme.js 23.515 B 575 Em tempo de execução: aplica o tema salvo antes da primeira renderização; segue as configurações claro/escuro do sistema operacional via data-default="auto"; preenche os seletores de tema, sincroniza as abas e expõe window.UITheme
ui-theme-base.css 13.255 B — Valores padrão dos elementos: texto do corpo, links, títulos, código, anel de foco, barras de rolagem, opções de redução de movimento, níveis de texto, .ui-markdown, cores do highlight.js
ui-components.css 51.344 B — Componentes: botões, campos de entrada, caixas de seleção, botões de rádio, switches, cartões, badges, caixas de aviso, abas, controles segmentados, tabelas, caixas de diálogo, menus, dicas de ferramenta, notificações, barra de progresso, blocos de código e um shell de aplicativo
ui-theme.css 86.389 B (21.197 B compactado com gzip) — Tokens de todos os dez temas (cerca de 20 KB após compactação com gzip)
ui-components.js 5.441 B 135 Funções opcionais para exibição de confirm(), alert(), prompt() e toast() com tema personalizado
ui-theme.d.ts 2.841 B — Declarações TypeScript para window.UITheme e window.UIComponents
update.py 16.081 B — Instala e atualiza a pasta; verifica cada arquivo em relação ao seu hash SHA-256
themes.json 4.089 B — Lista de temas (nome, família, cor de fundo, conjunto de cores, fontes)
files.json 1.401 B — Lista de checksums que o update.py utiliza para verificação
VERSION 30 B — Versão da pasta (ThemeForge 1.0.0 3db64d9f574f)
README.md 6.342 B — Instruções de uso específicas para este pacote
adapters/quasar.css 24.997 B — Mapeamento entre NiceGUI e Quasar
adapters/quasar.js 1.468 B 40 Ponte JavaScript entre NiceGUI e Quasar
adapters/tailwind.css 4.399 B — Mapeamento @theme inline para o Tailwind CSS v4
adapters/tailwind-v3.preset.js 2.915 B 54 Preset para o Tailwind CSS v3

O design e as ferramentas que criam o bundle (não copiados para o aplicativo):

Arquivo Tamanho O que é
README.md 6.592 B README do repositório
AGENTS.md 19.063 B Instruções de instalação em formato textual, para agentes de IA
CHANGELOG.md 4.425 B Histórico de versões (1.0.0 é o primeiro lançamento)
CLAUDE.md 1.498 B Convenções do repositório para o Claude
CONTRIBUTING.md 4.476 B Como contribuir com os temas
LICENSE 1.067 B Licença MIT; copyright © 2026 (o arquivo original menciona o autor pelo nome pessoal; a versão publicada no site usa um nome de marca; o texto no arquivo é o mesmo do LICENSE original); não incluído no zip de download (a linha de copyright original menciona o autor pelo nome pessoal, e o sistema de proteção de conteúdo do site considera isso uma divulgação de identidade não revisável)
docs/TOKENS.md 15.391 B Todos os tokens, agrupados por categoria
docs/COMPONENTS.md 13.889 B Todas as classes de componentes, com exemplos de marcação
docs/THEMES.md 8.081 B Os temas, notas de design e como adicionar um novo tema
docs/INTEGRATIONS.md 10.604 B Passos de instalação para cada framework
docs/TEXT.md 5.465 B Níveis de texto e estilo Markdown
docs/UPDATING.md 4.134 B Atualizações, fixação de versões, cache; o que os checksums comprovam
docs/contrast-report.md 124.372 B Relatório de auditoria de contraste (10 temas × 147–171 linhas)
docs/theme-template.css 9.854 B Modelo básico de tema para uso com tools/sync_theme.py
tokens/<theme>.json ~57 KB cada Tokens resolvidos de cada tema, no formato JSON do padrão W3C DTCG
examples/static-html/ 3.731 B index Exemplo simples em HTML/CSS/JS
examples/fastapi-jinja/ 2.172 B app.py Exemplo de uso com FastAPI e Jinja
specimen/index.html 17.721 B Visualização de todos os componentes em todos os temas, acessível localmente
tools/check_contrast.py 43.171 B Script para auditoria de contraste (executado no CI)
tools/lint_colors.py 22.711 B Verifica literais de cor no CSS do aplicativo
tools/sync_theme.py 41.671 B Reconstroi os arquivos ui-theme.css, tokens/*.json e docs/contrast-report.md a partir dos arquivos src/css/*.css
tools/update.py 16.081 B Script de instalação/verificação (equivalente ao ui-theme/update.py)
tools/screenshots.py 3.273 B Gera prévias dos temas para uso em docs/images/
tests/test_tools.py 17.606 B Testes unitários em Python (32 testes neste clone; 1 foi ignorado)
tests/run_browser_tests.py 3.570 B Testes no Chrome headless para verificar o funcionamento do runtime
tests/runtime.html 24.930 B Arquivo de teste para execução em navegador
.github/workflows/ci.yml — CI: auditoria de contraste, validação via node --check, testes unitários, testes de navegador e verificação de CRLF; executado no Linux, Windows e Python 3.9

O próprio CI do repositório executa três tarefas: checks no Ubuntu com Python 3.12, tools-on-windows no Windows com Python 3.11 e updater-on-oldest-python no Ubuntu com Python 3.9. O clone local passa no teste node --check em todos os arquivos JS enviados; a ferramenta de contraste reproduz todas as dez linhas da auditoria; e os testes unitários também são aprovados (32 aprovados, 1 ignorado em 1,212 s no Linux, Python 3.14, 05/10/2026).

Tokens de design (grupos, função, valor de exemplo)

Todo tema resolve todos os tokens. Os valores abaixo são os do tema Purple (a base :root); os demais temas possuem seus próprios valores resolvidos em tokens/<theme>.json (JSON DTCG). Use um token com var(--nome). Nunca redeclare um token no CSS do aplicativo — atribua às variáveis do app um prefixo específico (--meuapp-barra-lateral-w) ou crie um alias para o token (--meuapp-marca: var(--acento)). Fonte: docs/TOKENS.md.

Grupo Token Função Exemplo (Roxo)
Superfícies --surface-void mais escuro que a página (cobertura total) #08080f
Superfícies --surface-0 a própria página #0e0e1b
Superfícies --surface-1 navegação #14142a
Superfícies --surface-2 cartões #1d1d39
Superfícies --surface-3 estado de passagem do mouse #232342
Superfícies --surface-4 estado ativo #262648
Superfícies --surface-sunken áreas rebaixadas #0a0a14
Superfícies --surface-overlay menus, popovers #1d1d39
Superfícies --glass-1/2/3 painéis translúcidos rgba(29,29,57,.72/.84/.92)
Superfícies --glass-highlight brilho do vidro rgba(255,255,255,.055)
Superfícies --code-bg fundo de código #0b0b16
Texto --text-primary texto principal #e8e8f0
Texto --text-secondary rótulos, descrições #a0a0bd
Texto --text-tertiary dicas, timestamps #8d8db0
Texto --text-disabled controles desativados #717195
Texto --text-inverse texto sobre um fundo claro #0e0e1b
Texto --text-link / --text-link-hover links e texto de destaque #a78bfa / #c4b5fd
Texto --on-accent / --on-danger / --on-success / --on-warning / --on-media / --on-media-muted rótulo sobre um fundo colorido #ffffff / #2a0808 / …
Destaque --accent / --accent-hover / --accent-pressed destaque da marca, ações principais #7c3aed / #8250f0 / #6d28d9
Destaque --accent-subtle / --accent-muted / --accent-glow fundo tingido, preenchimento suave, brilho rgba(124,58,237,.16/.26/.35)
Destaque --accent-rgb permite ao JS compor rgba(var(--accent-rgb), .2) 124,58,237
Destaque --accent-2 / --accent-2-subtle destaque secundário #5eead4
CTA --cta / --cta-hover / --cta-pressed / --on-cta botão de ação importante #7c3aed / #8250f0 / #6d28d9 / #ffffff
CTA --cta-shadow / --cta-shadow-hover sombras para o botão 0 6px 20px rgba(124,58,237,.28) / .38
CTA --highlight / --highlight-subtle / --on-highlight marcações, cor de dica #fcd34d / rgba(252,211,77,.12) / #251a00
Linhas --border-subtle / --border / --border-strong bordas dos controles; --border-strong tem proporção 3:1 #21213b / #292945 / #6f6f9c
Linhas --divider linhas finas #21213b
Linhas --focus-ring / --focus-ring-width / --focus-ring-offset anel de foco #a78bfa / 2px / 2px
Linhas --glass-stroke / --glass-stroke-strong bordas de vidro rgba(255,255,255,.08/.16)
Estados dos controles --selected / --on-selected ativado/marcado/pressionado conforme o tema
Estados dos controles --unselected-border / --unselected-fg contorno desativado; proporção 3:1 em todas as superfícies conforme o tema
Status --success / --warning / --danger / --info pontos, barras, preenchimentos conforme o tema
Status --success-text / --warning-text / --danger-text / --info-text cor do texto de cada status conforme o tema
Status --success-subtle / --warning-subtle / --danger-subtle / --info-subtle fundo tingido de cada status conforme o tema
Status --success-border / --warning-border / --danger-border / --info-border bordas de status conforme o tema
Status --idle / --idle-text / --idle-subtle / --idle-border / --idle-hover estado neutro conforme o tema
Status --live / --live-text / --live-subtle / --live-border / --live-hover indicador de “ativo”/“em execução” conforme o tema
Código/Sintaxe --syn-bg / --syn-fg / --syn-comment / --syn-keyword / --syn-string / --syn-number / --syn-function / --syn-attr / --syn-tag / --syn-builtin / --syn-type / --syn-variable / --syn-literal / --syn-operator / --syn-title / --syn-addition esquema de destaque sintático conforme o tema
Código/Sintaxe --code-header-bg / --code-stroke moldura do bloco de código (escura em todos os temas) conforme o tema
Gráficos --cat-1 … --cat-12 cores das séries; proporção 3:1 em relação a --surface-0 conforme o tema
Gráficos --seq-1 … --seq-5 gradiente de baixo para alto conforme o tema
Gráficos --div-1 … --div-5 ruim, neutro, bom conforme o tema
Gráficos --chart-grid / --chart-axis elementos gráficos conforme o tema
Bolhas --bubble-user-text / --bubble-assistant-text / --bubble-user-bg / --bubble-assistant-bg bolhas de chat conforme o tema
Bolhas --rp-speech / --rp-thought / --rp-shout / --rp-whisper / --rp-ooc / --rp-action / --rp-critical cores das bolhas de roleplay conforme o tema
Diff --diff-add-bg / --diff-add-text / --diff-remove-bg / --diff-remove-text visualização de diff conforme o tema
Tipografia --fs-xs / --fs-sm / --fs-md / --fs-lg / --fs-xl / --fs-2xl tamanhos de fonte conforme o tema
Tipografia --fw-medium / --fw-semibold / --fw-bold pesos da fonte conforme o tema
Tipografia --font-sans / --font-mono / --font-display famílias de fontes conforme o tema
Espaçamento --space-1 … --space-8 espaços de 4 a 64 px conforme o tema
Raio --radius-sm / --radius-md / --radius-lg / --radius-pill formatos dos controles conforme o tema
Sombras --shadow-1 / --shadow-2 / --shadow-3 / --shadow-4 níveis de sombra conforme o tema
Camadas Z --z-modal / --z-toast / --z-popover / --z-nav ordem de empilhamento conforme o tema
Movimento --motion-fast / --motion-med / --motion-slow / --easing-standard tempos de animação (reduzido-movimento interrompe loops) conforme o tema
Markdown --md-bold / --md-italic / --md-bolditalic / --md-bolditalic-glow formatação Markdown no app conforme o tema
Miscelânea --mark-bg / --selection-text / --selection-bg / --media-filter / --quote-bar / --heartbeat-text / --heartbeat-hover / --offline-text / --on-offline / --canvas-handle pequenos recursos conforme o tema

Fonte: docs/TOKENS.md (22 grupos, ~270 tokens — grep -oE '\| \(–[a-zA-Z][a-zA-Z0-9-]*)` |’ docs/TOKENS.md | sort -u | wc -lretorna 272 nomes de token únicos; 22 grupos## `).

Classes de componentes (cada modificador, uma linha)

O estado é definido por atributos nativos (disabled, checked, aria-pressed, aria-selected, aria-current, aria-invalid, aria-busy, [open]) — nunca por uma classe extra. A maioria dos seletores usa apenas uma classe, de modo que uma regra posterior do app com a mesma especificidade prevalece. Propriedades lógicas são usadas em todo o código (funcionam corretamente em direção direita-esquerda). “On”, “checked”, “pressed” e “current” utilizam --selected; “off” é representado por um contorno; “disabled” tem borda tracejada e não é preenchido. Fonte: docs/COMPONENTS.md.

Classe Modificadores / partes O que é
ui-stack — Coluna, com espaçamento --space-3
ui-row — Linha com quebra de linha, centralizada, espaçamento --space-2
ui-grid --ui-grid-min preenche colunas automaticamente; min é definido no elemento
ui-container — Centralizado, largura máxima --content-max
ui-spacer — empurra o restante da linha para o final
ui-app __header __nav __main Estrutura básica do app (cabeçalho, navegação lateral, conteúdo principal); a navegação some abaixo de 760 px
ui-brand — Título do app no cabeçalho
ui-nav __label __item Navegação lateral
ui-title / ui-heading / ui-subheading / ui-lead / ui-kicker / ui-small / ui-mono / ui-num / ui-kbd / ui-code / ui-divider — hierarquia tipográfica (<hr> é .ui-divider)
ui-text-primary / -secondary / -tertiary / -disabled / -link — classes de nível de texto (use os tokens para novo código)
ui-markdown — container para Markdown renderizado; ver docs/TEXT.md
ui-btn --primary --ghost --outline --danger --cta --sm --lg --icon --block Botões; funciona também em <a>; combina com aria-pressed / aria-busy / disabled
ui-btn-group — botões adjacentes compartilham bordas arredondadas
ui-field — container de campo de formulário (rótulo + controle + ajuda)
ui-label — rótulo do campo
ui-input --sm input de texto
ui-select — <select> estilizado; data-ui-theme-picker monta o seletor de temas
ui-textarea — <textarea> estilizado
ui-help — texto de ajuda do campo (links para aria-describedby)
ui-error — texto de erro do campo (links para aria-describedby); exibido quando aria-invalid="true"
ui-input-group — par input + botão (ex.: busca)
ui-check — linha com checkbox/radio/switch
ui-checkbox — <input type="checkbox"> nativo estilizado
ui-radio — <input type="radio"> nativo estilizado
ui-switch — checkbox role="switch" estilizado como interruptor
ui-switch-state data-on data-off rótulos “On”/“Off” (aria-hidden; o interruptor anuncia seu próprio estado)
ui-range — input de faixa nativo colorido com --slider-color
ui-segmented — grupo de botões que funcionam como radio
ui-tabs ui-tab lista de abas (abas linkadas usam <a aria-current="page">); o app deve gerenciar a navegação por teclado
ui-card __header __title __footer --raised --interactive Cartão; aria-selected / aria-current delineiam um cartão selecionado
ui-well — área rebaixada (logs, prévias, conteúdo secundário)
ui-stat __label __value par rótulo/valor
ui-badge --success --warning --danger --info --live --accent --neutral selo em formato de pílula
ui-dot --success --warning --danger --info --live --neutral ponto de status
ui-count --accent --danger chip contador
ui-callout --info --success --warning --danger __title aviso colorido (use role="alert" para erros)
ui-table-wrap — envolve <table class="ui-table"> para cabeçalhos fixos/rolagem
ui-table --hover --compact td.num estilos de tabela
ui-dialog — <dialog> estilizado
ui-drawer — painel lateral em <dialog>
ui-menu __item lista de menu
[data-ui-tooltip] data-ui-tooltip-side="bottom" dica contextual em qualquer elemento
ui-progress — barra de progresso linear
ui-spinner — indicador de carregamento
ui-skeleton — esqueleto de carregamento
ui-breadcrumbs — lista de navegação
ui-pagination — paginação
ui-avatar — círculo de avatar
ui-chip __remove chip removível/selecionável
ui-details — accordion em <details>
ui-fieldset — fieldset + legenda
ui-codeblock __bar <figure> com <figcaption class="ui-codeblock__bar"> + <pre>
ui-empty — estado vazio
ui-bubble --user --assistant bolha de chat

Métodos públicos em window.UITheme e window.UIComponents

Fonte: ui-theme/ui-theme.d.ts (declarações TypeScript para ambos os globais).

window.UITheme (UIThemeApi):

Membro Tipo O que faz
version string (somente leitura) A versão da pasta, ex.: "1.0.0"
config objeto (somente leitura) { themes, default, auto, storageKey, families, printTheme }
current() () => string O slug do tema ativo
theme([slug]) (slug?) => UIThemeInfo \| null Informações sobre um tema (ou o tema ativo)
list() () => UIThemeInfo[] Todos os temas habilitados
set(slug) (slug) => string Muda para um tema; retorna o slug
reset() () => string Volta ao tema padrão; retorna o slug
partner([slug]) (slug?) => string \| null O tema claro/escuro correspondente numa família (ex.: laserlloyd ↔ laserlloyd-light)
toggleFamily() () => string \| null Alterna para o tema parceiro; retorna o novo slug
onChange(listener) (fn) => () => void Inscreve-se para receber notificações; retorna uma função para cancelar a inscrição; detail.print será true em caso de troca para impressão
token(name, [el]) (name, element?) => string Valor bruto do token (ex.: "#7c3aed")
tokens(names, [el]) (names, element?) => Record<name, string> Vários tokens de uma só vez
color(name) (name) => string Cor resolvida em formato rgb() para o canvas
colors(names) (names) => Record<name, string> Várias cores resolvidas para o canvas
mountPicker(target, [opts]) (elOrSel, options?) => HTMLSelectElement \| null Preenche um select para servir como seletor; as opções são { label, coreLabel, optInLabel, systemLabel }

O evento ui-theme-change é disparado em document contendo { slug, theme, previous, print }.

window.UIComponents (UIComponentsApi): (requer ui-components.js)

Método Assinatura O que faz
confirm (opts: UIDialogOptions \| string) => Promise<boolean> confirm() com temas; as opções são { title, message, label, confirmLabel, cancelLabel, danger }
alert (opts: UIDialogOptions \| string) => Promise<void> alert() com temas
prompt (opts: UIPromptOptions \| string) => Promise<string \| null> prompt() com temas; retorna null se o usuário cancelar; opções adicionais são { value, placeholder, type }
toast (message, { kind?, timeout? }) => HTMLElement Toast com tipo info / success / warning / danger; retorna o elemento

window.UI_THEME_MANIFEST (opcional; tem prioridade sobre os valores padrão definidos no script): { themes, default, defaultDark, defaultLight, storageKey, families, legacy, mirrorAttr, fontsHref, printTheme }. O campo themes aceita um array ou uma string com valores separados por vírgula.

Configurações via tag de script (data-* na tag <script>)

Atributo Valor padrão O que faz
data-themes os seis temas principais (purple,midnight-gold,glacier,forest,paper,daylight) Lista de temas habilitados separada por vírgulas; controla o seletor e quais valores são aceitos. Sem data-themes, o ui-theme.js habilita os seis temas com set==="core" (ui-theme.js:147-149).
data-default o primeiro tema habilitado (primeiro slug em data-themes, ou purple caso nenhum esteja habilitado e não seja auto) O slug do tema padrão; pode ser auto para seguir as configurações do sistema operacional. A string literal auto ativa o acompanhamento via prefers-color-scheme (ui-theme.js:164); um atributo ausente/vazio resulta no primeiro tema habilitado (ui-theme.js:177-179).
data-default-dark o primeiro tema não claro habilitado (primeiro slug em data-themes cujo ground !== "light", senão o primeiro tema habilitado, ou purple se nada estiver habilitado) O tema escuro correspondente ao modo auto. O ui-theme.js:168-175 utiliza esse valor quando o sistema operacional prefere o modo escuro e nenhum valor explícito foi definido.
data-default-light o primeiro tema claro habilitado (primeiro slug em data-themes cujo ground === "light", senão o primeiro tema habilitado, ou purple se nada estiver habilitado) O tema claro correspondente ao modo auto. Utiliza o mesmo código (ui-theme.js:168-175).
data-storage-key ui-theme Chave usada no localStorage para armazenar a escolha do usuário (ui-theme.js:185). O AGENTS.md §3 recomenda definir como <nome_do_app>.theme para evitar conflitos com outras aplicações que usem o ThemeForge na mesma origem.
data-families false Agrupa os temas por família no seletor
data-print-theme auto Define como a página será impressa: quando o tema ativo é escuro ou OLED, auto alterna para o tema claro da família (ou o primeiro tema claro habilitado, ou daylight); um slug específico faz com que o tema indicado seja usado; none impede a troca; quando o tema ativo é claro, a página é impressa normalmente (ui-theme.js:474-490).
data-legacy-key — Chave antiga de armazenamento para migração (em conjunto com data-legacy-map)
data-legacy-map — Mapeamento entre valores antigos e novos (objeto JSON)
data-mirror-attr — Copia o tema ativo para outro atributo (útil para bibliotecas que o leem)
data-fonts-href — URL de uma folha de estilo com as fontes do tema

Fonte: ui-theme.js:147-149, 164, 168-174, 185, 474-490 (valores padrão em tempo de execução) e AGENTS.md §3, §12 (recomendações de configuração — ex.: definir data-themes com os seis temas principais, data-default="auto" e data-storage-key="<nome_do_app>.theme").

Adaptadores

Adaptador Arquivos O que faz
NiceGUI / Quasar adapters/quasar.js + adapters/quasar.css Carregue adapters/quasar.js logo após o ui-theme.js e adapters/quasar.css após o ui-theme.css (usando ui.add_head_html). Os toggles, checkboxes e radios do Quasar adotam o design baseado no estado de controle; os controles desativados são exibidos tracejados com opacidade total. Remova qualquer chamada a ui.dark_mode() — o adaptador cuida disso.
Tailwind CSS v4 adapters/tailwind.css Insira @import "./<caminho>/ui-theme/adapters/tailwind.css"; após @import "tailwindcss";. Disponibiliza classes como bg-surface-2, text-fg, text-fg-muted, bg-accent, text-on-accent, border-line, etc. Para textos, usa-se fg-* pois os tamanhos text-* pertencem ao Tailwind.
Tailwind CSS v3 adapters/tailwind-v3.preset.js Configure presets: [require('./<caminho>/ui-theme/adapters/tailwind-v3.preset.js')]. Oferece os mesmos tokens do adaptador v4, porém expressos como um preset v3.

O adaptador Tailwind mapeia os tokens do tema; o adaptador Quasar mapeia as classes dos componentes. Nenhum deles é obrigatório para que o restante do pacote funcione.

Caminho completo de instalação (texto literal, conforme descrito no AGENTS.md)

O AGENTS.md descreve o processo de instalação em forma de texto, destinado a agentes de programação baseados em IA. Abaixo estão transcritos integralmente os dois primeiros tópicos; este é o prompt ao qual um agente de IA deve responder. Os caracteres foram escapados conforme a regra §8 do skill article-forge (um <blockquote> bruto mantém o Markdown inalterado, portanto <, >, & são codificados como &lt;, &gt;, &amp;).

## 1. Decisões iniciais

| Pergunta | Resposta padrão |
|---|---|
| Onde colocar a pasta? | Na pasta estática da aplicação, servida diretamente: `static/ui-theme/` (Flask, FastAPI, Django), `public/ui-theme/` (Vite, Next.js, Create React App), `app/static/ui-theme/` ou ao lado de `index.html` em sites simples. |
| Quais temas usar? | Os seis temas principais: `purple,midnight-gold,glacier,forest,paper,daylight`. Adicione os temas opt-in (`night-red`, `electric-yellow`, `laserlloyd`, `laserlloyd-light`) apenas se o usuário solicitá-los. |
| Tema padrão? | `auto`: segue a configuração de claro/escuro do sistema operacional até que o usuário faça uma escolha (`data-default-dark="midnight-gold"`, `data-default-light="daylight"`). |
| Chave de armazenamento? | `<nome_do_app>.theme`, ex.: `notes.theme`. |

## 2. Instalação

Execute a partir da pasta raiz da aplicação (Python 3.9 ou superior; substitua `static/ui-theme` pela pasta escolhida):


python3 -c &quot;import urllib.request as u,sys;sys.argv=['update.py','--dest','static/ui-theme'];exec(u.urlopen('https://raw.githubusercontent.com/LaserLloyd/ThemeForge/main/ui-theme/update.py').read())&quot;
No Windows use `python` (ou `py`) em vez de `python3`; a linha funciona tanto no PowerShell quanto no cmd e bash. O comando baixa o instalador, que por sua vez obtém a versão mais recente do GitHub, verifica cada arquivo com base na lista de checksums e cria a pasta. Para atualizações posteriores, basta executar `python3 static/ui-theme/update.py`. Em modo offline: baixe um arquivo compactado da versão (`.tar.gz`) em outro local e execute `python3 update.py --source <arquivo> --dest static/ui-theme` usando o `update.py` contido na pasta `ui-theme/`. Outras alternativas, caso o Python não esteja disponível: - **git:** `git clone --depth 1 https://github.com/LaserLloyd/ThemeForge.git ut-tmp`, copie `ut-tmp/ui-theme` para a aplicação e remova `ut-tmp`. - **Node:** `npx degit LaserLloyd/ThemeForge/ui-theme#v1.0.0 static/ui-theme`. - **Sem instalação (protótipos, páginas HTML isoladas):** carregue os arquivos via jsDelivr, fixando uma versão específica: `https://cdn.jsdelivr.net/gh/LaserLloyd/ThemeForge@v1.0.0/ui-theme/ui-theme.js` (e o mesmo caminho para cada arquivo CSS). Nunca utilize `@main`; a CDN armazena em cache por até 12 horas. Para atualizar uma página hospedada na CDN, basta alterar o número da versão; nesse caso, os comandos `update.py` e as etapas 8.5, 9 e 10 abaixo não se aplicam.

Os demais tópicos do AGENTS.md (seções 3–12) descrevem o bloco de cabeçalho, o seletor de temas, a geração de código a partir dos tokens, regras de estilo, gráficos, verificações de conformidade, a linha que deve ser inserida no AGENTS.md da própria aplicação para manter a padronização entre agentes, o comando de atualização, a tabela de solução de problemas e a lista de referências acima.

Auditoria de contraste (resumo, todos os temas)

O script tools/check_contrast.py é executado em CI a cada push. O relatório completo ocupa 124 KB (uma seção por tema, além de um resumo) e está em docs/contrast-report.md; o resumo é:

Tema Conjunto Perfil Verificações Falhas
purple core standard 147 0
midnight-gold core standard 147 0
glacier core standard 147 0
forest core standard 147 0
paper core standard 147 0
daylight core standard 147 0
electric-yellow opt-in standard 147 0
laserlloyd opt-in standard 147 0
laserlloyd-light opt-in standard 147 0
night-red opt-in night 171 0

Contrato exigido por todos os temas: texto principal deve ter contraste mínimo de 7:1, texto secundário 6:1 (o relatório de contraste menciona “promessa de 6:1 do contrato” — o docs/contrast-report.md assinala cada linha text-secondary on surface-2 com essa frase exata); todo nível de texto em qualquer superfície deve ter 4.5:1, os elementos desativados 3:1, os textos sobre fundos acentuados e de status 4.5:1, o texto selecionado 4.5:1, a diferença entre bordas selecionadas/não selecionadas e textos não selecionados em todas as superfícies 3:1, bordas fortes, trilhas de controle e anéis de foco 3:1; as cores sintáticas sobre --syn-bg devem ter 4.5:1 (com exceção dos comentários, que exigem 3.5:1). Lógica on/off por forma: um controle “ligado” é preenchido com --selected; o “desligado” aparece como contorno em --unselected-border; no caso de switches, o estado “on” acrescenta uma barra ao knob, enquanto o “off” adiciona um anel. O estado desativado é representado por linhas tracejadas e sem preenchimento, mesmo quando o controle estiver “ligado”.

Frameworks

Conforme descrito em docs/INTEGRATIONS.md: HTML simples · FastAPI, Flask, Starlette (templates Jinja) · Django · Vite, Vue, Svelte, SvelteKit, Astro · Next.js (router de aplicação) · NiceGUI (Quasar) · Tailwind CSS · Electron, Tauri, pywebview · Fontes · Gráficos · Política de Segurança de Conteúdo. Para cada framework: coloque ui-theme/ no local onde os arquivos estáticos são servidos, insira o bloco de cabeçalho na ordem indicada no AGENTS.md §3 e forneça a pasta sem cache (ou versione as URLs) para que atualizações sejam imediatamente visíveis. O repositório inclui dois exemplos práticos: examples/static-html/ (uma única página) e examples/fastapi-jinja/ (FastAPI + Jinja, com um app.py de 2.172 bytes).

Impressão, contraste e animações

Três aspectos que o runtime monitora e aos quais o CSS responde, sem necessidade de flags específicas por tema:

  • Impressão — O parâmetro data-print-theme controla o que será impresso (ui-theme.js:474-490): quando o tema ativo é escuro ou OLED, a opção auto alterna para o tema claro correspondente (ou o primeiro tema claro habilitado, ou daylight); um slug específico define qual tema será impresso; none não faz nenhuma alteração. Quando o tema ativo é claro, a página é impressa tal como está. A função de impressão oculta a navegação lateral, mensagens temporárias, menus, painéis e dicas de ferramentas.

  • prefers-contrast: more — todos os temas aumentam a espessura das linhas para um nível mais marcante e elevam o texto secundário ao nível terciário.

  • prefers-reduced-motion — interrompe animações em loop e encurta as demais animações; os tokens --motion-* passam a valer 0.

Versões

A partir do repositório na versão descrita neste artigo (clonado em 05/10/2026):

$ git log -1 --format='%h %ci'
56fb665 2026-10-05 21:46:52 +0900        # ThemeForge 1.0.0

$ cat ui-theme/VERSION
ThemeForge 1.0.0 3db64d9f574f

$ wc -c ui-theme/*.js ui-theme/*.css ui-theme/*.ts ui-theme/*.py 2>/dev/null
  23515 ui-theme.js
   5441 ui-components.js
   2841 ui-theme.d.ts
  16081 update.py
  13255 ui-theme-base.css
  51344 ui-components.css
  86389 ui-theme.css

$ node --check ui-theme.js ui-components.js
(node v24.18.0) — Tudo OK em ambos os arquivos, assim como em adapters/quasar.js e adapters/tailwind-v3.preset.js

$ python -m unittest discover -s tests
Foram executados 32 testes em 1,212s
OK (ignorados=1)

$ python tools/check_contrast.py --fail-on any
…
## Resumo
| Tema | Conjunto | Perfil | Verificações | Falhas |
| purple | core | standard | 147 | 0 |
| midnight-gold | core | standard | 147 | 0 |
| glacier | core | standard | 147 | 0 |
| forest | core | standard | 147 | 0 |
| paper | core | standard | 147 | 0 |
| daylight | core | standard | 147 | 0 |
| electric-yellow | opt-in | standard | 147 | 0 |
| laserlloyd | opt-in | standard | 147 | 0 |
| laserlloyd-light | opt-in | standard | 147 | 0 |
| night-red | opt-in | night | 171 | 0 |

Os alvos são os navegadores Chrome, Edge, Firefox e Safari atuais (versões de 2024 ou mais recentes). A implementação utiliza :has(), color-mix() e a API de popovers; navegadores mais antigos mantêm as cores, mas alguns estados de componentes e menus podem apresentar degradação visual.

Relacionado: ChatForge: um Assistente de IA Local com NPU para a Tecla Copilot · StudioForge: um servidor LLM exclusivo para GPU · DisPatch: chat de IA auto-hospedado · Meu conjunto de agentes de IA local · Como fazer com que um LLM adapte qualquer projeto ao seu sistema

Downloads

Gratuito para uso pessoal. Se isso te economizar uma tarde, o botão do café está logo ali.


← Mais de IA e LLM Local