feat: rebuild mintel.me as a single-page freelance site

The site now presents one freelance developer on one page: hero, introduction,
four typical cases (developer for a product, make an app reliable, automate a
process, a website) with what you get, how it runs and what it costs, a
process automation section, technology and project fit, how I work, two live
references, questions and contact.

- Hero and closing headline are drawn from running binary digits.
- Each case explains its four steps with an animated drawing; the automation
  section shows example workflows with work travelling between systems; a
  pipeline run shows what a test catches before a release.
- Contact is one email address, kept in parts and assembled in the browser so
  it never appears in the page source (src/domain/email.ts, spec first).
- Imprint and privacy pages added.
- The old site (blog, case studies, contact form, fixed-price pages, video
  rendering and related scripts) is removed. Its URLs redirect to the homepage.
- The deploy smoke test checks the legal pages and the redirects instead of
  the removed case study.
- Dev scripts use docker compose v2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 22:33:06 +02:00
co-authored by Claude Opus 5.5
parent 4eb663f42a
commit fa40fefe2f
781 changed files with 4925 additions and 55137 deletions
+19 -1
View File
@@ -20,6 +20,19 @@ App lives in `apps/web`. Concept and scope: `apps/web/plans/freelance-relaunch.m
5. Report the exact commands and results. "Done" means they were run on the current code.
Never weaken, skip or delete a test to make it pass.
## Copy rules (client-facing pages)
- Never mention AI as the owner's tool, and no internal method vocabulary (specs, TDD, mutation, coverage,
pull requests). The automation service may name AI as part of what the client gets. Plain language.
- Modest and factual: no promises the owner did not confirm, no superlatives. See the concept, section 1.
- One page: everything lives on the homepage. The header has only "Get in touch", which jumps to the contact
section (`#contact`). Contact is one email address: no calendar integration, no form. The only other
pages are `/imprint` and `/privacy`. URLs of the previous site redirect to `/` (see `next.config.mjs`).
- The email address is kept in parts (`src/content/site.ts`) and assembled in the browser by `EmailLink`.
Never write the full address into markup, metadata or copy.
- The hero design (binary-digit headline) is approved: do not change its design.
- Look at the result before reporting: take screenshots (desktop and mobile), do not ship blind.
## Architecture rules
- Functional core, imperative shell. Pure logic goes in `apps/web/src/domain/` (no I/O, no clock, no
@@ -40,7 +53,12 @@ App lives in `apps/web`. Concept and scope: `apps/web/plans/freelance-relaunch.m
## Gotchas
- `tsconfig` includes `.next/types`: after deleting a route, stale generated files there break `tsc`.
Run `next typegen` and remove the stale file.
- Run only one Stryker process at a time; parallel runs share `.stryker-tmp` and hang.
- Stryker needs `plugins` listed explicitly in `stryker.config.json` (pnpm layout) and ignores the large
asset folders via `ignorePatterns`; keep them in sync when adding top-level folders.
- `@mintel/*` packages are `link:` dependencies on a sibling `at-mintel` checkout.
- `@mintel/*` packages are `link:` dependencies on a sibling `at-mintel` checkout. The app itself now only
uses `@mintel/next-config`; the other entries in `package.json` are leftovers from the old site.
- Pushing `main` deploys to the testing environment; production is deployed from a `v*` tag.
- Git branches: work on `feat/*`, never directly on `main`.