Merge branch 'develop'
|
|
@ -406,7 +406,7 @@ async def serve_media(path: str, request: _Request):
|
|||
raise _HE(404, "Nicht gefunden.")
|
||||
return _media_response(filepath)
|
||||
|
||||
APP_VER = "951" # muss mit APP_VER in app.js übereinstimmen
|
||||
APP_VER = "961" # muss mit APP_VER in app.js übereinstimmen
|
||||
|
||||
@app.get("/.well-known/assetlinks.json")
|
||||
async def assetlinks():
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import time
|
||||
from fastapi import APIRouter, Depends
|
||||
from database import db
|
||||
from auth import get_current_user, get_current_user_optional
|
||||
|
|
@ -19,6 +20,35 @@ _STATS_SQL = """
|
|||
"""
|
||||
|
||||
|
||||
_pub_cache: dict = {"data": None, "ts": 0.0}
|
||||
_PUB_TTL = 300 # 5 Minuten
|
||||
|
||||
|
||||
@router.get("/public")
|
||||
async def public_stats():
|
||||
now = time.time()
|
||||
if _pub_cache["data"] and now - _pub_cache["ts"] < _PUB_TTL:
|
||||
return _pub_cache["data"]
|
||||
with db() as conn:
|
||||
users = conn.execute("SELECT COUNT(*) FROM users").fetchone()[0]
|
||||
dogs = conn.execute("SELECT COUNT(*) FROM dogs").fetchone()[0]
|
||||
km = conn.execute(
|
||||
"SELECT ROUND(COALESCE(SUM(distanz_km),0),0) FROM routes"
|
||||
).fetchone()[0]
|
||||
posts = conn.execute("SELECT COUNT(*) FROM forum_posts").fetchone()[0]
|
||||
diary = conn.execute("SELECT COUNT(*) FROM diary").fetchone()[0]
|
||||
data = {
|
||||
"users": users,
|
||||
"dogs": dogs,
|
||||
"km": int(km or 0),
|
||||
"forum_posts": posts,
|
||||
"diary_entries": diary,
|
||||
}
|
||||
_pub_cache["data"] = data
|
||||
_pub_cache["ts"] = now
|
||||
return data
|
||||
|
||||
|
||||
@router.get("/leaderboard")
|
||||
async def leaderboard(_user=Depends(get_current_user_optional)):
|
||||
with db() as conn:
|
||||
|
|
|
|||
BIN
backend/static/img/landing/alvan-nee.webp
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
backend/static/img/landing/ban-yaro-original.webp
Normal file
|
After Width: | Height: | Size: 174 KiB |
BIN
backend/static/img/landing/baptist-standaert.webp
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
backend/static/img/landing/chewy.webp
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
backend/static/img/landing/eric-ward.webp
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
backend/static/img/landing/nicholas-brownlow.webp
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
backend/static/img/landing/tamas-pap.webp
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
backend/static/img/landing/wade-austin-ellis.webp
Normal file
|
After Width: | Height: | Size: 32 KiB |
|
|
@ -3,7 +3,7 @@
|
|||
Router, State-Management, Navigation, Initialisierung.
|
||||
============================================================ */
|
||||
|
||||
const APP_VER = '951'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
const APP_VER = '961'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
const APP_VERSION = '1.5.1'; // ← semantische Version, wird bei make release gesetzt
|
||||
const IS_STAGING = location.hostname === 'staging.banyaro.app';
|
||||
// Cache-Bust-Parameter nach Update-Reload sofort entfernen
|
||||
|
|
|
|||
|
|
@ -3,6 +3,14 @@
|
|||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="color-scheme" content="light dark">
|
||||
<script>
|
||||
(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); });
|
||||
})();
|
||||
</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, ohne App Store.">
|
||||
<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">
|
||||
|
|
@ -161,6 +169,7 @@
|
|||
--surface: #fff;
|
||||
--border: #e8ddd0;
|
||||
--radius: 12px;
|
||||
color-scheme: light dark;
|
||||
}
|
||||
|
||||
body {
|
||||
|
|
@ -516,6 +525,199 @@
|
|||
}
|
||||
footer a { color: var(--primary); }
|
||||
footer .footer-links { margin-top: 0.75rem; display: flex; gap: 1.5rem; justify-content: center; flex-wrap: wrap; }
|
||||
|
||||
/* Hero Stats */
|
||||
.hero-stats {
|
||||
margin-top: 1.5rem;
|
||||
font-size: 0.88rem;
|
||||
opacity: 0.88;
|
||||
display: flex;
|
||||
gap: 0.6rem;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
.hero-stats strong { font-weight: 800; }
|
||||
.hero-stats .sep { opacity: 0.45; }
|
||||
|
||||
/* Big Stats Band */
|
||||
.stats-band {
|
||||
background: linear-gradient(135deg, #a86e2e 0%, #C4843A 50%, #d4944a 100%);
|
||||
color: white;
|
||||
padding: 2.5rem 0;
|
||||
}
|
||||
.stats-band-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
|
||||
gap: 1.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
.stats-band-item { padding: 0.5rem; }
|
||||
.stats-band-num {
|
||||
font-size: clamp(2rem, 5vw, 2.8rem);
|
||||
font-weight: 900;
|
||||
line-height: 1;
|
||||
letter-spacing: -0.02em;
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
.stats-band-label {
|
||||
font-size: 0.82rem;
|
||||
opacity: 0.82;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Testimonials */
|
||||
.testimonials-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 1.5rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
.testimonial-card {
|
||||
background: white;
|
||||
border-radius: 16px;
|
||||
padding: 1.75rem;
|
||||
box-shadow: 0 2px 16px rgba(0,0,0,.07);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.85rem;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.testimonial-stars { color: #f59e0b; letter-spacing: 2px; font-size: 0.95rem; }
|
||||
.testimonial-quote {
|
||||
font-size: 0.97rem;
|
||||
line-height: 1.7;
|
||||
color: var(--text);
|
||||
flex: 1;
|
||||
}
|
||||
.testimonial-quote::before { content: "„"; font-size: 1.3em; color: var(--primary); line-height: 0; vertical-align: -0.2em; margin-right: 2px; }
|
||||
.testimonial-quote::after { content: """; font-size: 1.3em; color: var(--primary); line-height: 0; vertical-align: -0.2em; margin-left: 2px; }
|
||||
.testimonial-author { font-size: 0.875rem; font-weight: 700; color: var(--text); }
|
||||
.testimonial-dog { font-size: 0.8rem; color: var(--primary); font-weight: 500; margin-top: 0.1rem; }
|
||||
.testimonial-placeholder { opacity: 0.4; font-style: italic; }
|
||||
|
||||
/* Foto-Sections */
|
||||
.photo-credit {
|
||||
position: absolute;
|
||||
bottom: 7px; right: 9px;
|
||||
font-size: 0.62rem;
|
||||
color: rgba(255,255,255,0.8);
|
||||
background: rgba(0,0,0,0.32);
|
||||
padding: 2px 7px;
|
||||
border-radius: 4px;
|
||||
letter-spacing: 0.03em;
|
||||
backdrop-filter: blur(3px);
|
||||
pointer-events: none;
|
||||
}
|
||||
.photo-strip {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4,1fr);
|
||||
gap: 3px;
|
||||
}
|
||||
@media (max-width: 640px) { .photo-strip { grid-template-columns: repeat(2,1fr); } }
|
||||
.photo-strip-item {
|
||||
position: relative;
|
||||
aspect-ratio: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
.photo-strip-item img {
|
||||
width: 100%; height: 100%;
|
||||
object-fit: cover;
|
||||
transition: transform 0.45s ease;
|
||||
display: block;
|
||||
}
|
||||
.photo-strip-item:hover img { transform: scale(1.04); }
|
||||
.moment-split {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
min-height: 420px;
|
||||
}
|
||||
@media (max-width: 700px) {
|
||||
.moment-split { grid-template-columns: 1fr; }
|
||||
.moment-split .moment-photo { aspect-ratio: 4/3; min-height: unset; }
|
||||
}
|
||||
.moment-photo { position: relative; overflow: hidden; }
|
||||
.moment-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
||||
.moment-text {
|
||||
background: linear-gradient(135deg, #C4843A 0%, #d4944a 100%);
|
||||
color: white;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: clamp(2rem,5vw,3.5rem);
|
||||
gap: 1.5rem;
|
||||
}
|
||||
.moment-text blockquote {
|
||||
font-size: clamp(1.3rem,2.5vw,1.9rem);
|
||||
font-weight: 800;
|
||||
line-height: 1.3;
|
||||
margin: 0;
|
||||
}
|
||||
.moment-text p { font-size: 1rem; opacity: 0.88; margin: 0; line-height: 1.65; }
|
||||
|
||||
/* Scroll animations */
|
||||
.fade-up {
|
||||
opacity: 0;
|
||||
transform: translateY(22px);
|
||||
transition: opacity 0.55s ease, transform 0.55s ease;
|
||||
}
|
||||
.fade-up.visible { opacity: 1; transform: none; }
|
||||
|
||||
/* Dark Mode */
|
||||
/* Dark-Mode via JS-Klasse (html.dark) — Fallback für macOS 26 / Brave */
|
||||
html.dark {
|
||||
--bg: #141210;
|
||||
--surface: #1e1a16;
|
||||
--text: #ede8e2;
|
||||
--text-secondary:#a89880;
|
||||
--text-muted: #6b5e50;
|
||||
--border: #2e2620;
|
||||
--primary-light: #3a2510;
|
||||
color-scheme: dark;
|
||||
}
|
||||
/* Dark-Mode via Media Query (Standard-Browser-Fallback) */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: #141210;
|
||||
--surface: #1e1a16;
|
||||
--text: #ede8e2;
|
||||
--text-secondary:#a89880;
|
||||
--text-muted: #6b5e50;
|
||||
--border: #2e2620;
|
||||
--primary-light: #3a2510;
|
||||
color-scheme: dark;
|
||||
}
|
||||
}
|
||||
html.dark body { background: #141210 !important; color: #ede8e2 !important; }
|
||||
html.dark nav { background: #1a1612 !important; border-color: #2e2620 !important; }
|
||||
html.dark nav a { color: #a89880 !important; }
|
||||
html.dark nav .nav-brand { color: #C4843A !important; }
|
||||
html.dark section { background: #141210 !important; }
|
||||
html.dark section:nth-child(even) { background: #1a1612 !important; }
|
||||
html.dark #fuer-beide { background: #1a1612 !important; }
|
||||
html.dark #funktionen { background: #1a1612 !important; }
|
||||
html.dark #welpen { background: #1a1612 !important; }
|
||||
html.dark #stimmen { background: #141210 !important; }
|
||||
html.dark #zuechter { background: #1a1208 !important; }
|
||||
html.dark #warum { background: #141210 !important; }
|
||||
html.dark #vergleich { background: #1a1612 !important; }
|
||||
html.dark #preise { background: #141210 !important; }
|
||||
html.dark #ueber { background: #1a1612 !important; }
|
||||
html.dark .outcome-card { background: #1e1a16 !important; border-color: #2e2620 !important; }
|
||||
html.dark .feature-card { background: #1e1a16 !important; border-color: #2e2620 !important; }
|
||||
html.dark .testimonial-card{ background: #1e1a16 !important; border-color: #2e2620 !important; }
|
||||
html.dark .pricing-card { background: #1e1a16 !important; border-color: #2e2620 !important; }
|
||||
html.dark .pricing-card.featured { border-color: #C4843A !important; }
|
||||
html.dark .audience-card > div { background: #1e1a16 !important; border-color: #2e2620 !important; }
|
||||
html.dark .feature-group-label { background: #3a2510 !important; color: #C4843A !important; }
|
||||
html.dark h2, html.dark h3 { color: #ede8e2 !important; }
|
||||
html.dark p { color: #a89880; }
|
||||
html.dark table { background: #1e1a16 !important; }
|
||||
html.dark th { background: #C4843A !important; }
|
||||
html.dark td { border-color: #2e2620 !important; color: #ede8e2 !important; }
|
||||
html.dark tr:nth-child(even) td { background: #141210 !important; }
|
||||
html.dark footer { background: #0d0b09 !important; }
|
||||
html.dark .section-intro { color: #a89880 !important; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -526,18 +728,25 @@
|
|||
<img src="/icons/icon-180.png" alt="Ban Yaro App Icon">
|
||||
<span class="logo-name">Ban Yaro</span>
|
||||
</div>
|
||||
<h1>Für Hundebesitzer.<br>Für Züchter.<br><em style="font-style:normal;color:#f5c07a">Eine App.</em></h1>
|
||||
<p>Tagebuch, Training und Gesundheit für Hundebesitzer. Stammbaum, Wurfverwaltung und Warteliste für Züchter. Nahtlos verbunden — kostenlos, ohne App Store, Daten in Deutschland.</p>
|
||||
<div class="header-badges">
|
||||
<h1>Weil jeder Moment<br>mit ihm zählt.</h1>
|
||||
<p>Ban Yaro begleitet euch durch jeden gemeinsamen Tag — Tagebuch, Training und Gesundheit für Hundebesitzer, Stammbaum und Wurfverwaltung für Züchter. Eine App. Mit ganzem Herzen.</p>
|
||||
<div style="display:flex;gap:1rem;justify-content:center;flex-wrap:wrap;margin-top:2rem">
|
||||
<a href="/" class="cta-btn" onclick="sessionStorage.setItem('by_stay_in_app','1')">Kostenlos starten</a>
|
||||
<a href="/zuechter" class="cta-btn" style="background:transparent;color:white;border:2px solid rgba(255,255,255,.6)">Ich bin Züchter</a>
|
||||
</div>
|
||||
<div class="header-badges" style="margin-top:1.5rem">
|
||||
<span class="badge">Kostenlos nutzbar</span>
|
||||
<span class="badge">Daten in Deutschland</span>
|
||||
<span class="badge">Kein App Store nötig</span>
|
||||
<span class="badge">Made in Germany</span>
|
||||
<span class="badge">Offline-fähig</span>
|
||||
</div>
|
||||
<div style="display:flex;gap:1rem;justify-content:center;flex-wrap:wrap;margin-top:2rem">
|
||||
<a href="/" class="cta-btn" onclick="sessionStorage.setItem('by_stay_in_app','1')">Ich bin Hundebesitzer</a>
|
||||
<a href="/zuechter" class="cta-btn" style="background:transparent;color:white;border:2px solid rgba(255,255,255,.6)">Ich bin Züchter</a>
|
||||
<div class="hero-stats" id="hero-stats" style="display:none">
|
||||
<strong id="stat-users">…</strong> Hundemenschen
|
||||
<span class="sep">·</span>
|
||||
<strong id="stat-dogs">…</strong> Hunde
|
||||
<span class="sep">·</span>
|
||||
<strong id="stat-km">…</strong> km Gassi-Wege
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
|
@ -595,8 +804,59 @@
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Stats Band -->
|
||||
<section class="stats-band" id="zahlen">
|
||||
<div class="container">
|
||||
<div class="stats-band-grid">
|
||||
<div class="stats-band-item fade-up">
|
||||
<div class="stats-band-num" id="big-users">…</div>
|
||||
<div class="stats-band-label">Hundemenschen</div>
|
||||
</div>
|
||||
<div class="stats-band-item fade-up">
|
||||
<div class="stats-band-num" id="big-dogs">…</div>
|
||||
<div class="stats-band-label">Hunde registriert</div>
|
||||
</div>
|
||||
<div class="stats-band-item fade-up">
|
||||
<div class="stats-band-num" id="big-km">…</div>
|
||||
<div class="stats-band-label">km Gassi-Routen</div>
|
||||
</div>
|
||||
<div class="stats-band-item fade-up">
|
||||
<div class="stats-band-num" id="big-posts">…</div>
|
||||
<div class="stats-band-label">Forum-Beiträge</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Emotionaler Split: Eric Ward -->
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));min-height:420px;overflow:hidden">
|
||||
<div style="position:relative;min-height:300px">
|
||||
<img src="/img/landing/eric-ward.webp" alt="Hundebesitzer umarmt seinen Golden Retriever"
|
||||
loading="lazy"
|
||||
style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block">
|
||||
<span class="photo-credit">© Eric Ward · Unsplash</span>
|
||||
</div>
|
||||
<div style="background:linear-gradient(135deg,#C4843A 0%,#d4944a 100%);color:white;
|
||||
display:flex;flex-direction:column;justify-content:center;
|
||||
padding:clamp(2rem,5vw,3.5rem);gap:1.5rem">
|
||||
<p style="font-size:clamp(1.3rem,2.5vw,1.9rem);font-weight:800;line-height:1.3;margin:0">
|
||||
„Ich kann mir ein Leben ohne ihn nicht mehr vorstellen."
|
||||
</p>
|
||||
<p style="font-size:1rem;opacity:0.88;margin:0;line-height:1.65">
|
||||
Das sagen uns Tausende Hundemenschen täglich. Ban Yaro begleitet diese Liebe — mit Tagebuch, Gesundheit, Training und einer Gemeinschaft die genauso fühlt wie du.
|
||||
</p>
|
||||
<a href="/" class="cta-btn"
|
||||
style="align-self:flex-start;background:white;color:#a86e2e;margin:0;box-shadow:0 4px 20px rgba(0,0,0,.2)"
|
||||
onclick="sessionStorage.setItem('by_stay_in_app','1')">Kostenlos starten</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Demo-Video -->
|
||||
<section id="demo" style="background:#1a1a1a;padding:64px 20px;text-align:center">
|
||||
<section id="demo" style="position:relative;background:#1a1a1a;padding:64px 20px;text-align:center;overflow:hidden">
|
||||
<img src="/img/landing/baptist-standaert.webp" alt=""
|
||||
loading="lazy" aria-hidden="true"
|
||||
style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 20%;opacity:0.15;filter:grayscale(50%)">
|
||||
<span class="photo-credit" style="position:absolute;top:7px;right:9px">© Baptist Standaert · Unsplash</span>
|
||||
<div style="max-width:480px;margin:0 auto">
|
||||
<h2 style="color:white;font-size:clamp(1.3rem,3.5vw,1.8rem);font-weight:800;margin:0 0 12px">
|
||||
Sieh selbst wie es sich anfühlt
|
||||
|
|
@ -759,6 +1019,70 @@
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Foto-Strip -->
|
||||
<section style="padding:0;overflow:hidden">
|
||||
<div style="display:grid;grid-template-columns:repeat(4,1fr);gap:3px">
|
||||
<div style="position:relative;aspect-ratio:1;overflow:hidden">
|
||||
<img src="/img/landing/alvan-nee.webp" alt="Zwei Hunde laufen einen Waldweg entlang" loading="lazy"
|
||||
style="width:100%;height:100%;object-fit:cover;display:block;transition:transform .4s ease">
|
||||
<span class="photo-credit">© Alvan Nee · Unsplash</span>
|
||||
</div>
|
||||
<div style="position:relative;aspect-ratio:1;overflow:hidden">
|
||||
<img src="/img/landing/nicholas-brownlow.webp" alt="Frau gibt ihrem Golden Retriever einen Kuss" loading="lazy"
|
||||
style="width:100%;height:100%;object-fit:cover;display:block;transition:transform .4s ease">
|
||||
<span class="photo-credit">© Nicholas Brownlow · Unsplash</span>
|
||||
</div>
|
||||
<div style="position:relative;aspect-ratio:1;overflow:hidden">
|
||||
<img src="/img/landing/wade-austin-ellis.webp" alt="Frau mit Labrador auf der Wiese" loading="lazy"
|
||||
style="width:100%;height:100%;object-fit:cover;display:block;transition:transform .4s ease">
|
||||
<span class="photo-credit">© Wade Austin Ellis · Unsplash</span>
|
||||
</div>
|
||||
<div style="position:relative;aspect-ratio:1;overflow:hidden">
|
||||
<img src="/img/landing/tamas-pap.webp" alt="Frau lacht während ihr Hund sie abschleckt" loading="lazy"
|
||||
style="width:100%;height:100%;object-fit:cover;display:block;transition:transform .4s ease">
|
||||
<span class="photo-credit">© Tamas Pap · Unsplash</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Testimonials -->
|
||||
<section id="stimmen" style="background:white">
|
||||
<div class="container">
|
||||
<h2>Was Hundemenschen sagen</h2>
|
||||
<p class="section-intro">Echte Menschen. Echte Hunde. Echte Momente.</p>
|
||||
<div class="testimonials-grid">
|
||||
|
||||
<div class="testimonial-card fade-up">
|
||||
<div class="testimonial-stars">★★★★★</div>
|
||||
<p class="testimonial-quote testimonial-placeholder">Hier könnte dein Zitat stehen — schreib uns an hallo@banyaro.app</p>
|
||||
<div>
|
||||
<div class="testimonial-author">Maria K.</div>
|
||||
<div class="testimonial-dog"><svg viewBox="0 0 256 256" style="width:.85rem;height:.85rem;fill:currentColor;vertical-align:middle"><use href="/icons/phosphor.svg#paw-print"></use></svg> Luna · Golden Retriever</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="testimonial-card fade-up">
|
||||
<div class="testimonial-stars">★★★★★</div>
|
||||
<p class="testimonial-quote testimonial-placeholder">Hier könnte dein Zitat stehen — schreib uns an hallo@banyaro.app</p>
|
||||
<div>
|
||||
<div class="testimonial-author">Thomas W.</div>
|
||||
<div class="testimonial-dog"><svg viewBox="0 0 256 256" style="width:.85rem;height:.85rem;fill:currentColor;vertical-align:middle"><use href="/icons/phosphor.svg#paw-print"></use></svg> Max · Labrador</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="testimonial-card fade-up">
|
||||
<div class="testimonial-stars">★★★★★</div>
|
||||
<p class="testimonial-quote testimonial-placeholder">Hier könnte dein Zitat stehen — schreib uns an hallo@banyaro.app</p>
|
||||
<div>
|
||||
<div class="testimonial-author">Sarah M.</div>
|
||||
<div class="testimonial-dog"><svg viewBox="0 0 256 256" style="width:.85rem;height:.85rem;fill:currentColor;vertical-align:middle"><use href="/icons/phosphor.svg#paw-print"></use></svg> Bella · Schäferhund</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Sektion B: Für Züchter -->
|
||||
<section id="zuechter" style="background: #fffbf0;">
|
||||
<div class="container">
|
||||
|
|
@ -802,7 +1126,9 @@
|
|||
<div style="display:flex;align-items:center;justify-content:center;gap:1rem;flex-wrap:wrap;max-width:720px;margin:0 auto">
|
||||
|
||||
<div style="background:rgba(255,255,255,.08);border:1px solid rgba(196,132,58,.3);border-radius:12px;padding:1.25rem 1.5rem;flex:1;min-width:160px;text-align:left">
|
||||
<div style="font-size:1.4rem;margin-bottom:.5rem">🏡</div>
|
||||
<div style="width:2rem;height:2rem;margin-bottom:.5rem">
|
||||
<svg viewBox="0 0 256 256" style="width:100%;height:100%;fill:white"><use href="/icons/phosphor.svg#house-line"></use></svg>
|
||||
</div>
|
||||
<div style="font-weight:700;font-size:.95rem;margin-bottom:.25rem">Züchter</div>
|
||||
<div style="font-size:.82rem;color:rgba(255,255,255,.6)">Legt Wurf an, dokumentiert Welpen, veröffentlicht in der Wurfbörse</div>
|
||||
</div>
|
||||
|
|
@ -810,7 +1136,9 @@
|
|||
<div style="color:rgba(196,132,58,.8);font-size:1.5rem;flex-shrink:0">→</div>
|
||||
|
||||
<div style="background:rgba(255,255,255,.08);border:1px solid rgba(196,132,58,.3);border-radius:12px;padding:1.25rem 1.5rem;flex:1;min-width:160px;text-align:left">
|
||||
<div style="font-size:1.4rem;margin-bottom:.5rem">🔍</div>
|
||||
<div style="width:2rem;height:2rem;margin-bottom:.5rem">
|
||||
<svg viewBox="0 0 256 256" style="width:100%;height:100%;fill:white"><use href="/icons/phosphor.svg#magnifying-glass"></use></svg>
|
||||
</div>
|
||||
<div style="font-weight:700;font-size:.95rem;margin-bottom:.25rem">Käufer</div>
|
||||
<div style="font-size:.82rem;color:rgba(255,255,255,.6)">Findet Wurf in der Wurfbörse, kontaktiert Züchter direkt per Chat</div>
|
||||
</div>
|
||||
|
|
@ -818,7 +1146,9 @@
|
|||
<div style="color:rgba(196,132,58,.8);font-size:1.5rem;flex-shrink:0">→</div>
|
||||
|
||||
<div style="background:rgba(196,132,58,.15);border:1px solid rgba(196,132,58,.5);border-radius:12px;padding:1.25rem 1.5rem;flex:1;min-width:160px;text-align:left">
|
||||
<div style="font-size:1.4rem;margin-bottom:.5rem">🐶</div>
|
||||
<div style="width:2rem;height:2rem;margin-bottom:.5rem">
|
||||
<svg viewBox="0 0 256 256" style="width:100%;height:100%;fill:#f5c07a"><use href="/icons/phosphor.svg#dog"></use></svg>
|
||||
</div>
|
||||
<div style="font-weight:700;font-size:.95rem;margin-bottom:.25rem;color:#f5c07a">Übergabe</div>
|
||||
<div style="font-size:.82rem;color:rgba(255,255,255,.6)">Welpen-Profil mit allem landet direkt in der App des neuen Besitzers</div>
|
||||
</div>
|
||||
|
|
@ -831,8 +1161,14 @@
|
|||
|
||||
<!-- Sektion C: Für Welpenkäufer -->
|
||||
<section id="welpen" style="background: white;">
|
||||
<div style="position:relative;height:280px;overflow:hidden">
|
||||
<img src="/img/landing/chewy.webp" alt="Pärchen mit Hund aus dem Tierheim" loading="lazy"
|
||||
style="width:100%;height:100%;object-fit:cover;object-position:center 40%">
|
||||
<div style="position:absolute;inset:0;background:linear-gradient(to bottom,rgba(0,0,0,.1),rgba(0,0,0,.55))"></div>
|
||||
<span class="photo-credit">© Chewy · Unsplash</span>
|
||||
</div>
|
||||
<div class="container">
|
||||
<h2>Den richtigen Welpen finden. Sicher.</h2>
|
||||
<h2 style="margin-top:2.5rem">Den richtigen Welpen finden. Sicher.</h2>
|
||||
<p class="section-intro">Verifizierte Züchter, transparente Gesundheitsdaten, direkter Kontakt. Kein Kleinanzeigen-Chaos.</p>
|
||||
|
||||
<div class="outcome-grid">
|
||||
|
|
@ -1118,15 +1454,32 @@
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<section id="ueber" style="background:white;padding:5rem 0">
|
||||
<div class="container" style="text-align:center">
|
||||
<h2>Warum „Ban Yaro"?</h2>
|
||||
<p class="section-intro" style="margin:1rem auto 2.5rem">
|
||||
Ban Yaro ist ein Hund. Genauer gesagt: ein Hund aus dem B-Wurf einer Züchterin,
|
||||
die Star Wars liebt und ihre Würfe nach Charakteren dieses Epos benennt.
|
||||
Ban Yaro ist der Namensgeber dieser App — und ein gutes Zeichen, dass hier
|
||||
Hundemenschen für Hundemenschen bauen.
|
||||
<section id="ueber" style="background:white;padding:0">
|
||||
<!-- Ban Yaro persönlich -->
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));overflow:hidden">
|
||||
<div style="position:relative;height:360px;max-height:420px">
|
||||
<img src="/img/landing/ban-yaro-original.webp"
|
||||
alt="Ban Yaro — der echte Hund hinter der App"
|
||||
loading="lazy"
|
||||
style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 30%;display:block">
|
||||
</div>
|
||||
<div style="background:var(--bg,#FAF7F2);padding:clamp(2rem,5vw,3.5rem);display:flex;flex-direction:column;justify-content:center;gap:1rem">
|
||||
<h2 style="margin:0">Warum „Ban Yaro"?</h2>
|
||||
<p style="color:var(--text-secondary,#555);line-height:1.75;margin:0">
|
||||
Ban Yaro ist ein echter Hund — aus dem B-Wurf einer Züchterin die Star Wars liebt
|
||||
und ihre Würfe nach Charakteren des Epos benennt. Er ist der Namensgeber dieser App
|
||||
und lebt in Ebersberg, Bayern.
|
||||
</p>
|
||||
<p style="color:var(--text-secondary,#555);line-height:1.75;margin:0">
|
||||
Ban Yaro wurde von einem Hundemenschen für Hundemenschen gebaut — von René Degelmann,
|
||||
der genau weiß wie es sich anfühlt seinen Hund täglich zu begleiten.
|
||||
</p>
|
||||
<p style="font-size:0.85rem;color:var(--text-muted,#888);margin:0">
|
||||
Ebersberg, Bayern · gegründet 2026 · <a href="mailto:hallo@banyaro.app">hallo@banyaro.app</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container" style="text-align:center;padding-top:3rem;padding-bottom:3rem">
|
||||
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:1.5rem;text-align:left;margin-top:3rem">
|
||||
|
||||
|
|
@ -1164,12 +1517,13 @@
|
|||
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- end container -->
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="container">
|
||||
<p><strong style="color:white">Ban Yaro</strong> — Die deutschsprachige Hunde-Plattform</p>
|
||||
<p style="margin-top:0.5rem">banyaro.app · DSGVO-konform · Hosting in Deutschland · Made with 🐾</p>
|
||||
<p style="margin-top:0.5rem">banyaro.app · DSGVO-konform · Hosting in Deutschland · Made with <svg viewBox="0 0 256 256" style="width:.9rem;height:.9rem;fill:#C4843A;vertical-align:middle;display:inline-block"><use href="/icons/phosphor.svg#paw-print"></use></svg></p>
|
||||
<div class="footer-links">
|
||||
<a href="/#impressum">Impressum</a>
|
||||
<a href="/#datenschutz">Datenschutz</a>
|
||||
|
|
@ -1179,12 +1533,58 @@
|
|||
</footer>
|
||||
|
||||
<script>
|
||||
// Alle Links die zur App führen (/) setzen das Flag damit kein Redirect-Loop entsteht
|
||||
// App-Links: kein Redirect-Loop
|
||||
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 von /api/stats/public
|
||||
var fmt = new Intl.NumberFormat('de-DE');
|
||||
fetch('/api/stats/public')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(d) {
|
||||
var ids = {
|
||||
users: ['stat-users', 'big-users'],
|
||||
dogs: ['stat-dogs', 'big-dogs'],
|
||||
km: ['stat-km', 'big-km'],
|
||||
forum_posts: [null, 'big-posts'],
|
||||
};
|
||||
function set(id, val) {
|
||||
var el = document.getElementById(id);
|
||||
if (el) el.textContent = fmt.format(val);
|
||||
}
|
||||
set('stat-users', d.users);
|
||||
set('stat-dogs', d.dogs);
|
||||
set('stat-km', d.km);
|
||||
set('big-users', d.users);
|
||||
set('big-dogs', d.dogs);
|
||||
set('big-km', d.km);
|
||||
set('big-posts', d.forum_posts);
|
||||
|
||||
var heroStats = document.getElementById('hero-stats');
|
||||
if (heroStats && d.users > 0) heroStats.style.display = 'flex';
|
||||
})
|
||||
.catch(function() {});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
Offline-Cache + Push Notifications + Tile-Cache
|
||||
============================================================ */
|
||||
|
||||
const CACHE_VERSION = 'by-v951';
|
||||
const CACHE_VERSION = 'by-v961';
|
||||
const CACHE_STATIC = `${CACHE_VERSION}-static`;
|
||||
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
|
||||
const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache
|
||||
|
|
|
|||