Rechtsseiten crawlbar: /datenschutz /agb /impressum als eigenständige HTML-Seiten (einzige Quelle, indexierbar) statt 302→Hash; SPA-Module holen Inhalt per fetch+inject (kein Text-Duplikat); Kontaktformular in geteilte contact-form.js; Sitemap+SW ergänzt, v1278

This commit is contained in:
rene 2026-06-09 18:21:49 +02:00
parent 43b6292d08
commit 40d117874b
13 changed files with 1047 additions and 782 deletions

View file

@ -670,6 +670,9 @@ async def sitemap():
("https://banyaro.app/help", "monthly", "0.7"),
("https://banyaro.app/knigge", "monthly", "0.7"),
("https://banyaro.app/partner", "monthly", "0.6"),
("https://banyaro.app/datenschutz", "yearly", "0.3"),
("https://banyaro.app/agb", "yearly", "0.3"),
("https://banyaro.app/impressum", "yearly", "0.3"),
]
try:
@ -2685,15 +2688,17 @@ async def wurfboerse_page():
# Rechtsseiten: Pfad-URLs (SEO-Footer, App-Store-Metadaten, E-Mails) auf die
# SPA-Hash-Routen umleiten — die Inhalte leben als SPA-Seiten (#agb, …).
# Rechtsseiten als eigenständige, crawlbare HTML-Seiten ausliefern (einzige Inhaltsquelle).
# Die SPA-Module (#agb, #datenschutz, #impressum) holen denselben Inhalt per fetch und
# injizieren ihn — so bleibt die In-App-Ansicht erhalten, ohne Text-Duplikat.
# Muss VOR dem SPA-Fallback registriert sein.
@app.get("/agb")
@app.get("/datenschutz")
@app.get("/impressum")
async def legal_page_redirect(request: _Request):
from fastapi.responses import RedirectResponse
async def legal_page(request: _Request):
page = request.url.path.strip("/")
return RedirectResponse(f"/#{page}", status_code=302)
return FileResponse(f"{STATIC_DIR}/{page}.html",
headers={"Cache-Control": "max-age=3600"})
# SPA Fallback — ALLE nicht-API-Routen gehen zur index.html

264
backend/static/agb.html Normal file
View file

@ -0,0 +1,264 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AGB — Ban Yaro</title>
<meta name="description" content="Allgemeine Geschäftsbedingungen von Ban Yaro — Leistungen, Preise, Laufzeit, Kündigung und Widerruf.">
<link rel="canonical" href="https://banyaro.app/agb">
<meta name="robots" content="index, follow">
<link rel="icon" href="/icons/favicon.ico">
<link rel="stylesheet" href="/css/design-system.css">
<link rel="stylesheet" href="/css/layout.css">
<link rel="stylesheet" href="/css/components.css">
<link rel="stylesheet" href="/css/utilities.css">
<style>
body{background:var(--c-bg);color:var(--c-text);font-family:var(--font-sans,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif);margin:0;}
.legal-bar{max-width:640px;margin:0 auto;padding:var(--space-4) var(--space-4) 0;}
.legal-bar a{color:var(--c-primary);text-decoration:none;font-size:var(--text-sm);font-weight:600;}
.legal-foot{max-width:640px;margin:var(--space-4) auto 0;padding:var(--space-4);border-top:1px solid var(--c-border);text-align:center;font-size:var(--text-sm);color:var(--c-text-muted);}
.legal-foot a{color:var(--c-primary);text-decoration:none;margin:0 var(--space-2);}
</style>
</head>
<body>
<nav class="legal-bar"><a href="/">← Ban Yaro</a></nav>
<main id="legal-content">
<div style="max-width:640px;margin:0 auto;padding:var(--space-6) var(--space-4)">
<h1 style="font-size:var(--text-2xl);font-weight:var(--weight-bold);
color:var(--c-text);margin:0 0 var(--space-2)">Allgemeine Geschäftsbedingungen</h1>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-bottom:var(--space-6)">Gültig ab Mai 2026</p>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-primary);margin:0 0 var(--space-2)">1. Geltungsbereich</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Diese AGB gelten für die Nutzung der Plattform <strong>Ban Yaro</strong>
(<a href="https://banyaro.app" style="color:var(--c-primary)">banyaro.app</a>), betrieben von:<br><br>
René Degelmann<br>
Ringstr. 26, 85560 Ebersberg<br>
E-Mail: <a href="mailto:hallo@banyaro.app" style="color:var(--c-primary)">hallo@banyaro.app</a>
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Sie gelten ausschließlich für kostenpflichtige Abonnements. Die kostenlose Nutzung
der App setzt lediglich die Registrierung voraus.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-primary);margin:0 0 var(--space-2)">2. Mindestalter</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Die Nutzung von Ban Yaro, insbesondere die Registrierung und der Abschluss eines
Abonnements, ist nur Personen ab 18 Jahren gestattet. Mit Abschluss des Vertrags
bestätigt der Nutzer, volljährig zu sein.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-primary);margin:0 0 var(--space-2)">3. Leistungen</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">Ban Yaro bietet folgende kostenpflichtige Abonnements an:</p>
<ul style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:var(--space-2) 0 0;padding-left:var(--space-5)">
<li>
<strong>Ban Yaro Pro — 29 EUR/Jahr:</strong> Erweiterte App-Funktionen für mehrere
Hunde, KI-Features, zusätzliche Karten-Layer, Chat und Playdate-Funktion sowie
alle weiteren Pro-Funktionen laut aktuellem Funktionsumfang.
</li>
<li>
<strong>Ban Yaro Züchter — 49 EUR/Jahr:</strong> Alle Pro-Funktionen plus
Zuchtkartei, Stammbaum, Wurfverwaltung und Züchterprofil.
</li>
</ul>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Die native iOS-App <strong>„Ban Yaro Go"</strong> ist kostenlos und dient als
Begleit-App für unterwegs. Kostenpflichtige Abonnements werden
<strong>ausschließlich über banyaro.app</strong> abgeschlossen und per Überweisung
bezahlt — <strong>nicht</strong> über einen App-Store-Kauf (kein In-App-Kauf).
Pro- und Züchter-Funktionen werden mit deinem banyaro-Konto freigeschaltet und
stehen damit auch in der iOS-App zur Verfügung.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Änderungen am Funktionsumfang werden vorab per E-Mail angekündigt. Wesentliche
Leistungsminderungen berechtigen zur außerordentlichen Kündigung.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-primary);margin:0 0 var(--space-2)">4. Nutzungsregeln / Community</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">Die Nutzung der Plattform-Features (Forum, Chat, Fotos, Kommentare) unterliegt folgenden Regeln:</p>
<ul style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:var(--space-2) 0 0;padding-left:var(--space-5)">
<li>Keine rechtswidrigen, beleidigenden, diskriminierenden oder irreführenden Inhalte</li>
<li>Kein Spam, keine Werbung ohne Genehmigung, keine Fake-Accounts</li>
<li>Respektvoller Umgang mit anderen Nutzern</li>
<li>Keine Verletzung von Urheberrechten Dritter bei hochgeladenen Inhalten</li>
</ul>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Bei Verstoß sind wir berechtigt, Inhalte zu entfernen und Accounts zu sperren oder
zu kündigen. Rechtswidrige Inhalte werden unverzüglich entfernt und ggf. Behörden
gemeldet. Meldungen können an
<a href="mailto:hallo@banyaro.app" style="color:var(--c-primary)">hallo@banyaro.app</a>
gerichtet werden.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-primary);margin:0 0 var(--space-2)">5. Nutzerinhalte und Lizenzen</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Durch das Hochladen von Inhalten (Fotos, Texte, Beiträge) räumt der Nutzer Ban Yaro
eine nicht-exklusive, kostenlose, weltweite Lizenz ein, diese Inhalte im Rahmen der
Plattform zu speichern, anzuzeigen und technisch zu verarbeiten. Diese Lizenz erlischt
mit Löschung des Inhalts oder Löschung des Accounts. Urheberrechte und sonstige
Rechte der Nutzer an ihren Inhalten bleiben unberührt.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-primary);margin:0 0 var(--space-2)">6. Preise und Zahlung</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Der Jahresbeitrag ist bei Vertragsschluss für die gesamte Laufzeit im Voraus fällig.
Die Zahlung erfolgt per Überweisung — IBAN und Verwendungszweck stehen auf der
Rechnung, die per E-Mail zugestellt wird. Der Betrag ist innerhalb von
<strong>14 Tagen</strong> nach Rechnungsstellung zu überweisen.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Bei Zahlungsverzug erhalten Sie zunächst eine Zahlungserinnerung. Bleibt der Betrag
danach weiterhin ausstehend, behalten wir uns die fristlose Kündigung des Vertrags
gemäß § 314 BGB vor.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-primary);margin:0 0 var(--space-2)">7. Vertragslaufzeit und Kündigung</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Die Erstlaufzeit beträgt <strong>12 Monate</strong> ab dem Tag der Freischaltung.
Nach Ablauf verlängert sich der Vertrag auf unbestimmte Zeit — kündbar jederzeit
mit einer Frist von <strong>einem Monat zum Monatsende</strong> (§ 309 Nr. 9 BGB).
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Die Kündigung ist jederzeit in den App-Einstellungen unter
<strong>Einstellungen → Abonnement → Kündigen</strong> möglich (§ 312k BGB).
Eine Kündigungsbestätigung wird per E-Mail zugesandt.
Der Zugang bleibt bis zum Ende der bereits bezahlten Laufzeit vollständig aktiv.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-primary);margin:0 0 var(--space-2)">8. Kein Erstattungsanspruch</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Bei vorzeitiger Kündigung durch den Nutzer erfolgt keine anteilige Rückerstattung
des Jahresbeitrags. Der Zugang bleibt bis zum Ende der Laufzeit vollständig nutzbar —
du verlierst also nichts, was du bereits bezahlt hast.
Gesetzliche Ansprüche bei vertragswidrigen Leistungen bleiben unberührt.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-primary);margin:0 0 var(--space-2)">9. Widerrufsrecht</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Da die Nutzung unmittelbar nach Freischaltung beginnt und du beim Kauf ausdrücklich
zustimmst, dass die Vertragserfüllung vor Ablauf der Widerrufsfrist beginnt, erlischt
dein 14-tägiges Widerrufsrecht mit Beginn der Nutzung (§ 356 Abs. 4 BGB). Dir ist
bekannt, dass du durch diese Zustimmung dein Widerrufsrecht verlierst. Die Zustimmung
wird beim Kauf aktiv protokolliert.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-primary);margin:0 0 var(--space-2)">10. Fristlose Kündigung durch den Anbieter</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Wir sind berechtigt, den Vertrag aus wichtigem Grund fristlos zu kündigen
(§ 314 BGB). Ein wichtiger Grund liegt insbesondere vor, wenn nach einer
Zahlungserinnerung der offene Betrag weiterhin nicht beglichen wird.
In diesem Fall endet der Zugang mit Wirkung der Kündigung.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-primary);margin:0 0 var(--space-2)">11. KI-Funktionen / Haftung für KI-Inhalte</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
KI-generierte Inhalte (Trainer-Empfehlungen, Gesundheitshinweise, Züchter-Analysen)
können fehlerhaft oder unvollständig sein. Sie dienen ausschließlich der allgemeinen
Information und ersetzen keine tierärztliche, veterinärmedizinische oder fachliche
Beratung. Ban Yaro haftet nicht für Schäden, die aus der Nutzung KI-generierter
Inhalte entstehen.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-primary);margin:0 0 var(--space-2)">12. Verfügbarkeit</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Wir streben eine hohe Verfügbarkeit von Ban Yaro an und arbeiten kontinuierlich
daran, die App stabil zu halten. Eine Garantie für ununterbrochene Verfügbarkeit
können wir jedoch nicht übernehmen. Geplante Wartungsarbeiten werden nach
Möglichkeit vorab in der App angekündigt.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-primary);margin:0 0 var(--space-2)">13. Änderungen dieser AGB</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Änderungen der AGB werden per <strong>E-Mail und in der App</strong> angekündigt —
mindestens 4 Wochen vor Inkrafttreten. Widersprichst du den Änderungen nicht
innerhalb dieser Frist, gelten sie als angenommen. Dein Widerspruchsrecht und
das Recht zur außerordentlichen Kündigung bleiben unberührt.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-primary);margin:0 0 var(--space-2)">14. Anwendbares Recht</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Es gilt ausschließlich <strong>deutsches Recht</strong>. Als Verbraucher hast du
deinen allgemeinen Gerichtsstand. Die EU-Plattform zur Online-Streitbeilegung
(ec.europa.eu/consumers/odr) wurde eingestellt. Wir nehmen nicht an alternativen
Streitbeilegungsverfahren teil (§ 36 VSBG).
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-primary);margin:0 0 var(--space-2)">15. Kontakt</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
René Degelmann<br>
Ringstr. 26, 85560 Ebersberg<br>
E-Mail: <a href="mailto:hallo@banyaro.app" style="color:var(--c-primary)">hallo@banyaro.app</a>
</p>
</section>
<p style="font-size:var(--text-xs);color:var(--c-text-muted);margin:0">
Stand: Juni 2026 · Version 3
</p>
</div>
</main>
<footer class="legal-foot">
<a href="/datenschutz">Datenschutz</a> · <a href="/agb">AGB</a> · <a href="/impressum">Impressum</a>
</footer>
</body>
</html>

View file

@ -0,0 +1,507 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Datenschutzerklärung — Ban Yaro</title>
<meta name="description" content="Datenschutzerklärung von Ban Yaro — welche Daten wir verarbeiten, deine Rechte nach DSGVO, Hosting in Deutschland.">
<link rel="canonical" href="https://banyaro.app/datenschutz">
<meta name="robots" content="index, follow">
<link rel="icon" href="/icons/favicon.ico">
<link rel="stylesheet" href="/css/design-system.css">
<link rel="stylesheet" href="/css/layout.css">
<link rel="stylesheet" href="/css/components.css">
<link rel="stylesheet" href="/css/utilities.css">
<style>
body{background:var(--c-bg);color:var(--c-text);font-family:var(--font-sans,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif);margin:0;}
.legal-bar{max-width:640px;margin:0 auto;padding:var(--space-4) var(--space-4) 0;}
.legal-bar a{color:var(--c-primary);text-decoration:none;font-size:var(--text-sm);font-weight:600;}
.legal-foot{max-width:640px;margin:var(--space-4) auto 0;padding:var(--space-4);border-top:1px solid var(--c-border);text-align:center;font-size:var(--text-sm);color:var(--c-text-muted);}
.legal-foot a{color:var(--c-primary);text-decoration:none;margin:0 var(--space-2);}
</style>
</head>
<body>
<nav class="legal-bar"><a href="/">← Ban Yaro</a></nav>
<main id="legal-content">
<div style="max-width:640px;margin:0 auto;padding:var(--space-6) var(--space-4)">
<h1 style="font-size:var(--text-2xl);font-weight:var(--weight-bold);
color:var(--c-text);margin:0 0 var(--space-6)">Datenschutzerklärung</h1>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Verantwortlicher</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
René Degelmann, Ringstr. 26, 85560 Ebersberg<br>
E-Mail: <a href="mailto:hallo@banyaro.app" style="color:var(--c-primary)">hallo@banyaro.app</a>
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Hosting &amp; Infrastruktur</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Die App wird auf einem eigenen Server (Synology DiskStation) in Deutschland betrieben.
Alle Daten werden ausschließlich auf diesem Server gespeichert und nicht an externe
Hoster übermittelt.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Für den E-Mail-Versand (Kontobestätigung, Benachrichtigungen, Rechnungen) nutzen wir
<strong>Brevo</strong> (Sendinblue SAS, 55 rue d'Amsterdam, 75008 Paris, Frankreich).
Brevo ist nach EU-Standardvertragsklauseln zertifiziert. Dabei werden E-Mail-Adresse
und Name übermittelt. Datenschutzinformationen:
<a href="https://www.brevo.com/de/legal/privacypolicy/" target="_blank" rel="noopener"
style="color:var(--c-primary)">brevo.com/de/legal/privacypolicy/</a>.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Für anonymisierte Nutzungsstatistiken betreiben wir <strong>Umami Analytics</strong>
auf unserem eigenen Server. Es werden keine personenbezogenen Daten oder IP-Adressen
gespeichert. Kein Tracking über Sitzungen hinweg.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Deine Daten gehören dir</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Ban Yaro ist eine private Community-App. Dein <strong>Tagebuch</strong>, deine
<strong>persönlichen Notizen</strong>, <strong>Gesundheitsdaten</strong> deines Hundes,
<strong>eigene Routen</strong> und dein <strong>Nutzerprofil</strong> sind
ausschließlich für dich sichtbar — sie werden weder an andere Nutzer noch an Dritte
weitergegeben. Öffentlich sichtbar sind nur Inhalte, die du bewusst veröffentlichst
(z. B. Forenbeiträge, Giftköder-Meldungen, öffentliche Gassi-Treffen).
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Welche Daten wir verarbeiten</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">Bei der Registrierung und Nutzung von Ban Yaro werden folgende Daten verarbeitet:</p>
<ul style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:var(--space-2) 0 0;padding-left:var(--space-5)">
<li><strong>Accountdaten:</strong> Benutzername, E-Mail-Adresse, Passphrase (verschlüsselt gespeichert)</li>
<li><strong>Hundeprofil:</strong> Name, Rasse, Alter, Foto (freiwillig)</li>
<li><strong>Gesundheitsdaten deines Hundes:</strong> Gewicht, Impfungen, Tierarztbesuche, Medikamente (freiwillig, nur für dich sichtbar)</li>
<li><strong>Tagebuch &amp; Notizen:</strong> Texte, Fotos, Stimmungseinträge (privat, nur für dich)</li>
<li><strong>Standortdaten:</strong> Nur nach expliziter Browser-Freigabe — für Karte, Gassi-Treffen,
Giftköder-Meldungen, Nearby-Alerts und Routenaufzeichnung. Standortdaten werden nicht dauerhaft
gespeichert, außer du speicherst selbst eine Route oder Meldung.</li>
<li><strong>Routendaten:</strong> Aufgezeichnete Routen (GPS-Wegpunkte) werden nur gespeichert,
wenn du sie explizit speicherst; sie sind standardmäßig privat.</li>
<li><strong>Fotos &amp; EXIF-Daten:</strong> Beim Hochladen von Bildern können GPS-Koordinaten
in den EXIF-Metadaten enthalten sein. Diese werden serverseitig ausgelesen, um Fotos auf der
Karte zu verorten — sofern vorhanden. Die Rohdaten werden nicht separat gespeichert.</li>
<li><strong>Inhalte:</strong> Forenbeiträge, Chatnachrichten, öffentliche Gassi-Treffen</li>
<li><strong>Technische Daten:</strong> IP-Adresse (für Sicherheit und Rate-Limiting, max. 30 Tage),
Browser-Typ</li>
</ul>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Rechtsgrundlage</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Die Verarbeitung erfolgt auf Basis von Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung)
für alle zur Bereitstellung des Dienstes notwendigen Daten, sowie Art. 6 Abs. 1 lit. a
DSGVO (Einwilligung) für optionale Funktionen wie Standortfreigabe und
Push-Benachrichtigungen. Einwilligungen können jederzeit mit Wirkung für die Zukunft
widerrufen werden (Art. 7 Abs. 3 DSGVO) — einfach die entsprechende Funktion in den
Einstellungen deaktivieren oder die Browser-Freigabe entziehen.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Impressum und rechtliche Grundlage nach § 5 DDG (Digitale-Dienste-Gesetz).
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Datenweitergabe</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Deine Daten werden nicht an Dritte verkauft oder zu Werbezwecken weitergegeben.
Öffentliche Inhalte (Forum, Wiki, Giftköder-Karte) sind für alle Nutzer sichtbar.
Profile sind standardmäßig nur für registrierte Nutzer sichtbar.
Admins und Moderatoren können gemeldete Inhalte zur Qualitätssicherung einsehen
(Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO — berechtigtes Interesse an
Plattformsicherheit).
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Direktnachrichten</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Nachrichten zwischen Nutzern (z. B. zwischen Hundesitter und Hundeeigentümer oder
zwischen Interessenten und Züchtern) werden auf unserem Server gespeichert, bis du
das Gespräch oder deinen Account löschst. Admins können gemeldete Nachrichten zur
Missbrauchsprüfung einsehen (Art. 6 Abs. 1 lit. f DSGVO — berechtigtes Interesse
an Plattformsicherheit). Nachrichten werden nicht an Dritte weitergegeben.
Du kannst Gespräche jederzeit selbst löschen.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Moderation &amp; Community</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Zur Sicherstellung der Plattformqualität und Einhaltung unserer Nutzungsregeln können
Moderatoren und automatische Systeme Inhalte prüfen. Rechtsgrundlage ist
Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an sicherer Plattform).
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">KI-Funktionen</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Ban Yaro bietet KI-gestützte Funktionen (Trainingsempfehlungen, Terminvorschläge,
Rassen-Informationen). Diese laufen primär auf einer <strong>lokalen KI auf unserem
eigenen Server in Deutschland</strong> — deine Anfragen verlassen dabei nicht unsere
Infrastruktur.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Als Ausweichlösung bei Nichtverfügbarkeit des lokalen Modells wird
<strong>Claude Sonnet 4.6</strong> von Anthropic, PBC (San Francisco, USA) genutzt.
In diesem Fall wird der Inhalt deiner Anfrage übermittelt. Bei Gesundheits- und
Ernährungsberichten kann dies Hundedaten (Name, Rasse, Gewicht, Impfhistorie,
Medikamente, Allergien) als Teil des Anfragetextes umfassen. Die Übermittlung
in die USA erfolgt auf Basis der EU-Standardvertragsklauseln (Art. 46 Abs. 2 lit. c DSGVO).
Datenschutzerklärung von Anthropic:
<a href="https://www.anthropic.com/privacy" target="_blank" rel="noopener"
style="color:var(--c-primary)">anthropic.com/privacy</a>.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Die <strong>Rassenerkennung per Foto</strong> sendet das hochgeladene Bild direkt an
Claude von Anthropic (USA) zur Analyse — es gibt hierfür keinen lokalen Fallback.
Das Foto wird nicht dauerhaft bei Anthropic gespeichert. Rechtsgrundlage: Einwilligung
gem. Art. 6 Abs. 1 lit. a DSGVO durch aktive Nutzung der Funktion.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Der <strong>KI-Trainer</strong> analysiert deinen bisherigen Trainingsfortschritt
(Übungshistorie, Erfolgsquoten, Streaks) und gibt personalisierte Empfehlungen.
Diese Analyse läuft auf unserem lokalen Server in Deutschland — deine Trainingsdaten
verlassen dabei nicht unsere Infrastruktur. Es findet kein Training oder Fine-Tuning
von KI-Modellen auf Basis deiner Nutzerdaten statt.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
KI-Empfehlungen sind Vorschläge und ersetzen keine tierärztliche Beratung.
Eine automatisierte Entscheidungsfindung mit rechtlicher Wirkung (Art. 22 DSGVO)
findet nicht statt.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
KI-Antworten können fehlerhaft oder unvollständig sein und dienen ausschließlich
allgemeinen Informationszwecken. Sie ersetzen keine tierärztliche oder fachliche
Beratung. Trotz EU-Standardvertragsklauseln besteht bei US-Anbietern ein Restrisiko,
dass US-Behörden auf übermittelte Daten zugreifen könnten.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Wetterdaten & Kartendienste</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Die Wetter-Funktion übermittelt auf Wunsch deine GPS-Koordinaten serverseitig an
<strong>Open-Meteo</strong> (Österreich, DSGVO-konform) für die Wettervorhersage.
Für das <strong>Regenradar</strong> nutzen wir primär die offenen Radardaten des
<strong>Deutschen Wetterdienstes (DWD)</strong>. Diese werden serverseitig von unserem
Server in Deutschland abgerufen und als Kartenkacheln bereitgestellt — dein Gerät
kontaktiert den DWD dabei nicht direkt. Steht das DWD-Radar nicht zur Verfügung,
werden ersatzweise Radarkacheln von <strong>RainViewer</strong> (USA) geladen; dabei
wird dein Browser direkt kontaktiert. Für weitere Wetter-Kartenlayer (z. B. Temperatur)
können Kacheln von <strong>OpenWeatherMap</strong> (OpenWeather Ltd., UK/USA) direkt im
Browser geladen werden. In allen Fällen werden keine Account-Daten übermittelt.
Rechtsgrundlage: Einwilligung gem. Art. 6 Abs. 1 lit. a DSGVO.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Für die automatische Ortsnamens-Ermittlung (z. B. im Wetter-Detail) werden deine
GPS-Koordinaten serverseitig an <strong>Nominatim</strong> der OpenStreetMap Foundation
(UK) übermittelt. Es werden ausschließlich Koordinaten weitergegeben — keine
personenbezogenen Daten.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Datenschutzerklärung Open-Meteo:
<a href="https://open-meteo.com/en/terms" target="_blank" rel="noopener"
style="color:var(--c-primary)">open-meteo.com/en/terms</a> ·
OpenWeatherMap:
<a href="https://openweathermap.org/privacy-policy" target="_blank" rel="noopener"
style="color:var(--c-primary)">openweathermap.org/privacy-policy</a> ·
OpenStreetMap/Nominatim:
<a href="https://osmfoundation.org/wiki/Privacy_Policy" target="_blank" rel="noopener"
style="color:var(--c-primary)">osmfoundation.org</a> ·
DWD:
<a href="https://www.dwd.de/DE/service/datenschutz/datenschutz_node.html" target="_blank" rel="noopener"
style="color:var(--c-primary)">dwd.de</a> ·
RainViewer:
<a href="https://www.rainviewer.com/privacy.html" target="_blank" rel="noopener"
style="color:var(--c-primary)">rainviewer.com</a>
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Kartenmaterial &amp; Offline-Karten</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Die Basiskarte besteht aus Vektordaten von <strong>OpenStreetMap</strong>, die wir auf
unserem eigenen Server in Deutschland aufbereiten und ausliefern (Vektor-Tiles im
PMTiles-Format). Für die Basiskarte werden daher <strong>keine externen
Kartenanbieter</strong> kontaktiert — die Kartenkacheln kommen von unserem Server.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Optional kannst du Kartenausschnitte für die <strong>Offline-Nutzung</strong>
herunterladen. Diese werden ausschließlich <strong>lokal auf deinem Gerät</strong>
gespeichert und nicht an Dritte übermittelt.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Routenvorschläge (OpenRouteService)</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Die Funktion <strong>„Routenvorschläge"</strong> berechnet auf Wunsch einen Rundweg
ausgehend von deinem aktuellen Standort. Dazu werden deine GPS-Koordinaten einmalig
an den Dienst <strong>OpenRouteService</strong> übermittelt, der von
<strong>HeiGIT</strong> am Karlsruher Institut für Technologie (KIT), Deutschland,
betrieben wird. Es werden ausschließlich die Koordinaten übertragen —
keine Account- oder Profildaten. OpenRouteService speichert keine
personenbezogenen Daten dauerhaft.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Die Funktion wird nur aktiv, wenn du deinen Standort im Browser freigibst und
bewusst einen Routenvorschlag anforderst (Einwilligung gem. Art. 6 Abs. 1 lit. a DSGVO).
Der Tagesvorschlag auf der Startseite wird nur berechnet, wenn du eingeloggt bist und
Standortzugriff erteilt hast — das Ergebnis wird lokal zwischengespeichert und
maximal einmal täglich neu abgerufen.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Datenschutzerklärung von OpenRouteService:
<a href="https://openrouteservice.org/privacy-policy/" target="_blank" rel="noopener"
style="color:var(--c-primary)">openrouteservice.org/privacy-policy</a>
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Ban Yaro Go — native iOS-App</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
<strong>Ban Yaro Go</strong> ist die optionale native iOS-Begleit-App zu banyaro.app.
Sie nutzt dasselbe banyaro-Konto und denselben Server in Deutschland — es gelten
daher zusätzlich zu den oben beschriebenen Verarbeitungen folgende iOS-spezifische
Punkte:
</p>
<ul style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:var(--space-2) 0 0;padding-left:var(--space-5)">
<li><strong>Hintergrund-Standort:</strong> Nur während einer von dir aktiv gestarteten
Gassi-Aufzeichnung erfasst die App deine GPS-Position auch bei gesperrtem Display, um
den Track fortzuführen. Außerhalb einer aktiven Aufzeichnung wird im Hintergrund kein
Standort erfasst. Der Track wird lokal auf dem Gerät gesichert und nur dann in dein
Konto übertragen, wenn du die Tour speicherst.</li>
<li><strong>Apple WeatherKit:</strong> Die Wetterfunktion der App bezieht Vorhersagedaten
über Apple WeatherKit (Apple Inc., USA). Dazu werden Standortkoordinaten an Apple
übermittelt — keine Account-Daten.</li>
<li><strong>Apple Health (HealthKit):</strong> Nur auf deinen ausdrücklichen Wunsch
schreibt die App abgeschlossene Touren als „Walking"-Workout inkl. Route in Apple
Health. Es werden <strong>keine</strong> Gesundheitsdaten aus Apple Health gelesen.
Diese Daten verbleiben auf deinem Gerät bzw. in deiner iCloud.</li>
<li><strong>Apple Maps:</strong> Zur Navigation (z. B. zu Gassi-Treffen) kann auf deinen
Wunsch Apple Maps geöffnet werden.</li>
<li><strong>GPX-Import:</strong> Aus anderen Apps geteilte GPX-Dateien werden lokal auf
dem Gerät verarbeitet; eine Übertragung erfolgt nur, wenn du die Tour speicherst.</li>
<li><strong>Push (APNs):</strong> Benachrichtigungen werden wie im Abschnitt
„Push-Benachrichtigungen" beschrieben über den Apple Push Notification Service zugestellt.</li>
</ul>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Rechtsgrundlage ist jeweils deine Einwilligung (Art. 6 Abs. 1 lit. a DSGVO) bzw. die
Vertragserfüllung (Art. 6 Abs. 1 lit. b DSGVO). Apple-Datenschutz:
<a href="https://www.apple.com/legal/privacy/de-ww/" target="_blank" rel="noopener"
style="color:var(--c-primary)">apple.com/legal/privacy</a>.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Technische Speicherung</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Ban Yaro verwendet technisch notwendige Speichermechanismen für den Betrieb der App:
Session-Tokens und Authentifizierungsdaten werden im Local Storage des Browsers
gespeichert. Ein Service Worker speichert App-Inhalte lokal für die Offline-Nutzung
(Cache). Push-Benachrichtigungs-Token werden für die Zustellung von Hinweisen benötigt.
Diese Speicherung ist für die Kernfunktion der App erforderlich; eine Einwilligung ist
nach § 25 Abs. 2 TTDSG nicht erforderlich. Es werden keine Tracking-Cookies eingesetzt.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Push-Benachrichtigungen</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Wenn du Push-Benachrichtigungen aktivierst, wird ein Abonnement-Token an den
Push-Dienst deines Browsers übermittelt: bei Android/Chrome an
<strong>Firebase Cloud Messaging</strong> (Google LLC, USA), bei iOS/Safari an
<strong>Apple Push Notification Service</strong> (Apple Inc., USA). Diese Dienste
erhalten lediglich den Token und die Benachrichtigung selbst — keine weiteren
Nutzerdaten. Die Übermittlung erfolgt auf Basis deiner Einwilligung
(Art. 6 Abs. 1 lit. a DSGVO), die du jederzeit in den Geräteeinstellungen widerrufen kannst.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Kalender-Abo (Webcal)</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Das Kalender-Abo nutzt einen persönlichen Token-Link. Wenn deine Kalender-App
diesen Link regelmäßig abruft, wird dabei deine IP-Adresse an unseren Server
übermittelt. Es werden keine weiteren Daten an Dritte weitergegeben.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Einladungslinks (Referral)</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Wenn du Freunde über deinen persönlichen Einladungslink einlädst, wird erfasst,
wie viele Personen sich darüber registriert haben — ohne personenbezogene Daten
der eingeladenen Personen zu speichern. Dir wird lediglich die Anzahl angezeigt.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Nutzungsanalyse (Umami)</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Wir verwenden Umami, ein datenschutzfreundliches Analysetool, das ausschließlich auf
unserem eigenen Server betrieben wird. Es werden keine Cookies gesetzt, keine
personenbezogenen Daten erhoben und keine Daten an Dritte weitergegeben.
Erfasst werden lediglich anonyme Seitenaufrufe zur Verbesserung der App
(Art. 6 Abs. 1 lit. f DSGVO — berechtigtes Interesse).
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Deine Rechte (DSGVO)</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Du hast das Recht auf <strong>Auskunft</strong> (Art. 15), <strong>Berichtigung</strong>
(Art. 16), <strong>Löschung</strong> (Art. 17), <strong>Einschränkung der Verarbeitung</strong>
(Art. 18) sowie <strong>Datenportabilität</strong> (Art. 20). Erteilte Einwilligungen
kannst du jederzeit mit Wirkung für die Zukunft widerrufen (Art. 7 Abs. 3 DSGVO).
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
<strong>Datenexport (Art. 20 DSGVO):</strong> Du kannst jederzeit unter
Einstellungen → „Meine Daten exportieren" eine vollständige Kopie deiner
gespeicherten Daten als JSON-Datei herunterladen. Der Export enthält Profildaten,
Hundedaten, Tagebuch (inkl. Medien-URLs), Gesundheitseinträge, Trainingsfortschritt,
Ausgaben, Verhaltensprotokoll, Versicherung, Ernährungsprofil und Futter-Reaktionen,
eigene Routen, Forum-Beiträge sowie Gassi-Teilnahmen und Gassi-Fotos.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Das JSON-Format ist maschinenlesbar und kann z. B. mit jedem Texteditor geöffnet
oder in andere Anwendungen importiert werden. Der Export wird direkt im Browser
erzeugt und nicht dauerhaft auf dem Server gespeichert.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Zur Ausübung weiterer Rechte wende dich per E-Mail an
<a href="mailto:hallo@banyaro.app" style="color:var(--c-primary)">hallo@banyaro.app</a>.<br><br>
Du hast außerdem das Recht, bei der zuständigen Datenschutz-Aufsichtsbehörde
Beschwerde einzulegen:<br>
<strong>Bayerisches Landesamt für Datenschutzaufsicht (BayLDA)</strong><br>
Promenade 18, 91522 Ansbach<br>
<a href="mailto:poststelle@lda.bayern.de"
style="color:var(--c-primary)">poststelle@lda.bayern.de</a> ·
<a href="https://www.lda.bayern.de" target="_blank" rel="noopener"
style="color:var(--c-primary)">www.lda.bayern.de</a>
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Zahlungsdaten</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Wenn du ein kostenpflichtiges Abonnement abschließt, verarbeiten wir folgende Daten:
Name, E-Mail-Adresse, Rechnungsadresse und den Zahlungseingang. Rechtsgrundlage ist
Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung). Rechnungsdaten werden gemäß
§ 147 AO <strong>10 Jahre</strong> aufbewahrt. Rechnungen werden per E-Mail mit
TLS-Verschlüsselung zugestellt.
</p>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Deine Zahlungsdaten (IBAN) werden nur für die Zuordnung des Zahlungseingangs intern
verwendet und nicht an Dritte weitergegeben. Die vertraglichen Bedingungen (Laufzeit,
Kündigung, Erstattung) findest du in unseren
<a href="/agb" style="color:var(--c-primary)">AGB</a>.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Speicherdauer</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Server-Logs werden nach 30 Tagen rotiert. IP-Adressen werden ausschließlich
zur Sicherheit und für Rate-Limiting maximal 30 Tage gespeichert.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Account-Löschung</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Wenn du deinen Account löschst, werden deine Daten nach folgendem Schema verarbeitet:
</p>
<ul style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:var(--space-2) 0 0;padding-left:var(--space-5)">
<li><strong>Sofort und unwiderruflich gelöscht:</strong> Account, Hundeprofile, Tagebuch
und Tagebuch-Medien, Gesundheitseinträge, Trainingsfortschritt, Ausgaben,
Verhaltensprotokoll, Versicherung, Ernährungsprofil, Futter-Einträge und -Reaktionen,
Forum-Beiträge, eigene Notizen, Direktnachrichten, Freundschaften,
Push-Benachrichtigungen, Einstellungen und Welten-Konfiguration.</li>
<li><strong>Anonymisiert (Urheber-Bezug auf NULL gesetzt):</strong> Eigene Routen,
Forum-Threads sowie von dir angelegte Wiki-Inhalte bleiben zur Verfügbarkeit für
die Community erhalten, sind aber nicht mehr deinem Account zuordenbar.</li>
<li><strong>10 Jahre aufbewahrt (gesetzliche Pflicht):</strong> Rechnungen und
Rechnungspositionen aus kostenpflichtigen Abonnements gemäß § 147 AO. Diese
enthalten Name, E-Mail-Adresse und Rechnungsadresse zum Zeitpunkt der Rechnung
und können vor Ablauf der Frist nicht gelöscht werden.</li>
</ul>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0;margin-top:var(--space-3)">
Es findet keine anonymisierte Weiterverarbeitung deiner privaten Inhalte
(Tagebuch, Gesundheit, Notizen) zu Trainings- oder Statistikzwecken statt.
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)">Mindestalter</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Die Nutzung von Ban Yaro ist nur Personen ab 18 Jahren gestattet. Durch die
Registrierung bestätigt der Nutzer, das 18. Lebensjahr vollendet zu haben.
</p>
</section>
<p style="font-size:var(--text-xs);color:var(--c-text-muted);margin:0">
Stand: Juni 2026 · Version 4
</p>
</div>
</main>
<footer class="legal-foot">
<a href="/datenschutz">Datenschutz</a> · <a href="/agb">AGB</a> · <a href="/impressum">Impressum</a>
</footer>
</body>
</html>

View file

@ -0,0 +1,142 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Impressum — Ban Yaro</title>
<meta name="description" content="Impressum von Ban Yaro — Anbieterkennzeichnung nach § 5 DDG und Kontakt.">
<link rel="canonical" href="https://banyaro.app/impressum">
<meta name="robots" content="index, follow">
<link rel="icon" href="/icons/favicon.ico">
<link rel="stylesheet" href="/css/design-system.css">
<link rel="stylesheet" href="/css/layout.css">
<link rel="stylesheet" href="/css/components.css">
<link rel="stylesheet" href="/css/utilities.css">
<style>
body{background:var(--c-bg);color:var(--c-text);font-family:var(--font-sans,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif);margin:0;}
.legal-bar{max-width:640px;margin:0 auto;padding:var(--space-4) var(--space-4) 0;}
.legal-bar a{color:var(--c-primary);text-decoration:none;font-size:var(--text-sm);font-weight:600;}
.legal-foot{max-width:640px;margin:var(--space-4) auto 0;padding:var(--space-4);border-top:1px solid var(--c-border);text-align:center;font-size:var(--text-sm);color:var(--c-text-muted);}
.legal-foot a{color:var(--c-primary);text-decoration:none;margin:0 var(--space-2);}
</style>
</head>
<body>
<nav class="legal-bar"><a href="/">← Ban Yaro</a></nav>
<main id="legal-content">
<div style="max-width:640px;margin:0 auto;padding:var(--space-6) var(--space-4)">
<h1 style="font-size:var(--text-2xl);font-weight:var(--weight-bold);
color:var(--c-text);margin:0 0 var(--space-6)">Impressum</h1>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);
color:var(--c-text);margin:0 0 var(--space-2)">Angaben gemäß § 5 DDG</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
René Degelmann<br>
Ringstr. 26<br>
85560 Ebersberg
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);
color:var(--c-text);margin:0 0 var(--space-2)">Kontakt</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0 0 var(--space-4)">
E-Mail: <a href="mailto:hallo@banyaro.app"
class="text-primary">hallo@banyaro.app</a><br>
Oder nutze das Formular — wir antworten in der Regel innerhalb von 24 Stunden.
</p>
<form id="contact-form" class="flex-col-gap-3">
<div class="grid-2">
<div>
<label for="cf-name" style="display:block;font-size:var(--text-xs);font-weight:600;margin-bottom:4px;color:var(--c-text)">Name *</label>
<input id="cf-name" type="text" required maxlength="100"
placeholder="Dein Name"
style="width:100%;padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);
border:1.5px solid var(--c-border);background:var(--c-surface);
color:var(--c-text);font-size:var(--text-sm);box-sizing:border-box">
</div>
<div>
<label for="cf-email" style="display:block;font-size:var(--text-xs);font-weight:600;margin-bottom:4px;color:var(--c-text)">E-Mail *</label>
<input id="cf-email" type="email" required maxlength="200"
placeholder="deine@email.de"
style="width:100%;padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);
border:1.5px solid var(--c-border);background:var(--c-surface);
color:var(--c-text);font-size:var(--text-sm);box-sizing:border-box">
</div>
</div>
<div>
<label for="cf-subject" style="display:block;font-size:var(--text-xs);font-weight:600;margin-bottom:4px;color:var(--c-text)">Betreff *</label>
<input id="cf-subject" type="text" required maxlength="150"
placeholder="Worum geht es?"
style="width:100%;padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);
border:1.5px solid var(--c-border);background:var(--c-surface);
color:var(--c-text);font-size:var(--text-sm);box-sizing:border-box">
</div>
<div>
<label for="cf-message" style="display:block;font-size:var(--text-xs);font-weight:600;margin-bottom:4px;color:var(--c-text)">Nachricht *</label>
<textarea id="cf-message" required maxlength="3000" rows="5"
placeholder="Deine Nachricht…"
style="width:100%;padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);
border:1.5px solid var(--c-border);background:var(--c-surface);
color:var(--c-text);font-size:var(--text-sm);resize:vertical;
font-family:inherit;box-sizing:border-box"></textarea>
</div>
<div id="cf-status" style="display:none;padding:var(--space-2) var(--space-3);
border-radius:var(--radius-md);font-size:var(--text-sm)"></div>
<button id="cf-submit" type="submit"
style="align-self:flex-start;padding:var(--space-2) var(--space-5);
border-radius:var(--radius-full);border:none;cursor:pointer;
background:var(--c-primary);color:#fff;font-size:var(--text-sm);
font-weight:600">
Nachricht senden
</button>
</form>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);
color:var(--c-text);margin:0 0 var(--space-2)">Verantwortlich für den Inhalt
gemäß § 18 Abs. 2 MStV</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
René Degelmann<br>
(Anschrift wie oben)
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);
color:var(--c-text);margin:0 0 var(--space-2)">Streitschlichtung</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Wir sind nicht bereit und nicht verpflichtet, an einem Streitbeilegungsverfahren vor einer
Verbraucherschlichtungsstelle teilzunehmen (§ 36 VSBG).
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);
color:var(--c-text);margin:0 0 var(--space-2)">Haftungshinweis</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Die Inhalte dieser App wurden mit größtmöglicher Sorgfalt erstellt. Für die Richtigkeit,
Vollständigkeit und Aktualität der Inhalte übernehmen wir keine Gewähr. Als
Diensteanbieter sind wir gemäß § 7 Abs. 1 DDG für eigene Inhalte verantwortlich.
Für nutzergenerierte Inhalte (Forenbeiträge, Fotos, Kommentare) sind ausschließlich
die jeweiligen Nutzer verantwortlich. Bei Bekanntwerden rechtswidriger Inhalte werden
diese im Rahmen der gesetzlichen Vorgaben (§§ 7 ff. DDG) geprüft und gegebenenfalls
unverzüglich entfernt.
</p>
</section>
<p style="font-size:var(--text-xs);color:var(--c-text-muted);margin:0">
Stand: Mai 2026
</p>
</div>
</main>
<footer class="legal-foot">
<a href="/datenschutz">Datenschutz</a> · <a href="/agb">AGB</a> · <a href="/impressum">Impressum</a>
</footer>
<script src="/js/contact-form.js"></script>
</body>
</html>

View file

@ -86,14 +86,14 @@
<title>Ban Yaro</title>
<!-- Theme + theme-color Statusleiste vor CSS setzen -->
<script src="/js/boot-early.js?v=1277"></script>
<script src="/js/boot-early.js?v=1278"></script>
<!-- CSS: Reihenfolge ist wichtig — ?v= zwingt Browser zur Neuladung -->
<link rel="stylesheet" href="/css/design-system.css?v=1277">
<link rel="stylesheet" href="/css/layout.css?v=1277">
<link rel="stylesheet" href="/css/components.css?v=1277">
<link rel="stylesheet" href="/css/utilities.css?v=1277">
<link rel="stylesheet" href="/css/lists.css?v=1277">
<link rel="stylesheet" href="/css/design-system.css?v=1278">
<link rel="stylesheet" href="/css/layout.css?v=1278">
<link rel="stylesheet" href="/css/components.css?v=1278">
<link rel="stylesheet" href="/css/utilities.css?v=1278">
<link rel="stylesheet" href="/css/lists.css?v=1278">
</head>
<body>
@ -620,11 +620,12 @@
<div id="modal-container"></div>
<!-- JS: Reihenfolge ist wichtig — erst Basis, dann Features -->
<script src="/js/api.js?v=1277"></script>
<script src="/js/ui.js?v=1277"></script>
<script src="/js/app.js?v=1277"></script>
<script src="/js/worlds.js?v=1277"></script>
<script src="/js/offline-indicator.js?v=1277"></script>
<script src="/js/api.js?v=1278"></script>
<script src="/js/ui.js?v=1278"></script>
<script src="/js/app.js?v=1278"></script>
<script src="/js/worlds.js?v=1278"></script>
<script src="/js/offline-indicator.js?v=1278"></script>
<script src="/js/contact-form.js?v=1278"></script>
<!-- Feature-Seiten werden lazy geladen -->
@ -634,7 +635,7 @@
<!-- Boot: Offline-Banner + SW-Registration (extrahiert für CSP) -->
<script src="/js/boot.js?v=1277"></script>
<script src="/js/boot.js?v=1278"></script>
</body>

View file

@ -3,7 +3,7 @@
Router, State-Management, Navigation, Initialisierung.
============================================================ */
const APP_VER = '1277'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const APP_VER = '1278'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const APP_VERSION = '1.6.0'; // ← semantische Version, wird bei make release gesetzt
window.APP_VER = APP_VER; // global verfügbar für andere Module (z.B. offline-indicator)
window.APP_VERSION = APP_VERSION;

View file

@ -0,0 +1,58 @@
/* ============================================================
BAN YARO Kontaktformular (geteilt)
Einzige Quelle für die Formular-Logik. Genutzt von:
- der eigenständigen Seite /impressum (Auto-Init auf document)
- der SPA-Impressum-Seite (window.initContactForm(container))
============================================================ */
window.initContactForm = function (root) {
const form = root.querySelector('#contact-form');
if (!form || form._bound) return; // einmal binden
form._bound = true;
const statusEl = root.querySelector('#cf-status');
const submitBtn = root.querySelector('#cf-submit');
form.addEventListener('submit', async e => {
e.preventDefault();
const name = root.querySelector('#cf-name').value.trim();
const email = root.querySelector('#cf-email').value.trim();
const subject = root.querySelector('#cf-subject').value.trim();
const message = root.querySelector('#cf-message').value.trim();
submitBtn.disabled = true;
submitBtn.textContent = 'Wird gesendet…';
statusEl.style.display = 'none';
try {
const res = await fetch('/api/contact', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, email, subject, message }),
});
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(err.detail || 'Fehler beim Senden.');
}
statusEl.style.display = 'block';
statusEl.style.background = 'var(--c-success-bg, #f0fdf4)';
statusEl.style.color = 'var(--c-success, #16a34a)';
statusEl.textContent = '✓ Nachricht gesendet — wir melden uns bald!';
form.reset();
} catch (err) {
statusEl.style.display = 'block';
statusEl.style.background = '#fef2f2';
statusEl.style.color = '#dc2626';
statusEl.textContent = err.message || 'Fehler beim Senden. Bitte versuche es später erneut.';
submitBtn.disabled = false;
submitBtn.textContent = 'Nachricht senden';
}
});
};
// Auto-Init für die eigenständige /impressum-Seite (kein Inline-Handler wegen CSP)
(function () {
function go() { try { window.initContactForm(document); } catch (e) {} }
if (document.readyState !== 'loading') go();
else document.addEventListener('DOMContentLoaded', go);
})();

View file

@ -1,200 +1,23 @@
/* ============================================================
BAN YARO Allgemeine Geschäftsbedingungen
BAN YARO Allgemeine Geschäftsbedingungen (SPA-Wrapper)
Einzige Inhaltsquelle: /agb.html (crawlbar). Diese Seite holt
den Inhalt per fetch und injiziert ihn kein Text-Duplikat.
============================================================ */
window.Page_agb = (() => {
const S = {
h2: `font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-primary);margin:0 0 var(--space-2)`,
p: `font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0`,
ul: `font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:var(--space-2) 0 0;padding-left:var(--space-5)`,
a: `color:var(--c-primary)`,
};
function sec(title, body) {
return `
<section style="margin-bottom:var(--space-6)">
<h2 style="${S.h2}">${title}</h2>
${body}
</section>`;
}
function init(container) {
container.innerHTML = `
<div style="max-width:640px;margin:0 auto;padding:var(--space-6) var(--space-4)">
<h1 style="font-size:var(--text-2xl);font-weight:var(--weight-bold);
color:var(--c-text);margin:0 0 var(--space-2)">Allgemeine Geschäftsbedingungen</h1>
<p style="${S.p};margin-bottom:var(--space-6)">Gültig ab Mai 2026</p>
${sec('1. Geltungsbereich', `
<p style="${S.p}">
Diese AGB gelten für die Nutzung der Plattform <strong>Ban Yaro</strong>
(<a href="https://banyaro.app" style="${S.a}">banyaro.app</a>), betrieben von:<br><br>
René Degelmann<br>
Ringstr. 26, 85560 Ebersberg<br>
E-Mail: <a href="mailto:hallo@banyaro.app" style="${S.a}">hallo@banyaro.app</a>
</p>
<p style="${S.p};margin-top:var(--space-3)">
Sie gelten ausschließlich für kostenpflichtige Abonnements. Die kostenlose Nutzung
der App setzt lediglich die Registrierung voraus.
</p>`)}
${sec('2. Mindestalter', `
<p style="${S.p}">
Die Nutzung von Ban Yaro, insbesondere die Registrierung und der Abschluss eines
Abonnements, ist nur Personen ab 18 Jahren gestattet. Mit Abschluss des Vertrags
bestätigt der Nutzer, volljährig zu sein.
</p>`)}
${sec('3. Leistungen', `
<p style="${S.p}">Ban Yaro bietet folgende kostenpflichtige Abonnements an:</p>
<ul style="${S.ul}">
<li>
<strong>Ban Yaro Pro 29 EUR/Jahr:</strong> Erweiterte App-Funktionen für mehrere
Hunde, KI-Features, zusätzliche Karten-Layer, Chat und Playdate-Funktion sowie
alle weiteren Pro-Funktionen laut aktuellem Funktionsumfang.
</li>
<li>
<strong>Ban Yaro Züchter 49 EUR/Jahr:</strong> Alle Pro-Funktionen plus
Zuchtkartei, Stammbaum, Wurfverwaltung und Züchterprofil.
</li>
</ul>
<p style="${S.p};margin-top:var(--space-3)">
Die native iOS-App <strong>Ban Yaro Go"</strong> ist kostenlos und dient als
Begleit-App für unterwegs. Kostenpflichtige Abonnements werden
<strong>ausschließlich über banyaro.app</strong> abgeschlossen und per Überweisung
bezahlt <strong>nicht</strong> über einen App-Store-Kauf (kein In-App-Kauf).
Pro- und Züchter-Funktionen werden mit deinem banyaro-Konto freigeschaltet und
stehen damit auch in der iOS-App zur Verfügung.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Änderungen am Funktionsumfang werden vorab per E-Mail angekündigt. Wesentliche
Leistungsminderungen berechtigen zur außerordentlichen Kündigung.
</p>`)}
${sec('4. Nutzungsregeln / Community', `
<p style="${S.p}">Die Nutzung der Plattform-Features (Forum, Chat, Fotos, Kommentare) unterliegt folgenden Regeln:</p>
<ul style="${S.ul}">
<li>Keine rechtswidrigen, beleidigenden, diskriminierenden oder irreführenden Inhalte</li>
<li>Kein Spam, keine Werbung ohne Genehmigung, keine Fake-Accounts</li>
<li>Respektvoller Umgang mit anderen Nutzern</li>
<li>Keine Verletzung von Urheberrechten Dritter bei hochgeladenen Inhalten</li>
</ul>
<p style="${S.p};margin-top:var(--space-3)">
Bei Verstoß sind wir berechtigt, Inhalte zu entfernen und Accounts zu sperren oder
zu kündigen. Rechtswidrige Inhalte werden unverzüglich entfernt und ggf. Behörden
gemeldet. Meldungen können an
<a href="mailto:hallo@banyaro.app" style="${S.a}">hallo@banyaro.app</a>
gerichtet werden.
</p>`)}
${sec('5. Nutzerinhalte und Lizenzen', `
<p style="${S.p}">
Durch das Hochladen von Inhalten (Fotos, Texte, Beiträge) räumt der Nutzer Ban Yaro
eine nicht-exklusive, kostenlose, weltweite Lizenz ein, diese Inhalte im Rahmen der
Plattform zu speichern, anzuzeigen und technisch zu verarbeiten. Diese Lizenz erlischt
mit Löschung des Inhalts oder Löschung des Accounts. Urheberrechte und sonstige
Rechte der Nutzer an ihren Inhalten bleiben unberührt.
</p>`)}
${sec('6. Preise und Zahlung', `
<p style="${S.p}">
Der Jahresbeitrag ist bei Vertragsschluss für die gesamte Laufzeit im Voraus fällig.
Die Zahlung erfolgt per Überweisung IBAN und Verwendungszweck stehen auf der
Rechnung, die per E-Mail zugestellt wird. Der Betrag ist innerhalb von
<strong>14 Tagen</strong> nach Rechnungsstellung zu überweisen.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Bei Zahlungsverzug erhalten Sie zunächst eine Zahlungserinnerung. Bleibt der Betrag
danach weiterhin ausstehend, behalten wir uns die fristlose Kündigung des Vertrags
gemäß § 314 BGB vor.
</p>`)}
${sec('7. Vertragslaufzeit und Kündigung', `
<p style="${S.p}">
Die Erstlaufzeit beträgt <strong>12 Monate</strong> ab dem Tag der Freischaltung.
Nach Ablauf verlängert sich der Vertrag auf unbestimmte Zeit kündbar jederzeit
mit einer Frist von <strong>einem Monat zum Monatsende</strong> (§ 309 Nr. 9 BGB).
</p>
<p style="${S.p};margin-top:var(--space-3)">
Die Kündigung ist jederzeit in den App-Einstellungen unter
<strong>Einstellungen Abonnement Kündigen</strong> möglich (§ 312k BGB).
Eine Kündigungsbestätigung wird per E-Mail zugesandt.
Der Zugang bleibt bis zum Ende der bereits bezahlten Laufzeit vollständig aktiv.
</p>`)}
${sec('8. Kein Erstattungsanspruch', `
<p style="${S.p}">
Bei vorzeitiger Kündigung durch den Nutzer erfolgt keine anteilige Rückerstattung
des Jahresbeitrags. Der Zugang bleibt bis zum Ende der Laufzeit vollständig nutzbar
du verlierst also nichts, was du bereits bezahlt hast.
Gesetzliche Ansprüche bei vertragswidrigen Leistungen bleiben unberührt.
</p>`)}
${sec('9. Widerrufsrecht', `
<p style="${S.p}">
Da die Nutzung unmittelbar nach Freischaltung beginnt und du beim Kauf ausdrücklich
zustimmst, dass die Vertragserfüllung vor Ablauf der Widerrufsfrist beginnt, erlischt
dein 14-tägiges Widerrufsrecht mit Beginn der Nutzung (§ 356 Abs. 4 BGB). Dir ist
bekannt, dass du durch diese Zustimmung dein Widerrufsrecht verlierst. Die Zustimmung
wird beim Kauf aktiv protokolliert.
</p>`)}
${sec('10. Fristlose Kündigung durch den Anbieter', `
<p style="${S.p}">
Wir sind berechtigt, den Vertrag aus wichtigem Grund fristlos zu kündigen
(§ 314 BGB). Ein wichtiger Grund liegt insbesondere vor, wenn nach einer
Zahlungserinnerung der offene Betrag weiterhin nicht beglichen wird.
In diesem Fall endet der Zugang mit Wirkung der Kündigung.
</p>`)}
${sec('11. KI-Funktionen / Haftung für KI-Inhalte', `
<p style="${S.p}">
KI-generierte Inhalte (Trainer-Empfehlungen, Gesundheitshinweise, Züchter-Analysen)
können fehlerhaft oder unvollständig sein. Sie dienen ausschließlich der allgemeinen
Information und ersetzen keine tierärztliche, veterinärmedizinische oder fachliche
Beratung. Ban Yaro haftet nicht für Schäden, die aus der Nutzung KI-generierter
Inhalte entstehen.
</p>`)}
${sec('12. Verfügbarkeit', `
<p style="${S.p}">
Wir streben eine hohe Verfügbarkeit von Ban Yaro an und arbeiten kontinuierlich
daran, die App stabil zu halten. Eine Garantie für ununterbrochene Verfügbarkeit
können wir jedoch nicht übernehmen. Geplante Wartungsarbeiten werden nach
Möglichkeit vorab in der App angekündigt.
</p>`)}
${sec('13. Änderungen dieser AGB', `
<p style="${S.p}">
Änderungen der AGB werden per <strong>E-Mail und in der App</strong> angekündigt
mindestens 4 Wochen vor Inkrafttreten. Widersprichst du den Änderungen nicht
innerhalb dieser Frist, gelten sie als angenommen. Dein Widerspruchsrecht und
das Recht zur außerordentlichen Kündigung bleiben unberührt.
</p>`)}
${sec('14. Anwendbares Recht', `
<p style="${S.p}">
Es gilt ausschließlich <strong>deutsches Recht</strong>. Als Verbraucher hast du
deinen allgemeinen Gerichtsstand. Die EU-Plattform zur Online-Streitbeilegung
(ec.europa.eu/consumers/odr) wurde eingestellt. Wir nehmen nicht an alternativen
Streitbeilegungsverfahren teil (§ 36 VSBG).
</p>`)}
${sec('15. Kontakt', `
<p style="${S.p}">
René Degelmann<br>
Ringstr. 26, 85560 Ebersberg<br>
E-Mail: <a href="mailto:hallo@banyaro.app" style="${S.a}">hallo@banyaro.app</a>
</p>`)}
<p style="font-size:var(--text-xs);color:var(--c-text-muted);margin:0">
Stand: Juni 2026 · Version 3
</p>
</div>
`;
async function init(container) {
try {
const res = await fetch('/agb');
const html = await res.text();
const doc = new DOMParser().parseFromString(html, 'text/html');
const content = doc.querySelector('#legal-content');
container.innerHTML = content
? content.innerHTML
: '<p style="padding:var(--space-4);color:var(--c-text-secondary)">Inhalt momentan nicht verfügbar.</p>';
} catch (e) {
container.innerHTML = '<p style="padding:var(--space-4);color:var(--c-text-secondary)">Die AGB sind offline nicht verfügbar — bitte einmal mit Internetverbindung öffnen.</p>';
}
}
function refresh() {}

View file

@ -1,411 +1,23 @@
/* ============================================================
BAN YARO Datenschutzerklärung
BAN YARO Datenschutzerklärung (SPA-Wrapper)
Einzige Inhaltsquelle: /datenschutz.html (crawlbar). Diese Seite
holt den Inhalt per fetch und injiziert ihn kein Text-Duplikat.
============================================================ */
window.Page_datenschutz = (() => {
const S = {
h2: `font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)`,
p: `font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0`,
ul: `font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:var(--space-2) 0 0;padding-left:var(--space-5)`,
a: `color:var(--c-primary)`,
};
function sec(title, body) {
return `
<section style="margin-bottom:var(--space-6)">
<h2 style="${S.h2}">${title}</h2>
${body}
</section>`;
}
function init(container) {
container.innerHTML = `
<div style="max-width:640px;margin:0 auto;padding:var(--space-6) var(--space-4)">
<h1 style="font-size:var(--text-2xl);font-weight:var(--weight-bold);
color:var(--c-text);margin:0 0 var(--space-6)">Datenschutzerklärung</h1>
${sec('Verantwortlicher', `
<p style="${S.p}">
René Degelmann, Ringstr. 26, 85560 Ebersberg<br>
E-Mail: <a href="mailto:hallo@banyaro.app" style="${S.a}">hallo@banyaro.app</a>
</p>`)}
${sec('Hosting &amp; Infrastruktur', `
<p style="${S.p}">
Die App wird auf einem eigenen Server (Synology DiskStation) in Deutschland betrieben.
Alle Daten werden ausschließlich auf diesem Server gespeichert und nicht an externe
Hoster übermittelt.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Für den E-Mail-Versand (Kontobestätigung, Benachrichtigungen, Rechnungen) nutzen wir
<strong>Brevo</strong> (Sendinblue SAS, 55 rue d'Amsterdam, 75008 Paris, Frankreich).
Brevo ist nach EU-Standardvertragsklauseln zertifiziert. Dabei werden E-Mail-Adresse
und Name übermittelt. Datenschutzinformationen:
<a href="https://www.brevo.com/de/legal/privacypolicy/" target="_blank" rel="noopener"
style="${S.a}">brevo.com/de/legal/privacypolicy/</a>.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Für anonymisierte Nutzungsstatistiken betreiben wir <strong>Umami Analytics</strong>
auf unserem eigenen Server. Es werden keine personenbezogenen Daten oder IP-Adressen
gespeichert. Kein Tracking über Sitzungen hinweg.
</p>`)}
${sec('Deine Daten gehören dir', `
<p style="${S.p}">
Ban Yaro ist eine private Community-App. Dein <strong>Tagebuch</strong>, deine
<strong>persönlichen Notizen</strong>, <strong>Gesundheitsdaten</strong> deines Hundes,
<strong>eigene Routen</strong> und dein <strong>Nutzerprofil</strong> sind
ausschließlich für dich sichtbar sie werden weder an andere Nutzer noch an Dritte
weitergegeben. Öffentlich sichtbar sind nur Inhalte, die du bewusst veröffentlichst
(z. B. Forenbeiträge, Giftköder-Meldungen, öffentliche Gassi-Treffen).
</p>`)}
${sec('Welche Daten wir verarbeiten', `
<p style="${S.p}">Bei der Registrierung und Nutzung von Ban Yaro werden folgende Daten verarbeitet:</p>
<ul style="${S.ul}">
<li><strong>Accountdaten:</strong> Benutzername, E-Mail-Adresse, Passphrase (verschlüsselt gespeichert)</li>
<li><strong>Hundeprofil:</strong> Name, Rasse, Alter, Foto (freiwillig)</li>
<li><strong>Gesundheitsdaten deines Hundes:</strong> Gewicht, Impfungen, Tierarztbesuche, Medikamente (freiwillig, nur für dich sichtbar)</li>
<li><strong>Tagebuch &amp; Notizen:</strong> Texte, Fotos, Stimmungseinträge (privat, nur für dich)</li>
<li><strong>Standortdaten:</strong> Nur nach expliziter Browser-Freigabe für Karte, Gassi-Treffen,
Giftköder-Meldungen, Nearby-Alerts und Routenaufzeichnung. Standortdaten werden nicht dauerhaft
gespeichert, außer du speicherst selbst eine Route oder Meldung.</li>
<li><strong>Routendaten:</strong> Aufgezeichnete Routen (GPS-Wegpunkte) werden nur gespeichert,
wenn du sie explizit speicherst; sie sind standardmäßig privat.</li>
<li><strong>Fotos &amp; EXIF-Daten:</strong> Beim Hochladen von Bildern können GPS-Koordinaten
in den EXIF-Metadaten enthalten sein. Diese werden serverseitig ausgelesen, um Fotos auf der
Karte zu verorten sofern vorhanden. Die Rohdaten werden nicht separat gespeichert.</li>
<li><strong>Inhalte:</strong> Forenbeiträge, Chatnachrichten, öffentliche Gassi-Treffen</li>
<li><strong>Technische Daten:</strong> IP-Adresse (für Sicherheit und Rate-Limiting, max. 30 Tage),
Browser-Typ</li>
</ul>`)}
${sec('Rechtsgrundlage', `
<p style="${S.p}">
Die Verarbeitung erfolgt auf Basis von Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung)
für alle zur Bereitstellung des Dienstes notwendigen Daten, sowie Art. 6 Abs. 1 lit. a
DSGVO (Einwilligung) für optionale Funktionen wie Standortfreigabe und
Push-Benachrichtigungen. Einwilligungen können jederzeit mit Wirkung für die Zukunft
widerrufen werden (Art. 7 Abs. 3 DSGVO) einfach die entsprechende Funktion in den
Einstellungen deaktivieren oder die Browser-Freigabe entziehen.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Impressum und rechtliche Grundlage nach § 5 DDG (Digitale-Dienste-Gesetz).
</p>`)}
${sec('Datenweitergabe', `
<p style="${S.p}">
Deine Daten werden nicht an Dritte verkauft oder zu Werbezwecken weitergegeben.
Öffentliche Inhalte (Forum, Wiki, Giftköder-Karte) sind für alle Nutzer sichtbar.
Profile sind standardmäßig nur für registrierte Nutzer sichtbar.
Admins und Moderatoren können gemeldete Inhalte zur Qualitätssicherung einsehen
(Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO berechtigtes Interesse an
Plattformsicherheit).
</p>`)}
${sec('Direktnachrichten', `
<p style="${S.p}">
Nachrichten zwischen Nutzern (z. B. zwischen Hundesitter und Hundeeigentümer oder
zwischen Interessenten und Züchtern) werden auf unserem Server gespeichert, bis du
das Gespräch oder deinen Account löschst. Admins können gemeldete Nachrichten zur
Missbrauchsprüfung einsehen (Art. 6 Abs. 1 lit. f DSGVO berechtigtes Interesse
an Plattformsicherheit). Nachrichten werden nicht an Dritte weitergegeben.
Du kannst Gespräche jederzeit selbst löschen.
</p>`)}
${sec('Moderation &amp; Community', `
<p style="${S.p}">
Zur Sicherstellung der Plattformqualität und Einhaltung unserer Nutzungsregeln können
Moderatoren und automatische Systeme Inhalte prüfen. Rechtsgrundlage ist
Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an sicherer Plattform).
</p>`)}
${sec('KI-Funktionen', `
<p style="${S.p}">
Ban Yaro bietet KI-gestützte Funktionen (Trainingsempfehlungen, Terminvorschläge,
Rassen-Informationen). Diese laufen primär auf einer <strong>lokalen KI auf unserem
eigenen Server in Deutschland</strong> deine Anfragen verlassen dabei nicht unsere
Infrastruktur.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Als Ausweichlösung bei Nichtverfügbarkeit des lokalen Modells wird
<strong>Claude Sonnet 4.6</strong> von Anthropic, PBC (San Francisco, USA) genutzt.
In diesem Fall wird der Inhalt deiner Anfrage übermittelt. Bei Gesundheits- und
Ernährungsberichten kann dies Hundedaten (Name, Rasse, Gewicht, Impfhistorie,
Medikamente, Allergien) als Teil des Anfragetextes umfassen. Die Übermittlung
in die USA erfolgt auf Basis der EU-Standardvertragsklauseln (Art. 46 Abs. 2 lit. c DSGVO).
Datenschutzerklärung von Anthropic:
<a href="https://www.anthropic.com/privacy" target="_blank" rel="noopener"
style="${S.a}">anthropic.com/privacy</a>.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Die <strong>Rassenerkennung per Foto</strong> sendet das hochgeladene Bild direkt an
Claude von Anthropic (USA) zur Analyse es gibt hierfür keinen lokalen Fallback.
Das Foto wird nicht dauerhaft bei Anthropic gespeichert. Rechtsgrundlage: Einwilligung
gem. Art. 6 Abs. 1 lit. a DSGVO durch aktive Nutzung der Funktion.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Der <strong>KI-Trainer</strong> analysiert deinen bisherigen Trainingsfortschritt
(Übungshistorie, Erfolgsquoten, Streaks) und gibt personalisierte Empfehlungen.
Diese Analyse läuft auf unserem lokalen Server in Deutschland deine Trainingsdaten
verlassen dabei nicht unsere Infrastruktur. Es findet kein Training oder Fine-Tuning
von KI-Modellen auf Basis deiner Nutzerdaten statt.
</p>
<p style="${S.p};margin-top:var(--space-3)">
KI-Empfehlungen sind Vorschläge und ersetzen keine tierärztliche Beratung.
Eine automatisierte Entscheidungsfindung mit rechtlicher Wirkung (Art. 22 DSGVO)
findet nicht statt.
</p>
<p style="${S.p};margin-top:var(--space-3)">
KI-Antworten können fehlerhaft oder unvollständig sein und dienen ausschließlich
allgemeinen Informationszwecken. Sie ersetzen keine tierärztliche oder fachliche
Beratung. Trotz EU-Standardvertragsklauseln besteht bei US-Anbietern ein Restrisiko,
dass US-Behörden auf übermittelte Daten zugreifen könnten.
</p>`)}
${sec('Wetterdaten & Kartendienste', `
<p style="${S.p}">
Die Wetter-Funktion übermittelt auf Wunsch deine GPS-Koordinaten serverseitig an
<strong>Open-Meteo</strong> (Österreich, DSGVO-konform) für die Wettervorhersage.
Für das <strong>Regenradar</strong> nutzen wir primär die offenen Radardaten des
<strong>Deutschen Wetterdienstes (DWD)</strong>. Diese werden serverseitig von unserem
Server in Deutschland abgerufen und als Kartenkacheln bereitgestellt dein Gerät
kontaktiert den DWD dabei nicht direkt. Steht das DWD-Radar nicht zur Verfügung,
werden ersatzweise Radarkacheln von <strong>RainViewer</strong> (USA) geladen; dabei
wird dein Browser direkt kontaktiert. Für weitere Wetter-Kartenlayer (z. B. Temperatur)
können Kacheln von <strong>OpenWeatherMap</strong> (OpenWeather Ltd., UK/USA) direkt im
Browser geladen werden. In allen Fällen werden keine Account-Daten übermittelt.
Rechtsgrundlage: Einwilligung gem. Art. 6 Abs. 1 lit. a DSGVO.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Für die automatische Ortsnamens-Ermittlung (z. B. im Wetter-Detail) werden deine
GPS-Koordinaten serverseitig an <strong>Nominatim</strong> der OpenStreetMap Foundation
(UK) übermittelt. Es werden ausschließlich Koordinaten weitergegeben keine
personenbezogenen Daten.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Datenschutzerklärung Open-Meteo:
<a href="https://open-meteo.com/en/terms" target="_blank" rel="noopener"
style="${S.a}">open-meteo.com/en/terms</a> ·
OpenWeatherMap:
<a href="https://openweathermap.org/privacy-policy" target="_blank" rel="noopener"
style="${S.a}">openweathermap.org/privacy-policy</a> ·
OpenStreetMap/Nominatim:
<a href="https://osmfoundation.org/wiki/Privacy_Policy" target="_blank" rel="noopener"
style="${S.a}">osmfoundation.org</a> ·
DWD:
<a href="https://www.dwd.de/DE/service/datenschutz/datenschutz_node.html" target="_blank" rel="noopener"
style="${S.a}">dwd.de</a> ·
RainViewer:
<a href="https://www.rainviewer.com/privacy.html" target="_blank" rel="noopener"
style="${S.a}">rainviewer.com</a>
</p>`)}
${sec('Kartenmaterial &amp; Offline-Karten', `
<p style="${S.p}">
Die Basiskarte besteht aus Vektordaten von <strong>OpenStreetMap</strong>, die wir auf
unserem eigenen Server in Deutschland aufbereiten und ausliefern (Vektor-Tiles im
PMTiles-Format). Für die Basiskarte werden daher <strong>keine externen
Kartenanbieter</strong> kontaktiert die Kartenkacheln kommen von unserem Server.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Optional kannst du Kartenausschnitte für die <strong>Offline-Nutzung</strong>
herunterladen. Diese werden ausschließlich <strong>lokal auf deinem Gerät</strong>
gespeichert und nicht an Dritte übermittelt.
</p>`)}
${sec('Routenvorschläge (OpenRouteService)', `
<p style="${S.p}">
Die Funktion <strong>Routenvorschläge"</strong> berechnet auf Wunsch einen Rundweg
ausgehend von deinem aktuellen Standort. Dazu werden deine GPS-Koordinaten einmalig
an den Dienst <strong>OpenRouteService</strong> übermittelt, der von
<strong>HeiGIT</strong> am Karlsruher Institut für Technologie (KIT), Deutschland,
betrieben wird. Es werden ausschließlich die Koordinaten übertragen
keine Account- oder Profildaten. OpenRouteService speichert keine
personenbezogenen Daten dauerhaft.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Die Funktion wird nur aktiv, wenn du deinen Standort im Browser freigibst und
bewusst einen Routenvorschlag anforderst (Einwilligung gem. Art. 6 Abs. 1 lit. a DSGVO).
Der Tagesvorschlag auf der Startseite wird nur berechnet, wenn du eingeloggt bist und
Standortzugriff erteilt hast das Ergebnis wird lokal zwischengespeichert und
maximal einmal täglich neu abgerufen.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Datenschutzerklärung von OpenRouteService:
<a href="https://openrouteservice.org/privacy-policy/" target="_blank" rel="noopener"
style="${S.a}">openrouteservice.org/privacy-policy</a>
</p>`)}
${sec('Ban Yaro Go — native iOS-App', `
<p style="${S.p}">
<strong>Ban Yaro Go</strong> ist die optionale native iOS-Begleit-App zu banyaro.app.
Sie nutzt dasselbe banyaro-Konto und denselben Server in Deutschland es gelten
daher zusätzlich zu den oben beschriebenen Verarbeitungen folgende iOS-spezifische
Punkte:
</p>
<ul style="${S.ul}">
<li><strong>Hintergrund-Standort:</strong> Nur während einer von dir aktiv gestarteten
Gassi-Aufzeichnung erfasst die App deine GPS-Position auch bei gesperrtem Display, um
den Track fortzuführen. Außerhalb einer aktiven Aufzeichnung wird im Hintergrund kein
Standort erfasst. Der Track wird lokal auf dem Gerät gesichert und nur dann in dein
Konto übertragen, wenn du die Tour speicherst.</li>
<li><strong>Apple WeatherKit:</strong> Die Wetterfunktion der App bezieht Vorhersagedaten
über Apple WeatherKit (Apple Inc., USA). Dazu werden Standortkoordinaten an Apple
übermittelt keine Account-Daten.</li>
<li><strong>Apple Health (HealthKit):</strong> Nur auf deinen ausdrücklichen Wunsch
schreibt die App abgeschlossene Touren als Walking"-Workout inkl. Route in Apple
Health. Es werden <strong>keine</strong> Gesundheitsdaten aus Apple Health gelesen.
Diese Daten verbleiben auf deinem Gerät bzw. in deiner iCloud.</li>
<li><strong>Apple Maps:</strong> Zur Navigation (z. B. zu Gassi-Treffen) kann auf deinen
Wunsch Apple Maps geöffnet werden.</li>
<li><strong>GPX-Import:</strong> Aus anderen Apps geteilte GPX-Dateien werden lokal auf
dem Gerät verarbeitet; eine Übertragung erfolgt nur, wenn du die Tour speicherst.</li>
<li><strong>Push (APNs):</strong> Benachrichtigungen werden wie im Abschnitt
Push-Benachrichtigungen" beschrieben über den Apple Push Notification Service zugestellt.</li>
</ul>
<p style="${S.p};margin-top:var(--space-3)">
Rechtsgrundlage ist jeweils deine Einwilligung (Art. 6 Abs. 1 lit. a DSGVO) bzw. die
Vertragserfüllung (Art. 6 Abs. 1 lit. b DSGVO). Apple-Datenschutz:
<a href="https://www.apple.com/legal/privacy/de-ww/" target="_blank" rel="noopener"
style="${S.a}">apple.com/legal/privacy</a>.
</p>`)}
${sec('Technische Speicherung', `
<p style="${S.p}">
Ban Yaro verwendet technisch notwendige Speichermechanismen für den Betrieb der App:
Session-Tokens und Authentifizierungsdaten werden im Local Storage des Browsers
gespeichert. Ein Service Worker speichert App-Inhalte lokal für die Offline-Nutzung
(Cache). Push-Benachrichtigungs-Token werden für die Zustellung von Hinweisen benötigt.
Diese Speicherung ist für die Kernfunktion der App erforderlich; eine Einwilligung ist
nach § 25 Abs. 2 TTDSG nicht erforderlich. Es werden keine Tracking-Cookies eingesetzt.
</p>`)}
${sec('Push-Benachrichtigungen', `
<p style="${S.p}">
Wenn du Push-Benachrichtigungen aktivierst, wird ein Abonnement-Token an den
Push-Dienst deines Browsers übermittelt: bei Android/Chrome an
<strong>Firebase Cloud Messaging</strong> (Google LLC, USA), bei iOS/Safari an
<strong>Apple Push Notification Service</strong> (Apple Inc., USA). Diese Dienste
erhalten lediglich den Token und die Benachrichtigung selbst keine weiteren
Nutzerdaten. Die Übermittlung erfolgt auf Basis deiner Einwilligung
(Art. 6 Abs. 1 lit. a DSGVO), die du jederzeit in den Geräteeinstellungen widerrufen kannst.
</p>`)}
${sec('Kalender-Abo (Webcal)', `
<p style="${S.p}">
Das Kalender-Abo nutzt einen persönlichen Token-Link. Wenn deine Kalender-App
diesen Link regelmäßig abruft, wird dabei deine IP-Adresse an unseren Server
übermittelt. Es werden keine weiteren Daten an Dritte weitergegeben.
</p>`)}
${sec('Einladungslinks (Referral)', `
<p style="${S.p}">
Wenn du Freunde über deinen persönlichen Einladungslink einlädst, wird erfasst,
wie viele Personen sich darüber registriert haben ohne personenbezogene Daten
der eingeladenen Personen zu speichern. Dir wird lediglich die Anzahl angezeigt.
</p>`)}
${sec('Nutzungsanalyse (Umami)', `
<p style="${S.p}">
Wir verwenden Umami, ein datenschutzfreundliches Analysetool, das ausschließlich auf
unserem eigenen Server betrieben wird. Es werden keine Cookies gesetzt, keine
personenbezogenen Daten erhoben und keine Daten an Dritte weitergegeben.
Erfasst werden lediglich anonyme Seitenaufrufe zur Verbesserung der App
(Art. 6 Abs. 1 lit. f DSGVO berechtigtes Interesse).
</p>`)}
${sec('Deine Rechte (DSGVO)', `
<p style="${S.p}">
Du hast das Recht auf <strong>Auskunft</strong> (Art. 15), <strong>Berichtigung</strong>
(Art. 16), <strong>Löschung</strong> (Art. 17), <strong>Einschränkung der Verarbeitung</strong>
(Art. 18) sowie <strong>Datenportabilität</strong> (Art. 20). Erteilte Einwilligungen
kannst du jederzeit mit Wirkung für die Zukunft widerrufen (Art. 7 Abs. 3 DSGVO).
</p>
<p style="${S.p};margin-top:var(--space-3)">
<strong>Datenexport (Art. 20 DSGVO):</strong> Du kannst jederzeit unter
Einstellungen Meine Daten exportieren" eine vollständige Kopie deiner
gespeicherten Daten als JSON-Datei herunterladen. Der Export enthält Profildaten,
Hundedaten, Tagebuch (inkl. Medien-URLs), Gesundheitseinträge, Trainingsfortschritt,
Ausgaben, Verhaltensprotokoll, Versicherung, Ernährungsprofil und Futter-Reaktionen,
eigene Routen, Forum-Beiträge sowie Gassi-Teilnahmen und Gassi-Fotos.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Das JSON-Format ist maschinenlesbar und kann z. B. mit jedem Texteditor geöffnet
oder in andere Anwendungen importiert werden. Der Export wird direkt im Browser
erzeugt und nicht dauerhaft auf dem Server gespeichert.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Zur Ausübung weiterer Rechte wende dich per E-Mail an
<a href="mailto:hallo@banyaro.app" style="${S.a}">hallo@banyaro.app</a>.<br><br>
Du hast außerdem das Recht, bei der zuständigen Datenschutz-Aufsichtsbehörde
Beschwerde einzulegen:<br>
<strong>Bayerisches Landesamt für Datenschutzaufsicht (BayLDA)</strong><br>
Promenade 18, 91522 Ansbach<br>
<a href="mailto:poststelle@lda.bayern.de"
style="${S.a}">poststelle@lda.bayern.de</a> ·
<a href="https://www.lda.bayern.de" target="_blank" rel="noopener"
style="${S.a}">www.lda.bayern.de</a>
</p>`)}
${sec('Zahlungsdaten', `
<p style="${S.p}">
Wenn du ein kostenpflichtiges Abonnement abschließt, verarbeiten wir folgende Daten:
Name, E-Mail-Adresse, Rechnungsadresse und den Zahlungseingang. Rechtsgrundlage ist
Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung). Rechnungsdaten werden gemäß
§ 147 AO <strong>10 Jahre</strong> aufbewahrt. Rechnungen werden per E-Mail mit
TLS-Verschlüsselung zugestellt.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Deine Zahlungsdaten (IBAN) werden nur für die Zuordnung des Zahlungseingangs intern
verwendet und nicht an Dritte weitergegeben. Die vertraglichen Bedingungen (Laufzeit,
Kündigung, Erstattung) findest du in unseren
<a href="#agb" style="${S.a}">AGB</a>.
</p>`)}
${sec('Speicherdauer', `
<p style="${S.p}">
Server-Logs werden nach 30 Tagen rotiert. IP-Adressen werden ausschließlich
zur Sicherheit und für Rate-Limiting maximal 30 Tage gespeichert.
</p>`)}
${sec('Account-Löschung', `
<p style="${S.p}">
Wenn du deinen Account löschst, werden deine Daten nach folgendem Schema verarbeitet:
</p>
<ul style="${S.ul}">
<li><strong>Sofort und unwiderruflich gelöscht:</strong> Account, Hundeprofile, Tagebuch
und Tagebuch-Medien, Gesundheitseinträge, Trainingsfortschritt, Ausgaben,
Verhaltensprotokoll, Versicherung, Ernährungsprofil, Futter-Einträge und -Reaktionen,
Forum-Beiträge, eigene Notizen, Direktnachrichten, Freundschaften,
Push-Benachrichtigungen, Einstellungen und Welten-Konfiguration.</li>
<li><strong>Anonymisiert (Urheber-Bezug auf NULL gesetzt):</strong> Eigene Routen,
Forum-Threads sowie von dir angelegte Wiki-Inhalte bleiben zur Verfügbarkeit für
die Community erhalten, sind aber nicht mehr deinem Account zuordenbar.</li>
<li><strong>10 Jahre aufbewahrt (gesetzliche Pflicht):</strong> Rechnungen und
Rechnungspositionen aus kostenpflichtigen Abonnements gemäß § 147 AO. Diese
enthalten Name, E-Mail-Adresse und Rechnungsadresse zum Zeitpunkt der Rechnung
und können vor Ablauf der Frist nicht gelöscht werden.</li>
</ul>
<p style="${S.p};margin-top:var(--space-3)">
Es findet keine anonymisierte Weiterverarbeitung deiner privaten Inhalte
(Tagebuch, Gesundheit, Notizen) zu Trainings- oder Statistikzwecken statt.
</p>`)}
${sec('Mindestalter', `
<p style="${S.p}">
Die Nutzung von Ban Yaro ist nur Personen ab 18 Jahren gestattet. Durch die
Registrierung bestätigt der Nutzer, das 18. Lebensjahr vollendet zu haben.
</p>`)}
<p style="font-size:var(--text-xs);color:var(--c-text-muted);margin:0">
Stand: Juni 2026 · Version 4
</p>
</div>
`;
async function init(container) {
try {
const res = await fetch('/datenschutz');
const html = await res.text();
const doc = new DOMParser().parseFromString(html, 'text/html');
const content = doc.querySelector('#legal-content');
container.innerHTML = content
? content.innerHTML
: '<p style="padding:var(--space-4);color:var(--c-text-secondary)">Inhalt momentan nicht verfügbar.</p>';
} catch (e) {
container.innerHTML = '<p style="padding:var(--space-4);color:var(--c-text-secondary)">Die Datenschutzerklärung ist offline nicht verfügbar — bitte einmal mit Internetverbindung öffnen.</p>';
}
}
function refresh() {}

View file

@ -1,176 +1,28 @@
/* ============================================================
BAN YARO Impressum
BAN YARO Impressum (SPA-Wrapper)
Einzige Inhaltsquelle: /impressum.html (crawlbar). Diese Seite
holt den Inhalt per fetch und injiziert ihn kein Text-Duplikat.
Das Kontaktformular wird über die geteilte contact-form.js gebunden.
============================================================ */
window.Page_impressum = (() => {
function init(container) {
container.innerHTML = `
<div style="max-width:640px;margin:0 auto;padding:var(--space-6) var(--space-4)">
<h1 style="font-size:var(--text-2xl);font-weight:var(--weight-bold);
color:var(--c-text);margin:0 0 var(--space-6)">Impressum</h1>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);
color:var(--c-text);margin:0 0 var(--space-2)">Angaben gemäß § 5 DDG</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
René Degelmann<br>
Ringstr. 26<br>
85560 Ebersberg
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);
color:var(--c-text);margin:0 0 var(--space-2)">Kontakt</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0 0 var(--space-4)">
E-Mail: <a href="mailto:hallo@banyaro.app"
class="text-primary">hallo@banyaro.app</a><br>
Oder nutze das Formular wir antworten in der Regel innerhalb von 24 Stunden.
</p>
<form id="contact-form" class="flex-col-gap-3">
<div class="grid-2">
<div>
<label for="cf-name" style="display:block;font-size:var(--text-xs);font-weight:600;margin-bottom:4px;color:var(--c-text)">Name *</label>
<input id="cf-name" type="text" required maxlength="100"
placeholder="Dein Name"
style="width:100%;padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);
border:1.5px solid var(--c-border);background:var(--c-surface);
color:var(--c-text);font-size:var(--text-sm);box-sizing:border-box">
</div>
<div>
<label for="cf-email" style="display:block;font-size:var(--text-xs);font-weight:600;margin-bottom:4px;color:var(--c-text)">E-Mail *</label>
<input id="cf-email" type="email" required maxlength="200"
placeholder="deine@email.de"
style="width:100%;padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);
border:1.5px solid var(--c-border);background:var(--c-surface);
color:var(--c-text);font-size:var(--text-sm);box-sizing:border-box">
</div>
</div>
<div>
<label for="cf-subject" style="display:block;font-size:var(--text-xs);font-weight:600;margin-bottom:4px;color:var(--c-text)">Betreff *</label>
<input id="cf-subject" type="text" required maxlength="150"
placeholder="Worum geht es?"
style="width:100%;padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);
border:1.5px solid var(--c-border);background:var(--c-surface);
color:var(--c-text);font-size:var(--text-sm);box-sizing:border-box">
</div>
<div>
<label for="cf-message" style="display:block;font-size:var(--text-xs);font-weight:600;margin-bottom:4px;color:var(--c-text)">Nachricht *</label>
<textarea id="cf-message" required maxlength="3000" rows="5"
placeholder="Deine Nachricht…"
style="width:100%;padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);
border:1.5px solid var(--c-border);background:var(--c-surface);
color:var(--c-text);font-size:var(--text-sm);resize:vertical;
font-family:inherit;box-sizing:border-box"></textarea>
</div>
<div id="cf-status" style="display:none;padding:var(--space-2) var(--space-3);
border-radius:var(--radius-md);font-size:var(--text-sm)"></div>
<button id="cf-submit" type="submit"
style="align-self:flex-start;padding:var(--space-2) var(--space-5);
border-radius:var(--radius-full);border:none;cursor:pointer;
background:var(--c-primary);color:#fff;font-size:var(--text-sm);
font-weight:600">
Nachricht senden
</button>
</form>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);
color:var(--c-text);margin:0 0 var(--space-2)">Verantwortlich für den Inhalt
gemäß § 18 Abs. 2 MStV</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
René Degelmann<br>
(Anschrift wie oben)
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);
color:var(--c-text);margin:0 0 var(--space-2)">Streitschlichtung</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Wir sind nicht bereit und nicht verpflichtet, an einem Streitbeilegungsverfahren vor einer
Verbraucherschlichtungsstelle teilzunehmen (§ 36 VSBG).
</p>
</section>
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);
color:var(--c-text);margin:0 0 var(--space-2)">Haftungshinweis</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Die Inhalte dieser App wurden mit größtmöglicher Sorgfalt erstellt. Für die Richtigkeit,
Vollständigkeit und Aktualität der Inhalte übernehmen wir keine Gewähr. Als
Diensteanbieter sind wir gemäß § 7 Abs. 1 DDG für eigene Inhalte verantwortlich.
Für nutzergenerierte Inhalte (Forenbeiträge, Fotos, Kommentare) sind ausschließlich
die jeweiligen Nutzer verantwortlich. Bei Bekanntwerden rechtswidriger Inhalte werden
diese im Rahmen der gesetzlichen Vorgaben (§§ 7 ff. DDG) geprüft und gegebenenfalls
unverzüglich entfernt.
</p>
</section>
<p style="font-size:var(--text-xs);color:var(--c-text-muted);margin:0">
Stand: Mai 2026
</p>
</div>
`;
async function init(container) {
try {
const res = await fetch('/impressum');
const html = await res.text();
const doc = new DOMParser().parseFromString(html, 'text/html');
const content = doc.querySelector('#legal-content');
container.innerHTML = content
? content.innerHTML
: '<p style="padding:var(--space-4);color:var(--c-text-secondary)">Inhalt momentan nicht verfügbar.</p>';
window.initContactForm?.(container);
} catch (e) {
container.innerHTML = '<p style="padding:var(--space-4);color:var(--c-text-secondary)">Das Impressum ist offline nicht verfügbar — bitte einmal mit Internetverbindung öffnen.</p>';
}
}
function _initContactForm(container) {
const form = container.querySelector('#contact-form');
const statusEl = container.querySelector('#cf-status');
const submitBtn = container.querySelector('#cf-submit');
if (!form) return;
form.addEventListener('submit', async e => {
e.preventDefault();
const name = container.querySelector('#cf-name').value.trim();
const email = container.querySelector('#cf-email').value.trim();
const subject = container.querySelector('#cf-subject').value.trim();
const message = container.querySelector('#cf-message').value.trim();
submitBtn.disabled = true;
submitBtn.textContent = 'Wird gesendet…';
statusEl.style.display = 'none';
try {
const res = await fetch('/api/contact', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, email, subject, message }),
});
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(err.detail || 'Fehler beim Senden.');
}
statusEl.style.display = 'block';
statusEl.style.background = 'var(--c-success-bg, #f0fdf4)';
statusEl.style.color = 'var(--c-success, #16a34a)';
statusEl.textContent = '✓ Nachricht gesendet — wir melden uns bald!';
form.reset();
} catch (err) {
statusEl.style.display = 'block';
statusEl.style.background = '#fef2f2';
statusEl.style.color = '#dc2626';
statusEl.textContent = err.message || 'Fehler beim Senden. Bitte versuche es später erneut.';
submitBtn.disabled = false;
submitBtn.textContent = 'Nachricht senden';
}
});
}
const _origInit = init;
function refresh() {}
return {
init(container) {
_origInit(container);
_initContactForm(container);
},
refresh
};
return { init, refresh };
})();

View file

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light dark">
<script src="/js/landing-init.js?v=1277"></script>
<script src="/js/landing-init.js?v=1278"></script>
<title>Ban Yaro — Die Hunde-App für Deutschland, Österreich & Schweiz</title>
<meta name="description" content="Ban Yaro: Die kostenlose All-in-One Hunde-App für DACH. Tagebuch, Giftköder-Alarm, Training mit KI, Forum, Wurfbörse, Stammbaum, Inzucht-Check — DSGVO-konform, offline-fähig, direkt im Browser oder als native iPhone-App (Ban Yaro Go).">
<meta name="keywords" content="Hunde App, Hunde Community, Wurfbörse, Züchter, Welpen kaufen, Stammbaum Hund, Inzuchtkoeffizient, Hundezucht, Impfpass Hund, Giftköder Alarm, Gassi Community, Hundetraining App, Hunde Forum, Hunde KI, Hundefilm Datenbank, Welpen Marktplatz">

View file

@ -4,7 +4,7 @@
============================================================ */
// ← EINZIGE Stelle für die Version — STATIC_ASSETS und CACHE_VERSION leiten sich ab
const VER = '1277';
const VER = '1278';
const CACHE_VERSION = `by-v${VER}`;
const CACHE_STATIC = `${CACHE_VERSION}-static`;
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
@ -412,7 +412,8 @@ self.addEventListener('fetch', event => {
// zieht der Update-Mechanismus (x-app-version + controllerchange) ohnehin separat.
if (url.pathname.startsWith('/css/') || url.pathname.startsWith('/js/pages/')
|| url.pathname.startsWith('/js/app.js') || url.pathname.startsWith('/js/ui.js')
|| url.pathname.startsWith('/js/api.js') || url.pathname.startsWith('/js/worlds.js')) {
|| url.pathname.startsWith('/js/api.js') || url.pathname.startsWith('/js/worlds.js')
|| url.pathname === '/datenschutz' || url.pathname === '/agb' || url.pathname === '/impressum') {
event.respondWith((async () => {
const network = fetch(event.request).then(response => {
if (response.ok) {