Messaging

Toast

Toasts are transient, self-dismissing notifications that confirm an action without demanding attention.

Components · Messaging

A toast is a floating notification that appears in response to an action, stays for a short time, and disappears on its own. Namirial toasts are built from --nm-toast-* tokens defined in namirial-theme.css, default to the primary intent, and can optionally carry action buttons that recolor to match the toast's intent.

Invoice sentYour client will receive it shortly.

Overview

A toast confirms that something just happened — a save, a send, an undo window — without interrupting the user's flow. It appears near a screen edge (commonly bottom-right), stacks with other toasts, and dismisses itself after a few seconds or when the user closes it.

When to use

Use a toast when:

  • You need to confirm the result of an action the user just took, and the confirmation doesn't need to persist.
  • The notification is independent of scroll position — it should stay visible even if the triggering element scrolls out of view.

Consider another component when:

  • The information must stay visible until the user acts on it — use Alert.
  • The feedback is tied to a specific spot in the layout rather than floating at a screen edge — use Message.
  • The action needs explicit confirmation before it happens (not after) — use a Confirmation Dialog.

Anatomy

A toast is an icon, a title + body text stack, a close button, and an optional row of action buttons.

Tokens and values that drive each part

PartRoleSource
ContainerFill--nm-toast-bg
ContainerBorder--nm-toast-border
ContainerShadow--nm-toast-shadow — 0 4px 16px
ContainerRadius / padding / gapborder-radius: 24px · padding: 16px · gap: 24px
ContainerSize boundmax-width: 480px
IconColor--nm-toast-fg
TitleColor / size--nm-toast-fg, 20px / 600
BodyColor / size--nm-toast-fg, 16px / 400
CloseColor--nm-toast-fg, opacity: 0.7 hover / 0.5 active
Ghost-secondary action buttonColor--nm-button-ghost-{intent}-fg — matches the toast's intent

Intent variants

Toast ships seven intents, defaulting to primary. Every part of the card — background, border, text, and icon — recolors together, and any nm-button--ghost.nm-button--secondary action inside picks up the matching button palette.

PrimaryGeneral confirmation.
InfoNeutral update.
PositiveAction succeeded.
WarningCompleted with caveats.
NegativeAction failed.

Content types

With actions

Invoice sentDelivered to client.

Without actions

CopiedLink copied to clipboard.

Light & dark theme

Only the toast's shadow is remapped under .dark — its background, border, and text already come from the intent-driven --palette-callout-alt-* scale.

Light data-theme="light"
Invoice sentDelivered to client.
Dark data-theme="dark"
Invoice sentDelivered to client.

Both previews are locked — they don't follow the page theme switcher.

Do & don't

✓Do
SavedYour changes are safe.
Keep the message short — a toast is glanced at, not read closely.
✕Don't
Your changes have been savedAll fields you edited in this form, including the attached documents and their metadata, have been persisted to the server.
Don't use a toast for content that needs to be read carefully — use Alert or Message instead.
✓Do
Upload failedCheck your connection and retry.
Give a failure toast a way to recover — a Retry action, when one makes sense.
✕Don't
Upload failed
Don't let a critical failure disappear on a timer with no way to act on it — use a persistent Alert instead.

Accessibility

Semantics

  • Render the toast region with role="status" (aria-live="polite") for routine confirmations, or role="alert" (aria-live="assertive") for failures that need immediate attention.
  • Mark the icon aria-hidden="true".

Timing & dismissal

  • Give the user enough time to read the message before auto-dismissing — don't use a fixed short timer regardless of content length; pause the timer on hover/focus.
  • Always provide a manual close button in addition to any auto-dismiss timer — some users need more time or use assistive tech that doesn't race the clock.

Focus

  • A toast must never steal keyboard focus on appearance — it's a passive notification, not an interruption.
  • Any action button inside it must still be reachable by keyboard for users who choose to engage with it.

Token reference

TokenRole
--nm-toast-bgContainer fill — recolored per intent
--nm-toast-borderContainer border — recolored per intent
--nm-toast-fgIcon, title, and body text color — recolored per intent
--nm-toast-additionalReserved accent slot, mirrors border — recolored per intent
--nm-toast-shadowDrop shadow color

Implementation

Auto-dismiss timing and stacking multiple toasts need JavaScript; the card itself is pure CSS.

<link rel="stylesheet" href="namirial-theme.css">

<div class="nm-toast nm-toast--positive" role="status" aria-live="polite">
  <div class="nm-toast__notification">
    <span class="nm-toast__icon" aria-hidden="true"><!-- icon --></span>
    <div class="nm-toast__text">
      <span class="nm-toast__title">Invoice sent</span>
      <span class="nm-toast__body">Delivered to client.</span>
    </div>
    <button type="button" class="nm-toast__close" aria-label="Dismiss"><!-- x icon --></button>
  </div>
  <div class="nm-toast__actions">
    <button type="button" class="nm-button nm-button--ghost nm-button--secondary nm-button--sm">View invoice</button>
  </div>
</div>

CSS classes

ClassValuesDefault
nm-toast--{intent}primary · secondary · accent · info · positive · negative · warning — omit for primary— (primary)
nm-toast__notificationIcon + text + close row—
nm-toast__actionsBottom action row, right-aligned—
nm-toast__closeDismiss button, 24×24px, must be a <button>—