| name | design-engineer |
| description | Universal design intelligence that makes any LLM — from 0.4B to frontier — produce premium-grade visual interfaces that look like they were designed by someone who charges $200/hr, not generated by AI. Encodes the visual craft, atmosphere, and depth that separate professional design from template output. Trigger when the user asks to design, build, style, prototype, or create ANY visual interface: landing pages, dashboards, components, apps, forms, cards, presentations, brand assets, or any UI. Also trigger for design reviews, accessibility audits, responsive layouts, dark mode, theming, design systems, or making existing UI look better. Even vague requests like "make it pretty", "build me a page", "style this", "it looks boring", or "make it premium" should trigger this skill. If the output will be seen by human eyes, this skill applies.
|
Design Engineer
You think like a designer. You build like an engineer. You ship like someone whose reputation is on the line.
The problem with most AI-generated UI isn't that it's wrong — it's that it's lifeless. It follows the rules but misses the soul. It looks like a template because it was built like a checklist instead of crafted like a product.
This skill fixes that. It teaches you not just correctness but visual craft — the atmosphere, depth, confidence, and restraint that make people say "who designed this?" instead of "did AI make this?"
Three laws:
- Understand before you build.
- Create atmosphere, not just layout.
- Verify with your eyes, not just your checklist.
Quick Start — For Any LLM
If you can only absorb one thing from this entire skill, absorb this. Copy this HTML skeleton and customize it. Every premium pattern is baked in — ambient gradients, glass cards, confident type, proper spacing, hover states, responsive, accessible. Even a basic LLM produces stunning output just by filling in this template.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PAGE_TITLE</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<style>
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--brand: #6366f1;
--brand-hover: #4f46e5;
--brand-active: #4338ca;
--brand-subtle: rgba(99, 102, 241, 0.1);
--brand-glow: rgba(99, 102, 241, 0.15);
--bg-primary: #09090b;
--bg-surface: #18181b;
--bg-raised: #27272a;
--bg-overlay: rgba(24, 24, 27, 0.8);
--text-primary: #fafafa;
--text-secondary: #a1a1aa;
--text-tertiary: #71717a;
--border: rgba(255, 255, 255, 0.08);
--border-strong: rgba(255, 255, 255, 0.15);
--font-heading: 'Inter', system-ui, -apple-system, sans-serif;
--font-body: 'Inter', system-ui, -apple-system, sans-serif;
--space-xs: 4px;
--space-sm: 8px;
--space-md: 16px;
--space-lg: 24px;
--space-xl: 32px;
--space-2xl: 48px;
--space-3xl: 64px;
--space-4xl: 96px;
--space-5xl: 128px;
--radius-sm: 8px;
--radius-md: 12px;
--radius-lg: 16px;
--radius-xl: 24px;
--radius-pill: 9999px;
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
--ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
}
.light {
--bg-primary: #fafafa;
--bg-surface: #ffffff;
--bg-raised: #f4f4f5;
--bg-overlay: rgba(255, 255, 255, 0.8);
--text-primary: #18181b;
--text-secondary: #71717a;
--text-tertiary: #a1a1aa;
--border: #e4e4e7;
--border-strong: #d4d4d8;
}
html { scroll-behavior: smooth; }
body {
font-family: var(--font-body);
font-size: 1rem;
line-height: 1.6;
color: var(--text-primary);
background-color: var(--bg-primary);
background-image:
radial-gradient(ellipse 80% 50% at 50% -20%, var(--brand-glow), transparent),
radial-gradient(ellipse 60% 40% at 80% 50%, rgba(168, 85, 247, 0.08), transparent);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.light body {
background-image:
radial-gradient(ellipse 80% 50% at 50% 0%, rgba(99, 102, 241, 0.04), transparent);
}
body::before {
content: '';
position: fixed;
inset: 0;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.03'/%3E%3C/svg%3E");
pointer-events: none;
z-index: 9999;
}
h1, h2, h3, h4 { font-family: var(--font-heading); }
.display {
font-size: clamp(2.5rem, 5vw, 3.75rem);
font-weight: 800;
line-height: 1.0;
letter-spacing: -0.03em;
}
h1 { font-size: clamp(2rem, 4vw, 3rem); font-weight: 700; line-height: 1.1; letter-spacing: -0.025em; }
h2 { font-size: clamp(1.5rem, 3vw, 1.875rem); font-weight: 600; line-height: 1.2; letter-spacing: -0.02em; }
h3 { font-size: 1.25rem; font-weight: 600; line-height: 1.4; }
.body-lg { font-size: 1.125rem; line-height: 1.7; }
.caption { font-size: 0.75rem; font-weight: 500; letter-spacing: 0.05em; text-transform: uppercase; }
.gradient-text {
background: linear-gradient(135deg, #6366f1, #a855f7, #ec4899);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.hero-text-fade {
background: linear-gradient(180deg, #ffffff 0%, rgba(255,255,255,0.7) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.container { width: 100%; max-width: 1280px; margin: 0 auto; padding: 0 var(--space-lg); }
.text-container { max-width: 36rem; }
section { padding: var(--space-3xl) 0; }
.hero { padding: var(--space-5xl) 0 var(--space-4xl); text-align: center; }
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-lg); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-lg); }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-lg); }
.flex-center { display: flex; align-items: center; justify-content: center; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.stack { display: flex; flex-direction: column; gap: var(--space-md); }
nav {
position: fixed;
top: 0; width: 100%; z-index: 50;
height: 64px;
display: flex; align-items: center; justify-content: space-between;
padding: 0 var(--space-lg);
background: var(--bg-overlay);
backdrop-filter: blur(16px) saturate(180%);
-webkit-backdrop-filter: blur(16px) saturate(180%);
border-bottom: 1px solid var(--border);
}
nav a { color: var(--text-secondary); text-decoration: none; font-size: 0.9375rem; font-weight: 500;
transition: color 0.2s ease; }
nav a:hover { color: var(--text-primary); }
.nav-links { display: flex; gap: var(--space-xl); align-items: center; }
.nav-logo { font-weight: 700; font-size: 1.125rem; color: var(--text-primary); text-decoration: none; }
.card {
background: rgba(255, 255, 255, 0.03);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: var(--space-xl);
transition: all 0.3s var(--ease-smooth);
}
.card:hover {
background: rgba(255, 255, 255, 0.05);
border-color: var(--border-strong);
transform: translateY(-2px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}
.light .card {
background: #ffffff;
backdrop-filter: none;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.02);
}
.light .card:hover {
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06), 0 2px 8px rgba(0, 0, 0, 0.04);
}
.card-featured {
position: relative;
border: 1px solid rgba(99, 102, 241, 0.3);
background: rgba(99, 102, 241, 0.05);
}
.card-featured::before {
content: '';
position: absolute;
inset: -1px;
border-radius: inherit;
padding: 1px;
background: linear-gradient(135deg, #6366f1, #a855f7);
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
}
.btn-primary {
display: inline-flex;
align-items: center;
justify-content: center;
height: 56px;
padding: 0 32px;
font-size: 1rem;
font-weight: 600;
font-family: inherit;
letter-spacing: -0.01em;
color: #ffffff;
background: linear-gradient(135deg, var(--brand), #8b5cf6);
border: none;
border-radius: 14px;
cursor: pointer;
position: relative;
transition: all 0.25s var(--ease-smooth);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
text-decoration: none;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px var(--brand-glow), 0 2px 8px rgba(0, 0, 0, 0.12);
}
.btn-primary:active {
transform: translateY(0) scale(0.98);
transition-duration: 0.1s;
}
.btn-primary:focus-visible {
outline: none;
box-shadow: 0 0 0 3px var(--bg-primary), 0 0 0 5px var(--brand);
}
.btn-primary svg { margin-left: 8px; transition: transform 0.2s ease; }
.btn-primary:hover svg { transform: translateX(3px); }
.btn-secondary {
display: inline-flex;
align-items: center;
justify-content: center;
height: 48px;
padding: 0 24px;
font-size: 0.9375rem;
font-weight: 500;
font-family: inherit;
color: var(--text-primary);
background: transparent;
border: 1px solid var(--border-strong);
border-radius: var(--radius-md);
cursor: pointer;
transition: all 0.2s ease;
text-decoration: none;
}
.btn-secondary:hover {
background: rgba(255, 255, 255, 0.05);
border-color: rgba(255, 255, 255, 0.25);
}
.light .btn-secondary:hover {
background: #f4f4f5;
border-color: #a1a1aa;
}
.btn-ghost {
display: inline-flex;
align-items: center;
height: 40px;
padding: 0 16px;
font-size: 0.875rem;
font-weight: 500;
font-family: inherit;
color: var(--text-secondary);
background: transparent;
border: none;
border-radius: var(--radius-sm);
cursor: pointer;
transition: all 0.15s ease;
text-decoration: none;
}
.btn-ghost:hover { color: var(--text-primary); background: rgba(255, 255, 255, 0.06); }
.cta-group { display: flex; gap: var(--space-md); align-items: center; flex-wrap: wrap; }
.cta-group.center { justify-content: center; }
input, textarea, select {
width: 100%;
height: 48px;
padding: 0 16px;
font-size: 0.9375rem;
font-family: inherit;
color: var(--text-primary);
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 10px;
outline: none;
transition: all 0.2s ease;
}
input:focus, textarea:focus, select:focus {
border-color: var(--brand);
box-shadow: 0 0 0 3px var(--brand-subtle);
}
textarea { height: 120px; padding: 14px 16px; resize: vertical; }
label { display: block; font-size: 0.875rem; font-weight: 500; margin-bottom: 6px; color: var(--text-secondary); }
.badge {
display: inline-flex; align-items: center;
padding: 4px 12px;
font-size: 0.75rem; font-weight: 600;
letter-spacing: 0.02em;
border-radius: var(--radius-pill);
background: var(--brand-subtle);
color: var(--brand);
}
.divider {
height: 1px;
background: linear-gradient(90deg, transparent, var(--border-strong), transparent);
border: none;
margin: var(--space-3xl) 0;
}
table { width: 100%; border-collapse: collapse; }
th { text-align: left; font-size: 0.75rem; font-weight: 600; text-transform: uppercase;
letter-spacing: 0.05em; color: var(--text-tertiary); padding: 12px 16px;
border-bottom: 1px solid var(--border-strong); }
td { padding: 16px; border-bottom: 1px solid var(--border); color: var(--text-secondary);
font-size: 0.9375rem; }
tr:hover td { background: rgba(255, 255, 255, 0.02); }
.light tr:hover td { background: #f9fafb; }
td:last-child, th:last-child { text-align: right; }
.avatar { width: 40px; height: 40px; border-radius: 50%; object-fit: cover;
border: 2px solid var(--border); }
.avatar-lg { width: 56px; height: 56px; }
[data-tooltip] { position: relative; cursor: help; }
[data-tooltip]:hover::after {
content: attr(data-tooltip);
position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%);
padding: 6px 12px; margin-bottom: 8px;
font-size: 0.75rem; font-weight: 500; white-space: nowrap;
color: var(--text-primary); background: var(--bg-raised);
border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
z-index: 100;
}
.fade-in {
opacity: 0; transform: translateY(20px);
transition: all 0.6s var(--ease-out);
}
.fade-in.visible { opacity: 1; transform: translateY(0); }
.fade-in:nth-child(2) { transition-delay: 0.1s; }
.fade-in:nth-child(3) { transition-delay: 0.2s; }
.fade-in:nth-child(4) { transition-delay: 0.3s; }
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-8px); }
}
@keyframes pulse-glow {
0%, 100% { box-shadow: 0 0 0 0 var(--brand-glow); }
50% { box-shadow: 0 0 20px 4px var(--brand-glow); }
}
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
@media (max-width: 1024px) {
.grid-4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
.grid-3 { grid-template-columns: 1fr; }
.grid-4 { grid-template-columns: 1fr; }
section { padding: var(--space-2xl) 0; }
.hero { padding: var(--space-4xl) 0 var(--space-3xl); }
.nav-links { display: none; }
}
@media (max-width: 640px) {
.grid-2 { grid-template-columns: 1fr; }
.btn-primary, .btn-secondary { width: 100%; }
.cta-group { flex-direction: column; }
.container { padding: 0 var(--space-md); }
}
</style>
</head>
<body>
<nav>
<a href="#" class="nav-logo">BRAND</a>
<div class="nav-links">
<a href="#features">Features</a>
<a href="#pricing">Pricing</a>
<a href="#" class="btn-primary" style="height:40px; padding:0 20px; font-size:0.875rem;">Get started</a>
</div>
</nav>
<section class="hero" style="padding-top: 160px;">
<div class="container" style="max-width: 800px;">
<div class="badge" style="margin-bottom: 24px;">Now in Beta</div>
<h1 class="display hero-text-fade">Your headline goes here</h1>
<p class="body-lg" style="color: var(--text-secondary); max-width: 32rem; margin: 24px auto 40px;">
One or two sentences that explain the value. Keep it short. Users scan, they don't read.
</p>
<div class="cta-group center">
<a href="#" class="btn-primary">
Start building free
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8h10m-4-4l4 4-4 4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
</a>
<a href="#" class="btn-secondary">Watch demo</a>
</div>
</div>
</section>
<section id="features">
<div class="container">
<div style="text-align:center; margin-bottom: 48px;">
<h2>Everything you need</h2>
<p style="color: var(--text-secondary); margin-top: 12px;">Subtitle that adds context.</p>
</div>
<div class="grid-3">
<div class="card fade-in">
<div style="width:48px; height:48px; border-radius:12px; background:var(--brand-subtle); display:flex; align-items:center; justify-content:center; margin-bottom:20px; color:var(--brand); font-size:1.25rem;">★</div>
<h3>Feature One</h3>
<p style="color: var(--text-secondary); margin-top: 8px;">Short description of the feature and why it matters.</p>
</div>
<div class="card fade-in">
<div style="width:48px; height:48px; border-radius:12px; background:var(--brand-subtle); display:flex; align-items:center; justify-content:center; margin-bottom:20px; color:var(--brand); font-size:1.25rem;">⚡</div>
<h3>Feature Two</h3>
<p style="color: var(--text-secondary); margin-top: 8px;">Short description of the feature and why it matters.</p>
</div>
<div class="card fade-in">
<div style="width:48px; height:48px; border-radius:12px; background:var(--brand-subtle); display:flex; align-items:center; justify-content:center; margin-bottom:20px; color:var(--brand); font-size:1.25rem;">✓</div>
<h3>Feature Three</h3>
<p style="color: var(--text-secondary); margin-top: 8px;">Short description of the feature and why it matters.</p>
</div>
</div>
</div>
</section>
<section style="background: var(--brand-subtle); border-top: 1px solid rgba(99,102,241,0.2); border-bottom: 1px solid rgba(99,102,241,0.2);">
<div class="container" style="text-align:center; max-width: 640px;">
<h2>Ready to get started?</h2>
<p style="color: var(--text-secondary); margin: 12px 0 32px;">Join thousands of teams already building with us.</p>
<a href="#" class="btn-primary">Start building free
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8h10m-4-4l4 4-4 4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
</a>
</div>
</section>
<footer style="padding: 48px 0 24px; border-top: 1px solid var(--border);">
<div class="container flex-between" style="flex-wrap:wrap; gap:16px;">
<span style="color: var(--text-tertiary); font-size: 0.875rem;">© 2025 Brand. All rights reserved.</span>
<div style="display:flex; gap:24px;">
<a href="#" style="color: var(--text-tertiary); font-size: 0.875rem; text-decoration:none;">Privacy</a>
<a href="#" style="color: var(--text-tertiary); font-size: 0.875rem; text-decoration:none;">Terms</a>
</div>
</div>
</footer>
<script>
const observer = new IntersectionObserver((entries) => {
entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('visible'); observer.unobserve(e.target); } });
}, { threshold: 0.1 });
document.querySelectorAll('.fade-in').forEach(el => observer.observe(el));
</script>
</body>
</html>
How to use this template: Replace BRAND, PAGE_TITLE, headlines, body text, and feature content. Change --brand color. Add class="light" to <html> for light theme. That's it — you'll have a page that looks designed, not generated.
For more patterns (dashboard, form, pricing, etc.), see references/starter-templates.md.
Phase 1 — Understand
Before writing code, answer four questions:
| Question | If unspecified |
|---|
| What is being built? | Infer from context |
| Who sees it? | General users who scan, not read |
| What mood? | Modern, premium, subtly sophisticated |
| Constraints? | Accessible, responsive, performant |
State your assumptions in one sentence. Don't over-interrogate — move.
Phase 2 — Design Metrics (Set Before You Build)
This is what separates engineered design from guesswork. Before writing any CSS, define measurable targets. These are your spec — you will verify against them in Phase 6.
Required Metrics (set all of these)
| Metric | Target | Why |
|---|
| Hero headline size | ≥ 48px (desktop), ≥ 32px (mobile) | Confidence. Most AI uses 36px — that's the template tell. |
| Section padding | ≥ 64px (desktop), ≥ 40px (mobile) | Breathing room. Cramped = cheap. |
| CTA height | ≥ 48px | Touch-friendly + visually substantial. See references/cta-buttons.md |
| CTA border-radius | ≥ 12px or pill (9999px) | Rounded = clickable. Sharp corners = 2015. |
| Body max-width | ≤ 36rem (576px) for text blocks | Readability. 65-75 chars per line. |
| Color contrast | ≥ 4.5:1 (text), ≥ 3:1 (large text) | WCAG AA. Non-negotiable. |
| Interactive states | hover + focus + active on 100% of clickable elements | If it's clickable, it must react. |
| Background type | radial gradient(s), NEVER flat color | Atmosphere. The #1 tell of AI-generated UI. |
| Card style | glass (dark) or elevated (light), NEVER flat | Depth. Cards must feel like they float. |
Font Selection (choose by mood, not by default)
Do NOT default to Inter for everything. Pick a font that matches the product's personality. See references/typography.md for the full guide.
| Mood | Heading Font | Body Font | When to Use |
|---|
| Tech / SaaS | Inter, Geist | Inter, Geist | Developer tools, clean dashboards |
| Bold / Confident | Plus Jakarta Sans | Inter, Plus Jakarta Sans | Startups, product launches |
| Editorial / Premium | DM Serif Display, Playfair Display | DM Sans, Inter | Luxury, editorial, agencies |
| Friendly / Warm | DM Sans, Outfit, Nunito | Same family | Consumer apps, community tools |
| FinTech / Trust | Space Grotesk, Manrope | Same family | Banking, finance, data products |
| Minimal / Luxe | system-ui, Instrument Sans | Same family | Luxury brands, minimalist products |
Write your choices down:
METRICS:
headline_size: [value]px
section_padding: [value]px
cta_height: [value]px
cta_radius: [value]px
font_heading: [font name]
font_body: [font name]
mood: [mood from table]
theme: [light / dark]
Phase 3 — Creative Direction
Make three binding decisions. Everything you build traces back to these.
Decision 1: Color — Build an Atmosphere, Not a Palette
Generic AI output picks "a blue" and some grays. Premium design builds a color atmosphere — a coordinated environment where every surface, glow, shadow, and accent feels like it belongs to the same world.
For dark themes:
--bg-primary: #09090b;
--bg-surface: #18181b;
--bg-raised: #27272a;
--bg-overlay: rgba(24, 24, 27, 0.8);
--text-primary: #fafafa;
--text-secondary: #a1a1aa;
--text-tertiary: #71717a;
--border: rgba(255, 255, 255, 0.08);
--border-strong: rgba(255, 255, 255, 0.15);
For light themes:
--bg-primary: #fafafa;
--bg-surface: #ffffff;
--bg-subtle: #f4f4f5;
--text-primary: #18181b;
--text-secondary: #71717a;
--text-tertiary: #a1a1aa;
--border: #e4e4e7;
--border-strong: #d4d4d8;
Brand color system — derive from ONE primary. See references/color-systems.md for full palette generation.
--brand: #6366f1;
--brand-hover: #4f46e5;
--brand-active: #4338ca;
--brand-subtle: rgba(99, 102, 241, 0.1);
--brand-glow: rgba(99, 102, 241, 0.15);
The 60-30-10 rule: 60% neutral backgrounds, 30% surface/text, 10% brand accent.
Decision 2: Typography — Be Confident, Be Intentional
Generic AI uses safe, small type with Inter everywhere. Premium design picks fonts by mood and uses large, confident type with dramatic size contrast.
Step 1: Pick your mood from the Phase 2 font table. Load the fonts:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=[Your+Font]:wght@400;500;600;700;800&display=swap" rel="stylesheet">
Step 2: Apply the premium type scale:
Display: 3.75rem (60px) — weight 700-800, line-height 1.0, tracking -0.03em
This is the single biggest visual upgrade for any page.
H1: 3rem (48px) — weight 700, line-height 1.1, tracking -0.025em
H2: 1.875rem (30px) — weight 600, line-height 1.2, tracking -0.02em
H3: 1.25rem (20px) — weight 600, line-height 1.4
Body: 1rem (16px) — weight 400, line-height 1.6
Small: 0.875rem (14px) — weight 400, line-height 1.5
Caption: 0.75rem (12px) — weight 500, tracking +0.05em
The key: the ratio between your largest and smallest text creates drama. Hero 60px / body 16px = 3.75:1. That's the confidence premium sites have.
For editorial mood, pair a serif heading with a sans body:
h1, h2, .display { font-family: 'DM Serif Display', Georgia, serif; }
body, p, .body { font-family: 'DM Sans', system-ui, sans-serif; }
Decision 3: Spacing — Be Generous
Generic AI is cramped. Premium design breathes. White space is the frame that makes content feel important.
4px — hairline (icon-to-label)
8px — tight (compact button padding, chip elements)
12px — within elements (input padding)
16px — between related items (form fields)
24px — between groups within a section
32px — between distinct groups
48px — minimum section spacing
64px — standard section padding
96px — hero/footer padding
128px — dramatic breathing room (above-fold hero)
The premium move: when in doubt, double the spacing. Most AI uses 48px between sections — premium sites use 80–128px.
Phase 4 — Build the Skeleton
Before polish, get the bones right:
- Content inventory — every text element including empty, loading, error, success states
- Layout skeleton — columns, navigation, action placement, visual hierarchy order
- Component inventory — be specific: "primary gradient CTA 56px, secondary glass button 48px, ghost icon button 40px"
Use the Quick Start template above as your skeleton, or see references/starter-templates.md for dashboard, form, pricing, and other page skeletons.
For layout patterns (sidebar + content, holy grail, split hero), see references/layouts.md.
Phase 5 — Build with Craft
This is where premium diverges from correct. The Quick Start template has all these patterns baked in, but here's why each one matters and how to customize them.
The Premium Background
Never use a flat color background. This is the #1 tell of AI-generated UI. Premium sites layer ambient depth:
body {
background-color: #09090b;
background-image:
radial-gradient(ellipse 80% 50% at 50% -20%, rgba(99, 102, 241, 0.15), transparent),
radial-gradient(ellipse 60% 40% at 80% 50%, rgba(168, 85, 247, 0.08), transparent);
}
body {
background-color: #fafafa;
background-image:
radial-gradient(ellipse 80% 50% at 50% 0%, rgba(99, 102, 241, 0.04), transparent);
}
This single technique — ambient radial gradient — transforms a page from template to crafted.
Glass Cards
.card {
background: rgba(255, 255, 255, 0.03);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.06);
border-radius: 16px;
padding: 32px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.card:hover {
background: rgba(255, 255, 255, 0.05);
border-color: rgba(255, 255, 255, 0.1);
transform: translateY(-2px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}
.card {
background: #ffffff;
border: 1px solid #e4e4e7;
border-radius: 16px;
padding: 32px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.02);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.card:hover {
border-color: #d4d4d8;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06), 0 2px 8px rgba(0, 0, 0, 0.04);
transform: translateY(-2px);
}
Premium CTAs — The Money Button
Read references/cta-buttons.md for the full CTA science. Here's the essentials:
CTA Copy Formula: [Action Verb] + [Value/Outcome]
Weak: Submit, Click here, Learn more
Strong: Start building free, Get your report, Open an account
Premium: Start writing smarter →, Ship your first site →, Automate your workflow →
CTA with trailing arrow — add → or an SVG arrow that slides right on hover. This tiny detail signals "this takes you forward."
Glass Navigation
nav {
position: fixed;
top: 0; width: 100%; z-index: 50;
height: 64px;
display: flex; align-items: center; justify-content: space-between;
padding: 0 24px;
background: rgba(9, 9, 11, 0.7);
backdrop-filter: blur(16px) saturate(180%);
-webkit-backdrop-filter: blur(16px) saturate(180%);
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
Gradient Text — The Premium Signature
.gradient-text {
background: linear-gradient(135deg, #6366f1, #a855f7, #ec4899);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
Use on the hero headline or one section title. Never body text.
Subtle Grain Texture
body::before {
content: '';
position: fixed;
inset: 0;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.03'/%3E%3C/svg%3E");
pointer-events: none;
z-index: 9999;
}
Content Craft
Buttons: Use the CTA Copy Formula. "Start building free →", "Send message →", "Get your report" — NEVER "Submit", "Click here", "Learn more".
Errors: "[What happened] + [How to fix]" — "Email needs @ and a domain"
Empty states: explain + guide + action button. Never "No data found."
Social proof: "Trusted by 10,000+ teams" + logo bar. Specific numbers > vague claims.
Loading: Use skeleton shimmer, never a spinner alone. See references/components.md.
Responsive
@media (min-width: 640px) { }
@media (min-width: 768px) { }
@media (min-width: 1024px) { }
Key responsive rules:
- Hero text:
clamp(2.25rem, 5vw, 3.75rem) — scales fluidly, no breakpoints needed
- Section padding: reduce ~40% on mobile (96px → 56px)
- CTA: full-width on mobile, maintain ≥ 48px height
- Nav: glass top bar → hamburger drawer on mobile
- Grids: 3-col → 1-col on mobile, 4-col → 2-col → 1-col
For detailed responsive patterns and mobile navigation, see references/responsive.md.
Phase 6 — Verify Against Your Metrics
Go back to the metrics you set in Phase 2. Check every single one. This is not optional.
Metric Verification Checklist
METRICS CHECK:
[ ] headline_size — measure the actual computed px. Is it ≥ your target?
[ ] section_padding — inspect spacing. Did you hit ≥ 64px?
[ ] cta_height — is every CTA ≥ 48px? Is the hero CTA ≥ 56px?
[ ] cta_radius — ≥ 12px or pill? No sharp corners on primary CTAs.
[ ] cta_copy — [Action Verb] + [Value]? No "Submit" or "Click here"?
[ ] font_heading — is it the mood-appropriate font you chose? NOT default Inter?
[ ] font_body — loaded from Google Fonts with preconnect + display=swap?
[ ] body_max_width — text blocks ≤ 36rem?
[ ] contrast — 4.5:1 on ALL text including over gradients?
[ ] interactive — hover + focus + active on EVERY clickable element?
[ ] background — radial gradient atmospheric glow? NOT flat color?
[ ] cards — glass or elevated? NOT flat white/dark rectangles?
Visual Verification (the squint test)
[ ] ATMOSPHERE — ambient glow? Glass? Grain? Or flat template?
[ ] DRAMA — hero headline dominates? CTA demands attention?
[ ] BREATHING — generous whitespace? Or cramped?
[ ] HIERARCHY — squint: title, CTA, sections clearly distinct in 3 layers?
[ ] RESPONSIVE — check at 375px / 768px / 1280px
[ ] PRIDE — would you put this in your portfolio?
If anything fails, fix it before shipping. Go back to the relevant phase. Premium is not a nice-to-have — it's the requirement.
Accessibility (Non-Negotiable)
Every pattern in this skill already meets WCAG AA. If you customize, maintain these standards. See references/accessibility.md for the complete guide.
Contrast: 4.5:1 text, 3:1 large text — test gradient text especially
Keyboard: Tab reaches every interactive element
Focus: visible indicator (brand glow ring counts)
Semantics: <nav>, <main>, <section>, <button> — never div-soup
Labels: <label for="id"> for every <input>, alt for every image
Color: never color-only — add icons or text
Reduced motion: disable ALL animation via prefers-reduced-motion
ARIA: aria-label on icon-only buttons, aria-current on nav
Skip link: first element in body: <a href="#main" class="sr-only focus:not-sr-only">Skip to content</a>
Pattern Library
Premium Landing Page
NAV glass sticky · logo · links · primary CTA far-right (48px height)
HERO ambient gradient bg · display-size headline (60px+) · mood-matched font
gradient or fade text · lead paragraph max-w 32rem
primary CTA 56px + secondary glass CTA · trailing arrow icon
optional: product screenshot with glass frame
PROOF "Trusted by X,000+ teams" + grayscale logo bar
FEATURES 3-col glass cards · brand-tinted icons · staggered fade-in
TESTIMONIAL glass cards · avatar circle + italic quote + name/role
PRICING 2-3 glass cards · featured = gradient border · toggle monthly/annual
CTAs: secondary on free, primary on featured, secondary on enterprise
FINAL CTA brand-tinted bg section · centered headline + primary CTA (repeat hero)
FOOTER muted text · 3-4 col links · bottom bar legal + social icons
Premium Dashboard
SIDEBAR w-60 glass · logo · grouped nav · active = brand bg tint · avatar bottom
HEADER title · breadcrumbs · actions right · subtle border-bottom
STATS 3-4 glass metric cards · large number + trend arrow + sparkline
CONTENT glass chart containers · brand-accent data colors
TABLE glass header · hover highlight · right-align numbers · zebra rows
Premium Form
CONTAINER centered max-w-lg · 96px+ top padding · ambient bg glow
CARD glass/white · rounded-2xl · p-8 to p-10
HEADER 24-30px title (mood font) + secondary description
FIELDS label above · 48px inputs · brand glow focus · optional ✓ on valid
ACTIONS primary gradient CTA 56px right-aligned · secondary as ghost/text link
CTA copy: "Send message →" not "Submit"
Premium Pricing
CONTAINER centered · 3-col grid (2-col + 1 on mobile)
HEADER "Choose your plan" centered · optional monthly/annual toggle
CARDS glass cards · same height · featured card has gradient border
price: 48px number + /mo suffix · feature list with ✓ icons
CTAs: secondary on Free, primary on Pro (featured), secondary on Enterprise
TOGGLE pill-shaped · brand background on active · smooth slide transition
Premium Auth (Login/Register)
LAYOUT split: left = brand art/gradient, right = form (or centered single card)
CARD glass/white · max-w-md · p-8 to p-10 · centered vertical
HEADER logo + "Welcome back" (24px) + subtitle (secondary color)
FIELDS email + password · label above · 48px height · show/hide toggle on password
ACTIONS primary CTA full-width 56px "Sign in →" · divider "or" · social buttons
FOOTER "Don't have an account? Sign up" link below card
Reference Files
For deeper knowledge on specific topics, read these references:
references/typography.md — Full font selection guide by mood (6 categories), premium type scale, font pairing rules, line height/spacing/length specs, font loading strategy with Google Fonts
references/cta-buttons.md — CTA anatomy (size, radius, padding science), hero/secondary/ghost CSS patterns, copy formula with examples, placement rules, drop shadow formula, icon animation patterns
references/color-systems.md — Building color atmospheres, deriving full palettes from one brand color, dark/light theme tokens, semantic colors (success/warning/error/info), 60-30-10 rule in practice
references/layouts.md — Flexbox and CSS Grid patterns, common page layouts (sidebar+content, holy grail, split hero, centered), container queries, aspect-ratio patterns
references/components.md — Modal/dialog, toast/notification, tabs, accordion, dropdown, tooltip, skeleton loader, progress bar, avatar group, breadcrumb, pagination, tag/chip patterns with complete CSS
references/animations.md — Entrance animations, scroll-triggered reveals, hover micro-interactions, page transitions, loading states, keyframe recipes, cubic-bezier curves, performance tips
references/responsive.md — Breakpoint strategy, fluid typography with clamp(), responsive grid patterns, mobile navigation (hamburger drawer), touch targets, responsive images, container queries
references/accessibility.md — WCAG AA complete guide, focus management, screen reader patterns, ARIA roles/states, skip links, color contrast tools, keyboard navigation, reduced motion, semantic HTML patterns
references/starter-templates.md — Complete copy-paste HTML starters for landing page (dark + light), dashboard, contact form, pricing page, auth page, blog layout, portfolio, 404 page
The Bottom Line
The difference between AI-generated UI and designed UI isn't correctness — AI nails correctness. The difference is atmosphere + intention. Ambient gradients behind the hero. Glass cards with subtle borders. Gradient CTAs that glow on hover and are tall enough to feel important. Confident 60px headlines in a mood-appropriate font (not always Inter). 128px of breathing room. Grain texture. The courage to let things be big and space be empty. And CTA copy that promises value, not just describes the action.
For basic LLMs: Use the Quick Start template. Change the brand color, fill in your content. You'll ship something premium.
For capable LLMs: Follow the full 6-phase workflow. Set metrics. Build to them. Verify. Ship something you're proud of.
The Quick Start template isn't a shortcut — it's a safety net. Every premium pattern is already encoded in its CSS. The phases are how you customize, extend, and make it truly yours.