skills/uiux-design/SKILL.md
UI component code implementation specialist. Trigger when WRITING or FIXING UI code — Tailwind CSS utilities, shadcn/ui components, Radix UI primitives, CVA component variants, Framer Motion animations, CSS variables for dark mode, WCAG accessibility code (ARIA labels, focus management, keyboard navigation), responsive layouts, skeleton loaders, empty states, Storybook stories, Figma-to-code. Also triggers for: fix this component, add dark mode, make this accessible, write a Button component, style this form, add animations, fix layout shift. For design PLANNING (choosing colors, styles, font pairings for a new project) use ui-ux-pro-max instead.
npx skillsauth add thesaifalitai/claude-setup uiux-designInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are a senior UI/UX engineer who turns design concepts into pixel-perfect, accessible, production-ready interfaces. You combine design thinking with precise implementation.
// tailwind.config.ts
import type { Config } from 'tailwindcss';
const config: Config = {
content: ['./src/**/*.{ts,tsx}'],
darkMode: 'class',
theme: {
extend: {
colors: {
primary: {
50: '#eff6ff',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
900: '#1e3a8a',
},
surface: {
DEFAULT: 'hsl(var(--surface))',
foreground: 'hsl(var(--surface-foreground))',
},
},
fontFamily: {
sans: ['Inter var', 'sans-serif'],
mono: ['JetBrains Mono', 'monospace'],
},
spacing: {
'4.5': '1.125rem',
'18': '4.5rem',
},
borderRadius: {
'4xl': '2rem',
},
},
},
};
export default config;
/* globals.css */
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--surface: 0 0% 98%;
--surface-foreground: 222.2 47.4% 11.2%;
--primary: 221.2 83.2% 53.3%;
--primary-foreground: 210 40% 98%;
--destructive: 0 84.2% 60.2%;
--border: 214.3 31.8% 91.4%;
--radius: 0.5rem;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--surface: 222.2 84% 7%;
--primary: 217.2 91.2% 59.8%;
--border: 217.2 32.6% 17.5%;
}
// ✅ Design token-based Button
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary' | 'ghost' | 'destructive';
size?: 'sm' | 'md' | 'lg';
loading?: boolean;
}
const buttonVariants = cva(
'inline-flex items-center justify-center rounded-lg font-medium transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
{
variants: {
variant: {
primary: 'bg-primary-600 text-white hover:bg-primary-700 active:bg-primary-800 shadow-sm',
secondary: 'bg-white text-gray-900 border border-gray-300 hover:bg-gray-50 shadow-sm dark:bg-gray-800 dark:text-gray-100 dark:border-gray-600',
ghost: 'hover:bg-gray-100 text-gray-700 dark:hover:bg-gray-800 dark:text-gray-300',
destructive: 'bg-red-600 text-white hover:bg-red-700',
},
size: {
sm: 'h-8 px-3 text-sm',
md: 'h-10 px-4 text-sm',
lg: 'h-12 px-6 text-base',
},
},
defaultVariants: { variant: 'primary', size: 'md' },
}
);
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ variant, size, loading, children, ...props }, ref) => (
<button className={buttonVariants({ variant, size })} ref={ref} {...props}>
{loading && <Spinner className="mr-2 h-4 w-4 animate-spin" />}
{children}
</button>
)
);
// ✅ Responsive grid
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 md:gap-6">
{items.map(item => <Card key={item.id} item={item} />)}
</div>
// ✅ Sidebar layout
<div className="flex h-screen overflow-hidden">
<aside className="hidden lg:flex w-64 flex-col border-r border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900">
<Sidebar />
</aside>
<main className="flex-1 overflow-y-auto">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-8">
{children}
</div>
</main>
</div>
// ✅ Sticky header with backdrop blur
<header className="sticky top-0 z-50 border-b border-gray-200/80 bg-white/80 backdrop-blur-md dark:border-gray-700/80 dark:bg-gray-900/80">
// Skeleton loader
export function CardSkeleton() {
return (
<div className="animate-pulse rounded-xl border border-gray-200 p-4">
<div className="h-4 w-2/3 rounded bg-gray-200 mb-3" />
<div className="h-3 w-full rounded bg-gray-100 mb-2" />
<div className="h-3 w-4/5 rounded bg-gray-100" />
</div>
);
}
// Empty state
export function EmptyState({ title, description, action }: EmptyStateProps) {
return (
<div className="flex flex-col items-center justify-center py-16 text-center">
<div className="rounded-full bg-gray-100 p-4 dark:bg-gray-800 mb-4">
<InboxIcon className="h-8 w-8 text-gray-400" />
</div>
<h3 className="text-lg font-semibold text-gray-900 dark:text-gray-100">{title}</h3>
<p className="mt-2 text-sm text-gray-500 max-w-sm">{description}</p>
{action && <div className="mt-6">{action}</div>}
</div>
);
}
// Page transition
const pageVariants = {
initial: { opacity: 0, y: 8 },
animate: { opacity: 1, y: 0 },
exit: { opacity: 0, y: -8 },
};
export function AnimatedPage({ children }: { children: React.ReactNode }) {
return (
<motion.div
variants={pageVariants}
initial="initial"
animate="animate"
exit="exit"
transition={{ duration: 0.2, ease: 'easeOut' }}
>
{children}
</motion.div>
);
}
// Staggered list
const container = { animate: { transition: { staggerChildren: 0.05 } } };
const item = { initial: { opacity: 0, y: 20 }, animate: { opacity: 1, y: 0 } };
// ✅ ARIA labels on all interactive elements
<button aria-label="Close dialog" onClick={onClose}>
<XIcon aria-hidden="true" />
</button>
// ✅ Form accessibility
<label htmlFor="email" className="block text-sm font-medium">Email</label>
<input
id="email"
type="email"
aria-describedby={errors.email ? 'email-error' : undefined}
aria-invalid={!!errors.email}
/>
{errors.email && <p id="email-error" role="alert" className="text-sm text-red-600">{errors.email}</p>}
// ✅ Focus management in modals
<Dialog>
<DialogContent onOpenAutoFocus={e => e.preventDefault()}>
{/* First focusable: close button */}
<DialogClose ref={closeRef} />
</DialogContent>
</Dialog>
// ✅ Keyboard navigation
<div role="listbox" aria-labelledby="list-label">
{options.map(opt => (
<div
key={opt.id}
role="option"
aria-selected={selected === opt.id}
tabIndex={0}
onKeyDown={e => e.key === 'Enter' && onSelect(opt.id)}
>
{opt.label}
</div>
))}
</div>
outline: none without alternative)prefers-reduced-motion)development
Use when building Vue 3 applications with Composition API, Nuxt 3, or Quasar. Invoke for Pinia, TypeScript, PWA, Capacitor mobile apps, Vite configuration.
tools
Expert Upwork freelancer skill for writing winning proposals, client communication, and project management. ALWAYS trigger for ANY task involving Upwork job proposals, bid writing, client messages, project scoping, milestone planning, contract setup, client onboarding, status updates, project handoffs, portfolio descriptions, rate negotiation, handling difficult clients, raising rates, dispute resolution, or review requests. Also triggers for: "write a proposal", "reply to client", "Upwork bid", "freelance proposal", "client message", "project quote", "scope of work", "follow up with client", "client is ghosting", "request review", "upwork job".
development
Design PLANNING and DISCOVERY specialist — use before writing any code. Invoke when CHOOSING a design direction: pick a visual style (glassmorphism, brutalism, minimalism, claymorphism, neumorphism, bento grid, skeuomorphism), generate a color palette, select font pairings, plan a design system, choose chart styles, or define the look-and-feel for a new project. Triggers: 'what style should I use', 'suggest a color palette', 'recommend fonts for my app', 'design system for a SaaS', 'what UI style fits a fintech app', 'generate a design brief', 'choose between dark/light theme', 'plan the visual identity'. Covers 50 styles, 97 palettes, 57 font pairings across React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind, shadcn/ui stacks. For WRITING or FIXING actual UI code (components, Tailwind classes, animations) use uiux-design instead.
tools
Use when building TypeScript applications requiring advanced type systems, generics, or full-stack type safety. Invoke for type guards, utility types, tRPC integration, monorepo setup.