From a744e6a16979ee57cf6b41a322a4edff62570cb7 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 13 May 2026 14:28:07 +0000 Subject: [PATCH 1/3] Add CLAUDE.md with codebase guidance for AI assistants Documents build/test commands, app architecture (single-page landing, lazy loading, content layer, theme system), code conventions, and testing setup for future Claude Code sessions. https://claude.ai/code/session_01ProhZcrkuekv742hSoWLct --- CLAUDE.md | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..d5e11119 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,83 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Commands + +```bash +npm run dev # Dev server at http://localhost:3000 +npm run build # Production build → dist/ +npm run preview # Serve the production build locally +npm run lint # ESLint, fails on any warning (--max-warnings 0) +npm run lint:fix # ESLint with auto-fix +npm run format # Prettier write +npm run typecheck # tsc --noEmit (TypeScript check without emitting) +npm run test # Vitest in watch mode +npm run test:run # Vitest single run (use before committing) +npm run e2e # Playwright end-to-end tests (requires a running dev server) +``` + +To run a single unit test file: `npx vitest run src/components/Navbar.test.tsx` + +Pre-commit hook runs `lint-staged`: ESLint --fix + Prettier --write on staged `.ts`/`.tsx`/`.js`/`.jsx` files. + +## Architecture + +DocuGen is a **single-page marketing/landing site** (no client-side router). Navigation is anchor-based (`#features`, `#pricing`, etc.). The app has no backend; all content is static. + +### Application entry + +`main.tsx` → wraps `` in `` → `App.tsx` renders the full page as a vertical stack of sections. + +Above-fold sections (`Hero`, `HowItWorks`, `FAQ`) are eagerly imported. Below-fold sections (`Features`, `Testimonials`, `Preview`, `Pricing`, `Newsletter`) use `React.lazy` + `` for code splitting. + +### Content layer + +**All copy lives in `src/data/content.ts`.** Never hardcode strings inside components. The file exports named constants (`HERO_COPY`, `FEATURES`, `FAQS`, `PRICING_COPY`, etc.) consumed directly in components. + +### Theme system + +`src/lib/ThemeContext.tsx` provides a React Context with `theme`, `toggleTheme`, and `setTheme`. Initial theme is read from `localStorage` (`docugen-theme`) and falls back to `prefers-color-scheme`. Theme is applied by toggling the `dark` class on ``. Tailwind is configured with `darkMode: 'class'`. + +Consume theme in components via the `useTheme` hook from `src/lib/useTheme.ts`. + +### Design tokens + +Custom Tailwind palette defined in `tailwind.config.js`: +- `teal-*` — primary accent color (e.g. `text-teal-400`, `bg-teal-600`) +- `dark-*` / `light-*` — semantic scale for text/backgrounds +- Fonts: `font-sans` → Inter, `font-mono` → JetBrains Mono + +Avoid arbitrary Tailwind values (`[...]`); extend the theme instead. + +### Animations + +Use Framer Motion only for entrance animations (`motion.div` with `initial`/`animate`/`whileInView`). Always set `viewport={{ once: true }}`. Duration: `0.5s` standard, `0.6s` complex. Stagger children with `delay: index * 0.1`. No spring or bounce effects. + +## Code Conventions + +- **Named exports only** — no default exports for components. +- **Absolute imports** from `src/` (TypeScript `moduleResolution: "bundler"` is configured; use `./` or `../` only when needed by tooling). +- **Import order**: React → external packages → internal components/utils. +- **No `any` types** — ESLint enforces `@typescript-eslint/no-explicit-any: error`. Use `unknown` with type guards. +- **Unused variables/params** cause build errors (`noUnusedLocals`, `noUnusedParameters` in `tsconfig.json`). Prefix with `_` to suppress if intentional. +- **Component file order**: imports → types/interfaces → constants → helper functions → main component → exports. +- **Component naming**: PascalCase for files and components; camelCase for utilities. + +## Testing + +Unit tests use Vitest + React Testing Library. Test files live **next to** the component they test with a `.test.tsx` extension (e.g. `FAQ.tsx` → `FAQ.test.tsx`). + +`src/test/setup.ts` provides global mocks for every test: +- `localStorage` — vi.fn() mock (reset `beforeEach`) +- `IntersectionObserver` — stubbed no-op class + +E2E tests are in `e2e/` using Playwright. They require the dev server to already be running (`npm run dev` in a separate terminal). + +## Environment Variables + +| Variable | Purpose | +|---|---| +| `VITE_PLAUSIBLE_DOMAIN` | Enables Plausible analytics (optional; no analytics if unset) | + +Prefix all client-side env vars with `VITE_` (Vite requirement). From c9965a65820caabf5d585b47ccb2002f6636e21e Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 13 May 2026 16:48:25 +0000 Subject: [PATCH 2/3] Fix three inaccuracies in CLAUDE.md flagged by Codex review - Use FAQ.test.tsx (exists) in the single-test example instead of Navbar.test.tsx (does not exist) - Correct import guidance: no baseUrl/paths configured, so relative imports are used throughout, not absolute src/ imports - Soften content-layer claim: note that some components (e.g. Navbar) still have inline strings not yet migrated to content.ts https://claude.ai/code/session_01ProhZcrkuekv742hSoWLct --- CLAUDE.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index d5e11119..6d786b67 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -17,7 +17,7 @@ npm run test:run # Vitest single run (use before committing) npm run e2e # Playwright end-to-end tests (requires a running dev server) ``` -To run a single unit test file: `npx vitest run src/components/Navbar.test.tsx` +To run a single unit test file: `npx vitest run src/components/FAQ.test.tsx` Pre-commit hook runs `lint-staged`: ESLint --fix + Prettier --write on staged `.ts`/`.tsx`/`.js`/`.jsx` files. @@ -33,7 +33,7 @@ Above-fold sections (`Hero`, `HowItWorks`, `FAQ`) are eagerly imported. Below-fo ### Content layer -**All copy lives in `src/data/content.ts`.** Never hardcode strings inside components. The file exports named constants (`HERO_COPY`, `FEATURES`, `FAQS`, `PRICING_COPY`, etc.) consumed directly in components. +Copy should live in `src/data/content.ts`, which exports named constants (`HERO_COPY`, `FEATURES`, `FAQS`, `PRICING_COPY`, etc.) consumed directly in components. Some components (e.g. `Navbar`) still contain inline strings not yet migrated to `content.ts`; new copy should go in `content.ts`. ### Theme system @@ -57,7 +57,7 @@ Use Framer Motion only for entrance animations (`motion.div` with `initial`/`ani ## Code Conventions - **Named exports only** — no default exports for components. -- **Absolute imports** from `src/` (TypeScript `moduleResolution: "bundler"` is configured; use `./` or `../` only when needed by tooling). +- **Relative imports** — `tsconfig.json` uses `moduleResolution: "bundler"` but has no `baseUrl`/`paths` and `vite.config.ts` has no aliases, so use `./` or `../` paths throughout. - **Import order**: React → external packages → internal components/utils. - **No `any` types** — ESLint enforces `@typescript-eslint/no-explicit-any: error`. Use `unknown` with type guards. - **Unused variables/params** cause build errors (`noUnusedLocals`, `noUnusedParameters` in `tsconfig.json`). Prefix with `_` to suppress if intentional. From 0b5526d2baae6e83e623e553bfcfd72ca788dd60 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 21 May 2026 10:20:35 +0000 Subject: [PATCH 3/3] Fix ThemeProvider placement in entry-point description main.tsx only mounts in ; ThemeProvider is rendered inside App.tsx, not main.tsx. https://claude.ai/code/session_01ProhZcrkuekv742hSoWLct --- CLAUDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 6d786b67..e352d1c3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -27,7 +27,7 @@ DocuGen is a **single-page marketing/landing site** (no client-side router). Nav ### Application entry -`main.tsx` → wraps `` in `` → `App.tsx` renders the full page as a vertical stack of sections. +`main.tsx` mounts `` inside ``. `App.tsx` owns the `` wrapper and renders the full page as a vertical stack of sections. Above-fold sections (`Hero`, `HowItWorks`, `FAQ`) are eagerly imported. Below-fold sections (`Features`, `Testimonials`, `Preview`, `Pricing`, `Newsletter`) use `React.lazy` + `` for code splitting.