Full interaction spec for the Notification Inbox screen — the only fully
implemented screen (plus the shell badge). Shared primitives (text fields,
motion tokens, a11y baseline) live in 00-shared/02,03,08,09; referenced by name.
Max content width 640 dp centered (tablet/desktop).
No separate detail page in v1 — tapping an item marks it read; if data
contains a known route hint ((proposed)data.targetUrl), navigate.
data is the raw event payload (notification.schema.ts:28-29), so v1 never
guesses — unknown payloads only mark read.
First load: GET /api/v1/notifications?page=1&limit=20.
Response envelope: { data: Notification[], meta: PaginationMeta } where
meta = { page, limit, totalItems, totalPages, hasNext, hasPrevious }
(pagination-query.dto.ts:32-39).
Infinite scroll: fetch page+1 when last item enters viewport and
meta.hasNext; append. Footer shows loading spinner; on failure, footer
becomes a retry row (do not clear existing items).
Pull-to-refresh: refetch page 1 and replace the list (keep scroll position
if totalItems unchanged).
Poll vs push: no WebSocket consumer exists in this module (01 §3) — v1
refreshes on foreground + after inbox mutations; (forward-looking) realtime
via WebSocket /ws (END_TO_END_USER_FLOWS.md:773-775).
Count ceiling: display 99+ above 99.
Hide when 0; no badge flash on first open of the session.