high priority medium complexity frontend pending frontend specialist Tier 2

Acceptance Criteria

Each bottom navigation tab announces its position as 'Tab N of 5' when focused by a screen reader on both iOS (VoiceOver) and Android (TalkBack)
Tab labels are announced in the order they appear visually, matching the StatefulShellRoute tab order (Home, Contacts, Add, Work, Notifications)
Semantics.indexInGroup is set correctly on each tab item so that screen readers report the correct ordinal position within the navigation group
OrdinalSortKey or CustomSortKey is applied so that focus traversal order matches visual left-to-right order regardless of widget insertion order
The active tab is announced with a selected/checked state in addition to its positional label
No duplicate or extraneous semantic nodes are exposed for decoration icons inside tab items
Position announcement persists correctly when the tab count changes (e.g., org-specific navigation variants with fewer tabs)
Screen reader focus does not jump unexpectedly when switching tabs programmatically

Technical Requirements

frameworks
Flutter
flutter_test
performance requirements
Semantics tree updates must complete within one frame (16 ms) to avoid perceptible focus lag
No additional widget rebuilds triggered solely by semantics annotation changes
ui components
AccessibleBottomNavigation
Semantics widget (indexInGroup, sortKey, label, selected)
MergeSemantics / ExcludeSemantics for icon decorations
StatefulShellRoute bottom nav host

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

Wrap each BottomNavigationBarItem content in a Semantics widget with `indexInGroup` set to the 1-based tab index and `label` composed as '${tabLabel}, Tab ${index} of ${total}'. Use `sortKey: OrdinalSortKey(index.toDouble())` to guarantee traversal order. Set `selected: isActive` to expose active state. Use `ExcludeSemantics` around purely decorative badge indicators or notification dots that should not be separately announced.

Retrieve the total tab count from the same list that drives the navigation so it stays in sync automatically. Be cautious about double-announcing the label — if the parent NavigationBar already exposes a label, merge the nodes rather than nesting two Semantics widgets. Test with `flutter run --profile` and the Accessibility Scanner (Android) and Accessibility Inspector (iOS Simulator) to verify the full announcement string before submitting.

Testing Requirements

Write flutter_test widget tests that pump the AccessibleBottomNavigation widget with 5 tabs and assert that each tab's SemanticsNode carries the correct label including positional text, the correct indexInGroup value, and a selected flag on the active tab. Use tester.getSemantics() and SemanticsController to traverse the semantics tree. Add integration tests on a physical device or emulator using the accessibility inspector to confirm VoiceOver and TalkBack behaviour. Cover the edge case where tabs are re-ordered or an org variant uses fewer than 5 tabs.

Aim for 100% branch coverage of the positional-label generation logic.

Component
Accessible Bottom Navigation
ui high
Epic Risks (3)
high impact high prob integration

Flutter does not natively enforce a focus trap within a bottom sheet or modal dialog in the semantic tree — VoiceOver and TalkBack can navigate outside the sheet to background content. Implementing a reliable focus trap requires overriding the semantic tree, which may conflict with the existing modal helper infrastructure in the app and require changes to shared components beyond this feature's scope.

Mitigation & Contingency

Mitigation: Prototype the focus trap on the first modal sheet implementation before building the remaining sheets. Evaluate Flutter's ExcludeSemantics and BlockSemantics widgets as the trap mechanism, and coordinate with the team owning the shared modal helpers to agree on a non-breaking integration point before writing production code.

Contingency: If a complete semantic focus trap cannot be implemented without breaking existing modal patterns, implement a partial solution using FocusScope with autofocus on the modal's first element and a prominent 'Return to main content' semantic action, documenting the deviation from WCAG 2.4.3 with a scheduled remediation item.

high impact medium prob technical

The activity wizard uses BLoC state management and the UI rebuilds the entire step widget subtree on transition. If the semantic tree is traversed by VoiceOver before the build cycle settles, focus may land on a stale or partially rendered step, causing the wrong step label or progress value to be announced. This is particularly problematic for blind users who cannot visually verify the announcement against the screen.

Mitigation & Contingency

Mitigation: Coordinate ActivityWizardStepSemantics with FocusManagementService (from the core services epic) to delay focus placement until the post-build callback confirms the new step's semantic tree is complete. Write integration tests using the AccessibilityTestHarness that assert the full announcement sequence across all five wizard steps.

Contingency: If post-build focus delay is insufficient due to async BLoC emission timing, add an explicit semantic notification barrier in the wizard cubit that emits a 'step ready' event only after the new widget tree has been marked as built, decoupling the announcement trigger from the raw state transition.

medium impact medium prob scope

Automated WCAG contrast ratio checking on widget tree snapshots may produce false positives for gradient backgrounds, dark-mode overrides, or design token overrides that are resolved at runtime but appear as unresolvable colours at static analysis time. Excessive false positives would erode team trust in the CI gate, leading to suppression rules that also mask real violations.

Mitigation & Contingency

Mitigation: Scope the WCAGComplianceChecker to check only solid-colour backgrounds in the first iteration, explicitly excluding gradients from contrast checks with documented rationale. Design the check output to distinguish 'undetermined' (gradient/unknown) from 'fail' (solid colour below threshold) so the team can take targeted action on genuine failures only.

Contingency: If false positive rates exceed 20% of reported violations during initial CI runs, switch the CI gate from a hard build failure to a warning annotation on the pull request, combined with a mandatory manual review step, until the checker's rule set has been tuned to match actual design token values.