Pular para o conteúdo
Lucas Bertolozzi Disponível para vagas

Construindo uma paleta de cores
que ninguém lê errado

Escopo do projeto

  • Diagnóstico da paleta anterior
  • Escolha do espaço de cor
  • Escala de 7 famílias e 12 tons
  • Matriz de contraste WCAG
  • Paletas de fundo claro e escuro
  • Variáveis no Figma
  • Documentação viva

Introdução

Numa tela de investimento, ler um número errado custa dinheiro. Por isso a cor da Clear foi construída a partir do contraste, e não conferida depois dele.

Empresa
Clear Corretora, XP Inc.
Base
OKLCH e WCAG 2.2
Role para explorar
Escrita OKLCH com as palavras lightness, chroma e hue, sobre um relevo de cores e o selo WCAG 2.2 acessível.

Resultado

Contraste no nível mais alto

Nas telas finais, todo texto passa no nível AAA da WCAG, a norma internacional de acessibilidade digital. O contraste é medido como uma razão entre o brilho do texto e o do fundo. 4,5:1 é o mínimo aceito e 7:1 é o nível mais alto.

Texto principal a 14,61:1, secundário a 9,21:1, etiquetas de status entre 7,09:1 e 12,62:1. Uma única exceção, declarada. Na paleta anterior, os rótulos dos gráficos ficavam perto de 3,5:1, abaixo do mínimo.

Problema

Uma escala que só funcionava na tentativa

Os rótulos de mínima e máxima do gráfico ficavam perto de 3,5:1 sobre o branco. Num app de corretora isso não é detalhe de estilo. É o preço da ação ilegível para quem enxerga pouco.

Trocar aquele cinza resolveria uma tela e mais nada, porque o problema era a escala inteira. A distância de luminosidade entre um tom e o próximo variava de 0,031 a 0,144, quase cinco vezes de diferença. Quem escolhia o tom 600 esperando um contraste recebia outro, e cada tela virava uma negociação nova.

Eram três famílias, primária, secundária e neutra, para um produto que precisa dizer alta, baixa, alerta, erro e informação.

Primária AAA 17,17:1 AAA 15,68:1 AAA 13,25:1 AAA 10,35:1 AA 6,90:1 AA 4,97:1 AAA 9,00:1 AAA 11,20:1 AAA 13,35:1 AAA 15,42:1 AAA 17,25:1 AAA 18,82:1 Secundária AAA 17,31:1 AAA 15,87:1 AAA 13,87:1 AAA 12,00:1 AAA 9,91:1 AAA 7,79:1 AA 5,53:1 AA 4,92:1 AAA 7,33:1 AAA 9,15:1 AAA 11,55:1 AAA 15,70:1 Neutra AAA 17,66:1 AAA 16,73:1 AAA 14,90:1 AAA 12,54:1 AAA 8,98:1 AA 5,85:1 AA 4,81:1 AAA 7,48:1 AAA 10,23:1 AAA 12,65:1 AAA 15,50:1 AAA 18,75:1
Em cada tom, a melhor cor de texto possível, branco ou quase preto, e o contraste que ela alcança.

Decisão

Por que não HSL?

HSL é o padrão da indústria e erra a luminosidade. Com a mesma receita, saturação 60% e luminosidade 40%, o verde fica com 3,25:1 sobre o branco e reprova. O vermelho fica com 7,23:1 e passa no nível mais alto. O número é igual, o brilho que o olho vê não é.

Escolhi OKLCH, um modelo que descreve a cor por luminosidade, croma e matiz seguindo a percepção do olho, e não a forma como a tela emite luz. Nele, a escala deixa de ser uma coleção de cores escolhidas e vira uma função. O tom 600 tem luminosidade 0,61 nas seis famílias de cor. É medida, não aproximação.

Os passos entre um tom e o próximo passaram a variar de 0,034 a 0,081. Duas vezes mais regular que antes.

Mesma receita, dois modelos

HSLsaturação 60% · luminosidade 40%

+2,35% 3,25:1 · reprova #29A352
−1,80% 7,23:1 · AAA #A32929

OKLCHluminosidade 0,45

+2,35% 7,07:1 · AAA #27643A
−1,80% 7,91:1 · AAA #952B29

Em HSL, o mesmo número de luminosidade gera brilhos diferentes. Em OKLCH, a mesma luminosidade parece igual para o olho.

Azul AAA 17,17:1 AAA 15,51:1 AAA 13,19:1 AAA 10,88:1 AAA 8,62:1 AA 6,50:1 AA 4,77:1 AA 5,56:1 AAA 8,00:1 AAA 9,90:1 AAA 12,31:1 AAA 15,68:1 Verde AAA 17,27:1 AAA 15,66:1 AAA 13,80:1 AAA 11,52:1 AAA 9,16:1 AAA 7,04:1 AA 5,22:1 AA 4,97:1 AAA 7,07:1 AAA 9,03:1 AAA 11,53:1 AAA 15,22:1 Vermelho AAA 17,18:1 AAA 15,39:1 AAA 13,03:1 AAA 10,65:1 AAA 8,25:1 AA 6,10:1 — 4,39:1 AA 5,75:1 AAA 7,91:1 AAA 9,79:1 AAA 12,32:1 AAA 15,80:1 Âmbar AAA 17,14:1 AAA 15,48:1 AAA 13,14:1 AAA 10,80:1 AAA 8,48:1 AA 6,48:1 AA 4,81:1 AA 5,30:1 AAA 7,49:1 AAA 9,40:1 AAA 11,88:1 AAA 15,55:1 Turquesa AAA 17,19:1 AAA 15,70:1 AAA 13,62:1 AAA 11,37:1 AAA 9,03:1 AA 6,92:1 AA 5,10:1 AA 5,02:1 AAA 7,14:1 AAA 9,07:1 AAA 11,67:1 AAA 15,32:1 Roxo AAA 17,13:1 AAA 15,42:1 AAA 13,10:1 AAA 10,71:1 AAA 8,31:1 AA 6,16:1 — 4,40:1 AA 5,91:1 AAA 8,08:1 AAA 9,95:1 AAA 12,40:1 AAA 15,77:1 Neutro AAA 17,81:1 AAA 16,78:1 AAA 15,01:1 AAA 12,66:1 AAA 9,26:1 AA 6,14:1 — 4,32:1 AAA 7,83:1 AAA 9,50:1 AAA 11,96:1 AAA 14,99:1 AAA 18,44:1
Em cada tom, a melhor cor de texto possível, branco ou quase preto, e o contraste que ela alcança.

Método

Quando o contraste entra na conta?

Conferido no fim, o contraste vira retrabalho. Escolhe, testa, reprova, volta. Usado como ponto de partida, ele vira garantia.

Calculei a matriz cruzada de todos os pares de texto e fundo do sistema e transformei o resultado em regra de uso. Quais tons aceitam texto, quais não aceitam, e a partir de que tamanho de letra a resposta muda. Quem desenha não precisa medir. Precisa seguir.

Recorte da matriz · texto sobre fundo, modo claro

FundoFundo suaveFundo rebaixadoAção principalAlta, fundoBaixa, fundo
Texto principal 18,44 · AAA 17,81 · AAA 16,78 · AAA 2,31 · reprova 2,61 · reprova 2,33 · reprova
Texto secundário 9,50 · AAA 9,17 · AAA 8,64 · AAA 1,19 · reprova 1,34 · reprova 1,20 · reprova
Texto terciário 7,83 · AAA 7,56 · AAA 7,12 · AAA 1,02 · reprova 1,11 · reprova 1,01 · reprova
Destaque 8,00 · AAA 7,72 · AAA 7,28 · AAA 1,00 · reprova 1,13 · reprova 1,01 · reprova
Alta, texto 9,03 · AAA 8,72 · AAA 8,21 · AAA 1,13 · reprova 1,28 · reprova 1,14 · reprova
Baixa, texto 7,91 · AAA 7,64 · AAA 7,20 · AAA 1,01 · reprova 1,12 · reprova 1,00 · reprova
Texto sobre cor 1,00 · reprova 1,04 · reprova 1,10 · reprova 8,00 · AAA 7,07 · AAA 7,91 · AAA
Par autorizado pelo sistema. Cada célula é pintada com o par real de texto e fundo.

Trade-off

Como mostrar alta e baixa sem depender da cor?

Alta em verde e baixa em vermelho é a convenção mais forte do mercado financeiro e uma das piores para acessibilidade. É o caso clássico de daltonismo, que atinge cerca de 8% dos homens. Aqui o erro não é estético, é o saldo da pessoa.

Abandonar a convenção não era opção, porque quem opera lê a cor antes do número. A saída foi não deixar a cor sozinha. O sinal de mais ou de menos vem sempre colado no número, e no gráfico cada série ganha traço e marcador próprios.

Aqui o OKLCH se pagou. O verde e o vermelho de alta e baixa estão no mesmo tom da escala, o 800, com a mesma luminosidade, 0,45. A linha de baixa não pesa mais que a de alta sem motivo. O preço dessa escolha é que, sem o matiz, os dois viram o mesmo tom. O sinal deixou de ser detalhe e virou regra.

Limite

Até onde a escala aguenta?

A paleta anterior vivia na borda do que a tela consegue mostrar, entre 95% e 100% do limite do sRGB, o conjunto de cores de uma tela comum, na maioria dos tons. Cor nessa região é instável. Ela satura, perde diferença entre tons vizinhos e muda de um aparelho para outro.

A escala nova segue uma curva de croma, a intensidade da cor, que vai de 28% a 88% desse limite. Sobe até o meio da rampa e cai nas pontas. Os tons muito claros e muito escuros abrem mão de intensidade para manter a luminosidade previsível. O sistema perde alguns tons vibrantes nas extremidades e ganha o direito de ser usado por regra.

QUANTO CADA TOM USA DO LIMITE DO sRGB

Paleta anterior Paleta nova

Decisão

Modo escuro é a paleta clara invertida?

Não. Cor muito saturada sobre fundo escuro parece vibrar e sair do plano, um efeito que cansa rápido em leitura longa. Essas cores ficaram fora do modo escuro, com o sistema da Atlassian como referência de tonalidade. As superfícies escuras passaram de três para quatro níveis.

Em vez de redefinir as mesmas variáveis conforme o contexto, montei dois conjuntos completos de primitivos, as cores cruas que o sistema inteiro referencia. Um para fundo claro, outro para escuro. A alternativa deixaria o arquivo mais enxuto e quebraria a entrega para desenvolvimento, porque o Dev Mode do Figma perde o rastro de um valor que muda de significado dependendo de onde está. Arquivo menor não vale entrega pior.

Superfícies do modo escuro · antes 3, agora 4

Fundo #0D1116

Fundo suave #14171E

Elevado #1B1F26

Sobreposição #24282F

Limite

E quando a matemática não fecha?

Seis séries de gráfico distinguíveis entre si a 3:1 exigiriam 3 elevado a 5, ou seja 243:1 entre os extremos. Uma tela comum oferece cerca de 21:1. Não existe paleta que resolva isso, e sistema que promete resolver está errando a conta.

A regra que ficou: cada série tem no mínimo 3:1 contra o fundo, e a diferença entre séries nunca depende só de cor. Traço, marcador e rótulo fazem o resto, como a própria norma exige.

Resultado

O que ficou para o time?

Um documento vivo de oito seções, do tipo que um time consulta em vez de perguntar. Propriedades, paleta, acessibilidade tipográfica, matriz de tokens no nível AAA, contraste de elementos que não são texto, aparência de foco, séries de gráfico e o guia de migração da versão anterior.

No Figma, 224 variáveis em três coleções. Primitivos com as cores cruas, semânticos com o significado de cada uso, como fundo, texto, alta e baixa, e componentes. Dois modos, claro e escuro.

A exceção declarada é o texto de exemplo (placeholder) do campo de busca, a 5,75:1. Passa no AA e não no AAA. Está documentada como exceção em vez de arredondada para cima, porque um sistema que esconde a própria exceção deixa de ser verificável.

Aprendizados

O que eu levo deste projeto

  1. 01

    Contraste é ponto de partida

    Quando a regra nasce da medida, ninguém precisa medir de novo. Conferir no fim só descobre o erro mais tarde.

  2. 02

    Exceção declarada vale mais que nota perfeita

    Um 5,75:1 escrito no documento é mais confiável do que um AAA em todo lugar que ninguém consegue verificar.

  3. 03

    Quando a cor não basta, a resposta não é outra cor

    Daltonismo e séries de gráfico tiveram a mesma saída, um segundo canal. Sinal, traço e marcador.

Créditos

Sistema de cor e verificação de acessibilidade meus de ponta a ponta, sobre a fundação de tokens primitivos da Clear que eu havia criado no SOMA.

Próximo projeto

Páginas de documentação do design system SOMA com a marca XP Inc.: tipografia, efeitos e a escala de cores.

XP Investimentos, Clear Corretora, XP Inc.

Ensinando três marcas a falarem a mesma língua

Em breve