Teoria das Cores para Interfaces
Cor em UI é principalmente um problema de luminosidade usando uma fantasia de matiz. Hierarquia, contraste, legibilidade e modo escuro são todos decididos pela luminosidade; o matiz carrega identidade e significado; o croma (saturação) carrega ênfase. Trabalhe nessa ordem.
O kit de ferramentas — use-o em vez de chutar
scripts/palette.py (Python 3, sem dependências) calcula tudo em OKLCH e mapeia para o gamute sRGB. Nunca chute uma taxa de contraste ou invente uma rampa manualmente quando puder calculá-la.
S=<skill-dir>/scripts/palette.py # <skill-dir> = diretório base mostrado quando esta skill carrega
python3 $S system "#6d28d9" # sistema completo: rampas + funções claro/escuro, todos os pares verificados
python3 $S system "#6d28d9" --format tailwind # Tailwind v4 @theme + variáveis semânticas (também: css, json = DTCG)
python3 $S ramp "#0f766e" --format css # uma rampa 50–950 (entrada ajustada ao passo mais próximo)
python3 $S neutral "#0f766e" --tint 0.01 # rampa cinza matizada para o matiz da marca
python3 $S contrast "#fff" "#7c3aed" # taxa WCAG + níveis + APCA Lc
python3 $S cvd "#16a34a" "#dc2626" "#2563eb" # simulação de daltonismo + pares confundíveis
python3 $S harmony "#6d28d9" --scheme split # relações de matiz em OKLCH
python3 $S convert "hsl(...)/#hex/oklch(...)" # conversão entre notações + quão vívida é a cor
system automaticamente percorre os passos ao longo de uma rampa quando um par falha (por exemplo, escurece text-muted até atingir 4.5:1) e imprime cada ajuste — repasse-os ao usuário, pois são decisões de design.
Fluxo de trabalho: de "preciso de cores" a tokens enviados
- Encontre a âncora. Já tem uma cor de marca? Use-a. Não tem? Derive da personalidade do produto (veja Escolhendo um matiz abaixo) e proponha 2–3 sementes com uma breve justificativa cada, em vez de uma única escolha arbitrária.
- Gere o sistema com
palette.py system <seed>. Uma rampa de acento, uma rampa neutra e apenas as rampas de status que o produto renderiza. - Mapeie para papéis semânticos, nunca use primitivas em componentes (
--color-accent,--color-text-muted, não--violet-600). A skill de construtor de design system cobre a arquitetura de tokens em profundidade. - Verifique: contraste no par renderizado (texto em sua superfície real, incluindo alfa/sobreposições), ambos os temas, verificação de CVD para qualquer significado codificado por cor (gráficos, status, tags).
- Aplique com moderação (abaixo) e então observe o resultado renderizado.
Quanta cor: distribuição
- Neutros fazem ~90% do trabalho. Fundos, superfícies, texto, bordas. Uma UI construída sobre bons neutros com um acento quase sempre parece mais profissional do que uma com múltiplos matizes.
- 60-30-10 é uma verificação de sanidade útil: ~60% neutro dominante, ~30% superfície secundária / variação neutra, ~10% acento. Se o acento exceder ~10–15% dos pixels, ele deixa de significar "aja aqui".
- Uma ação primária preenchida por visual. Cor no fundo de um botão é lida como primária de longe; texto colorido é lido como link.
- Uma cor, um significado. Se violeta significa "marca/interativo", não a use também para uma tag de categoria. Matizes de status devem ficar claramente separados do acento (a ferramenta mantém ≥25° no matiz OKLCH).
- Cor nunca é o único sinal. ~8% dos homens e ~0,5% das mulheres têm deficiência de visão de cores; combine cor com um ícone, rótulo, padrão ou posição.
Escolhendo um matiz (quando não há marca)
As associações são dependentes de cultura e fracas em comparação com a execução — uma paleta bem construída em qualquer matiz supera um matiz "psicologicamente correto" usado mal. Use-as como desempates:
| Família de matiz | Leitura comum em UI | Produtos típicos | Cuidado |
|---|---|---|---|
| Azul / índigo | confiança, calma, competência | fintech, SaaS, saúde, enterprise | a escolha mais genérica; aumente o croma ou desloque para índigo/ciano para se destacar |
| Violeta | criativo, premium, "IA" | ferramentas criativas, produtos de IA | violeta muito saturado agora é um sinal de "caspa de IA" |
| Verde / verde-azulado | crescimento, dinheiro, saúde, sucesso | finanças, sustentabilidade, bem-estar | conflita com status "sucesso" — ajuste o matiz de status |
| Vermelho / rosa | energia, urgência, paixão | comida, mídia, entretenimento | conflita com "perigo"; use para momentos de marca, mantenha ações destrutivas distintas |
| Laranja / âmbar | calor, amizade, ação | consumidor, comida, marketplaces | laranjas escuros tornam-se marrons; verifique preenchimentos em modo claro |
| Amarelo / lima | otimismo, atenção | consumidor, lúdico | não pode ter texto branco; use texto escuro sobre preenchimentos amarelos, ou use a marca como acento-subtle e escolha um passo mais escuro para preenchimentos (--hue-shift -15 mantém tons dourados em vez de verde-oliva) |
| Quase neutro (preto/pedra/areia) | luxo, editorial, ferramentas | ferramentas de dev, moda, portfólios | precisa de habilidade tipográfica e espacial para não parecer vazio |
Notas regionais úteis: vermelho é sortudo/celebratório na China, mas significa perda em finanças ocidentais (e ganho em tickers de ações chinesas/japonesas); branco está associado ao luto em partes do Leste Asiático. Para UIs financeiras, torne as cores de sobe/desce configuráveis.
Cor perceptual — por que OKLCH
A luminosidade HSL mente: hsl(60 100% 50%) (amarelo) e hsl(240 100% 50%) (azul) compartilham "L=50%" mas diferem enormemente em brilho percebido. É por isso que as rampas HSL têm contraste irregular e passos escuros/claros que não se alinham entre matizes.
OKLCH = L (luminosidade percebida 0–1) · C (croma, ~0–0.37) · H (ângulo de matiz). L igual ≈ luminosidade percebida igual entre matizes, então:
- o mesmo passo entre rampas (todos
-600s) tem contraste similar contra branco, - você pode rotacionar o matiz sem alterar a luminosidade (harmonias, cores de status que "combinam"),
- o modo escuro pode ser derivado raciocinando sobre L.
Ressalvas: o gamute sRGB é irregular — cada matiz tem um croma máximo diferente em cada L (amarelo atinge o pico perto de L≈0,95, azul perto de L≈0,45). A ferramenta mapeia o gamute reduzindo o croma, mantendo L e H. Cores de gamute amplo (Display-P3) são um aprimoramento: declare o valor sRGB primeiro, depois o P3/oklch() vívido dentro de @media (color-gamut: p3).
CSS suporta oklch() em todos os navegadores modernos; use-o em novos projetos web. Em plataformas nativas, converta para a notação da plataforma (hex/sRGB, Color(red:green:blue:), Color(0xFF…)) — a opção --notation hex da ferramenta ajuda.
Rampas, neutros e matizações
- Rampas mantêm um único matiz do início ao fim, com passos mais finos no lado claro (é onde os fundos vivem e o olho é mais sensível), e pico de croma no meio da rampa. 11 passos (50–950, convenção Tailwind) ou 12 (convenção Radix, cada passo tem uma função nomeada) — veja
references/ramps-and-roles.mdpara o mapa de funções. - Neutros matizados: misture um pouco do matiz da marca nos cinzas (croma ≈ 0.005–0.02). Isso faz toda a UI parecer coesa; cinzas #808080 puros parecem mortos ao lado de um acento saturado. Marca quente → cinzas quentes; frio → frio.
- Nunca use preto puro sobre branco puro para texto longo em UIs com marca; quase-preto (neutral-950) sobre quase-branco reduz o brilho. Fundos pretos puros no modo escuro causam borrões em OLED durante a rolagem; use L ≈ 0.13–0.18.
Modo escuro não é inversão
- A elevação vai mais clara, não sombra mais escura: superfície > fundo por ~0.03–0.06 L.
- Dessature os acentos ligeiramente e aumente sua luminosidade; tons médios saturados vibram em fundos escuros.
- Texto do corpo ligeiramente off-white (neutral-50/100), texto suave por volta de neutral-400.
- Preenchimentos frequentemente invertem seu rótulo para texto escuro (a ferramenta decide pelo contraste).
- Remede cada par; o contraste não sobrevive à reversão. Veja
references/dark-mode.md.
Contraste — os padrões
| Par | WCAG 2.2 AA | AAA | Orientação APCA (consultiva) |
|---|---|---|---|
| Texto do corpo (<24px / <18,66px negrito) | 4.5:1 | 7:1 | Lc 75+ (90 preferido) |
| Texto grande (≥24px ou ≥18,66px negrito) | 3:1 | 4.5:1 | Lc 60+ |
| Componentes de UI e objetos gráficos necessários para entendê-los (bordas de input, ícones, anéis de foco, marcas de gráfico) | 3:1 (SC 1.4.11) | — | Lc 45+ |
| Controles desabilitados, elementos decorativos, logotipos | isentos | — | — |
WCAG 2.x é a base legal/de conformidade (ADA, EN 301 549 / European Accessibility Act). APCA (candidato do WCAG 3) modela melhor a percepção, especialmente para modo escuro e texto claro, mas o WCAG 3 não é final — atenda ao WCAG 2.2 AA e use APCA como segunda opinião. Detalhes, regras de anel de foco e pegadinhas em references/contrast-and-cvd.md.
Gradientes, sobreposições e alfa
- Interpole gradientes
in oklab(suave, sem meio lamacento); usein oklchpara varreduras multicoloridas que ficariam cinzas no meio. Mantenha os pontos de parada próximos em luminosidade para fundos atrás de texto. - Texto sobre imagens: uma scrim (sobreposição gradiente) ou um fundo sólido; meça a região de pior caso.
- Cores com alfa (
/50,rgba) mudam o contraste dependendo do que está por baixo. Prefira tokens sólidos para texto; reserve alfa para sobreposições, hovers e sombras.
Visualização de dados
Paletas categóricas precisam de luminosidade aproximadamente igual e separação máxima de matiz; paletas sequenciais variam a luminosidade monotonicamente; paletas divergentes compartilham um ponto médio neutro. Use a skill dataviz se disponível — ela tem um método de paleta validado. Sempre execute palette.py cvd nas cores das séries do gráfico.
Revisando as cores de alguém — lista de verificação rápida
- Cada par texto/fundo medido em ambos os temas (não estimado)
- Bordas de input, anéis de foco, ícones que transmitem significado ≥ 3:1
- Nenhum hex/rgb bruto em componentes; apenas tokens semânticos
- Um acento, usado apenas para significado interativo/primário
- Cores de status distintas do acento e entre si sob simulação de CVD
- Neutros matizados consistentemente (não uma mistura de cinzas frios e quentes)
- Modo escuro projetado (superfícies mais claras para elevação, acentos ajustados), não invertido
- Significado nunca transmitido apenas por cor
Para uma auditoria completa do sistema de cores com descobertas classificadas por severidade, a skill better-colors é excelente; para escolher/derivar/gerar, fique aqui.
Referências
references/ramps-and-roles.md— mapeamento de funções passo a passo (Tailwind 50–950 e Radix 1–12), cores de estado (hover/active/disabled/selected)references/dark-mode.md— construção de tema escuro, elevação, especificidades de plataforma (cores semânticas iOS, superfícies tonais Material)references/contrast-and-cvd.md— detalhes do WCAG 2.2, níveis APCA, indicadores de foco, regras de design para CVDreferences/harmony-and-brand.md— esquemas de harmonia, derivação de cores secundárias, tradução de marca para UI, temperatura, contraste simultâneo