Ce document liste chaque critère prioritaire demandé, le fichier concerné et comment le tester au clavier / lecteur d’écran.
> Le module fonctionne sans souris, sans limite de temps, sans audio/vidéo automatique, sans drag-and-drop obligatoire.
| Critère | Fichiers | Implémentation | Test clavier |
|---|---|---|---|
| 2.1.1 Keyboard | index.html, js/app.js, css/styles.css | Toute fonction au clavier : boutons natifs <button>, <input>, Enter/Espace pour cartes. Aucun drag-and-drop. | Tab / Shift+Tab parcourt tout. Entrée ou Espace active chaque carte, soumet chaque réponse. |
| 2.1.2 No Keyboard Trap | js/app.js (closeDialog, trapFocus, global Escape) | Esc ferme tout panneau/dialog. Focus trap circulaire à l’intérieur du dialog uniquement, restitué à l’élément d’origine à la fermeture. | Ouvrir une carte levier → Tab circule dans le dialog → Esc ferme et rend le focus à la carte. |
| 2.4.3 Focus Order | js/app.js (ordre de rendu) | Séquence : h1 (focus programmatique à chaque écran) → instruction → choix (fieldset) → Soumettre → Continuer. Dialog : titre → contenu → Fermer. | Après navigation, le h1 reçoit le focus. Tab suit l’ordre visuel, sans saut. |
| 2.4.7 Focus Visible | css/styles.css (:focus-visible) | Indicateur 3 px, outline: 3px solid #0B6E84 + halo rgba(11,110,132,.22) — contraste ≥ 3:1 sur fond blanc. | Tab : anneau bleu bien visible sur chaque bouton/case. Testé à 200 % zoom. |
| 2.4.1 Bypass Blocks | index.html (.skip-link) | Lien « Passer au contenu principal / Skip to main content » en premier dans le DOM, visible au focus. | Tab au chargement → lien skip visible → Entrée amène à #main-content. |
| Critère | Fichiers | Implémentation | Test |
|---|---|---|---|
| 1.4.3 Contrast (Minimum) | css/styles.css | Texte #17212B sur #fff ≈ 16:1 ; #4A5A6A sur #fff ≈ 7:1 ; badges blanc sur #123047 ≈ 14:1. Grand texte ≥ 3:1, normal ≥ 4,5:1. | Axe DevTools / Lighthouse / Colour Contrast Analyser. |
| 1.4.11 Non-text Contrast | css/styles.css | Bordures #D7E1E8 → #B9CAD8 sur blanc, boutons #127C70/#C65B16 sur blanc, focus #0B6E84 — tous ≥ 3:1. | Vérifier bordures, icônes SVG, focus ring avec sonde contraste. |
| 1.4.1 Use of Color | js/app.js, css/styles.css | Feedback correct/incorrect = couleur + icône (✔/✘) + texte (Bonne réponse / Réponse à revoir). Jamais la couleur seule. | Couper la couleur (filtre niveaux de gris) : l’icône et le libellé restent discriminants. |
| 1.1.1 Non-text Content | index.html, js/app.js (svgVan, svgMap, svgRoad) | SVG informatifs avec aria-label ou <title> ; SVG décoratifs avec aria-hidden="true". | Inspecter : décoratifs aria-hidden="true", informatifs role="img" + aria-label. |
| 1.4.10 Reflow | css/styles.css | Layout fluide, max-width, pas de scroll horizontal à 320 px. | DevTools responsive 320×256 : aucun scroll horizontal sur texte/cartes. |
| 1.4.12 Text Spacing | css/styles.css | Aucune hauteur fixe qui tronque ; line-height hérité permet surcharge utilisateur. | Bookmarklet : * { line-height:1.5 !important; letter-spacing:.12em !important; word-spacing:.16em !important } — contenu reste utilisable. |
| prefers-reduced-motion | css/styles.css | @media (prefers-reduced-motion: reduce) coupe scroll-behavior et transitions. | OS → réduire animations → vérifier absence de mouvement. |
| Critère | Fichiers | Implémentation | Test |
|---|---|---|---|
| 1.3.1 / 1.3.2 Meaningful Sequence | index.html, js/app.js | HTML sémantique (header, main, fieldset/legend), un h1 par écran, ordre DOM = ordre visuel. | Désactiver CSS : lecture reste logique. |
| 3.1.1 / 3.1.2 Language | js/app.js, js/content.js | document.documentElement.lang mis à jour à chaque changement (fr/en). lang="en" sur passages anglais quand fr actif (et inversement). | Inspecter <html lang> après switch. Lecteur d’écran change de voix. |
| 4.1.2 Name, Role, Value | js/app.js | Vrais <button>, <input type="checkbox/radio">, aria-expanded sur cartes, aria-pressed si pertinent. | Axe : aucun role superflu ; contrôles ont nom accessible. |
| 4.1.3 Status Messages | index.html (#live-region), js/app.js (announce) | Feedback, score et résultats dans role="status" aria-live="polite" sans vol de focus. | NVDA/VoiceOver : le feedback est annoncé, le focus reste sur la page. |
| 3.3.1 / 3.3.2 / 3.3.3 Labels & Errors | js/app.js | Labels visibles liés par for/id, erreurs en texte + suggestion (« Veuillez sélectionner… »), bouton Reprendre le quiz (reset quiz seul). | Soumettre sans choix → message d’erreur texte annoncé. |
| 3.2.1 / 3.2.2 On Focus/Input | js/app.js | Aucun changement d’écran au focus ; navigation seulement sur activation explicite (click/Enter) via data-go. | Tab à travers les options ne change pas d’écran. |
| 2.5.3 Label in Name | js/app.js, js/content.js | Nom accessible contient le texte visible (« Soumettre la réponse », « Continuer »). | Inspecter Accessible Name = texte visible. |
| 2.4.6 Headings and Labels | js/content.js | Titres et libellés explicites (« Soumettre la réponse », pas « OK »). Chaque fieldset a une legend. | Lecture des titres : compréhensibles hors contexte. |
| 1.3.3 Sensory Characteristics | js/content.js | Aucune consigne « cliquez sur le bouton vert à droite ». Consignes par libellé, pas couleur/forme/position seule. | Chercher « vert / rouge / à droite » : aucune occurrence normative. |
| 1.4.4 Resize Text | css/styles.css | Unités relatives, pas de clipping à 200 % (zoom navigateur). | Zoom 200 % : texte lisible, pas de recouvrement, boutons ≥ 44 px. |
| 2.5.1 / 2.5.2 Pointer | js/app.js | Un clic/tap/touche suffit ; action au relâchement (click), pas au mousedown. | Tester tap et clic : une seule activation. |
setTimeout bloquant).role ARIA superflu sur élément sémantique.