Open it when: you're working on forms, the states a control can be in, empty and error screens, interface wording, or what a first-time visitor sees.
What we know
Forms
- One form can do several jobs. A booking button, a quote button and an upload-your-plans button can all open the same form, with its type already picked by the button that opened it. [our build]
- Use labels that stay put. A placeholder is an example, not a label. Give format rules before the user submits. [impeccable]
- Put errors inline, next to the field. Be specific, suggest a fix, and keep what the user typed. [impeccable]
- Stop double submission: disable the button while it's working. [impeccable]
- Never trust checks in the browser alone. Check again on the server. [impeccable]
- On phones, inputs under 16px make iOS Safari zoom in, which breaks form layouts. [impeccable]
- A switch is for settings that take effect at once. Anything that needs a submit uses a checkbox. [Astryx]
- Form inputs are controlled: the value and the change handler live in your code. [Astryx]
- Pick the control by the job. [Astryx]
- Short text such as names, emails, search: a text input.
- Longer text: a text area.
- One option from a list: a dropdown.
- Several from a known set: a checkbox dropdown, or chips you can remove.
- Files: a file input with drag and drop and checks on type, size and count.
- A layout component places fields but doesn't handle state or sending. Wrap it in a real
<form>. [Astryx]
States
- Every interactive control has default, hover, focus, active, disabled, loading and error states. [impeccable]
- Use one set of state names everywhere: hover, focus, active, disabled, selected, loading, error, warning, success, info. [impeccable]
- Keep controls consistent. If "save" looks different in two places, one is wrong. [impeccable]
- Use skeleton placeholders for loading, not spinners in the middle of content. [impeccable]
- Menus and pop-ups must escape their container. A dropdown inside a box that hides overflow gets cut off. Use
<dialog>, the popover API,position: fixedor a portal. [impeccable] - Don't reach for a modal first. Use one only when the task needs interruption or locked focus. [impeccable]
- Don't use a badge as decoration. Use it only for distinct states. [Astryx]
- Some awesome-design-md files have a no-hover rule: they document only the default and pressed states. Their "Known Gaps" section lists hover and other states the copying never saw. [awesome-design-md]
- Never rely on hover for anything that matters. Touch users can't hover. [impeccable]
- Interrupted gestures: if a drag is cancelled or the window loses focus, clear the drag state. The next tap must work without a reload. [impeccable]
- Wait about 300 ms after typing before running a search, and run scroll handlers at most about every 100 ms. [impeccable]
Empty and error screens
- An empty screen teaches the interface. It doesn't just say "nothing here". [impeccable]
- Every empty screen says what will be here, why it matters, how to start, and where to get help. [impeccable]
- Empty screens differ by cause. [impeccable]
- First use: show the value and offer a template.
- User cleared everything: a light touch, easy to recreate.
- No results: suggest a new search or clearing filters.
- No permission: explain.
- Error: offer a retry.
- An empty screen needs a title and a next step, so the user isn't stuck. [Astryx]
- A useful error says what failed, why (when that helps), and how to recover. No internal codes as the main message. [impeccable]
- Match server errors to screens: 400 a validation message, 401 back to login, 403 a permission message, 404 a not-found screen, 429 a slow-down message, 500 a general error with a way to get help. [impeccable]
- One broken part must not block the whole interface. [impeccable]
- Test extremes: very long and very short text, emoji, right-to-left text, accents, huge numbers, a thousand items, no data. [impeccable]
- Use logical CSS properties such as
margin-inline-start, so right-to-left text lays out correctly. [impeccable] - Leave 30 to 40% extra room for translations. [impeccable] impeccable says German often runs 30% longer than English (asserted, no evidence shown).
- Use the browser's Intl tools for dates, numbers and money, and a proper library for plurals. [impeccable]
Copy
- Use the product's own words. Buttons name their action. Errors name the problem and the fix. [impeccable]
- For each state, decide the one fact the user needs now, the next action, and the right tone. [impeccable]
- Say each idea once. If the heading explains it, the intro adds something new or goes. [impeccable]
- Labels say what will happen, not the gesture. Use the same word for the same thing everywhere. [impeccable]
- Active voice: "Save changes", not "Changes will be saved". [impeccable]
- A destructive action names the object and what happens to it. Prefer undo over a confirmation when recovery is safe. Never "Yes", "No", "OK" or "Submit" on a confirmation. [impeccable]
- Loading text names the real job. Never fake progress. [impeccable]
- Link text must make sense on its own. [impeccable]
- Write whole messages that translate, not sentences stitched together from fragments. [impeccable]
- Warmth is welcome around privacy, payment, deletion and lost access. Jokes are not. [impeccable]
- Avoid marketing buzzwords such as streamline, empower, supercharge, world-class, cutting-edge. Say what the product literally does. [impeccable] impeccable calls these instant AI tells (asserted, no evidence shown).
- Test copy at the target widths and at 200% zoom. Final copy is as short as it can be without losing meaning. [impeccable]
First use
- Get people to first value fast. The job is not to teach the whole product. [impeccable]
- Show, don't tell. Use the real product, not a separate tutorial mode. Teach one thing at a time. [impeccable]
- Introduce one to three core ideas. Keep a tour to three to seven steps. [impeccable]
- Supply sample data so a new user's first actions work. [impeccable]
- Teach a feature when people need it. Empty screens are a chance to teach. [impeccable]
- Let experienced users skip. Never hide the skip option. [impeccable]
- Show onboarding once. Remember that it's done, and respect dismissals. [impeccable]
- Ask for as little as possible at sign-up, and say why you need each thing. [impeccable]
Small pleasures
- A delightful moment must belong to this product. A neighbouring product shouldn't be able to use it unchanged. [impeccable]
- Match the celebration to the effort. A routine save should just feel certain. Never fake work to stage a flourish. [impeccable]
- Generic whimsy is worse than plain clarity. [impeccable]
Tools in this drawer
- Survive real data and errors:
/impeccable harden <target>. Pick it before launch, when the screens only work with perfect data. - Rewrite interface wording:
/impeccable clarify <target>. Pick it when buttons, errors or empty screens leave people unsure what to do. - First use and empty states:
/impeccable onboard <target>. Pick it when new users stall or empty screens say "nothing here". - Tool: Astryx forms. Pick it when you build on React and need well-behaved form controls quickly.