Dialogs
Confirmation and modal dialogs interrupt the page to ask for a decision or hold a focused task.
Components · Messaging
A dialog sits on a full-screen backdrop and makes the rest of the page inert until it's resolved. Namirial ships two dialog patterns from the same --nm-dialog-* tokens in namirial-theme.css: a compact Confirmation Dialog for yes/no decisions, and a general-purpose Modal Dialog — optionally collapsible — for short focused tasks.
Delete this document?
This action can't be undone.
Overview
Both patterns share the same .nm-dialog card and sit inside a .nm-dialog-backdrop that dims and blocks the page behind them. They differ in scope: a Confirmation Dialog only ever asks for a single yes/no decision; a Modal Dialog can hold any short, focused task.
When to use — Confirmation Dialog
- Before a destructive or hard-to-reverse action (delete, discard, cancel a subscription).
- The decision is binary — proceed or don't — and needs no other input.
When to use — Modal Dialog
- A short, self-contained task that needs the user's full attention (a quick edit form, a single setting, reviewing terms before continuing).
- Content that's too long for a Confirmation Dialog's single description line but still doesn't warrant its own page.
Consider another component when:
Anatomy
Every dialog is a header (icon, title, close), a body, and a footer of actions, floating on a backdrop. Confirmation Dialog indents its body to align with the title, next to the header icon; Modal Dialog does not.
Tokens and values that drive each part
| Part | Role | Source |
|---|---|---|
| Card | Fill | --nm-dialog-bg (fixed, neutral) |
| Card | Border | --nm-dialog-border — recolored per intent |
| Card | Shadow | --nm-dialog-shadow (default), --nm-dialog-shadow-2 (confirmation) |
| Card | Radius / padding / gap | border-radius: 24px · padding: 16px · gap: 24px |
| Title | Color / size | --nm-dialog-fg, 20px / 600 |
| Header icon | Color | --nm-dialog-icon-color — recolored per intent |
| Close / collapse toggle | Color | --nm-dialog-fg, opacity: 0.7 hover / 0.5 active |
| Description | Color / size | --nm-dialog-fg, 16px / 400 |
| Backdrop | Fill | --nm-dialog-backdrop |
Sizes (Modal Dialog)
Modal Dialog scales via max-width, defaulting to md. Confirmation Dialog is fixed at its own 480px max-width and doesn't use these size modifiers.
Intent variants
Both patterns share seven intents that recolor the border and header icon; the card fill always stays neutral (--nm-dialog-bg).
Primary
General-purpose confirmation.
Warning
Flags a caveat before proceeding.
Negative
Confirms a destructive action.
Content types
Confirmation Dialog
Fixed-width, header icon paired with an indented, single-purpose description, and exactly two footer actions — a neutral escape and one committing action.
Delete this document?
This action can't be undone.
Modal Dialog
General body content, no forced indentation, sized to fit what it holds.
Edit display name
This is how your name appears to other users.
Modal Dialog — collapsible
.nm-dialog--collapsible animates its body and footer between shown and .is-collapsed, toggled by .nm-dialog__toggle instead of (or alongside) a close button — useful for "show details" style disclosure inside a modal.
Advanced options
Light & dark theme
--nm-dialog-bg, -fg, -icon-color, and both shadow tokens are explicitly remapped under .dark — the card stays a neutral surface color independent of intent in both themes.
Delete?
Can't be undone.
Delete?
Can't be undone.
Both previews are locked — they don't follow the page theme switcher.
Do & don't
Delete this document?
This can't be undone.
Are you sure?
Do you want to continue?
Edit display name
Shown to other users.
Account settings
A full multi-section settings page doesn't belong stacked inside a modal — give it its own page instead.
Accessibility
Semantics
- Give the card
role="dialog"(orrole="alertdialog"for a Confirmation Dialog on a destructive action),aria-modal="true", and label it witharia-labelledbypointing at.nm-dialog__title. - Describe it with
aria-describedbypointing at.nm-dialog__description.
Focus
- On open, move focus to the dialog — the title, the first focusable element, or the least destructive footer action (never the destructive one by default).
- Trap Tab/Shift+Tab focus inside the dialog while it's open; nothing behind the backdrop should be reachable.
- On close, return focus to whatever triggered the dialog.
Keyboard
Escapecloses the dialog, equivalent to the close button — unless the dialog represents an unsavable, irreversible in-progress action.- Clicking the backdrop should close the dialog the same way
Escapedoes, unless doing so would silently discard unsaved input.
Labeling
- Never make the destructive action the visually dominant one by default focus/color alone — pair it with a clear, specific label.
Token reference
| Token | Role |
|---|---|
| --nm-dialog-bg | Card fill — fixed, not intent-driven |
| --nm-dialog-fg | Title and description text color |
| --nm-dialog-border | Card border — recolored per intent |
| --nm-dialog-icon-color | Header icon color — recolored per intent |
| --nm-dialog-shadow | Shadow — Confirmation Dialog |
| --nm-dialog-shadow-2 | Shadow — Modal Dialog (default) |
| --nm-dialog-backdrop | Backdrop fill |
Implementation
Open/close state, focus trapping, and backdrop click handling need JavaScript (or the native <dialog> element); the card and backdrop themselves are pure CSS.
<link rel="stylesheet" href="namirial-theme.css">
<div class="nm-dialog-backdrop">
<div class="nm-dialog nm-dialog--confirmation nm-dialog--negative" role="alertdialog" aria-modal="true" aria-labelledby="dlg-title" aria-describedby="dlg-desc">
<div class="nm-dialog__header">
<span class="nm-dialog__header-icon" aria-hidden="true"><!-- icon --></span>
<h3 class="nm-dialog__title" id="dlg-title">Delete this document?</h3>
</div>
<div class="nm-dialog__body">
<p class="nm-dialog__description" id="dlg-desc">This action can't be undone.</p>
</div>
<div class="nm-dialog__footer">
<button type="button" class="nm-button nm-button--secondary nm-button--md nm-button--ghost">Cancel</button>
<button type="button" class="nm-button nm-button--negative nm-button--md">Delete</button>
</div>
</div>
</div>CSS classes
| Class | Values | Default |
|---|---|---|
nm-dialog--{size} | xs · sm · md · lg · xl — omit for the md default (Modal Dialog only) | — (md) |
nm-dialog--confirmation | Fixed-width Confirmation Dialog layout, indented body | — |
nm-dialog--collapsible + .is-collapsed | Animates body/footer open/closed | — |
nm-dialog--{intent} | primary · secondary · accent · info · positive · negative · warning | — |
nm-dialog__close / nm-dialog__toggle | Close button / collapse toggle, 24×24px | — |
nm-dialog-backdrop | Full-screen dimmed backdrop wrapping the card | — |