assets/animations.css
/* Modern CSS Animations and Transitions
Copy these animations to your global CSS file */
/* Fade Animations */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeInDown {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Slide Animations */
@keyframes slideInLeft {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
@keyframes slideInRight {
from {
transform: translateX(100%);
}
to {
transform: translateX(0);
}
}
/* Scale Animations */
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0.9);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes scaleOut {
from {
opacity: 1;
transform: scale(1);
}
to {
opacity: 0;
transform: scale(0.9);
}
}
/* Bounce Animation */
@keyframes bounce {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-10px);
}
}
/* Pulse Animation */
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
/* Shimmer/Skeleton Loading */
@keyframes shimmer {
0% {
background-position: -1000px 0;
}
100% {
background-position: 1000px 0;
}
}
/* Spin Animation (for loaders) */
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
/* Utility Classes */
.animate-fade-in {
animation: fadeIn 0.3s ease-in;
}
.animate-fade-out {
animation: fadeOut 0.3s ease-out;
}
.animate-fade-in-up {
animation: fadeInUp 0.4s ease-out;
}
.animate-fade-in-down {
animation: fadeInDown 0.4s ease-out;
}
.animate-slide-in-left {
animation: slideInLeft 0.3s ease-out;
}
.animate-slide-in-right {
animation: slideInRight 0.3s ease-out;
}
.animate-scale-in {
animation: scaleIn 0.2s ease-out;
}
.animate-scale-out {
animation: scaleOut 0.2s ease-in;
}
.animate-bounce {
animation: bounce 1s infinite;
}
.animate-pulse {
animation: pulse 2s infinite;
}
.animate-spin {
animation: spin 1s linear infinite;
}
/* Skeleton Loader */
.skeleton {
background: linear-gradient(
90deg,
#f0f0f0 0px,
#e0e0e0 40px,
#f0f0f0 80px
);
background-size: 1000px;
animation: shimmer 2s infinite;
}
/* Hover Effects */
.hover-lift {
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.hover-lift:hover {
transform: translateY(-4px);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
}
.hover-glow {
transition: box-shadow 0.3s ease;
}
.hover-glow:hover {
box-shadow: 0 0 20px rgba(59, 130, 246, 0.5);
}
.hover-scale {
transition: transform 0.2s ease;
}
.hover-scale:hover {
transform: scale(1.05);
}
/* Smooth Transitions */
.transition-smooth {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.transition-fast {
transition: all 0.15s ease;
}
.transition-slow {
transition: all 0.5s ease;
}
/* Stagger Animation Delays (for lists) */
.stagger-item-1 {
animation-delay: 0.1s;
}
.stagger-item-2 {
animation-delay: 0.2s;
}
.stagger-item-3 {
animation-delay: 0.3s;
}
.stagger-item-4 {
animation-delay: 0.4s;
}
.stagger-item-5 {
animation-delay: 0.5s;
}
/* Accessibility: Respect prefers-reduced-motion */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
assets/button-variants.tsx
// Modern Button Component with Multiple Variants
// Copy and customize this component for your Next.js project
import React from 'react';
import { cn } from '@/lib/utils'; // or use your utility function
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger';
size?: 'sm' | 'md' | 'lg';
isLoading?: boolean;
children: React.ReactNode;
}
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant = 'primary', size = 'md', isLoading, children, disabled, ...props }, ref) => {
const baseStyles = 'inline-flex items-center justify-center font-medium transition-all duration-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed';
const variants = {
primary: 'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500 shadow-sm hover:shadow-md',
secondary: 'bg-slate-600 text-white hover:bg-slate-700 focus:ring-slate-500 shadow-sm hover:shadow-md',
outline: 'border-2 border-blue-600 text-blue-600 hover:bg-blue-50 focus:ring-blue-500',
ghost: 'text-slate-700 hover:bg-slate-100 focus:ring-slate-500',
danger: 'bg-red-600 text-white hover:bg-red-700 focus:ring-red-500 shadow-sm hover:shadow-md',
};
const sizes = {
sm: 'px-3 py-1.5 text-sm',
md: 'px-4 py-2 text-base',
lg: 'px-6 py-3 text-lg',
};
return (
<button
ref={ref}
className={cn(baseStyles, variants[variant], sizes[size], className)}
disabled={disabled || isLoading}
{...props}
>
{isLoading && (
<svg
className="animate-spin -ml-1 mr-2 h-4 w-4"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
/>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
</svg>
)}
{children}
</button>
);
}
);
Button.displayName = 'Button';
// Example usage:
// <Button variant="primary" size="md">Click me</Button>
// <Button variant="outline" size="lg" isLoading>Loading...</Button>
assets/card-variants.tsx
// Modern Card Component with Multiple Variants
// Copy and customize this component for your Next.js project
import React from 'react';
import { cn } from '@/lib/utils'; // or use your utility function
interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
variant?: 'default' | 'bordered' | 'elevated' | 'interactive';
padding?: 'none' | 'sm' | 'md' | 'lg';
children: React.ReactNode;
}
export const Card = React.forwardRef<HTMLDivElement, CardProps>(
({ className, variant = 'default', padding = 'md', children, ...props }, ref) => {
const baseStyles = 'rounded-xl bg-white transition-all duration-200';
const variants = {
default: 'shadow-sm',
bordered: 'border-2 border-slate-200',
elevated: 'shadow-lg hover:shadow-xl',
interactive: 'shadow-md hover:shadow-xl cursor-pointer hover:-translate-y-1',
};
const paddings = {
none: '',
sm: 'p-4',
md: 'p-6',
lg: 'p-8',
};
return (
<div
ref={ref}
className={cn(baseStyles, variants[variant], paddings[padding], className)}
{...props}
>
{children}
</div>
);
}
);
Card.displayName = 'Card';
export const CardHeader = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, children, ...props }, ref) => (
<div ref={ref} className={cn('mb-4', className)} {...props}>
{children}
</div>
));
CardHeader.displayName = 'CardHeader';
export const CardTitle = React.forwardRef<
HTMLHeadingElement,
React.HTMLAttributes<HTMLHeadingElement>
>(({ className, children, ...props }, ref) => (
<h3 ref={ref} className={cn('text-2xl font-bold text-slate-900', className)} {...props}>
{children}
</h3>
));
CardTitle.displayName = 'CardTitle';
export const CardDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, children, ...props }, ref) => (
<p ref={ref} className={cn('text-sm text-slate-600 mt-1', className)} {...props}>
{children}
</p>
));
CardDescription.displayName = 'CardDescription';
export const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, children, ...props }, ref) => (
<div ref={ref} className={cn('', className)} {...props}>
{children}
</div>
));
CardContent.displayName = 'CardContent';
export const CardFooter = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, children, ...props }, ref) => (
<div ref={ref} className={cn('mt-6 pt-4 border-t border-slate-200', className)} {...props}>
{children}
</div>
));
CardFooter.displayName = 'CardFooter';
// Example usage:
// <Card variant="interactive">
// <CardHeader>
// <CardTitle>Card Title</CardTitle>
// <CardDescription>Card description goes here</CardDescription>
// </CardHeader>
// <CardContent>
// <p>Your content here</p>
// </CardContent>
// <CardFooter>
// <Button>Action</Button>
// </CardFooter>
// </Card>
assets/input-variants.tsx
// Modern Input Component with Validation States
// Copy and customize this component for your Next.js project
import React from 'react';
import { cn } from '@/lib/utils'; // or use your utility function
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
helperText?: string;
leftIcon?: React.ReactNode;
rightIcon?: React.ReactNode;
}
export const Input = React.forwardRef<HTMLInputElement, InputProps>(
({ className, label, error, helperText, leftIcon, rightIcon, ...props }, ref) => {
const hasError = !!error;
const inputStyles = cn(
'w-full px-4 py-2.5 bg-white border rounded-lg transition-all duration-200',
'text-slate-900 placeholder:text-slate-400',
'focus:outline-none focus:ring-2 focus:ring-offset-0',
'disabled:bg-slate-50 disabled:text-slate-500 disabled:cursor-not-allowed',
hasError
? 'border-red-300 focus:border-red-500 focus:ring-red-200'
: 'border-slate-300 focus:border-blue-500 focus:ring-blue-200',
leftIcon && 'pl-10',
rightIcon && 'pr-10',
className
);
return (
<div className="w-full">
{label && (
<label className="block text-sm font-medium text-slate-700 mb-1.5">
{label}
</label>
)}
<div className="relative">
{leftIcon && (
<div className="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400">
{leftIcon}
</div>
)}
<input ref={ref} className={inputStyles} {...props} />
{rightIcon && (
<div className="absolute right-3 top-1/2 -translate-y-1/2 text-slate-400">
{rightIcon}
</div>
)}
</div>
{error && (
<p className="mt-1.5 text-sm text-red-600 flex items-center gap-1">
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
</svg>
{error}
</p>
)}
{helperText && !error && (
<p className="mt-1.5 text-sm text-slate-500">{helperText}</p>
)}
</div>
);
}
);
Input.displayName = 'Input';
// Textarea Component
interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
label?: string;
error?: string;
helperText?: string;
}
export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
({ className, label, error, helperText, ...props }, ref) => {
const hasError = !!error;
const textareaStyles = cn(
'w-full px-4 py-2.5 bg-white border rounded-lg transition-all duration-200',
'text-slate-900 placeholder:text-slate-400',
'focus:outline-none focus:ring-2 focus:ring-offset-0',
'disabled:bg-slate-50 disabled:text-slate-500 disabled:cursor-not-allowed',
'resize-none',
hasError
? 'border-red-300 focus:border-red-500 focus:ring-red-200'
: 'border-slate-300 focus:border-blue-500 focus:ring-blue-200',
className
);
return (
<div className="w-full">
{label && (
<label className="block text-sm font-medium text-slate-700 mb-1.5">
{label}
</label>
)}
<textarea ref={ref} className={textareaStyles} {...props} />
{error && (
<p className="mt-1.5 text-sm text-red-600 flex items-center gap-1">
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
</svg>
{error}
</p>
)}
{helperText && !error && (
<p className="mt-1.5 text-sm text-slate-500">{helperText}</p>
)}
</div>
);
}
);
Textarea.displayName = 'Textarea';
// Example usage:
// <Input
// label="Email"
// type="email"
// placeholder="you@example.com"
// leftIcon={<MailIcon />}
// helperText="We'll never share your email"
// />
// <Input
// label="Password"
// type="password"
// error="Password must be at least 8 characters"
// />
assets/layout-feature-grid.tsx
// Modern Feature Grid Layout
// Copy and customize this layout for your Next.js pages
import React from 'react';
interface Feature {
icon: React.ReactNode;
title: string;
description: string;
}
interface FeatureGridProps {
title?: string;
subtitle?: string;
features: Feature[];
columns?: 2 | 3 | 4;
}
export const FeatureGrid: React.FC<FeatureGridProps> = ({
title,
subtitle,
features,
columns = 3,
}) => {
const gridCols = {
2: 'md:grid-cols-2',
3: 'md:grid-cols-2 lg:grid-cols-3',
4: 'md:grid-cols-2 lg:grid-cols-4',
};
return (
<section className="py-20 px-4 sm:px-6 lg:px-8 bg-white">
<div className="max-w-7xl mx-auto">
{(title || subtitle) && (
<div className="text-center mb-16">
{title && (
<h2 className="text-3xl sm:text-4xl font-bold text-slate-900 mb-4">
{title}
</h2>
)}
{subtitle && (
<p className="text-xl text-slate-600 max-w-3xl mx-auto">
{subtitle}
</p>
)}
</div>
)}
<div className={`grid grid-cols-1 ${gridCols[columns]} gap-8`}>
{features.map((feature, index) => (
<div
key={index}
className="group p-6 rounded-xl hover:bg-slate-50 transition-all duration-300 hover:shadow-lg animate-fade-in-up"
style={{ animationDelay: `${index * 0.1}s` }}
>
<div className="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center mb-4 text-blue-600 group-hover:bg-blue-600 group-hover:text-white transition-all duration-300">
{feature.icon}
</div>
<h3 className="text-xl font-semibold text-slate-900 mb-2">
{feature.title}
</h3>
<p className="text-slate-600 leading-relaxed">
{feature.description}
</p>
</div>
))}
</div>
</div>
</section>
);
};
// Example usage with icons:
// import { Zap, Shield, Smartphone, Globe, Clock, Users } from 'lucide-react';
//
// <FeatureGrid
// title="Why Choose Us"
// subtitle="Everything you need to build modern web applications"
// columns={3}
// features={[
// {
// icon: <Zap size={24} />,
// title: "Lightning Fast",
// description: "Optimized for speed with cutting-edge performance techniques"
// },
// {
// icon: <Shield size={24} />,
// title: "Secure by Default",
// description: "Built with security best practices from the ground up"
// },
// {
// icon: <Smartphone size={24} />,
// title: "Mobile Responsive",
// description: "Looks great on any device, from phone to desktop"
// },
// {
// icon: <Globe size={24} />,
// title: "Global CDN",
// description: "Delivered fast to users anywhere in the world"
// },
// {
// icon: <Clock size={24} />,
// title: "24/7 Support",
// description: "Our team is always here to help you succeed"
// },
// {
// icon: <Users size={24} />,
// title: "Team Collaboration",
// description: "Built for teams to work together seamlessly"
// }
// ]}
// />
assets/layout-hero-section.tsx
// Modern Hero Section Layout
// Copy and customize this layout for your Next.js landing pages
import React from 'react';
import { cn } from '@/lib/utils';
interface HeroSectionProps {
variant?: 'centered' | 'split' | 'minimal';
title: string;
subtitle: string;
ctaPrimary?: {
text: string;
onClick: () => void;
};
ctaSecondary?: {
text: string;
onClick: () => void;
};
image?: string;
backgroundGradient?: boolean;
}
export const HeroSection: React.FC<HeroSectionProps> = ({
variant = 'centered',
title,
subtitle,
ctaPrimary,
ctaSecondary,
image,
backgroundGradient = true,
}) => {
if (variant === 'centered') {
return (
<section
className={cn(
'relative py-20 px-4 sm:px-6 lg:px-8',
backgroundGradient && 'bg-gradient-to-br from-blue-50 via-white to-purple-50'
)}
>
<div className="max-w-7xl mx-auto">
<div className="text-center">
<h1 className="text-4xl sm:text-5xl lg:text-6xl font-bold text-slate-900 mb-6 animate-fade-in-up">
{title}
</h1>
<p className="text-xl sm:text-2xl text-slate-600 mb-8 max-w-3xl mx-auto animate-fade-in-up stagger-item-1">
{subtitle}
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center animate-fade-in-up stagger-item-2">
{ctaPrimary && (
<button
onClick={ctaPrimary.onClick}
className="px-8 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-all hover:shadow-lg text-lg font-medium"
>
{ctaPrimary.text}
</button>
)}
{ctaSecondary && (
<button
onClick={ctaSecondary.onClick}
className="px-8 py-3 bg-white text-blue-600 border-2 border-blue-600 rounded-lg hover:bg-blue-50 transition-all text-lg font-medium"
>
{ctaSecondary.text}
</button>
)}
</div>
{image && (
<div className="mt-12 animate-fade-in-up stagger-item-3">
<img
src={image}
alt="Hero"
className="rounded-xl shadow-2xl mx-auto max-w-4xl"
/>
</div>
)}
</div>
</div>
</section>
);
}
if (variant === 'split') {
return (
<section
className={cn(
'relative py-20 px-4 sm:px-6 lg:px-8',
backgroundGradient && 'bg-gradient-to-br from-blue-50 via-white to-purple-50'
)}
>
<div className="max-w-7xl mx-auto">
<div className="grid lg:grid-cols-2 gap-12 items-center">
<div className="animate-fade-in-up">
<h1 className="text-4xl sm:text-5xl lg:text-6xl font-bold text-slate-900 mb-6">
{title}
</h1>
<p className="text-xl text-slate-600 mb-8">
{subtitle}
</p>
<div className="flex flex-col sm:flex-row gap-4">
{ctaPrimary && (
<button
onClick={ctaPrimary.onClick}
className="px-8 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-all hover:shadow-lg text-lg font-medium"
>
{ctaPrimary.text}
</button>
)}
{ctaSecondary && (
<button
onClick={ctaSecondary.onClick}
className="px-8 py-3 bg-white text-blue-600 border-2 border-blue-600 rounded-lg hover:bg-blue-50 transition-all text-lg font-medium"
>
{ctaSecondary.text}
</button>
)}
</div>
</div>
{image && (
<div className="animate-fade-in-up stagger-item-2">
<img
src={image}
alt="Hero"
className="rounded-xl shadow-2xl"
/>
</div>
)}
</div>
</div>
</section>
);
}
// Minimal variant
return (
<section className="relative py-32 px-4 sm:px-6 lg:px-8">
<div className="max-w-4xl mx-auto text-center">
<h1 className="text-5xl sm:text-6xl lg:text-7xl font-bold text-slate-900 mb-6 animate-fade-in-up">
{title}
</h1>
<p className="text-2xl text-slate-600 mb-8 animate-fade-in-up stagger-item-1">
{subtitle}
</p>
{(ctaPrimary || ctaSecondary) && (
<div className="flex flex-col sm:flex-row gap-4 justify-center animate-fade-in-up stagger-item-2">
{ctaPrimary && (
<button
onClick={ctaPrimary.onClick}
className="px-8 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-all hover:shadow-lg text-lg font-medium"
>
{ctaPrimary.text}
</button>
)}
{ctaSecondary && (
<button
onClick={ctaSecondary.onClick}
className="px-8 py-3 text-blue-600 hover:text-blue-700 transition-all text-lg font-medium"
>
{ctaSecondary.text} →
</button>
)}
</div>
)}
</div>
</section>
);
};
// Example usage:
// <HeroSection
// variant="centered"
// title="Build Amazing Things"
// subtitle="Create beautiful, responsive web applications with our modern toolkit"
// ctaPrimary={{ text: "Get Started", onClick: () => {} }}
// ctaSecondary={{ text: "Learn More", onClick: () => {} }}
// image="/hero-image.png"
// />
assets/utils-cn.ts
// Utility function for merging Tailwind CSS classes
// This is commonly used with shadcn/ui and other component libraries
// Copy this to your project's lib/utils.ts file
import { type ClassValue, clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
// If you don't have clsx and tailwind-merge installed, run:
// npm install clsx tailwind-merge
// Example usage:
// cn('px-4 py-2', 'bg-blue-500', { 'text-white': true, 'font-bold': false })
// Result: 'px-4 py-2 bg-blue-500 text-white'
index.js
export default async function frontend_enhancer(input) {
console.log("🧠 Running skill: frontend-enhancer");
// TODO: implement actual logic for this skill
return {
message: "Skill 'frontend-enhancer' executed successfully!",
input
};
}
package.json
{
"name": "@ai-labs-claude-skills/frontend-enhancer",
"version": "1.0.0",
"description": "Claude AI skill: frontend-enhancer",
"main": "index.js",
"files": [
"."
],
"license": "MIT",
"author": "AI Labs"
}
references/color_palettes.md
# Color Palettes for Frontend Enhancement
This reference contains professionally designed color palettes optimized for modern web applications.
## Modern Professional Palettes
### Palette 1: Corporate Blue
- **Primary**: `#2563EB` (Blue 600)
- **Primary Hover**: `#1D4ED8` (Blue 700)
- **Secondary**: `#64748B` (Slate 500)
- **Accent**: `#F59E0B` (Amber 500)
- **Background**: `#F8FAFC` (Slate 50)
- **Surface**: `#FFFFFF`
- **Text Primary**: `#0F172A` (Slate 900)
- **Text Secondary**: `#475569` (Slate 600)
- **Success**: `#10B981` (Emerald 500)
- **Warning**: `#F59E0B` (Amber 500)
- **Error**: `#EF4444` (Red 500)
- **Border**: `#E2E8F0` (Slate 200)
### Palette 2: Vibrant Purple
- **Primary**: `#8B5CF6` (Violet 500)
- **Primary Hover**: `#7C3AED` (Violet 600)
- **Secondary**: `#EC4899` (Pink 500)
- **Accent**: `#14B8A6` (Teal 500)
- **Background**: `#FAFAF9` (Stone 50)
- **Surface**: `#FFFFFF`
- **Text Primary**: `#1C1917` (Stone 900)
- **Text Secondary**: `#57534E` (Stone 600)
- **Success**: `#22C55E` (Green 500)
- **Warning**: `#F97316` (Orange 500)
- **Error**: `#F43F5E` (Rose 500)
- **Border**: `#E7E5E4` (Stone 200)
### Palette 3: Minimalist Gray
- **Primary**: `#18181B` (Zinc 900)
- **Primary Hover**: `#27272A` (Zinc 800)
- **Secondary**: `#71717A` (Zinc 500)
- **Accent**: `#06B6D4` (Cyan 500)
- **Background**: `#FAFAFA` (Zinc 50)
- **Surface**: `#FFFFFF`
- **Text Primary**: `#18181B` (Zinc 900)
- **Text Secondary**: `#52525B` (Zinc 600)
- **Success**: `#84CC16` (Lime 500)
- **Warning**: `#EAB308` (Yellow 500)
- **Error**: `#DC2626` (Red 600)
- **Border**: `#E4E4E7` (Zinc 200)
### Palette 4: Warm Sunset
- **Primary**: `#EA580C` (Orange 600)
- **Primary Hover**: `#C2410C` (Orange 700)
- **Secondary**: `#F97316` (Orange 500)
- **Accent**: `#FBBF24` (Amber 400)
- **Background**: `#FFFBEB` (Amber 50)
- **Surface**: `#FFFFFF`
- **Text Primary**: `#78350F` (Amber 900)
- **Text Secondary**: `#92400E` (Amber 800)
- **Success**: `#16A34A` (Green 600)
- **Warning**: `#D97706` (Amber 600)
- **Error**: `#DC2626` (Red 600)
- **Border**: `#FDE68A` (Amber 200)
### Palette 5: Ocean Fresh
- **Primary**: `#0891B2` (Cyan 600)
- **Primary Hover**: `#0E7490` (Cyan 700)
- **Secondary**: `#06B6D4` (Cyan 500)
- **Accent**: `#6366F1` (Indigo 500)
- **Background**: `#F0FDFA` (Teal 50)
- **Surface**: `#FFFFFF`
- **Text Primary**: `#134E4A` (Teal 900)
- **Text Secondary**: `#0F766E` (Teal 700)
- **Success**: `#14B8A6` (Teal 500)
- **Warning**: `#F59E0B` (Amber 500)
- **Error**: `#E11D48` (Rose 600)
- **Border**: `#99F6E4` (Teal 200)
### Palette 6: Dark Mode
- **Primary**: `#3B82F6` (Blue 500)
- **Primary Hover**: `#2563EB` (Blue 600)
- **Secondary**: `#6366F1` (Indigo 500)
- **Accent**: `#A855F7` (Purple 500)
- **Background**: `#0F172A` (Slate 900)
- **Surface**: `#1E293B` (Slate 800)
- **Text Primary**: `#F8FAFC` (Slate 50)
- **Text Secondary**: `#CBD5E1` (Slate 300)
- **Success**: `#10B981` (Emerald 500)
- **Warning**: `#FBBF24` (Amber 400)
- **Error**: `#F87171` (Red 400)
- **Border**: `#334155` (Slate 700)
## Tailwind CSS Configuration
To use these palettes in Tailwind CSS, add to `tailwind.config.js`:
```javascript
module.exports = {
theme: {
extend: {
colors: {
// Choose one palette and customize as needed
brand: {
primary: '#2563EB',
'primary-hover': '#1D4ED8',
secondary: '#64748B',
accent: '#F59E0B',
},
},
},
},
}
```
## CSS Variables Configuration
For vanilla CSS or CSS-in-JS, use CSS custom properties:
```css
:root {
--color-primary: #2563EB;
--color-primary-hover: #1D4ED8;
--color-secondary: #64748B;
--color-accent: #F59E0B;
--color-background: #F8FAFC;
--color-surface: #FFFFFF;
--color-text-primary: #0F172A;
--color-text-secondary: #475569;
--color-success: #10B981;
--color-warning: #F59E0B;
--color-error: #EF4444;
--color-border: #E2E8F0;
}
```
references/design_principles.md
# Frontend Design Principles
This reference outlines key design principles for creating aesthetically pleasing and user-friendly interfaces.
## Core Design Principles
### 1. Visual Hierarchy
- Use size, weight, and color to establish importance
- Larger, bolder, or brighter elements attract more attention
- Group related elements together
- Use whitespace to separate different sections
### 2. Spacing and Rhythm
- Consistent spacing creates visual harmony
- Use a spacing scale (e.g., 4px, 8px, 16px, 24px, 32px, 48px, 64px)
- Maintain adequate padding around interactive elements (minimum 44x44px touch targets)
- Use margins to create breathing room between sections
### 3. Typography
- Limit to 2-3 font families maximum
- Establish a clear type scale (e.g., 12px, 14px, 16px, 20px, 24px, 32px, 48px)
- Maintain readable line heights (1.5-1.75 for body text)
- Use font weights strategically (400 for body, 500-600 for emphasis, 700 for headings)
- Ensure sufficient contrast (WCAG AA: 4.5:1 for body text, 3:1 for large text)
### 4. Color Theory
- Use a primary color for main actions and branding
- Choose a secondary color for complementary actions
- Reserve accent colors for highlights and calls-to-action
- Maintain consistent color usage throughout the application
- Use neutral grays for text and backgrounds
- Consider color blindness and accessibility
### 5. Consistency
- Maintain consistent button styles, sizes, and behaviors
- Use the same component patterns throughout
- Keep navigation consistent across pages
- Establish and follow a design system
### 6. Responsiveness
- Design mobile-first, then scale up
- Use fluid typography and spacing
- Ensure touch targets are adequately sized on mobile
- Test across multiple device sizes
- Consider tablet-specific layouts
## Best Practices for Modern UI
### Cards and Containers
- Use subtle shadows for depth (box-shadow: 0 1px 3px rgba(0,0,0,0.1))
- Round corners for a softer feel (border-radius: 8px-12px)
- Add hover states for interactive cards
- Maintain consistent padding inside cards
### Buttons
- Primary buttons should be highly visible
- Use ghost/outline buttons for secondary actions
- Ensure adequate padding (px-4 py-2 minimum)
- Add hover and active states for feedback
- Include loading states for async actions
### Forms
- Label inputs clearly
- Show validation feedback inline
- Use appropriate input types (email, tel, number, etc.)
- Provide helpful placeholder text
- Group related fields together
- Show password requirements upfront
### Navigation
- Keep primary navigation persistent and visible
- Use breadcrumbs for deep hierarchies
- Highlight the active page/section
- Make click targets large enough
- Consider sticky navigation for long pages
### Animations
- Keep animations subtle and purposeful
- Use 200-300ms for micro-interactions
- Use 300-500ms for larger transitions
- Respect prefers-reduced-motion
- Avoid excessive motion that distracts
## Accessibility Guidelines
### Contrast
- WCAG AA: 4.5:1 for normal text, 3:1 for large text
- WCAG AAA: 7:1 for normal text, 4.5:1 for large text
- Test color combinations with contrast checkers
### Keyboard Navigation
- Ensure all interactive elements are keyboard accessible
- Provide visible focus indicators
- Maintain logical tab order
- Support escape key for closing modals
### Screen Readers
- Use semantic HTML (nav, main, article, aside)
- Provide alt text for images
- Use ARIA labels when necessary
- Ensure proper heading hierarchy (h1, h2, h3)
### Motion
- Respect prefers-reduced-motion media query
- Provide alternatives to motion-based interactions
- Avoid flashing content (seizure risk)
## Common Layout Patterns
### Hero Section
- Large, attention-grabbing headline
- Concise subheading
- Clear call-to-action
- Optional background image or illustration
### Feature Grid
- 2-3 columns on desktop
- Single column on mobile
- Icons or illustrations for each feature
- Concise descriptions
### Pricing Table
- Clear plan names and prices
- Feature comparison
- Highlighted recommended plan
- Clear call-to-action buttons
### Dashboard Layout
- Summary cards at the top
- Charts and graphs in the main area
- Filters and controls easily accessible
- Responsive grid layout
### Blog/Content Layout
- Wide reading column (60-70 characters per line)
- Clear typography hierarchy
- Adequate line spacing
- Sidebars for supplementary content