A user interface needs explicit states: idle, submitting, success, empty, and failed. A loading indicator alone does not explain what happened when a request times out. Keep submitted input available so the user can correct or retry it without retyping.
Use semantic controls and associated labels. Keyboard users must be able to submit and navigate errors. Announce meaningful status changes without flooding assistive technology with every streamed token. Disable or deduplicate repeated submissions where they could create duplicate actions.
Frontend validation helps usability, but the backend must repeat necessary checks because requests can bypass the interface. Treat rendered model output as untrusted content and avoid inserting arbitrary generated HTML.
Exercise: build or sketch a labeled question form with all five states. Simulate a rejected input and an upstream timeout, and define the recovery action.
Check: the form is usable without a mouse, preserves input on failure, and does not treat browser validation as a security boundary.