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
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Ausgaben-Archiv der Stadionzeitung, ganze Karte verlinkt auf die Ausgabe.
|
|
|
|
|
* Props: $issues array aus data/stadionzeitung.json (bereits neueste zuerst).
|
|
|
|
|
* Leer → freundlicher Hinweis statt leerer Sektion (nie brechen).
|
|
|
|
|
*/
|
|
|
|
|
$issues = $issues ?? [];
|
|
|
|
|
?>
|
|
|
|
|
<section class="section stadionzeitung-cards">
|
|
|
|
|
<div class="container">
|
|
|
|
|
<h2 class="visually-hidden">Ausgaben der Stadionzeitung</h2>
|
|
|
|
|
<?php if ($issues === []): ?>
|
|
|
|
|
<p class="text-muted">Noch keine Ausgabe digital verfügbar — zur nächsten Heimspiel-Stadionzeitung schauen wir wieder vorbei.</p>
|
|
|
|
|
<?php else: ?>
|
|
|
|
|
<ul class="stadionzeitung-cards__grid">
|
|
|
|
|
<?php foreach ($issues as $issue): ?>
|
|
|
|
|
<li>
|
|
|
|
|
<a class="stadionzeitung-card" href="<?= e(url('stadionzeitung/' . $issue['slug'])) ?>">
|
|
|
|
|
<div class="stadionzeitung-card__media">
|
|
|
|
|
<?php $firstPage = $issue['images'][0] ?? null; ?>
|
|
|
|
|
<?php if ($firstPage !== null && ($firstPage['type'] ?? 'image') === 'live' && ($firstPage['page'] ?? '') === 'cover'): ?>
|
|
|
|
|
<?php /* Seit dem automatischen Cover (Phase 3) beginnt jede Ausgabe mit der
|
|
|
|
|
echten, live gerenderten Titelseite statt einem Canva-Bild — die
|
|
|
|
|
dient hier direkt als Karten-Vorschau, keine zweite Bildquelle. */ ?>
|
|
|
|
|
<?php component('stadionzeitung-cover', ['issue' => $issue]); ?>
|
|
|
|
|
<?php elseif ($firstPage !== null): ?>
|
|
|
|
|
<?php component('img', ['image' => $firstPage, 'sizes' => '(max-width: 600px) 100vw, 360px', 'class' => 'stadionzeitung-card__img']); ?>
|
|
|
|
|
<?php endif; ?>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="stadionzeitung-card__body">
|
|
|
|
|
<h3 class="stadionzeitung-card__name">Gegen <?= e($issue['opponent']) ?></h3>
|
|
|
|
|
<p class="stadionzeitung-card__meta">
|
|
|
|
|
<time datetime="<?= e($issue['date']) ?>"><?= e(german_date($issue['date'])) ?></time>
|
|
|
|
|
· <?= (int) $issue['pages'] ?> Seiten
|
|
|
|
|
</p>
|
Stadionzeitungs-Archiv: Liste über die volle Breite statt Regal
Cover links, Angaben rechts daneben — dasselbe Muster wie .veranstaltung-card,
und aus demselben Grund: der Bestand ist klein.
Vorher war es ein horizontales Regal (grid-auto-flow: column, 280px-Spalten,
Scroll-Snap). Der Kommentar dort nannte genau die richtige Gefahr, "bei 1-3
Karten wie eine leere Fläche mit einer verlorenen Karte", löste sie aber nicht:
mit einer veröffentlichten Ausgabe stand eine 280px-Karte allein links auf einer
1280px breiten Seite. Eine Zeile über die volle Breite füllt die Fläche bei jeder
Anzahl.
Zwei Dinge sind dabei anders als bei den Veranstaltungen, beide begründet:
- Die Medienspalte ist schmaler (clamp bis 230px statt 26%), weil das Medium
hier die live gerenderte Cover-Seite mit festem A5-Verhältnis ist. Ein <img>
liesse sich per object-fit beschneiden, das Cover nicht — es bestimmt die
Zeilenhöhe. 230px Cover ergeben 326px Zeile.
- Das margin-top: auto am CTA ist weg. Es stammte aus der hochformatigen Karte,
wo der Link an den Kartenfuss gehörte; in der breiten Zeile riss es die drei
kurzen Zeilen auf 150px auseinander.
Neu in der Zeile: die Coverzeile des Interviews als Teaser (interview.teaser,
dieselbe Quelle wie "Im Heft" auf dem Cover). Sie füllt die Breite mit echtem
Inhalt statt Leerfläche und sagt, warum man die Ausgabe öffnen sollte; ohne
Interview entfällt sie, wie .veranstaltung-card__text.
Geprüft per Screenshot bei 1280px und bei echten 390px (iframe-Wrapper, weil
headless Chrome sonst eine Mindestbreite erzwingt): mobil steht das Cover über
den Angaben.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
2026-07-31 18:30:16 +02:00
|
|
|
<?php /* Coverzeile des Interviews als Teaser — dieselbe Quelle, die auch auf dem
|
|
|
|
|
Cover unter „Im Heft" steht. Sie füllt die breite Zeile mit echtem Inhalt
|
|
|
|
|
statt Leerfläche und sagt, warum man die Ausgabe öffnen sollte. Trägt eine
|
|
|
|
|
Ausgabe kein Interview, entfällt die Zeile (wie bei .veranstaltung-card__text). */
|
|
|
|
|
$kartenTeaser = trim((string) ($issue['interview']['teaser'] ?? '')); ?>
|
|
|
|
|
<?php if ($kartenTeaser !== ''): ?>
|
|
|
|
|
<p class="stadionzeitung-card__text"><?= e($kartenTeaser) ?></p>
|
|
|
|
|
<?php endif; ?>
|
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
|
|
|
<span class="stadionzeitung-card__cta">Ausgabe lesen <?= icon('arrow-right', 'stadionzeitung-card__arrow') ?></span>
|
|
|
|
|
</div>
|
|
|
|
|
</a>
|
|
|
|
|
</li>
|
|
|
|
|
<?php endforeach; ?>
|
|
|
|
|
</ul>
|
|
|
|
|
<?php endif; ?>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|