Commit 52b18fee authored by Jordan Grossemy's avatar Jordan Grossemy
Browse files

Le tunnel d'entrée n'avait pas de titre de page

Connexion, inscription, amorce de compte, second facteur, atterrissage : cinq
écrans sans « h1 ». Arrivé sur la page de connexion, un lecteur d'écran annonçait
un formulaire sans dire de quelle page il s'agissait — et c'est le seul endroit du
produit qu'on atteint sans être passé par ailleurs, donc le seul où l'on n'a aucun
autre repère.

Le titre existait visuellement : la ligne de marque du panneau, en vingt-deux
points et en gras, est le titre de la page. Elle n'était qu'un « div ». Elle
devient le « h1 », sans un pixel de différence — la marge par défaut du « h1 »
est remise à zéro dans la feuille de style.

Une garantie neuve exige ces cinq titres, parce qu'un défaut d'accessibilité qui
ne se voit pas revient exactement comme il est parti. Le contrôle statique
existant portait sur le focus visible, les cibles tactiles et la réduction
d'animation, pas sur les repères de page.

Deux fausses alertes que j'ai levées en chemin, et qui n'ont donc rien changé :
les radios de choix de modèle et les cartes de tableau blanc semblaient sans nom
accessible. Vérification faite dans la page, chaque radio a bien son « label »
associé et chaque carte tire son nom de son contenu. C'était l'outil de lecture
qui les sous-rapportait.

Co-Authored-By: Claude (RCA)
parent 21502bc9
Loading
Loading
Loading
Loading
+14 −0
Changes for apps/api/src/verification/accessibilite.ts: 14 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -93,4 +93,18 @@ export async function verifierAccessibilite(r: Rapport): Promise<void> {

  r.verifie("EX-19", "le mouvement respecte la réduction d'animation du système",
    /prefers-reduced-motion/.test(css));

  // Un « h1 » par écran, et le tunnel d'entrée n'en avait aucun : arrivé sur
  // la page de connexion, un lecteur d'écran annonçait un formulaire sans dire
  // de quelle page il s'agissait. On contrôle le tunnel, parce que c'est le
  // seul endroit qu'on atteint sans être passé par ailleurs.
  const tunnel = ["ecrans/Connexion.tsx", "ecrans/Inscription.tsx",
    "ecrans/Amorce.tsx", "ecrans/SecondFacteur.tsx", "ecrans/Atterrissage.tsx"];
  const sansTitre: string[] = [];
  for (const f of tunnel) {
    const source = await readFile(`${web}${f}`, "utf8");
    if (!source.includes("<h1")) sansTitre.push(f);
  }
  r.verifie("EX-19", `les ${tunnel.length} écrans du tunnel d'entrée portent un titre de page`,
    sansTitre.length === 0, sansTitre.join(" ; "));
}
+1 −1
Changes for apps/web/src/coque/Coque.tsx: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -292,7 +292,7 @@ export function Coque({ criseId }: { criseId: string }) {
    return (
      <div className="centre">
        <div className="panneau">
          <div className="marque">Crise inaccessible</div>
          <h1 className="marque">Crise inaccessible</h1>
          <p className="accroche">
            Vous n’êtes pas membre de l’organisation qui porte cette crise, ou elle
            n’existe pas.
+2 −2
Changes for apps/web/src/ecrans/Amorce.tsx: 2 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ export function Amorce() {
    return (
      <div className="centre">
        <div className="panneau">
          <div className="marque">Posez votre mot de passe</div>
          <h1 className="marque">Posez votre mot de passe</h1>
          <p className="accroche">
            Celui qui vous a été remis à l'installation a traversé un terminal,
            et peut-être une épaule. Il ne sert qu'à cette première connexion.
@@ -104,7 +104,7 @@ export function Amorce() {
  return (
    <div className="centre">
      <div className="panneau">
        <div className="marque">Activez votre second facteur</div>
        <h1 className="marque">Activez votre second facteur</h1>
        <p className="accroche">
          {amorce.destineARoot
            ? "Le droit d'administration vous sera accordé au bout de cette "
+1 −1
Changes for apps/web/src/ecrans/Atterrissage.tsx: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -185,7 +185,7 @@ export function Atterrissage({ genre }: { genre: string }) {
  return (
    <div className="centre">
      <div className="panneau">
        <div className="marque">Kastell</div>
        <h1 className="marque">Kastell</h1>

        {etat === "attente" && <p className="accroche">Un instant…</p>}

+1 −1
Changes for apps/web/src/ecrans/Connexion.tsx: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ export function Connexion({ versInscription }: { versInscription: () => void })
  return (
    <div className="centre">
      <div className="panneau">
        <div className="marque">Kastell</div>
        <h1 className="marque">Kastell</h1>
        <p className="accroche">
          {t("Cockpit de gestion de crise. Hors de votre système d’information, par construction.")}
        </p>
Loading