high priority low complexity frontend pending frontend specialist Tier 2

Acceptance Criteria

Every tappable element across SearchScreen, AccessibleSearchInputField, and SearchResultsList has a minimum hit-test area of 44×44 dp (logical pixels)
Elements that are visually smaller than 44×44 dp are wrapped with the accessible-touch-target-wrapper without altering their visual appearance
Tab/focus order follows reading order: search field → clear button → microphone button → first result card → second result card → ...
No focus trap exists anywhere in the search flow: pressing Tab (or Switch Access next) always moves focus forward and eventually reaches the bottom nav
Pressing the hardware back button (Android) or swipe-back (iOS) from SearchScreen returns focus to the previously focused element in the Contacts tab
Switch Access scanning highlights each interactive element in the correct order
FocusTraversalGroup is applied at the SearchScreen level with OrderedTraversalPolicy or ReadingOrderTraversalPolicy
A flutter_test semantic test enumerates all SemanticsNode tap actions and asserts each has a rect of at least 44×44 dp

Technical Requirements

frameworks
Flutter
flutter_test
apis
Flutter FocusTraversalGroup
Flutter Semantics API
accessible-touch-target-wrapper component
performance requirements
Touch target wrappers must not introduce extra layout passes; use SizedBox or ConstrainedBox with GestureDetector rather than nested InkWell layers
ui components
SearchScreen
AccessibleSearchInputField
SearchResultsList
accessible-touch-target-wrapper

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

Start with a systematic audit: list every widget with an InkWell, GestureDetector, IconButton, or TextButton, then measure its render size with Flutter DevTools Widget Inspector. Prioritize the clear button and microphone button in the search field — these are the most likely offenders. The accessible-touch-target-wrapper should use a transparent overlay with the same onTap callback, keeping the visual size unchanged (use Stack + Positioned or ConstrainedBox). For FocusTraversalGroup, wrap the entire SearchScreen body and use ReadingOrderTraversalPolicy as the default — only override with OrdinalSortKey if reading order diverges from visual order in a specific sub-section.

Document every element that was below 44×44 dp before the fix in a comment next to the wrapper so future developers understand why the wrapper is there.

Testing Requirements

Widget test using SemanticsController: iterate all nodes with hasTapAction, assert each has size >= Size(44, 44). Widget test: verify FocusTraversalGroup wraps SearchScreen and that FocusTraversalOrder matches expected reading order. Manual test checklist: (1) physical iOS device with VoiceOver swipe navigation — confirm order, (2) physical Android device with Switch Access — confirm scanning order, (3) external Bluetooth keyboard Tab navigation on both platforms. All manual test results must be documented in the PR description.

Component
Contact Search Screen
ui low
Epic Risks (2)
medium impact medium prob technical

Flutter's Semantics live region support for announcing dynamic result count changes may behave inconsistently between VoiceOver (iOS) and TalkBack (Android), particularly regarding announcement throttling and focus management, causing the feature to pass testing on one platform and fail on the other.

Mitigation & Contingency

Mitigation: Test live region announcements on both iOS (VoiceOver) and Android (TalkBack) early in development using the existing accessibility test harness. Reference the existing LiveRegionAnnouncer component (608-live-region-announcer) patterns used elsewhere in the app.

Contingency: If cross-platform consistency cannot be achieved, implement a platform-specific announcement strategy using the SemanticsService.announce API with platform-conditional announcement timing to work around OS-specific throttling behaviour.

low impact low prob dependency

Voice-to-text progressive enhancement for Blindeforbundet may not be available or may behave unpredictably on all device/OS combinations, particularly older Android devices, potentially causing crashes or silent failures that degrade the search experience.

Mitigation & Contingency

Mitigation: Implement voice-to-text as a strictly optional enhancement: detect availability at runtime, show the microphone button only when the platform speech API reports availability, and wrap all voice invocations in try/catch with graceful degradation to standard text input.

Contingency: If voice-to-text causes instability on a subset of devices discovered during TestFlight/beta, disable the feature flag for that platform version while a fix is investigated, without impacting the core text-based search functionality.