--- name: frontend-ui-engineering description: Use this skill when building or modifying production-quality user-facing interfaces. Builds accessible, responsive, visually polished UIs with proper component architecture, design system adherence, and WCAG 2.1 AA compliance. --- # Frontend UI Engineering ## Overview Build production-quality user interfaces that are accessible, performant, and visually polished. The goal is UI that looks like it was built by a design-aware engineer at a top company — not like it was generated by an AI. This means real design system adherence, proper accessibility, thoughtful interaction patterns, and no generic "AI aesthetic." ## When to Use - Building new UI components or pages - Modifying existing user-facing interfaces - Implementing responsive layouts - Adding interactivity or state management - Fixing visual or UX issues ## Component Architecture ### File Structure Colocate everything related to a component: ``` src/components/ TaskList/ TaskList.tsx # Component implementation TaskList.test.tsx # Tests types.ts # Component-specific types (if needed) ``` ### Component Patterns **Prefer composition over configuration:** ```tsx // Good: Composable // Avoid: Over-configured ``` **Separate data fetching from presentation:** ```tsx // Container: handles data export function TaskListContainer() { const { tasks, isLoading, error } = useTasks(); if (isLoading) return ; if (error) return ; if (tasks.length === 0) return ; return ; } // Presentation: handles rendering export function TaskList({ tasks }: { tasks: Task[] }) { return
{tasks.map(task => )}
; } ``` ## State Management Choose the simplest approach that works: ``` Local state (useState) → Component-specific UI state Lifted state → Shared between 2-3 sibling components Context → Theme, auth, locale (read-heavy, write-rare) URL state (searchParams) → Filters, pagination, shareable UI state Server state (React Query) → Remote data with caching Global store (Zustand, Redux) → Complex client state shared app-wide ``` **Avoid prop drilling deeper than 3 levels.** If you're passing props through components that don't use them, introduce context or restructure the component tree. ## Design System Adherence ### Reference-led UI Quality When the product needs a distinct visual direction: 1. Collect evidence before choosing a layout 2. Study 2-3 relevant screens. Record decisions about hierarchy, density, navigation, controls, responsive behavior, and interaction states 3. Turn those decisions into a short design contract before implementation 4. Rebuild using the product's own components, tokens, content, and visual language 5. Never copy another product's branding, proprietary text, or exact layout ### Avoid the AI Aesthetic | AI Default | Why It Is a Problem | Production Quality | |---|---|---| | Purple/indigo color schemes | Models default to visually "safe" palettes | Use the project's actual color palette | | Excessive gradients | Add visual noise, clash with design systems | Flat or subtle gradients from the design system | | Maximum border-radius everywhere | Ignores the hierarchy of corner radii in real designs | Consistent border-radius from the design system | | Generic hero sections | Template-driven, no connection to real content | Content-first layouts | | Lorem ipsum-style copy | Hides layout problems that real content reveals | Realistic placeholder content | | Oversized padding | Destroys visual hierarchy, wastes screen space | Consistent spacing scale | | Stock card grids | Ignores information priority and scanning patterns | Purpose-driven layouts | | Shadow-heavy design | Competes with content, slows rendering on low-end devices | Subtle or no shadows unless specified | ### Spacing and Layout Use a consistent spacing scale. Don't invent values: ```css /* Use the scale: 0.25rem increments (or whatever the project uses) */ /* Good */ padding: 1rem; /* 16px */ /* Good */ gap: 0.75rem; /* 12px */ /* Bad */ padding: 13px; /* Not on any scale */ /* Bad */ margin-top: 2.3rem; /* Not on any scale */ ``` ### Typography Respect the type hierarchy: ``` h1 → Page title (one per page) h2 → Section title h3 → Subsection title body → Default text small → Secondary/helper text ``` Don't skip heading levels. Don't use heading styles for non-heading content. ### Color - Use semantic color tokens: `text-primary`, `bg-surface`, `border-default` — not raw hex values - Ensure sufficient contrast (4.5:1 for normal text, 3:1 for large text) - Don't rely solely on color to convey information ## Accessibility (WCAG 2.1 AA) ### Keyboard Navigation Every interactive element must be keyboard accessible: ```tsx // ✓ Focusable by default // ✓ Custom element with keyboard support
{ if (e.key === 'Enter' || e.key === ' ') handleClick(); }} onClick={handleClick} >Click me
``` ### ARIA Labels ```tsx // Label interactive elements that lack visible text // Label form inputs ``` ### Focus Management ```tsx // Move focus when content changes (e.g., dialog opens) function Dialog({ isOpen, onClose }: DialogProps) { useEffect(() => { if (isOpen) closeButtonRef.current?.focus(); }, [isOpen]); // Trap focus inside dialog when open } ``` ### Meaningful Empty and Error States ```tsx // Don't show blank screens function TaskList({ tasks }: { tasks: Task[] }) { if (tasks.length === 0) { return (

No tasks yet

Get started by creating a new task.

); } return
...
; } ``` ## Responsive Design Design for mobile first, then expand. Test at these breakpoints: 320px, 768px, 1024px, 1440px. ```tsx // Mobile-first responsive using Tailwind
``` ## Loading and Transitions ```tsx // Skeleton loading (not spinners for content areas) function TaskListSkeleton() { return (
{Array.from({ length: 3 }).map((_, i) => (
))}
); } // Optimistic updates for perceived speed function useToggleTask() { // Update UI immediately, rollback on error } ``` ## Common Rationalizations | Rationalization | Reality | |---|---| | "Accessibility is a nice-to-have" | It's a legal requirement in many jurisdictions and an engineering quality standard. | | "We'll make it responsive later" | Retrofitting responsive design is 3x harder than building it from the start. | | "The design isn't final, so I'll skip styling" | Use the design system defaults. Unstyled UI creates a broken first impression. | | "This is just a prototype" | Prototypes become production code. Build the foundation right. | | "The AI aesthetic is fine for now" | It signals low quality. Use the project's actual design system from the start. | ## Red Flags - Components with more than 200 lines (split them) - Inline styles or arbitrary pixel values - Missing error states, loading states, or empty states - No keyboard navigation testing - Color as the sole indicator of state (red/green without text or icons) - Generic "AI look" (purple gradients, oversized cards, stock layouts) ## Verification After building UI: - [ ] Component renders without console errors - [ ] All interactive elements are keyboard accessible (Tab through the page) - [ ] Screen reader can convey the page's content and structure - [ ] Responsive: works at 320px, 768px, 1024px, 1440px - [ ] Loading, empty, error, success, and permission states handled when applicable - [ ] Follows the project's design system (spacing, colors, typography) - [ ] The rendered result passes a final UI-specific finish-gate review - [ ] No accessibility warnings in dev tools or axe-core