diff --git a/CLAUDE.md b/CLAUDE.md
index 17948fe..b866950 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -517,6 +517,7 @@ kein Download-Link — nur die Web-Ansicht. Der Ablauf pro Heimspiel ist damit:
Inhalt ist eine Liste von **Blöcken**, die Anzeigen füllen die Lücken dazwischen (⌷ = Lücke):
```
Cover → [Vorwort → Interview (nur wenn die Ausgabe eins trägt)] ⌷ Ergebnis-Rückblick ⌷
+ Gegnerstatistik der tragenden Mannschaft (automatisch aus deren Tabelle) ⌷
[je Mannschaft eine Tabelle, Reihenfolge = matchcenter.json — EIN Block, dazwischen nie eine
Anzeige; Erste + Zweite bilden im gefalteten Heft eine Doppelseite] ⌷ Vorschau ⌷ Termine ⌷
News ⌷ Ansprechpartner ⌷ Mitglied-werden-Poster ⌷ Historie-Teaser (Website-Verweis +
@@ -547,7 +548,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.
Ein `images[]`-Eintrag hat
`"type": "image"` (wie gehabt, `base`/`widths`/`alt`) oder `"type": "live"` (`page`: `cover` |
-`vorwort` | `interview` | `aufruf` | `tabelle` | `termine` | `news` | `ergebnisse` | `vorschau` | `kontakt` | `mitglied` | `historie` | `sportheim` | `partner` | `momente` | `impressum`, kein Bild;
+`vorwort` | `interview` | `aufruf` | `tabelle` | `termine` | `news` | `ergebnisse` | `gegner` | `vorschau` | `kontakt` | `mitglied` | `historie` | `sportheim` | `partner` | `momente` | `impressum`, kein Bild;
`tabelle` zusätzlich mit `team`: Team-Key aus `matchcenter.json`, ohne `team` greift der Team-Key
der Ausgabe). Fehlt `type` (alte Phase-1-Ausgaben) → Fallback `image`, bricht nicht. **Gerendert
wird jede Seite (Bild wie Live) über `app/components/stadionzeitung-seite.php`** — die eine
diff --git a/app/components/stadionzeitung-gegner.php b/app/components/stadionzeitung-gegner.php
new file mode 100644
index 0000000..9a206d3
--- /dev/null
+++ b/app/components/stadionzeitung-gegner.php
@@ -0,0 +1,88 @@
+ 'Tabellenplatz', 'key' => 'rank'],
+ ['label' => 'Spiele', 'key' => 'played'],
+ ['label' => 'Siege', 'key' => 'won'],
+ ['label' => 'Unentschieden', 'key' => 'drawn'],
+ ['label' => 'Niederlagen', 'key' => 'lost'],
+ ['label' => 'Tordifferenz', 'key' => 'goal_diff', 'signed' => true],
+ ['label' => 'Punkte', 'key' => 'points'],
+];
+
+$format = static function (?array $row, string $key, bool $signed = false): string {
+ if ($row === null || !array_key_exists($key, $row)) {
+ return '–';
+ }
+ $value = (int) $row[$key];
+ return $signed && $value > 0 ? '+' . $value : (string) $value;
+};
+?>
+
+
+ Unser Gegner
+ = e($opponentName) ?>
+
+ = e(trim(implode(' · ', array_filter([(string) ($info['league'] ?? ''), (string) ($info['season'] ?? '')])))) ?>
+
+
+
+
+
+
+ $fixture['home_crest'] ?? $own['crest'] ?? null, 'name' => $fixture['home'] ?? 'TSV 08 Kulmbach']); ?>
+ = e((string) ($fixture['home'] ?? 'TSV 08 Kulmbach')) ?>
+
+
+ gegen
+
+ = e(german_date($kickoffDate)) ?>
+
+
+ = e($kickoffTime) ?> Uhr
+
+
+
+ $fixture['away_crest'] ?? $opponent['crest'] ?? null, 'name' => $fixture['away'] ?? $opponentName]); ?>
+ = e((string) ($fixture['away'] ?? $opponentName)) ?>
+
+
+
+
+
+
+ TSV 08
+ Vergleich
+ ASV
+
+
+
+ = e($format($own, (string) $row['key'], (bool) ($row['signed'] ?? false))) ?>
+ = e((string) $row['label']) ?>
+ = e($format($opponent, (string) $row['key'], (bool) ($row['signed'] ?? false))) ?>
+
+
+
+
+
Die aktuellen Vergleichsdaten waren beim letzten Abruf nicht verfügbar.
+
+
diff --git a/app/components/stadionzeitung-seite.php b/app/components/stadionzeitung-seite.php
index 51d4280..6638955 100644
--- a/app/components/stadionzeitung-seite.php
+++ b/app/components/stadionzeitung-seite.php
@@ -10,7 +10,7 @@ declare(strict_types=1);
* $entry Eintrag aus issue.images[]:
* type 'image' (base/widths/alt),
* type 'live' (page: cover|vorwort|interview|aufruf|tabelle|termine|
- * news|ergebnisse|vorschau|kontakt; tabelle optional
+ * news|ergebnisse|gegner|vorschau|kontakt; tabelle optional
* mit team: Team-Key aus matchcenter.json),
* type 'leer' (weiße Füllseite, nur Druckfassung — hält die
* Seitenzahl auf einem Vielfachen von 4)
@@ -55,6 +55,9 @@ $type = $entry['type'] ?? 'image';
$data['ergebnisse'] ?? []]); ?>
+
+ $data['gegner'] ?? null]); ?>
+
$data['vorschau'] ?? []]); ?>
diff --git a/app/components/stadionzeitung-termine.php b/app/components/stadionzeitung-termine.php
index 84a7997..6246c88 100644
--- a/app/components/stadionzeitung-termine.php
+++ b/app/components/stadionzeitung-termine.php
@@ -8,7 +8,7 @@ declare(strict_types=1);
* (Kicker + Überschrift über einblendendem Vereinsfoto), aber mit einer
* Icon-Liste statt Fließtext.
*
- * Die drei Termine sind KEIN Live-Abruf: bin/stadionzeitung-add.php friert
+ * Die Termine sind KEIN Live-Abruf: bin/stadionzeitung-add.php friert
* sie beim Anlegen der Ausgabe einmalig ein (`termine_snapshot`, siehe dort
* und termine_build_lists()) — eine gedruckte Ausgabe zeigt dauerhaft, was
* am Spieltag anstand, nicht was von "heute" aus gesehen ansteht.
@@ -60,6 +60,8 @@ $termineLink = club_domain('termine');
} elseif (!$isMatch && !empty($item['location'])) {
$parts[] = (string) $item['location'];
}
+ $title = (string) ($item['title'] ?? '');
+ $meta = implode(' · ', $parts);
?>
= icon($isMatch ? 'trophy' : 'calendar-event') ?>
-
= e((string) ($item['title'] ?? '')) ?>
-
= e(implode(' · ', $parts)) ?>
+
= e($title) ?>
+
= e($meta) ?>
diff --git a/app/helpers.php b/app/helpers.php
index 31a6bf9..169ed88 100644
--- a/app/helpers.php
+++ b/app/helpers.php
@@ -988,10 +988,12 @@ function stadionzeitung_build_snapshot(array $issue): array
{
$date = (string) ($issue['date'] ?? '');
$issueTeam = (string) ($issue['team_key'] ?? '');
+ $issueOpponent = trim((string) ($issue['opponent'] ?? ''));
$tabellen = [];
$ergebnisse = [];
$vorschau = [];
+ $gegner = null;
foreach (json_load('matchcenter')['teams'] ?? [] as $team) {
$key = (string) ($team['key'] ?? '');
if ($key === '') {
@@ -1004,6 +1006,44 @@ function stadionzeitung_build_snapshot(array $issue): array
'table' => $team['table'] ?? [],
];
+ // Gegnerseite der tragenden Mannschaft: ausschließlich aus demselben
+ // Matchcenter-Datensatz wie die Tabelle ableiten. So gibt es keinen
+ // zweiten BFV-Abruf und der Stand wird beim Veröffentlichen zusammen
+ // mit den übrigen Live-Daten eingefroren.
+ if ($key === $issueTeam && $issueOpponent !== '') {
+ $table = is_array($team['table'] ?? null) ? $team['table'] : [];
+ $ownRow = null;
+ $opponentRow = null;
+ foreach ($table as $row) {
+ if (!empty($row['is_own_club'])) {
+ $ownRow = $row;
+ }
+ if (strcasecmp(trim((string) ($row['club'] ?? '')), $issueOpponent) === 0) {
+ $opponentRow = $row;
+ }
+ }
+
+ $fixture = null;
+ foreach ($team['next_matches'] ?? [] as $match) {
+ $matchDate = substr((string) ($match['kickoff'] ?? ''), 0, 10);
+ $clubs = [(string) ($match['home'] ?? ''), (string) ($match['away'] ?? '')];
+ if ($matchDate === $date && in_array($issueOpponent, $clubs, true)) {
+ $fixture = $match;
+ break;
+ }
+ }
+
+ $gegner = [
+ 'team_name' => (string) ($team['name'] ?? ''),
+ 'opponent' => $issueOpponent,
+ 'league' => (string) ($team['league'] ?? ''),
+ 'season' => (string) ($team['season'] ?? ''),
+ 'fixture' => $fixture,
+ 'own' => $ownRow,
+ 'opponent_stats' => $opponentRow,
+ ];
+ }
+
// Nur Spiele mit erfasstem Ergebnis — ein Testspiel ohne Tore ist
// kein Rückblick (dieselbe Regel wie im News-Feed).
$withScore = array_values(array_filter(
@@ -1058,6 +1098,7 @@ function stadionzeitung_build_snapshot(array $issue): array
return [
'tabellen' => $tabellen,
+ 'gegner' => $gegner,
'ergebnisse' => $ergebnisse,
'vorschau' => $vorschau,
// Fünf statt sechs: mit den größeren Überschriften + CTA-Fuß braucht
diff --git a/bin/stadionzeitung-add.php b/bin/stadionzeitung-add.php
index dc855a2..f966d30 100644
--- a/bin/stadionzeitung-add.php
+++ b/bin/stadionzeitung-add.php
@@ -309,6 +309,7 @@ try {
}
$bloecke[] = ['name' => 'ergebnisse', 'seiten' => [$live('ergebnisse')], 'anzeigen_danach' => true];
+ $bloecke[] = ['name' => 'gegner', 'seiten' => [$live('gegner')], 'anzeigen_danach' => true];
// Eine Tabellen-Seite je Mannschaft, Reihenfolge wie in matchcenter.json
// (= config 'matchcenter.teams'). Kommt eine Mannschaft dazu (z. B. die
diff --git a/data/anzeigen.json b/data/anzeigen.json
index 32b60fb..bc3f70e 100644
--- a/data/anzeigen.json
+++ b/data/anzeigen.json
@@ -124,7 +124,7 @@
{
"slug": "emons-stuebinger",
"sponsor": "Emons Spedition und AST Stübinger Hoch-, Tief- und Straßenbau, Kulmbach",
- "aktiv": true,
+ "aktiv": false,
"base": "img/anzeigen/emons-stuebinger",
"widths": [
480,
@@ -247,6 +247,53 @@
960,
1440
]
+ },
+ {
+ "slug": "emons-partnerdank",
+ "sponsor": "Emons Spedition und Dank an unsere Partner",
+ "aktiv": true,
+ "alt": "Anzeige: Emons Spedition, darunter unser Dank an alle Partner",
+ "base": "img/anzeigen/emons-partnerdank",
+ "widths": [
+ 480,
+ 960,
+ 1440
+ ]
+ },
+ {
+ "slug": "gagel-pickelmann",
+ "sponsor": "Gagel Bäder und Mineralölhandel Pickelmann",
+ "aktiv": true,
+ "base": "img/anzeigen/gagel-pickelmann",
+ "widths": [
+ 480,
+ 960,
+ 1440
+ ]
+ },
+ {
+ "slug": "schramm",
+ "sponsor": "Landgasthof und Metzgerei Schramm, Forstlahm",
+ "aktiv": true,
+ "base": "img/anzeigen/schramm",
+ "widths": [
+ 480,
+ 960,
+ 1440
+ ]
+ },
+ {
+ "slug": "tagesskifahrt-2027",
+ "sponsor": "Unsere Tagesskifahrt ins Hochzillertal 2027",
+ "aktiv": true,
+ "bis": "2027-02-20",
+ "alt": "Eigenanzeige: Unsere Tagesskifahrt ins Hochzillertal am 20. Februar 2027",
+ "base": "img/anzeigen/tagesskifahrt-2027",
+ "widths": [
+ 480,
+ 960,
+ 1440
+ ]
}
]
}
diff --git a/data/stadionzeitung.json b/data/stadionzeitung.json
index f011ad6..7690dee 100644
--- a/data/stadionzeitung.json
+++ b/data/stadionzeitung.json
@@ -1,5 +1,582 @@
{
"issues": [
+ {
+ "slug": "2026-08-29-asv-marktschorgast",
+ "opponent": "ASV Marktschorgast",
+ "date": "2026-08-29",
+ "team_key": "erste-mannschaft",
+ "status": "entwurf",
+ "pages": 44,
+ "player_image": {
+ "base": "img/stadionzeitung/2026-08-29-asv-marktschorgast/spieler",
+ "widths": [
+ 320,
+ 640,
+ 1000
+ ],
+ "ext": "png",
+ "alt": ""
+ },
+ "qr_image": "img/stadionzeitung/2026-08-29-asv-marktschorgast/qr.png",
+ "vorwort": {
+ "heading": "Jetzt soll der erste Heimsieg her!",
+ "paragraphs": [
+ "Liebe Fußballfreunde,",
+ "herzlich willkommen im Katzbachtal. Ein besonderer Gruß gilt dem Schiedsrichtergespann und unseren Gästen vom ASV Marktschorgast.",
+ "Der starke 7:1-Auswärtssieg in Rugendorf gibt uns Rückenwind. Trotzdem zählt heute nur die neue Aufgabe: Gegen den direkten Tabellennachbarn aus Marktschorgast wollen wir endlich unseren ersten Heimsieg feiern.",
+ "Leidenschaft, Wille, Heimsieg. Los geht's!"
+ ],
+ "closing": "Rot-schwarze Grüße",
+ "signee_name": "Benedikt Höfner",
+ "signee_role": "Sportlicher Leiter"
+ },
+ "interview": {
+ "teaser": "Unser Trainer Ali Kilic über den starken Auftritt in Rugendorf, den ASV Marktschorgast und den ersehnten ersten Heimsieg",
+ "heading": "Drei Fragen an Ali Kilic",
+ "person_name": "Ali Kilic",
+ "person_role": "Trainer 1. Mannschaft",
+ "intro": null,
+ "fragen": [
+ {
+ "frage": "Ali, wie blickst du auf das letzte Auswärtsspiel in Rugendorf zurück?",
+ "antwort": "Das war ein sehr guter Auftritt von uns. Trotz der teilweise hitzigen Stimmung haben wir uns nicht beirren lassen, sind bei unserem Spiel geblieben und haben über 90 Minuten eine konzentrierte Auswärtsleistung gezeigt. Das 7:1 wollen wir trotzdem nicht zu hoch hängen. Entscheidend ist, dass wir diesen Schwung mitnehmen und gegen Marktschorgast endlich unseren ersten Heimsieg holen."
+ },
+ {
+ "frage": "Marktschorgast steht aktuell einen Punkt vor uns. Was für einen Gegner erwartest du?",
+ "antwort": "Die Tabelle zeigt, wie eng es aktuell zugeht. Marktschorgast wird uns alles abverlangen. Für uns geht es darum, unabhängig vom Gegner unsere eigenen Prinzipien auf den Platz zu bringen, aufmerksam zu verteidigen und mutig nach vorne zu spielen."
+ },
+ {
+ "frage": "In den ersten beiden Heimspielen hat es noch nicht mit einem Sieg geklappt. Was müssen wir diesmal besser machen?",
+ "antwort": "Wir müssen von der ersten Minute an wach und konsequent sein. Gerade zuhause wollen wir das Spiel aktiv gestalten, unsere Fehler kleinhalten und unsere Chancen besser nutzen. Wenn wir als Mannschaft dieselbe Geschlossenheit wie in Rugendorf zeigen, haben wir sehr gute Möglichkeiten, den ersten Heimsieg zu holen."
+ }
+ ],
+ "photo": "img/persons/ali-kilic.jpg"
+ },
+ "aufruf": {
+ "kicker": "Sportfest 2026",
+ "heading": "Helfende Hände gesucht",
+ "intro": [
+ "Sportfest vom 4. bis 6. September.",
+ "Drei Tage Fußball, Essen und Feiern.",
+ "Dafür brauchen wir dich."
+ ],
+ "tasks_title": "Wobei wir Hilfe brauchen",
+ "tasks": [
+ "Grillen",
+ "Kaffee, Kuchen und Getränke verkaufen",
+ "Pizza backen und verkaufen",
+ "Kuchen backen und mitbringen"
+ ],
+ "contacts_intro": "Du willst mit anpacken? Melde dich bei einem von uns:",
+ "contacts": [
+ "Sam Kern",
+ "Kerstin Tauber",
+ "Fabian Früh"
+ ],
+ "link": "veranstaltungen/sportfest-2026",
+ "cta_label": "Alle Infos",
+ "cta_title": "Alles zum Sportfest",
+ "poster": {
+ "base": "img/veranstaltungen/sportfest-2026/plakat-01",
+ "widths": [
+ 640,
+ 1000,
+ 1587
+ ],
+ "alt": "Plakat zum Sportfest 2026 mit Luftbild unserer Sportanlage und den Terminen vom 4. bis 6. September"
+ }
+ },
+ "verfasser_photo": {
+ "base": "img/stadionzeitung/2026-08-29-asv-marktschorgast/verfasser",
+ "widths": [
+ 120,
+ 222
+ ],
+ "alt": ""
+ },
+ "termine_snapshot": [
+ {
+ "date": "2026-09-02",
+ "date_end": null,
+ "title": "(SG1) TSV Melkendorf III/ TSV 08 Kulmbach II – TSV 1902 Thurnau II",
+ "department": "fussball",
+ "type": "spiel",
+ "meta": "Heimspiel · Reserve BK 5 BT-KU",
+ "href": "/matchcenter",
+ "kickoff": "2026-09-02T18:00",
+ "team_name": "2. Mannschaft",
+ "league": "Reserve BK 5 BT-KU",
+ "raw": {
+ "kickoff": "2026-09-02T18:00",
+ "date_display": "Mi, 02.09.",
+ "time_display": "18:00 Uhr",
+ "competition": "Liga",
+ "home": "(SG1) TSV Melkendorf III/ TSV 08 Kulmbach II",
+ "away": "TSV 1902 Thurnau II",
+ "home_crest": "img/crests/00ES8GNK4O000002VV0AG08LVUPGND5I.png",
+ "away_crest": "img/crests/00ES8GNK4O00000SVV0AG08LVUPGND5I.png",
+ "is_home": true,
+ "team_key": "zweite-mannschaft",
+ "team_name": "2. Mannschaft"
+ }
+ },
+ {
+ "date": "2026-09-04",
+ "date_end": null,
+ "title": "TSV 08 Kulmbach – ATS Wartenfels",
+ "department": "fussball",
+ "type": "spiel",
+ "meta": "Heimspiel · Kreisklasse",
+ "href": "/matchcenter",
+ "kickoff": "2026-09-04T18:00",
+ "team_name": "1. Mannschaft",
+ "league": "Kreisklasse",
+ "raw": {
+ "kickoff": "2026-09-04T18:00",
+ "date_display": "Fr, 04.09.",
+ "time_display": "18:00 Uhr",
+ "competition": "Liga",
+ "home": "TSV 08 Kulmbach",
+ "away": "ATS Wartenfels",
+ "home_crest": "img/crests/00ES8GNK3G000012VV0AG08LVUPGND5I.png",
+ "away_crest": "img/crests/00ES8GNK4O000012VV0AG08LVUPGND5I.png",
+ "is_home": true,
+ "team_key": "erste-mannschaft",
+ "team_name": "1. Mannschaft"
+ }
+ },
+ {
+ "date": "2026-09-04",
+ "date_end": "2026-09-06",
+ "title": "Sportfest 2026",
+ "department": "verein",
+ "type": "event",
+ "meta": "16:30 Uhr · Hans-Rausch-Sportanlage",
+ "href": "/veranstaltungen/sportfest-2026",
+ "time": "16:30",
+ "location": "Hans-Rausch-Sportanlage",
+ "raw": {
+ "slug": "sportfest-2026",
+ "title": "Sportfest 2026",
+ "date_start": "2026-09-04",
+ "date_end": "2026-09-06",
+ "time": "16:30",
+ "location": "Hans-Rausch-Sportanlage",
+ "department": "verein",
+ "status": "veroeffentlicht",
+ "text": "Drei Tage Fußball, Essen, Trinken, Kaffee und Kuchen: bei uns ist für groß und klein alles dabei, für die Kinder steht eine Hüpfburg.",
+ "ankuendigung": null,
+ "rueckblick": null,
+ "karte": "club",
+ "anfahrt": [],
+ "plakate": [
+ {
+ "base": "img/veranstaltungen/sportfest-2026/plakat-01",
+ "widths": [
+ 640,
+ 1000,
+ 1587
+ ],
+ "alt": "Plakat zum Sportfest 2026 mit Luftbild unserer Sportanlage und den Terminen vom 4. bis 6. September",
+ "source": "1-ankuendigung.png"
+ },
+ {
+ "base": "img/veranstaltungen/sportfest-2026/plakat-02",
+ "widths": [
+ 640,
+ 1000,
+ 1587
+ ],
+ "alt": "Programmplakat zum Sportfest 2026 mit allen Spielen, Turnieren und der Kinderolympiade am Samstag",
+ "source": "2-programm.png"
+ }
+ ],
+ "galerie": []
+ }
+ },
+ {
+ "date": "2026-09-05",
+ "date_end": null,
+ "title": "(SG1) TSV Melkendorf III/ TSV 08 Kulmbach II – (SG 2) SV Weidenberg III/SSV Warmensteinach II (flex)",
+ "department": "fussball",
+ "type": "spiel",
+ "meta": "Heimspiel · Reserve BK 5 BT-KU",
+ "href": "/matchcenter",
+ "kickoff": "2026-09-05T18:00",
+ "team_name": "2. Mannschaft",
+ "league": "Reserve BK 5 BT-KU",
+ "raw": {
+ "kickoff": "2026-09-05T18:00",
+ "date_display": "Sa, 05.09.",
+ "time_display": "18:00 Uhr",
+ "competition": "Liga",
+ "home": "(SG1) TSV Melkendorf III/ TSV 08 Kulmbach II",
+ "away": "(SG 2) SV Weidenberg III/SSV Warmensteinach II (flex)",
+ "home_crest": "img/crests/00ES8GNK4O000002VV0AG08LVUPGND5I.png",
+ "away_crest": "img/crests/00ES8GNK4O000013VV0AG08LVUPGND5I.png",
+ "is_home": true,
+ "team_key": "zweite-mannschaft",
+ "team_name": "2. Mannschaft"
+ }
+ },
+ {
+ "date": "2026-09-06",
+ "date_end": null,
+ "title": "TSV 08 Kulmbach – 1. FC 1928 Schwarzenbach/Saale",
+ "department": "fussball",
+ "type": "spiel",
+ "meta": "Heimspiel · Frauen KL Ost",
+ "href": "/matchcenter",
+ "kickoff": "2026-09-06T11:00",
+ "team_name": "Frauenmannschaft",
+ "league": "Frauen KL Ost",
+ "raw": {
+ "kickoff": "2026-09-06T11:00",
+ "date_display": "So, 06.09.",
+ "time_display": "11:00 Uhr",
+ "competition": "Liga",
+ "home": "TSV 08 Kulmbach",
+ "away": "1. FC 1928 Schwarzenbach/Saale",
+ "home_crest": "img/crests/00ES8GNK3G000012VV0AG08LVUPGND5I.png",
+ "away_crest": "img/crests/00ES8GNK9O00000QVV0AG08LVUPGND5I.png",
+ "is_home": true,
+ "team_key": "damen",
+ "team_name": "Frauenmannschaft"
+ }
+ }
+ ],
+ "images": [
+ {
+ "type": "live",
+ "page": "cover"
+ },
+ {
+ "type": "live",
+ "page": "vorwort"
+ },
+ {
+ "type": "live",
+ "page": "interview"
+ },
+ {
+ "type": "live",
+ "page": "aufruf"
+ },
+ {
+ "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": "gegner"
+ },
+ {
+ "type": "image",
+ "base": "img/anzeigen/muench-richterstegner",
+ "widths": [
+ 480,
+ 960,
+ 1440
+ ],
+ "alt": "Anzeige: Planungsbüro Münch und Richter & Stegner Steuerungstechnik"
+ },
+ {
+ "type": "image",
+ "base": "img/anzeigen/malteser-herrmann",
+ "widths": [
+ 480,
+ 960,
+ 1440
+ ],
+ "alt": "Anzeige: Malteser-Hilfsdienst und Schlosserei Herrmann, 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/apotheken-wenkel",
+ "widths": [
+ 480,
+ 960,
+ 1440
+ ],
+ "alt": "Anzeige: Apotheke im Fritz, Stadtpark Apotheke und Schlüsseldienst Wenkel, Kulmbach"
+ },
+ {
+ "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": "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": "live",
+ "page": "historie"
+ },
+ {
+ "type": "image",
+ "base": "img/anzeigen/hanft",
+ "widths": [
+ 480,
+ 960,
+ 1440
+ ],
+ "alt": "Anzeige: Hanft Bürotechnik GmbH, Kulmbach"
+ },
+ {
+ "type": "image",
+ "base": "img/anzeigen/elma-kleinheinz",
+ "widths": [
+ 480,
+ 960,
+ 1440
+ ],
+ "alt": "Anzeige: elma GmbH Bayreuth und Metzgerei Kleinheinz, Kulmbach"
+ },
+ {
+ "type": "live",
+ "page": "sportheim"
+ },
+ {
+ "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/sportfest-2026-programm",
+ "widths": [
+ 480,
+ 960,
+ 1440
+ ],
+ "alt": "Eigenanzeige: Programm des Sportfests 2026 mit allen Spielen, Turnieren und der Kinderolympiade"
+ },
+ {
+ "type": "live",
+ "page": "partner"
+ },
+ {
+ "type": "image",
+ "base": "img/anzeigen/emons-partnerdank",
+ "widths": [
+ 480,
+ 960,
+ 1440
+ ],
+ "alt": "Anzeige: Emons Spedition, darunter unser Dank an alle Partner"
+ },
+ {
+ "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-08-29-asv-marktschorgast/rueckseite",
+ "widths": [
+ 480,
+ 960,
+ 1410
+ ],
+ "alt": "Rückseite der Stadionzeitung gegen ASV Marktschorgast"
+ }
+ ]
+ },
{
"slug": "2026-08-15-tsv-koednitz",
"opponent": "TSV Ködnitz",
@@ -1591,4 +2168,4 @@
}
}
]
-}
+}
\ No newline at end of file
diff --git a/public/assets/css/components.css b/public/assets/css/components.css
index 9ba7d1c..4adc914 100644
--- a/public/assets/css/components.css
+++ b/public/assets/css/components.css
@@ -6605,11 +6605,17 @@ body.is-sz-full .back-to-top {
font-weight: var(--fw-bold);
font-size: 4.4cqi;
line-height: 1.25;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
}
.stadionzeitung-termine__meta {
font-size: 3.1cqi;
color: var(--clr-text-muted);
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
}
/* === termine-list (Termine/Events-Seite) === */
@@ -7033,6 +7039,106 @@ a.news-feature__link:hover .news-feature__more {
line-height: 1;
}
+/* === stadionzeitung-gegner (Live-Seite) === */
+.stadionzeitung-gegner {
+ min-height: 100%;
+}
+
+.stadionzeitung-gegner__duell {
+ display: grid;
+ grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
+ align-items: center;
+ gap: 2.5cqi;
+ margin-bottom: 5cqi;
+ padding: 3.3cqi;
+ border: 1px solid var(--clr-glass-border);
+ border-radius: var(--radius-btn);
+ background: color-mix(in srgb, var(--clr-accent) 5%, #fff);
+}
+
+.stadionzeitung-gegner__club {
+ --crest-size: 12cqi;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 1.7cqi;
+ min-width: 0;
+ text-align: center;
+}
+
+.stadionzeitung-gegner__club strong {
+ font-size: 3.2cqi;
+ line-height: 1.15;
+}
+
+.stadionzeitung-gegner__club--own strong {
+ color: var(--clr-accent);
+}
+
+.stadionzeitung-gegner__match {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 0.5cqi;
+ font-size: 2.5cqi;
+ color: var(--clr-text-muted);
+ white-space: nowrap;
+}
+
+.stadionzeitung-gegner__match strong {
+ font-size: 2.9cqi;
+ color: var(--clr-text);
+}
+
+.stadionzeitung-gegner__vergleich {
+ border-block: 1px solid var(--clr-glass-border);
+}
+
+.stadionzeitung-gegner__vergleich-head,
+.stadionzeitung-gegner__vergleich-row {
+ display: grid;
+ grid-template-columns: 1fr 2fr 1fr;
+ align-items: center;
+ text-align: center;
+}
+
+.stadionzeitung-gegner__vergleich-head {
+ padding-block: 1.7cqi;
+ font-size: 2.5cqi;
+ font-weight: var(--fw-bold);
+ text-transform: uppercase;
+ letter-spacing: var(--ls-caps);
+ color: var(--clr-text-muted);
+}
+
+.stadionzeitung-gegner__vergleich-row {
+ min-height: 6.5cqi;
+ border-top: 1px solid var(--clr-glass-border);
+}
+
+.stadionzeitung-gegner__vergleich-row span {
+ font-size: 2.8cqi;
+ color: var(--clr-text-muted);
+}
+
+.stadionzeitung-gegner__vergleich-row strong {
+ font-family: var(--ff-heading);
+ font-size: 4.8cqi;
+ line-height: 1;
+}
+
+.stadionzeitung-gegner__vergleich-row strong:first-child {
+ color: var(--clr-accent);
+}
+
+.stadionzeitung-gegner__empty {
+ padding: 4.2cqi;
+ border: 1px solid var(--clr-glass-border);
+ font-size: 3.3cqi;
+ color: var(--clr-text-muted);
+ text-align: center;
+}
+
/* === stadionzeitung-vorschau (Live-Seite) === */
/* Nächstes Spiel je Mannschaft nach dem Spieltag — Meta-Zeile + Begegnung in
zwei Wappen-Zeilen (dasselbe Zeilen-Muster wie der Ergebnis-Rückblick),
@@ -8585,4 +8691,3 @@ body.lightbox-open {
overflow: hidden;
}
}
-
diff --git a/public/assets/img/anzeigen/emons-partnerdank-1440.jpg b/public/assets/img/anzeigen/emons-partnerdank-1440.jpg
new file mode 100644
index 0000000..e03c069
Binary files /dev/null and b/public/assets/img/anzeigen/emons-partnerdank-1440.jpg differ
diff --git a/public/assets/img/anzeigen/emons-partnerdank-480.jpg b/public/assets/img/anzeigen/emons-partnerdank-480.jpg
new file mode 100644
index 0000000..770c24e
Binary files /dev/null and b/public/assets/img/anzeigen/emons-partnerdank-480.jpg differ
diff --git a/public/assets/img/anzeigen/emons-partnerdank-960.jpg b/public/assets/img/anzeigen/emons-partnerdank-960.jpg
new file mode 100644
index 0000000..7d0a418
Binary files /dev/null and b/public/assets/img/anzeigen/emons-partnerdank-960.jpg differ
diff --git a/public/assets/img/anzeigen/gagel-pickelmann-1440.jpg b/public/assets/img/anzeigen/gagel-pickelmann-1440.jpg
new file mode 100644
index 0000000..8749036
Binary files /dev/null and b/public/assets/img/anzeigen/gagel-pickelmann-1440.jpg differ
diff --git a/public/assets/img/anzeigen/gagel-pickelmann-480.jpg b/public/assets/img/anzeigen/gagel-pickelmann-480.jpg
new file mode 100644
index 0000000..4f10435
Binary files /dev/null and b/public/assets/img/anzeigen/gagel-pickelmann-480.jpg differ
diff --git a/public/assets/img/anzeigen/gagel-pickelmann-960.jpg b/public/assets/img/anzeigen/gagel-pickelmann-960.jpg
new file mode 100644
index 0000000..0bad61a
Binary files /dev/null and b/public/assets/img/anzeigen/gagel-pickelmann-960.jpg differ
diff --git a/public/assets/img/anzeigen/schramm-1440.jpg b/public/assets/img/anzeigen/schramm-1440.jpg
new file mode 100644
index 0000000..629dca4
Binary files /dev/null and b/public/assets/img/anzeigen/schramm-1440.jpg differ
diff --git a/public/assets/img/anzeigen/schramm-480.jpg b/public/assets/img/anzeigen/schramm-480.jpg
new file mode 100644
index 0000000..85ec374
Binary files /dev/null and b/public/assets/img/anzeigen/schramm-480.jpg differ
diff --git a/public/assets/img/anzeigen/schramm-960.jpg b/public/assets/img/anzeigen/schramm-960.jpg
new file mode 100644
index 0000000..15aa789
Binary files /dev/null and b/public/assets/img/anzeigen/schramm-960.jpg differ
diff --git a/public/assets/img/anzeigen/tagesskifahrt-2027-1440.jpg b/public/assets/img/anzeigen/tagesskifahrt-2027-1440.jpg
new file mode 100644
index 0000000..9e36d34
Binary files /dev/null and b/public/assets/img/anzeigen/tagesskifahrt-2027-1440.jpg differ
diff --git a/public/assets/img/anzeigen/tagesskifahrt-2027-480.jpg b/public/assets/img/anzeigen/tagesskifahrt-2027-480.jpg
new file mode 100644
index 0000000..749cc3d
Binary files /dev/null and b/public/assets/img/anzeigen/tagesskifahrt-2027-480.jpg differ
diff --git a/public/assets/img/anzeigen/tagesskifahrt-2027-960.jpg b/public/assets/img/anzeigen/tagesskifahrt-2027-960.jpg
new file mode 100644
index 0000000..422d58c
Binary files /dev/null and b/public/assets/img/anzeigen/tagesskifahrt-2027-960.jpg differ
diff --git a/public/assets/img/instagram/Db-XCrOsd4q.jpg b/public/assets/img/instagram/Db-XCrOsd4q.jpg
new file mode 100644
index 0000000..de08636
Binary files /dev/null and b/public/assets/img/instagram/Db-XCrOsd4q.jpg differ
diff --git a/public/assets/img/instagram/Db2ya5TDMLC.jpg b/public/assets/img/instagram/Db2ya5TDMLC.jpg
new file mode 100644
index 0000000..b24092b
Binary files /dev/null and b/public/assets/img/instagram/Db2ya5TDMLC.jpg differ
diff --git a/public/assets/img/instagram/Dbk0vKCs-p2.jpg b/public/assets/img/instagram/Dbk0vKCs-p2.jpg
new file mode 100644
index 0000000..c4e0a61
Binary files /dev/null and b/public/assets/img/instagram/Dbk0vKCs-p2.jpg differ
diff --git a/public/assets/img/instagram/Dbs_SENMqBr.jpg b/public/assets/img/instagram/Dbs_SENMqBr.jpg
new file mode 100644
index 0000000..e64d5ff
Binary files /dev/null and b/public/assets/img/instagram/Dbs_SENMqBr.jpg differ
diff --git a/public/assets/img/instagram/DcJDDkEMo0d.jpg b/public/assets/img/instagram/DcJDDkEMo0d.jpg
new file mode 100644
index 0000000..33eeafa
Binary files /dev/null and b/public/assets/img/instagram/DcJDDkEMo0d.jpg differ
diff --git a/public/assets/img/instagram/DcPBlNMjKbP.jpg b/public/assets/img/instagram/DcPBlNMjKbP.jpg
new file mode 100644
index 0000000..c8eb135
Binary files /dev/null and b/public/assets/img/instagram/DcPBlNMjKbP.jpg differ
diff --git a/public/assets/img/instagram/DcQa-pwshfy.jpg b/public/assets/img/instagram/DcQa-pwshfy.jpg
new file mode 100644
index 0000000..45f4de7
Binary files /dev/null and b/public/assets/img/instagram/DcQa-pwshfy.jpg differ
diff --git a/public/assets/img/instagram/DcavewWMsVH.jpg b/public/assets/img/instagram/DcavewWMsVH.jpg
new file mode 100644
index 0000000..31806e9
Binary files /dev/null and b/public/assets/img/instagram/DcavewWMsVH.jpg differ
diff --git a/public/assets/img/instagram/DcjmUaMMJnD.jpg b/public/assets/img/instagram/DcjmUaMMJnD.jpg
new file mode 100644
index 0000000..9a4c16f
Binary files /dev/null and b/public/assets/img/instagram/DcjmUaMMJnD.jpg differ
diff --git a/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/qr-aufruf.png b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/qr-aufruf.png
new file mode 100644
index 0000000..59387ac
Binary files /dev/null and b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/qr-aufruf.png differ
diff --git a/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/qr.png b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/qr.png
new file mode 100644
index 0000000..6fe6fd7
Binary files /dev/null and b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/qr.png differ
diff --git a/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/rueckseite-1410.jpg b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/rueckseite-1410.jpg
new file mode 100644
index 0000000..3d23fc6
Binary files /dev/null and b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/rueckseite-1410.jpg differ
diff --git a/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/rueckseite-480.jpg b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/rueckseite-480.jpg
new file mode 100644
index 0000000..d042fa5
Binary files /dev/null and b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/rueckseite-480.jpg differ
diff --git a/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/rueckseite-960.jpg b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/rueckseite-960.jpg
new file mode 100644
index 0000000..a171c75
Binary files /dev/null and b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/rueckseite-960.jpg differ
diff --git a/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/spieler-1000.png b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/spieler-1000.png
new file mode 100644
index 0000000..c64c1a0
Binary files /dev/null and b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/spieler-1000.png differ
diff --git a/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/spieler-320.png b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/spieler-320.png
new file mode 100644
index 0000000..6d807e2
Binary files /dev/null and b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/spieler-320.png differ
diff --git a/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/spieler-640.png b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/spieler-640.png
new file mode 100644
index 0000000..cfcd852
Binary files /dev/null and b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/spieler-640.png differ
diff --git a/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/verfasser-120.jpg b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/verfasser-120.jpg
new file mode 100644
index 0000000..3c791cb
Binary files /dev/null and b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/verfasser-120.jpg differ
diff --git a/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/verfasser-222.jpg b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/verfasser-222.jpg
new file mode 100644
index 0000000..f455616
Binary files /dev/null and b/public/assets/img/stadionzeitung/2026-08-29-asv-marktschorgast/verfasser-222.jpg differ