Matchcenter: „Nächste Spiele" als Band statt Autoplay-Slider
Der Bereich wirkte deplatziert: der Track war auf 620px begrenzt und zeigte eine Folie, wodurch die Karte auf breiten Fenstern in ~840px Totraum schwebte; dazu derselbe Hintergrund wie der Hero direkt darüber, kein Akzent, und ein einsames „:" zwischen den Wappen, das wie ein fehlendes Ergebnis aussah. Neu als abgesetztes Band (.section--sunken, nutzt endlich das dafür vorgesehene, bisher unbenutzte Token --clr-bg-deep) mit roter Oberkante: links der Aufmacher (match-feature), rechts die folgenden Termine als verlinkte match-row-Zeilen ohne Kartenfläche. Der Aufmacher ist die große Variante der Terminzeile — Heim über Gast, linksbündig, gleiche Struktur wie die Zeilen daneben. Bewusst nur drei typografische Rollen (Meta-Zeile · Vereinsnamen in Coolvetica · Anstoßzeile mit Countdown) statt der acht der ersten Fassung, ohne Badges, Icons oder Button. Die eigene Mannschaft wird über Helligkeit markiert, nicht über font-weight — Coolvetica hat nur einen Schnitt, bold wäre synthetisch. match-row bekommt optionale $href/$meta-Props; Raster und Innenabstand liegen jetzt im __link-Wrapper, damit als Link die ganze Zeilenfläche klickbar ist. Neue Helper match_when() (ISO + deutscher Countdown, explizit Europe/Berlin, weil PHP global auf UTC läuft) und match_competition_label(). match-slider.php und match-card.php entfallen — Letztere wurde ausschließlich vom Slider genutzt. carousel.js treibt damit nur noch den Banner-Slider der Startseite und wird im Matchcenter nicht mehr geladen. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -125,6 +125,61 @@ function img_intrinsic_attrs(string $rel): string
|
||||
return $cache[$rel];
|
||||
}
|
||||
|
||||
/**
|
||||
* Anzeigewerte zu einem Anstoß. $kickoff = Zeit ohne Zonenangabe aus
|
||||
* data/matchcenter.json (z. B. 2026-08-01T14:00), gelesen als Europe/Berlin —
|
||||
* PHP läuft hier global auf UTC, deshalb explizit. Liefert:
|
||||
* iso maschinenlesbar mit Zone (für <time datetime> und den JS-Ticker)
|
||||
* countdown „heute, 14:00 Uhr" | „morgen, 14:00 Uhr" | „in 6 Tagen" | „in 3 Wochen"
|
||||
* Unlesbarer Wert → beide Felder leer; bereits angestoßenes Spiel → countdown leer.
|
||||
*/
|
||||
function match_when(string $kickoff): array
|
||||
{
|
||||
if ($kickoff === '') {
|
||||
return ['iso' => '', 'countdown' => ''];
|
||||
}
|
||||
$tz = new DateTimeZone('Europe/Berlin');
|
||||
try {
|
||||
$start = new DateTimeImmutable($kickoff, $tz);
|
||||
} catch (Exception) {
|
||||
return ['iso' => '', 'countdown' => ''];
|
||||
}
|
||||
$now = new DateTimeImmutable('now', $tz);
|
||||
if ($start <= $now) {
|
||||
return ['iso' => $start->format('c'), 'countdown' => ''];
|
||||
}
|
||||
// Kalendertage zählen, nicht 24-Stunden-Blöcke: ein Anstoß morgen um 14 Uhr
|
||||
// ist „morgen", auch wenn es nur 20 Stunden hin sind.
|
||||
$days = (int) $now->setTime(0, 0)->diff($start->setTime(0, 0))->format('%a');
|
||||
$time = $start->format('H:i') . ' Uhr';
|
||||
return [
|
||||
'iso' => $start->format('c'),
|
||||
'countdown' => match (true) {
|
||||
$days === 0 => 'heute, ' . $time,
|
||||
$days === 1 => 'morgen, ' . $time,
|
||||
$days < 14 => 'in ' . $days . ' Tagen',
|
||||
default => 'in ' . (int) round($days / 7) . ' Wochen',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Anzeigename eines Wettbewerbs aus data/matchcenter.json. Die BFV-API kennt nur
|
||||
* „Liga" und „Freundschaft": „Liga" wird durch den echten Liganamen ersetzt — ohne
|
||||
* $league bleibt sie leer, damit Ligaspiele in den Mannschafts-Sektionen nicht
|
||||
* redundant beschriftet werden (die Sektion nennt die Liga schon). „Freundschaft"
|
||||
* wird ausgeschrieben, damit erkennbar ist, warum ein Testspiel nicht in der
|
||||
* Tabelle zählt.
|
||||
*/
|
||||
function match_competition_label(string $competition, string $league = ''): string
|
||||
{
|
||||
return match ($competition) {
|
||||
'Liga' => $league,
|
||||
'Freundschaft' => 'Freundschaftsspiel',
|
||||
default => $competition,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Komponente rendern: component('hero', ['title' => …]).
|
||||
* Props werden als lokale Variablen extrahiert; Komponenten sind dumme Includes.
|
||||
|
||||
Reference in New Issue
Block a user