Interaction Patterns
Animation philosophy, empty state strategy, loading and error treatment, microcopy conventions, and the voice system governing UI text.
Interaction patterns cover the non-visual dimension of design -- how the product responds to user actions, communicates state, and speaks through text. These patterns have outsized impact: non-ideal states (loading, empty, error) make up 30-50% of actual user experience but receive less than 5% of typical design attention.
Animation Philosophy
Three Rules
-
Animate to communicate, never to decorate. Every animation must answer one of: Where did this come from? What just happened? What should I look at? Is the system working? If an animation doesn't answer any of these, remove it.
-
Prefer CSS, escalate to JavaScript only when CSS fails. CSS transitions run on the GPU compositor thread -- they don't block the main thread, don't add to the JS bundle, and work in Server Components. Escalate to Motion (framer-motion successor) only for exit animations, layout animations, spring physics, and staggered reveals.
-
Every animation has a reduced-motion fallback. 70 million people have vestibular disorders. The motion token system zeroes all durations under
prefers-reduced-motion: reduce, making every animation instant without removing feedback.
Animation Tiers
| Tier | Category | Examples | Priority |
|---|---|---|---|
| Primary | Conversion-critical | CTA button feedback, form validation, onboarding progress | Highest -- polish these |
| Secondary | Comprehension-supporting | Modal enter/exit, accordion expand, dropdown reveal | Medium -- CSS transitions |
| Decorative | Visual-only | Background particles, parallax, hover glow | Skip entirely -- zero ROI |
What to Animate First
| Animation | Business impact | Method |
|---|---|---|
| Skeleton-to-content transitions | Perceived performance +20% | CSS transitions |
| Form validation feedback | Error correction +22% faster | CSS transitions |
| Button press/active states | Conversion +6-10% | CSS (hover:scale-[1.02] active:scale-[0.97]) |
| Toast enter/exit | Spatial context for feedback | Motion (exit needs JS) |
| Modal open/close | Focus management, spatial context | Motion |
What to Skip at MVP
Page navigation transitions, tooltip show/hide, data table sorting, sidebar toggle on desktop, color/theme switching. Instant is fine for all of these.
Motion Tokens
| Token | Value | Use for |
|---|---|---|
--motion-fast | 100ms | Button active, toggle switch, focus ring, tooltip |
--motion-normal | 200ms | Modal enter, dropdown reveal, accordion expand |
--motion-slow | 350ms | Skeleton reveal, complex layout change, notification entry |
--motion-slower | 500ms | Full-page skeleton transition, onboarding step change |
GPU-Safe Properties
Only animate transform and opacity. These are composited on the GPU without triggering layout recalculation. Never animate width, height, top, left, margin, or padding -- they cause layout thrashing and visible jank on mobile.
Empty State Design
Why Empty States Matter
84% of users who encounter blank states without contextual help abandon in the first session. Nobel laureate Daniel Kahneman's peak-end rule shows people judge experiences by their most intense moment and the final moment. A single cryptic empty screen can define a user's memory of the entire product.
Every non-ideal state must answer three questions:
- What is happening?
- Is this normal?
- What should I do?
Four Empty State Types
| Type | When | Goal | Tone |
|---|---|---|---|
| First-use | New user encounters feature for first time | Drive first meaningful action | Welcoming, encouraging (Creator archetype) |
| No-data | Filters return nothing, search has no matches | Help user understand why + what to do | Helpful, contextual |
| Cleared/completion | User completed or cleared all items | Celebrate + suggest next step | Positive, congratulatory |
| Error-caused | Data should exist but can't be loaded | Communicate issue + offer recovery | Calm, transparent, actionable |
First-Use Strategy: Onboarding Checklist
The recommended MVP approach is an embedded 3-5 step checklist in the dashboard empty state. Each step is a concrete action toward value. This transforms "What do I do?" into guided progress. Completion psychology drives momentum.
Visual Treatment (MVP)
The MVP pattern for empty states uses an enhanced Lucide icon (48px) in the primary teal color, placed inside a soft-colored circle, with a title, brief explanation, and CTA button. This is implemented as a reusable EmptyState component. Icons are replaced with custom illustrations one by one as budget allows post-PMF.
Empty states are one of the highest-leverage personality injection points. The Creator + Magician archetype should come through here -- "Start your first research" (encouraging, exploratory) over "No data found" (clinical, hostile).
Loading State Design
Perceived Performance Over Actual Performance
Skeleton screens at 3 seconds feel faster than spinners at 2 seconds. The loading treatment is the primary driver of whether users perceive the product as "fast" or "slow."
Loading Hierarchy
| Tier | Scope | Treatment | Delay before showing |
|---|---|---|---|
| Full-page | New page, route change | Skeleton screen showing page layout | None -- show immediately |
| Section | Lazy-loaded panel, tab content | Section skeleton or spinner | 200ms (avoids flash for fast loads) |
| Action | Button click, form submit | Inline spinner on button, disable element | 100ms |
| Background | Data sync, polling | No visible indicator unless failure | Invisible unless >10s |
The 200ms Delay Rule
For section and action loads, wait 200ms before showing any loading indicator. If the response arrives in 150ms, a skeleton that immediately disappears is worse than showing nothing. Full-page loads skip the delay -- blank page flash is worse than skeleton flash.
Skeleton Screen Principles
- Match content layout approximately -- 3-5 shapes per component is sufficient.
- Neutral gray tones (
gray-200light mode,gray-700dark mode). Never brand colors. - Shimmer animation -- gradient highlight moving left to right.
- Never skeleton cached content -- if data is from cache or SSR, show it immediately.
Optimistic UI
Update the UI instantly as if the server confirmed. Roll back on rejection. Use for: toggles, favorites, reordering, inline edits, archiving, comments. Do not use for: permanent deletion, payments, permission changes, invitations, anything with >1-2% failure rate.
Error State Design
Error Severity Hierarchy
| Level | Scope | Display | Example |
|---|---|---|---|
| Field | Single input | Inline text below field + red border | "Email must include @" |
| Form | Multiple fields | Error summary at top + inline per field | "Please fix 3 errors below" |
| Section | Component data load failure | Error boundary with retry | "Couldn't load activity feed. [Retry]" |
| Page | Full page failure | Error page with recovery options | "Something went wrong. [Go to Dashboard] [Retry]" |
| App | Network outage, maintenance | Persistent banner | "You're offline. Changes will sync when reconnected." |
Error Message Formula
What happened + why (if known) + what to do next. Never blame the user. Never show raw error codes.
| Bad | Good |
|---|---|
| "Error 500" | "We couldn't load your dashboard data. This is usually temporary -- try refreshing." |
| "Invalid input" | "Email must include @ and a domain (e.g., name@company.com)" |
| "Request failed" | "Couldn't save your changes. Check your connection and try again." |
| "Unauthorized" | "You don't have access to this page. Contact your workspace admin." |
Error Message Principles
- Never blame the user ("Enter a valid email" not "You entered an invalid email")
- Never use technical jargon ("We couldn't save" not "500 Internal Server Error")
- Never use "Oops" -- trivializes frustration, grating on repeat encounters
- Always provide a path forward
- Use positive framing ("Use at least 8 characters" not "Must not be fewer than 8")
- Never clear form fields on error
Microcopy Conventions
Button Labels
Format: imperative verb + object noun, sentence case. 1-3 words (max 4 for complex actions).
| Verb | Meaning | Example |
|---|---|---|
| Create | Brings a new entity into existence | "Create project" |
| Save | Persists changes to existing entity | "Save changes" |
| Delete | Permanently removes (irreversible) | "Delete project" |
| Remove | Takes out of a list/group (entity still exists) | "Remove member" |
| Archive | Hides from active view (reversible) | "Archive project" |
| Send | Transmits to another person | "Send invitation" |
Never use: "OK," "Yes," "No," "Submit," "Click here."
Destructive Action Dialogs
For destructive actions, the safe/escape option (Cancel, Keep, Go back) is visually prominent or neutral. The destructive option uses danger/red styling but is never the default or auto-focused button. High-risk actions require typing a confirmation word.
Toast Messages
Format: past-tense verb + object. One line maximum. Include [Undo] for reversible destructive actions with a 5-6 second display.
| Action | Message | Duration |
|---|---|---|
| Create | "Project created" | 3s |
| Save | "Changes saved" | 2s |
| Delete | "Project deleted" + [Undo] | 5s |
| Copy | "Copied to clipboard" | 2s |
Date, Time, and Number Formatting
- Relative for under 7 days: "12 minutes ago," "Yesterday," "2 days ago"
- Absolute for 7+ days: "Mar 14, 2026"
- Full date on hover: "March 14, 2026 at 3:45 p.m."
- Use
Intl.DateTimeFormat-- never hardcode format strings - Store UTC, display in user's local timezone
- Dashboard numbers round aggressively: $47,832.41 displays as "$47.8K"
Notification Architecture
Three Predefined Modes
Instead of a 45-toggle preference matrix, users choose a mode:
| Mode | Behavior | Volume |
|---|---|---|
| Calm | In-app only for mentions/assignments, daily email digest | ~5-10/day |
| Regular (default) | Real-time in-app for direct interactions, batched for team activity | ~15-30/day |
| Power | Real-time across all channels for all activity | ~50+/day |
Expandable granular controls below the mode selector serve the ~5% of users who want fine-tuning.
Three-Tier Frequency Model
| Tier | Examples | Default | User control |
|---|---|---|---|
| Critical (always real-time) | Failed login, password change, payment failure | All channels | Cannot disable |
| Activity (configurable) | Mentions, assignments, comments | Real-time in-app + email | Can switch to digest or off |
| Informational (batched) | Product updates, usage reports | Weekly email digest | Can switch to real-time or off |
Related Pages
- Component Patterns -- EmptyState component, skeleton implementations
- Brand Identity -- voice characteristics and tone spectrum
- Anti-Patterns -- how empty states and copy counter generic AI output
- Design Tokens -- motion token values in CSS
Layout & Navigation
Responsive breakpoint strategy, five-zone sidebar, command palette, workspace switcher, and the structural decisions shaping how users move through Trovella.
Anti-Patterns
The twelve tells of AI-generated design and the specific countermeasures built into Trovella's design language.