Neej Frontend Craft
A unified frontend design + implementation skill that produces distinctive, production-grade interfaces. Combines design intelligence, a personal design system, animation best practices, and a self-evaluation loop into one workflow.
Core Philosophy
Great frontend is not about stacking libraries. It's about:
- Context-aware design decisions — every project has a different audience, tone, and purpose
- Encoded taste — specific, concrete preferences rather than vague "be bold" instructions
- Self-evaluation before delivery — catch AI slop patterns before the human sees them
- Restraint over excess — the best designs feel intentional, not decorated
Workflow (Follow Every Time)
Step 1: Read the Design Brief + Gather References
Before writing ANY frontend code, read references/design-brief.md in this skill's directory. It contains the personal design system, preferred aesthetic, font pairings, color systems, and anti-patterns. This is the source of truth for all visual decisions.
Reference URL Analysis (optional but recommended): Ask the human: "Any reference sites or designs you want this to feel like?" If they provide a URL:
- Use Defuddle (or WebFetch if Defuddle unavailable) to scrape the site
- Extract and note: color palette, font families, layout structure, spacing patterns, animation style
- Merge these observations with the design brief — the brief is the foundation, the reference is directional influence
- If the reference conflicts with the design brief (e.g., they show a pastel site but brief says dark-first), ask which to prioritize
If they provide a Figma file URL and Figma MCP is connected:
- Read the Figma file for design tokens, component structures, and layout data
- Use Figma tokens as the primary source for Step 3 (design token generation)
- Note any gaps where Figma doesn't define tokens — fill from design brief
Growing the Inspiration Library: When the human says "add [url] to inspiration" or "save this as reference":
- Use Defuddle to analyze the site
- Append to
references/inspiration-sites.mdwith: URL, what to study, what to steal, tier classification - Note the date added so stale references can be cleaned up
Step 2: Classify the Project Context
Determine which category this frontend falls into, as it changes everything:
| Context | Aesthetic Direction | Animation Level | Component Density |
|---|---|---|---|
| SaaS Dashboard | Clean, data-first, functional | Minimal — transitions only | High — tables, charts, sidebars |
| Landing Page | Bold, conversion-focused, atmospheric | Medium — scroll reveals, hero animations | Low — sections, CTAs, social proof |
| Marketing/Brand | Expressive, editorial, immersive | High — scroll-driven, parallax, micro-interactions | Low — storytelling sections |
| Client Portal | Professional, trustworthy, clear | Minimal — state transitions | Medium — forms, status, navigation |
| Developer Tool | Technical, information-dense, precise | Minimal — feedback only | Very High — code, configs, logs |
Step 3: Generate Design Tokens
For every new project or page, generate a design token block before writing UI code.
If a Figma MCP is connected and a Figma file exists for this project, read tokens from Figma first and use them as the source of truth. Otherwise, generate from the design brief.
PROJECT: [name]
CONTEXT: [category from Step 2]
FIGMA_SOURCE: [Figma file URL if available, otherwise "none — generating from design brief"]
PALETTE (OKLCH — hex fallback in comments):
background: oklch([L] [C] [H]) /* #hex */
surface: oklch([L] [C] [H]) /* #hex */
text-primary: oklch([L] [C] [H]) /* #hex */
text-secondary: oklch([L] [C] [H]) /* #hex */
accent: oklch([L] [C] [H]) /* #hex */
accent-hover: oklch([L] [C] [H]) /* #hex */
border: oklch([L] [C] [H]) /* #hex */
destructive: oklch([L] [C] [H]) /* #hex */
success: oklch([L] [C] [H]) /* #hex */
TYPOGRAPHY:
display: [font family] (variable) — [where to load from]
heading: [font family]
body: [font family] — dark mode weight adjustment: [e.g., 400→380]
mono: [font family]
scale: [base size, e.g., 16px with 1.25 ratio]
optical-sizing: auto
SPACING: [system, e.g., 4px base, multiples of 4]
RADII: [e.g., 6px default, 8px cards, 12px modals]
SHADOWS: [style description]
ANIMATION: [level from Step 2] — CSS-first, Motion for complex
DATA_VIZ: [chart library if needed — Recharts/Nivo/none]
ACCESSIBILITY: WCAG 2.2 AA, prefers-reduced-motion, prefers-contrast
ANTI-PATTERNS: [list 3-5 specific things to avoid for THIS project]
Step 4: Implement
Build the frontend using these constraints:
Stack (default unless otherwise specified):
- Next.js App Router + TypeScript
- Tailwind CSS v4 + CSS variables for theming (OKLCH color space)
- shadcn/ui as component primitives (Radix or Base UI underneath)
- Motion (formerly Framer Motion) for complex animations
- CSS View Transitions API for page transitions
- CSS Scroll-Driven Animations for simple scroll effects (Motion fallback for complex)
- Lucide React for icons
- Google Fonts or Fontsource for typography (variable fonts preferred)
- TanStack Table for data tables
- Recharts (standard dashboards) or Nivo (presentation-quality charts) for data viz
Project Scaffolding:
Use npx shadcn create (Visual Builder at ui.shadcn.com/create) to generate the initial project with design tokens baked in. Choose Radix UI or Base UI as primitive layer. Customize theme colors, fonts, icons, and border-radius in the builder, then further customize in globals.css with your project's design tokens from Step 3.
Implementation Rules:
- Every color must come from CSS variables — never hardcode hex values in components
- Typography scale must be defined once in globals.css and referenced via Tailwind classes
- All interactive elements need hover, focus, and active states
- Dark mode support via CSS variables +
classstrategy (notmedia) - Responsive: mobile-first, breakpoints at sm(640), md(768), lg(1024), xl(1280)
- Loading states for all async operations — skeleton screens, not spinners
- All text must have sufficient contrast (WCAG AA minimum: 4.5:1 for body, 3:1 for large text)
Animation Rules (read references/animation-patterns.md for full guide):
- Page load: stagger reveal with
motion.divvariants, 50-80ms stagger delay - Navigation: CSS View Transitions API for route changes (lighter than AnimatePresence). Fallback to
AnimatePresencefor complex shared-element transitions - Micro-interactions:
whileHover,whileTapon interactive elements — scale(1.02) max for buttons - Data loading: skeleton shimmer using CSS animation (not Motion — too heavy for this)
- Scroll-driven: CSS
animation-timeline: view()for simple reveals. Motion'suseScroll+useTransformfor complex parallax/progress-linked effects. Use@supports (animation-timeline: view())for progressive enhancement - NEVER animate layout properties (width, height, top, left) — use transform only
- NEVER add animation that doesn't serve UX purpose (guiding attention, confirming action, showing state)
Step 5: Self-Evaluate Before Delivery
Before presenting ANY frontend output, run through this checklist mentally. If any item fails, fix it before showing the human.
AI Slop Detection (CRITICAL — read references/evaluation-criteria.md):
- No purple gradients on white backgrounds
- No Inter, Roboto, Arial, or system-ui as primary fonts
- No centered-everything layouts (asymmetry is almost always better)
- No generic card grids with uniform rounded corners and shadows
- No stock-photo-energy hero sections
- No "Get Started" / "Learn More" as the only CTA text (be specific)
- No gratuitous glassmorphism or blur effects without purpose
- No rainbow gradient text
- No