diff --git a/.planning/quick/260921-jt4-barrierefreiheit-mit-bedienentscheidunge/260921-jt4-PLAN.md b/.planning/quick/260921-jt4-barrierefreiheit-mit-bedienentscheidunge/260921-jt4-PLAN.md
new file mode 100644
index 0000000..bdd77a9
--- /dev/null
+++ b/.planning/quick/260921-jt4-barrierefreiheit-mit-bedienentscheidunge/260921-jt4-PLAN.md
@@ -0,0 +1,720 @@
+---
+phase: quick-260921-jt4
+plan: 01
+type: execute
+wave: 1
+depends_on: []
+files_modified:
+ - apps/web/src/app/(portal)/marketplace/components/MarketplaceCard.tsx
+ - apps/web/src/app/(portal)/marketplace/components/MarketplaceCard.test.tsx
+ - apps/web/src/components/dashboard/widget-catalog-modal.tsx
+ - apps/web/src/components/dashboard/widget-catalog-modal.test.tsx
+ - apps/web/src/components/settings/calendar-settings-panel.tsx
+ - apps/web/src/components/settings/calendar-settings-panel.test.tsx
+ - apps/web/src/components/dashboard/widgets/note-widget.tsx
+ - apps/web/src/components/dashboard/widgets/note-widget.test.tsx
+ - apps/web/src/components/dashboard/widgets/note-task-list.tsx
+ - apps/web/src/components/dashboard/widgets/note-task-list.test.tsx
+ - apps/web/src/components/dashboard/widgets/calendar-widget.tsx
+ - apps/web/src/components/dashboard/widgets/calendar-widget.test.tsx
+ - apps/web/src/components/dashboard/widgets/calculator-widget.tsx
+ - apps/web/src/components/dashboard/widgets/favorites-widget.tsx
+ - apps/web/src/components/layout/header.tsx
+ - apps/web/src/components/settings/account-settings-form.tsx
+ - apps/web/src/app/(auth)/login/page.tsx
+ - apps/web/src/app/(auth)/reset-password/page.tsx
+ - apps/web/src/app/(auth)/reset-password/[token]/page.tsx
+ - apps/web/src/app/(portal)/change-password/page.tsx
+ - apps/web/src/app/(portal)/modules/cert-manager/components/SplitTab.tsx
+ - apps/web/src/app/(portal)/modules/cert-manager/zip-filename.ts
+ - apps/web/src/app/(portal)/modules/cert-manager/zip-filename.test.ts
+ - apps/web/src/lib/translations-identity.test.tsx
+ - apps/web/src/messages/de.json
+ - apps/web/src/messages/en.json
+ - apps/api/src/tenders/tender-normalizer.service.ts
+autonomous: true
+requirements: [D-01, D-02, D-03, D-04, D-05, D-06, D-07]
+
+estimate:
+ tokens: 150000
+ raw_tokens: 150000
+ tasks: 3
+ confidence: low
+
+must_haves:
+ truths:
+ - "Jede Stelle, die heute nur mit der Maus bedienbar ist, ist danach auch mit der
+ Tastatur bedienbar und wird von einer Vorlesehilfe als Schaltflaeche angesagt —
+ belegt durch Komponententests, die ein Tastaturereignis ausloesen, nicht durch
+ Auszeichnungs-Behauptungen (D-01)."
+ - "Das Erscheinungsbild ist an keiner der 13 Dateien ein anderes als vorher: kein
+ neuer Rahmen, kein neuer Abstand, keine verschobene Kachel (D-04)."
+ - "Biome meldet nach Abschluss genau 399 Befunde, 0 davon der Stufe error, und genau
+ EINEN a11y-Befund — den bewusst stehengelassenen Tastatur-Handler des
+ Taschenrechner-Rahmens. Keine einzige Unterdrueckung per biome-ignore (D-07)."
+ - "Drei Druecke auf Weiter im Kalender-Widget holen die Quellenliste genau einmal
+ statt dreimal, und zwei aufeinanderfolgende Termin-Abrufe tragen nie denselben
+ from/to-Bereich — gemessen im Netzwerkprotokoll des Browsers, nicht per fetch aus
+ der Seite."
+ - "Der ZIP-Name des Zertifikat-Aufteilers kommt aus dem Uebersetzungskatalog und ist
+ auf einer Windows-Freigabe garantiert gueltig, weil eine gepruefte Schutzfunktion
+ jeden unzulaessigen Namen abfaengt — nicht, weil das deutsche Wort zufaellig
+ harmlos ist."
+ - "Jede neue Beschriftung steht in de.json UND en.json, deutsche Oberflaechentexte in
+ der Sie-Form; beide Kataloge haben danach dieselbe Schluesselmenge (D-05)."
+ - "Fuer jede der 30 Fundstellen steht in der SUMMARY, welcher der vier Wege gewaehlt
+ wurde und — bei der Rueckfallvariante oder beim Stehenlassen — warum der gerade
+ Weg dort nicht ging."
+ artifacts:
+ - apps/web/src/app/(portal)/modules/cert-manager/zip-filename.ts
+ - apps/web/src/app/(portal)/modules/cert-manager/zip-filename.test.ts
+ - apps/web/src/components/dashboard/widget-catalog-modal.test.tsx
+ - apps/web/src/components/settings/calendar-settings-panel.test.tsx
+ - apps/web/src/lib/translations-identity.test.tsx
+ key_links:
+ - "Hintergrundflaeche eines Dialogs -> echte Schaltflaeche -> onClose: beim
+ Loeschen-Dialog MUSS dieser Weg abbrechen, niemals bestaetigen."
+ - "note-widget -> previewOptions -> rehypeSanitize: die XSS-Schranke T-IEX-01 muss
+ den Umbau des Kaestchen-Handlers unveraendert ueberleben."
+ - "calendar-widget -> computeFetchWindow -> fetchEvents: der Sperrgriff darf den
+ 5-Minuten-Auffrischer nicht mitsperren, sonst friert die Anzeige ein."
+---
+
+
+Die 30 zurueckgestellten Barrierefreiheits-Befunde abarbeiten — mit den vom Orchestrator
+getroffenen Bedienentscheidungen D-01 bis D-04 — und die vier namentlich vermerkten
+Restposten aus den heutigen Vorgaengen bi2 und gof schliessen.
+
+Purpose: Heute sind mehrere Bedienelemente ausschliesslich mit der Maus erreichbar. Wer
+mit der Tastatur oder einer Vorlesehilfe arbeitet, kann sie nicht ausloesen — das ist der
+eigentliche Schaden hinter diesen Befunden, kein Schoenheitsfehler der Zaehlung.
+
+Output: 13 Oberflaechendateien mit echten Schaltflaechen statt klickbarer Bereiche, zwei
+Uebersetzungskataloge im Gleichstand, fuenf neue bzw. erweiterte Testdateien, ein
+gemessener Rueckgang von 429 auf 399 Befunde und zwei Kalender-Abrufe weniger pro
+Monatswechsel.
+
+
+
+@~/.claude/gsd-core/workflows/execute-plan.md
+@~/.claude/gsd-core/templates/summary.md
+
+
+
+@.planning/STATE.md
+@CLAUDE.md
+@.planning/quick/260921-bi2-lint-rueckstand-abbauen-mechanische-fixe/260921-bi2-SUMMARY.md
+@.planning/quick/260921-gof-effekt-abhaengigkeiten-in-react-21-befun/260921-gof-VERIFICATION.md
+
+
+
+Vom Planer am 2026-09-21 unmittelbar vor dem Schreiben dieses Plans gemessen, nicht
+uebernommen:
+
+```
+npx biome lint . --reporter=json
+ -> total 429 real 350 test 79 errors 0 a11y 30
+```
+
+Die Zahl 429 ist die **Gesamtzahl inklusive Testdateien** (350 echter Quelltext + 79
+Testdateien), nicht der reine Quelltextanteil — die Auftragsbeschreibung bezeichnet sie
+als "real source only", das ist eine Fehlbeschriftung der sonst korrekten Zahl. Alle 30
+a11y-Befunde liegen in echtem Quelltext.
+
+Die 30 Fundstellen, mit Zeilennummer zum Zeitpunkt der Planung (Zeilen verschieben sich
+beim Umbau — arbeite nach Element, nicht nach Zeilennummer):
+
+| Datei | Zeile | Regel |
+|---|---|---|
+| `app/(auth)/login/page.tsx` | 105 | noAutofocus |
+| `app/(auth)/reset-password/[token]/page.tsx` | 139 | noAutofocus |
+| `app/(auth)/reset-password/page.tsx` | 99 | noAutofocus |
+| `app/(portal)/change-password/page.tsx` | 86 | noAutofocus |
+| `marketplace/components/MarketplaceCard.tsx` | 116 | noNoninteractiveElementInteractions, noStaticElementInteractions, useKeyWithClickEvents |
+| `components/dashboard/widget-catalog-modal.tsx` | 56 | noNoninteractiveElementInteractions, noStaticElementInteractions, useKeyWithClickEvents |
+| `components/dashboard/widget-catalog-modal.tsx` | 64 | noNoninteractiveElementInteractions, useKeyWithClickEvents |
+| `dashboard/widgets/calculator-widget.tsx` | 323 | noNoninteractiveElementInteractions |
+| `dashboard/widgets/calculator-widget.tsx` | 345 | useAriaPropsSupportedByRole |
+| `dashboard/widgets/calendar-widget.tsx` | 253 | noNoninteractiveElementInteractions, noStaticElementInteractions |
+| `dashboard/widgets/favorites-widget.tsx` | 266 | useAriaPropsSupportedByRole |
+| `dashboard/widgets/favorites-widget.tsx` | 462 | noNoninteractiveElementInteractions |
+| `dashboard/widgets/favorites-widget.tsx` | 474 | noNoninteractiveElementInteractions |
+| `dashboard/widgets/note-widget.tsx` | 184 | noNoninteractiveElementInteractions, noStaticElementInteractions, useKeyWithClickEvents |
+| `components/layout/header.tsx` | 156 | noNoninteractiveElementInteractions |
+| `components/settings/account-settings-form.tsx` | 161 | noNoninteractiveElementInteractions |
+| `components/settings/calendar-settings-panel.tsx` | 159, 182, 199 | useAriaPropsSupportedByRole |
+| `components/settings/calendar-settings-panel.tsx` | 373 | noNoninteractiveElementInteractions, noStaticElementInteractions, useKeyWithClickEvents |
+
+**Zwei Befunde der Auftragsbeschreibung sind beim Nachlesen anders als angenommen** — der
+Plan folgt dem gelesenen Quelltext, nicht der Annahme:
+
+1. **Vier der elf `noNoninteractiveElementInteractions` sind ueberhaupt keine Klicks**,
+ sondern `onError`-Handler an ``-Elementen (Ersatzweg fuer nicht ladende
+ Profilbilder und Favoriten-Symbole): `header.tsx:156`, `account-settings-form.tsx:161`,
+ `favorites-widget.tsx:462` und `:474`. Ein Ladefehler ist keine Bedienung; hier gibt es
+ nichts in eine Schaltflaeche zu verwandeln.
+2. **Alle fuenf `useAriaPropsSupportedByRole` haben dieselbe Gestalt**: ein `aria-label`
+ sitzt auf einem schlichten `
` bzw. `` ohne Rolle. Solche Elemente haben die
+ Rolle `generic`, die gar keine ARIA-Merkmale traegt — die Beschriftung wird von jeder
+ Vorlesehilfe **stillschweigend verworfen**. Das ist ein echter Mangel, kein Formfehler.
+
+
+
+Die folgenden Loesungswege wurden vom Planer **empirisch an Biome 2.5.0 mit der
+Projektkonfiguration geprueft** (Probedatei unter `apps/web/src/__probe__/`, danach
+geloescht). Das ist keine Vermutung — jede Zeile ist gemessen:
+
+| Probe | Ergebnis |
+|---|---|
+| `