DevSkyy Frontend Architecture
This skill activates when users discuss component architecture, design systems, CSS methodologies, or frontend patterns. Provides guidance on React patterns, state management architecture, component hierarchies, and scalable frontend design systems.
install
source · Clone the upstream repo
git clone https://github.com/The-Skyy-Rose-Collection-LLC/DevSkyy
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/The-Skyy-Rose-Collection-LLC/DevSkyy "$T" && mkdir -p ~/.claude/skills && cp -r "$T/wordpress-copilot/skills/frontend-architecture" ~/.claude/skills/the-skyy-rose-collection-llc-devskyy-frontend-architecture && rm -rf "$T"
manifest:
wordpress-copilot/skills/frontend-architecture/SKILL.mdsource content
Frontend Architecture
Design scalable, maintainable frontend architectures for WordPress themes and modern web applications.
When This Activates
- "design system", "component architecture", "CSS methodology"
- "state management", "component hierarchy", "atomic design"
- "frontend structure", "architecture patterns", "scalable frontend"
- User planning large-scale React/Vue/Svelte applications
- Discussing how to organize components and styles
Component Architecture Patterns
Atomic Design Methodology
Atoms → Molecules → Organisms → Templates → Pages
For SkyyRose:
atoms/ ├── Button/ # Primary CTA buttons (#B76E79) ├── Input/ # Form inputs with luxury styling ├── Icon/ # SVG icon system └── Typography/ # Playfair Display, sans-serif molecules/ ├── FormField/ # Label + Input + Error ├── ProductCard/ # Image + Title + Price + CTA ├── SearchBar/ # Input + Icon + Button └── NavItem/ # Icon + Text + Badge organisms/ ├── ProductGrid/ # Multiple ProductCards ├── CheckoutForm/ # Multiple FormFields ├── SiteHeader/ # Logo + Nav + Search + Cart └── ProductCarousel/ # Swiper + ProductCards templates/ ├── CollectionLayout/ # Header + Grid + Filters ├── ProductLayout/ # Header + 3D Viewer + Details └── CheckoutLayout/ # Header + Form + Summary pages/ ├── HomePage/ # Hero + Collections + Features ├── CollectionPage/ # CollectionLayout with data └── ProductPage/ # ProductLayout with product
Feature-Based Organization
// For complex features, group by domain features/ ├── product-configurator/ │ ├── components/ │ │ ├── ColorPicker.tsx │ │ ├── SizeSelector.tsx │ │ └── Scene3D.tsx │ ├── hooks/ │ │ ├── useConfiguration.ts │ │ └── use3DModel.ts │ ├── store/ │ │ └── configurationSlice.ts │ ├── types/ │ │ └── configuration.ts │ └── index.tsx # Public API ├── checkout/ │ ├── components/ │ ├── hooks/ │ ├── store/ │ └── index.tsx
State Management Architecture
When to Use What
| State Type | Solution | Example |
|---|---|---|
| Local UI | useState | Modal open/closed, form inputs |
| Form | React Hook Form | Checkout, contact forms |
| Shared UI | Context + Reducer | Theme (dark/light), cart |
| Server Cache | TanStack Query | Products, orders, user |
| Global App | Zustand/Redux | Auth, preferences, config |
SkyyRose Cart State Example
// Using Zustand for simplicity import { create } from 'zustand'; import { persist } from 'zustand/middleware'; interface CartItem { productId: string; variantId?: string; quantity: number; price: number; name: string; image: string; } interface CartStore { items: CartItem[]; addItem: (item: CartItem) => void; removeItem: (productId: string) => void; updateQuantity: (productId: string, quantity: number) => void; clearCart: () => void; total: () => number; } export const useCart = create<CartStore>()( persist( (set, get) => ({ items: [], addItem: (item) => set((state) => { const existing = state.items.find((i) => i.productId === item.productId); if (existing) { return { items: state.items.map((i) => i.productId === item.productId ? { ...i, quantity: i.quantity + item.quantity } : i ), }; } return { items: [...state.items, item] }; }), removeItem: (productId) => set((state) => ({ items: state.items.filter((i) => i.productId !== productId), })), updateQuantity: (productId, quantity) => set((state) => ({ items: state.items.map((i) => i.productId === productId ? { ...i, quantity } : i ), })), clearCart: () => set({ items: [] }), total: () => { return get().items.reduce((sum, item) => sum + item.price * item.quantity, 0); }, }), { name: 'skyyrose-cart', } ) );
CSS Architecture
BEM + CSS Modules Pattern
/* ProductCard.module.css */ .card { background: #FFFFFF; border-radius: 8px; transition: transform 0.3s ease; } .card:hover { transform: translateY(-4px); } .card__image { width: 100%; aspect-ratio: 1; object-fit: cover; } .card__title { font-family: 'Playfair Display', serif; color: #B76E79; /* SkyyRose primary */ font-size: 1.5rem; } .card__price { font-weight: 600; color: #2C2C2C; } .card__button { background: linear-gradient(135deg, #B76E79, #D4A5AE); color: #FFFFFF; padding: 12px 24px; border: none; border-radius: 4px; cursor: pointer; transition: opacity 0.2s; } .card__button:hover { opacity: 0.9; }
// ProductCard.tsx import styles from './ProductCard.module.css'; export function ProductCard({ product }) { return ( <div className={styles.card}> <img src={product.image} className={styles.card__image} /> <h3 className={styles.card__title}>{product.name}</h3> <p className={styles.card__price}>${product.price}</p> <button className={styles.card__button}>Add to Cart</button> </div> ); }
Tailwind + CVA Pattern
// For utility-first approach import { cva, type VariantProps } from 'class-variance-authority'; import { cn } from '@/lib/utils'; const buttonVariants = cva( 'inline-flex items-center justify-center rounded-md font-medium transition-colors', { variants: { variant: { primary: 'bg-[#B76E79] text-white hover:bg-[#A55D68]', secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200', ghost: 'hover:bg-gray-100', }, size: { sm: 'h-9 px-3 text-sm', md: 'h-11 px-6', lg: 'h-13 px-8 text-lg', }, }, defaultVariants: { variant: 'primary', size: 'md', }, } ); interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {} export function Button({ className, variant, size, ...props }: ButtonProps) { return ( <button className={cn(buttonVariants({ variant, size, className }))} {...props} /> ); }
Design System Implementation
Token System
// design-tokens.ts export const tokens = { colors: { brand: { primary: '#B76E79', secondary: '#D4A5AE', dark: '#8B5663', light: '#F5E6E8', }, neutral: { black: '#1A1A1A', gray: { 900: '#2C2C2C', 700: '#4A4A4A', 500: '#767676', 300: '#D1D1D1', 100: '#F5F5F5', }, white: '#FFFFFF', }, semantic: { success: '#22C55E', warning: '#F59E0B', error: '#EF4444', info: '#3B82F6', }, }, typography: { fontFamily: { heading: "'Playfair Display', serif", body: "'Inter', sans-serif", mono: "'JetBrains Mono', monospace", }, fontSize: { xs: '0.75rem', // 12px sm: '0.875rem', // 14px base: '1rem', // 16px lg: '1.125rem', // 18px xl: '1.25rem', // 20px '2xl': '1.5rem', // 24px '3xl': '1.875rem', // 30px '4xl': '2.25rem', // 36px }, fontWeight: { normal: 400, medium: 500, semibold: 600, bold: 700, }, }, spacing: { xs: '0.25rem', // 4px sm: '0.5rem', // 8px md: '1rem', // 16px lg: '1.5rem', // 24px xl: '2rem', // 32px '2xl': '3rem', // 48px '3xl': '4rem', // 64px }, animation: { duration: { fast: '150ms', base: '300ms', slow: '500ms', }, easing: { easeIn: 'cubic-bezier(0.4, 0, 1, 1)', easeOut: 'cubic-bezier(0, 0, 0.2, 1)', easeInOut: 'cubic-bezier(0.4, 0, 0.2, 1)', luxury: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', // Smooth luxury feel }, }, } as const;
Component Communication Patterns
Props Down, Events Up
// Parent → Child: Props // Child → Parent: Callbacks // Parent function ProductPage() { const [quantity, setQuantity] = useState(1); const handleAddToCart = (qty: number) => { addToCart({ ...product, quantity: qty }); }; return ( <ProductDetails product={product} quantity={quantity} onQuantityChange={setQuantity} onAddToCart={handleAddToCart} /> ); } // Child function ProductDetails({ product, quantity, onQuantityChange, onAddToCart }) { return ( <div> <h1>{product.name}</h1> <QuantitySelector value={quantity} onChange={onQuantityChange} /> <button onClick={() => onAddToCart(quantity)}> Add to Cart </button> </div> ); }
Context for Deep Props
// Avoid prop drilling with context import { createContext, useContext } from 'react'; const ThemeContext = createContext<{ mode: 'light' | 'dark' }>({ mode: 'light' }); export function ThemeProvider({ children }) { const [mode, setMode] = useState<'light' | 'dark'>('light'); return ( <ThemeContext.Provider value={{ mode, setMode }}> {children} </ThemeContext.Provider> ); } export const useTheme = () => useContext(ThemeContext); // Deep nested component can access theme function DeepNestedButton() { const { mode } = useTheme(); return <button data-theme={mode}>Click</button>; }
Performance Architecture
Code Splitting Strategy
// Route-based splitting import { lazy, Suspense } from 'react'; const HomePage = lazy(() => import('./pages/HomePage')); const ProductPage = lazy(() => import('./pages/ProductPage')); const CheckoutPage = lazy(() => import('./pages/CheckoutPage')); function App() { return ( <Suspense fallback={<LoadingSpinner />}> <Routes> <Route path="/" element={<HomePage />} /> <Route path="/products/:id" element={<ProductPage />} /> <Route path="/checkout" element={<CheckoutPage />} /> </Routes> </Suspense> ); }
Component-level splitting
// Heavy 3D component loaded on-demand const Product3DViewer = lazy(() => import('./Product3DViewer')); function ProductPage() { const [show3D, setShow3D] = useState(false); return ( <div> <button onClick={() => setShow3D(true)}>View in 3D</button> {show3D && ( <Suspense fallback={<div>Loading 3D viewer...</div>}> <Product3DViewer model={product.model} /> </Suspense> )} </div> ); }
WordPress Theme Integration
Enqueue React App in Theme
// functions.php function skyyrose_enqueue_react_app() { $asset_file = get_template_directory() . '/build/index.asset.php'; if (file_exists($asset_file)) { $asset = require $asset_file; wp_enqueue_script( 'skyyrose-app', get_template_directory_uri() . '/build/index.js', $asset['dependencies'], $asset['version'], true ); wp_enqueue_style( 'skyyrose-app', get_template_directory_uri() . '/build/index.css', [], $asset['version'] ); // Pass data to React wp_localize_script('skyyrose-app', 'skyyRoseData', [ 'apiUrl' => rest_url('skyyrose/v1'), 'nonce' => wp_create_nonce('wp_rest'), 'brandColor' => '#B76E79', 'collections' => get_skyyrose_collections(), ]); } } add_action('wp_enqueue_scripts', 'skyyrose_enqueue_react_app');
// React app entry point declare global { interface Window { skyyRoseData: { apiUrl: string; nonce: string; brandColor: string; collections: Array<{ id: string; name: string; slug: string }>; }; } } const root = ReactDOM.createRoot(document.getElementById('skyyrose-app')!); root.render( <StrictMode> <App config={window.skyyRoseData} /> </StrictMode> );
Decision Framework
When to Choose Architecture Pattern
| Scenario | Pattern |
|---|---|
| Small theme | Vanilla JS + WordPress |
| Interactive features | React islands |
| SPA-like experience | Full React SPA |
| Static + interactive | Next.js SSG + ISR |
| Complex state | Redux/Zustand |
SkyyRose Best Practices
- Component naming:
prefix for custom components (Skyy
,SkyyProductCard
)SkyyCheckout - Brand tokens: Always use
not hardcodedtokens.colors.brand.primary#B76E79 - Animations: Use
for smooth, premium feeltokens.animation.easing.luxury - Typography: Playfair Display for headings, Inter for body
- Spacing: Use design tokens, not arbitrary values
When User Asks For Architecture
- Understand scope: How many pages? How complex?
- Assess interactivity: Static content vs. dynamic features?
- Recommend pattern: Feature-based, atomic, or hybrid
- Design state: What needs to be shared? What's local?
- Plan performance: Code splitting, lazy loading, SSR
- WordPress integration: Theme structure, enqueue strategy
Provide complete, production-ready architecture plans with clear file structure and implementation order.