Toast Philosophy

Toasts are Ferni's brief voice in UI feedback. They should feel like a supportive friend, not enterprise software. Keep them warm, human, and concise.

Do

  • Use contractions ("Couldn't" not "Could not")
  • Keep it short (under 10 words ideal)
  • Use human tone ("That didn't work")
  • Offer recovery for errors ("Try again?")

Don't

  • Say "Please" (too formal)
  • Use "successfully" (redundant)
  • Show technical errors to users
  • Write more than one sentence

Toast Types

Success Toast

Confirmations and celebrations. Auto-dismisses in 2.5s.

Saved!
toast.success('Saved!');
toast.success(`${name} added!`);
toast.success("Got it! I'll remember that.");

Info Toast

Status updates and neutral information. Auto-dismisses in 2.5s.

Just a moment...
toast.info('Just a moment...');
toast.info('Checking...');
toast.info('Syncing your data');

Warning Toast

Soft alerts that guide action. Auto-dismisses in 2.5s.

Add a name first
toast.warning('Add a name first');
toast.warning('Your voice profile needs a refresh');
toast.warning('Running low on tokens');

Error Toast

Failures with recovery options. Stays longer (4s) for reading time.

Couldn't save that. Try again?
toast.error("Couldn't save that. Try again?");
toast.error("That didn't work. Retry?");
toast.error("Lost connection. Retry?");

Message Examples

Wrong Right Why
"Payment failed. Please try again." "Payment didn't go through. Try again?" More human, no "please"
"Failed to save changes" "Couldn't save that" Use contractions
"Voice enrollment complete successfully!" "Got it! I'll know your voice now." Drop "successfully", add warmth
"Error: Connection timeout" "Lost connection. Retry?" Human tone, offer action
"Please enter a valid email" "Enter a valid email" Avoid "please"
"Operation completed successfully" "Done!" Keep it short

Positioning

Top Left
Top Center
Top Right (Default)
Bottom Left
Bottom Center
Bottom Right

Animation

Enter & Exit

Toasts slide in from the edge and fade out gracefully.

.toast-enter {
  animation: toast-slide-in var(--duration-normal) var(--ease-spring);
}

.toast-exit {
  animation: toast-fade-out var(--duration-fast) var(--ease-ease-out);
}

@keyframes toast-slide-in {
  from {
    transform: translateX(100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes toast-fade-out {
  from { opacity: 1; }
  to { opacity: 0; }
}

Timing

Type Duration Rationale
Success 2.5s Quick confirmation, user knows what happened
Info 2.5s Status updates are glanceable
Warning 2.5s Soft alerts don't need long reading time
Error 4s Longer for reading + deciding on action

CSS Implementation

.toast {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--bg-elevated);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  font-size: var(--text-sm);
  font-family: var(--font-body);
  color: var(--text-primary);
  max-width: 360px;
}

.toast-success {
  border-left: 3px solid var(--success);
}

.toast-success .toast-icon {
  color: var(--success);
}

.toast-info {
  border-left: 3px solid var(--info);
}

.toast-info .toast-icon {
  color: var(--info);
}

.toast-warning {
  border-left: 3px solid var(--warning);
}

.toast-warning .toast-icon {
  color: var(--warning);
}

.toast-error {
  border-left: 3px solid var(--error);
}

.toast-error .toast-icon {
  color: var(--error);
}

/* Toast Container */
.toast-container {
  position: fixed;
  top: var(--space-4);
  right: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  z-index: var(--z-toast);
}

/* Reduced Motion */
@media (prefers-reduced-motion: reduce) {
  .toast {
    animation: none;
  }
}

Accessibility

ARIA Live Regions

Toast containers use role="status" and aria-live="polite" for screen reader announcements.

Focus Management

Toasts don't steal focus. Users can continue their current task while being informed.

Color + Icon

Status is conveyed through both color AND icon shape. Never rely on color alone.

Dismissible

Error toasts should be dismissible via click or Escape key for users who've read them.