Files
tsv08kulmbach-website/config/config.example.php
fs 3fa521eaf1 Design-System: Typo-Skala schließen, h4–h6 auf Abel, Icon-Größen tokenisieren
Zweiter Teil der Konsolidierung. Vorher standen 31 font-size-Werte außerhalb
der Skala — beim Durchgehen stellte sich heraus, dass 20 davon gar keine
Textgrößen sind: der icon()-Helper rendert 1em, also steuerte font-size dort
die Icon-Größe. Dafür gibt es jetzt eine eigene, kleine Skala (--icon-s/m/l/xl
in rem, --icon-inline-sm/--icon-inline/--icon-inline-lg in em für Icons, die im
Textfluss mitwachsen sollen). Elf Ad-hoc-Werte fallen damit auf sieben Stufen.

h4–h6 laufen nicht mehr über Coolvetica. Sie lagen mit 26px und 21px unter der
--fs-650-Grenze aus CLAUDE.md, ab der der Condensed-Schnitt in Uppercase
unleserlich wird — die Regel war also nur dokumentiert, nicht durchsetzbar.
Jetzt tragen h1–h3 Coolvetica (alle über der Grenze) und h4–h6 Abel mit
Sperrung. Bezeichnend: das einzige <h4> im Markup hatte sich genau dieses
Muster bereits von Hand gebaut. Die Basisregel liefert es jetzt, die Komponente
gibt ihre drei Duplikat-Deklarationen ab — sichtbar ändert sich dadurch nichts.

Neue Stufen schließen die Lücken: --fs-550 (fluider Lead), --fs-690 (Karten-
Überschrift) und --fs-1000 (Display-Hero). Vier fast deckungsgleiche clamp()-
Rampen für Karten-Überschriften (bento__heading, bento__stat-value,
group-card__name, team-card__name) laufen jetzt über --fs-690; team-card__name
wächst dabei am Desktop um ~5px, die anderen drei bleiben im 1px-Bereich.

Die Wappen-Initialen im Matchcenter hingen an zwei Mini-Schriftgrößen (10,4 und
11,2px) unterhalb der Skala. Sie sind in Wahrheit ~0,4 × Kreisdurchmesser,
folgen jetzt also --crest-size statt einer eigenen font-size. Nebenbei fallen
drei redundante Doppel-Selektoren weg: .crest--initials trägt immer auch .crest.

Ebenfalls tokenisiert: 27 letter-spacing-Werte mit elf verschiedenen Zahlen auf
vier Stufen (--ls-tight/caps/wide/wider), maximale Abweichung 0,02em.

Danach steht kein font-size- und kein letter-spacing-Wert mehr außerhalb von
tokens.css.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MSsVdooFLgPA8gPFp7HwZU
2026-07-27 10:17:13 +02:00

98 lines
5.3 KiB
PHP
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.
<?php
/**
* Vorlage für config/config.php — kopieren und Werte eintragen:
* cp config/config.example.php config/config.php
*
* config.php ist gitignored und liegt außerhalb des Webroots (zusätzlich per .htaccess gesperrt).
*
* ---------------------------------------------------------------------------
* CRONJOBS (im KAS anlegen, Typ „eigener Cronjob“ / Shell)
* ---------------------------------------------------------------------------
* SITE=/www/htdocs/<KAS-User>/tsv08kulmbach (echten Pfad einsetzen: pwd auf dem Server)
* PHP=/usr/bin/php (All-Inkl ggf. /usr/local/bin/php8.2 — `which php8.2` prüft es)
*
* # Instagram-Feed: 2×/Tag (versetzte Minuten, damit die Läufe sich nicht überlappen)
* 17 6,18 * * * cd $SITE && $PHP bin/instagram-sync.php >> storage/logs/instagram.log 2>&1
*
* # Matchcenter: 2×/Tag als Grundtakt
* 37 7,19 * * * cd $SITE && $PHP bin/matchcenter-sync.php >> storage/logs/matchcenter.log 2>&1
*
* # Matchcenter am Spieltag-Nachmittag/Abend ½-stündlich (Sa+So 1321 Uhr),
* # damit Ergebnisse und Tabelle zeitnah stehen.
* 7,37 13-21 * * 6,0 cd $SITE && $PHP bin/matchcenter-sync.php >> storage/logs/matchcenter.log 2>&1
*
* # Logrotation: sonntags nachts, damit spam.log/php-errors.log nicht unbegrenzt wachsen.
* 23 3 * * 0 cd $SITE && $PHP bin/log-rotate.php > /dev/null 2>&1
*
* Alle Skripte sind CLI-only; die Syncs sperren sich per Lock gegen Parallelläufe und lassen
* bei jedem Fehler den letzten guten Cache stehen — ein fehlgeschlagener Lauf schadet nie.
* Erstlauf nach dem Deploy einmal von Hand anstoßen (füllt Cache + Bilder/Wappen).
*
* ---------------------------------------------------------------------------
* NACH DEM DEPLOY
* ---------------------------------------------------------------------------
* php bin/preflight.php Config, Secrets, Schreibrechte, vendor/, PHP-Version prüfen
* php bin/smtp-test.php SMTP-Login testen (ohne Mailversand)
* danach je eine Testmail über /kontakt, /mitglied-werden und /sportheimbuchung
*/
return [
// Kanonische Basis-URL ohne trailing slash (für Canonical, OG, Sitemap).
'base_url' => 'https://www.tsv08kulmbach.de',
// 'production' oder 'development' (steuert Fehleranzeige).
'env' => 'production',
// Geheimer Schlüssel für die HMAC-Time-Trap der Formulare und den IP-Hash im Spam-Log.
// Generieren mit: php -r "echo bin2hex(random_bytes(32));"
// Für Produktion einen EIGENEN Wert erzeugen — nie den aus der lokalen Dev-Config
// übernehmen. Solange hier CHANGE_ME steht, weisen die Formular-Actions jeden
// Versand ab (config_problems()), damit die Time-Trap nie mit einem bekannten
// Schlüssel läuft.
'app_secret' => 'CHANGE_ME',
// All-Inkl SMTP (Postfach im KAS anlegen; Host = <KAS-Login>.kasserver.com).
// Verbindung testen ohne Mailversand: php bin/smtp-test.php
'smtp' => [
'host' => 'w01ca75d.kasserver.com',
'port' => 587, // STARTTLS
'username' => 'noreply@tsv08kulmbach.de', // volle Postfach-Adresse
'password' => 'POSTFACH_PASSWORT',
// Absender: das authentifizierte Postfach (gleiche Domain, sonst lehnt All-Inkl ab).
'from' => 'noreply@tsv08kulmbach.de',
'from_name' => 'TSV 08 Kulmbach',
// Empfänger der Formular-Mails.
'to' => 'info@tsv08kulmbach.de',
],
// Instagram-Scraper (bin/instagram-sync.php).
'instagram' => [
'username' => 'tsv08kulmbach',
'max_posts' => 9,
],
// Matchcenter-Scraper (bin/matchcenter-sync.php) — Spielplan/Ergebnisse/Tabelle
// aus der öffentlichen BFV-Widget-JSON-API. Die IDs sind keine Geheimnisse
// (sie steckten schon im alten BFV-Widget-Embed) und dürfen hier stehen.
'matchcenter' => [
// Referer für die BFV-Requests (gegen HTTP 418).
'referer' => 'https://widget-prod.bfv.de/',
'max_upcoming' => 5, // anstehende Spiele pro Team + im globalen Slider
'max_results' => 5, // letzte Ergebnisse pro Team
// key = Schlüssel in data/teams.json (für kuratierten Namen/Liga/Slug),
// team_id = BFV permanentId (saison-stabil). compound_id = Wettbewerbs-ID
// der Tabelle — nur Fallback: der Scraper leitet die aktuelle compoundId
// automatisch aus der Matches-API ab, sodass eine neue Saison von selbst
// übernommen wird. compound_id nur pflegen, falls die Auto-Erkennung mal fehlt.
'teams' => [
['key' => 'erste-mannschaft', 'team_id' => '016PKHIPIO000000VV0AG811VUDIC8D7', 'compound_id' => '02TBKEVREG000006VS5489BTVVQ0O654-G'],
// Vorerst deaktiviert (27.07.2026): Die BFV-Mannschaft hinter dieser ID lief in
// der Saison 25/26 als „(SG1) TSV Melkendorf I/ TSV 08 Kulmbach II" und liefert
// in 26/27 nur noch „TSV Melkendorf" — also Spiele ohne den TSV 08. Erst nach
// Klärung im Verein wieder aktivieren (ggf. mit neuer team_id).
// ['key' => 'zweite-mannschaft', 'team_id' => '016PCRVRJC000000VV0AG811VTE5EA5R', 'compound_id' => '02TD8CKMD8000006VS5489BTVTLPPK10-G'],
['key' => 'damen', 'team_id' => '01HLQ7QVES000000VV0AG80NVVKQLCU9', 'compound_id' => '02TK5AGFE0000004VS5489BUVVPGA9RV-G'],
],
],
];