Vereinshistorie-Seite: kompakter Hero, interaktive Museums-Timeline (Scroll-Reveal, Jahres-Sprungnav), Originalbilder unverändert
routes.php enthält auch die fussball-Route (User-WIP, Seite existiert) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,12 +4,14 @@ declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Vollflächiger Hero mit Hintergrundbild/-video, Titel, Intro und CTAs.
|
||||
* Props: $hero (array aus home.json: title, text, image, video?, ctas, align?)
|
||||
* Props: $hero (array aus home.json: title, text, image, video?, ctas, align?, compact?)
|
||||
* align-Varianten: 'center' (mittig zentriert), 'bottom-left' (Default).
|
||||
* compact: true → niedrigere Variante für Unterseiten-Header.
|
||||
*/
|
||||
$align = in_array($hero['align'] ?? '', ['center', 'bottom-left'], true) ? $hero['align'] : 'bottom-left';
|
||||
$compact = !empty($hero['compact']);
|
||||
?>
|
||||
<section class="hero<?= $align === 'center' ? ' hero--center' : '' ?>">
|
||||
<section class="hero<?= $align === 'center' ? ' hero--center' : '' ?><?= $compact ? ' hero--compact' : '' ?>">
|
||||
<div class="hero__media" aria-hidden="true">
|
||||
<?php component('img', ['image' => $hero['image'], 'sizes' => '100vw', 'eager' => true, 'class' => 'hero__img']); ?>
|
||||
<?php if (!empty($hero['video'])): ?>
|
||||
@@ -19,11 +21,15 @@ $align = in_array($hero['align'] ?? '', ['center', 'bottom-left'], true) ? $hero
|
||||
</div>
|
||||
<div class="container hero__content">
|
||||
<h1 class="hero__title"><?= e($hero['title']) ?><?php if (!empty($hero['tagline'])): ?> <span class="hero__tagline"><?= e($hero['tagline']) ?></span><?php endif; ?></h1>
|
||||
<?php if (!empty($hero['text'])): ?>
|
||||
<p class="hero__text"><?= e($hero['text']) ?></p>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($hero['ctas'])): ?>
|
||||
<div class="hero__actions">
|
||||
<?php foreach ($hero['ctas'] as $cta): ?>
|
||||
<?php component('cta', ['cta' => $cta]); ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
57
app/components/timeline.php
Normal file
57
app/components/timeline.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Interaktive Vereins-Timeline (Museums-Look). Props:
|
||||
* $events array — Stationen aus data/historie.json (year, text, image{src,width,height,alt})
|
||||
* Bilder werden bewusst in ORIGINALGRÖSSE eingebunden (keine Varianten) —
|
||||
* historisches Material bleibt unangetastet.
|
||||
* timeline.js ergänzt Scroll-Reveal + aktive Jahres-Navigation; ohne JS ist
|
||||
* alles sichtbar (Initial-Versteckt-Zustand nur unter .js-reveal).
|
||||
*/
|
||||
|
||||
// Anker je Jahr — Duplikate (2x 1972) bekommen einen Suffix, die Jahres-Nav
|
||||
// führt auf das jeweils erste Vorkommen.
|
||||
$seen = [];
|
||||
$prepared = [];
|
||||
foreach ($events as $event) {
|
||||
$slug = 'jahr-' . strtolower(preg_replace('/[^a-zA-Z0-9]+/', '-', $event['year']));
|
||||
$first = !isset($seen[$slug]);
|
||||
$seen[$slug] = ($seen[$slug] ?? 0) + 1;
|
||||
$prepared[] = $event + [
|
||||
'id' => $first ? $slug : $slug . '-' . $seen[$slug],
|
||||
'nav' => $slug,
|
||||
];
|
||||
}
|
||||
?>
|
||||
<section class="section timeline-section" data-timeline>
|
||||
<div class="container">
|
||||
<nav class="timeline-nav" aria-label="Zeitsprünge">
|
||||
<ol class="timeline-nav__list">
|
||||
<?php foreach ($prepared as $event): ?>
|
||||
<?php if ($event['id'] === $event['nav']): ?>
|
||||
<li><a href="#<?= e($event['nav']) ?>"><?= e($event['year']) ?></a></li>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</ol>
|
||||
</nav>
|
||||
<ol class="timeline">
|
||||
<?php foreach ($prepared as $i => $event): ?>
|
||||
<li class="timeline__event" id="<?= e($event['id']) ?>" data-nav="<?= e($event['nav']) ?>">
|
||||
<span class="timeline__marker" aria-hidden="true"></span>
|
||||
<article class="timeline__card">
|
||||
<h2 class="timeline__year"><?= e($event['year']) ?></h2>
|
||||
<figure class="timeline__figure">
|
||||
<img src="<?= e(asset($event['image']['src'])) ?>"
|
||||
alt="<?= e($event['image']['alt']) ?>"
|
||||
width="<?= e($event['image']['width']) ?>" height="<?= e($event['image']['height']) ?>"
|
||||
loading="<?= $i === 0 ? 'eager' : 'lazy' ?>" decoding="async">
|
||||
<figcaption class="timeline__text"><?= e($event['text']) ?></figcaption>
|
||||
</figure>
|
||||
</article>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ol>
|
||||
</div>
|
||||
</section>
|
||||
23
app/pages/historie.php
Normal file
23
app/pages/historie.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Vereinshistorie — schmaler Hero + interaktive Timeline.
|
||||
* Inhalte: data/historie.json (Single Source of Truth).
|
||||
*/
|
||||
$historie = json_load('historie');
|
||||
|
||||
$meta = [
|
||||
'title' => 'Vereinshistorie – Der Katzbachtaler Weg',
|
||||
'description' => 'Erlebe die bewegte Geschichte des TSV 08 Kulmbach – von den ersten Spielen an der Bayreuther Straße 1947 bis zur Hans-Rausch-Sportanlage im Katzbachtal.',
|
||||
'scripts' => ['timeline.js'],
|
||||
];
|
||||
|
||||
component('hero', ['hero' => $historie['hero']]);
|
||||
?>
|
||||
<div class="container section--slim">
|
||||
<p class="timeline-intro"><?= e($historie['intro']) ?></p>
|
||||
</div>
|
||||
<?php
|
||||
component('timeline', ['events' => $historie['events']]);
|
||||
@@ -10,6 +10,8 @@ declare(strict_types=1);
|
||||
* Canonical und Sitemap folgen automatisch.
|
||||
*/
|
||||
return [
|
||||
'' => ['file' => 'home.php', 'sitemap' => true],
|
||||
'404' => ['file' => '404.php', 'sitemap' => false],
|
||||
'' => ['file' => 'home.php', 'sitemap' => true],
|
||||
'fussball' => ['file' => 'fussball.php', 'sitemap' => true],
|
||||
'historie' => ['file' => 'historie.php', 'sitemap' => true],
|
||||
'404' => ['file' => '404.php', 'sitemap' => false],
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user