These are production patterns learned through real agency builds. Apply them on every project.
Tailwind 4 + Turbopack — Named CSS Classes Architecture
Tailwind 4 with Turbopack does NOT scan utility classes from large agent-generated files. This is both a Mike standing order AND a technical requirement.
Rule: All layout, color, and spacing go in named CSS classes in globals.css. Only structural Tailwind utilities (flex, grid, hidden, responsive breakpoints) are safe inline.
Never: className="bg-[#1a2744] px-6 py-4 text-white font-bold"
Always: className="hero-card" with .hero-card { background-color: var(--color-primary); padding: 1.5rem 2rem; color: white; font-weight: bold; } in globals.css
ShadCN v5 Install Pattern
ShadCN v5 init (base-nova style) injects @import "tw-animate-css" and @import "shadcn/tailwind.css" into globals.css. These BREAK builds in workspace-root situations.
Fix: Remove both injected imports. Tailwind v3 projects only need @tailwind base/components/utilities. ShadCN v5 semantic tokens (bg-card, text-foreground, text-muted-foreground, bg-muted) need CSS custom properties in :root. Reference them in tailwind.config.ts using hsl(var(--token)) pattern.
Also: Add all brand vars to :root (not just .light) so they work as defaults without data-theme attr.
Server Components Event Handlers
Server components cannot have onMouseEnter/onMouseLeave or any event handlers. Add "use client" to any component with event handlers.
framer-motion Animation Patterns
NEVER use initial={{ opacity: 0 }} with useInView — content will be invisible until JS fires AND user scrolls. Use whileInView instead with viewport={{ once: true, margin: "-100px" }}.
Hero content must NEVER use initial opacity animations. Hero content must be visible immediately on page load. Use static rendering for all above-the-fold content.
Next.js Font Loading
Always use next/font/google for Google Fonts. Never use <link> tags or external CDN. Apply font variables on <html> element.
next/image Rules
ALL images use next/image. Never use <img> tags. Above-fold hero: use priority prop. Below-fold: default lazy loading.
Image sources: Always local (/images/site/). Never use Unsplash, Pexels, or any stock photo CDN.
Shared Working Trees (Multi-Agent Git)
When sharing a git working tree with another agent: stage ONLY your files. Never use git add -A. Commit on isolated branch. Never git add files owned by other agents.
Class-Based Dark Mode Verification
Playwright emulateMedia colorScheme dark does NOT trigger next-themes class-based dark mode. CSS .dark selectors are correct — just can't verify via Playwright media emulation. Verify dark mode manually in browser.
Mobile Patterns
Mobile horizontal scroll: flex overflow-x-auto snap-x snap-mandatory + min-w-[200px] snap-start flex-shrink-0 on items.
Gradient fade scroll indicator: absolute right-0 w-8 bg-gradient-to-l from-[page-bg] to-transparent pointer-events-none md:hidden
Touch target pattern: min-h-11 min-w-[44px] flex items-center justify-center
CSS Techniques
- CSS conic-gradient for donut charts without SVG or JS
- CSS keyframe radar sweep (rotating conic-gradient) — strong ops-aesthetic element
- IntersectionObserver for scroll-spy: threshold 0.3 works for ~900px sections
- Self-contained HTML galleries: @import for Google Fonts (single external dep), inline everything else
End of site-corpus.md — 18 skills compiled for Frankie's Site Building SOP knowledge base.