From 559ace2f02864ebd0a0c8a053c3805d2beb63ec7 Mon Sep 17 00:00:00 2001 From: claude-dev Date: Thu, 5 Mar 2026 12:53:13 +0100 Subject: [PATCH] WCAG 2.1 AA: Focus-Styles, ARIA-Attribute, Tastatur-Navigation, Formvalidierung - Default :focus-visible auf allen interaktiven Elementen (WCAG 2.4.7) - A11y-Panel: role=group, Esc/Pfeiltasten, Fokus-Management - Checkbox sr-only statt display:none (Screenreader-zugaenglich) - Toggle-Switch Focus-Indikator - aria-required, aria-expanded, aria-haspopup auf Formularen/Dropdowns - Export-Dropdown: role=menu/menuitem/separator - Sidebar: aria-expanded auf Sektionen, aria-hidden auf Chevrons - Globaler Esc-Handler mit korrekter Schliess-Reihenfolge - Formvalidierung: aria-invalid, aria-describedby, Fokus auf Fehler - Notification-Items: role=button, tabindex=0 - Badges: aria-label/aria-hidden fuer Screenreader - SR-Announcement bei Sidebar-Lage-Auswahl Co-Authored-By: Claude Opus 4.6 --- src/static/css/style.css | 51 +++++++++++--- src/static/dashboard.html | 40 +++++------ src/static/index.html | 4 +- src/static/js/app.js | 128 +++++++++++++++++++++++++++++++++--- src/static/js/components.js | 8 +-- 5 files changed, 188 insertions(+), 43 deletions(-) diff --git a/src/static/css/style.css b/src/static/css/style.css index 644c818..e8918c1 100644 --- a/src/static/css/style.css +++ b/src/static/css/style.css @@ -2539,6 +2539,11 @@ a:hover { transition: transform 0.2s, background 0.2s; } +.toggle-label input:focus-visible + .toggle-switch { + outline: 2px solid var(--accent); + outline-offset: 2px; +} + .toggle-label input:checked + .toggle-switch { background: var(--accent); } @@ -3786,6 +3791,21 @@ a:hover { top: 0; } +/* === Default Focus-Visible fuer alle interaktiven Elemente (WCAG 2.4.7) === */ +a:focus-visible, button:focus-visible, input:focus-visible, +select:focus-visible, textarea:focus-visible, +[tabindex]:focus-visible, [role="button"]:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; +} + +/* Form-Fehler (Accessibility) */ +.form-error { + font-size: 12px; + color: var(--error); + margin-top: var(--sp-xs); +} + /* prefers-reduced-motion: alle Animationen deaktivieren */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { @@ -3847,10 +3867,22 @@ a:hover { color: var(--text-primary); user-select: none; } -.a11y-option input[type="checkbox"] { display: none; } +.a11y-option input[type="checkbox"] { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} .a11y-option .toggle-switch { flex-shrink: 0; } +.a11y-option input:focus-visible + .toggle-switch { + outline: 2px solid var(--accent); + outline-offset: 2px; +} .a11y-option input:checked + .toggle-switch { background: var(--accent); } @@ -4021,16 +4053,17 @@ a:hover { --input-border: #94A3B8; } -/* === A11y: Focus-Hervorhebung === */ -[data-a11y-focus="true"] a:focus, -[data-a11y-focus="true"] button:focus, -[data-a11y-focus="true"] input:focus, -[data-a11y-focus="true"] select:focus, -[data-a11y-focus="true"] textarea:focus, -[data-a11y-focus="true"] [tabindex]:focus, -[data-a11y-focus="true"] [role="button"]:focus { +/* === A11y: Verstaerkte Focus-Anzeige === */ +[data-a11y-focus="true"] a:focus-visible, +[data-a11y-focus="true"] button:focus-visible, +[data-a11y-focus="true"] input:focus-visible, +[data-a11y-focus="true"] select:focus-visible, +[data-a11y-focus="true"] textarea:focus-visible, +[data-a11y-focus="true"] [tabindex]:focus-visible, +[data-a11y-focus="true"] [role="button"]:focus-visible { outline: 3px solid var(--accent) !important; outline-offset: 2px !important; + box-shadow: 0 0 0 4px rgba(200, 168, 81, 0.3) !important; } /* === A11y: Größere Schrift === */ diff --git a/src/static/dashboard.html b/src/static/dashboard.html index cfe82d7..41b3100 100644 --- a/src/static/dashboard.html +++ b/src/static/dashboard.html @@ -53,8 +53,8 @@