Turnabteilung: Übersicht + 5 Disziplin-Unterseiten im Bento-Layout

- Neue Übersichtsseite (Hub: Hero + Disziplin-Kacheln) sowie Unterseiten für
  Erwachsenenturnen, Eltern-Kind-/Kinderturnen, Step Aerobic/Fitness/Pilates,
  Trampolin und Wettkampfturnen. Inhalte 1:1 von der alten Seite, gepflegt in
  der neuen Single-Source data/turnen.json.
- Neue Komponente group-schedule im einheitlichen Bento-Look wie die
  Mannschaftsseiten: Dashboard mit Trainingszeiten, Kontakt-Kachel (mailto an die
  Turnabteilung) und Trainingsort; gestapelte/gerasterte Gruppen-Karten für
  Mehr-Gruppen-Disziplinen, rote Hinweis-Kachel (z. B. Warteliste).
- Routing (app/routes.php) und Navigations-Dropdown (data/navigation.json) für
  Turnen; zugehörige Styles in components.css.
- Themenbezogene, self-hostete Unsplash-Platzhalterbilder für die Kacheln.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KDQZ6FuchNUh2bxSW9PeNv
This commit is contained in:
2026-06-19 10:33:03 +02:00
parent d0ff8922f3
commit ea622244db
30 changed files with 964 additions and 1 deletions

View File

@@ -0,0 +1,183 @@
<?php
declare(strict_types=1);
/**
* Turn-Disziplin im einheitlichen Bento-Look (wie die Mannschaftsseiten). Props:
* $location array{venue, street?, zip?, city?} (optional) — Trainingsort + „Route planen"
* $lead string (optional) — verantwortliche Übungsleitung (Akzent-Kachel)
* $notice string (optional) — hervorgehobener Hinweis (z. B. Wartelisten-Status)
* $groups array von Gruppen:
* { name, level?, intro?, details?:[{heading,text}], recommendation?, note?,
* trainers?:[…], sessions:[{ label?, day, time, note?, trainers?:[…] }] }
* $footnote string (optional) — Erläuterung (z. B. zur Sternchen-Kennzeichnung)
* $groupsTitle string (optional, Default 'Unsere Gruppen')
* $anchor string (optional, Default 'training')
*
* Eine Gruppe → Trainingszeiten landen als Bento-Kachel im Dashboard.
* Mehrere → Dashboard zeigt nur Ort/Verantwortlich, darunter eine Gruppen-Sektion.
* Gruppen mit Beschreibung werden gestapelt, schlichte Gruppen als Raster.
*/
$anchor = $anchor ?? 'training';
$groupsTitle = $groupsTitle ?? 'Unsere Gruppen';
$lead = $lead ?? '';
$notice = $notice ?? '';
$footnote = $footnote ?? '';
$groups = $groups ?? [];
$location = $location ?? [];
if ($groups === []) {
return;
}
$club = json_load('club');
$email = $club['email_turnen'] ?? ($club['email'] ?? '');
$single = count($groups) === 1;
$rich = false;
foreach ($groups as $g) {
if (!empty($g['intro']) || !empty($g['details'])) {
$rich = true;
break;
}
}
$hasVenue = !empty($location['venue']);
$mapsQuery = $hasVenue ? rawurlencode(trim(
($location['venue'] ?? '') . ', '
. ($location['street'] ?? '') . ', '
. ($location['zip'] ?? '') . ' ' . ($location['city'] ?? ''),
', '
)) : '';
/** Eine Trainingszeit (Tag/Zeit + optional Label, Notiz, Übungsleitung) ausgeben. */
$renderSession = static function (array $s): void {
?>
<li class="schedule-row">
<?php if (!empty($s['label'])): ?>
<span class="schedule-row__label"><?= e($s['label']) ?></span>
<?php endif; ?>
<span class="schedule-row__when">
<span class="schedule-row__day"><?= e($s['day']) ?></span>
<span class="schedule-row__time"><?= e($s['time']) ?></span>
</span>
<?php if (!empty($s['note'])): ?>
<span class="schedule-row__note text-muted"><?= e($s['note']) ?></span>
<?php endif; ?>
<?php if (!empty($s['trainers'])): ?>
<span class="schedule-row__trainers"><span class="schedule-row__trainers-label">Übungsleitung:</span> <?= e(implode(', ', $s['trainers'])) ?></span>
<?php endif; ?>
</li>
<?php
};
$soleSessions = $single ? ($groups[0]['sessions'] ?? []) : [];
$soleNote = $single ? ($groups[0]['note'] ?? '') : '';
?>
<section class="section turnen-dash-section" id="<?= e($anchor) ?>">
<div class="container">
<div class="turnen-dash<?= $single ? ' turnen-dash--single' : '' ?><?= $notice !== '' ? ' turnen-dash--notice' : '' ?>">
<?php if ($notice !== ''): ?>
<article class="bento__tile turnen-dash__notice">
<?= icon('info-circle', 'turnen-dash__notice-icon') ?>
<p><?= e($notice) ?></p>
</article>
<?php endif; ?>
<?php if ($single): ?>
<article class="bento__tile turnen-dash__training">
<h2 class="bento__heading"><?= icon('clock', 'bento__hicon') ?>Trainingszeiten</h2>
<ul class="bento__sessions">
<?php foreach ($soleSessions as $s): ?>
<li>
<span class="bento__day"><?= e($s['day']) ?></span>
<span class="bento__time"><?= e($s['time']) ?></span>
</li>
<?php endforeach; ?>
</ul>
<?php if ($soleNote !== ''): ?>
<p class="bento__note text-muted"><?= e($soleNote) ?></p>
<?php endif; ?>
<span class="bento__deco" aria-hidden="true"><?= icon('clock') ?></span>
</article>
<?php endif; ?>
<?php if ($lead !== '' || $email !== ''): ?>
<article class="bento__tile bento__tile--accent turnen-dash__contact">
<span class="bento__stat-label">Kontakt</span>
<?php if ($lead !== ''): ?>
<span class="bento__stat-value"><?= e($lead) ?></span>
<?php endif; ?>
<?php if ($email !== ''): ?>
<a class="turnen-dash__mail" href="mailto:<?= e($email) ?>"><?= icon('envelope', 'turnen-dash__mail-icon') ?>E-Mail schreiben</a>
<?php endif; ?>
</article>
<?php endif; ?>
<?php if ($hasVenue): ?>
<article class="bento__tile turnen-dash__venue">
<div class="turnen-dash__venue-main">
<h2 class="bento__heading"><?= icon('geo-alt', 'bento__hicon') ?>Trainingsort</h2>
<p class="bento__address">
<strong><?= e($location['venue']) ?></strong>
<?php if (!empty($location['street'])): ?> · <?= e($location['street']) ?><?php endif; ?>
<?php if (!empty($location['zip']) || !empty($location['city'])): ?>, <?= e(trim(($location['zip'] ?? '') . ' ' . ($location['city'] ?? ''))) ?><?php endif; ?>
</p>
</div>
<a class="btn btn--outline turnen-dash__route" href="https://www.google.com/maps/search/?api=1&amp;query=<?= e($mapsQuery) ?>" target="_blank" rel="noopener">Route planen<span class="visually-hidden"> (öffnet Google Maps in neuem Tab)</span></a>
<span class="bento__deco" aria-hidden="true"><?= icon('geo-alt') ?></span>
</article>
<?php endif; ?>
</div>
</div>
</section>
<?php if (!$single): ?>
<section class="section group-list-section" id="gruppen">
<div class="container">
<h2 class="group-list__title"><?= e($groupsTitle) ?></h2>
<div class="group-list <?= $rich ? 'group-list--stacked' : 'group-list--grid' ?>">
<?php foreach ($groups as $g): ?>
<article class="group-card">
<div class="group-card__body">
<h3 class="group-card__name"><?= e($g['name']) ?></h3>
<?php if (!empty($g['level'])): ?>
<p class="group-card__level"><?= e($g['level']) ?></p>
<?php endif; ?>
<?php if (!empty($g['intro'])): ?>
<p class="group-card__intro"><?= e($g['intro']) ?></p>
<?php endif; ?>
<?php foreach ($g['details'] ?? [] as $det): ?>
<?php if (!empty($det['heading'])): ?>
<h4 class="group-card__detail-heading"><?= e($det['heading']) ?></h4>
<?php endif; ?>
<?php if (!empty($det['text'])): ?>
<p class="group-card__detail-text"><?= e($det['text']) ?></p>
<?php endif; ?>
<?php endforeach; ?>
<?php if (!empty($g['recommendation'])): ?>
<p class="group-card__recommendation text-muted"><?= e($g['recommendation']) ?></p>
<?php endif; ?>
</div>
<?php if (!empty($g['sessions'])): ?>
<div class="group-card__schedule">
<p class="group-card__schedule-title"><?= icon('clock', 'group-card__schedule-icon') ?>Trainingszeiten</p>
<ul class="schedule-list">
<?php foreach ($g['sessions'] as $s): $renderSession($s); endforeach; ?>
</ul>
<?php if (!empty($g['trainers'])): ?>
<p class="group-card__trainers"><span class="schedule-row__trainers-label">Übungsleitung:</span> <?= e(implode(', ', $g['trainers'])) ?></p>
<?php endif; ?>
<?php if (!empty($g['note'])): ?>
<p class="group-card__note text-muted"><?= e($g['note']) ?></p>
<?php endif; ?>
</div>
<?php endif; ?>
</article>
<?php endforeach; ?>
</div>
<?php if ($footnote !== ''): ?>
<p class="group-list__footnote text-muted"><?= e($footnote) ?></p>
<?php endif; ?>
</div>
</section>
<?php endif; ?>

View File

@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
/**
* Turnen → Eltern-Kind- & Kinderturnen. Inhalt: data/turnen.json (disciplines.eltern-kind-turnen).
* Bündelt Eltern-Kind-Gruppen und die nach Alter gestaffelten Kinderturn-Gruppen.
* Struktur: Hero → Gruppen/Trainingszeiten → CTA.
*/
$slug = 'turnen/eltern-kind-turnen';
$data = json_load('turnen');
$d = $data['disciplines']['eltern-kind-turnen'];
$meta = [
'title' => 'Eltern-Kind- & Kinderturnen in Kulmbach',
'description' => $d['hero']['text'],
'og_image' => 'img/hero/hero-1600.jpg',
'schema' => page_schema([
['name' => 'Startseite', 'slug' => ''],
['name' => 'Turnen', 'slug' => 'turnen'],
['name' => 'Eltern-Kind- & Kinderturnen', 'slug' => $slug],
]),
];
component('hero', ['hero' => $d['hero']]);
component('group-schedule', [
'location' => $d['location'] ?? [],
'lead' => $d['lead'] ?? '',
'notice' => $d['notice'] ?? '',
'groups' => $d['groups'] ?? [],
'footnote' => $data['footnote'] ?? '',
]);

View File

@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
/**
* Turnen → Erwachsenenturnen. Inhalt: data/turnen.json (disciplines.erwachsenenturnen).
* Struktur: Hero → Gruppen/Trainingszeiten → CTA.
*/
$slug = 'turnen/erwachsenenturnen';
$d = json_load('turnen')['disciplines']['erwachsenenturnen'];
$meta = [
'title' => 'Erwachsenenturnen in Kulmbach',
'description' => $d['hero']['text'],
'og_image' => 'img/hero/hero-1600.jpg',
'schema' => page_schema([
['name' => 'Startseite', 'slug' => ''],
['name' => 'Turnen', 'slug' => 'turnen'],
['name' => 'Erwachsenenturnen', 'slug' => $slug],
]),
];
component('hero', ['hero' => $d['hero']]);
component('group-schedule', [
'location' => $d['location'] ?? [],
'lead' => $d['lead'] ?? '',
'groups' => $d['groups'] ?? [],
]);

View File

@@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
/**
* Turnen → Step Aerobic, Fitness & Pilates. Inhalt: data/turnen.json
* (disciplines.step-aerobic-fitness-pilates). Struktur: Hero → Kurse/Zeiten → CTA.
*/
$slug = 'turnen/step-aerobic-fitness-pilates';
$d = json_load('turnen')['disciplines']['step-aerobic-fitness-pilates'];
$meta = [
'title' => 'Step Aerobic, Fitness & Pilates in Kulmbach',
'description' => $d['hero']['text'],
'og_image' => 'img/hero/hero-1600.jpg',
'schema' => page_schema([
['name' => 'Startseite', 'slug' => ''],
['name' => 'Turnen', 'slug' => 'turnen'],
['name' => 'Step Aerobic, Fitness & Pilates', 'slug' => $slug],
]),
];
component('hero', ['hero' => $d['hero']]);
component('group-schedule', [
'groupsTitle' => 'Unsere Kurse',
'location' => $d['location'] ?? [],
'lead' => $d['lead'] ?? '',
'groups' => $d['groups'] ?? [],
]);

View File

@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
/**
* Turnen → Trampolinturnen. Inhalt: data/turnen.json (disciplines.trampolin).
* Struktur: Hero → Gruppen/Trainingszeiten → CTA.
*/
$slug = 'turnen/trampolin';
$d = json_load('turnen')['disciplines']['trampolin'];
$meta = [
'title' => 'Trampolinturnen in Kulmbach',
'description' => $d['hero']['text'],
'og_image' => 'img/hero/hero-1600.jpg',
'schema' => page_schema([
['name' => 'Startseite', 'slug' => ''],
['name' => 'Turnen', 'slug' => 'turnen'],
['name' => 'Trampolinturnen', 'slug' => $slug],
]),
];
component('hero', ['hero' => $d['hero']]);
component('group-schedule', [
'location' => $d['location'] ?? [],
'lead' => $d['lead'] ?? '',
'groups' => $d['groups'] ?? [],
]);

View File

@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
/**
* Turnen → Wettkampfturnen. Inhalt: data/turnen.json (disciplines.wettkampfturnen).
* Struktur: Hero → Gruppen/Trainingszeiten → CTA.
*/
$slug = 'turnen/wettkampfturnen';
$d = json_load('turnen')['disciplines']['wettkampfturnen'];
$meta = [
'title' => 'Wettkampfturnen in Kulmbach',
'description' => $d['hero']['text'],
'og_image' => 'img/hero/hero-1600.jpg',
'schema' => page_schema([
['name' => 'Startseite', 'slug' => ''],
['name' => 'Turnen', 'slug' => 'turnen'],
['name' => 'Wettkampfturnen', 'slug' => $slug],
]),
];
component('hero', ['hero' => $d['hero']]);
component('group-schedule', [
'location' => $d['location'] ?? [],
'lead' => $d['lead'] ?? '',
'groups' => $d['groups'] ?? [],
]);

38
app/pages/turnen.php Normal file
View File

@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
/**
* Turn-Übersichtsseite (reiner Hub). Inhalt: data/turnen.json.
* Struktur: Hero → Disziplin-Karten. Keine weiteren Sektionen — die Detailinhalte
* (Beiträge, FAQ, Trainingszeiten) leben auf den Disziplin-Unterseiten.
*/
$page = json_load('turnen')['overview'];
// Heros nutzen das Vereins-Default-Bild; nur die Übersichts-Kacheln zeigen die
// (vorläufigen) themenbezogenen Unsplash-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' => 'Step Aerobic, Fitness & Pilates', 'slug' => 'turnen/step-aerobic-fitness-pilates', 'category' => 'Max-Hundt-Schule', 'image' => ['base' => 'img/pages/turnen-step-aerobic', 'widths' => [640, 1000, 1600], 'alt' => 'Step Aerobic, 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, Step Aerobic, Fitness und Pilates, Trampolin- und Wettkampfturnen.',
'og_image' => 'img/hero/hero-1600.jpg',
'schema' => page_schema([
['name' => 'Startseite', 'slug' => ''],
['name' => 'Turnen', 'slug' => 'turnen'],
]),
];
component('hero', ['hero' => $page['hero']]);
component('team-cards', [
'teams' => $cards,
'title' => 'Unsere Turngruppen',
'title_hidden' => true,
'anchor' => 'gruppen',
]);

View File

@@ -16,6 +16,12 @@ return [
'fussball/zweite-mannschaft' => ['file' => 'team-zwei.php', 'sitemap' => true], 'fussball/zweite-mannschaft' => ['file' => 'team-zwei.php', 'sitemap' => true],
'fussball/damen' => ['file' => 'team-damen.php', 'sitemap' => true], 'fussball/damen' => ['file' => 'team-damen.php', 'sitemap' => true],
'jugendfussball' => ['file' => 'jugendfussball.php', 'sitemap' => true], 'jugendfussball' => ['file' => 'jugendfussball.php', 'sitemap' => true],
'turnen' => ['file' => 'turnen.php', 'sitemap' => true],
'turnen/erwachsenenturnen' => ['file' => 'turnen-erwachsenenturnen.php', 'sitemap' => true],
'turnen/eltern-kind-turnen' => ['file' => 'turnen-eltern-kind.php', 'sitemap' => true],
'turnen/step-aerobic-fitness-pilates' => ['file' => 'turnen-step-aerobic.php', 'sitemap' => true],
'turnen/trampolin' => ['file' => 'turnen-trampolin.php', 'sitemap' => true],
'turnen/wettkampfturnen' => ['file' => 'turnen-wettkampfturnen.php', 'sitemap' => true],
'verein' => ['file' => 'verein.php', 'sitemap' => true], 'verein' => ['file' => 'verein.php', 'sitemap' => true],
'historie' => ['file' => 'historie.php', 'sitemap' => true], 'historie' => ['file' => 'historie.php', 'sitemap' => true],
'impressum' => ['file' => 'impressum.php', 'sitemap' => true], 'impressum' => ['file' => 'impressum.php', 'sitemap' => true],

View File

@@ -12,7 +12,18 @@
{ "label": "Jugendfußball", "slug": "jugendfussball" } { "label": "Jugendfußball", "slug": "jugendfussball" }
] ]
}, },
{ "label": "Turnen", "slug": "turnen" }, {
"label": "Turnen",
"slug": "turnen",
"children": [
{ "label": "Übersicht", "slug": "turnen" },
{ "label": "Erwachsenenturnen", "slug": "turnen/erwachsenenturnen" },
{ "label": "Eltern-Kind-Turnen", "slug": "turnen/eltern-kind-turnen" },
{ "label": "Step Aerobic, Fitness und Pilates", "slug": "turnen/step-aerobic-fitness-pilates" },
{ "label": "Trampolin", "slug": "turnen/trampolin" },
{ "label": "Wettkampfturnen", "slug": "turnen/wettkampfturnen" }
]
},
{ {
"label": "Der Verein", "label": "Der Verein",
"slug": "verein", "slug": "verein",

244
data/turnen.json Normal file
View File

@@ -0,0 +1,244 @@
{
"overview": {
"hero": {
"align": "bottom-left",
"compact": true,
"title": "Turnen",
"text": "Entdecke Ansprechpartner und alle wichtigen Informationen rund ums Turnen beim TSV 08 Kulmbach.",
"image": {
"base": "img/hero/hero",
"widths": [640, 1000, 1600],
"alt": "Turnen beim TSV 08 Kulmbach"
},
"ctas": []
},
"cards_intro": "Die Turnabteilung des TSV 08 Kulmbach bietet neben dem klassischen Gerätturnen sowohl Trampolinturnen als auch Step Aerobic, Fitness und Pilates an. Weitere Informationen zu den Gruppen findest du in den einzelnen Rubriken.",
"fees_title": "Mitgliedsbeiträge",
"fees_intro": "Der Beitrag der Turnabteilung kommt zum allgemeinen TSV-Mitgliedsbeitrag hinzu. Trainiert dein Kind besonders viel, greift zusätzlich eine Förderstufe.",
"fees": [
{
"title": "Zusatzbeitrag für bestehende TSV-Mitglieder",
"rows": [
{ "label": "Einzelperson", "price": "24,00 € / Jahr" },
{ "label": "Familie", "price": "48,00 € / Jahr" }
],
"note": "Zusatzbeitrag zum bestehenden TSV-Mitgliedsbeitrag."
},
{
"title": "Gesamtbeitrag für Neumitglieder",
"rows": [
{ "label": "Kinder und Jugendliche", "price": "84,00 € / Jahr" },
{ "label": "Erwachsene", "price": "94,00 € / Jahr" },
{ "label": "Familie (ab 3 Personen)", "price": "184,00 € / Jahr" }
],
"note": "Bei einer Neuanmeldung sind sowohl der Grundbeitrag als auch der Abteilungsbeitrag Turnen, Verbandsabgaben und Sportunfall-Versicherung bereits enthalten."
},
{
"title": "Förderstufen (zusätzlich, je Jahr)",
"rows": [
{ "label": "Förderstufe 1 · 2 bis 4 Std. / Woche", "price": "120,00 € / Jahr" },
{ "label": "Förderstufe 2 · über 4 bis 8 Std. / Woche", "price": "180,00 € / Jahr" },
{ "label": "Förderstufe 3 · über 8 Std. / Woche", "price": "240,00 € / Jahr" }
],
"note": "Teilnehmer in Gruppen, die pro Woche zwei und mehr Stunden im „Mäximum Gym“ trainieren, fallen in eine Förderstufe. Die Förderstufenbeiträge fallen jährlich zusätzlich zum Mitgliedsbeitrag an."
}
],
"austritt": {
"title": "Austritt",
"text": "Der Austritt aus dem Verein ist nur zum Ende eines Kalenderjahres möglich und muss bis spätestens 30. September schriftlich erklärt werden. Der Beitrag ist in jedem Fall bis zum Jahresende zu entrichten."
},
"faq": [
{ "q": "Welche Turngruppen gibt es beim TSV 08 Kulmbach?", "a": "Eltern-Kind- und Kinderturnen, Erwachsenenturnen, Step Aerobic, Fitness und Pilates, Trampolinturnen sowie Wettkampfturnen von den Jüngsten ab 2 Jahren bis zu Erwachsenen." },
{ "q": "Ab welchem Alter kann mein Kind mitturnen?", "a": "Beim Eltern-Kind-Turnen starten die Jüngsten bereits ab etwa 2 Jahren gemeinsam mit ihren Eltern. Für ältere Kinder gibt es nach Alter gestaffelte Breitensportgruppen." },
{ "q": "Wo finden die Turnstunden statt?", "a": "Die meisten Gruppen trainieren im Mäximum Gym (Thurnauer Str. 51, 95326 Kulmbach). Step Aerobic, Fitness und Pilates laufen in der Max-Hundt-Schule, das Trampolinturnen in der Dreifachturnhalle der Carl-von-Linde-Realschule." },
{ "q": "Was kostet die Turnabteilung?", "a": "Bestehende TSV-Mitglieder zahlen einen Zusatzbeitrag von 24,00 € (Einzelperson) bzw. 48,00 € pro Jahr (Familie). Neumitglieder zahlen 84,00 € (Kinder/Jugendliche), 94,00 € (Erwachsene) oder 184,00 € (Familie ab 3 Personen) im Jahr inklusive Grundbeitrag, Verbandsabgaben und Sportunfall-Versicherung. Bei hohem Trainingsumfang kommt eine Förderstufe hinzu." },
{ "q": "Kann ich vorher zum Probetraining kommen?", "a": "Ja. Bei Interesse an einer aktiven Teilnahme nutze bitte zunächst unser Anfrageformular bzw. die Anmeldung, damit wir die aktuelle Platzverfügbarkeit prüfen können. Fragen beantworten wir auch per E-Mail an turnabteilung.tsv08kulmbach@gmail.com." }
],
"cta": {
"title": "Lust aufs Turnen bekommen?",
"text": "Bei Interesse an einer aktiven Teilnahme nutze bitte zunächst unser Anfrageformular bzw. die Anmeldung so prüfen wir die aktuelle Platzverfügbarkeit. Fragen beantwortet die Turnabteilung unter turnabteilung.tsv08kulmbach@gmail.com.",
"ctas": [
{ "label": "Mitglied werden", "slug": "mitglied-werden#anmeldung-turnen", "style": "primary" },
{ "label": "Zur Turn-Übersicht", "slug": "turnen", "style": "outline" }
]
}
},
"footnote": "* So im Trainingsplan der Abteilung gekennzeichnet.",
"disciplines": {
"erwachsenenturnen": {
"hero": {
"align": "bottom-left",
"compact": true,
"title": "Erwachsenenturnen",
"text": "Beweglich bleiben, Kraft und Koordination trainieren Turnen für Erwachsene im Mäximum Gym.",
"image": { "base": "img/hero/hero", "widths": [640, 1000, 1600], "alt": "Erwachsenenturnen beim TSV 08 Kulmbach" },
"ctas": []
},
"location": { "venue": "Mäximum Gym", "street": "Thurnauer Str. 51", "zip": "95326", "city": "Kulmbach" },
"lead": "Maxi Roßberg",
"groups": [
{
"name": "Erwachsenenturnen",
"sessions": [
{ "day": "Montag", "time": "18:00 20:00 Uhr" },
{ "day": "Mittwoch", "time": "18:00 20:00 Uhr" },
{ "day": "Donnerstag", "time": "18:30 20:00 Uhr" }
],
"trainers": []
}
]
},
"eltern-kind-turnen": {
"hero": {
"align": "bottom-left",
"compact": true,
"title": "Eltern-Kind- & Kinderturnen",
"text": "Bei uns starten die Jüngsten bereits ab 2 Jahren gemeinsam mit ihren Eltern und turnen sich über die Breitensportgruppen Schritt für Schritt nach oben.",
"image": { "base": "img/hero/hero", "widths": [640, 1000, 1600], "alt": "Eltern-Kind- und Kinderturnen beim TSV 08 Kulmbach" },
"ctas": []
},
"layout": "blocks",
"location": { "venue": "Mäximum Gym", "street": "Thurnauer Str. 51", "zip": "95326", "city": "Kulmbach" },
"lead": "Annelie Frisque",
"notice": "Aktuell sind alle Kinderturngruppen belegt. Bei Interesse setzen wir sie gerne auf die Warteliste.",
"groups": [
{
"name": "Eltern-Kind-Turnen",
"level": "ab ca. 2 4 Jahren",
"intro": "Bei uns starten die Jüngsten bereits ab 2 Jahren gemeinsam mit ihren Eltern. In dieser Gruppe kombinieren wir das klassische Eltern-Kind-Turnen mit Elementen des Kleinkinderturnens.",
"details": [
{ "heading": "Inhalt und Ziele", "text": "Wir fördern nicht nur eine sportartenübergreifende motorische Grundlagenausbildung, sondern vermitteln auch erste turnspezifische Grundlagen. Das oberste Ziel ist es, Spaß an der Bewegung zu wecken und persönliche Erfolgserlebnisse zu ermöglichen." },
{ "heading": "Ablauf und Struktur", "text": "Unser Konzept folgt festen Ritualen: Ein gemeinsames Aufwärmen und ein gemeinsamer Abschluss bilden den Rahmen. Den Hauptteil der Stunde bilden abwechslungsreiche Stationen oder Parcours, an denen sich die Kinder ausprobieren können. Für die Sicherheit vermitteln wir den Kindern frühzeitig Grundregeln (z. B. nur eine Person am Gerät)." },
{ "heading": "Motto", "text": "„Vieles kann, nichts muss“ die Kinder entscheiden gemeinsam mit ihren Eltern, was und wie viel sie ausprobieren möchten." }
],
"recommendation": "Bei besonderem Potenzial für Wettkampf- oder Leistungsgruppen sprechen unsere Trainer eine Empfehlung aus.",
"sessions": [
{ "label": "Kängurus", "day": "Dienstag", "time": "16:30 17:15 Uhr", "trainers": ["Carina Schleicher*"] },
{ "label": "Grashüpfer", "day": "Donnerstag", "time": "15:30 16:15 Uhr", "trainers": ["Annelie Frisque*", "Eva Wünsch"] }
]
},
{
"name": "Mäuse",
"level": "Breitensport · 5 7 Jahre",
"intro": "In unserer Gruppe für 5- bis 7-Jährige turnen die Kinder erstmals eigenständig und ohne elterliche Begleitung. Wir bieten einen idealen Einstieg in den Turnsport egal, ob das Kind bereits Vorerfahrungen aus dem Eltern-Kind-Turnen mitbringt oder ganz neu mit dem Turnen beginnt.",
"details": [
{ "heading": "Ziele und Entwicklung", "text": "Wir fördern gezielt die Beweglichkeit, Kraft und Koordination der Kinder. Dabei bauen wir auf vorhandenen Grundlagen auf oder vermitteln diese spielerisch neu, um eine vielseitige sportliche Basis zu schaffen." },
{ "heading": "An den Geräten", "text": "Ein Schwerpunkt liegt auf dem Kennenlernen der klassischen Wettkampfgeräte. Hier erlernen die Kinder erste turnspezifische Elemente und entwickeln Sicherheit sowie eine bessere Körperbeherrschung." }
],
"recommendation": "Bei besonderem Potenzial für Wettkampf- oder Leistungsgruppen sprechen unsere Trainer eine Empfehlung aus.",
"sessions": [
{ "label": "Mäuse I", "day": "Dienstag", "time": "17:30 18:30 Uhr", "trainers": ["Maxi Roßberg*", "Katrin und Marcus Braese"] },
{ "label": "Mäuse II", "day": "Donnerstag", "time": "16:30 17:30 Uhr", "trainers": ["Franziska Trotzke"] }
]
},
{
"name": "Tiger & Hühner",
"level": "Breitensport · ab 8 Jahre",
"intro": "In unseren Breitensportgruppen für Kinder und Jugendliche ab 8 Jahren steht die Begeisterung für Sport und Bewegung im Mittelpunkt. Wir bieten ein vielseitiges Training für alle, die Spaß am Turnen haben unabhängig vom Leistungsstand.",
"details": [
{ "heading": "Ziele und Training", "text": "Wir fördern die Fitness und Beweglichkeit durch ein breites Spektrum an Übungen. Dabei erlernen die Teilnehmer je nach ihren individuellen Möglichkeiten und Voraussetzungen verschiedene Basis-Turnelemente." },
{ "heading": "Der Fokus", "text": "Neben dem sportlichen Fortschritt legen wir großen Wert auf Teamgeist und den Spaß an der gemeinsamen Aktivität in der Halle." }
],
"recommendation": "Bei besonderem Potenzial für Wettkampf- oder Leistungsgruppen sprechen unsere Trainer eine Empfehlung aus.",
"trainers": ["Maxi Roßberg*", "Franziska Schmitt"],
"sessions": [
{ "label": "Tiger · 8 10 Jahre", "day": "Dienstag", "time": "18:30 19:30 Uhr", "note": "in geraden Kalenderwochen" },
{ "label": "Hühner · ab 11 Jahre", "day": "Dienstag", "time": "19:30 20:30 Uhr", "note": "in geraden Kalenderwochen" }
]
},
{
"name": "Flamingos",
"level": "Turnen · fortgeschritten · Alter nach Absprache",
"intro": "In unserer Gruppe für fortgeschrittenes Turnen bauen wir auf bereits erlernten turnerischen Fähigkeiten auf. Das Training orientiert sich an den Anforderungen der LK3 (Kür modifiziert Leistungsklasse 3).",
"details": [
{ "heading": "Trainingsinhalte", "text": "Je nach Voraussetzung erlernen wir Elemente wie Radwende, Flick-Flack und Salto (Boden), Kippen und Felge vorlings (Barren), Überschläge (Sprung) sowie Räder und Bogengänge (Balken)." },
{ "heading": "Wettkämpfe & Teamgeist", "text": "Wir nehmen vorzugsweise an Mannschaftswettkämpfen teil, um den Teamgeist zu fördern und die individuelle Leistung als Teil eines gemeinsamen Erfolgs zu erleben." }
],
"recommendation": "Eine Teilnahme erfolgt ausschließlich auf Empfehlung und Einladung durch unser Trainerteam. Wir gleichen das Leistungsniveau regelmäßig ab, um für jedes Kind die optimale Gruppe zu finden.",
"trainers": ["Christa Knarr*", "Maxi Roßberg*", "Annelie Frisque*", "Theresa Diener", "Lea Schramm", "Charlyn Simon", "Lia Buchwald"],
"sessions": [
{ "day": "Montag", "time": "18:00 19:00 Uhr" },
{ "day": "Mittwoch", "time": "18:00 20:00 Uhr" }
]
}
]
},
"step-aerobic-fitness-pilates": {
"hero": {
"align": "bottom-left",
"compact": true,
"title": "Step Aerobic, Fitness & Pilates",
"text": "Ausdauer, Kräftigung und Beweglichkeit für Erwachsene in der Max-Hundt-Schule.",
"image": { "base": "img/hero/hero", "widths": [640, 1000, 1600], "alt": "Step Aerobic, Fitness und Pilates beim TSV 08 Kulmbach" },
"ctas": []
},
"location": { "venue": "Max-Hundt-Schule", "city": "Kulmbach" },
"lead": "Karola Lorz",
"groups": [
{
"name": "Pilates",
"sessions": [ { "day": "Mittwoch", "time": "17:30 18:30 Uhr" } ],
"trainers": ["Karola Lorz"]
},
{
"name": "Fitness & Stretching",
"sessions": [ { "day": "Mittwoch", "time": "18:45 19:45 Uhr" } ],
"trainers": ["Karola Lorz"]
},
{
"name": "Step-Aerobic",
"sessions": [ { "day": "Donnerstag", "time": "19:30 20:30 Uhr" } ],
"trainers": ["Heike Wahler"]
}
]
},
"trampolin": {
"hero": {
"align": "bottom-left",
"compact": true,
"title": "Trampolinturnen",
"text": "Sprünge, Schrauben und Salti auf dem Großtrampolin in der Dreifachturnhalle der Carl-von-Linde-Realschule.",
"image": { "base": "img/hero/hero", "widths": [640, 1000, 1600], "alt": "Trampolinturnen beim TSV 08 Kulmbach" },
"ctas": []
},
"location": { "venue": "Dreifachturnhalle der Carl-von-Linde-Realschule", "city": "Kulmbach" },
"lead": "Tina Kornatz",
"groups": [
{
"name": "Trampolinturnen",
"sessions": [
{ "day": "Montag", "time": "17:30 / 18:00 20:30 Uhr" },
{ "day": "Donnerstag", "time": "17:30 / 18:00 20:30 Uhr" }
],
"note": "Der Einstieg erfolgt gestaffelt um 17:30 bzw. 18:00 Uhr.",
"trainers": []
}
]
},
"wettkampfturnen": {
"hero": {
"align": "bottom-left",
"compact": true,
"title": "Wettkampfturnen",
"text": "Leistungsorientiertes Gerätturnen mit regelmäßigem Training und Wettkämpfen im Mäximum Gym.",
"image": { "base": "img/hero/hero", "widths": [640, 1000, 1600], "alt": "Wettkampfturnen beim TSV 08 Kulmbach" },
"ctas": []
},
"location": { "venue": "Mäximum Gym", "street": "Thurnauer Str. 51", "zip": "95326", "city": "Kulmbach" },
"lead": "Franziska Trotzke",
"groups": [
{
"name": "Wettkampfturnen",
"sessions": [
{ "day": "Montag", "time": "15:00 18:00 Uhr" },
{ "day": "Mittwoch", "time": "15:00 18:00 Uhr" },
{ "day": "Donnerstag", "time": "16:30 18:30 Uhr" },
{ "day": "Freitag", "time": "14:00 17:00 Uhr" },
{ "day": "Samstag", "time": "09:00 13:00 Uhr" }
],
"trainers": []
}
]
}
}
}

View File

@@ -1465,6 +1465,340 @@
} }
} }
/* === turnen-dash (Turn-Disziplin-Dashboard im Bento-Look wie Mannschaftsseiten) === */
.turnen-dash {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.25rem;
}
/* Eine Gruppe: Trainingszeiten (2/3) + Verantwortlich (1/3), Ort volle Breite darunter. */
.turnen-dash--single {
grid-template-areas:
"train train lead"
"venue venue venue";
}
.turnen-dash--single .turnen-dash__training { grid-area: train; }
.turnen-dash--single .turnen-dash__contact { grid-area: lead; }
.turnen-dash--single .turnen-dash__venue { grid-area: venue; }
/* Mehrere Gruppen: Ort (2/3) + Kontakt rechts (1/3) — Zeiten stehen je Gruppe.
Kontakt steht dadurch konsistent rechts wie bei den Einzel-Disziplinen. */
.turnen-dash:not(.turnen-dash--single) {
grid-template-areas: "venue venue lead";
}
.turnen-dash:not(.turnen-dash--single) .turnen-dash__contact { grid-area: lead; }
.turnen-dash:not(.turnen-dash--single) .turnen-dash__venue { grid-area: venue; }
/* Mit Hinweis-Kachel: rote Banner-Zeile ganz oben (volle Breite). */
.turnen-dash--notice.turnen-dash--single {
grid-template-areas:
"notice notice notice"
"train train lead"
"venue venue venue";
}
.turnen-dash--notice:not(.turnen-dash--single) {
grid-template-areas:
"notice notice notice"
"venue venue lead";
}
.turnen-dash__notice { grid-area: notice; }
/* Hinweis-Kachel: klar rot, weiße Schrift, Icon links (z. B. Wartelisten-Status). */
.turnen-dash__notice {
flex-direction: row;
align-items: flex-start;
gap: 0.7rem;
background: var(--clr-accent);
border-color: var(--clr-accent);
color: #fff;
}
.turnen-dash__notice p {
margin: 0;
max-width: none;
font-size: var(--fs-600);
line-height: 1.5;
}
.turnen-dash__notice-icon {
flex: none;
margin-top: 0.1em;
font-size: 1.5rem;
}
/* Trainingsort: Adresse links, Route-Button rechts (wie team-bento__venue). */
.turnen-dash__venue {
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: 1.25rem;
}
.turnen-dash__venue-main {
position: relative;
z-index: 1;
}
.turnen-dash__venue .bento__heading {
margin-bottom: 0.6rem;
}
.turnen-dash__route {
position: relative;
z-index: 1;
flex: none;
}
/* Kontakt-Kachel: schlichter weißer Mail-Link (zentriert) auf der Akzentfläche. */
.turnen-dash__mail {
display: inline-flex;
align-self: center;
align-items: center;
gap: 0.45rem;
margin-top: 0.75rem;
color: #fff;
font-size: var(--fs-500);
text-decoration: underline;
text-underline-offset: 0.2em;
}
.turnen-dash__mail:hover,
.turnen-dash__mail:focus-visible {
color: rgb(255 255 255 / 0.82);
}
.turnen-dash__mail-icon {
flex: none;
}
@media (max-width: 900px) {
.turnen-dash,
.turnen-dash--single {
grid-template-columns: 1fr;
grid-template-areas:
"train"
"lead"
"venue";
}
.turnen-dash:not(.turnen-dash--single) {
grid-template-areas:
"lead"
"venue";
}
.turnen-dash--notice,
.turnen-dash--notice.turnen-dash--single {
grid-template-areas:
"notice"
"train"
"lead"
"venue";
}
.turnen-dash--notice:not(.turnen-dash--single) {
grid-template-areas:
"notice"
"lead"
"venue";
}
}
/* === group-list (Turn-Gruppen einer Disziplin) === */
.group-list__title {
margin-bottom: 1.5rem;
}
/* Schlichte Gruppen (z. B. Kurse) als Raster, beschreibende Gruppen gestapelt. */
.group-list--grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 1.25rem;
}
.group-list--stacked {
display: flex;
flex-direction: column;
gap: 1.25rem;
}
.group-card {
padding: 1.75rem 2rem 2rem;
background: var(--clr-glass-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
}
/* Gestapelt: Beschreibung links, Trainingszeiten-Panel rechts. */
.group-list--stacked .group-card {
display: grid;
grid-template-columns: 1.6fr 1fr;
gap: 2.5rem;
align-items: start;
padding: 2rem 2.25rem;
}
@media (max-width: 768px) {
.group-list--stacked .group-card {
grid-template-columns: 1fr;
gap: 1.5rem;
padding: 1.6rem 1.75rem 1.75rem;
}
}
/* Beschreibungsspalte: angenehme Zeilenlänge + Lesefluss. */
.group-card__body {
max-width: 64ch;
}
.group-card__name {
font-size: clamp(1.9rem, 1.5rem + 1.2vw, 2.3rem);
line-height: var(--lh-heading);
}
.group-card__level {
margin: -0.15rem 0 0;
font-size: var(--fs-500);
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--clr-text-muted);
}
.group-card__intro {
margin: 0.85rem 0 0;
line-height: 1.65;
}
.group-card__detail-heading {
margin: 1.6rem 0 0;
/* Body-Schrift (Abel) als Eyebrow — Coolvetica wäre in dieser Größe unleserlich. */
font-family: var(--ff-body);
font-size: var(--fs-500);
font-weight: 400;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--clr-accent);
}
.group-card__detail-text {
margin: 0.4rem 0 0;
line-height: 1.65;
}
.group-card__recommendation {
margin: 1.6rem 0 0;
padding-top: 1.1rem;
border-top: 1px solid var(--clr-glass-border);
font-size: var(--fs-500);
font-style: italic;
line-height: 1.6;
}
/* Trainingszeiten-Panel in der Karte. */
.group-card__schedule {
margin-top: 1.25rem;
}
.group-list--stacked .group-card__schedule {
margin-top: 0;
padding: 1.5rem 1.6rem;
background: var(--clr-bg);
border: 1px solid var(--clr-glass-border);
border-radius: var(--radius-card);
}
.group-card__schedule-title {
display: flex;
align-items: center;
gap: 0.5rem;
margin: 0 0 0.85rem;
font-size: var(--fs-600);
}
.group-card__schedule-icon {
flex: none;
color: var(--clr-accent);
}
.group-card__trainers {
margin: 0.85rem 0 0;
font-size: var(--fs-500);
line-height: 1.5;
}
.group-card__note {
margin: 0.5rem 0 0;
font-size: var(--fs-500);
}
/* Trainingszeiten-Liste (Tag/Zeit + optional Label, Notiz, Übungsleitung). */
.schedule-list {
margin: 0;
padding: 0;
list-style: none;
}
.schedule-row {
padding: 0.7rem 0;
border-bottom: 1px solid var(--clr-glass-border);
}
.schedule-row:first-child { padding-top: 0; }
.schedule-row:last-child { padding-bottom: 0; border-bottom: 0; }
.schedule-row__label {
display: block;
margin-bottom: 0.2rem;
font-size: var(--fs-600);
color: var(--clr-text);
}
.schedule-row__when {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 1rem;
}
.schedule-row__time {
font-size: var(--fs-600);
text-align: right;
white-space: nowrap;
}
.schedule-row__note {
display: block;
margin-top: 0.15rem;
font-size: var(--fs-500);
}
.schedule-row__trainers {
display: block;
margin-top: 0.25rem;
font-size: var(--fs-500);
line-height: 1.5;
}
.schedule-row__trainers-label {
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--clr-text-muted);
}
.group-list__footnote {
margin: 1.5rem 0 0;
font-size: var(--fs-500);
}
@media (max-width: 600px) {
.schedule-row__when {
flex-direction: column;
gap: 0.15rem;
}
.schedule-row__time {
text-align: left;
}
}
/* === cta-band === */ /* === cta-band === */
.cta-band__inner { .cta-band__inner {
max-width: 60ch; max-width: 60ch;

View File

@@ -0,0 +1,2 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
<path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0"/></svg>

After

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB