Completes 1908 without Web Push. While the app is open, due reminders now
actually surface; recurring reminders + snooze/done are manageable.
- reminders store (singleton): polls /api/notes/reminders every 45s while
the app is open; each due reminder fires ONCE as a toast (with an "Open"
action) and, if the user opts in, a page-context OS Notification — no
service worker, no PWA. Silently primes a stale backlog on first load;
only announces recently-due ones. AppShell starts/stops it.
- Editor reminder section: a Repeat picker (Does not repeat / Daily /
Weekly / Monthly / Yearly) + Done (advances a recurring reminder / clears
a one-off) + Snooze 1h/1d, shown when a reminder is set.
- RemindersView rebuilt as a chronological list: per row a due time +
recurrence badge + Done / 1h / 1d, click to open; plus an "Enable
notifications" opt-in and a note that background alerts come with native.
- Note type gains `recurrence`; notes store setRecurrence /
completeReminder / snoozeReminder.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm
Each data view now catches a failed load and shows an explicit error message
with a Retry button, instead of falling through to a misleading empty state.
Pairs with the global error toast: the toast says something failed, the view
says which and offers a retry.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm