Alle ausstehenden Aenderungen (Bilder, Texte) fuer den Server-Umzug uebernommen

This commit is contained in:
2026-08-05 18:05:53 +02:00
parent 9af0698056
commit e331965bf1
87 changed files with 8296 additions and 309 deletions
+548 -36
View File
@@ -120,8 +120,18 @@ header.site-header {
/* Eigene, etwas breitere Kappung als .container (1180px) — die Nav
braucht durch größere Schrift + mehr Abstand + Polarlicht-Padding
spürbar mehr Platz, ohne dass der restliche Seiteninhalt breiter
werden soll. */
width: min(1400px, 94vw);
werden soll.
Bugfix 04.08.2026: Der feste 1400px-Deckel war zu knapp — der
tatsächliche Inhalt (Logo+Menü+Sprachschalter+DogiCrew-Knopf+
Bewerben-Knopf) braucht bei aufgeklapptem Desktop-Menü (ab 1480px
Breite, siehe Media Query unten) ca. 1417px und lief dadurch IMMER
um ca. 17px über den Rahmen hinaus — auf breiten Bildschirmen ohne
sichtbaren Schaden (genug Luft drumherum), aber bei schmaleren
Fenstern knapp über der 1480px-Schwelle (z.B. Laptop-Fenster nicht
maximiert, oder Browser-Zoom >100%) wurde dadurch der rechte Rand
(der "Bewerben"-Knopf) sichtbar abgeschnitten. 1400px -> 1440px gibt
ausreichend Puffer, ohne auf breiten Screens spürbar größer zu wirken. */
width: min(1440px, 94vw);
margin: 0 auto;
display: flex;
align-items: center;
@@ -579,54 +589,114 @@ header.site-header {
0 0 22px rgba(143, 217, 234, .3),
0 0 22px rgba(217, 74, 92, .28);
}
/* Abo-Button (Supporter-Abo) — gleicher Polarlicht-Mechanismus wie
.nav-cta, aber in Babyblau/Lila (VIP-Anmutung) statt der allgemeinen
Regenbogen-Aurora.
Bugfix 04.08.2026: war Gold/Lila (rgba(212,175,55,...)) — dieser Knopf
erscheint in der Navigationsleiste auf JEDER Seite (auch auf
verwaltung.html, siehe Screenshot-Beschwerde), wurde von der 4. Runde
"überall wo gelb ist, Babyblau benutzen" aber NICHT erfasst, weil er in
main.css/main.js liegt statt in verwaltung.html selbst. Jetzt
nachgezogen: Gold -> Babyblau (rgba(143,217,234,...), derselbe Farbwert
wie beim allgemeinen .nav-cta-Polarlicht oben), Lila unverändert. Der
separate, deutlich größere Gold-VIP-Look von abonnieren.html/
supporter.html/gate.html/links.html/rabattcodes.html ist davon NICHT
betroffen — das ist eine eigenständige, bislang nie angesprochene
Design-Entscheidung für den öffentlichen Supporter-Bereich. */
.nav-cta-abo::before {
background:
radial-gradient(circle at 20% 30%, rgba(143, 217, 234, .95), transparent 55%),
radial-gradient(circle at 78% 70%, rgba(139, 92, 246, .85), transparent 58%);
}
.nav-cta-abo:hover {
box-shadow: 0 10px 26px rgba(0, 0, 0, .45),
0 0 22px rgba(143, 217, 234, .35),
0 0 22px rgba(139, 92, 246, .3);
}
@media (prefers-reduced-motion: reduce) {
.nav-cta::before, .nav-cta::after { animation: none; }
}
/* TikTok-Button: exakt derselbe Polarlicht-Mechanismus wie .nav-cta
(schwarze Pille + wandernde Farbwolken + Lichtschimmer), aber mit den
echten TikTok-Markenfarben (Cyan #25F4EE + Pink/Rot #FE2C55) statt der
allgemeinen Regenbogen-Aurora. Bewusst NUR für echte TikTok-Links
verwendet — keine anderen Social-/CTA-Buttons bekommen diese Farben. */
/* TikTok-Button "Glitch/Duotone" — eigener, klar erkennbarer Stil (nicht
mehr nur eine eingefärbte Kopie von .nav-cta): schwarze Pille mit einem
fließenden Cyan/Pink-Rahmen (klassischer Zwei-Layer-Background-Trick,
NICHT ein rotierender Masken-Ring — der verzerrt sich auf einer
länglichen Pillenform zu einer krummen Schlaufe statt einer sauberen
Kontur), einem dezenten Innenschimmer (KEIN nach außen strahlender
Blur-Wolken-Glow mehr — der hat vorher Text/Bilder drumherum überstrahlt,
Feedback vom 03.08.2026: "geht über den Text und das Bild"), einer
rotierenden Notenkopf-Spielmarke und einem Text mit TikToks
charakteristischem Chromatic-Aberration-/Glitch-Versatz (die Cyan/Rot-
Schattenkopien, die auch im echten TikTok-Logo stecken), der alle paar
Sekunden kurz "springt". Alle Effekte bleiben INNERHALB der Pille bzw.
direkt an ihrer Kante — die Auffälligkeit kommt vom Button selbst, nicht
von seiner Ausstrahlung. Bewusst NUR für echte TikTok-Links — die
Markenfarben (Cyan #25F4EE + Pink/Rot #FE2C55) bleiben exakt gleich. */
.btn-tiktok {
position: relative;
isolation: isolate;
overflow: hidden;
display: inline-flex;
align-items: center;
gap: .5rem;
padding: .85rem 2.1rem;
gap: .6rem;
padding: .85rem 2.2rem;
border-radius: 999px;
color: #fff;
font-weight: 700;
font-size: 1.08rem;
background: #0b0e14;
border: 1px solid rgba(255, 255, 255, .16);
font-weight: 800;
font-size: 1.1rem;
letter-spacing: .01em;
border: 2px solid transparent;
background:
linear-gradient(160deg, #12151b, #05070a 55%, #14171d) padding-box,
linear-gradient(90deg, #25F4EE, #FE2C55, #25F4EE) border-box;
background-size: 100% 100%, 260% 100%;
text-decoration: none;
transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
box-shadow: 0 6px 18px rgba(0, 0, 0, .35);
transition: transform .25s ease, box-shadow .25s ease;
box-shadow: 0 4px 12px rgba(0, 0, 0, .4),
inset 0 0 10px rgba(37, 244, 238, .12),
inset 0 0 10px rgba(254, 44, 85, .1);
animation: btn-tiktok-border-flow 5s linear infinite;
}
.btn-tiktok span {
.btn-tiktok-note {
position: relative;
z-index: 2;
text-shadow: 0 1px 3px rgba(0, 0, 0, .6), 0 0 14px rgba(0, 0, 0, .35);
z-index: 3;
display: inline-block;
font-size: 1.05em;
filter: drop-shadow(0 0 3px rgba(37, 244, 238, .8));
animation: btn-tiktok-spin 3.6s linear infinite;
}
.btn-tiktok-text {
/* Ruhezustand ist bewusst KLAR LESBAR (nur normaler Schlagschatten) —
der Cyan/Rot-Chromatic-Versatz von TikToks Logo erscheint nur ganz
kurz als Flicker (siehe @keyframes btn-tiktok-glitch), nicht dauerhaft,
sonst verschwimmt der Text (Feedback vom 03.08.2026: "kriegt man
TikTok nichtmal richtig gelesen"). */
position: relative;
z-index: 3;
text-shadow: 0 2px 6px rgba(0, 0, 0, .6);
animation: btn-tiktok-glitch 6s ease-in-out infinite;
}
.btn-tiktok::before {
/* Sehr dezentes Farbschimmern INNEN in der Pille — sorgt für Tiefe,
bleibt aber innerhalb der Ränder (kein overflow, kein Blur-Bleed). */
content: "";
position: absolute;
inset: -60%;
inset: 0;
z-index: 0;
border-radius: inherit;
background:
radial-gradient(circle at 22% 30%, rgba(37, 244, 238, .95), transparent 55%),
radial-gradient(circle at 78% 68%, rgba(254, 44, 85, .95), transparent 58%);
filter: blur(9px) saturate(1.35);
radial-gradient(circle at 18% 20%, rgba(37, 244, 238, .3), transparent 60%),
radial-gradient(circle at 85% 80%, rgba(254, 44, 85, .28), transparent 62%);
animation: nav-cta-aurora 9s ease-in-out infinite alternate;
pointer-events: none;
}
.btn-tiktok::after {
/* Diagonaler Lichtschimmer, wandert einmal quer über die Pille */
content: "";
position: absolute;
inset: 0;
z-index: 1;
border-radius: inherit;
background: linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, .4) 49%, transparent 63%);
background-size: 240% 100%;
mix-blend-mode: overlay;
@@ -634,14 +704,39 @@ header.site-header {
pointer-events: none;
}
.btn-tiktok:hover {
transform: translateY(-1px);
border-color: rgba(255, 255, 255, .32);
box-shadow: 0 10px 26px rgba(0, 0, 0, .45),
0 0 22px rgba(37, 244, 238, .35),
0 0 22px rgba(254, 44, 85, .35);
transform: translateY(-1px) scale(1.02);
box-shadow: 0 6px 16px rgba(0, 0, 0, .45),
inset 0 0 14px rgba(37, 244, 238, .2),
inset 0 0 14px rgba(254, 44, 85, .16);
}
@keyframes btn-tiktok-border-flow {
to { background-position: 0 0, -260% 0; }
}
@keyframes btn-tiktok-spin {
to { transform: rotate(360deg); }
}
@keyframes btn-tiktok-glitch {
/* 97% der Zeit klar lesbarer Text — der Chromatic-Versatz blitzt nur für
einen Wimpernschlag (~150ms von 6s) auf, statt dauerhaft zu "verwaschen". */
0%, 96%, 100% {
text-shadow: 0 2px 6px rgba(0, 0, 0, .6);
transform: translateX(0);
}
97% {
text-shadow: -3px 0 rgba(37, 244, 238, .95), 3px 0 rgba(254, 44, 85, .95), 0 2px 6px rgba(0, 0, 0, .6);
transform: translateX(-1px);
}
97.5% {
text-shadow: 3px 0 rgba(37, 244, 238, .95), -3px 0 rgba(254, 44, 85, .95), 0 2px 6px rgba(0, 0, 0, .6);
transform: translateX(1px);
}
98% {
text-shadow: 0 2px 6px rgba(0, 0, 0, .6);
transform: translateX(0);
}
}
@media (prefers-reduced-motion: reduce) {
.btn-tiktok::before, .btn-tiktok::after { animation: none; }
.btn-tiktok, .btn-tiktok::before, .btn-tiktok::after, .btn-tiktok-note, .btn-tiktok-text { animation: none; }
}
/* Silberner "Coming soon"-Button: eigener, deutlich edlerer Look als
@@ -1101,6 +1196,108 @@ header.site-header {
.card-shop { --brand-1: rgba(212, 175, 55, .85); --brand-2: rgba(255, 183, 77, .6); }
.card-bewerben { --brand-1: rgba(143, 217, 234, .85); --brand-2: rgba(139, 92, 246, .8); --brand-3: rgba(217, 74, 92, .5); }
/* "Feature"-Karten (links.html): zwei besondere, GRÖSSERE Kacheln über der
normalen Plattform-Icon-Reihe — Abo-System (VIP: Gold/Lila) und
Rabattcodes (Community-Ersparnis: Grün/Orange). Bauen auf .card-brand
auf (gleicher Aurora-/Schimmer-Mechanismus), bekommen zusätzlich einen
rotierenden Farbring (wie .card-duel) und ein Eckband mit Status-Text,
damit sie sich klar von den kompakten Plattform-Kacheln absetzen. */
.card-feature {
padding: 2.6rem 2rem;
min-height: 230px;
}
.card-feature::before { inset: -70%; }
.card-feature .icon-badge { font-size: 3.1rem; margin-bottom: .8rem; }
.card-feature h3 { font-size: 1.75rem; }
.card-feature-desc {
position: relative;
z-index: 2;
font-size: .96rem;
line-height: 1.55;
color: rgba(255, 255, 255, .8);
margin: .5rem auto 0;
max-width: 32ch;
text-shadow: 0 1px 3px rgba(0, 0, 0, .6), 0 0 14px rgba(0, 0, 0, .3);
}
/* Echtes <span> statt eines dritten Pseudo-Elements (::before/::after sind
an .card-brand schon für Aurora/Schimmer vergeben) — bewusst NICHT
rotiert (siehe .btn-tiktok-Notiz weiter oben: ein rotierender Masken-Ring
verzerrt sich auf länglichen/runden Formen), sondern ein ruhiger,
statischer Farbverlaufs-Rand. */
.card-feature-ring {
position: absolute;
inset: 0;
z-index: 3;
border-radius: inherit;
padding: 1.5px;
background: conic-gradient(from 0deg, var(--brand-1), var(--brand-2), var(--brand-1) 66%, var(--brand-2) 100%);
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
opacity: .8;
pointer-events: none;
}
.card-feature-badge {
position: absolute;
top: 1rem;
right: 1rem;
z-index: 4;
font-size: .66rem;
font-weight: 800;
letter-spacing: .05em;
text-transform: uppercase;
padding: .38rem .75rem;
border-radius: 999px;
background: rgba(8, 10, 14, .55);
border: 1px solid rgba(255, 255, 255, .28);
backdrop-filter: blur(4px);
color: #fff;
}
.card-feature:hover {
transform: translateY(-3px);
}
@media (prefers-reduced-motion: reduce) {
.card-feature { transition: none; }
}
.card-abo { --brand-1: rgba(212, 175, 55, .9); --brand-2: rgba(139, 92, 246, .75); }
.card-abo .card-feature-badge { color: #ffe9a8; border-color: rgba(255, 214, 102, .5); }
.card-rabatt { --brand-1: rgba(52, 211, 153, .9); --brand-2: rgba(251, 146, 60, .8); }
.card-rabatt .card-feature-badge { color: #baf7d6; border-color: rgba(94, 234, 167, .5); }
/* Breite Variante von .card-feature — nimmt die volle Container-Breite ein
(statt im 2er-Grid neben einer zweiten Karte zu stehen) und wechselt
dafür auf ein horizontales Layout: Icon links, Titel/Text rechts daneben
statt zentriert übereinander, damit die Breite bewusst genutzt wird statt
nur Leerraum links/rechts vom zentrierten Text zu erzeugen. */
.card-feature-wide {
display: flex;
align-items: center;
gap: 1.8rem;
text-align: left;
padding: 2.2rem 2.8rem;
min-height: auto;
}
.card-feature-wide .icon-badge {
flex-shrink: 0;
margin-bottom: 0;
}
.card-feature-wide .card-feature-text {
position: relative;
z-index: 2;
}
.card-feature-wide .card-feature-desc {
margin: .4rem 0 0;
max-width: 60ch;
}
@media (max-width: 640px) {
.card-feature-wide {
flex-direction: column;
text-align: center;
padding: 2.4rem 1.6rem;
}
.card-feature-wide .card-feature-desc { margin: .4rem auto 0; }
}
.nav-toggle {
display: none;
background: none;
@@ -1218,6 +1415,22 @@ header.site-header {
overflow: hidden;
}
.hero > .container { position: relative; z-index: 1; }
/* Zusätzlicher, garantiert deckender Schleier NUR hinter dem Hero-Text auf
Seiten mit Hintergrundfoto (.page-bg) — Ergänzung zum globalen
body.mit-hintergrund-Verlauf oben. Grund (BFSG/WCAG-Audit 04.08.2026):
der globale Verlauf allein reichte bei hellen Fotomotiven nicht überall
für AA-Kontrast (Eyebrow/H1/Lead direkt im Hero betroffen). Sitzt NUR
um den Text-Container, deckt also NICHT das scharfe .hero-banner-Foto
darüber ab (das bleibt unverändert sichtbar). */
.hero.page-bg > .container::before {
content: "";
position: absolute;
inset: -1.4rem -1.6rem;
z-index: -1;
border-radius: 28px;
background: color-mix(in srgb, var(--bg) 55%, transparent);
pointer-events: none;
}
.hero .worlds {
margin: .6rem 0 1.2rem;
color: var(--text-muted);
@@ -1390,7 +1603,7 @@ header.site-header {
padding: 1rem;
}
/* ---------- Timeline (Zeitreise) ---------- */
/* ---------- Timeline (Zeitreise) — alte, einfache Punkt+Linie-Variante ---------- */
.timeline { position: relative; margin: 2rem 0; padding-left: 2rem; border-left: 2px solid var(--border); }
.timeline-item { position: relative; padding-bottom: 2.4rem; }
.timeline-item::before {
@@ -1405,6 +1618,177 @@ header.site-header {
}
.timeline-item .date { color: var(--accent); font-weight: 700; font-size: .85rem; }
/* ---------- Zeitbaum (Zeitreise) — die Reise als wachsender Baum ----------
Ein Stamm (::before, per clip-path unten dicker als oben = "Wachstum")
läuft mittig durch alle Stationen. Jede Station ("Ast") hängt sich
abwechselnd links/rechts an den Stamm, verbunden über eine glühende
Astlinie. Meilenstein-Stationen bekommen eine goldene statt babyblaue
Aura. Oben ein Keim (🌱, Anfang), unten eine Krone (🌳, Fortsetzung). */
.zeit-baum {
position: relative;
margin: 3rem 0 1rem;
padding: 2.4rem 0;
}
.zeit-baum::before {
content: "";
position: absolute;
left: 50%;
top: 0; bottom: 0;
width: 44px;
transform: translateX(-50%);
background: linear-gradient(180deg,
rgba(143,217,234,.55) 0%,
rgba(139,92,246,.55) 45%,
rgba(217,196,90,.6) 100%);
clip-path: polygon(47% 0%, 53% 0%, 66% 100%, 34% 100%);
filter: blur(.2px);
box-shadow: 0 0 60px 6px rgba(143,217,234,.18);
opacity: .85;
}
.zeit-baum-kappe {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
gap: .3rem;
margin-bottom: .5rem;
text-align: center;
font-size: .85rem;
font-weight: 700;
color: var(--accent);
text-shadow: 0 0 14px rgba(143,217,234,.55);
}
.zeit-baum-kappe span:first-child { font-size: 1.6rem; filter: drop-shadow(0 0 10px rgba(143,217,234,.6)); }
.zeit-baum-wurzel {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
gap: .3rem;
margin-top: 1rem;
text-align: center;
font-size: .85rem;
font-weight: 700;
color: #e8d78f;
text-shadow: 0 0 14px rgba(217,196,90,.5);
}
.zeit-baum-wurzel span:first-child { font-size: 1.9rem; filter: drop-shadow(0 0 14px rgba(217,196,90,.6)); }
.zeit-ast {
position: relative;
display: flex;
width: 100%;
padding: 1.1rem 0;
}
.zeit-ast:nth-child(odd) { justify-content: flex-start; }
.zeit-ast:nth-child(even) { justify-content: flex-end; }
.zeit-node {
position: absolute;
left: 50%;
top: 50%;
width: 16px; height: 16px;
transform: translate(-50%, -50%);
border-radius: 50%;
background: radial-gradient(circle at 35% 30%, #fff, var(--accent) 60%, var(--accent-2) 100%);
box-shadow: 0 0 0 4px var(--bg), 0 0 18px 3px rgba(143,217,234,.6);
z-index: 2;
animation: zeit-node-pulse 3.2s ease-in-out infinite;
}
.zeit-ast.meilenstein .zeit-node {
background: radial-gradient(circle at 35% 30%, #fff, #e8d78f 55%, #b8892f 100%);
box-shadow: 0 0 0 4px var(--bg), 0 0 22px 5px rgba(232,215,143,.7);
}
@keyframes zeit-node-pulse {
0%, 100% { box-shadow: 0 0 0 4px var(--bg), 0 0 14px 2px rgba(143,217,234,.5); }
50% { box-shadow: 0 0 0 4px var(--bg), 0 0 24px 6px rgba(143,217,234,.85); }
}
.zeit-karte {
position: relative;
width: calc(50% - 2.6rem);
background: linear-gradient(160deg, rgba(23,27,33,.82), rgba(23,27,33,.55));
backdrop-filter: blur(6px);
border: 1px solid rgba(143,217,234,.25);
border-radius: 16px;
padding: 1.1rem 1.3rem;
box-shadow: 0 10px 26px rgba(0,0,0,.35);
transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}
.zeit-ast.meilenstein .zeit-karte { border-color: rgba(232,215,143,.4); }
.zeit-karte::before {
content: "";
position: absolute;
top: 50%;
width: 2.6rem;
height: 2px;
background: linear-gradient(90deg, rgba(143,217,234,.05), rgba(143,217,234,.65));
transform: translateY(-50%);
}
.zeit-ast:nth-child(odd) .zeit-karte::before { right: -2.6rem; }
.zeit-ast:nth-child(even) .zeit-karte::before { left: -2.6rem; background: linear-gradient(270deg, rgba(143,217,234,.05), rgba(143,217,234,.65)); }
.zeit-ast.meilenstein:nth-child(odd) .zeit-karte::before { background: linear-gradient(90deg, rgba(232,215,143,.05), rgba(232,215,143,.75)); }
.zeit-ast.meilenstein:nth-child(even) .zeit-karte::before { background: linear-gradient(270deg, rgba(232,215,143,.05), rgba(232,215,143,.75)); }
.zeit-karte:hover {
transform: translateY(-4px);
border-color: rgba(143,217,234,.55);
box-shadow: 0 16px 34px rgba(0,0,0,.45), 0 0 24px rgba(143,217,234,.2);
}
.zeit-ast.meilenstein .zeit-karte:hover {
border-color: rgba(232,215,143,.7);
box-shadow: 0 16px 34px rgba(0,0,0,.45), 0 0 26px rgba(232,215,143,.3);
}
.zeit-datum {
color: var(--accent);
font-weight: 700;
font-size: .82rem;
letter-spacing: .02em;
margin-bottom: .25rem;
}
.zeit-ast.meilenstein .zeit-datum { color: #e8d78f; }
.zeit-karte h3 { margin: 0 0 .4rem; font-size: 1.15rem; }
.zeit-karte p { margin: 0; color: var(--text-muted); font-size: .93rem; line-height: 1.55; }
.zeit-ast.zeit-final .zeit-karte { width: calc(100% - 4rem); max-width: 640px; text-align: center; }
.zeit-ast.zeit-final { justify-content: center !important; }
.zeit-ast.zeit-final .zeit-karte::before { display: none; }
.zeit-zitat {
font-weight: 700;
color: var(--text);
font-style: italic;
margin: .8rem 0 .5rem !important;
}
.zeit-familie {
font-weight: 800;
font-size: 1.05rem !important;
color: var(--accent) !important;
text-shadow: 0 0 14px rgba(143,217,234,.5);
}
.zeit-signoff {
margin-top: .8rem !important;
color: var(--text-muted);
font-style: italic;
}
/* Reveal-Animation (per IntersectionObserver in zeitreise.html getriggert) */
.zeit-ast { opacity: 0; transform: translateY(28px); transition: opacity .7s ease, transform .7s ease; }
.zeit-ast.zeit-sichtbar { opacity: 1; transform: translateY(0); }
@media (max-width: 780px) {
.zeit-baum::before { left: 22px; width: 30px; clip-path: polygon(44% 0%, 56% 0%, 70% 100%, 30% 100%); }
.zeit-ast, .zeit-ast:nth-child(odd), .zeit-ast:nth-child(even) { justify-content: flex-start; padding-left: 3rem; }
.zeit-node { left: 22px; }
.zeit-karte { width: 100%; }
.zeit-karte::before,
.zeit-ast:nth-child(even) .zeit-karte::before { left: -2.2rem; right: auto; width: 2.2rem; background: linear-gradient(270deg, rgba(143,217,234,.05), rgba(143,217,234,.65)); }
.zeit-ast.meilenstein .zeit-karte::before,
.zeit-ast.meilenstein:nth-child(even) .zeit-karte::before { background: linear-gradient(270deg, rgba(232,215,143,.05), rgba(232,215,143,.75)); }
.zeit-ast.zeit-final .zeit-karte { width: 100%; text-align: left; }
.zeit-ast.zeit-final { padding-left: 3rem; }
}
/* ---------- Gallery / Lightbox ---------- */
.filter-bar { display: flex; gap: .6rem; flex-wrap: wrap; margin-bottom: 1.6rem; }
.filter-btn {
@@ -1464,6 +1848,11 @@ footer.site-footer {
margin-top: 4rem;
position: relative;
z-index: 1;
/* Voll deckender Hintergrund (nicht color-mix/transparent) — auf Seiten
mit body.mit-hintergrund lag der Footer sonst direkt über dem fixen,
nur teilweise abgedunkelten Hintergrundfoto, was bei axe-core einen
color-contrast-Verstoß für .footer-grid .brand auslöste (04.08.2026). */
background: var(--bg);
}
.footer-grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 2rem; }
@media (max-width: 760px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@@ -1928,12 +2317,22 @@ body.mit-hintergrund::before {
background-size: cover;
background-position: center;
background-repeat: no-repeat;
/* Weichzeichnen + leicht abdunkeln: ruhiger Untergrund, der die Augen
beim Lesen nicht anstrengt. */
filter: blur(4px) brightness(.62) saturate(.95);
/* Weichzeichnen + abdunkeln: ruhiger Untergrund, der die Augen beim Lesen
nicht anstrengt. brightness(.45) statt vorher .62 — angepasst nach dem
BFSG/WCAG-Kontrast-Audit vom 04.08.2026 (axe-core fand color-contrast-
Verstöße auf allen Seiten mit Hintergrundfoto: helle Bildstellen
schimmerten durch die Abdunkelung, besonders im Hero-Bereich oben, wo
der ::after-Verlauf am schwächsten war). */
filter: blur(4px) brightness(.45) saturate(.95);
}
/* Abdunkelung für den Seitenkörper — bewusst kräftig, damit langes Lesen
angenehm bleibt. Das Motiv bleibt als ruhige Stimmung im Hintergrund. */
angenehm bleibt UND Text zuverlässig AA-Kontrast erreicht (siehe oben).
Werte am 04.08.2026 zweimal nachgeschärft (80/92/95% → 90/97/99% →
94/98/99.5%, volle Deckung schon ab 30% statt erst bei 100%) — nach dem
zusätzlichen Hero-Schleier (oben) waren vereinzelt noch Elemente knapp
unterhalb des Heros betroffen (z.B. `.bewerben-side-label`,
`h2.text-center` auf team-modis.html), wo der Verlauf noch nicht voll
angekommen war. Mit axe-core auf allen betroffenen Seiten gegengeprüft. */
body.mit-hintergrund::after {
content: "";
position: fixed;
@@ -1941,9 +2340,9 @@ body.mit-hintergrund::after {
z-index: -2;
pointer-events: none;
background: linear-gradient(to bottom,
color-mix(in srgb, var(--bg) 80%, transparent) 0%,
color-mix(in srgb, var(--bg) 92%, transparent) 45%,
color-mix(in srgb, var(--bg) 95%, transparent) 100%);
color-mix(in srgb, var(--bg) 94%, transparent) 0%,
color-mix(in srgb, var(--bg) 98%, transparent) 30%,
color-mix(in srgb, var(--bg) 99.5%, transparent) 100%);
}
/* ---- 2) Kopfbereich: ECHTES <img> statt CSS-Hintergrund ----
@@ -2622,6 +3021,119 @@ body.start-seite .music-toggle:focus-visible {
.music-toggle { transition: none; }
}
/* =========================================================================
Vorschau-Umschalter (nur für Dogi/VanVan, siehe main.js
renderVorschauSchalter/gate-worker.js) — unten LINKS, spiegelbildlich zum
Musik-Knopf unten rechts, exakt dieselbe Bauart (Kreisknopf mit
wandernden Farbwolken + Lichtschimmer, aufklappbares Panel). Eigenes,
festes Farbpaar (Gold/Lila, das Supporter-Abo-Motiv) statt der
Chamäleon-Farben des Musik-Knopfs — dieser Knopf soll bewusst IMMER
gleich aussehen, unabhängig vom Seitenbild. Symbol: 🎭 (Theatermasken —
"als jemand anderes ansehen", passt zum Rollen-Vorschau-Zweck). Nutzer-
Feedback 03.08.2026: statt einer dauerhaft sichtbaren Text-Knopfleiste
sollte es "so ein Button wie bei VanVan" sein, der sich erst bei Klick
öffnet. ========================================================== */
.vorschau-widget {
position: fixed;
left: 22px;
bottom: 22px;
z-index: 120;
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 12px;
}
.vorschau-toggle {
position: relative;
isolation: isolate;
overflow: hidden;
width: 54px;
height: 54px;
flex: none;
border-radius: 999px;
font-size: 1.45rem;
line-height: 1;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
color: #fff;
text-shadow: 0 1px 3px rgba(0, 0, 0, .55);
background: #0b0e14;
border: 1px solid rgba(212, 175, 55, .55);
box-shadow: 0 12px 30px rgba(0, 0, 0, .45), 0 0 24px rgba(212, 175, 55, .3);
transition: transform .25s ease, filter .25s ease, box-shadow .25s ease;
}
.vorschau-toggle::before {
content: "";
position: absolute;
inset: -50%;
z-index: 0;
background:
radial-gradient(circle at 25% 30%, rgba(255, 214, 102, .95), transparent 58%),
radial-gradient(circle at 75% 72%, rgba(139, 92, 246, .9), transparent 58%);
filter: blur(7px) saturate(1.3);
animation: btn-aurora 10s ease-in-out infinite alternate;
}
.vorschau-toggle::after {
content: "";
position: absolute;
inset: 0;
z-index: 1;
border-radius: 999px;
background: linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, .35) 49%, transparent 63%);
background-size: 240% 100%;
mix-blend-mode: overlay;
animation: btn-shimmer 5s linear infinite;
pointer-events: none;
}
.vorschau-toggle:hover, .vorschau-toggle:focus-visible {
transform: translateY(-2px) scale(1.05);
filter: brightness(1.12);
box-shadow: 0 16px 38px rgba(0, 0, 0, .5), 0 0 34px rgba(212, 175, 55, .5);
}
.vorschau-widget.open .vorschau-toggle { transform: rotate(-12deg); }
.vorschau-toggle span { position: relative; z-index: 2; }
@media (prefers-reduced-motion: reduce) { .vorschau-toggle::before, .vorschau-toggle::after { animation: none; } }
.vorschau-panel {
width: min(260px, calc(100vw - 44px));
padding: 1rem 1.1rem 1.1rem;
border-radius: var(--radius);
border: 1px solid var(--border);
background: var(--card-bg);
box-shadow: 0 24px 60px rgba(0, 0, 0, .6);
animation: music-panel-in .22s ease-out;
}
.vorschau-panel[hidden] { display: none; }
.vorschau-panel-head {
display: flex; align-items: center; justify-content: space-between; gap: .6rem;
margin-bottom: .8rem;
}
.vorschau-panel-head strong { font-size: .92rem; color: #ffe9a8; }
.vorschau-close {
background: none; border: 0; color: var(--text-muted); font-size: 1rem;
line-height: 1; padding: .2rem .3rem; cursor: pointer; border-radius: 6px;
}
.vorschau-close:hover { color: var(--accent); }
.vorschau-optionen { display: flex; flex-direction: column; gap: .4rem; }
.vorschau-optionen button {
display: block; width: 100%; text-align: left; font-size: .88rem; font-weight: 600;
padding: .6rem .8rem; border-radius: 9px; cursor: pointer;
background: transparent; border: 1px solid transparent; color: var(--text-muted);
transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.vorschau-optionen button:hover { border-color: var(--border); color: var(--text); }
.vorschau-optionen button.aktiv {
border-color: rgba(212, 175, 55, .6); color: #ffe9a8; background: rgba(212, 175, 55, .1);
}
@media (max-width: 620px) {
.vorschau-widget { left: 14px; bottom: 14px; }
.vorschau-toggle { width: 48px; height: 48px; font-size: 1.25rem; }
}
@media print { .vorschau-widget { display: none !important; } }
@media (prefers-reduced-motion: reduce) { .vorschau-panel { animation: none; } }
/* ---------- Live-Status-Punkt ---------- */
.live-dot {
display: inline-block;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

After

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

+104
View File
@@ -0,0 +1,104 @@
/* =====================================================================
admin-auth.js — gemeinsame Session-Logik fürs interne Team-Login
(dasselbe Owner-/Rollen-System wie schon fürs frühere Bewerbungs-
Postfach).
Session (Token + Rolle/Rechte) liegt in localStorage (Nutzer-Wunsch
04.08.2026: "den Zugangscode auf der Verwaltungsseite nur einmal am Tag
eingeben müssen") — localStorage übersteht anders als sessionStorage
auch das Schließen des Tabs/Browsers, sonst wäre "einmal am Tag" nicht
möglich. Eigener 24-Stunden-Ablauf hier im Client (siehe SESSION_MAX_AGE_MS)
zusätzlich zum server-seitigen Session-Timeout (lib/auth.js, ebenfalls
24 Std) — beide zusammen sorgen dafür, dass wirklich niemand länger als
einen Tag mit einem alten Code eingeloggt bleiben kann.
Ursprünglich für postfach.html/zugaenge.html gebaut (Bewerbungs-
Verwaltung) — die wurden am 01.08.2026 auf Dogis Wunsch entfernt ("nicht
mehr gebraucht"). Diese Datei selbst ist aber ein reines, seitenneutrales
Login-Werkzeug (kein Bewerbungscode) und wurde am 04.08.2026 reaktiviert
für verwaltung.html (Supporter-Abo-Administration) — nutzt exakt
denselben, weiterhin voll funktionsfähigen Backend-Login
(POST /auth/login), nur eine neue Seite drumherum.
===================================================================== */
const SESSION_KEY = "dogfather_admin_session";
const SESSION_MAX_AGE_MS = 24 * 60 * 60 * 1000;
function getSession() {
try {
const session = JSON.parse(localStorage.getItem(SESSION_KEY) || "null");
if (!session) return null;
if (!session.loggedInAt || Date.now() - session.loggedInAt > SESSION_MAX_AGE_MS) {
clearSession(); // älter als 24 Std -> als abgelaufen behandeln, neuer Code nötig
return null;
}
return session;
} catch {
return null;
}
}
function setSession(data) {
localStorage.setItem(SESSION_KEY, JSON.stringify({ ...data, loggedInAt: Date.now() }));
}
function clearSession() {
localStorage.removeItem(SESSION_KEY);
}
/** Prüft, ob die aktuelle Session (Owner oder Rolle+Overrides) ein Recht hat. */
function sessionHasPermission(session, key) {
if (!session) return false;
if (session.isOwner) return true;
const overrides = session.overrides || {};
if (Object.prototype.hasOwnProperty.call(overrides, key)) return !!overrides[key];
return Array.isArray(session.permissions) && session.permissions.includes(key);
}
async function apiCall(apiBaseUrl, path, body, { auth = true } = {}) {
const session = getSession();
const headers = { "Content-Type": "application/json" };
if (auth && session?.token) headers["Authorization"] = `Bearer ${session.token}`;
const res = await fetch(`${apiBaseUrl}${path}`, {
method: "POST",
headers,
body: JSON.stringify(body || {}),
});
let data;
try {
data = await res.json();
} catch {
data = { ok: false, error: "Ungültige Antwort vom Server." };
}
if (res.status === 401 && auth) {
clearSession(); // Session ist abgelaufen/ungültig -> zurück zum Login zwingen
}
return { httpOk: res.ok, ...data };
}
async function doLogin(apiBaseUrl, code) {
const res = await apiCall(apiBaseUrl, "/auth/login", { code }, { auth: false });
if (res.ok) {
setSession({
token: res.token,
isOwner: res.isOwner,
name: res.name,
username: res.username,
roleName: res.roleName,
permissions: res.permissions || [],
overrides: res.overrides || {},
});
}
return res;
}
async function doLogout(apiBaseUrl) {
await apiCall(apiBaseUrl, "/auth/logout", {});
clearSession();
}
// Für Einbindung ohne Modul-Bundler global verfügbar machen.
if (typeof window !== "undefined") {
window.AdminAuth = { getSession, setSession, clearSession, sessionHasPermission, apiCall, doLogin, doLogout };
}
+74
View File
@@ -39,6 +39,80 @@ const SCOUTS = [
fr: "Patrick est scout chez Team Dogi. Avec Bananenstift, il recherche et accompagne de nouveaux talents pour DogFather en tant que manager.",
pt: "Patrick é scout na Team Dogi. Junto com Bananenstift, ele busca e acompanha novos talentos para o DogFather como manager.",
},
// Kurzer Einstiegstext, direkt NEBEN dem Foto (siehe profil.html /
// person.intro). Die restliche, ausführlichere Vorstellung (bioHtml)
// folgt darunter im breiten Bereich — gleiches Muster wie Bananenstift.
intro: {
de: `
<p>Hallo, mein Name ist <strong>Patrick</strong>. Geboren wurde ich am <strong>18. Mai 1985</strong> im schönen Harz. 🏔️</p>
<p>Seit Mai 2021 bin ich auf TikTok aktiv. Mein erstes Video veröffentlichte ich am <strong>29. Mai 2021</strong>. Zu diesem Zeitpunkt hätte ich vermutlich selbst nicht erwartet, wie viele besondere Erfahrungen, Begegnungen und Erinnerungen mich auf dieser Reise noch erwarten würden.</p>
`,
"de-CH": `
<p>Hoi, ich heisse <strong>Patrick</strong>. Gebore bin ich am <strong>18. Mai 1985</strong> im schöne Harz. 🏔️</p>
<p>Sit Mai 2021 bin ich uf TikTok aktiv. Mis erste Video han ich am <strong>29. Mai 2021</strong> veröffentlicht. Zu dem Zytpunkt hätt ich wahrschindlich sälber nöd erwartet, wie vill bsundrigi Erfahrige, Begägnige und Erinnerige mich uf dere Reise no erwarted.</p>
`,
en: `
<p>Hi, my name is <strong>Patrick</strong>. I was born on <strong>May 18, 1985</strong> in the beautiful Harz region. 🏔️</p>
<p>I've been active on TikTok since May 2021. I published my first video on <strong>May 29, 2021</strong>. Back then, I probably wouldn't have expected just how many special experiences, encounters, and memories this journey would still bring me.</p>
`,
fr: `
<p>Bonjour, je m'appelle <strong>Patrick</strong>. Je suis né le <strong>18 mai 1985</strong> dans la belle région du Harz. 🏔️</p>
<p>Je suis actif sur TikTok depuis mai 2021. J'ai publié ma première vidéo le <strong>29 mai 2021</strong>. À l'époque, je ne m'attendais probablement pas à toutes les expériences, rencontres et souvenirs particuliers que ce parcours allait encore m'offrir.</p>
`,
pt: `
<p>Olá, o meu nome é <strong>Patrick</strong>. Nasci em <strong>18 de maio de 1985</strong>, na bela região do Harz. 🏔️</p>
<p>Estou ativo no TikTok desde maio de 2021. Publiquei o meu primeiro vídeo em <strong>29 de maio de 2021</strong>. Naquela altura, provavelmente eu mesmo não esperava quantas experiências, encontros e memórias especiais essa jornada ainda me traria.</p>
`,
},
// Ausführliche Fortsetzung von Patricks Vorstellung — erscheint UNTER
// dem Foto im breiten Lesebereich (siehe profil.html / person.bioHtml).
bioHtml: {
de: `
<p>Im Oktober 2024 wagte ich schließlich den nächsten Schritt und ging zum ersten Mal live. Seitdem durfte ich zahlreiche Menschen kennenlernen und einige von ihnen fest in mein Herz schließen. Genau diese Begegnungen und der persönliche Austausch machen TikTok für mich zu etwas Besonderem.</p>
<p>Auf den ersten Blick wirke ich gelegentlich etwas grimmig oder nachdenklich. Davon sollte man sich jedoch nicht täuschen lassen, denn mein Gesicht vermittelt manchmal einen ganz anderen Eindruck als meine tatsächliche Stimmung. 😅</p>
<p>Wer mich wirklich kennt, weiß, dass ich ein offener, humorvoller und herzlicher Mensch bin. Ich lache gerne, bin für jeden Spaß zu haben und unterstütze die Menschen, die mir wichtig sind. Ehrlichkeit, Zusammenhalt und gegenseitige Unterstützung haben für mich einen besonders hohen Stellenwert.</p>
<p>Als Scout unterstütze ich das Team dabei, neue Talente zu entdecken, ihnen zur Seite zu stehen und sie auf ihrem persönlichen Weg zu begleiten. Dabei geht es mir nicht nur um Zahlen oder Erfolge, sondern vor allem um die Menschen, ihre Ziele und ihre Entwicklung.</p>
<p>Ich freue mich auf alles, was noch vor mir liegt: neue Begegnungen, besondere Erinnerungen und viele weitere gemeinsame Momente.</p>
<p class="quote" style="margin-top:1rem;">Das bin ich Patrick. Nicht perfekt, manchmal mit einem grimmigen Blick, aber immer mit Herz. ❤️</p>
<p style="text-align:right;"><strong> euer Patrick ❤️</strong></p>
`,
"de-CH": `
<p>Im Oktober 2024 han ich schliesslich de nöchscht Schritt gwagt und bi zum erste Mal live gange. Sithär han ich zahlriichi Mönsche cha kenneleärne und e paar dervo fescht i mis Herz gschlosse. Genau die Begägnige und dr persönlich Uustuusch mached TikTok für mich zu öppisem Bsundrigem.</p>
<p>Uf de erschte Blick wirk ich mängisch chli grimmig oder nachdenklich. Dervo sött me sich aber nöd teusche la, dänn mis Gsicht vermittlet mängisch en ganz andere Yidruck als mini tatsächlichi Stimmig. 😅</p>
<p>Wer mich würklich känt, weiss, dass ich en offene, humorvolle und härzliche Mönsch bin. Ich lach gern, bin für jede Spass ztue und unterstütze d Mönsche, wo mir wichtig sind. Ehrlichkeit, Zämehalt und gägesitigi Unterstützig händ für mich en bsunders hohe Stellewert.</p>
<p>Als Scout unterstütz ich s Team derbi, neui Talänt z'entdecke, ihne zur Syte z'stah und sie uf ihrem persönliche Wäg z'begleite. Debii gaht's mir nöd nume um Zahle oder Erfolg, sondern vor allem um d Mönsche, ihri Ziel und ihri Entwicklig.</p>
<p>Ich fröi mich uf alles, wo no vor mir liit: neui Begägnige, bsundrigi Erinnerige und no vill gmeinsami Momänt.</p>
<p class="quote" style="margin-top:1rem;">Das bin ich Patrick. Nöd perfekt, mängisch mit emene grimmige Blick, aber immer mit Herz. ❤️</p>
<p style="text-align:right;"><strong> öie Patrick ❤️</strong></p>
`,
en: `
<p>In October 2024, I finally took the next step and went live for the first time. Since then, I've gotten to know so many people, and some of them have found a firm place in my heart. It's exactly these encounters and the personal exchange that make TikTok something special to me.</p>
<p>At first glance, I sometimes come across as a bit grumpy or lost in thought. But don't be fooled by that — my face sometimes gives a very different impression than my actual mood. 😅</p>
<p>Anyone who really knows me knows that I'm an open, humorous, and warm-hearted person. I love to laugh, I'm always up for a bit of fun, and I support the people who matter to me. Honesty, togetherness, and mutual support mean a great deal to me.</p>
<p>As a scout, I help the team discover new talent, stand by their side, and guide them on their personal journey. For me, it's not just about numbers or success — it's above all about the people, their goals, and their growth.</p>
<p>I'm looking forward to everything still ahead of me: new encounters, special memories, and many more moments together.</p>
<p class="quote" style="margin-top:1rem;">That's me Patrick. Not perfect, sometimes with a grumpy look, but always with heart. ❤️</p>
<p style="text-align:right;"><strong> your Patrick ❤️</strong></p>
`,
fr: `
<p>En octobre 2024, j'ai finalement franchi l'étape suivante et j'ai fait mon premier live. Depuis, j'ai pu rencontrer de nombreuses personnes et certaines d'entre elles ont pris une vraie place dans mon cœur. Ce sont justement ces rencontres et ces échanges personnels qui rendent TikTok si particulier pour moi.</p>
<p>Au premier abord, je peux parfois paraître un peu grognon ou pensif. Il ne faut cependant pas s'y fier, car mon visage donne parfois une impression bien différente de mon humeur réelle. 😅</p>
<p>Ceux qui me connaissent vraiment savent que je suis quelqu'un d'ouvert, plein d'humour et chaleureux. J'aime rire, je suis toujours partant pour m'amuser et je soutiens les personnes qui comptent pour moi. L'honnêteté, la cohésion et le soutien mutuel ont une valeur particulièrement importante à mes yeux.</p>
<p>En tant que scout, j'aide l'équipe à découvrir de nouveaux talents, à les épauler et à les accompagner sur leur propre chemin. Ce qui compte pour moi, ce n'est pas seulement les chiffres ou le succès, mais avant tout les personnes, leurs objectifs et leur évolution.</p>
<p>Je me réjouis de tout ce qui m'attend encore : de nouvelles rencontres, des souvenirs particuliers et bien d'autres moments partagés.</p>
<p class="quote" style="margin-top:1rem;">C'est moi, Patrick. Pas parfait, parfois avec un regard grognon, mais toujours avec du cœur. ❤️</p>
<p style="text-align:right;"><strong> votre Patrick ❤️</strong></p>
`,
pt: `
<p>Em outubro de 2024, finalmente dei o próximo passo e fiz a minha primeira live. Desde então, pude conhecer muitas pessoas e algumas delas conquistaram um lugar especial no meu coração. São exatamente esses encontros e a troca pessoal que tornam o TikTok algo especial para mim.</p>
<p>À primeira vista, às vezes pareço um pouco carrancudo ou pensativo. No entanto, não se deixe enganar por isso, porque o meu rosto às vezes transmite uma impressão bem diferente do meu humor real. 😅</p>
<p>Quem realmente me conhece sabe que sou uma pessoa aberta, bem-humorada e carinhosa. Gosto de rir, estou sempre pronto para me divertir e apoio as pessoas que são importantes para mim. Honestidade, união e apoio mútuo têm um valor muito especial para mim.</p>
<p>Como scout, ajudo a equipe a descobrir novos talentos, a estar ao lado deles e a acompanhá-los no seu caminho pessoal. Para mim, não se trata apenas de números ou sucesso, mas sobretudo das pessoas, dos seus objetivos e do seu desenvolvimento.</p>
<p>Estou animado com tudo o que ainda está por vir: novos encontros, memórias especiais e muitos outros momentos em conjunto.</p>
<p class="quote" style="margin-top:1rem;">Este sou eu Patrick. Não sou perfeito, às vezes com um olhar carrancudo, mas sempre com coração. ❤️</p>
<p style="text-align:right;"><strong> o seu Patrick ❤️</strong></p>
`,
},
quote: "", // TODO: Zitat von Patrick einholen
social: {},
status: "aktiv",
+1 -1
View File
@@ -17,7 +17,7 @@
const API_BASE_URL = "https://dogfather-universe-postfach.dogfather1608.workers.dev";
const CONTACT_EMAIL = "kontakt@dogfather-universe.example"; // TODO: echte Kontakt-E-Mail eintragen
const CONTACT_EMAIL = "dogfather[email protected]";
const FORM_TYPES = {
"form-creator": "creator",
+181
View File
@@ -0,0 +1,181 @@
/* =====================================================================
i18n-abonnieren.js — Übersetzungs-Wörterbuch NUR für abonnieren.html
Alle 5 Sprachen vollständig gepflegt (de, de-CH, en, fr, pt).
===================================================================== */
window.I18N_PAGE = {
ab_eyebrow: {
de: "👑 DogiCrew 🩵", "de-CH": "👑 DogiCrew 🩵",
en: "👑 DogiCrew 🩵", fr: "👑 DogiCrew 🩵", pt: "👑 DogiCrew 🩵",
},
ab_h1: {
de: "Mehr als ein Abo — deine Unterstützung wird Teil unserer Geschichte",
"de-CH": "Meh als es Abo — dini Unterstützig wird Teil vo üser Gschicht",
en: "More than a subscription — your support becomes part of our story",
fr: "Plus qu'un abonnement — ton soutien devient une part de notre histoire",
pt: "Mais do que uma assinatura — seu apoio se torna parte da nossa história",
},
ab_lead: {
de: "Kein gewöhnlicher Shop. Ein exklusives Dankeschön- und Treueprogramm für alle, die Dogfather dauerhaft unterstützen.",
"de-CH": "Kein gwöhnlicher Shop. Es exklusives Dankeschön- und Treueprogramm für alli, wo Dogfather duurhaft unterstütze.",
en: "Not a regular shop. An exclusive thank-you and loyalty program for everyone who supports Dogfather long-term.",
fr: "Pas une boutique ordinaire. Un programme exclusif de remerciement et de fidélité pour tous ceux qui soutiennent Dogfather durablement.",
pt: "Não é uma loja comum. Um programa exclusivo de agradecimento e fidelidade para todos que apoiam Dogfather a longo prazo.",
},
ab_text1: {
de: "Dieses Abonnement ist kein gewöhnlicher Shop und kein einfacher Kauf. Es ist für die Menschen gedacht, die Dogfather dauerhaft unterstützen und ein besonderer Teil dieser gemeinsamen Reise sein möchten.",
"de-CH": "Das Abonnement isch kein gwöhnlicher Shop und kein eifache Kauf. Es isch für die Mönsche gedacht, wo Dogfather duurhaft unterstütze und en bsundere Teil vo dere gmeinsame Reise si wänd.",
en: "This subscription is not a regular shop and not a simple purchase. It's for the people who support Dogfather long-term and want to be a special part of this shared journey.",
fr: "Cet abonnement n'est ni une boutique ordinaire ni un simple achat. Il est destiné aux personnes qui soutiennent Dogfather durablement et souhaitent faire partie de ce voyage commun.",
pt: "Esta assinatura não é uma loja comum nem uma compra simples. É para as pessoas que apoiam Dogfather a longo prazo e querem ser parte especial dessa jornada em comum.",
},
ab_text2: {
de: "Für 4,99 € im Monat erhältst du Zugang zu einem exklusiven Supporter-Bereich, besonderen Inhalten und einer persönlichen Treuekollektion. Mit jedem erfolgreich bezahlten Meilenstein wächst deine Sammlung: vom kleinen Hasen-Teddy über besondere Jubiläumsprämien bis zum exklusiven Hoodie nach 30 Monaten. Danach beginnt für dich eine neue Kollektion — mit neuen Designs, neuen Erinnerungen und derselben Bedeutung.",
"de-CH": "Für 4,99 € im Monat überchunnsch du Zugang zu emene exklusive Supporter-Bereich, bsundere Inhalt und ere persönliche Treuekollektion. Mit jedem erfolgriich bezahlte Meilestei wachst dini Sammlig: vom chline Hase-Teddy über bsundere Jubiläumsprämie bis zum exklusive Hoodie nach 30 Monet. Dernah fangt für dich e neui Kollektion a — mit neue Designs, neue Erinnerige und derselbe Bedeutig.",
en: "For 4.99 € a month, you get access to an exclusive supporter area, special content, and a personal loyalty collection. With every successfully paid milestone, your collection grows — from the small bunny teddy through special anniversary rewards up to the exclusive hoodie after 30 months. After that, a new collection begins for you, with new designs, new memories, and the same meaning.",
fr: "Pour 4,99 € par mois, tu as accès à un espace supporter exclusif, à du contenu spécial et à une collection de fidélité personnelle. Avec chaque mois payé avec succès, ta collection grandit : du petit lapin en peluche aux récompenses d'anniversaire jusqu'au hoodie exclusif après 30 mois. Ensuite, une nouvelle collection commence pour toi — avec de nouveaux designs, de nouveaux souvenirs et la même signification.",
pt: "Por 4,99 € por mês, você tem acesso a uma área exclusiva de apoiadores, conteúdo especial e uma coleção pessoal de fidelidade. A cada mês pago com sucesso, sua coleção cresce: do pequeno coelhinho de pelúcia até recompensas especiais de aniversário e o hoodie exclusivo após 30 meses. Depois disso, começa uma nova coleção para você — com novos designs, novas memórias e o mesmo significado.",
},
ab_vorteil1: {
de: "Exklusiver Supporter-Bereich", "de-CH": "Exklusive Supporter-Bereich",
en: "Exclusive supporter area", fr: "Espace supporter exclusif", pt: "Área exclusiva de apoiador",
},
ab_vorteil2: {
de: "Kleiner Hasen-Teddy nach 6 bezahlten Monaten", "de-CH": "Chline Hase-Teddy nach 6 bezahlte Monet",
en: "Small bunny teddy after 6 paid months", fr: "Petit lapin en peluche après 6 mois payés", pt: "Coelhinho de pelúcia pequeno após 6 meses pagos",
},
ab_vorteil3: {
de: "Mittelgroßer Hasen-Teddy nach 12 bezahlten Monaten", "de-CH": "Mittelgrosse Hase-Teddy nach 12 bezahlte Monet",
en: "Medium bunny teddy after 12 paid months", fr: "Lapin en peluche moyen après 12 mois payés", pt: "Coelhinho de pelúcia médio após 12 meses pagos",
},
ab_vorteil4: {
de: "Großer Hasen-Teddy nach 18 bezahlten Monaten", "de-CH": "Grosse Hase-Teddy nach 18 bezahlte Monet",
en: "Large bunny teddy after 18 paid months", fr: "Grand lapin en peluche après 18 mois payés", pt: "Coelhinho de pelúcia grande após 18 meses pagos",
},
ab_vorteil5: {
de: "Tasse & Autogrammkarte nach 24 bezahlten Monaten", "de-CH": "Tasse & Autogrammchärtli nach 24 bezahlte Monet",
en: "Mug & autograph card after 24 paid months", fr: "Tasse et carte autographe après 24 mois payés", pt: "Caneca e cartão autografado após 24 meses pagos",
},
ab_vorteil6: {
de: "Exklusiver Hoodie nach 30 bezahlten Monaten", "de-CH": "Exklusive Hoodie nach 30 bezahlte Monet",
en: "Exclusive hoodie after 30 paid months", fr: "Hoodie exclusif après 30 mois payés", pt: "Hoodie exclusivo após 30 meses pagos",
},
ab_vorteil7: {
de: "Neue Supporter-Kollektion nach jedem abgeschlossenen Zyklus", "de-CH": "Neui Supporter-Kollektion nach jedem abgschlossene Zyklus",
en: "New supporter collection after every completed cycle", fr: "Nouvelle collection supporter après chaque cycle terminé", pt: "Nova coleção de apoiador após cada ciclo concluído",
},
ab_vanvan_h2: {
de: "Die Teddy-Kollektion — in Kooperation mit VanVan", "de-CH": "Die Teddy-Kollektion — i Kooperation mit VanVan",
en: "The Teddy Collection — in Cooperation with VanVan", fr: "La collection de peluches — en coopération avec VanVan", pt: "A coleção de pelúcias — em cooperação com VanVan",
},
ab_vanvan_text: {
de: "Die DogiCrew 🩵 gehört Dogfather. Die Hasen-Teddys und die dazugehörigen Sammlerkollektionen entstehen jedoch in Zusammenarbeit mit VanVan — der rechten Hand von Dogfather, seiner wichtigsten Vertrauensperson und einem festen Bestandteil der Team-Dogi-Familie. Sie stehen für ihre besondere Rolle, den Zusammenhalt innerhalb der Community und die Verbindung zwischen Dogfather, VanVan und allen Menschen, die diesen gemeinsamen Weg dauerhaft unterstützen.",
"de-CH": "D DogiCrew 🩵 ghört Dogfather. D Hase-Teddys und die dezueghörige Sammlerkollektione entstönd aber i Zämearbeit mit VanVan — dr rechte Hand vo Dogfather, sinere wichtigste Vertrouensperson und emene feste Bestandteil vo dr Team-Dogi-Familie. Sie stönd für ihri bsundrigi Roll, dr Zämehalt innerhalb vo dr Community und d Verbindig zwüsche Dogfather, VanVan und alle Mönsche, wo dää gmeinsame Wäg duurhaft unterstütze.",
en: "The DogiCrew 🩵 belongs to Dogfather. The bunny teddies and their collector collections, however, are created in collaboration with VanVan — Dogfather's right hand, his most important trusted person, and a fixed part of the Team Dogi family. They represent her special role, the togetherness within the community, and the connection between Dogfather, VanVan, and everyone who supports this shared journey long-term.",
fr: "La DogiCrew 🩵 appartient à Dogfather. Les lapins en peluche et leurs collections de collectionneur sont cependant créés en collaboration avec VanVan — le bras droit de Dogfather, sa personne de confiance la plus importante et un membre à part entière de la famille Team Dogi. Ils représentent son rôle particulier, la cohésion au sein de la communauté et le lien entre Dogfather, VanVan et toutes les personnes qui soutiennent durablement ce parcours commun.",
pt: "A DogiCrew 🩵 pertence ao Dogfather. Os coelhinhos de pelúcia e suas coleções de colecionador, porém, nascem em colaboração com VanVan — a mão direita de Dogfather, sua pessoa de confiança mais importante e parte fixa da família Team Dogi. Eles representam seu papel especial, a união dentro da comunidade e a conexão entre Dogfather, VanVan e todas as pessoas que apoiam essa jornada em comum a longo prazo.",
},
ab_kollektion_coming_soon: {
de: `Coming soon…`, "de-CH": `Coming soon…`,
en: `Coming soon…`, fr: `Coming soon…`, pt: `Coming soon…`,
},
ab_preis_eyebrow: {
de: "DogiCrew 🩵", "de-CH": "DogiCrew 🩵",
en: "DogiCrew 🩵", fr: "DogiCrew 🩵", pt: "DogiCrew 🩵",
},
ab_preis_pro_monat: {
de: "/ Monat", "de-CH": "/ Monet",
en: "/ month", fr: "/ mois", pt: "/ mês",
},
ab_bed1: {
de: "Monatliche automatische Zahlung über PayPal", "de-CH": "Monetlichi automatischi Zahlig über PayPal",
en: "Monthly automatic payment via PayPal", fr: "Paiement mensuel automatique via PayPal", pt: "Pagamento mensal automático via PayPal",
},
ab_bed2: {
de: "Keine Mindestlaufzeit, jederzeit kündbar", "de-CH": "Kei Mindestlouffzyt, jederzyt kündbar",
en: "No minimum term, cancel anytime", fr: "Aucune durée minimale, résiliable à tout moment", pt: "Sem prazo mínimo, cancele quando quiser",
},
ab_bed3: {
de: "Kündigung zum Ende des bereits bezahlten Zeitraums", "de-CH": "Kündigung zum Ändi vom scho bezahlte Zytruum",
en: "Cancellation takes effect at the end of the already paid period", fr: "La résiliation prend effet à la fin de la période déjà payée", pt: "O cancelamento vale até o fim do período já pago",
},
ab_bed4: {
de: "Keine versteckten Zusatzkosten", "de-CH": "Kei versteckti Zuestzchöschte",
en: "No hidden extra costs", fr: "Aucun coût caché supplémentaire", pt: "Sem custos adicionais ocultos",
},
ab_laedt: {
de: "Einen Moment …", "de-CH": "En Momänt …",
en: "One moment …", fr: "Un instant …", pt: "Um momento …",
},
ab_feld_name: {
de: "Name oder Anzeigename", "de-CH": "Name oder Aazeigename",
en: "Name or display name", fr: "Nom ou pseudo", pt: "Nome ou nome de exibição",
},
ab_feld_tiktok: {
de: "TikTok-Benutzername", "de-CH": "TikTok-Benutzername",
en: "TikTok username", fr: "Nom d'utilisateur TikTok", pt: "Nome de usuário do TikTok",
},
ab_feld_email: {
de: "E-Mail-Adresse", "de-CH": "E-Mail-Adrässe",
en: "Email address", fr: "Adresse e-mail", pt: "Endereço de e-mail",
},
ab_btn_register: {
de: "Registrieren", "de-CH": "Registriere",
en: "Register", fr: "S'inscrire", pt: "Registrar",
},
ab_switch_login: {
de: "Schon Supporter? Hier einloggen", "de-CH": "Scho Supporter? Da yylogge",
en: "Already a supporter? Log in here", fr: "Déjà supporter ? Connecte-toi ici", pt: "Já é apoiador? Faça login aqui",
},
ab_btn_login_code: {
de: "Login-Code anfordern", "de-CH": "Login-Code aafordere",
en: "Request login code", fr: "Demander un code de connexion", pt: "Solicitar código de login",
},
ab_switch_register: {
de: "Noch kein Konto? Jetzt registrieren", "de-CH": "No kein Konto? Jetzt registriere",
en: "No account yet? Register now", fr: "Pas encore de compte ? Inscris-toi maintenant", pt: "Ainda não tem conta? Registre-se agora",
},
ab_code_hinweis: {
de: "Wir haben dir einen 6-stelligen Code per E-Mail geschickt.", "de-CH": "Mir händ dir en 6-stellige Code per E-Mail gschickt.",
en: "We've sent you a 6-digit code by email.", fr: "Nous t'avons envoyé un code à 6 chiffres par e-mail.", pt: "Enviamos um código de 6 dígitos para o seu e-mail.",
},
ab_feld_code: {
de: "Code", "de-CH": "Code",
en: "Code", fr: "Code", pt: "Código",
},
ab_btn_code_verify: {
de: "Bestätigen", "de-CH": "Bestätige",
en: "Confirm", fr: "Confirmer", pt: "Confirmar",
},
ab_eingeloggt_als: {
de: "Eingeloggt. Noch ein letzter Schritt:", "de-CH": "Yyglogget. No en letschte Schritt:",
en: "Logged in. One last step:", fr: "Connecté. Une dernière étape :", pt: "Conectado. Um último passo:",
},
ab_oder_email: {
de: "oder mit E-Mail", "de-CH": "oder mit E-Mail",
en: "or with email", fr: "ou avec e-mail", pt: "ou com e-mail",
},
ab_google_consent_btn: {
de: "Mit Google anmelden", "de-CH": "Mit Google aamelde",
en: "Continue with Google", fr: "Continuer avec Google", pt: "Continuar com o Google",
},
ab_google_consent_hint: {
de: "Beim Klick wird eine Verbindung zu Google hergestellt (deine IP-Adresse wird dabei übertragen).",
"de-CH": "Bim Klick wird e Verbindig zu Google hergstellt (dini IP-Adrässe wird debii übertreit).",
en: "Clicking this connects to Google (your IP address is transmitted in the process).",
fr: "En cliquant, une connexion à Google est établie (ton adresse IP est alors transmise).",
pt: "Ao clicar, é feita uma conexão com o Google (seu endereço IP é transmitido nesse processo).",
},
ab_paypal_laedt: {
de: "Zahlungsoptionen werden geladen …", "de-CH": "Zahligsoptione wärded gladen …",
en: "Loading payment options …", fr: "Chargement des options de paiement …", pt: "Carregando opções de pagamento …",
},
ab_bereits_supporter: {
de: "Du bist bereits Supporter! 🩵", "de-CH": "Du bisch scho Supporter! 🩵",
en: "You're already a supporter! 🩵", fr: "Tu es déjà supporter ! 🩵", pt: "Você já é apoiador! 🩵",
},
ab_btn_zum_bereich: {
de: "Zum Supporter-Bereich", "de-CH": "Zum Supporter-Bereich",
en: "Go to supporter area", fr: "Aller à l'espace supporter", pt: "Ir para a área do apoiador",
},
};
+2 -2
View File
@@ -177,8 +177,8 @@ window.I18N_PAGE = {
},
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 & die Modis — die Menschen, die DOGFATHER UNIVERSE tragen.",
"de-CH": "Vo VanVan & de Modis — die Mönsche, wo DOGFATHER UNIVERSE tröget.",
de: "VanVan & Modis — die Menschen, die DOGFATHER UNIVERSE tragen.",
"de-CH": "VanVan & Modis — die Mönsche, wo DOGFATHER UNIVERSE tröget.",
en: "From VanVan & the Modis — the people who carry DOGFATHER UNIVERSE.",
fr: "De VanVan et des Modis — les personnes qui portent DOGFATHER UNIVERSE.",
pt: "De VanVan e dos Modis — as pessoas que sustentam o DOGFATHER UNIVERSE.",
+6 -33
View File
@@ -38,42 +38,15 @@ window.I18N_PAGE = {
de: "Impressum", "de-CH": "Impressum",
en: "Legal Notice", fr: "Mentions légales", pt: "Aviso legal",
},
kt_impressum_p: {
de: `Angaben gemäß § 5 TMG<br>
[Firmenname / Betreiber]<br>
[Anschrift]<br>
[Kontakt]<br>
Vertreten durch: [Name]`,
"de-CH": `Angabe gmäss § 5 TMG<br>
[Firmename / Betriiber]<br>
[Adrässe]<br>
[Kontakt]<br>
Vertrete durch: [Name]`,
en: `Information according to § 5 TMG (German Telemedia Act)<br>
[Company name / operator]<br>
[Address]<br>
[Contact]<br>
Represented by: [Name]`,
fr: `Mentions légales selon l'article § 5 TMG (loi allemande sur les télémédias)<br>
[Nom de l'entreprise / exploitant]<br>
[Adresse]<br>
[Contact]<br>
Représenté par : [Nom]`,
pt: `Informações conforme o § 5 TMG (lei alemã de telemídia)<br>
[Nome da empresa / responsável]<br>
[Endereço]<br>
[Contato]<br>
Representado por: [Nome]`,
kt_impressum_hinweis: {
de: `Rechtstexte werden auf Deutsch bereitgestellt, um Übersetzungsfehler bei rechtlich verbindlichen Angaben zu vermeiden.`,
"de-CH": `Rächtstäxt wärded uf Dütsch bereitgstellt, dass käni Übersetzigsfähler bi rächtlich verbindlechne Angabe entstönd.`,
en: `Legal texts are provided in German only, to avoid translation errors in legally binding information.`,
fr: `Les mentions légales ne sont fournies qu'en allemand, afin d'éviter toute erreur de traduction dans des informations juridiquement contraignantes.`,
pt: `Os textos legais são fornecidos apenas em alemão, para evitar erros de tradução em informações juridicamente vinculativas.`,
},
kt_datenschutz_h2: {
de: "Datenschutz", "de-CH": "Datenschutz",
en: "Privacy Policy", fr: "Protection des données", pt: "Privacidade",
},
kt_datenschutz_p: {
de: "Diese Website wird aktuell lokal/offline entwickelt und ist noch nicht öffentlich gehostet. Sobald ein Hosting-Anbieter feststeht und Formulare (z.B. Bewerbung) echte Daten versenden, wird hier eine vollständige Datenschutzerklärung ergänzt (Verarbeitungszwecke, Rechtsgrundlage, Speicherdauer, Empfänger, Rechte der Nutzer:innen).",
"de-CH": "Die Website wird aktuell lokal/offline entwicklet und isch no nöd öffentlich gehostet. Sobald en Hosting-Aabieter feststoht und Formulär (z.B. Bewärbig) echti Date versände, wird da e vollständigi Dateschutzerklärig ergänzt (Verarbeitigszwäck, Rächtsgrundlag, Speicherduur, Empfänger, Rächt vo de Nutzer:inne).",
en: "This website is currently being developed locally/offline and is not yet publicly hosted. Once a hosting provider is finalized and forms (e.g. applications) send real data, a complete privacy policy will be added here (processing purposes, legal basis, retention period, recipients, users' rights).",
fr: "Ce site est actuellement développé en local/hors ligne et n'est pas encore hébergé publiquement. Dès qu'un hébergeur sera fixé et que les formulaires (p. ex. candidature) transmettront de vraies données, une déclaration de confidentialité complète sera ajoutée ici (finalités du traitement, base légale, durée de conservation, destinataires, droits des utilisateurs·rices).",
pt: "Este site está atualmente sendo desenvolvido localmente/offline e ainda não está hospedado publicamente. Assim que um provedor de hospedagem for definido e os formulários (por exemplo, candidatura) enviarem dados reais, uma política de privacidade completa será adicionada aqui (finalidades do tratamento, base legal, prazo de armazenamento, destinatários, direitos dos usuários).",
},
};
+30
View File
@@ -23,6 +23,36 @@ window.I18N_PAGE = {
de: "Nur auf Anfrage", "de-CH": "Nur uf Aafrag",
en: "By request only", fr: "Uniquement sur demande", pt: "Somente mediante solicitação",
},
lk_rabatt_badge: {
de: "🔒 Nur für Supporter", "de-CH": "🔒 Nur für Supporter",
en: "🔒 Supporters only", fr: "🔒 Réservé aux Supporters", pt: "🔒 Somente para apoiadores",
},
lk_rabatt_badge_frei: {
de: "✓ Freigeschaltet", "de-CH": "✓ Freigschalte",
en: "✓ Unlocked", fr: "✓ Débloqué", pt: "✓ Desbloqueado",
},
lk_rabatt_h3: {
de: "Rabattcodes", "de-CH": "Rabattcodes",
en: "Discount Codes", fr: "Codes de réduction", pt: "Códigos de desconto",
},
lk_rabatt_desc: {
de: "Codes von Dogis Partnern — exklusiv für Dogfather-Supporter.",
"de-CH": "Codes vo Dogis Partner — exklusiv für Dogfather-Supporter.",
en: "Codes from Dogi's partners — exclusive to Dogfather supporters.",
fr: "Des codes chez les partenaires de Dogi — exclusifs aux Supporters Dogfather.",
pt: "Códigos dos parceiros do Dogi — exclusivos para apoiadores do Dogfather.",
},
lk_rabatt_gesperrt_hinweis: {
de: "🔒 Rabattcodes sind nur für Dogfather-Supporter zugänglich. Werde jetzt Supporter, um sie freizuschalten.",
"de-CH": "🔒 Rabattcodes sind nur für Dogfather-Supporter zuegänglich. Wird jetzt Supporter, zum sie freizschalte.",
en: "🔒 Discount codes are only available to Dogfather supporters. Become a supporter now to unlock them.",
fr: "🔒 Les codes de réduction sont réservés aux Supporters Dogfather. Deviens Supporter dès maintenant pour les débloquer.",
pt: "🔒 Os códigos de desconto são exclusivos para apoiadores do Dogfather. Torne-se apoiador agora para desbloqueá-los.",
},
lk_rabatt_btn_abo: {
de: "Jetzt Supporter werden 👑", "de-CH": "Jetzt Supporter werde 👑",
en: "Become a supporter now 👑", fr: "Devenir Supporter maintenant 👑", pt: "Tornar-se apoiador agora 👑",
},
lk_shop_hint: {
de: "Folgt in Kürze", "de-CH": "Chunnt bald",
en: "Coming soon", fr: "Bientôt disponible", pt: "Em breve",
+64
View File
@@ -0,0 +1,64 @@
/* =====================================================================
i18n-rabattcodes.js — Übersetzungs-Wörterbuch NUR für rabattcodes.html
Alle 5 Sprachen vollständig gepflegt (de, de-CH, en, fr, pt).
===================================================================== */
window.I18N_PAGE = {
rc_eyebrow: {
de: "🔒 Nur für Supporter", "de-CH": "🔒 Nur für Supporter",
en: "🔒 Supporters only", fr: "🔒 Réservé aux Supporters", pt: "🔒 Somente para apoiadores",
},
rc_h1: {
de: "Rabattcodes", "de-CH": "Rabattcodes",
en: "Discount Codes", fr: "Codes de réduction", pt: "Códigos de desconto",
},
rc_lead: {
de: "Codes von Dogis Partnern — exklusiv für Dogfather-Supporter.",
"de-CH": "Codes vo Dogis Partner — exklusiv für Dogfather-Supporter.",
en: "Codes from Dogi's partners — exclusive to Dogfather supporters.",
fr: "Des codes chez les partenaires de Dogi — exclusifs aux Supporters Dogfather.",
pt: "Códigos dos parceiros do Dogi — exclusivos para apoiadores do Dogfather.",
},
rc_gesperrt_titel: {
de: "Nur für Dogfather-Supporter", "de-CH": "Nur für Dogfather-Supporter",
en: "Dogfather supporters only", fr: "Réservé aux Supporters Dogfather", pt: "Somente para apoiadores do Dogfather",
},
rc_gesperrt_text: {
de: "Rabattcodes sind ein exklusiver Vorteil der DogiCrew 🩵. Werde jetzt Teil davon, um sie freizuschalten, sobald die ersten Kooperationen live sind.",
"de-CH": "Rabattcodes sind e exklusive Vorteil vo dr DogiCrew 🩵. Wird jetzt Teil devo, zum sie freizschalte, sobald die erste Kooperatione live sind.",
en: "Discount codes are an exclusive perk of the DogiCrew 🩵. Join now to unlock them as soon as the first collaborations go live.",
fr: "Les codes de réduction sont un avantage exclusif de la DogiCrew 🩵. Rejoins-la dès maintenant pour les débloquer dès que les premières collaborations seront lancées.",
pt: "Os códigos de desconto são um benefício exclusivo da DogiCrew 🩵. Junte-se agora para desbloqueá-los assim que as primeiras parcerias forem lançadas.",
},
rc_btn_abo: {
de: "Jetzt Supporter werden 👑", "de-CH": "Jetzt Supporter werde 👑",
en: "Become a supporter now 👑", fr: "Devenir Supporter maintenant 👑", pt: "Tornar-se apoiador agora 👑",
},
rc_titel: {
de: "Codes folgen in Kürze", "de-CH": "Codes chömed bald",
en: "Codes coming soon", fr: "Codes bientôt disponibles", pt: "Códigos em breve",
},
rc_text: {
de: "Als Creator bekommt DogFather eigene Rabattcodes bei ausgewählten Partnern — die gibt er direkt an Team Dogi weiter. Sobald die ersten Kooperationen live sind, stehen die Codes genau hier.",
"de-CH": "Als Creator überchunnt DogFather eigeni Rabattcodes bi usgwählte Partner — die gitt er direkt a Team Dogi wyter. Sobald die erste Kooperatione live sind, stönd die Codes genau da.",
en: "As a creator, DogFather gets his own discount codes from selected partners — and passes them straight on to Team Dogi. As soon as the first collaborations go live, the codes will show up right here.",
fr: "En tant que créateur, DogFather reçoit ses propres codes de réduction chez des partenaires sélectionnés — et les transmet directement à Team Dogi. Dès que les premières collaborations seront lancées, les codes apparaîtront ici.",
pt: "Como criador, DogFather recebe seus próprios códigos de desconto de parceiros selecionados — e os repassa direto para a Team Dogi. Assim que as primeiras parcerias forem lançadas, os códigos aparecerão bem aqui.",
},
rc_beispiel_marke: {
de: "Partner-Marke", "de-CH": "Partner-Marke",
en: "Partner brand", fr: "Marque partenaire", pt: "Marca parceira",
},
rc_beispiel_code: {
de: `Code „DOGFATHER" · 10 %`, "de-CH": `Code „DOGFATHER" · 10 %`,
en: `Code "DOGFATHER" · 10%`, fr: `Code « DOGFATHER » · 10 %`, pt: `Código "DOGFATHER" · 10%`,
},
rc_btn_kontakt: {
de: "Auf dem Laufenden bleiben", "de-CH": "Am Bau blibe",
en: "Stay in the loop", fr: "Rester informé(e)", pt: "Fique por dentro",
},
rc_btn_zurueck: {
de: "← Zurück zu allen Links", "de-CH": "← Zrugg zu alle Links",
en: "← Back to all links", fr: "← Retour à tous les liens", pt: "← Voltar a todos os links",
},
};
+105
View File
@@ -0,0 +1,105 @@
/* =====================================================================
i18n-supporter.js — Übersetzungs-Wörterbuch NUR für supporter.html
Alle 5 Sprachen vollständig gepflegt (de, de-CH, en, fr, pt).
Hinweis: Die dynamisch aus der API befüllten Inhalte (Status-Labels,
Prämien-Namen, Archiv-Texte) werden aktuell noch fest auf Deutsch
generiert (siehe <script> unten im HTML) — vollständige Mehrsprachigkeit
für diese dynamischen Texte ist als Ausbaustufe vorgemerkt, hier zunächst
nur der statische Seitenrahmen (Überschriften/Buttons).
===================================================================== */
window.I18N_PAGE = {
su_eyebrow: {
de: "👑 Supporter-Bereich", "de-CH": "👑 Supporter-Bereich",
en: "👑 Supporter Area", fr: "👑 Espace Supporter", pt: "👑 Área do Apoiador",
},
su_lade: {
de: "Dein Supporter-Bereich", "de-CH": "Dis Supporter-Bereich",
en: "Your Supporter Area", fr: "Ton espace Supporter", pt: "Sua Área de Apoiador",
},
su_lead: {
de: "Danke, dass du Dogfather dauerhaft unterstützt.", "de-CH": "Danke, dass du Dogfather duurhaft unterstützisch.",
en: "Thank you for supporting Dogfather long-term.", fr: "Merci de soutenir Dogfather durablement.", pt: "Obrigado por apoiar Dogfather a longo prazo.",
},
su_fenster1_h2: {
de: "Mein Abo", "de-CH": "Mis Abo",
en: "My Subscription", fr: "Mon abonnement", pt: "Minha assinatura",
},
su_stat_status: {
de: "Status", "de-CH": "Status",
en: "Status", fr: "Statut", pt: "Status",
},
su_stat_preis: {
de: "Monatlicher Preis", "de-CH": "Monetliche Priis",
en: "Monthly price", fr: "Prix mensuel", pt: "Preço mensal",
},
su_stat_naechste_zahlung: {
de: "Nächste Zahlung", "de-CH": "Nächsti Zahlig",
en: "Next payment", fr: "Prochain paiement", pt: "Próximo pagamento",
},
su_stat_monate: {
de: "Bezahlte Monate gesamt", "de-CH": "Bezahlti Monet insgsamt",
en: "Total paid months", fr: "Total des mois payés", pt: "Total de meses pagos",
},
su_stat_zyklus: {
de: "Aktueller Zyklus", "de-CH": "Aktuelle Zyklus",
en: "Current cycle", fr: "Cycle actuel", pt: "Ciclo atual",
},
su_stat_details_hinweis: {
de: "Details ansehen", "de-CH": "Details aaluege",
en: "View details", fr: "Voir les détails", pt: "Ver detalhes",
},
su_kein_abo_text: {
de: "Du hast noch kein aktives Abo.", "de-CH": "Du häsch no kein aktivs Abo.",
en: "You don't have an active subscription yet.", fr: "Tu n'as pas encore d'abonnement actif.", pt: "Você ainda não tem uma assinatura ativa.",
},
su_kein_abo_btn: {
de: "Jetzt abonnieren", "de-CH": "Jetzt abonniere",
en: "Subscribe now", fr: "S'abonner maintenant", pt: "Assine agora",
},
su_fenster2_h2: {
de: "Mein aktueller Fortschritt", "de-CH": "Mis aktuelle Fortschritt",
en: "My Current Progress", fr: "Ma progression actuelle", pt: "Meu progresso atual",
},
su_archiv_h2: {
de: "Mein Sammlungsarchiv", "de-CH": "Mis Sammligsarchiv",
en: "My Collection Archive", fr: "Mes archives de collection", pt: "Meu arquivo de coleção",
},
su_verwalten_h2: {
de: "Abo verwalten", "de-CH": "Abo verwalte",
en: "Manage Subscription", fr: "Gérer l'abonnement", pt: "Gerenciar assinatura",
},
su_feld_name: {
de: "Name / Anzeigename", "de-CH": "Name / Aazeigename",
en: "Name / display name", fr: "Nom / pseudo", pt: "Nome / nome de exibição",
},
su_feld_tiktok: {
de: "TikTok-Benutzername", "de-CH": "TikTok-Benutzername",
en: "TikTok username", fr: "Nom d'utilisateur TikTok", pt: "Nome de usuário do TikTok",
},
su_btn_profil_speichern: {
de: "Speichern", "de-CH": "Spichere",
en: "Save", fr: "Enregistrer", pt: "Salvar",
},
su_profil_gespeichert: {
de: "Gespeichert.", "de-CH": "Gspicheret.",
en: "Saved.", fr: "Enregistré.", pt: "Salvo.",
},
su_btn_kuendigen: {
de: "Abo kündigen", "de-CH": "Abo kündige",
en: "Cancel subscription", fr: "Résilier l'abonnement", pt: "Cancelar assinatura",
},
su_btn_logout: {
de: "Ausloggen", "de-CH": "Uslogge",
en: "Log out", fr: "Se déconnecter", pt: "Sair",
},
su_nicht_eingeloggt: {
de: "Du bist nicht eingeloggt.", "de-CH": "Du bisch nid yyglogget.",
en: "You're not logged in.", fr: "Tu n'es pas connecté(e).", pt: "Você não está conectado.",
},
su_zum_abo: {
de: "Zur DogiCrew 🩵", "de-CH": "Zur DogiCrew 🩵",
en: "Go to the DogiCrew 🩵", fr: "Aller à la DogiCrew 🩵", pt: "Ir para a DogiCrew 🩵",
},
};
+257
View File
@@ -0,0 +1,257 @@
/* =====================================================================
i18n-tt-muddi.js — Übersetzungs-Wörterbuch NUR für tt-muddi.html
Alle 5 Sprachen vollständig gepflegt (de, de-CH, en, fr, pt).
Persönliche Widmung von Dogi an Tili ("TT-Muddi"), eingefügt am
03.08.2026 auf Wunsch von Dogi (Original-Text 1:1 von ihm geliefert,
siehe Chat-Verlauf). Bewusst NICHT von main p { font-size: 1.14rem }
& Co. wie bei vanvan.html abgewichen — gleiche "persönlicher Brief"-
Textgröße, damit lange emotionale Fließtexte gut lesbar bleiben.
===================================================================== */
window.I18N_PAGE = {
tm_eyebrow: {
de: "🩵 Familie", "de-CH": "🩵 Familie",
en: "🩵 Family", fr: "🩵 Famille", pt: "🩵 Família",
},
tm_h1: {
de: "Tili meine TikTok-Muddi und ein ganz besonderer Teil meines Lebens 🩵",
"de-CH": "Tili mini TikTok-Muddi und en ganz bsundere Teil vo minem Läbe 🩵",
en: "Tili my TikTok Muddi and a very special part of my life 🩵",
fr: "Tili ma TikTok Muddi et une partie très spéciale de ma vie 🩵",
pt: "Tili minha TikTok Muddi e uma parte muito especial da minha vida 🩵",
},
tm_lead: {
de: "Eine persönliche Widmung von Dogi an eine seiner wichtigsten Vertrauenspersonen.",
"de-CH": "E persönlichi Widmig vo Dogi a eini vo sine wichtigste Vertrouenspersone.",
en: "A personal dedication from Dogi to one of his most important trusted people.",
fr: "Une dédicace personnelle de Dogi à l'une de ses personnes de confiance les plus importantes.",
pt: "Uma dedicatória pessoal de Dogi a uma das pessoas de confiança mais importantes de sua vida.",
},
tm_1: {
de: "Es gibt Menschen, die einem nicht einfach nur begegnen. Sie treten in das eigene Leben und hinterlassen etwas, das sich nur schwer in Worte fassen lässt. Sie geben einem Kraft, schenken Vertrauen und erinnern einen daran, dass es selbst in schwierigen Zeiten noch ehrliche und gute Menschen gibt.",
"de-CH": "Es git Mönsche, wo eim nid eifach nur begägnet. Sie tred i eim's eigete Läbe und hinderlönd öppis, wo sich nur schwär i Worte fasse lat. Sie gänd eim Chraft, schänked Vertroue und erinnered eim dra, dass es sogar i schwierige Ziite no ehrlichi und guet Mönsche git.",
en: "There are people you don't just meet in passing. They step into your life and leave behind something that's hard to put into words. They give you strength, offer trust, and remind you that even in difficult times, there are still honest and good people out there.",
fr: "Il y a des gens qu'on ne fait pas que croiser. Ils entrent dans notre vie et y laissent quelque chose difficile à mettre en mots. Ils nous donnent de la force, nous offrent leur confiance et nous rappellent que même dans les moments difficiles, il existe encore des personnes honnêtes et bonnes.",
pt: "Há pessoas que a gente não apenas encontra. Elas entram na nossa vida e deixam algo que é difícil de colocar em palavras. Elas nos dão força, nos oferecem confiança e nos lembram que, mesmo em tempos difíceis, ainda existem pessoas honestas e boas.",
},
tm_quote1: {
de: "Für mich ist Tili genau so ein Mensch.",
"de-CH": "Für mich isch Tili genau so en Mönsch.",
en: "For me, Tili is exactly that kind of person.",
fr: "Pour moi, Tili est exactement ce genre de personne.",
pt: "Para mim, Tili é exatamente esse tipo de pessoa.",
},
tm_2: {
de: "Tili ist nicht nur eine Streamerin, die mich von Anfang an begleitet hat. Sie ist die erste und bis heute einzige Streamerin, die mir über all die Zeit hinweg treu geblieben ist. Während sich Wege verändert, Menschen entfernt und viele Versprechen irgendwann ihre Bedeutung verloren haben, war sie weiterhin da.",
"de-CH": "Tili isch nid nur e Streamerin, wo mich vo Afang a begleitet hät. Sie isch di erschti und bis hüt einzigi Streamerin, wo mir über die ganzi Ziit treu bliebe isch. Während sich Wäg veränderet, Mönsche entfernt und vieli Verspräche irgendwenn ihri Bedütig verlore händ, isch sie witerhin da gsi.",
en: "Tili isn't just a streamer who's been with me from the start. She's the first — and to this day the only — streamer who's stayed loyal to me through all this time. While paths changed, people drifted away, and many promises eventually lost their meaning, she kept being there.",
fr: "Tili n'est pas seulement une streameuse qui m'accompagne depuis le début. Elle est la première — et à ce jour la seule — streameuse qui m'est restée fidèle tout ce temps. Alors que les chemins changeaient, que des gens s'éloignaient et que beaucoup de promesses ont fini par perdre leur sens, elle est restée présente.",
pt: "Tili não é apenas uma streamer que me acompanha desde o início. Ela é a primeira — e até hoje a única — streamer que permaneceu fiel a mim ao longo de todo esse tempo. Enquanto caminhos mudavam, pessoas se afastavam e muitas promessas acabavam perdendo o sentido, ela continuou presente.",
},
tm_3a: {
de: "Nicht nur dann, wenn alles gut lief.",
"de-CH": "Nid nur denn, wenn alles guet gloffe isch.",
en: "Not only when everything was going well.",
fr: "Pas seulement quand tout allait bien.",
pt: "Não só quando tudo ia bem.",
},
tm_3b: {
de: "Nicht nur dann, wenn es etwas zu feiern gab.",
"de-CH": "Nid nur denn, wenn's öppis z'fiire gäbe hät.",
en: "Not only when there was something to celebrate.",
fr: "Pas seulement quand il y avait quelque chose à fêter.",
pt: "Não só quando havia algo a comemorar.",
},
tm_3c: {
de: "Sondern auch in den Momenten, in denen es schwierig wurde und ich Menschen an meiner Seite besonders gebraucht habe.",
"de-CH": "Sondern au i dene Momänt, wo's schwierig worde isch und ich Mönsche a minere Siite bsunders bruucht ha.",
en: "But also in the moments when things got difficult and I especially needed people by my side.",
fr: "Mais aussi dans les moments où c'est devenu difficile et où j'avais particulièrement besoin de gens à mes côtés.",
pt: "Mas também nos momentos em que as coisas ficaram difíceis e eu precisava especialmente de pessoas ao meu lado.",
},
tm_4: {
de: "Genau diese Treue ist etwas, das ich niemals als selbstverständlich ansehen werde.",
"de-CH": "Genau die Treui isch öppis, wo ich niemals als sälbschtverständlich aluege werd.",
en: "That exact loyalty is something I will never take for granted.",
fr: "Cette fidélité est précisément quelque chose que je ne considérerai jamais comme acquise.",
pt: "Exatamente essa lealdade é algo que eu nunca vou considerar óbvio.",
},
tm_5: {
de: "Doch Tili ist für mich schon lange viel mehr als eine Streamerin oder ein Teil meiner TikTok-Geschichte. Sie ist meine zweite Mama, meine ganz persönliche TikTok-Muddi. Ein Mensch, bei dem ich mich nicht verstellen muss und bei dem ich weiß, dass ich mit meinen Gedanken, meinen Sorgen und meinen Gefühlen niemals allein bin.",
"de-CH": "Doch Tili isch für mich scho lang viel meh als e Streamerin oder en Teil vo minere TikTok-Gschicht. Sie isch mini zwöiti Mama, mini ganz persönlichi TikTok-Muddi. En Mönsch, bi dem ich mich nid verstelle muess und bi dem ich weiss, dass ich mit mine Gedanke, mine Sorge und mine Gfüehl niemals elei bi.",
en: "But Tili has long been much more to me than a streamer or a part of my TikTok story. She's my second mom, my very own TikTok Muddi. A person I don't have to pretend around, and with whom I know I'm never alone with my thoughts, my worries, and my feelings.",
fr: "Mais Tili est depuis longtemps bien plus qu'une streameuse ou une partie de mon histoire sur TikTok. Elle est ma deuxième maman, ma TikTok Muddi bien à moi. Une personne avec qui je n'ai pas besoin de faire semblant, et avec qui je sais que je ne suis jamais seul avec mes pensées, mes soucis et mes sentiments.",
pt: "Mas Tili há muito tempo é bem mais do que uma streamer ou uma parte da minha história no TikTok. Ela é minha segunda mãe, minha própria TikTok Muddi. Uma pessoa com quem não preciso fingir e com quem sei que nunca estou sozinho com meus pensamentos, minhas preocupações e meus sentimentos.",
},
tm_6: {
de: "Sie hört zu, ohne sofort zu urteilen. Sie sagt ehrlich ihre Meinung, auch wenn diese vielleicht nicht immer das ist, was ich gerade hören möchte. Und genau das macht echtes Vertrauen aus: nicht nur die schönen Worte zu sagen, sondern füreinander da zu sein, ehrlich zu bleiben und sich gegenseitig wieder aufzurichten.",
"de-CH": "Sie lost zue, ohni sofort z'urteile. Sie seit ehrlich ihri Meinig, au wenn die vilicht nid immer das isch, won ich grad ghöre well. Und genau das macht echts Vertroue us: nid nur die schöne Wörter z'säge, sondern füreinand da z'si, ehrlich z'bliibe und sich gägeseitig wieder ufz'richte.",
en: "She listens without immediately judging. She's honest with her opinion, even when it's not always what I want to hear in that moment. And that's exactly what real trust is: not just saying the nice words, but being there for each other, staying honest, and helping each other back up.",
fr: "Elle écoute sans juger immédiatement. Elle dit honnêtement son avis, même si ce n'est pas toujours ce que j'ai envie d'entendre sur le moment. Et c'est exactement ça, la vraie confiance : ce n'est pas seulement dire de belles paroles, mais être là l'un pour l'autre, rester honnête et se relever mutuellement.",
pt: "Ela escuta sem julgar de imediato. Ela é honesta com sua opinião, mesmo quando nem sempre é o que eu quero ouvir naquele momento. E é exatamente isso que faz a confiança verdadeira: não apenas dizer palavras bonitas, mas estar presente um pelo outro, permanecer honesto e ajudar o outro a se reerguer.",
},
tm_7: {
de: "Neben VanVan gehört Tili zu den wichtigsten Vertrauenspersonen in meinem Leben. Sie kennt nicht nur den Streamer Dogfather, den die Menschen auf TikTok sehen. Sie kennt auch den Menschen dahinter. Sie kennt meine starken Seiten, aber auch meine Unsicherheiten, meine Sorgen und die Momente, in denen selbst ich nicht mehr genau weiß, wie es weitergehen soll.",
"de-CH": "Näbe VanVan ghört Tili zu de wichtigste Vertrouenspersone i minem Läbe. Sie kennt nid nur dr Streamer Dogfather, won d Lüt uf TikTok gseh. Sie kennt au dr Mönsch dehinder. Sie kennt mini starche Siite, aber au mini Unsicherheite, mini Sorge und die Momänt, wo sogar ich nümm gnau weiss, wie's witergo söll.",
en: "Alongside VanVan, Tili is one of the most important trusted people in my life. She doesn't just know Dogfather the streamer that people see on TikTok. She also knows the person behind it. She knows my strengths, but also my insecurities, my worries, and the moments when even I no longer know exactly how to move forward.",
fr: "Aux côtés de VanVan, Tili fait partie des personnes de confiance les plus importantes de ma vie. Elle ne connaît pas seulement Dogfather le streamer que les gens voient sur TikTok. Elle connaît aussi la personne derrière. Elle connaît mes forces, mais aussi mes incertitudes, mes soucis et les moments où même moi je ne sais plus exactement comment avancer.",
pt: "Ao lado de VanVan, Tili é uma das pessoas de confiança mais importantes da minha vida. Ela não conhece apenas o Dogfather streamer que as pessoas veem no TikTok. Ela também conhece a pessoa por trás disso. Ela conhece meus pontos fortes, mas também minhas inseguranças, minhas preocupações e os momentos em que até eu mesmo não sei mais exatamente como seguir em frente.",
},
tm_8: {
de: "Und trotzdem bleibt sie.",
"de-CH": "Und trotzdäm bliibt sie.",
en: "And still, she stays.",
fr: "Et pourtant, elle reste.",
pt: "E, mesmo assim, ela fica.",
},
tm_9: {
de: "Tili gibt mir das Gefühl, verstanden und angenommen zu werden nicht aufgrund von Zahlen, Reichweite, Erfolgen oder irgendeiner Rolle, sondern einfach als der Mensch, der ich bin.",
"de-CH": "Tili git mir s'Gfühl, verstande und agnoh z'werde nid wäge Zahle, Reichwiite, Erfolg oder irgend ere Roll, sondern eifach als dr Mönsch, wo ich bi.",
en: "Tili gives me the feeling of being understood and accepted — not because of numbers, reach, success, or any kind of role, but simply as the person I am.",
fr: "Tili me donne le sentiment d'être compris et accepté — pas à cause de chiffres, de portée, de succès ou d'un quelconque rôle, mais simplement en tant que la personne que je suis.",
pt: "Tili me dá a sensação de ser compreendido e aceito — não por causa de números, alcance, sucesso ou qualquer papel, mas simplesmente como a pessoa que eu sou.",
},
tm_10: {
de: "Sie ist für mich ein Stück Familie geworden.",
"de-CH": "Sie isch für mich es Stück Familie worde.",
en: "She's become a piece of family to me.",
fr: "Elle est devenue pour moi un morceau de famille.",
pt: "Ela se tornou, para mim, um pedaço de família.",
},
tm_11: {
de: "Eine Familie, die nicht durch denselben Namen oder dasselbe Blut entstanden ist, sondern durch Vertrauen, Loyalität, gemeinsame Erlebnisse und die Entscheidung, auch dann füreinander da zu sein, wenn das Leben einmal nicht perfekt läuft.",
"de-CH": "E Familie, wo nid dur dr gliich Name oder s'gliich Bluet entstande isch, sondern dur Vertroue, Loyalität, gmeinsami Erläbnis und dr Entscheid, au denn füreinand da z'si, wenn's Läbe emol nid perfekt lauft.",
en: "A family that wasn't created by the same name or the same blood, but through trust, loyalty, shared experiences, and the decision to be there for each other even when life isn't running perfectly.",
fr: "Une famille qui n'est pas née du même nom ou du même sang, mais de la confiance, de la loyauté, des expériences partagées et de la décision d'être là l'un pour l'autre, même quand la vie ne se déroule pas parfaitement.",
pt: "Uma família que não nasceu do mesmo nome ou do mesmo sangue, mas da confiança, da lealdade, de experiências compartilhadas e da decisão de estar presente um pelo outro mesmo quando a vida não corre perfeitamente.",
},
tm_12: {
de: "Für mich steht Tili für Hoffnung. Sie ist einer der Menschen, die mir zeigen, dass das Gute im Menschen noch existiert. Dass es noch Personen gibt, die nicht nur an sich selbst denken. Menschen, die ein ehrliches Herz besitzen, anderen Mut machen und ihre Hand nicht zurückziehen, sobald der Weg schwieriger wird.",
"de-CH": "Für mich staht Tili für Hoffnig. Sie isch eini vo dene Mönsche, wo mir zeiged, dass s'Guete im Mönsch no existiert. Dass es no Persone git, wo nid nur a sich sälber dänked. Mönsche, wo es ehrlichs Härz händ, andere Muet mached und ihri Hand nid zruckzieh, sobald dr Wäg schwieriger wird.",
en: "To me, Tili stands for hope. She's one of the people who show me that the good in people still exists. That there are still people who don't just think of themselves. People with an honest heart who give others courage and don't pull their hand away the moment the road gets harder.",
fr: "Pour moi, Tili incarne l'espoir. Elle fait partie de ces personnes qui me montrent que la bonté existe encore chez l'être humain. Qu'il existe encore des gens qui ne pensent pas seulement à eux-mêmes. Des personnes au cœur honnête, qui donnent du courage aux autres et ne retirent pas leur main dès que le chemin devient plus difficile.",
pt: "Para mim, Tili representa esperança. Ela é uma das pessoas que me mostram que o bem ainda existe nas pessoas. Que ainda existem pessoas que não pensam só em si mesmas. Pessoas de coração honesto, que dão coragem aos outros e não retiram a mão assim que o caminho fica mais difícil.",
},
tm_13: {
de: "Gerade in einer Welt, in der vieles schnelllebig und oberflächlich geworden ist, ist ein Mensch wie Tili etwas unglaublich Wertvolles.",
"de-CH": "Grad i ere Wält, wo vieles schnälllebig und oberflächlich worde isch, isch en Mönsch wie Tili öppis unglaublich Wärtvolls.",
en: "Especially in a world where so much has become fast-paced and superficial, a person like Tili is something incredibly valuable.",
fr: "Justement dans un monde où beaucoup de choses sont devenues éphémères et superficielles, une personne comme Tili est quelque chose d'incroyablement précieux.",
pt: "Justamente em um mundo onde muita coisa se tornou apressada e superficial, uma pessoa como Tili é algo incrivelmente valioso.",
},
tm_14: {
de: "Sie hat mich unterstützt, an mich geglaubt und mir immer wieder gezeigt, dass ich nicht allein bin. Vielleicht kann ich ihr niemals vollständig zurückgeben, was sie mir durch ihre Art, ihre Treue und ihr Vertrauen gegeben hat. Aber ich möchte, dass sie weiß, dass ich nichts davon vergesse.",
"de-CH": "Sie hät mich unterstützt, a mich glaubt und mir immer wieder zeigt, dass ich nid elei bi. Vilicht chan ich ihre niemals vollständig zruckgäh, was sie mir dur ihri Art, ihri Treui und ihres Vertroue gäh hät. Aber ich well, dass sie weiss, dass ich nüt devo vergiss.",
en: "She has supported me, believed in me, and shown me again and again that I'm not alone. Maybe I can never fully give back what she has given me through her way, her loyalty, and her trust. But I want her to know that I forget none of it.",
fr: "Elle m'a soutenu, a cru en moi et m'a montré encore et encore que je ne suis pas seul. Je ne pourrai peut-être jamais lui rendre pleinement ce qu'elle m'a donné par sa manière d'être, sa fidélité et sa confiance. Mais je veux qu'elle sache que je n'oublie rien de tout cela.",
pt: "Ela me apoiou, acreditou em mim e me mostrou repetidas vezes que eu não estou sozinho. Talvez eu nunca consiga retribuir totalmente o que ela me deu através do seu jeito, da sua lealdade e da sua confiança. Mas eu quero que ela saiba que eu não esqueço nada disso.",
},
tm_15a: {
de: "Ich vergesse nicht, wer geblieben ist.",
"de-CH": "Ich vergiss nid, wär bliebe isch.",
en: "I don't forget who stayed.",
fr: "Je n'oublie pas qui est resté.",
pt: "Eu não esqueço quem ficou.",
},
tm_15b: {
de: "Ich vergesse nicht, wer an mich geglaubt hat.",
"de-CH": "Ich vergiss nid, wär a mich glaubt hät.",
en: "I don't forget who believed in me.",
fr: "Je n'oublie pas qui a cru en moi.",
pt: "Eu não esqueço quem acreditou em mim.",
},
tm_15c: {
de: "Und ich vergesse niemals, wer mir in schweren Momenten gezeigt hat, dass Aufgeben keine Lösung ist.",
"de-CH": "Und ich vergiss niemals, wär mir i schwäre Momänt zeigt hät, dass Ufgäh kei Lösig isch.",
en: "And I will never forget who showed me in the hardest moments that giving up is not a solution.",
fr: "Et je n'oublierai jamais qui m'a montré, dans les moments difficiles, qu'abandonner n'est pas une solution.",
pt: "E eu nunca vou esquecer quem me mostrou, nos momentos mais difíceis, que desistir não é solução.",
},
tm_16: {
de: "Diese Seite ist deshalb nicht einfach nur eine Vorstellung. Sie ist eine persönliche Widmung an einen Menschen, der einen festen Platz in meinem Leben und in meinem Herzen besitzt.",
"de-CH": "Die Site isch drum nid eifach nur e Vorstellig. Sie isch e persönlichi Widmig a en Mönsch, wo en fäschte Platz i minem Läbe und i minem Härz hät.",
en: "This page is therefore not just an introduction. It's a personal dedication to a person who holds a firm place in my life and in my heart.",
fr: "Cette page n'est donc pas simplement une présentation. C'est une dédicace personnelle à une personne qui occupe une place solide dans ma vie et dans mon cœur.",
pt: "Por isso, esta página não é apenas uma apresentação. É uma dedicatória pessoal a uma pessoa que ocupa um lugar firme na minha vida e no meu coração.",
},
tm_danke_h2: {
de: "Danke, Tili.", "de-CH": "Danke, Tili.",
en: "Thank you, Tili.", fr: "Merci, Tili.", pt: "Obrigado, Tili.",
},
tm_danke1: {
de: "Danke für deine Treue.", "de-CH": "Danke für dini Treui.",
en: "Thank you for your loyalty.", fr: "Merci pour ta fidélité.", pt: "Obrigado pela sua lealdade.",
},
tm_danke2: {
de: "Danke für dein Vertrauen.", "de-CH": "Danke für dis Vertroue.",
en: "Thank you for your trust.", fr: "Merci pour ta confiance.", pt: "Obrigado pela sua confiança.",
},
tm_danke3: {
de: "Danke für deine Ehrlichkeit.", "de-CH": "Danke für dini Ehrlichkeit.",
en: "Thank you for your honesty.", fr: "Merci pour ton honnêteté.", pt: "Obrigado pela sua honestidade.",
},
tm_danke4: {
de: "Danke für jedes Gespräch, jeden Rat und jeden Moment, in dem du für mich da warst.",
"de-CH": "Danke für jedes Gspräch, jede Rat und jede Momänt, wo du für mich da gsi bisch.",
en: "Thank you for every conversation, every piece of advice, and every moment you were there for me.",
fr: "Merci pour chaque conversation, chaque conseil et chaque instant où tu as été là pour moi.",
pt: "Obrigado por cada conversa, cada conselho e cada momento em que você esteve presente por mim.",
},
tm_danke5: {
de: "Danke dafür, dass du meine TikTok-Muddi bist und mir immer wieder zeigst, wie wertvoll echte Verbundenheit sein kann.",
"de-CH": "Danke defür, dass du mini TikTok-Muddi bisch und mir immer wieder zeigsch, wie wärtvoll echti Verbundeheit si cha.",
en: "Thank you for being my TikTok Muddi and for showing me again and again how valuable real connection can be.",
fr: "Merci d'être ma TikTok Muddi et de me montrer encore et encore à quel point un vrai lien peut être précieux.",
pt: "Obrigado por ser minha TikTok Muddi e por me mostrar repetidas vezes o quanto uma conexão verdadeira pode ser valiosa.",
},
tm_17: {
de: "Egal, wie viele Wege noch vor uns liegen und wie sehr sich das Leben verändern wird: Du wirst immer ein wichtiger Teil meiner Geschichte sein.",
"de-CH": "Egal, wie vieli Wäg no vor eus liege und wie sehr sich s'Läbe verändere wird: Du wirsch immer en wichtige Teil vo minere Gschicht si.",
en: "No matter how many paths still lie ahead of us and how much life will change: you will always be an important part of my story.",
fr: "Peu importe combien de chemins nous attendent encore et à quel point la vie changera : tu resteras toujours une part importante de mon histoire.",
pt: "Não importa quantos caminhos ainda estejam pela frente e o quanto a vida vá mudar: você sempre será uma parte importante da minha história.",
},
tm_18a: {
de: "Nicht nur als Streamerin.", "de-CH": "Nid nur als Streamerin.",
en: "Not only as a streamer.", fr: "Pas seulement en tant que streameuse.", pt: "Não só como streamer.",
},
tm_18b: {
de: "Nicht nur als Unterstützerin.", "de-CH": "Nid nur als Unterstützerin.",
en: "Not only as a supporter.", fr: "Pas seulement en tant que soutien.", pt: "Não só como apoiadora.",
},
tm_18c: {
de: "Sondern als Vertrauensperson, zweite Mama und Familie.",
"de-CH": "Sondern als Vertrouensperson, zwöiti Mama und Familie.",
en: "But as a trusted person, second mom, and family.",
fr: "Mais en tant que personne de confiance, deuxième maman et famille.",
pt: "Mas como pessoa de confiança, segunda mãe e família.",
},
tm_quote2: {
de: "Diese Seite ist für dich, Tili weil besondere Menschen einen besonderen Platz verdienen.",
"de-CH": "Die Site isch für dich, Tili wil bsundrigi Mönsche en bsundere Platz verdienend.",
en: "This page is for you, Tili — because special people deserve a special place.",
fr: "Cette page est pour toi, Tili — parce que les personnes spéciales méritent une place spéciale.",
pt: "Esta página é para você, Tili — porque pessoas especiais merecem um lugar especial.",
},
tm_signatur_dank: {
de: "In tiefer Dankbarkeit und von ganzem Herzen",
"de-CH": "In tüüfer Dankbarkeit und vo ganzem Härz",
en: "In deep gratitude and with all my heart",
fr: "Avec une profonde gratitude et de tout mon cœur",
pt: "Com profunda gratidão e de todo o coração",
},
tm_signatur1: {
de: "Dein Dogi", "de-CH": "Dein Dogi",
en: "Your Dogi", fr: "Ton Dogi", pt: "Seu Dogi",
},
tm_signatur2: {
de: "Dogfather Filipe 🩵", "de-CH": "Dogfather Filipe 🩵",
en: "Dogfather Filipe 🩵", fr: "Dogfather Filipe 🩵", pt: "Dogfather Filipe 🩵",
},
tm_btn_zurueck: {
de: "← Zurück zu DogFather", "de-CH": "← Zrugg zu DogFather",
en: "← Back to DogFather", fr: "← Retour à DogFather", pt: "← Voltar a DogFather",
},
};
+313 -49
View File
@@ -13,83 +13,347 @@ window.I18N_PAGE = {
en: "Time Travel", fr: "Voyage dans le temps", pt: "Viagem no Tempo",
},
zr_lead: {
de: `Die Geschichte von DogFather &amp; Team Dogi.`,
"de-CH": `Die Gschicht vo DogFather &amp; Team Dogi.`,
en: `The story of DogFather &amp; Team Dogi.`,
fr: `L'histoire de DogFather &amp; Team Dogi.`,
pt: `A história de DogFather &amp; Team Dogi.`,
de: `Vom ersten Livestream bis zum DOGFATHER UNIVERSE — die Reise von DogFather &amp; Team Dogi.`,
"de-CH": `Vom erste Livestream bis zum DOGFATHER UNIVERSE — d Reise vo DogFather &amp; Team Dogi.`,
en: `From the first livestream to the DOGFATHER UNIVERSE — the journey of DogFather &amp; Team Dogi.`,
fr: `Du premier live à l'univers DOGFATHER UNIVERSE — le parcours de DogFather &amp; Team Dogi.`,
pt: `Da primeira live ao DOGFATHER UNIVERSE — a jornada de DogFather &amp; Team Dogi.`,
},
zr_datum_folgt: {
de: "Datum folgt", "de-CH": "Datum chunnt no",
en: "Date coming soon", fr: "Date à venir", pt: "Data em breve",
},
/* ---------- Station 1 — Datum folgt ---------- */
zr_ev1_h3: {
de: "Start als Content Creator", "de-CH": "Start als Content Creator",
en: "Start as a content creator", fr: "Débuts en tant que créateur de contenu", pt: "Início como criador de conteúdo",
en: "Start as a Content Creator", fr: "Débuts en tant que créateur de contenu", pt: "Início como criador de conteúdo",
},
zr_ev1_p: {
de: "Die ersten Schritte auf TikTok.",
"de-CH": "Die erste Schritt uf TikTok.",
en: "The first steps on TikTok.",
fr: "Les premiers pas sur TikTok.",
pt: "Os primeiros passos no TikTok.",
de: "DogFather beginnt seine Reise auf TikTok. Aus ersten Videos und Livestreams entwickelt sich Schritt für Schritt ein eigener Content-Stil mit Humor, Persönlichkeit und direkter Nähe zur Community.",
"de-CH": "DogFather startet sini Reise uf TikTok. Us de erste Videos und Livestreams entwicklet sich Schritt für Schritt en eigete Content-Stil mit Humor, Persönlichkeit und direkte Nechi zur Community.",
en: "DogFather begins his journey on TikTok. From his first videos and livestreams, a unique content style emerges step by step — full of humor, personality, and a genuine closeness to the community.",
fr: "DogFather commence son aventure sur TikTok. À travers ses premières vidéos et lives, un style de contenu bien à lui se dessine peu à peu, fait d'humour, de personnalité et d'une réelle proximité avec la communauté.",
pt: "DogFather começa sua jornada no TikTok. A partir dos primeiros vídeos e lives, um estilo de conteúdo próprio vai surgindo aos poucos, cheio de humor, personalidade e proximidade real com a comunidade.",
},
/* ---------- Station 2 — Datum folgt ---------- */
zr_ev2_h3: {
de: "HasiDog entsteht", "de-CH": "HasiDog entstaht",
en: "HasiDog is born", fr: "Naissance de HasiDog", pt: "Nasce o HasiDog",
de: "Team Dogi entsteht", "de-CH": "Team Dogi entstaht",
en: "Team Dogi Is Born", fr: "Naissance de Team Dogi", pt: "Nasce a Team Dogi",
},
zr_ev2_p: {
de: "Aus dem Spitznamen wird eine eigene Marke — inkl. Musikprojekt auf Spotify.",
"de-CH": "Us em Spitzname wird e eigeni Marke — inklusive Musikprojekt uf Spotify.",
en: "The nickname becomes its own brand — including a music project on Spotify.",
fr: "Le surnom devient une marque à part entière — avec un projet musical sur Spotify.",
pt: "O apelido se transforma em uma marca própria — incluindo um projeto musical no Spotify.",
de: "Aus einzelnen Zuschauern wird eine starke Gemeinschaft. Menschen kommen zusammen, unterstützen sich gegenseitig und erschaffen eine Community, in der Zusammenhalt, Loyalität und Respekt an erster Stelle stehen.",
"de-CH": "Us einzelne Zueschauer wird e starki Gmeinschaft. D Lüt chömed zäme, unterstützed sich gägesitig und erschaffed e Community, wo Zämehalt, Loyalität und Respekt a erster Stell stönd.",
en: "Individual viewers grow into a powerful community. People come together, support each other, and build a community where unity, loyalty, and respect come first.",
fr: "De simples spectateurs se transforment en une communauté soudée. Les gens se rassemblent, se soutiennent mutuellement et créent une communauté où la cohésion, la loyauté et le respect passent avant tout.",
pt: "De simples espectadores nasce uma comunidade forte. As pessoas se unem, se apoiam mutuamente e criam uma comunidade onde união, lealdade e respeito vêm em primeiro lugar.",
},
/* ---------- Station 3 — Ostern 2025 (Meilenstein) ---------- */
zr_ev3_date: {
de: "Ostern 2025", "de-CH": "Oschtere 2025",
en: "Easter 2025", fr: "Pâques 2025", pt: "Páscoa de 2025",
},
zr_ev3_h3: {
de: "Start als Manager bei Spicy Media", "de-CH": "Start als Manager bi Spicy Media",
en: "Start as a manager at Spicy Media", fr: "Débuts en tant que manager chez Spicy Media", pt: "Início como gerente na Spicy Media",
de: "HasiDog wird geboren", "de-CH": "HasiDog wird gebore",
en: "HasiDog Is Born", fr: "Naissance de HasiDog", pt: "Nasce o HasiDog",
},
zr_ev3_p: {
de: "DogFather übernimmt die Manager-Rolle, erste Scouts und Creator kommen dazu.",
"de-CH": "DogFather übernimmt d Manager-Rolle, die erste Scouts und Creator chömed dezue.",
en: "DogFather takes on the manager role, and the first scouts and creators join.",
fr: "DogFather prend le rôle de manager, les premiers scouts et créateurs rejoignent l'équipe.",
pt: "DogFather assume o papel de gerente, os primeiros scouts e criadores se juntam.",
de: "Aus einem Spitznamen entsteht eine eigenständige Marke. HasiDog entwickelt sich zu einem festen Bestandteil des DogFather-Universums mit eigener Persönlichkeit, eigenen Geschichten und einem geplanten Musikprojekt auf Spotify.",
"de-CH": "Us emene Spitzname wird e eigeständigi Marke. HasiDog entwicklet sich zu emene feste Bestandteil vom DogFather-Universum — mit eigeter Persönlichkeit, eigete Gschichte und emene plante Musikprojekt uf Spotify.",
en: "A nickname becomes its own brand. HasiDog grows into a fixed part of the DogFather universe — with his own personality, his own stories, and a planned music project on Spotify.",
fr: "Un surnom devient une marque à part entière. HasiDog devient un élément incontournable de l'univers DogFather — avec sa propre personnalité, ses propres histoires et un projet musical prévu sur Spotify.",
pt: "Um apelido se transforma em uma marca própria. HasiDog se torna parte fixa do universo DogFather — com personalidade, histórias e um projeto musical planejado no Spotify.",
},
/* ---------- Station 4 — 7. März 2026 (Meilenstein) ---------- */
zr_ev4_date: {
de: "7. März 2026", "de-CH": "7. März 2026",
en: "March 7, 2026", fr: "7 mars 2026", pt: "7 de março de 2026",
},
zr_ev4_h3: {
de: `Buch „Hasidog &amp; Casper"`,
"de-CH": `Buech „Hasidog &amp; Casper"`,
en: `Book „Hasidog &amp; Casper"`,
fr: `Livre « Hasidog &amp; Casper »`,
pt: `Livro „Hasidog &amp; Casper"`,
de: "Der 28-Stunden-Stream", "de-CH": "De 28-Stunde-Stream",
en: "The 28-Hour Stream", fr: "Le stream de 28 heures", pt: "A live de 28 horas",
},
zr_ev4_p: {
de: "Die Geschichte von DogFather und seinem Husky wird zum Buch.",
"de-CH": "D Gschicht vo DogFather und sim Husky wird zum Buech.",
en: "The story of DogFather and his husky becomes a book.",
fr: "L'histoire de DogFather et de son husky devient un livre.",
pt: "A história de DogFather e seu husky vira um livro.",
de: "DogFather stellt sich einer besonderen Herausforderung und streamt insgesamt 28 Stunden. Ein intensives Erlebnis voller Unterhaltung, besonderer Momente und starkem Zusammenhalt innerhalb der Community.",
"de-CH": "DogFather stellt sich ere bsundere Herusforderig und streamt insgsamt 28 Stund. Es intensivs Erläbnis voller Underhaltig, bsundere Momänt und starkem Zämehalt innerhalb vo de Community.",
en: "DogFather takes on a very special challenge and streams for a total of 28 hours. An intense experience full of entertainment, special moments, and strong community spirit.",
fr: "DogFather se lance un défi hors norme et streame pendant 28 heures d'affilée. Une expérience intense, pleine de divertissement, de moments forts et d'une grande cohésion au sein de la communauté.",
pt: "DogFather encara um desafio especial e transmite ao vivo por 28 horas seguidas. Uma experiência intensa, cheia de diversão, momentos especiais e muita união na comunidade.",
},
/* ---------- Station 5 — Mai 2026 ---------- */
zr_ev5_date: {
de: "Mai 2026", "de-CH": "Mai 2026",
en: "May 2026", fr: "Mai 2026", pt: "Maio de 2026",
},
zr_ev5_h3: {
de: "Kooperation VanVan Teddys", "de-CH": "Kooperation VanVan Teddys",
en: "VanVan Teddys collaboration", fr: "Collaboration VanVan Teddys", pt: "Colaboração VanVan Teddys",
de: "Ein neues Kapitel beginnt", "de-CH": "Es neus Kapitel fangt a",
en: "A New Chapter Begins", fr: "Un nouveau chapitre commence", pt: "Um novo capítulo começa",
},
zr_ev5_p: {
de: "Merchandise-Kooperation rund um VanVan startet.",
"de-CH": "D Merchandise-Kooperation rund um VanVan startet.",
en: "The merchandise collaboration around VanVan begins.",
fr: "La collaboration de produits dérivés autour de VanVan démarre.",
pt: "Começa a colaboração de produtos em torno do VanVan.",
de: "DogFather beendet die Zusammenarbeit mit seiner bisherigen Agentur und entscheidet sich dazu, seinen weiteren Weg neu auszurichten. Der Fokus liegt dabei auf persönlicher Weiterentwicklung, neuen Zielen und mehr Eigenständigkeit.",
"de-CH": "DogFather beendet d Zämearbeit mit sinere bisherige Agentur und entscheidet sich derfür, sim wiitere Wäg neu uszrichte. De Fokus liit derbi uf persönlicher Wiiterentwicklig, neue Ziel und meh Eigeständigkeit.",
en: "DogFather ends his collaboration with his previous agency and decides to realign his path. The focus shifts to personal growth, new goals, and greater independence.",
fr: "DogFather met fin à sa collaboration avec son agence précédente et décide de réorienter sa trajectoire. L'accent est désormais mis sur son développement personnel, de nouveaux objectifs et plus d'indépendance.",
pt: "DogFather encerra a parceria com sua antiga agência e decide reorientar seu caminho. O foco passa a ser o desenvolvimento pessoal, novas metas e mais independência.",
},
/* ---------- Station 6 — 2. bis 15. Juni 2026 ---------- */
zr_ev6_date: {
de: "2. bis 15. Juni 2026", "de-CH": "2. bis 15. Juni 2026",
en: "June 215, 2026", fr: "Du 2 au 15 juin 2026", pt: "De 2 a 15 de junho de 2026",
},
zr_ev6_h3: {
de: "DOGFATHER UNIVERSE geht online", "de-CH": "DOGFATHER UNIVERSE gaht online",
en: "DOGFATHER UNIVERSE goes online", fr: "DOGFATHER UNIVERSE est mis en ligne", pt: "DOGFATHER UNIVERSE entra no ar",
de: "Die große 12-Stunden-Challenge", "de-CH": "Die grossi 12-Stunde-Challenge",
en: "The Big 12-Hour Challenge", fr: "Le grand défi de 12 heures", pt: "O grande desafio de 12 horas",
},
zr_ev6_p: {
de: "Die eigene Website vereint alle drei Welten erstmals an einem Ort.",
"de-CH": "Die eigeni Website vereint alli drei Wälte zum erste Mal a eim Ort.",
en: "The own website brings all three worlds together in one place for the first time.",
fr: "Le site officiel réunit pour la première fois les trois univers en un seul endroit.",
pt: "O próprio site reúne os três universos pela primeira vez em um só lugar.",
de: "Im Rahmen einer besonderen Community-Aktion stellt sich DogFather einer weiteren Streaming-Herausforderung. Gemeinsam mit Team Dogi entstehen zahlreiche unterhaltsame und unvergessliche Momente.",
"de-CH": "Im Rahme vonere bsundere Community-Aktion stellt sich DogFather ere wiitere Streaming-Herusforderig. Zäme mit Team Dogi entstönd zahlriichi underhaltsami und unvergässlichi Momänt.",
en: "As part of a special community event, DogFather takes on another streaming challenge. Together with Team Dogi, countless entertaining and unforgettable moments are created.",
fr: "Dans le cadre d'une action communautaire spéciale, DogFather relève un nouveau défi de streaming. Avec Team Dogi, de nombreux moments divertissants et inoubliables voient le jour.",
pt: "Como parte de uma ação especial da comunidade, DogFather encara mais um desafio de live. Junto com a Team Dogi, surgem inúmeros momentos divertidos e inesquecíveis.",
},
/* ---------- Station 7 — Juli 2026 ---------- */
zr_ev7_date: {
de: "Juli 2026", "de-CH": "Juli 2026",
en: "July 2026", fr: "Juillet 2026", pt: "Julho de 2026",
},
zr_ev7_h3: {
de: "Start als Manager bei Spicy Media", "de-CH": "Start als Manager bi Spicy Media",
en: "Starting as a Manager at Spicy Media", fr: "Débuts en tant que manager chez Spicy Media", pt: "Início como gerente na Spicy Media",
},
zr_ev7_p: {
de: "DogFather übernimmt bei Spicy Media die Rolle als Manager. Neben seiner Tätigkeit als Streamer beginnt er damit, Creator zu begleiten, Talente zu fördern und ein eigenes, starkes Team aufzubauen.",
"de-CH": "DogFather übernimmt bi Spicy Media d Rolle als Manager. Näbe sinere Tätigkeit als Streamer fangt er a, Creator z'begleite, Talänt z'fördere und es eiges, starkes Team ufzboue.",
en: "DogFather takes on the role of manager at Spicy Media. Alongside his work as a streamer, he begins guiding creators, nurturing talent, and building his own strong team.",
fr: "DogFather devient manager chez Spicy Media. En plus de son activité de streamer, il commence à accompagner des créateurs, à révéler des talents et à bâtir sa propre équipe solide.",
pt: "DogFather assume o cargo de gerente na Spicy Media. Além de atuar como streamer, ele passa a acompanhar criadores, descobrir talentos e construir sua própria equipe forte.",
},
/* ---------- Station 8 — Juli 2026 ---------- */
zr_ev8_date: {
de: "Juli 2026", "de-CH": "Juli 2026",
en: "July 2026", fr: "Juillet 2026", pt: "Julho de 2026",
},
zr_ev8_h3: {
de: "Das Manager-Team wächst", "de-CH": "Ds Manager-Team wachst",
en: "The Manager Team Grows", fr: "L'équipe de management s'agrandit", pt: "A equipe de gerência cresce",
},
zr_ev8_p: {
de: "Mit VanVan als rechter Hand und Diene als wichtiger Unterstützung entsteht eine klare Teamstruktur. Gemeinsam werden Creator begleitet, Probleme gelöst und neue Projekte geplant.",
"de-CH": "Mit VanVan als rechti Hand und Diene als wichtigi Unterstützig entstaht e klari Teamstruktur. Zäme wärded Creator begleitet, Problem glöst und neui Projekt planet.",
en: "With VanVan as his right hand and Diene as key support, a clear team structure takes shape. Together, they guide creators, solve problems, and plan new projects.",
fr: "Avec VanVan comme bras droit et Diene comme soutien essentiel, une structure d'équipe claire se met en place. Ensemble, ils accompagnent les créateurs, résolvent les problèmes et planifient de nouveaux projets.",
pt: "Com VanVan como braço direito e Diene como apoio fundamental, surge uma estrutura de equipe clara. Juntos, eles acompanham criadores, resolvem problemas e planejam novos projetos.",
},
/* ---------- Station 9 — 27. Juli bis 2. August 2026 (Meilenstein) ---------- */
zr_ev9_date: {
de: "27. Juli bis 2. August 2026", "de-CH": "27. Juli bis 2. Auguscht 2026",
en: "July 27 August 2, 2026", fr: "Du 27 juillet au 2 août 2026", pt: "De 27 de julho a 2 de agosto de 2026",
},
zr_ev9_h3: {
de: "Der Creator Cup", "de-CH": "De Creator Cup",
en: "The Creator Cup", fr: "Le Creator Cup", pt: "O Creator Cup",
},
zr_ev9_p: {
de: "Gemeinsam mit Cidem organisiert DogFather den Creator Cup für die Streamer von Spicy Media. Liveminuten, Teamherzen und Coins werden zu Punkten verbunden mit besonderen Preisen und einer starken gemeinsamen Aktion.",
"de-CH": "Zäme mit Cidem organisiert DogFather de Creator Cup für d Streamer vo Spicy Media. Liveminute, Teamherze und Coins wärded zu Punkt — verbunde mit bsundere Priise und ere starke gmeinsame Aktion.",
en: "Together with Cidem, DogFather organizes the Creator Cup for Spicy Media's streamers. Live minutes, team hearts, and coins become points — combined with special prizes and a strong joint event.",
fr: "Avec Cidem, DogFather organise le Creator Cup pour les streamers de Spicy Media. Minutes de live, cœurs d'équipe et coins deviennent des points, avec des récompenses spéciales et un fort esprit collectif.",
pt: "Junto com Cidem, DogFather organiza o Creator Cup para os streamers da Spicy Media. Minutos ao vivo, corações da equipe e coins viram pontos, com prêmios especiais e uma forte ação em conjunto.",
},
/* ---------- Station 10 — 28. Juli 2026 ---------- */
zr_ev10_date: {
de: "28. Juli 2026", "de-CH": "28. Juli 2026",
en: "July 28, 2026", fr: "28 juillet 2026", pt: "28 de julho de 2026",
},
zr_ev10_h3: {
de: "Patrick und Bananenstift werden Scouts", "de-CH": "Patrick und Bananenstift wärded Scouts",
en: "Patrick and Bananenstift Become Scouts", fr: "Patrick et Bananenstift deviennent scouts", pt: "Patrick e Bananenstift se tornam scouts",
},
zr_ev10_p: {
de: "Patrick und Bananenstift schließen sich DogFather als Scouts an. Ihre Aufgabe ist es, neue Talente auf TikTok zu entdecken, zu begleiten und auf ihrem Weg als Creator zu unterstützen.",
"de-CH": "Patrick und Bananenstift schliessed sich DogFather als Scouts a. Ihri Ufgab isch, neui Talänt uf TikTok z'entdecke, z'begleite und uf ihrem Wäg als Creator z'unterstütze.",
en: "Patrick and Bananenstift join DogFather as scouts. Their job is to discover new talent on TikTok, guide them, and support them on their journey as creators.",
fr: "Patrick et Bananenstift rejoignent DogFather en tant que scouts. Leur mission : dénicher de nouveaux talents sur TikTok, les accompagner et les soutenir dans leur parcours de créateur.",
pt: "Patrick e Bananenstift se juntam a DogFather como scouts. A missão deles é descobrir novos talentos no TikTok, acompanhá-los e apoiá-los em sua jornada como criadores.",
},
/* ---------- Station 11 — 28. Juli 2026 ---------- */
zr_ev11_date: {
de: "28. Juli 2026", "de-CH": "28. Juli 2026",
en: "July 28, 2026", fr: "28 juillet 2026", pt: "28 de julho de 2026",
},
zr_ev11_h3: {
de: "Aufbau eines eigenen Creator-Systems", "de-CH": "Ufbou vonemene eigete Creator-System",
en: "Building an Own Creator System", fr: "Construction d'un système de créateurs", pt: "Construção de um sistema próprio de criadores",
},
zr_ev11_p: {
de: "DogFather entwickelt gemeinsam mit seinen Scouts eine langfristige Struktur für Creator, Scouts und zukünftige Manager. Das Ziel: Menschen nicht nur zu finden, sondern sie dauerhaft zu fördern und gemeinsam mit ihnen zu wachsen.",
"de-CH": "DogFather entwicklet zäme mit sine Scouts e langfristigi Struktur für Creator, Scouts und zuekünftigi Manager. Ds Ziel: Mensche nid nur z'finde, sondern sie duurhaft z'fördere und zäme mit ihne z'wachse.",
en: "Together with his scouts, DogFather develops a long-term structure for creators, scouts, and future managers. The goal: not just to find people, but to support them long-term and grow together with them.",
fr: "Avec ses scouts, DogFather développe une structure durable pour les créateurs, les scouts et les futurs managers. L'objectif : ne pas seulement trouver des talents, mais les accompagner durablement et grandir avec eux.",
pt: "Junto com seus scouts, DogFather desenvolve uma estrutura de longo prazo para criadores, scouts e futuros gerentes. O objetivo: não apenas encontrar pessoas, mas apoiá-las de forma duradoura e crescer junto com elas.",
},
/* ---------- Station 12 — Ende Juli 2026 (Meilenstein) ---------- */
zr_ev12_date: {
de: "Ende Juli 2026", "de-CH": "Ändi Juli 2026",
en: "Late July 2026", fr: "Fin juillet 2026", pt: "Final de julho de 2026",
},
zr_ev12_h3: {
de: "Das DOGFATHER UNIVERSE nimmt Form an", "de-CH": "Ds DOGFATHER UNIVERSE nimmt Form a",
en: "The DOGFATHER UNIVERSE Takes Shape", fr: "L'univers DOGFATHER UNIVERSE prend forme", pt: "O DOGFATHER UNIVERSE toma forma",
},
zr_ev12_p: {
de: "Die Planung einer eigenen Website beginnt. Sie soll die drei großen Welten von DogFather erstmals miteinander verbinden: den Streamer DogFather, den Manager bei Spicy Media und die Marke HasiDog.",
"de-CH": "D Planig vonere eigete Website startet. Sie soll die drei grosse Wälte vo DogFather zum erste Mal mitenand verbinde: de Streamer DogFather, de Manager bi Spicy Media und d Marke HasiDog.",
en: "Planning begins for a website of its own. It's meant to connect DogFather's three big worlds for the first time: the streamer DogFather, the manager at Spicy Media, and the HasiDog brand.",
fr: "La planification d'un site web propre commence. Il doit réunir pour la première fois les trois grands univers de DogFather : le streamer DogFather, le manager chez Spicy Media et la marque HasiDog.",
pt: "Começa o planejamento de um site próprio. Ele deve unir pela primeira vez os três grandes universos de DogFather: o streamer DogFather, o gerente na Spicy Media e a marca HasiDog.",
},
/* ---------- Station 13 — Datum folgt ---------- */
zr_ev13_h3: {
de: `Das Buch „HasiDog &amp; Casper"`, "de-CH": `Ds Buech „HasiDog &amp; Casper"`,
en: `The Book "HasiDog &amp; Casper"`, fr: `Le livre « HasiDog &amp; Casper »`, pt: `O livro "HasiDog &amp; Casper"`,
},
zr_ev13_p: {
de: "Die besondere Geschichte von DogFather, HasiDog und seinem Husky Casper wird zu einem eigenen Buchprojekt. Eine Geschichte über Freundschaft, Familie, Zusammenhalt und gemeinsame Abenteuer.",
"de-CH": "D bsunderi Gschicht vo DogFather, HasiDog und sim Husky Casper wird zu emene eigete Buechprojekt. E Gschicht über Fründschaft, Familie, Zämehalt und gmeinsami Abentüür.",
en: "The special story of DogFather, HasiDog, and his husky Casper becomes its own book project. A story about friendship, family, togetherness, and shared adventures.",
fr: "L'histoire particulière de DogFather, HasiDog et de son husky Casper devient un véritable projet de livre. Une histoire d'amitié, de famille, de cohésion et d'aventures partagées.",
pt: "A história especial de DogFather, HasiDog e seu husky Casper se transforma em um projeto de livro próprio. Uma história sobre amizade, família, união e aventuras compartilhadas.",
},
/* ---------- Station 14 — Datum folgt ---------- */
zr_ev14_h3: {
de: "HasiDog startet auf Spotify", "de-CH": "HasiDog startet uf Spotify",
en: "HasiDog Launches on Spotify", fr: "HasiDog arrive sur Spotify", pt: "HasiDog estreia no Spotify",
},
zr_ev14_p: {
de: "HasiDog erhält sein eigenes Musikprojekt. Songs und weitere Informationen folgen.",
"de-CH": "HasiDog überchunnt si eiges Musikprojekt. Songs und wiiteri Informatione chömed no.",
en: "HasiDog gets his own music project. Songs and more information to follow.",
fr: "HasiDog obtient son propre projet musical. Chansons et informations complémentaires à venir.",
pt: "HasiDog ganha seu próprio projeto musical. Músicas e mais informações em breve.",
},
/* ---------- Station 15 — Datum folgt ---------- */
zr_ev15_h3: {
de: "Kooperation mit VanVan Teddys", "de-CH": "Kooperation mit VanVan Teddys",
en: "Collaboration with VanVan Teddys", fr: "Collaboration avec VanVan Teddys", pt: "Colaboração com VanVan Teddys",
},
zr_ev15_p: {
de: "Eine eigene Merchandise-Kooperation rund um VanVan startet. Geplant sind besondere Produkte, die ihre Persönlichkeit und ihre wichtige Rolle innerhalb von Team Dogi widerspiegeln.",
"de-CH": "E eigeni Merchandise-Kooperation rund um VanVan startet. Plant sind bsunderi Produkt, wo ihri Persönlichkeit und ihri wichtigi Roll innerhalb vo Team Dogi widerspiegled.",
en: "A dedicated merchandise collaboration around VanVan launches. Special products are planned that reflect her personality and her important role within Team Dogi.",
fr: "Une collaboration de produits dérivés dédiée à VanVan démarre. Des produits spéciaux sont prévus, reflétant sa personnalité et son rôle important au sein de Team Dogi.",
pt: "Começa uma colaboração própria de produtos em torno da VanVan. Estão previstos produtos especiais que refletem sua personalidade e seu papel importante dentro da Team Dogi.",
},
/* ---------- Station 16 — Datum folgt ---------- */
zr_ev16_h3: {
de: "Die ersten betreuten Creator", "de-CH": "Die erste betreute Creator",
en: "The First Supported Creators", fr: "Les premiers créateurs accompagnés", pt: "Os primeiros criadores acompanhados",
},
zr_ev16_p: {
de: "Die ersten Creator schließen sich dem Team von Manager DogFather an. Sie erhalten persönliche Unterstützung, Hilfe bei Problemen, Profil-Checks, Schulungen und eine langfristige Begleitung auf TikTok.",
"de-CH": "Die erste Creator schliessed sich em Team vom Manager DogFather a. Sie überchömed persönlichi Unterstützig, Hilf bi Problem, Profil-Checks, Schulige und e langfristigi Begleitig uf TikTok.",
en: "The first creators join Manager DogFather's team. They receive personal support, help with problems, profile checks, training, and long-term guidance on TikTok.",
fr: "Les premiers créateurs rejoignent l'équipe du manager DogFather. Ils bénéficient d'un accompagnement personnalisé, d'aide en cas de problème, de vérifications de profil, de formations et d'un suivi durable sur TikTok.",
pt: "Os primeiros criadores se juntam à equipe do gerente DogFather. Eles recebem apoio pessoal, ajuda com problemas, análises de perfil, treinamentos e acompanhamento de longo prazo no TikTok.",
},
/* ---------- Station 17 — Datum folgt ---------- */
zr_ev17_h3: {
de: "Weitere Scouts und Manager kommen hinzu", "de-CH": "Wiiteri Scouts und Manager chömed dezue",
en: "More Scouts and Managers Join", fr: "Plus de scouts et de managers rejoignent l'équipe", pt: "Mais scouts e gerentes se juntam",
},
zr_ev17_p: {
de: "Das Team soll langfristig weiter wachsen. Engagierte Scouts erhalten die Möglichkeit, sich über verschiedene Entwicklungsstufen bis hin zum eigenen Manager weiterzuentwickeln.",
"de-CH": "Ds Team söll langfristig wiiter wachse. Engagierti Scouts überchömed d Möglichkeit, sich über verschideni Entwickligsstufe bis zum eigete Manager wiiterzentwickle.",
en: "The team is set to keep growing long-term. Dedicated scouts get the chance to develop through various stages all the way up to becoming a manager themselves.",
fr: "L'équipe est destinée à continuer de grandir sur le long terme. Les scouts engagés ont la possibilité d'évoluer à travers différents niveaux, jusqu'à devenir eux-mêmes managers.",
pt: "A equipe deve continuar crescendo a longo prazo. Scouts dedicados ganham a chance de evoluir por diferentes níveis até se tornarem gerentes.",
},
/* ---------- Station 18 — Datum folgt ---------- */
zr_ev18_h3: {
de: "Das erste Community-Treffen", "de-CH": "Ds erste Community-Träffe",
en: "The First Community Meetup", fr: "La première rencontre communautaire", pt: "O primeiro encontro da comunidade",
},
zr_ev18_p: {
de: "Team Dogi begegnet sich nicht mehr nur im Livestream oder auf Discord. Beim gemeinsamen Treffen entstehen echte Erinnerungen, die zeigen, dass diese Community weit mehr als nur Zahlen und Likes ist.",
"de-CH": "Team Dogi begägnet sich nid nur im Livestream oder uf Discord. Bim gmeinsame Träffe entstönd echti Erinnerige, wo zeiged, dass die Community wit meh isch als nume Zahle und Likes.",
en: "Team Dogi no longer just meets in livestreams or on Discord. At the shared meetup, real memories are made — proof that this community is far more than just numbers and likes.",
fr: "Team Dogi ne se retrouve plus seulement en live ou sur Discord. Lors de la rencontre commune naissent de vrais souvenirs, preuve que cette communauté est bien plus que des chiffres et des likes.",
pt: "A Team Dogi não se encontra mais só em lives ou no Discord. No encontro presencial nascem memórias reais, mostrando que essa comunidade é muito mais do que números e curtidas.",
},
/* ---------- Station 19 — 2026 Datum folgt (Meilenstein) ---------- */
zr_ev19_date: {
de: "2026 Datum folgt", "de-CH": "2026 Datum chunnt no",
en: "2026 date coming soon", fr: "2026 date à venir", pt: "2026 data em breve",
},
zr_ev19_h3: {
de: "DOGFATHER UNIVERSE geht online", "de-CH": "DOGFATHER UNIVERSE gaht online",
en: "DOGFATHER UNIVERSE Goes Online", fr: "DOGFATHER UNIVERSE est en ligne", pt: "DOGFATHER UNIVERSE entra no ar",
},
zr_ev19_p: {
de: "Die offizielle Website öffnet ihre Türen. Sie vereint DogFather als Streamer, seine Arbeit als Manager bei Spicy Media, HasiDog, Casper, Team Dogi, die Creator, Scouts, Moderatoren und alle wichtigen Projekte erstmals an einem gemeinsamen Ort.",
"de-CH": "D offizielli Website öffnet ihri Türe. Sie vereint DogFather als Streamer, sini Arbeit als Manager bi Spicy Media, HasiDog, Casper, Team Dogi, d Creator, d Scouts, d Moderatore und alli wichtige Projäkt zum erste Mal a eim gmeinsame Ort.",
en: "The official website opens its doors. It brings together DogFather as a streamer, his work as a manager at Spicy Media, HasiDog, Casper, Team Dogi, the creators, scouts, moderators, and all major projects in one shared place for the first time.",
fr: "Le site officiel ouvre ses portes. Il réunit pour la première fois DogFather en tant que streamer, son travail de manager chez Spicy Media, HasiDog, Casper, Team Dogi, les créateurs, les scouts, les modérateurs et tous les projets importants en un seul endroit.",
pt: "O site oficial abre suas portas. Ele reúne pela primeira vez, em um só lugar, DogFather como streamer, seu trabalho como gerente na Spicy Media, HasiDog, Casper, a Team Dogi, os criadores, scouts, moderadores e todos os projetos importantes.",
},
/* ---------- Station 20 — Fortsetzung folgt (Finale) ---------- */
zr_ev20_date: {
de: "Fortsetzung folgt", "de-CH": "Fortsetzig chunnt no",
en: "To be continued", fr: "À suivre", pt: "Continua",
},
zr_ev20_h3: {
de: "Die Geschichte ist noch lange nicht vorbei", "de-CH": "D Gschicht isch no lang nid verbi",
en: "The Story Is Far From Over", fr: "L'histoire est loin d'être terminée", pt: "A história está longe de acabar",
},
zr_ev20_p: {
de: "Das DOGFATHER UNIVERSE wächst weiter. Neue Creator, Kooperationen, Aktionen, Musikprojekte, Geschichten und große Community-Momente werden Teil dieser Reise.",
"de-CH": "Ds DOGFATHER UNIVERSE wachst wiiter. Neui Creator, Kooperatione, Aktione, Musikprojäkt, Gschichte und grossi Community-Momänt wärded Teil vo dere Reise.",
en: "The DOGFATHER UNIVERSE keeps growing. New creators, collaborations, events, music projects, stories, and big community moments become part of this journey.",
fr: "L'univers DOGFATHER UNIVERSE continue de grandir. Nouveaux créateurs, collaborations, actions, projets musicaux, histoires et grands moments communautaires font désormais partie de cette aventure.",
pt: "O DOGFATHER UNIVERSE continua crescendo. Novos criadores, parcerias, ações, projetos musicais, histórias e grandes momentos da comunidade fazem parte dessa jornada.",
},
zr_ev20_quote: {
de: "Denn aus einem einzelnen TikTok-Livestream wurde eine Community und aus dieser Community wurde eine Familie.",
"de-CH": "Dänn us eim einzelne TikTok-Livestream isch e Community worde — und us dere Community isch e Familie worde.",
en: "Because a single TikTok livestream became a community — and this community became a family.",
fr: "Car un simple live TikTok est devenu une communauté — et cette communauté est devenue une famille.",
pt: "Porque uma simples live no TikTok virou uma comunidade — e essa comunidade virou uma família.",
},
zr_ev20_familie: {
de: "Team Dogi ist Familie. 🩵", "de-CH": "Team Dogi isch Familie. 🩵",
en: "Team Dogi is family. 🩵", fr: "Team Dogi, c'est la famille. 🩵", pt: "Team Dogi é família. 🩵",
},
zr_ev20_signoff: {
de: "Liebe Grüße<br>-euer DogFather", "de-CH": "Liebi Grüess<br>-öie DogFather",
en: "With love,<br>-your DogFather", fr: "Avec toute mon affection,<br>-votre DogFather", pt: "Com carinho,<br>-seu DogFather",
},
/* ---------- Baum-Deko ---------- */
zr_baum_start: {
de: "Der Anfang", "de-CH": "De Aafang",
en: "The Beginning", fr: "Le début", pt: "O começo",
},
zr_baum_wächst: {
de: "…und die Geschichte wächst weiter", "de-CH": "…und d Gschicht wachst wiiter",
en: "…and the story keeps growing", fr: "…et l'histoire continue de grandir", pt: "…e a história continua a crescer",
},
};
+205 -1
View File
@@ -82,6 +82,7 @@
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": "Zytreis", en: "Timeline", fr: "Chronologie", pt: "Linha do tempo" },
nav_dogfather_ttmuddi: { de: "TT-Muddi", "de-CH": "TT-Muddi", en: "TT-Muddi", fr: "TT-Muddi", pt: "TT-Muddi" },
nav_hasidog: { de: "HasiDog", "de-CH": "HasiDog", en: "HasiDog", fr: "HasiDog", pt: "HasiDog" },
nav_hasidog_welt: { de: "HasiDog-Welt", "de-CH": "HasiDog-Wält", 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" },
@@ -100,6 +101,9 @@
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": "Bewärbe 🩵", en: "Apply 🩵", fr: "Postuler 🩵", pt: "Candidatar-se 🩵" },
nav_cta_abo_anonym: { de: "DogiCrew 👑", "de-CH": "DogiCrew 👑", en: "DogiCrew 👑", fr: "DogiCrew 👑", pt: "DogiCrew 👑" },
nav_cta_abo_aktivieren: { de: "Abo aktivieren 👑", "de-CH": "Abo aktiviere 👑", en: "Activate Subscription 👑", fr: "Activer l'abonnement 👑", pt: "Ativar assinatura 👑" },
nav_cta_abo_bereich: { de: "Supporter-Bereich 👑", "de-CH": "Supporter-Bereich 👑", en: "Supporter Area 👑", fr: "Espace Supporter 👑", pt: "Área do Apoiador 👑" },
nav_toggle_aria: { de: "Menü öffnen", "de-CH": "Menü uftue", en: "Open menu", fr: "Ouvrir le menu", pt: "Abrir menu" },
sprache_aria: { de: "Sprache wählen", "de-CH": "Sprach uswähle", en: "Choose language", fr: "Choisir la langue", pt: "Escolher idioma" },
brand_tagline: {
@@ -192,6 +196,7 @@
{ key: "nav_dogfather_streamer", href: "streamer.html" },
{ key: "nav_dogfather_casper", href: "casper.html" },
{ key: "nav_dogfather_vanvan", href: "vanvan.html" },
{ key: "nav_dogfather_ttmuddi", href: "tt-muddi.html" },
{ key: "nav_dogfather_zeitreise", href: "zeitreise.html" },
],
},
@@ -313,6 +318,173 @@
</div>`;
}
/* ===================================================================
Vorschau-Modus für Dogi + VanVan (Zugangsschranke, siehe gate-worker.js)
Solange die Seite noch nicht öffentlich ist, kommen nur Dogi und VanVan
per Zugangscode rein (gate-worker.js setzt dabei ein lesbares Cookie
"dogi_role=dogi"/"vanvan" — NICHT das eigentliche Sicherheits-Cookie,
das bleibt HttpOnly). Damit die beiden die Seite auch "als Abonnent"
bzw. "als Nicht-Abonnent" ansehen können, OHNE ein echtes Abo
abschließen zu müssen, gibt es einen kleinen Umschalter unten links,
der NUR erscheint, wenn das Rollen-Cookie gesetzt ist. Die Wahl landet
in localStorage und wird von renderAboButton() sowie von supporter.js/
supporter.html (Mock-Daten statt echtem API-Aufruf) ausgelesen.
=================================================================== */
const VORSCHAU_SCHLUESSEL = "dogiPreviewMode"; // "abonnent" | "nicht-abonnent" | leer = echter Stand
function getCookieWert(name) {
const treffer = document.cookie.match(new RegExp(`(?:^|;\\s*)${name}=([^;]+)`));
return treffer ? decodeURIComponent(treffer[1]) : null;
}
function getVorschauRolle() {
return getCookieWert("dogi_role"); // "dogi" | "vanvan" | null
}
/* Realistischer Anzeigename fürs Vorschau-Konto — Nutzer-Feedback
03.08.2026: "ich will in der Vorschau alles sehen wie es fertig sein
wird, nix da stehen haben von Vorschau, das bringt mir nix." Statt dem
Wort "Vorschau" irgendwo im Text zeigt die Vorschau jetzt einfach den
Namen der Person, die gerade eingeloggt ist (Dogi oder VanVan) — sieht
dadurch exakt so aus wie ein echtes, fertiges Konto. */
function vorschauAnzeigename() {
const rolle = getVorschauRolle();
return rolle === "vanvan" ? "VanVan" : "Dogi";
}
window.dogiVorschauName = vorschauAnzeigename; // öffentlich, für supporter.html
function getVorschauModus() {
if (!getVorschauRolle()) return null; // Umschalter nur für Dogi/VanVan gültig
const wert = localStorage.getItem(VORSCHAU_SCHLUESSEL);
return wert === "abonnent" || wert === "nicht-abonnent" ? wert : null;
}
function setVorschauModus(modus) {
if (modus) localStorage.setItem(VORSCHAU_SCHLUESSEL, modus);
else localStorage.removeItem(VORSCHAU_SCHLUESSEL);
renderHeader();
renderVorschauSchalter();
document.dispatchEvent(new CustomEvent("dogi-vorschau-geaendert", { detail: { modus } }));
}
window.dogiVorschauModus = getVorschauModus; // öffentlich, für supporter.html/abonnieren.html
/* Aufklappbarer Kreisknopf unten links, spiegelbildlich zum Musik-Knopf
unten rechts (gleiche Bauart, siehe .vorschau-toggle/.vorschau-panel in
main.css) — Nutzer-Feedback 03.08.2026: statt einer dauerhaft offenen
Text-Knopfleiste "so ein Button wie bei VanVan", der sich erst bei
Klick öffnet. Nur EINMAL erzeugt (wie beim Musik-Widget), damit ein
offenes Panel beim nahtlosen Seitenwechsel nicht jedes Mal neu gebaut
wird — nur der Inhalt (aktive Auswahl) wird bei jedem Aufruf aktuell
gehalten. */
function renderVorschauSchalter() {
if (!getVorschauRolle()) return; // öffentliche Besucher sehen nie etwas
let widget = document.getElementById("vorschau-widget");
if (!widget) {
widget = document.createElement("div");
widget.className = "vorschau-widget";
widget.id = "vorschau-widget";
widget.innerHTML = `
<div class="vorschau-panel" id="vorschau-panel" hidden>
<div class="vorschau-panel-head">
<strong>🎭 Vorschau</strong>
<button class="vorschau-close" id="vorschau-close" type="button" aria-label="Vorschau-Feld schließen">✕</button>
</div>
<div class="vorschau-optionen" id="vorschau-optionen"></div>
</div>
<button class="vorschau-toggle" id="vorschau-toggle" type="button"
aria-expanded="false" aria-controls="vorschau-panel"
title="Vorschau: als Abonnent/Nicht-Abonnent ansehen"><span>🎭</span></button>`;
document.body.appendChild(widget);
const panel = document.getElementById("vorschau-panel");
const toggle = document.getElementById("vorschau-toggle");
const oeffnen = (auf) => {
panel.hidden = !auf;
toggle.setAttribute("aria-expanded", String(auf));
widget.classList.toggle("open", auf);
};
toggle.addEventListener("click", () => oeffnen(panel.hidden));
document.getElementById("vorschau-close").addEventListener("click", () => oeffnen(false));
document.addEventListener("keydown", (e) => {
if (e.key === "Escape" && !panel.hidden) oeffnen(false);
});
document.getElementById("vorschau-optionen").addEventListener("click", (e) => {
const btn = e.target.closest("button[data-vorschau]");
if (!btn) return;
setVorschauModus(btn.dataset.vorschau === "echt" ? null : btn.dataset.vorschau);
});
}
const aktuell = getVorschauModus();
const knopf = (wert, label) => {
const aktiv = wert === "echt" ? !aktuell : aktuell === wert;
return `<button type="button" data-vorschau="${wert}" class="${aktiv ? "aktiv" : ""}">${aktiv ? "✓ " : ""}${label}</button>`;
};
document.getElementById("vorschau-optionen").innerHTML =
knopf("echt", "Echter Login-Stand") + knopf("abonnent", "Als Abonnent") + knopf("nicht-abonnent", "Als Nicht-Abonnent");
}
/* Abo-Button in der Hauptnavigation (Dogfather_VanVan_Supporter_Abo.odt,
Abschnitt 3) — Beschriftung/Ziel hängt vom Supporter-Login-Stand ab.
Bewusst KEIN API-Aufruf bei jedem Seitenaufruf (würde jede einzelne
Seite der Website an den Worker koppeln) — stattdessen wird der zuletzt
bekannte Stand aus localStorage gelesen, den supporter.html/
abonnieren.html bei jedem eigenen Laden aktuell hält (siehe dort).
Vorschau-Modus (Dogi/VanVan, siehe oben) überschreibt das für den
Nav-Knopf, unabhängig vom echten Login-Stand.
Nutzer-Feedback 03.08.2026: Ist man eingeloggt UND hat ein Abo, soll im
Knopf nicht der generische Text "Supporter-Bereich" stehen, sondern der
eigene Benutzername (aus /supporter/me → profile.displayName, wird von
abonnieren.html/supporter.html per S.cacheDisplayName() aktuell
gehalten). displayName ist freier Nutzertext -> escapeHtml() ist
Pflicht (sonst XSS über den eigenen Anzeigenamen möglich), und wird auf
eine im Knopf sinnvolle Länge gekürzt. */
function escapeHtml(text) {
return String(text).replace(/[&<>"']/g, (z) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }[z]));
}
function kuerzen(text, maxLaenge) {
return text.length > maxLaenge ? text.slice(0, maxLaenge - 1).trimEnd() + "…" : text;
}
function bereichLabel(name) {
const sauber = (name || "").trim();
if (!sauber) return t("nav_cta_abo_bereich");
return `${escapeHtml(kuerzen(sauber, 18))} 👑`;
}
function renderAboButton() {
const vorschau = getVorschauModus();
if (vorschau === "abonnent") {
// Ist Dogi/VanVan zufällig wirklich mit einem echten Konto
// eingeloggt (echter Name im Speicher), soll auch in der Vorschau
// DER echte Name stehen. Ohne echtes Konto fällt es auf den Namen
// der eingeloggten Rolle zurück (vorschauAnzeigename() — "Dogi" oder
// "VanVan"), NICHT auf einen erkennbaren "Vorschau"-Platzhalter,
// damit die Vorschau exakt so aussieht wie das fertige Ergebnis
// (Nutzer-Feedback 03.08.2026: "nix da stehen haben von Vorschau,
// das bringt mir nix").
const echterName = localStorage.getItem("supporterDisplayName");
return `<a class="nav-cta nav-cta-abo" href="supporter.html"><span>${bereichLabel(echterName || vorschauAnzeigename())}</span></a>`;
}
if (vorschau === "nicht-abonnent") {
return `<a class="nav-cta nav-cta-abo" href="abonnieren.html"><span>${t("nav_cta_abo_anonym")}</span></a>`;
}
const token = localStorage.getItem("supporterToken");
const status = localStorage.getItem("supporterSubStatus");
if (!token) {
return `<a class="nav-cta nav-cta-abo" href="abonnieren.html"><span>${t("nav_cta_abo_anonym")}</span></a>`;
}
const hatBereich = ["active", "pending", "suspended", "cancelled"].includes(status);
if (hatBereich) {
const name = localStorage.getItem("supporterDisplayName");
return `<a class="nav-cta nav-cta-abo" href="supporter.html"><span>${bereichLabel(name)}</span></a>`;
}
return `<a class="nav-cta nav-cta-abo" href="abonnieren.html"><span>${t("nav_cta_abo_aktivieren")}</span></a>`;
}
function renderHeader() {
const el = document.getElementById("site-header");
if (!el) return;
@@ -329,6 +501,7 @@
<nav class="nav-links">
${NAV.map(renderNavItem).join("")}
${renderSprachSchalter()}
${renderAboButton()}
<a class="nav-cta" href="bewerben.html"><span>${t("nav_cta_bewerben")}</span></a>
</nav>
</div>
@@ -389,6 +562,7 @@
<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="tt-muddi.html">${t("nav_dogfather_ttmuddi")}</a></li>
<li><a href="zeitreise.html">${t("nav_dogfather_zeitreise")}</a></li>
</ul>
</div>
@@ -415,7 +589,7 @@
</div>
<div class="container footer-bottom">
<span>${t("footer_copyright").replace("{jahr}", year)}</span>
<span><a href="kontakt.html">${t("footer_impressum")}</a></span>
<span><a href="kontakt.html">${t("footer_impressum")}</a> · <a href="agb.html">AGB</a></span>
</div>
</footer>`;
}
@@ -750,6 +924,28 @@
}
alterInhalt.replaceWith(neuerInhalt);
// Seiteneigene <style>-Blöcke im <head> mitnehmen (Nutzer-Feedback
// 03.08.2026: "wenn ich den Abo-Knopf drücke, sieht die Seite zuerst
// kaputt aus, erst nach einem manuellen Neuladen stimmt es"). Ursache:
// viele Seiten (abonnieren.html, supporter.html, rabattcodes.html,
// tt-muddi.html, ...) haben ihr eigenes Feintuning als <style> direkt
// im <head> stehen. Beim nahtlosen Wechsel wurde bisher NUR <main>
// ausgetauscht — der <head> blieb unverändert, das eigene <style> der
// neuen Seite kam nie mit. Ein echter Neuladen (F5) parst das
// Dokument komplett neu und hatte das Problem deshalb nie gezeigt.
// Alle mit main.js/main.css geteilten Styles kommen ausschließlich
// über <link rel="stylesheet">, nie über ein <style> im <head> — jedes
// <style>-Element dort ist also garantiert seitenEIGEN und darf beim
// Wechsel 1:1 ersetzt werden.
document.head.querySelectorAll("style[data-seiteneigen]").forEach((el) => el.remove());
dok.head.querySelectorAll("style").forEach((el) => {
const neu = document.createElement("style");
neu.setAttribute("data-seiteneigen", "");
neu.textContent = el.textContent;
document.head.appendChild(neu);
});
// 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),
@@ -832,10 +1028,18 @@
}
document.addEventListener("DOMContentLoaded", () => {
// Das <style>, das die ERSTE Seite selbst mitbringt (roh aus dem HTML
// geparst, noch ohne unsere Markierung), muss dieselbe Markierung wie
// die später per SPA-Wechsel nachgeladenen bekommen — sonst würde
// seiteLaden() es nie wieder entfernen können und es bliebe für immer
// im <head> hängen, sobald man einmal weiterklickt (siehe Kommentar
// dort für den vollen Zusammenhang).
document.head.querySelectorAll("style:not([data-seiteneigen])").forEach((el) => el.setAttribute("data-seiteneigen", ""));
renderHeader();
renderFooter();
renderFog();
renderMusicWidget();
renderVorschauSchalter();
musikKnopfFarbenAnpassen();
nahtloseNavigationAktivieren();
applyTranslations(); // seiteneigene data-i18n-Elemente (z.B. Startseite) übersetzen
+63
View File
@@ -0,0 +1,63 @@
/* =====================================================================
supporter.js — gemeinsame Helfer für abonnieren.html + supporter.html
(Dogfather Supporter-Abo). Eigenes, von main.js/forms.js
komplett getrenntes Token-System (localStorage-Key "supporterToken"),
siehe cloudflare-worker/src/lib/supporter-auth.js.
===================================================================== */
(function () {
const API_BASE = "https://dogfather-universe-postfach.dogfather1608.workers.dev";
function getToken() {
return localStorage.getItem("supporterToken") || "";
}
function setToken(token) {
localStorage.setItem("supporterToken", token);
}
function clearToken() {
localStorage.removeItem("supporterToken");
localStorage.removeItem("supporterSubStatus");
localStorage.removeItem("supporterDisplayName");
}
/* Wird vom Nav-Abo-Button in main.js gelesen (renderAboButton), damit die
Beschriftung/das Ziel sofort beim nächsten Seitenwechsel stimmt, ohne
dass main.js selbst einen API-Aufruf machen muss. */
function cacheSubStatus(status) {
if (status) localStorage.setItem("supporterSubStatus", status);
else localStorage.removeItem("supporterSubStatus");
}
/* Name der eingeloggten Person (aus /supporter/me → profile.displayName) —
damit der Nav-Knopf bei aktivem Abo statt des generischen "Supporter-
Bereich" gleich den Benutzernamen zeigen kann (Nutzer-Feedback
03.08.2026). Wird von abonnieren.html/supporter.html nach jedem
erfolgreichen /supporter/me-Aufruf gesetzt. */
function cacheDisplayName(name) {
if (name) localStorage.setItem("supporterDisplayName", name);
else localStorage.removeItem("supporterDisplayName");
}
async function apiFetch(path, body, authed) {
const headers = { "Content-Type": "application/json" };
if (authed) headers.Authorization = `Bearer ${getToken()}`;
let res;
try {
res = await fetch(`${API_BASE}${path}`, { method: "POST", headers, body: JSON.stringify(body || {}) });
} catch {
throw new Error("Verbindung zum Server fehlgeschlagen. Bitte prüfe deine Internetverbindung.");
}
let data = null;
try {
data = await res.json();
} catch {
/* leere Antwort ist ok, z.B. bei manchen Fehlern */
}
if (!res.ok || !data || data.ok === false) {
const err = new Error((data && data.error) || `Anfrage fehlgeschlagen (${res.status}).`);
err.code = data && data.code;
err.status = res.status;
throw err;
}
return data;
}
window.DogiSupporter = { API_BASE, getToken, setToken, clearToken, cacheSubStatus, cacheDisplayName, apiFetch };
})();