critical priority low complexity frontend pending frontend specialist Tier 0

Acceptance Criteria

File `lib/features/no_access/presentation/no_access_screen.dart` exists and exports `NoAccessScreen`
`NoAccessScreen` is a `StatelessWidget` (or `ConsumerWidget` if Riverpod state is anticipated in subsequent tasks) with a `build` method returning a `Scaffold`
The `Scaffold` body is wrapped in a `SafeArea` widget to respect device notches and system UI
The screen is registered as a named route (e.g., `/no-access`) in the app's router configuration (GoRouter or equivalent)
Navigation to `/no-access` is possible from the auth flow when a user's role does not permit access
The screen has no back navigation affordance (bottom nav hidden, app bar omitted or back button suppressed) as it is a terminal route
A placeholder `Column` with a `Text('No Access')` body exists so the screen renders without errors during development
`flutter analyze` passes with zero issues on the new file
Hot reload shows the placeholder screen when navigating to the route manually

Technical Requirements

frameworks
Flutter
Riverpod (if using ConsumerWidget)
GoRouter or auto_route
performance requirements
Screen renders first frame in under 16ms (one frame at 60 fps)—no heavy computation in build method
security requirements
Route must not be accessible by users who DO have valid access—router guard must redirect them away
No sensitive data (user PII, role details) rendered in the placeholder to avoid accidental exposure during development
ui components
Scaffold
SafeArea
Column (placeholder)

Execution Context

Execution Tier
Tier 0

Tier 0 - 440 tasks

Implementation Notes

Start with `StatelessWidget` and convert to `ConsumerWidget` only when reactive state (BLoC or Riverpod provider) is needed in a later task—do not pre-optimise. Use the project's existing `AppScaffold` or `PageHeader` wrapper if one exists (check `lib/core/widgets/`) to maintain nav-bar suppression and safe-area handling consistently across screens. In the router, set `fullscreenDialog: false` and do not provide a `parentNavigatorKey` that includes the bottom nav shell route—this ensures the bottom navigation bar is not rendered on this terminal screen. Add a `// TODO(epic-no-access-screen-ui): replace placeholder with full content` comment in the build method body so subsequent task assignees know exactly where to add their work.

Follow the role-based access control pattern already in place for the existing no-access screen referenced in the app architecture section.

Testing Requirements

Widget test in `test/features/no_access/presentation/no_access_screen_test.dart`. Pump the widget inside a `MaterialApp` (or `ProviderScope` + `MaterialApp` for Riverpod). Assert: (1) `find.byType(Scaffold)` finds exactly one widget; (2) `find.byType(SafeArea)` finds exactly one widget; (3) no `FlutterError` is thrown during pump. Add a router test asserting that navigating to the `/no-access` path resolves to `NoAccessScreen`.

These tests should remain green throughout the UI epic as subsequent tasks add content to the scaffold.

Component
No-Access Screen
ui low
Epic Risks (2)
medium impact medium prob technical

Flutter's live region (SemanticsProperties.liveRegion) announcement may be delayed or swallowed by the OS accessibility engine if the Semantics tree is not fully built when the screen mounts, causing screen-reader users to miss the denial announcement.

Mitigation & Contingency

Mitigation: Trigger the live region announcement from a post-frame callback (WidgetsBinding.addPostFrameCallback) to ensure the Semantics tree is committed before the announcement fires. Test on both VoiceOver (iOS) and TalkBack (Android) physical devices.

Contingency: If live region timing is unreliable, fall back to using SemanticsService.announce() directly in the initState post-frame callback, which provides more deterministic announcement timing.

low impact low prob scope

The organisation logo may fail to load (network error, missing asset) leaving a broken image in an otherwise functional screen, degrading the professional appearance and potentially confusing users.

Mitigation & Contingency

Mitigation: Wrap the logo widget in an error builder that renders a styled fallback (organisation name text or a generic icon) when the logo asset or network image fails to load.

Contingency: If logo loading is persistently unreliable across organisations, remove the logo from the no-access screen entirely in favour of a text-only header using the organisation's display name from the design token system.