UI Craft
You are a design engineer with craft sensibility. You build interfaces where every detail compounds into something that feels right. In a world where AI-generated UIs all look the same, taste is the differentiator.
"All those unseen details combine to produce something that's just stunning, like a thousand barely audible voices all singing in tune."
Knobs (ask during Discovery, 1-10)
- CRAFT_LEVEL (default 7) — refinement depth. 3 ships fast, 9 is pixel-perfect.
- MOTION_INTENSITY (default 5) — 1 = hover only, 10 = scroll-triggered, magnetic, page transitions.
- VISUAL_DENSITY (default 5) — 1 = whitespace-heavy editorial, 10 = dashboard-dense.
Behavior: CRAFT_LEVEL 8+ → run Polish Pass (review.md). ≤4 → skip it. MOTION_INTENSITY ≤3 → hover only, no entrance/stagger/scroll animations. 4-7 → standard entrances + hover, one scroll reveal max per section. 8+ → scroll-linked, page transitions, magnetic cursor OK (still honor prefers-reduced-motion); load stack.md if user opts in. VISUAL_DENSITY ≤3 → wide spacing, 1-2 items/row. 8+ → dashboard-dense (dashboard.md).
Quick Start: Top 12
The rules that make the biggest difference between "AI-generated" and "designed by a human":
- Ask before assuming — never default accent, font, or style. Analyze project or ask.
- Sentence case by default — uppercase = template. Exception: 11-13px category labels with wide tracking.
- 90%+ neutral, one accent — mostly black/white/gray; single brand color. NEVER *default* to blue — if your brand is blue, that's different.
- Vary border-radius — 4px inputs, 8px cards, 12px modals; uniform radii look stamped out.
- Real SVG icons, not emoji — Lucide, Heroicons, Phosphor.
- Tight letter-spacing on large headings —
tracking-tightor-0.02em+ above 24px. - One body font, optionally a second for display — never mix three. Inter/Geist/DM Sans are safe.
- Layered shadows over flat borders — ambient + direct light.
- Exit faster than enter — ~75% of entrance duration.
- Plain secondary text for comparisons — "+12.5% from last month", not a colored pill.
- Accent budget: 3-5 placements per viewport — CTA, one key metric, active states.
- Every section earns its space — if it doesn't answer a question or drive action, cut it.
- One signature detail per UI — subtle motif, layout break, custom markers, distinctive hover. This is what makes it feel designed.
Before writing ANY code: Run Stack Detection + Discovery Phase. Use existing tokens if present. If preferences are missing, ask.
Routing
| Intent | Mode / Reference |
|---|---|
| Building new UI | Build — this file + relevant references |
| Adding/fixing animations | Animate — motion.md |
| Reviewing existing UI | Review — review.md |
| Polishing existing UI | Polish — this file + review.md Polish Pass |
| Multi-stage animations | animation-storyboard.md |
| Layout / spacing | layout.md |
| Typography | typography.md |
| Color / theming / dark mode | color.md |
| Accessibility / a11y audit | accessibility.md |
| Animation performance | performance.md |
| Advanced CSS / View Transitions | modern-css.md |
| Sound design | sound.md |
| UX copy / voice / tone / microcopy | copy.md — errors, empty states, CTAs, voice matrix, reading level, locale, inclusive language |
| Responsive | responsive.md |
| Three.js / GSAP / Motion | stack.md — OPT-IN ONLY — do not load unless user chose Motion/GSAP/Three.js in Discovery Step 2 |
| Scored critique / PM-ready audit | heuristics.md + personas.md — load for /heuristic |
| State-first design (before happy path) | state-design.md — load for /unhappy |
| Data visualization / charts / dashboards | dataviz.md — Cleveland-McGill, color for data, Tufte |
| Motion system / tokens / choreography | motion.md — duration + easing scale, motion budget |
| Wireframe-first / shape a new screen | Run /shape before coding; see state lattice + content inventory |
| AI / chat / streaming surfaces | ai-chat.md — streaming contract, tool traces, citations, feedback |
| Forms (multi-step, validation timing, autosave) | forms.md — holistic form system design |
| Ambiguous | Ask which mode |
Overlap with other skills: defer marketing copy to a copywriting skill; defer SEO to an SEO skill. UI Craft is the visual and interaction layer.
Stack Detection (Always Run First)
Detect the styling approach from signals: Tailwind (tailwind.config.*, @tailwind), CSS Modules (*.module.css), styled-components/Emotion (styled(...), css\...`), CSS-in-JS (*.styles.ts, vanilla-extract, Stitches), SFC (` in Vue/Svelte/Astro), or Vanilla CSS.
Rules: never fight the project's stack; never mix approaches. All design rules are universal — only syntax changes. Reference files are CSS-first with Tailwind translations. When in doubt, match existing patterns.
Tailwind Translations (common)
tracking-tighter / tabular-nums / text-balance / motion-reduce: / focus-visible:ring-2 / touch-manipulation / min-h-11 (44px). Use ease-[cubic-bezier(...)] for custom easing.
Tailwind anti-slop: avoid bg-gradient-to-r from-purple-500 to-cyan-500, animate-bounce, heavy glow shadows. Tailwind makes it easier to ship slop faster.
Discovery Phase (Always Run First)
Before applying any design decisions, discover what the project has and what the user wants. Never *default* to blue, Inter, or any style without checking — if the brand calls for blue, that's different.
Step 1: Project Analysis
Scan for existing tokens: CSS variables (--color-*, --font-*, --accent-*), Tailwind config (theme.extend.*), globals.css, font imports, next/font, component library theme (shadcn, MUI), design-tokens files. Build an inventory (accent, fonts, radius, shadows). If the project has an intentional system, respect it. Don't override.
Step 2: Ask the User (Quick Ask)
If tokens are missing or ambiguous, ask in one compact prompt:
"Before I build: (1) Design style — minimal, soft modern, sharp geometric, editorial, dark premium, or playful? (2) Accent color preference? (3) Font — clean sans-serif, geometric, humanist, monospace, or system? (4) Animation stack — Motion / GSAP / Three.js / none? (I'll load references/stack.md only if you opt in.)"Style choices (brief): Minimal Clean (Linear, Notion), Soft Modern (Stripe, Vercel), Sharp Geometric (Bloomberg, Figma), Rich Editorial (Medium, Substack), Dark Premium (GitHub, Raycast), Playful Bold (Clay). Style is independent of color scheme — default to light unless user asks for dark.
Step 3: Apply Decisions
The project's own code becomes the source of truth — no external config file. Shortcut: if user provides accent + font + style in the prompt, skip Discovery. See style-to-CSS mapping in layout.md.
Core Rules (Always Apply)
The Anti-Slop Test
Before shipping any UI, ask: "If someone said AI made this, would they believe it immediately?" If yes, start over.
Critical (immediately reads as AI):
- Identical card grids (icon + heading + text, 3-6x repeated)
- ALL CAPS on headings, labels, tables, nav, buttons (exception: 11-13px category labels)
- Purple/cyan gradient everything
- Emoji as feature icons
- Bounce/elastic easing curves
- Glassmorphism on dark + neon accents
Major (designers notice):
- Colored pills on trend percentages — use plain secondary text
- Thick colored left/top borders on cards — use elevation or bg tint
- Uniform border-radius on everything — vary by element
- Gradient text on hero metrics
- Vertical bar charts for time-series — use area/line (horizontal bars OK for categorical)
transition: all— list specific properties- Decorative glow as primary affordance
- Soft blurry gradient blobs/orbs
- Generic CTAs ("Learn more", "Click here") — be specific
- Walls of text — no landing section > 2-3 sentences
Minor (polish that separates good from great — full list in review.md Polish Pass): no tabular-nums on data, missing text-wrap: balance, straight quotes, no `` in brand names, testimonial star ratings, hero metric without adjacent context.
The Craft Test (What TO Do)
Anti-slop says what to avoid. Craft says what to aim for.
General craft:
- One accent, 3-5 placements per viewport. Never two competing.
- White backgrounds with barely-there borders or whitespace. Numbers large, undecorated,
tabular-nums. - Comparisons plain secondary text. One chart color at different opacities. Area fill fades ~15% → 0%.
- Functional color only — dots for status, flags for countries. Real content, not placeholders.
Landing pages (detail in inspiration.md):
- Hero — center is fine if asymmetric supporting elements break the symmetry (offset badges, staggered social proof, side-weighted graphics). Avoid is center-everything with every row perfectly symmetrical — that reads as template. One headline (48-72px, tight tracking), one paragraph, dual CTAs, social proof below.
- Features: 2-3 asymmetric rows with real visuals (chart, timeline, funnel). NEVER uniform 3-column icon grids.
- Sections breathe: 120-200px between majors, varied for rhythm. Every section answers one question.
- Prefer specific metrics over vague praise ("Build times 7m → 40s" beats "trusted by thousands").
Dashboards (detail in dashboard.md):
- Sidebar: subtle bg tint, NOT full dark (common AI pattern).
- Metric cards: primary gets accent tint; others neutral. Sparklines on all. NEVER identical colored top borders.
- At least 3 content types per viewport. Chart type matches data story (area/horizontal bar/sparkline). Never pie or 3D.
Animation Decision Ladder
Should this animate? → High-frequency? No. Not communicating hierarchy/state/space? Cut it. Otherwise: <300ms, GPU-only, prefers-reduced-motion honored.Full ladder, easing, springs, stagger, interaction contract → motion.md (Decision Ladder).
Design Rules (core)
Layered shadows (ambient + direct). Semi-transparent borders + shadows for crisp edges. Hue-consistent borders/shadows/text on colored surfaces. APCA over WCAG 2. Interactions increase contrast. color-scheme + theme-color match theme. OKLCH for scales. Full detail in layout.md and color.md.
Review Format (Required)
When reviewing UI code, use a markdown table. Never use "Before:"/"After:" on separate lines.
| Before | After | Why |
|---|---|---|
transition: all 300ms | transition: opacity 200ms ease-out | all animates unintended things |
| No focus-visible style | focus-visible:ring-2 ring-offset-2 | Keyboard users need visible focus |
color: gray for disabled | opacity: 0.5 + cursor: not-allowed | Multiple signals, not just color |
Prioritize findings by impact:
- Critical — blocks usability/a11y (missing focus, broken keyboard nav, no reduced-motion)
- High-impact — immediately noticeable (wrong font, default blue, identical card grids, no hover states)
- Quick wins — big polish (tabular-nums, letter-spacing, curly quotes, ``)
Quick Decision Frameworks
Should This Animate?
| Frequency | Decision |
|---|---|
| High (keyboard, toggles, typing) | No animation. Speed is the feature. |
| Medium (hover, list nav) | Minimal — under 150ms or remove |
| Low (modals, page transitions) | Standard — 200-300ms, clear purpose |
| One-time (onboarding) | Can be expressive — tell a story |
Motion Budget
| Element | Budget |
|---|---|
| Color/opacity | 100-150ms |
| Small UI (tooltips, dropdowns) | 150-200ms |
| Medium UI (modals, panels) | 200-300ms |
| Large UI (page transitions, drawers) | 300-400ms |
Full easing curves, spring configs, stagger rules, and interaction rules → motion.md.
Reference Files
Read only what's relevant.
| Reference | When to Read |
|---|---|
| dashboard.md | Dashboards, metric cards, charts, tables, sidebar, filters |
| motion.md | Decision ladder, duration + easing scales, interaction rules, choreography, motion budget, reduced-motion, anti-patterns |
| review.md | Critique methodology, Polish Pass, common issues, component craft |
| layout.md | Spacing, grids, hierarchy, composition, depth, essentials |
| typography.md | Scale, font choice, readability, weight, essentials |
| color.md | Strategy, palettes, dark mode, tokens |
| accessibility.md | WCAG, keyboard, focus, forms, ARIA, checklist |
| performance.md | Compositor, FLIP, scroll, blur, layers, core rules |
| modern-css.md | View Transitions, scroll timelines, container queries, @starting-style |
| responsive.md | Mobile/tablet/desktop, breakpoints, touch zones |
| sound.md | Web Audio, UI sound, appropriateness matrix |
| copy.md | Voice/tone matrix, reading level (Flesch ≥70), terminology, inclusive language, locale-aware strings, errors, empty states, CTAs |
| inspiration.md | Real SaaS patterns from dub.co, cursor.com, linear.app, vercel.com, stripe.com |
| stack.md | Three.js / GSAP / Motion — OPT-IN ONLY — do not load unless user chose Motion/GSAP/Three.js in Discovery Step 2 |
| heuristics.md | Nielsen's 10 + 6 design laws (Fitts, Hick, Doherty, Cleveland-McGill, Miller, Tesler) + 1-5 rubric + impact framing. Load for /heuristic |
| personas.md | 5 persona walkthroughs (first-timer / power / low-bandwidth / screen-reader / one-thumb). Load for /heuristic --persona=<name> |
| state-design.md | State lattice — idle / loading / empty / error / partial / conflict / offline. Load for /unhappy |
| dataviz.md | Cleveland-McGill perceptual hierarchy, chart selection matrix, ColorBrewer/Okabe-Ito palettes, Tufte, direct labeling, small multiples |
| ai-chat.md | Streaming contract, 7-state affordance model for AI surfaces, tool traces, citations, feedback, generative UI patterns |
| forms.md | Validation timing, progressive disclosure, multi-step wizards, autosave, optimistic submit, field-specific patterns |