# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project

Kit UI is a static-export toolkit (Next.js 16, React 19, TypeScript strict) with five browser-based tools: Color, Units, ASCII, Media, and Favicon. All heavy processing runs client-side via WebAssembly. Deployed at kit.pivoine.art.

## Commands

```bash
pnpm dev          # Dev server with Turbopack (localhost:3000)
pnpm build        # Static export to /out
pnpm lint         # ESLint (next/core-web-vitals)
pnpm postinstall  # Copies WASM binaries to public/wasm/ (runs automatically on install)
```

There are no test suites. Use `pnpm build` to verify changes compile correctly.

## Architecture

### Routing (App Router)

```
app/
├── page.tsx              # Landing page (dark mode forced)
├── (app)/layout.tsx      # Wraps all tools with Providers + AppShell
├── (app)/color/          # Color manipulation (@valknarthing/pastel-wasm)
├── (app)/units/          # Unit converter (187+ units, 23 categories)
├── (app)/ascii/          # ASCII art (373 figlet fonts)
├── (app)/media/          # File converter (FFmpeg + ImageMagick WASM)
└── (app)/favicon/        # Favicon/PWA asset generator
```

### Code Organization

Each tool follows a mirrored structure across three directories:

- **`app/(app)/{tool}/page.tsx`** — Route entry point
- **`components/{tool}/`** — UI components for the tool
- **`lib/{tool}/`** — Business logic, WASM wrappers, stores, and utilities
- **`types/`** — Shared TypeScript definitions

Shared UI primitives live in `components/ui/` (shadcn/ui, customized with glassmorphic styling). Layout shell in `components/layout/`.

### State Management (three layers)

1. **URL params** — Primary for shareable state (`useSearchParams` / `useRouter().push`)
2. **React Query** — Async WASM computations with caching
3. **Zustand** — Per-tool client stores in `lib/{tool}/`
4. **localStorage** — Persistence for theme, favorites, history

### WASM Integration

WASM modules (FFmpeg, ImageMagick, pastel-wasm) are lazy-loaded on first use. Binaries live in `public/wasm/` and are copied there by the postinstall script — don't move them manually. WASM logic is browser-only; do not attempt to run it in Node.

## Conventions

- **`'use client'`** only where needed (WASM, browser APIs, interactive state). Default to RSC.
- **Styling**: Tailwind CSS 4 with CSS-first config in `app/globals.css`. Use `cn()` from `lib/utils/cn.ts` for conditional classes. Use `@utility glass` for glassmorphic effects and gradient utilities (`gradient-purple-blue`, etc.).
- **Icons**: Lucide React exclusively.
- **Imports**: Use `@/` path alias (resolves to project root).
- **Components**: shadcn/ui from `components/ui/` as building blocks.
- **Logic/UI separation**: Business logic in `lib/`, UI in `components/`. Keep them separate.

## Deployment

Static export (`output: 'export'` in next.config.ts) served by Nginx via Docker. No Node.js runtime in production.

```bash
docker build -t kit-ui .
docker run -p 80:80 kit-ui
```

## PWA

Service worker at `public/sw.js` pre-caches core assets and WASM binaries. Manifest generated from `app/manifest.ts` (force-static). Cache version: `kit-ui-v1`.
