first publish

This commit is contained in:
2026-09-06 17:21:52 +02:00
commit b8e41b4d55
147 changed files with 19367 additions and 0 deletions

555
docs/HANDOVER.md Normal file
View File

@@ -0,0 +1,555 @@
# Übergabe Website Anelia Wolf
Stand: 03.09.2026 · Übergabe an die betreuende Agentur
Dieses Dokument beschreibt, **was gebaut wurde**, **wie es betrieben wird** und
**was vor dem Livegang noch fehlt**. Die technische Kurzfassung für Entwickler
steht in `README.md`, die vollständige Begründung jeder Designentscheidung in
`docs/superpowers/specs/2026-09-02-anelia-wolf-website-design.md` (Spec) und
`docs/superpowers/plans/2026-09-02-anelia-wolf-build-plan.md` (Bauplan).
---
## 1. Was gebaut wurde
### 1.1 Umfang
Eine statische Website in **zwei Sprachen**, ohne Backend, ohne Datenbank,
ohne Cookie-Banner. Deutsch ist die Originalfassung und liegt auf den bisherigen
Adressen, Englisch liegt vollstaendig unter `/en/`:
| Route | Inhalt |
|---|---|
| `/` | Startseite, sechs nummerierte Sektionen: 01 Positionierung · 02 Leistungen · 03 WOLF-Prinzip · 04 Über Anelia · 05 Für wen (mit Termine-Ledger) · 06 Kontakt |
| `/leistungen/coaching/` | Coaching & Analysen |
| `/leistungen/trainings/` | Trainings & Workshops |
| `/leistungen/keynotes/` | Keynotes & Speaking |
| `/impressum/` | Impressum |
| `/datenschutz/` | Datenschutzerklärung |
| 404 | „Diese Fährte endet hier.“ deutsch, mit englischem Zweizeiler darunter |
| `/en/` | English start page |
| `/en/services/coaching/` | Coaching & Assessments |
| `/en/services/trainings/` | Training & Workshops |
| `/en/services/keynotes/` | Keynotes & Speaking |
| `/en/imprint/` | Imprint (Übersetzung, verbindlich bleibt `/impressum/`) |
| `/en/privacy/` | Privacy (Übersetzung, verbindlich bleibt `/datenschutz/`) |
Dazu erzeugt der Build `sitemap.xml`, `robots.txt`, `icon.svg` und `apple-icon.png`.
### 1.2 Technik
Next.js 16 (App Router) im **Static Export**, React 19, Tailwind v4,
GSAP 3.15 + ScrollTrigger, Lenis (Smooth Scroll), TypeScript. Paketmanager npm.
**Bewusste Selbstbeschränkungen** sie sind keine Kosmetik, die
Datenschutzerklärung sagt sie ausdrücklich zu:
- **keine externen Requests**: keine Google Fonts, keine CDNs, keine Karten,
keine Videos, keine Social-Plugins, kein Analytics, keine iframes.
Schriften werden über `next/font` **zur Build-Zeit selbst gehostet**
(`out/_next/static/media/*.woff2`).
- **kein Storage**: kein localStorage, kein sessionStorage, keine Cookies.
Deshalb ist auch kein Cookie-Banner nötig und keiner eingebaut.
- **kein Server hinter dem Kontaktformular**, kein Newsletter. Das Formular in
Abschnitt 06 setzt aus den Eingaben eine `mailto:`-Nachricht zusammen und
übergibt sie dem E-Mail-Programm der Besucherin es sendet selbst nichts.
> Wer eine dieser Zusagen ändert (z. B. ein Analytics-Tool einbaut), **muss**
> `src/content/legal.ts` (Ziffer 2, 3 und 6 der Datenschutzerklärung) mit ändern
> und braucht in der Regel ein Consent-Banner.
### 1.3 Design-System
Alle Tokens stehen an genau einer Stelle: `src/app/globals.css`.
**Farben** (aus dem Logo abgeleitet):
| Token | Wert | Verwendung |
|---|---|---|
| `--ink` | `#0f0e0c` | dunkler Grund |
| `--ivory` | `#f6f1e8` | heller Grund |
| `--bone` | `#eee6d8` | zweiter heller Grund (Termine) |
| `--gold` | `#c9a24d` | Gold **nur auf dunklem Grund** (8,05:1 auf Ink) |
| `--gold-deep` | `#7d5f1b` | Gold **nur auf hellem Grund** (5,3:1 auf Ivory) |
| `--grey-warm` / `--grey-deep` | `#a8a196` / `#5e5a52` | gedämpfter Text dunkel / hell |
Gold ist rationiert: Haarlinien, Ziffern, Labels, Striche nie Fließtext.
Die großen Display-Ziffern auf hellem Grund nutzen `--gold-700` (`#a37a2c`,
3,5:1 zulässig, weil sie mit 147 px als Large Text gelten und dekorativ sind).
**Typografie**: Playfair Display (Display, Headlines/Ziffern/Formel/Zitate),
Source Sans 3 (Fließtext), DM Mono (Labels, Meta-Zeilen). Gewählt am 06.09.2026
aus dem Vergleich unter `/schrift-test/` (dort Paarung 01).
Feste Regel: **die Display-Schrift wird nirgends unter 28 px gesetzt** kleinere
Titel laufen in Source Sans 3. Geprüft, siehe QA-Log.
Das Betonungswort einer Headline ist kursiv und auf dunklem Grund zusätzlich golden;
auf hellem Grund bleibt es rein typografisch, weil der Gold-Verlauf auf Elfenbein
nur auf 2,4:1 käme. Die Regel steht in `globals.css`, nicht in den Komponenten.
**Form**: Radius 0, keine Schatten, kein Bold. Die Seite ist aus Haarlinien
gebaut. Die Grenze zwischen zwei Farbblöcken ist eine 1 px Gold-Haarlinie.
**Grund/Theme (wichtig für spätere Eingriffe)**: Jedes Themenblock-Element
(`[data-theme="dark"|"light"]`) malt **seinen eigenen, deckenden Grund**.
Es gibt **kein JavaScript, das Farben umschaltet** ein früherer Ansatz
(„ThemeTween“) wurde entfernt, weil Text kurzzeitig auf der falschen Palette
landen konnte. Die Regeln dafür stehen in `globals.css` im Block
„Ground & boundary (no JS)“. Neue Sektionen brauchen nur ein
`data-theme="dark"` oder `"light"` Grund und Gold-Naht kommen automatisch.
### 1.4 Motion
Alle Bewegungen laufen über GSAP + ScrollTrigger, Smooth Scroll über Lenis.
Die Primitiven liegen in `src/components/motion/`:
| Komponente | Aufgabe |
|---|---|
| `Reveal`, `Lines` | Einblenden von Blöcken und Zeilen beim Scrollen (nur `opacity`/`y`) |
| `Rule` | die Gold-Haarlinie, die sich beim Erscheinen aufzieht |
| `Draw` | Strichanimation des Wolf-Monogramms |
| `Door`, `Curtain` | Seitenübergänge |
| `Magnet` | leichter Cursor-Magnetismus auf Buttons |
| `ScrollProgress` | 1 px Fortschrittslinie unter dem Header |
| `TransitionLink` | Links mit Übergang + Anker-Offset |
**Barrierefreiheit der Motion**: Reveals animieren ausschließlich `opacity`
(und `y`) nie `visibility`/`autoAlpha`, damit noch nicht sichtbare Elemente
in der Tab-Reihenfolge bleiben. `prefers-reduced-motion` ist überall über
`gsap.matchMedia` behandelt; die Formel-Sektion (300 svh Sticky-Bühne) fällt
dabei auf ihre natürliche Höhe zusammen. Fokusring: 2 px, sichtbar auf beiden
Gründen. Ein „Zum Inhalt springen“-Link liegt vor dem Header.
### 1.5 Inhalte
**Sämtliche Texte liegen in `src/content/*.ts`** (`home`, `coaching`,
`trainings`, `keynotes`, `legal`, `chrome`, `not-found`). Wer Copy ändert,
ändert dort nie im JSX. Stammdaten (Name, E-Mail, Telefon, LinkedIn,
Navigation, Routen) liegen in `src/lib/site.ts`.
Die englischen Texte liegen daneben in `src/content/en/` Datei für Datei
dieselbe Struktur. Erzwungen wird das über den Typ: jede deutsche Inhaltsdatei
exportiert ihre Form (z. B. `export type CoachingContent = Widen<typeof coaching>`),
die englische Datei erfüllt genau diesen Typ. Fehlt drüben ein Feld oder heisst
es anders, schlägt `npx tsc --noEmit` fehl die Fassungen können also nicht
auseinanderlaufen. `Widen<T>` (`src/content/widen.ts`) macht dabei aus den
`as const`-Literaltypen der deutschen Datei wieder `string`; ohne das wäre
„Coaching & Analysen“ der Typ und nicht der Wert.
---
### 1.6 Zwei Sprachen
Deutsch ist die Originalfassung, Englisch die Uebersetzung. Beide sind
vollstaendig es gibt keine Seite, die nur in einer Sprache existiert.
**Adressen.** Deutsch bleibt auf `/`, `/leistungen/…`, `/impressum/`.
Englisch bekommt englische Segmente: `/en/`, `/en/services/…`, `/en/imprint/`.
Beides steht an genau einer Stelle: `routesByLang` in `src/lib/i18n.ts`.
Wer eine Adresse aendert, aendert sie dort Navigation, Fuss, Sitemap,
hreflang und der Sprachumschalter lesen alle aus dieser Tabelle.
**Umschalter.** Die beiden Flaggen im Kopf (`LangSwitch.tsx`) fuehren nicht
pauschal auf die Startseite, sondern auf das Gegenstueck derselben Seite
(`counterpart()`). Unter 1024 px ist im Kopf kein Platz; dort steht der
Umschalter im Overlay-Menue. Eine Flagge steht streng genommen fuer ein Land
und nicht fuer eine Sprache deshalb steht das Kuerzel DE/EN daneben und der
zugaengliche Name nennt die Sprache ausgeschrieben.
**Zwei Wurzel-Layouts.** `app/(de)/layout.tsx` schreibt `<html lang="de">`,
`app/en/layout.tsx` schreibt `<html lang="en">`. Im App Router schreibt nur das
Wurzel-Layout das `<html>`-Element, und die Sprache des Dokuments gehoert dort
hin (WCAG 3.1.1) ein `<div lang="en">` weiter unten waere nicht dasselbe.
Die Gruppe `(de)` taucht in keiner URL auf. Beide Layouts bestehen nur aus
einem Aufruf von `<Shell lang>` (`src/components/layout/Shell.tsx`), das
Dokument steht also trotzdem nur einmal im Projekt. Zwei Folgen davon:
- Ein Sprachwechsel ist ein vollstaendiger Seitenaufbau statt einer
Client-Navigation. Bei einem Sprachwechsel ist das richtig Metadaten,
Huelle und Inhalt wechseln ohnehin komplett.
- Next kann keine gemeinsame 404 mehr zusammensetzen und faellt ohne
Gegenmassnahme auf seine eigene, weisse Fehlerseite zurueck. Deshalb
`experimental.globalNotFound` in `next.config.ts` und
`src/app/global-not-found.tsx`; diese Datei rendert das ganze Dokument
selbst. Sie erzeugt `out/404.html`.
**Seitenaufbau nur einmal.** Die Routendateien enthalten nur Metadaten und
reichen ihre Inhaltsdatei weiter; der Aufbau steht in
`src/components/pages/` (`HomeBody`, `CoachingBody`, `TrainingsBody`,
`KeynotesBody`, `NotFoundBody`). Eine Layout-Aenderung wirkt damit in beiden
Sprachen, ohne dass jemand daran denken muss.
**Rechtstexte.** Verbindlich ist die deutsche Fassung. `/en/imprint/` und
`/en/privacy/` sagen das im ersten Abschnitt und verlinken die deutsche Seite.
Die Platzhalter sind in beiden Fassungen dieselben Angaben, und der Build-Guard
prueft beide Dateien wer nur die deutsche fuellt, kommt nicht am Launch-Flip
vorbei.
**Suchmaschinen.** Jede Seite traegt `canonical` auf sich selbst und
`hreflang` auf beide Fassungen plus `x-default` auf Deutsch
(`alternatesFor()` in `src/lib/i18n.ts`). Die `sitemap.xml` fuehrt alle zwoelf
Seiten mit denselben Alternates.
---
## 2. Betrieb: entwickeln, bauen, deployen
```bash
npm install
npm run dev # Entwicklungsserver http://localhost:3000
npm run lint # ESLint
npx tsc --noEmit # Typprüfung
npm run build # erzeugt out/
```
### Deployment
`next.config.ts` setzt `output: "export"` und `trailingSlash: true`.
`npm run build` schreibt den Ordner **`out/`** das ist das komplette
Deployment. Vorgehen:
1. `npm run build`
2. **Inhalt von `out/`** (nicht den Ordner selbst) in das Web-Root des Hosters
hochladen FTP, rsync, Git-Deploy, Netlify-Drop, was auch immer.
3. Fertig. **Kein Node-Prozess auf dem Server, kein `next start`,
keine Datenbank, keine Umgebungsvariablen.**
Es funktioniert damit auf jedem Standard-Hoster (Apache, nginx, Uberspace,
Hetzner Webhosting, Netlify, Vercel, IONOS …).
**`trailingSlash: true`** bedeutet: jede Route ist ein Ordner mit
`index.html` (`out/leistungen/coaching/index.html`). Das ist genau deshalb so
gewählt, damit auch „dumme“ Hoster ohne Rewrite-Regeln die Seiten ausliefern.
Bitte den Hoster **nicht** so konfigurieren, dass er Trailing Slashes entfernt.
**404**: `out/404.html` ist die Fehlerseite. Bei Apache genügt
`ErrorDocument 404 /404.html`, Netlify/Vercel finden sie automatisch.
Nginx: `error_page 404 /404.html;`.
**HTTPS**: Pflicht (die Datenschutzerklärung nennt TLS). Zusätzlich empfohlen:
`Strict-Transport-Security`, `X-Content-Type-Options: nosniff`,
`Referrer-Policy: strict-origin-when-cross-origin`. Da die Seite keine externen
Ressourcen lädt, ist eine sehr strenge Content-Security-Policy möglich.
**Domain**: In `src/lib/site.ts` steht `https://anelia-wolf.com`. Dieser Wert
speist Canonical-URLs, OpenGraph und `sitemap.xml`. Bei anderer Domain hier
ändern und neu bauen.
---
## 3. Bilder und Logo einspielen (Drop-in)
### Logo: erledigt
Das Original-Logo der Kundin ist eingebaut. `public/brand/logo-mark.svg` enthält das
Monogramm, abgeleitet aus `v3-anelia-wolf-gold.svg`: ohne C2PA-Metadaten (rund 16 KB, die
sonst auf jeder Seite mitgeliefert würden), ohne weißes Hintergrundrechteck, ohne Wortmarke,
auf die Marke beschnitten, schwarze Flächen auf `currentColor`. Die Original-Koordinaten
sind unverändert, deshalb sitzt der Goldverlauf exakt wie im Original. Details stehen in
`public/brand/README.md`.
Zwei Dinge sind dadurch anders als in der ursprünglichen Spec:
- **Die Marke wird als Ganzes aufgewischt, nicht Strich für Strich gezeichnet.** Das Logo
besteht aus Flächen, nicht aus Linien; eine Strichanimation wäre darauf unsichtbar. Vor
allem aber sind die Teile verzahnt: Die Brust des Wolfs ist der mittlere Strich des W, und
das rechte V existiert nur als zwei Fragmente um den Kopf herum. Nacheinander gezeichnet
zerfällt die Marke sichtbar in Bruchstücke. Sie wird deshalb in einer Bewegung von oben
nach unten aufgedeckt, sodass jedes Zwischenbild ein sauberer Querschnitt der fertigen
Marke ist. Das gezeichnete Ersatz-Monogramm (`WolfMark.tsx`) animiert weiterhin als
Strich; `src/components/motion/Draw.tsx` entscheidet das automatisch anhand der Datei.
- **Die 404-Seite zeigt das vollständige Monogramm.** Die Spec sah dort das W ohne Wolf vor
(„Hier ist der Wolf nicht."). Aus demselben Grund geht das nicht. Die Zeile heißt jetzt
„Diese Fährte endet hier."
`public/brand/logo-full.png` (2400 × 1260 px) ist das Social-Preview-Bild und wurde aus
demselben Original erzeugt: Monogramm und Wortmarke auf Tinte. Es wird als OpenGraph-Bild
ausgeliefert, also beim Teilen auf LinkedIn.
Die Wortmarke „ANELIA WOLF" bleibt im Kopf und im Fuß **echter Text** (Source Sans 3, gesperrt) und
kein Bild: So bleibt sie bei jeder Fenstergröße scharf, ist vorlesbar und markierbar.
### Alles Weitere
Die Seite ist so gebaut, dass **fehlende Assets nichts kaputt machen**: Sie
rendert dann eine dokumentierte typografische Alternative. Sobald die Datei im
richtigen Ordner mit dem richtigen Namen liegt, wird sie **ohne Codeänderung**
verwendet nur neu bauen.
### `public/brand/` siehe `public/brand/README.md`
| Datei | Anforderung | Fehlt sie, dann … |
|---|---|---|
| `logo-mark.svg` | nur das W-Monogramm mit Wolfskopf, transparent, **echtes SVG mit Pfaden** | typografisches `<WolfMark/>`-Monogramm als Platzhalter |
| `logo-full.png` | komplettes Logo mit Wordmark, 1200 × 630 px (oder das Doppelte) | kein Social-Preview-Bild in den OpenGraph-Daten |
**Nur SVG** für das Monogramm die Strichanimation braucht echte Pfade, ein
PNG wird ignoriert. Keine Gold-Variante nötig (die Seite färbt über
`currentColor`). **Kein `<script>` im SVG**: die Datei wird inline eingebettet,
ein Skript darin **bricht den Build ab** (dann ohne Interaktivität exportieren).
### `public/photos/` siehe `public/photos/README.md`
| Datei | Format | Verwendung |
|---|---|---|
| `anelia-hero.jpg` | Hochkant 4:5, min. 1600 px breit, ruhiger Hintergrund | Startseite Hero |
| `anelia-portrait.jpg` | Hochkant 3:4, min. 1400 px breit | „Über Anelia“ |
| `anelia-stage.jpg` | Querformat 3:2, Bühnenfoto | Keynotes-Seite |
### `public/speaker-profil.pdf`
Optional. Liegt die Datei **und** steht `flags.showSpeakerPdf` auf `true`,
erscheint die Speaker-Profil-Zeile auf der Keynotes-Seite. Fehlt beides,
wird der ganze Block „Für Veranstalter“ **gar nicht gerendert** es bleibt
kein leerer Rahmen stehen.
> Wichtig: `src/components/brand/WolfMark.tsx` ist das gezeichnete
> Platzhalter-Monogramm und wird **nicht** angefasst. Das echte Logo kommt
> ausschließlich über `public/brand/logo-mark.svg` herein.
---
## 4. Flags (`src/lib/site.ts`)
Über diese Schalter werden Blöcke freigegeben, sobald die Inhalte oder
Freigaben vorliegen. Kein Flag verlangt eine Codeänderung an Komponenten.
| Flag | aktuell | Bedeutung |
|---|---|---|
| `showPlaceholders` | `true` | offene Pflichtangaben stehen **sichtbar** als „[…]“ in Gold. Vor Livegang auf `false` siehe Abschnitt 5. |
| `hostOutsideEu` | `false` | nur `true`, wenn Hoster **oder** E-Mail-/Office-Anbieter außerhalb EU/EWR sitzen. Bei `false` wird der Drittland-Absatz der Datenschutzerklärung gar nicht gerendert (eine unrichtige Drittland-Angabe verletzt Art. 13 Abs. 1 lit. f DSGVO). |
| `showFaq` | `true` | FAQ-Sektionen auf den Leistungsseiten |
| `showStimmen` | `false` | Testimonial-Block erst mit Zitaten **und** schriftlicher Einwilligung |
| `showSpeakerPdf` | `false` | Speaker-Profil-Zeile (braucht zusätzlich das PDF) |
| `showSecondTalk` | `false` | zweiter Vortrag „Unlock your Sales-DNA“ |
| `show24hPromise` | `false` | Zusage „Antwort innerhalb von 24 Stunden“ |
| `showIndustry` | `false` | Branchennennung im Nebentätigkeits-Kontext |
| `showTwins` | `true` | Zwillinge-Satz in der Biografie |
| `showLangSwitch` | `true` | Sprachumschalter im Kopf und im Overlay-Menü. Auf `false` verschwinden beide Flaggen, die englischen Seiten bleiben über ihre Adresse erreichbar. |
Nicht bestätigte Aussagen sind bewusst ausgeschaltet: eine Zusage, die nicht
gehalten wird (24-h-Antwort), und ein Testimonial ohne Einwilligung sind
rechtlich riskanter als eine Leerstelle.
---
## 5. Vor dem Livegang: LEGAL_TODO
Die vollständige, kommentierte Liste steht in **`src/lib/legal.ts`**
(`LEGAL_TODO` für Impressum/Datenschutz, `CONTENT_TODO` für die
Leistungsseiten). Kurzfassung:
**Impressum**
1. Ladungsfähige Anschrift (Straße, Hausnummer, PLZ, Ort) **kein Postfach**.
2. USt-IdNr. (§ 27a UStG) oder W-IdNr. (§ 139c AO) oder Abschnitt streichen;
Kleinunternehmerregelung ja/nein.
3. Berufshaftpflicht vorhanden? Dann Versicherer, Anschrift, Geltungsbereich
sonst Absatz streichen.
4. Optionale Geschäftsbezeichnung nur, wenn sie tatsächlich geführt wird.
5. Bildnachweis: Fotograf:in, Logo-Designer:in/Agentur, Website-Agentur.
6. „Stand“-Datum setzen.
7. „WOLF-Prinzip“ bleibt als **„Bezeichnung“** stehen, bis die Marke
eingetragen ist (Markenrecherche empfohlen der Begriff wird von Dritten
verwendet). Erst danach darf der Urheberrechtsabsatz Markenschutz behaupten.
**Datenschutz**
8. Hosting-Anbieter (Firma, Anschrift, Land) und Löschfrist der Server-Logfiles
(üblich 714 Tage) beim Hoster erfragen; **AV-Vertrag abschließen**.
9. Sitzt Hoster oder E-Mail-/Office-Anbieter außerhalb EU/EWR?
Dann `flags.hostOutsideEu` auf `true` **und** Land + Garantie-Grundlage
eintragen.
10. E-Mail-/Office-Anbieter eintragen; AV-Vertrag.
11. Aufbewahrungsfrist für Anfragen festlegen (z. B. 12 Monate).
12. Zuständige Aufsichtsbehörde des Bundeslandes eintragen.
13. „Stand“-Datum setzen.
14. Vor Livegang prüfen: keine Requests an Dritte, kein Storage im Build
(aktuell erfüllt siehe QA-Log).
**Bildnachweise** nach § 13 UrhG in den Bild-Captions setzen (Hero,
Über Anelia, Keynotes-Bühne). „Foto: [Name]“ als Platzhalter erfüllt die
Nennungspflicht nicht.
**CONTENT_TODO** (sichtbare „[…]“ außerhalb der Rechtstexte): Dauer des
Auswertungsgesprächs und Analyse-Tool, Dauer/Paket in der Coaching-
Rahmentabelle, Gruppengröße und Umfang der Trainingsreihe.
### Der Flip
```
1. LEGAL_TODO und CONTENT_TODO abarbeiten (echte Angaben in src/content/*.ts)
2. flags.showPlaceholders = false
3. npm run build
```
**Schutzmechanismus**: Steht danach noch irgendwo ein „[…]“ in einer
Pflichtangabe, **bricht der Build ab und nennt die Fundstelle**
(`assertNoPlaceholders` in `src/lib/legal.ts`). Der Flip kann also nicht
ungelesen live gehen. Absätze, die ohne ihren Platzhalter sinnlos wären, sind
als `optional` markiert und entfallen beim Flip vollständig es entstehen
keine Sätze wie „Anelia Wolf,,“.
---
## 6. Aufgabe nach dem Event (herCAREER, 23.10.2026)
Auf der Startseite steht in Sektion 05 ein **Termine-Ledger** mit zwei Zeilen
(`src/content/home.ts`, Export `termine`):
- 23.10.2026 · 10:30 Keynote „Das WOLF-Prinzip Mut zum Erfolg!“,
herCAREER Expo, MOC München, Auditorium 2
- 22.23.10.2026 Ausstellerin, herCAREER Expo, Halle 3, Stand P.10.2
**Ab dem 24.10.2026 sind diese Zeilen falsch** („Termine“ im Futur für ein
vergangenes Event). Zu tun, mit Termin im Kalender:
1. Entweder die Zeilen in `src/content/home.ts` auf einen Rückblick umstellen
(„Gesprochen bei herCAREER 2026“) oder durch neue Termine ersetzen.
2. Sind keine neuen Termine da: den Block durch einen Stimmen-Block ersetzen
(`flags.showStimmen`), sobald Zitate mit Einwilligung vorliegen.
3. Auch anpassen: `src/content/keynotes.ts` (Meta-Zeile
„Keynote · herCAREER Expo 2026 · 23.10. · 10:30“) und
`src/content/home.ts` (Marginalie „Bühne“, Fact-Zeile).
4. `npm run build`, `out/` hochladen.
**Offen: Wer pflegt das, und wann?** Das ist Spec §12 Punkt 17 und muss mit
der Kundin geklärt werden am besten als feste Zuständigkeit plus
Kalendereintrag für den 24.10.2026.
---
## 7. Offene Fragen an die Kundin (Spec §12)
Diese Punkte blockieren den Livegang bzw. schalten Blöcke frei. Die
vollständige Fassung steht in
`docs/superpowers/specs/2026-09-02-anelia-wolf-website-design.md`, Abschnitt 12.
1. **Logo-Vektor**: Original-SVG/AI des W-Monogramms; Bestätigung, dass der
Wolf als Einzelstrich gezeichnet und allein gezeigt werden darf (Favicon,
Curtain). Schriftliche Nutzungsrechte vom Designer.
2. **Impressum/Datenschutz**: Anschrift, USt-IdNr. oder W-IdNr. (oder keins),
Kleinunternehmerregelung, Berufshaftpflicht, Bundesland (Aufsichtsbehörde),
Hoster und E-Mail-Anbieter.
3. **Nebentätigkeit**: Darf „B2B-Außendienst“ genannt werden? Darf
„Medizinprodukte“ genannt werden? Der Arbeitgeber wird nie genannt.
4. **Biografie-Freigabe**: Vater als Händler, Zahntechnikerin,
Abteilungsleitung, Premium-Store-Management, Zwillinge jede Angabe einzeln
bestätigen; dürfen später Jahreszahlen ergänzt werden?
5. **Fotos**: Welche Originale existieren (≥ 2000 px, hoch/quer/Bühne)?
Name der Fotografin für den Bildnachweis. Rechte am herCAREER-Bild.
6. **Analyse-Tool**: Welches Instrument (DISG / INSIGHTS / persolog / …)?
Aktive Lizenz? Darf Name/Badge erscheinen? Dauer des Auswertungsgesprächs.
7. **Rahmenwerte**: Sitzungslänge und Pakete im Coaching; Gruppengrößen und
Serienformat bei Trainings; Reiseradius und Technik bei Keynotes.
8. **Preise**: Spanne oder „auf Anfrage“ für Coaching, Trainingstag, Keynote.
9. **FAQ-Antworten** für die drei Leistungsseiten (die Sektion erscheint nur
mit Antworten).
10. **Zweiter Vortrag**: Darf „Unlock your Sales-DNA“ gelistet werden, mit
welchem Inhalt? Weitere Vorträge?
11. **Speaker-Profil-PDF**: existiert oder wird erstellt (Kurzvita, Themen,
Fotos, Technik)?
12. **Zusagen**: „Antwort innerhalb von 24 Stunden“ ja/nein? Kostenfreies
30-Minuten-Kennenlerngespräch bestätigen.
13. **Testimonials/Referenzen**: Zitate mit Name, Rolle, Unternehmen und
schriftlicher Einwilligung? Logos mit Erlaubnis? herCAREER-Logo-Erlaubnis
(sonst bleibt es beim reinen Textlink aktuell so umgesetzt).
14. **Zielgruppen-Gewichtung**: B2B zuerst oder Einzelpersonen zuerst?
(Reiner Copy-Tausch: Reihenfolge in „Leistungen“ und Hero-Subline.)
15. **Sprache**: zum Launch nur Deutsch; englische Route später?
„Deutsch & Englisch“ im Masthead bezieht sich auf ihre Leistungen, nicht
auf die Website.
16. **Marke**: „WOLF-Prinzip“ wird von Dritten verwendet Markenrecherche
empfohlen. Bis zur Eintragung sagt die Seite „Bezeichnung“, nie „Wortmarke“.
17. **Nach dem 23.10.2026**: Wer pflegt den Termine-Block, und wann?
(Siehe Abschnitt 6.)
---
## 8. QA-Log
Geprüft am 03.09.2026 gegen den laufenden Dev-Server und den
Produktions-Build.
### Automatisiert / Build
| Prüfung | Ergebnis |
|---|---|
| `npx tsc --noEmit -p tsconfig.json` | fehlerfrei |
| `npm run lint` (ESLint) | fehlerfrei |
| `npm run build` | erfolgreich, 12 statische Seiten |
| Routen in `out/` | `/`, `/leistungen/coaching/`, `/leistungen/trainings/`, `/leistungen/keynotes/`, `/impressum/`, `/datenschutz/`, `404.html` (+ `_not-found/`) alle vorhanden |
| `localStorage` / `sessionStorage` / `document.cookie` in `out/` | **kein Treffer** (HTML, JS, CSS geprüft) |
| Externe Origins in den HTML-Dateien | nur `anelia-wolf.com`, `linkedin.com`, `her-career.com`, `bfdi.bund.de`, `schema.org`, `w3.org` (SVG-Namespace) |
| Externe Ressourcen | keine: 0 iframes, alle `<script src>` unter `/_next/`, alle 18 `@font-face` zeigen auf lokale `.woff2` in `_next/static/media/`. Die Treffer `nextjs.org`, `react.dev`, `gsap.com`, `github.com` liegen ausschließlich als Text in Fehlermeldungen und Lizenzkommentaren in Vendor-Bundles **keine Requests**. |
| Genau ein `<h1>` je Seite | erfüllt auf allen 9 gebauten HTML-Dateien |
### Visuell / im Browser
| Prüfung | Ergebnis |
|---|---|
| Startseite 1440 × 900: Hero, Formel-Bühne → Sektion 04, Kontakt-Sektion | korrekt; Header überlagert keinen Inhalt, Nav vollständig sichtbar |
| Startseite 390 × 844 (mobil): Hero | korrekt; „Menü“-Trigger, Masthead zweizeilig, kein Überlauf |
| Horizontaler Überlauf (`scrollWidth == innerWidth`) | erfüllt auf `/`, allen drei Leistungsseiten (390 px) sowie Impressum, Datenschutz und 404 (375 px) |
| Display-Untergrenze 28 px | erfüllt: kein Display-Text unter 28 px auf Startseite und Leistungsseiten |
| Gold nur auf dunklem Grund | erfüllt: `--gold` (`#c9a24d`) nur auf Ink, heller Grund nutzt `--gold-deep` / `--gold-700` |
| Farbwechsel an Blockgrenzen | kein Text auf der falschen Palette; jeder Block malt seinen eigenen Grund, Gold-Haarlinie sitzt auf der Naht |
| Seitenübergreifende Anker | `/leistungen/coaching/` → Header „Kontakt“ landet auf `/#kontakt`, Sektion 89 px unter Fensterkante = Header 73 px + 16 px Offset; `/leistungen/keynotes/` → Footer „Über Anelia“ landet identisch auf `/#ueber` |
| `prefers-reduced-motion` | Hero identisch zur Normalansicht; Seitenhöhe fällt von 10 248 px auf 8 362 px, weil die Formel-Bühne wie vorgesehen zusammenklappt |
| Flag-gesteuerte Blöcke | Keynotes-Seite rendert bei `showSpeakerPdf: false` und fehlendem PDF **keinen** leeren „Für Veranstalter“-Block |
| 404 mobil | Monogramm über die Breite skaliert, kein Überlauf |
### Hinweis zu Screenshots aus der Entwicklung
In Screenshots vom Dev-Server erscheint unten links ein rundes schwarzes
Symbol mit „N“. Das ist der **Next.js-Devtools-Indikator** des
Entwicklungsservers (`<nextjs-portal>`), **nicht Teil der Website** im
Produktions-Build aus `out/` ist er nicht vorhanden.
### Nicht geprüft / bewusst offen
- Reale Endgeräte (nur Chrome-Headless mit Viewport-Emulation getestet),
Safari/iOS und Firefox.
- Screenreader-Durchlauf mit NVDA/VoiceOver (Struktur, Fokusreihenfolge und
Kontraste sind geprüft, ein echter Vorlesedurchlauf steht aus).
- Verhalten mit eingespielten echten Fotos und echtem Logo-SVG die
Drop-in-Pfade sind implementiert und dokumentiert, aber mit den finalen
Dateien noch nicht durchlaufen.
- Alles unter Abschnitt 5 (Rechtstexte) und Abschnitt 7 (offene Fragen).
---
## 9. Kurz-Checkliste für den Livegang
- [ ] Logo-SVG und Fotos nach `public/brand/` bzw. `public/photos/` legen
- [ ] LEGAL_TODO und CONTENT_TODO in `src/lib/legal.ts` abgearbeitet
- [ ] `flags.showPlaceholders = false`, `npm run build` läuft durch
- [ ] Freigegebene Blöcke per Flag eingeschaltet (FAQ, Stimmen, Speaker-PDF …)
- [ ] `hostOutsideEu` korrekt gesetzt, AV-Verträge mit Hoster und E-Mail-Anbieter
- [ ] Domain in `src/lib/site.ts` stimmt, HTTPS aktiv, 404-Seite konfiguriert
- [ ] `out/` hochgeladen, alle zwölf Routen im Browser geprüft (sechs deutsch, sechs englisch)
- [ ] Sprachumschalter auf jeder Seite geprüft: er führt auf dieselbe Seite in der anderen Sprache, nicht auf die Startseite
- [ ] Kalendereintrag für den 24.10.2026 (Termine-Block, Abschnitt 6)
---
## 10. Temporäre Testseiten (vor dem Livegang löschen)
Zwei interne Seiten zur Schriftwahl. Beide sind nicht verlinkt, stehen nicht in der
Sitemap, tragen `noindex` und sind in der `robots.txt` gesperrt.
| Route | Zweck |
|---|---|
| `/schrift-test/` | Der Hero in 27 Schriftpaarungen untereinander, mit Index am rechten Rand |
| `/schrift-test/seite/` | Die vollständige Startseite mit Umschalter zwischen drei Paarungen |
Die Paarungen 01 bis 19 stammen aus der Liste von pagecloud, 20 bis 26 sind eigene
Vorschläge. Auf der Vergleichsseite hängt der Wechsel an zwei CSS-Variablen auf `<html>`:
`--font-bodoni` für die Display-Schrift, `--font-jost` für den Text. Deshalb wechseln auch
Kopf- und Fußzeile mit, obwohl die im Root-Layout stehen.
**Löschen:** den Ordner `src/app/(de)/schrift-test/` entfernen und die Zeile mit `disallow`
in `src/app/robots.ts` zurücksetzen. Damit verschwinden rund 40 Schriftfamilien und
etwa 4,9 MB Schriftdateien wieder aus dem Build. Die eigentlichen Seiten laden davon
nichts: Die Startseite lädt drei Schriftdateien, vorher wie nachher.
Wenn die Entscheidung auf eine andere Paarung fällt, sind es zwei Stellen:
`src/lib/fonts.ts` (die drei `next/font`-Aufrufe) und `src/app/globals.css`
(die Fallback-Listen in `--font-display` und `--font-sans`).