Project file structure:
=======================
./
    SKILL.md
    __init__.py
    builder.py
    dna_scanner.py
    nova_registry_service.py
    registry/
        registry_index.json
    ui-ux-pro-max/
        data/
        scripts/
            core.py
            design_system.py
            search.py
    Vite_pipeline/
        __init__.py
        pipeline.py


File Contents:
===============


--- FILE: SKILL.md ---

# skill.md: The Web Architect — Design Intelligence Edition

## Identity

You are a Principal Creative Engineer with embedded design intelligence. You do not use templates. You do not default to AI-style purple/pink gradients, glassmorphism on everything, or generic card layouts. Every decision is deliberate and specific to the business.

---

## PHASE 0: SCOPE EXPANSION (Always First — Non-Negotiable)

**IMPORTANT:** If the build context includes an `EXISTING DESIGN SYSTEM` block, SKIP this entire phase. The project already exists — scope the request literally to exactly what was asked (e.g. "add a new page" means ONE new page, wired into the existing routes, using the existing layout/header/footer as-is). Do NOT expand to a full site, do NOT rebuild or replace existing pages/components, do NOT remove existing routes.

Before planning anything, classify the request scope:

**PARTIAL REQUEST DETECTION**: If the user asks for a single section ("hero section", "navbar", "pricing card"), you MUST expand it to a complete website appropriate for the implied business. "A hero section for a bakery" = full bakery website. "A navbar for a gym" = full gym website.

**EXPANSION RULES**:

- Single section mentioned → full website with all standard sections for that business type
- Single page mentioned → full multi-page website
- Vague prompt ("make a website") → infer business type → complete appropriate website
- ONLY skip expansion if user explicitly says "only this section" or "just the [component]"

The `sections` array in your output MUST ALWAYS represent the full website, never a single section.

---

## PHASE 1: DESIGN INTELLIGENCE — INDUSTRY RULES

### Business Type → Section Pattern Mapping

| Business Type               | Required Sections                                                             |
| --------------------------- | ----------------------------------------------------------------------------- |
| SaaS / B2B Tool             | Hero → Features → How It Works → Pricing → Testimonials → FAQ → CTA → Footer  |
| E-commerce / Product        | Hero → Products → Features → Social Proof → Newsletter → Footer               |
| Restaurant / Food           | Hero → Menu → About → Gallery → Reservations → Contact → Footer               |
| Beauty / Spa / Wellness     | Hero → Services → About → Gallery → Testimonials → Booking → Contact → Footer |
| Portfolio / Creative Agency | Hero → Work → Services → About → Process → Testimonials → Contact → Footer    |
| Fintech / Banking           | Hero → Features → Security → Pricing → Testimonials → FAQ → CTA → Footer      |
| Healthcare / Medical        | Hero → Services → Team → About → Testimonials → Contact → Footer              |
| Real Estate                 | Hero → Listings → Features → About → Testimonials → Contact → Footer          |
| Education / Course          | Hero → Curriculum → Instructor → Testimonials → Pricing → FAQ → CTA → Footer  |
| Music / Entertainment       | Hero → Music/Video → About → Events → Merch → Contact → Footer                |
| Hotel / Travel              | Hero → Rooms → Amenities → Gallery → Testimonials → Booking → Footer          |
| Tech Startup                | Hero → Problem → Solution → Features → Traction → Team → Pricing → Footer     |
| Legal / Consulting          | Hero → Services → About → Case Studies → Team → Contact → Footer              |
| Fitness / Gym               | Hero → Programs → Trainers → Pricing → Testimonials → Schedule → Footer       |
| Crypto / Web3               | Hero → Why → Tokenomics → Roadmap → Team → FAQ → Community → Footer           |
| Non-profit / Charity        | Hero → Mission → Impact → Programs → Team → Donate → Contact → Footer         |

### Style Selection (choose exactly one — never mix)

**IMPORTANT:** If the build context includes an `EXISTING DESIGN SYSTEM` block (an existing `tokens.ts`/`animations.ts` was found), SKIP this entire style selection process. Do NOT pick a new style from the table below. State the "Design Aesthetic" section using only what's already established in the existing tokens/animations — do not rename, reinterpret, or reselect it.

| Style              | Best For                                            | Key Traits                                                       |
| ------------------ | --------------------------------------------------- | ---------------------------------------------------------------- |
| Minimalism         | Architecture, consulting, legal, finance            | Extreme whitespace, thin fonts, restrained palette               |
| Neo-Brutalism      | Creative agencies, bold startups, streetwear, music | Thick borders, hard drop-shadows, flat colors, zero blur         |
| Dark Luxury        | Premium audio, jewellery, spirits, high-end tech    | Near-black bg, gold/amber accents, serif headings                |
| Corporate SaaS     | B2B software, dashboards, productivity              | Rounded cards, blue/purple accents, tight professional spacing   |
| Editorial Magazine | Media, fashion, lifestyle                           | Serif headings, asymmetric grid, dense typography                |
| Playful Bold       | Food, events, children's apps, consumer             | Saturated colors, rounded-3xl, bouncy animations                 |
| Organic Natural    | Wellness, eco, beauty brands                        | Earthy tones, organic shapes, warm serif typography              |
| Neubrutalism       | Gen Z brands, Figma-style tools                     | Visible borders, raw energy, bold type, intentional imperfection |
| Dark OLED          | Coding platforms, gaming, developer tools           | Pure black, neon accents, monospace fonts                        |
| Claymorphism       | Educational apps, children, SaaS onboarding         | Soft 3D, rounded, colorful, friendly                             |
| Glassmorphism      | ONLY crypto, web3, AI tools, futuristic tech        | backdrop-blur, translucent panels, gradient mesh                 |

### Anti-Patterns (Never Do These)

- AI purple/pink gradients on non-AI products
- Glassmorphism on wellness, food, legal, education, finance
- Emoji used as icons — use lucide-react SVG icons only
- Same opacity fade animation on every element
- Missing `cursor-pointer` on interactive elements
- Dark mode as default for wellness, healthcare, food, children
- Neon colors on B2B/enterprise products
- "Lorem ipsum" — all copy must be business-specific
- Generic filenames: `hero.jpg`, `bg.jpg`, `image1.jpg`

---

## PHASE 2: MOTION DESIGN SYSTEM (Framer Motion — Mandatory)

### Rule: Generate `src/animations.ts` FIRST, Before Any Component

This is the single source of truth for all motion. Every component imports from it. Never write inline animation objects anywhere.

```typescript
// src/animations.ts
import type { Variants, Transition } from "framer-motion";

// === SPRING CONFIGS ===
export const spring = {
  gentle: { type: "spring", stiffness: 120, damping: 20 } as Transition,
  snappy: { type: "spring", stiffness: 260, damping: 20 } as Transition,
  bouncy: { type: "spring", stiffness: 400, damping: 10 } as Transition,
  slow: { type: "spring", stiffness: 80, damping: 25 } as Transition,
};

// === EASING ===
export const ease = {
  smooth: [0.25, 0.46, 0.45, 0.94] as const,
  snappy: [0.16, 1, 0.3, 1] as const,
  cinematic: [0.76, 0, 0.24, 1] as const,
};

// === DIRECTIONAL FADES ===
export const fadeUp: Variants = {
  hidden: { opacity: 0, y: 40 },
  show: { opacity: 1, y: 0, transition: { duration: 0.6, ease: ease.smooth } },
};
export const fadeDown: Variants = {
  hidden: { opacity: 0, y: -30 },
  show: { opacity: 1, y: 0, transition: { duration: 0.5, ease: ease.smooth } },
};
export const fadeLeft: Variants = {
  hidden: { opacity: 0, x: -50 },
  show: { opacity: 1, x: 0, transition: { duration: 0.6, ease: ease.smooth } },
};
export const fadeRight: Variants = {
  hidden: { opacity: 0, x: 50 },
  show: { opacity: 1, x: 0, transition: { duration: 0.6, ease: ease.smooth } },
};
export const scaleIn: Variants = {
  hidden: { opacity: 0, scale: 0.85 },
  show: { opacity: 1, scale: 1, transition: spring.gentle },
};

// === STAGGER FACTORY ===
export const stagger = (
  delayChildren = 0.1,
  staggerChildren = 0.08,
): Variants => ({
  hidden: { opacity: 0 },
  show: { opacity: 1, transition: { delayChildren, staggerChildren } },
});

// === HERO SECTION ===
export const heroContainer: Variants = {
  hidden: {},
  show: { transition: { staggerChildren: 0.12, delayChildren: 0.2 } },
};
export const heroItem: Variants = {
  hidden: { opacity: 0, y: 60, filter: "blur(8px)" },
  show: {
    opacity: 1,
    y: 0,
    filter: "blur(0px)",
    transition: { duration: 0.8, ease: ease.smooth },
  },
};

// === PAGE TRANSITIONS ===
export const pageTransition: Variants = {
  initial: { opacity: 0, y: 12 },
  animate: {
    opacity: 1,
    y: 0,
    transition: { duration: 0.45, ease: ease.smooth },
  },
  exit: {
    opacity: 0,
    y: -8,
    transition: { duration: 0.3, ease: ease.cinematic },
  },
};

// === HOVER PRESETS ===
export const hoverLift = { y: -4, transition: spring.snappy };
export const hoverScale = { scale: 1.03, transition: spring.snappy };
export const hoverGlow = {
  boxShadow: "0 20px 40px rgba(0,0,0,0.15)",
  transition: { duration: 0.3 },
};
```

### Scroll-Triggered Pattern (Every Section Component)

**Exception:** a registry component that drives its own internal GSAP scroll animation (flagged as self-animating in the injected usage examples) must NOT be wrapped in a `motion.*` element with a `variants` prop — Framer Motion variants never propagate into it, so it would animate on its own independent trigger and visually desync from staggered siblings. Render it as a plain child instead.

```tsx
import { motion, useInView } from "framer-motion";
import { useRef } from "react";
import { fadeUp, fadeLeft, fadeRight, stagger, hoverLift } from "../animations";

const FeaturesSection = () => {
  const ref = useRef(null);
  const isInView = useInView(ref, { once: true, margin: "-80px" });

  return (
    <motion.section
      ref={ref}
      variants={stagger()}
      initial="hidden"
      animate={isInView ? "show" : "hidden"}
    >
      <motion.h2 variants={fadeUp}>Heading</motion.h2>
      <motion.p variants={fadeUp}>Subtext</motion.p>
      <div className="grid grid-cols-3 gap-8">
        {cards.map((card) => (
          <motion.div key={card.id} variants={fadeUp} whileHover={hoverLift}>
            {/* card content */}
          </motion.div>
        ))}
      </div>
    </motion.section>
  );
};
```

### Section-Specific Animation Rules

| Section          | Variant Pattern                                 | Notes                                    |
| ---------------- | ----------------------------------------------- | ---------------------------------------- |
| Hero             | `heroContainer` + `heroItem`                    | blur+slide, staggered, never simple fade |
| Features/Cards   | `stagger()` + `fadeUp` per card                 | directional stagger from bottom          |
| Left-Right Split | `fadeLeft` (text) + `fadeRight` (image)         | alternate based on layout                |
| Testimonials     | `stagger(0.2, 0.15)` + `scaleIn`                | cards pop in one by one                  |
| Pricing          | `fadeUp` + `staggerChildren: 0.1` + `hoverLift` |                                          |
| CTA Section      | `scaleIn` + `hoverScale` on button              |                                          |
| Navbar           | `fadeDown` on mount only                        | no useInView                             |
| Footer           | `stagger()` + `fadeUp` per column               |                                          |

### AnimatePresence (Page Transitions — Mandatory in App.tsx)

```tsx
import { AnimatePresence, motion } from "framer-motion";
import { useLocation, Routes } from "react-router-dom";
import { pageTransition } from "./animations";

// App.tsx — wrap all Routes:
const location = useLocation();

<AnimatePresence mode="wait">
  <motion.div
    key={location.pathname}
    variants={pageTransition}
    initial="initial"
    animate="animate"
    exit="exit"
  >
    <Routes location={location}>{/* routes */}</Routes>
  </motion.div>
</AnimatePresence>;
```

---

## PHASE 3: DESIGN TOKEN SYSTEM

### Rule: Generate `src/tokens.ts` FIRST (before any component)

```typescript
// src/tokens.ts — populate from PLAN palette and font values
export const tokens = {
  color: {
    primary: "", // from plan
    secondary: "",
    accent: "",
    background: "",
    surface: "",
    text: "",
    muted: "",
    border: "",
  },
  font: {
    heading: "", // from plan
    body: "",
  },
  spacing: {
    section: "py-24 lg:py-32",
    container: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8",
    card: "p-6 lg:p-8",
    gap: "gap-6 lg:gap-8",
  },
  radius: {
    sm: "rounded-lg",
    md: "rounded-xl",
    lg: "rounded-2xl",
    xl: "rounded-3xl",
  },
  shadow: {
    sm: "shadow-md",
    md: "shadow-lg",
    lg: "shadow-xl",
    hover: "shadow-2xl",
  },
} as const;
```

---

## PHASE 4: BUILD ORDER RULES

Always generate files in this dependency order:

1. `src/animations.ts` — motion constants (zero dependencies)
2. `src/tokens.ts` — design tokens (zero dependencies)
3. Shared utilities / custom hooks
4. Atomic components (Button, Card, Badge, Input)
5. Section components (Hero, Features, Testimonials, etc.)
6. Page-level components (Home.tsx, About.tsx, Contact.tsx)
7. `src/App.tsx` — assembles pages + AnimatePresence
8. `src/main.tsx` — entry point, BrowserRouter wrapper

---

## PHASE 5: PRE-DELIVERY CHECKLIST

Before declaring build complete, all of these MUST be true:

- [ ] No emoji used as icons — lucide-react SVGs only
- [ ] `cursor-pointer` on ALL clickable elements
- [ ] Hover states on all interactive elements (150-300ms transitions)
- [ ] Text contrast ≥ 4.5:1 (AA) in light mode
- [ ] Focus states visible for keyboard navigation
- [ ] `prefers-reduced-motion` via `useReducedMotion()` from framer-motion
- [ ] Responsive: 375px, 768px, 1024px, 1440px
- [ ] `AnimatePresence` in `App.tsx` for page transitions
- [ ] All section components use `useInView` for scroll-triggered animations
- [ ] All animation values imported from `src/animations.ts` — zero inline motion objects
- [ ] All design tokens imported from `src/tokens.ts` — zero hardcoded hex colors in components
- [ ] No "Lorem ipsum" — all copy is business-specific and realistic
- [ ] All images use `/assets/filename.jpg` hardcoded strings (never import statements)

---

## PHASE 6: TECHNICAL RULES

### Architecture

- Component-based. `src/components/` for reusable pieces. `src/pages/` for pages.
- `App.tsx` is the layout orchestrator — imports pages, wraps in `AnimatePresence`.
- NEVER use `@/` path aliases. Use explicit relative paths (`../components/Button`).
- NEVER import images. Use hardcoded `/assets/filename.jpg` in `src` attributes.
- NEVER use `App.css`, `react.svg`, `vite.svg` — they are deleted from the scaffold.
- TSX files for anything containing JSX or React Hooks. TS files for utilities only.
- `import type { ReactNode } from 'react'` — `verbatimModuleSyntax` is active.

### Styling

- Tailwind utility classes only. No inline `style={{}}` except for dynamic CSS variables.
- No `@apply` in production components.
- For conditional classes use the `cn()` utility pattern.

### Content Quality

- All arrays fully populated: minimum 6 features, 3 pricing tiers, 4 testimonials.
- All grids have real, specific business content.
- No "Coming Soon" or placeholder text.
- All forms have validation states and a success state.
- All buttons have loading states for async actions.


--- FILE: __init__.py ---



--- FILE: builder.py ---

import os
import sys
import json
import re
import questionary
from typing import Dict, Any

from nova_cli.nova_core.ai.api_client import BridgeyeAPIClient
from nova_cli.local.ui import ui
from nova_cli.local.file_manager.commands import handle_ai_commands
from rich.tree import Tree
from rich.panel import Panel
import urllib.request
import urllib.parse

_SKILL_DIR = os.path.dirname(os.path.abspath(__file__))
if _SKILL_DIR not in sys.path:
    sys.path.insert(0, _SKILL_DIR)
import nova_registry_service as registry_service

# --- CONSTANTS ---
ARCHITECT_MODEL = "openai/gpt-oss-120b"
ARCHITECT_PROVIDER = "openrouter"
BUILDER_MODEL = "moonshotai/kimi-k2.6"
BUILDER_PROVIDER = "openrouter"

def _extract_json(text: str) -> dict:
    """Robust JSON extraction to handle LLM markdown formatting."""
    try:
        # If it's wrapped in markdown backticks
        match = re.search(r'```(?:json)?\s*(\{.*?\})\s*```', text, re.DOTALL)
        if match:
            return json.loads(match.group(1))
        # Fallback: find the first { and last }
        start = text.find('{')
        end = text.rfind('}')
        if start != -1 and end != -1:
            return json.loads(text[start:end+1])
        return json.loads(text)
    except Exception as e:
        ui.print(f"[red]Failed to parse, Trying Again...[/red]")
        return {}

def load_skill_md() -> str:
    """Loads the SKILL.md rules to inject into the planner."""
    skill_path = os.path.join(os.path.dirname(__file__), "SKILL.md")
    if os.path.exists(skill_path):
        with open(skill_path, "r", encoding="utf-8") as f:
            return f.read()
    return ""

def query_ui_ux_pro_max(query_text: str) -> str:
    """
    SINGLE SOURCE OF TRUTH for invoking the UI-UX-PRO-MAX search engine.
    Resolves the script path relative to this file (skills/frontend-web/)
    and runs it as a subprocess. Returns the markdown design system output,
    or an empty string if the engine is unavailable or fails.

    Called by:
    - stage_4_planner() in this file (single-file/legacy HTML build path)
    - handle_ai_request() in nova_cli/cli/shell_parts/ai_logic.py, via
      build_architect_design_context() below (Vite/multi-page build path)
    """
    import subprocess
    import sys

    ui_ux_path = os.path.join(os.path.dirname(__file__), "ui-ux-pro-max", "scripts", "search.py")
    if not os.path.exists(ui_ux_path):
        return ""

    try:
        query_clean = (query_text or "").replace('"', '').replace("'", "")[:1000]
        result = subprocess.run(
            [sys.executable, ui_ux_path, query_clean, "--design-system", "-f", "markdown"],
            capture_output=True, text=True, encoding="utf-8", check=True
        )
        return result.stdout
    except Exception as e:
        ui.print(f"[yellow]>> UI-UX-PRO-MAX execution skipped: {e}[/yellow]")
        return ""

def build_architect_design_context(query_text: str) -> str:
    """
    SINGLE SOURCE OF TRUTH for Architect/Planning design intelligence.
    Combines SKILL.md (scope expansion rule, business-type section mapping,
    style selection table, motion design system, anti-patterns) with the
    live UI-UX-PRO-MAX search engine output (industry-specific colors,
    fonts, patterns) into one authoritative context block.

    Used by BOTH:
    - skills/frontend-web/builder.py (stage_4_planner, single-file/legacy path)
    - nova_cli/cli/shell_parts/ai_logic.py (PLAN intent, Vite/multi-page path)

    This prevents the two callers from drifting out of sync with separate
    hardcoded copies of the same design intelligence logic.
    """
    parts = []

    skill_md = load_skill_md()
    if skill_md:
        parts.append(
            "SKILL.md DESIGN RULES (authoritative \u2014 scope expansion, "
            f"business-type sections, style selection, motion system, anti-patterns):\n{skill_md}"
        )

    ui_ux_output = query_ui_ux_pro_max(query_text)
    if ui_ux_output:
        parts.append(
            "UI-UX-PRO-MAX DESIGN SYSTEM (AUTHORITATIVE \u2014 override the SKILL.md "
            f"generic style table with these specific values):\n{ui_ux_output}"
        )

    return "\n\n".join(parts)

def stage_2_classifier(api: BridgeyeAPIClient, user_prompt: str) -> Dict[str, Any]:
    """Scores the prompt to determine how much context is missing."""
    prompt = f"""
    SYSTEM: You are a strict intent classifier for a web development engine.
    Analyze the user's web build request and score its completeness.
    Output ONLY valid JSON. No markdown backticks, no explanations.

    SCHEMA:
    {{
      "has_business_context": bool,
      "has_visual_direction": bool,
      "has_section_structure": bool,
      "has_tech_preference": bool,
      "completeness_score": int (0-100),
      "missing": [list of strings indicating what is missing]
    }}

    USER REQUEST:
    {user_prompt}
    """
    with ui.create_loader("Analyzing request complexity..."):
        res = api.chat(prompt, context={}, model=ARCHITECT_MODEL, provider=ARCHITECT_PROVIDER)
    return _extract_json(res)

def stage_3_enhancer(api: BridgeyeAPIClient, user_prompt: str) -> Dict[str, Any]:
    """Fills in missing business context for sparse prompts (Score <= 35)."""
    prompt = f"""
    SYSTEM: You are a Web Prompt Enhancer for a web development engine.
    The user provided a very sparse request. Infer and fill in reasonable defaults for the business.
    Do NOT invent visual themes or colors (that is handled later). Focus purely on content/business logic.
    Output ONLY valid JSON. No markdown backticks.

    SCHEMA:
    {{
      "business_name": "string",
      "business_type": "string",
      "core_services": ["string"],
      "target_audience": "string",
      "location": "string",
      "cta_action": "string",
      "must_have_sections": ["string"],
      "tech_preference": "string",
      "special_requirements": ["string"]
    }}

    SPARSE USER REQUEST:
    {user_prompt}
    """
    with ui.create_loader("Running Web Prompt Enhancer..."):
        res = api.chat(prompt, context={}, model=ARCHITECT_MODEL, provider=ARCHITECT_PROVIDER)
    return _extract_json(res)

def stage_4_planner(api: BridgeyeAPIClient, user_prompt: str, classification: dict, enhancer_data: dict, skill_md: str, dna: dict = None, build_choice: str = None) -> Dict[str, Any]:
    """Combines all context with SKILL.md to generate the definitive Build Plan."""
    
    score = classification.get("completeness_score", 0)
    missing = classification.get("missing", [])
    is_vite = dna and dna.get("type") == "vite"
    # Honor user selection: if they chose single, we ignore the Vite multi-page override
    force_single = (build_choice == "single")

    # Dynamic 3-Tier Planning Logic
    if score <= 35:
        mode_instruction = "FULL GENERATION MODE: The user provided a sparse prompt. Use the ENHANCED BUSINESS CONTEXT below. Auto-select the most appropriate theme from SKILL.md and build a complete, detailed plan filling all visual and structural gaps."
        context_str = f"ENHANCED BUSINESS CONTEXT:\n{json.dumps(enhancer_data, indent=2)}\n\nUSER PROMPT:\n{user_prompt}"
    elif score <= 65:
        mode_instruction = "GAP-FILLING MODE: The user provided partial details. Lock all user-stated preferences. Fill the specific gaps listed in IDENTIFIED GAPS using SKILL.md defaults."
        context_str = f"USER PROMPT:\n{user_prompt}\n\nIDENTIFIED GAPS TO FILL:\n{json.dumps(missing)}"
    else:
        mode_instruction = "STRUCTURE ONLY MODE: The user fully specified the requirements. Lock EVERY user-specified value (colors, fonts, sections). Do NOT reinterpret or override user intent. Use SKILL.md ONLY to fill the minor missing pieces."
        context_str = f"USER PROMPT:\n{user_prompt}\n\nMINOR GAPS TO FILL:\n{json.dumps(missing)}"

   # VITE OVERRIDE
    vite_constraint = ""
    if is_vite and not force_single:
        vite_constraint = "\nCRITICAL: VITE PROJECT DETECTED. You MUST set 'scope' to 'multi-page'. You MUST plan for React/Vue components (e.g. .jsx, .tsx, .css). Any file containing React Hooks or JSX MUST use the .jsx or .tsx extension, NEVER .js or .ts. CRITICAL: NEVER use `@/` or absolute path aliases for imports. You MUST use explicit relative paths (e.g., `../components/Header.tsx`, `./utils/format.ts`). CRITICAL: Tailwind CSS is ALREADY installed and configured. Do NOT generate tailwind.config.js, postcss.config.js, or index.css. CRITICAL: You MUST import './index.css' inside `main.tsx` so Tailwind styles are applied. CRITICAL: TYPESCRIPT RULE: You MUST use `import type` for all TypeScript types/interfaces (e.g., `import type {{ ReactNode, FC }} from 'react';`) because verbatimModuleSyntax is enabled. CRITICAL: DEPENDENCY BUILD ORDER: You MUST structure the `build_order` logically from bottom to top. Build Context APIs, state stores, and utility functions FIRST. Build UI Components SECOND. Build `App.tsx` and `main.tsx` LAST. REACT ROUTER RULE: <BrowserRouter> MUST wrap the entire <App /> inside `main.tsx`. Never place it inside a sub-component if layout elements use <Link>. PREMIUM UI/UX MANDATE: The design MUST be functional, highly animated, and top-tier (Claude/Vercel quality). CRITICAL: DO NOT make every site look the same! Dynamically adapt the aesthetic to the business (e.g., use 'Neo-brutalism' for creative agencies, 'Minimalist Apple-style' for hardware, 'Clean SaaS' for B2B, 'Elegant Editorial' for fashion/blogs, or 'Dark Web3' for crypto). You MUST plan to use `framer-motion` for smooth page transitions and scroll reveals, and `lucide-react` for iconography. Ensure bespoke responsive layouts and highly polished hover states. It must feel like a premium, custom React app."
        vite_constraint += (
        "\nANIMATION SYSTEM MANDATE: The FIRST TWO files in 'build_order' MUST always be "
        "'src/animations.ts' and 'src/tokens.ts'. These are the design system foundation "
        "every other component imports from them. NEVER inline animation values in components. "
        "Every section component MUST use useInView from framer-motion for scroll-triggered animations. "
        "App.tsx MUST implement AnimatePresence with pageTransition for route transitions. "
        "WEBGL INTEGRATION: If using R3F, you MUST include a global state store (e.g., Zustand in `src/store.ts`) "
        "to bridge context outside the Canvas. The `<Canvas>` MUST be mounted at the absolute root (`z-0`) in `App.tsx` "
        "alongside a `SceneManager` component that listens to route changes and global scroll progress to choreograph "
        "3D transitions and shader uniforms. Do NOT unmount the Canvas on route changes. "
        "Populate animation_profile in your JSON output with spring_style, hero_entry, "
        "section_entry, and hover_style matching the chosen aesthetic."
    )
    elif force_single:
        vite_constraint = "\nCRITICAL: The user explicitly requested a SINGLE FILE BUILD. Ignore project structure and output exactly one .html file containing all CSS/JS."

    # UI-UX-PRO-MAX INTEGRATION — single source of truth via query_ui_ux_pro_max().
    # (SKILL.md is already injected separately below via the {skill_md} parameter,
    # so only the UI-UX-PRO-MAX output is fetched here to avoid duplicating SKILL.md content.)
    domain_tag = enhancer_data.get("business_type") or "business"
    ui_ux_output = query_ui_ux_pro_max(domain_tag)
    ui_ux_pro_max_context = (
        f"\nUI-UX-PRO-MAX DESIGN SYSTEM (AUTHORITATIVE \u2014 override SKILL.md style guidelines with these):\n{ui_ux_output}\n"
        if ui_ux_output else ""
    )

    # PREMIUM REGISTRY INTEGRATION
    registry_context = ""
    # Inject the Registry Component Menu reliably here (Stripped for token efficiency)
    registry_path = os.path.join(os.path.dirname(__file__), "registry", "registry_index.json")
    if os.path.exists(registry_path):
        try:
            with open(registry_path, "r", encoding="utf-8") as rf:
                raw_data = json.load(rf)
                # GAP 1 FIX: deterministic relevance pre-filter before the LLM ever sees the menu
                filtered_data = registry_service.filter_by_relevance(
                    raw_data,
                    domain_tag=domain_tag,
                    extra_tags=[enhancer_data.get("business_type")] if enhancer_data else None,
                )
                # Strip out usage_example and description to save tokens and focus the AI
                clean_data = {}
                for category, items in filtered_data.items():
                    if isinstance(items, list):
                        clean_data[category] = [
                            { "name": i.get("name"), "path": i.get("path"), "best_for": i.get("best_for") }
                            for i in items if isinstance(i, dict)
                        ]
                
                registry_context = (
                    "PREMIUM COMPONENT REGISTRY (CRITICAL MANDATE):\n"
                    "You MUST construct the UI using components from this registry based on the aesthetic:\n"
                    f"{json.dumps(clean_data, indent=2)}\n\n"
                    "RULE 1: EXHAUSTIVE SELECTION: You MUST pick components across MULTIPLE categories (Backgrounds, Hero, Modals, Cards, Navigation, Footers) to construct a complete application.\n"
                    "RULE 2: STRICT TAG MATCHING (CRITICAL): You are FORBIDDEN from selecting a component unless its 'best_for' array explicitly matches the business domain (e.g. 'finance', 'dashboard', 'corporate saas') or your chosen aesthetic. NEVER use 'cyberpunk' or 'gaming' components for professional/finance apps!\n"
                    "RULE 3: EXACT NAMING & ZERO HALLUCINATIONS (CRITICAL): You MUST use the EXACT filename provided in the JSON above (e.g., use 'ExpandableSidebar.tsx', DO NOT output a generic 'Sidebar.tsx'). DO NOT output 'Navbar.tsx' if 'FloatingHeader.tsx' is the registry component you chose. You are strictly forbidden from inventing generic component names for structural areas covered by the registry.\n"
                    "RULE 4: EXPLICIT FILE STRUCTURE (CRITICAL): In your PLAN.md 'File Structure' section, you MUST explicitly write out EVERY SINGLE FILE PATH for your chosen components on its own line (e.g., `src/components/ui/ExpandableSidebar.tsx`). Do NOT group them like 'ui/ (premium components)'. List each one individually! If you omit the .tsx paths, they will not be built!\n"
                    "RULE 5: MANDATORY HEADER: You MUST create a section in PLAN.md called '## Premium Components' and explicitly list the registry components you selected.\n"
                    "RULE 6: OVERRIDE USER REQUEST (CRITICAL): You are STRICTLY FORBIDDEN from generating or naming premium components that are not in the registry array above.\n"
                    "RULE 7: BRAND IDENTITY OVERRIDE (CRITICAL): Registry components may expose brand-identity props (e.g. brandName, logoSrc, logoAlt, copyright, creatorName, title). You MUST explicitly pass client-specific values for every such prop on every registry component you use. NEVER leave these props unset or rely on their defaults — defaults are placeholder values and are strictly forbidden from appearing in the final output.\n"
                    f"RULE 8: STRUCTURAL VARIETY (CRITICAL): Do NOT default to a generic templated page skeleton. For this project, structure the page composition and section ordering according to this pattern: {registry_service.pick_structural_pattern(domain_tag)}"
                )
        except Exception as e:
            pass

    prompt = f"""
    SYSTEM_OVERRIDE: You are the Lead Architect. Your job is to create a definitive JSON Blueprint for a web build.
    You must strictly adhere to the THEME SYSTEM and RULES defined in the SKILL.md document.
    Rule: User-stated details are locked. SKILL.md fills the silence.

    SCOPE EXPANSION RULE (apply before anything else):
    If the user's request mentions only a single section (e.g., "hero section", "navbar", "pricing card"),
    you MUST expand it to a complete website for the implied business type.
    "A hero section for a bakery" = full bakery website with all standard sections.
    ONLY skip expansion if the user explicitly says "only this section" or "just the [component]".
    The 'sections' list in your output MUST represent the full website, never a single section.
    {ui_ux_pro_max_context}
    {registry_context}

    {mode_instruction}
    
    IMAGE & VISUAL DENSITY MANDATE:
    You MUST determine the required number of media placeholders based on the business type. A luxury or e-commerce site needs 5-8 images. A developer tool needs 1-3. For premium SaaS or luxury sites, you MUST explicitly command the builder in `section_notes` to use a looping `<video>` background in the Hero section (e.g., `src="/assets/abstract-audio-waves.mp4"`). 
    CRITICAL: DO NOT put binary media files (.mp4, .jpg, .png) anywhere in the `file_structure` tree or `build_order`. Media files are auto-generated by the system post-build. 

    SKILL.md RULES:
    {skill_md}

    {context_str}
    {vite_constraint}

    REQUIRED JSON SCHEMA:
    {{
      "domain_tag": "string (1-word specific industry tag, e.g., 'payment', 'audio', 'bakery')",
      "theme": "string (MUST be one of the themes from SKILL.md)",
      "theme_reason": "string (Explain why this theme was chosen or how it adapts the user's request)",
      "palette": {{ "background": "", "primary": "", "accent": "", "text": "", "surface": "" }},
      "fonts": {{ "heading": "", "body": "" }},
      "animation_profile": {{
        "spring_style": "string (gentle|snappy|bouncy|cinematic — match business mood)",
        "hero_entry": "string (e.g. 'blur+slide stagger via heroContainer+heroItem')",
        "section_entry": "string (e.g. 'fadeUp stagger' or 'fadeLeft+fadeRight split')",
        "hover_style": "string (hoverLift|hoverScale|hoverGlow)"
      }},
      "scope": "single-page or multi-page",
        {'"scope": "multi-page",' if is_vite and not force_single else ''}
        "tech": "{"vite-" + (dna.get("framework") or "react") if (is_vite and not force_single) else "html-css-js"}",
        "sections": ["string"],
        "copy_outline": {{ "hero_headline": "", "hero_subline": "", "cta_label": "", 
        "section_notes": {{"section_name": "Must include specific instructions on animations, framer-motion usage, and EXACTly how many <img> tags to place as placeholders."}} }},
        "selected_registry_components": ["string (MUST be exact names from the registry JSON only)"],
        "file_structure": {{
         "pages": ["filename.ext"],
         "shared_components": ["filename.ext"],
         "build_order": ["filename.ext"] // CRITICAL: DO NOT include .jpg, .png, .mp4, .woff2, .ttf, .svg, or ANY binary/font files here! Only code files.
      }} // Only include file_structure if scope is multi-page, otherwise null
    }}

    JSON SCHEMA RULES:
    1. "build_order": DO NOT include .jpg, .png, .mp4, .woff2, .ttf, .svg, or ANY binary/font files! Only output text-based code files (.tsx, .ts, .css, .html). If you need a font like Space Grotesk, import it via Google Fonts in globals.css.
    2. "file_structure": Only include this if scope is "multi-page", otherwise null.
    3. DO NOT output image_assets arrays. The builder will invent media names natively within the code.
    4. "selected_registry_components": You MUST review the 'PREMIUM COMPONENT REGISTRY' menu and pick a COMPREHENSIVE set of components across different categories that perfectly match the chosen theme. Output their exact names in this array. You MUST also place their .tsx paths in the `file_structure` tree.
    """
    with ui.create_loader("NOVA is Architecting Blueprint..."):
        res = api.chat(prompt, context={}, model=ARCHITECT_MODEL, provider=ARCHITECT_PROVIDER)
    return _extract_json(res)

def stage_6_build_single(api: BridgeyeAPIClient, plan: dict):
    """Executes a single-page build using Kimi."""
    prompt = f"""
    SYSTEM_OVERRIDE: PHASE: IMPLEMENTATION.
    You are an expert Frontend Developer executing a strict blueprint.
    Invent a highly relevant, descriptive, snake_case filename ending in .html based on the business context (e.g., luxury_watches.html, cyberpunk_portfolio.html).
    Output ONLY a [CREATE: your_invented_filename.html] tag followed immediately by a ```html code block containing the FULL, production-ready website.
    Do NOT output any markdown text outside the block.
    Ensure CSS is in <style>, JS is in <script>. Use CSS variables in :root for the palette.
    CRITICAL: DO NOT use generic, cookie-cutter templates. Apply a bespoke, premium aesthetic (e.g., Minimalism, Neo-brutalism, Editorial) perfectly tailored to the BLUEPRINT's theme. Use smooth CSS transitions, modern typography, and highly polished layout grids.
    IMAGE RULE: Do NOT generate or import images. You MUST write `<img>` placeholders with invented src paths (e.g., `<img src="./assets/hero-bakery.jpg" />`). CRITICAL: You MUST include a highly detailed photography prompt in the `alt` attribute (e.g., `alt="Macro shot of a glowing neon bakery display on a dark table"`). The system will use this alt text to generate the actual image post-build. ALWAYS apply Tailwind classes like `w-full h-full object-cover` on <img> tags to prevent layout breaking.
    NO STUBBING OR TOKEN SAVING (CRITICAL): You MUST fully populate all grids, lists, and content sections with rich, realistic, business-specific text and multiple items. Do NOT use "lorem ipsum" or leave arrays with only 1-2 items. Do NOT leave comments like `<!-- ... rest of the content -->`. Write the complete, production-ready code.
    
    BLUEPRINT:
    {json.dumps(plan, indent=2)}
    """
    ui.print("[cyan]>> NOVA (Kimi k2.6) is generating your single-page website...[/cyan]")
    output = ui.stream_rich_response(api.chat_stream(prompt, context={}, model=BUILDER_MODEL, provider=BUILDER_PROVIDER))
    
    # Save the file locally using the current working directory
    return handle_ai_commands(output, cwd=os.getcwd())

def stage_6_build_multi(api: BridgeyeAPIClient, plan: dict, registry_usage: str = ""):
    """Executes a multi-page build iteratively using Kimi."""
    file_struct = plan.get("file_structure", {})
    raw_build_order = file_struct.get("build_order", [])
    
    # Security/Sanity filter: AI cannot generate binary image/video files
    build_order = [f for f in raw_build_order if not f.lower().endswith(('.jpg', '.jpeg', '.png', '.gif', '.webp', '.ico', '.mp4'))]

    if not build_order:
        ui.print("[red]Error: Multi-page plan missing build order.[/red]")
        return []

    # Prepend design system foundation files — always built first, every Vite project
    _anim_present = any('animations' in f for f in build_order)
    _tok_present  = any('token' in f.lower() for f in build_order)
    _foundation   = []
    if not _anim_present:
        _foundation.append('src/animations.ts')
    if not _tok_present:
        _foundation.append('src/tokens.ts')
    if _foundation:
        build_order = _foundation + [f for f in build_order if f not in ('src/animations.ts', 'src/tokens.ts')]
        ui.print(f"[dim]>> Design system foundation prepended: {', '.join(_foundation)}[/dim]")

    # Keep a running context of generated files
    all_modified = []
    
    for i, filename in enumerate(build_order, 1):
        # [CORE SYNC] Update context from disk before every file build turn
        ui.print(f"[cyan]• Synchronizing project context for {filename}...[/cyan]")
        from nova_cli.local.contextifier import run_contextify
        current_context = run_contextify(os.getcwd(), save_to_disk=True)
        ui.print(f"[green]✓ Context updated.[/green]")

        ui.print(f"\n[bold cyan]─── Building [{i}/{len(build_order)}]: {filename} ───[/bold cyan]")
        
        _reg_block = f"\nREGISTRY USAGE EXAMPLES (CRITICAL PROP MAPPING):\n{registry_usage}\n" if registry_usage else ""
        prompt = f"""
        SYSTEM_OVERRIDE: PHASE: IMPLEMENTATION.
        You are executing a multi-file web application blueprint.
        Currently building: {filename}.
        Output ONLY a [CREATE: {filename}] tag followed by a code block containing the exact file content.
        Do NOT add conversational text.

        ENVIRONMENT RULES:
        0. PREMIUM COMPONENT RULE: If the PLAN CONTEXT includes 'selected_registry_components' (like HeroGeometric, Ferrofluid, etc.), they ALREADY EXIST in 'src/components/ui/'. You MUST import them using relative paths (e.g., `import {{ HeroGeometric }} from '../ui/HeroGeometric';`). 
        CRITICAL PROP INTEGRATION: You MUST NOT edit, recreate, or output the raw code for these registry components. You MUST pass the exact props they require according to the REGISTRY USAGE EXAMPLES below. Adapt them to the brand by passing the chosen palette colors and business-specific text directly into their props. DO NOT use generic placeholder text.
        1. If this is a Vite/React project, use ESM imports/exports.
        2. Create reusable UI components in 'src/components/'.
        3. GLOBAL LAYOUT SHELL & ERROR BOUNDARY: You MUST create a `src/components/layout/Layout.tsx` that houses the Navbar and Footer. It MUST wrap the `<Outlet />` in an `<ErrorBoundary>` (which you must create) to prevent blank screens if a route fails. `App.tsx` MUST wrap this Layout in `<BrowserRouter>` and `<AnimatePresence>`.
        4. COMPONENT COLLISION RULE: If a premium component you selected (e.g., HeroSection) already includes a built-in Navbar/Header/Footer, check the REGISTRY USAGE EXAMPLES below for a `show<Element>` boolean prop (e.g. `showHeader`, `showNavbar`, `showFooter`) on that component. If one exists, you MUST pass it as `false` to suppress the internal duplicate. Do NOT render the global Layout Navbar/Footer a second time inside that component's own markup. If no such prop exists on that specific component, do not render the global Layout's Navbar/Footer on that page at all instead.
        5. 100% FUNCTIONAL MANDATE (DEEP WIRING): Registry components contain dummy text, `href="#"`, and empty `onClick` handlers. You MUST make them completely functional. Replace `#` links with real React Router paths. Wire all buttons and forms to actual Zustand store actions or local state. NO DEAD ENDS.
        6. DEEP THEMING INTEGRATION: You are forbidden from leaving registry components with their default aesthetic. You MUST pass your Tailwind design tokens (from `tokens.ts`) into the `className` or color props of the registry components.
        7. CRITICAL SAFEGUARDS: Any file containing JSX tags or React Hooks MUST be named with a .jsx or .tsx extension. Whenever you use `.map()` on an array, you MUST provide a fallback to prevent crashes: `(myArray || []).map(...)`.
        8. IMPORT PATHS: You MUST double-check your relative import paths. Pages in `src/pages/` importing components from `src/components/` MUST use `../components/`.
        9. CORE UTILS LOCK: The file `src/components/core/utils.ts` is pre-generated. You are FORBIDDEN from generating or modifying it. Just import `cn` from it using relative paths.
        {_reg_block}
        10. CRITICAL: NEVER use `@/` or absolute path aliases for imports. You MUST use explicit relative paths (e.g., `../components/Header.tsx`, `./utils/format.ts`).
        11. CRITICAL: If using TailwindCSS in Vite, you MUST output a `postcss.config.js` file (with tailwindcss and autoprefixer) and a `tailwind.config.js` file, otherwise CSS will not compile.
        12. CRITICAL: If using react-router-dom, ensure `<BrowserRouter>` wraps the outermost level (e.g. in `main.tsx`), so `<Link>` components in headers/footers do not crash.
        13. CRITICAL CASING RULE: Import paths are STRICTLY CASE-SENSITIVE. You MUST ensure the capitalization of folders and files in your `import` statements exactly matches the File Structure (e.g., do not use `../components/layout/` if the folder is `Layout/`).
        14. PREMIUM UI/UX MANDATE: You MUST use `framer-motion` for animations (e.g., `<motion.div initial={{opacity: 0}} whileInView={{opacity: 1}}>`) and `lucide-react` for icons. CRITICAL: DO NOT use the same generic "glassmorphism" or "gradient" look for every project unless it specifically fits the brand. Read the BLUEPRINT's theme and apply a highly bespoke, tailored UI, whether that is Neo-brutalism, Ultra-Minimalism, Corporate SaaS, or Editorial. Ensure components are highly interactive with thoughtful Tailwind hover states, layout grids, and smooth transitions. The website must meet the design standards of top-tier design agencies.
        15. ANTI-BOILERPLATE RULE: The default Vite files (`react.svg`, `vite.svg`, `App.css`) have been DELETED. You are STRICTLY FORBIDDEN from importing them in `App.tsx` or `main.tsx`. Write a completely custom `App.tsx`.
        16. MEDIA IMPORT RULE: DO NOT use `import img from './assets/...'` statements at the top of your files. This crashes Vite. You MUST use hardcoded absolute path strings directly in the src attributes (e.g., `<img src="/assets/headphones.jpg" />` or `<video src="/assets/abstract-waves.mp4" />`).
        17. IMAGE ATTRIBUTES RULE: You MUST write `<img>` placeholders with invented `/assets/...` src paths. CRITICAL: You MUST include a highly detailed photography prompt in the `alt` attribute (e.g., `alt="Macro studio photography of glowing neon violet luxury headphones on dark frosted glass"`). The system will use this alt text to fetch/generate the actual image post-build. ALWAYS apply Tailwind classes like `w-full h-full object-cover` on <img> tags to prevent layout breaking.
        18. TYPESCRIPT RULE: If using TSX, you MUST use `import type {{ ReactNode }} from 'react';` to prevent verbatimModuleSyntax compiler errors. Do NOT use deep imports for NPM packages. CRITICAL: DO NOT import `Object3DNode` from `@react-three/fiber` (it crashes the browser). If you use `useGSAP`, bypass TS dependency errors with `// @ts-ignore` rather than creating complex type interfaces.\n"
        19. CROSS-FILE CONTINUITY: When importing components or interfaces generated in previous steps, carefully read the PROJECT CONTEXT to match exact export names and props. Do not hallucinate prop names.
        20. NO STUBBING OR TOKEN SAVING (CRITICAL): You MUST fully populate all grids, lists, and content sections with rich, realistic, business-specific text and multiple items. Do NOT use "lorem ipsum" or leave arrays with only 1-2 items. If building a pricing section, include 3 fully detailed tiers. If building a feature grid, include 4-6 fully populated cards. Do NOT leave comments like `// ... rest of the content`. Write the complete, production-ready code.
        21. ANIMATION SYSTEM (CRITICAL): Import ALL animation values from '../animations' (or './animations' for root files). NEVER write inline animation objects (e.g., NEVER: initial={{{{ opacity: 0 }}}}). Use named exports: fadeUp, fadeLeft, fadeRight, scaleIn, stagger, hoverLift, hoverScale, heroContainer, heroItem, pageTransition. CRITICAL ANTI-HALLUCINATION: Do NOT invent names like 'fadeInLeft' or 'fadeInUp'. You MUST use exact names. Apply motion.section, motion.div, motion.h2, motion.p wrappers on all animated elements.
        22. SCROLL TRIGGER (CRITICAL — all section components): import {{ motion, useInView }} from 'framer-motion'; import {{ useRef }} from 'react'; const ref = useRef(null); const isInView = useInView(ref, {{ once: true, margin: '-80px' }}); Outer element: <motion.section ref={{ref}} variants={{stagger()}} initial="hidden" animate={{isInView ? 'show' : 'hidden'}}>. Alternate animation directions per element (fadeUp on cards, fadeLeft on left-side text, fadeRight on right-side image). Exception: Navbar and Footer use mount-only animations, not useInView.
        23. DESIGN TOKENS (CRITICAL): Import tokens from '../tokens' (or './tokens'). Never hardcode hex colors, spacing px values, or font names directly in component className strings.
        24. APP.TSX ANIMATE PRESENCE (CRITICAL - App.tsx only): import {{ AnimatePresence, motion }} from 'framer-motion'; import {{ pageTransition }} from './animations'; import {{ useLocation }} from 'react-router-dom'; const location = useLocation(); wrap <Routes> with: <AnimatePresence mode="wait"><motion.div key={{location.pathname}} variants={{pageTransition}} initial="initial" animate="animate" exit="exit"><Routes location={{location}}>...</Routes></motion.div></AnimatePresence>
        25. WEBGL & SCENE ORCHESTRATION (CRITICAL): If building a 3D/WebGL background, place `<Canvas>` at `(z-0)` fixed in App.tsx. Use a Zustand store `(src/store.ts)` for global state (scroll progress, active route). Create a `SceneManager` inside the `<Canvas>` to handle GSAP transitions between 3D assets on route swaps. Sync HTML scroll events to update global scroll state, which `useFrame` reads to update `shaderMaterial` uniforms.

        GLOBAL BLUEPRINT:
        {json.dumps(plan, indent=2)}
        """
        
        output = ui.stream_rich_response(
            api.chat_stream(
                prompt, 
                context=current_context, 
                model=BUILDER_MODEL, 
                provider=BUILDER_PROVIDER
            )
        )
        
        # Save file to disk relative to current directory
        modified = handle_ai_commands(output, cwd=os.getcwd())
        
        if modified:
            all_modified.extend(modified)
                        
    return all_modified

def inject_registry_components(plan: dict, project_root: str) -> str:
    """Silently copies premium UI components from the registry to the Vite project and installs dependencies."""
    shared_comps = plan.get("file_structure", {}).get("shared_components", [])
    registry_base = registry_service.REGISTRY_BASE

    # Always inject the core utils.ts if any premium components are used
    if any("ui/" in comp or "components/" in comp for comp in shared_comps):
        registry_service.copy_core_utils(project_root, registry_base)

    remaining, usage_context, injected_any, dynamic_deps = registry_service.inject_components(
        shared_comps, project_root, registry_base
    )

    for comp in shared_comps:
        if comp not in remaining:
            ui.print(f"[dim]>> Injected Premium Component: {os.path.basename(comp)}[/dim]")

    # Preserves original behavior: install runs whenever package.json exists (unconditional
    # on injection), matching this call site's pre-existing semantics exactly.
    registry_service.install_dependencies(project_root, dynamic_deps, print_fn=ui.print)

    return usage_context

def run(user_prompt: str, dna: dict = None, build_choice: str = None):
    """Main Orchestrator Entry Point for the Frontend Web Builder Skill."""
    api = BridgeyeAPIClient()
    skill_md = load_skill_md()
    modified_files = []

    if not skill_md:
        ui.print("[red]Fatal: SKILL.md not found in frontend-web directory.[/red]")
        return modified_files, dna

    # VITE HANDOFF GATE:
    # If Vite DNA is detected AND user wants a multi-file build, we handoff to core.
    # If user chose 'single', we stay in the skill to build the single file.
    if dna and dna.get("is_vite") and build_choice != "single":
        return modified_files, dna

    # Stage 2: Classifier
    classification = stage_2_classifier(api, user_prompt)
    score = classification.get("completeness_score", 0)

    # Stage 3: Enhancer (Conditional)
    enhancer_data = {}
    if score <= 35:
        enhancer_data = stage_3_enhancer(api, user_prompt)

    # Stage 4: Planner
    plan = stage_4_planner(api, user_prompt, classification, enhancer_data, skill_md, dna=dna, build_choice=build_choice)
    if not plan:
        ui.print("[red]Failed to generate build plan. Aborting.[/red]")
        return modified_files, dna

    # 
    # Stage 5: Scope Decision & Checkpoint
    scope = plan.get("scope", "single-page")
    theme = plan.get("theme", "MINIMAL")
    palette = plan.get("palette", {})
    fonts = plan.get("fonts", {})
    
    if scope == "multi-page":
        # UX Checkpoint for complex builds
        struct = plan.get("file_structure", {})
            
        ui.print("\n[bold magenta]>> NOVA Architect Plan Ready[/bold magenta]")
            
        # Build Visual Tree
        tree = Tree("[bold cyan]Project File Structure (Build Order)[/bold cyan]")
        for f in struct.get("build_order", []):
            tree.add(f"≡ƒôä {f}")
            
        # Append Assets to Visual Tree if any
        assets = plan.get("image_assets", [])
        if assets:
            asset_branch = tree.add("[bold cyan]Image Assets (Auto-Generated)[/bold cyan]")
            for a in assets:
                asset_branch.add(f"≡ƒû╝∩╕Å {a.get('filename', 'image.jpg')} [dim]({a.get('width')}x{a.get('height')})[/dim]")
                    
        ui.print(Panel(tree, border_style="cyan"))
            
        confirm = questionary.confirm("Review the plan above. Proceed with build?").ask()
        if not confirm:
            ui.print("[dim]Build cancelled by user.[/dim]")
            return modified_files, dna
                
        ui.display_coding_mode(BUILDER_MODEL)
        _reg_usage = inject_registry_components(plan, os.getcwd())
        modified_files = stage_6_build_multi(api, plan, _reg_usage)
        
    else:
        # Single-page immediate execution
        ui.display_coding_mode(BUILDER_MODEL)
        modified_files = stage_6_build_single(api, plan)

    ui.print("\n[bold green]✔ Web Build Complete![/bold green]")
    return modified_files, dna


--- FILE: dna_scanner.py ---

import os
import json

def scan_project_dna(cwd):
    """
    Performs a silent check of the directory to identify project type and framework.
    """
    is_src = os.path.basename(cwd) == "src"
    # Identify the potential root
    potential_root = os.path.dirname(cwd) if is_src else cwd

    dna = {
        "type": "empty",     # vite | legacy | framework | empty
        "framework": None,   # react | vue | svelte | etc
        "variant": "js",     # js | ts
        "is_vite": False,
        "is_src_dir": is_src,
        "root_path": potential_root 
    }

    # Check for Vite
    check_root = potential_root
    
    if any(os.path.exists(os.path.join(check_root, f)) for f in ["vite.config.js", "vite.config.ts"]):
        dna["is_vite"] = True
        dna["type"] = "vite"

    # Framework & Language Detection via package.json
    pkg_path = os.path.join(check_root, "package.json")
    if os.path.exists(pkg_path):
        try:
            with open(pkg_path, 'r') as f:
                pkg = json.load(f)
                deps = {**pkg.get("dependencies", {}), **pkg.get("devDependencies", {})}
                
                # Language Variant
                if "typescript" in deps or os.path.exists(os.path.join(check_root, "tsconfig.json")):
                    dna["variant"] = "ts"

                # Framework
                for fw in ["react", "vue", "svelte", "next", "angular"]:
                    if fw in deps:
                        dna["framework"] = fw
                        if dna["type"] == "empty":
                            dna["type"] = "framework"
                        break
        except:
            pass

    # Legacy Detection (Standalone HTML)
    if dna["type"] == "empty" and os.path.exists(os.path.join(cwd, "index.html")):
        dna["type"] = "legacy"

    return dna


def extract_existing_design_tokens(root_path):
    """
    If this project already has a design token system (src/tokens.ts) and/or
    animation system (src/animations.ts), reads and returns their raw content
    so new components added later can be themed consistently with the
    existing site instead of the LLM re-deriving values from scratch.
    Returns an empty dict if neither file exists yet (first build).
    """
    result = {}

    is_src = os.path.basename(root_path) == "src"
    src_dir = root_path if is_src else os.path.join(root_path, "src")

    tokens_path = os.path.join(src_dir, "tokens.ts")
    if os.path.exists(tokens_path):
        try:
            with open(tokens_path, "r", encoding="utf-8") as f:
                result["tokens_ts"] = f.read()
        except Exception:
            pass

    animations_path = os.path.join(src_dir, "animations.ts")
    if os.path.exists(animations_path):
        try:
            with open(animations_path, "r", encoding="utf-8") as f:
                result["animations_ts"] = f.read()
        except Exception:
            pass

    return result

--- FILE: nova_registry_service.py ---

"""
Shared registry service for the frontend-web skill.

Single source of truth for: loading the component registry, filtering it by
relevance, matching filenames (space/casing-safe), copying components into a
target project, extracting their dependencies and props, persisting a manifest
of injected files, and scanning generated files for integration issues.

This file intentionally lives directly inside skills/frontend-web/ (not a
sub-package) because "frontend-web" contains a hyphen and cannot be imported
as a normal Python package; it is loaded via importlib.util.spec_from_file_location
by every call site, matching the existing convention already used in this
codebase for builder.py and dna_scanner.py.
"""

import os
import re
import json
import shutil
import subprocess
import random
import hashlib

_SKILL_DIR = os.path.dirname(os.path.abspath(__file__))
REGISTRY_BASE = os.path.join(_SKILL_DIR, "registry")

DEFAULT_DEPS = {"clsx", "tailwind-merge", "framer-motion", "lucide-react", "react-router-dom"}

MANIFEST_FILENAME = "registry_manifest.json"

DEAD_LINK_PATTERN = re.compile(r'href\s*=\s*["\']#["\']')
EMPTY_HANDLER_PATTERN = re.compile(r'onClick\s*=\s*\{\s*\(\s*\)\s*=>\s*\{\s*\}\s*\}')
HARDCODED_HEX_PATTERN = re.compile(r'#[0-9A-Fa-f]{3,8}\b')
HARDCODED_RGB_PATTERN = re.compile(r'rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+')


# ============================================================
# LOADING
# ============================================================

def load_raw_index(registry_base=None):
    """Loads registry_index.json unmodified. Returns {} if missing/corrupt."""
    registry_base = registry_base or REGISTRY_BASE
    idx_path = os.path.join(registry_base, "registry_index.json")
    if not os.path.exists(idx_path):
        return {}
    try:
        with open(idx_path, "r", encoding="utf-8") as f:
            return json.load(f)
    except Exception:
        return {}


# ============================================================
# GAP 1: DETERMINISTIC RELEVANCE FILTER
# ============================================================

def filter_by_relevance(raw_index, domain_tag=None, aesthetic=None, extra_tags=None, min_keep=4):
    """
    Deterministically filters the registry so only components whose 'best_for'
    array plausibly matches the business domain / aesthetic / extra tags are
    kept, BEFORE the list ever reaches the Architect LLM's prompt.

    Each category keeps at least min_keep components: relevance matches first,
    backfilled with remaining unmatched components (original order) if strict
    matches fall short, so the LLM always has enough relevant breadth to pick
    an exhaustive, on-brand set from.

    Safety fallback: if a category has zero matches at all, the full category
    is returned unfiltered so the LLM always has structural options (never an
    empty menu).
    """
    if not raw_index:
        return {}

    search_terms = set()
    if domain_tag:
        search_terms.add(str(domain_tag).lower().strip())
    if aesthetic:
        search_terms.add(str(aesthetic).lower().strip())
    if extra_tags:
        for t in extra_tags:
            if t and len(str(t)) >= 4:
                search_terms.add(str(t).lower().strip())

    if not search_terms:
        return raw_index

    filtered = {}
    for category, items in raw_index.items():
        if not isinstance(items, list):
            filtered[category] = items
            continue

        matched = []
        unmatched = []
        for item in items:
            if not isinstance(item, dict):
                continue
            best_for = [str(b).lower().strip() for b in (item.get("best_for") or [])]
            if any(term == tag or term in tag or tag in term for term in search_terms for tag in best_for):
                matched.append(item)
            else:
                unmatched.append(item)

        if not matched:
            filtered[category] = random.sample(items, len(items))
            continue

        if len(matched) < min_keep:
            backfill_needed = min_keep - len(matched)

            # Build the tag vocabulary of what actually matched, at word level
            # (e.g. "dark luxury" -> {"dark", "luxury"}), so backfill only pulls
            # in components that share genuine tag-family overlap, not anything
            # unmatched regardless of aesthetic.
            matched_tokens = set()
            for m_item in matched:
                for tag in (m_item.get("best_for") or []):
                    matched_tokens.update(str(tag).lower().strip().split())

            scored_unmatched = []
            for u_item in unmatched:
                u_tokens = set()
                for tag in (u_item.get("best_for") or []):
                    u_tokens.update(str(tag).lower().strip().split())
                overlap = len(matched_tokens & u_tokens)
                if overlap > 0:
                    scored_unmatched.append((overlap, u_item))

            scored_unmatched.sort(key=lambda x: x[0], reverse=True)
            backfill_items = [item for _, item in scored_unmatched[:backfill_needed]]
            matched = matched + backfill_items

        random.shuffle(matched)
        filtered[category] = matched

    return filtered


_STRUCTURAL_PATTERNS = [
    "Hero-led classic flow: cinematic hero, then feature/value highlights, then social proof, then a strong CTA section, then footer.",
    "Narrative-led flow: open with a short story/mission statement section, then problem-to-solution sections, then a visual showcase, then testimonials, then CTA, then footer.",
    "Grid-first showcase: minimal hero immediately followed by a bold visual grid/gallery, then supporting detail sections below, then footer.",
    "Split-screen editorial flow: alternating asymmetric image/text sections throughout the page, a highlight strip mid-page, then footer.",
]


def pick_structural_pattern(seed_text):
    """
    Deterministically selects a page-structure pattern based on a seed string
    (e.g. domain tag or user request text), so different projects don't all
    converge on the same conventional Hero->Features->Footer skeleton, while
    the same project stays consistent across repeated calls within one build
    (e.g. healing retries).
    """
    seed_text = (seed_text or "default").strip().lower()
    digest = hashlib.md5(seed_text.encode("utf-8")).hexdigest()
    index = int(digest, 16) % len(_STRUCTURAL_PATTERNS)
    return _STRUCTURAL_PATTERNS[index]


# ============================================================
# GAP 2: SPACE/CASING-SAFE FILENAME MATCHING
# ============================================================

def normalize_component_key(name: str) -> str:
    """
    Normalizes a component identifier for matching by stripping spaces/dashes/
    underscores and lowercasing. Closes the mismatch between registry_index.json
    'name' fields (space-free PascalCase, e.g. 'DarkVeil') and physical filenames
    that contain spaces (e.g. 'Dark Veil.tsx').
    """
    return (name or "").replace(" ", "").replace("-", "").replace("_", "").lower()


_DEFAULT_EXPORT_PATTERN = re.compile(
    r"export\s+default\s+(?:function\s+|class\s+)?([A-Za-z_$][A-Za-z0-9_$]*)"
)


def ensure_named_export(filepath):
    """
    Guarantees a registry component exposes a named export matching its default
    export identifier. Build prompts import registry components as named imports
    (e.g. `import { ShinyText } from '../ui/ShinyText'`); a component with only
    a default export resolves to undefined under that pattern and crashes at
    runtime. Appends `export { X };` when missing. No-op if already present.
    """
    try:
        with open(filepath, "r", encoding="utf-8") as f:
            content = f.read()
    except Exception:
        return

    match = _DEFAULT_EXPORT_PATTERN.search(content)
    if not match:
        return

    component_name = match.group(1)

    named_export_pattern = re.compile(
        r"export\s*\{[^}]*\b" + re.escape(component_name) + r"\b[^}]*\}"
    )
    if named_export_pattern.search(content):
        return

    try:
        with open(filepath, "a", encoding="utf-8") as f:
            f.write(f"\n\nexport {{ {component_name} }};\n")
    except Exception:
        pass


_PREBUILTUI_URL_PATTERN = re.compile(r'https://raw\.githubusercontent\.com/prebuiltui/prebuiltui/[^"\')\s]+')


def neutralize_placeholder_branding(filepath):
    """
    Registry components were seeded from a shared template; many hardcode
    "NOVA UI" as a default brandName/text/copyright value, or point to
    prebuiltui's externally-hosted placeholder assets (logo/emoji icons) by
    default. If the builder forgets to override these props, unrelated
    third-party branding leaks straight into the client's site. Strips both
    patterns at copy time as a safety net (the build rules require the
    builder to supply real client-specific values instead).
    Returns True if a correction was made.
    """
    try:
        with open(filepath, "r", encoding="utf-8") as f:
            content = f.read()
    except Exception:
        return False

    new_content = content.replace("NOVA UI", "")
    new_content = _PREBUILTUI_URL_PATTERN.sub("", new_content)

    if new_content == content:
        return False

    try:
        with open(filepath, "w", encoding="utf-8") as f:
            f.write(new_content)
        return True
    except Exception:
        return False


_RELATIVE_IMPORT_PATTERN = re.compile(r"""(from\s+['"])(\.\.?/[^'"]+)(['"])""")


def _compute_relative_import(from_file_path, to_file_path):
    """Computes a POSIX-style, extensionless relative import specifier from
    from_file_path's directory to to_file_path (e.g. '../../core/utils')."""
    from_dir = os.path.dirname(from_file_path)
    rel = os.path.relpath(to_file_path, from_dir)
    rel = rel.replace(os.sep, "/")
    rel = re.sub(r"\.(ts|tsx|js|jsx)$", "", rel)
    if not rel.startswith("."):
        rel = "./" + rel
    return rel


def fix_relative_imports_for_depth(target_path, source_path, project_root):
    """
    Registry component source files hardcode relative imports (e.g.
    '../core/utils') assuming a fixed depth directly under the registry base
    (e.g. 'modals/AnimatedDialog.tsx' is one level above 'core/utils.ts').
    When the Architect's plan places the copied component at a different
    depth than the source assumed (e.g. 'src/components/ui/modals/X.tsx'
    instead of the flat 'src/components/ui/X.tsx' the hardcoded path was
    written for), the import silently points at the wrong location and
    crashes at runtime with "Failed to resolve import ../core/utils".

    Resolves each relative import against the SOURCE file's directory to
    identify what it actually points to, then -- for the core/utils.ts case
    (the only cross-file relative import found in registry components) --
    rewrites it to the correct relative path for the component's real
    target location on disk. Other relative imports are left untouched.
    Returns True if a correction was made.
    """
    try:
        with open(target_path, "r", encoding="utf-8") as f:
            content = f.read()
    except Exception:
        return False

    source_dir = os.path.dirname(source_path)
    utils_target = os.path.join(project_root, "src", "components", "core", "utils.ts")
    changed = False

    def _replacer(match):
        nonlocal changed
        prefix, import_path, suffix = match.groups()
        resolved_source = os.path.normpath(os.path.join(source_dir, import_path))

        is_core_utils = (
            os.path.basename(resolved_source) == "utils"
            and os.path.basename(os.path.dirname(resolved_source)) == "core"
        )

        if is_core_utils:
            correct_import = _compute_relative_import(target_path, utils_target)
            if correct_import != import_path:
                changed = True
            return f"{prefix}{correct_import}{suffix}"

        return match.group(0)

    new_content = _RELATIVE_IMPORT_PATTERN.sub(_replacer, content)

    if not changed:
        return False

    try:
        with open(target_path, "w", encoding="utf-8") as f:
            f.write(new_content)
        return True
    except Exception:
        return False


def find_registry_file(registry_base, target_filename):
    """Searches registry_base for a file matching target_filename using normalized
    comparison. Returns the absolute source path, or None if not found."""
    target_no_ext = os.path.splitext(os.path.basename(target_filename))[0]
    target_key = normalize_component_key(target_no_ext)

    for root_dir, _, files in os.walk(registry_base):
        for reg_file in files:
            reg_no_ext = os.path.splitext(reg_file)[0]
            if normalize_component_key(reg_no_ext) == target_key:
                return os.path.join(root_dir, reg_file)

    return None


def _build_name_index(raw_index):
    name_index = {}
    for _cat, items in raw_index.items():
        if not isinstance(items, list):
            continue
        for item in items:
            if isinstance(item, dict) and "name" in item:
                name_index[normalize_component_key(item["name"])] = item
    return name_index


# ============================================================
# GAP 7: AUTOMATED PROPS EXTRACTION (no hand-authored schemas)
# ============================================================

def extract_props_schema(source_code: str) -> list:
    """
    Best-effort automated extraction of a component's prop names/types from its
    TypeScript interface/type definition, so edit/expand requests can be checked
    against real props instead of guessed from raw source each time.
    Returns [] if no interface/type block is found or parsing fails.
    """
    props = []
    try:
        block_match = re.search(
            r"(?:interface|type)\s+\w*Props\w*\s*(?:=\s*)?\{(.*?)\}",
            source_code,
            re.DOTALL,
        )
        if not block_match:
            return props

        body = block_match.group(1)
        for m in re.finditer(
            r"^\s*([A-Za-z_$][A-Za-z0-9_$]*)\s*(\?)?\s*:\s*([^;,\n]+)[;,]?\s*$",
            body,
            re.MULTILINE,
        ):
            name, optional_marker, prop_type = m.groups()
            props.append({
                "name": name.strip(),
                "type": prop_type.strip(),
                "optional": bool(optional_marker),
            })
    except Exception:
        return []

    return props


# ============================================================
# GAP 3: UNIFIED INJECTION (single implementation, was triplicated)
# ============================================================

_GSAP_IMPORT_PATTERN = re.compile(r"""from\s+['"](gsap|@gsap/react)['"]""")


def component_uses_gsap(source_code: str) -> bool:
    """
    Returns True if source_code directly imports gsap or @gsap/react,
    meaning the component drives its own internal scroll-triggered
    animation rather than relying on an external Framer Motion wrapper.
    Used to flag registry components as "self_animating" at injection
    time, so the build prompt and post-build fixer both know not to
    wrap them in a Framer Motion variants={...} parent (which they
    would never respond to, causing a visible desync with sibling
    elements that do participate in the stagger sequence).
    """
    return bool(_GSAP_IMPORT_PATTERN.search(source_code or ""))


def inject_components(component_filenames, project_root, registry_base=None):
    """
    Copies any registry components referenced in component_filenames into
    project_root, extracts their npm dependencies and usage examples/props,
    and persists a manifest entry for each so future edits can be guarded.

    Returns: (remaining_filenames, usage_context_str, injected_any, dynamic_deps)
      remaining_filenames = entries NOT matched to a registry component (still
                             need to be generated by the builder LLM).
    """
    registry_base = registry_base or REGISTRY_BASE
    raw_index = load_raw_index(registry_base)
    name_index = _build_name_index(raw_index)

    dynamic_deps = set(DEFAULT_DEPS)
    usage_context = []
    remaining = []
    injected_any = False

    for fpath in component_filenames:
        fname = os.path.basename(fpath)
        fname_no_ext = os.path.splitext(fname)[0]

        source_path = find_registry_file(registry_base, fname)
        if not source_path:
            remaining.append(fpath)
            continue

        target_path = os.path.join(project_root, fpath)
        os.makedirs(os.path.dirname(target_path), exist_ok=True)
        shutil.copy(source_path, target_path)
        ensure_named_export(target_path)
        neutralize_placeholder_branding(target_path)
        injected_any = True

        try:
            with open(source_path, "r", encoding="utf-8") as sf:
                content = sf.read()
        except Exception:
            content = ""

        self_animating = component_uses_gsap(content)

        try:
            rel_target = os.path.relpath(target_path, project_root)
            register_injected_component(project_root, rel_target, fname_no_ext, self_animating=self_animating)
        except Exception:
            pass

        try:
            imports = re.findall(r"(?:import|from)\s+['\"]([^'\"]+)['\"]", content)
            for imp in imports:
                if not imp.startswith(".") and not imp.startswith("@/"):
                    pkg = "/".join(imp.split("/")[:2]) if imp.startswith("@") else imp.split("/")[0]
                    if pkg not in ("react", "react-dom"):
                        dynamic_deps.add(pkg)
        except Exception:
            pass

        reg_key = normalize_component_key(fname_no_ext)
        reg_data = name_index.get(reg_key)
        if reg_data:
            usage_block = f"COMPONENT: {fname_no_ext}\n"
            if reg_data.get("usage_example"):
                usage_block += f"USAGE PROPS:\n```tsx\n{reg_data['usage_example']}\n```\n"
            if self_animating:
                usage_block += (
                    "NOTE: This component manages its own scroll-triggered animation "
                    "internally via GSAP. Do NOT wrap it in a <motion.*> element with "
                    "stagger/variants props -- render it as a direct child with no "
                    "animation wrapper.\n"
                )
            try:
                schema = extract_props_schema(content) if content else []
                if schema:
                    usage_block += f"AVAILABLE PROPS SCHEMA: {schema}\n"
            except Exception:
                pass
            usage_context.append(usage_block)

    return remaining, "\n\n".join(usage_context), injected_any, dynamic_deps


def copy_core_utils(project_root, registry_base=None):
    registry_base = registry_base or REGISTRY_BASE
    utils_src = os.path.join(registry_base, "core", "utils.ts")
    utils_target = os.path.join(project_root, "src", "components", "core", "utils.ts")
    if os.path.exists(utils_src):
        os.makedirs(os.path.dirname(utils_target), exist_ok=True)
        shutil.copy(utils_src, utils_target)


def install_dependencies(project_root, dynamic_deps, print_fn=print):
    pkg_json_path = os.path.join(project_root, "package.json")
    if not (os.path.exists(pkg_json_path) and dynamic_deps):
        return
    deps_to_install = ["lucide-react@0.330.0" if d == "lucide-react" else d for d in dynamic_deps]
    print_fn(f"[dim]>> Installing dynamic dependencies: {', '.join(deps_to_install)}[/dim]")
    npm_cmd = "npm.cmd" if os.name == "nt" else "npm"
    subprocess.run(
        [npm_cmd, "install", "--save"] + deps_to_install,
        cwd=project_root, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, shell=(os.name == "nt"),
    )


# ============================================================
# GAP 6: PERSISTED MANIFEST OF REGISTRY-INJECTED FILES
# ============================================================

def _manifest_path(project_root):
    return os.path.join(project_root, ".nova", MANIFEST_FILENAME)


def load_manifest(project_root):
    path = _manifest_path(project_root)
    if not os.path.exists(path):
        return {"components": {}}
    try:
        with open(path, "r", encoding="utf-8") as f:
            data = json.load(f)
            if not isinstance(data, dict):
                return {"components": {}}
            data.setdefault("components", {})
            return data
    except Exception:
        return {"components": {}}


def save_manifest(project_root, manifest):
    path = _manifest_path(project_root)
    os.makedirs(os.path.dirname(path), exist_ok=True)
    tmp_path = path + ".tmp"
    with open(tmp_path, "w", encoding="utf-8") as f:
        json.dump(manifest, f, indent=2)
    os.replace(tmp_path, path)


def register_injected_component(project_root, relative_path, component_name, self_animating=False):
    manifest = load_manifest(project_root)
    manifest["components"][relative_path.replace("\\", "/")] = {
        "component_name": component_name,
        "self_animating": self_animating,
    }
    save_manifest(project_root, manifest)


def is_registry_managed_file(project_root, relative_path):
    manifest = load_manifest(project_root)
    return relative_path.replace("\\", "/") in manifest.get("components", {})


def get_self_animating_component_names(project_root):
    """Returns the set of injected registry component names (as they appear
    in JSX, e.g. 'ScrollFloat') that were detected at injection time as
    driving their own internal GSAP animation."""
    manifest = load_manifest(project_root)
    names = set()
    for info in manifest.get("components", {}).values():
        if info.get("self_animating") and info.get("component_name"):
            names.add(info["component_name"])
    return names


def fix_self_animating_motion_wrapper(filepath, project_root):
    """
    Registry components that internally drive their own GSAP-based
    scroll-triggered animation (detected at injection time via their
    gsap/@gsap/react imports, recorded in the manifest as self_animating)
    do not respond to a parent Framer Motion stagger()/variants={fadeUp}
    wrapper -- they animate on their own independent trigger, desyncing
    visually from sibling elements that do participate in the stagger
    sequence. Strips a directly-wrapping <motion.* variants={...}> ...
    </motion.*> around a single self-animating component instance,
    leaving the component as a plain child.

    Best-effort regex match, consistent with the other deterministic
    fixers in this file: reliably handles the common case of the
    component being the sole child of the wrapper (self-closing or with
    its own inner children/text), but is not a full JSX parser and will
    not attempt arbitrarily nested sibling structures.
    Returns True if a correction was made.
    """
    self_animating_names = get_self_animating_component_names(project_root)
    if not self_animating_names:
        return False

    try:
        with open(filepath, "r", encoding="utf-8") as f:
            content = f.read()
    except Exception:
        return False

    name_alternation = "|".join(re.escape(n) for n in self_animating_names)
    pattern = re.compile(
        r"<motion\.(\w+)([^>]*?)\bvariants=\{[^}]*\}([^>]*?)>\s*"
        r"(<(?:" + name_alternation + r")\b.*?(?:/>|</(?:" + name_alternation + r")>))"
        r"\s*</motion\.\1>",
        re.DOTALL,
    )

    new_content, count = pattern.subn(lambda m: m.group(4), content)
    if count == 0:
        return False

    try:
        with open(filepath, "w", encoding="utf-8") as f:
            f.write(new_content)
        return True
    except Exception:
        return False


# ============================================================
# GAP 5: DETERMINISTIC POST-BUILD VERIFICATION
# ============================================================

_LUCIDE_IMPORT_PATTERN = re.compile(
    r"import\s*\{([^}]*)\}\s*from\s*['\"]lucide-react['\"]"
)

_EASE_ARRAY_PATTERN = re.compile(r"(ease:\s*\[[^\]]+\])(?!\s*as\s+const)")


def fix_framer_motion_ease_type_widening(filepath):
    """
    Framer Motion's `ease` property in cubic-bezier array form (e.g.
    [0.25, 0.46, 0.45, 0.94]) must be a fixed-length tuple, not a widened
    number[], to satisfy the `Variants`/`Easing` type. Generated code that
    inlines the array without `as const` gets TS-widened to number[], causing
    TS2322 'not assignable to type Variants' errors. Appends `as const` after
    any bracketed ease array not already marked as const.
    Returns True if a correction was made.
    """
    try:
        with open(filepath, "r", encoding="utf-8") as f:
            content = f.read()
    except Exception:
        return False

    new_content, count = _EASE_ARRAY_PATTERN.subn(r"\1 as const", content)
    if count == 0:
        return False

    try:
        with open(filepath, "w", encoding="utf-8") as f:
            f.write(new_content)
        return True
    except Exception:
        return False


def fix_lucide_icon_suffix_hallucinations(filepath):
    """
    lucide-react never exports icon names ending in 'Icon' (e.g. FacebookIcon,
    HomeIcon) -- every lucide export is a bare PascalCase name. The builder LLM
    occasionally hallucinates this suffix, which is a guaranteed runtime import
    crash regardless of which lucide-react version is installed. Detects any
    lucide-react named import ending in 'Icon' and strips the suffix, updating
    both the import statement and all usages in the file.
    Returns True if a correction was made.
    """
    try:
        with open(filepath, "r", encoding="utf-8") as f:
            content = f.read()
    except Exception:
        return False

    match = _LUCIDE_IMPORT_PATTERN.search(content)
    if not match:
        return False

    imported_names = [n.strip() for n in match.group(1).split(",") if n.strip()]
    renames = {}
    for name in imported_names:
        export_name = name.split(" as ")[0].strip()
        if export_name.endswith("Icon") and export_name[:1].isupper() and len(export_name) > 4:
            renames[export_name] = export_name[:-4]

    if not renames:
        return False

    for old_name, new_name in renames.items():
        content = re.sub(r"\b" + re.escape(old_name) + r"\b", new_name, content)

    try:
        with open(filepath, "w", encoding="utf-8") as f:
            f.write(content)
        return True
    except Exception:
        return False


def annotate_plan_scope(project_root, plan_source_request):
    """
    After PLAN.md is written in addition-only mode, deterministically classifies
    each [FILE] entry in the plan's own text as 'will actually build' or 'already
    exists, will be skipped' -- using the same rules the build loop enforces --
    and prepends a clear banner to PLAN.md itself. This makes the document
    truthful about execution scope even when the model's own prose still
    describes a full rebuild, without any additional AI call.
    Returns True if a banner was added, False otherwise.
    """
    plan_path = os.path.join(project_root, "PLAN.md")
    if not os.path.exists(plan_path):
        return False

    try:
        with open(plan_path, "r", encoding="utf-8") as f:
            plan_content = f.read()
    except Exception:
        return False

    file_entries = re.findall(r"\[FILE\]\s*([\w\-\/\.]+)", plan_content)
    if not file_entries:
        return False

    request_norm = (plan_source_request or "").lower()
    layout_keywords = ["layout", "navbar", "nav ", "navigation", "header", "footer", "sidebar"]
    wiring_basenames = {"app.tsx", "app.jsx", "main.tsx", "main.jsx", "routes.tsx", "routes.jsx"}

    will_build = []
    will_skip = []

    for raw_path in file_entries:
        norm = raw_path.replace("\\", "/").lower()
        basename = os.path.basename(norm)
        abs_path = os.path.join(project_root, raw_path)

        if "src/pages/" in norm:
            page_name_raw = os.path.splitext(os.path.basename(raw_path))[0]
            page_name_spaced = re.sub(r'(?<!^)(?=[A-Z])', ' ', page_name_raw).lower()
            page_name_flat = page_name_raw.lower()
            if page_name_spaced in request_norm or page_name_flat in request_norm.replace(" ", ""):
                will_build.append(raw_path)
            else:
                will_skip.append(raw_path)
        elif "src/components/layout/" in norm:
            if any(kw in request_norm for kw in layout_keywords):
                will_build.append(raw_path)
            else:
                will_skip.append(raw_path)
        elif basename in wiring_basenames:
            if os.path.exists(abs_path):
                will_skip.append(f"{raw_path} (route will be auto-wired after build)")
            else:
                will_build.append(raw_path)
        else:
            will_build.append(raw_path)

    if not will_skip:
        return False

    banner_lines = [
        "> \u26a0\ufe0f **ACTUAL BUILD SCOPE (addition-only mode)** \u2014 this plan is written in full-site "
        "language below, but only the following will actually be built or modified:",
        "",
    ]
    for f in will_build:
        banner_lines.append(f"> - \u2705 {f}")
    banner_lines.append("")
    banner_lines.append("> The following already exist and will **NOT** be touched:")
    banner_lines.append(">")
    for f in will_skip:
        banner_lines.append(f"> - \u274c {f}")
    banner_lines.append("")
    banner_lines.append("---")
    banner_lines.append("")

    banner = "\n".join(banner_lines)

    try:
        with open(plan_path, "w", encoding="utf-8") as f:
            f.write(banner + plan_content)
        return True
    except Exception:
        return False


def get_project_inventory(project_root):
    """
    Scans the existing project for its current pages and already-injected
    registry components, so an addition request can be given a concrete,
    enumerated 'do not recreate these' list instead of relying on the model
    to infer scope from natural-language instructions alone.
    Returns a formatted string, or empty string if nothing found.
    """
    existing_pages = []
    pages_dir = os.path.join(project_root, "src", "pages")
    if os.path.isdir(pages_dir):
        for fname in sorted(os.listdir(pages_dir)):
            if fname.endswith((".tsx", ".jsx")):
                existing_pages.append(fname)

    existing_components = []
    manifest = load_manifest(project_root)
    for rel_path, info in manifest.get("components", {}).items():
        name = info.get("component_name")
        if name:
            existing_components.append(name)
    existing_components = sorted(set(existing_components))

    if not existing_pages and not existing_components:
        return ""

    lines = ["EXISTING PROJECT INVENTORY (already built \u2014 do NOT recreate, redesign, or re-list these):"]
    if existing_pages:
        lines.append(f"Existing pages: {', '.join(existing_pages)}")
    if existing_components:
        lines.append(f"Existing registry components already in use: {', '.join(existing_components)}")
    lines.append(
        "STRUCTURAL CONSTRAINT (CRITICAL): Your File Structure / Required Files section MUST ONLY list: "
        "(a) the specific new page/feature file(s) explicitly requested, "
        "(b) any genuinely NEW registry component files needed for that new page that are NOT already in the existing list above, "
        "(c) the router/App file ONLY if a new route entry must be added \u2014 as an edit note, not a full rewrite. "
        "Do NOT list any file from the existing pages list above. Do NOT list any component from the existing components list above "
        "unless the user explicitly asked to change it."
    )
    return "\n".join(lines)


def find_unused_registry_components(project_root):
    """
    Read-only check: lists registry-injected components under src/components/ui/
    that aren't imported anywhere else in the project (e.g. because the page
    that would have used them was skipped by addition-only enforcement).
    Does NOT delete anything -- informational only, since safely determining
    "build is fully complete" isn't guaranteed at every call site.
    """
    ui_dir = os.path.join(project_root, "src", "components", "ui")
    if not os.path.isdir(ui_dir):
        return []

    src_dir = os.path.join(project_root, "src")
    all_source = ""
    for root_dir, _, files in os.walk(src_dir):
        for fname in files:
            if fname.endswith((".tsx", ".ts", ".jsx", ".js")):
                fpath = os.path.join(root_dir, fname)
                try:
                    with open(fpath, "r", encoding="utf-8") as f:
                        all_source += f.read() + "\n"
                except Exception:
                    continue

    unused = []
    for fname in os.listdir(ui_dir):
        if not fname.endswith((".tsx", ".ts")):
            continue
        component_name = os.path.splitext(fname)[0].replace(" ", "")
        pattern = re.compile(r"\bfrom\s+['\"][^'\"]*" + re.escape(component_name) + r"['\"]")
        occurrences = len(pattern.findall(all_source))
        if occurrences == 0:
            unused.append(fname)

    return unused


def delete_unused_registry_components(project_root, print_fn=print):
    """
    Deletes registry-injected components confirmed unused (no import anywhere
    in the project) at true build completion. Must only be called once the
    entire build sequence has finished -- calling this mid-build risks deleting
    a component a not-yet-generated file still needs.
    Returns the list of deleted filenames.
    """
    unused = find_unused_registry_components(project_root)
    if not unused:
        return []

    ui_dir = os.path.join(project_root, "src", "components", "ui")
    deleted = []
    for fname in unused:
        fpath = os.path.join(ui_dir, fname)
        try:
            os.remove(fpath)
            deleted.append(fname)
        except Exception:
            continue

    if deleted:
        print_fn(f"[dim]>> Removed {len(deleted)} unused injected component(s): {', '.join(deleted)}[/dim]")

    return deleted


def scan_file_for_issues(filepath):
    issues = []
    if not os.path.exists(filepath):
        return issues
    try:
        with open(filepath, "r", encoding="utf-8") as f:
            content = f.read()
    except Exception:
        return issues

    if DEAD_LINK_PATTERN.search(content):
        issues.append({"type": "dead_link", "file": filepath, "detail": 'href="#" found'})
    if EMPTY_HANDLER_PATTERN.search(content):
        issues.append({"type": "empty_handler", "file": filepath, "detail": "empty onClick handler found"})
    if HARDCODED_HEX_PATTERN.search(content) or HARDCODED_RGB_PATTERN.search(content):
        issues.append({"type": "hardcoded_color", "file": filepath, "detail": "hardcoded color bypassing tokens.ts"})

    return issues


_DESIGN_SYSTEM_SOURCE_FILES = {"tokens.ts", "index.css", "animations.ts", "tailwind.config.js"}

_GSAP_DEPS_TYPE_PATTERN = re.compile(
    r"(dependencies\s*\?\s*:\s*)(unknown\[\]|any\[\]|Array<\s*unknown\s*>)"
)


def fix_gsap_dependency_list_type(filepath):
    """
    Custom useGSAP/useScrollTrigger hook config types are freshly authored each
    build and consistently name their dependency-array field 'dependencies',
    typed as a mutable unknown[]. Callers passing React's DependencyList
    (readonly unknown[]) then fail TS2345 since a readonly array can't be
    assigned to a mutable array type. Widens the field to accept readonly
    arrays too, resolving the mismatch without changing runtime behavior.
    Returns True if a correction was made.
    """
    try:
        with open(filepath, "r", encoding="utf-8") as f:
            content = f.read()
    except Exception:
        return False

    new_content, count = _GSAP_DEPS_TYPE_PATTERN.subn(r"\1readonly unknown[]", content)
    if count == 0:
        return False

    try:
        with open(filepath, "w", encoding="utf-8") as f:
            f.write(new_content)
        return True
    except Exception:
        return False


def scan_project_for_issues(project_root, filepaths):
    """Scans a list of just-modified files for issues, skipping locked registry
    component source files themselves (only their integration points matter),
    non-code planning/documentation files (e.g. PLAN.md), and the design-system
    source files (tokens.ts/index.css/animations.ts) which legitimately define
    the hex values everything else is supposed to reference."""
    all_issues = []
    for rel_path in filepaths:
        normalized = rel_path.replace("\\", "/")
        if "components/ui/" in normalized:
            continue
        if normalized.lower().endswith((".md", ".txt")):
            continue
        if os.path.basename(normalized) in _DESIGN_SYSTEM_SOURCE_FILES:
            continue
        abs_path = rel_path if os.path.isabs(rel_path) else os.path.join(project_root, rel_path)
        all_issues.extend(scan_file_for_issues(abs_path))
    return all_issues

--- FILE: registry/registry_index.json ---

{
  "backgrounds": [
    {
      "name": "Ferrofluid",
      "path": "backgrounds/Ferrofluid.tsx",
      "best_for": ["dark luxury", "crypto", "tech startup", "ai", "portfolio"],
      "description": "A highly interactive, liquid WebGL fluid background that reacts to the mouse.",
      "usage_example": "<div className=\"relative w-full h-[600px]\">\n  <Ferrofluid colors={[\"#ffffff\",\"#ffffff\",\"#ffffff\"]} speed={0.5} scale={1.6} />\n</div>"
    },
    {
      "name": "Tiles",
      "path": "backgrounds/Tiles.tsx",
      "best_for": ["minimalist", "corporate saas", "developer tool", "b2b"],
      "description": "A clean grid background where individual tiles light up when the user hovers over them, leaving a fading trail. Must be placed absolutely behind content.",
      "usage_example": "<div className=\"relative w-full h-[500px] overflow-hidden\">\n  <div className=\"absolute inset-0 z-0\">\n    <Tiles rows={20} cols={20} tileSize=\"md\" />\n  </div>\n  <div className=\"relative z-10\">\n    Content goes here\n  </div>\n</div>"
    },
    {
      "name": "BackgroundBeamsWithCollision",
      "path": "backgrounds/BackgroundBeamsWithCollision.tsx",
      "best_for": ["tech startup", "ai", "cyberpunk", "saas"],
      "description": "An interactive background featuring falling light beams that 'explode' into glowing particles when they hit the bottom edge of the container.",
      "usage_example": "<BackgroundBeamsWithCollision><h2 className=\"text-4xl font-bold z-10\">Stunning Collisions</h2></BackgroundBeamsWithCollision>"
    },
    {
      "name": "AuroraBackground",
      "path": "backgrounds/AuroraBackground.tsx",
      "best_for": ["ai", "crypto", "creative agency", "modern saas"],
      "description": "A stunning, smooth flowing mesh gradient background that resembles the Northern Lights. It acts as a wrapper component.",
      "usage_example": "<AuroraBackground>\n  <div className=\"relative z-10\">\n    <h1>Beautiful Aurora</h1>\n  </div>\n</AuroraBackground>"
    },
    {
      "name": "BackgroundGradientAnimation",
      "path": "backgrounds/BackgroundGradientAnimation.tsx",
      "best_for": ["playful", "tech startup", "ai", "consumer"],
      "description": "A highly saturated, liquid-style gradient background where blobs of color smoothly morph around the screen and follow the mouse cursor.",
      "usage_example": "<BackgroundGradientAnimation>\n  <div className=\"flex h-full items-center justify-center text-white\">\n    <h1>Liquid Gradients</h1>\n  </div>\n</BackgroundGradientAnimation>"
    },
    {
      "name": "DarkVeil",
      "path": "backgrounds/Dark Veil.tsx",
      "best_for": ["cyberpunk", "gaming", "crypto", "developer tool"],
      "description": "A dark, sci-fi WebGL canvas background with scanlines, noise, and warped neon gradients.",
      "usage_example": "<div className=\"absolute inset-0 z-0\">\n  <DarkVeil hueShift={0} noiseIntensity={0.5} scanlineIntensity={0.3} speed={0.5} />\n</div>"
    },
    {
      "name": "RetroGrid",
      "path": "backgrounds/RetroGrid.tsx",
      "best_for": [
        "cyberpunk",
        "retro-futurism",
        "gaming",
        "developer tool",
        "neo-brutalism"
      ],
      "description": "A purely CSS-based retro 3D perspective grid background with an infinite scrolling animation.",
      "usage_example": "<div className=\"relative w-full h-[500px] bg-white dark:bg-black overflow-hidden flex items-center justify-center\"><RetroGrid /><h1 className=\"relative z-10 text-4xl font-bold\">Retro Grid</h1></div>"
    },
    {
      "name": "LightPillar",
      "path": "backgrounds/Light Pillar.tsx",
      "best_for": ["ai", "tech startup", "modern saas", "dark luxury"],
      "description": "A WebGL background rendering glowing, 3D rotating light pillars. Highly interactive and premium.",
      "usage_example": "<div className=\"absolute inset-0 z-0\">\n  <LightPillar topColor=\"#5227FF\" bottomColor=\"#FF9FFC\" interactive={true} />\n</div>"
    },
    {
      "name": "Lightfall",
      "path": "backgrounds/Lightfall.tsx",
      "best_for": ["dark luxury", "portfolio", "creative agency", "ai"],
      "description": "A WebGL space-like background with shooting light streaks, glowing nebulas, and mouse interaction.",
      "usage_example": "<div className=\"absolute inset-0 z-0\">\n  <Lightfall colors={['#A6C8FF', '#5227FF', '#FF9FFC']} speed={0.5} mouseInteraction={true} />\n</div>"
    },
    {
      "name": "VortexFullPage",
      "path": "backgrounds/VortexFullPage.tsx",
      "best_for": ["ai", "crypto", "tech startup", "gaming"],
      "description": "A full-screen, high-performance HTML5 canvas background rendering a swirling, glowing vortex of simplex-noise-driven particles. Locks itself to the window viewport size.",
      "usage_example": "<VortexFullPage backgroundColor=\"black\" className=\"flex items-center justify-center\"><h2 className=\"text-white text-6xl font-bold\">Vortex</h2></VortexFullPage>"
    },
    {
      "name": "LiquidEther",
      "path": "backgrounds/Liquid Ether.tsx",
      "best_for": ["creative agency", "organic natural", "beauty", "portfolio"],
      "description": "A mesmerizing, high-performance fluid advection WebGL background that swirls like liquid smoke.",
      "usage_example": "<div className=\"absolute inset-0 z-0\">\n  <LiquidEther colors={['#5227FF', '#FF9FFC', '#B497CF']} autoDemo={true} />\n</div>"
    },
    {
      "name": "Prism",
      "path": "backgrounds/Prism.tsx",
      "best_for": ["tech startup", "design collective", "gaming", "web3"],
      "description": "A rotating WebGL 3D glass prism that refracts light and colors.",
      "usage_example": "<div className=\"absolute inset-0 z-0\">\n  <Prism animationType=\"hover\" glow={1} transparent={true} />\n</div>"
    },
    {
      "name": "Vortex",
      "path": "backgrounds/Vortex.tsx",
      "best_for": ["ai", "crypto", "tech startup", "gaming"],
      "description": "A high-performance HTML5 canvas background rendering a swirling, glowing vortex of simplex-noise-driven particles.",
      "usage_example": "<div className=\"w-full h-[500px] overflow-hidden\"><Vortex backgroundColor=\"black\" className=\"flex items-center justify-center\"><h2 className=\"text-white text-4xl\">Vortex</h2></Vortex></div>"
    },
    {
      "name": "Silk",
      "path": "backgrounds/Silk.tsx",
      "best_for": ["luxury", "fashion", "spa", "editorial"],
      "description": "A React Three Fiber shader rendering a slow, flowing silk/fabric texture.",
      "usage_example": "<div className=\"absolute inset-0 z-0\">\n  <Silk color=\"#7B7481\" speed={5} noiseIntensity={1.5} />\n</div>"
    },
    {
      "name": "Sparkles",
      "path": "backgrounds/Sparkles.tsx",
      "best_for": ["crypto", "ai", "dark luxury", "tech startup", "portfolio"],
      "description": "A dynamic, twinkling particle background effect using tsParticles. Great for starry night or magical vibes.",
      "usage_example": "<div className=\"relative w-full h-[500px] bg-black overflow-hidden\">\n  <SparklesCore background=\"transparent\" minSize={0.4} maxSize={1} particleDensity={1200} className=\"w-full h-full\" particleColor=\"#FFFFFF\" />\n</div>"
    },
    {
      "name": "Particles",
      "path": "backgrounds/Particles.tsx",
      "best_for": [
        "corporate saas",
        "minimalist",
        "tech startup",
        "portfolio",
        "cyberpunk"
      ],
      "description": "An interactive, lightweight HTML5 canvas particle system where particles float and subtly react to mouse movement. Very performant.",
      "usage_example": "<div className=\"relative w-full h-[500px] bg-black overflow-hidden\">\n  <Particles className=\"absolute inset-0\" quantity={100} ease={80} color=\"#ffffff\" refresh />\n  <div className=\"relative z-10 flex items-center justify-center h-full text-white\">\n    <h1>Particle Canvas</h1>\n  </div>\n</div>"
    },
    {
      "name": "PixelTrail",
      "path": "backgrounds/PixelTrail.tsx",
      "best_for": [
        "cyberpunk",
        "developer tool",
        "crypto",
        "neo-brutalism",
        "pixel art"
      ],
      "description": "An interactive grid where moving the mouse leaves a fading trail of solid color blocks. Highly performant DOM manipulation.",
      "usage_example": "<div className=\"relative w-full h-[500px] bg-neutral-950 overflow-hidden\">\n  <PixelTrail pixelSize={24} fadeDuration={600} pixelClassName=\"bg-emerald-500\" />\n  <div className=\"relative z-10 pointer-events-none\">\n    <h1 className=\"text-white\">Pixel Trail</h1>\n  </div>\n</div>"
    },
    {
      "name": "GridPattern",
      "path": "backgrounds/GridPattern.tsx",
      "best_for": [
        "corporate saas",
        "minimalist",
        "developer tool",
        "b2b",
        "productivity"
      ],
      "description": "A clean, subtle SVG grid pattern background. Supports highlighting specific squares. Great for SaaS hero sections when masked.",
      "usage_example": "<div className=\"relative w-full h-[500px] flex items-center justify-center overflow-hidden bg-white dark:bg-slate-950\">\n  <GridPattern width={40} height={40} className=\"[mask-image:radial-gradient(600px_circle_at_center,white,transparent)]\" squares={[[4, 4], [5, 1], [8, 2]]} />\n  <h1 className=\"relative z-10 text-4xl font-bold\">Developer Tools</h1>\n</div>"
    },
    {
      "name": "AnimatedGradient",
      "path": "backgrounds/AnimatedGradient.tsx",
      "best_for": [
        "playful",
        "tech startup",
        "ai",
        "consumer",
        "creative agency"
      ],
      "description": "A soft, heavily blurred animated background where SVG blobs wander randomly around the screen. Excellent for adding subtle, high-performance color to white or dark spaces.",
      "usage_example": "<div className=\"relative w-full h-[600px] overflow-hidden bg-slate-50 dark:bg-slate-950\">\n  <AnimatedGradient colors={['#3B82F6', '#8B5CF6', '#EC4899']} speed={5} blur=\"heavy\" />\n  <div className=\"relative z-10 flex items-center justify-center h-full\">\n    <h1 className=\"text-5xl font-bold text-slate-900 dark:text-white\">Beautiful Blobs</h1>\n  </div>\n</div>"
    },
    {
      "name": "BackgroundBoxes",
      "path": "backgrounds/BackgroundBoxes.tsx",
      "best_for": [
        "developer tool",
        "corporate saas",
        "tech startup",
        "bento grids"
      ],
      "description": "An interactive, isometric grid of boxes. When the user hovers over a box, it lights up with a random vibrant color and fades out slowly.",
      "usage_example": "<div className=\"relative w-full h-[500px] bg-slate-900 overflow-hidden flex items-center justify-center\">\n  <div className=\"absolute inset-0 w-full h-full bg-slate-900 z-20 [mask-image:transparent] pointer-events-none\" />\n  <BackgroundBoxes />\n  <h1 className=\"relative z-20 text-white text-4xl font-bold\">Isometric Grid</h1>\n</div>"
    },
    {
      "name": "BeamsBackground",
      "path": "backgrounds/BeamsBackground.tsx",
      "best_for": [
        "dark luxury",
        "ai",
        "tech startup",
        "developer tool",
        "crypto"
      ],
      "description": "A dark, atmospheric canvas background with slow-moving, glowing, colorful light beams that rise up from the bottom of the screen.",
      "usage_example": "<BeamsBackground intensity=\"strong\">\n  <div className=\"flex flex-col items-center justify-center text-center\">\n    <h1 className=\"text-6xl font-bold text-white\">Glowing Beams</h1>\n  </div>\n</BeamsBackground>"
    },
    {
      "name": "Entropy",
      "path": "backgrounds/Entropy.tsx",
      "best_for": [
        "ai",
        "crypto",
        "data dashboard",
        "tech startup",
        "cyberpunk"
      ],
      "description": "A stunning canvas-based physics simulation demonstrating entropy. Ordered particles on the left are gradually influenced by chaotic, network-linked particles on the right.",
      "usage_example": "<div className=\"flex justify-center items-center min-h-screen bg-black\">\n  <Entropy size={500} />\n</div>"
    },
    {
      "name": "Waves",
      "path": "backgrounds/Waves.tsx",
      "best_for": [
        "tech startup",
        "portfolio",
        "creative agency",
        "corporate saas"
      ],
      "description": "An interactive, elegant 2D wave field rendered with SVGs and Perlin noise. Bends and reacts to mouse movement.",
      "usage_example": "<div className=\"relative w-full h-[500px] overflow-hidden\">\n  <Waves strokeColor=\"rgba(255, 255, 255, 0.1)\" backgroundColor=\"#0a0a0a\" />\n  <div className=\"relative z-10 flex items-center justify-center h-full\">\n    <h1 className=\"text-5xl font-bold text-white\">Interactive Waves</h1>\n  </div>\n</div>"
    },
    {
      "name": "SpiralAnimation",
      "path": "backgrounds/SpiralAnimation.tsx",
      "best_for": ["tech startup", "ai", "crypto", "gaming", "creative agency"],
      "description": "A complex 3D particle system drawn on an HTML5 canvas. It visualizes a massive spiral galaxy of stars forming and spinning. Ideal for high-end tech or sci-fi themes.",
      "usage_example": "<div className=\"relative w-full h-[600px]\">\n  <SpiralAnimation />\n  <div className=\"absolute inset-0 flex items-center justify-center pointer-events-none\">\n    <h1 className=\"text-5xl font-bold text-white text-center\">The Cosmos<br/><span className=\"text-2xl font-normal text-white/60\">Awaits</span></h1>\n  </div>\n</div>"
    },
    {
      "name": "BGPattern",
      "path": "backgrounds/BGPattern.tsx",
      "best_for": [
        "corporate saas",
        "minimalist",
        "developer tool",
        "bento grids",
        "clean"
      ],
      "description": "A high-performance, purely CSS-based background pattern generator. Supports dots, grids, stripes, and checkboards with automatic edge-fading masks.",
      "usage_example": "<div className=\"relative w-full h-[500px] flex items-center justify-center bg-slate-50 dark:bg-slate-950 overflow-hidden\">\n  <BGPattern variant=\"dots\" mask=\"fade-edges\" size={20} fill=\"rgba(100, 116, 139, 0.2)\" />\n  <h1 className=\"relative z-10 text-4xl font-bold text-slate-900 dark:text-white\">CSS Patterns</h1>\n</div>"
    },
    {
      "name": "EtherealShadow",
      "path": "backgrounds/EtherealShadow.tsx",
      "best_for": [
        "dark luxury",
        "creative agency",
        "minimalist",
        "editorial",
        "wellness"
      ],
      "description": "A highly atmospheric, liquid shadow effect driven by advanced SVG displacement filters. Extremely subtle and elegant.",
      "usage_example": "<div className=\"relative w-full h-[600px] bg-slate-50 dark:bg-slate-950 overflow-hidden\">\n  <EtherealShadow color=\"rgba(99, 102, 241, 0.4)\" animation={{ scale: 50, speed: 40 }} noise={{ opacity: 0.1, scale: 1 }} className=\"absolute inset-0\">\n    <h1 className=\"text-5xl font-serif text-slate-900 dark:text-white\">Ethereal Depth</h1>\n  </EtherealShadow>\n</div>"
    },
    {
      "name": "FlickeringGrid",
      "path": "backgrounds/FlickeringGrid.tsx",
      "best_for": [
        "cyberpunk",
        "developer tool",
        "crypto",
        "tech startup",
        "ai"
      ],
      "description": "A highly performant HTML5 canvas background rendering a dense grid of squares that flicker smoothly. Respects IntersectionObserver to pause when off-screen.",
      "usage_example": "<div className=\"relative w-full h-[500px] flex items-center justify-center overflow-hidden bg-slate-950\">\n  <FlickeringGrid squareSize={4} gridGap={6} color=\"#10B981\" maxOpacity={0.4} flickerChance={0.1} />\n  <h1 className=\"relative z-10 text-5xl font-bold text-white tracking-tight\">System Online</h1>\n</div>"
    },
    {
      "name": "SmokeBackground",
      "path": "backgrounds/SmokeBackground.tsx",
      "best_for": ["dark luxury", "gaming", "creative agency", "tech startup"],
      "description": "A dark, atmospheric WebGL2 volumetric smoke animation. Highly performant and accepts a custom hex color for the smoke tint.",
      "usage_example": "<div className=\"relative w-full h-[600px]\">\n  <SmokeBackground smokeColor=\"#7C3AED\">\n    <h1 className=\"text-5xl font-bold text-white\">Mystic Smoke</h1>\n  </SmokeBackground>\n</div>"
    },
    {
      "name": "GradientBackground",
      "path": "backgrounds/GradientBackground.tsx",
      "best_for": [
        "corporate saas",
        "minimalist",
        "playful",
        "creative agency"
      ],
      "description": "A smooth, continuously animating linear gradient background using Framer Motion. Highly customizable and lightweight.",
      "usage_example": "<div className=\"w-full h-[400px]\">\n  <GradientBackground overlay={true} overlayOpacity={0.2}>\n    <h1 className=\"text-5xl font-bold text-white\">Smooth Gradients</h1>\n  </GradientBackground>\n</div>"
    },
    {
      "name": "FallingPattern",
      "path": "backgrounds/FallingPattern.tsx",
      "best_for": [
        "tech startup",
        "creative agency",
        "modern saas",
        "minimalist"
      ],
      "description": "A highly mesmerizing, continuous falling particle pattern achieved entirely through CSS radial gradients and Framer Motion.",
      "usage_example": "<div className=\"relative w-full h-[500px] overflow-hidden\">\n  <FallingPattern color=\"rgba(99,102,241,0.5)\" backgroundColor=\"#020617\" density={1.5} className=\"absolute inset-0\" />\n  <div className=\"relative z-10 flex h-full items-center justify-center\">\n    <h1 className=\"text-4xl font-bold text-white\">Falling Data</h1>\n  </div>\n</div>"
    },
    {
      "name": "GradientDots",
      "path": "backgrounds/GradientDots.tsx",
      "best_for": ["playful", "gaming", "creative agency", "tech startup"],
      "description": "A mesmerizing animated background of colorful, shifting gradients masked by a strict hexagonal dot grid. Pure CSS and Framer Motion.",
      "usage_example": "<div className=\"relative w-full h-[500px] overflow-hidden\">\n  <GradientDots dotSize={8} spacing={12} backgroundColor=\"#0a0a0a\" />\n  <div className=\"relative z-10 flex h-full items-center justify-center\">\n    <h1 className=\"text-5xl font-black text-white mix-blend-difference\">Gradient Dots</h1>\n  </div>\n</div>"
    },
    {
      "name": "BlueprintShader",
      "path": "backgrounds/BlueprintShader.tsx",
      "best_for": [
        "cyberpunk",
        "developer tool",
        "crypto",
        "tech startup",
        "ai"
      ],
      "description": "An incredibly advanced WebGL2 shader rendering a deep-navy technical blueprint. Features moving grids, dithered shading, ASCII glyph overlays, and cinematic vignette.",
      "usage_example": "<div className=\"relative w-full h-[600px]\">\n  <BlueprintShader>\n    <h1 className=\"text-5xl font-mono text-white\">System Architecture</h1>\n  </BlueprintShader>\n</div>"
    },
    {
      "name": "DottedSurface",
      "path": "backgrounds/DottedSurface.tsx",
      "best_for": ["tech startup", "ai", "corporate saas", "minimalist"],
      "description": "An elegant, continuous 3D wave of floating dots rendered via Three.js. Automatically adapts its color for light/dark mode.",
      "usage_example": "<div className=\"relative w-full h-[600px] flex items-center justify-center bg-slate-50 dark:bg-slate-950 overflow-hidden\">\n  <DottedSurface />\n  <h1 className=\"relative z-10 text-5xl font-bold text-slate-900 dark:text-white\">Data Topology</h1>\n</div>"
    },
    {
      "name": "NeonMaze",
      "path": "backgrounds/NeonMaze.tsx",
      "best_for": ["cyberpunk", "gaming", "crypto", "tech startup"],
      "description": "An isometric, highly animated HTML5 canvas background depicting a neon, undulating maze of blocks. Excellent for retro, cyberpunk, or gaming aesthetics.",
      "usage_example": "<div className=\"relative w-full h-[500px]\">\n  <NeonMaze>\n    <h1 className=\"text-5xl font-black text-white bg-black/50 px-6 py-2 rounded-lg backdrop-blur-sm\">CYBER MAZE</h1>\n  </NeonMaze>\n</div>"
    }
  ],

  "hero": [
    {
      "name": "HeroGeometric",
      "path": "hero/HeroGeometric.tsx",
      "best_for": [
        "design collective",
        "creative agency",
        "modern saas",
        "dark luxury"
      ],
      "description": "A dark, elegant hero section with floating, slow-moving geometric glass shapes.",
      "usage_example": "<HeroGeometric badge=\"Design Collective\" title1=\"Elevate Your Vision\" title2=\"Crafting Exceptions\" />"
    },
    {
      "name": "BackgroundCircles",
      "path": "hero/BackgroundCircles.tsx",
      "best_for": [
        "tech startup",
        "ai",
        "modern saas",
        "minimalist",
        "data dashboard"
      ],
      "description": "A full-screen hero section featuring animated, rotating, glowing gradient circles with an underlying grid mask. Highly customizable via the 'variant' prop.",
      "usage_example": "<BackgroundCircles title=\"Welcome to the Future\" description=\"The ultimate AI tool for modern teams.\" variant=\"primary\" />"
    },
    {
      "name": "BackgroundPaths",
      "path": "hero/BackgroundPaths.tsx",
      "best_for": ["minimalist", "corporate saas", "editorial", "b2b service"],
      "description": "A clean, high-contrast hero section featuring animated flowing SVG paths in the background and a spring-animated letter-by-letter text reveal.",
      "usage_example": "<BackgroundPaths title=\"Crafting Digital Excellence\" />"
    },
    {
      "name": "HeroHighlight",
      "path": "hero/HeroHighlight.tsx",
      "best_for": ["developer tool", "corporate saas", "tech startup", "ai"],
      "description": "A hero background with a dot-matrix pattern that reveals a glowing accent color under the mouse cursor. Includes a <Highlight> component to animate a gradient background behind text.",
      "usage_example": "import { HeroHighlight, Highlight } from '../ui/HeroHighlight';\n\n<HeroHighlight>\n  <h1 className=\"text-4xl font-bold text-black dark:text-white\">\n    Building the future, <Highlight>one pixel at a time.</Highlight>\n  </h1>\n</HeroHighlight>"
    },
    {
      "name": "HeroSection",
      "path": "hero/HeroSection.tsx",
      "best_for": [
        "corporate saas",
        "tech startup",
        "creative agency",
        "ecommerce"
      ],
      "description": "A complete, production-ready SaaS Hero Section. Includes a scroll-reactive fixed navigation bar, split hero text with primary and ghost CTAs, an embedded video showcase, and a responsive logo trust strip. Zero external dependencies.",
      "usage_example": "<HeroSection brandName=\"Elysium\" logoHref=\"/\" headline=\"Timeless Craft, Modern Precision\" description=\"Swiss-made mechanical watches for those who measure success in decades, not seasons.\" primaryCtaLabel=\"Explore the Collection\" primaryCtaHref=\"/collection\" secondaryCtaLabel=\"Book a Fitting\" secondaryCtaHref=\"/appointments\" showHeader={false} showLogoStrip={false} />"
    },
    {
      "name": "HeroWithVideo",
      "path": "hero/HeroWithVideo.tsx",
      "best_for": ["corporate saas", "tech startup", "portfolio"],
      "description": "A clean, modern hero section featuring a fully responsive navigation bar with a mobile drawer, a theme toggle, an email capture form, and a massive rounded video container that plays on command.",
      "usage_example": "<HeroWithVideo brandName=\"Nexus\" heroTitle=\"Innovation Meets Simplicity\" heroDescription=\"Discover cutting-edge solutions designed for the modern digital landscape. We build tools that empower creators and developers to ship faster.\" navAboutHref=\"/about\" navBlogHref=\"/blog\" loginHref=\"/login\" ctaLabel=\"Start Free Trial\" showNavbar={false} />"
    },
    {
      "name": "VideoScrollHero",
      "path": "hero/VideoScrollHero.tsx",
      "best_for": ["portfolio", "creative agency", "ecommerce", "media"],
      "description": "A scroll-linked hero section. Features a sticky video container that smoothly scales up from a small card to full size as the user scrolls down the page.",
      "usage_example": "<VideoScrollHero title=\"Your Brand Name\" subtitle=\"Scroll to discover our story\" videoSrc=\"/assets/hero-video.mp4\" />"
    },
    {
      "name": "VHSHero",
      "path": "hero/VHSHero.tsx",
      "best_for": ["cyberpunk", "gaming", "music", "retro-futurism"],
      "description": "An incredibly immersive, high-impact WebGL hero section. Features a fully custom Three.js distortion shader, interactive noise particles, RGB split glitch text, and aggressive GSAP entrance animations.",
      "usage_example": "<VHSHero title=\"CYBER_CORE\" badge=\"SYSTEM ONLINE\" subtitle={<>{'>'} NEURAL.LINK.ACTIVE {'<'}<br/>{'>'} DATA.STREAM.SYNC {'<'}</>} ctaText=\"> INITIATE_HACK <\" />"
    }
  ],

  "text_effects": [
    {
      "name": "BlurText",
      "path": "text_effects/Blur Text.tsx",
      "best_for": ["minimalist", "editorial", "corporate saas", "fashion"],
      "description": "Animates text in word-by-word with a smooth cinematic blur effect triggered on scroll.",
      "usage_example": "<BlurText text=\"Designing the Future\" delay={50} direction=\"top\" />"
    },
    {
      "name": "GradientText",
      "path": "text_effects/GradientText.tsx",
      "best_for": ["saas", "tech startup", "playful", "crypto"],
      "description": "Text with a continuously flowing animated gradient background. Great for highlighting specific keywords.",
      "usage_example": "<GradientText colors={['#5227FF', '#FF9FFC', '#B497CF']} animationSpeed={8}>Supercharge your workflow</GradientText>"
    },
    {
      "name": "ScrollFloat",
      "path": "text_effects/Scroll Float.tsx",
      "best_for": ["editorial", "portfolio", "creative agency", "fashion"],
      "description": "GSAP ScrollTrigger effect where characters float up and lock into place as the user scrolls down the page.",
      "usage_example": "<ScrollFloat animationDuration={1} stagger={0.03}>Creative Visionary</ScrollFloat>"
    },
    {
      "name": "ShinyText",
      "path": "text_effects/Shiny Text.tsx",
      "best_for": ["dark luxury", "crypto", "premium", "saas"],
      "description": "A sleek, metallic shine that repeatedly sweeps across the text. Perfect for premium feature highlights.",
      "usage_example": "<ShinyText text=\"Premium Quality\" speed={3} color=\"#b5b5b5\" shineColor=\"#ffffff\" />"
    },
    {
      "name": "ShuffleText",
      "path": "text_effects/Shuffle.tsx",
      "best_for": ["cyberpunk", "developer tool", "crypto", "neo-brutalism"],
      "description": "A GSAP text effect where letters rapidly scramble, shuffle, and lock into the final string. Hacker aesthetic.",
      "usage_example": "<ShuffleText text=\"SYSTEM INITIALIZED\" shuffleTimes={3} scrambleCharset=\"!@#$%^&*()\" />"
    },
    {
      "name": "SplitText",
      "path": "text_effects/Split Text.tsx",
      "best_for": ["editorial", "minimalist", "portfolio", "architecture"],
      "description": "Advanced GSAP SplitText integration that reveals text character-by-character or line-by-line smoothly on scroll.",
      "usage_example": "<SplitText text=\"Elegant Typography\" splitType=\"chars\" delay={50} />"
    },
    {
      "name": "TextType",
      "path": "text_effects/Text Type.tsx",
      "best_for": ["developer tool", "ai", "terminal", "micro saas"],
      "description": "A realistic typewriter effect with a blinking cursor. Can loop through an array of sentences.",
      "usage_example": "<TextType text={[\"npm run dev\", \"npm run build\", \"npm run deploy\"]} typingSpeed={50} loop={true} />"
    },
    {
      "name": "ParticleText",
      "path": "text_effects/ParticleText.tsx",
      "best_for": ["tech startup", "ai", "portfolio", "cyberpunk"],
      "description": "An interactive HTML5 canvas effect where colorful particles fly in to form words. The user can interact with the particles via right-click to disperse them.",
      "usage_example": "<div className=\"w-full h-[400px] bg-neutral-950\">\n  <ParticleText words={[\"CRAFTED\", \"IN\", \"SWITZERLAND\"]} />\n</div>"
    },
    {
      "name": "UnderlineAnimation",
      "path": "text_effects/UnderlineAnimation.tsx",
      "best_for": ["minimalist", "editorial", "portfolio", "corporate saas"],
      "description": "A collection of highly polished, interactive text underline animations including center-out, comes-in-goes-out, and goes-out-comes-in. Perfect for premium navigation links.",
      "usage_example": "<div className=\"flex gap-4\"><CenterUnderline label=\"Home\" /><ComesInGoesOutUnderline label=\"About\" /></div>"
    }
  ],

  "effects": [
    {
      "name": "GooeyFilter",
      "path": "effects/GooeyFilter.tsx",
      "best_for": ["playful", "organic", "creative"],
      "description": "An invisible SVG filter that makes overlapping elements merge together like liquid goo.",
      "usage_example": "<>\n  <GooeyFilter id=\"goo-effect\" strength={10} />\n  {/* Add style={{ filter: 'url(#goo-effect)' }} to the parent container of the items you want to be gooey */}\n</>"
    },
    {
      "name": "Glow",
      "path": "effects/Glow.tsx",
      "best_for": [
        "dark luxury",
        "corporate saas",
        "minimalist",
        "tech startup"
      ],
      "description": "A subtle, elegant radial background glow effect. Used to highlight hero sections or feature cards.",
      "usage_example": "<div className=\"relative w-full overflow-hidden\">\n <Glow variant=\"top\" />\n <div className=\"relative z-10\">Content over the glow</div>\n</div>"
    },
    {
      "name": "ShineBorder",
      "path": "effects/ShineBorder.tsx",
      "best_for": ["corporate saas", "tech startup", "ai", "crypto"],
      "description": "An animated background border effect that continuously shines around the container's perimeter. Great for highlighting pricing cards or featured elements.",
      "usage_example": "<div className=\"flex items-center justify-center p-8\">\n  <ShineBorder color={[\"#A07CFE\", \"#FE8FB5\", \"#FFBE7B\"]} duration={8} borderWidth={2} borderRadius={12}>\n    <div className=\"w-full h-full flex flex-col items-center justify-center p-8 bg-white dark:bg-black rounded-[12px]\">\n      <h2 className=\"text-2xl font-bold dark:text-white\">Pro Plan</h2>\n      <p className=\"dark:text-neutral-400 mt-2\">Experience full power</p>\n    </div>\n  </ShineBorder>\n</div>"
    },
    {
      "name": "BorderBeam",
      "path": "effects/BorderBeam.tsx",
      "best_for": ["corporate saas", "tech startup", "ai", "crypto", "gaming"],
      "description": "An elegant, high-performance CSS border effect where a glowing beam traces the perimeter of any container. It perfectly inherits the container's border radius.",
      "usage_example": "<div className=\"relative w-full max-w-sm p-12 bg-white dark:bg-neutral-900 rounded-2xl shadow-xl flex items-center justify-center\">\n  <BorderBeam size={250} duration={12} delay={0} />\n  <h2 className=\"text-2xl font-bold dark:text-white\">Premium Card</h2>\n</div>"
    },
    {
      "name": "Magnetic",
      "path": "effects/Magnetic.tsx",
      "best_for": [
        "portfolio",
        "creative agency",
        "interactive buttons",
        "neo-brutalism"
      ],
      "description": "A physics-based interaction wrapper that pulls its children toward the mouse cursor using spring animations. Perfect for highly tactile buttons or floating elements.",
      "usage_example": "<Magnetic intensity={0.8} actionArea=\"global\"><button className=\"px-6 py-3 bg-black text-white rounded-full\">Hover near me</button></Magnetic>"
    }
  ],

  "media": [
    {
      "name": "VideoPlayer",
      "path": "media/VideoPlayer.tsx",
      "best_for": [
        "portfolio",
        "corporate saas",
        "creative agency",
        "tech startup",
        "entertainment"
      ],
      "description": "A beautiful, custom-styled HTML5 video player overlay using Framer Motion. Features a floating glassmorphic control bar that reveals on hover, custom sliders, playback speed controls, and volume toggles.",
      "usage_example": "<div className=\"w-full p-8\">\n  <VideoPlayer src=\"https://www.w3schools.com/html/mov_bbb.mp4\" />\n</div>"
    },
    {
      "name": "HeroVideoDialog",
      "path": "media/HeroVideoDialog.tsx",
      "best_for": [
        "corporate saas",
        "tech startup",
        "portfolio",
        "creative agency"
      ],
      "description": "A beautiful video thumbnail component that reveals an interactive play button on hover. Clicking it smoothly morphs the video into a full-screen, backdrop-blurred iframe modal.",
      "usage_example": "<div className=\"w-full max-w-4xl mx-auto p-4\">\n  <HeroVideoDialog \n    videoSrc=\"https://www.youtube.com/embed/qh3NGpYRG3I?autoplay=1\" \n    thumbnailSrc=\"https://images.unsplash.com/photo-1611162617474-5b21e879e113?q=80&w=1920&auto=format&fit=crop\" \n    animationStyle=\"from-center\" \n  />\n</div>"
    },
    {
      "name": "DynamicFrameLayout",
      "path": "media/DynamicFrameLayout.tsx",
      "best_for": ["portfolio", "creative agency", "entertainment", "fashion"],
      "description": "A dynamic 3x3 CSS grid layout that expands a specific video cell significantly when hovered. Videos automatically play on hover and pause on leave.",
      "usage_example": "import { DynamicFrameLayout, Frame } from '../ui/DynamicFrameLayout';\n\nconst sampleFrames: Frame[] = [\n  { id: 1, video: 'https://www.w3schools.com/html/mov_bbb.mp4', defaultPos: { x: 0, y: 0, w: 4, h: 4 } },\n  { id: 2, video: 'https://www.w3schools.com/html/mov_bbb.mp4', defaultPos: { x: 4, y: 0, w: 4, h: 4 } },\n  { id: 3, video: 'https://www.w3schools.com/html/mov_bbb.mp4', defaultPos: { x: 8, y: 0, w: 4, h: 4 } },\n  { id: 4, video: 'https://www.w3schools.com/html/mov_bbb.mp4', defaultPos: { x: 0, y: 4, w: 4, h: 4 } },\n  { id: 5, video: 'https://www.w3schools.com/html/mov_bbb.mp4', defaultPos: { x: 4, y: 4, w: 4, h: 4 } },\n  { id: 6, video: 'https://www.w3schools.com/html/mov_bbb.mp4', defaultPos: { x: 8, y: 4, w: 4, h: 4 } },\n  { id: 7, video: 'https://www.w3schools.com/html/mov_bbb.mp4', defaultPos: { x: 0, y: 8, w: 4, h: 4 } },\n  { id: 8, video: 'https://www.w3schools.com/html/mov_bbb.mp4', defaultPos: { x: 4, y: 8, w: 4, h: 4 } },\n  { id: 9, video: 'https://www.w3schools.com/html/mov_bbb.mp4', defaultPos: { x: 8, y: 8, w: 4, h: 4 } }\n];\n\nexport default function App() {\n  return (\n    <div className=\"w-full h-screen p-8 bg-black\">\n      <DynamicFrameLayout frames={sampleFrames} showFrames={true} gapSize={8} />\n    </div>\n  );\n}"
    },
    {
      "name": "HeroVideo",
      "path": "media/HeroVideo.tsx",
      "best_for": ["tech startup", "portfolio", "creative agency", "ecommerce"],
      "description": "A scroll-linked layout component. A small, rounded video at the top of the screen gradually expands, un-clips, and straightens out to fill the viewport as the user scrolls down.",
      "usage_example": "import { ContainerScroll, ContainerStagger, ContainerAnimated, ContainerInset } from '../ui/HeroVideo';\n\nexport default function App() {\n  return (\n    <ContainerScroll className=\"bg-black\">\n      <div className=\"sticky top-0 w-full flex flex-col items-center pt-24 text-center z-10\">\n        <ContainerStagger>\n          <ContainerAnimated animation=\"blur\">\n            <h1 className=\"text-white text-6xl font-bold\">Scroll Down</h1>\n          </ContainerAnimated>\n        </ContainerStagger>\n      </div>\n      <ContainerInset className=\"w-full h-screen absolute top-0 left-0\">\n        <video src=\"https://www.w3schools.com/html/mov_bbb.mp4\" autoPlay loop muted playsInline className=\"w-full h-full object-cover\" />\n      </ContainerInset>\n    </ContainerScroll>\n  );\n}"
    },
    {
      "name": "ScrollExpandMedia",
      "path": "media/ScrollExpandMedia.tsx",
      "best_for": ["portfolio", "creative agency", "ecommerce", "media"],
      "description": "A scroll-linked media expansion component. As the user scrolls, a central media element (video or image) aggressively expands to fill the screen while the background fades out, locking the user until the transition is complete.",
      "usage_example": "<ScrollExpandMedia mediaType=\"video\" mediaSrc=\"https://www.w3schools.com/html/mov_bbb.mp4\" bgImageSrc=\"https://images.unsplash.com/photo-1611162617474-5b21e879e113?q=80&w=1920&auto=format&fit=crop\" title=\"Scroll To Expand\" date=\"2024\" scrollToExpand=\"Keep Scrolling\" textBlend={true}>\n  <div className=\"text-white text-4xl font-bold text-center py-20\">Welcome to the inner content!</div>\n</ScrollExpandMedia>"
    },
    {
      "name": "VideoThumbnailPlayer",
      "path": "media/VideoThumbnailPlayer.tsx",
      "best_for": ["corporate saas", "tech startup", "portfolio"],
      "description": "A responsive, card-style video thumbnail with title and description overlays. Clicking the card opens a full-screen, framer-motion animated iframe modal.",
      "usage_example": "<div className=\"w-full max-w-xl mx-auto p-4\">\n  <VideoThumbnailPlayer \n    title=\"Product Demo\"\n    description=\"Watch how to 10x your workflow in just 2 minutes.\"\n    thumbnailUrl=\"https://images.unsplash.com/photo-1611162617474-5b21e879e113?q=80&w=1920&auto=format&fit=crop\" \n    videoUrl=\"https://www.youtube.com/embed/qh3NGpYRG3I?autoplay=1\"\n  />\n</div>"
    },
    {
      "name": "VideoPlayerPro",
      "path": "media/VideoPlayerPro.tsx",
      "best_for": [
        "portfolio",
        "corporate saas",
        "media",
        "entertainment",
        "education"
      ],
      "description": "A premium, standalone custom video player featuring an animated floating glassmorphic control bar. Includes playback speed settings, volume slider overlays, and fullscreen support. Zero dependencies outside of framer-motion.",
      "usage_example": "<div className=\"w-full max-w-4xl p-8\">\n  <VideoPlayerPro src=\"/assets/product-tour.mp4\" />\n</div>"
    },
    {
      "name": "VideoModal",
      "path": "media/VideoModal.tsx",
      "best_for": [
        "tech startup",
        "corporate saas",
        "portfolio",
        "creative agency"
      ],
      "description": "A sophisticated suite of compound components for building highly customized video modals. Features native framer-motion reveals, auto-hiding play buttons via CSS groups, and extensive layout flexibility.",
      "usage_example": "<VideoModal>\n  <VideoModalTrigger><button>Play Video</button></VideoModalTrigger>\n  <VideoModalContent>\n    <VideoModalTitle>Feature Deep Dive</VideoModalTitle>\n    <VideoPlayer>\n      <VideoPreview><img src=\"/poster.jpg\" /></VideoPreview>\n      <VideoPlayButton><PlayIcon /></VideoPlayButton>\n      <VideoModalVideo><iframe src=\"https://youtube...\" /></VideoModalVideo>\n    </VideoPlayer>\n  </VideoModalContent>\n</VideoModal>"
    }
  ],

  "modals": [
    {
      "name": "MorphingDialog",
      "path": "modals/MorphingDialog.tsx",
      "best_for": ["portfolio", "creative agency", "ecommerce", "saas"],
      "description": "A highly sophisticated compound component that uses Framer Motion layout animations to smoothly morph a trigger card/button into a full-screen modal.",
      "usage_example": "<MorphingDialog>\n  <MorphingDialogTrigger className=\"bg-blue-500 text-white p-4 rounded-xl\">\n    <MorphingDialogTitle>Open Details</MorphingDialogTitle>\n  </MorphingDialogTrigger>\n  <MorphingDialogContainer>\n    <MorphingDialogContent className=\"bg-white dark:bg-neutral-900 p-8 rounded-3xl shadow-2xl w-full max-w-md\">\n      <MorphingDialogTitle className=\"text-2xl font-bold mb-4 dark:text-white\">Expanded State</MorphingDialogTitle>\n      <MorphingDialogDescription className=\"text-neutral-500\">\n        This modal smoothly animated from the trigger button using layoutId. Press Esc or click outside to close.\n      </MorphingDialogDescription>\n      <MorphingDialogClose className=\"text-neutral-500 hover:text-black dark:hover:text-white transition-colors\" />\n    </MorphingDialogContent>\n  </MorphingDialogContainer>\n</MorphingDialog>"
    },
    {
      "name": "ThumbnailButton",
      "path": "media/ThumbnailButton.tsx",
      "best_for": ["corporate saas", "tech startup", "portfolio"],
      "description": "A compact button containing a tiny video thumbnail. When clicked, it expands via Framer Motion's layout animations into a full-screen video player. Supports native videos and YouTube.",
      "usage_example": "<div className=\"flex justify-center p-8\">\n  <ThumbnailButton youtubeId=\"qh3NGpYRG3I\" title=\"Watch the Trailer\" />\n</div>"
    },
    {
      "name": "PublishDialog",
      "path": "modals/PublishDialog.tsx",
      "best_for": ["corporate saas", "developer tool", "dashboard", "b2b"],
      "description": "A clean, highly accessible confirmation dialog box built with Framer Motion. Features a prominent icon indicator and clean cancel/action buttons.",
      "usage_example": "<PublishDialog title=\"Publish to production?\" description=\"These changes will be visible to all users immediately.\" />"
    },
    {
      "name": "AnimatedDialog",
      "path": "modals/AnimatedDialog.tsx",
      "best_for": ["dashboard", "corporate saas", "settings", "forms"],
      "description": "A fully customizable, zero-dependency, Framer Motion powered compound dialog component. A perfect drop-in replacement for Radix/Shadcn dialogs with smooth spring animations.",
      "usage_example": "<Dialog><DialogTrigger className=\"px-4 py-2 bg-black text-white rounded-md\">Open</DialogTrigger><DialogContent><DialogHeader><DialogTitle>Edit Profile</DialogTitle><DialogDescription>Make changes to your profile here.</DialogDescription></DialogHeader></DialogContent></Dialog>"
    }
  ],

  "elements": [
    {
      "name": "Timestamp",
      "path": "elements/Timestamp.tsx",
      "best_for": ["entertainment", "corporate saas", "media"],
      "description": "A small, cleanly formatted timestamp badge with tabular numbers to prevent jitter. Commonly used over video thumbnails or audio players.",
      "usage_example": "<div className=\"relative w-64 h-36 bg-slate-200 dark:bg-slate-800 rounded-lg overflow-hidden\">\n  <img src=\"https://images.unsplash.com/photo-1611162617474-5b21e879e113?q=80&w=640&auto=format&fit=crop\" className=\"w-full h-full object-cover\" />\n  <Timestamp seconds={3725} className=\"absolute bottom-2 right-2\" />\n</div>"
    },
    {
      "name": "SocialLinks",
      "path": "elements/SocialLinks.tsx",
      "best_for": ["portfolio", "creative agency", "footers", "about"],
      "description": "An interactive list of text links. On hover, it smoothly reveals a floating, slightly rotated image thumbnail associated with the link.",
      "usage_example": "<SocialLinks socials={[{ name: 'Twitter', image: '/assets/twitter-bg.jpg' }]} />"
    },
    {
      "name": "Counter",
      "path": "elements/Counter.tsx",
      "best_for": ["dashboard", "ecommerce"],
      "description": "A simple, styled increment/decrement counter element.",
      "usage_example": "<Counter title=\"Adjust Quantity\" initialValue={1} />"
    },
    {
      "name": "AnimatedLink",
      "path": "elements/AnimatedLink.tsx",
      "best_for": ["editorial", "portfolio", "minimalist", "creative agency"],
      "description": "A pure Tailwind CSS animated link that features a smooth underline reveal and a draw-in arrow icon on hover. Zero external animation dependencies.",
      "usage_example": "<AnimatedLink href=\"/work\" variant=\"left\">View our work</AnimatedLink>"
    },
    {
      "name": "TopBanner",
      "path": "elements/TopBanner.tsx",
      "best_for": ["marketing", "ecommerce", "corporate saas", "tech startup"],
      "description": "A sticky top-level announcement banner. Includes a localStorage persistence mechanism so users don't see it again after dismissing it, and a highly animated multi-gradient 'rainbow' style option.",
      "usage_example": "<TopBanner id=\"promo-banner-1\" variant=\"rainbow\" message={<>🎉 Big sale happening now! <a href='#' className='underline'>Shop now</a></>} />"
    }
  ],

  "cards": [
    {
      "name": "InfoCard",
      "path": "cards/InfoCard.tsx",
      "best_for": ["ecommerce", "portfolio", "creative agency", "saas"],
      "description": "A highly interactive, stackable information card. On hover, it expands smoothly and spreads out multiple stacked images (or videos) like a deck of cards. Includes built-in dismiss states.",
      "usage_example": "<div className=\"w-full max-w-sm p-4\">\n  <InfoCard>\n    <InfoCardContent>\n      <InfoCardTitle>New Collection</InfoCardTitle>\n      <InfoCardDescription>Hover to view items</InfoCardDescription>\n    </InfoCardContent>\n    <InfoCardMedia \n      media={[\n        { src: 'https://images.unsplash.com/photo-1523275335684-37898b6baf30?w=400&h=300&fit=crop', alt: 'Watch' },\n        { src: 'https://images.unsplash.com/photo-1524592094714-0f0654e20314?w=400&h=300&fit=crop', alt: 'Clock' }\n      ]}\n    />\n    <InfoCardFooter>\n      <InfoCardDismiss>Dismiss</InfoCardDismiss>\n      <InfoCardAction>View All</InfoCardAction>\n    </InfoCardFooter>\n  </InfoCard>\n</div>"
    },
    {
      "name": "AIGenCard",
      "path": "cards/AIGenCard.tsx",
      "best_for": ["ai", "tech startup", "corporate saas", "portfolio"],
      "description": "A highly complex, fully-featured AI Generation interface card. Includes multi-modal tabs (Image/Video/Avatar), advanced settings, a prompt generation simulator with progress bars, and a searchable generation history list. Zero external dependencies.",
      "usage_example": "<div className=\"flex w-full min-h-screen items-center justify-center p-8 bg-zinc-50 dark:bg-zinc-900\">\n  <AIGenCard />\n</div>"
    },
    {
      "name": "HoverPlayCard",
      "path": "cards/HoverPlayCard.tsx",
      "best_for": ["portfolio", "ecommerce", "creative agency", "media"],
      "description": "A structural card that automatically plays a muted video on hover. Clicking the card unmutes the video and takes full control of playback. Perfect for gallery grids and product listings.",
      "usage_example": "<HoverPlayCard src=\"/assets/product-video.mp4\" poster=\"/assets/poster.jpg\" className=\"w-full max-w-sm aspect-video\" />"
    },
    {
      "name": "VideoUploadCard",
      "path": "cards/VideoUploadCard.tsx",
      "best_for": [
        "corporate saas",
        "tech startup",
        "portfolio",
        "creator economy"
      ],
      "description": "An interactive video upload card with drag-and-drop support. Features a dramatic 'vending machine' drop animation when the video preview appears.",
      "usage_example": "<VideoUploadCard title=\"Upload Demo\" description=\"Drag and drop your video file here.\" />"
    },
    {
      "name": "VideoGeneratorCard",
      "path": "cards/VideoGeneratorCard.tsx",
      "best_for": ["ai", "tech startup", "corporate saas", "creator economy"],
      "description": "A beautiful prompt input card designed for AI video generation. Features an image storyboard preview strip, media type toggles, and a modern glassmorphic blur-backdrop aesthetic.",
      "usage_example": "<VideoGeneratorCard storyboardImages={[{src: '/assets/image1.jpg', alt: 'Frame 1'}]} initialPrompt=\"Animate these frames...\" />"
    },
    {
      "name": "AnimatedBanner",
      "path": "cards/AnimatedBanner.tsx",
      "best_for": ["ecommerce", "events", "marketing", "dashboard"],
      "description": "A dynamic promotional banner card featuring an autoplaying video background, customizable gradient overlay, and a real-time countdown timer.",
      "usage_example": "<AnimatedBanner title=\"Cyber Monday Sale\" subtitle=\"Up to 50% off everything\" videoSrc=\"/assets/promo.mp4\" deadline={new Date(Date.now() + 86400000)} />"
    }
  ],

  "sections": [
    {
      "name": "FeaturedDemoGrid",
      "path": "sections/FeaturedDemoGrid.tsx",
      "best_for": ["corporate saas", "b2b", "developer tool", "tech startup"],
      "description": "A robust Bento-box style feature section. Features a large video/image player alongside smaller feature cards and an integration logo grid.",
      "usage_example": "<FeaturedDemoGrid title={<>Supercharge your <br/> sales workflow.</>} videoSrc=\"/assets/demo.mp4\" />"
    },
    {
      "name": "WorkspaceWelcome",
      "path": "sections/WorkspaceWelcome.tsx",
      "best_for": [
        "corporate saas",
        "dashboard",
        "productivity tool",
        "creator economy"
      ],
      "description": "An onboarding or dashboard welcome section featuring a personalized greeting, quick action buttons, and a featured video card.",
      "usage_example": "<WorkspaceWelcome userName=\"Alex\" videoTitle=\"Getting Started\" videoDescription=\"Learn the basics in 2 minutes\" videoThumbnail=\"/assets/thumbnail.jpg\" actions={[{ label: 'New Project', icon: <Plus size={16} /> }]} />"
    },
    {
      "name": "OnboardingChecklist",
      "path": "sections/OnboardingChecklist.tsx",
      "best_for": ["corporate saas", "dashboard", "productivity tool"],
      "description": "A responsive onboarding checklist card. Features a split layout with animated list items on the left and a video thumbnail on the right that opens a fully functional, zero-dependency video modal.",
      "usage_example": "<OnboardingChecklist title=\"Get Started\" description=\"Complete these steps to finish setting up your account.\" videoThumbnailUrl=\"/assets/thumbnail.jpg\" videoUrl=\"https://www.youtube.com/embed/dQw4w9WgXcQ?autoplay=1\" items={[{ id: 1, text: 'Create Profile' }]} />"
    },
    {
      "name": "ClippedVideoTab",
      "path": "sections/ClippedVideoTab.tsx",
      "best_for": ["tech startup", "ai", "corporate saas", "developer tool"],
      "description": "A highly stylized, complex section featuring a polygon-clipped video container. Includes floating navigational tabs and a central glassmorphic status card that animates its data based on the selected tab.",
      "usage_example": "<ClippedVideoTab title=\"Our Platforms\" description=\"Crafted interactive UI systems for modern workflows.\" />"
    },
    {
      "name": "AboutGrid",
      "path": "sections/AboutGrid.tsx",
      "best_for": ["corporate saas", "marketing", "b2b", "education"],
      "description": "A clean, modern 3-column grid section with a subtle top-centered radial glow. Perfect for displaying 'About' points, features, or benefits using icon headers.",
      "usage_example": "<AboutGrid title=\"Why choose us?\" subtitle=\"The best features tailored for your business.\" />"
    },
    {
      "name": "DesignAgencyLanding",
      "path": "sections/DesignAgencyLanding.tsx",
      "best_for": [
        "creative agency",
        "portfolio",
        "tech startup",
        "design collective"
      ],
      "description": "An incredibly comprehensive, full-page template. Includes a sticky navbar, gradient hero, bento-grid portfolio, staggered services, testimonials, interactive contact form, and a full footer.",
      "usage_example": "<DesignAgencyLanding />"
    },
    {
      "name": "LinkInBioSection",
      "path": "sections/LinkInBioSection.tsx",
      "best_for": ["portfolio", "personal", "creator economy", "social"],
      "description": "A complete, full-page 'Link in Bio' or personal portfolio section. Features a glowing avatar, social links array, an about card, and a functional contact form with built-in validation and simulated toast notifications.",
      "usage_example": "<LinkInBioSection name=\"Alex\" headline=\"Hi, I'm Alex\" />"
    }
  ],

  "footers": [
    {
      "name": "Footer2",
      "path": "footers/Footer2.tsx",
      "best_for": ["corporate saas", "ecommerce", "b2b", "marketing"],
      "description": "A comprehensive, 5-column footer section featuring a large brand area on the left, multiple navigation link columns, and a standard bottom copyright bar.",
      "usage_example": "<Footer2 tagline=\"Building the future of the web.\" copyright=\"© 2025 YourBrand. All rights reserved.\" />"
    },
    {
      "name": "MinimalFooter",
      "path": "footers/MinimalFooter.tsx",
      "best_for": ["minimalist", "portfolio", "tech startup", "micro saas"],
      "description": "A clean, compact footer. Features circular social icon buttons on the top right, and a uniquely gridded bottom row with right-aligned main and legal links.",
      "usage_example": "<MinimalFooter brandName=\"Acme Corp\" copyright={{ text: \"© 2025 Acme.\" }} />"
    },
    {
      "name": "LargeNameFooter",
      "path": "footers/LargeNameFooter.tsx",
      "best_for": [
        "tech startup",
        "portfolio",
        "neo-brutalism",
        "design collective"
      ],
      "description": "A striking modern footer that features a massive, gradient-clipped brand name text spanning the bottom, alongside clean column navigation and a quick-share social action.",
      "usage_example": "<LargeNameFooter brandName=\"Acme Corp\" largeText=\"ACME\" />"
    },
    {
      "name": "FooterNewsletter",
      "path": "footers/FooterNewsletter.tsx",
      "best_for": ["corporate saas", "ecommerce", "marketing", "blog"],
      "description": "A feature-rich 4-column footer featuring an integrated email newsletter signup form, detailed contact info, and an interactive dark mode toggle.",
      "usage_example": "<FooterNewsletter brandName=\"Acme Corp\" newsletterTitle=\"Join our weekly newsletter.\" quickLinks={[{ label: 'Home', href: '/' }, { label: 'Pricing', href: '/pricing' }, { label: 'Contact', href: '/contact' }]} socialLinks={[{ platform: 'twitter', href: 'https://twitter.com/acmecorp' }, { platform: 'linkedin', href: 'https://linkedin.com/company/acmecorp' }]} legalLinks={[{ label: 'Privacy Policy', href: '/privacy' }, { label: 'Terms of Service', href: '/terms' }]} />"
    },
    {
      "name": "StackedCircularFooter",
      "path": "footers/StackedCircularFooter.tsx",
      "best_for": ["creative agency", "portfolio", "playful", "consumer"],
      "description": "A highly centered, minimalist footer. Features a distinct circular logo container at the top, followed by navigation links, social icons, and an inline newsletter subscription form.",
      "usage_example": "<StackedCircularFooter brandName=\"Acme Corp\" />"
    },
    {
      "name": "IconFooter",
      "path": "footers/IconFooter.tsx",
      "best_for": ["corporate saas", "developer tool", "b2b", "minimalist"],
      "description": "An elegant, clean multi-column footer that renders small Lucide icons next to every navigation link. Social links are cleanly formatted as an inline bulleted list below the brand description.",
      "usage_example": "<IconFooter brand={{ name: 'Stripe', description: 'Financial infrastructure for the internet.', href: '/' }} />"
    },
    {
      "name": "ThemeToggleFooter",
      "path": "footers/ThemeToggleFooter.tsx",
      "best_for": ["minimalist", "portfolio", "micro saas", "developer tool"],
      "description": "An ultra-minimalist, pill-shaped micro footer. It features a built-in light/dark mode toggle and a smooth 'scroll to top' button.",
      "usage_example": "<ThemeToggleFooter />"
    },
    {
      "name": "RadialGlowFooter",
      "path": "footers/RadialGlowFooter.tsx",
      "best_for": ["ai", "crypto", "tech startup", "dark luxury"],
      "description": "An elegant, animated footer with a subtle radial gradient top-glow. Uses Framer Motion to stagger a blur-fade-in effect across its columns as it scrolls into view.",
      "usage_example": "<RadialGlowFooter brandName=\"Nexus AI\" />"
    },
    {
      "name": "Footer7",
      "path": "footers/Footer7.tsx",
      "best_for": ["corporate saas", "tech startup", "b2b", "editorial"],
      "description": "A split-layout footer. Features the brand logo, description, and social icons constrained to a left column, and 3 columns of navigation links stretching across the right.",
      "usage_example": "<Footer7 description=\"Building tools for modern developers.\" />"
    },
    {
      "name": "AnimatedWaveFooter",
      "path": "footers/AnimatedWaveFooter.tsx",
      "best_for": ["tech startup", "portfolio", "creative agency", "music"],
      "description": "An interactive full-screen footer that features a purely mathematical, animated sine-wave visualization constructed from expanding DOM elements.",
      "usage_example": "<AnimatedWaveFooter leftLinks={[{ href: '/about', label: 'About' }, { href: '/careers', label: 'Careers' }, { href: '/privacy', label: 'Privacy' }]} rightLinks={[{ href: 'https://twitter.com/acmecorp', label: 'Twitter' }, { href: 'https://github.com/acmecorp', label: 'GitHub' }]} copyrightText=\"© 2026 Acme Corp. All rights reserved.\" />"
    },
    {
      "name": "StickyFooter",
      "path": "footers/StickyFooter.tsx",
      "best_for": ["portfolio", "creative agency", "editorial"],
      "description": "A sophisticated footer that is revealed as if 'stuck' beneath the page content via clever clip-path tricks. Features staggered entrance animations and a massive gradient title.",
      "usage_example": "<StickyFooter title=\"Ready to talk?\" sections={[{ title: 'Studio', links: [{ label: 'Work', href: '/work' }, { label: 'About', href: '/about' }] }, { title: 'Connect', links: [{ label: 'Contact', href: '/contact' }, { label: 'Careers', href: '/careers' }] }]} />"
    },
    {
      "name": "TapedFooter",
      "path": "footers/TapedFooter.tsx",
      "best_for": ["startup", "neo-brutalism", "playful", "portfolio"],
      "description": "A striking, boxed footer with a brutalist/playful aesthetic featuring SVG 'tape' elements holding the corners to the background. Features categorized columns with 'soon' badge states.",
      "usage_example": "<TapedFooter brandName=\"ActivationLed\" />"
    },
    {
      "name": "Footer4Col",
      "path": "footers/Footer4Col.tsx",
      "best_for": ["corporate saas", "b2b", "marketing", "ecommerce"],
      "description": "A robust 4-column footer featuring a prominent brand description on the left, social links below it, and a multi-column link grid with a pulsing 'Live Chat' indicator and inline contact icons.",
      "usage_example": "<Footer4Col company={{ name: 'Acme Corp', description: 'Building tools that help teams ship faster.' }} contactInfo={[{ icon: Mail, text: 'hello@acme.com', href: 'mailto:hello@acme.com' }, { icon: Phone, text: '+1 (555) 987-6543', href: 'tel:+15559876543' }]} />"
    },
    {
      "name": "FadeInFooter",
      "path": "footers/FadeInFooter.tsx",
      "best_for": ["corporate saas", "minimalist", "tech startup", "portfolio"],
      "description": "A clean, multi-column footer featuring a staggered fade-in Framer Motion entrance animation as it scrolls into view.",
      "usage_example": "<FadeInFooter brandName=\"Acme Corp\" description=\"Empowering businesses with intelligent solutions.\" />"
    },
    {
      "name": "CenteredFooter",
      "path": "footers/CenteredFooter.tsx",
      "best_for": ["minimalist", "portfolio", "micro saas", "personal"],
      "description": "A clean, centrally aligned footer featuring an inline list of text links, social icons, and copyright text.",
      "usage_example": "<CenteredFooter copyright=\"© 2025 Acme Corp. All rights reserved.\" />"
    },
    {
      "name": "Footer1",
      "path": "footers/Footer1.tsx",
      "best_for": ["minimalist", "blog", "portfolio"],
      "description": "A muted, centered footer block with an extensive row of social icons including TikTok and Threads, and a single row of standard navigation links.",
      "usage_example": "<Footer1 copyright=\"© 2025 YourBrand. All rights reserved.\" />"
    },
    {
      "name": "CorporateFooter",
      "path": "footers/CorporateFooter.tsx",
      "best_for": ["corporate saas", "enterprise", "ecommerce", "b2b"],
      "description": "A massive, multi-column mega menu footer designed for enterprise sites with lots of links. Features a dedicated 'About' text block on the left and a dense grid of categorised links on the right.",
      "usage_example": "<CorporateFooter brandName=\"Acme Enterprise\" />"
    },
    {
      "name": "BorderedGridFooter",
      "path": "footers/BorderedGridFooter.tsx",
      "best_for": ["editorial", "minimalist", "portfolio", "creative agency"],
      "description": "An elegant, structurally divided grid footer featuring top-aligned social links with arrows and clean, separated link columns. Uses a subtle radial glow at the top edge.",
      "usage_example": "<BorderedGridFooter brandName=\"Acme Studio\" />"
    },
    {
      "name": "GradientCenteredFooter",
      "path": "footers/GradientCenteredFooter.tsx",
      "best_for": ["ai", "crypto", "web3", "dark luxury"],
      "description": "A striking, deeply colored gradient footer centered around a prominent logo and concise brand description. Excellent for dark-mode or tech-heavy aesthetics.",
      "usage_example": "<GradientCenteredFooter brandName=\"Acme AI\" />"
    },
    {
      "name": "StickyRevealFooter",
      "path": "footers/StickyRevealFooter.tsx",
      "best_for": ["corporate saas", "enterprise", "fintech", "b2b"],
      "description": "A massive, multi-column enterprise footer that reveals itself via a sticky clip-path effect as the user scrolls to the bottom of the page. Features a subtle radial glow background and staggered fade-in animations.",
      "usage_example": "<StickyRevealFooter brandName=\"Acme Finance\" legalLinks={[{ title: 'Privacy Policy', href: '/privacy' }, { title: 'Terms of Service', href: '/terms' }]} />"
    },
    {
      "name": "BoxedMinimalFooter",
      "path": "footers/BoxedMinimalFooter.tsx",
      "best_for": ["b2b", "corporate saas", "minimalist", "tech startup"],
      "description": "A very structured, bordered-box footer constrained to a max-width center column, giving it a technical, precision feel. Features a subtle radial gradient background.",
      "usage_example": "<BoxedMinimalFooter brandName=\"Acme Tech\" description=\"A comprehensive fintech platform.\" />"
    },
    {
      "name": "AppDownloadFooter",
      "path": "footers/AppDownloadFooter.tsx",
      "best_for": ["consumer", "ecommerce", "fitness", "social"],
      "description": "A structured footer specifically designed for consumer-facing apps. Features a multi-column link grid and beautifully styled, built-in App Store and Google Play download badges.",
      "usage_example": "<AppDownloadFooter brandName=\"Acme Fitness\" showAppStore={true} showPlayStore={true} />"
    },
    {
      "name": "FlickeringGridFooter",
      "path": "footers/FlickeringGridFooter.tsx",
      "best_for": ["tech startup", "ai", "crypto", "corporate saas"],
      "description": "An incredibly advanced tech footer. Features compliance badges (SOC2, HIPAA, GDPR), animated arrow hover states on links, and a massive background canvas that renders text using flickering pixel squares.",
      "usage_example": "<FlickeringGridFooter brandName=\"Nexus AI\" flickerTextDesktop=\"Analyze Data Faster.\" />"
    },
    {
      "name": "HoverTextFooter",
      "path": "footers/HoverTextFooter.tsx",
      "best_for": ["portfolio", "creative agency", "tech startup", "web3"],
      "description": "An incredibly interactive, dark-mode focused footer. The brand name takes up the full width in massive text, and hovering over it reveals a stunning, cursor-following multi-color gradient mask.",
      "usage_example": "<HoverTextFooter text=\"ACME STUDIO\" navLinks={[{ label: 'Work', href: '/work' }, { label: 'Studio', href: '/studio' }, { label: 'Contact', href: '/contact' }]} />"
    },
    {
      "name": "FloatingLogoFooter",
      "path": "footers/FloatingLogoFooter.tsx",
      "best_for": ["portfolio", "creative agency", "saas", "tech startup"],
      "description": "A striking, highly centralized footer featuring a giant faded brand name spanning the background, with a distinct floating brand icon centered over a horizontal line at the bottom.",
      "usage_example": "<FloatingLogoFooter brandName=\"NEXUS\" />"
    },
    {
      "name": "AnimatedSubscribeFooter",
      "path": "footers/AnimatedSubscribeFooter.tsx",
      "best_for": ["corporate saas", "marketing", "ecommerce", "startup"],
      "description": "A structured 4-column footer featuring an interactive newsletter subscription form with inline loading, success, and error animated states.",
      "usage_example": "<AnimatedSubscribeFooter brandName=\"Acme Corp\" />"
    },
    {
      "name": "BadgeFooter",
      "path": "footers/BadgeFooter.tsx",
      "best_for": ["corporate saas", "tech startup", "developer tool"],
      "description": "A classic, clean footer layout that features optional inline badges next to navigation links (e.g., 'New', 'Hiring', 'Pro') to highlight specific pages.",
      "usage_example": "<BadgeFooter brandName=\"Acme Corp\" description=\"The platform teams use to ship faster.\" columns={[{ title: 'Product', links: [{ label: 'Features', href: '/features' }, { label: 'Pricing', href: '/pricing' }, { label: 'Changelog', href: '/changelog', badge: 'New' }] }, { title: 'Company', links: [{ label: 'Careers', href: '/careers', badge: 'Hiring' }, { label: 'Blog', href: '/blog' }] }]} bottomLinks={[{ label: 'Privacy', href: '/privacy' }, { label: 'Terms', href: '/terms' }]} />"
    },
    {
      "name": "StatusFooter",
      "path": "footers/StatusFooter.tsx",
      "best_for": ["tech startup", "developer tool", "corporate saas"],
      "description": "A highly technical, Vercel-inspired footer. Features categorized columns, native inline dropdown menus for legal/SDK links, a system status indicator, and a built-in zero-dependency theme toggle switch.",
      "usage_example": "<StatusFooter statusText=\"All systems normal.\" statusColor=\"bg-emerald-500\" />"
    },
    {
      "name": "TerminalFooter",
      "path": "footers/TerminalFooter.tsx",
      "best_for": ["developer tool", "cyberpunk", "tech startup", "dark oled"],
      "description": "A developer-focused, technical footer featuring monospaced typography, a faint grid background, a terminal-style input field, and unique expanding-dot hover effects on the navigation links.",
      "usage_example": "<TerminalFooter brandName=\"SEEKER\" description=\"Command-line tools for modern developers.\" statusText=\"All systems operational\" sections={[{ title: 'Product', links: [{ title: 'Docs', href: '/docs' }, { title: 'Pricing', href: '/pricing' }] }, { title: 'Connect', links: [{ title: 'GitHub', href: 'https://github.com/seeker' }, { title: 'Discord', href: 'https://discord.gg/seeker' }] }]} />"
    },
    {
      "name": "CinematicFooter",
      "path": "footers/CinematicFooter.tsx",
      "best_for": ["creative agency", "portfolio", "gaming", "consumer"],
      "description": "A full-screen cinematic footer featuring GSAP scroll-reveal curtains, physics-based magnetic glassmorphism buttons, an animated aurora background, and an infinite scrolling marquee.",
      "usage_example": "<CinematicFooter brandName=\"Elysium\" heading=\"Own the Moment\" marqueeItems={[\"Swiss Movement\", \"Sapphire Crystal\", \"Lifetime Warranty\", \"Free Engraving\"]} creatorName=\"Elysium Timepieces\" />"
    },
    {
      "name": "WordmarkFooter",
      "path": "footers/WordmarkFooter.tsx",
      "best_for": ["portfolio", "creative agency", "music", "fashion"],
      "description": "A highly performant, ultra-minimal footer. Displays a giant brand wordmark that features a metallic shine reacting to mouse movements via direct DOM manipulation (zero re-renders).",
      "usage_example": "<WordmarkFooter brandName=\"NEXUS\" />"
    }
  ],

  "navigation": [
    {
      "name": "FloatingHeader",
      "path": "navigation/FloatingHeader.tsx",
      "best_for": ["corporate saas", "minimalist", "tech startup", "portfolio"],
      "description": "A sticky, floating pill-shaped navigation bar. Features a glassmorphic background and a fully responsive, Framer Motion powered slide-out mobile drawer.",
      "usage_example": "<FloatingHeader brandName=\"Nexus AI\" links={[{ label: 'Product', href: '/product' }, { label: 'Pricing', href: '/pricing' }, { label: 'Docs', href: '/docs' }]} loginText=\"Sign In\" signupText=\"Start Free Trial\" />"
    },
    {
      "name": "ExpandableSidebar",
      "path": "navigation/ExpandableSidebar.tsx",
      "best_for": ["dashboard", "corporate saas", "b2b", "internal tools"],
      "description": "A highly functional, space-saving dashboard sidebar. Collapses to an icon-only view and smoothly expands on hover using Framer Motion. Includes built-in custom dropdowns for organization and user settings.",
      "usage_example": "<ExpandableSidebar organizationName=\"Acme Corp\" currentPath=\"/dashboard\" />"
    },
    {
      "name": "AnimatedSidebar",
      "path": "navigation/AnimatedSidebar.tsx",
      "best_for": ["dashboard", "corporate saas", "internal tools", "b2b"],
      "description": "A fully customizable, zero-dependency, Framer Motion powered compound Sidebar component. A perfect drop-in replacement for Radix/Shadcn sidebars with smooth spring animations, mobile slide-out drawers, and collapsible icon states.",
      "usage_example": "<SidebarProvider><Sidebar><SidebarHeader>Brand</SidebarHeader><SidebarContent><SidebarGroup><SidebarGroupLabel>Menu</SidebarGroupLabel><SidebarMenu><SidebarMenuItem><SidebarMenuButton>Item 1</SidebarMenuButton></SidebarMenuItem></SidebarMenu></SidebarGroup></SidebarContent></Sidebar></SidebarProvider>"
    },
    {
      "name": "MacDock",
      "path": "navigation/MacDock.tsx",
      "best_for": ["portfolio", "creative agency", "playful", "dashboard"],
      "description": "An interactive, macOS-style floating dock navigation. Uses Framer Motion spring physics to smoothly magnify icons as the user's cursor approaches them.",
      "usage_example": "<MacDock><DockIcon><HomeIcon /></DockIcon><DockIcon><UserIcon /></DockIcon></MacDock>"
    },
    {
      "name": "MegaMenuHeader",
      "path": "navigation/MegaMenuHeader.tsx",
      "best_for": ["corporate saas", "enterprise", "b2b", "marketing"],
      "description": "A full-width, fixed header navigation bar designed for complex SaaS sites. Features Framer Motion animated mega-menu dropdowns on desktop and a clean accordion slide-down menu on mobile.",
      "usage_example": "<MegaMenuHeader brandName=\"Acme Corp\" />"
    },
    {
      "name": "Breadcrumbs",
      "path": "navigation/Breadcrumbs.tsx",
      "best_for": ["dashboard", "ecommerce", "documentation", "corporate saas"],
      "description": "A highly accessible, customizable compound breadcrumb component used to display the current page hierarchy. Built without external Radix dependencies.",
      "usage_example": "<Breadcrumb><BreadcrumbList><BreadcrumbItem><BreadcrumbLink href=\"/\">Home</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbPage>Current Page</BreadcrumbPage></BreadcrumbItem></BreadcrumbList></Breadcrumb>"
    }
  ],

  "core_dependencies": ["core/utils.ts"]
}


--- FILE: ui-ux-pro-max/scripts/core.py ---

import csv
import os
import math
import re
from collections import Counter

class BM25:
    """Lightweight BM25 Search Engine in pure Python."""
    def __init__(self, corpus, k1=1.5, b=0.75):
        self.corpus = corpus
        self.k1 = k1
        self.b = b
        self.doc_len = [len(doc) for doc in corpus]
        self.avgdl = sum(self.doc_len) / len(corpus) if corpus else 0
        self.df = Counter()
        for doc in corpus:
            self.df.update(set(doc))
        self.idf = {}
        N = len(corpus)
        for word, freq in self.df.items():
            self.idf[word] = math.log(1 + (N - freq + 0.5) / (freq + 0.5))

    def get_scores(self, query):
        scores = [0] * len(self.corpus)
        for q in query:
            if q not in self.df:
                continue
            idf = self.idf[q]
            for i, doc in enumerate(self.corpus):
                tf = doc.count(q)
                if tf == 0:
                    continue
                score = idf * (tf * (self.k1 + 1)) / (tf + self.k1 * (1 - self.b + self.b * self.doc_len[i] / self.avgdl))
                scores[i] += score
        return scores

def tokenize(text):
    if not text:
        return []
    return re.findall(r'\w+', text.lower())

def load_csv(filename):
    base_dir = os.path.dirname(os.path.dirname(__file__))
    filepath = os.path.join(base_dir, "data", filename)
    if not os.path.exists(filepath):
        return []
    with open(filepath, "r", encoding="utf-8") as f:
        reader = csv.DictReader(f)
        return list(reader)

def search_csv(filename, query_text, search_columns):
    rows = load_csv(filename)
    if not rows: return {}
    corpus = []
    for r in rows:
        doc = " ".join(str(r.get(col, "")) for col in search_columns)
        corpus.append(tokenize(doc))
    bm25 = BM25(corpus)
    scores = bm25.get_scores(tokenize(query_text))
    if not scores or max(scores) == 0:
        return rows[0]
    return rows[scores.index(max(scores))]

--- FILE: ui-ux-pro-max/scripts/design_system.py ---

def generate_design_system_md(domain_data, style_data, color_data, typo_data):
    md = []
    domain_name = domain_data.get('Product Type', 'Business').title()
    
    md.append(f"## Authoritative Design System: {domain_name}")
    md.append(f"**Key Considerations**: {domain_data.get('Key Considerations', 'Professional, Clean')}")
    md.append(f"**Aesthetic Style**: {style_data.get('Style Category', 'Minimalist')}")
    
    md.append("\n### 1. Typography System")
    md.append(f"- **Heading Font**: {typo_data.get('Heading Font', 'Inter')}")
    md.append(f"- **Body Font**: {typo_data.get('Body Font', 'Inter')}")
    md.append(f"- **Type Scale & Rules**: {typo_data.get('Notes', 'Use bold headings and legible body text.')}")
    
    md.append("\n### 2. Color Palette (Tailwind / Tokens)")
    md.append(f"- **Primary**: {color_data.get('Primary', '#000000')}")
    md.append(f"- **Secondary**: {color_data.get('Secondary', '#4A4A4A')}")
    md.append(f"- **Accent**: {color_data.get('Accent', '#3B82F6')}")
    md.append(f"- **Background**: {color_data.get('Background', '#FFFFFF')}")
    md.append(f"- **Surface/Cards**: {color_data.get('Card', '#F3F4F6')}")
    md.append(f"- **Text**: {color_data.get('Foreground', '#111827')}")
    
    md.append("\n### 3. Structural & Layout Rules")
    md.append(f"- {style_data.get('Implementation Checklist', '')}")
    
    md.append("\n### 4. Animation & Interaction")
    md.append(f"- {style_data.get('Effects & Animation', 'Smooth, subtle transitions.')}")
    
    md.append("\n### 5. Domain-Specific Anti-Patterns (NEVER DO THESE)")
    md.append(f"- [X] {style_data.get('Do Not Use For', '')}")
                
    return "\n".join(md)

--- FILE: ui-ux-pro-max/scripts/search.py ---

import sys
import argparse
import os

# Force UTF-8 encoding for stdout to prevent Windows cp1252 crash
if hasattr(sys.stdout, 'reconfigure'):
    sys.stdout.reconfigure(encoding='utf-8')

# Add current directory to path so imports work correctly when called as a subprocess
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

from core import search_csv
from design_system import generate_design_system_md

def main():
    parser = argparse.ArgumentParser(description="UI-UX-PRO-MAX Intelligence Engine")
    parser.add_argument("query", type=str, help="The business domain or description to search for")
    parser.add_argument("--design-system", action="store_true", help="Format output as a full design system")
    parser.add_argument("-f", "--format", type=str, default="markdown", choices=["markdown"], help="Output format")
    
    args = parser.parse_args()
    
    # 1. Product / Industry
    domain_data = search_csv("products.csv", args.query, ["Product Type", "Keywords", "Key Considerations"])
    if not domain_data:
        print("No design intelligence found. Ensure data CSVs exist.", file=sys.stderr)
        sys.exit(1)
        
    # 2. Styles
    style_query = args.query + " " + domain_data.get("Primary Style Recommendation", "")
    style_data = search_csv("styles.csv", style_query, ["Style Category", "Keywords", "Best For"])
    
    # 3. Colors
    color_query = args.query + " " + domain_data.get("Color Palette Focus", "") + " " + domain_data.get("Product Type", "")
    color_data = search_csv("colors.csv", color_query, ["Product Type", "Notes", "Primary"])
    
    # 4. Typography
    typo_query = args.query + " " + domain_data.get("Product Type", "")
    typo_data = search_csv("typography.csv", typo_query, ["Category", "Mood/Style Keywords", "Best For"])
    
    if args.design_system and args.format == "markdown":
        md_output = generate_design_system_md(domain_data, style_data, color_data, typo_data)
        print(md_output)
    else:
        # Fallback raw output
        print(f"Matched Domain: {domain_data.get('domain')}")

if __name__ == "__main__":
    main()

--- FILE: Vite_pipeline/__init__.py ---



--- FILE: Vite_pipeline/pipeline.py ---

import os
import subprocess
import shutil
import sys
import time


def run_vite_pipeline(interface):
    # 1. Check Node
    npm_path = shutil.which('npm') or (shutil.which('npm.cmd') if sys.platform == "win32" else None)
    if not npm_path:
        interface.print("[bold red]Error: NPM not found. Please install Node.js.[/bold red]")
        return None

    # 2. Only prompt shown to the user: the project name
    project_name = interface.input("[bold cyan]Project name > [/bold cyan]").strip()
    if not project_name:
        interface.print("[dim]>> Cancelled.[/dim]")
        return None

    # 3. Fully non-interactive scaffold: React + TypeScript + React Compiler,
    #    Oxlint ships pre-configured in this template, npm install deferred
    #    (handled by the existing steps further down this function).
    interface.print(f"[bold cyan]>> Scaffolding Vite project '{project_name}'...[/bold cyan]")

    npm_cmd = "npm.cmd" if sys.platform == "win32" else "npm"
    cmd = [
        npm_cmd, "create", "vite@latest", project_name, "--",
        "--template", "react-compiler-ts",
        "--no-interactive",
        "--no-immediate",
    ]

    try:
        with interface.create_loader(f"Running create-vite for '{project_name}'..."):
            result = subprocess.run(
                cmd,
                cwd=os.getcwd(),
                capture_output=True,
                text=True,
                shell=(sys.platform == "win32"),
            )
    except Exception as e:
        interface.print(f"[red]Error: Vite scaffolding failed: {e}[/red]")
        return None

    if result.returncode != 0:
        interface.print("[bold red]Error: Vite scaffolding failed.[/bold red]")
        error_output = (result.stderr or result.stdout or "").strip()
        if error_output:
            interface.script_output(error_output[:2000], title="create-vite Output", color="red")
        return None

    target_dir = os.path.abspath(os.path.join(os.getcwd(), project_name))

    if not os.path.exists(target_dir):
        interface.print(f"[red]Error: Folder '{project_name}' not found after scaffolding.[/red]")
        return None

    interface.print(f"[bold green] Vite project '{project_name}' scaffolded.[/bold green]")

    # Windows npm.cmd path safety: Rename folder if it contains shell-breaking characters
    if "&" in project_name:
        safe_name = project_name.replace("&", "and").replace("  ", " ").strip()
        safe_dir = os.path.abspath(os.path.join(os.getcwd(), safe_name))
        try:
            os.rename(target_dir, safe_dir)
            target_dir = safe_dir
            project_name = safe_name
            interface.print(f"[yellow]>> Auto-renamed folder to '{project_name}' to prevent Windows npm crash.[/yellow]")
        except Exception as e:
            interface.print(f"[red]Error renaming folder for shell safety: {e}[/red]")
            return None

    npx_cmd = "npx.cmd" if sys.platform == "win32" else "npx"
    npm_cmd = "npm.cmd" if sys.platform == "win32" else "npm"

    with interface.create_loader(f"Running npm install in {project_name}..."):
        subprocess.run(f"{npm_cmd} install", cwd=target_dir, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    
    # Execute Post-Scaffold automated Tailwind steps silently
    try:
        with interface.create_loader("Initializing TailwindCSS + PostCSS (v3 Locked for AI Compatibility)..."):
            # Lock to Tailwind v3.4 to guarantee compatibility with LLM-generated tailwind.config.js
            subprocess.run(f"{npm_cmd} install -D tailwindcss@^3.4.17 postcss autoprefixer", cwd=target_dir, shell=True, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
            
            # 1. Aggressively wipe out all default CSS and SVG junk across ANY framework
            src_dir = os.path.join(target_dir, "src")
            if os.path.exists(src_dir):
                for file in os.listdir(src_dir):
                    if file.endswith(".css") or file.endswith(".svg"):
                        os.remove(os.path.join(src_dir, file))
            
            assets_dir = os.path.join(src_dir, "assets")
            if os.path.exists(assets_dir):
                for file in os.listdir(assets_dir):
                    if file.endswith(".svg"):
                        os.remove(os.path.join(assets_dir, file))
                        
            public_vite_svg = os.path.join(target_dir, "public", "vite.svg")
            if os.path.exists(public_vite_svg):
                os.remove(public_vite_svg)

            # 2. Unconditionally write the Tailwind base to index.css
            css_path = os.path.join(src_dir, "index.css")
            with open(css_path, "w") as f:
                f.write("@tailwind base;\n@tailwind components;\n@tailwind utilities;\n")
            
            # 3. Create postcss.config.js directly (Standard v3 format)
            postcss_config_path = os.path.join(target_dir, "postcss.config.js")
            with open(postcss_config_path, "w") as f:
                f.write('export default {\n  plugins: {\n    tailwindcss: {},\n    autoprefixer: {},\n  },\n}')
            
            # 4. Create tailwind.config.js directly (covering React, Vue, Svelte, etc.)
            tailwind_config_path = os.path.join(target_dir, "tailwind.config.js")
            with open(tailwind_config_path, "w") as f:
                f.write('''/** @type {import('tailwindcss').Config} */\nexport default {\n  content: [\n    "./index.html",\n    "./src/**/*.{js,ts,jsx,tsx,vue,svelte}",\n  ],\n  theme: {\n    extend: {},\n  },\n  plugins: [],\n}''')
                    
        interface.print("[bold green]✔ Vite + Tailwind Scaffold Complete![/bold green]")
        
    except Exception as e:
        interface.print(f"[red]Error during Tailwind setup: {e}[/red]")

    return target_dir