A11y: Struktur/Kontraste/Formulare (#166-#168), Nicht-Text (#169), Verhalten (#170), CI-Schutz (#171) #174

Merged
stwaidele merged 6 commits from a11y-mittel into main 2026-07-21 16:29:26 +02:00
Collaborator

Dritte Tranche des A11y-Milestones. GESTAPELT auf PR #173 (das wiederum auf #172 stapelt) — bitte in der Reihenfolge #172, #173, dieser PR fast-forward mergen; danach zeigt jeder PR nur seine eigenen Commits.

#166: Skip-Link als erster Tab-Stopp auf #main; visually-hidden h1 fuer die Seitenansicht (+ aria-label am Titel-Input); Sidebar-Resizer in die nav-Landmarke.
#167: AA-geprueftes Dark-Schema fuer die oeffentliche Server-Shell; Wikilinks permanent unterstrichen (waren nur farblich markiert, 2,5:1); neues Token --color-border-input (#7d8a97) fuer Feld-Raender.
#168: Field verdrahtet Fehler/Hinweise per aria-describedby/aria-invalid mit dem Eingabefeld; Quota-Select benannt; leere Aktions-/Erledigt-Spaltenkoepfe beschriftet (inkl. Server-Renderpfad der Aufgabenuebersicht).
#169: Task-Checkboxen in BEIDEN Renderpfaden benannt; NodeView-Host ist jetzt selbst das li (TipTaps div-Host brach die Listensemantik; #137-Pixel-Abstimmung nachgemessen unveraendert); Wissensgraph-SVG mit beschreibendem aria-label. Hinweis: gecachte Seiten uebernehmen das Checkbox-Label erst mit dem naechsten Persist (wie bei jeder docToHtml-Aenderung). Der Bild-Alt-Editor existierte bereits — Audit-Befund insoweit gegenstandslos.
#170: Toast-Standzeit 6s; Einstellungs-Schalter Einzeltasten-Kuerzel deaktivieren (e und /); prefers-reduced-motion fuer CSS und Graph-Simulation. KEIN neues role=status (legal.spec-Falle).
#171: @axe-core/playwright als devDependency (+2 Pakete, von Stefan freigegeben); neuer CI-Pack a11y.spec.ts (Login/Lesemodus/Editor/Settings, WCAG A/AA, leere Allowlist).

Verifikation: Voller lokaler Audit-Harness-Lauf: von urspruenglich 13 axe-Regelverstoessen verbleiben 0 auf den gescannten Kern-Screens; api-Vollsuite 423 Tests gruen (frische DB); shared-Tests 171 gruen; e2e auth/content/tasks/editor/sidebar/settings-nav/reorder/page-tree/favorites/graph/search/legal gruen; Checkbox-Ausrichtung in beiden Renderpfaden nachgemessen (1px-Versatz wie von Stefan abgenommen). Zwei Spec-Erwartungen nachgefuehrt (Locator-Scope, Sektionszahl 8). Schliesst #166, #167, #168, #169, #170, #171.

Dritte Tranche des A11y-Milestones. GESTAPELT auf PR #173 (das wiederum auf #172 stapelt) — bitte in der Reihenfolge #172, #173, dieser PR fast-forward mergen; danach zeigt jeder PR nur seine eigenen Commits. **#166:** Skip-Link als erster Tab-Stopp auf #main; visually-hidden h1 fuer die Seitenansicht (+ aria-label am Titel-Input); Sidebar-Resizer in die nav-Landmarke. **#167:** AA-geprueftes Dark-Schema fuer die oeffentliche Server-Shell; Wikilinks permanent unterstrichen (waren nur farblich markiert, 2,5:1); neues Token --color-border-input (#7d8a97) fuer Feld-Raender. **#168:** Field verdrahtet Fehler/Hinweise per aria-describedby/aria-invalid mit dem Eingabefeld; Quota-Select benannt; leere Aktions-/Erledigt-Spaltenkoepfe beschriftet (inkl. Server-Renderpfad der Aufgabenuebersicht). **#169:** Task-Checkboxen in BEIDEN Renderpfaden benannt; NodeView-Host ist jetzt selbst das li (TipTaps div-Host brach die Listensemantik; #137-Pixel-Abstimmung nachgemessen unveraendert); Wissensgraph-SVG mit beschreibendem aria-label. Hinweis: gecachte Seiten uebernehmen das Checkbox-Label erst mit dem naechsten Persist (wie bei jeder docToHtml-Aenderung). Der Bild-Alt-Editor existierte bereits — Audit-Befund insoweit gegenstandslos. **#170:** Toast-Standzeit 6s; Einstellungs-Schalter Einzeltasten-Kuerzel deaktivieren (e und /); prefers-reduced-motion fuer CSS und Graph-Simulation. KEIN neues role=status (legal.spec-Falle). **#171:** @axe-core/playwright als devDependency (+2 Pakete, von Stefan freigegeben); neuer CI-Pack a11y.spec.ts (Login/Lesemodus/Editor/Settings, WCAG A/AA, leere Allowlist). **Verifikation:** Voller lokaler Audit-Harness-Lauf: von urspruenglich 13 axe-Regelverstoessen verbleiben 0 auf den gescannten Kern-Screens; api-Vollsuite 423 Tests gruen (frische DB); shared-Tests 171 gruen; e2e auth/content/tasks/editor/sidebar/settings-nav/reorder/page-tree/favorites/graph/search/legal gruen; Checkbox-Ausrichtung in beiden Renderpfaden nachgemessen (1px-Versatz wie von Stefan abgenommen). Zwei Spec-Erwartungen nachgefuehrt (Locator-Scope, Sektionszahl 8). Schliesst #166, #167, #168, #169, #170, #171.
fable-5 added 10 commits 2026-07-21 15:25:25 +02:00
Gemeinsamer useModalFocus-Hook: Initialfokus in den Dialog, Tab/Shift-Tab
zyklisch gefangen, Fokus-Rückgabe an den Auslöser (bzw. returnFocusRef,
wenn der öffnende Menüpunkt mit dem Menü unmountet). Dialoge tragen jetzt
aria-labelledby auf ihre Überschrift und tabindex=-1 als Fokus-Fallback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGM8jo3hwoV9wsCVGfy8iq
#163: Dokumentsprache und Seitentitel der SPA
Some checks failed
CI / Lint, typecheck, test (pull_request) Successful in 4m43s
CI / Build container images (pull_request) Successful in 1m11s
CI / Auth e2e pack (pull_request) Successful in 7m14s
CI / Import/export fidelity gate (pull_request) Successful in 56s
CD / Deploy to Test (push) Blocked by required conditions
CD / Smoke tests against Test (push) Blocked by required conditions
CD / Promote to Int (push) Blocked by required conditions
CI / Auth e2e pack (push) Blocked by required conditions
CI / Import/export fidelity gate (push) Blocked by required conditions
CI / Build container images (push) Blocked by required conditions
CD / Build and push images (push) Has been cancelled
CI / Lint, typecheck, test (push) Has been cancelled
418aafd5ec
i18n spiegelt die aktive Sprache auf <html lang> (Init + languageChanged;
der User-Locale-Wechsel in auth-context läuft über dasselbe Event). Neuer
useDocumentTitle-Hook setzt je Route einen sprechenden Titel
(Seite — Teich — Dorfteich), verdrahtet in allen Routen-Komponenten;
dynamische Titel folgen den geladenen Daten.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGM8jo3hwoV9wsCVGfy8iq
Die Editorfläche bekommt einen lokalisierten zugänglichen Namen und ist
im Lesemodus role=document statt eines unbenannten Textfelds (setOptions
im selben Layout-Effekt wie setEditable). Eingeklappte Sidebar zusätzlich
inert (aria-hidden allein ließ fokussierbare Kinder im Tab-Weg). Die
li-Zwischenknoten der Listboxen (Wikilink-/Mention-Autocomplete,
Suchergebnisse) sind role=presentation, damit listbox→option wieder eine
gültige Eltern-Kind-Beziehung ist. Toolbar: Pfeiltasten-Navigation über
die Controls (native Selects behalten ihre Pfeiltasten) und ein
sprechendes Toolbar-Label statt des Absatz-Buttons-Labels.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGM8jo3hwoV9wsCVGfy8iq
#165: Reflow bei 320 px und Tastatur-Scrollbarkeit
Some checks failed
CI / Lint, typecheck, test (pull_request) Successful in 4m39s
CI / Build container images (pull_request) Successful in 4m2s
CI / Auth e2e pack (pull_request) Successful in 7m17s
CI / Import/export fidelity gate (pull_request) Successful in 56s
CD / Deploy to Test (push) Blocked by required conditions
CD / Smoke tests against Test (push) Blocked by required conditions
CD / Promote to Int (push) Blocked by required conditions
CI / Auth e2e pack (push) Blocked by required conditions
CI / Import/export fidelity gate (push) Blocked by required conditions
CI / Build container images (push) Blocked by required conditions
CD / Build and push images (push) Has been cancelled
CI / Lint, typecheck, test (push) Has been cancelled
d4d4282c55
Vier Ursachen des seitenweiten Horizontal-Scrollens behoben: die Topbar
saß mit min-content-Breite in der Grid-Spalte (min-width: 0 nach dem
#100-Muster) und wickelt auf schmalen Viewports auf eine zweite Zeile
(Grid-Zeile minmax, Suchtext wird zum Icon); die aufgeklappte Sidebar
liegt unter 40rem als Overlay über dem Inhalt statt ihn auf einen
Streifen zu quetschen; Footer wickelt; Titel-Input und Settings-Spalte
schrumpfen (min-width bzw. align-items: stretch im Schmal-Layout).
Der Haupt-Scrollbereich ist per tabindex=0 tastatur-scrollbar — auf den
Rechtstext-Seiten gab es sonst keinen Weg, den Inhalt zu scrollen.

Gemessen: 10 Ansichten bei 320 px ohne Dokument-Überlauf (vorher 892 px
Inhaltsbreite); e2e content/settings-nav/sidebar/legal/page-tree/search
grün.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGM8jo3hwoV9wsCVGfy8iq
Skip-Link als erster Tab-Stopp springt auf #main; die angemeldete
Seitenansicht bekommt ein visually-hidden h1 (der sichtbare Titel ist
ein Input, der jetzt auch ein aria-label trägt); der Sidebar-Resizer
wandert in die nav-Landmarke (absolut an der Kante positioniert), damit
kein Inhalt außerhalb von Landmarken liegt. Zwei e2e-Locator auf das
Sidebar-Formular gescoped — das Editor-Titelfeld matcht seit dem neuen
Label ebenfalls auf /title|titel/i.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGM8jo3hwoV9wsCVGfy8iq
Die öffentliche Server-Shell bekommt AA-geprüfte Dark-Mode-Farben
(color-scheme: light dark hatte den UA dunkel rendern lassen, Links
fielen durch 1.4.3; Text 14,8:1, Links 10,1:1, Muted 8,5:1). Wikilinks
tragen eine permanente Unterstreichung — Farbe allein war das einzige
Link-Merkmal bei nur 2,5:1 Abstand zum Fließtext (1.4.1). Neues Token
--color-border-input (#7d8a97, 3,5:1/3,3:1) für Eingabefeld-Ränder
(1.4.11); Wächter-Kommentar am Favoriten-Gold.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGM8jo3hwoV9wsCVGfy8iq
Der Field-Baustein verdrahtet Hinweis/Fehler jetzt per aria-describedby
und aria-invalid mit dem Eingabefeld (cloneElement auf das einzelne
Kind; Fragmente bleiben unangetastet) — Screenreader nennen den Fehler
damit auch beim Feld-Fokus. Quota-Typ-Select mit Namen; die leeren
Aktions-/Erledigt-Spaltenköpfe in API-Tokens, Feed-Tokens, Sitzungen
und der Aufgabenübersicht (NodeView UND Server-Renderpfad) tragen
visually-hidden-Beschriftungen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGM8jo3hwoV9wsCVGfy8iq
Task-Checkboxen tragen in beiden Renderpfaden einen Namen: docToHtml
setzt aria-label aus dem Aufgabentext, die Editor-NodeView ebenso. Die
NodeView rendert ihr Host-Element jetzt selbst als li (ReactNodeView-
Renderer as/attrs) — TipTaps zusätzliches div-Host-Element zwischen ul
und li brach die Listensemantik; der Wrapper flacht per display:contents
ab, die #137-Pixel-Abstimmung bleibt erhalten (Selektor auf die neue
Tiefe nachgeführt, Ausrichtung nachgemessen: 1px-Versatz unverändert).
Der Wissensgraph-SVG bekommt ein beschreibendes aria-label inklusive
Verweis auf die Backlinks als gleichwertige Listenform. Der
Bild-Alt-Editor existierte bereits (Bild-Controls bei Auswahl) — kein
Änderungsbedarf. Hinweis: gecachte Seiten übernehmen das
Checkbox-Label wie bei jeder docToHtml-Änderung erst mit dem nächsten
Persist ihrer Inhalte.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGM8jo3hwoV9wsCVGfy8iq
Toast-Standzeit 2,5s auf 6s (WCAG 2.2.1 — für Screenreader-/Zoom-Nutzer
kaum erfassbar). Neue Einstellungs-Sektion Bedienung mit dem Schalter
Einzeltasten-Kürzel deaktivieren (lokale Geräte-Einstellung); die
Handler von e und / prüfen sie beim Tastendruck (WCAG 2.1.4).
prefers-reduced-motion: CSS-Transitions kollabieren auf instant, die
Graph-Simulation rechnet ihr Layout synchron zu Ende statt zu animieren
(WCAG 2.2.2). settings-nav-Spec auf 8 Sektionen nachgeführt. Bewusst
KEIN zusätzliches role=status (legal.spec-Locator-Falle).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGM8jo3hwoV9wsCVGfy8iq
#171: A11y-Tooling — axe-Smoke-Pack in CI
All checks were successful
CI / Lint, typecheck, test (pull_request) Successful in 4m38s
CI / Build container images (pull_request) Successful in 4m0s
CI / Auth e2e pack (pull_request) Successful in 7m31s
CI / Import/export fidelity gate (pull_request) Successful in 55s
CD / Build and push images (push) Successful in 17s
CD / Deploy to Test (push) Successful in 14s
CD / Smoke tests against Test (push) Successful in 1m24s
CD / Promote to Int (push) Successful in 11s
CI / Lint, typecheck, test (push) Successful in 4m50s
CI / Build container images (push) Has been skipped
CI / Auth e2e pack (push) Successful in 7m32s
CI / Import/export fidelity gate (push) Successful in 55s
0a26572933
@axe-core/playwright als devDependency (exakt +2 Lockfile-Pakete,
axe-core hat null Runtime-Dependencies; Freigabe durch Stefan im Chat).
Neuer e2e-Pack a11y.spec.ts scannt Login, Lesemodus, aktiven Editor und
Nutzer-Einstellungen gegen WCAG 2.1 A/AA — jede neue Verletzung bricht
den Build (Allowlist bewusst leer, nur mit Begründung erweiterbar);
Best-Practice-Regeln bleiben außen vor. In ci.yml als eigener Schritt
mit Rate-Limit-Reset nach dem Muster der übrigen Packs verdrahtet.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGM8jo3hwoV9wsCVGfy8iq
stwaidele merged commit 0a26572933 into main 2026-07-21 16:29:26 +02:00
Sign in to join this conversation.
No description provided.