# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Common Commands ```bash # Development npm run dev # Start dev server on port 3000 npm run dev:clean # Clean .next/dist then start dev server # Build & Preview npm run build # Build production files to dist/ npm run build:clean # Clean then build npm run preview # Serve dist/ on port 3000 (npx serve) # Linting & Type Checking npm run lint # ESLint (configured in config/lint/.eslintrc.json) npm run type-check # tsc --noEmit # E2E Testing (Playwright) npm run test # Run all E2E tests npm run test:e2e # Same as above npm run test:smoke # Only @smoke-tagged tests npm run test:visual # Visual regression (Desktop Chrome) npm run test:visual:all # Visual regression (all projects) npm run test:visual:update # Update visual snapshots npx playwright test --grep "test name" # Run a single E2E test by name # Unit Testing (Jest) npm run test:unit # Run all unit tests npm run test:coverage # Coverage report (thresholds: 80% branches/functions/lines) npx jest --testPathPattern="button" # Run a single test file matching pattern # Quality Checks npm run check:contrast # Color contrast audit npm run check:headings # Heading hierarchy audit npm run lighthouse # Lighthouse CI performance audit # Database (Prisma + SQLite) npm run db:seed # Seed the dev database npm run db:reset # Reset database with migrations ``` ## Architecture ### Tech Stack - **Next.js 14** (App Router) with **hybrid rendering** — static pages + API routes (Note: `output: 'export'` was recently removed; the project is transitioning away from pure static export) - **React 18**, **TypeScript 5** (strict mode with `noUncheckedIndexedAccess`) - **Tailwind CSS 3** with design tokens exposed as CSS custom properties (all tokenized via `var()` references in `tailwind.config.js`) - **Framer Motion** for animations, **Lucide React** for icons, **Zod** for validation - **shadcn/ui** pattern (Radix UI + class-variance-authority + tailwind-merge) - **Prisma** with SQLite for backend data (admin, auth, CMS) ### Path Alias `@/` maps to `src/` — configured in both `tsconfig.json` (`paths`) and `jest.config.js` (`moduleNameMapper`). ### TypeScript Strictness Beyond `strict: true`, the project enables: - `noUncheckedIndexedAccess: true` — array/object index access returns `T | undefined`, requiring null checks. This is a significant constraint to be aware of when writing code. - `noImplicitReturns`, `noFallthroughCasesInSwitch`, `noUnusedLocals`, `noUnusedParameters` ### Route Structure (App Router) ``` src/app/ ├── layout.tsx # Root layout: fonts, metadata, theme, analytics, SEO schemas ├── (marketing)/ # Route group — all public marketing pages │ ├── layout.tsx # Shared: Header + Footer + PageTransition + ErrorBoundary │ ├── page.tsx # Home (delegates to home-content-cms.tsx) │ ├── about/ # About page (client.tsx) │ ├── news/ # News list + [slug] detail │ ├── contact/ # Contact form │ ├── products/ # Products hub (HSI model) │ │ ├── page.tsx # Product listing (enterprise suites + standalone) │ │ ├── [id]/ # Product detail (four-layer narrative) │ │ ├── standalone/[id]/ # Standalone product detail │ │ ├── erp-upgrade/ # Specific product landing pages │ │ └── erp-upgrade-v3/ │ ├── services/ # Services list + [id] detail │ ├── solutions/ # Solutions list + [id] detail (cross-references products) │ ├── cases/ # Case studies │ └── team/ # Team page ├── api/ │ ├── admin/ # Admin API │ ├── auth/ # Authentication API │ ├── cms/ # CMS API routes (draft mode, revalidation) │ └── contact/ # Contact form submission ├── privacy/, terms/ # Legal pages └── fonts/ # Local font files (Geist Sans/Mono) ``` ### Archiving Convention When replacing a page or component with a new version, move the old one to an `_archive/` subdirectory (e.g., `src/app/(marketing)/_archive/` for old homepage iterations). The archive is excluded from TypeScript compilation via `tsconfig.json`. ### Dark Mode Dark mode uses the `data-theme="dark"` HTML attribute (not Tailwind's `dark:` class). An inline `