States & Feedback · the full lifecycle, not just at rest
States
01
Button — the six states
Every button answers in six ways. The last one here is live — hover it, press it, tab to it. The rest are forced previews so you can see each state side by side. A button missing its active state feels dead the moment you press it.
default
hover
focus
active
disabled
loading
real element
Button states
Six answers
hover lift + shadow
focus indigo ring (keyboard)
active press down + darken
disabled grey, not-allowed, no shadow
loading spinner, blocks re-trigger
02
Input — resting, focus, error, valid
A field shows its state and, when something's wrong, says what. A red border with no message tells someone they failed without telling them how to fix it. Focus gets a soft ring, error gets a message, success confirms quietly.
We'll only use this to set up your trial.
✕ That doesn't look like an email address.
✓ Looks good.
Input states
Say what's wrong
focus indigo border + soft ring
error red border + a message that explains
valid green border, quiet confirm
Validate on blur/submit, not every keystroke.
03
Loading — spinner or skeleton
Two waiting patterns for two situations. A spinner for a discrete action, a skeleton for a whole region loading in — the skeleton mimics the shape of what's coming so the arrival isn't jarring. Anything past ~300ms needs one; anything under 100ms shouldn't flash one.
Loading
Spinner & skeleton
Spinner — a discrete action working
Skeleton — a region loading; mimics its shape
Over ~300ms shows a loader; under 100ms doesn't. Block double-fire.
04
Empty — guide the first action
Before there's any data, the screen isn't blank — it's a designed moment that tells someone what goes here and how to start. An empty region with nothing in it reads as broken; a good empty state reads as an invitation.
✉
No invoices yet
Connect your first source and Northwind will start tracking and chasing automatically.
Empty state
An invitation
Designed, not blank. Icon + what-goes-here + the first action.
Guide the first step; don't apologize for being empty.
A truly blank region reads as a bug.
05
Error — name it, offer a way out
An error tells you what happened and gives you a way forward. Never a dead end, never blame, never a raw code. Calm, human, and always with the recovery action right there — retry, go back, get help.
!
Couldn't reach your invoice source
The connection timed out. This is usually temporary — your data is safe.
Error state
Calm + recoverable
Say what failed, in plain words. No codes, no blame.
Always offer the way out — retry, back, contact.
Reassure when true ("your data is safe").
06
Success — confirm, then get out of the way
Success is a quick, clear confirmation that then disappears. A toast that auto-dismisses, an inline check. It should never linger or over-celebrate — a permanent "SUCCESS!!!" banner is just noise. Confirm it happened and move on.
Reminder scheduled
✓
All set
Your invoices are being tracked.
Success
Brief & done
Toast — transient, auto-dismiss ~3–4s
Inline — a completed region confirms and rests
Don't over-celebrate. Confirm, then get out of the way.
07
The principle — never leave silence
Under every state above is one rule: the interface always answers. An action acknowledged within ~100ms, a wait shown as loading, a failure given a way out. Silence is the only unacceptable response — without feedback, "working" and "broken" look identical, and people re-click.
Every action → an acknowledgment (~100ms)
Every wait → a loading state
Every failure → a recovery path
Silence is the one response you never ship.
Feedback principle
Always answer
The interface must never go silent on an interaction.
Under 100ms feedback or it feels broken and users re-click.
"Working" and "broken" look identical without feedback.
Created for you, with ❤️ by Robert Evans· The AI Design Architect