The guide · AI-built interfaces

Why your AI-built app
looks unfinished.

The app works. The demo went well. And still, people looking at it for the first time hesitate — and they cannot tell you why. Here are the eight visual tells, why AI tools and rushed builds produce every one of them, how to check your own app in fifteen minutes, and what is usually going on in the code underneath.

Spacing

Why are the gaps all different?

Open two pages of your app and measure the space between the heading and the content. On a product built by people it is the same number, because someone chose a spacing scale — a short list of allowed gaps — and every screen uses it. On an AI-built app it is whatever the model emitted that time.

The reason is structural, not aesthetic: the generator has no shared source for spacing, so there is nothing to be consistent with. That is also why fixing one page does not fix the others.

Self-check: take screenshots of two pages and lay them side by side. Do the section gaps, card padding and button heights match? If you have to squint, they do not.

Type

Why does the text change size from page to page?

The single fastest way to tell an AI-built interface from a designed one is the headings. A designed product has perhaps five text sizes, used everywhere in the same roles. A generated product has fifteen, because each screen chose its own — and the settings page ends up with a bigger title than the dashboard.

Type scale is also where perceived quality lives. Users cannot say why one app feels more trustworthy than another, but consistent type is most of the answer.

Self-check: open the browser inspector on the main heading of three different pages and read the font size. Three numbers means no type scale exists.

Alignment

Why do things almost line up?

A heading whose left edge is two pixels from the content beneath it. Three buttons in a row at three slightly different heights because one has an icon. An avatar that is not quite centred in its circle. Each one is too small to report as a bug, and together they are what “amateur” looks like.

They happen because the generator positions each element with its own numbers instead of placing everything on one grid. There is no grid to align to, so nothing aligns.

Self-check: hold a ruler, or a sheet of paper, against the left edge of your content column and scroll. Anything that steps in or out was never aligned.

Colour

Why are there nine greys?

Generated code writes colour values inline — a hex code typed straight into the component. Do that on forty screens and you have forty opinions about what grey is. Borders, muted text and backgrounds all drift, and the app looks faintly dirty without anyone being able to say why.

The same mechanism produces the contrast problem: light grey text on white that reads fine on the founder’s calibrated laptop and disappears on a phone in daylight.

Self-check: search the codebase for the # character followed by six characters. If the count is in the hundreds, there is no palette — there is a pile.

Responsive

Why does it only look right on your laptop?

Breakpoints — the widths at which a layout rearranges itself — are decisions. Nobody made them. The generator produced a layout for the screen it imagined, and everything narrower or wider is an accident: tables that scroll sideways on a phone, a sidebar that covers the content, a primary button below the fold, paragraphs 200 characters wide on a large monitor.

A large share of any product’s traffic arrives on a phone. This is the tell users hit first and the one founders see last, because founders use laptops.

Self-check: open the app on your phone and try to complete the one action the product exists for. Time it. Then try it on a screen wider than 1,600 pixels.

States

What does a new user actually see?

You prompted for the dashboard, so the model built the dashboard — full of data. A new user has no data, so they see a blank page with no explanation. A slow request shows nothing, so they click again and create a duplicate. An error shows raw JSON. Hover, focus and disabled states are missing, so keyboard users cannot tell where they are.

Empty, loading and error states are the screens real users meet first and the ones that were never in any prompt. They are cheap to write and they change the first impression completely.

Self-check: create a brand-new account and look at every page before adding any data. Then turn on network throttling in the browser and click the slowest action twice.

Accessibility

Can it be used without a mouse?

Put the mouse down and press Tab. On a product built with rules, a visible ring moves through the controls in a sensible order and Enter activates them. On a generated one, focus vanishes, skips the custom dropdown entirely, or lands on things that are not controls. Turn on a screen reader and the icons announce as “button, button, button”, because nobody gave them names.

This is not a niche concern. It is how a meaningful share of users work, it is a legal requirement in most markets you will sell into, and it is a direct consequence of the same missing rules — one accessible component reused everywhere is easy; twelve copies are never all fixed.

Self-check: complete your product’s main action using only the keyboard. Then run the browser’s built-in accessibility audit on the busiest page and read the first five findings.

Language

Does the translation fit?

If the app ships in more than one language, switch to the longest one you support and watch the layout. Buttons sized for “Save” overflow on “Speichern”; a heading that fit on one line wraps into the image below it. Dates print month-first for a European user, numbers get the wrong separators, and a dozen strings are still in English because they were typed straight into the component.

Translation is usually treated as a spreadsheet problem. It is a layout and code problem: the strings have to live outside the components, and the components have to survive text twice as long as the English.

Self-check: switch to your longest language and screenshot the three busiest screens. Then search the source for any user-facing sentence that is not in a translation file.

Underneath · Why polish finds more than polish

The look is the symptom.
The code is the cause.

Every tell above has the same origin: the generator produced each piece on its own, with nothing shared between them. That shows on the screen as drift. It shows in the repository as this:

HighReusability

One button, written twelve times.

Instead of one component used on every screen, there is a fresh copy per screen, each slightly different. This is why the spacing cannot be fixed in one place — there is no one place. It is also why each new feature takes longer than the last.

HighMaintainability

Every value typed by hand.

Colours, widths and margins as literals inside each file, hundreds of times. Changing the brand colour is a ninety-file edit. A new engineer needs a week just to learn where things are, which is the real cost of a codebase nobody structured.

HighScalability

Nothing separated, so nothing can grow.

Data fetching, business rules and presentation in one file per screen. Adding a feature touches everything and breaks something unrelated. The app is not slow yet; it is stuck.

CriticalSecurity

The things found on the way.

Nobody goes looking for security problems while fixing fonts, and they get found anyway: a role check that only exists in the interface, an endpoint that returns another user’s record when one number changes, a secret in the repository. These are outside a polish job and inside a code audit, and you should be told the day they are seen.

Common questions

Why do AI-generated interfaces look inconsistent?

Because each screen is generated as a separate answer to a separate prompt. The model has no memory of the spacing, type sizes or colours it used on the previous screen, so it invents new ones. The same thing happens when an inexperienced developer builds screen by screen without a design system. Consistent products exist because someone defined the rules once and reused them; inconsistent ones exist because those rules were never written down anywhere in the code.

Can I fix the look of my AI-built app without a redesign?

Almost always. The layouts and flows are usually fine; what is missing is consistency. Defining one spacing scale, one type scale and one colour palette in code, then bringing every screen onto them, changes how the product reads without changing what it does. The work is engineering, not design — which is why it can be quoted as a fixed sprint.

Does an unpolished interface mean the code is bad?

Not always, but they usually travel together, for the same reason: the generator produced each piece in isolation. The visual drift you can see is caused by duplicated components and hand-typed values you cannot see, and those are the same things that make the app slow to change and hard to hand to another engineer. Fixing the look properly means opening the components, so it is also the moment the structure gets looked at.

What should I check before paying anyone to polish my app?

Eight things, on your own screen, in fifteen minutes: measure three gaps between sections on two different pages and see whether they match; compare the main heading size on two pages; check whether buttons in a row share the same height; count the greys; open the app on a phone; log in as a brand-new user with no data; complete the main action with only the keyboard; and, if it is translated, switch to your longest language. If four or more fail, the app has no design rules in its code, and polish will pay for itself.

The code-side companion to this guide: what breaks when AI builds your app. Every long-form guide, with read times, is in the Playbook.