first publish
This commit is contained in:
555
docs/HANDOVER.md
Normal file
555
docs/HANDOVER.md
Normal 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 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`).
|
||||
Reference in New Issue
Block a user