# Rebreak-Native — Accessibility Audit & DiGA-Roadmap

Author: Ahmed (QA)  ·  Stand: 2026-05-07  ·  Status: Initial Audit, READ-ONLY

User-Trigger 2026-05-08: „Thema accessibility auf beide Plattformen checken — es gibt
Test-Frameworks dafür. Damit können wir bei DiGA punkten."

Scope dieses Dokuments:
1. Bestandsaufnahme der A11y-Awareness im rebreak-native-Code (iOS + Android)
2. Mapping auf WCAG 2.1 Level AA + DiGA-Anforderungen
3. Test-Framework-Empfehlung (RN-spezifisch)
4. Roadmap Pre-TestFlight / Pre-DiGA-Antrag / Post-Launch

---

## 1. Executive Summary

**Aktuelle A11y-Coverage in rebreak-native: ~1,3 %.**

Empirisch: 6 Treffer für `accessibilityLabel|accessibilityRole|accessibilityHint|accessibilityState|accessible=`-Props
verteilt auf 5 Files (Mail-Add-Account, ProtectionLockedCard, AppHeader-Back-Button,
ProtectionCard-Settings-Icon, DomainGrid-Add-Btn + DomainGrid-State).

Demgegenüber im selben Tree: **453 Touchable-Komponenten** (`Pressable` /
`TouchableOpacity` / `<Button`) und **50 TextInputs** verteilt auf **83 tsx-Files** —
also faktisch **>97 % unbeschriftet** für Screen-Reader (VoiceOver / TalkBack).

**DiGA-Risk-Score: HOCH.**

Begründung:
- BfArM verlangt für DiGA-Zertifizierung die Erfüllung von **WCAG 2.1 Level AA**
  (DVG §139e, BIK BITV-konformes Verfahren). Heute erfüllt rebreak-native diese
  Stufe **auf keiner Seite**.
- Recovery-User-Kohorte hat überdurchschnittlich oft Komorbiditäten:
  Sehbeeinträchtigung (Diabetes, Augenleiden), motorische Einschränkungen,
  starke kognitive Last in Krisen-Momenten — d.h. der **SOS-Flow ist
  a11y-mission-critical**, und der ist heute komplett unzugänglich für Screen-Reader.
- Apple App-Review (für External Beta) und Google Play prüfen seit 2024 bei
  Mental-Health-/Health-Apps zunehmend systematisch auf VoiceOver/TalkBack-Walkthrough.

**Empfehlung:** Sofortmaßnahme für SOS-Flow + Auth-Flow + Demographics-Form vor
TestFlight Internal (Wochenend-Cutover). Roadmap-Arbeit für Vollabdeckung pre-DiGA.

---

## 2. Component-by-Component-Status (Critical Paths)

Legende: ✅ ausreichend / ⚠️ teilweise / 🔴 fehlt komplett

### 2.1 SOS-Flow — `app/urge.tsx` (1333 Lines) — 🔴

Höchste Priorität (Krisen-Use-Case, Recovery-Schutz).

| Element                                               | Line   | A11y-Status | Finding                                                                 |
| ----------------------------------------------------- | ------ | ----------- | ----------------------------------------------------------------------- |
| Exit-Button (Pressable + Icon-only)                   | 1094   | 🔴          | kein `accessibilityLabel`, ScreenReader liest „Button" (oder schweigt) |
| TTS-Stop-Button                                       | 1116   | 🔴          | kein Label, kein Hint, keine `accessibilityState={{busy: …}}`         |
| Sound-Toggle-Button                                   | 1123   | 🔴          | toggled `soundEnabled` ohne `accessibilityState={{checked}}`           |
| Scroll-Down-Button                                    | 1160   | 🔴          | nur Icon                                                                |
| Lyra-Chip-Button (`handleChip`)                       | 1209   | 🔴          | kritisch: das sind die SOS-Action-Chips (Atem/Spiel/Cooldown), Screen-Reader liest gar nichts |
| Eingabefeld TextInput                                 | 1231   | 🔴          | kein `accessibilityLabel`                                              |
| Send-Button (Pressable, mit Disabled-State)           | 1244   | 🔴          | `disabled={thinking || !input.trim()}` — Screen-Reader bekommt kein `accessibilityState={{disabled}}` |

**Verdict:** SOS-Flow ist für sehbehinderte User nicht bedienbar. Absoluter
DiGA-Blocker.

### 2.2 SOS-Spiele — `components/urge/UrgeGames.tsx` (1067 Lines) — 🔴

Wir haben gerade native D-Pad-Buttons gemacht (Snake) und Tetris-Action-Buttons.
**Keiner** hat `accessibilityLabel` oder `accessibilityRole`.

| Element                              | Line | Finding                                                                    |
| ------------------------------------ | ---- | -------------------------------------------------------------------------- |
| Game-Picker-Pressable                | 37   | 🔴 ohne Label                                                              |
| Snake-D-Pad-Btn (Up/Down/Left/Right) | 360  | 🔴 reine Icon-Pressable, Direction-Info komplett unsichtbar für VoiceOver |
| Tetris-Action-Btn (Rotate/Drop)      | 405  | ⚠️ hat sichtbares Label aber kein explicit `accessibilityLabel`           |
| Memory-Card-Pressable                | 541  | 🔴 ohne Label, kein State-Info „revealed/matched"                          |
| Abandon-Button                       | 292  | 🔴 ohne Label                                                              |
| Replay/Continue-Buttons              | 724  | ⚠️ haben Text-Inhalt — aber `accessibilityRole="button"` fehlt            |

**Verdict:** Snake/Tetris/Memory/RPS sind faktisch reine Sehende-Spiele. Für
DiGA-Recovery-Effektmessung problematisch (a11y-User können die Distraktions-
Mechanik nicht nutzen).

### 2.3 Profile + Demographics — `app/profile/index.tsx` + `components/profile/DemographicsAccordion.tsx` (272 / 621 Lines) — 🔴

DiGA-Pflicht-Daten-Erhebung (Phase C).

| Element                                          | Line     | Finding                                                                        |
| ------------------------------------------------ | -------- | ------------------------------------------------------------------------------ |
| TextInput Geburtsjahr                            | 267      | 🔴 kein Label, nur Placeholder „z.B. 1989" — nicht für VoiceOver lesbar       |
| SelectButton Geschlecht                          | 296      | 🔴 nicht als „Combobox/Spinner" markiert, Screen-Reader nennt keine Auswahl   |
| TextInput Beruf                                  | 304      | 🔴 wie Geburtsjahr                                                              |
| SelectButton Familienstand                       | 320      | 🔴                                                                              |
| SelectButton Bundesland                          | 328      | 🔴                                                                              |
| TextInput Stadt                                  | 336      | 🔴                                                                              |
| Modal-Picker (`onSelect(value)`)                 | 587      | 🔴 jeder Picker-Eintrag ist `Pressable` ohne Label → VoiceOver liest gar nichts |
| Revoke-Consent-Pressable                         | 351      | 🔴 wichtig für DSGVO Art. 7(3)                                                 |
| Modal-Backdrop                                   | 539      | 🔴 fehlt `accessibilityViewIsModal` (iOS) / Focus-Trap                          |

**Verdict:** Gerade diese Form ist DSGVO Art. 9 + DiGA-Datensatz-Pflicht. Wenn
ein blinder User die Demographics nicht ausfüllen kann, **fehlen seine Daten in
der DiGA-Versorgungs-Studie** (Bias).

### 2.4 Header + Dropdown — `components/AppHeader.tsx` + `components/header/HeaderDropdownMenu.tsx` — ⚠️

| Element                            | Line       | Finding                                              |
| ---------------------------------- | ---------- | ---------------------------------------------------- |
| Back-Button                        | 56         | ✅ `accessibilityLabel="Zurück"`                     |
| Notification-Bell-Pressable        | 72         | 🔴 kein Label, Badge-Count gar nicht angesagt        |
| Avatar/Dropdown-Trigger            | 88         | 🔴 kein Label „Profilmenü öffnen"                   |
| Dropdown Backdrop-Pressable        | 86 (Menu)  | 🔴                                                   |
| Dropdown Items (Profile/Settings/Logout) | 108–239 | 🔴 keine Labels, Modal hat kein `accessibilityViewIsModal` |

### 2.5 ComposeCard — `components/ComposeCard.tsx` — ⚠️

hitSlop ≥44pt korrekt umgesetzt (Apple-HIG-konform), aber **keine** a11y-Labels:

| Element                       | Line | Finding                                            |
| ----------------------------- | ---- | -------------------------------------------------- |
| TextInput Compose             | 110  | 🔴 nur Placeholder, kein Label                    |
| Image-Remove-Pressable        | 130  | 🔴 nur Close-Icon                                 |
| Image-Picker-Pressable        | 147  | 🔴 Text „Foto" nur visuell                         |
| Cancel-Pressable              | 160  | ⚠️ hat Text-Child, aber Role/Label-Mapping unklar |
| Share-Submit-Pressable        | 168  | 🔴 disabled-State nicht annonciert                |

### 2.6 Blocker — `app/(app)/blocker.tsx` + `components/blocker/*.tsx` — ⚠️ (best-of)

Hier ist mit Abstand die meiste a11y-Awareness — Schutz-Settings sind DiGA-
mission-critical und das ist hier korrekt erkannt:

| Element                                | A11y-Status | Note                                          |
| -------------------------------------- | ----------- | --------------------------------------------- |
| ProtectionCard Settings-Icon           | ✅          | `accessibilityLabel={t('blocker.protection_settings_a11y')}` |
| ProtectionLockedCard Settings-Icon     | ✅          | dito                                          |
| DomainGrid Add-Domain-Pressable        | ✅          | Label + `accessibilityState={{disabled}}`     |
| Switch (LayerSwitchCard, ProtectionCard) | ⚠️        | RN-Switch hat default `accessibilityRole="switch"` aber kein i18n-Label |
| ProtectionDetailsSheet                 | 🔴          | Modal ohne `accessibilityViewIsModal`         |
| AddDomainSheet TextInput               | 🔴          | kein Label                                    |
| CooldownBanner                         | 🔴          | Animation, kein `accessibilityLiveRegion="polite"` |
| DeactivationExplainerSheet             | 🔴          | Modal-Pattern wie oben                        |

### 2.7 Auth-Flow — `app/(auth)/{signin,signup,forgot-password,confirm,confirm-otp,device-limit}.tsx` — 🔴

Zugang zur App = a11y-Pflicht-Pfad.

| Element (signin)              | Line | Finding                                        |
| ----------------------------- | ---- | ---------------------------------------------- |
| OAuth-Google-Btn              | 103  | 🔴 nur Icon-+-Text-Children, kein expliziter Label |
| OAuth-Apple-Btn               | 117  | 🔴 dito                                         |
| TextInput Email               | 139  | ✅ `autoComplete="email"` + ⚠️ kein expliziter `accessibilityLabel` |
| TextInput Password            | 151  | ✅ `autoComplete="password"` + ⚠️ kein Label  |
| Forgot-Password-Pressable     | 162  | 🔴                                              |
| Submit-Button                 | 173  | 🔴 disabled-State nicht annonciert             |
| Signup-Link-Pressable         | 186  | 🔴                                              |

`autoComplete` hilft Password-Manager, ersetzt aber **kein** `accessibilityLabel`.

### 2.8 Community / PostCard / PostCommentsSheet — 🔴

`components/PostCard.tsx`: hitSlop ≥44pt korrekt, aber Like-/Comment-Buttons
ohne Label. Like-Count (`localCount`) wird visuell angezeigt aber nicht in
`accessibilityValue` exposed → Screen-Reader liest nur „Button".

### 2.9 Animation & Reduce-Motion — 🔴 (Cross-cutting)

- **270 Animation/Reanimated-Usages** im Code (`Animated.*` / `FadeIn` /
  `useNativeDriver` / `useSharedValue`).
- **0 Treffer** für `AccessibilityInfo.isReduceMotionEnabled` /
  `useReduceMotion()`.

WCAG 2.3.3 (Animation from Interactions, AAA) und 2.2.2 (Pause/Stop/Hide, AA) sind
heute pauschal verletzt — die App respektiert Systemeinstellung „Bewegung
reduzieren" nicht. Für vestibuläre Empfindlichkeit problematisch.

### 2.10 Dynamic-Type / Font-Scaling — ⚠️ (Cross-cutting)

- 398 explizite `fontSize:` / `font-size`-Vorkommen im Code.
- 0 `allowFontScaling={false}` Bypässe (gut!) — RN skaliert per default mit
  iOS Dynamic-Type / Android-Font-Scale.
- ABER: viele Layouts nutzen `fontSize` als hartcodierten Pixel — bei extremem
  Font-Scale (Accessibility Sizes XXX-Large) brechen die Layouts wahrscheinlich.

### 2.11 Color-Contrast — ⚠️ (Cross-cutting)

Häufige Hex-Codes aus Codebase:
- `#a3a3a3` (neutral-400) auf `#ffffff` → contrast-ratio **2,84:1** → **fail
  WCAG AA** (4.5:1 für Body-Text)
- `#737373` (neutral-500) auf `#ffffff` → contrast-ratio **4,48:1** → **fail
  WCAG AA** (knapp; Norm fordert 4,5:1)
- `placeholderTextColor="#a3a3a3"` (signin Lines 143, 155) → fail

→ Alle „muted" / „placeholder" Texte erfüllen WCAG AA nicht. Screenshot-
basierter axe-Audit würde dutzende Findings melden.

### 2.12 Screen-Reader-Detection — 🔴 (Cross-cutting)

`grep AccessibilityInfo|isScreenReaderEnabled` → 0 Treffer.

Heißt: keine Komponente verhält sich anders, wenn Screen-Reader an ist
(z.B. Auto-Play-Audio von Lyra-TTS bei aktivem VoiceOver = problematisch,
wenn beide gleichzeitig sprechen).

### 2.13 Touch-Target-Size — ⚠️

- iOS HIG verlangt 44×44pt → vielfach via `hitSlop=12` nachträglich erfüllt
  (gut: ComposeCard, PostCard).
- Android Material verlangt **48×48dp** → heutige Mehrheit der Buttons ist
  hitSlop=12 → **44pt erreicht aber 48dp Android-Norm fehlt knapp**.

---

## 3. Test-Framework-Empfehlung

### 3.1 Was es gibt für RN

| Tool                                       | Was es kann                                                                   | Empfehlung |
| ------------------------------------------ | ----------------------------------------------------------------------------- | ---------- |
| `@testing-library/react-native` (RNTL)     | `getByA11yLabel`, `getByRole`, `getByA11yState` — Component-Test-Assertions | **JA — Pflicht** |
| `@testing-library/jest-native`             | Custom Matchers `toBeAccessible`, `toHaveAccessibilityValue`                  | **JA**     |
| `react-native-accessibility-engine` (Meta) | DEV-time Audit-Output beim Render — gibt Warnings für fehlende Labels        | **JA, Phase 2** |
| `axe-core-react-native`                    | Programmatic axe-Engine-Run gegen Component-Tree                             | **Optional**, instabil für SDK 53 |
| Maestro                                    | E2E — kann `id: "<accessibilityLabel>"` als Selektor → indirekt a11y-Test    | **JA**     |
| Apple Accessibility Inspector (Xcode)      | manuelle Audit-Tour mit Audit-Button                                          | **Pflicht**, manuell pre-Release |
| Android Accessibility Scanner (Play Store) | manueller Audit über App, gibt Findings-Report                                | **Pflicht**, manuell pre-Release |
| BIK BITV-Test (DE)                         | offizieller deutscher BITV-Test-Bericht — DiGA-konform                       | **Pflicht für DiGA-Antrag**, externer Provider |

### 3.2 Empfehlung in einem Satz

**`jest-expo` + `@testing-library/react-native` + `jest-native` für automatisierte Component-A11y-Assertions, plus `react-native-accessibility-engine` als Dev-Time-Linter, plus Maestro-Flows mit `id: "<accessibilityLabel>"`-Selektoren als E2E-Validation. Manuelle VoiceOver/TalkBack-Tour pre-Release. BIK BITV-Test als externer Audit pre-DiGA-Antrag.**

### 3.3 Setup-Aufwand

| Schritt                                                        | Aufwand   |
| -------------------------------------------------------------- | --------- |
| `pnpm add -D jest-expo @testing-library/react-native @testing-library/jest-native` | 15 min    |
| `jest.config.js` + `jest-setup.ts` mit jest-native-Matchern   | 30 min    |
| Erste 3 Component-A11y-Tests (Smoke)                          | 2 h       |
| `react-native-accessibility-engine` integrieren               | 1 h       |
| Maestro-A11y-Selektoren in vorhandenen Flows umstellen        | 1 h       |
| Dokumentierte VoiceOver/TalkBack-Manual-Test-Checkliste        | 2 h       |

### 3.4 Beispiel — A11y-Component-Test

```typescript
// apps/rebreak-native/tests/components/AppHeader.a11y.test.tsx
import { render } from '@testing-library/react-native';
import '@testing-library/jest-native/extend-expect';
import { AppHeader } from '../../components/AppHeader';

describe('AppHeader — a11y contracts', () => {
  it('Back-Button hat accessibilityLabel und role="button"', () => {
    const { getByA11yLabel } = render(<AppHeader showBack title="Profil" />);
    const back = getByA11yLabel('Zurück');
    expect(back).toBeTruthy();
    expect(back).toHaveAccessibilityRole('button');
  });

  it('Notification-Bell hat Label mit Badge-Count', () => {
    const { getByA11yLabel } = render(<AppHeader notifCount={3} />);
    expect(getByA11yLabel(/Benachrichtigungen.*3/i)).toBeTruthy();
  });

  it('Avatar/Dropdown-Trigger hat Label', () => {
    const { getByA11yLabel } = render(<AppHeader />);
    expect(getByA11yLabel(/Profilmenü/i)).toBeTruthy();
  });
});
```

---

## 4. WCAG 2.1 Level AA — Mapping rebreak-native (heute)

Pflicht-Kriterien für DiGA, geprüft gegen Codebase 2026-05-07:

| WCAG-SC                          | Level | Status heute | Begründung                                           |
| -------------------------------- | ----- | ------------ | ---------------------------------------------------- |
| 1.1.1 Non-text Content           | A     | 🔴 Fail      | 97 % der Icon-Pressables ohne `accessibilityLabel`  |
| 1.3.1 Info and Relationships     | A     | 🔴 Fail      | Form-Labels in Demographics fehlen, Modal-Roles fehlen |
| 1.3.5 Identify Input Purpose     | AA    | ⚠️ Partial   | Auth nutzt `autoComplete`, sonst nirgends           |
| 1.4.3 Contrast (Minimum) Text    | AA    | 🔴 Fail      | `#a3a3a3 / #ffffff` = 2,84:1 — siehe oben           |
| 1.4.4 Resize Text                | AA    | ⚠️ Partial   | RN font scales by default, aber Layout bricht bei XXL |
| 1.4.10 Reflow                    | AA    | ⚠️ Unknown   | nicht systematisch getestet                          |
| 1.4.11 Non-text Contrast         | AA    | 🔴 Fail      | Switch-Border, Icon-Outlines auf vielen Hellgrau-Backgrounds |
| 2.1.1 Keyboard                   | A     | n.a.         | RN nativ (kein Keyboard-Use-Case auf Phone)         |
| 2.2.2 Pause, Stop, Hide          | A     | 🔴 Fail      | Animationen pausieren nicht bei Reduce-Motion       |
| 2.4.3 Focus Order                | A     | 🔴 Unknown   | Modals haben kein Focus-Trap → Order kaputt mit VoiceOver |
| 2.4.6 Headings and Labels        | AA    | 🔴 Fail      | Headings wie ProfileHeader haben kein `accessibilityRole="header"` |
| 2.5.5 Target Size                | AA    | ⚠️ Partial   | iOS 44pt via hitSlop OK, Android 48dp knapp        |
| 3.2.1 On Focus                   | A     | ✅ Pass      | keine unerwarteten Context-Changes on Focus         |
| 3.3.1 Error Identification       | A     | ⚠️ Partial   | Errors als Text gerendert, aber kein `accessibilityLiveRegion="assertive"` |
| 3.3.2 Labels or Instructions     | A     | 🔴 Fail      | Form-Inputs haben Placeholder statt Label          |
| 4.1.2 Name, Role, Value          | A     | 🔴 Fail      | überall fehlt Name/Role-Markup                      |
| 4.1.3 Status Messages            | AA    | 🔴 Fail      | Toasts/SuccessAlert nicht als `accessibilityLiveRegion` |

**Zusammenfassung:** rebreak-native erfüllt heute ~3 von 17 für DiGA relevanten
WCAG-AA-Kriterien.

---

## 5. DiGA-Punkte-Strategy

### 5.1 Was BfArM real fragt (laut DiGA-Verfahrensverzeichnis)

DiGA-Antrag-Modul „Barrierefreiheit" verlangt:
- **Selbsterklärung WCAG 2.1 AA-Konformität** (Pflicht, schriftlich)
- **Test-Bericht** (BIK BITV-Test ODER eigener dokumentierter Audit)
- **Nutzergruppen-Reflexion** (welche Behinderungs-Pattern wurden wie adressiert?)
- **Process-Commitment** (wie wird A11y in Entwicklung+Releases sichergestellt?)

### 5.2 Low-hanging-fruit (hoher BfArM-Eindruck, niedriger Aufwand)

| Maßnahme                                                                    | Effort | DiGA-Score |
| --------------------------------------------------------------------------- | ------ | ---------- |
| `accessibilityLabel` auf alle Icon-Pressables im SOS-Flow + Auth + Demographics | 1 Tag  | hoch       |
| `accessibilityRole="header"` auf alle h1/h2-Texte                          | 2 h    | mittel     |
| `useReduceMotion`-Hook + `Animated.timing` skip wenn true                  | 4 h    | hoch       |
| `accessibilityViewIsModal` auf alle 12 Modals                              | 3 h    | mittel     |
| Color-Tokens in `lib/theme.ts` auf WCAG-AA-konforme Hex anheben (`#a3a3a3` → `#737373`, etc.) | 4 h | hoch       |
| Standard-Typing-Pattern für Forms: `<FieldRow accessibilityLabel={…}>`     | 1 Tag  | hoch       |

### 5.3 Architektur-Investments (hoher Effort, höherer Score)

- **A11y-Wrapper-Komponenten**: `<A11yPressable>`, `<A11yTextInput>` zentral mit
  Pflicht-Props. Migrationsweg über alle 453 Touchables.
- **Theme-Audit-Pipeline**: lint-rule die jede neue Hex-Color gegen
  `getContrastRatio(fg, bg)` prüft.
- **CI-Gate**: jest-A11y-Tests und `react-native-accessibility-engine` in CI,
  PR-Block bei Regression.
- **Dynamic-Type-aware-Layouts**: alle „fixed-width-Cards" auf flex-basiert
  refactoren, Tests bei XXL-Font.
- **i18n-Pflicht-Audit**: jeder neue `accessibilityLabel` muss aus `t(…)`
  kommen, nicht hartcodiert „Zurück" wie heute in AppHeader.

### 5.4 DiGA-Self-Statement (Vorschlag für DSFA mit Hans-Müller)

> rebreak verpflichtet sich zur Erfüllung der WCAG-2.1-Level-AA-Kriterien
> entsprechend BIK-BITV-Test-Standard. Pre-Release-Audit erfolgt durch
> [BIK-Provider], jährliches Re-Assessment ist Bestandteil unserer
> Entwicklungsprozesse. Automatisierte A11y-Component-Tests sind Bestandteil
> unseres CI-Gates (Pull-Request-Blocker bei Regression).

→ vor DiGA-Antrag prüfen mit Hans-Müller (DSB).

---

## 6. Roadmap

### 6.1 Pre-TestFlight (Wochenende 2026-05-09/10) — absolutes Minimum

Ziel: A11y-Apple-Review-Risk reduzieren, ohne den Cutover zu blockieren.

| Task                                                                              | Form          | Aufwand |
| --------------------------------------------------------------------------------- | ------------- | ------- |
| `accessibilityLabel` auf alle 7 Pressables in `app/urge.tsx`                     | manuell       | 30 min  |
| `accessibilityLabel` auf 4 OAuth + Forgot + Submit + Signup-Link in `signin.tsx` | manuell       | 20 min  |
| `accessibilityLabel` auf Notification-Bell + Avatar-Trigger in `AppHeader.tsx`   | manuell       | 10 min  |
| `accessibilityLabel` auf Demographics-TextInputs + SelectButtons (8 Felder)      | manuell       | 30 min  |
| `accessibilityViewIsModal={true}` auf SosFeedbackModal + GamePickerDrawer + InlineRatingDrawer + ProtectionDetailsSheet | manuell | 30 min  |
| Manueller VoiceOver-Smoke-Walk (Login → SOS-Trigger → Lyra-Chip) auf iPhone-Build | manuell      | 30 min  |

**Owner:** rebreak-native-ui (UI-Edit-Approval beim User holen).

**Wichtig:** das ist NUR Pflaster für TestFlight Internal. Reicht nicht für DiGA.

### 6.2 Pre-DiGA-Antrag (Phase nach Public-Beta) — Vollabdeckung Critical Paths

| Task                                                                               | Aufwand |
| ---------------------------------------------------------------------------------- | ------- |
| jest-expo + RNTL + jest-native installieren + jest.config.js                      | 1 h     |
| `react-native-accessibility-engine` als Dev-Plugin                                 | 1 h     |
| A11y-Wrapper-Components `<A11yPressable>` + `<A11yTextInput>`                     | 1 Tag   |
| Migration: alle 453 Pressables → A11yPressable mit Pflicht-Label                   | 5 Tage  |
| Migration: alle 50 TextInputs → A11yTextInput mit Pflicht-Label                    | 1 Tag   |
| `useReduceMotion()`-Hook in alle Animation-Files                                   | 2 Tage  |
| Color-Token-Audit in `lib/theme.ts` (WCAG-AA-konform)                             | 1 Tag   |
| Headings-Roles auf alle Section-Titel                                              | 4 h     |
| `accessibilityLiveRegion="polite"` auf Toasts/SuccessAlert/CooldownBanner         | 2 h     |
| jest-A11y-Component-Tests (5 wichtigste Components, je 4–6 Assertions)            | 1 Tag   |
| Maestro-Flows: Selektoren auf accessibilityLabel umstellen                         | 1 Tag   |
| Dokumentierte VoiceOver/TalkBack-Manual-QA-Checkliste                              | 0,5 Tag |

**Owner:** rebreak-native-ui + Ahmed (Tests).

### 6.3 Post-Launch — kontinuierliches A11y-Gate

| Task                                                                            | Aufwand |
| ------------------------------------------------------------------------------- | ------- |
| GitHub Action: jest-A11y-Tests + RN-A11y-Engine in CI, PR-Block bei Regression | 2 h     |
| BIK BITV-Test-Provider beauftragen pre-DiGA-Antrag                              | User-Action |
| Apple Accessibility Audit (Xcode) als Pre-Release-Step in `ops/` dokumentieren | 1 h     |
| Android Accessibility Scanner als Pre-Release-Step                              | 1 h     |
| jährliche A11y-Audit-Cycle (DSFA-Anhang)                                       | User+Hans-Müller |

---

## 7. Konkrete TODOs nach Priorität

### Hoch (vor TestFlight, Wochenende)

1. SOS-Flow `app/urge.tsx` Lines 1094, 1116, 1123, 1160, 1209, 1231, 1244 — `accessibilityLabel` ergänzen (rebreak-native-ui).
2. Auth-Flow `(auth)/signin.tsx` Lines 103, 117, 139, 151, 162, 173, 186 — Labels (rebreak-native-ui).
3. AppHeader Lines 72, 88 — Notification + Avatar Labels (rebreak-native-ui).
4. Demographics Form Lines 267, 296, 304, 320, 328, 336, 351 — Labels (rebreak-native-ui).
5. Modals: `accessibilityViewIsModal` setzen (5 Sheets/Modals) (rebreak-native-ui).

### Mittel (Pre-DiGA-Antrag)

6. Test-Framework-Setup (`jest-expo`, RNTL, jest-native) (Ahmed).
7. A11y-Wrapper-Components (rebreak-native-ui + Ahmed-Konsultation für Test-Hooks).
8. Color-Token-Refactor in `lib/theme.ts` (rebreak-native-ui).
9. `useReduceMotion`-Cross-cutting (rebreak-native-ui).
10. BIK BITV-Test-Provider auswählen (User-Decision).

### Niedrig (Post-Launch)

11. CI-A11y-Gate (Ahmed + DevOps/Backyard).
12. Dokumentierte Pre-Release-Checkliste in `ops/RELEASE_READINESS.md` ergänzen (Ahmed).
13. Quartals-A11y-Re-Audit nach Feature-Release (DSFA-Anhang) (Ahmed + Hans-Müller).

---

## 8. Open Questions an User

1. **A11y-Bug-Fix-Scope am Wochenende vor TestFlight:** Soll rebreak-native-ui die ~25 fehlenden Labels in SOS-/Auth-/Demographics-/Header-Critical-Paths noch in den Cutover-Build einbauen (Effort ~2 h, Apple-Review-Risk-Reducer für External Beta), oder erst V2 nach Internal?
2. **BIK BITV-Test-Provider:** Soll Ahmed Provider-Vorschläge sammeln (BIT-inklusiv, BFIT-Bund, etc., Kosten 5–15k EUR), oder hat User schon Kontakt? Zeitpunkt: vor oder nach DiGA-Antrag-Submission?
3. **DiGA-Self-Statement-Wording:** Soll im DSFA-Anhang explizit „WCAG 2.1 AA"-Commitment stehen mit Test-Coverage-Quote (siehe TESTING_STATE.md §4.4) oder bewusst weicher formulieren („wir streben an…")? Hans-Müller-Frage.

---

Ende. — Ahmed
