agentleFS
ckorhonenckorhonen/claude-skills/skills/ui-design/SKILL.md

ui-design

Skill17 starsChanged 4 months agoMITView on GitHub

Opinionated constraints for building better interfaces with agents. Use when building UI components, implementing animations, designing layouts, reviewing frontend accessibility, or working with Tailwind CSS, motion/react, or accessible primitives like Radix/Base UI.

59 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use harness-design, graphic-design and 10 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • VictoriakaeySkill

    harness-design

    Use when designing or improving the action space, observation format, tool boundaries, and evaluation signals of an LLM agent. Covers the five layers of harness design: what tools the agent has, what it sees after acting, how each tool is scoped, how behavior is evaluated, and how to iterate when the agent misbehaves. Prevents the most common harness failures — agents that pick wrong tools, ignore critical information, or loop without progress.

    Also in 3 projects that use this

  • travisjneumanSkill

    graphic-design

    Professional graphic design principles for digital and print media. Use when creating visual designs, choosing color palettes, typography, layouts, or providing design feedback.

    Also in 3 projects that use this

  • soilmassSkill

    typography

    Typography and kinetic text animations including character reveals, typewriter effects, scramble/decode, wave motion, and animated gradients. Use when creating text reveals, headline animations, number counters, or any text-based motion effects.

    Also in 3 projects that use this

  • MicrosoftSkill

    typescript

    TypeScript best practices for this monorepo. Use this skill when: (1) writing new TypeScript code, (2) reviewing TypeScript code, (3) working with API responses, fetch calls, or JSON parsing, (4) adding or modifying types and interfaces.

    Also in 7 projects that use this

  • OpenAISkill

    auth

    Authentication integration guidance — Clerk (native Vercel Marketplace), Descope, and Auth0 setup for Next.js applications. Covers middleware auth patterns, sign-in/sign-up flows, and Marketplace provisioning. Use when implementing user authentication.

    Also in 3 projects that use this

  • VercelSkill

    react

    React renderer for json-render that turns JSON specs into React components. Use when working with @json-render/react, building React UIs from JSON, creating component catalogs, or rendering AI-generated specs.

    Also in 4 projects that use this

The file

We split this skill into the rules it gives an agent

12 rules. 0 are common, 9 are distinctive, and 3 are very specific to this project.

  • 0

    Common

    Most of the 50 edited versions we read keep these.

  • 9

    Distinctive

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Test colors: Use online contrast checkers (https://webaim.org/resources/contrastchecker/)

    line 154
  2. Very specific:

    For colored text (not gray): Use darker tints (red-700 not red-300)

    line 159
  3. Very specific:

    Stack on mobile: Use flex-col by default, md:flex-row for desktop

    line 190
  4. Very specific:

    Use flex-1 instead of fixed widths for flexible layouts

    line 193
  5. Distinctive:

    Test responsiveness: Check at 375px (iPhone SE) and 768px (tablet) breakpoints

    line 194
  6. Distinctive:

    Avoid horizontal scroll: Never force users to scroll sideways

    line 195
  7. Distinctive:

    No recovery path from errors

    line 220
  8. Distinctive:

    Loading states: Use structural skeletons (not spinners)

    line 223
  9. Distinctive:

    Disabled states: Always provide visual feedback

    line 232
  10. Distinctive:

    Never silently disable without explaining why

    line 234
  11. Distinctive:

    Problem: All text the same size, all colors the same weight, all spacing the same distance — nothing stands out.

    line 238
  12. Distinctive:

    One accent color per view: Use a single color for CTAs, not multiple colors fighting for attention

    line 281

“Common” is measured: kept by at least 6 in 10 of the 50 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

UI Design

Opinionated constraints for building better interfaces with agents.

When to Use

  • Building UI components with Tailwind CSS
  • Implementing animations or transitions
  • Adding interactive elements with keyboard/focus behavior
  • Reviewing frontend code for accessibility
  • Designing layouts with proper z-index and spacing
  • Working with loading states, error handling, or empty states

Stack

RequirementRule
Tailwind CSSMUST use defaults (spacing, radius, shadows) before custom values
Animation libraryMUST use motion/react (formerly framer-motion) for JS animation
CSS animationSHOULD use tw-animate-css for entrance and micro-animations
Class logicMUST use cn utility (clsx + tailwind-merge)

Components

RequirementRule
Interactive primitivesMUST use accessible primitives (Base UI, React Aria, Radix) for keyboard/focus behavior
Existing componentsMUST use project's existing primitives first
ConsistencyNEVER mix primitive systems within the same interaction surface
New primitivesSHOULD prefer Base UI if compatible with stack
Icon buttonsMUST add aria-label to icon-only buttons
Custom behaviorNEVER rebuild keyboard or focus behavior by hand unless explicitly requested

Interaction

RequirementRule
Destructive actionsMUST use AlertDialog for destructive or irreversible actions
Loading statesSHOULD use structural skeletons
Viewport heightNEVER use h-screen, use h-dvh
Fixed elementsMUST respect safe-area-inset
Error displayMUST show errors next to where the action happens
Input behaviorNEVER block paste in input or textarea elements

Animation

RequirementRule
DefaultNEVER add animation unless explicitly requested
Compositor propsMUST animate only transform, opacity
Layout propsNEVER animate width, height, top, left, margin, padding
Paint propsSHOULD avoid background, color except for small, local UI (text, icons)
Entrance easingSHOULD use ease-out on entrance
Feedback timingNEVER exceed 200ms for interaction feedback
LoopingMUST pause looping animations when off-screen
AccessibilityMUST respect prefers-reduced-motion
Custom easingNEVER introduce custom easing curves unless explicitly requested
Large surfacesSHOULD avoid animating large images or full-screen surfaces

Typography

RequirementRule
HeadingsMUST use text-balance
Body textMUST use text-pretty for paragraphs
DataMUST use tabular-nums
Dense UISHOULD use truncate or line-clamp
Letter spacingNEVER modify letter-spacing (tracking-) unless explicitly requested

Layout

RequirementRule
Z-indexMUST use a fixed scale (no arbitrary z-x)
Square elementsSHOULD use size-x instead of w-x + h-x

Performance

RequirementRule
Blur effectsNEVER animate large blur() or backdrop-filter surfaces
Will-changeNEVER apply will-change outside an active animation
useEffectNEVER use for anything expressible as render logic

Design

RequirementRule
GradientsNEVER use unless explicitly requested
Purple/multicolor gradientsNEVER use
Glow effectsNEVER use as primary affordances
ShadowsSHOULD use Tailwind CSS default scale unless explicitly requested
Empty statesMUST give one clear next action
Accent colorsSHOULD limit to one per view
Color tokensSHOULD use existing theme or Tailwind CSS tokens before introducing new ones

Common Pitfalls

The most common UI design failures occur in spacing, color contrast, mobile responsiveness, state management, and visual hierarchy. These gotchas are discovered through repeated agent mistakes when building interfaces.

1. Inconsistent Spacing (Arbitrary Margins, No System)

Problem: Using an inconsistent mix of Tailwind spacing values without a deliberate system makes layouts feel incoherent.

// ❌ WRONG - arbitrary pixel values, no spacing system
<div className="ml-[13px] mr-[22px] pt-[7px]">Content</div>

// ✅ CORRECT - use system scales
<div className="ml-4 mr-4 pt-4">Content</div>

Why it fails:

  • Designs look accidental (some spacing is 2px, some is 16px, no pattern)
  • Mobile layouts break (spacing doesn't scale proportionally)
  • Alignment is impossible (gaps don't align to grid)

Fix:

  • ALWAYS use Tailwind spacing scale (0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, etc.)
  • Define spacing systems for common patterns:
    • Button padding: px-4 py-2
    • Card padding: p-6
    • Gap between sections: gap-8
    • Nested spacing: ml-6 (not ml-3)
  • Group related elements with consistent gaps (use same gap-x for all horizontal lists)

2. Poor Color Contrast (Accessibility Violations)

Problem: Color combinations that fail WCAG AA contrast ratios (4.5:1 for text, 3:1 for UI components) making content illegible for low-vision users.

// ❌ WRONG - gray-400 text on gray-100 background fails contrast
<p className="text-gray-400 bg-gray-100">Important content</p>

// ✅ CORRECT - gray-700 on gray-100 passes WCAG AA
<p className="text-gray-700 bg-gray-100">Important content</p>

Why it fails:

  • Approximately 4-5% of users have color blindness, and a broader 15%+ have some form of visual impairment
  • Users on bright displays (phones) can't read low-contrast text
  • Legal liability (WCAG compliance required in many jurisdictions)

Fix:

  • Use color pairs with sufficient contrast:
    • text-gray-900/text-white on any background (always safe)
    • text-gray-700 on light backgrounds
    • text-gray-300 on dark backgrounds
  • Test colors: Use online contrast checkers (https://webaim.org/resources/contrastchecker/)
  • Avoid problematic pairs:
    • gray-400 on gray-100 ❌
    • red-500 on pink-100 ❌
    • Disabled states: use text-gray-400 on white, text-gray-600 on color
  • For colored text (not gray): Use darker tints (red-700 not red-300)

3. Mobile-Unfriendly Layouts (Small Touch Targets, Horizontal Scroll)

Problem: Touch targets smaller than 44×44px, horizontal scrolling, or layouts that don't adapt to narrow viewports.

// ❌ WRONG - button too small, no responsive layout
<button className="px-2 py-1 text-xs">Click me</button>
<div className="flex gap-2">
  <div className="w-80">Sidebar</div>
  <div className="w-80">Content</div>
</div>

// ✅ CORRECT - hit target size, responsive stack
<button className="px-4 py-3 md:px-6 md:py-3">Click me</button>
<div className="flex flex-col md:flex-row gap-4">
  <div className="w-full md:w-80">Sidebar</div>
  <div className="flex-1">Content</div>
</div>

Why it fails:

  • 40% of traffic is mobile; small buttons are impossible to tap
  • Horizontal scrolling is a UX nightmare on phones
  • Layouts that work on desktop can be unusable on mobile

Fix:

  • Minimum touch target: 44×44px
    • Buttons: at least px-4 py-3 (standard: px-6 py-3)
    • Links: wrap in larger clickable area
  • Stack on mobile: Use flex-col by default, md:flex-row for desktop
  • Use responsive widths:
    • w-full on mobile, md:w-80 or md:w-1/3 on desktop
    • Use flex-1 instead of fixed widths for flexible layouts
  • Test responsiveness: Check at 375px (iPhone SE) and 768px (tablet) breakpoints
  • Avoid horizontal scroll: Never force users to scroll sideways

4. Missing States (Loading, Error, Empty, Disabled)

Problem: Interfaces that only show the happy path, failing silently when loading, erroring, or empty.

// ❌ WRONG - no feedback states
<button onClick={save}>Save</button>
<div>{data.map(item => <ItemCard item={item} />)}</div>

// ✅ CORRECT - all states accounted for
<button onClick={save} disabled={loading}>
  {loading ? 'Saving...' : 'Save'}
</button>

{loading && <LoadingSkeleton />}
{error && <ErrorAlert message={error} />}
{!loading && data.length === 0 && <EmptyState action="Create your first item" />}
{!loading && !error && data.map(item => <ItemCard item={item} />)}

Why it fails:

  • Users don't know if action worked (no feedback = perceived failure)
  • Empty lists look broken (not intentionally empty)
  • No recovery path from errors

Fix:

  • Loading states: Use structural skeletons (not spinners)
    • Layout remains stable while content loads
    • Users see what's coming, not just spinning
  • Error states: Show next to the failed action
    • Explain what happened and how to fix it
    • Include retry button
  • Empty states: Make intentional and actionable
    • "No items yet" → "Create your first item" (button)
    • Show what empty state means, how to populate
  • Disabled states: Always provide visual feedback
    • disabled={true} + opacity-50 or cursor-not-allowed
    • Never silently disable without explaining why

5. Unclear Hierarchy (Everything Looks Equally Important)

Problem: All text the same size, all colors the same weight, all spacing the same distance — nothing stands out.

// ❌ WRONG - flat hierarchy
<div className="text-lg text-gray-700">
  <div className="text-lg text-gray-700">Subheading</div>
  <div className="text-lg text-gray-700">Subtitle</div>
  <button className="text-lg px-4 py-2">Action</button>
</div>

// ✅ CORRECT - clear hierarchy
<div>
  <h1 className="text-3xl font-bold text-gray-900">Title</h1>
  <h2 className="text-xl font-semibold text-gray-700 mt-6">Subheading</h2>
  <p className="text-base text-gray-600 mt-2">Subtitle</p>
  <button className="mt-6 px-6 py-3 bg-blue-600 text-white font-semibold rounded">
    Primary Action
  </button>
</div>

Why it fails:

  • Users don't know where to look first
  • Scanning pages is slower (no skimmable structure)
  • Important actions get missed

Fix:

  • Size hierarchy:
    • Headings: text-3xl (h1) → text-2xl (h2) → text-xl (h3)
    • Body text: text-base (paragraphs) → text-sm (secondary)
  • Weight hierarchy:
    • Primary actions: font-bold or font-semibold
    • Important text: font-semibold
    • Body: font-normal
    • Secondary: font-normal with lighter color
  • Color hierarchy:
    • Primary text: text-gray-900
    • Secondary text: text-gray-600
    • Tertiary: text-gray-500
  • Spacing hierarchy:
    • Section gaps: gap-8 (largest)
    • Component gaps: gap-4
    • Dense content: gap-2
  • One accent color per view: Use a single color for CTAs, not multiple colors fighting for attention

Quick Reference

Allowed Animation Properties

transform, opacity

Forbidden Animation Properties

width, height, top, left, margin, padding, blur(), backdrop-filter

Required Accessibility Patterns

// Icon button - always add aria-label
<button aria-label="Close dialog">
  <XIcon />
</button>

// Respect reduced motion
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; }
}

Class Utility Pattern

import { clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.