diff --git a/CLAUDE.md b/CLAUDE.md index f5d6835..ab2a534 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -60,6 +60,7 @@ selbst gehosteter Stack ohne Abhängigkeiten von Drittanbietern. | Veranstaltungen (`/veranstaltungen` + Detailseiten) | `data/veranstaltungen.json` + `public/assets/img/veranstaltungen/` | Termin, Texte, Programm, Turnierpläne (`turniere[]`, nur fürs Heft), Abschnitte von Claude im Chat gepflegt — **außer `plakate` und `galerie`: die schreibt ausschließlich `bin/veranstaltung-bilder.php`**. Adresse nie in die Texte schreiben (steht in `club.json`) | | News (`/news` + optionale Detailseiten) | `data/news.json` (redaktionelle Meldungen; `artikel[]` = Fließtext-Blöcke, `status` = Entwurf/veröffentlicht) — Instagram-Posts und Ergebnisse kommen weiterhin nur aus `data/instagram.json`/`data/matchcenter.json`, werden auf der News-Seite nur gemergt | Von Claude im Chat gepflegt wie `events.json`/`teams.json` — **keine** Automatisierung, kein Bin-Skript. Instagram/Ergebnisse nie hier duplizieren. `text` bleibt der Teaser (Feed, Meta-Description, Article-Schema), der Artikel steht in `artikel[]` | | Dateiablage `/dateien` (Konfiguration) | `public/dateien/_filesconfig.php` (Rechte pro Konto: `storage/dateien/system/users/admin/config.php`) | **`storage/dateien/system/config/config.php` von Hand editieren** — die App generiert sie selbst und überschreibt sie bei jedem Update. Passwörter/Lizenz gehören in `config.php` (`dateien.*`) | +| Logo-Downloads (`/logo`) | Texte: `data/logo.json` · Master: `storage/logo-quellen/*.svg` | Die Dateien unter `public/assets/downloads/logo/` sind **maschinenverwaltet von `bin/logo-build.php`** — nie von Hand skalieren, nie von Hand umfärben, nie einzeln nachlegen. Auch keine Dateiliste in die JSON schreiben: welche Formate es gibt, entscheidet das Skript, Größen liest die Seite von der Platte | | Icons | `public/assets/icons/` (Bootstrap Icons, lokal) via `icon()`-Helper | Inline-SVG-Pfade von Hand ins Markup, Emoji/Unicode-Glyphen, gezeichnete CSS-Icons, Icon-Font/CDN | Per-Page-Meta (Title/Description/OG) lebt in der jeweiligen Page-Datei (`app/pages/*.php`) im `$meta`-Array. @@ -239,7 +240,7 @@ Funktion, sie ist die einzige Stelle, an der aus JSON HTML entsteht. Web wie CLI. Kein `error_log()`, kein `file_put_contents()` auf eine Logdatei, keine eigene Log-Closure in einem neuen Skript. - Kanal = Dateiname unter `storage/logs/`: `mail` · `spam` · `instagram` · `matchcenter` · - `stadionzeitung` · `veranstaltungen` · `chronik` · `filesgallery` · `logrotate` + `stadionzeitung` · `veranstaltungen` · `chronik` · `filesgallery` · `logo` · `logrotate` (letzterer nur für den Übersprungen-Hinweis des Cron-Endpoints, der seinen Kanal aus dem Job-Namen bildet) (`php-errors.log` schreibt PHP selbst, eigenes Format). @@ -1180,6 +1181,66 @@ funktionieren hier **nicht** — sie brauchen eine öffentliche URL, unser `stor `public/dateien/.htaccess` (braucht `'unsafe-inline'` für Scripts/Styles: die App interpoliert Inline-Code per PHP und kennt keine Nonces) — sie gilt nur dort, die Seiten behalten die strikte. +## Logo-Downloadseite `/logo` + +Damit die Abteilungen das Wappen selbst holen können, statt jedes Mal zu fragen: eine +öffentliche Seite mit jeder Variante in jedem gängigen Format, dazu die Farbwerte und die +Nutzungsregeln. Verlinkt **nur in der Fußzeile** (`navigation.json` → `legal`), nicht im +Hauptmenü. Die Dateien werden **einmalig lokal** erzeugt und committet; nichts davon läuft +auf dem Server, es gibt keinen Cron und keine Laufzeit-Abhängigkeit. + +**Drei Varianten, alle aus EINER Master-SVG** (`storage/logo-quellen/aktuell.svg`, identisch +zum Website-Asset `public/assets/img/logo.svg`): `farbig`, `einfarbig-schwarz` und +`einfarbig-weiss`. Die Umfärbung passiert durch Austausch der Farbklassen im ``-Block +der CorelDRAW-Datei (`.fil0`/`.fil3` schwarz, `.fil1` weiß, `.fil2` rot) — +`bin/logo-build.php` bricht ab, wenn eine erwartete Klasse fehlt, sonst entstünde stillschweigend +dreimal dasselbe Logo. +**Die beiden einfarbigen Fassungen sind exakte Negative voneinander:** nur Linien, ALLE +Flächen frei. Zwei Irrwege dahin, beide am 17.09.2026 korrigiert: eine Fassung „für dunklen +Grund" behielt das rote Schild und war damit keine einfarbige, sondern ein farbiges Logo mit +weißen Konturen; und `einfarbig-schwarz` ersetzte Rot durch **Weiß**, wodurch im PNG eine +deckend weiße Schildfläche steckte (auf farbigem Papier ein weißer Klotz). **Einfarbig heißt +einfarbig:** ein Vollton, der Rest transparent. Nachweisbar über die Volltonfarben im PNG, +je Variante darf genau eine vorkommen. + +**Gerastert wird mit headless Chrome, nicht mit GD.** `bin/img-resize.php` kann keine SVG lesen, +und Inkscape, rsvg-convert oder ImageMagick gibt es hier nicht (auf dem Shared Hosting erst +recht nicht). Chrome kann beides, was gebraucht wird: transparent rastern (`--screenshot` + +`--default-background-color=00000000`) und ein **echtes Vektor-PDF** drucken (`--print-to-pdf`, +nachgemessen: Kurven-Operatoren im Inhaltsstrom, kein eingebettetes Pixelbild). +**Kein `--user-data-dir`** — der naheliegende eigene Profilordner lässt Chrome 152 beim ersten +Aufruf endlos hängen, ohne Bild und ohne Meldung. Ohne den Schalter läuft jeder Aufruf in +Sekunden durch, auch bei geöffnetem Chrome. Wer das ändert, misst die Laufzeit nach. + +**Der JPG-Hintergrund gehört zur Variante**, nicht zum Format: JPG kann keine Transparenz, und +die weiße Fassung auf weißem Grund wäre ein leeres Blatt. `einfarbig-weiss` wird deshalb auf +Anthrazit (`#222`) flachgelegt, alle anderen auf Weiß (`jpg_bg` je Eintrag in `$OUTPUTS`). + +**EPS gibt es bewusst nicht.** Dafür bräuchte es Illustrator, Inkscape oder Ghostscript; ein +Composer-Paket verbietet Regel 1. Druckereien nehmen PDF oder SVG, beides liegt als Vektor +bereit. Steht die Frage doch im Raum, beantwortet sie die FAQ auf der Seite. + +**Retro-Logos:** `retro[]` in `data/logo.json` ist vorbereitet und vorerst leer — im Projekt +existiert kein einziges historisches Wappen (weder im Repo noch in `.context/`, der alten +CMS-Datenbank oder der Chronik-Sammlung). Kommt ein Scan, wird er eine weitere Datei in +`storage/logo-quellen/` plus ein Eintrag in `$OUTPUTS`; liegt er nur als Pixelbild vor, erzeugt +das Skript PNG und JPG über `resize_image_variants()` und lässt SVG und PDF weg. + +**Die Seite ist bewusst karg** (Felix, 17.09.2026): Einleitungstext, Nutzungshinweis +(„nicht verzerren, nicht einfärben"), die Abschnittsüberschrift über den Karten und eine +fünfteilige FAQ waren gebaut und sind alle wieder entfernt worden; das ZIP über alle +Varianten hatte ebenfalls eine eigene Sektion samt Überschrift „Alles auf einmal" und ist +jetzt nur noch ein Knopf unter dem Karten-Raster (Prop `paket` der Komponente) — „alles +davon" gehört direkt unter das, worauf es sich bezieht. Eine Downloadseite ist ein +Regal, kein Text: Wappen, Knöpfe, Farben, fertig. Die Variantenbeschreibungen sind auf drei +Wörter gekürzt („Stempel, Gravur, einfarbiger Druck."). Die Überschrift steht noch als +`visually-hidden` im DOM, damit die Heading-Kette nicht von `h1` auf `h3` springt. +**Nichts davon wieder hinzuerklären.** + +`bin/preflight.php` prüft, dass zu jeder Variante die Dateien existieren (**Fehler**, nicht +Warnung: die Komponente lässt einen Knopf ohne Datei still weg, man sähe es der Seite nicht an) +und warnt, wenn eine Master-SVG neuer ist als das Erzeugte. + ## Chronik 2028 (Materialsammlung fürs Jubiläum) Sammelt Fundstücke für die Vereinschronik zum 120-jährigen Bestehen. **Reine Recherche-Werkzeuge, diff --git a/app/components/footer.php b/app/components/footer.php index a78259f..5c3f92d 100644 --- a/app/components/footer.php +++ b/app/components/footer.php @@ -91,7 +91,7 @@ $extraLinks = array_merge($extraLinks, $nav['ctas'] ?? []);