Files
tsv08kulmbach-website/app/pages/turnen.php

130 lines
8.0 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
/**
Turn-Beiträge sichtbar machen (standen nirgends auf der Website) Die Turnabteilung verlinkt die Beiträge in Einladungen für neue Familien und nimmt zum September auf — die Angaben waren aber auf der ganzen Website nicht zu finden. Nachgeprüft: 0 Treffer auf /turnen und allen fünf Disziplin-Seiten, /mitglied-werden führt nur die Fußball-Beiträge. Es war keine verlorene Seite, sondern eine Lücke im Code: app/pages/turnen.php rendert nur Hero, Karten und Formular. In data/turnen.json lagen ungenutzt cards_intro, fees (drei Tabellen), austritt und faq (fünf Fragen). Der Docblock behauptete, die Beiträge lägen auf den Unterseiten — sie lagen dort nicht, und in der Git-Historie wurden sie nie gerendert. Inhalte 1:1 wie auf der alten Seite (gegengeprüft an 2024.tsv08kulmbach.de, Tab "Allgemeines"): Zusatzbeitrag 24/48 €, Neumitglieder 84/94/184 €, Förderstufen 120/180/240 €, Austritt zum 30. September. Nichts umformuliert, die Abteilung entscheidet über Änderungen. Struktur jetzt Hero → Karten → Beiträge (#beitraege) → FAQ → Formular. Der Anker ist die Adresse für die Einladungen. Nur bestehende Komponenten benutzt (fee-table wie auf /mitglied-werden, faq, team-cards mit intro); neu ist allein der Wrapper .fee-tables. Die FAQ füllt zusätzlich das FAQPage-Schema, weil page_schema() sie als zweiten Parameter bekommt. Feinschliff nach Sichtprüfung: Kartentitel von --fs-650 auf --fs-675, weil 28px Coolvetica neben 21px Fließtext zu klein wirkten; Karten gleich hoch (der Grid-Default stretch statt align-items: start, gemessen vorher 252/377/471px) mit dem Hinweis am Kartenfuß; und minmax(min(22rem, 100%), 1fr) statt minmax(22rem, 1fr), weil die Karten am Handy 352px breit in einem 347px-Raster standen und überliefen. NOCH offen: overview.cta ist weiter unbenutzt. Der Block verlinkt "Zur Turn-Übersicht" und gehört auf die Disziplin-Unterseiten, nicht auf die Übersicht — dort wäre es ein Selbstlink. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:40:23 +02:00
* Turn-Übersichtsseite (Hub + Beiträge + Abteilungskontakt). Inhalt: data/turnen.json.
* Struktur: Hero Disziplin-Karten Beiträge FAQ Anfrageformular.
*
* Hier stand vorher „Die Detailinhalte (Beiträge, Trainingszeiten) leben auf den
* Disziplin-Unterseiten" — das war falsch, und zwar folgenreich: die Seite gab
* fees/austritt/faq NIE aus, die Unterseiten auch nicht, und damit standen die
* Turn-Beiträge NIRGENDS auf der Website (nachgeprüft 31.07.2026: 0 Treffer auf
* /turnen und allen fünf Unterseiten; /mitglied-werden führt nur die Fußball-
* Beiträge). Die Turnabteilung verlinkt diese Angaben in Einladungen für neue
* Familien, deshalb ist der Beitragsblock hier verankert (#beitraege).
* Die Daten selbst stimmen 1:1 mit der alten Seite überein (gegengeprüft an
* 2024.tsv08kulmbach.de): Zusatzbeitrag 24/48 , Neumitglieder 84/94/184 ,
* Förderstufen 120/180/240 , Austritt zum 30. September.
*
Turn-Anmeldung als eigene FAQ-Frage, Knöpfe in FAQ-Antworten möglich Der Anmelde-Vorgang der Abteilung (erst Platz anfragen, dann Aufnahmeantrag) stand nirgends auf der Seite. Auf der alten Seite gab es dafür einen Block „ANMELDUNG" mit zwei Knöpfen. Erst als eigene Sektion unter den Beiträgen gebaut (cta-band), auf Wunsch von Felix wieder entfernt und stattdessen als eigene FAQ-Frage umgesetzt. Zwei Sektionen mit denselben Knöpfen auf einer Seite schwächen beide Stellen, und man weiß nicht mehr, welcher der richtige Weg ist. Deshalb ist auch overview.cta ganz aus data/turnen.json raus statt unbenutzt liegen zu bleiben — genau so ein toter Block hat heute schon einmal in die Irre geführt (die Notiz „NOCH unbenutzt" stand monatelang im Docblock von turnen.php). faq.php bekommt dafür ein optionales ctas-Feld pro Eintrag, gerendert über die bestehende cta-Komponente, also keine neue Knopf-Variante. .faq__actions bricht um, weil zwei Knöpfe auf einem schmalen Handy nicht nebeneinander passen. Die Antwort nennt beide Wege bewusst AUCH in Worten: faq_schema() liest nur q und a, Knöpfe landen nie im FAQPage-Schema. Stünde in der Antwort nur „so geht's" plus zwei Knöpfe, hätte Google eine Antwort ohne Ziel. Nachgeprüft: sechs Fragen im Schema, der neue Antworttext ist HTML- und Markup-frei. Gemessen bei 390px: kein Überlauf, Knöpfe 130x44 und 193x44 (Trefferfläche erfüllt). Die fünf Turn-Unterseiten hatten als einzige von 105 PHP-Dateien keinen Zeilenumbruch am Dateiende, das ist mitkorrigiert. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 22:31:57 +02:00
* Der Anmelde-Vorgang der Abteilung (erst Platz anfragen, dann Aufnahmeantrag) steht als
* eigene FAQ-Frage samt den zwei Knöpfen, nicht als eigene Sektion. Das war eine bewusste
* Entscheidung von Felix (31.07.2026): ein Band unter den Beiträgen war gebaut und wurde
* wieder entfernt, weil dieselbe Sache dann zweimal auf der Seite stand. Deshalb gibt es
* `overview.cta` nicht mehr wer die Knöpfe sucht, findet sie in `overview.faq`.
Stadionzeitung, Veranstaltungen, News-Artikel, Lightbox und Anzeigen-Verteilung Stadionzeitung: Live-Seiten (Tabellen, Ergebnisse, Vorschau, Termine, News, Kontakt, Historie, Sportheim, Partner, Momente, Impressum), automatisches Cover, Swipe-Viewer mit Vollbildmodus und die Druckfassung als Falt-Heft. Anzeigen kommen jetzt aus dem Bestand und werden gleichmäßig verteilt, nie mehr als zwei hintereinander (vorher vier Blöcke à fünf). Die Doppelseiten-Regel rechnet das Skript selbst, statt sie von Hand zu prüfen. Veranstaltungen: Bereich /veranstaltungen mit Detailseite pro Fest, Lebenszyklus über das Datum (Ankündigung vor dem Fest, Rückblick danach), Galerie mit Lightbox. veranstaltungen.json ist dritte Termin-Quelle, damit ein Fest nie doppelt gepflegt wird. News-Artikel als dritte dynamische Prefix-Route, gemeinsamer detail-head. Behobene Fehler: - Wappen-Kontexte setzten Zeilen-Layout auf .crest statt auf die Zeile; das Wappen wurde zum Grid, Vereinsname und Tore rutschten darunter zusammen (Ergebnis-Rückblick, Vorschau, Cover). - --header-h (60px) unterschätzt die Kopfleiste um 32px (Logo 72px + 20px Versatz): neues abgeleitetes --header-space, sonst klebten Zurück-Links unter dem Logo. - base_url in der Produktions-Config ohne www, während .htaccess auf www umleitet; preflight prüft das jetzt. - .lightbox brauchte display:none mit (0,2,0), sonst lag das Overlay offen. Neue Werkzeuge: bin/anzeige-add.php (Anzeigen-Bestand), bin/veranstaltung-bilder.php (Plakate und Galerien, Alt-Texte folgen der Quelldatei), bin/qr.php (Druck-QR mit Warnung, wenn base_url nicht auf die echte Domain zeigt). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 14:55:27 +02:00
*
* Das Formular ist die allgemeine contact-form-Komponente mit
* department => 'turnen': Auswahlliste sind die Disziplinen, Empfänger ist die
* Turnabteilung (club.email_turnen) statt info@. Die alte Seite hatte dafür ein
* eigenes, zweites Formular hier ist es dieselbe Komponente und dieselbe
* Action, damit der Spam-Schutz nicht doppelt gepflegt werden muss.
*/
$page = json_load('turnen')['overview'];
// Die Kündigung darf formlos per Mail kommen (Turnabteilung, 31.07.2026). Die Adresse
// steht ausschließlich in club.json — der Austritt-Text in turnen.json markiert ihre
// Stelle mit {mail}, dasselbe Muster wie der Material-Aufruf auf /historie. Ersetzt
// wird NACH inline_links_html(): so bleibt der Fließtext escaped und nur der Platzhalter
// wird zu HTML. Umgekehrt käme der fertige Link escaped als Text auf die Seite.
$mailTurnen = json_load('club')['email_turnen'];
$austrittText = strtr(
inline_links_html($page['austritt']['text'] ?? ''),
['{mail}' => '<a href="mailto:' . e($mailTurnen) . '">' . e($mailTurnen) . '</a>']
);
// Eltern-Kind-, Erwachsenen- und Fitness/Pilates-Seite haben seit 19.08.2026 echte
// (Symbolbild-)Fotos aus der Turnabteilung, in Hero UND Kachel. Trampolin- und
// Wettkampf-Hero zeigen weiter VORÜBERGEHEND das Drohnen-Luftbild des Vereinsgeländes
// (img/pages/vereinsgelaende, Quelle: data/turnen.json); liegt dafür ein Hallenbild vor,
// den Hero-Block in data/turnen.json und das og_image der Seiten-Datei mittauschen.
$cards = [
['name' => 'Erwachsenenturnen', 'slug' => 'turnen/erwachsenenturnen', 'category' => 'Mäximum Gym', 'image' => ['base' => 'img/pages/turnen-erwachsenenturnen', 'widths' => [640, 1000, 1536], 'alt' => 'Turnerinnen üben Gleichgewicht auf dem Schwebebalken (Symbolbild)']],
['name' => 'Eltern-Kind- & Kinderturnen', 'slug' => 'turnen/eltern-kind-turnen', 'category' => 'ab ca. 2 Jahren', 'image' => ['base' => 'img/pages/turnen-eltern-kind', 'widths' => [640, 1000, 1536], 'alt' => 'Kinder turnen an Balken, Kästen und einer Koordinationsleiter in der Halle (Symbolbild)']],
['name' => 'Fitness & Pilates', 'slug' => 'turnen/fitness-pilates', 'category' => 'Max-Hundt-Schule', 'image' => ['base' => 'img/pages/turnen-fitness-pilates', 'widths' => [640, 1000, 1536], 'alt' => 'Gruppe trainiert mit Kniebeugen auf Matten im Sportraum (Symbolbild)']],
Turn-Anmeldung als eigene FAQ-Frage, Knöpfe in FAQ-Antworten möglich Der Anmelde-Vorgang der Abteilung (erst Platz anfragen, dann Aufnahmeantrag) stand nirgends auf der Seite. Auf der alten Seite gab es dafür einen Block „ANMELDUNG" mit zwei Knöpfen. Erst als eigene Sektion unter den Beiträgen gebaut (cta-band), auf Wunsch von Felix wieder entfernt und stattdessen als eigene FAQ-Frage umgesetzt. Zwei Sektionen mit denselben Knöpfen auf einer Seite schwächen beide Stellen, und man weiß nicht mehr, welcher der richtige Weg ist. Deshalb ist auch overview.cta ganz aus data/turnen.json raus statt unbenutzt liegen zu bleiben — genau so ein toter Block hat heute schon einmal in die Irre geführt (die Notiz „NOCH unbenutzt" stand monatelang im Docblock von turnen.php). faq.php bekommt dafür ein optionales ctas-Feld pro Eintrag, gerendert über die bestehende cta-Komponente, also keine neue Knopf-Variante. .faq__actions bricht um, weil zwei Knöpfe auf einem schmalen Handy nicht nebeneinander passen. Die Antwort nennt beide Wege bewusst AUCH in Worten: faq_schema() liest nur q und a, Knöpfe landen nie im FAQPage-Schema. Stünde in der Antwort nur „so geht's" plus zwei Knöpfe, hätte Google eine Antwort ohne Ziel. Nachgeprüft: sechs Fragen im Schema, der neue Antworttext ist HTML- und Markup-frei. Gemessen bei 390px: kein Überlauf, Knöpfe 130x44 und 193x44 (Trefferfläche erfüllt). Die fünf Turn-Unterseiten hatten als einzige von 105 PHP-Dateien keinen Zeilenumbruch am Dateiende, das ist mitkorrigiert. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 22:31:57 +02:00
// Einziges echtes Foto unter den Kacheln (31.07.2026). Nur 640 breit, weil die
// Vorlage über WhatsApp kam und dort auf 718 px eingedampft wurde;
// resize_image_variants() skaliert nie hoch. Liegt das Original vom Handy vor:
// php bin/img-resize.php <quelle> public/assets/img/pages/turnen-trampolin 640,1000,1600 82
// und hier wieder alle drei Breiten eintragen.
['name' => 'Trampolinturnen', 'slug' => 'turnen/trampolin', 'category' => 'Carl-von-Linde-Realschule', 'image' => ['base' => 'img/pages/turnen-trampolin', 'widths' => [640], 'alt' => 'Aufgebaute Trampoline und Sicherheitsmatten in der Dreifachturnhalle, in der wir trainieren']],
['name' => 'Wettkampfturnen', 'slug' => 'turnen/wettkampfturnen', 'category' => 'Leistungssport', 'image' => ['base' => 'img/pages/turnen-wettkampf', 'widths' => [640, 1000, 1600], 'alt' => 'Wettkampfturnen beim TSV 08 Kulmbach']],
];
$meta = [
'title' => 'Turnen in Kulmbach',
Step Aerobic entfernt, Seite heißt jetzt Fitness & Pilates Rückmeldung der Turnabteilung: Step Aerobic findet nicht mehr statt. Wichtig war der Befund vor der Änderung: die Seite bündelt DREI Angebote — Pilates, Fitness & Stretching und Step-Aerobic. Ein pauschales "die Card raus" hätte Pilates und Fitness mitgenommen. Entfernt ist deshalb nur die eine Gruppe (Donnerstag 19:30, Heike Wahler); Pilates und Fitness & Stretching bei Karola Lorz laufen unverändert weiter. Heike Wahler stand nur in dieser Gruppe und erscheint damit nicht mehr auf der Website — das ist die einzige Nebenwirkung, die jemandem auffallen könnte. Umbenannt in "Fitness & Pilates" an allen zehn Fundstellen: navigation.json, turnen.json (Disziplin-Schlüssel, Hero-Titel, drei Übersichtstexte), ansprechpartner.json, news.json, turnen.php (Karte, Alt-Text, Meta) und die Seiten-Datei selbst. URL mitgezogen wie besprochen: turnen/step-aerobic-fitness-pilates → turnen/fitness-pilates, samt Seiten-Datei und den drei Bilddateien (git mv, Historie bleibt). Der alte Slug war in der Sitemap und ist indexiert, deshalb eine 301 in public/.htaccess — VOR dem Front Controller, sonst würde index.php den Pfad als unbekannten Slug abfangen und 404 rendern. Geprüft: /turnen/fitness-pilates liefert 200 mit nur noch zwei Gruppen, Sitemap führt ausschließlich den neuen Slug, Navigation, Übersichtskarte und der News-Artikel verweisen darauf, keine Referenz auf die alten Bildnamen mehr. Der alte Slug gibt lokal 404, weil php -S keine .htaccess liest; die 301 greift auf Apache. Nicht geändert: das Wort "Step-Aerobic" in der CLAUDE.md-Sprachregel. Dort ist es ein Beispiel für orthografisch nötige Bindestriche und bleibt als solches richtig, auch ohne den Kurs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:50:47 +02:00
'description' => 'Die Turnabteilung des TSV 08 Kulmbach: Eltern-Kind- und Kinderturnen, Erwachsenenturnen, Fitness und Pilates, Trampolin- und Wettkampfturnen.',
Stadionzeitung, Veranstaltungen, News-Artikel, Lightbox und Anzeigen-Verteilung Stadionzeitung: Live-Seiten (Tabellen, Ergebnisse, Vorschau, Termine, News, Kontakt, Historie, Sportheim, Partner, Momente, Impressum), automatisches Cover, Swipe-Viewer mit Vollbildmodus und die Druckfassung als Falt-Heft. Anzeigen kommen jetzt aus dem Bestand und werden gleichmäßig verteilt, nie mehr als zwei hintereinander (vorher vier Blöcke à fünf). Die Doppelseiten-Regel rechnet das Skript selbst, statt sie von Hand zu prüfen. Veranstaltungen: Bereich /veranstaltungen mit Detailseite pro Fest, Lebenszyklus über das Datum (Ankündigung vor dem Fest, Rückblick danach), Galerie mit Lightbox. veranstaltungen.json ist dritte Termin-Quelle, damit ein Fest nie doppelt gepflegt wird. News-Artikel als dritte dynamische Prefix-Route, gemeinsamer detail-head. Behobene Fehler: - Wappen-Kontexte setzten Zeilen-Layout auf .crest statt auf die Zeile; das Wappen wurde zum Grid, Vereinsname und Tore rutschten darunter zusammen (Ergebnis-Rückblick, Vorschau, Cover). - --header-h (60px) unterschätzt die Kopfleiste um 32px (Logo 72px + 20px Versatz): neues abgeleitetes --header-space, sonst klebten Zurück-Links unter dem Logo. - base_url in der Produktions-Config ohne www, während .htaccess auf www umleitet; preflight prüft das jetzt. - .lightbox brauchte display:none mit (0,2,0), sonst lag das Overlay offen. Neue Werkzeuge: bin/anzeige-add.php (Anzeigen-Bestand), bin/veranstaltung-bilder.php (Plakate und Galerien, Alt-Texte folgen der Quelldatei), bin/qr.php (Druck-QR mit Warnung, wenn base_url nicht auf die echte Domain zeigt). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 14:55:27 +02:00
'og_image' => 'img/pages/vereinsgelaende-1600.jpg',
Turn-Beiträge sichtbar machen (standen nirgends auf der Website) Die Turnabteilung verlinkt die Beiträge in Einladungen für neue Familien und nimmt zum September auf — die Angaben waren aber auf der ganzen Website nicht zu finden. Nachgeprüft: 0 Treffer auf /turnen und allen fünf Disziplin-Seiten, /mitglied-werden führt nur die Fußball-Beiträge. Es war keine verlorene Seite, sondern eine Lücke im Code: app/pages/turnen.php rendert nur Hero, Karten und Formular. In data/turnen.json lagen ungenutzt cards_intro, fees (drei Tabellen), austritt und faq (fünf Fragen). Der Docblock behauptete, die Beiträge lägen auf den Unterseiten — sie lagen dort nicht, und in der Git-Historie wurden sie nie gerendert. Inhalte 1:1 wie auf der alten Seite (gegengeprüft an 2024.tsv08kulmbach.de, Tab "Allgemeines"): Zusatzbeitrag 24/48 €, Neumitglieder 84/94/184 €, Förderstufen 120/180/240 €, Austritt zum 30. September. Nichts umformuliert, die Abteilung entscheidet über Änderungen. Struktur jetzt Hero → Karten → Beiträge (#beitraege) → FAQ → Formular. Der Anker ist die Adresse für die Einladungen. Nur bestehende Komponenten benutzt (fee-table wie auf /mitglied-werden, faq, team-cards mit intro); neu ist allein der Wrapper .fee-tables. Die FAQ füllt zusätzlich das FAQPage-Schema, weil page_schema() sie als zweiten Parameter bekommt. Feinschliff nach Sichtprüfung: Kartentitel von --fs-650 auf --fs-675, weil 28px Coolvetica neben 21px Fließtext zu klein wirkten; Karten gleich hoch (der Grid-Default stretch statt align-items: start, gemessen vorher 252/377/471px) mit dem Hinweis am Kartenfuß; und minmax(min(22rem, 100%), 1fr) statt minmax(22rem, 1fr), weil die Karten am Handy 352px breit in einem 347px-Raster standen und überliefen. NOCH offen: overview.cta ist weiter unbenutzt. Der Block verlinkt "Zur Turn-Übersicht" und gehört auf die Disziplin-Unterseiten, nicht auf die Übersicht — dort wäre es ein Selbstlink. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:40:23 +02:00
// Zweiter Parameter = FAQ: sichtbare Fragen und FAQPage-Schema kommen aus
// derselben Quelle, damit sie nie auseinanderlaufen (CLAUDE.md).
'schema' => page_schema([
['name' => 'Startseite', 'slug' => ''],
['name' => 'Turnen', 'slug' => 'turnen'],
Turn-Beiträge sichtbar machen (standen nirgends auf der Website) Die Turnabteilung verlinkt die Beiträge in Einladungen für neue Familien und nimmt zum September auf — die Angaben waren aber auf der ganzen Website nicht zu finden. Nachgeprüft: 0 Treffer auf /turnen und allen fünf Disziplin-Seiten, /mitglied-werden führt nur die Fußball-Beiträge. Es war keine verlorene Seite, sondern eine Lücke im Code: app/pages/turnen.php rendert nur Hero, Karten und Formular. In data/turnen.json lagen ungenutzt cards_intro, fees (drei Tabellen), austritt und faq (fünf Fragen). Der Docblock behauptete, die Beiträge lägen auf den Unterseiten — sie lagen dort nicht, und in der Git-Historie wurden sie nie gerendert. Inhalte 1:1 wie auf der alten Seite (gegengeprüft an 2024.tsv08kulmbach.de, Tab "Allgemeines"): Zusatzbeitrag 24/48 €, Neumitglieder 84/94/184 €, Förderstufen 120/180/240 €, Austritt zum 30. September. Nichts umformuliert, die Abteilung entscheidet über Änderungen. Struktur jetzt Hero → Karten → Beiträge (#beitraege) → FAQ → Formular. Der Anker ist die Adresse für die Einladungen. Nur bestehende Komponenten benutzt (fee-table wie auf /mitglied-werden, faq, team-cards mit intro); neu ist allein der Wrapper .fee-tables. Die FAQ füllt zusätzlich das FAQPage-Schema, weil page_schema() sie als zweiten Parameter bekommt. Feinschliff nach Sichtprüfung: Kartentitel von --fs-650 auf --fs-675, weil 28px Coolvetica neben 21px Fließtext zu klein wirkten; Karten gleich hoch (der Grid-Default stretch statt align-items: start, gemessen vorher 252/377/471px) mit dem Hinweis am Kartenfuß; und minmax(min(22rem, 100%), 1fr) statt minmax(22rem, 1fr), weil die Karten am Handy 352px breit in einem 347px-Raster standen und überliefen. NOCH offen: overview.cta ist weiter unbenutzt. Der Block verlinkt "Zur Turn-Übersicht" und gehört auf die Disziplin-Unterseiten, nicht auf die Übersicht — dort wäre es ein Selbstlink. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:40:23 +02:00
], $page['faq'] ?? []),
];
component('hero', ['hero' => $page['hero']]);
component('team-cards', [
'teams' => $cards,
'title' => 'Unsere Turngruppen',
'title_hidden' => true,
Turn-Beiträge sichtbar machen (standen nirgends auf der Website) Die Turnabteilung verlinkt die Beiträge in Einladungen für neue Familien und nimmt zum September auf — die Angaben waren aber auf der ganzen Website nicht zu finden. Nachgeprüft: 0 Treffer auf /turnen und allen fünf Disziplin-Seiten, /mitglied-werden führt nur die Fußball-Beiträge. Es war keine verlorene Seite, sondern eine Lücke im Code: app/pages/turnen.php rendert nur Hero, Karten und Formular. In data/turnen.json lagen ungenutzt cards_intro, fees (drei Tabellen), austritt und faq (fünf Fragen). Der Docblock behauptete, die Beiträge lägen auf den Unterseiten — sie lagen dort nicht, und in der Git-Historie wurden sie nie gerendert. Inhalte 1:1 wie auf der alten Seite (gegengeprüft an 2024.tsv08kulmbach.de, Tab "Allgemeines"): Zusatzbeitrag 24/48 €, Neumitglieder 84/94/184 €, Förderstufen 120/180/240 €, Austritt zum 30. September. Nichts umformuliert, die Abteilung entscheidet über Änderungen. Struktur jetzt Hero → Karten → Beiträge (#beitraege) → FAQ → Formular. Der Anker ist die Adresse für die Einladungen. Nur bestehende Komponenten benutzt (fee-table wie auf /mitglied-werden, faq, team-cards mit intro); neu ist allein der Wrapper .fee-tables. Die FAQ füllt zusätzlich das FAQPage-Schema, weil page_schema() sie als zweiten Parameter bekommt. Feinschliff nach Sichtprüfung: Kartentitel von --fs-650 auf --fs-675, weil 28px Coolvetica neben 21px Fließtext zu klein wirkten; Karten gleich hoch (der Grid-Default stretch statt align-items: start, gemessen vorher 252/377/471px) mit dem Hinweis am Kartenfuß; und minmax(min(22rem, 100%), 1fr) statt minmax(22rem, 1fr), weil die Karten am Handy 352px breit in einem 347px-Raster standen und überliefen. NOCH offen: overview.cta ist weiter unbenutzt. Der Block verlinkt "Zur Turn-Übersicht" und gehört auf die Disziplin-Unterseiten, nicht auf die Übersicht — dort wäre es ein Selbstlink. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:40:23 +02:00
'intro' => $page['cards_intro'] ?? null,
'anchor' => 'gruppen',
]);
Turn-Beiträge sichtbar machen (standen nirgends auf der Website) Die Turnabteilung verlinkt die Beiträge in Einladungen für neue Familien und nimmt zum September auf — die Angaben waren aber auf der ganzen Website nicht zu finden. Nachgeprüft: 0 Treffer auf /turnen und allen fünf Disziplin-Seiten, /mitglied-werden führt nur die Fußball-Beiträge. Es war keine verlorene Seite, sondern eine Lücke im Code: app/pages/turnen.php rendert nur Hero, Karten und Formular. In data/turnen.json lagen ungenutzt cards_intro, fees (drei Tabellen), austritt und faq (fünf Fragen). Der Docblock behauptete, die Beiträge lägen auf den Unterseiten — sie lagen dort nicht, und in der Git-Historie wurden sie nie gerendert. Inhalte 1:1 wie auf der alten Seite (gegengeprüft an 2024.tsv08kulmbach.de, Tab "Allgemeines"): Zusatzbeitrag 24/48 €, Neumitglieder 84/94/184 €, Förderstufen 120/180/240 €, Austritt zum 30. September. Nichts umformuliert, die Abteilung entscheidet über Änderungen. Struktur jetzt Hero → Karten → Beiträge (#beitraege) → FAQ → Formular. Der Anker ist die Adresse für die Einladungen. Nur bestehende Komponenten benutzt (fee-table wie auf /mitglied-werden, faq, team-cards mit intro); neu ist allein der Wrapper .fee-tables. Die FAQ füllt zusätzlich das FAQPage-Schema, weil page_schema() sie als zweiten Parameter bekommt. Feinschliff nach Sichtprüfung: Kartentitel von --fs-650 auf --fs-675, weil 28px Coolvetica neben 21px Fließtext zu klein wirkten; Karten gleich hoch (der Grid-Default stretch statt align-items: start, gemessen vorher 252/377/471px) mit dem Hinweis am Kartenfuß; und minmax(min(22rem, 100%), 1fr) statt minmax(22rem, 1fr), weil die Karten am Handy 352px breit in einem 347px-Raster standen und überliefen. NOCH offen: overview.cta ist weiter unbenutzt. Der Block verlinkt "Zur Turn-Übersicht" und gehört auf die Disziplin-Unterseiten, nicht auf die Übersicht — dort wäre es ein Selbstlink. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:40:23 +02:00
?>
<?php /* Beiträge. Der Anker #beitraege ist die Adresse, die die Turnabteilung in
Einladungen weitergibt nicht umbenennen. Drei Tabellen über die
bestehende fee-table-Komponente (dieselbe wie auf /mitglied-werden),
darunter die Austrittsregel, weil sie zur Beitragsfrage gehört. */ ?>
Beitragsblock: Sektions-Kopf nach Hausmuster, Preise größer Drei Dinge, zwei aus deinem Feedback und eines von mir. 1) Der Einleitungstext klebte ohne Abstand an der Überschrift und lief über die volle Breite, über 120 Zeichen je Zeile ("schaut weird aus"). Ursache: ich hatte <p class="lead"> geschrieben — eine Klasse, die es im Projekt gar nicht gibt, der Absatz war also völlig unformatiert. Jetzt das etablierte Muster (.membership-signup__head, instagram, partners): zentrierter Kopf, 60ch breit, Luft nach unten. Anmerkung im Code: dasselbe Kopf-Muster steht damit zum vierten Mal fast gleich in components.css — ein gemeinsames .section__head wäre die Aufräumung, aber ein eigener Umbau. 2) Preise von 28px auf 34px. Sie tragen die Hervorhebung allein, seit die Farbe weg ist, und sind die Information, auf die man in einer Beitragstabelle sieht. 3) Selbst aufgefallen: die Überschrift "Austritt" lag in .prose und rendert dort mit 21px Abel — exakt Fließtextgröße, also gar keine Auszeichnung. In Impressum und Artikeln ist das richtig, deshalb .prose nicht angetastet, sondern eigene Klassen für den Hinweis: 28px Coolvetica (die Untergrenze für Versalien) mit derselben dezenten Sperrung wie die Kartentitel. Außerdem: data/turnen.json ist wieder in seiner ursprünglichen Formatierung. Mein JSON-Schreiber hatte im vorigen Commit die kompakten Arrays aufgeklappt ("widths": [640, 1000, 1600] wurde vierzeilig) — inhaltlich identisch, aber 371 Diff-Zeilen für eine Umbenennung. Jetzt textuell ersetzt statt neu geschrieben: 17 Diff-Zeilen, Inhalt per Vergleich identisch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:55:48 +02:00
<section class="section section--tinted fees" id="beitraege">
Turn-Beiträge sichtbar machen (standen nirgends auf der Website) Die Turnabteilung verlinkt die Beiträge in Einladungen für neue Familien und nimmt zum September auf — die Angaben waren aber auf der ganzen Website nicht zu finden. Nachgeprüft: 0 Treffer auf /turnen und allen fünf Disziplin-Seiten, /mitglied-werden führt nur die Fußball-Beiträge. Es war keine verlorene Seite, sondern eine Lücke im Code: app/pages/turnen.php rendert nur Hero, Karten und Formular. In data/turnen.json lagen ungenutzt cards_intro, fees (drei Tabellen), austritt und faq (fünf Fragen). Der Docblock behauptete, die Beiträge lägen auf den Unterseiten — sie lagen dort nicht, und in der Git-Historie wurden sie nie gerendert. Inhalte 1:1 wie auf der alten Seite (gegengeprüft an 2024.tsv08kulmbach.de, Tab "Allgemeines"): Zusatzbeitrag 24/48 €, Neumitglieder 84/94/184 €, Förderstufen 120/180/240 €, Austritt zum 30. September. Nichts umformuliert, die Abteilung entscheidet über Änderungen. Struktur jetzt Hero → Karten → Beiträge (#beitraege) → FAQ → Formular. Der Anker ist die Adresse für die Einladungen. Nur bestehende Komponenten benutzt (fee-table wie auf /mitglied-werden, faq, team-cards mit intro); neu ist allein der Wrapper .fee-tables. Die FAQ füllt zusätzlich das FAQPage-Schema, weil page_schema() sie als zweiten Parameter bekommt. Feinschliff nach Sichtprüfung: Kartentitel von --fs-650 auf --fs-675, weil 28px Coolvetica neben 21px Fließtext zu klein wirkten; Karten gleich hoch (der Grid-Default stretch statt align-items: start, gemessen vorher 252/377/471px) mit dem Hinweis am Kartenfuß; und minmax(min(22rem, 100%), 1fr) statt minmax(22rem, 1fr), weil die Karten am Handy 352px breit in einem 347px-Raster standen und überliefen. NOCH offen: overview.cta ist weiter unbenutzt. Der Block verlinkt "Zur Turn-Übersicht" und gehört auf die Disziplin-Unterseiten, nicht auf die Übersicht — dort wäre es ein Selbstlink. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:40:23 +02:00
<div class="container">
Beitragsblock: Sektions-Kopf nach Hausmuster, Preise größer Drei Dinge, zwei aus deinem Feedback und eines von mir. 1) Der Einleitungstext klebte ohne Abstand an der Überschrift und lief über die volle Breite, über 120 Zeichen je Zeile ("schaut weird aus"). Ursache: ich hatte <p class="lead"> geschrieben — eine Klasse, die es im Projekt gar nicht gibt, der Absatz war also völlig unformatiert. Jetzt das etablierte Muster (.membership-signup__head, instagram, partners): zentrierter Kopf, 60ch breit, Luft nach unten. Anmerkung im Code: dasselbe Kopf-Muster steht damit zum vierten Mal fast gleich in components.css — ein gemeinsames .section__head wäre die Aufräumung, aber ein eigener Umbau. 2) Preise von 28px auf 34px. Sie tragen die Hervorhebung allein, seit die Farbe weg ist, und sind die Information, auf die man in einer Beitragstabelle sieht. 3) Selbst aufgefallen: die Überschrift "Austritt" lag in .prose und rendert dort mit 21px Abel — exakt Fließtextgröße, also gar keine Auszeichnung. In Impressum und Artikeln ist das richtig, deshalb .prose nicht angetastet, sondern eigene Klassen für den Hinweis: 28px Coolvetica (die Untergrenze für Versalien) mit derselben dezenten Sperrung wie die Kartentitel. Außerdem: data/turnen.json ist wieder in seiner ursprünglichen Formatierung. Mein JSON-Schreiber hatte im vorigen Commit die kompakten Arrays aufgeklappt ("widths": [640, 1000, 1600] wurde vierzeilig) — inhaltlich identisch, aber 371 Diff-Zeilen für eine Umbenennung. Jetzt textuell ersetzt statt neu geschrieben: 17 Diff-Zeilen, Inhalt per Vergleich identisch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:55:48 +02:00
<header class="fees__head">
<h2><?= e($page['fees_title']) ?></h2>
Turn-Beiträge sichtbar machen (standen nirgends auf der Website) Die Turnabteilung verlinkt die Beiträge in Einladungen für neue Familien und nimmt zum September auf — die Angaben waren aber auf der ganzen Website nicht zu finden. Nachgeprüft: 0 Treffer auf /turnen und allen fünf Disziplin-Seiten, /mitglied-werden führt nur die Fußball-Beiträge. Es war keine verlorene Seite, sondern eine Lücke im Code: app/pages/turnen.php rendert nur Hero, Karten und Formular. In data/turnen.json lagen ungenutzt cards_intro, fees (drei Tabellen), austritt und faq (fünf Fragen). Der Docblock behauptete, die Beiträge lägen auf den Unterseiten — sie lagen dort nicht, und in der Git-Historie wurden sie nie gerendert. Inhalte 1:1 wie auf der alten Seite (gegengeprüft an 2024.tsv08kulmbach.de, Tab "Allgemeines"): Zusatzbeitrag 24/48 €, Neumitglieder 84/94/184 €, Förderstufen 120/180/240 €, Austritt zum 30. September. Nichts umformuliert, die Abteilung entscheidet über Änderungen. Struktur jetzt Hero → Karten → Beiträge (#beitraege) → FAQ → Formular. Der Anker ist die Adresse für die Einladungen. Nur bestehende Komponenten benutzt (fee-table wie auf /mitglied-werden, faq, team-cards mit intro); neu ist allein der Wrapper .fee-tables. Die FAQ füllt zusätzlich das FAQPage-Schema, weil page_schema() sie als zweiten Parameter bekommt. Feinschliff nach Sichtprüfung: Kartentitel von --fs-650 auf --fs-675, weil 28px Coolvetica neben 21px Fließtext zu klein wirkten; Karten gleich hoch (der Grid-Default stretch statt align-items: start, gemessen vorher 252/377/471px) mit dem Hinweis am Kartenfuß; und minmax(min(22rem, 100%), 1fr) statt minmax(22rem, 1fr), weil die Karten am Handy 352px breit in einem 347px-Raster standen und überliefen. NOCH offen: overview.cta ist weiter unbenutzt. Der Block verlinkt "Zur Turn-Übersicht" und gehört auf die Disziplin-Unterseiten, nicht auf die Übersicht — dort wäre es ein Selbstlink. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:40:23 +02:00
<?php if (!empty($page['fees_intro'])): ?>
Beitragsblock: Sektions-Kopf nach Hausmuster, Preise größer Drei Dinge, zwei aus deinem Feedback und eines von mir. 1) Der Einleitungstext klebte ohne Abstand an der Überschrift und lief über die volle Breite, über 120 Zeichen je Zeile ("schaut weird aus"). Ursache: ich hatte <p class="lead"> geschrieben — eine Klasse, die es im Projekt gar nicht gibt, der Absatz war also völlig unformatiert. Jetzt das etablierte Muster (.membership-signup__head, instagram, partners): zentrierter Kopf, 60ch breit, Luft nach unten. Anmerkung im Code: dasselbe Kopf-Muster steht damit zum vierten Mal fast gleich in components.css — ein gemeinsames .section__head wäre die Aufräumung, aber ein eigener Umbau. 2) Preise von 28px auf 34px. Sie tragen die Hervorhebung allein, seit die Farbe weg ist, und sind die Information, auf die man in einer Beitragstabelle sieht. 3) Selbst aufgefallen: die Überschrift "Austritt" lag in .prose und rendert dort mit 21px Abel — exakt Fließtextgröße, also gar keine Auszeichnung. In Impressum und Artikeln ist das richtig, deshalb .prose nicht angetastet, sondern eigene Klassen für den Hinweis: 28px Coolvetica (die Untergrenze für Versalien) mit derselben dezenten Sperrung wie die Kartentitel. Außerdem: data/turnen.json ist wieder in seiner ursprünglichen Formatierung. Mein JSON-Schreiber hatte im vorigen Commit die kompakten Arrays aufgeklappt ("widths": [640, 1000, 1600] wurde vierzeilig) — inhaltlich identisch, aber 371 Diff-Zeilen für eine Umbenennung. Jetzt textuell ersetzt statt neu geschrieben: 17 Diff-Zeilen, Inhalt per Vergleich identisch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:55:48 +02:00
<p class="fees__intro"><?= e($page['fees_intro']) ?></p>
Turn-Beiträge sichtbar machen (standen nirgends auf der Website) Die Turnabteilung verlinkt die Beiträge in Einladungen für neue Familien und nimmt zum September auf — die Angaben waren aber auf der ganzen Website nicht zu finden. Nachgeprüft: 0 Treffer auf /turnen und allen fünf Disziplin-Seiten, /mitglied-werden führt nur die Fußball-Beiträge. Es war keine verlorene Seite, sondern eine Lücke im Code: app/pages/turnen.php rendert nur Hero, Karten und Formular. In data/turnen.json lagen ungenutzt cards_intro, fees (drei Tabellen), austritt und faq (fünf Fragen). Der Docblock behauptete, die Beiträge lägen auf den Unterseiten — sie lagen dort nicht, und in der Git-Historie wurden sie nie gerendert. Inhalte 1:1 wie auf der alten Seite (gegengeprüft an 2024.tsv08kulmbach.de, Tab "Allgemeines"): Zusatzbeitrag 24/48 €, Neumitglieder 84/94/184 €, Förderstufen 120/180/240 €, Austritt zum 30. September. Nichts umformuliert, die Abteilung entscheidet über Änderungen. Struktur jetzt Hero → Karten → Beiträge (#beitraege) → FAQ → Formular. Der Anker ist die Adresse für die Einladungen. Nur bestehende Komponenten benutzt (fee-table wie auf /mitglied-werden, faq, team-cards mit intro); neu ist allein der Wrapper .fee-tables. Die FAQ füllt zusätzlich das FAQPage-Schema, weil page_schema() sie als zweiten Parameter bekommt. Feinschliff nach Sichtprüfung: Kartentitel von --fs-650 auf --fs-675, weil 28px Coolvetica neben 21px Fließtext zu klein wirkten; Karten gleich hoch (der Grid-Default stretch statt align-items: start, gemessen vorher 252/377/471px) mit dem Hinweis am Kartenfuß; und minmax(min(22rem, 100%), 1fr) statt minmax(22rem, 1fr), weil die Karten am Handy 352px breit in einem 347px-Raster standen und überliefen. NOCH offen: overview.cta ist weiter unbenutzt. Der Block verlinkt "Zur Turn-Übersicht" und gehört auf die Disziplin-Unterseiten, nicht auf die Übersicht — dort wäre es ein Selbstlink. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:40:23 +02:00
<?php endif; ?>
Beitragsblock: Sektions-Kopf nach Hausmuster, Preise größer Drei Dinge, zwei aus deinem Feedback und eines von mir. 1) Der Einleitungstext klebte ohne Abstand an der Überschrift und lief über die volle Breite, über 120 Zeichen je Zeile ("schaut weird aus"). Ursache: ich hatte <p class="lead"> geschrieben — eine Klasse, die es im Projekt gar nicht gibt, der Absatz war also völlig unformatiert. Jetzt das etablierte Muster (.membership-signup__head, instagram, partners): zentrierter Kopf, 60ch breit, Luft nach unten. Anmerkung im Code: dasselbe Kopf-Muster steht damit zum vierten Mal fast gleich in components.css — ein gemeinsames .section__head wäre die Aufräumung, aber ein eigener Umbau. 2) Preise von 28px auf 34px. Sie tragen die Hervorhebung allein, seit die Farbe weg ist, und sind die Information, auf die man in einer Beitragstabelle sieht. 3) Selbst aufgefallen: die Überschrift "Austritt" lag in .prose und rendert dort mit 21px Abel — exakt Fließtextgröße, also gar keine Auszeichnung. In Impressum und Artikeln ist das richtig, deshalb .prose nicht angetastet, sondern eigene Klassen für den Hinweis: 28px Coolvetica (die Untergrenze für Versalien) mit derselben dezenten Sperrung wie die Kartentitel. Außerdem: data/turnen.json ist wieder in seiner ursprünglichen Formatierung. Mein JSON-Schreiber hatte im vorigen Commit die kompakten Arrays aufgeklappt ("widths": [640, 1000, 1600] wurde vierzeilig) — inhaltlich identisch, aber 371 Diff-Zeilen für eine Umbenennung. Jetzt textuell ersetzt statt neu geschrieben: 17 Diff-Zeilen, Inhalt per Vergleich identisch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:55:48 +02:00
</header>
Turn-Beiträge sichtbar machen (standen nirgends auf der Website) Die Turnabteilung verlinkt die Beiträge in Einladungen für neue Familien und nimmt zum September auf — die Angaben waren aber auf der ganzen Website nicht zu finden. Nachgeprüft: 0 Treffer auf /turnen und allen fünf Disziplin-Seiten, /mitglied-werden führt nur die Fußball-Beiträge. Es war keine verlorene Seite, sondern eine Lücke im Code: app/pages/turnen.php rendert nur Hero, Karten und Formular. In data/turnen.json lagen ungenutzt cards_intro, fees (drei Tabellen), austritt und faq (fünf Fragen). Der Docblock behauptete, die Beiträge lägen auf den Unterseiten — sie lagen dort nicht, und in der Git-Historie wurden sie nie gerendert. Inhalte 1:1 wie auf der alten Seite (gegengeprüft an 2024.tsv08kulmbach.de, Tab "Allgemeines"): Zusatzbeitrag 24/48 €, Neumitglieder 84/94/184 €, Förderstufen 120/180/240 €, Austritt zum 30. September. Nichts umformuliert, die Abteilung entscheidet über Änderungen. Struktur jetzt Hero → Karten → Beiträge (#beitraege) → FAQ → Formular. Der Anker ist die Adresse für die Einladungen. Nur bestehende Komponenten benutzt (fee-table wie auf /mitglied-werden, faq, team-cards mit intro); neu ist allein der Wrapper .fee-tables. Die FAQ füllt zusätzlich das FAQPage-Schema, weil page_schema() sie als zweiten Parameter bekommt. Feinschliff nach Sichtprüfung: Kartentitel von --fs-650 auf --fs-675, weil 28px Coolvetica neben 21px Fließtext zu klein wirkten; Karten gleich hoch (der Grid-Default stretch statt align-items: start, gemessen vorher 252/377/471px) mit dem Hinweis am Kartenfuß; und minmax(min(22rem, 100%), 1fr) statt minmax(22rem, 1fr), weil die Karten am Handy 352px breit in einem 347px-Raster standen und überliefen. NOCH offen: overview.cta ist weiter unbenutzt. Der Block verlinkt "Zur Turn-Übersicht" und gehört auf die Disziplin-Unterseiten, nicht auf die Übersicht — dort wäre es ein Selbstlink. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:40:23 +02:00
<div class="fee-tables">
<?php foreach ($page['fees'] as $feeTable): ?>
<?php component('fee-table', ['fees' => $feeTable]); ?>
<?php endforeach; ?>
</div>
Beitragsblock: Sektions-Kopf nach Hausmuster, Preise größer Drei Dinge, zwei aus deinem Feedback und eines von mir. 1) Der Einleitungstext klebte ohne Abstand an der Überschrift und lief über die volle Breite, über 120 Zeichen je Zeile ("schaut weird aus"). Ursache: ich hatte <p class="lead"> geschrieben — eine Klasse, die es im Projekt gar nicht gibt, der Absatz war also völlig unformatiert. Jetzt das etablierte Muster (.membership-signup__head, instagram, partners): zentrierter Kopf, 60ch breit, Luft nach unten. Anmerkung im Code: dasselbe Kopf-Muster steht damit zum vierten Mal fast gleich in components.css — ein gemeinsames .section__head wäre die Aufräumung, aber ein eigener Umbau. 2) Preise von 28px auf 34px. Sie tragen die Hervorhebung allein, seit die Farbe weg ist, und sind die Information, auf die man in einer Beitragstabelle sieht. 3) Selbst aufgefallen: die Überschrift "Austritt" lag in .prose und rendert dort mit 21px Abel — exakt Fließtextgröße, also gar keine Auszeichnung. In Impressum und Artikeln ist das richtig, deshalb .prose nicht angetastet, sondern eigene Klassen für den Hinweis: 28px Coolvetica (die Untergrenze für Versalien) mit derselben dezenten Sperrung wie die Kartentitel. Außerdem: data/turnen.json ist wieder in seiner ursprünglichen Formatierung. Mein JSON-Schreiber hatte im vorigen Commit die kompakten Arrays aufgeklappt ("widths": [640, 1000, 1600] wurde vierzeilig) — inhaltlich identisch, aber 371 Diff-Zeilen für eine Umbenennung. Jetzt textuell ersetzt statt neu geschrieben: 17 Diff-Zeilen, Inhalt per Vergleich identisch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:55:48 +02:00
<?php /* Bewusst NICHT .prose: dort rendert ein h3 mit 21px Abel, also exakt
Fließtextgröße in Impressum und Artikeln richtig, hier ist „Austritt"
aber eine Auszeichnung und wäre nicht von Fließtext zu unterscheiden. */ ?>
Turn-Beiträge sichtbar machen (standen nirgends auf der Website) Die Turnabteilung verlinkt die Beiträge in Einladungen für neue Familien und nimmt zum September auf — die Angaben waren aber auf der ganzen Website nicht zu finden. Nachgeprüft: 0 Treffer auf /turnen und allen fünf Disziplin-Seiten, /mitglied-werden führt nur die Fußball-Beiträge. Es war keine verlorene Seite, sondern eine Lücke im Code: app/pages/turnen.php rendert nur Hero, Karten und Formular. In data/turnen.json lagen ungenutzt cards_intro, fees (drei Tabellen), austritt und faq (fünf Fragen). Der Docblock behauptete, die Beiträge lägen auf den Unterseiten — sie lagen dort nicht, und in der Git-Historie wurden sie nie gerendert. Inhalte 1:1 wie auf der alten Seite (gegengeprüft an 2024.tsv08kulmbach.de, Tab "Allgemeines"): Zusatzbeitrag 24/48 €, Neumitglieder 84/94/184 €, Förderstufen 120/180/240 €, Austritt zum 30. September. Nichts umformuliert, die Abteilung entscheidet über Änderungen. Struktur jetzt Hero → Karten → Beiträge (#beitraege) → FAQ → Formular. Der Anker ist die Adresse für die Einladungen. Nur bestehende Komponenten benutzt (fee-table wie auf /mitglied-werden, faq, team-cards mit intro); neu ist allein der Wrapper .fee-tables. Die FAQ füllt zusätzlich das FAQPage-Schema, weil page_schema() sie als zweiten Parameter bekommt. Feinschliff nach Sichtprüfung: Kartentitel von --fs-650 auf --fs-675, weil 28px Coolvetica neben 21px Fließtext zu klein wirkten; Karten gleich hoch (der Grid-Default stretch statt align-items: start, gemessen vorher 252/377/471px) mit dem Hinweis am Kartenfuß; und minmax(min(22rem, 100%), 1fr) statt minmax(22rem, 1fr), weil die Karten am Handy 352px breit in einem 347px-Raster standen und überliefen. NOCH offen: overview.cta ist weiter unbenutzt. Der Block verlinkt "Zur Turn-Übersicht" und gehört auf die Disziplin-Unterseiten, nicht auf die Übersicht — dort wäre es ein Selbstlink. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:40:23 +02:00
<?php if (!empty($page['austritt']['title'])): ?>
Beitragsblock: Sektions-Kopf nach Hausmuster, Preise größer Drei Dinge, zwei aus deinem Feedback und eines von mir. 1) Der Einleitungstext klebte ohne Abstand an der Überschrift und lief über die volle Breite, über 120 Zeichen je Zeile ("schaut weird aus"). Ursache: ich hatte <p class="lead"> geschrieben — eine Klasse, die es im Projekt gar nicht gibt, der Absatz war also völlig unformatiert. Jetzt das etablierte Muster (.membership-signup__head, instagram, partners): zentrierter Kopf, 60ch breit, Luft nach unten. Anmerkung im Code: dasselbe Kopf-Muster steht damit zum vierten Mal fast gleich in components.css — ein gemeinsames .section__head wäre die Aufräumung, aber ein eigener Umbau. 2) Preise von 28px auf 34px. Sie tragen die Hervorhebung allein, seit die Farbe weg ist, und sind die Information, auf die man in einer Beitragstabelle sieht. 3) Selbst aufgefallen: die Überschrift "Austritt" lag in .prose und rendert dort mit 21px Abel — exakt Fließtextgröße, also gar keine Auszeichnung. In Impressum und Artikeln ist das richtig, deshalb .prose nicht angetastet, sondern eigene Klassen für den Hinweis: 28px Coolvetica (die Untergrenze für Versalien) mit derselben dezenten Sperrung wie die Kartentitel. Außerdem: data/turnen.json ist wieder in seiner ursprünglichen Formatierung. Mein JSON-Schreiber hatte im vorigen Commit die kompakten Arrays aufgeklappt ("widths": [640, 1000, 1600] wurde vierzeilig) — inhaltlich identisch, aber 371 Diff-Zeilen für eine Umbenennung. Jetzt textuell ersetzt statt neu geschrieben: 17 Diff-Zeilen, Inhalt per Vergleich identisch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:55:48 +02:00
<div class="fees__note">
<h3 class="fees__note-title"><?= e($page['austritt']['title']) ?></h3>
<p><?= $austrittText ?></p>
Turn-Beiträge sichtbar machen (standen nirgends auf der Website) Die Turnabteilung verlinkt die Beiträge in Einladungen für neue Familien und nimmt zum September auf — die Angaben waren aber auf der ganzen Website nicht zu finden. Nachgeprüft: 0 Treffer auf /turnen und allen fünf Disziplin-Seiten, /mitglied-werden führt nur die Fußball-Beiträge. Es war keine verlorene Seite, sondern eine Lücke im Code: app/pages/turnen.php rendert nur Hero, Karten und Formular. In data/turnen.json lagen ungenutzt cards_intro, fees (drei Tabellen), austritt und faq (fünf Fragen). Der Docblock behauptete, die Beiträge lägen auf den Unterseiten — sie lagen dort nicht, und in der Git-Historie wurden sie nie gerendert. Inhalte 1:1 wie auf der alten Seite (gegengeprüft an 2024.tsv08kulmbach.de, Tab "Allgemeines"): Zusatzbeitrag 24/48 €, Neumitglieder 84/94/184 €, Förderstufen 120/180/240 €, Austritt zum 30. September. Nichts umformuliert, die Abteilung entscheidet über Änderungen. Struktur jetzt Hero → Karten → Beiträge (#beitraege) → FAQ → Formular. Der Anker ist die Adresse für die Einladungen. Nur bestehende Komponenten benutzt (fee-table wie auf /mitglied-werden, faq, team-cards mit intro); neu ist allein der Wrapper .fee-tables. Die FAQ füllt zusätzlich das FAQPage-Schema, weil page_schema() sie als zweiten Parameter bekommt. Feinschliff nach Sichtprüfung: Kartentitel von --fs-650 auf --fs-675, weil 28px Coolvetica neben 21px Fließtext zu klein wirkten; Karten gleich hoch (der Grid-Default stretch statt align-items: start, gemessen vorher 252/377/471px) mit dem Hinweis am Kartenfuß; und minmax(min(22rem, 100%), 1fr) statt minmax(22rem, 1fr), weil die Karten am Handy 352px breit in einem 347px-Raster standen und überliefen. NOCH offen: overview.cta ist weiter unbenutzt. Der Block verlinkt "Zur Turn-Übersicht" und gehört auf die Disziplin-Unterseiten, nicht auf die Übersicht — dort wäre es ein Selbstlink. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 20:40:23 +02:00
</div>
<?php endif; ?>
</div>
</section>
<?php
component('faq', ['faq' => $page['faq'] ?? []]);
Wartelisten-Hinweis für Tiger und Hühner, über dem Anfrageformular Die Turnabteilung (Maxi) beantwortet laufend Anfragen nach einem Wartelistenplatz für „Tiger" und „Hühner", den es nicht gibt. Auf der alten Seite stand der Hinweis direkt über dem Anfrageformular, hier fehlte er. Schlimmer: an der Stelle stand das GEGENTEIL. Der bisherige Hinweis lautete "Aktuell sind alle Kinderturngruppen belegt. Bei Interesse setzen wir sie gerne auf die Warteliste." — für alle Kindergruppen, also auch für die beiden, die keine Liste führen. Der Satz hat einen Teil der Anfragen vermutlich erst erzeugt. Er ist nicht gelöscht, sondern auf die übrigen Gruppen eingegrenzt und aufs Du umgestellt (Haus-Stil; vorher stand dort klein "sie"). Der Text steht genau EINMAL, in data/turnen.json unter disciplines.eltern-kind-turnen.notice + notice_title. Zwei Stellen lesen ihn: die rote Kachel auf /turnen/eltern-kind-turnen (gab es schon) und neu ein Block direkt über dem Formular auf /turnen. Ändert die Abteilung die Lage, ist das eine Zeile in einer Datei. Umsetzung: - notice_title ist neu, weil eine rote Fläche ohne Überschrift wie eine Fehlermeldung liest. Abel statt Coolvetica, der Schnitt ist bei ~19px in Versalien unleserlich (CLAUDE.md, Design). - Der Block steht AUSSERHALB des <form> und damit außerhalb der role="status"-Region: ein dauerhafter Hinweis, keine Rückmeldung zum Absenden. In der Live-Region läse ihn ein Screenreader bei jeder Formularmeldung erneut vor. Kein role="alert", er steht schon beim Laden da. - Überschrift als h3 unter der h2 des Intro-Blocks, damit die Folge nicht springt. - .contact__notice übernimmt bewusst die Optik von .turnen-dash__notice, damit beide Stellen als derselbe Hinweis erkennbar sind. Weiß auf --clr-accent erreicht 4,92:1 und trägt damit Fließtext (WCAG 1.4.3). Kommt ein dritter Ort dazu, gehören die gemeinsamen Eigenschaften in eine geteilte .notice-Klasse; für zwei wäre das verfrüht. Gemessen: Hinweisbreite gleich Formularbreite (720px bei 1280, 347px bei 390), kein Überlauf. preflight ohne neue Meldungen. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 21:54:10 +02:00
/* Der Wartelisten-Hinweis steht DIREKT über dem Formular, so wie auf der alten Seite.
Grund ist Arbeitsaufwand in der Abteilung, kein Design: fuer „Tiger" und „Huehner"
kommen laufend Anfragen nach einem Wartelistenplatz, den es nicht gibt, und jede muss
einzeln beantwortet werden. Wer hier schreibt, soll es vorher lesen. Der Text kommt aus
derselben Stelle wie die Kachel auf der Kinderturn-Unterseite
(disciplines.eltern-kind-turnen.notice), ein Hinweis und eine Quelle. */
$kinderturnen = json_load('turnen')['disciplines']['eltern-kind-turnen'] ?? [];
Stadionzeitung, Veranstaltungen, News-Artikel, Lightbox und Anzeigen-Verteilung Stadionzeitung: Live-Seiten (Tabellen, Ergebnisse, Vorschau, Termine, News, Kontakt, Historie, Sportheim, Partner, Momente, Impressum), automatisches Cover, Swipe-Viewer mit Vollbildmodus und die Druckfassung als Falt-Heft. Anzeigen kommen jetzt aus dem Bestand und werden gleichmäßig verteilt, nie mehr als zwei hintereinander (vorher vier Blöcke à fünf). Die Doppelseiten-Regel rechnet das Skript selbst, statt sie von Hand zu prüfen. Veranstaltungen: Bereich /veranstaltungen mit Detailseite pro Fest, Lebenszyklus über das Datum (Ankündigung vor dem Fest, Rückblick danach), Galerie mit Lightbox. veranstaltungen.json ist dritte Termin-Quelle, damit ein Fest nie doppelt gepflegt wird. News-Artikel als dritte dynamische Prefix-Route, gemeinsamer detail-head. Behobene Fehler: - Wappen-Kontexte setzten Zeilen-Layout auf .crest statt auf die Zeile; das Wappen wurde zum Grid, Vereinsname und Tore rutschten darunter zusammen (Ergebnis-Rückblick, Vorschau, Cover). - --header-h (60px) unterschätzt die Kopfleiste um 32px (Logo 72px + 20px Versatz): neues abgeleitetes --header-space, sonst klebten Zurück-Links unter dem Logo. - base_url in der Produktions-Config ohne www, während .htaccess auf www umleitet; preflight prüft das jetzt. - .lightbox brauchte display:none mit (0,2,0), sonst lag das Overlay offen. Neue Werkzeuge: bin/anzeige-add.php (Anzeigen-Bestand), bin/veranstaltung-bilder.php (Plakate und Galerien, Alt-Texte folgen der Quelldatei), bin/qr.php (Druck-QR mit Warnung, wenn base_url nicht auf die echte Domain zeigt). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 14:55:27 +02:00
component('contact-form', [
Wartelisten-Hinweis für Tiger und Hühner, über dem Anfrageformular Die Turnabteilung (Maxi) beantwortet laufend Anfragen nach einem Wartelistenplatz für „Tiger" und „Hühner", den es nicht gibt. Auf der alten Seite stand der Hinweis direkt über dem Anfrageformular, hier fehlte er. Schlimmer: an der Stelle stand das GEGENTEIL. Der bisherige Hinweis lautete "Aktuell sind alle Kinderturngruppen belegt. Bei Interesse setzen wir sie gerne auf die Warteliste." — für alle Kindergruppen, also auch für die beiden, die keine Liste führen. Der Satz hat einen Teil der Anfragen vermutlich erst erzeugt. Er ist nicht gelöscht, sondern auf die übrigen Gruppen eingegrenzt und aufs Du umgestellt (Haus-Stil; vorher stand dort klein "sie"). Der Text steht genau EINMAL, in data/turnen.json unter disciplines.eltern-kind-turnen.notice + notice_title. Zwei Stellen lesen ihn: die rote Kachel auf /turnen/eltern-kind-turnen (gab es schon) und neu ein Block direkt über dem Formular auf /turnen. Ändert die Abteilung die Lage, ist das eine Zeile in einer Datei. Umsetzung: - notice_title ist neu, weil eine rote Fläche ohne Überschrift wie eine Fehlermeldung liest. Abel statt Coolvetica, der Schnitt ist bei ~19px in Versalien unleserlich (CLAUDE.md, Design). - Der Block steht AUSSERHALB des <form> und damit außerhalb der role="status"-Region: ein dauerhafter Hinweis, keine Rückmeldung zum Absenden. In der Live-Region läse ihn ein Screenreader bei jeder Formularmeldung erneut vor. Kein role="alert", er steht schon beim Laden da. - Überschrift als h3 unter der h2 des Intro-Blocks, damit die Folge nicht springt. - .contact__notice übernimmt bewusst die Optik von .turnen-dash__notice, damit beide Stellen als derselbe Hinweis erkennbar sind. Weiß auf --clr-accent erreicht 4,92:1 und trägt damit Fließtext (WCAG 1.4.3). Kommt ein dritter Ort dazu, gehören die gemeinsamen Eigenschaften in eine geteilte .notice-Klasse; für zwei wäre das verfrüht. Gemessen: Hinweisbreite gleich Formularbreite (720px bei 1280, 347px bei 390), kein Überlauf. preflight ohne neue Meldungen. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 21:54:10 +02:00
'intro' => $page['contact'],
'return' => 'turnen',
'department' => 'turnen',
'notice' => $kinderturnen['notice'] ?? '',
'noticeTitle' => $kinderturnen['notice_title'] ?? '',
Trampolin: Schnupper-Einladung, Hinweise bekommen zwei Tonlagen Info von Eva aus der Trampolin-Gruppe: neue Kinder können ab September (Schulbeginn) gerne schnuppern kommen. Die Info stand nirgends. Rot wäre dafür falsch gewesen. Die Farbe bekommt deshalb eine Bedeutung: --stop (gefüllt rot) heißt „geht nicht", --info (Glas-Fläche, Rot nur im Icon) heißt „geht". Eine Einladung in Alarmrot liest sich wie eine Absage, und wenn alles rot ist, stumpft Rot ab und der echte Wartelisten-Stopp bei „Tiger" und „Hühner" verliert seine Wirkung. --info ist ab jetzt der Default. Damit steht der Hinweis an drei Stellen, also greift die Bedingung aus dem letzten Commit („kommt ein dritter Ort dazu, gehören die gemeinsamen Eigenschaften in eine geteilte Klasse"): neu app/components/notice.php als einzige Render-Stelle statt dreimal dasselbe Markup. Die beiden bestehenden Klassen schrumpfen auf das, was sie wirklich beitragen — .turnen-dash__notice nur noch grid-area, .contact__notice nur noch die Formularbreite. Die tote .turnen-dash__notice-icon-Regel ist raus, der CSS-Abschnitt neu sortiert (notice als eigener Block hinter turnen-dash statt mitten hinein). Text, Tonlage und Icon stehen wie gehabt in data/turnen.json bei der Disziplin, nicht im Template. Kinderturnen trägt jetzt explizit notice_tone: stop, Trampolin nichts und ist damit neutral. Das Grid-Template für --notice + --single gab es schon, an beiden Breakpoints — die Trampolin-Seite hat eine Gruppe und wäre sonst auseinandergefallen. Gemessen bei 390px: kein Überlauf auf allen drei Seiten, Trampolin-Fläche rgba(0,0,0,0.22) (Glas), die beiden anderen #e20612. Zwölf Seiten geprüft, alle 200. preflight ohne neue Meldungen. OFFEN, mit Eva oder Tina zu klären: der zweite Satz („Schreib uns davor einfach kurz eine Nachricht") ist von mir, Eva hat ihn nicht gesagt. Wenn die Kinder einfach zum Training kommen dürfen, gehört er weg. Und die Einladung steht bisher nur auf /turnen/trampolin, nicht auf der Übersicht /turnen. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 22:04:41 +02:00
'noticeTone' => $kinderturnen['notice_tone'] ?? 'info',
'noticeIcon' => $kinderturnen['notice_icon'] ?? 'info-circle',
Stadionzeitung, Veranstaltungen, News-Artikel, Lightbox und Anzeigen-Verteilung Stadionzeitung: Live-Seiten (Tabellen, Ergebnisse, Vorschau, Termine, News, Kontakt, Historie, Sportheim, Partner, Momente, Impressum), automatisches Cover, Swipe-Viewer mit Vollbildmodus und die Druckfassung als Falt-Heft. Anzeigen kommen jetzt aus dem Bestand und werden gleichmäßig verteilt, nie mehr als zwei hintereinander (vorher vier Blöcke à fünf). Die Doppelseiten-Regel rechnet das Skript selbst, statt sie von Hand zu prüfen. Veranstaltungen: Bereich /veranstaltungen mit Detailseite pro Fest, Lebenszyklus über das Datum (Ankündigung vor dem Fest, Rückblick danach), Galerie mit Lightbox. veranstaltungen.json ist dritte Termin-Quelle, damit ein Fest nie doppelt gepflegt wird. News-Artikel als dritte dynamische Prefix-Route, gemeinsamer detail-head. Behobene Fehler: - Wappen-Kontexte setzten Zeilen-Layout auf .crest statt auf die Zeile; das Wappen wurde zum Grid, Vereinsname und Tore rutschten darunter zusammen (Ergebnis-Rückblick, Vorschau, Cover). - --header-h (60px) unterschätzt die Kopfleiste um 32px (Logo 72px + 20px Versatz): neues abgeleitetes --header-space, sonst klebten Zurück-Links unter dem Logo. - base_url in der Produktions-Config ohne www, während .htaccess auf www umleitet; preflight prüft das jetzt. - .lightbox brauchte display:none mit (0,2,0), sonst lag das Overlay offen. Neue Werkzeuge: bin/anzeige-add.php (Anzeigen-Bestand), bin/veranstaltung-bilder.php (Plakate und Galerien, Alt-Texte folgen der Quelldatei), bin/qr.php (Druck-QR mit Warnung, wenn base_url nicht auf die echte Domain zeigt). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 14:55:27 +02:00
]);