# 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