Every broken, interrupted, or dead-ended state, drawn in the app's calm register. The whole point of this board: a broken moment stays ink and muted — it never borrows a sunset accent. Tangerine means live, marigold means Starter, rose means Celebrator / finale — those stay semantic, so an error rendered in alarm color would read as a broken promise, not a hiccup. Voice is plain and blame-free; retry is the single way forward; nothing already loaded is thrown away; and a dead-end never reveals whether the door was closed by a delete or a block.
The feed opened with no connection and nothing cached. A full-screen quiet state, sibling to the empty states: ink glyph, calm headline, one muted sentence, a quiet ink-outline Retry — no accent, no alarm.
The app states it once and waits. No spinner held forever, no scolding, no big red banner — just the plain sentence and a way to nudge it. The glyph is two stepping-stones with a gap, original and quiet: no wifi-slash, no cloud.
Pagination failed mid-scroll. Everything already loaded stays; one quiet inline row does the recovery. This is the canon dressing for the app's existing list error-recovery — it never takes over the screen.
A failed page never blanks the feed or throws up a modal. The cards you already scrolled stay exactly where they are; the fade at the bottom edge shows the list simply stopped, and one centered row offers to fetch the rest.
Publishing failed after you hit post. The composer keeps everything local until the server confirms, so nothing you wrote or picked is gone. A bottom sheet says so and offers to re-send it as-is.
The note and media are held on the device the whole time; a failed publish just means the app hasn't heard back yet. Try again re-sends the identical draft — same words, same photo, same order.
A deep link resolved to something you can't see. A full-screen dead-end: ink glyph of a pill with a soft opening — a door left ajar — a calm headline, one muted line, and a quiet way back to your feed.
deleted, author-blocked-you, and you-blocked-author all render this exact screen — indistinguishable by design. There is nothing to diagnose and no one to name; the state is the same door whichever reason closed it.
One card's image failed to fetch. The card keeps its full reserved height and the media area becomes a calm field — no broken-image icon, no gray X. Tapping retries just that one image.
Every step has media, so the card reserves its aspect ratio no matter what. A failed image doesn't shrink the card, jump the scroll, or stamp a broken-image glyph — it fills the same space with a quiet paper field and a faint prompt.
The last-resort catch-all, used only when nothing more specific is known. Still a full-screen quiet state — plain headline, one reassuring line, the same ink-outline Retry.
When the app genuinely doesn't know what broke, it says so plainly and offers one button — it does not invent a specific-sounding excuse. Everything an engineer needs is already elsewhere.
The rules that keep every broken state calm, honest, and free of blame — the spine every surface above is drawn from.
When something breaks, the app gets quieter, not louder.
states-empty.html. The
first-run and honest-zero surfaces live there; the interrupted and failed surfaces live
here. Both share one doctrine: the app never manufactures alarm. Full-screen states reuse
the empty-state grammar (glyph · headline · sentence · one quiet action); the inline
“Couldn't load more” row is the canon dressing for the list's existing
error-recovery; and the deep-link dead-end (panel 04) is the single screen behind which
delete and block are made indistinguishable — enforced on the server, not just the
client, so no reason ever leaks.