Files
Orchestrator/privat/CV/.kiro/specs/personal-homepage/tasks.md
T

419 lines
25 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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