Zweite Live-Uhr fuer "spezielles Live-Event" + mehr Farbe im Radar

Nutzer-Wunsch 20.08.2026: "wuensch mir nur noch bissl farbe und sehr
wichtig ist dass ich auch spezielle live events da auch eintragen kann
in der verwaltungsseite so dass da eine zweite uhr erscheint wo die zeit
dann fuer dieses spezielle event laeuft."

- Neue Verwaltungs-Sektion "Spezielles Live-Event": Titel (Deutsch, wird
  automatisch uebersetzt), echtes Datum+Uhrzeit, optionaler Link, Aktiv-
  Schalter -- nur mit Titel + Zukunftsdatum aktivierbar.
- Zweite Uhr auf streamplan.html (Magenta/Violett statt Cyan/Gold, direkt
  neben der bestehenden), nur sichtbar wenn ein Event aktiviert ist und
  das Zieldatum noch nicht vorbei ist. Echter Countdown inkl. Tage (z.B.
  "2T 03:14:59"), "Jetzt"-Zeiger zeigt wie bei Uhr 1 die tatsaechliche
  Uhrzeit, der magentafarbene Fixpunkt markiert die Tageszeit des Events.
  Zieldatum wird als UTC gespeichert -- jede besuchende Person sieht den
  exakt richtigen Countdown in ihrer eigenen Zeitzone.
- "Bissl Farbe": bunter Farbverlauf (Cyan/Violett/Gold) auf dem aeusseren
  Ring statt reinem Grauton, kraeftigerer Sweep-Farbschein.
- Backend: neue routes/special-event.js (getSpecialEventPublic nur bei
  aktiv+zukuenftig, getSpecialEventAdmin fuer Entwuerfe, saveSpecialEvent
  mit Validierung), 13 automatisierte Tests gegen eine Fake-DB bestanden.
- Bugfix unterwegs gefunden (Playwright-Screenshot, wiederholtes Muster
  auf dieser Seite): .stream-radar-wrap blieb trotz [hidden]-Attribut
  sichtbar (display:block ueberschreibt die eingebaute [hidden]-Regel bei
  gleicher Spezifitaet) -- explizite Regel ergaenzt, per Playwright erneut
  verifiziert (display:none bestaetigt).

Backend-Teil (server-internal/) noch ohne Deploy-Zugriff -- Dogi muss ihn
manuell auf dogiintern ausrollen, sonst bleibt die zweite Uhr unsichtbar.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-08-20 23:24:17 +02:00
co-authored by Claude Opus 5
parent 7fdceadb9e
commit 519e209bce
40 changed files with 763 additions and 369 deletions
+68 -29
View File
@@ -19,17 +19,17 @@
<meta name="twitter:description" content="Wann geht DogFather live? Streamplan und Livebereich." />
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
<link rel="stylesheet" href="assets/css/main.css?v=20260820i" />
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260820i" />
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260820i" />
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260820i" />
<link rel="stylesheet" href="assets/css/main.css?v=20260820j" />
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260820j" />
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260820j" />
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260820j" />
</head>
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-streamplan.jpg?v=20260820i');--page-bg-mobile:url('/assets/img/bg-streamplan-mobile.jpg?v=20260820i');">
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-streamplan.jpg?v=20260820j');--page-bg-mobile:url('/assets/img/bg-streamplan-mobile.jpg?v=20260820j');">
<div id="site-header"></div>
<main>
<section class="hero page-bg">
<div class="hero-banner"><img src="/assets/img/bg-streamplan.jpg?v=20260820i" alt="" loading="eager" /></div>
<div class="hero-banner"><img src="/assets/img/bg-streamplan.jpg?v=20260820j" alt="" loading="eager" /></div>
<div class="container">
<span class="eyebrow" data-i18n="sp_eyebrow">Welt 1 — DogFather</span>
<h1 data-i18n="sp_h1">Streamplan &amp; Livebereich</h1>
@@ -37,28 +37,67 @@
<!-- Live-Radar (20.08.2026, Nutzer-Wunsch "geiler und spezieller"): 24h-Ziffernblatt
mit festem 20-Uhr-Leuchtpunkt + echtem "Jetzt"-Zeiger, schaltet live auf Rot/Puls
um, sonst zählt es zum nächsten 20-Uhr-Termin runter. Siehe assets/js/streamplan.js. -->
<div class="stream-radar-wrap">
<div class="stream-radar" id="stream-radar">
<div class="stream-radar-sweep" aria-hidden="true"></div>
<svg viewBox="0 0 300 300" class="stream-radar-dial" aria-hidden="true">
<circle cx="150" cy="150" r="130" class="radar-ring-outer"></circle>
<circle cx="150" cy="150" r="94" class="radar-ring-inner"></circle>
<g id="radar-ticks"></g>
<g id="radar-fixmarker"></g>
<line id="radar-now-hand" class="radar-now-hand" x1="150" y1="150" x2="150" y2="50"></line>
<circle id="radar-now-dot" class="radar-now-dot" cx="150" cy="50" r="5"></circle>
<circle cx="150" cy="150" r="4" class="radar-center-dot"></circle>
</svg>
<div class="stream-radar-center">
<span class="stream-radar-dot" id="radar-status-dot"></span>
<span class="stream-radar-status" id="radar-status-text" data-i18n="sp_radar_loading">Lädt …</span>
<span class="stream-radar-countdown" id="radar-countdown"></span>
<span class="stream-radar-sub" id="radar-status-sub"></span>
um, sonst zählt es zum nächsten 20-Uhr-Termin runter. Zweite Uhr (rechts, Magenta/
Violett) für ein optionales "spezielles Live-Event" aus der Verwaltung -- nur
sichtbar, wenn dort eins aktiviert ist. Siehe assets/js/streamplan.js. -->
<div class="stream-radar-reihe">
<div class="stream-radar-wrap">
<div class="stream-radar" id="stream-radar">
<div class="stream-radar-sweep" aria-hidden="true"></div>
<svg viewBox="0 0 300 300" class="stream-radar-dial" aria-hidden="true">
<defs>
<linearGradient id="radarGradTaeglich" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#8fd9ea"></stop>
<stop offset="50%" stop-color="#8b5cf6"></stop>
<stop offset="100%" stop-color="#e8c465"></stop>
</linearGradient>
</defs>
<circle cx="150" cy="150" r="130" class="radar-ring-outer" stroke="url(#radarGradTaeglich)"></circle>
<circle cx="150" cy="150" r="94" class="radar-ring-inner"></circle>
<g id="radar-ticks"></g>
<g id="radar-fixmarker"></g>
<line id="radar-now-hand" class="radar-now-hand" x1="150" y1="150" x2="150" y2="50"></line>
<circle id="radar-now-dot" class="radar-now-dot" cx="150" cy="50" r="5"></circle>
<circle cx="150" cy="150" r="4" class="radar-center-dot"></circle>
</svg>
<div class="stream-radar-center">
<span class="stream-radar-dot" id="radar-status-dot"></span>
<span class="stream-radar-status" id="radar-status-text" data-i18n="sp_radar_loading">Lädt …</span>
<span class="stream-radar-countdown" id="radar-countdown"></span>
<span class="stream-radar-sub" id="radar-status-sub"></span>
</div>
</div>
<a class="btn btn-primary stream-radar-watch-btn" id="radar-watch-btn" href="https://www.tiktok.com/@dogfather0804" target="_blank" rel="noopener" hidden data-i18n="sp_radar_watch_btn">🔴 Jetzt anschauen</a>
<p class="small muted stream-radar-hinweis" data-i18n="sp_radar_hinweis">Alle Zeiten in deiner Ortszeit.</p>
</div>
<div class="stream-radar-wrap" id="se-radar-wrap" hidden>
<div class="stream-radar event-spezial" id="se-radar">
<div class="stream-radar-sweep" aria-hidden="true"></div>
<svg viewBox="0 0 300 300" class="stream-radar-dial" aria-hidden="true">
<defs>
<linearGradient id="radarGradSpezial" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#ff5cb8"></stop>
<stop offset="50%" stop-color="#c9a6ff"></stop>
<stop offset="100%" stop-color="#e8c465"></stop>
</linearGradient>
</defs>
<circle cx="150" cy="150" r="130" class="radar-ring-outer" stroke="url(#radarGradSpezial)"></circle>
<circle cx="150" cy="150" r="94" class="radar-ring-inner"></circle>
<g id="se-radar-ticks"></g>
<g id="se-radar-fixmarker"></g>
<line id="se-radar-now-hand" class="radar-now-hand" x1="150" y1="150" x2="150" y2="50"></line>
<circle id="se-radar-now-dot" class="radar-now-dot" cx="150" cy="50" r="5"></circle>
<circle cx="150" cy="150" r="4" class="radar-center-dot"></circle>
</svg>
<div class="stream-radar-center">
<span class="stream-radar-titel" id="se-radar-titel"></span>
<span class="stream-radar-countdown" id="se-radar-countdown"></span>
<span class="stream-radar-sub" data-i18n="sp_radar_hinweis_spezial">Spezielles Live-Event</span>
</div>
</div>
<a class="btn btn-primary stream-radar-watch-btn" id="se-radar-link" href="#" target="_blank" rel="noopener" hidden data-i18n="sp_radar_mehr_erfahren">Mehr erfahren →</a>
</div>
<a class="btn btn-primary stream-radar-watch-btn" id="radar-watch-btn" href="https://www.tiktok.com/@dogfather0804" target="_blank" rel="noopener" hidden data-i18n="sp_radar_watch_btn">🔴 Jetzt anschauen</a>
<p class="small muted stream-radar-hinweis" data-i18n="sp_radar_hinweis">Alle Zeiten in deiner Ortszeit.</p>
</div>
<div class="btn-row" style="justify-content:center;">
@@ -87,8 +126,8 @@
</main>
<div id="site-footer"></div>
<script src="assets/js/i18n-streamplan.js?v=20260820i"></script>
<script src="assets/js/main.js?v=20260820i"></script>
<script src="assets/js/streamplan.js?v=20260820i"></script>
<script src="assets/js/i18n-streamplan.js?v=20260820j"></script>
<script src="assets/js/main.js?v=20260820j"></script>
<script src="assets/js/streamplan.js?v=20260820j"></script>
</body>
</html>