ADR-017 ActifActive token

Correction du contraste de `text.disabled` et ajout de `background.hover`

DateDate
2026-05-29
DécideursDecision makers
Design System Lead

English summary: Fixes text.disabled (1.57:1 contrast, used incorrectly on non-disabled elements) by changing its reference to resolve to #767676 (4.54:1, WCAG AA), and adds a background.hover token to replace a hardcoded hover color. Also documents a pre-existing Tailwind/Radix naming mismatch in semantic.json, resolved later in ADR-018.

>

*The original French version follows below — preserved unaltered as the historical record.*


Contexte

L'audit WCAG 2.2 intégré au build a détecté deux types de non-conformités :

1. Valeur du token text.disabled inaccessible

Le token semantic.color.text.disabled référençait {color.neutral.300}, résolu en #d9d9d9. Ce gris très clair produit un ratio de contraste de 1.57:1 sur fond blanc — bien en dessous du seuil AA (4.5:1).

WCAG 1.4.3 exempte les composants UI inactifs du critère de contraste. Cependant, deux problèmes se posaient :

(labels de groupe dans la sidebar, tags de pipeline). L'exemption WCAG ne s'appliquait donc pas.

minimale est préférable par convention — notamment pour les utilisateurs avec déficience visuelle légère non couverte par les seuils WCAG.

2. Token background.hover manquant

Le fond au survol des lignes de tableau utilisait une valeur codée en dur (#eff6ff, un bleu clair hors palette). Aucun token sémantique ne couvrait cet usage.

3. Incohérence structurelle préexistante (non résolue dans cet ADR)

tokens/semantic.json utilise une nomenclature Tailwind (neutral.0neutral.900, blue.700), tandis que tokens/primitives.json utilise la nomenclature Radix UI (gray.1gray.12, blue.1blue.12). Les références de semantic.json ne se résolvent pas dans primitives.jsonsite/build.js contourne ce problème avec des valeurs codées en dur. Cette incohérence est documentée mais hors scope de cet ADR (voir section *Alternatives rejetées*).


Décision

Token text.disabled

Valeur changée de {color.neutral.300}{color.neutral.500}

AvantAprès
Référence{color.neutral.300}{color.neutral.500}
Valeur résolue#d9d9d9#767676
Ratio sur blanc1.57:1 ❌4.54:1 ✅
WCAG 1.4.3 (texte normal)ÉchecPasse AA

neutral.500 correspond à la position médiane d'une échelle neutre (≈ Tailwind #737373), ce qui est sémantiquement cohérent pour un texte réduit mais lisible.

L'intention du token est mise à jour pour documenter explicitement :

  • la valeur résolue attendue (#767676)
  • le ratio de contraste
  • l'exemption WCAG 1.4.3 applicable aux UI inactives, maintenue accessible par convention

Token background.hover

Ajout de semantic.color.background.hover{color.neutral.50} (#fafafa)

Couvre le fond au survol des tableaux et listes sans recourir à une valeur codée en dur. Remplace l'usage antérieur de #eff6ff (bleu clair hors palette) et de background.subtle (#f0f0f0, trop contrasté pour un effet de survol discret).

Usages incorrects de text-disabled corrigés

Les éléments non désactivés qui utilisaient text-disabled ont été basculés sur text-secondary :

  • .sidebar-label (labels de groupe de navigation)
  • .pipeline-tag (étiquettes de catégorie dans la section pipeline)

Alternatives rejetées

AlternativeRaison du rejet
Garder #d9d9d9 et invoquer l'exemption WCAG 1.4.3L'exemption ne s'appliquait pas aux usages concrets (sidebar labels, pipeline tags), qui ne sont pas des UI inactives. Corriger uniquement les usages sans changer la valeur du token aurait laissé le token intrinsèquement risqué.
Utiliser {color.neutral.700} (#646464) comme text.disabledIdentique à text-secondary. Efface la distinction sémantique entre texte secondaire et texte désactivé.
Résoudre l'incohérence structurelle Tailwind / Radix dans cet ADRChangement de périmètre beaucoup plus large : impacte toutes les références de semantic.json et nécessite une migration coordonnée de build.js, de tokens.css et de la documentation. Traité séparément.
Ajouter un primitif gray.10.5 (#767676) dans primitives.jsonCasse la cohérence de l'échelle Radix (pas de demi-steps). La valeur #767676 n'existe pas dans Radix UI et serait un écart difficile à justifier.

Conséquences

Pour les agents IA :

  • color.text.disabled encode désormais une intention accessible par défaut
  • L'intent mis à jour documente la valeur résolue et le ratio — un agent peut vérifier

la conformité sans résoudre la chaîne de tokens

Pour les composants :

  • Tout composant utilisant var(--agtc-semantic-color-text-disabled) bénéficie

automatiquement du contraste corrigé

  • var(--agtc-semantic-color-background-hover) est disponible pour les survols de lignes

Incohérence structurelle restante :

  • tokens/semantic.json référence {color.neutral.500} qui ne se résout pas dans

tokens/primitives.json (nomenclature incompatible)

  • site/build.js continue de hardcoder les valeurs résolues
  • Un ADR dédié à la migration vers une nomenclature unifiée est à créer

Incidents ou déclencheurs

Détection lors de l'audit WCAG 2.2 automatique (npm run build) après déploiement sur GitHub Pages. L'audit a signalé des paires de contraste sous le seuil 4.5:1 impliquant text-disabled sur des éléments non désactivés.

← ADR-016 ADR-018 →