Generador de Temas & Paletas OKLCH

Generador de paletas armónicas y tokens de diseño accesibles en espacio perceptual OKLCH. Diseñado con validación de contraste WCAG AAA para Dark/Light mode y exportación directa a CSS y Tailwind CSS v4.

Paleta Armónica (5 tonos)

Clic en cualquier swatch para copiar HEX

Design Tokens (Oscuro)

Haz clic para copiar HEX
--primary#236BDD
--secondary#E3BE80
--accent#426EB4
--muted#12161C
--background#030407

Vista Previa de Interfaz

#004FBE
#3B82F6
#84B3FF
#F7D193
#B99964
B
Buscer SaaS Dashboard
Revenue+12.5%
$48,290

vs. último periodo

LatenciaAtención
142ms

P95 · últimas 24h

ErroresCrítico
3

últimas 4 horas

🛡️WCAG 2.1 AA Verificado: Mín. interactivo 4.76:1 (≥4.5:1) · Micro-tipografía 9.14:1 (AAA)
AA PASSOKLCH

Exportar Código

:root {
  --background: #F7FAFF;
  --foreground: #051127;
  --primary: #2068D9;
  --primary-foreground: #F7FAFF;
  --primary-text: #10397B;
  --secondary: #F7D193;
  --secondary-foreground: #261E10;
  --secondary-text: #523800;
  --accent: #426EB4;
  --accent-foreground: #F7FAFF;
  --accent-text: #0F3A7B;
  --muted: #E6ECF5;
  --muted-foreground: #393D44;
  --card: #FFFFFF;
  --card-foreground: #041127;
  --border: #D5DBE5;
  --ring: #2068D9;
  --input: #EAEFF7;
  --destructive: #9D2E56;
  --destructive-foreground: #FFF8F9;
  --destructive-text: #6C1737;
  --success: #006646;
  --success-foreground: #F3FDF8;
  --success-text: #004931;
  --warning: #9B3B00;
  --warning-foreground: #FFF9F6;
  --warning-text: #682500;
}

.dark {
  --background: #030407;
  --foreground: #F8FAFF;
  --primary: #236BDD;
  --primary-foreground: #F7FAFF;
  --primary-text: #83B2FD;
  --secondary: #E3BE80;
  --secondary-foreground: #261E10;
  --secondary-text: #E3BE80;
  --accent: #426EB4;
  --accent-foreground: #F7FAFF;
  --accent-text: #83B2FD;
  --muted: #12161C;
  --muted-foreground: #A0A5AC;
  --card: #0A0B0E;
  --card-foreground: #F8FAFF;
  --border: #1B1F27;
  --ring: #236BDD;
  --input: #111419;
  --destructive: #AD4568;
  --destructive-foreground: #FFF8FA;
  --destructive-text: #F090AB;
  --success: #007C56;
  --success-foreground: #F3FDF8;
  --success-text: #66C79D;
  --warning: #AF4E1E;
  --warning-foreground: #FFF9F6;
  --warning-text: #F19771;
}
Behind the Build

Cómo construí un generador de temas accesible con OKLCH y Tailwind v4

Las decisiones técnicas detrás de la herramienta: espacios perceptuales, algoritmos de gamut y contraste en CSS moderno.

Buscer

Julio Buscer

Ingeniería · Asistido por IA

Full Stack & Arquitectura de Software

Lectura: 4 min

“Armé este generador porque me cansé de lidiar con los mismos problemas de siempre: botones secundarios que brillan más que el principal, textos ilegibles en tarjetas oscuras y colores que se rompen al pasarlos a CSS. Aquí te cuento cómo lo resolví y por qué tomé cada decisión.”

¿Qué hace?

Calcula paletas completas para modo claro y oscuro con contraste accesible, listas para copiar y pegar en Tailwind v4 (@theme) o variables CSS. Todo corre en tu navegador sin librerías pesadas.

¿Por qué hacía falta?

Los modelos tradicionales como HSL tratan la luz como una escala matemática lineal sin reflejar cómo el ojo humano percibe el brillo. El resultado común son textos claros que pierden legibilidad sobre fondos amarillos o verdes, o temas oscuros con saturación excesiva que cansan la vista.

4 decisiones clave al armar la herramienta

Decisión 01Espacio de color

Cambiar HSL por OKLCH

El problema

En HSL, un amarillo al 50% y un azul al 50% tienen el mismo número, pero el ojo humano ve el amarillo mucho más brillante. Si pones texto blanco sobre ese amarillo, simplemente no se puede leer.

La solución

Cambiamos a OKLCH. En este espacio, la luminosidad (L) coincide con cómo vemos la luz en la vida real: un 70% de brillo se ve igual de claro en un azul que en un amarillo.

Regla práctica:Usa OKLCH si quieres que los contrastes de tus botones no dependan de la suerte.
Ottosson, B. (2020). A perceptual color space for computer graphics.
Ver fuente
Decisión 02Límites de pantalla

Ajustar colores fuera de gama en vez de recortarlos

El problema

Al calcular colores en OKLCH puedes obtener tonos que un monitor normal no puede mostrar. Si dejas que el navegador recorte los canales RGB a la fuerza, el color se deforma y un morado termina viéndose azul opaco.

La solución

Metimos una búsqueda binaria rápida: congelamos el tono y el brillo, y solo bajamos la saturación poco a poco hasta que el color quepa bien en pantalla sin perder su identidad.

Regla práctica:Si un color se sale de la pantalla, baja su saturación; no dejes que el navegador lo recorte a lo loco.
W3C (2022). CSS Color Module Level 4: Gamut Mapping Algorithm.
Ver fuente
Decisión 03Tipografía

Separar el color del botón del color del texto

El problema

Un color con brillo medio funciona bien para el fondo de un botón grande, pero si usas ese mismo color en un texto chico sobre fondo oscuro, las letras se pierden y cansan la vista.

La solución

Creamos variables de texto específicas (*-text). Aclaran el tono de la letra lo suficiente para cumplir contraste AAA (6.5:1 o más) sin cambiar el color de tu botón.

Regla práctica:El fondo de un botón tiene mucha área; las letras finas necesitan mucho más contraste de luz.
W3C WCAG 2.1 — Criterio de conformidad 1.4.6 Contraste (Mejorado).
Ver fuente
Decisión 04Jerarquía visual & espectro

Curva de luminosidad natural y jerarquía de botones

El problema

Al rotar 180° para buscar complementarios, forzar la misma luminosidad del color base hace que amarillos y tonos cálidos se conviertan en marrón fango o mostaza sucia. Además, si los botones secundarios no tienen presencia o usan texto al tanteo, la interfaz se rompe y falla accesibilidad.

La solución

Modelamos la curva de luminosidad natural de los conos humanos (Helmholtz-Kohlrausch) en OKLCH: los complementarios cálidos se modulan a su pico natural (L ≈ 0.82-0.88), se mapean con cuerpo real al botón secundario con contraste AAA garantizado (>11:1), y la herramienta audita en tiempo real cada ratio interactivo.

Regla práctica:Cada matiz tiene un brillo natural en el ojo humano; no fuerces a un amarillo a tener la luz de un azul.
Vos, J. J. (1960). Some new aspects of chromostereopsis. JOSA.
Ver fuente

Las 6 armonías que incluye el generador

Complementario

180°

Colores opuestos modulados con su luminosidad natural espectral para evitar tonos fangosos.

Tríada

120° / 240°

Tres puntos repartidos por igual en el círculo cromático para interfaces variadas.

Análogo

+15° / +30°

Colores vecinos para interfaces tranquilas y uniformes.

División Complementaria

150° / 210°

Color base con los dos vecinos de su opuesto. Buen contraste sin tanta tensión.

Tetrádica

60° / 180° / 240°

Dos pares de complementarios para cuando necesitas muchos estados o etiquetas.

Monocromático

0° (ΔL, ΔC)

Mismo tono cambiando solo brillo y saturación. Ideal para interfaces limpias.

4 cosas que te sirven para cualquier proyecto

1

Evita el negro puro (#000000) de fondo en modo oscuro: con colores vivos hace que las letras parezcan vibrar; usa grises oscuros.

2

Respeta la luminosidad natural de cada matiz: el amarillo necesita L > 0.80 para no verse como mostaza o fango.

3

Guía la mirada con el brillo y contraste: el botón secundario debe tener cuerpo armónico y pasar siempre WCAG AA.

4

Aprovecha el CSS nativo: Tailwind v4 y las variables CSS ya resuelven esto en el navegador sin meter librerías de más.

Cómo usarlo con Tailwind CSS v4

Copias el bloque @theme en tu CSS y listo. Tienes modo claro y oscuro funcionando con variables nativas, sin configurar nada extra.

Stack Tecnológico

El motor cromático de esta herramienta corre con 0 dependencias en npm. Decidí implementar las fórmulas matemáticas directamente en TypeScript para mantener un bundle ultra ligero (0 KB añadidos) y tener control total sobre cada cálculo cromático basado en estándares abiertos, aunque existen excelentes librerías en el ecosistema.

Transformación Matricial OKLab / OKLCH

Código

Espacio perceptual sin distorsión de tono

Para este generador, implementé las matrices espectrales de Björn Ottosson directamente en ~40 líneas para operar de forma nativa en OKLCH sin desvío de matiz ('hue shift') y con cero sobrecarga en el bundle. Si buscas soluciones ya empaquetadas, librerías consolidadas como chroma-js o colord son opciones populares para manipulación general.

Gamut Mapping Binario (W3C CSS Color 4)

Código

Adaptación de colores fuera de sRGB

Para esta herramienta específica, implementé el algoritmo oficial de búsqueda binaria de la W3C en solo 30 líneas, logrando adaptar colores fuera de pantalla conservando fielmente el matiz y la luminosidad deseados. En proyectos con necesidades más amplias, librerías completas como colorjs.io ofrecen implementaciones muy robustas de estándares modernos.

Curva de Luminosidad Natural Espectral

Código

Compensación psicofísica de matices (Helmholtz-Kohlrausch)

Para evitar que complementarios cálidos (como el amarillo o lima) colapsen a tonos mostaza o fango al rotar desde un azul, formulé getNaturalLightness() y adjustLightnessForHue() en ~20 líneas sin dependencias. Modula la luminosidad al pico perceptual de cada matiz, produciendo dorados limpios y contrastes WCAG AAA.

Entintado Armónico Universal y Auditoría WCAG

Código

Supresión de vibración visual y contraste ergonómico en tiempo real

Para erradicar el empaste sucio del negro plano y la vibración visual sobre botones interactivos en modo claro, implementé un algoritmo que activa texto claro en colores con L < 0.65 e inyecta entintado armónico en el matiz exacto de cada botón, con validación de contraste en vivo en vez de notas estáticas. Para chequeos matemáticos convencionales, polished o paquetes a11y son alternativas comunes.

Preguntas frecuentes

Q:¿Cómo comparto una paleta con mi equipo?

Solo copia la URL del navegador o dale clic a 'Compartir paleta'. El color base, la armonía y el modo se sincronizan en el enlace sin recargar la página, así tu equipo verá exactamente la misma combinación al abrirlo.

Q:¿Por qué el complementario de un azul se ve dorado o amarillo limpio en vez de mostaza sucio?

Porque aplicamos una curva de luminosidad natural. El ojo humano percibe el amarillo con mucha más luz de forma natural. Si le forzáramos la luminosidad baja de un azul, nuestro cerebro lo interpretaría como lodo o mostaza.

Q:¿Puedo pasar estos tokens a Figma o Tokens Studio?

Sí. En la pestaña 'Tokens W3C (JSON)' puedes copiar el archivo listo para importar en el plugin Tokens Studio de Figma o compilar con Style Dictionary bajo la especificación oficial del W3C.

Q:¿Cuál es la diferencia entre OKLCH y HSL?

HSL calcula el brillo de forma matemática sin fijarse en cómo vemos los humanos. OKLCH ajusta los números para que coincidan con lo que de verdad vemos: si dos colores tienen el mismo brillo en OKLCH, realmente se ven igual de claros.

Q:¿Por qué hay variables especiales como --primary-text?

Porque un color que funciona bien de fondo en un botón grande se vuelve ilegible en letras chiquitas sobre fondo oscuro. Las variables *-text aclaran el texto para que se lea sin esfuerzo y pase las pruebas de accesibilidad.

Q:¿Cómo paso estos colores a mi proyecto?

Pegas el bloque @theme en tu globals.css. Tailwind v4 crea en automático las clases como bg-primary o text-primary-text, y al alternar la clase .dark los colores cambian solos.

Q:¿Qué pasa si elijo un color muy saturado?

El generador le baja la saturación paso a paso hasta donde tu pantalla pueda mostrarlo, manteniendo el mismo tono sin deformarlo.

Q:¿Cómo se calcula la nota de accesibilidad WCAG del visor?

Se audita dinámicamente en tiempo real: calculamos el contraste matemático de cada par interactivo y tipográfico en pantalla, mostrando la calificación real certificada (AA PASS o AAA PASS) sin textos inventados.

Q:¿Necesito instalar algo para usar los colores?

Nada. Todo funciona con CSS estándar del navegador y Tailwind v4.

¿Te sirvió este Behind the Build?

Compártelo con tu equipo o en tus redes para impulsar el diseño de interfaces accesibles con OKLCH.