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

@@ -5,10 +5,16 @@ declare(strict_types=1);
/**
* Datenschutzerklärung — zugeschnitten auf den tatsächlichen Stack:
* komplett self-hosted, keine Tracker/Analyse/Werbe-Dienste, keine externen
* Fonts/Maps/Embeds. Einzige Verarbeitungen: Server-Logs (Hoster), die drei
* Formulare (Versand über den All-Inkl-Mailserver, also derselbe Auftrags-
* verarbeiter wie beim Hosting), server-seitig gecachter Instagram-Feed
* (Bilder von unserer Domain). Vereinsdaten aus club.json.
* Fonts/Maps/Embeds. Einzige Verarbeitungen: Server-Logs (Hoster), die vier
* Formulare (Kontakt, Turnabteilung, Mitgliedsantrag, Sportheimbuchung; Versand
* über den All-Inkl-Mailserver, also derselbe Auftragsverarbeiter wie beim
* Hosting), server-seitig gecachter Instagram-Feed (Bilder von unserer Domain).
* Vereinsdaten aus club.json.
*
* Alle Empfänger liegen auf unserer eigenen Domain bei All-Inkl (info@,
* turnen@) — deshalb stimmt die Aussage weiter unten, dass kein zusätzlicher
* E-Mail-Dienstleister im Spiel ist. Zeigt ein Postfach künftig auf einen
* fremden Anbieter, muss dieser Satz mit.
*/
$club = json_load('club');
$addr = $club['address'] ?? [];
@@ -36,7 +42,7 @@ $meta = [
</p>
</div>
<div class="legal__body">
<div class="legal__body prose">
<section>
<h2>Verantwortlicher</h2>
<p>Verantwortlich für die Datenverarbeitung auf dieser Website ist:</p>
@@ -123,6 +129,12 @@ $meta = [
Tracking-Zwecken</strong> und bindet keine Dienste ein, die solche Cookies
setzen würden. Aus diesem Grund benötigen wir auch kein Cookie-Banner.
</p>
<p>
Eine Ausnahme betrifft nur den passwortgeschützten internen Bereich
(siehe „Interne Dateiablage“): Wer sich dort anmeldet, erhält ein
technisch notwendiges Sitzungs-Cookie, das die Anmeldung für die Dauer
der Sitzung merkt. Ohne dieses Cookie ist eine Anmeldung nicht möglich.
</p>
</section>
<section>
@@ -152,6 +164,15 @@ $meta = [
E-Mail-Adresse, optional die Telefonnummer sowie Art, Datum und Personenzahl
deiner Veranstaltung, um dir ein Angebot machen zu können.
</p>
<p>
Das <strong>Anfrageformular der Turnabteilung</strong> auf
<a href="<?= e(url('turnen')) ?>">/turnen</a> erhebt dieselben Angaben wie das
Kontaktformular, statt eines Betreffs jedoch die Turngruppe, für die du dich
interessierst; eine Nachricht ist dort freiwillig. Diese Anfragen gehen an das
Postfach der Turnabteilung
(<a href="mailto:<?= e($club['email_turnen']) ?>"><?= e($club['email_turnen']) ?></a>),
weil die Abteilung sie selbst beantwortet.
</p>
<p>
Rechtsgrundlage ist deine Einwilligung (Art. 6 Abs. 1 lit. a DSGVO), die du
mit dem Absenden erteilst, sowie unser berechtigtes Interesse bzw. die
@@ -160,6 +181,18 @@ $meta = [
deine Anfrage abschließend bearbeitet ist und keine gesetzlichen
Aufbewahrungspflichten entgegenstehen.
</p>
<p>
Schickst du uns Material für unsere <strong>Vereinshistorie</strong> Fotos,
Zeitungsausschnitte, Dokumente oder Erinnerungen an
<a href="mailto:<?= e($club['email_historie']) ?>"><?= e($club['email_historie']) ?></a>,
bewahren wir es gemeinsam mit deinem Namen als Quellenangabe in unserem
Vereinsarchiv auf. Grundlage dafür ist unser berechtigtes Interesse an der
Dokumentation der Vereinsgeschichte (Art. 6 Abs. 1 lit. f DSGVO).
Veröffentlichen auf dieser Website, in einer Chronik oder Festschrift
tun wir nur, was du uns ausdrücklich freigegeben hast (Art. 6 Abs. 1 lit. a
DSGVO); diese Freigabe kannst du jederzeit widerrufen. Sind auf Bildern
weitere Personen erkennbar, sag uns bitte, was du darüber weißt.
</p>
<p>
Der technische Versand der Formular-Nachrichten als E-Mail läuft über den
Mailserver unseres Webhosters ALL-INKL.COM (siehe oben) — die Daten bleiben
@@ -177,6 +210,35 @@ $meta = [
</p>
</section>
<section>
<h2>Interne Dateiablage</h2>
<p>
Unter <code>/dateien</code> betreiben wir einen
<strong>passwortgeschützten Bereich</strong>, in dem Mitglieder Fotos und
Videos von Vereinsveranstaltungen für die Website abliefern können. Er ist
nicht öffentlich, nicht verlinkt und von Suchmaschinen ausgenommen; die
Zugangsdaten geben wir nur intern weiter.
</p>
<p>
Verarbeitet werden dort ausschließlich die hochgeladenen Dateien selbst
(einschließlich der darin enthaltenen Aufnahmen von Personen und der
technischen Bilddaten wie Aufnahmezeit oder Kameramodell) sowie der
gewählte Benutzername mit dem Zeitpunkt der Anmeldung. Fehlgeschlagene
Anmeldeversuche halten wir zum Schutz gegen automatisierte Angriffe kurz
fest, dabei die IP-Adresse nur als nicht zurückrechenbare Prüfsumme.
</p>
<p>
Die Dateien liegen ausschließlich auf unserem eigenen Webspace, außerhalb
des öffentlich erreichbaren Bereichs, und werden nicht an Dritte
weitergegeben. Rechtsgrundlage ist Art. 6 Abs. 1 lit. f DSGVO
(berechtigtes Interesse an der Vereinskommunikation); für die
Veröffentlichung von Personenaufnahmen auf der Website gilt zusätzlich der
Abschnitt „Foto- und Videoaufnahmen“. Wer nicht möchte, dass eine Aufnahme
von ihm dort abgelegt oder veröffentlicht wird, kann sich jederzeit an die
oben genannten Kontaktdaten wenden wir löschen sie dann.
</p>
</section>
<section>
<h2>Keine Analyse-, Tracking- oder Werbedienste</h2>
<p>