Design Patterns
Design Patterns
Responsive Design Strategy
Mobile-First Approach
-
Base styles target mobile (< 640px)
-
Progressive enhancement for tablet (768px+) and desktop (1024px+)
-
Touch-friendly targets: minimum 44px × 44px
Breakpoints (from design-tokens.md):
const breakpoints = {
sm: '640px', // Small devices
md: '768px', // Tablets
lg: '1024px', // Desktops
xl: '1280px', // Large desktops
'2xl': '1536px' // Extra large
};
Theme Support
Light/Dark Mode
-
Use Tailwind’s
dark:variant -
Store preference in localStorage
-
Respect system preference (
prefers-color-scheme) -
Smooth transitions between themes
Implementation Pattern:
// Use next-themes for theme management
import { ThemeProvider } from 'next-themes';
<ThemeProvider attribute="class" defaultTheme="system">
{children}
</ThemeProvider>
Animation Strategy
Library: Framer Motion (for complex animations) + CSS Transitions (for simple states)
When to Use Framer Motion:
-
Page transitions
-
Complex multi-step animations
-
Gesture-based interactions (drag, swipe)
-
Orchestrated animations (stagger effects)
When to Use CSS Transitions:
-
Hover states
-
Focus indicators
-
Simple show/hide animations
-
Color/opacity changes
Performance Guidelines:
-
Respect
prefers-reduced-motion -
Animate
transformandopacityonly (GPU-accelerated) -
Avoid animating
width,height,top,left -
Keep animations under 300ms for UI feedback
Example:
// Framer Motion for page transitions
import { motion } from 'framer-motion';
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{ duration: 0.2 }}
>
{content}
</motion.div>
// CSS for hover states
.button {
transition: background-color 150ms ease-in-out;
}
.button:hover {
background-color: var(--color-primary-600);
}
Loading States
Pattern: Skeleton screens + Suspense boundaries
Requirements:
-
Show skeleton UI while data loads
-
Use React Suspense for async components
-
Provide meaningful loading indicators
-
Avoid full-page spinners (use progressive loading)
Example:
import { Suspense } from 'react';
import { CampaignListSkeleton } from '@/components/skeletons';
<Suspense fallback={<CampaignListSkeleton />}>
<CampaignList />
</Suspense>
Error Handling
Pattern: Error boundaries + user-friendly messages
Requirements:
-
Catch errors at component boundaries
-
Show actionable error messages
-
Provide retry mechanisms
-
Log errors to monitoring service (Sentry) (Future/2026 Spike)
Example:
<ErrorBoundary
fallback={<ErrorFallback />}
onError={(error) => logToSentry(error)}
>
<CampaignEditor />
</ErrorBoundary>