Design System

Notifications

How the system announces change.

The system has four notification primitives, each with a locked anatomy and attention budget.

TOAST · transient · auto-dismiss 6s MISSION SYNCED 12 track updates pushed to GRIDWATCH-04. ! SYNC FAILED Connection to theater-04 lost. Retrying… BANNER · persistent · sits below top nav SCHEDULED MAINTENANCE Theater sync enters maintenance window 22:00Z - 23:00Z. Write operations will be queued and replayed on resume. × CALLOUT · inline · part of the page flow TRAINING CONSTRUCT Adversary orders of battle and territorial state in this scenario are synthetic. Not drawn from live operational reporting or cleared intelligence products. DIALOG · modal · destructive confirmation ! Terminate BLU-2? This ends active overwatch. Cannot be undone. CANCEL TERMINATE

The hierarchy

Four tiers, in descending order of persistence and ascending order of attention demanded:

Tier Primitive Persistence Use when…
Classification strip fdt-classification Always visible It’s the classification / security context of the surface itself. Structural, not notifying. See FDT-specific primitives.
Banner wa-callout Stays until resolved or dismissed Persistent information applies to the current surface - “You’re viewing read-only data from a snapshot,” “Sync is delayed, last update 14:23Z”
Toast wa-toast Ephemeral, auto-dismisses Confirmation of a user action - “Mission saved,” “Track classified as hostile”
Alert / Dialog wa-dialog Blocks interaction until resolved Requires user decision - “Discard changes?”, “Confirm termination?”

The rule for picking one: match the persistence to the information. Ephemeral action feedback is a toast. Persistent surface-state information is a banner. Required decision is a dialog.

Severity mapping

All four tiers share the same severity palette, driven by the same semantic tokens:

Severity Color Use
Info / brand electric-500 / electric-400 text Neutral informational - “System updated to v1.2.3”
Success neutral User action completed - “Mission saved”
Caution caution Recoverable warning - “Sync is slower than usual”
Danger hostile / hostile-400 text Action failed or critical condition - “Request denied: insufficient clearance”

The severity determines the left border color on banners, the icon color on toasts, and the primary button variant on dialogs. Severity is also announced via ARIA live regions (aria-live="polite" for info/success, aria-live="assertive" for caution/danger).

Toast

Ephemeral confirmations of user actions. Toasts announce that something the user did succeeded, failed, or produced a recoverable condition.

Anatomy

  • Position: bottom-right on desktop, bottom-center on mobile
  • Width: 320–480px
  • Icon: FA Sharp Regular, 16px, in semantic color
  • Message: Inter 500 13px, fog-100, one line preferred, two maximum
  • Dismiss control: xmark icon top-right, 12px, steel-300
  • Optional action: one text button right-aligned, Inter 500 13px, electric-400 - e.g., Undo

Stacking

  • Maximum 3 toasts visible at a time. Newest at the top of the stack.
  • A fourth toast replaces the oldest (first-in-first-out).
  • Stack spacing: 8px between toasts.

Dismissal timing

Severity Auto-dismiss after
Info / success 5 seconds
Caution 8 seconds
Danger Never - manual dismiss only

Danger toasts require the operator to see and acknowledge them. An auto-dismissing “Request denied” toast is worse than useless.

Never use a toast for

  • Information the operator must act on (use a dialog or banner)
  • Confirmation of passive actions the user already saw happen (field saves, menu opens) - the UI already shows the outcome
  • Multi-line explanations (toast is a headline, not an article)

Persistent surface-level information. Banners stay visible as long as the condition they describe is active.

Anatomy

  • Position: top of the main content area, directly below the classification strip if one is present
  • Width: full width of the content area
  • Left border: 3px in semantic color
  • Background: navy-800, 1px navy-600 border on the non-accent sides
  • Icon: 16px semantic color, top-aligned left
  • Content: Inter 400 14px, fog-200, up to 3 lines
  • Optional primary action: inline wa-button on the right of the banner - e.g., Refresh data
  • Dismiss control: xmark icon far-right, only when the banner is dismissible (non-critical banners). Critical banners (security notices, data-integrity warnings) are not dismissible until the condition resolves.

Stacking

  • Maximum 2 banners visible at a time. If more conditions apply, consolidate into one banner or let the most critical take the slot.
  • Banners stack vertically with 8px gap, highest-severity on top.

Never use a banner for

  • Fleeting confirmations (use a toast)
  • Required decisions (use a dialog)
  • Dense dashboards where the banner would compete with data content - if the surface is packed, the banner should probably be a toast with a persistent status indicator

Alert / Dialog

Blocks the surface until the operator makes a decision. Used for destructive actions, permission requests, unsaved changes warnings, confirmation of irreversible operations.

Anatomy (wa-dialog)

  • Overlay: navy-900 at 70% opacity behind the dialog
  • Dialog: navy-800 background, navy-600 1px border, --fdt-glow-lg halo, 4px border radius
  • Width: 480px standard, 640px for dialogs with form content, 320px for terse confirmations (all responsive down to mobile full-width minus 32px)
  • Title: H3, Inter 600 16px, fog-100
  • Body: Inter 400 14px, fog-200, describes the action and its consequences
  • Actions: right-aligned at the bottom, horizontal row. Minimum one action. Destructive actions use danger variant with an action-named label (“Terminate program,” not “OK”). Cancel / non-destructive options use neutral plain.

Rules

  • Always at least one action. A dialog with no action is a banner.
  • Never dismiss by clicking outside. Require an explicit action - clicking outside closes consumer dialogs, but operator dialogs protect against accidental decisions.
  • Keyboard: Esc cancels (triggers the secondary / cancel action), Enter confirms the primary action.
  • Never auto-dismiss. Dialogs wait for the operator.
  • Never more than one dialog at a time. If a second dialog would appear, queue it behind the first - never stack.

Destructive dialog pattern

Title:   Terminate program?
Body:    This will stop all in-flight operations for PROGRAM-23-ALPHA
         and archive the workspace. This cannot be undone.
Actions: [Cancel]  [Terminate program]
                   ^ danger variant

The destructive action button carries the action name, not “OK.” The operator’s last read before clicking is what they’re about to do, not an affirmation.

ARIA and screen readers

  • Toasts: wrapped in role="status" (info/success) or role="alert" (caution/danger), with aria-live matching the severity
  • Banners: the container has role="region" with aria-label describing the banner’s purpose
  • Dialogs: wa-dialog handles role="dialog", aria-modal="true", and focus trapping automatically. The dialog title is the accessible name.
  • Announce timing: severity determines urgency - aria-live="polite" for info/success (doesn’t interrupt), aria-live="assertive" for caution/danger (interrupts current announcement)

Anti-patterns

  • Toasts for critical information. They disappear. If the operator looks away for 5 seconds, it’s gone.
  • Multiple simultaneous dialogs. Stack-overflow of user decisions. Queue or consolidate.
  • Banners in dense dashboards. They compete with the data content. Use a persistent status indicator in the header instead.
  • Toasts that acknowledge expected behavior. “Clicked a button,” “Saved a field,” “Navigated to a page” - if the UI already visibly changed, the toast is noise.
  • Classification strips used as notifications. They’re structural and always present - not a signal of change. If you need to signal a classification change, use a banner with the classification change as the content.
  • Dialogs for informational messages. If no decision is required, it’s a banner (persistent info) or toast (ephemeral). Dialogs are for decisions.
  • “X” close button as the only action on a dialog. Every dialog has at least one labeled action button.
  • Ambiguous action names. OK, Submit, Yes, Confirm don’t describe what happens. Use Terminate program, Delete user, Revoke access, Save draft - the button label is what the operator reads before clicking.