# CLAUDE.md — operating instructions for Claude Code ## Read this first 1. **`AGENTS.md` is the source of truth for this project.** Read it in full before your first edit in any session. It carries the locked decisions, the credential register, the open questions, and the full history. 2. **You are required to maintain `AGENTS.md`** under the constitution written at the top of it. Update *Current Truth* in place; append to the *Change Log*, newest first; never edit a past entry; never delete history. Record decisions and plans, not only executed work. Stamp facts `[verified YYYY-MM-DD]` or `[assumed]`. 3. Update it **at the end of every working session**, not only when something ships. A session that produced a decision and no code still produces a Change Log entry. 4. **Read `AGENTS.md` §12 Standing Reminders at the start of every substantial session and surface anything live to Pouya.** These are decisions he parked deliberately, not settled matters — R1 in particular is his explicit instruction to keep raising the licensure wording. A parked decision that stops being raised has quietly become permanent, which is the failure mode §12 exists to prevent. ## The one rule that matters more than the code Pouya is a licensed legal professional. **No factual claim about him, his credentials, his experience, or his practice may appear on a public page unless it is in the Verified table in `AGENTS.md` §4.** If a page needs a fact you do not have: - Do not infer it from context. - Do not soften it into something defensible ("extensive experience", "years of"). - Do not carry it over from the old site — the old site contained a fictitious founder, invented matter values, and a fabricated testimonial. - **Leave `TODO(pouya): ` in the source, and add the question to `AGENTS.md` §9.** A build that fails on an unanswered question is a correct build. Read the Forbidden table in §4 before writing any statistic, number, or superlative. ## Commands ```bash npm install npm run dev # local dev server npm run build # static build to ./dist npm run preview # serve ./dist locally npm run check # astro check — type and template errors npm run lint # eslint + prettier check ``` ## Where things live ``` AGENTS.md living project record — read first, maintain always docs/ the specs you build from 01-architecture.md sitemap, URL map, per-page content outline 02-design-system.md tokens, type scale, motion, contrast constraints 03-content-spec.md voice, copy rules, per-page copy deck 04-seo-spec.md metadata, structured data, sitemap, crawlability 05-backend-spec.md intake form, Lambda/DynamoDB/SES, booking, PIPEDA 06-deployment.md S3/CloudFront, GitHub Actions OIDC, cutover checklist src/ styles/tokens.css design tokens — the single source of colour and scale styles/global.css reset, base type, utilities layouts/ page shells components/ UI components pages/ routes (file-based) content/ content collections; Insights MDX lives here data/site.ts site-wide constants, nav, contact details public/ static assets served as-is ``` ## Conventions **Framework.** Astro, `output: 'static'`. Never introduce a server runtime without a Change Log entry recording why. **JavaScript.** Default to zero. Reach for an Astro island only when a feature genuinely cannot be CSS or progressive HTML. If you add a `client:*` directive, say why in the Change Log. A `
` element beats a JS accordion. **Styling.** Plain CSS with custom properties. No Tailwind, no CSS-in-JS, no utility framework. Every colour, space, and font size comes from a token in `tokens.css` — no raw hex values and no magic numbers in component styles. **Accessibility is a build requirement, not a polish pass.** Semantic landmarks, one `

` per page, heading levels never skipped, visible focus states, all interactive elements reachable by keyboard, `prefers-reduced-motion` honoured on every animation. Gold `#c9a876` never sits on cream — it fails contrast at 2.10:1. See `docs/02-design-system.md`. **Images.** Astro `` with explicit width and height. AVIF/WebP with fallback. Never base64-inline an image into HTML — the old site did this with ~1 MB of logo PNGs. **Fonts.** Self-hosted, subset, `font-display: swap`, preloaded. No Google Fonts request at runtime — it costs a round trip and adds a third-party call to a page that collects legal inquiries. **Every page ships with:** a unique `` and meta description, a canonical URL, Open Graph and Twitter card tags, and appropriate JSON-LD. See `docs/04-seo-spec.md`. A page without these is not finished. **Commits.** Conventional Commits (`feat:`, `fix:`, `docs:`, `chore:`, `refactor:`). One logical change per commit. Never commit secrets, `.env` files, or AWS credentials — deploys use OIDC role assumption. **Performance budget.** Lighthouse ≥ 95 on all four categories, on mobile, for every page. Under 100 KB of JS on any route. LCP under 2.0 s on a simulated Slow 4G connection. Treat a budget breach as a failing build. ## What "done" means for a page - [ ] Copy written from `docs/03-content-spec.md`, every claim traceable to `AGENTS.md` §4 - [ ] No `TODO(pouya)` left unlogged in §9 - [ ] Unique title, meta description, canonical, OG/Twitter tags, JSON-LD - [ ] Semantic HTML; keyboard navigable; reduced-motion honoured - [ ] Lighthouse ≥ 95 mobile, all four categories - [ ] Renders correctly with JavaScript disabled - [ ] `AGENTS.md` Change Log entry appended