# TSV 08 Kulmbach — Website Neubau von tsv08kulmbach.de. Vereinsseite (Fußball + Turnen, gegründet 1908) als sauberer, selbst gehosteter Stack ohne Abhängigkeiten von Drittanbietern. ## Stack & Umgebung - **Frontend:** Natives HTML, Vanilla CSS, Vanilla JS. Kein Framework, keine Build-Pipeline, kein Node. - **Backend:** Vanilla PHP ≥ 8.1, Composer nur für `phpmailer/phpmailer`. Keine Template-Engine. - **Hosting-Ziel:** Apache Shared Hosting, PHP 8.x, `.htaccess`, Cronjobs verfügbar. - **Lokales Dev:** `php -S localhost:8000 -t public public/index.php` (index.php fungiert als Router-Script, weil `php -S` kein .htaccess kennt). - **Docroot:** `public/`. Falls der Hoster nur das Repo-Root serviert, greift die Root-`.htaccess` (Rewrite → `public/`, Deny für alles andere). ## Harte Regeln (nicht verhandelbar) 1. **Keine externen Einbindungen.** Keine CDNs, keine externen Fonts/Scripts/iframes/Embeds, keine Tracking-/Analytics-Dienste, kein reCAPTCHA. Alles wird self-hosted. Einzige erlaubte ausgehende Verbindungen: Brevo SMTP (Mailversand, serverseitig) und der Instagram-Scraper (CLI/Cron, nie im Request-Pfad). Besucher-Browser kontaktieren ausschließlich unsere Domain. Die CSP (`default-src 'self'`) erzwingt das — nicht aufweichen. 2. **`.context/` und `.context_db/` sind reine Referenz** (alte, unsichere CMS-Seite). Von dort werden nur Assets (Bilder/Fonts/Videos), Texte und Styling-Werte extrahiert. **Niemals Code übernehmen, niemals Dateien von dort direkt verlinken.** Assets immer nach `public/assets/` kopieren/optimieren. 3. **Kein Admin-/Pflege-Backend bauen.** Inhalte werden per Chat gepflegt: Claude editiert `data/*.json` bzw. die Seiten-Dateien. Kein Login, keine Schreib-Endpoints. 4. **Sensible Altdaten nie übernehmen:** Aus dem DB-Dump keine Mail-Logs, Formulareinträge, Passwort-Hashes, Tokens oder personenbezogene Daten migrieren. 5. **Secrets nur in `config/config.php`** (gitignored, außerhalb des Webroots, per .htaccess denied). Niemals hardcoden, loggen oder ausgeben. `config/config.example.php` dokumentiert alle Keys. ## Single Source of Truth (vor JEDER Änderung prüfen) | Was | Einzige Quelle | Niemals | |---|---|---| | Farben, Fonts, Spacing, Radii, Schatten | `public/assets/css/tokens.css` | Hex-Werte/Magic Numbers in anderen CSS-Dateien | | Seiten-Slugs & Routing | `app/routes.php` | URLs woanders hart verdrahten | | Navigation (Labels/Reihenfolge) | `data/navigation.json` | Menüpunkte in Templates | | Vereinsdaten (Name, Adresse, Kontakt, Social, Geo) | `data/club.json` | Adresse/E-Mail irgendwo als Text duplizieren | | Startseiten-Inhalte | `data/home.json` | Texte in `pages/home.php` | | Mannschaften (Kader, Trainer, Hero, FAQ) | `data/teams.json` | Spieler-/Trainernamen in Team-Templates | | Fußball-/Jugend-/Vereinsseite (Inhalte) | `data/fussball.json` · `data/jugend.json` · `data/verein.json` | Texte in den jeweiligen `pages/*.php` | | Banner-Slider (Startseite) | `data/banners.json` | Slides in `pages/home.php` oder der Komponente | | Partner/Sponsoren | `data/partners.json` | — | | Instagram-Cache | `data/instagram.json` + `public/assets/img/instagram/` | **maschinenverwaltet von `bin/instagram-sync.php` — nie von Hand editieren** | | Matchcenter (Spiele/Ergebnisse/Tabellen) | `data/matchcenter.json` + `public/assets/img/crests/` | **maschinenverwaltet von `bin/matchcenter-sync.php` — nie von Hand editieren**. Team-/Wettbewerbs-IDs in `config.php` (`matchcenter.teams`) | | Icons | `public/assets/icons/` (Bootstrap Icons, lokal) via `icon()`-Helper | Inline-SVG-Pfade von Hand ins Markup, Emoji/Unicode-Glyphen, gezeichnete CSS-Icons, Icon-Font/CDN | Per-Page-Meta (Title/Description/OG) lebt in der jeweiligen Page-Datei (`app/pages/*.php`) im `$meta`-Array. **Strukturierte Daten (JSON-LD):** Seiten setzen `$meta['schema']` = Array von schema.org-Knoten; `app/components/jsonld.php` hängt sie an den globalen `@graph` (Organization `#club`) an — nie ein `