Mehrsprachigkeit: Sprachumschalter in der Navigation (DE/CH/EN/FR/PT)
Neues i18n-System, komplett clientseitig (kein Build-Tool): - main.js: I18N_CORE übersetzt Navigation, Fußzeile und Musik-Widget auf JEDER Seite (Markennamen wie DogFather/HasiDog/Casper/Team Dogi bleiben bewusst in jeder Sprache gleich). Sprachumschalter (Flagge + Kürzel) neu im Nav-Bar, per Klick wählbar, Wahl landet in localStorage und bleibt beim Klicken durch die Seite erhalten. - Jeder komplett neue Besuch (kein gespeicherter Wert) startet IMMER auf Deutsch - keine automatische Browsersprache-Erkennung, wie gewünscht. - assets/js/i18n-index.js: vollständiges Wörterbuch für die Startseite (Hero, Charaktere, Foto-Collage, Stats, "Was dich erwartet", Team-Vorschau, Aktionen, Galerie, Testimonial, finaler CTA) inkl. der dynamischen Live-Status-Texte. - Schweizer Hochdeutsch (de-CH) korrekt mit ss statt ß angelegt (z.B. "Musik-Feld schliessen"). - Weitere Unterseiten (streamer.html, vanvan.html, ...) bekommen ihr eigenes Wörterbuch schrittweise in künftigen Runden - Navigation/ Fußzeile/Musik-Widget sind aber schon jetzt überall mehrsprachig.
This commit is contained in:
@@ -191,6 +191,13 @@ header.site-header {
|
||||
}
|
||||
.nav-dropdown a:hover, .nav-dropdown a.active { background: var(--bg-alt); color: var(--accent); }
|
||||
|
||||
/* Sprachumschalter — schmalerer Dropdown reicht (nur Flagge + 2-stelliges
|
||||
Kürzel pro Zeile), rechtsbündig statt zentriert, damit er nicht über
|
||||
den Seitenrand hinausragt. */
|
||||
.sprach-schalter > button { font-size: 1.02rem; }
|
||||
.sprach-schalter .nav-dropdown { min-width: 130px; left: auto; right: 0; transform: none; }
|
||||
.sprach-schalter .nav-dropdown a { display: flex; align-items: center; gap: .5rem; }
|
||||
|
||||
/* "Bewerben" ist der Treffpunkt beider Welten (Team Dogi + Spicy Media) —
|
||||
deshalb bewusst FEST babyblau + rot, unabhängig vom Theme der gerade
|
||||
offenen Seite. Statt einer einfachen 50/50-Teilung ein echtes
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
/* =====================================================================
|
||||
i18n-index.js — Übersetzungs-Wörterbuch NUR für index.html
|
||||
|
||||
Wird von main.js (applyTranslations) über data-i18n="schluessel" auf
|
||||
die passenden Elemente angewendet. Nur auf der Startseite eingebunden
|
||||
— andere Seiten haben aktuell noch kein eigenes Wörterbuch und bleiben
|
||||
bewusst auf Deutsch (Navigation/Fußzeile/Musik-Widget sind aber überall
|
||||
mehrsprachig, siehe I18N_CORE in main.js).
|
||||
|
||||
Schweizer Hochdeutsch (de-CH) ist auf dieser Seite überall identisch zu
|
||||
Deutsch (de) — keiner der Texte hier enthält ein ß.
|
||||
===================================================================== */
|
||||
|
||||
window.I18N_PAGE = {
|
||||
idx_hero_h1: {
|
||||
de: "Streamer. Community. HasiDog. Manager.<br>Gemeinsam stark.",
|
||||
"de-CH": "Streamer. Community. HasiDog. Manager.<br>Gemeinsam stark.",
|
||||
en: "Streamer. Community. HasiDog. Manager.<br>Stronger together.",
|
||||
fr: "Streamer. Communauté. HasiDog. Manager.<br>Plus forts ensemble.",
|
||||
pt: "Streamer. Comunidade. HasiDog. Manager.<br>Mais fortes juntos.",
|
||||
},
|
||||
idx_hero_lead: {
|
||||
de: "Drei Welten, eine Familie: Team Dogi.",
|
||||
"de-CH": "Drei Welten, eine Familie: Team Dogi.",
|
||||
en: "Three worlds, one family: Team Dogi.",
|
||||
fr: "Trois mondes, une famille : Team Dogi.",
|
||||
pt: "Três mundos, uma família: Team Dogi.",
|
||||
},
|
||||
idx_live_loading: {
|
||||
de: "Status wird geladen …",
|
||||
"de-CH": "Status wird geladen …",
|
||||
en: "Loading status …",
|
||||
fr: "Chargement du statut …",
|
||||
pt: "Carregando status …",
|
||||
},
|
||||
idx_live_info: {
|
||||
de: `DogFather geht <strong>jeden Tag ab 20 Uhr</strong> live — oft schon tagsüber, zu wechselnden Zeiten. <a href="streamplan.html">Streamplan ansehen →</a>`,
|
||||
"de-CH": `DogFather geht <strong>jeden Tag ab 20 Uhr</strong> live — oft schon tagsüber, zu wechselnden Zeiten. <a href="streamplan.html">Streamplan ansehen →</a>`,
|
||||
en: `DogFather goes live <strong>every day from 8 PM</strong> — often earlier too, at varying times. <a href="streamplan.html">View the schedule →</a>`,
|
||||
fr: `DogFather est en live <strong>tous les jours à partir de 20h</strong> — souvent même plus tôt, à des horaires variables. <a href="streamplan.html">Voir le programme →</a>`,
|
||||
pt: `DogFather fica ao vivo <strong>todos os dias a partir das 20h</strong> — muitas vezes já durante o dia, em horários variados. <a href="streamplan.html">Ver a programação →</a>`,
|
||||
},
|
||||
idx_hero_btn_links: {
|
||||
de: "Alle Links 🩵", "de-CH": "Alle Links 🩵",
|
||||
en: "All Links 🩵", fr: "Tous les liens 🩵", pt: "Todos os links 🩵",
|
||||
},
|
||||
idx_hero_btn_team: {
|
||||
de: "Teil vom Team werden", "de-CH": "Teil vom Team werden",
|
||||
en: "Join the team", fr: "Rejoindre l'équipe", pt: "Fazer parte da equipe",
|
||||
},
|
||||
idx_hero_card1_tag: { de: "Welt 1", "de-CH": "Welt 1", en: "World 1", fr: "Monde 1", pt: "Mundo 1" },
|
||||
idx_hero_card1_desc: {
|
||||
de: "Streamer, Entertainer, das Herz hinter dem Kanal. Halligalli, Humor und ein offenes Ohr für die Community.",
|
||||
"de-CH": "Streamer, Entertainer, das Herz hinter dem Kanal. Halligalli, Humor und ein offenes Ohr für die Community.",
|
||||
en: "Streamer, entertainer, the heart behind the channel. Good times, humor, and an open ear for the community.",
|
||||
fr: "Streamer, entertainer, le cœur de la chaîne. Bonne humeur, humour et une oreille attentive pour la communauté.",
|
||||
pt: "Streamer, entertainer, o coração por trás do canal. Diversão, humor e sempre um ouvido aberto para a comunidade.",
|
||||
},
|
||||
idx_hero_card2_tag: { de: "Welt 2", "de-CH": "Welt 2", en: "World 2", fr: "Monde 2", pt: "Mundo 2" },
|
||||
idx_hero_card2_desc: {
|
||||
de: "Die Community, das Maskottchen und Husky Casper — die verspielte, familiäre Seite von Team Dogi.",
|
||||
"de-CH": "Die Community, das Maskottchen und Husky Casper — die verspielte, familiäre Seite von Team Dogi.",
|
||||
en: "The community, the mascot, and Husky Casper — the playful, family side of Team Dogi.",
|
||||
fr: "La communauté, la mascotte et le husky Casper — le côté joueur et familial de Team Dogi.",
|
||||
pt: "A comunidade, o mascote e o husky Casper — o lado brincalhão e familiar do Team Dogi.",
|
||||
},
|
||||
idx_hero_card3_tag: { de: "Welt 3", "de-CH": "Welt 3", en: "World 3", fr: "Monde 3", pt: "Mundo 3" },
|
||||
idx_hero_card3_desc: {
|
||||
de: "Als Manager bei Spicy Media: Scouts, Creator und faire Zusammenarbeit auf Augenhöhe.",
|
||||
"de-CH": "Als Manager bei Spicy Media: Scouts, Creator und faire Zusammenarbeit auf Augenhöhe.",
|
||||
en: "As a manager at Spicy Media: scouts, creators, and fair collaboration at eye level.",
|
||||
fr: "En tant que manager chez Spicy Media : scouts, creators et une collaboration équitable, d'égal à égal.",
|
||||
pt: "Como manager na Spicy Media: scouts, creators e uma parceria justa entre iguais.",
|
||||
},
|
||||
idx_char_eyebrow: {
|
||||
de: "🩵 Die Gesichter der Welten", "de-CH": "🩵 Die Gesichter der Welten",
|
||||
en: "🩵 The Faces of the Worlds", fr: "🩵 Les visages des mondes", pt: "🩵 Os rostos dos mundos",
|
||||
},
|
||||
idx_char_lead: {
|
||||
de: "Zwei Charaktere, ein Universum — klick dich in ihre Welt.",
|
||||
"de-CH": "Zwei Charaktere, ein Universum — klick dich in ihre Welt.",
|
||||
en: "Two characters, one universe — click your way into their world.",
|
||||
fr: "Deux personnages, un seul univers — clique pour entrer dans leur monde.",
|
||||
pt: "Dois personagens, um universo — clique e entre no mundo deles.",
|
||||
},
|
||||
idx_char1_sub: {
|
||||
de: "Streamer · Entertainer · Welt 1", "de-CH": "Streamer · Entertainer · Welt 1",
|
||||
en: "Streamer · Entertainer · World 1", fr: "Streamer · Entertainer · Monde 1", pt: "Streamer · Entertainer · Mundo 1",
|
||||
},
|
||||
idx_char2_sub: {
|
||||
de: "Community · Maskottchen · Welt 2", "de-CH": "Community · Maskottchen · Welt 2",
|
||||
en: "Community · Mascot · World 2", fr: "Communauté · Mascotte · Monde 2", pt: "Comunidade · Mascote · Mundo 2",
|
||||
},
|
||||
idx_char_go: {
|
||||
de: "Zur Welt →", "de-CH": "Zur Welt →",
|
||||
en: "Enter the world →", fr: "Découvrir le monde →", pt: "Ver o mundo →",
|
||||
},
|
||||
idx_collage_eyebrow: {
|
||||
de: "🩵 Gesichter hinter dem Universum", "de-CH": "🩵 Gesichter hinter dem Universum",
|
||||
en: "🩵 Faces Behind the Universe", fr: "🩵 Les visages derrière l'univers", pt: "🩵 Rostos por trás do universo",
|
||||
},
|
||||
idx_collage_cap_team: { de: "Team 🩵🐾", "de-CH": "Team 🩵🐾", en: "Team 🩵🐾", fr: "Équipe 🩵🐾", pt: "Equipe 🩵🐾" },
|
||||
idx_collage_cap_huskylife: { de: "Husky-Life", "de-CH": "Husky-Life", en: "Husky Life", fr: "Vie de husky", pt: "Vida de husky" },
|
||||
idx_collage_cap_nose: { de: "Nase an Nase 🩵", "de-CH": "Nase an Nase 🩵", en: "Nose to Nose 🩵", fr: "Nez à nez 🩵", pt: "Nariz a nariz 🩵" },
|
||||
idx_collage_footer: {
|
||||
de: "DogFather & Casper — die zwei Gesichter hinter dem ganzen Universum. 🩵🐾",
|
||||
"de-CH": "DogFather & Casper — die zwei Gesichter hinter dem ganzen Universum. 🩵🐾",
|
||||
en: "DogFather & Casper — the two faces behind the whole universe. 🩵🐾",
|
||||
fr: "DogFather & Casper — les deux visages derrière tout l'univers. 🩵🐾",
|
||||
pt: "DogFather & Casper — os dois rostos por trás de todo o universo. 🩵🐾",
|
||||
},
|
||||
idx_stats_team: {
|
||||
de: "Menschen im Team Dogi", "de-CH": "Menschen im Team Dogi",
|
||||
en: "People in Team Dogi", fr: "Personnes dans Team Dogi", pt: "Pessoas no Team Dogi",
|
||||
},
|
||||
idx_stats_daily_label: { de: "Täglich", "de-CH": "Täglich", en: "Daily", fr: "Chaque jour", pt: "Diariamente" },
|
||||
idx_stats_daily_desc: {
|
||||
de: "live ab 20 Uhr", "de-CH": "live ab 20 Uhr",
|
||||
en: "live from 8 PM", fr: "en live dès 20h", pt: "ao vivo a partir das 20h",
|
||||
},
|
||||
idx_stats_worlds: {
|
||||
de: "Welten, eine Familie", "de-CH": "Welten, eine Familie",
|
||||
en: "worlds, one family", fr: "mondes, une famille", pt: "mundos, uma família",
|
||||
},
|
||||
idx_stats_family: {
|
||||
de: "Team Dogi ist Familie", "de-CH": "Team Dogi ist Familie",
|
||||
en: "Team Dogi is family", fr: "Team Dogi, c'est la famille", pt: "Team Dogi é família",
|
||||
},
|
||||
idx_expect_eyebrow: {
|
||||
de: "Ein bisschen von allem", "de-CH": "Ein bisschen von allem",
|
||||
en: "A little bit of everything", fr: "Un peu de tout", pt: "Um pouco de tudo",
|
||||
},
|
||||
idx_expect_h2: {
|
||||
de: "Was dich im Universum erwartet", "de-CH": "Was dich im Universum erwartet",
|
||||
en: "What awaits you in the universe", fr: "Ce qui t'attend dans l'univers", pt: "O que te espera no universo",
|
||||
},
|
||||
idx_expect_c1_h3: { de: "🎥 Streamer", "de-CH": "🎥 Streamer", en: "🎥 Streamer", fr: "🎥 Streamer", pt: "🎥 Streamer" },
|
||||
idx_expect_c1_p: {
|
||||
de: "Halligalli, Humor & Hasencontent.", "de-CH": "Halligalli, Humor & Hasencontent.",
|
||||
en: "Good times, humor & bunny content.", fr: "Bonne humeur, humour et contenu de lapin.", pt: "Diversão, humor e conteúdo de coelho.",
|
||||
},
|
||||
idx_expect_c2_h3: { de: "🕰️ Zeitreise", "de-CH": "🕰️ Zeitreise", en: "🕰️ Timeline", fr: "🕰️ Chronologie", pt: "🕰️ Linha do tempo" },
|
||||
idx_expect_c2_p: {
|
||||
de: "Die Geschichte von DogFather & Team Dogi.", "de-CH": "Die Geschichte von DogFather & Team Dogi.",
|
||||
en: "The story of DogFather & Team Dogi.", fr: "L'histoire de DogFather et de Team Dogi.", pt: "A história de DogFather e do Team Dogi.",
|
||||
},
|
||||
idx_expect_c3_h3: { de: "🩵 Community", "de-CH": "🩵 Community", en: "🩵 Community", fr: "🩵 Communauté", pt: "🩵 Comunidade" },
|
||||
idx_expect_c3_p: {
|
||||
de: "Team Dogi ist Familie.", "de-CH": "Team Dogi ist Familie.",
|
||||
en: "Team Dogi is family.", fr: "Team Dogi, c'est la famille.", pt: "Team Dogi é família.",
|
||||
},
|
||||
idx_expect_c4_h3: { de: "🐾 Casper", "de-CH": "🐾 Casper", en: "🐾 Casper", fr: "🐾 Casper", pt: "🐾 Casper" },
|
||||
idx_expect_c4_p: {
|
||||
de: "Der Husky an DogFathers Seite.", "de-CH": "Der Husky an DogFathers Seite.",
|
||||
en: "The husky by DogFather's side.", fr: "Le husky aux côtés de DogFather.", pt: "O husky ao lado de DogFather.",
|
||||
},
|
||||
idx_expect_c5_h3: { de: "🧑🤝🧑 Modi-Team", "de-CH": "🧑🤝🧑 Modi-Team", en: "🧑🤝🧑 Modi-Team", fr: "🧑🤝🧑 Modi-Team", pt: "🧑🤝🧑 Modi-Team" },
|
||||
idx_expect_c5_p: {
|
||||
de: "VanVan, Diene & Co.", "de-CH": "VanVan, Diene & Co.",
|
||||
en: "VanVan, Diene & co.", fr: "VanVan, Diene et l'équipe.", pt: "VanVan, Diene e equipe.",
|
||||
},
|
||||
idx_expect_c6_h3: { de: "🖼️ Medien: DogFather", "de-CH": "🖼️ Medien: DogFather", en: "🖼️ Media: DogFather", fr: "🖼️ Médias : DogFather", pt: "🖼️ Mídia: DogFather" },
|
||||
idx_expect_c7_h3: { de: "🐰 Medien: HasiDog", "de-CH": "🐰 Medien: HasiDog", en: "🐰 Media: HasiDog", fr: "🐰 Médias : HasiDog", pt: "🐰 Mídia: HasiDog" },
|
||||
idx_expect_c8_h3: { de: "🐺 Medien: Casper", "de-CH": "🐺 Medien: Casper", en: "🐺 Media: Casper", fr: "🐺 Médias : Casper", pt: "🐺 Mídia: Casper" },
|
||||
idx_expect_media_p: {
|
||||
de: "Fotos, Videos & Events.", "de-CH": "Fotos, Videos & Events.",
|
||||
en: "Photos, videos & events.", fr: "Photos, vidéos et événements.", pt: "Fotos, vídeos e eventos.",
|
||||
},
|
||||
idx_team_h2: { de: "Team Dogi 🩵", "de-CH": "Team Dogi 🩵", en: "Team Dogi 🩵", fr: "Team Dogi 🩵", pt: "Team Dogi 🩵" },
|
||||
idx_team_lead: {
|
||||
de: "Von VanVan bis zu den Scouts — die Menschen, die DOGFATHER UNIVERSE tragen.",
|
||||
"de-CH": "Von VanVan bis zu den Scouts — die Menschen, die DOGFATHER UNIVERSE tragen.",
|
||||
en: "From VanVan to the scouts — the people who carry DOGFATHER UNIVERSE.",
|
||||
fr: "De VanVan aux scouts — les personnes qui portent DOGFATHER UNIVERSE.",
|
||||
pt: "De VanVan aos scouts — as pessoas que sustentam o DOGFATHER UNIVERSE.",
|
||||
},
|
||||
idx_team_btn_modi: {
|
||||
de: "Modi-Team ansehen", "de-CH": "Modi-Team ansehen",
|
||||
en: "View Modi-Team", fr: "Voir l'équipe Modi", pt: "Ver equipe Modi",
|
||||
},
|
||||
idx_team_btn_scouts: {
|
||||
de: "Scout-Team ansehen", "de-CH": "Scout-Team ansehen",
|
||||
en: "View Scout Team", fr: "Voir l'équipe Scouts", pt: "Ver equipe Scouts",
|
||||
},
|
||||
idx_aktionen_h2: {
|
||||
de: "Was gerade läuft", "de-CH": "Was gerade läuft",
|
||||
en: "What's happening right now", fr: "Ce qui se passe en ce moment", pt: "O que está rolando agora",
|
||||
},
|
||||
idx_aktionen_btn: {
|
||||
de: "Alle Aktionen & Projekte", "de-CH": "Alle Aktionen & Projekte",
|
||||
en: "All actions & projects", fr: "Toutes les actions et projets", pt: "Todas as ações e projetos",
|
||||
},
|
||||
idx_galerie_h2: { de: "Impressionen", "de-CH": "Impressionen", en: "Impressions", fr: "Aperçus", pt: "Impressões" },
|
||||
idx_galerie_btn: {
|
||||
de: "Zur ganzen Galerie", "de-CH": "Zur ganzen Galerie",
|
||||
en: "View the full gallery", fr: "Voir toute la galerie", pt: "Ver galeria completa",
|
||||
},
|
||||
idx_testimonial_eyebrow: {
|
||||
de: "Was andere sagen", "de-CH": "Was andere sagen",
|
||||
en: "What others say", fr: "Ce que les autres disent", pt: "O que os outros dizem",
|
||||
},
|
||||
idx_testimonial_quote: {
|
||||
de: "„Hier stehen bald echte Stimmen aus der Community. 🩵“",
|
||||
"de-CH": "„Hier stehen bald echte Stimmen aus der Community. 🩵“",
|
||||
en: "“Real voices from the community will be here soon. 🩵”",
|
||||
fr: "« De vrais témoignages de la communauté arriveront bientôt ici. 🩵 »",
|
||||
pt: "“Em breve, depoimentos reais da comunidade estarão aqui. 🩵”",
|
||||
},
|
||||
idx_testimonial_attrib: {
|
||||
de: "— Team Dogi", "de-CH": "— Team Dogi", en: "— Team Dogi", fr: "— Team Dogi", pt: "— Team Dogi",
|
||||
},
|
||||
idx_testimonial_btn: {
|
||||
de: "Mehr Stimmen", "de-CH": "Mehr Stimmen",
|
||||
en: "More voices", fr: "Plus de témoignages", pt: "Mais depoimentos",
|
||||
},
|
||||
idx_cta_eyebrow: { de: "🩵 Bereit?", "de-CH": "🩵 Bereit?", en: "🩵 Ready?", fr: "🩵 Prêt·e ?", pt: "🩵 Pronto?" },
|
||||
idx_cta_h2: {
|
||||
de: "Werde Teil von DOGFATHER UNIVERSE", "de-CH": "Werde Teil von DOGFATHER UNIVERSE",
|
||||
en: "Become part of DOGFATHER UNIVERSE", fr: "Rejoins DOGFATHER UNIVERSE", pt: "Faça parte do DOGFATHER UNIVERSE",
|
||||
},
|
||||
idx_cta_lead: {
|
||||
de: "Als Zuschauer:in, Creator, Scout oder Kooperationspartner — hier ist für jeden Platz.",
|
||||
"de-CH": "Als Zuschauer:in, Creator, Scout oder Kooperationspartner — hier ist für jeden Platz.",
|
||||
en: "As a viewer, creator, scout, or cooperation partner — there's room for everyone here.",
|
||||
fr: "Que tu sois spectateur·rice, creator, scout ou partenaire — il y a une place pour toi ici.",
|
||||
pt: "Como espectador(a), creator, scout ou parceiro(a) — aqui há espaço para todos.",
|
||||
},
|
||||
idx_cta_btn_links: {
|
||||
de: "Alle Links 🩵", "de-CH": "Alle Links 🩵",
|
||||
en: "All Links 🩵", fr: "Tous les liens 🩵", pt: "Todos os links 🩵",
|
||||
},
|
||||
idx_cta_btn_bewerben: {
|
||||
de: "Jetzt bewerben", "de-CH": "Jetzt bewerben",
|
||||
en: "Apply now", fr: "Postuler maintenant", pt: "Candidate-se agora",
|
||||
},
|
||||
|
||||
/* Live-Status (wird von index.html per JS gesetzt, siehe dortiges
|
||||
Inline-Skript — Schlüssel hier nur zentral gepflegt) */
|
||||
idx_live_now: {
|
||||
de: "Jetzt live: {titel}", "de-CH": "Jetzt live: {titel}",
|
||||
en: "Live now: {titel}", fr: "En direct : {titel}", pt: "Ao vivo agora: {titel}",
|
||||
},
|
||||
idx_live_now_generic: {
|
||||
de: "Jetzt live!", "de-CH": "Jetzt live!",
|
||||
en: "Live now!", fr: "En direct !", pt: "Ao vivo agora!",
|
||||
},
|
||||
idx_live_offline: {
|
||||
de: "Gerade offline", "de-CH": "Gerade offline",
|
||||
en: "Currently offline", fr: "Actuellement hors ligne", pt: "Offline no momento",
|
||||
},
|
||||
idx_live_error: {
|
||||
de: "Status gerade nicht abrufbar", "de-CH": "Status gerade nicht abrufbar",
|
||||
en: "Status currently unavailable", fr: "Statut actuellement indisponible", pt: "Status indisponível no momento",
|
||||
},
|
||||
};
|
||||
+276
-55
@@ -8,38 +8,193 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
/* ===================================================================
|
||||
Mehrsprachigkeit (i18n)
|
||||
|
||||
Fünf Sprachen: Deutsch (Standard, IMMER die Sprache beim ersten
|
||||
Besuch), Englisch, Schweizer Hochdeutsch (ß→ss, sonst wie Deutsch),
|
||||
Französisch, Portugiesisch. Rein clientseitig, kein Build-Tool:
|
||||
- I18N_CORE deckt die sitewide gemeinsamen Textstücke ab (Navigation,
|
||||
Fußzeile, Musik-Widget) — läuft auf JEDER Seite, weil main.js
|
||||
überall eingebunden ist.
|
||||
- Seiteneigene Inhalte (z.B. die Startseite) bekommen zusätzlich ein
|
||||
eigenes Wörterbuch über window.I18N_PAGE (siehe assets/js/i18n-*.js),
|
||||
das per data-i18n="schluessel" auf Elemente gemappt wird.
|
||||
Markennamen (DogFather, HasiDog, Casper, VanVan, Team Dogi,
|
||||
Modi-Team, Scout-Team, Streamer, Creator, Manager, Community) bleiben
|
||||
bewusst in JEDER Sprache unübersetzt — das ist die Marke.
|
||||
Gewählte Sprache landet in localStorage und bleibt beim Klicken durch
|
||||
die Seite erhalten. Ein komplett neuer Besuch (keine Speicherung)
|
||||
startet immer auf Deutsch — nie automatische Browsersprache-Erkennung.
|
||||
=================================================================== */
|
||||
const SPRACHEN = [
|
||||
{ code: "de", flagge: "🇩🇪", kurz: "DE" },
|
||||
{ code: "de-CH", flagge: "🇨🇭", kurz: "CH" },
|
||||
{ code: "en", flagge: "🇬🇧", kurz: "EN" },
|
||||
{ code: "fr", flagge: "🇫🇷", kurz: "FR" },
|
||||
{ code: "pt", flagge: "🇵🇹", kurz: "PT" },
|
||||
];
|
||||
const SPRACHE_SCHLUESSEL = "dogi-sprache";
|
||||
|
||||
function getSprache() {
|
||||
const gespeichert = localStorage.getItem(SPRACHE_SCHLUESSEL);
|
||||
return SPRACHEN.some((s) => s.code === gespeichert) ? gespeichert : "de";
|
||||
}
|
||||
|
||||
function setSprache(code) {
|
||||
if (!SPRACHEN.some((s) => s.code === code)) return;
|
||||
localStorage.setItem(SPRACHE_SCHLUESSEL, code);
|
||||
document.documentElement.setAttribute("lang", code);
|
||||
renderHeader();
|
||||
renderFooter();
|
||||
applyTranslations();
|
||||
applyMusicWidgetSprache();
|
||||
// Seiteneigene Skripte (z.B. der Live-Status auf index.html) können
|
||||
// darauf reagieren, um dynamisch gesetzten Text (nicht über
|
||||
// data-i18n) ebenfalls neu zu übersetzen.
|
||||
document.dispatchEvent(new CustomEvent("dogi-sprache-geaendert", { detail: { sprache: code } }));
|
||||
}
|
||||
|
||||
const I18N_CORE = {
|
||||
nav_start: { de: "Start", "de-CH": "Start", en: "Home", fr: "Accueil", pt: "Início" },
|
||||
nav_dogfather: { de: "DogFather", "de-CH": "DogFather", en: "DogFather", fr: "DogFather", pt: "DogFather" },
|
||||
nav_dogfather_person: { de: "Die Person", "de-CH": "Die Person", en: "The Person", fr: "La personne", pt: "A pessoa" },
|
||||
nav_dogfather_streamer: { de: "Streamer", "de-CH": "Streamer", en: "Streamer", fr: "Streamer", pt: "Streamer" },
|
||||
nav_dogfather_casper: { de: "Casper", "de-CH": "Casper", en: "Casper", fr: "Casper", pt: "Casper" },
|
||||
nav_dogfather_vanvan: { de: "VanVan", "de-CH": "VanVan", en: "VanVan", fr: "VanVan", pt: "VanVan" },
|
||||
nav_dogfather_zeitreise: { de: "Zeitreise", "de-CH": "Zeitreise", en: "Timeline", fr: "Chronologie", pt: "Linha do tempo" },
|
||||
nav_hasidog: { de: "HasiDog", "de-CH": "HasiDog", en: "HasiDog", fr: "HasiDog", pt: "HasiDog" },
|
||||
nav_hasidog_welt: { de: "HasiDog-Welt", "de-CH": "HasiDog-Welt", en: "HasiDog World", fr: "Monde HasiDog", pt: "Mundo HasiDog" },
|
||||
nav_hasidog_modi: { de: "Modi-Team", "de-CH": "Modi-Team", en: "Modi-Team", fr: "Modi-Team", pt: "Modi-Team" },
|
||||
nav_hasidog_community: { de: "Community", "de-CH": "Community", en: "Community", fr: "Communauté", pt: "Comunidade" },
|
||||
nav_hasidog_stimmen: { de: "Stimmen", "de-CH": "Stimmen", en: "Voices", fr: "Témoignages", pt: "Depoimentos" },
|
||||
nav_hasidog_streamplan: { de: "Streamplan", "de-CH": "Streamplan", en: "Stream schedule", fr: "Programme des streams", pt: "Programação das lives" },
|
||||
nav_manager: { de: "Manager", "de-CH": "Manager", en: "Manager", fr: "Manager", pt: "Manager" },
|
||||
nav_manager_dogfather: { de: "Manager DogFather", "de-CH": "Manager DogFather", en: "Manager DogFather", fr: "Manager DogFather", pt: "Manager DogFather" },
|
||||
nav_manager_scouts: { de: "Scout-Team", "de-CH": "Scout-Team", en: "Scout Team", fr: "Équipe Scouts", pt: "Equipe Scouts" },
|
||||
nav_manager_creator: { de: "Creator", "de-CH": "Creator", en: "Creator", fr: "Creator", pt: "Creator" },
|
||||
nav_manager_werte: { de: "Werte", "de-CH": "Werte", en: "Values", fr: "Valeurs", pt: "Valores" },
|
||||
nav_manager_bewerben: { de: "Bewerben", "de-CH": "Bewerben", en: "Apply", fr: "Postuler", pt: "Candidatar-se" },
|
||||
nav_medien: { de: "Medien", "de-CH": "Medien", en: "Media", fr: "Médias", pt: "Mídia" },
|
||||
nav_medien_dogfather: { de: "DogFather", "de-CH": "DogFather", en: "DogFather", fr: "DogFather", pt: "DogFather" },
|
||||
nav_medien_hasidog: { de: "HasiDog", "de-CH": "HasiDog", en: "HasiDog", fr: "HasiDog", pt: "HasiDog" },
|
||||
nav_medien_casper: { de: "Casper", "de-CH": "Casper", en: "Casper", fr: "Casper", pt: "Casper" },
|
||||
nav_links: { de: "Links", "de-CH": "Links", en: "Links", fr: "Liens", pt: "Links" },
|
||||
nav_cta_bewerben: { de: "Bewerben 🩵", "de-CH": "Bewerben 🩵", en: "Apply 🩵", fr: "Postuler 🩵", pt: "Candidatar-se 🩵" },
|
||||
nav_toggle_aria: { de: "Menü öffnen", "de-CH": "Menü öffnen", en: "Open menu", fr: "Ouvrir le menu", pt: "Abrir menu" },
|
||||
sprache_aria: { de: "Sprache wählen", "de-CH": "Sprache wählen", en: "Choose language", fr: "Choisir la langue", pt: "Escolher idioma" },
|
||||
brand_tagline: {
|
||||
de: "Streamer · Community · HasiDog · Manager",
|
||||
"de-CH": "Streamer · Community · HasiDog · Manager",
|
||||
en: "Streamer · Community · HasiDog · Manager",
|
||||
fr: "Streamer · Communauté · HasiDog · Manager",
|
||||
pt: "Streamer · Comunidade · HasiDog · Manager",
|
||||
},
|
||||
footer_tagline: {
|
||||
de: "Streamer. Community. HasiDog. Manager. Gemeinsam stark.",
|
||||
"de-CH": "Streamer. Community. HasiDog. Manager. Gemeinsam stark.",
|
||||
en: "Streamer. Community. HasiDog. Manager. Stronger together.",
|
||||
fr: "Streamer. Communauté. HasiDog. Manager. Plus forts ensemble.",
|
||||
pt: "Streamer. Comunidade. HasiDog. Manager. Mais fortes juntos.",
|
||||
},
|
||||
footer_h4_hasidog_manager: { de: "HasiDog & Manager", "de-CH": "HasiDog & Manager", en: "HasiDog & Manager", fr: "HasiDog et Manager", pt: "HasiDog e Manager" },
|
||||
footer_h4_mehr: { de: "Mehr", "de-CH": "Mehr", en: "More", fr: "Plus", pt: "Mais" },
|
||||
footer_scouts: { de: "Scouts", "de-CH": "Scouts", en: "Scouts", fr: "Scouts", pt: "Scouts" },
|
||||
footer_alle_links: { de: "Alle Links", "de-CH": "Alle Links", en: "All links", fr: "Tous les liens", pt: "Todos os links" },
|
||||
footer_kontakt: { de: "Kontakt", "de-CH": "Kontakt", en: "Contact", fr: "Contact", pt: "Contato" },
|
||||
footer_copyright: {
|
||||
de: "© {jahr} DogFather Universe. Team Dogi ist Familie 🩵",
|
||||
"de-CH": "© {jahr} DogFather Universe. Team Dogi ist Familie 🩵",
|
||||
en: "© {jahr} DogFather Universe. Team Dogi is family 🩵",
|
||||
fr: "© {jahr} DogFather Universe. Team Dogi, c'est la famille 🩵",
|
||||
pt: "© {jahr} DogFather Universe. Team Dogi é família 🩵",
|
||||
},
|
||||
footer_impressum: { de: "Impressum & Datenschutz", "de-CH": "Impressum & Datenschutz", en: "Legal notice & privacy", fr: "Mentions légales et confidentialité", pt: "Aviso legal e privacidade" },
|
||||
music_title: { de: "Musik von Team Dogi 🎵", "de-CH": "Musik von Team Dogi 🎵", en: "Music from Team Dogi 🎵", fr: "Musique de Team Dogi 🎵", pt: "Música do Team Dogi 🎵" },
|
||||
music_close_aria: { de: "Musik-Feld schließen", "de-CH": "Musik-Feld schliessen", en: "Close music panel", fr: "Fermer le panneau musique", pt: "Fechar painel de música" },
|
||||
music_intro: {
|
||||
de: "Läuft weiter, solange du auf dieser Seite bleibst. 🩵",
|
||||
"de-CH": "Läuft weiter, solange du auf dieser Seite bleibst. 🩵",
|
||||
en: "Keeps playing as long as you stay on this page. 🩵",
|
||||
fr: "Continue de jouer tant que tu restes sur cette page. 🩵",
|
||||
pt: "Continua tocando enquanto você ficar nesta página. 🩵",
|
||||
},
|
||||
music_toggle_title: { de: "Musik von Hasidog & Van-Van", "de-CH": "Musik von Hasidog & Van-Van", en: "Music from Hasidog & Van-Van", fr: "Musique de Hasidog et Van-Van", pt: "Música de Hasidog e Van-Van" },
|
||||
music_spotify_suffix: { de: "auf Spotify anhören", "de-CH": "auf Spotify anhören", en: "listen on Spotify", fr: "écouter sur Spotify", pt: "ouvir no Spotify" },
|
||||
};
|
||||
|
||||
function t(schluessel) {
|
||||
const eintrag = I18N_CORE[schluessel];
|
||||
if (!eintrag) return schluessel;
|
||||
const sprache = getSprache();
|
||||
return eintrag[sprache] || eintrag.de || schluessel;
|
||||
}
|
||||
|
||||
/* Elemente mit data-i18n="schluessel" übersetzen — Wörterbuch kommt aus
|
||||
window.I18N_PAGE (seiteneigen, z.B. assets/js/i18n-index.js). Fehlt
|
||||
der Schlüssel oder die Sprache, bleibt der bestehende (deutsche) Text
|
||||
einfach stehen, statt kaputtzugehen. */
|
||||
function applyTranslations() {
|
||||
const sprache = getSprache();
|
||||
document.documentElement.setAttribute("lang", sprache);
|
||||
|
||||
const seitenWoerterbuch = window.I18N_PAGE || {};
|
||||
document.querySelectorAll("[data-i18n]").forEach((el) => {
|
||||
const eintrag = seitenWoerterbuch[el.getAttribute("data-i18n")];
|
||||
if (!eintrag) return;
|
||||
const text = eintrag[sprache] || eintrag.de;
|
||||
if (text) el.innerHTML = text;
|
||||
});
|
||||
|
||||
// data-i18n-attr="alt:schluessel;title:andererSchluessel" — für Attribute
|
||||
// statt Textinhalt (z.B. Bild-Alt-Texte).
|
||||
document.querySelectorAll("[data-i18n-attr]").forEach((el) => {
|
||||
el.getAttribute("data-i18n-attr")
|
||||
.split(";")
|
||||
.map((teil) => teil.trim())
|
||||
.filter(Boolean)
|
||||
.forEach((teil) => {
|
||||
const [attr, schluessel] = teil.split(":");
|
||||
const eintrag = seitenWoerterbuch[schluessel];
|
||||
if (!eintrag) return;
|
||||
const text = eintrag[sprache] || eintrag.de;
|
||||
if (text) el.setAttribute(attr, text);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* ---------- Navigationsstruktur (an einer Stelle pflegen) ---------- */
|
||||
const NAV = [
|
||||
{ label: "Start", href: "index.html" },
|
||||
{ key: "nav_start", href: "index.html" },
|
||||
{
|
||||
label: "DogFather",
|
||||
key: "nav_dogfather",
|
||||
children: [
|
||||
{ label: "Die Person", href: "dogfather.html" },
|
||||
{ label: "Streamer", href: "streamer.html" },
|
||||
{ label: "Casper", href: "casper.html" },
|
||||
{ label: "VanVan", href: "vanvan.html" },
|
||||
{ label: "Zeitreise", href: "zeitreise.html" },
|
||||
{ key: "nav_dogfather_person", href: "dogfather.html" },
|
||||
{ key: "nav_dogfather_streamer", href: "streamer.html" },
|
||||
{ key: "nav_dogfather_casper", href: "casper.html" },
|
||||
{ key: "nav_dogfather_vanvan", href: "vanvan.html" },
|
||||
{ key: "nav_dogfather_zeitreise", href: "zeitreise.html" },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "HasiDog",
|
||||
key: "nav_hasidog",
|
||||
children: [
|
||||
{ label: "HasiDog-Welt", href: "hasidog.html" },
|
||||
{ label: "Modi-Team", href: "team-modis.html" },
|
||||
{ label: "Community", href: "community.html" },
|
||||
{ label: "Stimmen", href: "stimmen.html" },
|
||||
{ key: "nav_hasidog_welt", href: "hasidog.html" },
|
||||
{ key: "nav_hasidog_modi", href: "team-modis.html" },
|
||||
{ key: "nav_hasidog_community", href: "community.html" },
|
||||
{ key: "nav_hasidog_stimmen", href: "stimmen.html" },
|
||||
// Streamplan zurück unter HasiDog — Wunsch Dogi.
|
||||
{ label: "Streamplan", href: "streamplan.html" },
|
||||
{ key: "nav_hasidog_streamplan", href: "streamplan.html" },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Manager",
|
||||
key: "nav_manager",
|
||||
children: [
|
||||
{ label: "Manager DogFather", href: "manager.html" },
|
||||
{ label: "Scout-Team", href: "team-scouts.html" },
|
||||
{ label: "Creator", href: "creator.html" },
|
||||
{ label: "Werte", href: "werte.html" },
|
||||
{ label: "Bewerben", href: "bewerben.html" },
|
||||
{ key: "nav_manager_dogfather", href: "manager.html" },
|
||||
{ key: "nav_manager_scouts", href: "team-scouts.html" },
|
||||
{ key: "nav_manager_creator", href: "creator.html" },
|
||||
{ key: "nav_manager_werte", href: "werte.html" },
|
||||
{ key: "nav_manager_bewerben", href: "bewerben.html" },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -47,14 +202,14 @@
|
||||
// Foto/Video/Aktionen getrennt zu sein — Wunsch von Dogi: pro Welt
|
||||
// (DogFather/HasiDog/Casper) gibt es EINE Seite mit allem
|
||||
// kategorisiert (Fotos, Videos, Events), siehe medien-*.html.
|
||||
label: "Medien",
|
||||
key: "nav_medien",
|
||||
children: [
|
||||
{ label: "DogFather", href: "medien-dogfather.html" },
|
||||
{ label: "HasiDog", href: "medien-hasidog.html" },
|
||||
{ label: "Casper", href: "medien-casper.html" },
|
||||
{ key: "nav_medien_dogfather", href: "medien-dogfather.html" },
|
||||
{ key: "nav_medien_hasidog", href: "medien-hasidog.html" },
|
||||
{ key: "nav_medien_casper", href: "medien-casper.html" },
|
||||
],
|
||||
},
|
||||
{ label: "Links", href: "links.html" },
|
||||
{ key: "nav_links", href: "links.html" },
|
||||
];
|
||||
|
||||
/* Aktuelle Datei — wird beim nahtlosen Seitenwechsel mit aktualisiert. */
|
||||
@@ -66,23 +221,41 @@
|
||||
|
||||
function renderNavItem(item) {
|
||||
if (!item.children) {
|
||||
return `<a class="nav-flat${isActive(item.href) ? " active" : ""}" href="${item.href}">${item.label}</a>`;
|
||||
return `<a class="nav-flat${isActive(item.href) ? " active" : ""}" href="${item.href}">${t(item.key)}</a>`;
|
||||
}
|
||||
const activeChild = item.children.some((c) => isActive(c.href));
|
||||
return `
|
||||
<div class="nav-group${activeChild ? " open-hint" : ""}">
|
||||
<button type="button" aria-expanded="false">${item.label} <span aria-hidden="true">▾</span></button>
|
||||
<button type="button" aria-expanded="false">${t(item.key)} <span aria-hidden="true">▾</span></button>
|
||||
<div class="nav-dropdown">
|
||||
${item.children
|
||||
.map(
|
||||
(c) =>
|
||||
`<a href="${c.href}"${isActive(c.href) ? ' class="active"' : ""}>${c.label}</a>`
|
||||
`<a href="${c.href}"${isActive(c.href) ? ' class="active"' : ""}>${t(c.key)}</a>`
|
||||
)
|
||||
.join("")}
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
/* Sprachumschalter — eigener nav-group-artiger Dropdown, zeigt die
|
||||
aktuell gewählte Sprache (Flagge + Kürzel) und listet beim Klick die
|
||||
übrigen 4 Sprachen auf. */
|
||||
function renderSprachSchalter() {
|
||||
const aktuell = getSprache();
|
||||
const aktiv = SPRACHEN.find((s) => s.code === aktuell) || SPRACHEN[0];
|
||||
return `
|
||||
<div class="nav-group sprach-schalter">
|
||||
<button type="button" aria-expanded="false" aria-label="${t("sprache_aria")}">${aktiv.flagge} ${aktiv.kurz} <span aria-hidden="true">▾</span></button>
|
||||
<div class="nav-dropdown">
|
||||
${SPRACHEN.map(
|
||||
(s) =>
|
||||
`<a href="#" data-sprache="${s.code}"${s.code === aktuell ? ' class="active"' : ""}>${s.flagge} ${s.kurz}</a>`
|
||||
).join("")}
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function renderHeader() {
|
||||
const el = document.getElementById("site-header");
|
||||
if (!el) return;
|
||||
@@ -92,13 +265,14 @@
|
||||
<a class="brand" href="index.html">
|
||||
<img class="brand-logo" src="assets/img/logo-dogfather.png" alt="DogFather Logo" />
|
||||
<span>DOGFATHER UNIVERSE
|
||||
<small>Streamer · Community · HasiDog · Manager</small>
|
||||
<small>${t("brand_tagline")}</small>
|
||||
</span>
|
||||
</a>
|
||||
<button class="nav-toggle" type="button" aria-label="Menü öffnen" aria-expanded="false">☰</button>
|
||||
<button class="nav-toggle" type="button" aria-label="${t("nav_toggle_aria")}" aria-expanded="false">☰</button>
|
||||
<nav class="nav-links">
|
||||
${NAV.map(renderNavItem).join("")}
|
||||
<a class="nav-cta" href="bewerben.html"><span>Bewerben 🩵</span></a>
|
||||
${renderSprachSchalter()}
|
||||
<a class="nav-cta" href="bewerben.html"><span>${t("nav_cta_bewerben")}</span></a>
|
||||
</nav>
|
||||
</div>
|
||||
</header>`;
|
||||
@@ -120,6 +294,12 @@
|
||||
});
|
||||
});
|
||||
|
||||
el.querySelectorAll(".sprach-schalter [data-sprache]").forEach((link) => {
|
||||
link.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
setSprache(link.dataset.sprache);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* Klick außerhalb schließt offene Menüs. Bewusst NUR EINMAL angemeldet —
|
||||
@@ -142,43 +322,43 @@
|
||||
<div>
|
||||
<div class="brand"><span class="heart">🩵</span> DOGFATHER UNIVERSE</div>
|
||||
<p class="small" style="margin-top:.8rem;max-width:32ch;">
|
||||
Streamer. Community. HasiDog. Manager. Gemeinsam stark.
|
||||
${t("footer_tagline")}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4>DogFather</h4>
|
||||
<ul>
|
||||
<li><a href="dogfather.html">Die Person</a></li>
|
||||
<li><a href="streamer.html">Streamer</a></li>
|
||||
<li><a href="casper.html">Casper</a></li>
|
||||
<li><a href="vanvan.html">VanVan</a></li>
|
||||
<li><a href="zeitreise.html">Zeitreise</a></li>
|
||||
<li><a href="dogfather.html">${t("nav_dogfather_person")}</a></li>
|
||||
<li><a href="streamer.html">${t("nav_dogfather_streamer")}</a></li>
|
||||
<li><a href="casper.html">${t("nav_dogfather_casper")}</a></li>
|
||||
<li><a href="vanvan.html">${t("nav_dogfather_vanvan")}</a></li>
|
||||
<li><a href="zeitreise.html">${t("nav_dogfather_zeitreise")}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4>HasiDog & Manager</h4>
|
||||
<h4>${t("footer_h4_hasidog_manager")}</h4>
|
||||
<ul>
|
||||
<li><a href="hasidog.html">HasiDog-Welt</a></li>
|
||||
<li><a href="team-modis.html">Modi-Team</a></li>
|
||||
<li><a href="community.html">Community</a></li>
|
||||
<li><a href="stimmen.html">Stimmen</a></li>
|
||||
<li><a href="streamplan.html">Streamplan</a></li>
|
||||
<li><a href="manager.html">Manager DogFather</a></li>
|
||||
<li><a href="team-scouts.html">Scouts</a></li>
|
||||
<li><a href="hasidog.html">${t("nav_hasidog_welt")}</a></li>
|
||||
<li><a href="team-modis.html">${t("nav_hasidog_modi")}</a></li>
|
||||
<li><a href="community.html">${t("nav_hasidog_community")}</a></li>
|
||||
<li><a href="stimmen.html">${t("nav_hasidog_stimmen")}</a></li>
|
||||
<li><a href="streamplan.html">${t("nav_hasidog_streamplan")}</a></li>
|
||||
<li><a href="manager.html">${t("nav_manager_dogfather")}</a></li>
|
||||
<li><a href="team-scouts.html">${t("footer_scouts")}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Mehr</h4>
|
||||
<h4>${t("footer_h4_mehr")}</h4>
|
||||
<ul>
|
||||
<li><a href="links.html">Alle Links</a></li>
|
||||
<li><a href="bewerben.html">Bewerben</a></li>
|
||||
<li><a href="kontakt.html">Kontakt</a></li>
|
||||
<li><a href="links.html">${t("footer_alle_links")}</a></li>
|
||||
<li><a href="bewerben.html">${t("nav_manager_bewerben")}</a></li>
|
||||
<li><a href="kontakt.html">${t("footer_kontakt")}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container footer-bottom">
|
||||
<span>© ${year} DogFather Universe. Team Dogi ist Familie 🩵</span>
|
||||
<span><a href="kontakt.html">Impressum & Datenschutz</a></span>
|
||||
<span>${t("footer_copyright").replace("{jahr}", year)}</span>
|
||||
<span><a href="kontakt.html">${t("footer_impressum")}</a></span>
|
||||
</div>
|
||||
</footer>`;
|
||||
}
|
||||
@@ -228,22 +408,22 @@
|
||||
widget.innerHTML = `
|
||||
<div class="music-panel" id="music-panel" hidden>
|
||||
<div class="music-panel-head">
|
||||
<strong>Musik von Team Dogi 🎵</strong>
|
||||
<button class="music-close" id="music-close" type="button" aria-label="Musik-Feld schließen">✕</button>
|
||||
<strong id="music-title-text">${t("music_title")}</strong>
|
||||
<button class="music-close" id="music-close" type="button" aria-label="${t("music_close_aria")}">✕</button>
|
||||
</div>
|
||||
<p class="small muted" style="margin:.2rem 0 .6rem;">Läuft weiter, solange du auf dieser Seite bleibst. 🩵</p>
|
||||
<p class="small muted" id="music-intro-text" style="margin:.2rem 0 .6rem;">${t("music_intro")}</p>
|
||||
${SPOTIFY_ARTISTS.map(
|
||||
(a) => `
|
||||
<p class="music-artist-label">${a.name}</p>
|
||||
<iframe data-src="https://open.spotify.com/embed/artist/${a.id}?utm_source=generator&theme=0"
|
||||
height="152" loading="lazy" title="${a.name} auf Spotify anhören"
|
||||
height="152" loading="lazy" data-artist="${a.name}" title="${a.name} ${t("music_spotify_suffix")}"
|
||||
allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture"
|
||||
allowfullscreen></iframe>`
|
||||
).join("")}
|
||||
</div>
|
||||
<button class="music-toggle" id="music-toggle" type="button"
|
||||
aria-expanded="false" aria-controls="music-panel"
|
||||
title="Musik von Hasidog & Van-Van"><span>🎵</span></button>`;
|
||||
title="${t("music_toggle_title")}"><span>🎵</span></button>`;
|
||||
document.body.appendChild(widget);
|
||||
|
||||
const panel = document.getElementById("music-panel");
|
||||
@@ -271,6 +451,23 @@
|
||||
});
|
||||
}
|
||||
|
||||
/* Das Musik-Widget wird nur EINMAL erzeugt (damit der laufende Player
|
||||
beim Seitenwechsel nicht abreißt) — bei Sprachwechsel deshalb nicht
|
||||
neu rendern, sondern nur die Texte/Attribute darin austauschen. */
|
||||
function applyMusicWidgetSprache() {
|
||||
const titel = document.getElementById("music-title-text");
|
||||
if (titel) titel.textContent = t("music_title");
|
||||
const schliessen = document.getElementById("music-close");
|
||||
if (schliessen) schliessen.setAttribute("aria-label", t("music_close_aria"));
|
||||
const intro = document.getElementById("music-intro-text");
|
||||
if (intro) intro.textContent = t("music_intro");
|
||||
const toggle = document.getElementById("music-toggle");
|
||||
if (toggle) toggle.setAttribute("title", t("music_toggle_title"));
|
||||
document.querySelectorAll("#music-widget iframe[data-artist]").forEach((f) => {
|
||||
f.setAttribute("title", `${f.dataset.artist} ${t("music_spotify_suffix")}`);
|
||||
});
|
||||
}
|
||||
|
||||
/* ===================================================================
|
||||
Musik-Knopf: Chamäleon-Farben
|
||||
|
||||
@@ -487,6 +684,11 @@
|
||||
}
|
||||
|
||||
alterInhalt.replaceWith(neuerInhalt);
|
||||
// Seiteneigenes i18n-Wörterbuch zurücksetzen — sonst könnte das der
|
||||
// VORHERIGEN Seite (z.B. Startseite) fälschlich auf der neuen Seite
|
||||
// weiterwirken. Hat die neue Seite ein eigenes (z.B. i18n-index.js),
|
||||
// setzt skripteUebernehmen() es gleich neu.
|
||||
window.I18N_PAGE = null;
|
||||
|
||||
// Seitenmotiv + Sonderklassen mitnehmen: Die Bildvariablen hängen am
|
||||
// <body>, damit das Motiv die ganze Seite trägt — beim Wechsel also mit
|
||||
@@ -521,6 +723,7 @@
|
||||
musikKnopfFarbenAnpassen(); // Chamäleon-Knopf an die neue Seite anpassen
|
||||
|
||||
await skripteUebernehmen(dok);
|
||||
applyTranslations(); // seiteneigene data-i18n-Elemente der neuen Seite übersetzen
|
||||
}
|
||||
|
||||
function nahtloseNavigationAktivieren() {
|
||||
@@ -569,5 +772,23 @@
|
||||
renderMusicWidget();
|
||||
musikKnopfFarbenAnpassen();
|
||||
nahtloseNavigationAktivieren();
|
||||
applyTranslations(); // seiteneigene data-i18n-Elemente (z.B. Startseite) übersetzen
|
||||
});
|
||||
|
||||
/* Kleine öffentliche Schnittstelle für seiteneigene Inline-Skripte
|
||||
(z.B. der Live-Status auf index.html), die außerhalb dieser IIFE
|
||||
ebenfalls die aktuelle Sprache übersetzen wollen. */
|
||||
window.dogiSprache = getSprache;
|
||||
window.dogiUebersetzen = function (schluessel, ersetzungen) {
|
||||
const eintrag = (window.I18N_PAGE || {})[schluessel];
|
||||
if (!eintrag) return schluessel;
|
||||
const sprache = getSprache();
|
||||
let text = eintrag[sprache] || eintrag.de || schluessel;
|
||||
if (ersetzungen) {
|
||||
Object.keys(ersetzungen).forEach((platzhalter) => {
|
||||
text = text.replace(`{${platzhalter}}`, ersetzungen[platzhalter]);
|
||||
});
|
||||
}
|
||||
return text;
|
||||
};
|
||||
})();
|
||||
|
||||
+81
-62
@@ -49,34 +49,34 @@
|
||||
</div>
|
||||
<div class="container">
|
||||
<span class="eyebrow">🩵 DOGFATHER UNIVERSE</span>
|
||||
<h1>Streamer. Community. HasiDog. Manager.<br>Gemeinsam stark.</h1>
|
||||
<p class="lead worlds">Drei Welten, eine Familie: Team Dogi.</p>
|
||||
<h1 data-i18n="idx_hero_h1">Streamer. Community. HasiDog. Manager.<br>Gemeinsam stark.</h1>
|
||||
<p class="lead worlds" data-i18n="idx_hero_lead">Drei Welten, eine Familie: Team Dogi.</p>
|
||||
|
||||
<div class="card" style="max-width:420px;margin:1.4rem auto 0;padding:1rem 1.4rem;">
|
||||
<span class="badge rank-1"><span class="live-dot is-unknown" id="live-dot"></span><span id="live-text">Status wird geladen …</span></span>
|
||||
<p class="small" style="margin:.5rem 0 0;">DogFather geht <strong>jeden Tag ab 20 Uhr</strong> live — oft schon tagsüber, zu wechselnden Zeiten. <a href="streamplan.html">Streamplan ansehen →</a></p>
|
||||
<span class="badge rank-1"><span class="live-dot is-unknown" id="live-dot"></span><span id="live-text" data-i18n="idx_live_loading">Status wird geladen …</span></span>
|
||||
<p class="small" data-i18n="idx_live_info" style="margin:.5rem 0 0;">DogFather geht <strong>jeden Tag ab 20 Uhr</strong> live — oft schon tagsüber, zu wechselnden Zeiten. <a href="streamplan.html">Streamplan ansehen →</a></p>
|
||||
</div>
|
||||
|
||||
<div class="btn-row" style="justify-content:center;">
|
||||
<a class="btn btn-primary" href="links.html">Alle Links 🩵</a>
|
||||
<a class="btn btn-outline" href="bewerben.html">Teil vom Team werden</a>
|
||||
<a class="btn btn-primary" href="links.html" data-i18n="idx_hero_btn_links">Alle Links 🩵</a>
|
||||
<a class="btn btn-outline" href="bewerben.html" data-i18n="idx_hero_btn_team">Teil vom Team werden</a>
|
||||
</div>
|
||||
|
||||
<div class="hero-grid">
|
||||
<a class="card" href="dogfather.html" data-theme="dogfather">
|
||||
<span class="tag">Welt 1</span>
|
||||
<span class="tag" data-i18n="idx_hero_card1_tag">Welt 1</span>
|
||||
<h3>DogFather</h3>
|
||||
<p>Streamer, Entertainer, das Herz hinter dem Kanal. Halligalli, Humor und ein offenes Ohr für die Community.</p>
|
||||
<p data-i18n="idx_hero_card1_desc">Streamer, Entertainer, das Herz hinter dem Kanal. Halligalli, Humor und ein offenes Ohr für die Community.</p>
|
||||
</a>
|
||||
<a class="card" href="hasidog.html" data-theme="hasidog">
|
||||
<span class="tag">Welt 2</span>
|
||||
<span class="tag" data-i18n="idx_hero_card2_tag">Welt 2</span>
|
||||
<h3>HasiDog</h3>
|
||||
<p>Die Community, das Maskottchen und Husky Casper — die verspielte, familiäre Seite von Team Dogi.</p>
|
||||
<p data-i18n="idx_hero_card2_desc">Die Community, das Maskottchen und Husky Casper — die verspielte, familiäre Seite von Team Dogi.</p>
|
||||
</a>
|
||||
<a class="card" href="manager.html" data-theme="spicymedia">
|
||||
<span class="tag">Welt 3</span>
|
||||
<span class="tag" data-i18n="idx_hero_card3_tag">Welt 3</span>
|
||||
<h3>Manager DogFather</h3>
|
||||
<p>Als Manager bei Spicy Media: Scouts, Creator und faire Zusammenarbeit auf Augenhöhe.</p>
|
||||
<p data-i18n="idx_hero_card3_desc">Als Manager bei Spicy Media: Scouts, Creator und faire Zusammenarbeit auf Augenhöhe.</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -85,9 +85,9 @@
|
||||
<!-- ================= CHARAKTERE: DOGFATHER-HUSKY & HASIDOG-HASE ================= -->
|
||||
<section class="section-tight">
|
||||
<div class="container text-center">
|
||||
<span class="eyebrow">🩵 Die Gesichter der Welten</span>
|
||||
<span class="eyebrow" data-i18n="idx_char_eyebrow">🩵 Die Gesichter der Welten</span>
|
||||
<h2>DogFather & HasiDog</h2>
|
||||
<p class="lead" style="max-width:52ch;margin:0 auto 2.4rem;">Zwei Charaktere, ein Universum — klick dich in ihre Welt.</p>
|
||||
<p class="lead" data-i18n="idx_char_lead" style="max-width:52ch;margin:0 auto 2.4rem;">Zwei Charaktere, ein Universum — klick dich in ihre Welt.</p>
|
||||
|
||||
<div class="char-showcase">
|
||||
<a class="char-card dogfather" href="streamer.html">
|
||||
@@ -95,8 +95,8 @@
|
||||
alt="DogFather — Husky mit blauem Hoodie und Cap" />
|
||||
<span class="char-meta">
|
||||
<span class="char-name">DogFather</span>
|
||||
<span class="char-sub">Streamer · Entertainer · Welt 1</span>
|
||||
<span class="char-go">Zur Welt →</span>
|
||||
<span class="char-sub" data-i18n="idx_char1_sub">Streamer · Entertainer · Welt 1</span>
|
||||
<span class="char-go" data-i18n="idx_char_go">Zur Welt →</span>
|
||||
</span>
|
||||
</a>
|
||||
<a class="char-card hasidog" href="hasidog.html">
|
||||
@@ -104,8 +104,8 @@
|
||||
alt="HasiDog — grauer Hase mit schwarzem Hoodie und Cap" />
|
||||
<span class="char-meta">
|
||||
<span class="char-name">HasiDog</span>
|
||||
<span class="char-sub">Community · Maskottchen · Welt 2</span>
|
||||
<span class="char-go">Zur Welt →</span>
|
||||
<span class="char-sub" data-i18n="idx_char2_sub">Community · Maskottchen · Welt 2</span>
|
||||
<span class="char-go" data-i18n="idx_char_go">Zur Welt →</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
@@ -115,7 +115,7 @@
|
||||
<!-- ================= FOTO-COLLAGE: DOGFATHER & CASPER ================= -->
|
||||
<section class="section-tight">
|
||||
<div class="container text-center">
|
||||
<span class="eyebrow">🩵 Gesichter hinter dem Universum</span>
|
||||
<span class="eyebrow" data-i18n="idx_collage_eyebrow">🩵 Gesichter hinter dem Universum</span>
|
||||
<h2>DogFather & Casper</h2>
|
||||
<div class="collage-wrap" id="collage-wrap">
|
||||
<div class="collage-item">
|
||||
@@ -128,18 +128,18 @@
|
||||
</div>
|
||||
<div class="collage-item">
|
||||
<div class="collage-photo frame-silver"><img class="collage-img" data-fallback="DogFather & Casper" src="assets/img/dogfather-casper-1.jpg" alt="DogFather und Casper zusammen" style="object-position:center 18%;"></div>
|
||||
<p class="collage-caption">Team 🩵🐾</p>
|
||||
<p class="collage-caption" data-i18n="idx_collage_cap_team">Team 🩵🐾</p>
|
||||
</div>
|
||||
<div class="collage-item">
|
||||
<div class="collage-photo frame-gold"><img class="collage-img" data-fallback="Casper" src="assets/img/casper-2.jpg" alt="Casper"></div>
|
||||
<p class="collage-caption">Husky-Life</p>
|
||||
<p class="collage-caption" data-i18n="idx_collage_cap_huskylife">Husky-Life</p>
|
||||
</div>
|
||||
<div class="collage-item">
|
||||
<div class="collage-photo frame-tuerkis"><img class="collage-img" data-fallback="DogFather & Casper" src="assets/img/dogfather-casper-2.jpg" alt="DogFather und Casper Nase an Nase"></div>
|
||||
<p class="collage-caption">Nase an Nase 🩵</p>
|
||||
<p class="collage-caption" data-i18n="idx_collage_cap_nose">Nase an Nase 🩵</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="small muted" style="max-width:50ch;margin:0 auto;">DogFather & Casper — die zwei Gesichter hinter dem ganzen Universum. 🩵🐾</p>
|
||||
<p class="small muted" data-i18n="idx_collage_footer" style="max-width:50ch;margin:0 auto;">DogFather & Casper — die zwei Gesichter hinter dem ganzen Universum. 🩵🐾</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -147,10 +147,10 @@
|
||||
<section class="section-tight">
|
||||
<div class="container">
|
||||
<div class="grid grid-4" id="stats-bar">
|
||||
<div class="card text-center"><h3 id="stat-team">–</h3><p class="small muted">Menschen im Team Dogi</p></div>
|
||||
<div class="card text-center"><h3>Täglich</h3><p class="small muted">live ab 20 Uhr</p></div>
|
||||
<div class="card text-center"><h3>3</h3><p class="small muted">Welten, eine Familie</p></div>
|
||||
<div class="card text-center"><h3>🩵</h3><p class="small muted">Team Dogi ist Familie</p></div>
|
||||
<div class="card text-center"><h3 id="stat-team">–</h3><p class="small muted" data-i18n="idx_stats_team">Menschen im Team Dogi</p></div>
|
||||
<div class="card text-center"><h3 data-i18n="idx_stats_daily_label">Täglich</h3><p class="small muted" data-i18n="idx_stats_daily_desc">live ab 20 Uhr</p></div>
|
||||
<div class="card text-center"><h3>3</h3><p class="small muted" data-i18n="idx_stats_worlds">Welten, eine Familie</p></div>
|
||||
<div class="card text-center"><h3>🩵</h3><p class="small muted" data-i18n="idx_stats_family">Team Dogi ist Familie</p></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -158,17 +158,17 @@
|
||||
<!-- ================= WAS DICH ERWARTET ================= -->
|
||||
<section>
|
||||
<div class="container">
|
||||
<span class="eyebrow text-center" style="display:block;text-align:center;">Ein bisschen von allem</span>
|
||||
<h2 class="text-center">Was dich im Universum erwartet</h2>
|
||||
<span class="eyebrow text-center" data-i18n="idx_expect_eyebrow" style="display:block;text-align:center;">Ein bisschen von allem</span>
|
||||
<h2 class="text-center" data-i18n="idx_expect_h2">Was dich im Universum erwartet</h2>
|
||||
<div class="grid grid-4">
|
||||
<a class="card" href="streamer.html"><h3>🎥 Streamer</h3><p class="small">Halligalli, Humor & Hasencontent.</p></a>
|
||||
<a class="card" href="zeitreise.html"><h3>🕰️ Zeitreise</h3><p class="small">Die Geschichte von DogFather & Team Dogi.</p></a>
|
||||
<a class="card" href="community.html"><h3>🩵 Community</h3><p class="small">Team Dogi ist Familie.</p></a>
|
||||
<a class="card" href="casper.html"><h3>🐾 Casper</h3><p class="small">Der Husky an DogFathers Seite.</p></a>
|
||||
<a class="card" href="team-modis.html"><h3>🧑🤝🧑 Modi-Team</h3><p class="small">VanVan, Diene & Co.</p></a>
|
||||
<a class="card" href="medien-dogfather.html"><h3>🖼️ Medien: DogFather</h3><p class="small">Fotos, Videos & Events.</p></a>
|
||||
<a class="card" href="medien-hasidog.html"><h3>🐰 Medien: HasiDog</h3><p class="small">Fotos, Videos & Events.</p></a>
|
||||
<a class="card" href="medien-casper.html"><h3>🐺 Medien: Casper</h3><p class="small">Fotos, Videos & Events.</p></a>
|
||||
<a class="card" href="streamer.html"><h3 data-i18n="idx_expect_c1_h3">🎥 Streamer</h3><p class="small" data-i18n="idx_expect_c1_p">Halligalli, Humor & Hasencontent.</p></a>
|
||||
<a class="card" href="zeitreise.html"><h3 data-i18n="idx_expect_c2_h3">🕰️ Zeitreise</h3><p class="small" data-i18n="idx_expect_c2_p">Die Geschichte von DogFather & Team Dogi.</p></a>
|
||||
<a class="card" href="community.html"><h3 data-i18n="idx_expect_c3_h3">🩵 Community</h3><p class="small" data-i18n="idx_expect_c3_p">Team Dogi ist Familie.</p></a>
|
||||
<a class="card" href="casper.html"><h3 data-i18n="idx_expect_c4_h3">🐾 Casper</h3><p class="small" data-i18n="idx_expect_c4_p">Der Husky an DogFathers Seite.</p></a>
|
||||
<a class="card" href="team-modis.html"><h3 data-i18n="idx_expect_c5_h3">🧑🤝🧑 Modi-Team</h3><p class="small" data-i18n="idx_expect_c5_p">VanVan, Diene & Co.</p></a>
|
||||
<a class="card" href="medien-dogfather.html"><h3 data-i18n="idx_expect_c6_h3">🖼️ Medien: DogFather</h3><p class="small" data-i18n="idx_expect_media_p">Fotos, Videos & Events.</p></a>
|
||||
<a class="card" href="medien-hasidog.html"><h3 data-i18n="idx_expect_c7_h3">🐰 Medien: HasiDog</h3><p class="small" data-i18n="idx_expect_media_p">Fotos, Videos & Events.</p></a>
|
||||
<a class="card" href="medien-casper.html"><h3 data-i18n="idx_expect_c8_h3">🐺 Medien: Casper</h3><p class="small" data-i18n="idx_expect_media_p">Fotos, Videos & Events.</p></a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -176,12 +176,12 @@
|
||||
<!-- ================= TEAM PREVIEW ================= -->
|
||||
<section class="section-tight team-bg">
|
||||
<div class="container">
|
||||
<h2 class="text-center">Team Dogi 🩵</h2>
|
||||
<p class="lead text-center" style="max-width:60ch;margin:0 auto;">Von VanVan bis zu den Scouts — die Menschen, die DOGFATHER UNIVERSE tragen.</p>
|
||||
<h2 class="text-center" data-i18n="idx_team_h2">Team Dogi 🩵</h2>
|
||||
<p class="lead text-center" data-i18n="idx_team_lead" style="max-width:60ch;margin:0 auto;">Von VanVan bis zu den Scouts — die Menschen, die DOGFATHER UNIVERSE tragen.</p>
|
||||
<div id="team-preview" class="grid grid-4"></div>
|
||||
<div class="btn-row" style="justify-content:center;">
|
||||
<a class="btn btn-outline" href="team-modis.html">Modi-Team ansehen</a>
|
||||
<a class="btn btn-outline" href="team-scouts.html">Scout-Team ansehen</a>
|
||||
<a class="btn btn-outline" href="team-modis.html" data-i18n="idx_team_btn_modi">Modi-Team ansehen</a>
|
||||
<a class="btn btn-outline" href="team-scouts.html" data-i18n="idx_team_btn_scouts">Scout-Team ansehen</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -189,10 +189,10 @@
|
||||
<!-- ================= AKTIONEN TEASER ================= -->
|
||||
<section>
|
||||
<div class="container">
|
||||
<h2 class="text-center">Was gerade läuft</h2>
|
||||
<h2 class="text-center" data-i18n="idx_aktionen_h2">Was gerade läuft</h2>
|
||||
<div id="aktionen-teaser" class="grid grid-3"></div>
|
||||
<div class="btn-row" style="justify-content:center;">
|
||||
<a class="btn btn-outline" href="medien-dogfather.html#events">Alle Aktionen & Projekte</a>
|
||||
<a class="btn btn-outline" href="medien-dogfather.html#events" data-i18n="idx_aktionen_btn">Alle Aktionen & Projekte</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -200,7 +200,7 @@
|
||||
<!-- ================= GALERIE TEASER ================= -->
|
||||
<section class="section-tight">
|
||||
<div class="container">
|
||||
<h2 class="text-center">Impressionen</h2>
|
||||
<h2 class="text-center" data-i18n="idx_galerie_h2">Impressionen</h2>
|
||||
<div class="grid grid-4">
|
||||
<div class="collage-photo" style="aspect-ratio:1;border-radius:var(--radius);"><img src="assets/img/casper-3.jpg" alt="Casper" style="width:100%;height:100%;object-fit:cover;object-position:center 20%;" /></div>
|
||||
<div class="collage-photo frame-lila" style="aspect-ratio:1;border-radius:var(--radius);"><img src="assets/img/card-vanvan.jpg" alt="VanVan" style="width:100%;height:100%;object-fit:cover;" /></div>
|
||||
@@ -208,7 +208,7 @@
|
||||
<div class="collage-photo frame-gold" style="aspect-ratio:1;border-radius:var(--radius);"><img src="assets/img/card-dogfather.jpg" alt="DogFather" style="width:100%;height:100%;object-fit:cover;" /></div>
|
||||
</div>
|
||||
<div class="btn-row" style="justify-content:center;">
|
||||
<a class="btn btn-outline" href="medien-dogfather.html">Zur ganzen Galerie</a>
|
||||
<a class="btn btn-outline" href="medien-dogfather.html" data-i18n="idx_galerie_btn">Zur ganzen Galerie</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -216,13 +216,13 @@
|
||||
<!-- ================= TESTIMONIAL ================= -->
|
||||
<section>
|
||||
<div class="container text-center">
|
||||
<span class="eyebrow">Was andere sagen</span>
|
||||
<span class="eyebrow" data-i18n="idx_testimonial_eyebrow">Was andere sagen</span>
|
||||
<div class="card" style="max-width:640px;margin:1rem auto 0;">
|
||||
<p class="quote" style="font-size:1.15rem;">„Hier stehen bald echte Stimmen aus der Community. 🩵"</p>
|
||||
<p class="small muted">— Team Dogi</p>
|
||||
<p class="quote" data-i18n="idx_testimonial_quote" style="font-size:1.15rem;">„Hier stehen bald echte Stimmen aus der Community. 🩵"</p>
|
||||
<p class="small muted" data-i18n="idx_testimonial_attrib">— Team Dogi</p>
|
||||
</div>
|
||||
<div class="btn-row" style="justify-content:center;">
|
||||
<a class="btn btn-outline" href="stimmen.html">Mehr Stimmen</a>
|
||||
<a class="btn btn-outline" href="stimmen.html" data-i18n="idx_testimonial_btn">Mehr Stimmen</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -232,12 +232,12 @@
|
||||
<!-- ================= FINALER CTA ================= -->
|
||||
<section class="hero">
|
||||
<div class="container text-center">
|
||||
<span class="eyebrow">🩵 Bereit?</span>
|
||||
<h2>Werde Teil von DOGFATHER UNIVERSE</h2>
|
||||
<p class="lead" style="max-width:56ch;margin:0 auto;">Als Zuschauer:in, Creator, Scout oder Kooperationspartner — hier ist für jeden Platz.</p>
|
||||
<span class="eyebrow" data-i18n="idx_cta_eyebrow">🩵 Bereit?</span>
|
||||
<h2 data-i18n="idx_cta_h2">Werde Teil von DOGFATHER UNIVERSE</h2>
|
||||
<p class="lead" data-i18n="idx_cta_lead" style="max-width:56ch;margin:0 auto;">Als Zuschauer:in, Creator, Scout oder Kooperationspartner — hier ist für jeden Platz.</p>
|
||||
<div class="btn-row" style="justify-content:center;">
|
||||
<a class="btn btn-primary" href="links.html">Alle Links 🩵</a>
|
||||
<a class="btn btn-secondary" href="bewerben.html">Jetzt bewerben</a>
|
||||
<a class="btn btn-primary" href="links.html" data-i18n="idx_cta_btn_links">Alle Links 🩵</a>
|
||||
<a class="btn btn-secondary" href="bewerben.html" data-i18n="idx_cta_btn_bewerben">Jetzt bewerben</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -247,6 +247,7 @@
|
||||
<script src="assets/js/data-modis.js"></script>
|
||||
<script src="assets/js/data-scouts.js"></script>
|
||||
<script src="assets/js/data-aktionen.js"></script>
|
||||
<script src="assets/js/i18n-index.js"></script>
|
||||
<script src="assets/js/main.js"></script>
|
||||
<script>
|
||||
// Gleiche Worker-URL wie in assets/js/forms.js / postfach.html eintragen,
|
||||
@@ -277,19 +278,36 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
const liveText = document.getElementById("live-text");
|
||||
|
||||
if (API_BASE_URL && liveDot && liveText) {
|
||||
// Übersetzter Text hängt vom Live-Zustand ab (nicht per data-i18n
|
||||
// abbildbar) — letzten bekannten Zustand merken, damit ein
|
||||
// Sprachwechsel den Text sofort neu übersetzen kann, ohne auf den
|
||||
// nächsten 30s-Poll warten zu müssen.
|
||||
let letzterZustand = { status: "loading" };
|
||||
|
||||
const texteNeuSetzen = () => {
|
||||
if (letzterZustand.status === "live") {
|
||||
liveText.textContent = letzterZustand.titel
|
||||
? window.dogiUebersetzen("idx_live_now", { titel: letzterZustand.titel })
|
||||
: window.dogiUebersetzen("idx_live_now_generic");
|
||||
} else if (letzterZustand.status === "offline") {
|
||||
liveText.textContent = window.dogiUebersetzen("idx_live_offline");
|
||||
} else if (letzterZustand.status === "error") {
|
||||
liveText.textContent = window.dogiUebersetzen("idx_live_error");
|
||||
} else {
|
||||
liveText.textContent = window.dogiUebersetzen("idx_live_loading");
|
||||
}
|
||||
};
|
||||
|
||||
liveDot.classList.add("is-unknown");
|
||||
liveText.textContent = "Status wird geladen …";
|
||||
texteNeuSetzen();
|
||||
document.addEventListener("dogi-sprache-geaendert", texteNeuSetzen);
|
||||
|
||||
const applyLiveStatus = (data) => {
|
||||
const isLive = !!(data && data.live);
|
||||
liveDot.classList.remove("is-unknown");
|
||||
liveDot.classList.toggle("is-live", isLive);
|
||||
|
||||
if (isLive) {
|
||||
liveText.textContent = data.title ? `Jetzt live: ${data.title}` : "Jetzt live!";
|
||||
} else {
|
||||
liveText.textContent = "Gerade offline";
|
||||
}
|
||||
letzterZustand = isLive ? { status: "live", titel: data.title } : { status: "offline" };
|
||||
texteNeuSetzen();
|
||||
};
|
||||
|
||||
const refreshLiveStatus = () =>
|
||||
@@ -299,7 +317,8 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
.catch(() => {
|
||||
liveDot.classList.remove("is-live");
|
||||
liveDot.classList.add("is-unknown");
|
||||
liveText.textContent = "Status gerade nicht abrufbar";
|
||||
letzterZustand = { status: "error" };
|
||||
texteNeuSetzen();
|
||||
});
|
||||
|
||||
refreshLiveStatus();
|
||||
|
||||
Reference in New Issue
Block a user