high priority low complexity frontend pending frontend specialist Tier 3

Acceptance Criteria

When the Cubit emits OrgSelectionError, an inline error banner or card is shown within OrgSelectionScreen (no modal dialog)
The error message references the name of the org that was tapped (e.g., 'Could not connect to [Org Name]. Please try again.')
Three distinct error messages exist in the localization file: inactive_org_error, network_error, and unreachable_tenant_error
A 'Try again' button is present in the error state and re-emits the SelectOrg event for the same org
A 'Contact support' link is present and opens the device's default email client or a deep-linked support URL
No error string is hardcoded in Dart source — all strings are accessed via the localization delegate (e.g., AppLocalizations.of(context).inactiveOrgError(orgName))
The error state is dismissible: tapping another org card clears the error and begins a new selection attempt
Error text passes WCAG 2.2 AA contrast ratio (minimum 4.5:1 against background)
Screen reader announces the error message automatically when it appears (using Semantics with liveRegion or equivalent)
Widget test confirms the correct localized string is rendered for each error type

Technical Requirements

frameworks
Flutter
flutter_bloc
flutter_localizations
apis
OrgSelectionService (error type discrimination)
data models
OrgSelectionError (errorType enum: inactive, network, unreachable)
Organization (for org name interpolation)
performance requirements
Error state must render within one frame of Cubit emission
security requirements
Error messages must never expose internal server error codes, stack traces, or tenant IDs to the user
Support link must use a hardcoded approved URL or mailto — never constructed from user-supplied input
ui components
Inline error banner widget (e.g., ErrorBanner) with icon, message text, retry button, and support link
Semantics with liveRegion: true for automatic screen reader announcement
TextButton or InkWell for support link

Execution Context

Execution Tier
Tier 3

Tier 3 - 413 tasks

Can start after Tier 2 completes

Implementation Notes

Define a sealed class or enum OrgSelectionErrorType { inactive, network, unreachable } and include it in the OrgSelectionError state alongside the orgName string. In the screen, use a BlocBuilder that switches on errorType to select the correct localization key. Place the error banner at the top of the scrollable content area (below the OnboardingProgressIndicator if present) — not as an overlay. Use Flutter's built-in localization ARB files; add parameterized messages with the org name as a placeholder argument.

For the support link, use url_launcher to open mailto or a web URL. Ensure the Semantics node for the banner has liveRegion: true so TalkBack/VoiceOver reads it without user focus. The retry button should dispatch the same SelectOrg event stored in the error state.

Testing Requirements

Write widget tests for each error type: (1) inactive org shows inactive_org_error string with correct org name interpolated, (2) network failure shows network_error string, (3) unreachable tenant shows unreachable_tenant_error string. Verify: (4) retry button re-triggers selection, (5) support link widget is present and has correct URL, (6) no hardcoded strings exist (grep test). Write Cubit unit test ensuring OrgSelectionError carries the errorType and orgName fields. Use flutter_test with a test localization delegate.

Verify WCAG contrast in design review, not in automated tests.

Epic Risks (2)
low impact high prob technical

OrgSelectionScreen and OrgContextSwitcher render partner-specific logos, colors, and text from dynamic data. Golden tests (pixel-comparison screenshots) will fail whenever branding assets are updated in the backend, causing CI failures that block unrelated PRs and eroding developer trust in the test suite.

Mitigation & Contingency

Mitigation: Use fixture-based golden tests with static mock Organization models containing embedded test assets rather than network-fetched assets. Separate branding asset acceptance tests into a dedicated CI job that only runs on branding-related PRs and is maintained by the design team.

Contingency: If golden test maintenance overhead becomes excessive, replace pixel-comparison goldens with semantic widget tests that assert widget tree structure and key property values, reserving golden tests for only the most stable, design-critical elements.

high impact medium prob scope

Several partner organizations (especially Blindeforbundet) have users who rely entirely on VoiceOver or TalkBack. Complex branded card layouts with overlaid logos, names, and selection states are notoriously difficult to make fully accessible; missing semantics or incorrect focus order could make the selection screen completely unusable for screen reader users before launch.

Mitigation & Contingency

Mitigation: Involve an accessibility specialist in the design review before any widget implementation begins. Use Flutter's Semantics widget with explicit label, hint, and button role on OrgCardWidget. Conduct manual screen reader testing on both iOS (VoiceOver) and Android (TalkBack) for every sprint that touches these screens, not just before release.

Contingency: If full WCAG compliance cannot be achieved within the sprint, implement a simplified text-list fallback mode that activates when the system detects an active screen reader, presenting orgs as plain accessible list tiles instead of the branded card layout.