---
globs: src/components/**/*.tsx
---

# Component Patterns

## Component Structure

### File Organization
- Place reusable components in `src/components/`
- Use PascalCase for component files: `ComponentName.tsx`
- Group related components in subdirectories when needed

### Component Template
```typescript
import { cn } from '@/lib/utils'

interface ComponentProps {
  className?: string
  children?: React.ReactNode
  // Other props
}

export function ComponentName({ 
  className, 
  children, 
  ...props 
}: ComponentProps) {
  return (
    <div className={cn("base-styles", className)} {...props}>
      {children}
    </div>
  )
}
```

## shadcn/ui Integration

### Using shadcn/ui Components
```typescript
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'

export function ProjectCard({ project }: { project: Project }) {
  return (
    <Card className="bg-black border-gray-800">
      <CardHeader>
        <CardTitle className="text-white">{project.title}</CardTitle>
      </CardHeader>
      <CardContent>
        <Badge variant="outline">{project.category}</Badge>
      </CardContent>
    </Card>
  )
}
```

### Extending shadcn/ui Components
```typescript
// Create wrapper components for common patterns
import { Button } from '@/components/ui/button'
import { cn } from '@/lib/utils'

interface PrimaryButtonProps extends React.ComponentProps<typeof Button> {
  loading?: boolean
}

export function PrimaryButton({ 
  loading, 
  className, 
  children, 
  ...props 
}: PrimaryButtonProps) {
  return (
    <Button 
      className={cn("bg-primary hover:bg-primary/90", className)}
      disabled={loading}
      {...props}
    >
      {loading ? "Loading..." : children}
    </Button>
  )
}
```

## Animation Patterns

### Framer Motion Usage
```typescript
import { motion } from 'framer-motion'

export function AnimatedCard({ children }: { children: React.ReactNode }) {
  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.3 }}
      className="card-styles"
    >
      {children}
    </motion.div>
  )
}
```

## Component Composition

### Compound Components
```typescript
// Parent component
export function Accordion({ children }: { children: React.ReactNode }) {
  return <div className="accordion-container">{children}</div>
}

// Child components
export function AccordionItem({ children }: { children: React.ReactNode }) {
  return <div className="accordion-item">{children}</div>
}

export function AccordionTrigger({ children }: { children: React.ReactNode }) {
  return <button className="accordion-trigger">{children}</button>
}

// Usage
<Accordion>
  <AccordionItem>
    <AccordionTrigger>Title</AccordionTrigger>
    <AccordionContent>Content</AccordionContent>
  </AccordionItem>
</Accordion>
```

## Props and TypeScript

### Interface Patterns
```typescript
// Use descriptive interface names
interface ProjectCardProps {
  project: Project
  variant?: 'default' | 'featured'
  showDescription?: boolean
  onSelect?: (project: Project) => void
}

// Use React.ComponentProps for extending HTML elements
interface CustomButtonProps extends React.ComponentProps<'button'> {
  variant?: 'primary' | 'secondary'
  size?: 'sm' | 'md' | 'lg'
}
```

## Styling Guidelines

1. **Tailwind First**: Use utility classes before custom CSS
2. **Conditional Classes**: Use `cn()` utility for conditional styling
3. **Responsive Design**: Mobile-first approach with responsive utilities
4. **Dark Theme**: Ensure all components work in dark mode
5. **Accessibility**: Include proper ARIA labels and semantic HTML