A thread on V2EX kicked off with a simple prompt: what does "AI smell" actually look like in a UI?
The replies got specific fast. Over-large corner radii and rounded cards everywhere. Shadow soup. Fake-tech glow effects. A big icon on the left with a giant heading on the right. Oversized number dashboards. Metric cards lined up four to six across. Subtitles and explanatory text in places nobody asked for. And the one that stuck with me: a button labeled "Test Connection" with a line of helper text next to it reading "test whether your API connection works."
Most of these threads turn into a taste argument. Someone says frosted glass is the tell, someone else says no, frosted glass was everywhere in old personal blogs, the real tell is a purple theme. That's fun, but it doesn't ship anything. The more interesting move is to take the parts of the list that are structural and mechanical, and build something that checks for them on demand.
The signal worth extracting
Not every item on the list is machine-checkable. "Looks premium but has nothing to do with the actual business" is a judgment call. "Pseudo-tech glow" is close to one. But a surprising number of the tells are just patterns in the markup and inline styles:
- Corner radius above some threshold, applied widely
- Multiple stacked box-shadows, or shadows on nearly every block
- A row of four to six metric cards with the same structure
- Helper text sitting right next to a button that already has a clear label
- Thin-weight small text near headings with unusually wide letter-spacing
- Gradients applied to many surfaces at once
One commenter made a point that goes deeper than aesthetics: the generated UI is "full" in the happy path and empty on failure. "Test Connection" works great until it fails, and then all you get is "operation failed" with no indication of whether it was a timeout, a bad address, or an auth problem. That's not something a style scanner can catch, but it's worth naming in the report as a known blind spot. The auditor flags surface patterns. It does not evaluate whether error states are actually useful.
What a builder can assemble here
The shape of this is a small service, not a product. You feed it a page's HTML, it parses the markup and inline styles, scores each heuristic against a rule table, and hands back a report. Three pieces cover it.
The scanner itself is Python. You can run Python online to parse the markup, walk the element tree, count rounded cards, tally shadow declarations, detect the four-to-six metric-card row, and check for button labels that are shadowed by adjacent helper text. Each check returns a hit count and the offending snippets, not just a boolean, because "you have 11 cards with 24px radius" is far more actionable than "rounded corners: yes."
The rules live in a database rather than hard-coded in the scanner, which matters more than it sounds. Thresholds are opinions. One team thinks a 16px radius is fine; another wants to flag anything over 8px. Keeping each rule as a row — pattern, threshold, weight, severity, a short note — means you can tune the auditor without touching the Python. A SQLite editor lets you hand-edit those rows directly: bump the radius threshold, lower the weight on gradients because your brand actually uses them, disable the letter-spacing check entirely. The scanner reads the table at runtime, so a tweak takes effect on the next scan.
The output is a page. Once the scan produces a score and a list of hits, you render it as a report and run HTML online so each audit has a shareable URL. Group the findings by severity, show the matched snippets inline, and put the total score up top with a clear caveat. A reviewer can open the link, see exactly which elements tripped which rule, and decide what's worth changing.
The boundary, stated plainly
Here's the part that keeps this honest: a structural scanner can tell you a page has eleven rounded cards, six metric tiles in a row, and shadows on nearly every block. It cannot tell you the design is bad. Those two things are not the same. A dashboard with six metric cards might be exactly right for the data. A generous corner radius might be a deliberate brand choice. The checklist from the thread is a set of correlations people noticed, not laws of good design.
So the auditor should present itself as a pattern detector, not a judge. The score is a prompt for a human to look harder at specific elements, not a verdict. If you dress it up as an authority — big number, confident grade, no caveats — you've built the exact thing the thread was complaining about: a UI that looks precise and premium while quietly overstating what it knows. The report that says "here are the patterns we found, you decide if they're a problem" is more useful and more honest than one that says "your design is 62% AI."
Why this is worth building at all
The practical value shows up in review. A commenter in the thread admitted their own vibe-coded app ended up stuffed with explanatory text the model added on its own, and they still haven't cleaned it all out. That's the common case. The generated page looks plausible, you ship it, and the tells accumulate quietly. A quick scan before a page goes out catches the mechanical ones — the redundant helper text, the shadow pile-up, the metric-card row that nobody decided on — and leaves the taste calls to you.
It's a weekend-sized tool with a tight scope: parse, score against an editable table, publish a report, and keep the boundary visible. The checklist did the hard part by being specific. Turning it into something you can run on a URL is mostly plumbing, and the plumbing is the point.