Accessibilité
Ce que ce site vise en matière d’accessibilité, le taux de conformité mesuré, comment il a été mesuré, et comment signaler un défaut.
Référentiel visé
Ce site vise le RGAA 4.1 (Référentiel général d’amélioration de l’accessibilité), qui reprend en droit français les critères du WCAG 2.1 niveau AA.
Cet engagement est volontaire : le site est édité à titre personnel, ce n’est ni un service public ni un site institutionnel, et rien ne l’oblige légalement à s’y conformer. La démarche est poursuivie parce qu’un site qui prétend rendre lisibles des comptes publics doit rester lisible par tout le monde, pas seulement par celles et ceux qui n’en ont pas besoin.
État de l’audit et taux de conformité
95,7 % des points vérifiés lors de cet audit sont conformes (22 conformes, 1 non conforme, sur 23 points effectivement vérifiés).
Ce site est donc partiellement conforme au RGAA 4.1, et pas plus que cela : 3 point(s) sont sans objet (aucun contenu concerné), et 4 point(s) n’ont PAS été vérifiés lors de cet audit — ils ne comptent ni comme conformes ni comme non conformes, et sont listés plus bas. Une conformité partielle honnêtement déclarée vaut mieux qu’une conformité totale invérifiable.
Audit conduit le 2 septembre 2026.
Méthode de l’audit
Cet audit porte sur les treize écrans du site — accueil, exploration (racine, nœud, feuille), recherche (avec et sans résultat), Parlement, sources, mentions légales, méthode, contact, cette page, suivi, une fiche de candidat, une fiche de proposition et une adresse inexistante — servis par un vrai Apache et un vrai PHP-FPM (le harnais de `tests/htaccess.test.ts`), dans les deux thèmes, clair et sombre.
Une partie des critères est vérifiée MÉCANIQUEMENT : un test qui tourne à chaque évolution du site (`npm test`, `npm run test:php`, `npm run build`) et qui échouerait si le site régressait sur ce point. Le reste a été vérifié MANUELLEMENT, à la date de cet audit, par lecture du code servi et de la feuille de style assemblée — sans garantie contre une régression future, puisqu’aucun test ne le protège.
Certains points n’ont pas été vérifiés du tout : ils sont listés comme tels, pas comptés comme conformes. Une conformité partielle honnêtement déclarée vaut mieux qu’une conformité totale invérifiable.
En amont de cet audit, deux vérifications automatisées tournent à
chaque évolution du site : scripts/design/contrastes.mjs,
lancé par npm run build, et les suites de tests
(npm test, npm run test:php).
Constats, thématique par thématique
Images
-
Conforme Chaque image porte une alternative adaptée
La seule image du monde rendu est le badge de marque de l’en-tête (`entete__badge`) : `alt=""`, correct puisqu’elle est décorative — le nom du site est écrit en texte, dans le même lien, juste à côté. Aucune autre balise `<img>` n’est rendue par les gabarits PHP.
Cadres
-
Sans objet Cadres
Aucune balise `<iframe>` n’est rendue par les gabarits PHP.
Couleurs
-
Conforme Le contraste du texte et des éléments non textuels porteurs d’information atteint le seuil requis
ÉCART TROUVÉ PAR CET AUDIT, CORRIGÉ LE 2 SEPTEMBRE 2026 : `scripts/design/contrastes.mjs` ne mesurait que la palette catégorielle du graphique (dix couleurs) et sa rampe séquentielle — jamais le texte courant sur le fond de page, les liens, ni les encarts d’information/de méthode que plusieurs écrans affichent (contact, méthode, cette page). Étendu : sept paires de jetons de base (texte courant, texte atténué, lien, texte des deux encarts, bordure de contrôle, anneau de focus) sont désormais mesurées elles aussi, dans les mêmes trois déclinaisons de thème. Toutes passent. Le script tourne à chaque `npm run build` et interrompt la compilation sous 4,5:1 pour un texte ou 3:1 pour un élément non textuel porteur d’information.
-
Conforme La couleur n’est jamais le seul moyen de porter une information
`api/lib/Composition.php` documente la règle du monde visuel (« la couleur est un ordre, jamais une identité ») : chaque segment coloré porte son libellé, son montant et sa part en texte, dans le même balisage que la couleur.
Multimédia
-
Sans objet Multimédia
Aucune balise `<video>` ni `<audio>`, aucun contenu animé autoportant, n’est rendu par les gabarits PHP.
Tableaux
-
Sans objet Tableaux
Aucune balise `<table>` de données n’est rendue par les gabarits PHP — les chiffres du monde visuel sont portés par des listes et des segments, pas des tableaux.
Liens
-
Conforme Chaque lien a un intitulé qui nomme sa destination
Lecture des gabarits PHP : chaque lien porte le libellé de sa destination (source, proposition, page) ; aucun intitulé générique du type « cliquez ici » n’a été trouvé.
-
Conforme Un lien qui ouvre une nouvelle fenêtre l’annonce
ÉCART TROUVÉ PAR CET AUDIT, CORRIGÉ LE 2 SEPTEMBRE 2026 : huit liens portant `target="_blank"` (sources, mentions légales, fiches de candidat et de suivi, cette page) n’annonçaient pas l’ouverture d’une nouvelle fenêtre. Corrigé DANS LES GABARITS : `Format::nouvelleFenetre()` ajoute une annonce masquée « (nouvelle fenêtre) » (`.visuellement-masque`, `planche-socle.css`) à chacun de ces liens.
Scripts
-
Conforme Le contenu et la navigation restent accessibles sans JavaScript
Chaque écran se rend entièrement côté serveur : contenu, navigation, recherche et formulaire de contact fonctionnent sans JavaScript. Le seul script chargé (`public/theme.js`) ne bloque aucun contenu ; sans lui, le thème suit le réglage système via une requête media CSS seule.
-
Non conforme Le réglage manuel du thème reste disponible sans JavaScript
Le sélecteur de thème (`fieldset[data-controle-theme]`) est rendu avec l’attribut `hidden` et n’est révélé que par `public/theme.js` : sans JavaScript, aucun moyen de choisir manuellement le thème clair ou sombre n’est offert — seul le réglage système s’applique. Aucun contenu n’est perdu, mais cette préférence-là dépend du script.
Éléments obligatoires
-
Conforme Chaque écran déclare un type de document complet et sa langue
`tests/coquille-rendu.php` vérifie, sur huit écrans dont la page d’erreur, un doctype complet et `<html lang="fr">`.
-
Conforme Chaque écran a un titre de page distinct et informatif
Chaque page passe un sujet distinct à `Format::titrer()`, qui compose « Sujet · L’argent public » — vérifié par lecture des appels dans `api/pages/*.php`.
Structuration de l’information
-
Conforme Un seul titre de niveau 1 par écran
`verificationsPartagees()` (`tests/lib/rgaa.php`), appelé par les quatorze harnais d’écran.
-
Conforme La hiérarchie des titres ne saute aucun niveau
Rendu et lu le 2 septembre 2026 sur huit écrans sans paramètre (accueil, recherche, Parlement, sources, mentions, méthode, cette page, suivi) : aucun saut de niveau constaté.
-
Non vérifié La hiérarchie des titres ne saute aucun niveau, sur les écrans paramétrés
Les écrans à paramètre (exploration, fiche de candidat, fiche de proposition) n’ont pas été rendus individuellement pour cette vérification lors de cet audit ; ils partagent les mêmes fonctions de section que les écrans vérifiés, sans preuve directe.
-
Conforme Deux repères de même rôle portent des intitulés distincts
`reperesHomonymes()` (`tests/lib/rgaa.php`), appelé par les quatorze harnais d’écran.
Présentation de l’information
-
Conforme Le zoom du navigateur n’est pas bloqué
La balise viewport (`Document::entete()`) ne porte ni `maximum-scale` ni `user-scalable=no`.
-
Non vérifié Le contenu reste lisible et utilisable à 200 % et 400 % de zoom
Non mesuré dans un navigateur réel lors de cet audit — seule l’absence de blocage du zoom a été vérifiée.
-
Conforme Le focus clavier reste visible
Depuis cet audit, `tests/specificite-plancher.php` vérifie qu’aucune règle de la feuille assemblée ne retire le contour de focus par défaut (`outline: none`/`0`, sous aucune forme d’écriture) ; onze feuilles de la planche portent en outre leur propre règle `:focus-visible` par famille de composant.
-
Conforme Chaque cible interactive atteint le plancher de taille de 44 px, une fois la cascade résolue
`ciblesSansPlancher()` (`tests/lib/rgaa.php`) résout désormais la CASCADE — spécificité puis ordre d’apparition, comme un navigateur — plutôt que de retenir « une règle qui convient » : voir la section dédiée à cette limite, ci-dessous.
Formulaires
-
Conforme Chaque champ a une étiquette associée
Chaque champ du formulaire de contact (`PageContact::champs()`) porte un `<label for>` explicite ; le champ piège anti-robot est masqué aux technologies d’assistance (`aria-hidden`).
-
Conforme Une erreur de saisie est associée au champ et annoncée
Une erreur de champ est reliée par `aria-describedby` et signalée par `aria-invalid="true"` ; l’erreur globale porte `role="alert"` (`PageContact::champs()`, `PageContact::alerte()`).
-
Conforme Aucun test de type CAPTCHA ne bloque l’envoi
Le seul filtre anti-robot est un champ piège masqué aux technologies d’assistance, jamais un CAPTCHA visuel ou sonore.
-
Non vérifié Le formulaire de contact a été essayé avec un lecteur d’écran réel
Non testé avec un lecteur d’écran réel (NVDA, VoiceOver, JAWS) lors de cet audit — seule la structure du balisage a été relue.
Navigation
-
Conforme Le lien d’évitement est le premier élément focalisable
`premierElementFocalisable()` (`tests/lib/rgaa.php`), appelé par les quatorze harnais d’écran.
-
Conforme Plusieurs moyens indépendants permettent d’atteindre une page
Trois moyens : la navigation d’en-tête (commune à tous les écrans), la recherche (`/recherche`), et `sitemap.xml` (généré à chaque `npm run build`).
-
Conforme La navigation reste cohérente d’un écran à l’autre
L’en-tête et le pied de page sont rendus par les mêmes méthodes partagées (`Document::entete()`, `Document::pied()`) sur tous les écrans du monde « L’unité répétée ».
-
Non vérifié L’ordre de tabulation complet est logique et sans piège, au-delà du lien d’évitement
Non parcouru à la main lors de cet audit, au-delà de la position du lien d’évitement (vérifiée mécaniquement).
Consultation
-
Conforme Aucun contenu ne s’actualise ni ne disparaît après un délai
Le site est entièrement statique côté contenu : aucune temporisation, aucun rafraîchissement automatique.
-
Conforme Aucun contenu ne clignote
Les seules transitions sont des changements de fond ou de couleur au survol ou à la mise au point (90 ms) — aucune animation répétée ni clignotante.
Une limite connue du contrôle automatisé
Le contrôle automatisé de la taille des cibles tactiles (44 px minimum) résout la cascade CSS — spécificité puis ordre d’apparition, comme un navigateur — depuis cet audit. Une règle qui semblait couvrir un élément mais dont il était en réalité exclu par la cascade ne peut plus le déclarer conforme à tort.
Cette résolution ne porte QUE sur cette propriété-là. Elle ne se généralise pas aux autres propriétés CSS (taille de police, couleur, mise en page) : une collision de spécificité sur l’une d’elles ne serait pas vue automatiquement. Deux collisions de ce type se sont déjà produites par le passé et ont été corrigées à la main, avec une garde ciblée sur le cas précis rencontré — pas une garde générale, qui demanderait de faire correspondre des sélecteurs à des éléments réels sans navigateur ni DOM.
Cette limite reste donc irréductible avec l’outillage actuel (aucun navigateur ne participe à ces suites de tests) et continue d’être énoncée ici plutôt que tue.
Non-conformités connues
- Le réglage manuel du thème reste disponible sans JavaScript — Le sélecteur de thème (`fieldset[data-controle-theme]`) est rendu avec l’attribut `hidden` et n’est révélé que par `public/theme.js` : sans JavaScript, aucun moyen de choisir manuellement le thème clair ou sombre n’est offert — seul le réglage système s’applique. Aucun contenu n’est perdu, mais cette préférence-là dépend du script.
Ce qui n’a pas été vérifié
Ces points n’entrent pas dans le taux de conformité publié plus haut — ni comme conformes, ni comme non conformes.
- La hiérarchie des titres ne saute aucun niveau, sur les écrans paramétrés — Les écrans à paramètre (exploration, fiche de candidat, fiche de proposition) n’ont pas été rendus individuellement pour cette vérification lors de cet audit ; ils partagent les mêmes fonctions de section que les écrans vérifiés, sans preuve directe.
- Le contenu reste lisible et utilisable à 200 % et 400 % de zoom — Non mesuré dans un navigateur réel lors de cet audit — seule l’absence de blocage du zoom a été vérifiée.
- Le formulaire de contact a été essayé avec un lecteur d’écran réel — Non testé avec un lecteur d’écran réel (NVDA, VoiceOver, JAWS) lors de cet audit — seule la structure du balisage a été relue.
- L’ordre de tabulation complet est logique et sans piège, au-delà du lien d’évitement — Non parcouru à la main lors de cet audit, au-delà de la position du lien d’évitement (vérifiée mécaniquement).
Signaler un défaut d’accessibilité
Si une partie de ce site vous est inaccessible, le formulaire de contact transmet le signalement à l’éditeur, qui s’engage à en tenir compte.
Voie de recours
Si, après avoir signalé un défaut d’accessibilité, vous n’obtenez pas de réponse satisfaisante, vous pouvez saisir le Défenseur des droits (nouvelle fenêtre), l’autorité indépendante compétente en matière d’accessibilité numérique en France.