a11y(dock): le dock du minuteur devient un landmark region libelléUnverified
L'audit axe-core, lancé avec un minuteur en attente, signalait le dock hors de tout landmark (règle region, modéré). role=region + aria-label traduit (« Minuteur »), quatre langues. Claude-Session: https://claude.ai/code/session_01T6va3mdY9tqrDQYJBVYgT6
2a051ef parent: 8c47448 modified
src/i18n.rs +6 -0 | @@ -162,6 +162,8 @@ pub struct Tr { | ||
| 162 | 162 | /// Dock : « {} restantes » / « à répartir ». |
| 163 | 163 | pub remaining_pat: &'static str, |
| 164 | 164 | pub split_pending_note: &'static str, |
| 165 | + /// Landmark du dock du minuteur (role=region, hors <main> et <header>). | |
| 166 | + pub timer_dock_aria: &'static str, | |
| 165 | 167 | pub toast_timer_cancelled: &'static str, |
| 166 | 168 | // ─── stats ─── |
| 167 | 169 | pub title_stats: &'static str, |
| @@ -540,6 +542,7 @@ pub static FR: Tr = Tr { | ||
| 540 | 542 | category_many: "catégories", |
| 541 | 543 | remaining_pat: "{} restantes", |
| 542 | 544 | split_pending_note: "à répartir", |
| 545 | + timer_dock_aria: "Minuteur", | |
| 543 | 546 | toast_timer_cancelled: "Minuteur annulé", |
| 544 | 547 | title_stats: "Statistiques", |
| 545 | 548 | my_entries_arrow: "Mes saisies →", |
| @@ -857,6 +860,7 @@ pub static EN: Tr = Tr { | ||
| 857 | 860 | category_many: "categories", |
| 858 | 861 | remaining_pat: "{} left", |
| 859 | 862 | split_pending_note: "to split", |
| 863 | + timer_dock_aria: "Timer", | |
| 860 | 864 | toast_timer_cancelled: "Timer cancelled", |
| 861 | 865 | title_stats: "Statistics", |
| 862 | 866 | my_entries_arrow: "My entries →", |
| @@ -1174,6 +1178,7 @@ pub static DE: Tr = Tr { | ||
| 1174 | 1178 | category_many: "Kategorien", |
| 1175 | 1179 | remaining_pat: "{} übrig", |
| 1176 | 1180 | split_pending_note: "zu verteilen", |
| 1181 | + timer_dock_aria: "Timer", | |
| 1177 | 1182 | toast_timer_cancelled: "Timer abgebrochen", |
| 1178 | 1183 | title_stats: "Statistik", |
| 1179 | 1184 | my_entries_arrow: "Meine Einträge →", |
| @@ -1491,6 +1496,7 @@ pub static PT_BR: Tr = Tr { | ||
| 1491 | 1496 | category_many: "categorias", |
| 1492 | 1497 | remaining_pat: "{} restantes", |
| 1493 | 1498 | split_pending_note: "a repartir", |
| 1499 | + timer_dock_aria: "Cronômetro", | |
| 1494 | 1500 | toast_timer_cancelled: "Cronômetro cancelado", |
| 1495 | 1501 | title_stats: "Estatísticas", |
| 1496 | 1502 | my_entries_arrow: "Meus registros →", |
| @@ -162,6 +162,8 @@ pub struct Tr { | |||
| 162 | /// Dock : « {} restantes » / « à répartir ». | 162 | /// Dock : « {} restantes » / « à répartir ». |
| 163 | pub remaining_pat: &'static str, | 163 | pub remaining_pat: &'static str, |
| 164 | pub split_pending_note: &'static str, | 164 | pub split_pending_note: &'static str, |
| 165 | + /// Landmark du dock du minuteur (role=region, hors <main> et <header>). | ||
| 166 | + pub timer_dock_aria: &'static str, | ||
| 165 | pub toast_timer_cancelled: &'static str, | 167 | pub toast_timer_cancelled: &'static str, |
| 166 | // ─── stats ─── | 168 | // ─── stats ─── |
| 167 | pub title_stats: &'static str, | 169 | pub title_stats: &'static str, |
| @@ -540,6 +542,7 @@ pub static FR: Tr = Tr { | |||
| 540 | category_many: "catégories", | 542 | category_many: "catégories", |
| 541 | remaining_pat: "{} restantes", | 543 | remaining_pat: "{} restantes", |
| 542 | split_pending_note: "à répartir", | 544 | split_pending_note: "à répartir", |
| 545 | + timer_dock_aria: "Minuteur", | ||
| 543 | toast_timer_cancelled: "Minuteur annulé", | 546 | toast_timer_cancelled: "Minuteur annulé", |
| 544 | title_stats: "Statistiques", | 547 | title_stats: "Statistiques", |
| 545 | my_entries_arrow: "Mes saisies →", | 548 | my_entries_arrow: "Mes saisies →", |
| @@ -857,6 +860,7 @@ pub static EN: Tr = Tr { | |||
| 857 | category_many: "categories", | 860 | category_many: "categories", |
| 858 | remaining_pat: "{} left", | 861 | remaining_pat: "{} left", |
| 859 | split_pending_note: "to split", | 862 | split_pending_note: "to split", |
| 863 | + timer_dock_aria: "Timer", | ||
| 860 | toast_timer_cancelled: "Timer cancelled", | 864 | toast_timer_cancelled: "Timer cancelled", |
| 861 | title_stats: "Statistics", | 865 | title_stats: "Statistics", |
| 862 | my_entries_arrow: "My entries →", | 866 | my_entries_arrow: "My entries →", |
| @@ -1174,6 +1178,7 @@ pub static DE: Tr = Tr { | |||
| 1174 | category_many: "Kategorien", | 1178 | category_many: "Kategorien", |
| 1175 | remaining_pat: "{} übrig", | 1179 | remaining_pat: "{} übrig", |
| 1176 | split_pending_note: "zu verteilen", | 1180 | split_pending_note: "zu verteilen", |
| 1181 | + timer_dock_aria: "Timer", | ||
| 1177 | toast_timer_cancelled: "Timer abgebrochen", | 1182 | toast_timer_cancelled: "Timer abgebrochen", |
| 1178 | title_stats: "Statistik", | 1183 | title_stats: "Statistik", |
| 1179 | my_entries_arrow: "Meine Einträge →", | 1184 | my_entries_arrow: "Meine Einträge →", |
| @@ -1491,6 +1496,7 @@ pub static PT_BR: Tr = Tr { | |||
| 1491 | category_many: "categorias", | 1496 | category_many: "categorias", |
| 1492 | remaining_pat: "{} restantes", | 1497 | remaining_pat: "{} restantes", |
| 1493 | split_pending_note: "a repartir", | 1498 | split_pending_note: "a repartir", |
| 1499 | + timer_dock_aria: "Cronômetro", | ||
| 1494 | toast_timer_cancelled: "Cronômetro cancelado", | 1500 | toast_timer_cancelled: "Cronômetro cancelado", |
| 1495 | title_stats: "Estatísticas", | 1501 | title_stats: "Estatísticas", |
| 1496 | my_entries_arrow: "Meus registros →", | 1502 | my_entries_arrow: "Meus registros →", |
modified
templates/app.html +1 -1 | @@ -26,7 +26,7 @@ | ||
| 26 | 26 | chrono ou le bandeau « X min mesurées »), sauf quand le timer tourne dans |
| 27 | 27 | une AUTRE équipe — là, rien d'autre ne le signale. -#} |
| 28 | 28 | {% if let Some(t) = shell.timer %}{% if shell.tab != "add" || t.foreign %} |
| 29 | -<div class="timer-dock"> | |
| 29 | +<div class="timer-dock" role="region" aria-label="{{ shell.tr.timer_dock_aria }}"> | |
| 30 | 30 | {% if t.running || t.foreign %} |
| 31 | 31 | {#- Arrêter : bascule au passage sur l'équipe du timer si besoin. -#} |
| 32 | 32 | <form method="post" action="/timer/arreter" style="margin:0"> |
| @@ -26,7 +26,7 @@ | |||
| 26 | chrono ou le bandeau « X min mesurées »), sauf quand le timer tourne dans | 26 | chrono ou le bandeau « X min mesurées »), sauf quand le timer tourne dans |
| 27 | une AUTRE équipe — là, rien d'autre ne le signale. -#} | 27 | une AUTRE équipe — là, rien d'autre ne le signale. -#} |
| 28 | {% if let Some(t) = shell.timer %}{% if shell.tab != "add" || t.foreign %} | 28 | {% if let Some(t) = shell.timer %}{% if shell.tab != "add" || t.foreign %} |
| 29 | -<div class="timer-dock"> | 29 | +<div class="timer-dock" role="region" aria-label="{{ shell.tr.timer_dock_aria }}"> |
| 30 | {% if t.running || t.foreign %} | 30 | {% if t.running || t.foreign %} |
| 31 | {#- Arrêter : bascule au passage sur l'équipe du timer si besoin. -#} | 31 | {#- Arrêter : bascule au passage sur l'équipe du timer si besoin. -#} |
| 32 | <form method="post" action="/timer/arreter" style="margin:0"> | 32 | <form method="post" action="/timer/arreter" style="margin:0"> |