patterns
Error states
What happened, whose fault it was, what to do. Wolf errors never blame the civilian and never just say 'An error occurred.'
Read the full spec404 — page not found
Neutral icon, honest copy, at least one navigation path.
404
Page not found
We couldn't find this page. It may have moved, or the link might be broken.
500 — something broke on our side
Warning-coloured icon, humble apology, retry preserves state.
500
Something broke on our side
We've logged it and we're looking. Try again in a minute, or let us know if it keeps happening.
Inline field error
Red border, specific message, associated via aria-describedby. Never just 'Invalid input.'
That doesn't look like a valid email address.
<div>
<Label htmlFor="email">Email</Label>
<Input
id="email"
type="email"
defaultValue="guard@midrand"
aria-invalid
aria-describedby="email-error"
className="border-destructive focus-visible:ring-destructive"
/>
<p id="email-error" className="mt-1 text-sm text-destructive">
That doesn't look like a valid email address.
</p>
</div>Section-level error — failed data load
Card in a tinted destructive background — accent only, never fills the whole page red.
Couldn't load reports
The connection dropped. We'll try again automatically.
Voice — what happened, whose fault, what to do
Per voice-and-tone §5.3. Specific about what broke, never jargon, always a recovery action.
- Upload failsUpload failed.That file didn't upload. Looks like the connection dropped.
- Wrong credentialsInvalid credentials.Either the email or password is wrong. Try again.
- 500 server errorInternal Server ErrorSomething broke on our side. Try again in a minute.