A form architecture with one entry point
Think in phases: capture, validate, send and close state cleanly.
The `submit` event should orchestrate the flow. That is where you decide whether local validation passes, whether a request should be sent and how the UI should react afterward.
When each field validates itself with no central coordination, forms tend to drift into inconsistent behavior.
Capture
Read the form data once.
- `FormData`
- `Object.fromEntries()`
Normalize
Clean values before validating.
- `trim()`
- lowercase email
Validate
Apply per-field rules with useful messages.
- required
- length and format
Submit
Send with clear UI state.
- disable the button
- clean up in `finally`