Sistemas de color para modo oscuro: cómo construir una paleta que funcione a las 2 a.m.
Una guía práctica de sistemas de color para modo oscuro. El modelo de elevación de superficies, la regla de desaturación, la calibración del acento y las siete marcas que lanzan las paletas oscuras más limpias en 2026.

Sistemas de color para modo oscuro: cómo construir una paleta que funcione a las 2 a.m.
Un modo oscuro es un sistema paralelo, y los productos que se limitan a accionar un interruptor sobre la paleta clara son los que se ven rotos cuando se apagan las luces.
Ese es todo el artículo en una frase. La razón por la que la mayoría de los modos oscuros fracasan es más concreta: los diseñadores recurren a "invertir la paleta clara" y terminan con llanuras de gris sobre gris o con un coral eléctrico que quema las retinas. La solución es arquitectónica, no cosmética. Construye un sistema paralelo con su propio modelo de elevación, su propio conjunto de reglas de desaturación y su propia calibración del acento, y el resultado se verá intencional porque lo es.
Un modo oscuro es un sistema paralelo, no una inversión
Tu paleta clara tiene tokens de fondo, superficie, borde, texto y acento. Tu paleta oscura necesita todos esos mismos tokens, y sus valores no son el inverso de los valores claros. El croma se comporta distinto con luminosidades bajas. Los cambios de tono ocurren en el límite perceptual. Lo que se lee como un coral limpio en L 0.62 en modo claro se convierte en un neón vibrante en L 0.72 en modo oscuro sobre una superficie casi negra.
Los equipos que lanzan modos oscuros limpios no tocan un interruptor. Diseñan una segunda paleta, la mapean a la misma capa de tokens semánticos y conectan ambas mediante un cambio de modo en la raíz del tema. Es más trabajo. Es el único enfoque que no te deja en ridículo.
El modelo de elevación de superficies
Fondo. Superficie. Superficie elevada. Superficie superpuesta. Toda interfaz con un buen diseño de modo oscuro tiene estos cuatro niveles, y saltarse el tercero es la razón más común por la que las interfaces oscuras se sienten planas.
En modo claro, la elevación es obvia: las tarjetas blancas se asientan sobre fondos grises, las sombras salen baratas y la profundidad es gratis. En modo oscuro, las sombras desaparecen contra las superficies oscuras. La elevación tiene que vivir en la luminosidad de la propia superficie. Cada nivel es un paso pequeño y deliberado hacia arriba en luminosidad, no un salto.
Los cuatro niveles no son decisiones estéticas. Son estructura de carga. Cada componente de tu sistema se apoya en uno de estos niveles, y la legibilidad de cada par texto-sobre-superficie depende del lugar de la pila en el que lo coloques.
El fondo marca el suelo
El fondo es el nivel más profundo. La regla: nunca uses negro puro (oklch(0 0 0)) a plena saturación. Usa un casi negro ligeramente teñido, alrededor del 8 al 10 por ciento de luminosidad. El tinte casi siempre es cálido, porque los negros fríos se leen más baratos y más gélidos de lo que el producto merece.
Un valor como oklch(0.10 0.012 30) te da un carbón cálido y oscuro que se lee como "negro" en cualquier pantalla, pero evita la sensación de vacío muerto del negro puro. El croma de 0.012 y el ángulo de tono de 30 grados (una ligera inclinación cálida) bastan. Más, y se ve turbio. Menos, y se ve sin vida.
La superficie sostiene el contenido
La superficie es el nivel donde se asienta la mayor parte del contenido, ligeramente elevada respecto al fondo. El paso de luminosidad del fondo a la superficie suele ser de 3 a 5 puntos en OKLCH. Ese salto es la primera señal que lee el ojo: aquí vive el contenido, el fondo queda detrás.
oklch(0.14 0.010 30) contra oklch(0.10 0.012 30) es separación visual suficiente sin borde ni sombra. El croma baja un poco porque, a medida que aumenta la luminosidad en las superficies oscuras, el croma necesita retroceder para evitar que se mezcle de forma turbia con el fondo. Es sutil al renderizar y completamente incorrecto si te lo saltas.
Superficie elevada y superficie superpuesta
Las superficies elevadas contienen tarjetas y paneles. Las superficies superpuestas contienen modales y hojas. La progresión de luminosidad continúa: superficie elevada en aproximadamente oklch(0.18 0.008 30), superficie superpuesta en oklch(0.22 0.007 30). El croma baja en cada paso porque más arriba en la pila significa más cerca del espectador, y esas superficies necesitan sentirse limpias.
La razón por la que la mayoría de las interfaces oscuras se desploman en una papilla gris plana es que los diseñadores usan dos niveles: fondo y superficie. Las tarjetas viven en el fondo, el texto vive en la superficie y todo se lee a la misma profundidad. Añade el tercer y el cuarto nivel y la interfaz gana legibilidad al instante sin una sola sombra paralela.
La regla de desaturación
Los colores saturados que funcionan en claro queman de noche. La regla: desatura los acentos entre un 15 y un 25 por ciento y baja todavía más el croma en textos y bordes. No se trata de atenuar la marca. Se trata de cómo procesa el ojo el croma con poca luz ambiental.
Con mucha luz ambiental (la oficina a mediodía), el croma vivo se lee vibrante. Con poca luz ambiental (el escritorio a medianoche), ese mismo croma se lee agresivo, con halo y físicamente incómodo. La solución no es temerle al color. Es calibrarlo. La marca sigue siendo reconocible. El producto deja de doler.
Por qué el texto blanco puro es un error
Blanco puro sobre casi negro no es alto contraste, es demasiado contraste. El efecto de halo, en el que el texto brillante parece sangrar hacia el entorno oscuro, es un fenómeno óptico documentado que hace que las interfaces oscuras sean más difíciles de leer, no más fáciles.
El valor correcto para el texto principal en modo oscuro ronda el 90 a 95 por ciento de luminosidad con un toque de tinte cálido. oklch(0.93 0.005 60) se lee como "blanco" pero no produce halo. El texto secundario baja a oklch(0.70 0.010 60), todavía legible en tamaño de cuerpo, visualmente recesivo frente al texto principal. El blanco roto es el valor que los diseñadores más suelen equivocar, porque parece un compromiso y en realidad es el valor correcto.
La calibración del acento mantiene la marca reconocible
Los acentos de marca tienen que leerse en modo oscuro sin perder identidad. La calibración es un aumento de luminosidad más una bajada de croma, no un cambio de tono. Si el acento en modo claro es oklch(0.62 0.22 25), el acento en modo oscuro es oklch(0.72 0.17 25). Mismo tono. Más luminosidad para que destaque sobre superficies oscuras. Menos croma para que no haga halo.
El error es tratar el modo oscuro como un lugar donde los acentos se atenúan. Atenuar mata el reconocimiento de marca. Subir la luminosidad y bajar el croma conserva la sensación de la paleta de colores de marca y evita la quemadura visual. El usuario no nota el ajuste. Nota que el producto se ve bien.

La pasada de contraste que WCAG no hace
Las relaciones de contraste de WCAG 2.1 dejan pasar mucha interfaz oscura fea. Una relación de 4.5:1 entre una superficie oscura y un texto gris apagado puede pasar WCAG y aun así ser realmente difícil de leer en condiciones ambientales reales. La segunda pasada es APCA, que modela la percepción de luminosidad con más precisión, sobre todo en la distinción de luz sobre oscuro.
Después de APCA, haz la prueba del ojo. El shimmer es la vibración que ves cuando dos colores de luminosidad parecida pero croma distinto se sientan juntos. El halo es el sangrado de los elementos brillantes hacia el entorno oscuro. El bloom es el resplandor percibido en los acentos saturados. Si aparece cualquiera de estos, el par falla sin importar la relación. Arregla los valores, no la relación. Para una pasada más profunda sobre la mecánica del contraste de color accesible, la metodología completa cubre casos límite que la auditoría en modo claro no revela.
Siete marcas que lanzan paletas oscuras limpias
Linear, Notion, Vercel, Stripe, GitHub, Arc y Raycast resuelven el modo oscuro cada una a su manera. Los patrones que comparten son los que vale la pena robar.
| Marca | Modelo de superficie | Estrategia de acento | Lo que hacen bien |
|---|---|---|---|
| Linear | Cuatro niveles reales, pasos estrechos | Morado elevado, croma ~0.15 | Pasos tan estrechos que la profundidad se lee continua |
| Notion | Tres niveles con superposición | Uso mínimo de acento en oscuro | Casi sin croma, toda profundidad |
| Vercel | Binario (fondo + elevado) | Solo blanco | Brutalmente simple; funciona porque se compromete |
| Stripe | Cuatro niveles, tinte cálido | Azul calibrado, no reducido | Los datos densos se leen limpios en cada nivel |
| GitHub | Tres temas con nombre (oscuro, atenuado, alto contraste) | Azul verdoso, desaturado | "Atenuado" es el valor por defecto correcto |
| Arc | Tinte personalizado por espacio | Tono totalmente definido por el usuario | Elevación por cambio de tono, no de luminosidad |
| Raycast | Dos niveles con mucho desenfoque | Acento naranja, muy elevado | El desenfoque crea elevación implícita |
Linear es la implementación de referencia. Los pasos de superficie son lo bastante estrechos como para que la interfaz se lea como un único campo oscuro con profundidad real. El acento morado se identifica como el morado de Linear sin quemar nunca. La jerarquía tipográfica se apoya en pasos de luminosidad en los tokens de texto, no solo en el tamaño.
Vercel demuestra que el modelo binario puede funcionar si te comprometes del todo. Sin tercera superficie. Sin estados grises. Todo es fondo profundo o superficie ligeramente elevada, y el compromiso monocromo hace que parezca una decisión de diseño y no una limitación. La mayoría de los equipos no puede lograrlo porque tiene colores de estado, ilustraciones y momentos de marca que necesitan elevación.
La opción "Dimmed" de GitHub es la intuición correcta aplicada al alcance equivocado. La construyeron como una variante de tema, pero la lección real es que una superficie oscura de tinte cálido es más cómoda para lecturas largas que el valor frío por defecto. Todo modo oscuro debería ser cálido por defecto.
¿Quieres un modo oscuro que se vea intencional a las 2 a.m. en lugar de invertido a mediodía? Brainy diseña sistemas de color oscuros paralelos con el modelo de elevación, la calibración del acento y el mapa de tokens OKLCH listos para llevar a Figma y CSS. Contrata a Brainy.
El mapa de tokens de un modo oscuro funcional
El mapa de tokens de abajo entrega un modo oscuro real en coordenadas de color OKLCH. Los primitivos son los valores en bruto. Los semánticos son los roles. Lleva los primitivos a una colección de variables de Figma como valores en bruto. Mapea los semánticos a los primitivos como alias. Esa arquitectura de dos capas es todo el sistema de tokens.
| Token | Rol | Valor OKLCH | Hex aprox. |
|---|---|---|---|
--color-bg | Suelo del fondo | oklch(0.10 0.012 30) | #191512 |
--color-surface | Superficie de contenido por defecto | oklch(0.14 0.010 30) | #221e1a |
--color-surface-elevated | Tarjetas, paneles | oklch(0.18 0.008 30) | #2c2723 |
--color-surface-overlay | Modales, menús, hojas | oklch(0.22 0.007 30) | #35302c |
--color-text-primary | Texto de cuerpo, títulos | oklch(0.93 0.005 60) | #edeae5 |
--color-text-secondary | Pies, etiquetas, metadatos | oklch(0.70 0.010 60) | #b0a89e |
--color-text-disabled | Estados deshabilitados | oklch(0.45 0.005 60) | #6e6860 |
--color-border-subtle | Divisores, líneas finas | oklch(0.22 0.008 30) | #36302b |
--color-border-default | Bordes de inputs, bordes de tarjetas | oklch(0.28 0.010 30) | #433d37 |
--color-accent | CTA principal, estados activos | oklch(0.72 0.17 25) | #e0816a |
--color-accent-muted | Hover, acento secundario | oklch(0.65 0.12 25) | #c27060 |
--color-accent-subtle | Fondo teñido detrás de elementos de acento | oklch(0.16 0.04 25) | #2a1e1a |
El tono corre entre 25 y 30 grados en todo el sistema (territorio de coral cálido). El sistema cohesiona porque la temperatura es consistente del suelo al techo. Cambiar el tono a 250 grados te da una paleta tipo Linear. Cambiarlo a 200 grados te da una paleta cercana a Vercel. La estructura no cambia. Solo cambia el tono.
Para la implementación, toda la tabla se mapea a propiedades personalizadas de CSS en :root[data-theme="dark"]. En Figma, cada fila es una variable en una colección de modo "Dark". Esa arquitectura de dos colecciones es lo que hace que un sistema de diseño escale entre superficies.

Cambio de modo: la implementación que no parpadea
Cambiar de modo sin un destello del tema equivocado se resuelve fijando el esquema de color en el elemento html antes de que se ejecute cualquier JavaScript. Cualquier otro enfoque falla en al menos un caso límite.
El patrón: lee localStorage en busca de una preferencia guardada en una etiqueta <script> en línea y bloqueante dentro de <head>. Aplica data-theme="dark" o data-theme="light" al elemento html de forma síncrona, antes de que se renderice el CSS que referencia las propiedades personalizadas. Sin React. Sin useEffect. Sin destello.
<script>
const saved = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
document.documentElement.dataset.theme = saved ?? (prefersDark ? 'dark' : 'light');
</script>
Ese script es bloqueante por diseño. Se ejecuta antes del renderizado. El destello de contenido sin estilo lo causa aplicar el tema en JavaScript después del primer pintado, y este único script bloqueante lo elimina por completo.
Preferencia del sistema, valor por defecto y anulación
El valor por defecto debe seguir la preferencia del sistema operativo. La anulación del usuario debe persistir en localStorage. El interruptor debe exponer tres estados: sistema, claro y oscuro.
Un interruptor de dos estados es un error de diseño. El usuario que configura su sistema operativo en oscuro y quiere que la app lo siga no quiere gestionar un segundo interruptor. El interruptor necesita un estado "sistema" que borre la anulación almacenada y deje que mande la preferencia del sistema operativo. La mayoría de las apps construyen dos estados y luego reciben un ticket de soporte cada vez que alguien cambia el tema de su sistema operativo y se pregunta por qué la app no lo siguió.
FAQ
¿Usar colores de acento en modo oscuro perjudica la batería en OLED?
Los colores de acento cubren una superficie pequeña en una interfaz típica. El ahorro de batería del modo oscuro en OLED proviene casi por completo de las áreas de superficie oscura. Un botón CTA coral sobre fondo oscuro no cambia de forma significativa el consumo de batería. Los fondos de negro puro importan. Las ilustraciones saturadas a pantalla completa importan. Un botón no.
¿Puedo usar directamente el color de marca del modo claro como acento del modo oscuro?
No sin calibrar. Si tu color de marca en modo claro está en L 0.55 a 0.65 en OKLCH, usarlo directamente sobre una superficie oscura rendirá por debajo (demasiado apagado para destacar) o hará halo (demasiado vivo contra un ambiente oscuro). Sube la luminosidad entre 8 y 12 puntos. Baja el croma entre un 20 y un 30 por ciento. Mantén el tono. Ese es el acento calibrado para modo oscuro.
¿Cuál es el modo oscuro mínimo viable para un sistema que todavía no tiene uno?
Fondo, superficie, superficie elevada, texto principal, texto secundario, acento. Seis tokens. No está completo, pero es un sistema. Cada componente puede mapearse a uno de estos seis valores, el modelo de elevación está listo para ampliarse y puedes lanzarlo sin pasar vergüenza. Empieza ahí, no con cien tokens y ninguna estructura.
¿Es aceptable alguna vez un modo oscuro autogenerado?
Para prototipos, herramientas internas y productos con un solo diseñador activo, una inversión automática con ajustes de saturación es aceptable como punto de partida. Como modo oscuro lanzado de un producto con estándares de marca y usuarios reales, no. Los modos oscuros automáticos fallan en los colores de acento, fallan en la ilustración y fallan en los estados de los componentes. Son un boceto inicial, no un sistema terminado.
¿OKLCH hace más fácil construir un modo oscuro?
Muchísimo. El eje de luminosidad perceptualmente uniforme de OKLCH hace que los pasos de luminosidad entre niveles de elevación se comporten como se espera en todos los tonos. En HSL, un paso de 5 puntos en naranja se ve distinto de un paso de 5 puntos en azul. En OKLCH, no. Construir el modelo de elevación en OKLCH significa que los pasos se sienten consistentes sin importar el tono del acento. El argumento completo a favor del color OKLCH cubre las matemáticas en profundidad.
¿Los tokens semánticos deben diferir entre claro y oscuro, o solo los primitivos?
Los primitivos difieren. Los semánticos se quedan igual. --color-surface significa "la superficie de contenido por defecto" en ambos modos. El primitivo al que apunta es distinto en modo oscuro. Ese es el sentido de la arquitectura de dos capas. Los componentes referencian semánticos. Los semánticos referencian primitivos. El cambio de modo reasigna primitivos. Los componentes se actualizan solos y de forma correcta.
El cambio que realmente desbloquean los sistemas de modo oscuro
Un modo oscuro de verdad es una superficie de diseño paralela. No una ocurrencia tardía. No un interruptor en ajustes. Una segunda superficie con su propia estructura, sus propias restricciones y sus propias decisiones de oficio. Los equipos que la tratan así lanzan productos que se ven intencionales a las 2 a.m. Los equipos que accionan un interruptor lanzan productos que parecen sin terminar.
El modelo de elevación es el cimiento. La regla de desaturación y la calibración del acento son la capa de oficio. El mapa de tokens OKLCH es la implementación. El interruptor de tres estados con cambio de modo sin parpadeo es la condición de lanzamiento. Cada pieza se conecta. Ninguna es opcional si quieres que el resultado sea bueno.
Construye el sistema paralelo. Lanza el mapa. La diferencia se nota.
¿Quieres un modo oscuro que se vea intencional a las 2 a.m. en lugar de invertido a mediodía? Brainy diseña sistemas de color oscuros paralelos con el modelo de elevación, la calibración del acento y el mapa de tokens OKLCH listos para llevar a Figma y CSS. Contrata a Brainy.
Ahora guardando en drafts/dark-mode-color-systems.md.
Want a dark mode that looks intentional at 2 a.m. instead of inverted at noon? Brainy designs parallel dark color systems with the elevation model, accent calibration, and the OKLCH token map ready to drop into Figma and CSS.
Get Started




