Toast
Non-intrusive feedback notifications that feel like Ferni's brief voice in the UI. Warm, human, and SHORT.
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.
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.
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.
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.
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
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.