# TODO.md

Granular work list. Checked items are done; each maps to atomic commits.

## Milestone 0 — Scaffold
- [x] Init git, enable pnpm, move docs into `docs/`
- [x] Root `README.md`, `.gitignore`, `PROJECT_STATUS.md`, `TODO.md`
- [ ] Initial commit on `main`, then feature branch
- [ ] `site/` Astro project: `package.json`, `astro.config.mjs`, `tsconfig.json`, Tailwind config
- [ ] ESLint + Prettier config
- [ ] `pnpm install` + verify `pnpm build` on empty skeleton

## Milestone 1 — Tokens & styles
- [ ] `styles/tokens.css` (colour/space/type/radius/motion, both themes via `[data-theme]`)
- [ ] `styles/base.css` (reset, base element styles, focus ring, dot-grid, prose)
- [ ] `styles/motion.css` (keyframes + reduced-motion layer)
- [ ] Tailwind `@theme` wired to tokens; verify no raw hex/px in components (lint guard)

## Milestone 2 — i18n
- [ ] `i18n/locales.ts` (locale config)
- [ ] `i18n/slugMap.ts` (pageId ↔ {en,no} paths + section anchors) — the tested contract
- [ ] `i18n/dictionary.en.ts` + `dictionary.no.ts` (typed, same interface)
- [ ] `i18n/t.ts` accessor + `getLocale`/`resolvePath` helpers
- [ ] Astro i18n config (defaultLocale en at root, no prefixed)

## Milestone 3 — Content
- [ ] Zod schemas (`content.config.ts`) per DATA_MODEL
- [ ] profile EN/NO · skills EN/NO · experience EN/NO · projects EN/NO (jobtrack, inboxintel, homelab) · meta pages
- [ ] Locale-invariant field inheritance loader
- [ ] Content parity + schema validation (feeds CI later)

## Milestone 4 — UI atoms + core
- [ ] ui: Chip, Button, SplitCvButton, LangSwitch, ThemeToggle, Card, SectionLabel, TraceMotif, FramedImage, Tooltip
- [ ] core: Base/Page/Home/CaseStudy layouts, Header, MobileNav, Footer, Seo, ThemeScript, SkipLink

## Milestone 5 — Home
- [ ] Hero, ProofStrip, SkillsGrid, ProjectCards, ExperienceTimeline, AboutTeaser, ContactBand

## Milestone 6 — Case study
- [ ] CsHeader, TldrBox, MiniToc, SectionRenderer, DecisionList, ArchDiagram, Gallery+Lightbox host, NextPrev
- [ ] Capability template (homelab)

## Milestone 7 — Pages
- [ ] Home (en/no), projects index, 3 case studies ×2, experience, about, contact, cv, colophon, 404

## Milestone 8 — Behaviour
- [ ] theme.ts, nav.ts, observer.ts, lightbox.ts, form.ts (≤15 kB total)

## Milestone 9 — SEO
- [ ] Seo component meta + hreflang from slug map
- [ ] JSON-LD builders (Person, CreativeWork, WebSite, BreadcrumbList)
- [ ] OG image generation, sitemap, robots.txt

## Milestone 10 — Relay
- [ ] .NET 9 minimal API: validate, honeypot/time-trap, rate-limit, SMTP send, /healthz
- [ ] appsettings + env config, Dockerfile

## Milestone 11 — Tests
- [ ] vitest: dictionary parity, slug-map bijection, JSON-LD shape
- [ ] playwright: both locales render, lang switch mapping, CV downloads, form contract, a11y (axe), keyboard

## Milestone 12 — Docker + CI
- [ ] site Dockerfile (multi-stage → nginx) + nginx.conf (headers, caching, redirects)
- [ ] relay Dockerfile
- [ ] compose (prod + dev) + `.env.example`
- [ ] `.gitea/workflows` CI pipeline (gates → build → images)

## Milestone 13 — Verification
- [ ] Lighthouse budgets, axe clean, acceptance criteria walkthrough, PROJECT_STATUS final
