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
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.
| Sí | 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.
| 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
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.
| Sí | 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
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.
| Sí | 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.
Generada en cada build desde tokens/build/contrast.json. No es una opinión de revisión: es una compuerta que bloquea el release.
| 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 |
| 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
captionpasó de 2.37:1 a 4.51:1 ymutedde 4.25:1 a 6.08:1 en modo laboratorio;captionde 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.
mutedse oscureció más allá del mínimo a propósito: puesto justo en el umbral quedaba en la misma luminosidad quecaptiony los dos tokens colapsaban en un solo gris.
■ UMB-COL-004 · Color · error
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.
| Sí | 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:
signal es la marca de datos. Le aplica 3:1.signal-text es cualquier texto o enlace en color señal. Le aplica 4.5:1.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.
| 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 |
| 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
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.
| Sí | 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
signalymodelson 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.
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 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.
| Sí | 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
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.
| Sí | 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.
■ UMB-COL-001 · Color · error
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.
| Sí | 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
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.
| Sí | 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
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.
| Sí | 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.