Files
tsv08kulmbach-website/app/pages/turnen.php
fs e7572b34d6 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

113 lines
6.7 KiB
PHP

<?php
declare(strict_types=1);
/**
* 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.
*
* NOCH unbenutzt: overview.cta („Lust aufs Turnen bekommen?"). Der Block verlinkt
* „Zur Turn-Übersicht" und gehört damit auf die Disziplin-Unterseiten, nicht hierher
* — auf der Übersicht wäre das ein Selbstlink.
*
* 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'];
// Heros aller Turn-Seiten zeigen VORÜBERGEHEND das Drohnen-Luftbild des
// Vereinsgeländes (img/pages/vereinsgelaende, Quelle: data/turnen.json) statt des
// Fußballplatz-Bildes. Ehrlicher wäre ein Bild aus der Turnhalle — liegt eines
// vor, tauschen die sechs Hero-Blöcke in data/turnen.json und das og_image der
// sechs Seiten-Dateien. Die Übersichts-Kacheln zeigen weiter die (vorläufigen)
// themenbezogenen Platzhalter aus public/assets/img/pages/.
$cards = [
['name' => 'Erwachsenenturnen', 'slug' => 'turnen/erwachsenenturnen', 'category' => 'Mäximum Gym', 'image' => ['base' => 'img/pages/turnen-erwachsenenturnen', 'widths' => [640, 1000, 1600], 'alt' => 'Erwachsenenturnen beim TSV 08 Kulmbach']],
['name' => 'Eltern-Kind- & Kinderturnen', 'slug' => 'turnen/eltern-kind-turnen', 'category' => 'ab ca. 2 Jahren', 'image' => ['base' => 'img/pages/turnen-eltern-kind', 'widths' => [640, 1000, 1600], 'alt' => 'Eltern-Kind- und Kinderturnen beim TSV 08 Kulmbach']],
['name' => 'Fitness & Pilates', 'slug' => 'turnen/fitness-pilates', 'category' => 'Max-Hundt-Schule', 'image' => ['base' => 'img/pages/turnen-fitness-pilates', 'widths' => [640, 1000, 1600], 'alt' => 'Fitness und Pilates beim TSV 08 Kulmbach']],
['name' => 'Trampolinturnen', 'slug' => 'turnen/trampolin', 'category' => 'Carl-von-Linde-Realschule', 'image' => ['base' => 'img/pages/turnen-trampolin', 'widths' => [640, 1000, 1600], 'alt' => 'Trampolinturnen beim TSV 08 Kulmbach']],
['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',
'description' => 'Die Turnabteilung des TSV 08 Kulmbach: Eltern-Kind- und Kinderturnen, Erwachsenenturnen, Fitness und Pilates, Trampolin- und Wettkampfturnen.',
'og_image' => 'img/pages/vereinsgelaende-1600.jpg',
// 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'],
], $page['faq'] ?? []),
];
component('hero', ['hero' => $page['hero']]);
component('team-cards', [
'teams' => $cards,
'title' => 'Unsere Turngruppen',
'title_hidden' => true,
'intro' => $page['cards_intro'] ?? null,
'anchor' => 'gruppen',
]);
?>
<?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. */ ?>
<section class="section section--tinted fees" id="beitraege">
<div class="container">
<header class="fees__head">
<h2><?= e($page['fees_title']) ?></h2>
<?php if (!empty($page['fees_intro'])): ?>
<p class="fees__intro"><?= e($page['fees_intro']) ?></p>
<?php endif; ?>
</header>
<div class="fee-tables">
<?php foreach ($page['fees'] as $feeTable): ?>
<?php component('fee-table', ['fees' => $feeTable]); ?>
<?php endforeach; ?>
</div>
<?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. */ ?>
<?php if (!empty($page['austritt']['title'])): ?>
<div class="fees__note">
<h3 class="fees__note-title"><?= e($page['austritt']['title']) ?></h3>
<p><?= inline_links_html($page['austritt']['text']) ?></p>
</div>
<?php endif; ?>
</div>
</section>
<?php
component('faq', ['faq' => $page['faq'] ?? []]);
/* 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'] ?? [];
component('contact-form', [
'intro' => $page['contact'],
'return' => 'turnen',
'department' => 'turnen',
'notice' => $kinderturnen['notice'] ?? '',
'noticeTitle' => $kinderturnen['notice_title'] ?? '',
'noticeTone' => $kinderturnen['notice_tone'] ?? 'info',
'noticeIcon' => $kinderturnen['notice_icon'] ?? 'info-circle',
]);