---
name: generating
description: How to generate pixel-perfect TSX components
metadata:
  tags: generation, tsx, css, react, pixel-perfect
---

# Generating Pixel-Perfect Components

The goal is components that are **indistinguishable** from the original, not approximations.

## Anti-Patterns (AI Slop)

These produce generic-looking clones:

```tsx
// WRONG: Generic Tailwind approximations
<div className="bg-blue-500 p-4 rounded-lg shadow-md">
  <h1 className="text-3xl font-bold">Welcome</h1>
  <p className="text-gray-600 mt-2">Description</p>
</div>
```

Problems:
- `bg-blue-500` is not the exact color
- `p-4` is not the exact padding
- `text-3xl` is not the exact font size
- Generic, template-like structure

## Correct Approach

Extract and preserve EXACT values:

```tsx
// RIGHT: Exact values from the original
<div 
  className="rounded-[1rem] p-[13.44px_19.04px]"
  style={{
    backgroundColor: '#F5F3ED',
    boxShadow: '0px 2.688px 2.688px 0px rgba(136, 89, 0, 1)',
  }}
>
  <h1 
    className="font-marker leading-none tracking-tighter"
    style={{fontSize: '160px', color: '#3C2F12'}}
  >
    Symposium
  </h1>
  <p className="font-sans text-[20px] leading-tight text-[#1A1A1A] mt-[8px]">
    Description text here
  </p>
</div>
```

## Extraction Rules

### Colors

1. Find the exact hex value in the source CSS/styles
2. Define it as a CSS variable in `globals.css`
3. Use the variable OR exact hex in components

```css
/* globals.css */
@theme {
  --color-accent: #3C2F12;
  --color-highlight: #FDE047;
}
```

```tsx
// Component - either works
<div className="bg-accent">  // uses CSS variable
<div className="bg-[#3C2F12]">  // exact hex
```

### Font Sizes

Never approximate. Use exact values:

```tsx
// WRONG
<h1 className="text-6xl">  // This is 60px, but original might be 64px

// RIGHT
<h1 className="text-[64px]">  // Exact value
<h1 style={{fontSize: '64px'}}>  // Also works
```

### Spacing

Use Tailwind arbitrary values for non-standard spacing:

```tsx
// WRONG - approximation
<div className="p-4 mt-8">  // 16px and 32px

// RIGHT - exact values
<div className="p-[13.44px] mt-[28px]">  // Exact from original
```

### Complex Backgrounds

Use inline styles for gradients, blurs, and multi-layer effects:

```tsx
<div 
  className="absolute inset-0"
  style={{
    background: 'linear-gradient(to bottom, #333, #000)',
  }}
/>

<div 
  className="absolute w-[60%] opacity-[0.66]"
  style={{
    filter: 'blur(76.4px)',
  }}
/>
```

### Shadows

Preserve exact shadow values:

```tsx
// WRONG - generic Tailwind shadow
<div className="shadow-lg">

// RIGHT - exact shadow
<div style={{boxShadow: '0 10px 30px rgba(0,0,0,0.1)'}}>
// OR
<div className="shadow-[0_10px_30px_rgba(0,0,0,0.1)]">
```

### Transforms

Preserve rotations, scales, and translations:

```tsx
<div 
  className="inline-block"
  style={{transform: 'rotate(-1.5deg)'}}
>
  Tape Label
</div>
```

## Asset URL Mapping

The scraper downloads assets to `public/assets/`. Map URLs:

```tsx
// Original HTML
<img src="https://cdn.example.com/images/hero-bg.png" />

// After download, asset is at: ./output/public/assets/hero-bg.png

// In component
<img src="/assets/hero-bg.png" alt="Hero background" />

// For Next.js Image optimization
import Image from 'next/image';
<Image src="/assets/hero-bg.png" alt="Hero" width={800} height={600} />
```

## Preserving Layout Complexity

### Absolute Positioning

If the original uses absolute positioning, preserve it:

```tsx
<div className="relative min-h-[900px]">
  {/* Background element */}
  <div className="absolute top-0 left-0 w-full h-[648px]">
    <img src="/assets/grid.svg" className="w-full h-full object-cover opacity-30" />
  </div>
  
  {/* Floating element */}
  <div className="absolute top-[10%] right-[5%] w-[45%] transform rotate-2">
    <div className="polaroid">
      <img src="/assets/photo.jpg" />
    </div>
  </div>
  
  {/* Content */}
  <div className="relative z-10 pt-[88px]">
    ...
  </div>
</div>
```

### Z-Index Layers

Preserve stacking order:

```tsx
<div className="relative">
  <div className="absolute z-0">Background</div>
  <div className="absolute z-10">Middle layer</div>
  <div className="absolute z-20">Top layer</div>
  <div className="relative z-30">Content</div>
</div>
```

### Overflow and Clipping

```tsx
<div className="relative overflow-hidden rounded-[1rem]">
  {/* This content gets clipped */}
  <div className="absolute -top-10 -left-10 w-[200%]">
    ...
  </div>
</div>
```

## Interactive States

Preserve hover, focus, and active states:

```tsx
<button 
  className="
    relative overflow-hidden 
    bg-white border border-dashed border-[#D1CEC5]
    px-10 py-3 
    text-[#1A1A1A] font-bold uppercase tracking-widest text-[14px]
    transition-all
    hover:bg-black hover:text-white hover:border-solid
  "
>
  <span className="relative z-10">Join Us</span>
  <div className="absolute inset-0 bg-black translate-y-full group-hover:translate-y-0 transition-transform duration-300" />
</button>
```

## Animations

For simple animations, use Tailwind:

```tsx
<div className="animate-pulse">
```

For complex animations, define in globals.css:

```css
@keyframes float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-10px); }
}

.animate-float {
  animation: float 3s ease-in-out infinite;
}
```

## Component Structure Template

```tsx
// "use client" only if needed for interactivity
"use client";

import Image from 'next/image';

export default function SectionName() {
  return (
    <section 
      id="section-name" 
      className="relative py-24 overflow-hidden"
      style={{backgroundColor: '#F5F3ED'}}
    >
      {/* Background Effects */}
      <div className="absolute inset-0 pointer-events-none">
        {/* Glow blobs, patterns, etc. */}
      </div>

      {/* Content Container */}
      <div className="container relative z-10">
        {/* Section content */}
      </div>

      {/* Styled-jsx for complex/unique styles */}
      <style jsx>{`
        .custom-effect {
          /* Complex CSS that doesn't fit Tailwind */
        }
      `}</style>
    </section>
  );
}
```

## Quality Verification

After generating, check:

1. **Side-by-side comparison** - Does it look identical?
2. **Color picker test** - Are hex values exact?
3. **Font inspection** - Are fonts loading correctly?
4. **Spacing measurement** - Are dimensions exact?
5. **Responsive test** - Does it break at same points?

## Real-World Component Examples

### Navigation with Sticky Header

```tsx
"use client";

import Link from 'next/link';
import Image from 'next/image';
import {useState, useEffect} from 'react';

export default function Navigation() {
  const [scrolled, setScrolled] = useState(false);

  useEffect(() => {
    const handleScroll = () => setScrolled(window.scrollY > 50);
    window.addEventListener('scroll', handleScroll);
    return () => window.removeEventListener('scroll', handleScroll);
  }, []);

  return (
    <nav 
      className={`
        fixed top-0 left-0 right-0 z-50
        transition-all duration-300
        ${scrolled 
          ? 'bg-white/95 backdrop-blur-sm shadow-[0_2px_20px_rgba(0,0,0,0.08)]' 
          : 'bg-transparent'
        }
      `}
    >
      <div className="max-w-[1400px] mx-auto px-8 py-5 flex items-center justify-between">
        {/* Logo */}
        <Link href="/" className="flex items-center gap-3">
          <Image 
            src="/assets/logo.svg" 
            alt="Logo" 
            width={40} 
            height={40}
            className="w-[40px] h-[40px]"
          />
          <span className="font-script text-[24px] text-[#3C2F12]">Socratica</span>
        </Link>

        {/* Nav Links */}
        <div className="hidden md:flex items-center gap-8">
          {['About', 'Events', 'Community', 'Apply'].map((item) => (
            <Link 
              key={item}
              href={`#${item.toLowerCase()}`}
              className="text-[14px] font-medium tracking-wide text-[#1A1A1A] hover:text-[#3C2F12] transition-colors"
            >
              {item}
            </Link>
          ))}
        </div>

        {/* CTA Button */}
        <button className="
          px-6 py-2.5 
          bg-[#1A1A1A] text-white 
          text-[13px] font-bold uppercase tracking-widest
          rounded-full
          hover:bg-[#3C2F12] transition-colors
        ">
          RSVP
        </button>
      </div>
    </nav>
  );
}
```

### Hero with Polaroid Collage Layout

```tsx
import Image from 'next/image';

export default function Hero() {
  const photos = [
    {src: '/assets/photo1.jpg', rotation: -3, top: '15%', left: '5%', width: 280},
    {src: '/assets/photo2.jpg', rotation: 5, top: '25%', right: '8%', width: 320},
    {src: '/assets/photo3.jpg', rotation: -2, bottom: '20%', left: '12%', width: 260},
    {src: '/assets/photo4.jpg', rotation: 4, bottom: '15%', right: '5%', width: 300},
  ];

  return (
    <section className="relative min-h-screen overflow-hidden bg-[#F5F3ED]">
      {/* Grid Background */}
      <div className="absolute inset-x-0 top-0 h-[648px] pointer-events-none z-0">
        <Image 
          src="/assets/grid.svg"
          alt=""
          fill
          className="object-cover opacity-30"
        />
      </div>

      {/* Glow Effects */}
      <div className="absolute top-[10%] left-[5%] w-[400px] h-[400px] rounded-full z-0" 
        style={{
          background: 'radial-gradient(circle, #ABE0FF 0%, transparent 70%)',
          filter: 'blur(60px)',
          opacity: 0.4,
        }}
      />
      <div className="absolute top-[30%] right-[10%] w-[500px] h-[500px] rounded-full z-0"
        style={{
          background: 'radial-gradient(circle, #F88944 0%, transparent 70%)',
          filter: 'blur(80px)',
          opacity: 0.3,
        }}
      />

      {/* Polaroid Photos - Absolute positioned */}
      {photos.map((photo, i) => (
        <div 
          key={i}
          className="absolute hidden lg:block"
          style={{
            top: photo.top,
            left: photo.left,
            right: photo.right,
            bottom: photo.bottom,
            transform: `rotate(${photo.rotation}deg)`,
            zIndex: 5 + i,
          }}
        >
          <div className="bg-white p-3 pb-10 shadow-[0_10px_30px_rgba(0,0,0,0.12)]">
            <Image 
              src={photo.src}
              alt=""
              width={photo.width}
              height={photo.width * 0.75}
              className="object-cover"
            />
          </div>
        </div>
      ))}

      {/* Main Content Card */}
      <div className="relative z-10 max-w-[1400px] mx-auto px-4 sm:px-8 pt-[120px]">
        <div className="
          relative bg-white rounded-[1rem] 
          shadow-sm border border-[#D1CEC5] 
          overflow-hidden 
          min-h-[850px]
          p-10 sm:p-16
        ">
          {/* Tape Label */}
          <div 
            className="
              inline-block px-3 py-1 
              bg-[#FDE047] 
              font-hand font-bold 
              text-[14px] uppercase
            "
            style={{transform: 'rotate(-1.5deg)'}}
          >
            You're invited
          </div>

          {/* Headline */}
          <div className="mt-8">
            <span className="text-[20px] md:text-[24px] font-sans text-[#1A1A1A]">
              You are invited to the world's greatest celebration of
            </span>
          </div>

          <h1 
            className="font-marker tracking-tighter leading-none mt-4"
            style={{fontSize: 'clamp(80px, 12vw, 160px)', color: '#3C2F12'}}
          >
            Symposium
          </h1>

          <p className="max-w-[600px] mt-8 text-[18px] leading-relaxed text-[#666]">
            Join us for an evening of intellectual discourse, creative exploration, 
            and meaningful connections at our annual gathering.
          </p>

          {/* CTA */}
          <button className="
            mt-10 px-10 py-4
            bg-white border border-dashed border-[#D1CEC5]
            text-[14px] font-bold uppercase tracking-widest text-[#1A1A1A]
            transition-all
            hover:bg-[#1A1A1A] hover:text-white hover:border-solid
          ">
            RSVP Now
          </button>
        </div>
      </div>
    </section>
  );
}
```

### Feature Grid with Icons

```tsx
import Image from 'next/image';

const features = [
  {
    icon: '/assets/icon-community.svg',
    title: 'Community',
    description: 'Connect with like-minded individuals passionate about ideas.',
  },
  {
    icon: '/assets/icon-learning.svg',
    title: 'Learning',
    description: 'Expand your horizons through workshops and discussions.',
  },
  {
    icon: '/assets/icon-creativity.svg',
    title: 'Creativity',
    description: 'Express yourself through collaborative projects.',
  },
];

export default function Features() {
  return (
    <section className="py-[120px] bg-white">
      <div className="max-w-[1200px] mx-auto px-8">
        <h2 className="text-center text-[48px] font-bold text-[#1A1A1A] tracking-tight">
          What We Offer
        </h2>
        
        <div className="grid grid-cols-1 md:grid-cols-3 gap-12 mt-16">
          {features.map((feature, i) => (
            <div key={i} className="text-center">
              <div className="w-[80px] h-[80px] mx-auto mb-6">
                <Image 
                  src={feature.icon}
                  alt=""
                  width={80}
                  height={80}
                  className="w-full h-full"
                />
              </div>
              <h3 className="text-[24px] font-semibold text-[#1A1A1A]">
                {feature.title}
              </h3>
              <p className="mt-4 text-[16px] leading-relaxed text-[#666]">
                {feature.description}
              </p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}
```

### Footer with Multi-Column Layout

```tsx
import Link from 'next/link';
import Image from 'next/image';

const footerLinks = {
  'About': ['Our Story', 'Team', 'Careers', 'Press'],
  'Events': ['Upcoming', 'Past Events', 'Submit Event', 'Calendar'],
  'Community': ['Join', 'Guidelines', 'Discord', 'Newsletter'],
  'Legal': ['Privacy', 'Terms', 'Cookies'],
};

export default function Footer() {
  return (
    <footer className="bg-[#1A1A1A] text-white py-20">
      <div className="max-w-[1400px] mx-auto px-8">
        <div className="grid grid-cols-2 md:grid-cols-5 gap-12">
          {/* Brand Column */}
          <div className="col-span-2 md:col-span-1">
            <Image 
              src="/assets/logo-white.svg"
              alt="Socratica"
              width={120}
              height={40}
            />
            <p className="mt-6 text-[14px] text-[#888] leading-relaxed">
              Building spaces for intellectual curiosity since 2020.
            </p>
          </div>

          {/* Link Columns */}
          {Object.entries(footerLinks).map(([category, links]) => (
            <div key={category}>
              <h4 className="text-[12px] font-bold uppercase tracking-widest text-[#888] mb-4">
                {category}
              </h4>
              <ul className="space-y-3">
                {links.map((link) => (
                  <li key={link}>
                    <Link 
                      href="#"
                      className="text-[14px] text-[#CCC] hover:text-white transition-colors"
                    >
                      {link}
                    </Link>
                  </li>
                ))}
              </ul>
            </div>
          ))}
        </div>

        {/* Bottom Bar */}
        <div className="mt-16 pt-8 border-t border-[#333] flex flex-col md:flex-row justify-between items-center gap-4">
          <p className="text-[13px] text-[#666]">
            © 2024 Socratica. All rights reserved.
          </p>
          <div className="flex items-center gap-6">
            {['twitter', 'instagram', 'linkedin'].map((social) => (
              <Link key={social} href={`https://${social}.com`}>
                <Image 
                  src={`/assets/icon-${social}.svg`}
                  alt={social}
                  width={20}
                  height={20}
                  className="opacity-60 hover:opacity-100 transition-opacity"
                />
              </Link>
            ))}
          </div>
        </div>
      </div>
    </footer>
  );
}
```

### Card with Glassmorphism Effect

```tsx
export default function GlassCard() {
  return (
    <div 
      className="
        relative p-8 rounded-[20px] 
        border border-white/20
        overflow-hidden
      "
      style={{
        background: 'rgba(255, 255, 255, 0.1)',
        backdropFilter: 'blur(20px)',
        WebkitBackdropFilter: 'blur(20px)',
      }}
    >
      {/* Gradient overlay */}
      <div 
        className="absolute inset-0 pointer-events-none"
        style={{
          background: 'linear-gradient(135deg, rgba(255,255,255,0.15) 0%, rgba(255,255,255,0) 100%)',
        }}
      />
      
      <div className="relative z-10">
        <h3 className="text-[24px] font-semibold text-white">
          Glass Card Title
        </h3>
        <p className="mt-4 text-[16px] text-white/70">
          Content with glassmorphism effect.
        </p>
      </div>
    </div>
  );
}
```

### Animated Gradient Background

```tsx
"use client";

export default function AnimatedGradientSection() {
  return (
    <section className="relative min-h-[600px] overflow-hidden">
      {/* Animated gradient background */}
      <div 
        className="absolute inset-0 animate-gradient"
        style={{
          background: 'linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab)',
          backgroundSize: '400% 400%',
        }}
      />
      
      {/* Content */}
      <div className="relative z-10 flex items-center justify-center min-h-[600px]">
        <h2 className="text-[64px] font-bold text-white text-center">
          Animated Gradient
        </h2>
      </div>

      <style jsx>{`
        @keyframes gradient {
          0% { background-position: 0% 50%; }
          50% { background-position: 100% 50%; }
          100% { background-position: 0% 50%; }
        }
        .animate-gradient {
          animation: gradient 15s ease infinite;
        }
      `}</style>
    </section>
  );
}
```
