From ffaea03e581e7831b156f651d20ef9b09a1b8d5d Mon Sep 17 00:00:00 2001 From: jwinterm Date: Fri, 16 Jan 2026 15:03:12 -0500 Subject: [PATCH] Fix critical accessibility and SEO issues - Fix homepage heading hierarchy (h2 -> h1) - Add page-specific metadata to services and about pages - Fix outline-none on form inputs for keyboard accessibility - Delete sync conflict files - Add group class back to bento cards for hover animations - Use raw CSS for glassmorphism to fix Tailwind opacity errors - Add TODO.md with production checklist - Add semantic CSS classes (.section-container, .glass-card) - Update Tailwind config for opacity modifier support --- TODO.md | 131 + apps/web/public/images/favicon_192.png | Bin 0 -> 15492 bytes .../web/public/images/logo_dark_w_name_bg.png | Bin 0 -> 1246174 bytes .../public/images/logo_dark_w_name_trans.png | Bin 0 -> 204989 bytes apps/web/public/images/logo_light_trans.png | Bin 0 -> 239514 bytes .../public/images/logo_light_w_name_bg.png | Bin 0 -> 1293445 bytes .../public/images/logo_light_w_name_trans.png | Bin 0 -> 219787 bytes .../web/public/images/logo_w_circle_trans.jpg | Bin 0 -> 71272 bytes apps/web/public/manifest.json | 16 + apps/web/src/app/about/page.tsx | 24 +- apps/web/src/app/globals.css | 28 +- apps/web/src/app/layout.tsx | 15 +- apps/web/src/app/page.tsx | 58 +- apps/web/src/app/services/page.tsx | 86 +- .../components/about/founder-signature.tsx | 110 +- .../src/components/contact/contact-form.tsx | 104 +- .../components/landing/services-preview.tsx | 26 +- apps/web/src/components/layout/footer.tsx | 3 +- apps/web/src/components/layout/site-logo.tsx | 29 + ....sync-conflict-20260116-104626-3QPCLGW.tsx | 67 - .../src/components/portfolio/bento-grid.tsx | 26 +- apps/web/tailwind.config.ts | 8 +- ....sync-conflict-20260116-104636-3QPCLGW.tsx | 151 - ...sync-conflict-20260116-104636-3QPCLGW.yaml | 4169 ----------------- 24 files changed, 485 insertions(+), 4566 deletions(-) create mode 100644 TODO.md create mode 100644 apps/web/public/images/favicon_192.png create mode 100644 apps/web/public/images/logo_dark_w_name_bg.png create mode 100644 apps/web/public/images/logo_dark_w_name_trans.png create mode 100644 apps/web/public/images/logo_light_trans.png create mode 100644 apps/web/public/images/logo_light_w_name_bg.png create mode 100644 apps/web/public/images/logo_light_w_name_trans.png create mode 100644 apps/web/public/images/logo_w_circle_trans.jpg create mode 100644 apps/web/public/manifest.json create mode 100644 apps/web/src/components/layout/site-logo.tsx delete mode 100644 apps/web/src/components/portfolio/bento-grid.sync-conflict-20260116-104626-3QPCLGW.tsx delete mode 100644 packages/ui/src/procedural/nebula-field.sync-conflict-20260116-104636-3QPCLGW.tsx delete mode 100644 pnpm-lock.sync-conflict-20260116-104636-3QPCLGW.yaml 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 +