Diseño con IA — del prompt al producto — 7. Color avanzado: paletas, modo oscuro y accesibilidad total

20 min read min de lecture
Capítulo 07

Color avanzado: paletas, modo oscuro y accesibilidad total

Capítulo 7 de 10 · 70%

Objetivos de este capítulo

  • Extender la paleta en escalas de tonos coherentes
  • Construir un modo oscuro que no sea un simple negativo
  • Garantizar la accesibilidad más allá del texto: daltonismo, no-texto, estados

Cuando una paleta se encuentra con el mundo real

Dos retornos caen la misma mañana en Studio Mango. El primero viene de un betatester de Sereno: « Soy daltónico, y no veo la diferencia entre sus mensajes de éxito y de error. » El segundo viene del cliente: « Mis usuarios meditan por la noche — necesitamos un modo oscuro. » Dos peticiones diferentes, una misma lección: la paleta del capítulo 2, perfecta en condiciones ideales, debe ahora enfrentarse a la diversidad real de los ojos y de los contextos de uso.

Este capítulo completa tu caja de herramientas de color en cuatro frentes: extender cada color en escala de tonos (porque ocho colores nunca bastan mucho tiempo), razonar en luminosidad percibida con OKLCH, construir un modo oscuro digno de ese nombre, y llevar la accesibilidad más allá del contraste del texto — daltonismo, elementos no textuales, estados semánticos. Al final, ya no entregarás una paleta: entregarás un tema completo.

De los colores a las escalas de tonos

Tu token --color-primary es un tono único. Pero en cuanto la interfaz crece, necesitas a sus vecinos: una versión muy clara para un fondo de banda, una versión oscura para el hover, una versión casi negra para texto sobre fondo claro. En lugar de improvisar esas variantes caso por caso, los design systems profesionales definen una escala de 9 a 11 matices por tono, numerados de 50 (el más claro) a 900 (el más oscuro).

Cada número tiene un rol convencional: 50-100 para los fondos teñidos sutiles, 200-300 para los bordes y estados desactivados, 500 como color base, 600-700 para los hovers y estados activos, 800-900 para texto del tono sobre fondo claro. Esta convención hace las decisiones rápidas y coherentes: « la banda de información usa sage-50 de fondo y sage-800 de texto » se entiende de inmediato, y el contraste queda casi garantizado por construcción — los extremos de una escala bien hecha pasan AA entre sí.

css
:root {
  /* Escala sage — generada con luminosidad percibida regular */
  --sage-50:  #F2F6F4;   /* fondos teñidos sutiles */
  --sage-100: #E1EAE6;
  --sage-200: #C4D5CE;   /* bordes, separadores */
  --sage-300: #A3BDB3;
  --sage-400: #7E9D91;
  --sage-500: #4A7C6F;   /* base: botones, enlaces */
  --sage-600: #3D685D;   /* hover */
  --sage-700: #32554C;   /* activo */
  --sage-800: #27423B;   /* texto teñido sobre fondo claro */
  --sage-900: #1C302B;
}

/* Los roles apuntan a la escala — nunca al revés */
:root {
  --color-primary: var(--sage-500);
  --color-primary-hover: var(--sage-600);
  --color-primary-surface: var(--sage-50);
}

Fíjate en la arquitectura de dos pisos del código de arriba: la escala bruta (--sage-500) por un lado, los roles funcionales (--color-primary) por el otro, con los roles apuntando a la escala. Esta indirección es la clave del modo oscuro que llega más abajo: cambiarás lo que los roles designan, sin tocar ni la escala ni los componentes.

OKLCH: razonar en luminosidad percibida

Para generar esas escalas, el formato de color importa más de lo que parece. El HSL clásico tiene un defecto conocido: su « luminosidad » miente. Un amarillo y un azul al 50 % de luminosidad HSL no tienen en absoluto la misma claridad percibida por el ojo — el amarillo parece radiante, el azul oscuro. Consecuencia: una escala generada en HSL tiene peldaños irregulares, y los ratios de contraste se vuelven imprevisibles de un tono a otro.

El formato moderno OKLCH corrige esto: su eje L mide la luminosidad tal como el ojo la percibe. Dos colores OKLCH con la misma L parecen realmente igual de claros, sea cual sea el tono. Para ti, es un superpoder práctico: pide tus escalas « en OKLCH, con un paso de luminosidad regular », y todos tus tonos (sage, melocotón, rojo de error) tendrán matices alineados — el 600 del verde y el 600 del rojo ofrecerán el mismo contraste sobre fondo blanco.

OKLCH está soportado por todos los navegadores modernos. Para los navegadores muy antiguos, pide a la IA que proporcione el fallback hexadecimal de cada valor — dos líneas por token, la versión hex primero, la versión oklch después.
PROMPT
Extiende mi design system de Sereno en escalas de tonos completas:
- para cada color base (sage #4A7C6F, melocotón #E8A87C, rojo error #B5544D), genera una escala de 10 matices (50 a 900) en OKLCH con un paso de luminosidad percibida regular
- conserva el tono y ajusta sobre todo luminosidad y croma: los matices claros ligeramente desaturados, los oscuros ligeramente más saturados
- da para cada matiz: el valor oklch(), el fallback hex, y el ratio de contraste sobre blanco Y sobre #1A1F1D
- termina con una tabla de combinaciones garantizadas AA: qué número de texto sobre qué número de fondo
Formato: bloque :root CSS comentado.

El modo oscuro no es un negativo

Primera intuición que matar: el modo oscuro no es la inversión de la paleta clara. Invertir produce un fondo negro puro (#000) que hace vibrar el texto blanco, colores saturados que se vuelven fluorescentes y sombras invisibles. Un buen tema oscuro descansa sobre cuatro principios. Uno: un fondo gris muy oscuro teñido (para Sereno, un gris verdoso profundo como #141816), nunca negro puro. Dos: colores desaturados — sobre fondo oscuro, la misma saturación parece más chillona, así que se baja el croma un punto.

Tres: la elevación por la claridad. En modo claro, una tarjeta se destaca por su sombra; en modo oscuro, las sombras ya no se ven — es la propia superficie la que se aclara ligeramente (una tarjeta es un poco más clara que el fondo, una modal todavía un poco más). Cuatro: el blanco roto en lugar del blanco puro (#E8ECEA en lugar de #FFFFFF), para reducir la vibración en las largas lecturas nocturnas — precisamente el contexto de uso de Sereno.

Y aquí es donde tu arquitectura de dos pisos rinde: para crear el tema oscuro, no tocas ni los componentes ni la escala — solo redeclaras los roles en un bloque prefers-color-scheme: dark. --color-surface apunta ahora al gris profundo, --color-primary a un sage-400 más claro (porque sobre fondo oscuro, es la versión clara del tono la que contrasta). Treinta líneas de CSS, y toda la interfaz bascula.

css
/* Modo oscuro: se redeclaran los roles, nada más */
@media (prefers-color-scheme: dark) {
  :root {
    --color-surface: #141816;          /* gris verdoso profundo, nada de negro puro */
    --color-surface-raised: #1E2421;   /* elevación por la claridad */
    --color-text: #E8ECEA;             /* blanco roto, nada de blanco puro */
    --color-text-muted: #9DABA5;       /* reverificado: 5.2:1 sobre surface */
    --color-primary: var(--sage-400);  /* versión clara del tono */
    --color-primary-hover: var(--sage-300);
    --color-primary-surface: #20302B;
    --shadow-soft: none;               /* la elevación sustituye a la sombra */
    --shadow-raised: none;
  }
}
PROMPT
Genera el tema oscuro completo de Sereno a partir de mis tokens claros (abajo):
[pega aquí tu bloque :root + tus escalas]
Reglas:
- redeclara ÚNICAMENTE los roles en @media (prefers-color-scheme: dark), sin tocar ni las escalas ni los componentes
- fondo gris verdoso profundo (nada de negro puro), texto blanco roto (nada de #FFF)
- desatura ligeramente los acentos, usa los matices claros de las escalas para primary
- sustituye las sombras por la elevación: surface-raised más clara que surface
- da el ratio de contraste de CADA combinación texto/fondo del tema oscuro
- señala toda combinación por debajo de 4,5:1 y propón la corrección
El modo oscuro pone todos los contadores de contraste a cero: una combinación AA en claro puede suspender en oscuro. La trampa clásica es --color-text-muted, ya al límite en claro, que se vuelve ilegible sobre fondo oscuro. Exige los ratios en cifras de los dos temas.

Daltonismo: no codificar nunca la información solo por el color

Volvamos al betatester. Aproximadamente el 8 % de los hombres y el 0,5 % de las mujeres perciben mal ciertos colores — la mayoría de las veces la distinción rojo/verde, exactamente la pareja que Sereno usa para error/éxito. La regla de accesibilidad es absoluta: el color no debe ser nunca el único canal que porta una información. Un mensaje de error rojo debe señalarse también con un icono, un prefijo textual (« Error: ») o una forma distinta. Un campo inválido debe tener un borde más grueso o un icono, no solo un borde rojo.

El reflejo de verificación: pide a la IA que simule. « Describe esta interfaz tal como la vería una persona deuteranope; lista cada lugar donde una información solo está portada por el color. » También puedes hacer el test mental de la escala de grises: si toda la página pasara a blanco y negro, ¿los estados seguirían siendo distinguibles? Si sí, tu diseño es robusto; si no, ya sabes qué doblar con un icono o una etiqueta.

WCAG más allá del texto: el 3:1 de los elementos de interfaz

El capítulo 2 cubrió el texto (4,5:1). Pero las WCAG imponen también un mínimo de 3:1 para los elementos no textuales portadores de sentido: el borde de un campo de formulario (si no, el campo es invisible), un icono que sirve de botón, el anillo de focus, el estado marcado de una casilla, el trazo de un gráfico. Es el ángulo muerto de casi todas las paletas pastel — el borde gris claro tan elegante de tu maqueta probablemente da 1,8:1, y un usuario con baja visión simplemente no encuentra dónde hacer clic.

Piensa también en los estados semánticos como parejas completas: cada color de estado (éxito, error, advertencia, información) existe en versión texto, versión fondo y versión borde — y cada combinación pasa sus umbrales en los dos temas. Es el momento en que tu sistema deja la « paleta bonita » para convertirse en un verdadero tema de producción.

flowchart TD
  P["Paleta base: roles y tonos"] --> E["Escalas 50 a 900 en OKLCH"]
  E --> T1["Ratios de texto: 4,5 a 1 mínimo"]
  E --> T2["Ratios no-texto: 3 a 1 mínimo"]
  T1 --> D["Simulación daltonismo: info nunca solo por color"]
  T2 --> D
  D --> S["Tema oscuro: roles redeclarados y reprobados"]
  S --> V["Tema validado: light + dark documentados"]
El pipeline de validación del color: de la paleta al tema completo, cada etapa tiene su test.

Entregar un tema, no colores

Recapitulemos el entregable final para el desarrollador de Sereno: las escalas de tonos (la materia prima), los roles funcionales en dos declaraciones (claro y oscuro), las parejas de estados semánticos completas, y un breve documento de uso — qué número de escala para qué uso, qué combinaciones están garantizadas, cómo añadir un tono sin romper el sistema. Añade el respeto a la elección del usuario: el tema sigue prefers-color-scheme por defecto, pero un interruptor manual debe poder forzarlo, porque meditar por la noche en modo claro forzado no es una experiencia premium.

El betatester daltónico recibirá una interfaz donde cada estado va doblado de un icono; el cliente tendrá su modo oscuro digno de una app de meditación nocturna. Y tú habrás aprendido la lección que va más allá del color: un design system no se juzga en condiciones ideales, sino en la diversidad real de los ojos, las pantallas y los contextos que va a encontrarse.

🛠️ Te toca a ti

Contexto

El cliente espera el modo oscuro para la próxima release, y el retorno del betatester daltónico debe tratarse en la misma pasada. Dispones de tus tokens del capítulo 2 y de media jornada. El entregable: un tema claro + oscuro completo, verificado más allá del texto, con su documentación de uso para el desarrollador.

Instrucciones

  1. Haz generar las escalas de 10 matices (50-900) en OKLCH para tus tres tonos principales, con fallbacks hex y ratios de contraste.
  2. Reestructura tus tokens en dos pisos: escalas brutas por un lado, roles funcionales por el otro.
  3. Genera el tema oscuro redeclarando únicamente los roles: fondo teñido profundo, acentos desaturados, elevación por la claridad.
  4. Exige los ratios en cifras de todas las combinaciones de los dos temas y haz corregir todo lo que baje de 4,5:1 (texto) o 3:1 (no-texto).
  5. Haz la auditoría de daltonismo: pide la lista de informaciones portadas únicamente por el color, y dobla cada una con un icono o una etiqueta.
  6. Prueba la landing completa en los dos temas (incluido el formulario y sus estados de error) y redacta las 10 líneas de documentación de uso.
Pista — Empieza por la arquitectura de dos pisos (escalas → roles): es ella la que hace el modo oscuro casi gratuito. Si tienes que modificar un componente para el tema oscuro, es la señal de que un valor en duro se ha escapado de los roles.

En resumen

  • Un color base se convierte en una escala de 9-11 matices (50-900), cada número con un rol convencional.
  • La arquitectura de dos pisos — escalas brutas, roles funcionales que apuntan a ellas — hace los temas intercambiables.
  • OKLCH mide la luminosidad percibida: escalas regulares y contrastes previsibles de un tono a otro.
  • El modo oscuro no es un negativo: fondo teñido profundo, acentos desaturados, elevación por la claridad, blanco roto.
  • Todos los contrastes deben reprobarse en oscuro — el texto atenuado es la trampa clásica.
  • La información no debe portarse nunca solo por el color: icono, etiqueta o forma como doble canal (el 8 % de los hombres son daltónicos).
  • Las WCAG imponen también 3:1 a los elementos no textuales: bordes de campos, iconos activos, focus, estados.

Quiz — comprueba tu comprensión

1. ¿Para qué sirve una escala de tonos (50 a 900)?

Cada número tiene un rol convencional (50 = fondo sutil, 500 = base, 600 = hover, 800 = texto teñido): las decisiones se vuelven rápidas y el contraste previsible.

2. ¿Cuál es la ventaja de OKLCH sobre HSL?

En HSL, un amarillo y un azul al « 50 % » no tienen la misma claridad percibida. El eje L de OKLCH es perceptual: misma L = misma claridad sentida, y por tanto contrastes alineados entre tonos.

3. ¿Cómo construir un buen modo oscuro?

La inversión produce colores fluorescentes y sombras invisibles. Se redeclaran únicamente los roles: gris teñido profundo, blanco roto, matices claros de las escalas para los acentos.

4. ¿Qué hacer por un usuario daltónico que confunde los mensajes de error y de éxito?

El color no debe ser nunca el único canal de una información. El test mental: en blanco y negro, los estados deben seguir siendo distinguibles.

5. ¿Qué ratio de contraste mínimo se aplica a los elementos no textuales portadores de sentido (bordes de campos, iconos activos)?

Las WCAG exigen 3:1 para los componentes de interfaz: un borde de campo a 1,8:1 hace el formulario ilocalizable para un usuario con baja visión.

6. ¿Por qué reprobar todos los contrastes tras crear el tema oscuro?

Cada rol apunta a valores nuevos: los ratios se recalculan por completo. El texto atenuado, ya al límite en claro, es el primero en caer por debajo del umbral.

Auteur(s)

R

REHOUMA Haythem

Haythem Rehouma est un ingénieur et architecte IA et cloud, formateur et enseignant technique, avec un profil orienté IA médicale, AWS, MLOps, LLM/RAG et vision par ordinateur.