# What is vibe coding and where does design usually go wrong?

By Thales Andrades Machado · Updated October 23, 2026

> Vibe coding is building software by talking to an AI that writes the code from natural language prompts; Andrej Karpathy coined the term in 2025. On the design side, the usual failures are a generic palette, weak hierarchy, low contrast, missing states, layouts that break on phones, uncontrolled motion and effects that are too heavy.

Vibe coding has become the name for a new way of making software: instead of writing code line by line, you describe what you want to an AI, try the result and ask for changes. It is a fast way to get an idea off the ground, and also the source of visual problems that repeat from project to project. This guide defines the term with sources and walks through the nine most common design mistakes, with a fix for each one.

## What is vibe coding?

Andrej Karpathy coined the term in February 2025, in a post on X, as Martin Fowler records. In Fowler's definition, vibe coding is building a software application by prompting an LLM, telling it what to build, trying it out and prompting for changes, without looking at any of the code the LLM generates. Karpathy's original post talks about fully giving in to the vibes and forgetting that the code even exists.

Google Cloud describes vibe coding as a practice that makes app building more accessible, especially for people with limited programming experience: the main role shifts from writing code line by line to guiding an AI assistant, in conversation, to generate, refine and debug the application. The page separates two forms:

- **Pure vibe coding**: you trust the AI's output with little or no inspection. It suits rapid ideation and what Karpathy called throwaway weekend projects.
- **Responsible AI-assisted development**: the AI acts as a pair programmer, and you review, test and understand the code, taking full ownership of the final product.

Fowler also notes that the term caught on to the point that many people now say "vibe coding" for work where the code does get reviewed. In practice, most people reading this guide sit somewhere between the two.

## Why is design the weak spot of vibe coding?

Three factors add up. First, the model leans toward the most likely pattern: Anthropic's prompting documentation says that, without guidance, models can default to generic patterns that create what users call the "AI slop" aesthetic. Second, each screen tends to start in a different chat, with no shared visual rules. Third, checking stops when the screen works, not when it works well for every person on every device. In pure vibe coding, nobody checks contrast, keyboard focus or the weight of effects, because nobody is reading the code or testing beyond the happy path.

## What are the most common visual mistakes?

| Mistake | What it looks like | Fix |
|---|---|---|
| Generic palette | Purple gradient, colors with no role | Color tokens with defined roles |
| Random spacing | Similar blocks with different gaps | A single spacing scale |
| Weak hierarchy | Everything the same size, or everything highlighted | A type scale and one focal point per screen |
| Low contrast | Light gray on white | 4.5:1 for normal text and 3:1 for large text |
| Missing states | No loading, empty, error or focus state | Ask for each state explicitly |
| Mobile as an afterthought | Sideways scrolling, tiny buttons | Mobile first, 320 px with no sideways scrolling, 24 px targets |
| Uncontrolled motion | Endless animation with no pause | Reduced motion support and a pause control |
| Heavy effects | Slow page, jumping layout | Load on demand and measure Core Web Vitals |
| Patched-on dark mode | Colors inverted without a plan | Tokens for both themes |

## How do you fix each mistake?

### Generic palette

This is the most recognizable symptom: the purple gradient on a white background that Anthropic's own documentation lists as a cliché. The fix is to give every color a role (background, surface, text, secondary text, border, accent, success and error) and store them all as tokens, for example in the Tailwind CSS v4 `@theme` block. A picker like [Anilina](https://vibecode.thmtecnologia.com/en/components/anilina/), which works in OKLCH, shows WCAG contrast against a chosen background and generates a 50 to 950 scale, helps you build the palette. At the top of the page, a slow-moving background in your brand colors, such as [Lusco-fusco](https://vibecode.thmtecnologia.com/en/components/lusco-fusco/), rated Light in the catalog, replaces the default gradient.

### Random spacing

The AI picks a different gap for every block, and the screen loses its rhythm. Define a spacing scale, add a rule to `CLAUDE.md` or to your Cursor rules saying that every margin and padding comes from it, and put more space between groups than inside each group.

### Weak hierarchy

When the heading, subheading and buttons carry similar weight, people do not know where to look. Use a short type scale, one dominant element per screen and heading tags in order, from `h1` to `h6`, without skipping levels, as the Vue accessibility guide recommends.

### Low contrast

Light gray on white looks elegant on a desktop monitor and disappears on a phone in bright sunlight, a case the Vue accessibility guide itself mentions. WCAG 2.2 success criterion 1.4.3, at level AA, requires at least 4.5:1 for normal text and 3:1 for large text. Put the number in your prompt and ask the AI to check every color pair.

### Missing states

The AI delivers the screen with data and with the mouse hovering, and forgets the rest: loading, empty, error, disabled and keyboard focus. WCAG 2.2 success criterion 2.4.7, at level AA, requires keyboard-operable interfaces to have a mode where the focus indicator is visible. For action feedback, a component like [Baralho](https://vibecode.thmtecnologia.com/en/components/baralho/), with success, error, warning, info and loading notices plus an undo action, covers in one go a state that is often missing.

### Mobile as an afterthought

Vibe coding usually happens on a big monitor, and the phone comes later. WCAG success criterion 1.4.10, at level AA, asks for content that works at a width equivalent to 320 CSS pixels without scrolling in two dimensions, and WCAG 2.2 criterion 2.5.8 asks for touch targets of at least 24 by 24 CSS pixels, with some exceptions. Tailwind CSS helps because it is mobile first: unprefixed utilities apply at every screen size, and prefixes like `md:` apply from that breakpoint up. For filters and details on phones, a panel that slides up from the bottom, like [Mezanino](https://vibecode.thmtecnologia.com/en/components/mezanino/), is often more comfortable than a centered modal, and anchored hints like the ones in [Baliza](https://vibecode.thmtecnologia.com/en/components/baliza/) flip sides when they hit the edge of the screen.

### Uncontrolled motion

Animation on everything is tiring and can bother people who are sensitive to motion. The `prefers-reduced-motion` media feature detects when someone has asked their system for less motion, and every effect needs a static or calmer version for that case. On top of that, WCAG success criterion 2.2.2, at level A, requires a way to pause, stop or hide any content that moves on its own, lasts more than five seconds and appears alongside other content, such as autoplaying carousels and endlessly scrolling marquees.

### Effects that are too heavy

A WebGL background, a cursor trail and a 3D image carousel on the same page drag performance down, especially on phones. web.dev counts as a good experience an LCP of 2.5 s or less, an INP of 200 ms or less and a CLS of 0.1 or less. CLS gets worse with images without dimensions, content injected after load and web fonts; the advice is to always set width and height on images and videos, or reserve the space with `aspect-ratio`, and to animate with `transform`. Use at most one heavy effect per page and load it on demand.

### Patched-on dark mode

Asking for "a dark mode" at the end of a project tends to produce colors inverted without a plan and broken contrast somewhere. The `prefers-color-scheme` media feature detects whether someone has asked for a light or dark theme in their operating system or browser settings. Define tokens for both themes from the start and check contrast in both.

## How do you ask the AI to fix it?

Once you have identified the mistakes, ask for the fix with the list in hand. This prompt works in Claude Code and in Cursor:

```text
Run a visual audit of this screen and fix it in this order: 1) replace hard-coded colors with @theme tokens; 2) apply the spacing scale; 3) keep a single focal point; 4) make text contrast at least 4.5:1; 5) add loading, empty, error and visible focus states; 6) test at 320 px with no sideways scrolling and 24 px touch targets; 7) add a prefers-reduced-motion version and a pause button for anything that moves on its own; 8) confirm that LCP, INP and CLS did not get worse. Before each fix, explain the problem in one sentence; afterwards, show a screenshot of the result.
```

If you are pure vibe coding, without reading the code, this audit is the minimum before you publish something other people will use. If you do review the code, it becomes part of the process, like any other test.

## Where do ready-made components help?

Many of these mistakes disappear when the piece arrives already solved. THM Componentes is a catalog of 268 components for Vue 3 and Nuxt, 115 of them exclusive, and each component comes with a prompt ready for Claude Code and Cursor. The exclusive components mentioned here already handle details that AI tends to forget, such as the focus trap and Esc key in [Mezanino](https://vibecode.thmtecnologia.com/en/components/mezanino/) and the input masks and validation for Brazilian tax IDs and postal codes in [Despachante](https://vibecode.thmtecnologia.com/en/components/despachante/). Official support covers Vue 3 and Nuxt; in React, the AI has to convert the code, and the conversion needs review.

For the full finishing method, see [How to make an AI-built app look professional](https://vibecode.thmtecnologia.com/en/guides/how-to-make-an-ai-built-app-look-professional/). To write prompts that avoid these mistakes from the start, see [How to prompt Claude Code and Cursor for a beautiful interface](https://vibecode.thmtecnologia.com/en/guides/how-to-prompt-claude-code-and-cursor-for-a-beautiful-ui/).

## Sources

- [Martin Fowler: Vibe Coding](https://martinfowler.com/bliki/VibeCoding.html)
- [Google Cloud: Vibe Coding Explained: Tools and Guides](https://cloud.google.com/discover/what-is-vibe-coding)
- [Claude Platform Docs: Prompting best practices](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices)
- [Vue.js: Accessibility](https://vuejs.org/guide/best-practices/accessibility)
- [W3C: Understanding Success Criterion 1.4.3: Contrast (Minimum)](https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html)
- [W3C: Understanding Success Criterion 2.4.7: Focus Visible](https://www.w3.org/WAI/WCAG22/Understanding/focus-visible.html)
- [W3C: Understanding Success Criterion 1.4.10: Reflow](https://www.w3.org/WAI/WCAG21/Understanding/reflow.html)
- [W3C: Understanding Success Criterion 2.5.8: Target Size (Minimum)](https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum.html)
- [Tailwind CSS: Responsive design](https://tailwindcss.com/docs/responsive-design)
- [MDN: prefers-reduced-motion CSS media feature](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/prefers-reduced-motion)
- [W3C: Understanding Success Criterion 2.2.2: Pause, Stop, Hide](https://www.w3.org/WAI/WCAG22/Understanding/pause-stop-hide.html)
- [web.dev: Web Vitals](https://web.dev/articles/vitals)
- [web.dev: Optimize Cumulative Layout Shift](https://web.dev/articles/optimize-cls)
- [MDN: prefers-color-scheme CSS media feature](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/prefers-color-scheme)
