Loading, empty, error and success each need a deliberate design.
Never ship a screen with only its data-full state designed.
A brand-new Notion or Todoist account isn't full of data, it's empty, and that blank screen is the first real impression the product makes. The strong version turns it into onboarding: one clear next action, a sample to copy, a line of encouragement. Skip it and the new user lands in a void and leaves. The same care applies to loading (a skeleton, not a frozen screen), errors (what happened and how to recover), and success (confirm the action actually landed).
This is about deliberate design, not maximal design. A tiny, self-evident component rarely needs a bespoke empty or error treatment, and lavishing effort on every micro-state is a poor use of time. Spend the care where a state is common, confusing, or costly: first run, a failed payment, a dropped connection.
Teams design the AI's 'here's your answer' state and forget generating, empty, and failure — the states users actually get stuck in.
An automated agent issues the wrong refund and leaves no clear route to correct it.
An AI generation feature only designed its success state — failures and waits look broken.