Color y modos

02 · Color y modos

Los dos modos comparten tipografía, layout, logo y semántica. Solo cambian los tokens de color.

Cuándo
modo laboratorio (claro) — por defecto Sitio, informes, decks, documentos, prensa
modo instrumento (oscuro) Tableros en vivo, tarjetas sociales, pantallas de monitoreo, divisores de sección y diapositivas de cifra grande

Se cambia con data-mode="instrumento" o la clase .u-dark sobre un contenedor completo.

■ UMB-COL-007 · Color · error

No se mezclan los dos modos dentro de un mismo panel

Los tokens cascadean por subárbol. Mezclarlos dentro de una superficie produce texto de un modo sobre fondo del otro, que es exactamente el caso que la compuerta de contraste no puede prever.

data-mode=“instrumento” sobre un contenedor completo.
No Un panel claro con una tarjeta oscura dentro, o al revés.

Excepciones

Comprobación: En revisión.

Desde v1.0. Regla normativa: rules/rules.yaml.

Los tokens

Token laboratorio instrumento Rol de contraste
base #f2f3f1 #101418 superficie
panel #fafaf8 #171c22 superficie
ink #16191c #edf1f4 texto
muted #565d57 #8b95a0 texto
caption #6c706d #7a848f texto
border #dde0dc #2a3138 mobiliario
gridline #e6e8e4 #232a31 mobiliario
baseline #c4c9c4 #3a434c mobiliario
signal #128273 #5fd4c4 marca
signal-text #227c6f #5fd4c4 texto
model #5a63d8 #8b93f8 marca
model-text #5962d7 #8b93f8 texto
alert #c8503f #e26a5a marca
alert-text #be4737 #e26a5a texto
series-4 #902a00 #ffce2c marca
series-5 #6331a0 #b454b3 marca
missing #e3e5e1 #1d242b mobiliario

Cada token declara un rol de contraste, y ese rol es lo que la compuerta de CI comprueba:

Rol Umbral Qué es
texto 4.5:1 Cualquier cosa que se lea
marca 3:1 Series, barras, puntos — el dato mismo
mobiliario exento Retícula, borde, línea base
superficie Fondos: se mide contra ellos

La exención del mobiliario es deliberada y se declara token por token. Las líneas de retícula tienen que quedar por debajo del dato; exigirles 3:1 haría que compitieran con él. Esa es también la razón por la que la compuerta es creíble: si fallara permanentemente en la retícula, alguien la apagaría, y con ella las comprobaciones que sí importan.

■ UMB-COL-005 · Color · error

Todo texto alcanza 4.5:1 contra base y contra panel

Es un laboratorio de interés público: la lectura no puede depender de tener buena vista y una buena pantalla. v1.0 afirmaba cumplir AA en ambos modos y no lo cumplía en cuatro pares; el 44% del texto del sitio principal fallaba.

Usar ink, muted, caption y las variantes *-text, que la compuerta ya verifica.
No Usar signal, model o alert como color de texto pequeño en modo laboratorio.

Comprobación: Automática — verify-tokens, comprobación contrast-text.

Origen: umbral-engineering.md §4 afirmaba lo contrario; audit §2.

Ver también: UMB-COL-006 · UMB-A11Y-005

Desde v1.0. Regla normativa: rules/rules.yaml.

■ UMB-COL-006 · Color · error

Toda marca de datos alcanza 3:1; el mobiliario de la gráfica está exento y así se declara

WCAG 1.4.11 aplica a los gráficos necesarios para entender el contenido. Las líneas de retícula no lo son: deben quedar por debajo del dato. Distinguir ambos casos es lo que permite que la compuerta de contraste sea creíble en vez de estar siempre apagada.

Declarar contrastRole en cada token: text, mark, furniture o surface.
No Exigir 3:1 a una retícula, ni eximir a una serie de datos.

Comprobación: Automática — verify-tokens, comprobación contrast-mark.

Origen: Decisión OQ-001.

Ver también: UMB-COL-005

Desde v1.1. Regla normativa: rules/rules.yaml.

La matriz de contraste

Generada en cada build desde tokens/build/contrast.json. No es una opinión de revisión: es una compuerta que bloquea el release.

modo laboratorio

Token Sobre Ratio Rol Umbral
ink base 15.85:1 texto 4.5:1 pasa
ink panel 16.88:1 texto 4.5:1 pasa
muted base 6.08:1 texto 4.5:1 pasa
muted panel 6.48:1 texto 4.5:1 pasa
caption base 4.51:1 texto 4.5:1 pasa
caption panel 4.81:1 texto 4.5:1 pasa
border base 1.19:1 mobiliario exento
border panel 1.27:1 mobiliario exento
gridline base 1.10:1 mobiliario exento
gridline panel 1.18:1 mobiliario exento
baseline base 1.50:1 mobiliario exento
baseline panel 1.60:1 mobiliario exento
signal base 4.22:1 marca 3:1 pasa
signal panel 4.49:1 marca 3:1 pasa
signal-text base 4.51:1 texto 4.5:1 pasa
signal-text panel 4.80:1 texto 4.5:1 pasa
model base 4.48:1 marca 3:1 pasa
model panel 4.77:1 marca 3:1 pasa
model-text base 4.54:1 texto 4.5:1 pasa
model-text panel 4.83:1 texto 4.5:1 pasa
alert base 4.03:1 marca 3:1 pasa
alert panel 4.29:1 marca 3:1 pasa
alert-text base 4.55:1 texto 4.5:1 pasa
alert-text panel 4.84:1 texto 4.5:1 pasa
series-4 base 7.49:1 marca 3:1 pasa
series-4 panel 7.98:1 marca 3:1 pasa
series-5 base 7.61:1 marca 3:1 pasa
series-5 panel 8.11:1 marca 3:1 pasa
missing base 1.13:1 mobiliario exento
missing panel 1.21:1 mobiliario exento

modo instrumento

Token Sobre Ratio Rol Umbral
ink base 16.28:1 texto 4.5:1 pasa
ink panel 15.08:1 texto 4.5:1 pasa
muted base 6.08:1 texto 4.5:1 pasa
muted panel 5.63:1 texto 4.5:1 pasa
caption base 4.86:1 texto 4.5:1 pasa
caption panel 4.50:1 texto 4.5:1 pasa
border base 1.40:1 mobiliario exento
border panel 1.30:1 mobiliario exento
gridline base 1.27:1 mobiliario exento
gridline panel 1.18:1 mobiliario exento
baseline base 1.83:1 mobiliario exento
baseline panel 1.70:1 mobiliario exento
signal base 10.30:1 marca 3:1 pasa
signal panel 9.54:1 marca 3:1 pasa
signal-text base 10.30:1 texto 4.5:1 pasa
signal-text panel 9.54:1 texto 4.5:1 pasa
model base 6.71:1 marca 3:1 pasa
model panel 6.22:1 marca 3:1 pasa
model-text base 6.71:1 texto 4.5:1 pasa
model-text panel 6.22:1 texto 4.5:1 pasa
alert base 5.67:1 marca 3:1 pasa
alert panel 5.25:1 marca 3:1 pasa
alert-text base 5.67:1 texto 4.5:1 pasa
alert-text panel 5.25:1 texto 4.5:1 pasa
series-4 base 12.43:1 marca 3:1 pasa
series-4 panel 11.51:1 marca 3:1 pasa
series-5 base 4.28:1 marca 3:1 pasa
series-5 panel 3.96:1 marca 3:1 pasa
missing base 1.17:1 mobiliario exento
missing panel 1.09:1 mobiliario exento

Comprobados 44 pares · 0 fallos · 8 tokens de mobiliario exentos por declaración explícita.

Los tokens con rol mobiliario —retícula, borde, línea base— están deliberadamente por debajo de 3:1: deben quedar por debajo del dato. La exención se declara token por token en tokens/src/semantic.color.tokens.json y nunca se hereda.

Qué cambió respecto a v1.0

caption pasó de 2.37:1 a 4.51:1 y muted de 4.25:1 a 6.08:1 en modo laboratorio; caption de 2.93:1 a 4.51:1 en instrumento. Las correcciones mantienen el tono exacto y mueven solo la luminosidad, de modo que cada token sigue siendo reconociblemente el mismo color.

muted se oscureció más allá del mínimo a propósito: puesto justo en el umbral quedaba en la misma luminosidad que caption y los dos tokens colapsaban en un solo gris.

La señal

■ UMB-COL-004 · Color · error

El color signal se usa en un solo elemento de la capa de datos por vista

La jerarquía visual de Umbral depende de que exista un único punto de atención. Si todo resalta, nada resalta. El alcance se limita a la capa de datos porque Streamlit aplica primaryColor a todos sus widgets a la vez y no existe configuración que lo restrinja a un elemento.

Una serie, una cifra o un elemento de UI en signal.
No Signal en el logo, el botón y la serie principal a la vez.

Comprobación: En revisión.

Origen: Brand book p.03 «La señal es sagrada»; medido: 17 elementos en desaparecidosmx, 10 en pautamx, 4 en cabildo-libre.

Desde v1.0. Regla normativa: rules/rules.yaml.

signal existe en dos variantes porque hace dos trabajos con umbrales distintos:

Lo mismo vale para model-text y alert-text. La razón es que la marca obliga a etiquetar las series directamente al final de la línea en vez de usar una caja de leyenda — y una etiqueta de serie es texto pequeño, no una marca.

Las series categóricas

modo laboratorio

Orden Token Valor
1 signal #128273
2 model #5a63d8
3 muted #565d57
4 alert #c8503f
5 series-4 #902a00
6 series-5 #6331a0

Los tres pares peor separados, medidos en distancia OKLab bajo simulación de dicromacía:

Par Normal Protanopía Deuteranopía Tritanopía
signal / model 0.208 0.189 0.171 0.014
muted / alert 0.2 0.058 0.155 0.259
muted / series-5 0.184 0.181 0.155 0.06

modo instrumento

Orden Token Valor
1 signal #5fd4c4
2 model #8b93f8
3 muted #8b95a0
4 alert #e26a5a
5 series-4 #ffce2c
6 series-5 #b454b3

Los tres pares peor separados, medidos en distancia OKLab bajo simulación de dicromacía:

Par Normal Protanopía Deuteranopía Tritanopía
signal / model 0.214 0.208 0.163 0.076
muted / series-5 0.18 0.163 0.09 0.2
model / muted 0.134 0.134 0.133 0.107

Por debajo de ~0.10 dos marcas dejan de distinguirse con fiabilidad. Por eso la etiqueta directa (UMB-CHT-005) y la prohibición de codificar solo con color (UMB-A11Y-005) no son estilísticas: son la mitigación real del punto más débil de la paleta.

■ UMB-COL-008 · Color · error

Un color categórico nuevo se deriva en OKLCH y se verifica contra dicromacia

Variar solo el tono no basta: para un dicrómata el tono colapsa a un solo eje. Medido, la mejor quinta serie posible variando solo tono queda en 0.042 de separación OKLab, por debajo del umbral de ~0.10 en el que dos marcas dejan de distinguirse.

Variar tono y, si hace falta, luminosidad; verificar con audit/scripts/cvd.py.
No Añadir una serie por parecido estético sin medir su separación.

Comprobación: Automática — verify-tokens, comprobación series-separation.

Origen: OQ-009. Sustituye la regla de v1.0 «variando solo el tono» para el caso categórico.

Desde v1.1. Regla normativa: rules/rules.yaml.

El punto débil heredado

signal y model son indistinguibles bajo tritanopía (separación OKLab 0.014). Se hereda de v1.0 y no puede corregirse sin cambiar un color que define la marca.

La mitigación no es cosmética: es la etiqueta directa obligatoria (UMB-CHT-005) y la prohibición de codificar significado solo con color (UMB-A11Y-005). Si respetas esas dos reglas, la debilidad de la paleta no llega al lector.

Rampas

Tres rampas, todas derivadas en OKLCH con pasos de luminosidad perceptualmente parejos:

Rampa Para qué
Secuencial signal (7 pasos) Intensidad de una variable. La rampa por defecto de un coroplético.
Secuencial model (7 pasos) Una segunda variable, nunca en la misma figura que la anterior.
Divergente alert→neutro→signal (9 pasos) Cambio, superávit/déficit, por encima/por debajo de lo esperado.

■ UMB-COL-009 · Color · error

Las dos rampas secuenciales no codifican dos variables en la misma figura

Las rampas ancladas en signal y en model son indistinguibles bajo tritanopía (separación OKLab 0.014). Dos mapas lado a lado codificados con ellas son el mismo mapa para ese lector.

Una rampa secuencial por figura; si hacen falta dos, variar también el rango de luminosidad.
No Un coroplético en rampa signal junto a otro en rampa model.

Comprobación: En revisión.

Origen: Decisión OQ-005.

Desde v1.1. Regla normativa: rules/rules.yaml.

El punto neutro de la divergente está deliberadamente cerca del fondo de la página, para que «sin cambio» se lea como ausencia de énfasis y no como una categoría más.

■ UMB-COL-010 · Color · error

Dato faltante, dato suprimido y cero se distinguen visualmente entre sí

En datos de desaparición y de delito la diferencia entre «no hay registro», «se suprimió por debajo del umbral de reporte» y «ocurrieron cero casos» es sustantiva. Representarlas igual es afirmar algo falso.

missing como relleno plano; suppressed con la trama de 45°; cero en el extremo de la rampa.
No Pintar el faltante como el valor más bajo de la escala.

Comprobación: En revisión.

Origen: KICKOFF §3.3 pide un relleno de faltante y una trama de suprimido; v1.0 no definía ninguno.

Ver también: UMB-NUM-006

Desde v1.1. Regla normativa: rules/rules.yaml.

Prohibiciones

■ UMB-COL-001 · Color · error

No se usa blanco ni negro puros

El blanco y el negro puros producen un contraste duro que cansa la lectura larga y delatan que el color no vino de los tokens. base e ink existen precisamente para eso.

var(–u-base) y var(–u-ink).
No #fff, #ffffff, #000, white, black.

Comprobación: Automática — umbral-lint, comprobación pure-black-white.

Origen: Brand book p.03; medido en desaparecidosmx (6 elementos en #FFFFFF).

Desde v1.0. Regla normativa: rules/rules.yaml.

■ UMB-COL-003 · Color · error

No se usan degradados

El degradado introduce una variación de color que no codifica nada. En una gráfica compite con la escala; en la interfaz es decoración.

Rellenos sólidos; una rampa secuencial si hay que codificar intensidad.
No linear-gradient decorativo, fondos con degradado, barras degradadas.

Excepciones

Comprobación: Automática — umbral-lint, comprobación no-gradient.

Desde v1.0. Regla normativa: rules/rules.yaml.

■ UMB-COL-002 · Color · error

Ningún color se escribe a mano: todos vienen de los tokens

Un valor enunciado en dos lugares deja de coincidir. Así fue como el mplstyle de v1.0 terminó con una tercera serie distinta a la de su propio brand book.

var(–u-signal), tokens[‘signal’], umbral_laboratorio$signal.
No #128273 escrito directamente en una hoja de estilo, un notebook o una gráfica.

Comprobación: Automática — umbral-lint, comprobación hardcoded-token-hex.

Origen: CLAUDE.md §2; audit §3.5.

Ver también: UMB-PRO-003

Desde v1.0. Regla normativa: rules/rules.yaml.