feat(privat/CV): sync to latest upstream (cv-upstream/main, 30f9608b)

This commit is contained in:
2026-07-07 15:20:55 +02:00
parent 8ac664d33d
commit a4efabbc60
417 changed files with 48564 additions and 712 deletions
@@ -0,0 +1,418 @@
# Implementation Plan: personal-homepage (andreknie.de)
## Overview
Build a personal homepage for Dr. Andre Knie at andreknie.de using Vite 8 + React 19 (JSX), react-router-dom v7, Express 5 backend, CSS custom properties theming, file-based CMS (content/ directory with markdown + YAML), and Docker + Caddy deployment. The Projekt-KIQ-HP reference (cloned at reference/Projekt-KIQ-HP/) serves as a code reference for visual patterns (glass morphism, animated background, bottom dock, bento grid).
## Tasks
- [x] 1. Project scaffolding and core infrastructure
- [x] 1.1 Initialize project with Vite 8 + React 19 and configure tooling
- Create new repository `andreknie.de/` with `npm create vite@latest` (React template)
- Install dependencies: react-router-dom v7, vite (v8), vitest, fast-check, @testing-library/react
- Configure `vite.config.js` with plugin slot for content loader
- Create `.env.example` with SMTP and server config placeholders
- Set up `vitest.config.js` with jsdom environment
- _Requirements: 18.1, 18.2_
- [x] 1.2 Create CSS theming system with custom properties
- Create `src/index.css` with full `:root` variable block (colors, spacing, typography, transitions, radii)
- Use placeholder neutral blue (`#4a9eff`) as accent color
- Define glass morphism utility classes (`.glass-panel`, `.text-gradient`, `.bento-glow`)
- Import Inter font from Google Fonts
- Implement dark theme base (`--bg-color: #0a0a0a`)
- _Requirements: 17.1, 17.2_
- [x] 1.3 Create directory structure for content, server, and plugins
- Create `content/` with subdirectories: posts/, kniepunkt/, podcast/, talks/, consulting/, resources/, events/, meta/
- Create `public/` with subdirectories: images/, logos/, resources/, patterns/
- Create `server/` with subdirectories: routes/, middleware/, services/, data/
- Create `plugins/` directory
- Create `src/` with subdirectories: components/, pages/, hooks/, utils/, data/
- _Requirements: 14.1, 14.3_
- [x] 1.4 Create sample content files for all content types
- Create `content/meta/profile.yaml` with stakeholder profile data (name, roles, summary, positioning, dHive info)
- Create `content/meta/stats.yaml` with key facts (50+ Projekte, 13+ Jahre KI, 60+ Publikationen, 100% DSGVO & AI-Act)
- Create `content/meta/audiences.yaml` with target audience descriptions
- Create at least 1 sample file per content type (post, kniepunkt issue, podcast episode, talk, consulting example, resource, event)
- Follow exact YAML/frontmatter schemas from design document
- _Requirements: 1.1, 1.2, 1.4, 2.1, 14.1, 15.1_
- [x] 2. Vite content plugin and content utilities
- [x] 2.1 Implement `plugins/vite-plugin-content.js` for build-time content transformation
- Read all files from `content/` subdirectories at build time
- Parse markdown files with frontmatter (gray-matter) into JSON (title, date, tags, summary, body as HTML via marked/remark)
- Parse YAML files into JSON objects
- Validate required fields per content type (warn on missing, don't fail build)
- Export transformed content as virtual modules importable by React components
- _Requirements: 14.1, 14.2, 14.3_
- [x] 2.2 Implement `src/utils/contentLoader.js` for runtime content access
- Implemented as `src/hooks/useContent.js` (loading by type, sorting by date desc, tag filtering)
- Create utility functions to load content by type (getPosts, getTalks, getConsultingExamples, etc.)
- Implement sorting by publication date descending (newest first)
- Implement tag extraction for dynamic filter options (max 20 distinct tags)
- Implement content-area validation (reject invalid content-area values with error message)
- _Requirements: 13.4, 13.5, 14.4, 14.5_
- [ ]* 2.3 Write property tests for content transformation and validation (Property 10)
- **Property 10: Content file validation**
- Generate arbitrary content objects with random missing/invalid fields
- Assert: missing required attributes → rejection with error indicating missing fields
- Assert: invalid content-area → rejection with error listing valid areas
- **Validates: Requirements 9.4, 14.1, 14.4**
- [ ]* 2.4 Write property tests for content list sorting (Property 2)
- **Property 2: Content list sorting**
- Generate arbitrary lists of content objects with random dates
- Assert: output is always sorted by publication date descending
- **Validates: Requirements 3.3, 7.3, 8.2, 14.5**
- [ ]* 2.5 Write property tests for dynamic filter derivation (Property 8)
- **Property 8: Dynamic filter options derived from content**
- Generate arbitrary sets of content objects with random tags
- Assert: available filter options = complete set of distinct tags (up to 20)
- **Validates: Requirements 13.4, 13.5**
- [ ] 3. Checkpoint — Content pipeline verified
- Ensure all tests pass, ask the user if questions arise.
- [x] 4. Shared UI components
- [x] 4.1 Implement BackgroundPattern, GlassCard, and BentoGrid components
- BackgroundPattern implemented (canvas particle field); glass/grid realized via `.glass-panel` utility + per-page grids
- `BackgroundPattern.jsx` + `.css`: animated drifting SVG background (mirrored-quadrant technique from reference)
- `GlassCard.jsx` + `.css`: reusable glass-morphism card with backdrop-filter blur
- `BentoGrid.jsx` + `.css`: responsive grid layout for content cards with hover glow effect
- Reference: Projekt-KIQ-HP patterns for visual implementation
- _Requirements: 17.1, 17.2_
- [x] 4.2 Implement Navigation and BottomDock components
- Navigation uses written-out top-bar links (no hamburger overlay, per stakeholder preference)
- `Navigation.jsx` + `.css`: top bar with logo + hamburger overlay menu (same overlay pattern from reference)
- `BottomDock.jsx` + `.css`: fixed bottom navigation pill with rotating conic-gradient light border
- Navigation items: Home, Kniepunkt, Podcast, Speaking, Consulting, Resources, Kontakt
- _Requirements: 1.1_
- [x] 4.3 Implement Footer with dHive cross-reference and newsletter form slot
- `Footer.jsx` + `.css`: CTA section + newsletter form slot + legal links (Impressum, Datenschutz)
- Include visible link to d-hive.de with stakeholder role (Founder & Managing Director)
- dHive branding ≤ 20% of section area, positioned after personal name/title
- Link opens in new tab (`target="_blank"`)
- _Requirements: 16.1, 16.2, 16.3_
- [ ] 4.4 Implement ContentFilter and Pagination components
- OPEN: dedicated ContentFilter, Pagination, SEOHead components not yet implemented (ScrollToTop exists)
- `ContentFilter.jsx` + `.css`: tag-based filtering UI, derives options dynamically from content metadata
- `Pagination.jsx` + `.css`: page navigation for lists (10 items per page)
- `ScrollToTop.jsx`: scroll restoration on route change
- `SEOHead.jsx`: meta tags per page
- _Requirements: 13.1, 13.2, 13.3, 8.3_
- [ ]* 4.5 Write property tests for content filtering (Property 7)
- **Property 7: Content filtering returns only matching items**
- Generate arbitrary content sets with random tags and arbitrary filter selections
- Assert: filtered result contains exactly those items whose tags include the selected criterion
- **Validates: Requirements 13.1, 13.2**
- [ ]* 4.6 Write property tests for pagination (Property 12)
- **Property 12: Pagination constraint**
- Generate arbitrary lists of items (length 0100)
- Assert: each page contains at most 10 items; pagination controls present when items > 10
- **Validates: Requirements 8.3**
- [x] 5. App shell and routing
- [x] 5.1 Implement App.jsx with react-router-dom v7 routing
- Set up `App.jsx` with BackgroundPattern, Navigation, Routes, Footer, BottomDock
- Configure routes: `/`, `/kniepunkt`, `/kniepunkt/:slug`, `/podcast`, `/speaking`, `/consulting`, `/resources`, `/kontakt`, `/impressum`, `/datenschutz`
- Add 404 fallback route with friendly error page
- Implement `main.jsx` entry point with BrowserRouter
- _Requirements: 3.4, 18.4_
- [x] 5.2 Implement custom hooks (useContent, useFormSubmit)
- useContent, useFormSubmit, validation.js, formatDate.js all present
- `src/hooks/useContent.js`: content loading, filtering by tag, sorting, pagination
- `src/hooks/useFormSubmit.js`: form submission with validation, error handling, loading state
- `src/utils/validation.js`: email format validation, field presence checks, length constraints
- `src/utils/formatDate.js`: German locale date formatting
- _Requirements: 13.1, 13.2, 4.4, 11.5, 12.5_
- [x] 6. Page implementations — Home and content pages
- [x] 6.1 Implement HomePage with Hero, Stats, ContentHighlights, AudienceSection, CTASection
- Home includes Hero, StatsCube, photo-band, Mein-Ansatz (positioning), Audiences, LogoMarquee, Testimonials, UpcomingEvents
- `Hero.jsx`: stakeholder name, professional photo, summary (≤150 words), all roles listed
- `Stats.jsx`: key facts from stats.yaml in animated counters
- `AudienceSection.jsx`: explicitly name target audiences (mid-sized companies, HR, OD, IT leaders, managing directors)
- `ContentHighlights.jsx`: latest content from each area
- `CTASection.jsx`: call-to-action for contact/speaking
- Profile visible without scrolling on 1280×720 viewport
- _Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 2.1, 2.3, 2.4, 17.3, 17.4, 17.5_
- [x] 6.2 Implement KniepunktPage and KniepunktIssuePage
- `Kniepunkt.jsx`: distinct labeled section, list of all newsletter issues (title + date), sorted newest first, with ContentFilter
- `KniepunktIssue.jsx`: full rendered markdown content of selected issue
- Visually separated from other homepage content
- _Requirements: 7.1, 7.2, 7.3, 7.4_
- [x] 6.3 Implement PodcastPage
- 12 episodes with Spotify/Apple/YouTube/Castro links
- `Podcast.jsx`: visually distinct section with podcast name, description, episode listing
- Episodes: title, date, summary, sorted reverse-chronological
- Max 10 episodes per page with Pagination component
- Each episode links to audio on hosting platform or embedded player
- Empty state message when no episodes available
- _Requirements: 8.1, 8.2, 8.3, 8.4, 8.5_
- [x] 6.4 Implement SpeakingPage with talk list and talk request form
- `Speaking.jsx`: list of talks with topic title, description, format (keynote/workshop/panel), past events
- Show at least 3 speaking examples with topic title, event name, and format
- Include TalkRequestForm component (implemented in task 7)
- Hide section if no talks available
- _Requirements: 2.2, 5.1, 5.2, 5.3, 5.4_
- [x] 6.5 Implement ConsultingPage
- ServiceAccordion + 3 consulting examples (OPEN: more examples per MATERIAL-LISTE)
- `Consulting.jsx`: BentoGrid of ExampleCards (310 examples)
- Each card: title, industry tag, org-size category (505000 employees), problem domain, approach, outcomes
- No client names, revenue figures, or internal identifiers exposed
- Informational message if no examples available
- _Requirements: 6.1, 6.2, 6.3, 6.4_
- [x] 6.6 Implement ResourcesPage with lead capture
- OPEN: no resource content files yet (content/resources/ empty)
- `Resources.jsx`: list of resources with title, short description (≤200 chars), download indicator
- `LeadCaptureForm.jsx`: modal form requiring name (max 100), email (validated), company (max 150)
- Display required fields and purpose before submission
- Inline validation errors with data retention on failure
- _Requirements: 4.1, 4.2, 4.3, 4.4, 4.6_
- [x] 6.7 Implement ContactPage, Impressum, and Datenschutz
- OPEN: Impressum/Datenschutz contain placeholder legal data (needs real address, USt-IdNr)
- `Contact.jsx`: contact form with name, email, message (max 2000 chars), validation errors per field
- `Impressum.jsx`: static legal content
- `Datenschutz.jsx`: static privacy policy content
- _Requirements: 11.1, 11.5_
- [ ] 6.8 Implement Events display (within relevant pages or as section)
- UpcomingEvents component exists, but content/events/ is empty — OPEN: add event content
- Display events grouped by year, upcoming before past, each group sorted by date descending
- Each event: title, date (ISO 8601), location, event type, description (≤300 chars)
- _Requirements: 9.1, 9.2, 9.3_
- [ ]* 6.9 Write property tests for content rendering completeness (Property 1)
- **Property 1: Content rendering completeness**
- Generate arbitrary content objects per type with all required fields
- Assert: rendered output contains all required fields for that type
- **Validates: Requirements 3.1, 3.2, 3.5, 4.1, 5.2, 6.1, 6.3, 7.2, 8.2, 8.4**
- [ ]* 6.10 Write property tests for event chronological grouping (Property 9)
- **Property 9: Event chronological grouping**
- Generate arbitrary event sets with dates spanning past and future
- Assert: upcoming events appear before past events; each group sorted by date descending; grouped by year
- **Validates: Requirements 9.2**
- [ ] 7. Checkpoint — Frontend pages complete
- Ensure all tests pass, ask the user if questions arise.
- [x] 8. Express 5 backend — form handling and confirmation flow
- [x] 8.1 Set up Express 5 server with middleware
- `server/index.js`: Express 5 entry point with JSON body parsing, CORS, error middleware
- `server/middleware/rateLimiter.js`: rate limiting per endpoint (contact: 3/h, talk: 3/h, newsletter: 5/h, resource: 10/h)
- `server/middleware/validator.js`: input validation middleware (field presence, email format, length constraints)
- Health check endpoint: `GET /api/health`
- _Requirements: 11.1, 12.1_
- [x] 8.2 Implement confirmation token service
- `server/services/confirmationToken.js`: generate unique tokens (crypto.randomUUID), store with expiration, verify, cleanup expired
- Token storage in JSON files under `server/data/`
- Contact tokens expire after 24h, talk request and newsletter tokens after 48h
- Scheduled cleanup interval (every hour) for expired tokens
- _Requirements: 10.3, 10.4, 11.2, 11.4, 12.2, 12.4_
- [x] 8.3 Implement mailer service with nodemailer
- `server/services/mailer.js`: nodemailer configuration from environment variables
- Email templates: confirmation email (with unique link), stakeholder notification email
- Send exactly one confirmation email per valid submission
- _Requirements: 10.3, 11.2, 12.2_
- [x] 8.4 Implement contact form route with double opt-in
- `server/routes/contact.js`: POST `/api/contact` — validate, store pending, send confirmation email
- POST `/api/contact/confirm/:token` — verify token, forward message to stakeholder, mark confirmed
- Reject expired/invalid tokens with appropriate status codes (404/410)
- _Requirements: 11.1, 11.2, 11.3, 11.4, 11.5_
- [x] 8.5 Implement talk request route with double opt-in
- `server/routes/talk-request.js`: POST `/api/talk-request` — validate (name, email, event_name, topic, message), store pending, send confirmation
- POST `/api/talk-request/confirm/:token` — verify token (48h), forward to stakeholder
- _Requirements: 12.1, 12.2, 12.3, 12.4, 12.5_
- [x] 8.6 Implement newsletter signup route with double opt-in
- `server/routes/newsletter.js`: POST `/api/newsletter` — validate email, check for existing subscription, store pending, send confirmation
- GET `/api/newsletter/confirm/:token` — verify token (48h), activate subscription, create Sales_Funnel entry
- Detect and reject duplicate subscriptions with informational message
- Discard unconfirmed subscriptions after 48h
- _Requirements: 10.1, 10.2, 10.3, 10.4, 10.5, 10.6_
- [x] 8.7 Implement resource download route with lead capture
- `server/routes/resource-download.js`: POST `/api/resource-download` — validate (name, email, company, resource_id), store lead record with timestamp, return download URL
- Lead record must be retrievable for Sales_Funnel development
- _Requirements: 4.2, 4.3, 4.5_
- [ ]* 8.8 Write property tests for form validation (Property 3)
- **Property 3: Form validation rejects invalid input**
- Generate arbitrary form payloads with random missing/invalid fields
- Assert: invalid submissions are rejected with field-level errors; valid data retained
- **Validates: Requirements 4.4, 10.5, 11.5, 12.5**
- [ ]* 8.9 Write property tests for token expiration (Property 4)
- **Property 4: Confirmation token expiration**
- Generate tokens with arbitrary creation times and verify against expiration windows
- Assert: expired tokens are rejected; associated records discarded
- **Validates: Requirements 10.4, 11.4, 12.4**
- [ ]* 8.10 Write property tests for valid submission triggering confirmation (Property 5)
- **Property 5: Valid submission triggers confirmation email**
- Generate arbitrary valid form submissions (all fields present, valid email)
- Assert: unique token generated, pending request stored, exactly one confirmation email sent
- **Validates: Requirements 10.3, 11.2, 12.2**
- [ ]* 8.11 Write property tests for valid token confirmation (Property 6)
- **Property 6: Valid token confirmation forwards to stakeholder**
- Generate valid unexpired tokens with associated pending records
- Assert: confirmation results in forwarding to stakeholder and record marked confirmed
- **Validates: Requirements 11.3, 12.3**
- [ ]* 8.12 Write property tests for lead data storage (Property 11)
- **Property 11: Lead data storage integrity**
- Generate arbitrary valid lead capture submissions
- Assert: stored record contains all submitted fields + resource_id + timestamp; record is retrievable
- **Validates: Requirements 4.5**
- [ ]* 8.13 Write property tests for duplicate subscription detection (Property 13)
- **Property 13: Duplicate subscription detection**
- Generate arbitrary email addresses, some already in active subscriptions
- Assert: duplicate emails are rejected with informational message; no duplicate entry created
- **Validates: Requirements 10.6**
- [ ] 9. Checkpoint — Backend API complete
- Ensure all tests pass, ask the user if questions arise.
- [ ] 10. Integration and wiring
- [x] 10.1 Wire frontend forms to backend API endpoints
- useFormSubmit posts to /api endpoints with success/error handling
- Connect ContactForm to POST `/api/contact`
- Connect TalkRequestForm to POST `/api/talk-request`
- Connect NewsletterForm to POST `/api/newsletter`
- Connect LeadCaptureForm to POST `/api/resource-download`
- Handle success/error responses with appropriate UI feedback (toast notifications, success messages)
- _Requirements: 10.1, 11.1, 12.1, 4.2_
- [ ] 10.2 Create confirmation landing pages
- OPEN: inline success messages exist, but dedicated email-confirmation landing pages / token-confirm routes in the SPA are not yet built
- Success page shown after email confirmation (contact, talk request)
- Newsletter confirmation success page
- Expired/invalid token error page
- _Requirements: 11.2, 11.3, 12.2, 12.3_
- [ ]* 10.3 Write integration tests for form submission flows
- Test contact form: submit → pending stored → confirmation email triggered
- Test talk request: submit → pending stored → confirmation email triggered
- Test newsletter: submit → pending stored → double opt-in email triggered
- Test resource download: submit lead data → lead stored → download URL returned
- _Requirements: 10.2, 10.3, 11.2, 11.3, 12.2, 12.3, 4.5_
- [ ] 11. Deployment configuration
- [x] 11.1 Create Dockerfile and docker-compose.yml for backend
- Dockerfile: Node.js image, install dependencies, run Express server on port 3003
- docker-compose.yml: single `backend` service, volume mount for `server/data/`, env file reference
- _Requirements: 18.1_
- [x] 11.2 Create Caddyfile for production serving
- Auto HTTPS via Let's Encrypt for andreknie.de
- Reverse proxy `/api/*` to Express backend on port 3003
- Serve static SPA files with `try_files {path} /index.html`
- Security headers (HSTS, X-Content-Type-Options, CSP)
- Gzip/zstd compression
- Immutable cache for `/assets/*`
- _Requirements: 18.4_
- [x] 11.3 Configure Vite build with content plugin integration
- vite-plugin-content registered; `npm run build` produces complete dist/ (verified)
- Register `vite-plugin-content` in `vite.config.js`
- Verify `npm run build` produces complete `dist/` with all content embedded
- Ensure build output is deployable as static files to `/opt/andreknie/site/`
- _Requirements: 14.2_
- [ ] 12. Final checkpoint — Full integration verified
- Ensure all tests pass, ask the user if questions arise.
## Notes
- Tasks marked with `*` are optional and can be skipped for faster MVP
- Each task references specific requirements for traceability
- Checkpoints ensure incremental validation
- Property tests validate universal correctness properties from the design document (13 properties total)
- Unit tests validate specific examples and edge cases
- The project is created as a NEW repository — not inside the current CV workspace
- Use `reference/Projekt-KIQ-HP/` as visual pattern reference (glass morphism, animated background, bottom dock, bento grid)
- Colors are placeholder (neutral blue #4a9eff) — easily changeable via CSS custom properties in `:root`
- Content files in `content/` ARE the CMS — no database needed for content
- Backend only handles forms (contact, talk request, newsletter, resource download)
- All forms use double opt-in (confirmation email with token)
- fast-check is the property-based testing library; Vitest is the test runner
## Task Dependency Graph
```json
{
"waves": [
{ "id": 0, "tasks": ["1.1", "1.3"] },
{ "id": 1, "tasks": ["1.2", "1.4"] },
{ "id": 2, "tasks": ["2.1"] },
{ "id": 3, "tasks": ["2.2", "2.3", "2.4", "2.5"] },
{ "id": 4, "tasks": ["4.1", "4.2", "4.3", "4.4", "5.1"] },
{ "id": 5, "tasks": ["4.5", "4.6", "5.2"] },
{ "id": 6, "tasks": ["6.1", "6.2", "6.3", "6.4", "6.5", "6.6", "6.7", "6.8"] },
{ "id": 7, "tasks": ["6.9", "6.10", "8.1"] },
{ "id": 8, "tasks": ["8.2", "8.3"] },
{ "id": 9, "tasks": ["8.4", "8.5", "8.6", "8.7"] },
{ "id": 10, "tasks": ["8.8", "8.9", "8.10", "8.11", "8.12", "8.13"] },
{ "id": 11, "tasks": ["10.1", "10.2"] },
{ "id": 12, "tasks": ["10.3", "11.1", "11.2", "11.3"] }
]
}
```
## Offene Themen (Stand-Abgleich)
Die Kernimplementierung (Frontend-Seiten, Backend-Formulare mit Double-Opt-In, Content-Pipeline, Deployment-Konfiguration) steht und baut fehlerfrei. Offen sind im Wesentlichen Inhalte, Verifikation und optionale Tests.
### Inhalte / Redaktion (blockiert Go-Live)
- [x] Impressum mit echten Daten füllen — Telefon entfernt, E-Mail kontakt@d-hive.de (Task 6.7)
- [ ] Datenschutzerklärung final juristisch prüfen — Inhalt vorhanden, Telefon entfernt, datenschutz@d-hive.de für Betroffenenrechte (Task 6.7)
- [ ] Weitere Consulting-Beispiele (Ziel 5+, aktuell 3) inkl. Leistungsübersicht & Ergebnis-Zahlen (Task 6.5, MATERIAL-LISTE) — *in Arbeit beim Stakeholder*
- [ ] Testimonials final freigeben (3 Entwürfe vorhanden, Freigabe der Personen ausstehend) — *in Arbeit beim Stakeholder*
### Nice to have (Inhalte, kein Go-Live-Blocker)
- [ ] Event-Inhalte ergänzen — `content/events/` ist leer (Task 6.8)
- [ ] Resource-Inhalte ergänzen — `content/resources/` ist leer (Task 6.6)
### Funktionale Lücken
- [ ] Dedizierte ContentFilter-, Pagination- und SEOHead-Komponenten (Task 4.4)
- [ ] Confirmation-Landingpages im SPA (Token-Confirm-Routen, Erfolg/Abgelaufen) — bisher nur Inline-Erfolgsmeldungen (Task 10.2)
### Verifikation & Deployment
- [ ] Backend lokal end-to-end testen (Formular → Bestätigungsmail → Weiterleitung); SMTP-Konfiguration in `.env` erforderlich
- [ ] Produktiv-Deployment durchführen (dist/ auf Server, Docker-Backend starten, Caddy)
### Optionale Property-/Integrationstests (mit `*` markiert, MVP-übersprungen)
- [ ] 2.3, 2.4, 2.5 — Content-Validierung, Sortierung, Filter-Ableitung
- [ ] 4.5, 4.6 — Filterung, Pagination
- [ ] 6.9, 6.10 — Rendering-Vollständigkeit, Event-Gruppierung
- [ ] 8.88.13 — Formularvalidierung, Token-Ablauf, Bestätigungsmail, Lead-Speicherung, Duplikat-Erkennung
- [ ] 10.3 — Integrationstests der Formular-Flows
### Material (siehe `andreknie.de/MATERIAL-LISTE.md`)
- [ ] Professionelles Hero-/Profilbild (freigestellt) — aktuell Platzhalter `andre-knie.jpg`
- [ ] Open-Graph-Image, Favicon
- [ ] Optional: Hero-Video, Testimonial-Videos, Podcast-Cover