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
This commit is contained in:
2026-07-31 14:55:27 +02:00
parent 3fb480dd78
commit a101b0c3ec
861 changed files with 75244 additions and 487 deletions

View File

@@ -8,6 +8,9 @@
--clr-accent: #e20612; /* Marken-Rot (alte DB: primary_accent) */
--clr-accent-dark: #b00510; /* Hover/Active auf Rot */
--clr-accent-rgb: 226 6 18; /* für rgb(var(--clr-accent-rgb) / α) */
--clr-accent-hsl: 356.7 94.8% 45.5%; /* dasselbe Rot als H S L */
--clr-accent-h: 356.7; /* nur der Farbton — die Dateiablage (/dateien)
leitet daraus ihre Flächen ab, siehe dateien.css */
--clr-bg: #222222; /* Grund-Hintergrund (mit Textur) */
--clr-bg-deep: #161616; /* abgesetzte Sektionen */
--clr-bg-footer: #000000;
@@ -16,19 +19,29 @@
--clr-text-muted: #b3b3b3; /* 7.7:1 auf --clr-bg */
--clr-text-faint: #8c8c8c; /* 4.5:1 auf --clr-bg (AA) */
--clr-sepia-bg: #f3efe4; /* Timeline-Museumsrahmen (Foto-Mount) */
--clr-logo-card: #ffffff; /* Partner-Logowall: Farb-Logos brauchen neutralen weißen Grund */
--clr-photo-frame: #faf9f6; /* Polaroid-Rahmen (split--polaroid): fast reinweiß, minimal warm */
--clr-tape: rgb(255 250 235 / 0.4); /* Klebestreifen auf Polaroids: milchig, leicht vergilbt */
--clr-sepia-text: #3a372f; /* Timeline-Text auf hellem Sepia-Grund */
--clr-glass-bg: rgb(0 0 0 / 0.22); /* dunkles Glas (dunkler als der Grund) */
--clr-glass-border: rgb(255 255 255 / 0.14); /* sehr dezenter Card-Rand — Glow/Sheen tragen die Kontur */
--clr-glass-border-strong: rgb(255 255 255 / 0.45); /* Back-to-Top, position-/group-card etc.: ≥3:1 (WCAG 1.4.11) */
--clr-field-bg: rgb(255 255 255 / 0.07); /* Formularfelder: sanfte Füllfläche (etwas heller als das Glas) */
--clr-field-bg-solid: #313131; /* dieselbe Fläche, aber OPAK (--clr-field-bg über --clr-bg gerechnet) —
nötig für den Autofill-Fix (box-shadow inset kann keine Transparenz
über die native Browser-Füllung legen, siehe components.css) */
--clr-field-border: rgb(255 255 255 / 0.22); /* Feld-Rand weich — Fläche + Rand machen das Feld erkennbar */
--clr-field-border-hover: rgb(255 255 255 / 0.4); /* Feld-Hover: dezent */
--clr-lightbox-bg: rgb(0 0 0 / 0.93); /* Bild-Großansicht (lightbox): fast schwarz, damit das Foto
allein wirkt und der Seitenhintergrund nicht durchdrückt */
--clr-error: #ff8a8a; /* Formularfehler, lesbar auf dunkel */
--clr-success: #8ce99a;
/* --- Typografie --- */
--ff-heading: 'Coolvetica', 'Arial Narrow', system-ui, sans-serif;
--ff-body: 'Abel', 'Helvetica Neue', system-ui, sans-serif;
--ff-serif: 'PT Serif', Georgia, 'Times New Roman', serif; /* nur Stadionzeitung-Vorwort-Fließtext */
--ff-signature: 'Mr Dafoe', cursive; /* nur Unterschrift des Vorwort-Unterzeichners (Stadionzeitung) */
--fs-300: 0.8125rem; /* 13px Buttons klein */
--fs-400: 0.9375rem; /* 15px Footer, Meta */
--fs-500: 1.125rem; /* 18px Navigation */
@@ -111,6 +124,7 @@
/* --- Form & Tiefe --- */
--radius-btn: 8px;
--radius-card: 15px;
--radius-photo: 4px; /* Polaroid-/Fotorahmen (split--polaroid): fast eckig wie ein echter Abzug */
--shadow: 0 0 14px rgb(0 0 0 / 0.15);
--shadow-card: 0 14px 38px rgb(0 0 0 / 0.42), inset 0 1px 0 rgb(255 255 255 / 0.18); /* Hover-Lift + Top-Sheen */
@@ -122,8 +136,15 @@
--container-max: 1200px;
--container-pad: var(--space-s);
--space-section: var(--space-6xl);
--header-h: 60px;
--logo-h: 72px;
--header-h: 60px; /* Mindesthöhe der Kopfleiste (.site-header__inner) */
--logo-h: 72px; /* Logo — größer als --header-h, bestimmt also faktisch die Höhe */
--header-top: 20px; /* Versatz der Leiste von oben (.site-header) */
/* Was die Kopfleiste vom Seitenanfang wegnimmt. NICHT --header-h dafür
nehmen: die Leiste ist wegen des Logos 72px hoch, nicht 60px, und sitzt
zusätzlich 20px versetzt — wer mit --header-h rechnet, landet 32px zu
hoch und schiebt seinen Inhalt unter das Logo. Abgeleitet statt fest,
damit es nicht auseinanderläuft, wenn Logo oder Versatz sich ändern. */
--header-space: calc(var(--header-top) + var(--logo-h));
/* --- Bewegung --- */
--transition: 300ms ease;