# Modals Overlaid surfaces that interrupt the user — dialogs, confirmations, sheets, drawers. Built on `base-ui` / Radix primitives in the product family (`kdcvault/frontend/src/components/ui/dialog.tsx`, `sheet.tsx`). ## Anatomy See `anatomy.svg`. Backdrop · panel · header (title + close) · body · footer (actions, right-aligned). ## Variants | Token | Use | Width | Position | |-------|-----|-------|----------| | `modal.default` | Confirmations, forms (≤ 5 fields) | 480px | centered | | `modal.wide` | Multi-step wizards, content browsers | 720px | centered | | `modal.sheet` | Slide-in side panel (editing, filters) | 420px | right edge | | `modal.drawer` | Bottom sheet (mobile) | 100% | bottom edge | | `modal.fullscreen` | Immersive flows | 100% | full viewport | ## Tokens & layout - Radius `rounded.xl` (16px); sheet variants use `rounded.lg` on inner edge only. - Background `surface.background`; backdrop `rgba(26,21,48,0.45)`. - Shadow `elevation.4` (`0 24px 80px -24px rgba(26,21,48,0.22)`). - Padding 24px; footer separated by `1px border.default` top edge. - Open animation: `kdc-fade-up` (360ms cubic-bezier, `translateY(6px)` → 0). ## Accessibility - `role="dialog"` (or `alertdialog` for destructive confirmations) with `aria-labelledby` / `aria-describedby`. - Trap focus inside the modal; first focusable element receives focus on open. - Close on `Esc`; restore focus to the trigger element on close. - Backdrop click closes only non-destructive modals; confirmations require explicit action. - Disable body scroll while open. ## Do / Don't - ✅ Right-align primary action in the footer (`primary` or `accent`); secondary / cancel on the left. - ✅ Use a `sheet` for editing context that benefits from staying tethered to a list. - ❌ Don't stack modals — open a `sheet` from inside a modal instead. - ❌ Don't put more than one CTA in a single modal footer.