The screenshot looks right. You open it on your phone and a button is off the edge. You submit the form with an empty field and nothing happens, no error, no spinner, just a page that sat there. None of this is a bug in the usual sense. The code does what it was asked. It was asked for the case where everything goes well.

The idea

An AI writes the screen you described, and you described the moment it works. Real screens spend most of their life in the other three states: nothing yet, waiting, and something went wrong. Those states plus two access questions, does it work on a small screen and does it work without a mouse, are the whole difference between a demo and something you can hand to a person.

code
  EVERY SCREEN HAS FOUR STATES
  ---------------------------------------------------------------
  EMPTY     no data yet          say why, and what to do first
            (new account,        "No invoices yet. Create one ->"
             no results)         never a blank rectangle
  ---------------------------------------------------------------
  LOADING   waiting on the       show it within ~100ms, or the
            server               user clicks the button twice
  ---------------------------------------------------------------
  ERROR     it failed            say what failed and what they
                                 can do. "Something went wrong"
                                 is not an error message
  ---------------------------------------------------------------
  READY     the happy path       the one your AI built
  ---------------------------------------------------------------

How it works

A form has two jobs: stop bad input, and explain itself. Checking the input in the browser is a courtesy to the user and nothing more, because anyone can bypass it. The check that counts runs on your server, and it has to run there even though you already wrote one in the browser. When it rejects something, the message goes next to the field that caused it, in words the user can act on. "Invalid" is not one of those words.

Small screens are not a separate design, they are the default one. Most people who open your link will open it on a phone. A layout built at desktop width and then squeezed usually breaks in the same two places: a table that will not fit, and a fixed-width element that pushes the whole page sideways.

Without a mouse means two different users. Someone tabbing through with a keyboard, and someone whose screen is being read aloud to them by a . Both are served by the same thing: using the real HTML element. A <button> is focusable, announces itself as a button, and fires on Enter. A <div onClick> looks identical and does none of that.

What to do

  1. When you ask for a screen, ask for all four states in the same request. "Build the invoice list, including the empty state, a loading state, and what it shows when the fetch fails."
  2. Validate on the server for every form, and return a message per field. Ask for it explicitly, or you will get browser-only validation and a generic alert.
  3. Check the phone before you call it done. In your browser, open developer tools and switch to a narrow device size. Then put down the mouse and press Tab through the page: if you cannot see where you are, or cannot reach a control, neither can a keyboard user.
  4. Say "use real HTML elements, no div buttons" once in your project instructions and it stops being a per-request fight.

Where it breaks

Accessibility has a long tail and this page is not it. Colour contrast, focus order in a modal, form labels tied to their inputs, motion for people who get sick from it: the published rules are the WCAG guidelines, and an AI is good at applying them when you name them. What it will not do is decide for you which of your users matter.

There is also a real trap in asking for polish too early. Loading skeletons, animations and empty-state illustrations on a screen whose data model is about to change are work you throw away. Build the four states, ship it, and let the thing tell you where it is actually rough.