FT FreeToolsHub

Blog / 5 Things To Do So Your Web UI Doesn't Look AI-Generated

5 Things To Do So Your Web UI Doesn't Look AI-Generated

Published October 17, 2026 · 9 min read

Imagine you have just shipped a landing page. Layout tidy, code clean, responsive on every breakpoint. You send the link to a client, and the reply is one sentence: looks good, but it feels like every other site I have seen.

Nothing on that screen is technically wrong, but the client can sense that something is missing even without being able to name it. That something is product specificity: every color, font, layout choice, and line of copy belongs to this product, instead of being the average pattern the model knows best.

This is the fix. Five concrete moves a developer can apply in an afternoon that move an AI-built UI from technically fine to looks like a real product. None of them require hiring a designer.

Why AI output looks so similar

In August 2025 Adam Wathan, a co-founder of Tailwind CSS, posted a half-joking apology on X. He apologized for making every button in Tailwind UI use bg-indigo-500 five years earlier, which, in his words, turned every AI-built interface purple.

The joke was half-serious. A common theory is that models lean toward the patterns that show up most often in tutorials and example code, so their output drifts toward the internet's average. The theory is not fully proven, but the lesson holds either way: without direction, a model will land on the most common pattern it knows.

That shifts the developer's job. You are no longer checking whether the screen works. You are checking whether it belongs to this product.

Pick colors from your product's world, not from the defaults

Color is the fastest signal a page sends. The moment a hero section shows an indigo-to-purple gradient, visitors feel they have seen it before — without reading a single word.

Here is the default version most models produce (Tailwind v3 syntax):

<!-- Before -->
<section class="bg-gradient-to-br from-indigo-500 to-purple-500 text-white">
  <h1 class="text-5xl font-bold">Manage your shop with ease</h1>
  <a href="/signup" class="rounded-full bg-white px-6 py-3 text-indigo-500">
    Start free
  </a>
</section>

Beyond taste there is a technical catch. White text on #6366F1 (Tailwind v3's indigo-500) measures about 4.47:1 using the WCAG contrast formula. WCAG Success Criterion 1.4.3 (Level AA) asks for at least 4.5:1 for regular-size text. The gap is tiny, but formally the gradient does not pass. The more purple end, #A855F7, comes in around 3.96:1.

So how do you pick a palette without guessing? Answer three questions first.

  • Where is the product used? A shop owner opens a cashier app on a phone, often under bright light, which means strong contrast.
  • What objects belong to its world? For a point-of-sale app: paper receipts, cash books, change. From there: a receipt-paper cream and one calm, money-like green.
  • What feeling should it build? Calm and trustworthy, not like a tech startup.

The palette that falls out of those three answers:

:root {
  --neutral: #FBF6EC; /* cream background, close to receipt paper */
  --text:    #1E293B; /* blue-black, softer than pure black */
  --brand:   #1F7A5A; /* deep green for buttons and key elements */
  --accent:  #F2A93B; /* amber, used sparingly */
}

White on --brand measures roughly 5.26:1, which passes. For proportions, the 60-30-10 rule is a reliable default: roughly 60% neutral, 30% brand, 10% accent. Not an official standard, but it keeps colors from competing for attention.

One tip if you generate UI with AI: do not ask "what color looks good?". Put your palette in the prompt, in hex.

Choose one star for every screen

Open an AI-built dashboard and you will see a row of stat cards with the same size and the same font weight. It is neat, but the eye has no idea where to begin.

This is visual hierarchy, as the Nielsen Norman Group calls it: arranging elements so the eye follows the order of importance you intend. The tools are simple — size, color contrast, spacing.

<!-- Before: four cards, all identical -->
<div class="grid grid-cols-4 gap-4">
  <div class="rounded-xl bg-slate-100 p-4">
    <p class="text-sm text-slate-500">Sales</p>
    <p class="text-2xl font-semibold">Rp 4,280,000</p>
  </div>
  <!-- 3 more cards with exactly the same classes -->
</div>
<!-- After: one number leads -->
<div class="rounded-2xl bg-[var(--brand)] p-6 text-white">
  <p class="text-sm">Today's sales</p>
  <p class="text-4xl font-bold">Rp 4,280,000</p>
  <p class="text-sm">up 8% from yesterday</p>
</div>

<div class="mt-4 grid grid-cols-3 gap-3">
  <div class="rounded-xl bg-slate-100 p-4">
    <p class="text-xs text-slate-600">Orders</p>
    <p class="text-lg font-semibold">86</p>
  </div>
  <!-- New customers, Low stock -->
</div>

The question to answer for each screen: if a user looks for three seconds, what is the one thing they should take away? Make that the largest element. Everything else steps down one level.

There is an easy way to test hierarchy. Blur the view, or look at it from across the room. If everything is equally loud, the hierarchy is not there yet.

On type, three size levels (title, body, note) are usually enough. And pick your font on purpose. Using Inter is fine, but if you use it because it appeared by default, you will end up identical to everyone else who did not choose. Try a few alternatives, then commit to one family for the whole project.

Give layout rhythm, not three identical cards

The Features section of an AI landing page is almost always three cards side by side: icon on top, title in the middle, two lines of description underneath. Three features rarely carry equal weight. One is the reason people use the product at all, and the other two are nice extras.

<!-- Before -->
<div class="grid grid-cols-3 gap-6">
  <div class="rounded-2xl bg-indigo-50 p-6 text-center shadow-md">
    <div class="mx-auto h-12 w-12 rounded-full bg-indigo-500"></div>
    <h3>Easy to use</h3>
    <p>An intuitive interface for everyone.</p>
  </div>
  <!-- two more cards with the same structure -->
</div>
<!-- After: one lead feature, two supporting -->
<div class="grid gap-4 md:grid-cols-[2fr_1fr]">
  <article class="row-span-2 rounded-2xl bg-[var(--brand)] p-8 text-white">
    <h3 class="text-2xl font-bold">Record sales without internet</h3>
    <p class="mt-3">Data stays on the phone and syncs by itself when the signal returns.</p>
  </article>
  <article class="rounded-xl bg-[var(--neutral)] p-5">
    <h3 class="font-semibold">Print receipts to a Bluetooth printer</h3>
  </article>
  <article class="rounded-xl bg-[var(--neutral)] p-5">
    <h3 class="font-semibold">Daily report via WhatsApp</h3>
  </article>
</div>

Two things work together. First, card size follows the weight of the content, so the eye knows what is primary. Second, spacing carries information. Elements that sit close together read as one group, so the gap between cards in a group (16px) is deliberately smaller than the gap between page sections (32px).

So spacing is not decided at random. Pick a scale and stick to it. Tailwind's own spacing scale is already built on multiples of 4px, so you only need to commit to a few steps:

:root {
  --s-1: 4px;   /* between an icon and its label */
  --s-2: 8px;
  --s-3: 16px;  /* within a group */
  --s-4: 24px;
  --s-5: 32px;  /* between sections */
  --s-6: 48px;
}

Another tell of an AI default: every element sharing the same corner radius and shadow. If buttons, cards, inputs, and modals are all rounded-2xl shadow-md, nothing looks important.

Write copy for your users, not copy anyone could use

Design is not only how things look. The words inside a screen decide whether it feels deliberate or not, and generic copy is the clearest giveaway. A login form is a good example because almost everyone has seen one:

<!-- Before -->
<h1>Welcome back!</h1>
<p>Enter your details to continue your journey</p>
<input placeholder="Enter your email" />
<button>Submit</button>
<p class="text-red-500">Something went wrong. Please try again.</p>
<!-- After -->
<h1>Sign in to Kasirku</h1>
<p>Use the email you registered for your shop</p>

<label for="email">Shop email</label>
<input id="email" type="email" autocomplete="email"
       aria-invalid="true" aria-describedby="email-error" />
<p id="email-error" role="alert">
  This email isn't registered. Check the spelling, or register your shop.
</p>
<button type="submit">Sign in</button>

The difference comes down to a few habits:

  • Buttons name their action. "Sign in," "Save changes," "Send receipt" — not "Submit." And if the button says "Save," the confirmation says "Saved," not "Success!"
  • Errors say what happened and what to do next. "Something went wrong" gives the user nothing to act on.
  • Labels stay visible. A placeholder disappears the moment someone types and its color is often too pale. Grey #9CA3AF on white measures about 2.54:1; the minimum contrast criterion still applies to placeholders, so #6B7280 at roughly 4.83:1 is the floor.
  • One language. If your users are Indonesian, do not leave stray English strings from a template behind. They are easy to miss and instantly visible.

Before writing any line of text, ask: if this sentence were pasted into a different product, would it still make sense? If yes, it is not specific enough.

Design every state, not just the ideal screen

AI-generated designs usually show one state: full of data, button in its normal look, everything working. Real users run into other states far more often: no data yet, a slow connection, a printer that won't connect, keyboard focus, or a partially filled form.

Designing these states is one of the most effective ways to make a UI feel mature. Start with the button:

.btn {
  background: var(--brand);
  color: #fff;
  border-radius: 999px;
  padding: 0.625rem 1.25rem;
  transition: background-color 150ms;
}
.btn:hover { background: #165C44; }

/* Focus ring for keyboard users */
.btn:focus-visible {
  outline: 3px solid var(--text);
  outline-offset: 3px;
}

.btn[aria-busy="true"] { cursor: progress; }
.btn:disabled {
  background: #E2E8F0;
  color: #64748B;
  cursor: not-allowed;
}

A few notes on that block:

  • Use :focus-visible. This pseudo-class shows a focus indicator only when the browser decides focus should be made evident, such as when a user tabs through the page. W3C documents it as a sufficient technique (C45). Do not delete the outline without replacing it.
  • Check the ring's contrast. Our amber accent looks nice, but against white it measures only about 2:1. WCAG 1.4.11 asks for at least 3:1 for UI components and focus indicators against adjacent colors, which is why the focus ring uses the text color at roughly 14.6:1 instead.
  • Disabled buttons play by their own rules. Inactive components are exempt from the contrast requirement, but they still need to read as "cannot be pressed."

Then the states beyond the button:

  • Loading. Show a skeleton shaped like the real content, not a blank screen or a lone spinner in the middle of the page.
  • Empty. An empty screen is an invitation to act. "No orders yet today" plus a "Record your first sale" button is far more useful than a table with headers and no rows.
  • Error. Name the problem and offer a way out: "Receipt failed to send. Printer not connected," with a "Try again" button.

A quick check before you publish

Before you hit publish, ask yourself five things:

  1. Was this palette chosen from the product's world, and does all the text pass contrast?
  2. If the screen is blurred, is there still one element that clearly stands out?
  3. Is any section a row of identical cards even though the content has different weight?
  4. If this copy were pasted into another product, would it still make sense?
  5. Have hover, keyboard focus, loading, empty, and error states been designed?

Bonus: a prompt that gives direction

If you still use AI to build UI, your results will be far more distinctive when you give it specific constraints. For example:

Build a landing page for Kasirku, a point-of-sale app for small
neighborhood shops.

Palette: cream background #FBF6EC, brand green #1F7A5A, amber accent
#F2A93B (used sparingly), text #1E293B.

Do not use purple-blue gradients and do not use three equal-size
feature cards. Show one lead feature at a large size and two smaller
ones.

Buttons must name their action.
Include hover, focus-visible, loading, disabled, and empty states.
Text contrast must be at least 4.5:1.

A prompt like this does not guarantee a perfect result, but it changes the starting point — from "the internet's average" to "decisions you already made." When a generic instruction lands on generic output, this one shifts most of the defaults before the model renders a single pixel.

A practical way to keep the discipline after that: turn the prompt into a checklist you run on every new screen. The wider set of utilities we use to ship these screens — from on-device image tools to AI video generators for the hero motion — is in our developer tools and AI tools directories. When a good landing page needs a hero video, we like SocialToPrompt for turning reference clips into Veo- or Kling-ready prompts, and VideoSPrompt for picking from a library of working prompts when we do not have a source clip. For the SEO loop that follows a launch, SEONib handles the long-tail article layer in the background. None of these are required for the design fixes above — they sit one layer downstream.

Frequently asked questions

Why does AI-generated UI all look the same?

Because the patterns most common in tutorials and example code show up most often in training data. Without direction, the model converges on the internet's average: indigo to purple gradients, three identical feature cards, a rounded icon tile above every heading. The fix is not to avoid AI — it is to give it decisions that already reflect your product, not the defaults.

Which of the five moves is the highest leverage?

Point 4 — replacing generic copy with copy that only makes sense for your product. It takes about five minutes and the effect is immediate, because visitors read words before they read layouts. Once copy is specific, the visual decisions (palette, hierarchy, layout) feel like they belong to the same product.

Do I still need a designer if I follow this list?

For most landing pages and internal tools, no. The list is specifically designed to be applied by a developer who is not a designer. For a brand-defining first impression, a designer still earns their fee. The five moves bring you from "looks like every other AI site" to "looks like a real product." Going further than that is taste, which is harder to teach.

What is the minimum contrast ratio for normal text?

WCAG Success Criterion 1.4.3 (Level AA) asks for at least 4.5:1 for regular-size text and 3:1 for large text (18px+ or 14px bold). Placeholder text and disabled components have different thresholds — 4.5:1 still applies to placeholders, but disabled UI is exempt from contrast requirements entirely (it still has to read as "not pressable"). UI components and focus indicators are governed by 1.4.11 at 3:1 against adjacent colors.

Will the bonus prompt actually produce a distinctive landing page?

It produces a far better starting point than "make me a landing page for X" — about 60 percent of the defaults are eliminated before the model renders a single pixel. You still have to review what comes back, but the work shifts from rewriting generic output to refining specific output, which is much faster.

Related reading