uxskill
Star on GitHub
Blog · Italiano · 2026-05-28

Design AI coding — perché ogni AI tira fuori la stessa interfaccia.

Chiunque abbia chiesto a Claude Code, Cursor, Windsurf, GitHub Copilot, Cline o Continue di generare una landing riconosce l'output al primo sguardo: Inter tirato a dimensioni da display, gradiente dal viola al blu, tre card identiche in fila, e sotto l'hero la solita frase «Build something amazing». Il problema non è lo strumento. Il problema è che tutti questi strumenti hanno imparato dallo stesso bacino di template. ux-skill blocca esattamente quei default dentro la CI — senza LLM in mezzo, con 145 regole regex deterministiche.

Gli otto difetti visivi che ogni AI consegna

Abbiamo catalogato l'intera collezione nella tassonomia delle impronte di design AI. Questi otto compaiono praticamente in ogni hero generato:

  1. Inter usato come font da display — un font disegnato per leggibilità su dimensioni piccole, tirato fino a 90 px nell'hero. L'esatto contrario del suo caso d'uso.
  2. Gradiente dal viola al blu — la famiglia #7C3AED → #3B82F6, immancabile come sfondo della prima sezione.
  3. Tre card identiche in linea — icona, titolo di una parola, sottotitolo di una frase, ripetuti tre volte.
  4. Fade-in-up universale — applicato a ogni figlio diretto di ogni sezione, senza distinzione di ruolo.
  5. Tutto centrato — hero, card, form, tutto sull'asse verticale centrale della pagina.
  6. Copy generico — «Build something amazing», «Beautiful experiences», «Revolutionizing X», zero nomi specifici del prodotto.
  7. URL di stock photo — placeholder generici al posto di vere schermate del prodotto.
  8. Ombre pesanti su un design flat — il riflesso «deve risaltare» incontra la moda del flat, e ne esce una profondità visiva confusa.

Ogni difetto preso da solo non è un errore. È la combinazione, gli otto contemporaneamente sulla stessa pagina, a produrre l'impronta riconoscibile. Uno passa con un'alzata di spalle. Quattro nello stesso above-the-fold e si può tirare a indovinare quale tool li ha generati.

Perché i prompt non bastano

La prima reazione di ogni team è infilare istruzioni nel prompt: «niente gradiente di default», «scegli un font da display vero», «non ripetere tre card uguali». Regge per un messaggio. Al successivo, l'indicazione si diluisce, la finestra di contesto si gonfia, e l'impronta riemerge. Guidare via prompt è probabilistico e perde forza con la lunghezza della conversazione.

Quello che serve è un fondo deterministico — un controllo che gira dopo che il modello ha scritto, senza un altro LLM nel loop. È esattamente il buco che ux-skill riempie. Il recommender restringe a monte le scelte del modello; il linter rimanda indietro a valle quello che è passato lo stesso.

Non rispondere allo stocastico con altro stocastico

L'idea «mettiamo un secondo LLM a valutare l'output del primo» rispunta sempre, ma la valutazione via LLM ha la stessa varianza della generazione via LLM: dipende dal prompt di rating, dagli esempi few-shot, dalla versione del modello del giorno. In CI serve uno strato che restituisca lo stesso verdetto ogni volta. Il determinismo è l'unica forza di una regex, e qui è più che sufficiente.

145 regole regex, niente LLM, dentro la CI

Il linter scansiona ogni file in *.tsx, *.jsx, *.vue, *.svelte, *.astro, *.css, *.scss, *.html. Applica 145 espressioni regolari con i flag i e m. Restituisce JSON con ID della regola, severità, file, riga, colonna, estratto e la correzione suggerita.

# Lint locale, gate di default su high+critical
$ uxskill lint
[OK] Scanned 142 files in 412ms · 0 findings at threshold high

# Sottocartella + JSON
$ uxskill lint apps/web/src --json | jq '.summary'
{
  "critical": 0,
  "high": 4,
  "medium": 11,
  "low": 3,
  "total": 18
}

Zero chiamate a LLM. La scansione media su un repository Next.js da 200 file è di 380 ms a freddo, 90 ms a caldo. La descrizione completa delle regole è nella guida al regex linter.

Prima e dopo, su un hero reale

Qui sotto un blocco hero semplificato preso da uno starter Next.js, che cade in tre regole, e la versione riscritta che esce con exit 0. Stessa intenzione di conversione, impronta diversa.

// Prima — 3 finding high
<section className="bg-gradient-to-br
  from-purple-500 via-violet-500
  to-blue-500 py-32">
  <h1 className="font-['Inter']
    text-7xl leading-none">
    Build something amazing.
  </h1>
  <div className="grid grid-cols-3 gap-6">
    <Card icon="Zap" title="Fast" />
    <Card icon="Shield" title="Safe" />
    <Card icon="Heart" title="Loved" />
  </div>
</section>

// Dopo — 0 finding
<section className="bg-stone-50 py-28">
  <h1 className="font-['Fraunces']
    text-6xl leading-[1.04]
    tracking-tight">
    Il livello di routing del carico
    che il tuo TMS non ha mai spedito.
  </h1>
  <div className="grid grid-cols-12 gap-6 mt-16">
    <Card className="col-span-7"
      title="Consolidamento spedizioni" />
    <Card className="col-span-5"
      title="Ranking trasportatori" />
  </div>
</section>

Nel «prima» scattano tre regole: Inter su text-7xl, il gradiente canonico dell'AI, e la griglia di tre card identiche. Nel «dopo» Fraunces (display) si accoppia a Inter (corpo), la superficie diventa piatta, e la griglia passa a un asimmetrico 7-e-5. L'intenzione è la stessa, l'impronta è sparita.

Il recommender alza il pavimento. Il linter abbassa il soffitto. Servono entrambi.

Mettere un design system serio dentro Claude Code

Claude Code è il terreno nativo di ux-skill. L'installazione dal marketplace sta in due righe:

# Plugin marketplace di Claude Code
$ /plugin marketplace add Laith0003/ux-skill
$ /plugin install ux@ux-skill

Una volta installato, 22 comandi slash si registrano nella sessione di Claude Code. /ux-discover raccoglie un brief in 10 campi via domande mirate, /ux-recommend lancia cinque ricerche in parallelo (industria, stile, palette, tipografia, motion), e /ux-persist save scrive MASTER.md, tokens.css e manifest.json nella root del repository. Una volta su disco, questi file vengono letti da Claude Code in ogni sessione successiva.

Per Cursor il percorso è .cursorrules + server MCP, comando uxskill init --target cursor. Per Windsurf, .windsurfrules + MCP, uxskill init --target windsurf. Per GitHub Copilot, ux-skill genera .github/copilot-instructions.md e collega il linter su disco via uxskill init --target copilot.

Tre percorsi di installazione, un solo motore

Lo stesso pacchetto Python raggiunge i 17 IDE della matrice di compatibilità. Scegli il percorso più vicino al tuo editor:

Editor Percorso Comando
Claude CodeMarketplace/plugin install ux@ux-skill
Cursor.cursorrules + MCPuxskill init --target cursor
Windsurf.windsurfrules + MCPuxskill init --target windsurf
GitHub Copilotcopilot-instructions.mduxskill init --target copilot
Cline / ContinueServer MCPuxskill mcp-config --target cline
JetBrains AI Assistant.junie/guidelines.mduxskill init --target jetbrains
ZedMCP stdiouxskill init --target zed
Codex CLI / AiderCLI direttapip install uxskill

Sotto ogni percorso lo stesso pacchetto: 1.182 voci di catalogo, 145 regole, 131 specifiche di brand, 22 comandi, 75 test verdi a ogni release.

Perimetro onesto

Le regole prendono la struttura. Non prendono il gusto.

Il linter non segnalerà mai «questa sezione ha un ritmo sbagliato» o «questo copy suona freddo». Quello è lavoro di una persona, o di un LLM in fase di review. Quello che la regex cattura in modo affidabile è ogni impronta esprimibile come token letterale, pattern o forma — vale a dire la maggior parte dei default dell'AI, perché il modello torna sempre allo stesso artefatto.

Non facciamo girare un LLM-giudice nella CI, intenzionalmente. Se il tuo metro è «sembra fatto da un designer», quella è una code review, non un lint. ux-skill mette a disposizione ux critique per quel passaggio, ma gira on demand nell'editor, non nella CI.

Letture correlate

Installa

17 IDE. Un solo motore. 145 regole.

Recommender, linter, server MCP, 22 comandi, 131 specifiche di brand e 1.182 voci di catalogo viaggiano insieme. Il linter gira sotto il secondo, il resto on demand. MIT, niente telemetria, niente account.

$ /plugin marketplace add Laith0003/ux-skill
$ /plugin install ux@ux-skill
— oppure —
$ pip install uxskill
— oppure —
$ npx uxskill@alpha init