feat: freelance page, a story on the homepage, and design fixes
The homepage was too long and read as a list of sections. The technical ones (project fit, tools, how a change is secured) move to a page of their own, /freelance and /en/freelance, linked from the header, the footer and a pointer on the homepage. The rest is reordered into one story (who, what you need, examples, how working together goes, results, questions, contact) and each section opens with a sentence that leads over from the one before. routes.ts: a page may now have the same name in both languages. Before, /en/<german name> was always moved to the English name, which for such a page would have redirected the address onto itself. Design: list titles such as "Passt gut" are real headings instead of small grey labels. The automation examples, their description and the run are one box, so it is clear they belong together. Digits on light backgrounds are the blue of the panels instead of black. The square corner marks on the rounded service cards are gone. The years in the career line are readable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -25,9 +25,14 @@ App lives in `apps/web`. Concept and scope: `apps/web/plans/freelance-relaunch.m
|
||||
- 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 the language switch and "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 the imprint and the privacy notice. URLs of the previous site redirect to `/`
|
||||
- Two content pages. The homepage tells one story from top to bottom (who, what you need, examples, how
|
||||
working together goes, results, questions, contact); each section opens with a `bridge` sentence from
|
||||
`story` in the content files that leads over from the one before. The technical sections (project fit,
|
||||
tools, how a change is secured) live on `/freelance` (`/en/freelance`), for people who develop themselves
|
||||
or lead a team. Do not move technical detail back onto the homepage.
|
||||
- The header has the link to the freelance page, the language switch and "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 the imprint and the privacy notice. URLs of the previous site redirect to `/`
|
||||
(see `next.config.mjs`).
|
||||
- Title, description and link previews come from `site` in `src/content/de.ts` and `en.ts`.
|
||||
The share image is a screenshot of the real hero, one per language: after changing the hero headline or
|
||||
@@ -39,8 +44,8 @@ App lives in `apps/web`. Concept and scope: `apps/web/plans/freelance-relaunch.m
|
||||
|
||||
## Two languages (German is the main one)
|
||||
|
||||
- German lives at the root (`/`, `/impressum`, `/datenschutz`), English under `/en` (`/en/imprint`,
|
||||
`/en/privacy`). The app directory renders both under `app/[locale]`; `proxy.ts` maps the public addresses
|
||||
- German lives at the root (`/`, `/freelance`, `/impressum`, `/datenschutz`), English under `/en`
|
||||
(`/en/freelance`, `/en/imprint`, `/en/privacy`). The app directory renders both under `app/[locale]`; `proxy.ts` maps the public addresses
|
||||
onto it. All routing and detection rules are pure functions in `src/domain/routes.ts` and `locale.ts`.
|
||||
- Detection: an address without a language follows the `lang` cookie (set only by the language switch), then
|
||||
the browser's `Accept-Language`, then German. `/en/...` is never redirected.
|
||||
@@ -54,8 +59,9 @@ App lives in `apps/web`. Concept and scope: `apps/web/plans/freelance-relaunch.m
|
||||
|
||||
- Building blocks live in `apps/web/src/components/bits/`: `DecodeText` (mono labels resolving from digits),
|
||||
`BitWipe` (headline revealed behind a column of digits), `BitReveal` (picture assembling from bits),
|
||||
`BinaryTicker`, `ScrollBits`, `BitBurst`, `BitCurtain` (the language switch transition). Reuse them
|
||||
instead of inventing new effects.
|
||||
`BinaryTicker`, `ScrollBits`, `BitBurst`, `BitCurtain` (the language switch transition), `BitAura` (a lit
|
||||
edge that sheds digits; glow only on dark surfaces, on light ones just a few blue digits), `BitSeam`,
|
||||
`BitGlow`. Reuse them instead of inventing new effects.
|
||||
- `DecodeText` is for monospaced text only; in proportional type the changing glyph widths make text jump.
|
||||
- Never put an in-view trigger on an element that clips itself away (clip-path): a fully clipped element
|
||||
never counts as visible. Observe an unclipped wrapper (see `BitWipe`).
|
||||
|
||||
Reference in New Issue
Block a user