Files
fs 75fce4f680 Logo-Downloadseite /logo mit Erzeuger-Skript
Damit die Abteilungen das Wappen selbst holen können, statt jedes Mal zu fragen:
drei Varianten (farbig, einfarbig schwarz, einfarbig weiß) in SVG, PDF, PNG und JPG,
dazu ein ZIP über alles und die Vereinsfarben. Verlinkt nur in der Fußzeile.

Bisher lag das Logo genau einmal im Projekt, als eine einzige SVG. Es gab kein PNG,
kein JPG, kein PDF und keine einfarbige Fassung.

bin/logo-build.php erzeugt alle Dateien aus einer Master-SVG unter storage/logo-quellen/.
Gerastert wird mit headless Chrome, weil GD kein SVG lesen kann und weder Inkscape noch
rsvg-convert noch ImageMagick verfügbar sind; das PDF ist dabei echter Vektor. Das Skript
läuft einmalig lokal, nichts davon im Request-Pfad. bin/preflight.php meldet als Fehler,
wenn eine Download-Datei fehlt: die Komponente ließe den Knopf sonst still weg.

Die beiden einfarbigen Fassungen sind exakte Negative voneinander, nur Linien, alle
Flächen frei. EPS gibt es bewusst nicht, dafür fehlt jedes Werkzeug; SVG und PDF decken
die Druckereien ab. Frühere Vereinslogos sind vorbereitet, aber im Projekt liegt bisher
kein einziges historisches Wappen vor.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J9mubC8gtpjtJntbhSJBRS
2026-09-17 10:10:08 +02:00

103 lines
4.3 KiB
PHP

<?php
declare(strict_types=1);
/**
* Footer: Brand-Block (Logo, Entity-Satz, Social), Seiten-Navigation,
* Kontakt (NAP aus club.json — identisch zu JSON-LD), Rechtliches.
* Alle Daten aus den Single-Source-Dateien (club.json / navigation.json).
*/
$club = json_load('club');
$nav = json_load('navigation');
$socialLabels = ['instagram' => 'Instagram', 'facebook' => 'Facebook', 'youtube' => 'YouTube'];
$socialIcons = ['instagram' => 'instagram', 'facebook' => 'facebook', 'youtube' => 'youtube'];
// Hauptnav in Spalten gruppieren: jeder Hauptpunkt mit Unterpunkten wird eine
// Footer-Spalte (Heading verlinkt die Übersicht, darunter die Kinder). Standalone-
// Hauptpunkte (ohne Kinder) und CTAs sammeln sich als „Mehr“-Spalte. Anker-Links raus.
$sections = [];
$extraLinks = [];
foreach ($nav['main'] as $item) {
if (str_starts_with($item['slug'], '#')) {
continue;
}
$children = [];
foreach ($item['children'] ?? [] as $child) {
if ($child['slug'] !== $item['slug']) { // „Übersicht“ dupliziert nur den Eltern-Slug = Heading
$children[] = $child;
}
}
if ($children) {
$sections[] = ['label' => $item['label'], 'slug' => $item['slug'], 'links' => $children];
} else {
$extraLinks[] = ['label' => $item['label'], 'slug' => $item['slug']];
}
}
$extraLinks = array_merge($extraLinks, $nav['ctas'] ?? []);
?>
<footer class="site-footer">
<div class="container site-footer__grid">
<div class="site-footer__brand">
<img src="<?= e(asset('img/logo.svg')) ?>" alt="" width="62" height="80" loading="lazy">
<p class="site-footer__claim"><?= e($club['description']) ?></p>
<ul class="site-footer__social" aria-label="Social Media">
<?php foreach ($club['social'] as $key => $socialUrl): ?>
<?php if ($socialUrl): ?>
<li>
<a href="<?= e($socialUrl) ?>" rel="noopener">
<?= icon($socialIcons[$key] ?? 'link-45deg') ?><?= e($socialLabels[$key] ?? ucfirst($key)) ?>
</a>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
</div>
<?php foreach ($sections as $section): ?>
<nav aria-label="<?= e($section['label']) ?>">
<h2 class="site-footer__heading">
<a href="<?= e(url($section['slug'])) ?>"><?= e($section['label']) ?></a>
</h2>
<ul class="site-footer__list">
<?php foreach ($section['links'] as $item): ?>
<li><a href="<?= e(url($item['slug'])) ?>"><?= e($item['label']) ?></a></li>
<?php endforeach; ?>
</ul>
</nav>
<?php endforeach; ?>
<div>
<h2 class="site-footer__heading">Kontakt</h2>
<address class="site-footer__address">
<p>
<?= icon('geo-alt') ?>
<span><?= e($club['address']['venue']) ?><br>
<?= e($club['address']['street']) ?><br>
<?= e($club['address']['zip']) ?> <?= e($club['address']['city']) ?></span>
</p>
<p>
<?= icon('envelope') ?>
<a href="mailto:<?= e($club['email']) ?>"><?= e($club['email']) ?></a>
</p>
</address>
<?php if ($extraLinks): ?>
<ul class="site-footer__list site-footer__list--extra">
<?php foreach ($extraLinks as $item): ?>
<li><a href="<?= e(url($item['slug'])) ?>"><?= e($item['label']) ?></a></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div>
</div>
<div class="site-footer__bottom">
<div class="container site-footer__bottom-inner">
<p>&copy; <?= e(date('Y')) ?> <?= e($club['legal_name']) ?></p>
<ul class="site-footer__legal" aria-label="Service und Rechtliches">
<?php foreach ($nav['legal'] as $item): ?>
<li><a href="<?= e(url($item['slug'])) ?>"><?= e($item['label']) ?></a></li>
<?php endforeach; ?>
</ul>
<p class="site-footer__memberships">Mitglied in: <?= e(implode(' · ', $club['memberships'])) ?></p>
</div>
</div>
</footer>