Compare commits
2 Commits
7aae3d5ca9
...
70831b9bea
| Author | SHA1 | Date | |
|---|---|---|---|
| 70831b9bea | |||
| fbb23a8732 |
17
CLAUDE.md
@@ -548,6 +548,8 @@ Inhalt:
|
|||||||
Rand: Freistellungs-Exporte lassen oft viel leeren, transparenten
|
Rand: Freistellungs-Exporte lassen oft viel leeren, transparenten
|
||||||
Rand stehen, sonst wirkt der Spieler auf dem Cover kleiner als nötig)
|
Rand stehen, sonst wirkt der Spieler auf dem Cover kleiner als nötig)
|
||||||
<ordner>/verfasser.* optional, Porträtfoto für die Signatur im automatischen Vorwort
|
<ordner>/verfasser.* optional, Porträtfoto für die Signatur im automatischen Vorwort
|
||||||
|
<ordner>/galerie/* optional, Fotos vom letzten Spiel (natsort, das erste ist der
|
||||||
|
Aufmacher, höchstens sieben) für die Bento-Galerie-Seite
|
||||||
```
|
```
|
||||||
**Keine Anzeigen im Ablieferordner** (seit 31.07.2026): die kommen aus dem dauerhaften Bestand
|
**Keine Anzeigen im Ablieferordner** (seit 31.07.2026): die kommen aus dem dauerhaften Bestand
|
||||||
`data/anzeigen.json`, gepflegt mit `php bin/anzeige-add.php <bild-oder-ordner>` (Dateiname = Slug,
|
`data/anzeigen.json`, gepflegt mit `php bin/anzeige-add.php <bild-oder-ordner>` (Dateiname = Slug,
|
||||||
@@ -571,6 +573,7 @@ Inhalt ist eine Liste von **Blöcken**, die Anzeigen füllen die Lücken dazwisc
|
|||||||
```
|
```
|
||||||
Cover → [Vorwort → Programm* → Interview → Aufruf (jedes nur wenn die Ausgabe es trägt)] ⌷
|
Cover → [Vorwort → Programm* → Interview → Aufruf (jedes nur wenn die Ausgabe es trägt)] ⌷
|
||||||
[Turnierpläne*: je Turnier eine Seite, EIN Block] ⌷ Ergebnis-Rückblick ⌷
|
[Turnierpläne*: je Turnier eine Seite, EIN Block] ⌷ Ergebnis-Rückblick ⌷
|
||||||
|
[Galerie, nur wenn galerie/ geliefert] ⌷
|
||||||
[Gegnerstatistik: normal nur die tragende Mannschaft, in der Sportfest-Ausgabe je
|
[Gegnerstatistik: normal nur die tragende Mannschaft, in der Sportfest-Ausgabe je
|
||||||
Mannschaft mit Heimspiel am Fest eine — EIN Block, automatisch aus deren Tabelle] ⌷
|
Mannschaft mit Heimspiel am Fest eine — EIN Block, automatisch aus deren Tabelle] ⌷
|
||||||
[je Mannschaft eine Tabelle, Reihenfolge = matchcenter.json — EIN Block, dazwischen nie eine
|
[je Mannschaft eine Tabelle, Reihenfolge = matchcenter.json — EIN Block, dazwischen nie eine
|
||||||
@@ -606,7 +609,7 @@ Lücken bekommen 7 Lücken zwei. Zwei hintereinander ist das Optimum, nicht eins
|
|||||||
Zweier-Paar auf einer Doppelseite landen kann, schlägt man das Heft gelegentlich auf zwei Anzeigen auf.
|
Zweier-Paar auf einer Doppelseite landen kann, schlägt man das Heft gelegentlich auf zwei Anzeigen auf.
|
||||||
Ein `images[]`-Eintrag hat
|
Ein `images[]`-Eintrag hat
|
||||||
`"type": "image"` (wie gehabt, `base`/`widths`/`alt`) oder `"type": "live"` (`page`: `cover` |
|
`"type": "image"` (wie gehabt, `base`/`widths`/`alt`) oder `"type": "live"` (`page`: `cover` |
|
||||||
`vorwort` | `interview` | `programm` | `aufruf` | `turnier` | `tabelle` | `termine` | `news` | `ergebnisse` | `gegner` | `vorschau` | `kontakt` | `mitglied` | `historie` | `sportheim` | `partner` | `danke` | `momente` | `impressum`, kein Bild;
|
`vorwort` | `interview` | `programm` | `aufruf` | `turnier` | `tabelle` | `termine` | `news` | `ergebnisse` | `gegner` | `vorschau` | `kontakt` | `mitglied` | `historie` | `sportheim` | `partner` | `danke` | `momente` | `galerie` | `impressum`, kein Bild;
|
||||||
`tabelle` und `gegner` zusätzlich mit `team`: Team-Key aus `matchcenter.json`, ohne `team` greift der
|
`tabelle` und `gegner` zusätzlich mit `team`: Team-Key aus `matchcenter.json`, ohne `team` greift der
|
||||||
Team-Key der Ausgabe; `turnier` mit `turnier`: Key aus `turniere[]` der Ausgaben-Veranstaltung;
|
Team-Key der Ausgabe; `turnier` mit `turnier`: Key aus `turniere[]` der Ausgaben-Veranstaltung;
|
||||||
`danke` mit `anzeige`: das platzierte Anzeigenmotiv, siehe unten). Fehlt `type` (alte Phase-1-Ausgaben) → Fallback `image`, bricht nicht. **Gerendert
|
`danke` mit `anzeige`: das platzierte Anzeigenmotiv, siehe unten). Fehlt `type` (alte Phase-1-Ausgaben) → Fallback `image`, bricht nicht. **Gerendert
|
||||||
@@ -819,6 +822,18 @@ chat-gepflegt und von `bin/stadionzeitung-add.php` über erneute Läufe durchget
|
|||||||
Nebenbei löst das oft die Seitenzahl: drei Gegnerseiten statt einer sind **zwei Seiten mehr**, und
|
Nebenbei löst das oft die Seitenzahl: drei Gegnerseiten statt einer sind **zwei Seiten mehr**, und
|
||||||
ein Heft, das bei 42 stand, steht damit auf 44.
|
ein Heft, das bei 42 stand, steht damit auf 44.
|
||||||
|
|
||||||
|
**Galerie-Seite (02.10.2026): Fotos vom letzten Spiel als Bento-Raster.** Optional, hinter dem
|
||||||
|
Ergebnis-Rückblick (`stadionzeitung-galerie.php`). Das Feld `galerie` mischt zwei Pfleger, wie bei
|
||||||
|
den Veranstaltungsbildern: `kicker`, `heading`, `text` und die **Alt-Texte** sind Chat-Pflege,
|
||||||
|
`bilder[]` schreibt `bin/stadionzeitung-add.php` aus `<ordner>/galerie/` (Breiten 640/1200).
|
||||||
|
Alt-Texte hängen an `source` (Originaldateiname) und folgen ihrem Bild; neue Fotos bekommen die
|
||||||
|
Überschrift als Platzhalter, das Skript nennt sie per WARN. **Der Ordner ist der komplette
|
||||||
|
Bestand:** ein Lauf ohne `galerie/` lässt die Seite entfallen, weil der Ausgaben-Ordner geleert
|
||||||
|
wurde. Kein Snapshot nötig, die Bilder liegen im Ausgaben-Ordner und kein Sync fasst sie an.
|
||||||
|
Raster: 6×4-Gitter, das erste Foto 4×2, die Anordnung je Anzahl (1 bis 7) als Klasse
|
||||||
|
`__bento--nN` mit `grid-template-areas`. Entstanden als Füllseite, die eine 43-seitige Ausgabe
|
||||||
|
auf 44 brachte.
|
||||||
|
|
||||||
**Gegner- und Ergebnisseite neu gestaltet (19.09.2026).** Beide Seiten waren inhaltlich richtig und
|
**Gegner- und Ergebnisseite neu gestaltet (19.09.2026).** Beide Seiten waren inhaltlich richtig und
|
||||||
gestalterisch leer, der Umbau lief über mehrere verworfene Entwürfe. Was davon bleibt:
|
gestalterisch leer, der Umbau lief über mehrere verworfene Entwürfe. Was davon bleibt:
|
||||||
- **Ergebnisse als Anzeigetafel** (Vorbild kicker/Sofascore): Wappen und Name je Seite, das Ergebnis
|
- **Ergebnisse als Anzeigetafel** (Vorbild kicker/Sofascore): Wappen und Name je Seite, das Ergebnis
|
||||||
|
|||||||
50
app/components/stadionzeitung-galerie.php
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Galerie-Seite der Stadionzeitung (Live-Seite, optional) — Fotos vom letzten
|
||||||
|
* Spiel als Bento-Raster: ein großes Aufmacherfoto, die übrigen in kleineren
|
||||||
|
* Kacheln darum. Das Raster füllt die ganze Blattfläche unter dem Kopf, die
|
||||||
|
* Fotos werden per object-fit auf ihre Kachel beschnitten.
|
||||||
|
*
|
||||||
|
* Props: $issue Eintrag aus data/stadionzeitung.json. Gelesen wird das Feld
|
||||||
|
* `galerie`: `kicker`, `heading`, `text?` sind Chat-Pflege, `bilder[]`
|
||||||
|
* (base/widths/alt/source) schreibt bin/stadionzeitung-add.php aus
|
||||||
|
* <ordner>/galerie/. Alt-Texte kommen aus dem Chat und hängen an `source`.
|
||||||
|
*
|
||||||
|
* Die Bilder liegen im Ausgaben-Ordner und werden von keinem Sync angefasst,
|
||||||
|
* deshalb braucht die Seite keinen Snapshot.
|
||||||
|
*/
|
||||||
|
$galerie = is_array($issue['galerie'] ?? null) ? $issue['galerie'] : [];
|
||||||
|
$bilder = array_slice(array_values(array_filter(
|
||||||
|
$galerie['bilder'] ?? [],
|
||||||
|
static fn ($b): bool => is_array($b) && !empty($b['base']) && !empty($b['widths'])
|
||||||
|
)), 0, 7);
|
||||||
|
$kicker = trim((string) ($galerie['kicker'] ?? 'Rückblick'));
|
||||||
|
$heading = trim((string) ($galerie['heading'] ?? 'Fotos vom letzten Spiel'));
|
||||||
|
$text = trim((string) ($galerie['text'] ?? ''));
|
||||||
|
?>
|
||||||
|
<div class="stadionzeitung-galerie">
|
||||||
|
<header class="stadionzeitung-page__head">
|
||||||
|
<?php if ($kicker !== ''): ?>
|
||||||
|
<p class="stadionzeitung-page__kicker"><?= e($kicker) ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
<h2 class="stadionzeitung-page__heading"><?= e($heading) ?></h2>
|
||||||
|
<?php if ($text !== ''): ?>
|
||||||
|
<p class="stadionzeitung-galerie__text"><?= e($text) ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
</header>
|
||||||
|
<?php if ($bilder !== []): ?>
|
||||||
|
<div class="stadionzeitung-galerie__bento stadionzeitung-galerie__bento--n<?= count($bilder) ?>">
|
||||||
|
<?php foreach ($bilder as $i => $bild): ?>
|
||||||
|
<?php component('img', [
|
||||||
|
'image' => $bild,
|
||||||
|
// Aufmacher gut zwei Drittel der Seitenbreite, die Kacheln ein Drittel.
|
||||||
|
'sizes' => $i === 0 ? '(min-width: 520px) 340px, 70vw' : '(min-width: 520px) 240px, 50vw',
|
||||||
|
'class' => 'stadionzeitung-galerie__foto',
|
||||||
|
]); ?>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
@@ -11,7 +11,8 @@ declare(strict_types=1);
|
|||||||
* type 'image' (base/widths/alt),
|
* type 'image' (base/widths/alt),
|
||||||
* type 'live' (page: cover|vorwort|interview|programm|aufruf|turnier|
|
* type 'live' (page: cover|vorwort|interview|programm|aufruf|turnier|
|
||||||
* tabelle|termine|news|ergebnisse|gegner|vorschau|kontakt|
|
* tabelle|termine|news|ergebnisse|gegner|vorschau|kontakt|
|
||||||
* mitglied|historie|sportheim|partner|danke|momente|impressum;
|
* mitglied|historie|sportheim|partner|danke|momente|galerie|
|
||||||
|
* impressum;
|
||||||
* tabelle und gegner optional mit team: Team-Key aus
|
* tabelle und gegner optional mit team: Team-Key aus
|
||||||
* matchcenter.json; turnier mit turnier: Key aus
|
* matchcenter.json; turnier mit turnier: Key aus
|
||||||
* veranstaltungen.json → turniere[] der Ausgaben-Veranstaltung),
|
* veranstaltungen.json → turniere[] der Ausgaben-Veranstaltung),
|
||||||
@@ -96,6 +97,9 @@ $type = $entry['type'] ?? 'image';
|
|||||||
wie jede andere Anzeige in images[] eingefroren ist. */ ?>
|
wie jede andere Anzeige in images[] eingefroren ist. */ ?>
|
||||||
<?php component('stadionzeitung-danke', ['anzeige' => $entry['anzeige'] ?? null]); ?>
|
<?php component('stadionzeitung-danke', ['anzeige' => $entry['anzeige'] ?? null]); ?>
|
||||||
<?php break; ?>
|
<?php break; ?>
|
||||||
|
<?php case 'galerie': ?>
|
||||||
|
<?php component('stadionzeitung-galerie', ['issue' => $issue]); ?>
|
||||||
|
<?php break; ?>
|
||||||
<?php case 'momente': ?>
|
<?php case 'momente': ?>
|
||||||
<?php component('stadionzeitung-momente', ['items' => $data['momente'] ?? []]); ?>
|
<?php component('stadionzeitung-momente', ['items' => $data['momente'] ?? []]); ?>
|
||||||
<?php break; ?>
|
<?php break; ?>
|
||||||
|
|||||||
@@ -386,6 +386,24 @@ if (is_file($szFile)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Stadionzeitung: Galerie-Fotos vorhanden? ---
|
||||||
|
// Die Galerie-Bilder liegen im Ausgaben-Ordner, den bin/stadionzeitung-add.php bei
|
||||||
|
// jedem Lauf leert und neu füllt. Fehlt eine Datei (Lauf ohne galerie/ im Ordner,
|
||||||
|
// Bild nicht mitcommittet), zeigt die Seite ein kaputtes Bild.
|
||||||
|
if (is_file($szFile)) {
|
||||||
|
$szData = $szData ?? (json_decode((string) file_get_contents($szFile), true) ?: []);
|
||||||
|
foreach ($szData['issues'] ?? [] as $ausgabe) {
|
||||||
|
foreach ($ausgabe['galerie']['bilder'] ?? [] as $bild) {
|
||||||
|
foreach ($bild['widths'] ?? [] as $w) {
|
||||||
|
$datei = PUBLIC_PATH . '/assets/' . ($bild['base'] ?? '') . "-{$w}.jpg";
|
||||||
|
if (!is_file($datei)) {
|
||||||
|
$errors[] = "Stadionzeitung '{$ausgabe['slug']}': Galerie-Foto fehlt (" . ($bild['base'] ?? '?') . "-{$w}.jpg).";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- Inline-Styles (die CSP verwirft sie stillschweigend) ---
|
// --- Inline-Styles (die CSP verwirft sie stillschweigend) ---
|
||||||
// Diese Prüfung existiert wegen eines echten Ausfalls am 31.07.2026: der
|
// Diese Prüfung existiert wegen eines echten Ausfalls am 31.07.2026: der
|
||||||
// Banner-Slider setzte sein Hintergrundbild per style="--banner-bg: url(…)". Auf
|
// Banner-Slider setzte sein Hintergrundbild per style="--banner-bg: url(…)". Auf
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ declare(strict_types=1);
|
|||||||
* <ordner>/spieler.* optional, freigestelltes Spielerfoto (PNG mit Transparenz)
|
* <ordner>/spieler.* optional, freigestelltes Spielerfoto (PNG mit Transparenz)
|
||||||
* fürs Cover — wird unverändert kopiert, nie über GD neu kodiert
|
* fürs Cover — wird unverändert kopiert, nie über GD neu kodiert
|
||||||
* <ordner>/verfasser.* optional, Porträtfoto für die Vorwort-Signatur
|
* <ordner>/verfasser.* optional, Porträtfoto für die Vorwort-Signatur
|
||||||
|
* <ordner>/galerie/* optional, Fotos vom letzten Spiel (natsort = Reihenfolge,
|
||||||
|
* das erste ist der Aufmacher) für die Bento-Galerie-
|
||||||
|
* Seite hinter dem Ergebnis-Rückblick, höchstens sieben
|
||||||
*
|
*
|
||||||
* KEINE Anzeigen im Ordner (seit 31.07.2026): die kommen aus dem dauerhaften
|
* KEINE Anzeigen im Ordner (seit 31.07.2026): die kommen aus dem dauerhaften
|
||||||
* Bestand data/anzeigen.json, gepflegt mit bin/anzeige-add.php. Sponsorenmotive
|
* Bestand data/anzeigen.json, gepflegt mit bin/anzeige-add.php. Sponsorenmotive
|
||||||
@@ -157,6 +160,7 @@ $vorwort = $findOne('vorwort');
|
|||||||
$rueckseite = $findOne('rueckseite');
|
$rueckseite = $findOne('rueckseite');
|
||||||
$spieler = $findOne('spieler');
|
$spieler = $findOne('spieler');
|
||||||
$verfasser = $findOne('verfasser');
|
$verfasser = $findOne('verfasser');
|
||||||
|
$galerieQuellen = $findAll('galerie');
|
||||||
// Anzeigen kommen NICHT mehr aus dem Ablieferordner, sondern aus dem dauerhaften
|
// Anzeigen kommen NICHT mehr aus dem Ablieferordner, sondern aus dem dauerhaften
|
||||||
// Bestand (data/anzeigen.json, gepflegt über bin/anzeige-add.php). Ein noch
|
// Bestand (data/anzeigen.json, gepflegt über bin/anzeige-add.php). Ein noch
|
||||||
// vorhandener anzeigen/-Unterordner wäre also wirkungslos — dann besser sagen,
|
// vorhandener anzeigen/-Unterordner wäre also wirkungslos — dann besser sagen,
|
||||||
@@ -206,6 +210,9 @@ $oldCover = $oldIssue['cover'] ?? null;
|
|||||||
// der BFV-Zeile) und die Liste der Mannschaften, die zusätzlich eine
|
// der BFV-Zeile) und die Liste der Mannschaften, die zusätzlich eine
|
||||||
// Gegnerseite bekommen — beides Chat-Pflege, überlebt erneute Läufe wie vorwort.
|
// Gegnerseite bekommen — beides Chat-Pflege, überlebt erneute Läufe wie vorwort.
|
||||||
$oldOpponentShort = $oldIssue['opponent_short'] ?? null;
|
$oldOpponentShort = $oldIssue['opponent_short'] ?? null;
|
||||||
|
// Galerie-Seite: Kopf (kicker/heading/text) und Alt-Texte sind Chat-Pflege,
|
||||||
|
// die Bilder schreibt dieser Lauf aus <ordner>/galerie/ (siehe unten).
|
||||||
|
$oldGalerie = is_array($oldIssue['galerie'] ?? null) ? $oldIssue['galerie'] : null;
|
||||||
$oldGegnerTeams = is_array($oldIssue['gegner_teams'] ?? null) ? array_values($oldIssue['gegner_teams']) : null;
|
$oldGegnerTeams = is_array($oldIssue['gegner_teams'] ?? null) ? array_values($oldIssue['gegner_teams']) : null;
|
||||||
$veranstaltung = null;
|
$veranstaltung = null;
|
||||||
if (is_string($oldVeranstaltung) && $oldVeranstaltung !== '') {
|
if (is_string($oldVeranstaltung) && $oldVeranstaltung !== '') {
|
||||||
@@ -317,6 +324,61 @@ $bild = static function (string $src, string $name, string $alt) use ($destDir,
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// --- Galerie (optional): Fotos vom letzten Spiel als Bento-Seite. Wie bei den
|
||||||
|
// Veranstaltungsbildern ist der Ordner immer der KOMPLETTE Bestand (der
|
||||||
|
// Ausgaben-Ordner wurde oben geleert), Alt-Texte hängen an `source`, dem
|
||||||
|
// Originaldateinamen, und folgen ihrem Bild auch bei neuer Reihenfolge. Zwei
|
||||||
|
// Breiten reichen: der Aufmacher steht mit gut zwei Dritteln der Seitenbreite. ---
|
||||||
|
$galerieMax = 7;
|
||||||
|
$galerie = $oldGalerie;
|
||||||
|
if ($galerieQuellen !== []) {
|
||||||
|
$altBySource = [];
|
||||||
|
foreach ($oldGalerie['bilder'] ?? [] as $b) {
|
||||||
|
if (is_array($b) && !empty($b['source'])) {
|
||||||
|
$altBySource[(string) $b['source']] = (string) ($b['alt'] ?? '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$platzhalter = trim((string) ($oldGalerie['heading'] ?? '')) ?: 'Fotos vom letzten Spiel';
|
||||||
|
if (count($galerieQuellen) > $galerieMax) {
|
||||||
|
$log(sprintf('galerie/ enthält %d Fotos, das Raster fasst %d — die übrigen bleiben weg.', count($galerieQuellen), $galerieMax), 'WARN');
|
||||||
|
}
|
||||||
|
$galerieBilder = [];
|
||||||
|
$ohneAlt = [];
|
||||||
|
foreach (array_slice($galerieQuellen, 0, $galerieMax) as $n => $src) {
|
||||||
|
$source = basename($src);
|
||||||
|
$name = sprintf('galerie-%02d', $n + 1);
|
||||||
|
try {
|
||||||
|
$variants = resize_image_variants($src, "{$destDir}/{$name}", [640, 1200], 80);
|
||||||
|
} catch (RuntimeException $e) {
|
||||||
|
$fail("Galerie-Foto {$source} fehlgeschlagen: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
$generated = array_values(array_unique(array_column($variants, 'width')));
|
||||||
|
sort($generated);
|
||||||
|
$alt = trim($altBySource[$source] ?? '');
|
||||||
|
if ($alt === '' || $alt === $platzhalter) {
|
||||||
|
$ohneAlt[] = $source;
|
||||||
|
$alt = $platzhalter;
|
||||||
|
}
|
||||||
|
$galerieBilder[] = [
|
||||||
|
'source' => $source,
|
||||||
|
'base' => "img/stadionzeitung/{$slug}/{$name}",
|
||||||
|
'widths' => $generated,
|
||||||
|
'alt' => $alt,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$galerie = ($oldGalerie ?? []) + ['kicker' => 'Rückblick', 'heading' => $platzhalter];
|
||||||
|
$galerie['bilder'] = $galerieBilder;
|
||||||
|
$log(count($galerieBilder) . ' Galerie-Fotos übernommen.');
|
||||||
|
if ($ohneAlt !== []) {
|
||||||
|
$log('Galerie: noch ohne eigenen Alt-Text (im Chat ergänzen): ' . implode(', ', $ohneAlt), 'WARN');
|
||||||
|
}
|
||||||
|
} elseif (!empty($oldGalerie['bilder'])) {
|
||||||
|
// Die Dateien sind mit dem Ausgaben-Ordner weg; ohne galerie/ im Ordner
|
||||||
|
// lieferte die Seite sonst kaputte Bilder.
|
||||||
|
$log('Die Ausgabe hatte eine Galerie, der Ordner liefert aber kein galerie/ mehr — die Galerie-Seite entfällt.', 'WARN');
|
||||||
|
$galerie['bilder'] = [];
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inhalt als Liste von BLÖCKEN, Anzeigen kommen anschließend in die Lücken
|
* Inhalt als Liste von BLÖCKEN, Anzeigen kommen anschließend in die Lücken
|
||||||
* dazwischen. Ein Block ist eine Folge von Seiten, die zusammenbleiben MUSS;
|
* dazwischen. Ein Block ist eine Folge von Seiten, die zusammenbleiben MUSS;
|
||||||
@@ -375,6 +437,12 @@ try {
|
|||||||
|
|
||||||
$bloecke[] = ['name' => 'ergebnisse', 'seiten' => [$live('ergebnisse')], 'anzeigen_danach' => true];
|
$bloecke[] = ['name' => 'ergebnisse', 'seiten' => [$live('ergebnisse')], 'anzeigen_danach' => true];
|
||||||
|
|
||||||
|
// Galerie direkt hinter dem Ergebnis-Rückblick: erst das Ergebnis, dann die
|
||||||
|
// Bilder dazu. Eigener Block, eine Anzeige dazwischen ist unbedenklich.
|
||||||
|
if (!empty($galerie['bilder'])) {
|
||||||
|
$bloecke[] = ['name' => 'galerie', 'seiten' => [$live('galerie')], 'anzeigen_danach' => true];
|
||||||
|
}
|
||||||
|
|
||||||
// Gegnerseite(n): normal nur die tragende Mannschaft; in der Sportfest-Ausgabe
|
// Gegnerseite(n): normal nur die tragende Mannschaft; in der Sportfest-Ausgabe
|
||||||
// je Mannschaft mit Heimspiel am Fest eine (drei Heimspiele, drei Seiten), als
|
// je Mannschaft mit Heimspiel am Fest eine (drei Heimspiele, drei Seiten), als
|
||||||
// EIN Block. Welche das sind, entscheidet stadionzeitung_gegner_fixtures() —
|
// EIN Block. Welche das sind, entscheidet stadionzeitung_gegner_fixtures() —
|
||||||
@@ -761,6 +829,7 @@ $issues[] = [
|
|||||||
'aufruf' => $oldAufruf,
|
'aufruf' => $oldAufruf,
|
||||||
'veranstaltung' => $oldVeranstaltung,
|
'veranstaltung' => $oldVeranstaltung,
|
||||||
'cover' => $oldCover,
|
'cover' => $oldCover,
|
||||||
|
'galerie' => $galerie,
|
||||||
'verfasser_photo' => $verfasserPhoto,
|
'verfasser_photo' => $verfasserPhoto,
|
||||||
'termine_snapshot' => $termineSnapshot,
|
'termine_snapshot' => $termineSnapshot,
|
||||||
'images' => $images,
|
'images' => $images,
|
||||||
|
|||||||
@@ -1,5 +1,548 @@
|
|||||||
{
|
{
|
||||||
"issues": [
|
"issues": [
|
||||||
|
{
|
||||||
|
"slug": "2026-10-03-vfb-kulmbach",
|
||||||
|
"opponent": "VfB Kulmbach",
|
||||||
|
"opponent_short": null,
|
||||||
|
"gegner_teams": [
|
||||||
|
"damen"
|
||||||
|
],
|
||||||
|
"date": "2026-10-03",
|
||||||
|
"team_key": "erste-mannschaft",
|
||||||
|
"status": "entwurf",
|
||||||
|
"pages": 44,
|
||||||
|
"player_image": {
|
||||||
|
"base": "img/stadionzeitung/2026-10-03-vfb-kulmbach/spieler",
|
||||||
|
"widths": [
|
||||||
|
320,
|
||||||
|
640,
|
||||||
|
1000
|
||||||
|
],
|
||||||
|
"ext": "png",
|
||||||
|
"alt": ""
|
||||||
|
},
|
||||||
|
"qr_image": "img/stadionzeitung/2026-10-03-vfb-kulmbach/qr.png",
|
||||||
|
"vorwort": {
|
||||||
|
"heading": "Willkommen zum Stadtderby",
|
||||||
|
"paragraphs": [
|
||||||
|
"Liebe Fußballfreunde,",
|
||||||
|
"herzlich willkommen im Katzbachtal zum ersten Stadtderby dieser Saison gegen den VfB. Ein besonderer Gruß gilt dem Schiedsrichtergespann und unseren Nachbarn samt ihren Anhängern.",
|
||||||
|
"Nach dem ärgerlichen 2:3 in Kirchleus wollen wir heute vor eigenem Publikum ein anderes Gesicht zeigen. Seid laut, feuert unsere Mannschaft an und bleibt dabei fair. Am Abend spielen dann unsere Frauen als Tabellenführer in Waldershof. Auf geht's!"
|
||||||
|
],
|
||||||
|
"closing": "Rot-schwarze Grüße",
|
||||||
|
"signee_name": "Benedikt Höfner",
|
||||||
|
"signee_role": "Sportlicher Leiter"
|
||||||
|
},
|
||||||
|
"interview": {
|
||||||
|
"teaser": "Unser Trainer Ali Kilic über die Niederlage in Kirchleus und das Stadtderby",
|
||||||
|
"heading": "Drei Fragen an Ali Kilic",
|
||||||
|
"person_name": "Ali Kilic",
|
||||||
|
"person_role": "Trainer 1. Mannschaft",
|
||||||
|
"intro": null,
|
||||||
|
"fragen": [
|
||||||
|
{
|
||||||
|
"frage": "Ali, das 2:3 in Kirchleus war ärgerlich. Wie geht die Mannschaft damit um?",
|
||||||
|
"antwort": "Die Niederlage hat uns alle geärgert, weil mehr drin war. Abhaken ist trotzdem das Einzige, was hilft. Wir haben die Woche gut genutzt und wollen heute vor unseren eigenen Zuschauern Wiedergutmachung betreiben."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frage": "Heute kommt der VfB zum ersten Stadtderby dieser Saison. Was erwartest du?",
|
||||||
|
"antwort": "Wir freuen uns riesig auf die Partie, so ein Spiel hat man nicht jede Woche. Ich rechne mit einer hitzigen und zweikampfbetonten Partie, in der es auch mal zur Sache geht. Gerade dann müssen wir einen kühlen Kopf bewahren und dürfen uns nicht aus dem Konzept bringen lassen."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frage": "Worauf wird es spielerisch ankommen?",
|
||||||
|
"antwort": "Ganz wichtig werden die Umschaltmomente, gerade wenn wir aus dem Ballbesitz heraus ins Gegenpressing kommen. Dann brauchen wir gute Abläufe. Schalten wir in den Konter um, müssen wir die Positionen sauber besetzen und Anspielstationen bieten, um schnell nach vorne zu spielen."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"photo": "img/persons/ali-kilic.jpg"
|
||||||
|
},
|
||||||
|
"aufruf": null,
|
||||||
|
"veranstaltung": null,
|
||||||
|
"cover": null,
|
||||||
|
"galerie": {
|
||||||
|
"kicker": "Rückblick",
|
||||||
|
"heading": "Unterwegs in Kirchleus",
|
||||||
|
"bilder": [
|
||||||
|
{
|
||||||
|
"source": "01-IMG_0586_01.jpg",
|
||||||
|
"base": "img/stadionzeitung/2026-10-03-vfb-kulmbach/galerie-01",
|
||||||
|
"widths": [
|
||||||
|
640,
|
||||||
|
1200
|
||||||
|
],
|
||||||
|
"alt": "Einer unserer Spieler holt in Kirchleus zum Schuss aus, ein Gegenspieler kommt einen Schritt zu spät."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "02-IMG_0692_01.jpg",
|
||||||
|
"base": "img/stadionzeitung/2026-10-03-vfb-kulmbach/galerie-02",
|
||||||
|
"widths": [
|
||||||
|
640,
|
||||||
|
1200
|
||||||
|
],
|
||||||
|
"alt": "Zweikampf um den Ball: Einer unserer Spieler setzt sich gegen einen Kirchleuser durch."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "03-IMG_0565_01.jpg",
|
||||||
|
"base": "img/stadionzeitung/2026-10-03-vfb-kulmbach/galerie-03",
|
||||||
|
"widths": [
|
||||||
|
640,
|
||||||
|
1200
|
||||||
|
],
|
||||||
|
"alt": "Einer unserer Spieler treibt den Ball nach vorne, ein Kirchleuser läuft heran."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "04-IMG_0612_01.jpg",
|
||||||
|
"base": "img/stadionzeitung/2026-10-03-vfb-kulmbach/galerie-04",
|
||||||
|
"widths": [
|
||||||
|
640,
|
||||||
|
1200
|
||||||
|
],
|
||||||
|
"alt": "An der Eckfahne nimmt einer unserer Spieler den Ball an."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "05-IMG_0571_01.jpg",
|
||||||
|
"base": "img/stadionzeitung/2026-10-03-vfb-kulmbach/galerie-05",
|
||||||
|
"widths": [
|
||||||
|
640,
|
||||||
|
1200
|
||||||
|
],
|
||||||
|
"alt": "Einer unserer Spieler läuft in der Herbstsonne über den Platz."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"text": "Am 27. September haben wir beim 1. FC Kirchleus knapp mit 2:3 verloren."
|
||||||
|
},
|
||||||
|
"verfasser_photo": {
|
||||||
|
"base": "img/stadionzeitung/2026-10-03-vfb-kulmbach/verfasser",
|
||||||
|
"widths": [
|
||||||
|
120,
|
||||||
|
222
|
||||||
|
],
|
||||||
|
"alt": ""
|
||||||
|
},
|
||||||
|
"termine_snapshot": [
|
||||||
|
{
|
||||||
|
"date": "2026-10-11",
|
||||||
|
"date_end": null,
|
||||||
|
"title": "TSV 08 Kulmbach – VfB Moschendorf (flex)",
|
||||||
|
"department": "fussball",
|
||||||
|
"type": "spiel",
|
||||||
|
"meta": "Heimspiel · Frauen KL Ost",
|
||||||
|
"href": "/matchcenter",
|
||||||
|
"kickoff": "2026-10-11T10:30",
|
||||||
|
"team_name": "Frauenmannschaft",
|
||||||
|
"league": "Frauen KL Ost",
|
||||||
|
"raw": {
|
||||||
|
"kickoff": "2026-10-11T10:30",
|
||||||
|
"date_display": "So, 11.10.",
|
||||||
|
"time_display": "10:30 Uhr",
|
||||||
|
"competition": "Liga",
|
||||||
|
"home": "TSV 08 Kulmbach",
|
||||||
|
"away": "VfB Moschendorf (flex)",
|
||||||
|
"home_crest": "img/crests/00ES8GNK3G000012VV0AG08LVUPGND5I.png",
|
||||||
|
"away_crest": "img/crests/00ES8GNK8G000019VV0AG08LVUPGND5I.png",
|
||||||
|
"is_home": true,
|
||||||
|
"team_key": "damen",
|
||||||
|
"team_name": "Frauenmannschaft"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2026-10-11",
|
||||||
|
"date_end": null,
|
||||||
|
"title": "(SG1) TSV Bischofsgrün I/FC Gefrees II – TSV 08 Kulmbach",
|
||||||
|
"department": "fussball",
|
||||||
|
"type": "spiel",
|
||||||
|
"meta": "Auswärtsspiel · Kreisklasse",
|
||||||
|
"href": "/matchcenter",
|
||||||
|
"kickoff": "2026-10-11T15:30",
|
||||||
|
"team_name": "1. Mannschaft",
|
||||||
|
"league": "Kreisklasse",
|
||||||
|
"raw": {
|
||||||
|
"kickoff": "2026-10-11T15:30",
|
||||||
|
"date_display": "So, 11.10.",
|
||||||
|
"time_display": "15:30 Uhr",
|
||||||
|
"competition": "Liga",
|
||||||
|
"home": "(SG1) TSV Bischofsgrün I/FC Gefrees II",
|
||||||
|
"away": "TSV 08 Kulmbach",
|
||||||
|
"home_crest": "img/crests/00ES8GNK3G000002VV0AG08LVUPGND5I.png",
|
||||||
|
"away_crest": "img/crests/00ES8GNK3G000012VV0AG08LVUPGND5I.png",
|
||||||
|
"is_home": false,
|
||||||
|
"team_key": "erste-mannschaft",
|
||||||
|
"team_name": "1. Mannschaft"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2027-02-20",
|
||||||
|
"date_end": null,
|
||||||
|
"title": "Tagesskifahrt 2027",
|
||||||
|
"department": "verein",
|
||||||
|
"type": "event",
|
||||||
|
"meta": "Skigebiet Hochzillertal",
|
||||||
|
"href": "/veranstaltungen/tagesskifahrt-2027",
|
||||||
|
"time": "",
|
||||||
|
"location": "Skigebiet Hochzillertal",
|
||||||
|
"raw": {
|
||||||
|
"slug": "tagesskifahrt-2027",
|
||||||
|
"title": "Tagesskifahrt 2027",
|
||||||
|
"date_start": "2027-02-20",
|
||||||
|
"date_end": null,
|
||||||
|
"time": "",
|
||||||
|
"location": "Skigebiet Hochzillertal",
|
||||||
|
"department": "verein",
|
||||||
|
"status": "veroeffentlicht",
|
||||||
|
"text": "Wir fahren für einen Tag zum Skifahren ins Skigebiet Hochzillertal. Die Plätze sind auf 40 Personen begrenzt, angemeldet wird bei Fabian Früh.",
|
||||||
|
"ankuendigung": [
|
||||||
|
"Einmal im Winter machen wir uns gemeinsam auf und fahren für einen Tag ins Skigebiet Hochzillertal bei Kaltenbach. Ob Erwachsene, Jugendliche oder Kinder: Auf den Pisten ist für alle etwas dabei. Die Fahrt ist auf 40 Personen begrenzt, wer dabei sein möchte, meldet sich am besten früh.",
|
||||||
|
"Erwachsene zahlen 115 Euro, Jugendliche 95 Euro und Kinder 70 Euro. Anmelden könnt ihr euch bei Fabian Früh unter 0160 97516797."
|
||||||
|
],
|
||||||
|
"rueckblick": null,
|
||||||
|
"karte": "",
|
||||||
|
"anfahrt": [],
|
||||||
|
"plakate": [
|
||||||
|
{
|
||||||
|
"base": "img/veranstaltungen/tagesskifahrt-2027/plakat-01",
|
||||||
|
"widths": [
|
||||||
|
640,
|
||||||
|
1000,
|
||||||
|
1024
|
||||||
|
],
|
||||||
|
"alt": "Plakat zu unserer Tagesskifahrt am Samstag, 20. Februar 2027 ins Skigebiet Hochzillertal, mit den Preisen für Erwachsene, Jugendliche und Kinder und der Anmeldung bei Fabian Früh.",
|
||||||
|
"source": "1-ankuendigung.jpeg"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"galerie": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "cover"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "vorwort"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "interview"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/eldorado",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: eldorado Radsporttechnik Kulmbach"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "ergebnisse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/egu",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: Erfrischungsgetränke-Union Kulmbacher Gruppe GmbH"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/hofmann-graef",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: Buchhandlung Hofmann, Kulmbach, und Automobilwerkstatt Gräf, Thurnau"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "galerie"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/muench-richterstegner",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: Planungsbüro Münch und Richter & Stegner Steuerungstechnik"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "gegner",
|
||||||
|
"team": "erste-mannschaft"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "gegner",
|
||||||
|
"team": "damen"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/malteser-herrmann",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: Malteser-Hilfsdienst und Schlosserei Herrmann, Kulmbach"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/apotheken-wenkel",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: Apotheke im Fritz, Stadtpark Apotheke und Schlüsseldienst Wenkel, Kulmbach"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "tabelle",
|
||||||
|
"team": "erste-mannschaft"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "tabelle",
|
||||||
|
"team": "zweite-mannschaft"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "tabelle",
|
||||||
|
"team": "damen"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/karl-geyer",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: Geyer Farbe + Raum, Kulmbach, Starthilfe Boden"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "vorschau"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/gsb",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: GSB Security und GSB Gebäude Service, Bindlach"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/physiofit-wohlfart",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: Physio Fit Neudrossenfeld und Textilpflege Wohlfart, Kulmbach"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "termine"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/sport2000-pizza",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: Sport 2000 Downstairs und Kulmbacher Pizza-Service"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/schulz-csu",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: Schreinerei Schulz, Mainleus, und CSU Stadtverband Kulmbach"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "news"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/mattis-ka2",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: Karl Mattis Flaschnerei und KA2 Fitness, Kulmbach"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "kontakt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/motor-nuetzel",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: Motor-Nützel Vertriebs-GmbH, Bayreuth"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/vereinskarte-edeka",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1410
|
||||||
|
],
|
||||||
|
"alt": "Eigenanzeige: So funktioniert die Vereinskarte beim E center Seidl Kulmbach"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "mitglied"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/trapper-verkehrsakademie",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: Trapper GmbH Entsorgungsfachbetrieb und Verkehrsakademie, Kulmbach"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "historie"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/ohnemueller-dippold",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: Gaststätte und Metzgerei Ohne-Müller, Kulmbach-Weiher, und Bäckerei Dippold, Melkendorf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/hanft",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: Hanft Bürotechnik GmbH, Kulmbach"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "sportheim"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/elma-kleinheinz",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: elma GmbH Bayreuth und Metzgerei Kleinheinz, Kulmbach"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "partner"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "danke",
|
||||||
|
"anzeige": {
|
||||||
|
"base": "img/anzeigen/emons",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1141
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: Emons Spedition Himmelkron, Ihr Partner für nationale und internationale Transporte"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/stadionzeitung-digital",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Eigenanzeige: Unsere Stadionzeitung gibt es jetzt auch online, mit QR-Code zum Scannen"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/gagel-pickelmann",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: Gagel Bäder und Mineralölhandel Pickelmann"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "momente"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/schramm",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Anzeige: Landgasthof und Metzgerei Schramm, Forstlahm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/anzeigen/tagesskifahrt-2027",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1440
|
||||||
|
],
|
||||||
|
"alt": "Eigenanzeige: Unsere Tagesskifahrt ins Hochzillertal am 20. Februar 2027"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "live",
|
||||||
|
"page": "impressum"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"base": "img/stadionzeitung/2026-10-03-vfb-kulmbach/rueckseite",
|
||||||
|
"widths": [
|
||||||
|
480,
|
||||||
|
960,
|
||||||
|
1410
|
||||||
|
],
|
||||||
|
"alt": "Rückseite der Stadionzeitung gegen VfB Kulmbach"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"slug": "2026-09-19-sg-wirsberg-kupferberg",
|
"slug": "2026-09-19-sg-wirsberg-kupferberg",
|
||||||
"opponent": "(SG1) TSV Wirsberg I/ FC Kupferberg I",
|
"opponent": "(SG1) TSV Wirsberg I/ FC Kupferberg I",
|
||||||
|
|||||||
@@ -8628,6 +8628,83 @@ p.stadionzeitung-turnier__label:first-of-type {
|
|||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* === stadionzeitung-galerie (Live-Seite, optional: Fotos vom letzten Spiel) === */
|
||||||
|
/* Bento-Raster auf einem 6×4-Gitter: das erste Foto ist der Aufmacher (4×2),
|
||||||
|
die übrigen legen sich je nach Anzahl darum. Die Fläche unter dem Kopf gehört
|
||||||
|
komplett den Fotos, beschnitten wird per object-fit — wie bei den Momenten
|
||||||
|
ohne Bildunterschriften, der Alt-Text trägt die Beschreibung.
|
||||||
|
Das Raster wächst per flex in die feste A5-Höhe; min-height ist der Halt für
|
||||||
|
den gestapelten Viewer ohne JS, wo die Seite keine feste Höhe hat (dann
|
||||||
|
kollabierten die 1fr-Zeilen auf null). 95cqi passt unter jeden Kopf mit
|
||||||
|
Textzeile (gemessen gegen 141,9cqi Blatthöhe). */
|
||||||
|
.stadionzeitung-galerie {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie .stadionzeitung-page__head {
|
||||||
|
margin-bottom: 2.5cqi;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__text {
|
||||||
|
font-size: 3.4cqi;
|
||||||
|
color: var(--clr-text-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__bento {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-height: 95cqi;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(6, 1fr);
|
||||||
|
grid-template-rows: repeat(4, 1fr);
|
||||||
|
gap: 1.5cqi;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__foto {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__foto:nth-child(1) { grid-area: a; }
|
||||||
|
.stadionzeitung-galerie__foto:nth-child(2) { grid-area: b; }
|
||||||
|
.stadionzeitung-galerie__foto:nth-child(3) { grid-area: c; }
|
||||||
|
.stadionzeitung-galerie__foto:nth-child(4) { grid-area: d; }
|
||||||
|
.stadionzeitung-galerie__foto:nth-child(5) { grid-area: e; }
|
||||||
|
.stadionzeitung-galerie__foto:nth-child(6) { grid-area: f; }
|
||||||
|
.stadionzeitung-galerie__foto:nth-child(7) { grid-area: g; }
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__bento--n1 {
|
||||||
|
grid-template-areas: "a a a a a a" "a a a a a a" "a a a a a a" "a a a a a a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__bento--n2 {
|
||||||
|
grid-template-areas: "a a a a a a" "a a a a a a" "b b b b b b" "b b b b b b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__bento--n3 {
|
||||||
|
grid-template-areas: "a a a a a a" "a a a a a a" "b b b c c c" "b b b c c c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__bento--n4 {
|
||||||
|
grid-template-areas: "a a a a b b" "a a a a b b" "c c c d d d" "c c c d d d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__bento--n5 {
|
||||||
|
grid-template-areas: "a a a a b b" "a a a a c c" "d d d e e e" "d d d e e e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__bento--n6 {
|
||||||
|
grid-template-areas: "a a a a b b" "a a a a c c" "d d e e f f" "d d e e f f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.stadionzeitung-galerie__bento--n7 {
|
||||||
|
grid-template-areas: "a a a a b b" "a a a a c c" "d d e e f f" "d d e e g g";
|
||||||
|
}
|
||||||
|
|
||||||
/* === stadionzeitung-druck (Druckfassung, Broschüren-Montage) === */
|
/* === stadionzeitung-druck (Druckfassung, Broschüren-Montage) === */
|
||||||
/* Bildschirm-Ansicht der Route ?druck=1: jedes Blatt als A4-quer-Vorschau
|
/* Bildschirm-Ansicht der Route ?druck=1: jedes Blatt als A4-quer-Vorschau
|
||||||
(297:210) mit zwei A5-Seiten, in Broschüren-Reihenfolge (die Montage
|
(297:210) mit zwei A5-Seiten, in Broschüren-Reihenfolge (die Montage
|
||||||
|
|||||||
|
After Width: | Height: | Size: 285 KiB |
|
After Width: | Height: | Size: 88 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 194 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 190 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 220 KiB |
|
After Width: | Height: | Size: 78 KiB |
BIN
public/assets/img/stadionzeitung/2026-10-03-vfb-kulmbach/qr.png
Normal file
|
After Width: | Height: | Size: 576 B |
|
After Width: | Height: | Size: 398 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 222 KiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 224 KiB |
|
After Width: | Height: | Size: 804 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 6.7 KiB |