<!-- Free part of the ihumane Front-end build module, generated from pro/front-end/ by scripts/build-free.js. Edit pro/front-end/, not this file. -->

# 4 · States, forms and focus

A design usually shows a control at rest. People meet it while hovering,
tabbing, pressing, waiting and getting it wrong. A form is where most of
this happens at once, and where people give up when it goes badly. Build
every state the control can be in, let the browser help with the fields, and
put focus where people expect it.

---

> **In ihumane Pro** (https://ihumane.ai/#pricing):
> - F1 · Build every interactive state, and make focus visible

### F2 · Every field: a label, the right type, autocomplete
**Rule:** Each field has a visible `<label for>` that says what goes in it
(a placeholder is not a label). Use the type that matches: `email`, `tel`,
`url`, `password`, `search`, `date`. For numbers that aren't amounts (codes,
card numbers, postcodes) use `type="text"` with `inputmode="numeric"`, not
`type="number"`. Add `autocomplete` with the right token (`name`, `email`,
`tel`, `street-address`, `postal-code`, `current-password`,
`new-password`, `one-time-code`). Group radios and checkboxes in a
`fieldset` with a `legend`. Give every field a `name`.
**Why:** The right type gives a phone the right keyboard: an @ key for
email, a number pad for a code. Autocomplete fills a whole address in one
tap, and lets a password manager do its job. Without a label, a screen
reader says "edit text" and nothing else, and once someone starts typing,
the placeholder that told them what to type is gone.
**Agent trap:** a field built to look like the design, with the label as
placeholder text and every type left as `text`:
```html
<input placeholder="Email">
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="email" required>
```
**Check:** `checks/layout.js` flags fields with no label or only a
placeholder, email and phone fields typed as `text`, and common fields with
no `autocomplete`. On a phone width, focus each field and check the keyboard
type (in DevTools device mode, or name the type in your report).

> **In ihumane Pro** (https://ihumane.ai/#pricing):
> - F3 · Check fields when people finish, not while they type
> - F4 · Disabled, read-only and hidden mean different things
> - F5 · One submit, clearly busy, nothing lost
> - F6 · Dialogs and menus move focus in, and give it back
> - F7 · Tab order follows reading order

## Summary checklist

- [ ] Every control has hover, focus-visible, active and disabled styles; focus is visible everywhere.
- [ ] Nothing important is only on hover.
- [ ] Every field has a label, the right type, `autocomplete`, and a `name`.
- [ ] Errors appear when a field is left or the form is submitted, under the field, linked to it; focus goes to the first error.
- [ ] No disabled control without a visible reason; submit can always be pressed.
- [ ] Real `<form>`, Enter submits, one request per submit, nothing lost on failure.
- [ ] Dialogs and menus: focus in, Escape out, focus back to the trigger.
- [ ] Tab order matches what you see; no positive `tabindex`.
