Stage 1's later screens and modules need the interactions DESIGN.md
fixes once for the product (ADR 0059). @ekklesia/ui gains them,
additively:
- ConfirmationDialog: simple, destructive, or typed-phrase
confirmation, with severity chosen by the caller. Destructive is
marked by symbol and frame, not colour alone, and starts on Cancel.
A required phrase must match exactly (forgiving only surrounding
whitespace and NFC). While busy, Cancel and Escape are disabled.
- ToastProvider / useToasts: a top-center toast system per React tree,
never a package singleton (ADR 0040). Live regions are mounted
before any toast arrives; errors are assertive and persist until
dismissed; routine toasts last at least three seconds and longer for
longer text. Timers pause on hover and focus; duplicates refresh;
errors are never displaced; every timer is cleared on unmount.
- ErrorState: recovery actions, plus collapsed technical details and a
reference, rendered as bounded inert text.
- Skeleton / SkeletonGroup: an aria-busy region labelled once, with
every animation stopped under prefers-reduced-motion.
- PageHeader `back` (link or button) above the page's one h1.
- Dialog: the focus trap ADR 0039 deferred, plus focus restoration and
an accessible description. Escape is now handled on the dialog
itself, so a drawer it was opened from stays open.
The shell validates Back targets (parseReturnTarget, dashboardBack):
only a canonical Dashboard page on this origin is accepted, otherwise
Back goes to the page's parent. It never uses history.back().
Biome's scope-aware suspicious/noAlert is now an error in the root
biome.json. tests/native-dialogs.test.ts proves it catches real
dialogs and not lookalikes, and scans for the forms the rule misses.
It supersedes the shell-only regex test.
Co-Authored-By: Claude Opus 5.5 <[email protected]>