# TASK 24 — Toast notifications (in-app, non-blocking) > Catalog: [`TASKS.md`](../TASKS.md) — status and requirements live here. ### Status: ✅ Done (shipped 2026-08-23, branch `task24-notifications`) Replace blocking MessageBoxes with in-window toasts; promote actionable log-only failures. ### Requirements: 1. Library: **Notification.Wpf 11.0.0** (Platonenkov fork of Federerer/Notifications.Wpf) — MIT, active, targets net8.0-windows. Notice #10 added to `THIRD-PARTY-NOTICES.txt`. 2. Placement: bottom-right above the footer (`NotificationArea x:Name="ToastArea"`, last child of MainWindow's root grid → topmost z-order, `Grid.RowSpan=4`, `Margin="0,0,12,96"`, outside the preview Viewbox), max 4 stacked. 3. Behavior: Info ~4s / Success ~4s / Warning ~8s auto-dismiss; **Error sticky until dismissed**. 4. Styling: dark card tints matching the health-banner language (slate `#3a3b52` info, green `#1d5c38` success, amber `#b8860b` warning, dark-red `#8f1f1f` error); corner radius 8; keep-visible-on-hover. 5. Threading: all Show calls marshal via a Dispatcher captured at construction (encoder/pump events fire off-thread). ### Migrations (MessageBox → toast): - Webcam acquire failure ×2 (`AddWebcamToStagedSceneAsync`, `SwapWebcamIdentityAsync`) → Warning - Image read failure (`PickImageBytes`) → Warning - Sign-in unsuccessful → Warning; sign-in failed → Error ### Promotions (log-only → toast, each keeps its AppLog line): - Go-live prep ×3: reusable stream unavailable / broadcast insert failed / prep exception → Error - Frame-pump death while live (`OnFramePumpFailed`) → Error - Mic missing at startup (`StartMicCaptureAsync`) → Warning (once) - Premium lapse at startup re-validation → Warning - Saved-session refresh failure (signed out notice) → Info Deliberately left alone: offline license re-validation skip (log-only — would spam every launch); SocialsDialog slot-delete YesNo confirm (stays modal). ### Tests: - Unit: pure severity→request mapping (`NotificationServiceTests`) — area routing, lifetimes, tints. - Integration (the ONE): real window-hosted `ToastArea` + real service — Info auto-dismisses, Error sticks (`NotificationAreaIntegrationTests`, RealApp collection). ### Library facts (cost a hunt — see also ai.md): - Area routing matches the area's XAML `Name` against the request's `AreaName`; unknown name silently drops. - `NeverExpires()` = `ExpirationTime = TimeSpan.MaxValue` (not null); `NotificationColor.ToHex()` returns `#AARRGGBB`. - Overlay-window shutdown caveat avoided entirely by using the in-window area mode.