Compare commits
2
Commits
d0613f86c1
...
6910112d97
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6910112d97 | ||
|
|
e2bd436084 |
@@ -18,10 +18,10 @@
|
|||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
<meta name="robots" content="noindex" />
|
<meta name="robots" content="noindex" />
|
||||||
<title>Seite nicht gefunden — DOGFATHER UNIVERSE</title>
|
<title>Seite nicht gefunden — DOGFATHER UNIVERSE</title>
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-404.js?v=20260821p"></script>
|
<script src="assets/js/i18n-404.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+7
-7
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Unterstütze Dogfather dauerhaft mit der DogiCrew 🩵 und sammle exklusive Treueprämien — die Teddy-Kollektion entsteht in Kooperation mit VanVan." />
|
<meta name="twitter:description" content="Unterstütze Dogfather dauerhaft mit der DogiCrew 🩵 und sammle exklusive Treueprämien — die Teddy-Kollektion entsteht in Kooperation mit VanVan." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
<style>
|
<style>
|
||||||
/* =====================================================================
|
/* =====================================================================
|
||||||
Preis-/Anmelde-Kiste — komplett neu gestaltet (Nutzer-Feedback
|
Preis-/Anmelde-Kiste — komplett neu gestaltet (Nutzer-Feedback
|
||||||
@@ -603,9 +603,9 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-abonnieren.js?v=20260821p"></script>
|
<script src="assets/js/i18n-abonnieren.js?v=20260821q"></script>
|
||||||
<script src="assets/js/supporter.js?v=20260821p"></script>
|
<script src="assets/js/supporter.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
const S = window.DogiSupporter;
|
const S = window.DogiSupporter;
|
||||||
|
|||||||
@@ -20,10 +20,10 @@
|
|||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
<meta name="robots" content="noindex" />
|
<meta name="robots" content="noindex" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -134,6 +134,6 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+7
-7
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Detailansicht einer Aktion oder eines Projekts von Team Dogi." />
|
<meta name="twitter:description" content="Detailansicht einer Aktion oder eines Projekts von Team Dogi." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -51,9 +51,9 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/data-aktionen.js?v=20260821p"></script>
|
<script src="assets/js/data-aktionen.js?v=20260821q"></script>
|
||||||
<script src="assets/js/i18n-aktion-detail.js?v=20260821p"></script>
|
<script src="assets/js/i18n-aktion-detail.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
|
|||||||
@@ -4107,6 +4107,75 @@ body.start-seite .music-toggle:focus-visible {
|
|||||||
background: linear-gradient(135deg, #ffd0e8, #a8e4f2);
|
background: linear-gradient(135deg, #ffd0e8, #a8e4f2);
|
||||||
box-shadow: 0 0 16px rgba(255, 154, 208, .3);
|
box-shadow: 0 0 16px rgba(255, 154, 208, .3);
|
||||||
}
|
}
|
||||||
|
/* Gewähltes Profilbild statt Anfangsbuchstabe (21.08.2026). Erbt Größe und
|
||||||
|
runde Form von .stimmen-karte-avatar oben, ersetzt nur Füllung/Farbe. */
|
||||||
|
.stimmen-karte-avatar-bild {
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background: rgba(255, 255, 255, .05);
|
||||||
|
box-shadow: 0 0 14px rgba(212, 175, 55, .25);
|
||||||
|
}
|
||||||
|
.stimmen-karte-avatar-bild img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
||||||
|
|
||||||
|
/* ---------- Profilbild-Auswahl im Einreichen-Formular (21.08.2026) ----------
|
||||||
|
Nutzer-Wunsch: "paar geile bilder zum aussuchen ... das soll denen auch
|
||||||
|
als möglichkeit gegeben sein". Kachelraster, das sich der Breite anpasst;
|
||||||
|
die getroffene Wahl bekommt einen goldenen Ring statt nur einer leichten
|
||||||
|
Aufhellung — sonst ist auf dunklem Grund kaum erkennbar, was gewählt ist. */
|
||||||
|
.stimmen-avatar-titel {
|
||||||
|
display: block;
|
||||||
|
font-size: .82rem; font-weight: 700; letter-spacing: .04em;
|
||||||
|
text-transform: uppercase; color: var(--text-muted);
|
||||||
|
margin-bottom: .25rem;
|
||||||
|
}
|
||||||
|
.stimmen-avatar-hinweis { margin: 0 0 .7rem; }
|
||||||
|
.stimmen-avatar-wahl {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(58px, 1fr));
|
||||||
|
gap: .6rem;
|
||||||
|
}
|
||||||
|
.stimmen-avatar-kachel {
|
||||||
|
position: relative;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
padding: 0;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
background: rgba(255, 255, 255, .04);
|
||||||
|
border: 2px solid rgba(255, 255, 255, .12);
|
||||||
|
transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
|
||||||
|
}
|
||||||
|
.stimmen-avatar-kachel img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
||||||
|
.stimmen-avatar-keins {
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
width: 100%; height: 100%;
|
||||||
|
font-size: 1.15rem; color: var(--text-muted);
|
||||||
|
}
|
||||||
|
.stimmen-avatar-kachel:hover { transform: translateY(-2px); border-color: rgba(255, 233, 168, .6); }
|
||||||
|
.stimmen-avatar-kachel.aktiv {
|
||||||
|
border-color: #ffe9a8;
|
||||||
|
box-shadow: 0 0 0 2px rgba(212, 175, 55, .45), 0 0 18px rgba(212, 175, 55, .4);
|
||||||
|
}
|
||||||
|
.stimmen-avatar-kachel:focus-visible { outline: 2px solid #ffe9a8; outline-offset: 3px; }
|
||||||
|
/* "Eigenes Bild"-Kachel (21.08.2026): gestrichelter Rand, damit sofort
|
||||||
|
erkennbar ist, dass hier noch nichts drin ist und etwas hinzugefügt
|
||||||
|
werden kann -- im Unterschied zu den fertigen Auswahlbildern daneben.
|
||||||
|
Sobald ein Bild hochgeladen wurde, ersetzt das <img> das Plus-Zeichen
|
||||||
|
und die Kachel sieht aus wie die anderen. */
|
||||||
|
.stimmen-avatar-eigenes { border-style: dashed; border-color: rgba(255, 233, 168, .45); }
|
||||||
|
.stimmen-avatar-eigenes:has(img) { border-style: solid; }
|
||||||
|
.stimmen-avatar-plus {
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
width: 100%; height: 100%;
|
||||||
|
font-size: 1.3rem; line-height: 1; color: #ffe9a8;
|
||||||
|
}
|
||||||
|
/* Während des Hochladens: kurz gedimmt, damit klar ist, dass etwas läuft. */
|
||||||
|
.stimmen-avatar-eigenes.laedt { opacity: .5; pointer-events: none; }
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.stimmen-avatar-kachel { transition: none; }
|
||||||
|
.stimmen-avatar-kachel:hover { transform: none; }
|
||||||
|
}
|
||||||
|
|
||||||
.stimmen-karte-namen { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
|
.stimmen-karte-namen { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
|
||||||
.stimmen-karte-name { font-weight: 700; color: var(--text); font-size: .95rem; }
|
.stimmen-karte-name { font-weight: 700; color: var(--text); font-size: .95rem; }
|
||||||
.stimmen-karte-tiktok {
|
.stimmen-karte-tiktok {
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/* =====================================================================
|
||||||
|
data-stimmen-avatare.js — Auswahlbilder für die "Stimmen" (21.08.2026,
|
||||||
|
Nutzer-Wunsch: "ich soll auch paar geile bilder zum aussuchen haben als
|
||||||
|
profilbild falls die leute kein bild mit schicken, das soll denen auch
|
||||||
|
als möglichkeit gegeben sein").
|
||||||
|
|
||||||
|
EINE gemeinsame Liste für beide Seiten: stimmen.html (dort wählt die
|
||||||
|
einreichende Person selbst) und verwaltung.html (dort kann Dogi/VanVan
|
||||||
|
das Bild nachträglich ändern). Getrennte Listen wären auseinander-
|
||||||
|
gelaufen, sobald irgendwann ein Bild dazukommt oder wegfällt.
|
||||||
|
|
||||||
|
Bewusst nur Figuren, Maskottchen und das Logo — KEINE echten Personen
|
||||||
|
aus dem Team. Sonst könnte sich eine fremde Person mit dem Gesicht von
|
||||||
|
Dogi, VanVan oder einem Modi als Absender darstellen.
|
||||||
|
|
||||||
|
WICHTIG: Die "id"-Werte müssen mit der Liste
|
||||||
|
ERLAUBTE_AVATARE in server-internal/routes/testimonials.js
|
||||||
|
übereinstimmen — der Server nimmt nur bekannte Ids an, damit über das
|
||||||
|
öffentliche Formular kein beliebiger Pfad eingeschleust werden kann.
|
||||||
|
===================================================================== */
|
||||||
|
/* Nutzer-Wunsch 21.08.2026: "benutz da bitte nur die originalen husky und
|
||||||
|
hasen. mach nur die zwei." -- vorher standen hier acht Bilder (zusätzlich
|
||||||
|
Husky-Kopf, zwei Kosmos-Varianten, zwei Casper-Bilder, Logo). Die beiden
|
||||||
|
Originalfiguren bleiben, der Rest ist raus. Die Bilddateien selbst wurden
|
||||||
|
NICHT gelöscht: sollten sie je wieder gebraucht werden, genügt es, die
|
||||||
|
Zeile hier (und die passende Id in ERLAUBTE_AVATARE, siehe unten) wieder
|
||||||
|
zu ergänzen. */
|
||||||
|
window.STIMMEN_AVATARE = [
|
||||||
|
{ id: "husky-hoodie", name: "DogFather-Husky", datei: "/assets/img/stimmen-avatare/stimme-husky-hoodie.png" },
|
||||||
|
{ id: "hase-hoodie", name: "HasiDog", datei: "/assets/img/stimmen-avatare/stimme-hase-hoodie.png" },
|
||||||
|
];
|
||||||
|
|
||||||
|
/* Liefert die Bilddatei zu einer gespeicherten Auswahl.
|
||||||
|
- bekannte Id -> das zugehörige Auswahlbild
|
||||||
|
- "/uploads/…" -> ein von der Verwaltung hochgeladenes eigenes Foto
|
||||||
|
(kommt als vollständige Adresse vom Server, siehe testimonials.js)
|
||||||
|
- sonst -> null, dann zeigt die Karte wie bisher den Anfangs-
|
||||||
|
buchstaben des Namens. */
|
||||||
|
window.stimmeAvatarBild = function (wert) {
|
||||||
|
if (!wert) return null;
|
||||||
|
if (/^https?:\/\//i.test(wert)) return wert;
|
||||||
|
const treffer = (window.STIMMEN_AVATARE || []).find((a) => a.id === wert);
|
||||||
|
return treffer ? treffer.datei : null;
|
||||||
|
};
|
||||||
@@ -40,6 +40,17 @@ window.I18N_PAGE = {
|
|||||||
de: "Deine Nachricht", "de-CH": "Dini Nachricht",
|
de: "Deine Nachricht", "de-CH": "Dini Nachricht",
|
||||||
en: "Your Message", fr: "Ton message", pt: "Sua mensagem",
|
en: "Your Message", fr: "Ton message", pt: "Sua mensagem",
|
||||||
},
|
},
|
||||||
|
st_form_avatar_label: {
|
||||||
|
de: "Dein Profilbild (optional)", "de-CH": "Dis Profilbild (optional)",
|
||||||
|
en: "Your profile picture (optional)", fr: "Ta photo de profil (facultatif)", pt: "Sua foto de perfil (opcional)",
|
||||||
|
},
|
||||||
|
st_form_avatar_hinweis: {
|
||||||
|
de: "Ohne Auswahl erscheint einfach der erste Buchstabe deines Namens.",
|
||||||
|
"de-CH": "Ohni Uuswahl erschiint eifach de erscht Buechstab vo dim Name.",
|
||||||
|
en: "If you don't pick one, the first letter of your name is shown instead.",
|
||||||
|
fr: "Sans choix, la première lettre de ton prénom s'affichera.",
|
||||||
|
pt: "Sem escolha, aparece apenas a primeira letra do seu nome.",
|
||||||
|
},
|
||||||
st_form_nachricht_placeholder: {
|
st_form_nachricht_placeholder: {
|
||||||
de: "Erzähl uns, was dir Team Dogi bedeutet …", "de-CH": "Verzell eus, was dir Team Dogi bedütet …",
|
de: "Erzähl uns, was dir Team Dogi bedeutet …", "de-CH": "Verzell eus, was dir Team Dogi bedütet …",
|
||||||
en: "Tell us what Team Dogi means to you …", fr: "Dis-nous ce que Team Dogi représente pour toi …", pt: "Conte-nos o que a Team Dogi significa para você …",
|
en: "Tell us what Team Dogi means to you …", fr: "Dis-nous ce que Team Dogi représente pour toi …", pt: "Conte-nos o que a Team Dogi significa para você …",
|
||||||
|
|||||||
+93
-2
@@ -9,6 +9,88 @@
|
|||||||
(function () {
|
(function () {
|
||||||
const API_BASE_URL = "https://postfach.dogfather-universe.com";
|
const API_BASE_URL = "https://postfach.dogfather-universe.com";
|
||||||
|
|
||||||
|
/* ---------- Profilbild-Auswahl (21.08.2026) ----------
|
||||||
|
Baut die Kacheln aus der gemeinsamen Liste in data-stimmen-avatare.js
|
||||||
|
auf. Bewusst echte <button>-Elemente statt <div>: so ist die Auswahl
|
||||||
|
auch mit der Tastatur bedienbar und Screenreader melden sie als
|
||||||
|
Schaltfläche. "" = bewusst kein Bild (erste Kachel). */
|
||||||
|
let gewaehlterAvatar = "";
|
||||||
|
const wahlEl = document.getElementById("stimmen-avatar-wahl");
|
||||||
|
if (wahlEl) {
|
||||||
|
const liste = window.STIMMEN_AVATARE || [];
|
||||||
|
const kachel = (id, inhalt, titel) =>
|
||||||
|
`<button type="button" class="stimmen-avatar-kachel" data-avatar="${id}" role="radio" aria-checked="false" title="${titel}" aria-label="${titel}">${inhalt}</button>`;
|
||||||
|
|
||||||
|
/* Letzte Kachel: eigenes Bild (21.08.2026, Nutzer-Wunsch "und die
|
||||||
|
auswahl wo die leute selbst ein bild rein setzen können"). Die
|
||||||
|
versteckte Datei-Auswahl liegt gleich daneben; die Kachel selbst
|
||||||
|
löst sie nur aus, damit die Optik zu den anderen Kacheln passt. */
|
||||||
|
wahlEl.innerHTML =
|
||||||
|
kachel("", `<span class="stimmen-avatar-keins" aria-hidden="true">✦</span>`, "Kein Bild") +
|
||||||
|
liste.map((a) => kachel(a.id, `<img src="${a.datei}" alt="" loading="lazy" />`, a.name)).join("") +
|
||||||
|
`<button type="button" class="stimmen-avatar-kachel stimmen-avatar-eigenes" id="stimmen-avatar-eigenes"
|
||||||
|
role="radio" aria-checked="false" title="Eigenes Bild hochladen" aria-label="Eigenes Bild hochladen">
|
||||||
|
<span class="stimmen-avatar-plus" aria-hidden="true">+</span>
|
||||||
|
</button>
|
||||||
|
<input type="file" id="stimmen-avatar-datei" accept="image/jpeg,image/png,image/webp" hidden />`;
|
||||||
|
|
||||||
|
const eigenesBtn = document.getElementById("stimmen-avatar-eigenes");
|
||||||
|
const dateiInput = document.getElementById("stimmen-avatar-datei");
|
||||||
|
let eigenesBildUrl = "";
|
||||||
|
|
||||||
|
const markiere = () => {
|
||||||
|
wahlEl.querySelectorAll(".stimmen-avatar-kachel").forEach((b) => {
|
||||||
|
// Die "eigenes Bild"-Kachel hat kein data-avatar; sie gilt als
|
||||||
|
// gewählt, wenn die aktuelle Auswahl die hochgeladene Adresse ist.
|
||||||
|
const wert = b === eigenesBtn ? eigenesBildUrl : b.dataset.avatar;
|
||||||
|
const aktiv = !!gewaehlterAvatar === !!wert && wert === gewaehlterAvatar;
|
||||||
|
b.classList.toggle("aktiv", aktiv);
|
||||||
|
b.setAttribute("aria-checked", aktiv ? "true" : "false");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
wahlEl.addEventListener("click", (e) => {
|
||||||
|
const btn = e.target.closest(".stimmen-avatar-kachel");
|
||||||
|
if (!btn) return;
|
||||||
|
if (btn === eigenesBtn) {
|
||||||
|
// Schon hochgeladen -> einfach wieder auswählen, sonst Dateidialog.
|
||||||
|
if (eigenesBildUrl) { gewaehlterAvatar = eigenesBildUrl; markiere(); }
|
||||||
|
else dateiInput.click();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gewaehlterAvatar = btn.dataset.avatar;
|
||||||
|
markiere();
|
||||||
|
});
|
||||||
|
|
||||||
|
dateiInput.addEventListener("change", async () => {
|
||||||
|
const datei = dateiInput.files && dateiInput.files[0];
|
||||||
|
if (!datei) return;
|
||||||
|
const fehlerEl = document.getElementById("stimmen-fehler");
|
||||||
|
eigenesBtn.classList.add("laedt");
|
||||||
|
try {
|
||||||
|
const form = new FormData();
|
||||||
|
form.append("image", datei);
|
||||||
|
const res = await fetch(`${API_BASE_URL}/testimonials/upload-avatar`, { method: "POST", body: form });
|
||||||
|
const data = await res.json();
|
||||||
|
if (!data.ok) {
|
||||||
|
if (fehlerEl) { fehlerEl.textContent = data.error || "Das Bild konnte nicht hochgeladen werden."; fehlerEl.classList.add("zeige"); }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
eigenesBildUrl = data.url;
|
||||||
|
gewaehlterAvatar = data.url;
|
||||||
|
eigenesBtn.innerHTML = `<img src="${data.url}" alt="" />`;
|
||||||
|
markiere();
|
||||||
|
} catch {
|
||||||
|
if (fehlerEl) { fehlerEl.textContent = "Das Bild konnte nicht hochgeladen werden (keine Verbindung)."; fehlerEl.classList.add("zeige"); }
|
||||||
|
} finally {
|
||||||
|
eigenesBtn.classList.remove("laedt");
|
||||||
|
dateiInput.value = ""; // erlaubt, dieselbe Datei erneut zu wählen
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
markiere();
|
||||||
|
}
|
||||||
|
|
||||||
const formular = document.getElementById("stimmen-formular");
|
const formular = document.getElementById("stimmen-formular");
|
||||||
if (formular) {
|
if (formular) {
|
||||||
const erfolgEl = document.getElementById("stimmen-erfolg");
|
const erfolgEl = document.getElementById("stimmen-erfolg");
|
||||||
@@ -28,7 +110,7 @@
|
|||||||
const res = await fetch(`${API_BASE_URL}/testimonials/submit`, {
|
const res = await fetch(`${API_BASE_URL}/testimonials/submit`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ name, tiktokUsername, nachricht }),
|
body: JSON.stringify({ name, tiktokUsername, nachricht, avatar: gewaehlterAvatar || null }),
|
||||||
});
|
});
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
if (!data.ok) {
|
if (!data.ok) {
|
||||||
@@ -74,7 +156,16 @@
|
|||||||
(t) => `<div class="stimmen-karte">
|
(t) => `<div class="stimmen-karte">
|
||||||
<p class="stimmen-karte-text">${escapeHtml(t.nachricht)}</p>
|
<p class="stimmen-karte-text">${escapeHtml(t.nachricht)}</p>
|
||||||
<div class="stimmen-karte-fuss">
|
<div class="stimmen-karte-fuss">
|
||||||
<span class="stimmen-karte-avatar" aria-hidden="true">${escapeHtml(erstesZeichen(t.name))}</span>
|
${
|
||||||
|
/* Gewähltes Bild, sonst wie bisher der Anfangsbuchstabe.
|
||||||
|
escapeHtml auch auf der Bildadresse: sie stammt zwar aus
|
||||||
|
unserer eigenen Liste bzw. vom Server, aber sie landet
|
||||||
|
hier in einem HTML-Attribut — da gehört sie grundsätzlich
|
||||||
|
entschärft, unabhängig von der Herkunft. */
|
||||||
|
(window.stimmeAvatarBild && window.stimmeAvatarBild(t.avatar))
|
||||||
|
? `<span class="stimmen-karte-avatar stimmen-karte-avatar-bild" aria-hidden="true"><img src="${escapeHtml(window.stimmeAvatarBild(t.avatar))}" alt="" loading="lazy" /></span>`
|
||||||
|
: `<span class="stimmen-karte-avatar" aria-hidden="true">${escapeHtml(erstesZeichen(t.name))}</span>`
|
||||||
|
}
|
||||||
<span class="stimmen-karte-namen">
|
<span class="stimmen-karte-namen">
|
||||||
<span class="stimmen-karte-name">${escapeHtml(t.name)}</span>
|
<span class="stimmen-karte-name">${escapeHtml(t.name)}</span>
|
||||||
${t.tiktokUsername ? `<span class="stimmen-karte-tiktok">@${escapeHtml(t.tiktokUsername)}</span>` : ""}
|
${t.tiktokUsername ? `<span class="stimmen-karte-tiktok">@${escapeHtml(t.tiktokUsername)}</span>` : ""}
|
||||||
|
|||||||
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Du bist Streamer und suchst einen Manager? Bewirb dich als Creator bei Spicy Media." />
|
<meta name="twitter:description" content="Du bist Streamer und suchst einen Manager? Bewirb dich als Creator bei Spicy Media." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund bewerben-seite" style="--page-bg:url('/assets/img/bg-bewerben-creator.jpg');--page-bg-mobile:url('/assets/img/bg-bewerben-creator-mobile.jpg');">
|
<body class="mit-hintergrund bewerben-seite" style="--page-bg:url('/assets/img/bg-bewerben-creator.jpg');--page-bg-mobile:url('/assets/img/bg-bewerben-creator-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -70,8 +70,8 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/forms.js?v=20260821p"></script>
|
<script src="assets/js/forms.js?v=20260821q"></script>
|
||||||
<script src="assets/js/i18n-bewerben-creator.js?v=20260821p"></script>
|
<script src="assets/js/i18n-bewerben-creator.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -22,10 +22,10 @@
|
|||||||
<meta name="twitter:description" content="Kooperationsanfrage an Manager DogFather / Spicy Media." />
|
<meta name="twitter:description" content="Kooperationsanfrage an Manager DogFather / Spicy Media." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund bewerben-seite" style="--page-bg:url('/assets/img/bg-bewerben.jpg');--page-bg-mobile:url('/assets/img/bg-bewerben-mobile.jpg');">
|
<body class="mit-hintergrund bewerben-seite" style="--page-bg:url('/assets/img/bg-bewerben.jpg');--page-bg-mobile:url('/assets/img/bg-bewerben-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -68,8 +68,8 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/forms.js?v=20260821p"></script>
|
<script src="assets/js/forms.js?v=20260821q"></script>
|
||||||
<script src="assets/js/i18n-bewerben-kooperation.js?v=20260821p"></script>
|
<script src="assets/js/i18n-bewerben-kooperation.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+7
-7
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Werde Modi bei Team Dogi — DogFathers persönliches Community-Team." />
|
<meta name="twitter:description" content="Werde Modi bei Team Dogi — DogFathers persönliches Community-Team." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund bewerben-seite" style="--page-bg:url('/assets/img/bg-bewerben-modi.jpg');--page-bg-mobile:url('/assets/img/bg-bewerben-modi-mobile.jpg');">
|
<body class="mit-hintergrund bewerben-seite" style="--page-bg:url('/assets/img/bg-bewerben-modi.jpg');--page-bg-mobile:url('/assets/img/bg-bewerben-modi-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -79,8 +79,8 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/forms.js?v=20260821p"></script>
|
<script src="assets/js/forms.js?v=20260821q"></script>
|
||||||
<script src="assets/js/i18n-bewerben-modi.js?v=20260821p"></script>
|
<script src="assets/js/i18n-bewerben-modi.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+7
-7
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Werde Scout für DogFather bei der Spicy Media Agentur — finde neue Talente." />
|
<meta name="twitter:description" content="Werde Scout für DogFather bei der Spicy Media Agentur — finde neue Talente." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund bewerben-seite" style="--page-bg:url('/assets/img/bg-bewerben-scout.jpg');--page-bg-mobile:url('/assets/img/bg-bewerben-scout-mobile.jpg');">
|
<body class="mit-hintergrund bewerben-seite" style="--page-bg:url('/assets/img/bg-bewerben-scout.jpg');--page-bg-mobile:url('/assets/img/bg-bewerben-scout-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -71,8 +71,8 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/forms.js?v=20260821p"></script>
|
<script src="assets/js/forms.js?v=20260821q"></script>
|
||||||
<script src="assets/js/i18n-bewerben-scout.js?v=20260821p"></script>
|
<script src="assets/js/i18n-bewerben-scout.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+6
-6
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Werde Teil vom Team: Modi bei Team Dogi, Scout oder Creator bei Spicy Media, oder Kooperation anfragen." />
|
<meta name="twitter:description" content="Werde Teil vom Team: Modi bei Team Dogi, Scout oder Creator bei Spicy Media, oder Kooperation anfragen." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund bewerben-seite" style="--page-bg:url('/assets/img/bg-bewerben-split.jpg');--page-bg-mobile:url('/assets/img/bg-bewerben-split-mobile.jpg');">
|
<body class="mit-hintergrund bewerben-seite" style="--page-bg:url('/assets/img/bg-bewerben-split.jpg');--page-bg-mobile:url('/assets/img/bg-bewerben-split-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-bewerben.js?v=20260821p"></script>
|
<script src="assets/js/i18n-bewerben.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+6
-6
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Der Husky an DogFathers Seite — das tierische Gesicht der HasiDog-Welt." />
|
<meta name="twitter:description" content="Der Husky an DogFathers Seite — das tierische Gesicht der HasiDog-Welt." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-casper.jpg');--page-bg-mobile:url('/assets/img/bg-casper-mobile.jpg');">
|
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-casper.jpg');--page-bg-mobile:url('/assets/img/bg-casper-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-casper.js?v=20260821p"></script>
|
<script src="assets/js/i18n-casper.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+6
-6
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Team Dogi ist Familie — die Community rund um DogFather und HasiDog." />
|
<meta name="twitter:description" content="Team Dogi ist Familie — die Community rund um DogFather und HasiDog." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-community.jpg');--page-bg-mobile:url('/assets/img/bg-community-mobile.jpg');">
|
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-community.jpg');--page-bg-mobile:url('/assets/img/bg-community-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-community.js?v=20260821p"></script>
|
<script src="assets/js/i18n-community.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+7
-7
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Content Creator, die Teil von DogFather / Spicy Media sind." />
|
<meta name="twitter:description" content="Content Creator, die Teil von DogFather / Spicy Media sind." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-creator.jpg');--page-bg-mobile:url('/assets/img/bg-creator-mobile.jpg');">
|
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-creator.jpg');--page-bg-mobile:url('/assets/img/bg-creator-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -60,9 +60,9 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/data-creator.js?v=20260821p"></script>
|
<script src="assets/js/data-creator.js?v=20260821q"></script>
|
||||||
<script src="assets/js/i18n-creator.js?v=20260821p"></script>
|
<script src="assets/js/i18n-creator.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", async () => {
|
document.addEventListener("DOMContentLoaded", async () => {
|
||||||
const grid = document.getElementById("creator-grid");
|
const grid = document.getElementById("creator-grid");
|
||||||
|
|||||||
+6
-6
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Wer ist DogFather wirklich? Persönlichkeit, Werte und die Geschichte hinter dem Content." />
|
<meta name="twitter:description" content="Wer ist DogFather wirklich? Persönlichkeit, Werte und die Geschichte hinter dem Content." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-dogfather-person.jpg');--page-bg-mobile:url('/assets/img/bg-dogfather-person-mobile.jpg');">
|
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-dogfather-person.jpg');--page-bg-mobile:url('/assets/img/bg-dogfather-person-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -158,7 +158,7 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-dogfather.js?v=20260821p"></script>
|
<script src="assets/js/i18n-dogfather.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -26,8 +26,8 @@
|
|||||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
<meta name="apple-mobile-web-app-title" content="DogFather" />
|
<meta name="apple-mobile-web-app-title" content="DogFather" />
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<style>
|
<style>
|
||||||
/* =====================================================================
|
/* =====================================================================
|
||||||
Zugangsseite — bewusst kein braves Standard-Login-Formular, sondern
|
Zugangsseite — bewusst kein braves Standard-Login-Formular, sondern
|
||||||
@@ -222,6 +222,25 @@
|
|||||||
background: linear-gradient(120deg, #ff8fc6 0%, #c084fc 30%, #ffd76a 55%, #ff8fc6 80%, #c084fc 100%);
|
background: linear-gradient(120deg, #ff8fc6 0%, #c084fc 30%, #ffd76a 55%, #ff8fc6 80%, #c084fc 100%);
|
||||||
background-size: 340% 340%;
|
background-size: 340% 340%;
|
||||||
}
|
}
|
||||||
|
/* Dienes Kachel (21.08.2026, Nutzer-Wunsch: "mach eine 3 Zugangskiste ...
|
||||||
|
ich will nämlich dass Diene schon jetzt auch die Seite sieht, damit wir
|
||||||
|
mit mehreren Augen die letzten kleinen Details verbessern"). Wieder eine
|
||||||
|
EIGENE Farbwelt (Smaragd/Mint/Gold) statt einer Umfärbung der beiden
|
||||||
|
anderen -- so ist auf einen Blick klar, welche Kachel wem gehört. */
|
||||||
|
.gate-card--diene {
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, rgba(13,24,20,.92), rgba(8,15,13,.96)) padding-box,
|
||||||
|
linear-gradient(110deg, #6ee7b7, #34d399, #d4af37, #6ee7b7) border-box;
|
||||||
|
box-shadow: 0 30px 70px -25px rgba(0,0,0,.75), 0 0 50px -20px rgba(52,211,153,.35);
|
||||||
|
}
|
||||||
|
.gate-card-icon--diene { background-image: url('assets/img/avatar-diene.jpg'); }
|
||||||
|
.gate-card--diene .gate-card-icon { border-color: rgba(110,231,183,.65); }
|
||||||
|
.gate-card--diene .gate-card-name { color: #c7f5e3; }
|
||||||
|
.gate-card--diene input:focus { border-color: rgba(52,211,153,.7); box-shadow: 0 0 0 4px rgba(52,211,153,.16); }
|
||||||
|
.gate-card-btn--diene {
|
||||||
|
background: linear-gradient(120deg, #6ee7b7 0%, #34d399 30%, #ffd76a 55%, #6ee7b7 80%, #34d399 100%);
|
||||||
|
background-size: 340% 340%;
|
||||||
|
}
|
||||||
.gate-card .gate-fehler { margin-top: .7rem; }
|
.gate-card .gate-fehler { margin-top: .7rem; }
|
||||||
@media (max-width: 480px) {
|
@media (max-width: 480px) {
|
||||||
.gate-cards { flex-direction: column; align-items: center; }
|
.gate-cards { flex-direction: column; align-items: center; }
|
||||||
@@ -275,6 +294,16 @@
|
|||||||
</button>
|
</button>
|
||||||
<p class="gate-fehler" id="gate-fehler-vanvan"></p>
|
<p class="gate-fehler" id="gate-fehler-vanvan"></p>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<form id="gate-form-diene" class="gate-card gate-card--diene" novalidate>
|
||||||
|
<span class="gate-card-icon gate-card-icon--diene" aria-hidden="true"></span>
|
||||||
|
<h2 class="gate-card-name">Diene</h2>
|
||||||
|
<input type="text" id="gate-code-diene" placeholder="Zugangscode" autocomplete="off" autocapitalize="off" spellcheck="false" />
|
||||||
|
<button type="submit" class="btn-holo gate-card-btn gate-card-btn--diene">
|
||||||
|
<span class="btn-holo-text">💚 Öffnen</span>
|
||||||
|
</button>
|
||||||
|
<p class="gate-fehler" id="gate-fehler-diene"></p>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -374,6 +403,7 @@
|
|||||||
}
|
}
|
||||||
bindeGateKachel("gate-form-dogi", "gate-code-dogi", "gate-fehler-dogi");
|
bindeGateKachel("gate-form-dogi", "gate-code-dogi", "gate-fehler-dogi");
|
||||||
bindeGateKachel("gate-form-vanvan", "gate-code-vanvan", "gate-fehler-vanvan");
|
bindeGateKachel("gate-form-vanvan", "gate-code-vanvan", "gate-fehler-vanvan");
|
||||||
|
bindeGateKachel("gate-form-diene", "gate-code-diene", "gate-fehler-diene");
|
||||||
|
|
||||||
/* Service-Worker-Registrierung — auf allen anderen Seiten macht das main.js, diese Seite
|
/* Service-Worker-Registrierung — auf allen anderen Seiten macht das main.js, diese Seite
|
||||||
ist aber bewusst eigenstaendig und laedt main.js nicht. Ohne registrierten Service
|
ist aber bewusst eigenstaendig und laedt main.js nicht. Ohne registrierten Service
|
||||||
|
|||||||
+6
-6
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="HasiDog: Maskottchen, Musikprojekt und die verspielte, familiäre Seite von Team Dogi." />
|
<meta name="twitter:description" content="HasiDog: Maskottchen, Musikprojekt und die verspielte, familiäre Seite von Team Dogi." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-hasidog.jpg');--page-bg-mobile:url('/assets/img/bg-hasidog-mobile.jpg');">
|
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-hasidog.jpg');--page-bg-mobile:url('/assets/img/bg-hasidog-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -186,7 +186,7 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-hasidog.js?v=20260821p"></script>
|
<script src="assets/js/i18n-hasidog.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+8
-8
@@ -19,10 +19,10 @@
|
|||||||
<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: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" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="start-seite">
|
<body class="start-seite">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -290,10 +290,10 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/data-modis.js?v=20260821p"></script>
|
<script src="assets/js/data-modis.js?v=20260821q"></script>
|
||||||
<script src="assets/js/data-scouts.js?v=20260821p"></script>
|
<script src="assets/js/data-scouts.js?v=20260821q"></script>
|
||||||
<script src="assets/js/i18n-index.js?v=20260821p"></script>
|
<script src="assets/js/i18n-index.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
<script>
|
<script>
|
||||||
// Gleiche URL wie in assets/js/forms.js / postfach.html — läuft seit
|
// Gleiche URL wie in assets/js/forms.js / postfach.html — läuft seit
|
||||||
// 05.08.2026 auf dem eigenen Server statt auf Cloudflare Workers.
|
// 05.08.2026 auf dem eigenen Server statt auf Cloudflare Workers.
|
||||||
|
|||||||
+6
-6
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Kontakt, Impressum und Datenschutz von DOGFATHER UNIVERSE." />
|
<meta name="twitter:description" content="Kontakt, Impressum und Datenschutz von DOGFATHER UNIVERSE." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -126,7 +126,7 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-kontakt.js?v=20260821p"></script>
|
<script src="assets/js/i18n-kontakt.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+6
-6
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Alle Social-Media- und Musik-Links von DogFather an einem Ort — plus QR-Codes." />
|
<meta name="twitter:description" content="Alle Social-Media- und Musik-Links von DogFather an einem Ort — plus QR-Codes." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
<style>
|
<style>
|
||||||
/* Rabattcodes: an das Supporter-Abo gekoppelt (Nutzer-Feedback
|
/* Rabattcodes: an das Supporter-Abo gekoppelt (Nutzer-Feedback
|
||||||
03.08.2026: "verbinde es mit dem Abo... wenn die Leute drauf drücken
|
03.08.2026: "verbinde es mit dem Abo... wenn die Leute drauf drücken
|
||||||
@@ -140,8 +140,8 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-links.js?v=20260821p"></script>
|
<script src="assets/js/i18n-links.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
|||||||
+7
-7
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="DogFather als Manager bei der Spicy Media Agency: Scouts, Creator und faire Zusammenarbeit." />
|
<meta name="twitter:description" content="DogFather als Manager bei der Spicy Media Agency: Scouts, Creator und faire Zusammenarbeit." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-manager.jpg');--page-bg-mobile:url('/assets/img/bg-manager-mobile.jpg');">
|
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-manager.jpg');--page-bg-mobile:url('/assets/img/bg-manager-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -139,9 +139,9 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/data-manager.js?v=20260821p"></script>
|
<script src="assets/js/data-manager.js?v=20260821q"></script>
|
||||||
<script src="assets/js/i18n-manager.js?v=20260821p"></script>
|
<script src="assets/js/i18n-manager.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
<script>
|
<script>
|
||||||
// "Weitere Manager" (21.08.2026) -- siehe Kommentar bei #weitere-manager-root
|
// "Weitere Manager" (21.08.2026) -- siehe Kommentar bei #weitere-manager-root
|
||||||
// oben. Aktuell IMMER window.MANAGERS === [] (siehe data-manager.js), Inhalt
|
// oben. Aktuell IMMER window.MANAGERS === [] (siehe data-manager.js), Inhalt
|
||||||
|
|||||||
+9
-9
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Fotos und Videos rund um Husky Casper an einem Ort." />
|
<meta name="twitter:description" content="Fotos und Videos rund um Husky Casper an einem Ort." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund" data-welt="casper" style="--page-bg:url('/assets/img/bg-medien-casper.jpg');--page-bg-mobile:url('/assets/img/bg-medien-casper-mobile.jpg');">
|
<body class="mit-hintergrund" data-welt="casper" style="--page-bg:url('/assets/img/bg-medien-casper.jpg');--page-bg-mobile:url('/assets/img/bg-medien-casper-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -59,10 +59,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/data-media.js?v=20260821p"></script>
|
<script src="assets/js/data-media.js?v=20260821q"></script>
|
||||||
<script src="assets/js/data-videos.js?v=20260821p"></script>
|
<script src="assets/js/data-videos.js?v=20260821q"></script>
|
||||||
<script src="assets/js/medien-welt.js?v=20260821p"></script>
|
<script src="assets/js/medien-welt.js?v=20260821q"></script>
|
||||||
<script src="assets/js/i18n-medien-casper.js?v=20260821p"></script>
|
<script src="assets/js/i18n-medien-casper.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+10
-10
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Fotos, Videos und Events aus DogFathers Welt an einem Ort." />
|
<meta name="twitter:description" content="Fotos, Videos und Events aus DogFathers Welt an einem Ort." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund" data-welt="dogfather" style="--page-bg:url('/assets/img/bg-dogfather.jpg');--page-bg-mobile:url('/assets/img/bg-dogfather-mobile.jpg');">
|
<body class="mit-hintergrund" data-welt="dogfather" style="--page-bg:url('/assets/img/bg-dogfather.jpg');--page-bg-mobile:url('/assets/img/bg-dogfather-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -65,11 +65,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/data-media.js?v=20260821p"></script>
|
<script src="assets/js/data-media.js?v=20260821q"></script>
|
||||||
<script src="assets/js/data-videos.js?v=20260821p"></script>
|
<script src="assets/js/data-videos.js?v=20260821q"></script>
|
||||||
<script src="assets/js/data-aktionen.js?v=20260821p"></script>
|
<script src="assets/js/data-aktionen.js?v=20260821q"></script>
|
||||||
<script src="assets/js/medien-welt.js?v=20260821p"></script>
|
<script src="assets/js/medien-welt.js?v=20260821q"></script>
|
||||||
<script src="assets/js/i18n-medien-dogfather.js?v=20260821p"></script>
|
<script src="assets/js/i18n-medien-dogfather.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+10
-10
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Fotos, Videos und Events aus der HasiDog-Welt an einem Ort." />
|
<meta name="twitter:description" content="Fotos, Videos und Events aus der HasiDog-Welt an einem Ort." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund" data-welt="hasidog" style="--page-bg:url('/assets/img/bg-medien-hasidog.jpg');--page-bg-mobile:url('/assets/img/bg-medien-hasidog-mobile.jpg');">
|
<body class="mit-hintergrund" data-welt="hasidog" style="--page-bg:url('/assets/img/bg-medien-hasidog.jpg');--page-bg-mobile:url('/assets/img/bg-medien-hasidog-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -65,11 +65,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/data-media.js?v=20260821p"></script>
|
<script src="assets/js/data-media.js?v=20260821q"></script>
|
||||||
<script src="assets/js/data-videos.js?v=20260821p"></script>
|
<script src="assets/js/data-videos.js?v=20260821q"></script>
|
||||||
<script src="assets/js/data-aktionen.js?v=20260821p"></script>
|
<script src="assets/js/data-aktionen.js?v=20260821q"></script>
|
||||||
<script src="assets/js/medien-welt.js?v=20260821p"></script>
|
<script src="assets/js/medien-welt.js?v=20260821q"></script>
|
||||||
<script src="assets/js/i18n-medien-hasidog.js?v=20260821p"></script>
|
<script src="assets/js/i18n-medien-hasidog.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+10
-10
@@ -16,10 +16,10 @@
|
|||||||
<meta name="twitter:card" content="summary_large_image" />
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
<meta name="robots" content="noindex" /> <!-- generische URL, echte Team-Seiten verlinken hierher -->
|
<meta name="robots" content="noindex" /> <!-- generische URL, echte Team-Seiten verlinken hierher -->
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
<style>
|
<style>
|
||||||
.profil-photo { aspect-ratio: 4/5; max-width: 420px; margin: 0 auto; }
|
.profil-photo { aspect-ratio: 4/5; max-width: 420px; margin: 0 auto; }
|
||||||
.profil-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
.profil-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
||||||
@@ -130,12 +130,12 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/data-modis.js?v=20260821p"></script>
|
<script src="assets/js/data-modis.js?v=20260821q"></script>
|
||||||
<script src="assets/js/data-scouts.js?v=20260821p"></script>
|
<script src="assets/js/data-scouts.js?v=20260821q"></script>
|
||||||
<script src="assets/js/data-creator.js?v=20260821p"></script>
|
<script src="assets/js/data-creator.js?v=20260821q"></script>
|
||||||
<script src="assets/js/data-manager.js?v=20260821p"></script>
|
<script src="assets/js/data-manager.js?v=20260821q"></script>
|
||||||
<script src="assets/js/i18n-profil.js?v=20260821p"></script>
|
<script src="assets/js/i18n-profil.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", async () => {
|
document.addEventListener("DOMContentLoaded", async () => {
|
||||||
const slug = new URLSearchParams(location.search).get("p") || "";
|
const slug = new URLSearchParams(location.search).get("p") || "";
|
||||||
|
|||||||
+6
-6
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Rabattcodes von Dogis Partnern für Team Dogi — spar bares Geld bei ausgewählten Marken." />
|
<meta name="twitter:description" content="Rabattcodes von Dogis Partnern für Team Dogi — spar bares Geld bei ausgewählten Marken." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
<style>
|
<style>
|
||||||
/* Leere-Zustand-Kachel im "Gutschein"-Look: gestrichelter Rand wie ein
|
/* Leere-Zustand-Kachel im "Gutschein"-Look: gestrichelter Rand wie ein
|
||||||
ausgeschnittener Coupon, damit auch OHNE echte Codes schon klar ist,
|
ausgeschnittener Coupon, damit auch OHNE echte Codes schon klar ist,
|
||||||
@@ -131,8 +131,8 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-rabattcodes.js?v=20260821p"></script>
|
<script src="assets/js/i18n-rabattcodes.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ import { getEventsPublic, getEventsAdmin, saveEvent, uploadEventImage } from "./
|
|||||||
import { getSpecialEventPublic, getSpecialEventAdmin, saveSpecialEvent } from "./routes/special-event.js";
|
import { getSpecialEventPublic, getSpecialEventAdmin, saveSpecialEvent } from "./routes/special-event.js";
|
||||||
import {
|
import {
|
||||||
submitTestimonial, getApprovedTestimonialsPublic, getTestimonialsAdmin, setTestimonialStatus, deleteTestimonial,
|
submitTestimonial, getApprovedTestimonialsPublic, getTestimonialsAdmin, setTestimonialStatus, deleteTestimonial,
|
||||||
|
uploadEigenesTestimonialBild,
|
||||||
setTestimonialAvatar, uploadTestimonialAvatar,
|
setTestimonialAvatar, uploadTestimonialAvatar,
|
||||||
} from "./routes/testimonials.js";
|
} from "./routes/testimonials.js";
|
||||||
import {
|
import {
|
||||||
@@ -195,6 +196,14 @@ app.post("/auth/login", wrap(login));
|
|||||||
app.get("/events-of-year", wrap(getEventsPublic));
|
app.get("/events-of-year", wrap(getEventsPublic));
|
||||||
app.get("/special-event", wrap(getSpecialEventPublic));
|
app.get("/special-event", wrap(getSpecialEventPublic));
|
||||||
app.post("/testimonials/submit", wrap(submitTestimonial));
|
app.post("/testimonials/submit", wrap(submitTestimonial));
|
||||||
|
/* Öffentlich, ohne Login: eigenes Profilbild für die eigene Stimme
|
||||||
|
hochladen (21.08.2026). Bewusst mit derselben multer-Härtung wie der
|
||||||
|
Verwaltungs-Upload (nur JPG/PNG/WebP, max. 5 MB, zufälliger Dateiname);
|
||||||
|
zusätzlich bremst die Route selbst Massen-Uploads pro IP aus (siehe
|
||||||
|
uploadEigenesTestimonialBild in routes/testimonials.js). Sichtbar wird
|
||||||
|
ein hochgeladenes Bild erst, wenn die zugehörige Stimme freigegeben
|
||||||
|
wird -- Einreichungen landen immer zuerst in der Warteschlange. */
|
||||||
|
app.post("/testimonials/upload-avatar", stimmenBildUpload.single("image"), wrap(uploadEigenesTestimonialBild));
|
||||||
app.get("/testimonials", wrap(getApprovedTestimonialsPublic));
|
app.get("/testimonials", wrap(getApprovedTestimonialsPublic));
|
||||||
app.get("/team", wrap(getTeamPublic));
|
app.get("/team", wrap(getTeamPublic));
|
||||||
app.get("/site-texts", wrap(getSiteTextsPublic));
|
app.get("/site-texts", wrap(getSiteTextsPublic));
|
||||||
|
|||||||
@@ -36,10 +36,65 @@ function forbidden(res) {
|
|||||||
Adresse oder etwas, das später als HTML/Adresse ausgewertet wird) und so
|
Adresse oder etwas, das später als HTML/Adresse ausgewertet wird) und so
|
||||||
auf einer freigegebenen Stimme fremde Inhalte einbetten. Es werden
|
auf einer freigegebenen Stimme fremde Inhalte einbetten. Es werden
|
||||||
deshalb ausschließlich diese festen Ids angenommen. */
|
deshalb ausschließlich diese festen Ids angenommen. */
|
||||||
const ERLAUBTE_AVATARE = [
|
/* 21.08.2026 auf die zwei Originalfiguren reduziert (Nutzer-Wunsch, siehe
|
||||||
"husky-hoodie", "hase-hoodie", "husky-kopf", "husky-kosmos",
|
data-stimmen-avatare.js). Muss mit der Liste dort übereinstimmen.
|
||||||
"hase-kosmos", "casper", "casper-blick", "logo",
|
Bereits freigegebene Stimmen mit einem der entfernten Bilder behalten
|
||||||
];
|
ihren Eintrag in der Datenbank -- sie zeigen dann wieder den
|
||||||
|
Anfangsbuchstaben, weil stimmeAvatarBild() die Id nicht mehr auflöst
|
||||||
|
(siehe dort: unbekannt -> null -> Buchstaben-Medaillon). Kein Fehler,
|
||||||
|
keine kaputten Bilder. */
|
||||||
|
const ERLAUBTE_AVATARE = ["husky-hoodie", "hase-hoodie"];
|
||||||
|
|
||||||
|
/* Eigenes hochgeladenes Bild (21.08.2026, Nutzer-Wunsch: "und die auswahl
|
||||||
|
wo die leute selbst ein bild rein setzen können").
|
||||||
|
|
||||||
|
Akzeptiert wird ausschließlich eine Adresse, die exakt auf unseren
|
||||||
|
eigenen Upload-Ordner zeigt und danach nur noch aus einem zufälligen
|
||||||
|
Dateinamen besteht (UUID + Endung, so legt multer sie an, siehe
|
||||||
|
index.js). Damit kann über dieses Feld weder eine fremde Adresse
|
||||||
|
eingeschleust noch per "../" aus dem Ordner ausgebrochen werden --
|
||||||
|
dieselbe Schutzabsicht wie bei der festen Id-Liste oben. */
|
||||||
|
const UPLOAD_BASIS = "https://postfach.dogfather-universe.com/uploads/testimonials/";
|
||||||
|
function istEigenesHochgeladenesBild(wert) {
|
||||||
|
if (!wert.startsWith(UPLOAD_BASIS)) return false;
|
||||||
|
const datei = wert.slice(UPLOAD_BASIS.length);
|
||||||
|
return /^[a-f0-9-]{36}\.(jpe?g|png|webp)$/i.test(datei);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Einfache Missbrauchsbremse für den öffentlichen Bild-Upload (kein Login
|
||||||
|
nötig). Ohne sie könnte jemand den Endpunkt in einer Schleife aufrufen
|
||||||
|
und die Festplatte des Servers vollschreiben. Bewusst schlicht im
|
||||||
|
Arbeitsspeicher gehalten: es gibt hier nur einen Serverprozess, und ein
|
||||||
|
Neustart (der den Zähler leert) ist kein Schaden. */
|
||||||
|
const UPLOAD_MAX_PRO_STUNDE = 10;
|
||||||
|
const uploadZaehler = new Map(); // ip -> { anzahl, fensterStart }
|
||||||
|
function uploadKontingentFrei(ip) {
|
||||||
|
const jetzt = Date.now();
|
||||||
|
const eintrag = uploadZaehler.get(ip);
|
||||||
|
if (!eintrag || jetzt - eintrag.fensterStart > 60 * 60 * 1000) {
|
||||||
|
uploadZaehler.set(ip, { anzahl: 1, fensterStart: jetzt });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (eintrag.anzahl >= UPLOAD_MAX_PRO_STUNDE) return false;
|
||||||
|
eintrag.anzahl += 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Öffentlich (ohne Login): Profilbild für die eigene Einreichung hochladen.
|
||||||
|
Die Datei ist danach zwar unter ihrer zufälligen Adresse abrufbar, taucht
|
||||||
|
aber NIRGENDS auf, solange Dogi/VanVan die zugehörige Stimme nicht
|
||||||
|
freigeben -- jede Einreichung geht zuerst in die Warteschlange. Typ und
|
||||||
|
Größe begrenzt multer (nur JPG/PNG/WebP, max. 5 MB, zufälliger Name). */
|
||||||
|
export async function uploadEigenesTestimonialBild(req, res) {
|
||||||
|
const ip = req.ip || req.socket?.remoteAddress || "unbekannt";
|
||||||
|
if (!uploadKontingentFrei(ip)) {
|
||||||
|
return json(res, { ok: false, error: "Zu viele Uploads in kurzer Zeit. Bitte versuch es später nochmal." }, 429);
|
||||||
|
}
|
||||||
|
if (!req.file) return json(res, { ok: false, error: "Keine Bilddatei erhalten." }, 400);
|
||||||
|
const url = `${UPLOAD_BASIS}${req.file.filename}`;
|
||||||
|
logAction("anonym", "testimonial.eigenes_bild_hochgeladen", req.file.filename, null);
|
||||||
|
return json(res, { ok: true, url });
|
||||||
|
}
|
||||||
|
|
||||||
function oeffentlichesFeld(row) {
|
function oeffentlichesFeld(row) {
|
||||||
return {
|
return {
|
||||||
@@ -83,7 +138,7 @@ export async function submitTestimonial(req, res) {
|
|||||||
// (statt die Einreichung abzulehnen) — die Nachricht ist das Wichtige,
|
// (statt die Einreichung abzulehnen) — die Nachricht ist das Wichtige,
|
||||||
// und ein fehlendes Bild ist kein Grund, jemanden abzuweisen.
|
// und ein fehlendes Bild ist kein Grund, jemanden abzuweisen.
|
||||||
const gewaehlt = String(body.avatar || "").trim();
|
const gewaehlt = String(body.avatar || "").trim();
|
||||||
const avatar = ERLAUBTE_AVATARE.includes(gewaehlt) ? gewaehlt : null;
|
const avatar = ERLAUBTE_AVATARE.includes(gewaehlt) || istEigenesHochgeladenesBild(gewaehlt) ? gewaehlt : null;
|
||||||
|
|
||||||
const id = generateId();
|
const id = generateId();
|
||||||
db.prepare(
|
db.prepare(
|
||||||
|
|||||||
+7
-1
@@ -194,6 +194,12 @@ export async function gateAuthHandler(req, res) {
|
|||||||
let role = null;
|
let role = null;
|
||||||
if (process.env.SITE_ACCESS_CODE_DOGI && timingSafeEqual(code, process.env.SITE_ACCESS_CODE_DOGI)) role = "dogi";
|
if (process.env.SITE_ACCESS_CODE_DOGI && timingSafeEqual(code, process.env.SITE_ACCESS_CODE_DOGI)) role = "dogi";
|
||||||
else if (process.env.SITE_ACCESS_CODE_VANVAN && timingSafeEqual(code, process.env.SITE_ACCESS_CODE_VANVAN)) role = "vanvan";
|
else if (process.env.SITE_ACCESS_CODE_VANVAN && timingSafeEqual(code, process.env.SITE_ACCESS_CODE_VANVAN)) role = "vanvan";
|
||||||
|
// Dritter Zugang, 21.08.2026 (Nutzer-Wunsch: "ich will nämlich dass Diene
|
||||||
|
// schon jetzt auch die Seite sieht, damit wir mit mehreren Augen die
|
||||||
|
// letzten kleinen Details verbessern"). Eigener Code + eigene Rolle statt
|
||||||
|
// Weitergabe eines bestehenden Codes -- so lässt sich der Zugang später
|
||||||
|
// einzeln wieder entziehen, ohne Dogi oder VanVan auszusperren.
|
||||||
|
else if (process.env.SITE_ACCESS_CODE_DIENE && timingSafeEqual(code, process.env.SITE_ACCESS_CODE_DIENE)) role = "diene";
|
||||||
|
|
||||||
if (!role) {
|
if (!role) {
|
||||||
recordGateFailedAttempt(clientKey);
|
recordGateFailedAttempt(clientKey);
|
||||||
@@ -211,7 +217,7 @@ export async function gateAuthHandler(req, res) {
|
|||||||
export function gateMiddleware(req, res, next) {
|
export function gateMiddleware(req, res, next) {
|
||||||
const pfad = req.path;
|
const pfad = req.path;
|
||||||
|
|
||||||
const codesKonfiguriert = !!(process.env.SITE_ACCESS_SECRET && (process.env.SITE_ACCESS_CODE_DOGI || process.env.SITE_ACCESS_CODE_VANVAN));
|
const codesKonfiguriert = !!(process.env.SITE_ACCESS_SECRET && (process.env.SITE_ACCESS_CODE_DOGI || process.env.SITE_ACCESS_CODE_VANVAN || process.env.SITE_ACCESS_CODE_DIENE));
|
||||||
if (!codesKonfiguriert) return next();
|
if (!codesKonfiguriert) return next();
|
||||||
|
|
||||||
if (pfad === "/gate-auth" && req.method === "POST") {
|
if (pfad === "/gate-auth" && req.method === "POST") {
|
||||||
|
|||||||
+23
-7
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Was die Community und das Team über DogFather sagen." />
|
<meta name="twitter:description" content="Was die Community und das Team über DogFather sagen." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-stimmen.jpg');--page-bg-mobile:url('/assets/img/bg-stimmen-mobile.jpg');">
|
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-stimmen.jpg');--page-bg-mobile:url('/assets/img/bg-stimmen-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -67,6 +67,21 @@
|
|||||||
<label for="st-nachricht" data-i18n="st_form_nachricht_label">Deine Nachricht</label>
|
<label for="st-nachricht" data-i18n="st_form_nachricht_label">Deine Nachricht</label>
|
||||||
<textarea id="st-nachricht" maxlength="500" rows="4" required data-i18n-attr="placeholder:st_form_nachricht_placeholder" placeholder="Erzähl uns, was dir Team Dogi bedeutet …"></textarea>
|
<textarea id="st-nachricht" maxlength="500" rows="4" required data-i18n-attr="placeholder:st_form_nachricht_placeholder" placeholder="Erzähl uns, was dir Team Dogi bedeutet …"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Profilbild-Auswahl (21.08.2026, Nutzer-Wunsch: "ich soll auch
|
||||||
|
paar geile bilder zum aussuchen haben als profilbild falls die
|
||||||
|
leute kein bild mit schicken, das soll denen auch als
|
||||||
|
möglichkeit gegeben sein"). Bewusst OHNE Datei-Upload: das
|
||||||
|
Formular ist öffentlich und ohne Anmeldung erreichbar, ein
|
||||||
|
offener Upload wäre eine Einladung für beliebiges Material.
|
||||||
|
Wer ein eigenes Foto möchte, schickt es Dogi direkt — er kann
|
||||||
|
es in der Verwaltung hinterlegen. Die Kacheln werden aus
|
||||||
|
data-stimmen-avatare.js aufgebaut, damit Seite und Verwaltung
|
||||||
|
garantiert dieselbe Auswahl zeigen. -->
|
||||||
|
<div class="field">
|
||||||
|
<span class="stimmen-avatar-titel" data-i18n="st_form_avatar_label">Dein Profilbild (optional)</span>
|
||||||
|
<p class="small muted stimmen-avatar-hinweis" data-i18n="st_form_avatar_hinweis">Ohne Auswahl erscheint einfach der erste Buchstabe deines Namens.</p>
|
||||||
|
<div class="stimmen-avatar-wahl" id="stimmen-avatar-wahl" role="radiogroup" aria-labelledby="stimmen-avatar-titel"></div>
|
||||||
|
</div>
|
||||||
<button type="submit" class="btn btn-primary" style="width:100%;" data-i18n="st_form_absenden">💙 Nachricht einreichen</button>
|
<button type="submit" class="btn btn-primary" style="width:100%;" data-i18n="st_form_absenden">💙 Nachricht einreichen</button>
|
||||||
</form>
|
</form>
|
||||||
<p class="stimmen-erfolg" id="stimmen-erfolg" data-i18n="st_form_erfolg">Danke dir! Deine Nachricht wurde eingereicht und wird von Dogi persönlich geprüft. 🩵</p>
|
<p class="stimmen-erfolg" id="stimmen-erfolg" data-i18n="st_form_erfolg">Danke dir! Deine Nachricht wurde eingereicht und wird von Dogi persönlich geprüft. 🩵</p>
|
||||||
@@ -87,8 +102,9 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-stimmen.js?v=20260821p"></script>
|
<script src="assets/js/data-stimmen-avatare.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/i18n-stimmen.js?v=20260821q"></script>
|
||||||
<script src="assets/js/stimmen.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
|
<script src="assets/js/stimmen.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+6
-6
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Die persönliche Geschichte hinter DogFather — Filipe, Streamer, Manager bei Spicy Media und Hundepapa von Husky Casper." />
|
<meta name="twitter:description" content="Die persönliche Geschichte hinter DogFather — Filipe, Streamer, Manager bei Spicy Media und Hundepapa von Husky Casper." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-streamer.jpg');--page-bg-mobile:url('/assets/img/bg-streamer-mobile.jpg');">
|
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-streamer.jpg');--page-bg-mobile:url('/assets/img/bg-streamer-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -217,7 +217,7 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-streamer.js?v=20260821p"></script>
|
<script src="assets/js/i18n-streamer.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+9
-9
@@ -19,17 +19,17 @@
|
|||||||
<meta name="twitter:description" content="Wann geht DogFather live? Streamplan und Livebereich." />
|
<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" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-streamplan.jpg?v=20260821p');--page-bg-mobile:url('/assets/img/bg-streamplan-mobile.jpg?v=20260821p');">
|
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-streamplan.jpg?v=20260821q');--page-bg-mobile:url('/assets/img/bg-streamplan-mobile.jpg?v=20260821q');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<section class="hero page-bg">
|
<section class="hero page-bg">
|
||||||
<div class="hero-banner"><img src="/assets/img/bg-streamplan.jpg?v=20260821p" alt="" loading="eager" /></div>
|
<div class="hero-banner"><img src="/assets/img/bg-streamplan.jpg?v=20260821q" alt="" loading="eager" /></div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<span class="eyebrow" data-i18n="sp_eyebrow">Welt 1 — DogFather</span>
|
<span class="eyebrow" data-i18n="sp_eyebrow">Welt 1 — DogFather</span>
|
||||||
<h1 data-i18n="sp_h1">Streamplan & Livebereich</h1>
|
<h1 data-i18n="sp_h1">Streamplan & Livebereich</h1>
|
||||||
@@ -126,8 +126,8 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-streamplan.js?v=20260821p"></script>
|
<script src="assets/js/i18n-streamplan.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
<script src="assets/js/streamplan.js?v=20260821p"></script>
|
<script src="assets/js/streamplan.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+7
-7
@@ -9,10 +9,10 @@
|
|||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
<meta name="theme-color" content="#0b0d10" />
|
<meta name="theme-color" content="#0b0d10" />
|
||||||
<meta name="robots" content="noindex" />
|
<meta name="robots" content="noindex" />
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
<style>
|
<style>
|
||||||
/* =====================================================================
|
/* =====================================================================
|
||||||
Supporter-Bereich — komplett neu gestaltet (Nutzer-Feedback
|
Supporter-Bereich — komplett neu gestaltet (Nutzer-Feedback
|
||||||
@@ -515,9 +515,9 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-supporter.js?v=20260821p"></script>
|
<script src="assets/js/i18n-supporter.js?v=20260821q"></script>
|
||||||
<script src="assets/js/supporter.js?v=20260821p"></script>
|
<script src="assets/js/supporter.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
const S = window.DogiSupporter;
|
const S = window.DogiSupporter;
|
||||||
|
|||||||
+7
-7
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="VanVan, Diene, Funny, Miss und Marina — das Modi-/Core-Team von Team Dogi." />
|
<meta name="twitter:description" content="VanVan, Diene, Funny, Miss und Marina — das Modi-/Core-Team von Team Dogi." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-modis.jpg');--page-bg-mobile:url('/assets/img/bg-modis.jpg');">
|
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-modis.jpg');--page-bg-mobile:url('/assets/img/bg-modis.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -72,9 +72,9 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/data-modis.js?v=20260821p"></script>
|
<script src="assets/js/data-modis.js?v=20260821q"></script>
|
||||||
<script src="assets/js/i18n-team-modis.js?v=20260821p"></script>
|
<script src="assets/js/i18n-team-modis.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
const grid = document.getElementById("modis-grid");
|
const grid = document.getElementById("modis-grid");
|
||||||
|
|||||||
+7
-7
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Die Scouts von Team Dogi bei Spicy Media." />
|
<meta name="twitter:description" content="Die Scouts von Team Dogi bei Spicy Media." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-scouts.jpg');--page-bg-mobile:url('/assets/img/bg-scouts-mobile.jpg');">
|
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-scouts.jpg');--page-bg-mobile:url('/assets/img/bg-scouts-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -49,9 +49,9 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/data-scouts.js?v=20260821p"></script>
|
<script src="assets/js/data-scouts.js?v=20260821q"></script>
|
||||||
<script src="assets/js/i18n-team-scouts.js?v=20260821p"></script>
|
<script src="assets/js/i18n-team-scouts.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
const grid = document.getElementById("scouts-grid");
|
const grid = document.getElementById("scouts-grid");
|
||||||
|
|||||||
+6
-6
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Eine persönliche Widmung von Dogi an Tili — seine TikTok-Muddi, die erste und bis heute einzige Streamerin, die ihm all die Zeit treu geblieben ist." />
|
<meta name="twitter:description" content="Eine persönliche Widmung von Dogi an Tili — seine TikTok-Muddi, die erste und bis heute einzige Streamerin, die ihm all die Zeit treu geblieben ist." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
<style>
|
<style>
|
||||||
/* Gleiche Anpassung wie vanvan.html: der site-weit etwas größere
|
/* Gleiche Anpassung wie vanvan.html: der site-weit etwas größere
|
||||||
Fließtext wirkt bei einem so langen persönlichen Brief zu wuchtig —
|
Fließtext wirkt bei einem so langen persönlichen Brief zu wuchtig —
|
||||||
@@ -153,7 +153,7 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-tt-muddi.js?v=20260821p"></script>
|
<script src="assets/js/i18n-tt-muddi.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+6
-6
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="VanVan erzählt ihre Geschichte: wie sie zu Team Dogi kam, wer sie ist und was DogFather und Team Dogi ihr bedeuten." />
|
<meta name="twitter:description" content="VanVan erzählt ihre Geschichte: wie sie zu Team Dogi kam, wer sie ist und was DogFather und Team Dogi ihr bedeuten." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
<style>
|
<style>
|
||||||
/* Auf Wunsch: der site-weit vergrößerte Fließtext wirkte auf VanVans
|
/* Auf Wunsch: der site-weit vergrößerte Fließtext wirkte auf VanVans
|
||||||
eigener Seite zu groß (viel Text am Stück) — hier gezielt wieder
|
eigener Seite zu groß (viel Text am Stück) — hier gezielt wieder
|
||||||
@@ -175,7 +175,7 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-vanvan.js?v=20260821p"></script>
|
<script src="assets/js/i18n-vanvan.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+129
-10
@@ -19,10 +19,10 @@
|
|||||||
<link rel="apple-touch-icon" href="assets/img/apple-touch-icon-admin.png" />
|
<link rel="apple-touch-icon" href="assets/img/apple-touch-icon-admin.png" />
|
||||||
<meta name="apple-mobile-web-app-title" content="DogiCrew-Verwaltung" />
|
<meta name="apple-mobile-web-app-title" content="DogiCrew-Verwaltung" />
|
||||||
<meta name="theme-color" content="#0e0a16" />
|
<meta name="theme-color" content="#0e0a16" />
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
<style>
|
<style>
|
||||||
/* =====================================================================
|
/* =====================================================================
|
||||||
verwaltung.html — Dogis privater Command-Center-Bereich.
|
verwaltung.html — Dogis privater Command-Center-Bereich.
|
||||||
@@ -69,6 +69,15 @@
|
|||||||
Sättigung und weniger Helligkeit → sticht jetzt genauso klar hervor
|
Sättigung und weniger Helligkeit → sticht jetzt genauso klar hervor
|
||||||
wie die anderen drei Akzentfarben.
|
wie die anderen drei Akzentfarben.
|
||||||
===================================================================== */
|
===================================================================== */
|
||||||
|
/* Profilbild-Auswahl in "Stimmen verwalten" (21.08.2026). Die Kacheln
|
||||||
|
selbst kommen aus main.css (.stimmen-avatar-*) — hier nur die Einbettung
|
||||||
|
in die Verwaltungs-Karte, etwas kleiner als auf der oeffentlichen Seite,
|
||||||
|
damit eine Einreichung nicht unnoetig hoch wird. */
|
||||||
|
.vw-stimme-avatar-block { margin-top: 1rem; padding-top: .9rem; border-top: 1px solid var(--border); }
|
||||||
|
.vw-stimme-avatar-wahl { grid-template-columns: repeat(auto-fill, minmax(46px, 1fr)); max-width: 520px; }
|
||||||
|
.vw-stimme-upload { display: block; margin-top: .8rem; color: var(--text-muted); }
|
||||||
|
.vw-stimme-upload input { display: block; margin-top: .3rem; }
|
||||||
|
|
||||||
#supp-root, #vw-stats-root, #session-bar { --accent: #7dd3fc; --accent-2: #38bdf8; --accent-contrast: #1a1408; }
|
#supp-root, #vw-stats-root, #session-bar { --accent: #7dd3fc; --accent-2: #38bdf8; --accent-contrast: #1a1408; }
|
||||||
body { position: relative; }
|
body { position: relative; }
|
||||||
/* Nutzer-Wunsch 04.08.2026 (3. Runde): "alles bisschen größer, Schrift
|
/* Nutzer-Wunsch 04.08.2026 (3. Runde): "alles bisschen größer, Schrift
|
||||||
@@ -1207,12 +1216,13 @@
|
|||||||
<!-- 21.08.2026: für den "Bestehende Mitglieder importieren"-Knopf in der
|
<!-- 21.08.2026: für den "Bestehende Mitglieder importieren"-Knopf in der
|
||||||
Team-Verwaltung -- liest die von Hand gepflegten Profile aus diesen
|
Team-Verwaltung -- liest die von Hand gepflegten Profile aus diesen
|
||||||
Dateien aus und bietet an, sie 1:1 in die Datenbank zu übernehmen. -->
|
Dateien aus und bietet an, sie 1:1 in die Datenbank zu übernehmen. -->
|
||||||
<script src="assets/js/data-modis.js?v=20260821p"></script>
|
<script src="assets/js/data-modis.js?v=20260821q"></script>
|
||||||
<script src="assets/js/data-scouts.js?v=20260821p"></script>
|
<script src="assets/js/data-scouts.js?v=20260821q"></script>
|
||||||
<script src="assets/js/data-creator.js?v=20260821p"></script>
|
<script src="assets/js/data-creator.js?v=20260821q"></script>
|
||||||
<script src="assets/js/data-manager.js?v=20260821p"></script>
|
<script src="assets/js/data-manager.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/data-stimmen-avatare.js?v=20260821q"></script>
|
||||||
<script src="assets/js/admin-auth.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
|
<script src="assets/js/admin-auth.js?v=20260821q"></script>
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
const API_BASE_URL = "https://postfach.dogfather-universe.com";
|
const API_BASE_URL = "https://postfach.dogfather-universe.com";
|
||||||
@@ -1689,6 +1699,43 @@
|
|||||||
stehen nur die sinnvollen Aktionen zur Verfügung. */
|
stehen nur die sinnvollen Aktionen zur Verfügung. */
|
||||||
const TESTIMONIAL_STATUS_LABELS = { eingereicht: "🟡 Neu", freigegeben: "🟢 Freigegeben", abgelehnt: "⚪ Abgelehnt" };
|
const TESTIMONIAL_STATUS_LABELS = { eingereicht: "🟡 Neu", freigegeben: "🟢 Freigegeben", abgelehnt: "⚪ Abgelehnt" };
|
||||||
|
|
||||||
|
/* Profilbild-Auswahl je Einreichung (21.08.2026, Nutzer-Wunsch: "ich soll
|
||||||
|
auch paar geile bilder zum aussuchen haben als profilbild"). Nutzt
|
||||||
|
dieselbe Liste wie die öffentliche Seite (data-stimmen-avatare.js), damit
|
||||||
|
Dogi genau die Bilder sieht, die es auch wirklich gibt. Zusätzlich zu den
|
||||||
|
Auswahlbildern kann hier ein eigenes Foto hochgeladen werden — das darf
|
||||||
|
bewusst NUR die Verwaltung, nicht das öffentliche Formular. */
|
||||||
|
function avatarWahlHtml(t) {
|
||||||
|
const liste = window.STIMMEN_AVATARE || [];
|
||||||
|
const aktiv = (wert) => (t.avatar === wert ? " aktiv" : "");
|
||||||
|
const eigenes = t.avatar && /^https?:\/\//i.test(t.avatar);
|
||||||
|
return `
|
||||||
|
<div class="vw-stimme-avatar-block">
|
||||||
|
<span class="small" style="color:var(--text-muted);display:block;margin-bottom:.45rem;">Profilbild</span>
|
||||||
|
<div class="stimmen-avatar-wahl vw-stimme-avatar-wahl">
|
||||||
|
<button type="button" class="stimmen-avatar-kachel${aktiv(null) || (t.avatar ? "" : " aktiv")}" data-avatar="" title="Kein Bild (Anfangsbuchstabe)">
|
||||||
|
<span class="stimmen-avatar-keins" aria-hidden="true">✦</span>
|
||||||
|
</button>
|
||||||
|
${liste
|
||||||
|
.map(
|
||||||
|
(a) =>
|
||||||
|
`<button type="button" class="stimmen-avatar-kachel${aktiv(a.id)}" data-avatar="${a.id}" title="${escapeHtml(a.name)}"><img src="${a.datei}" alt="" loading="lazy" /></button>`
|
||||||
|
)
|
||||||
|
.join("")}
|
||||||
|
${
|
||||||
|
eigenes
|
||||||
|
? `<button type="button" class="stimmen-avatar-kachel aktiv" data-avatar="${escapeHtml(t.avatar)}" title="Eigenes Foto"><img src="${escapeHtml(t.avatar)}" alt="" loading="lazy" /></button>`
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<label class="small vw-stimme-upload">
|
||||||
|
Eigenes Foto hochladen (max. 5 MB, JPG/PNG/WebP)
|
||||||
|
<input type="file" class="testimonial-foto-input" accept="image/jpeg,image/png,image/webp" />
|
||||||
|
</label>
|
||||||
|
<p class="small testimonial-avatar-status" style="margin:.35rem 0 0;"></p>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
function testimonialKarteHtml(t) {
|
function testimonialKarteHtml(t) {
|
||||||
return `<div class="card vw-card vw-shine-card" style="margin-bottom:1rem;padding:1.3rem 1.4rem;" data-testimonial-id="${t.id}">
|
return `<div class="card vw-card vw-shine-card" style="margin-bottom:1rem;padding:1.3rem 1.4rem;" data-testimonial-id="${t.id}">
|
||||||
<div style="display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;flex-wrap:wrap;">
|
<div style="display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;flex-wrap:wrap;">
|
||||||
@@ -1703,6 +1750,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p style="margin:.8rem 0 0;">${escapeHtml(t.nachricht)}</p>
|
<p style="margin:.8rem 0 0;">${escapeHtml(t.nachricht)}</p>
|
||||||
|
${avatarWahlHtml(t)}
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1733,6 +1781,77 @@
|
|||||||
await ladeUndRenderTestimonials();
|
await ladeUndRenderTestimonials();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* Profilbild anklicken = sofort speichern. Bewusst OHNE die ganze Liste
|
||||||
|
neu zu laden: sonst springt die Ansicht bei jedem Klick nach oben und
|
||||||
|
man verliert die Stelle, an der man gerade arbeitet. Stattdessen wird
|
||||||
|
nur die Markierung innerhalb dieser einen Karte umgesetzt. */
|
||||||
|
listeEl.querySelectorAll(".vw-stimme-avatar-wahl").forEach((wahl) => {
|
||||||
|
wahl.addEventListener("click", async (e) => {
|
||||||
|
const kachel = e.target.closest(".stimmen-avatar-kachel");
|
||||||
|
if (!kachel) return;
|
||||||
|
const karte = kachel.closest("[data-testimonial-id]");
|
||||||
|
const statusEl = karte.querySelector(".testimonial-avatar-status");
|
||||||
|
const avatar = kachel.dataset.avatar || "";
|
||||||
|
const res = await window.AdminAuth.apiCall(API_BASE_URL, "/admin/testimonials/avatar", {
|
||||||
|
id: karte.dataset.testimonialId,
|
||||||
|
avatar,
|
||||||
|
});
|
||||||
|
if (!res.ok) {
|
||||||
|
statusEl.textContent = res.error || "Speichern fehlgeschlagen.";
|
||||||
|
statusEl.style.color = "#ff6b6b";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wahl.querySelectorAll(".stimmen-avatar-kachel").forEach((b) => b.classList.remove("aktiv"));
|
||||||
|
kachel.classList.add("aktiv");
|
||||||
|
statusEl.textContent = "✅ Profilbild gespeichert.";
|
||||||
|
statusEl.style.color = "#baf7d6";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Eigenes Foto: wird sofort bei der Auswahl hochgeladen UND direkt als
|
||||||
|
Bild dieser Stimme gesetzt — ein zusätzlicher "Speichern"-Klick wäre
|
||||||
|
hier nur eine Stolperfalle (dieselbe Logik wie bei den Event-Bildern). */
|
||||||
|
listeEl.querySelectorAll(".testimonial-foto-input").forEach((input) => {
|
||||||
|
input.addEventListener("change", async () => {
|
||||||
|
const datei = input.files?.[0];
|
||||||
|
if (!datei) return;
|
||||||
|
const karte = input.closest("[data-testimonial-id]");
|
||||||
|
const statusEl = karte.querySelector(".testimonial-avatar-status");
|
||||||
|
statusEl.style.color = "";
|
||||||
|
statusEl.textContent = "Foto wird hochgeladen …";
|
||||||
|
|
||||||
|
const form = new FormData();
|
||||||
|
form.append("image", datei);
|
||||||
|
const session = window.AdminAuth.getSession();
|
||||||
|
try {
|
||||||
|
const res = await fetch(`${API_BASE_URL}/admin/testimonials/upload-avatar`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: session?.token ? { Authorization: `Bearer ${session.token}` } : {},
|
||||||
|
body: form,
|
||||||
|
});
|
||||||
|
const data = await res.json();
|
||||||
|
if (!data.ok) {
|
||||||
|
statusEl.textContent = data.error || "Upload fehlgeschlagen.";
|
||||||
|
statusEl.style.color = "#ff6b6b";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const gesetzt = await window.AdminAuth.apiCall(API_BASE_URL, "/admin/testimonials/avatar", {
|
||||||
|
id: karte.dataset.testimonialId,
|
||||||
|
avatar: data.url,
|
||||||
|
});
|
||||||
|
if (!gesetzt.ok) {
|
||||||
|
statusEl.textContent = gesetzt.error || "Foto konnte nicht gesetzt werden.";
|
||||||
|
statusEl.style.color = "#ff6b6b";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await ladeUndRenderTestimonials();
|
||||||
|
} catch {
|
||||||
|
statusEl.textContent = "Upload fehlgeschlagen (keine Verbindung).";
|
||||||
|
statusEl.style.color = "#ff6b6b";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===== "Team verwalten" — Modis/Scouts/Creator/Manager (21.08.2026) =====
|
/* ===== "Team verwalten" — Modis/Scouts/Creator/Manager (21.08.2026) =====
|
||||||
|
|||||||
+6
-6
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Die Werte, nach denen DogFather als Manager bei Spicy Media arbeitet." />
|
<meta name="twitter:description" content="Die Werte, nach denen DogFather als Manager bei Spicy Media arbeitet." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-werte.jpg');--page-bg-mobile:url('/assets/img/bg-werte-mobile.jpg');">
|
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-werte.jpg');--page-bg-mobile:url('/assets/img/bg-werte-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -113,7 +113,7 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-werte.js?v=20260821p"></script>
|
<script src="assets/js/i18n-werte.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+6
-6
@@ -19,10 +19,10 @@
|
|||||||
<meta name="twitter:description" content="Die Geschichte von DogFather in einer interaktiven Zeitleiste." />
|
<meta name="twitter:description" content="Die Geschichte von DogFather in einer interaktiven Zeitleiste." />
|
||||||
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="assets/css/main.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/main.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260821q" />
|
||||||
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821p" />
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260821q" />
|
||||||
</head>
|
</head>
|
||||||
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-zeitreise.jpg');--page-bg-mobile:url('/assets/img/bg-zeitreise-mobile.jpg');">
|
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-zeitreise.jpg');--page-bg-mobile:url('/assets/img/bg-zeitreise-mobile.jpg');">
|
||||||
<div id="site-header"></div>
|
<div id="site-header"></div>
|
||||||
@@ -237,8 +237,8 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<div id="site-footer"></div>
|
<div id="site-footer"></div>
|
||||||
<script src="assets/js/i18n-zeitreise.js?v=20260821p"></script>
|
<script src="assets/js/i18n-zeitreise.js?v=20260821q"></script>
|
||||||
<script src="assets/js/main.js?v=20260821p"></script>
|
<script src="assets/js/main.js?v=20260821q"></script>
|
||||||
<script>
|
<script>
|
||||||
/* Wachstums-Reveal: Äste blenden sich beim Scrollen sanft ein — passt
|
/* Wachstums-Reveal: Äste blenden sich beim Scrollen sanft ein — passt
|
||||||
zum "wachsenden Baum"-Konzept dieser Seite. Rein page-lokal, betrifft
|
zum "wachsenden Baum"-Konzept dieser Seite. Rein page-lokal, betrifft
|
||||||
|
|||||||
Reference in New Issue
Block a user