Cores na tela são apenas números, mas os formatos variam bastante — HEX para designers, RGB para o CSS tradicional, HSL para manipulação intuitiva, OKLCH para espaços perceptualmente uniformes, e classes Tailwind para workflows utility-first. Este picker mantém todos os cinco sincronizados: edite qualquer campo e os outros quatro resolvem em microssegundos, com a swatch atualizando no lugar. Tudo roda no navegador; nada vai para servidor.
Espaços de cor: por que uma cor tem cinco nomes
Uma cor na tela, no nível mais baixo, são três tensões — o quanto o monitor empurra os subpixels vermelho, verde e azul. O padrão de referência dessas tensões é o sRGB (IEC 61966-2-1), ratificado em 1996 e ainda o baseline seguro para trabalho cross-device na web. Todo valor HEX e todo rgb() simples no CSS vive em sRGB. Os displays modernos da Apple — iPhone, iPad Pro, MacBook Pro — renderizam o gamut mais amplo Display P3, que contém cerca de 25% mais volume de cor e alcança vermelhos e verdes mais profundos que sRGB não consegue representar.
HSL, OKLCH e a paleta Tailwind não são espaços separados no sentido de gamut — são parametrizações diferentes do mesmo cubo sRGB. HEX/RGB descrevem o cubo em coordenadas cruas. HSL rotaciona para matiz/saturação/luminosidade visando edição intuitiva. OKLCH remodela para acompanhar a percepção humana. As classes Tailwind são um subconjunto curado de 244 pontos pensado para UI de produto.
HEX e RGB: as tensões literais
HEX é a notação curta do designer para uma tripla sRGB. #ef4444 significa vermelho 0xef (239), verde 0x44 (68), azul 0x44 (68); a mesma cor em CSS aparece como rgb(239, 68, 68). A forma de três dígitos #f44 expande dobrando cada nibble: #f44 → #ff4444. O picker aceita as duas formas, normaliza para hex de seis dígitos em minúsculas no commit, e rejeita input malformado inline em vez de pegar um fallback silencioso.
RGB é HEX com o parsing removido. Designers tendem a copiar HEX do Figma, engenheiros tendem a digitar RGB direto em literais CSS-in-JS. Não há diferença de informação. A forma HEX de oito dígitos com alpha (#ef4444cc) é reconhecida pelos navegadores, mas este picker trata sRGB de três canais apenas — alpha é uma preocupação separada, em camadas.
HSL: intuitivo mas desigual
O HSL foi adicionado ao CSS no fim dos anos 2000 para dar aos designers uma parametrização mais intuitiva: matiz é a posição numa roda de cores de 360°, saturação é o quanto a cor é vívida, luminosidade é grosso modo o quanto é brilhante. Rotacionar o matiz mantendo saturação e luminosidade constantes produz um ciclo limpo. Reduzir saturação a zero gera cinza. Empurrar luminosidade até 100% gera branco. Esses mapeamentos casam com o modo como as pessoas falam sobre cor.
O detalhe é que HSL é geométrico, não perceptual. Luminosidade 50% é mais escuro para azul do que para amarelo — o mesmo número mapeia para brilhos percebidos diferentes dependendo do matiz. Para edições rápidas tudo bem; para trabalho sistemático (paletas, pares de dark-mode, ajuste de contraste) isso morde. É o problema que o OKLCH resolve.
OKLCH: percepção como unidade
O OKLab foi publicado por Björn Ottosson em dezembro de 2020 como um post de blog — não um artigo acadêmico formal, apenas uma solução cuidadosamente trabalhada para um problema em processamento de imagem. Ele ajustou uma transformação contra dados empíricos de discriminação de cor (elipses de MacAdam, dataset Luo-Rigg) de forma que distâncias numéricas iguais no espaço correspondam a distâncias percebidas iguais para um observador humano. A forma polar, OKLCH, troca as coordenadas cartesianas a/b por chroma e hue. Foi adicionada ao CSS Color Module Level 4 no fim de 2021.
Os ganhos práticos: interpolar entre duas cores OKLCH mantém o matiz percebido (HSL famosamente afunda no cinza no meio do caminho entre pares complementares), e ajustar luminosidade move de forma previsível em todo o espectro. O Tailwind v4 armazena sua paleta inteira em OKLCH justamente por isso. Luminosidade L vai de 0 a 1, chroma C vai aproximadamente de 0 a 0.4 dentro do sRGB (mais alto só em displays wide-gamut), hue H é em graus como no HSL. Quando o chroma é zero, a cor é acromática e o matiz é matematicamente indefinido; este picker normaliza esse caso para H=0.
Tailwind: uma paleta curada de 244 pontos
O sistema de cores default do Tailwind tem 22 famílias — slate, gray, zinc, neutral, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose — cada uma com 11 tons de 50 (mais claro) a 950 (mais escuro). O tom 950 entrou na v3.3 do Tailwind (abril de 2023); codebases mais antigas param em 900. Black e white fecham a paleta em 244 cores nomeadas. A adoção do Tailwind na community frontend brasileira é hoje um dos pontos de convergência mais fortes entre times de design e engenharia.
O picker mapeia qualquer cor sRGB para a classe Tailwind mais próxima calculando a distância euclidiana no espaço de canais de 8 bits e retornando a menor. Δ=0 é um match exato; abaixo de 20 é visualmente indistinguível; acima de 50 significa que o tom mais próximo é um shift perceptível e você provavelmente deveria estender seu config em vez de aproximar. O lookup roda a cada digitação e nunca trava o input.
Precisão de conversão e drift no round-trip
Ir de HEX → HSL → HEX perde no máximo um canal por eixo, porque HSL armazena valores em ponto flutuante que voltam quantizados para 8 bits na saída. HEX → OKLCH → HEX pode driftar em dois canais em cantos extremos do gamut, porque OKLCH passa por um estágio de sRGB linear com raízes cúbicas que não invertem exatamente em aritmética de ponto flutuante. Esses drifts ficam abaixo do limiar perceptual — o olho não consegue distinguir que seu #abcdef voltou como #aacdef.
Para armazenamento, trate sempre o HEX como fonte da verdade. O histórico recente do picker segue a mesma regra: apenas o HEX canônico é persistido, e as quatro formas derivadas são recalculadas no recall. Duas razões. Primeira, payload menor. Segunda, nenhum risco de que um fix futuro na matemática de conversão produza snapshots desatualizados no seu histórico.
EyeDropper: quando o navegador colabora
A EyeDropper API permite que uma página amostre qualquer pixel sob o cursor — em qualquer lugar da tela, inclusive fora da janela do navegador. O gesto do usuário (clicar no botão) é o consentimento; não há prompt intrusivo. O detalhe é o suporte: engines baseadas em Chromium (Chrome 95+, Edge, Opera, Brave) implementam; Firefox e Safari ainda não. O picker detecta window.EyeDropper no mount e desabilita o botão de forma limpa quando ausente — em vez de quebrar ou fingir funcionar.
Onde o workflow paga o próprio custo
Migração de design system é o caso pesado: você tem um HEX da marca, quer a classe Tailwind mais próxima para um protótipo rápido, e quer ver qual é a luminosidade OKLCH antes de comprometer-se com um par. Outros padrões: ajustar pares de dark-mode (manter o matiz, baixar a luminosidade, observar o OKLCH-L num número sensato), avaliar headroom de acessibilidade (delta de OKLCH-L entre foreground e background serve como proxy útil para contraste WCAG), extrair uma cor de um screenshot ou app externo via EyeDropper, ou apenas manter uma paleta de trabalho na tira de recentes enquanto você esboça.

