diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..2cc6c87 --- /dev/null +++ b/TODO.md @@ -0,0 +1,131 @@ +# Such Software - Production Checklist + +## 🔴 Before Production Deployment + +### 1. Cloudflare Turnstile Configuration + +The contact form uses Cloudflare Turnstile for bot protection. You need to set up the secret key for production: + +1. Go to [Cloudflare Dashboard](https://dash.cloudflare.com/) → Turnstile +2. Create a new site or use existing widget +3. Copy the **Site Key** (public) and **Secret Key** (private) +4. Set environment variables: + +```bash +# In your production environment (Vercel, etc.) +NEXT_PUBLIC_TURNSTILE_SITE_KEY=your_site_key_here +TURNSTILE_SECRET_KEY=your_secret_key_here +``` + +⚠️ **Warning:** The current implementation returns `true` if no secret key is set. This is fine for development but must be configured in production. + +See: `apps/web/src/lib/turnstile.ts` + +--- + +## 🟡 Medium Priority Improvements + +### 2. Extract Shared Header Component + +The header is duplicated across three pages: +- `apps/web/src/app/page.tsx` +- `apps/web/src/app/services/page.tsx` +- `apps/web/src/app/about/page.tsx` + +Create a shared component at `apps/web/src/components/layout/header.tsx`. + +### 3. Add `prefers-reduced-motion` Support + +The NebulaField and DynamicBackground components run animations without checking user preferences. + +File: `packages/ui/src/procedural/nebula-field.tsx` + +Add: +```tsx +const prefersReducedMotion = typeof window !== 'undefined' + ? window.matchMedia('(prefers-reduced-motion: reduce)').matches + : false; + +if (prefersReducedMotion) { + return
; +} +``` + +### 4. Add Skip-to-Content Link + +For keyboard accessibility, add a skip link in `apps/web/src/app/layout.tsx`: + +```tsx + + Skip to main content + +``` + +### 5. Add `aria-hidden` to Decorative Icons + +In `apps/web/src/app/about/page.tsx`, add `aria-hidden="true"` to decorative icons: +```tsx +