Apply WCAG 2.2 AA accessibility to selection screen
epic-activity-type-configuration-business-logic-task-007 — Enhance ActivityTypeSelectionScreen to meet WCAG 2.2 AA requirements. Set minimum 44x44dp touch targets on all list items, add Semantics widgets with descriptive labels for screen reader support (VoiceOver/TalkBack), ensure sufficient contrast ratios using design tokens, verify focus traversal order is logical, and add live region announcements when the list loads or an error occurs. Validate with Flutter accessibility inspector.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 6 - 158 tasks
Can start after Tier 5 completes
Implementation Notes
Use Semantics(liveRegion: true, label: '...') wrapped around the list container to announce load completion — do not wrap individual items. Wrap each ListTile or custom item widget with a Semantics parent that merges child semantics. For touch targets, prefer wrapping in an InkWell or GestureDetector inside a SizedBox(height: 44, width: double.infinity) rather than padding hacks, as SizedBox correctly expands the hit-test area. Use design token ColorTokens.onSurface and ColorTokens.surface pairs exclusively — never hardcode hex values.
Focus traversal is automatic in Flutter's default traversal policy; verify it is not broken by any custom FocusNode usage introduced in the parent wizard. Use FocusTraversalGroup if reordering is needed. Run flutter analyze and dart fix before marking complete.
Testing Requirements
Widget tests must verify that SemanticsNode labels match expected strings using tester.getSemantics(). Use flutter_test's SemanticsController to traverse the semantics tree and assert liveRegion announcements fire on state transition. Contrast ratios must be verified by a static design token audit (unit test asserting color pair luminance ratios). Manual test pass required on a physical iOS device with VoiceOver enabled and an Android device with TalkBack enabled.
Accessibility inspector run must produce zero errors.
Metadata flag combination rules differ between organisations (e.g., Blindeforbundet honorarium thresholds, HLF mutual exclusion of km and transit). Encoding these as generic service-level validation may be insufficient, forcing organisation-specific branching inside the service that becomes unmaintainable as new organisations are onboarded.
Mitigation & Contingency
Mitigation: Model flag validation as a pure function that accepts an ActivityTypeMetadata object and an org configuration record, making org-specific rules data-driven rather than hardcoded. Establish the validation contract in the foundation epic so the service just delegates to the validator.
Contingency: Defer complex cross-flag validation to a lightweight edge function that can be updated without a mobile app release, accepting that initial validation in the mobile service layer is permissive and corrected server-side.
Blindeforbundet users rely on VoiceOver and JAWS. If the selection screen is built with non-semantic widgets that fail accessibility audit late in the sprint, a significant rework of the widget tree may be required, blocking the registration wizard integration.
Mitigation & Contingency
Mitigation: Build the selection screen against the project's established accessibility design tokens and semantics wrapper conventions from the start. Run Flutter's semantic tree inspector and a manual VoiceOver pass before marking any widget task complete.
Contingency: Wrap all tappable items in the project's SemanticsWrapperWidget and schedule a dedicated accessibility review session with a screen reader user from Blindeforbundet before the epic is closed.