high priority low complexity frontend pending frontend specialist Tier 0

Acceptance Criteria

A new Dart file exists at the correct path (e.g., lib/features/notifications/preferences/notification_preferences_screen.dart) exporting a NotificationPreferencesScreen widget
The screen renders an AppBar with the correct localised title (Norwegian: 'Varslingsinnstillinger', English: 'Notification preferences')
The screen body is a SingleChildScrollView containing a Column — vertical scrolling works on a device with a small screen height
At least two named section groupings are present in the layout (e.g., 'Scenario notifications', 'General') with section header labels using the correct design token typography style
All spacing values (padding, margin, gap between sections) use design token constants — no hardcoded pixel values
All colour values use design token constants — no hardcoded hex or Color() literals
The screen is registered as a named route in the app's route configuration (go_router or Navigator 2.0) and can be navigated to by its route name without errors
The screen is reachable from the Settings screen via a tap on a 'Notification preferences' menu item
Running `flutter test` on a basic widget test that pumps NotificationPreferencesScreen passes — screen renders without overflow or exception
The scaffold compiles without warnings with `flutter analyze`

Technical Requirements

frameworks
Flutter
Riverpod or BLoC (for future state wiring, scaffold should be provider-ready)
data models
AppRoute enum or route name constants (for route registration)
performance requirements
Screen must render first frame in under 16ms on a mid-range device (no expensive build-time computations)
No unnecessary rebuilds — use const constructors for all static widgets
security requirements
No user preference data is read or written in this scaffold task — state wiring is out of scope
ui components
AppBar (existing shared widget or Material AppBar with design token styling)
SingleChildScrollView
Column with section grouping
Section header label widget (text using design token typography)
Placeholder ListTile or container for future toggle items

Execution Context

Execution Tier
Tier 0

Tier 0 - 440 tasks

Implementation Notes

Follow the existing screen file structure already established in the project (e.g., lib/features/settings/settings_screen.dart as a reference). Use the project's design token constants (AppSpacing, AppColors, AppTypography or equivalent) — do not introduce new constants for this screen. Register the route in the same place all other routes are registered — do not create a new routing file. Keep the screen stateless for now (StatelessWidget) — state management will be added in the next task.

Use const where possible on all static children. Section grouping can be a simple Padding + Text header above a Card or a simple Container — match the visual pattern of existing settings sections in the app.

Testing Requirements

Write one basic widget test that pumps NotificationPreferencesScreen inside a MaterialApp with the app's theme and verifies: (1) the AppBar title text is present, (2) the section header labels are present, (3) no RenderFlex overflow errors are thrown on a 320x568 viewport (smallest common iPhone size). No BLoC/Riverpod mocks needed for this scaffold task. Run `flutter analyze` and ensure zero warnings before marking the task done.

Epic Risks (2)
medium impact medium prob technical

The in-app notification banner depends on a Supabase Realtime subscription to detect new notification records. If the subscription reconnects slowly after an app resume from background, or if Realtime delivery is delayed under high load, the banner may not appear within the 2-second acceptance criterion.

Mitigation & Contingency

Mitigation: Implement an explicit subscription reconnect handler on app foreground events using Flutter's AppLifecycleState.resumed hook, and add a polling fallback that queries for unread notifications once per app foreground event as a safety net against missed Realtime events.

Contingency: If Realtime proves unreliable in production, promote the polling fallback to the primary mechanism with a 30-second interval, accepting slight latency in exchange for reliability.

medium impact medium prob technical

Cold-start deep linking (app not running when push notification is tapped) requires deferred navigation after the Flutter engine and Supabase session are fully initialised. If the deep link is consumed before authentication completes, the router may navigate to a protected route without a valid session, causing an error or redirect loop.

Mitigation & Contingency

Mitigation: Implement a deferred navigation queue in scenario-deep-link-router that holds the parsed deep-link target until the auth session restoration lifecycle event fires, following the existing deep-link-handler pattern used in the BankID and Vipps authentication flows.

Contingency: If deferred navigation is not achievable within the epic's scope, fall back to navigating the user to the notification centre (which is always accessible post-login) where the relevant notification record is visible and tappable.