556 lines
28 KiB
Markdown
556 lines
28 KiB
Markdown
# Ü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 7–14 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`).
|