Filipe, 30.09.2026: „wenn wir bei highlights videos rein setzen will
ich nicht mehr dass wir sie freigeben muessen, sobald die reingesetzt
wurden sollen die sofort zu sehen sein."
=====================================================================
WAS ICH NICHT GETAN HABE, UND WARUM NICHT
=====================================================================
Die naheliegende Loesung waere gewesen, `highlight` aus
`TREFF_FREIGABE_BRETTER` zu streichen. Das waere falsch: Auf diesem
Brett laedt auch die COMMUNITY hoch -- Clips, Bilder, Fanart. Im
Quelltext steht woertlich daneben:
„Zwei Schloesser, weil hier fremde Inhalte hochgeladen werden --
Urheberrecht und Anstand sind nichts, was man nachtraeglich
klaert."
Filipe meint nicht das. Er meint: „wenn WIR videos rein setzen".
=====================================================================
DIE UNTERSCHEIDUNG STAND SCHON IM HAUS -- nur nicht im Code
=====================================================================
Derselbe Quelltext sagt ueber die zwei Freigabe-Bretter
Verschiedenes:
ansteht -> der SCHALTER „Im Treff zeigen". Das Team entscheidet
JE TERMIN, ob die Community ihn sieht.
highlight -> der Urheberrechts- und Anstandsfilter.
Ein Filter fragt „hat das jemand angesehen?". Wenn der, der ihn
bedienen darf, den Eintrag SELBST anlegt, ist die Antwort ja. Genau
diese Begruendung steht seit dem Uebernehmen aus dem Katalog im
Haus: „Eine zweite daneben waere keine Sicherheit, sondern ein
Klick."
Ein Schalter dagegen ist eine Entscheidung je Fall. Termine bleiben
deshalb unberuehrt -- sonst stuende jeder interne Termin sofort im
Treff, und danach hat niemand gefragt.
Neu: `FREIGABE_IST_FILTER` und `sofortFreigeben()` in
workspace-treff.js. DIE BEDINGUNG FRAGT DIE ROLLE, NICHT DEN WEG --
waere der Weg gefragt, waere aus dem Filter ein Loch geworden, sobald
jemand einen zweiten Weg baut. Ein Community-Mitglied ab „Stamm"
darf weiterhin einstellen; sein Eintrag wartet auf das Team.
Gerufen an ZWEI Stellen: beim Videoweg und beim Anlegen von Hand.
Beide hatten es bisher nicht.
=====================================================================
DIE VORHANDENE FREIGABEPRUEFUNG BEWEIST DAS NICHT
=====================================================================
Sie blieb nach der Aenderung gruen -- und das zu Recht: Sie legt ihre
Eintraege unmittelbar in der Datenbank an und prueft damit den
Mechanismus, nicht den Weg. Haette ich mich darauf verlassen, waere
eine Aenderung ausgeliefert worden, fuer die keine Zeile spricht.
pruef-treff (+5): DogFather legt ueber den echten Weg an -> die
Community sieht es SOFORT. Ein TERMIN bleibt verborgen. Die Regel
gibt fuer eine Rolle von aussen NICHT frei und fuer Termine
ueberhaupt nicht.
pruef-video (+3): Der Videoweg hat seinen eigenen Aufruf -- genau
dort wird einer vergessen. Geprueft wird die Freigabezeile selbst,
samt Gegenprobe „freigegeben ist nur, was auch angelegt wurde".
Meinen Abschnitt hatte ich erst HINTER das Abschalten des
nachgebauten TikTok-Dienstes gehaengt -- der Kopf der Datei warnt
woertlich davor („das Abschalten steht ganz hinten"). Gelesen habe
ich ihn, als es rot wurde.
UND `pruef-struktur` HAT MEINE EIGENE NEUE ZEILE GEFANGEN: Sie bildete
das Datum aus UTC statt Ortszeit -- zwischen Mitternacht und zwei Uhr
waere es der falsche Tag gewesen. Behoben mit `tagLokal()`, Minuten
nach dem Schreiben.
Gemessen: pruef-treff 85/0 (war 80), pruef-video 74/0 (war 71),
pruef-highlights 31/0, pruef-bereiche-lesend 37/0,
pruef-treff-werkzeuge 73/0, pruef-alle-sehen-es 43/0,
pruef-community-sicht 10/0, pruef-wege-nach-draussen 67/0,
pruef-struktur 44/0.
Co-Authored-By: Claude Opus 5 <[email protected]>
534 lines
29 KiB
HTML
534 lines
29 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de" data-theme="dogfather">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>DOGFATHER UNIVERSE — Streamer. Community. HasiDog. Manager.</title>
|
||
<meta name="description" content="DOGFATHER UNIVERSE: die Heimat von DogFather als Streamer, der HasiDog-Community und Manager DogFather bei Spicy Media." />
|
||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/universe-32.png?v=202609301254" />
|
||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/universe-180.png?v=202609301254" />
|
||
<link rel="manifest" href="/manifest.json" />
|
||
<meta name="theme-color" content="#065f76" />
|
||
<meta property="og:type" content="website" />
|
||
<meta property="og:site_name" content="DOGFATHER UNIVERSE" />
|
||
<meta property="og:title" content="DOGFATHER UNIVERSE — Streamer. Community. HasiDog. Manager." />
|
||
<meta property="og:description" content="DOGFATHER UNIVERSE: die Heimat von DogFather als Streamer, der HasiDog-Community und Manager DogFather bei Spicy Media." />
|
||
<meta property="og:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||
<meta property="og:url" content="https://dogfather-universe.com/index.html" />
|
||
<meta name="twitter:card" content="summary_large_image" />
|
||
<meta name="twitter:title" content="DOGFATHER UNIVERSE — Streamer. Community. HasiDog. Manager." />
|
||
<meta name="twitter:description" content="DOGFATHER UNIVERSE: die Heimat von DogFather als Streamer, der HasiDog-Community und Manager DogFather bei Spicy Media." />
|
||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||
|
||
<link rel="stylesheet" href="assets/css/main.css?v=202609301254" />
|
||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=202609301254" />
|
||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=202609301254" />
|
||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=202609301254" />
|
||
</head>
|
||
<body class="start-seite">
|
||
<div id="site-header"></div>
|
||
|
||
<main>
|
||
<!-- ================= HERO ================= -->
|
||
<section class="hero hero-cinematic">
|
||
<!-- Großes Trio-Artwork als Kino-Hintergrund (DogFather · Dogi · HasiDog).
|
||
|
||
Das scharfe Bild ist seit 27.08.2026 ein echtes <img> statt eines
|
||
CSS-Hintergrunds. Grund: Als Hintergrund mit "contain" endete es an
|
||
einer harten Kante, und darunter/darüber lag sichtbar die verwaschene
|
||
Fassung — es sah aus wie ein aufgeklebtes Band quer über der Seite
|
||
("es überschneidet den hintergrund"). Ein echtes Bild lässt sich an
|
||
seinen eigenen Rändern weich ausblenden, egal wie breit der
|
||
Bildschirm ist; ein CSS-Hintergrund kann das nicht, weil die Kante
|
||
dort je nach Fensterformat woanders liegt. -->
|
||
<div class="hero-artwork" aria-hidden="true">
|
||
<img class="hero-artwork-scharf" src="assets/img/universe-trio.jpg?v=202609301254"
|
||
width="1600" height="900" alt="" fetchpriority="high" decoding="async" />
|
||
</div>
|
||
|
||
<div class="hero-atmosphere" aria-hidden="true">
|
||
<span class="atmosphere-blend"></span>
|
||
|
||
<!-- Zone 1: Polarlicht oben -->
|
||
<span class="aurora-band a1"></span>
|
||
<span class="aurora-band a2"></span>
|
||
<span class="aurora-band a3"></span>
|
||
|
||
<!-- Zone 2: Rauch in der Mitte -->
|
||
<span class="smoke-blob" style="width:380px;height:380px;top:26%;left:4%;"></span>
|
||
<span class="smoke-blob" style="width:300px;height:300px;top:38%;right:6%;animation-delay:-11s;"></span>
|
||
<span class="smoke-blob" style="width:260px;height:260px;top:48%;left:38%;animation-delay:-22s;"></span>
|
||
|
||
<!-- Zone 3: Nebel unten -->
|
||
<span class="fog-ground"></span>
|
||
</div>
|
||
<div class="container">
|
||
<span class="eyebrow">🩵 DOGFATHER UNIVERSE</span>
|
||
<h1 data-i18n="idx_hero_h1">Streamer. Community. HasiDog. Manager.<br>Gemeinsam stark.</h1>
|
||
<p class="lead worlds" data-i18n="idx_hero_lead">Drei Welten, eine Familie: Team Dogi.</p>
|
||
|
||
<div class="card" style="max-width:420px;margin:1.4rem auto 0;padding:1rem 1.4rem;">
|
||
<span class="badge rank-1"><span class="live-dot is-unknown" id="live-dot"></span><span id="live-text" data-i18n="idx_live_loading">Status wird geladen …</span></span>
|
||
<p class="small" data-i18n="idx_live_info" style="margin:.5rem 0 0;">DogFather geht <strong>jeden Tag ab 20 Uhr</strong> live — oft schon tagsüber, zu wechselnden Zeiten. <a href="streamplan.html">Streamplan ansehen →</a></p>
|
||
</div>
|
||
|
||
<div class="btn-row" style="justify-content:center;">
|
||
<a class="btn btn-primary" href="links.html" data-i18n="idx_hero_btn_links">Alle Links 🩵</a>
|
||
<a class="btn btn-outline" href="bewerben.html" data-i18n="idx_hero_btn_team">Teil vom Team werden</a>
|
||
</div>
|
||
|
||
<div class="hero-grid">
|
||
<a class="card" href="dogfather.html" data-theme="dogfather">
|
||
<span class="tag" data-i18n="idx_hero_card1_tag">Welt 1</span>
|
||
<h2>DogFather</h2>
|
||
<p data-i18n="idx_hero_card1_desc">Streamer, Entertainer, das Herz hinter dem Kanal. Halligalli, Humor und ein offenes Ohr für die Community.</p>
|
||
</a>
|
||
<a class="card" href="hasidog.html" data-theme="hasidog">
|
||
<span class="tag" data-i18n="idx_hero_card2_tag">Welt 2</span>
|
||
<h2>HasiDog</h2>
|
||
<p data-i18n="idx_hero_card2_desc">Die Community, das Maskottchen und Husky Casper — die verspielte, familiäre Seite von Team Dogi.</p>
|
||
</a>
|
||
<a class="card" href="manager.html" data-theme="spicymedia">
|
||
<span class="tag" data-i18n="idx_hero_card3_tag">Welt 3</span>
|
||
<h2 data-i18n="idx_hero_card3_h3">Manager DogFather</h2>
|
||
<p data-i18n="idx_hero_card3_desc">Als Manager bei Spicy Media: Scouts, Creator und faire Zusammenarbeit auf Augenhöhe.</p>
|
||
</a>
|
||
</div>
|
||
|
||
<!-- "Event des Jahres": volle Breite wie die 3 Welt-Kacheln zusammen. Seit
|
||
20.08.2026 (Nutzer-Wunsch) NUR sichtbar, wenn Dogi/VanVan mindestens ein
|
||
Event in der Verwaltung ausgefüllt UND aktiviert haben -- kein
|
||
Standard-/Platzhalterinhalt mehr, kompletter Abschnitt bleibt bis dahin
|
||
unsichtbar (siehe zeigeJahresEvents() weiter unten). Klick öffnet ein
|
||
großes Detail-Fenster (Bild/Titel/Text größer, optionaler direkter Link)
|
||
statt sofort wegzunavigieren. -->
|
||
<div class="jahres-events" id="jahres-events" hidden>
|
||
<div class="jahres-events-head">
|
||
<span class="tag" data-i18n="idx_jahres_events_tag">🏆 Event des Jahres</span>
|
||
</div>
|
||
<div class="jahres-events-grid" id="jahres-events-grid">
|
||
<button type="button" class="jahres-event-card" id="jahres-event-1" data-slot="1" hidden>
|
||
<span class="jahres-event-shine" aria-hidden="true"></span>
|
||
<img class="jahres-event-bild" alt="" hidden />
|
||
<span class="jahres-event-datum"></span>
|
||
<h3></h3>
|
||
<!-- Hülle um den Absatz (27.08.2026): Die Kürzung auf feste
|
||
Zeilenzahl (-webkit-line-clamp) wirkt NICHT, wenn der Absatz
|
||
selbst ein Raster-Kind ist -- der Browser wandelt sein
|
||
display dann um (gemessen: "flow-root"), und statt sauber
|
||
gekürztem Text wird eine Zeile mittendurch abgeschnitten.
|
||
Mit dieser Hülle ist der Absatz wieder ein normaler Block,
|
||
und die Kürzung greift. karte.querySelector("p") findet ihn
|
||
unverändert, die Verwaltungs-Logik bleibt also gleich. -->
|
||
<div class="jahres-event-textwrap"><p></p></div>
|
||
<span class="jahres-event-mehr" data-i18n="idx_jahres_events_mehr">Mehr erfahren →</span>
|
||
</button>
|
||
<button type="button" class="jahres-event-card" id="jahres-event-2" data-slot="2" hidden>
|
||
<span class="jahres-event-shine" aria-hidden="true"></span>
|
||
<img class="jahres-event-bild" alt="" hidden />
|
||
<span class="jahres-event-datum"></span>
|
||
<h3></h3>
|
||
<!-- Hülle um den Absatz (27.08.2026): Die Kürzung auf feste
|
||
Zeilenzahl (-webkit-line-clamp) wirkt NICHT, wenn der Absatz
|
||
selbst ein Raster-Kind ist -- der Browser wandelt sein
|
||
display dann um (gemessen: "flow-root"), und statt sauber
|
||
gekürztem Text wird eine Zeile mittendurch abgeschnitten.
|
||
Mit dieser Hülle ist der Absatz wieder ein normaler Block,
|
||
und die Kürzung greift. karte.querySelector("p") findet ihn
|
||
unverändert, die Verwaltungs-Logik bleibt also gleich. -->
|
||
<div class="jahres-event-textwrap"><p></p></div>
|
||
<span class="jahres-event-mehr" data-i18n="idx_jahres_events_mehr">Mehr erfahren →</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Detail-Fenster für "Event des Jahres" -- bewusst außerhalb der Hero-Sektion
|
||
(die hat eigene transform-/overflow-Effekte für die Polarlicht-/Nebel-
|
||
Animation, die ein position:fixed-Fenster aus der Zentrierung bringen
|
||
könnten). -->
|
||
<div class="jahres-event-modal-overlay" id="jahres-event-modal-overlay" hidden>
|
||
<div class="jahres-event-modal" role="dialog" aria-modal="true" aria-labelledby="jahres-event-modal-titel">
|
||
<button type="button" class="jahres-event-modal-close" id="jahres-event-modal-close" aria-label="Schließen">✕</button>
|
||
<img class="jahres-event-modal-bild" id="jahres-event-modal-bild" alt="" hidden />
|
||
<div class="jahres-event-modal-body">
|
||
<span class="jahres-event-modal-datum" id="jahres-event-modal-datum"></span>
|
||
<h2 id="jahres-event-modal-titel"></h2>
|
||
<p id="jahres-event-modal-text"></p>
|
||
<a class="btn btn-primary jahres-event-modal-link" id="jahres-event-modal-link" href="#" target="_blank" rel="noopener" hidden></a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ================= CHARAKTERE: DOGFATHER-HUSKY & HASIDOG-HASE ================= -->
|
||
<section class="section-tight">
|
||
<div class="container text-center">
|
||
<span class="eyebrow" data-i18n="idx_char_eyebrow">🩵 Die Gesichter der Welten</span>
|
||
<h2>DogFather & HasiDog</h2>
|
||
<p class="lead" data-i18n="idx_char_lead" style="max-width:52ch;margin:0 auto 2.4rem;">Zwei Charaktere, ein Universum — klick dich in ihre Welt.</p>
|
||
|
||
<div class="char-showcase">
|
||
<a class="char-card dogfather" href="streamer.html">
|
||
<img src="assets/img/char-dogfather.jpg?v=202609301254" width="599" height="1212"
|
||
alt="DogFather — Husky mit blauem Hoodie und Cap" />
|
||
<span class="char-meta">
|
||
<span class="char-name">DogFather</span>
|
||
<span class="char-sub" data-i18n="idx_char1_sub">Streamer · Entertainer · Welt 1</span>
|
||
<span class="char-go" data-i18n="idx_char_go">Zur Welt →</span>
|
||
</span>
|
||
</a>
|
||
<a class="char-card hasidog" href="hasidog.html">
|
||
<img src="assets/img/char-hasidog.jpg?v=202609301254" width="599" height="1212"
|
||
alt="HasiDog — grauer Hase mit schwarzem Hoodie und Cap" />
|
||
<span class="char-meta">
|
||
<span class="char-name">HasiDog</span>
|
||
<span class="char-sub" data-i18n="idx_char2_sub">Community · Maskottchen · Welt 2</span>
|
||
<span class="char-go" data-i18n="idx_char_go">Zur Welt →</span>
|
||
</span>
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ================= FOTO-COLLAGE: DOGFATHER & CASPER ================= -->
|
||
<section class="section-tight">
|
||
<div class="container text-center">
|
||
<span class="eyebrow" data-i18n="idx_collage_eyebrow">🩵 Gesichter hinter dem Universum</span>
|
||
<h2>DogFather & Casper</h2>
|
||
<div class="collage-wrap" id="collage-wrap">
|
||
<div class="collage-item">
|
||
<div class="collage-photo"><img class="collage-img" data-fallback="DogFather" src="assets/img/dogfather-portrait.jpg?v=202609301254" alt="DogFather" style="object-position:center top;"></div>
|
||
<p class="collage-caption">DogFather 🩵</p>
|
||
</div>
|
||
<div class="collage-item">
|
||
<div class="collage-photo frame-lila"><img class="collage-img" data-fallback="Casper" src="assets/img/casper-1.jpg?v=202609301254" alt="Casper" style="object-position:center top;"></div>
|
||
<p class="collage-caption">Casper 🐾</p>
|
||
</div>
|
||
<div class="collage-item">
|
||
<div class="collage-photo frame-silver"><img class="collage-img" data-fallback="DogFather & Casper" src="assets/img/dogfather-casper-1.jpg?v=202609301254" alt="DogFather und Casper zusammen" style="object-position:center 18%;"></div>
|
||
<p class="collage-caption" data-i18n="idx_collage_cap_team">Team 🩵🐾</p>
|
||
</div>
|
||
<div class="collage-item">
|
||
<div class="collage-photo frame-gold"><img class="collage-img" data-fallback="Casper" src="assets/img/casper-2.jpg?v=202609301254" alt="Casper"></div>
|
||
<p class="collage-caption" data-i18n="idx_collage_cap_huskylife">Husky-Life</p>
|
||
</div>
|
||
<div class="collage-item">
|
||
<div class="collage-photo frame-tuerkis"><img class="collage-img" data-fallback="DogFather & Casper" src="assets/img/dogfather-casper-2.jpg?v=202609301254" alt="DogFather und Casper Nase an Nase"></div>
|
||
<p class="collage-caption" data-i18n="idx_collage_cap_nose">Nase an Nase 🩵</p>
|
||
</div>
|
||
</div>
|
||
<p class="small muted" data-i18n="idx_collage_footer" style="max-width:50ch;margin:0 auto;">DogFather & Casper — die zwei Gesichter hinter dem ganzen Universum. 🩵🐾</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ================= STATS ================= -->
|
||
<section class="section-tight">
|
||
<div class="container">
|
||
<div class="grid grid-4" id="stats-bar">
|
||
<div class="card text-center"><h3 id="stat-team">–</h3><p class="small muted" data-i18n="idx_stats_team">Menschen im Team Dogi</p></div>
|
||
<div class="card text-center"><h3 data-i18n="idx_stats_daily_label">Täglich</h3><p class="small muted" data-i18n="idx_stats_daily_desc">live ab 20 Uhr</p></div>
|
||
<div class="card text-center"><h3>3</h3><p class="small muted" data-i18n="idx_stats_worlds">Welten, eine Familie</p></div>
|
||
<div class="card text-center"><h3>🩵</h3><p class="small muted" data-i18n="idx_stats_family">Team Dogi ist Familie</p></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ================= WAS DICH ERWARTET ================= -->
|
||
<section>
|
||
<div class="container">
|
||
<span class="eyebrow text-center" data-i18n="idx_expect_eyebrow" style="display:block;text-align:center;">Ein bisschen von allem</span>
|
||
<h2 class="text-center" data-i18n="idx_expect_h2">Was dich im Universum erwartet</h2>
|
||
<div class="grid grid-4">
|
||
<a class="card" href="streamer.html"><h3 data-i18n="idx_expect_c1_h3">🎥 Streamer</h3><p class="small" data-i18n="idx_expect_c1_p">Halligalli, Humor & Hasencontent.</p></a>
|
||
<a class="card" href="zeitreise.html"><h3 data-i18n="idx_expect_c2_h3">🕰️ Zeitreise</h3><p class="small" data-i18n="idx_expect_c2_p">Die Geschichte von DogFather & Team Dogi.</p></a>
|
||
<a class="card" href="community.html"><h3 data-i18n="idx_expect_c3_h3">🩵 Community</h3><p class="small" data-i18n="idx_expect_c3_p">Team Dogi ist Familie.</p></a>
|
||
<a class="card" href="casper.html"><h3 data-i18n="idx_expect_c4_h3">🐾 Casper</h3><p class="small" data-i18n="idx_expect_c4_p">Der Husky an DogFathers Seite.</p></a>
|
||
<a class="card" href="team-modis.html"><h3 data-i18n="idx_expect_c5_h3">🧑🤝🧑 Modi-Team</h3><p class="small" data-i18n="idx_expect_c5_p">VanVan, Diene & Co.</p></a>
|
||
<a class="card" href="medien-dogfather.html"><h3 data-i18n="idx_expect_c6_h3">🖼️ Medien: DogFather</h3><p class="small" data-i18n="idx_expect_media_p">Fotos, Videos & Events.</p></a>
|
||
<a class="card" href="medien-hasidog.html"><h3 data-i18n="idx_expect_c7_h3">🐰 Medien: HasiDog</h3><p class="small" data-i18n="idx_expect_media_p">Fotos, Videos & Events.</p></a>
|
||
<a class="card" href="medien-casper.html"><h3 data-i18n="idx_expect_c8_h3">🐺 Medien: Casper</h3><p class="small" data-i18n="idx_expect_media_p">Fotos, Videos & Events.</p></a>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ================= TEAM PREVIEW ================= -->
|
||
<section class="section-tight team-bg">
|
||
<div class="container">
|
||
<h2 class="text-center" data-i18n="idx_team_h2">Team Dogi 🩵</h2>
|
||
<p class="lead text-center" data-i18n="idx_team_lead" style="max-width:60ch;margin:0 auto;">VanVan & Modis — die Menschen, die DOGFATHER UNIVERSE tragen.</p>
|
||
<!-- Nutzer-Wunsch 21.08.2026: die vier Personen-Kacheln (VanVan/Diene/
|
||
Funny/Miss) hier auf der Startseite entfernt -- Überschrift, Text
|
||
und der Knopf zum Modi-Team bleiben. Die Kacheln selbst gibt es
|
||
weiterhin vollständig auf team-modis.html. -->
|
||
<div class="btn-row" style="justify-content:center;">
|
||
<a class="btn btn-outline" href="team-modis.html" data-i18n="idx_team_btn_modi">Modi-Team ansehen</a>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Nutzer-Wunsch 21.08.2026: der "Was gerade läuft"-Aktionen-Teaser
|
||
(Überschrift + Button "Alle Aktionen & Projekte", direkt hier davor)
|
||
wurde entfernt. data-aktionen.js/aktion-detail.html bleiben unangetastet,
|
||
nur die Startseiten-Vorschau ist weg. -->
|
||
|
||
<!-- ================= GALERIE TEASER ================= -->
|
||
<section class="section-tight">
|
||
<div class="container">
|
||
<h2 class="text-center" data-i18n="idx_galerie_h2">Impressionen</h2>
|
||
<div class="grid grid-4">
|
||
<div class="collage-photo" style="aspect-ratio:1;border-radius:var(--radius);"><img src="assets/img/casper-3.jpg?v=202609301254" alt="Casper" style="width:100%;height:100%;object-fit:cover;object-position:center 20%;" /></div>
|
||
<div class="collage-photo frame-lila" style="aspect-ratio:1;border-radius:var(--radius);"><img src="assets/img/card-vanvan.jpg?v=202609301254" alt="VanVan" style="width:100%;height:100%;object-fit:cover;" /></div>
|
||
<div class="collage-photo frame-silver" style="aspect-ratio:1;border-radius:var(--radius);"><img src="assets/img/casper-4.jpg?v=202609301254" alt="Casper" style="width:100%;height:100%;object-fit:cover;object-position:42% center;" /></div>
|
||
<div class="collage-photo frame-gold" style="aspect-ratio:1;border-radius:var(--radius);"><img src="assets/img/card-dogfather.jpg?v=202609301254" alt="DogFather" style="width:100%;height:100%;object-fit:cover;" /></div>
|
||
</div>
|
||
<div class="btn-row" style="justify-content:center;">
|
||
<a class="btn btn-outline" href="medien-dogfather.html" data-i18n="idx_galerie_btn">Zur ganzen Galerie</a>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ================= TESTIMONIAL ================= -->
|
||
<section>
|
||
<div class="container text-center">
|
||
<span class="eyebrow" data-i18n="idx_testimonial_eyebrow">Was andere sagen</span>
|
||
<div class="card" style="max-width:640px;margin:1rem auto 0;">
|
||
<p class="quote" data-i18n="idx_testimonial_quote" style="font-size:1.15rem;">„Hier stehen bald echte Stimmen aus der Community. 🩵"</p>
|
||
<p class="small muted" data-i18n="idx_testimonial_attrib">— Team Dogi</p>
|
||
</div>
|
||
<div class="btn-row" style="justify-content:center;">
|
||
<a class="btn btn-outline" href="stimmen.html" data-i18n="idx_testimonial_btn">Mehr Stimmen</a>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
|
||
|
||
<!-- ================= FINALER CTA ================= -->
|
||
<section class="hero">
|
||
<div class="container text-center">
|
||
<span class="eyebrow" data-i18n="idx_cta_eyebrow">🩵 Bereit?</span>
|
||
<h2 data-i18n="idx_cta_h2">Werde Teil von DOGFATHER UNIVERSE</h2>
|
||
<p class="lead" data-i18n="idx_cta_lead" style="max-width:56ch;margin:0 auto;">Als Zuschauer:in, Creator, Scout oder Kooperationspartner — hier ist für jeden Platz.</p>
|
||
<div class="btn-row" style="justify-content:center;">
|
||
<a class="btn btn-primary" href="links.html" data-i18n="idx_cta_btn_links">Alle Links 🩵</a>
|
||
<a class="btn btn-secondary" href="bewerben.html" data-i18n="idx_cta_btn_bewerben">Jetzt bewerben</a>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<div id="site-footer"></div>
|
||
<script src="assets/js/data-modis.js?v=202609301254"></script>
|
||
<script src="assets/js/data-scouts.js?v=202609301254"></script>
|
||
<script src="assets/js/i18n-index.js?v=202609301254"></script>
|
||
<script src="assets/js/main.js?v=202609301254"></script>
|
||
<script>
|
||
// Gleiche URL wie in assets/js/forms.js / postfach.html — läuft seit
|
||
// 05.08.2026 auf dem eigenen Server statt auf Cloudflare Workers.
|
||
const API_BASE_URL = "https://postfach.dogfather-universe.com";
|
||
|
||
document.addEventListener("DOMContentLoaded", () => {
|
||
// Foto-Collage: solange echte Fotos fehlen, hübschen Platzhalter statt
|
||
// kaputtem Bild-Icon zeigen. Sobald ein Foto unter dem passenden Pfad
|
||
// (assets/img/dogfather-portrait.jpg etc.) liegt, taucht es automatisch auf.
|
||
document.querySelectorAll(".collage-img").forEach((img) => {
|
||
img.addEventListener(
|
||
"error",
|
||
() => {
|
||
const div = document.createElement("div");
|
||
div.className = "img-placeholder";
|
||
const fotoFolgtText = window.dogiUebersetzen ? window.dogiUebersetzen("idx_foto_folgt") : "Foto folgt";
|
||
div.innerHTML = `${img.dataset.fallback}<br><span class="small">${fotoFolgtText}</span>`;
|
||
img.replaceWith(div);
|
||
},
|
||
{ once: true }
|
||
);
|
||
});
|
||
|
||
// Live-Status: grün = läuft gerade, rot = offline.
|
||
// Der Wert kommt automatisch von TikTok (Cron im Worker prüft jede Minute).
|
||
// Die Seite fragt alle 30 Sekunden nach, damit der Punkt ohne Neuladen umspringt.
|
||
const liveDot = document.getElementById("live-dot");
|
||
const liveText = document.getElementById("live-text");
|
||
|
||
if (API_BASE_URL && liveDot && liveText) {
|
||
// Übersetzter Text hängt vom Live-Zustand ab (nicht per data-i18n
|
||
// abbildbar) — letzten bekannten Zustand merken, damit ein
|
||
// Sprachwechsel den Text sofort neu übersetzen kann, ohne auf den
|
||
// nächsten 30s-Poll warten zu müssen.
|
||
let letzterZustand = { status: "loading" };
|
||
|
||
const texteNeuSetzen = () => {
|
||
if (letzterZustand.status === "live") {
|
||
liveText.textContent = letzterZustand.titel
|
||
? window.dogiUebersetzen("idx_live_now", { titel: letzterZustand.titel })
|
||
: window.dogiUebersetzen("idx_live_now_generic");
|
||
} else if (letzterZustand.status === "offline") {
|
||
liveText.textContent = window.dogiUebersetzen("idx_live_offline");
|
||
} else if (letzterZustand.status === "error") {
|
||
liveText.textContent = window.dogiUebersetzen("idx_live_error");
|
||
} else {
|
||
liveText.textContent = window.dogiUebersetzen("idx_live_loading");
|
||
}
|
||
};
|
||
|
||
liveDot.classList.add("is-unknown");
|
||
texteNeuSetzen();
|
||
document.addEventListener("dogi-sprache-geaendert", texteNeuSetzen);
|
||
|
||
const applyLiveStatus = (data) => {
|
||
const isLive = !!(data && data.live);
|
||
liveDot.classList.remove("is-unknown");
|
||
liveDot.classList.toggle("is-live", isLive);
|
||
letzterZustand = isLive ? { status: "live", titel: data.title } : { status: "offline" };
|
||
texteNeuSetzen();
|
||
};
|
||
|
||
const refreshLiveStatus = () =>
|
||
fetch(`${API_BASE_URL}/live-status`, { cache: "no-store" })
|
||
.then((res) => res.json())
|
||
.then(applyLiveStatus)
|
||
.catch(() => {
|
||
liveDot.classList.remove("is-live");
|
||
liveDot.classList.add("is-unknown");
|
||
letzterZustand = { status: "error" };
|
||
texteNeuSetzen();
|
||
});
|
||
|
||
refreshLiveStatus();
|
||
setInterval(refreshLiveStatus, 30000);
|
||
// Beim Zurückwechseln zum Tab sofort aktualisieren statt bis zu 30 s warten.
|
||
document.addEventListener("visibilitychange", () => {
|
||
if (!document.hidden) refreshLiveStatus();
|
||
});
|
||
}
|
||
|
||
/* "Event des Jahres": seit 20.08.2026 in der Verwaltung pflegbar (Bild,
|
||
Text, Link, Aktiv-Schalter je Slot, siehe verwaltung.html +
|
||
server-internal/routes/events.js). Nutzer-Wunsch 20.08.2026: "die
|
||
kisten sollen leer sein solang wie ich nichts rein setze, am besten
|
||
sollen die sogar immer nur erscheinen wenn ich was rein setze und sie
|
||
aktiviere" — der Server liefert über /events-of-year ohnehin NUR
|
||
aktivierte Slots (inaktive/leere kommen als null), hier also einfach:
|
||
kein Eintrag -> Kachel bleibt versteckt, kompletter Abschnitt bleibt
|
||
versteckt, wenn beide Slots leer sind. Klick öffnet ein großes
|
||
Detail-Fenster statt sofort zu navigieren. */
|
||
const feldJahresEvent = (x) => (window.dogiFeld ? window.dogiFeld(x) : x || "");
|
||
let jahresEventsDaten = [null, null];
|
||
|
||
function zeigeJahresEventKachel(slot, daten) {
|
||
const karte = document.getElementById(`jahres-event-${slot}`);
|
||
if (!karte) return;
|
||
if (!daten) {
|
||
karte.hidden = true;
|
||
return;
|
||
}
|
||
const bild = karte.querySelector(".jahres-event-bild");
|
||
if (daten.bild) {
|
||
bild.src = daten.bild;
|
||
bild.alt = feldJahresEvent(daten.titel);
|
||
bild.hidden = false;
|
||
} else {
|
||
bild.hidden = true;
|
||
}
|
||
karte.querySelector(".jahres-event-datum").textContent = daten.datum || "";
|
||
karte.querySelector("h3").textContent = feldJahresEvent(daten.titel);
|
||
karte.querySelector("p").textContent = feldJahresEvent(daten.text);
|
||
karte.hidden = false;
|
||
}
|
||
|
||
function aktualisiereJahresEventsSichtbarkeit() {
|
||
const aktiveSlots = jahresEventsDaten.filter(Boolean).length;
|
||
const abschnitt = document.getElementById("jahres-events");
|
||
const grid = document.getElementById("jahres-events-grid");
|
||
abschnitt.hidden = aktiveSlots === 0;
|
||
// Genau 1 aktives Event: Kachel zentriert und etwas größer statt halb
|
||
// leerem Raster (Nutzer-Wunsch: "kacheln sollen bissl spezieller sein").
|
||
grid.classList.toggle("jahres-events-grid-einzeln", aktiveSlots === 1);
|
||
}
|
||
|
||
function jahresEventModalOeffnen(slot) {
|
||
const daten = jahresEventsDaten[slot - 1];
|
||
if (!daten) return;
|
||
const bild = document.getElementById("jahres-event-modal-bild");
|
||
if (daten.bild) {
|
||
bild.src = daten.bild;
|
||
bild.alt = feldJahresEvent(daten.titel);
|
||
bild.hidden = false;
|
||
} else {
|
||
bild.hidden = true;
|
||
}
|
||
document.getElementById("jahres-event-modal-datum").textContent = daten.datum || "";
|
||
document.getElementById("jahres-event-modal-titel").textContent = feldJahresEvent(daten.titel);
|
||
document.getElementById("jahres-event-modal-text").textContent = feldJahresEvent(daten.text);
|
||
const linkEl = document.getElementById("jahres-event-modal-link");
|
||
if (daten.link) {
|
||
linkEl.href = daten.link;
|
||
linkEl.textContent = feldJahresEvent(window.I18N_PAGE?.idx_jahres_event_modal_link) || "Direkt ansehen →";
|
||
linkEl.hidden = false;
|
||
} else {
|
||
linkEl.hidden = true;
|
||
}
|
||
const overlay = document.getElementById("jahres-event-modal-overlay");
|
||
overlay.hidden = false;
|
||
requestAnimationFrame(() => overlay.classList.add("offen"));
|
||
document.body.classList.add("modal-offen");
|
||
}
|
||
|
||
function jahresEventModalSchliessen() {
|
||
const overlay = document.getElementById("jahres-event-modal-overlay");
|
||
overlay.classList.remove("offen");
|
||
document.body.classList.remove("modal-offen");
|
||
setTimeout(() => { overlay.hidden = true; }, 220);
|
||
}
|
||
|
||
document.getElementById("jahres-event-1")?.addEventListener("click", () => jahresEventModalOeffnen(1));
|
||
document.getElementById("jahres-event-2")?.addEventListener("click", () => jahresEventModalOeffnen(2));
|
||
document.getElementById("jahres-event-modal-close")?.addEventListener("click", jahresEventModalSchliessen);
|
||
document.getElementById("jahres-event-modal-overlay")?.addEventListener("click", (e) => {
|
||
if (e.target.id === "jahres-event-modal-overlay") jahresEventModalSchliessen();
|
||
});
|
||
document.addEventListener("keydown", (e) => {
|
||
if (e.key === "Escape" && !document.getElementById("jahres-event-modal-overlay").hidden) jahresEventModalSchliessen();
|
||
});
|
||
|
||
if (API_BASE_URL) {
|
||
const ladeJahresEvents = () =>
|
||
fetch(`${API_BASE_URL}/events-of-year`, { cache: "no-store" })
|
||
.then((res) => res.json())
|
||
.then((data) => {
|
||
if (!data?.ok) return;
|
||
jahresEventsDaten = data.events;
|
||
zeigeJahresEventKachel(1, data.events[0]);
|
||
zeigeJahresEventKachel(2, data.events[1]);
|
||
aktualisiereJahresEventsSichtbarkeit();
|
||
})
|
||
.catch(() => {
|
||
/* Kein Fehler nötig -- der Abschnitt bleibt einfach unsichtbar. */
|
||
});
|
||
ladeJahresEvents();
|
||
// Bei Sprachwechsel mit den zuletzt geladenen Daten neu rendern (kein
|
||
// erneuter Server-Aufruf nötig) — Titel/Text stehen ja bereits in allen
|
||
// Sprachen im geladenen Objekt.
|
||
document.addEventListener("dogi-sprache-geaendert", () => {
|
||
zeigeJahresEventKachel(1, jahresEventsDaten[0]);
|
||
zeigeJahresEventKachel(2, jahresEventsDaten[1]);
|
||
});
|
||
}
|
||
|
||
// Stats: Team-Größe aus den Datenobjekten berechnen
|
||
const teamCount = (window.MODIS || []).length + (window.SCOUTS || []).length;
|
||
const statTeam = document.getElementById("stat-team");
|
||
if (statTeam) statTeam.textContent = teamCount > 0 ? `${teamCount}+` : "–";
|
||
|
||
// Nutzer-Wunsch 21.08.2026: die Team-Vorschau (vier Personen-Kacheln unter
|
||
// "Team Dogi 🩵") wurde entfernt -- der zugehörige Render-Code stand hier.
|
||
// data-modis.js/data-scouts.js bleiben eingebunden, weil die Statistik-Zeile
|
||
// weiter oben ("Menschen im Team Dogi") sie weiterhin auszählt.
|
||
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|