/* ============================================================ BAN YARO — Landing Page Init Dark-Mode-Check, Scroll-Animationen, Live-Stats, Stay-In-App Extrahiert aus landing.html für CSP-Härtung ============================================================ */ // Dark Mode (CSS-Klasse) (function() { var mq = window.matchMedia('(prefers-color-scheme: dark)'); if (mq.matches) document.documentElement.classList.add('dark'); mq.addEventListener('change', function(e) { document.documentElement.classList.toggle('dark', e.matches); }); })(); document.addEventListener('DOMContentLoaded', function() { // App-Links: kein Redirect-Loop (ersetzt onclick="sessionStorage.setItem(...)") document.querySelectorAll('[data-stay-in-app]').forEach(function(el) { el.addEventListener('click', function() { sessionStorage.setItem('by_stay_in_app', '1'); }); }); // Hundebesitzer-Details-Toggle (ersetzt inline onclick) document.querySelectorAll('[data-toggle-target]').forEach(function(el) { el.addEventListener('click', function() { var c = document.getElementById(el.dataset.toggleTarget); if (!c) return; c.classList.toggle('open'); var open = c.classList.contains('open'); var openTxt = el.dataset.toggleTextOpen || '▴ Weniger anzeigen'; var closeTxt = el.dataset.toggleTextClose || el.textContent; if (!el.dataset.toggleTextClose) el.dataset.toggleTextClose = closeTxt; el.textContent = open ? openTxt : el.dataset.toggleTextClose; }); }); // Auch ältere App-Links erfassen (Fallback ohne data-stay-in-app) document.querySelectorAll('a[href="/"], a[href^="/#"]').forEach(function(a) { a.addEventListener('click', function() { sessionStorage.setItem('by_stay_in_app', '1'); }); }); // Scroll-Animationen var _observer = new IntersectionObserver(function(entries) { entries.forEach(function(e) { if (e.isIntersecting) { e.target.classList.add('visible'); _observer.unobserve(e.target); } }); }, { threshold: 0.12 }); document.querySelectorAll('.outcome-card, .feature-card, .usp-item, .pricing-card').forEach(function(el) { el.classList.add('fade-up'); _observer.observe(el); }); document.querySelectorAll('.fade-up').forEach(function(el) { _observer.observe(el); }); // Live-Zahlen var fmt = new Intl.NumberFormat('de-DE'); fetch('/api/stats/public') // r.ok prüfen: der SW antwortet offline mit 503+JSON ({detail:…}) → json() wirft nicht .then(function(r) { if (!r.ok) throw new Error('stats ' + r.status); return r.json(); }) .then(function(d) { function set(id, val) { var el = document.getElementById(id); if (el) el.textContent = fmt.format(val); } set('big-users', d.users); set('big-dogs', d.dogs); set('big-km', d.km); set('big-posts', d.forum_posts); set('big-diary', d.diary_entries); set('big-kotbeutel', d.kotbeutel); var heroStats = document.getElementById('hero-stats'); if (!heroStats || !d.users) return; var items = [ { val: d.users, label: 'Hundemenschen' }, { val: d.dogs, label: 'Hunde' }, { val: d.km, label: 'km Gassi-Wege' }, { val: d.diary_entries, label: 'Tagebuch-Einträge' }, { val: d.kotbeutel, label: 'Mülleimer für Kotbeutel'}, ]; items.sort(function(a, b) { return a.val - b.val; }); heroStats.innerHTML = items.map(function(item, i) { return (i > 0 ? '·' : '') + '' + fmt.format(item.val) + ' ' + item.label; }).join(''); heroStats.style.display = 'flex'; }) .catch(function() {}); });