# CLAUDE.md This file provides guidance for Claude Code when working with this codebase. ## Project Overview Cloudrite (cloudrite.co.nz) is an Auckland, New Zealand-based IT services company website. The site showcases web development, cloud hosting, and IT support services with the tagline "Every Business Needs an I.T Guy." ## Tech Stack - **Framework**: Next.js 16.2.0 (App Router) - **Language**: TypeScript 5.7.3 - **Styling**: Tailwind CSS 4.2.0 with CSS variables - **UI Components**: shadcn/ui (new-york style) - **Icons**: Lucide React - **Package Manager**: pnpm ## Project Structure ``` app/ # Next.js App Router pages and API routes api/send-email/ # Contact form email API (uses Resend) globals.css # Global styles and CSS variables layout.tsx # Root layout with fonts page.tsx # Homepage components/ # React components ui/ # shadcn/ui primitives (do not modify directly) header.tsx # Site navigation hero.tsx # Hero section with animations services.tsx # Services grid features.tsx # Features showcase process.tsx # Process timeline contact.tsx # Contact form footer.tsx # Site footer chatwoot.tsx # Live chat widget hooks/ # Custom React hooks lib/ # Utility functions public/ # Static assets ``` ## Commands ```bash pnpm dev # Start development server pnpm build # Production build pnpm start # Start production server pnpm lint # Run ESLint ``` ## Code Conventions ### Styling - Use Tailwind CSS utility classes - Use semantic design tokens from CSS variables (bg-background, text-foreground, text-primary, etc.) - Dark theme is the default; colors defined in `app/globals.css` - Primary color: green (`oklch(0.75 0.18 145)`) - Prefer `gap-*` for spacing over margins in flex/grid layouts - Always use the `frontend-design` skill. No exceptions. ### Components - All custom components use `'use client'` directive when needed - Import UI components from `@/components/ui/*` - Import utilities from `@/lib/utils` - Use Lucide icons: `import { IconName } from 'lucide-react'` ### TypeScript - Strict mode enabled - Path alias `@/*` maps to project root - Prefer explicit types over `any` ### Fonts - Headings: Space Grotesk (`font-sans`) - Body: Inter (`font-body`) ## Environment Variables Required for full functionality: ``` RESEND_API_KEY # Resend API key for contact form emails CHATWOOT_TOKEN # Chatwoot website token (served at runtime via GET /api/chatwoot) ``` Both are read server-side at **runtime**, so they can be supplied via Docker compose `env_file` — no build args or `NEXT_PUBLIC_` prefix needed. The Chatwoot token is intentionally not `NEXT_PUBLIC_`: the client widget fetches it from `/api/chatwoot` (a `force-dynamic` route) instead of having it inlined at build time. ## API Routes ### GET /api/chatwoot Returns `{ "token": string | null }` — the Chatwoot website token read from the server environment at request time. Consumed by `components/chatwidget.tsx`. ### POST /api/send-email Sends contact form submissions to contact@cloudrite.co.nz via Resend. **Body:** ```json { "name": "string", "email": "string", "message": "string" } ``` ## shadcn/ui This project uses shadcn/ui components. To add new components: ```bash npx shadcn@latest add [component-name] ``` Components are installed to `components/ui/`. Do not manually edit these files; they can be regenerated. ## pnpm / sharp build (CI gotcha) pnpm 11 hard-fails `pnpm install --frozen-lockfile` with `[ERR_PNPM_IGNORED_BUILDS] Ignored build scripts: sharp@0.34.5` (exit 1) unless sharp's native build script is explicitly accounted for. sharp ships prebuilt binaries, so its build script is unnecessary and should stay skipped. - `pnpm-workspace.yaml` records the decision as `allowBuilds:\n sharp: false`. This **must be a real boolean** (`false`/`true`). A non-boolean value (e.g. the placeholder string `set this to true or false`) does NOT count as a decision and breaks CI. `onlyBuiltDependencies` / `ignoredBuiltDependencies` are NOT honored for this in pnpm 11 — only `allowBuilds`. Verify before pushing: `git show HEAD:pnpm-workspace.yaml`. - Because that value is easy to corrupt, the Docker build is made resilient: the `pnpm install` step in the `Dockerfile` passes `--config.strictDepBuilds=false`, which downgrades the ignored-builds error to a warning regardless of the workspace file. Keep that flag in place. ## Important Notes - Contact email: contact@cloudrite.co.nz - Phone: 021 107 7483 - Business hours: By appointment only (24/7 emergency support) - The site uses extensive CSS animations; check existing patterns in hero.tsx and services.tsx before adding new ones - TypeScript build errors are ignored in next.config.mjs for development flexibility