theme-contrast.test.ts parses tokens.css and asserts every real UI colour
pairing (4.5:1 text, 3:1 UI) for BOTH palettes, so palette drift fails
unit tests instead of review. theme.test.ts covers resolve/apply logic
(Node >= 22 ships a shadowing undefined localStorage global — the test
brings its own in-memory storage). The a11y pack now runs its four scans
in light AND dark via emulateMedia; the new theme pack exercises the
three-way switch end to end (instant apply, reload persistence, live OS
follow in system mode, override beats OS). ADR 0018 records the theming
model broadly: modes now, accent themes by derivation later.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QRtCnB3uLdQtFmvp9HXcRX
Die Zeilen-Aktionen der Personenverwaltung sind jetzt IconButtons
(lucide): MailCheck (Bestätigung erneut senden, nur bei Ausstehend),
ShieldPlus/ShieldMinus (Zum Admin machen / Admin entfernen),
UserX/UserCheck (Deaktivieren/Aktivieren), Trash2 (Löschen) — in dieser
Reihenfolge. Das zweistufige Löschen bleibt: die Bestätigung ist
weiterhin ein roter Text-Button und erhält beim Umschalten den Fokus
(kein Fokusverlust, ADR 0017). Lokalisierte Namen kommen unverändert
aus users.json via IconButton (aria-label+title), Icons aria-hidden.
Der Admin-Bereich ist neu im a11y-CI-Pack (axe WCAG A/AA auf /admin).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@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