@orkestra-ai/contraste
v0.1.0
Published
A régua de contraste da suíte Orkestra: mede todas as superfícies x papéis x temas de um globals.css contra os mínimos da WCAG 2.1. Zero dependências.
Maintainers
Readme
@orkestra-ai/contraste
Mede o contraste de um globals.css contra os mínimos da WCAG 2.1 §1.4.3 —
todas as superfícies × todos os papéis de texto × os dois temas.
Zero dependências. Node ≥ 18.
npx @orkestra-ai/contraste app/globals.css=== app/globals.css
temas lidos: escuro=":root" claro=":root[data-theme="light"]"
32 pares medidos
todos dentro do mínimo da WCAGSai com 1 se algum par reprovar, se um bloco de tema não for encontrado, se um token faltar ou se um valor não for hexadecimal. Serve como portão de CI.
Por que mede tudo, e não uma superfície
Porque foi assim que um defeito real passou. Uma correção anterior mediu o texto apagado contra um fundo, passou com 4,67:1 e declarou vitória. O mesmo token dava 4,46:1 sobre o fundo elevado e 4,16:1 sobre o painel — e é dentro de cartão que os rótulos vivem. Um portão só mede a pergunta que ele faz.
Dois mínimos, e o segundo é o esquecido
| | mínimo | | ------------------------------------------------------------------ | ------ | | texto normal | 4,5:1 | | texto grande e elemento gráfico — borda de 1px, traço de ícone | 3,0:1 |
Texto desabilitado é medido contra o piso gráfico: ele precisa de ser perceptível, não confortável. Exigir-lhe 4,5:1 obrigaria a uma cor que já não se lê como desabilitada.
O que ele lê
Tokens --color-* declarados em blocos de tema:
- escuro:
:root,html, e dentro de@media (prefers-color-scheme: dark); - claro:
:root[data-theme="light"],html[data-theme="light"],.light,:root.light.
Superfícies: --color-bg-base, --color-bg-raised, --color-bg-sunken,
--color-bg-panel. Papéis: --color-text-primary, --color-text-secondary,
--color-text-muted, --color-text-disabled.
At-rules que não são tema são ignoradas — inclusive o @theme do Tailwind v4,
cujos valores são pontes var() e não cores.
--color-text-inverted fica fora de propósito: é usado sobre preenchimento
de acento, não sobre superfície, e medi-lo contra as superfícies daria números
plausíveis e sem sentido.
Nunca sai verde sem medir
É a propriedade que o pacote existe para garantir. Uma régua que lê CSS e não encontra os tokens reportaria zero reprovações e passaria — por isso toda lacuna lança, com o motivo e o ficheiro nomeados: bloco ausente, token ausente, valor não hexadecimal.
API
import { medirCss, tokensDoCss, razao, MINIMO_TEXTO } from '@orkestra-ai/contraste';
const v = medirCss(css, 'app/globals.css');
v.reprovadas; // Medicao[]
razao('#757f9c', '#10162a'); // 4.51Aviso
Ferramenta interna da suíte Orkestra, publicada para os nossos repositórios a poderem instalá-la. Funciona para qualquer projeto com a mesma convenção de tokens, mas a lista de superfícies e papéis não é configurável nesta versão.
MIT.
