- "Termin buchen" in der Kopfleiste, im Kontakt und als Buchungs-Fläche mit allen Angeboten - Direkte Buchen-Knöpfe für Einzelcoaching, Gruppenstunden und Stundenplan - G&H-Siegel im Footer, auf Ernährung und bei den Ausbildungen - Datenschutz um die Online-Terminbuchung ergänzt - tools/make_zip.sh baut das Übergabe-Paket Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
561 lines
33 KiB
Python
561 lines
33 KiB
Python
"""Quelle aller Seiten. Inhalte hier ändern, dann:
|
||
|
||
python3 tools/build_pages.py
|
||
"""
|
||
import hashlib, os
|
||
from PIL import Image
|
||
|
||
OUT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||
SITE = "https://schmacko-napf.de"
|
||
|
||
def version(path):
|
||
# Prüfsumme als ?v=… – Browser laden CSS/JS nach jeder Änderung neu statt aus dem Cache
|
||
return hashlib.md5(open(os.path.join(OUT, path), "rb").read()).hexdigest()[:8]
|
||
CSS_V, JS_V = version("assets/site.css"), version("assets/site.js")
|
||
|
||
LOGO = "assets/img/logo.webp"
|
||
CERT = "assets/img/gh-siegel.webp"
|
||
CERT_ALT = "Zertifiziert nach G&H Tierernährung – Gesund gefüttert Heidi Herrmann"
|
||
|
||
# Buchungsportal (PetWorkers) – & als & für HTML-Attribute
|
||
PW = "https://schmacko-napf.petworkers.app/"
|
||
BOOK = {
|
||
"coach": ("Einzelcoaching", PW + "seite.php?name=einzelcoaching&id=11&sysname=coaching"),
|
||
"groups": ("Gruppenstunden", PW + "seite.php?name=gruppenstunden&id=12&sysname=groups"),
|
||
"courses": ("Kurse & Workshops", PW + "index.php?id=13"),
|
||
"food": ("Ernährungsberatung", PW + "seite.php?name=ernaehrungsberatung"),
|
||
"buy": ("Kaufberatung", PW + "seite.php?name=kaufberatung"),
|
||
"cal": ("Stundenplan", PW + "index.php?view=kalender"),
|
||
}
|
||
EXT = ' target="_blank" rel="noopener"'
|
||
BARF = "assets/img/barf-teller.webp"
|
||
|
||
def img(name, alt, sizes="(max-width: 980px) 100vw, 55vw", lazy=True):
|
||
"""Foto aus assets/img mit kleiner (-900) und großer Variante."""
|
||
big, small = f"assets/img/{name}.webp", f"assets/img/{name}-900.webp"
|
||
wb = Image.open(os.path.join(OUT, big)).width
|
||
ws = Image.open(os.path.join(OUT, small)).width
|
||
load = ' loading="lazy"' if lazy else ""
|
||
return f'<img src="{big}" srcset="{small} {ws}w, {big} {wb}w" sizes="{sizes}" alt="{alt}"{load}>'
|
||
|
||
PHONE, PHONE_HREF = "+49 176 569 329 42", "tel:+4917656932942"
|
||
MAIL = "info@schmacko-napf.de"
|
||
WA = "https://wa.me/4917656932942"
|
||
|
||
def ic(d, sw="1.8"):
|
||
return f'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="{sw}" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">{d}</svg>'
|
||
I = {
|
||
"arrow": ic('<path d="M5 12h14M13 6l6 6-6 6"/>', "2"),
|
||
"down": ic('<path d="M12 5v14M6 13l6 6 6-6"/>', "2"),
|
||
"menu": ic('<path d="M4 7h16M4 12h16M4 17h16"/>', "2"),
|
||
"phone": ic('<path d="M5 4h4l2 5-2.5 1.5a11 11 0 0 0 5 5L15 13l5 2v4a2 2 0 0 1-2 2A16 16 0 0 1 3 6a2 2 0 0 1 2-2"/>'),
|
||
"mail": ic('<rect x="3" y="5" width="18" height="14" rx="2.5"/><path d="m4 7 8 6 8-6"/>'),
|
||
"chat": ic('<path d="M20 11.5a8 8 0 0 1-11.8 7L4 20l1.5-4A8 8 0 1 1 20 11.5z"/>'),
|
||
"bowl": ic('<path d="M3 12h18a9 9 0 0 1-18 0z"/><path d="M8 8c0-2 2-2 2-4M13 8c0-2 2-2 2-4"/>'),
|
||
"bone": ic('<path d="M8 8 16 16M6.5 4.5a2 2 0 0 0-2 2 2 2 0 1 0 3 2.5l7.5 7.5a2 2 0 1 0 2.5 3 2 2 0 0 0 2-2 2 2 0 1 0-2.5-3L9.5 7a2 2 0 0 0-3-2.5z"/>'),
|
||
"leash": ic('<circle cx="17" cy="7" r="3"/><path d="M15 9.5 6 19M4 17l3 3"/>'),
|
||
"car": ic('<path d="M5 16V11l2-5h10l2 5v5"/><path d="M3 16h18v3H3z"/><circle cx="7.5" cy="13" r="1"/><circle cx="16.5" cy="13" r="1"/>'),
|
||
"shield": ic('<path d="M12 3 5 6v6c0 4.5 3 7.5 7 9 4-1.5 7-4.5 7-9V6z"/><path d="m9 12 2 2 4-4"/>'),
|
||
"wind": ic('<path d="M3 9h11a3 3 0 1 0-3-3M3 15h15a3 3 0 1 1-3 3M3 12h8"/>'),
|
||
"ext": ic('<path d="M7 17 17 7M9 7h8v8"/>', "2"),
|
||
"cal": ic('<rect x="3.5" y="5" width="17" height="15" rx="2.5"/><path d="M3.5 10h17M8 3v4M16 3v4"/>'),
|
||
}
|
||
ARROW_BADGE = f'<span class="panel-arrow">{I["arrow"]}</span>'
|
||
|
||
NAV = [("hundeschule.html", "Hundetraining"), ("ernaehrung.html", "Ernährung"), ("shop.html", "Shop"),
|
||
("transportboxen.html", "Transportboxen"), ("ueber-mich.html", "Über mich"), ("index.html#kontakt", "Kontakt")]
|
||
|
||
def head(title, desc, path, robots=""):
|
||
url = f"{SITE}/{'' if path == 'index.html' else path}"
|
||
meta_robots = f'\n <meta name="robots" content="{robots}">' if robots else ""
|
||
return f'''<!doctype html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>{title}</title>
|
||
<meta name="description" content="{desc}">{meta_robots}
|
||
<link rel="canonical" href="{url}">
|
||
<meta name="theme-color" content="#fcfaf4">
|
||
<meta property="og:type" content="website">
|
||
<meta property="og:locale" content="de_DE">
|
||
<meta property="og:site_name" content="Schmacko Napf & Hundetraining by Katha">
|
||
<meta property="og:title" content="{title}">
|
||
<meta property="og:description" content="{desc}">
|
||
<meta property="og:url" content="{url}">
|
||
<meta property="og:image" content="{SITE}/assets/img/vorschau.jpg">
|
||
<link rel="icon" href="assets/favicon.svg" type="image/svg+xml">
|
||
<link rel="apple-touch-icon" href="apple-touch-icon.png">
|
||
<link rel="preload" href="assets/fonts/questrial-latin.woff2" as="font" type="font/woff2" crossorigin>
|
||
<link rel="stylesheet" href="assets/site.css?v={CSS_V}">
|
||
</head>
|
||
'''
|
||
|
||
def header(current=None):
|
||
cur = ' aria-current="page"'
|
||
links = "\n".join(f' <a href="{h}"{cur if h == current else ""}>{t}</a>' for h, t in NAV)
|
||
return f''' <a class="skip" href="#inhalt">Zum Inhalt springen</a>
|
||
<header class="site-header">
|
||
<div class="header-inner">
|
||
<a class="brand" href="index.html" aria-label="Schmacko Napf – Startseite"><img src="{LOGO}" alt="Schmacko Napf & Hundetraining by Katha" width="68" height="68"></a>
|
||
<nav class="nav" aria-label="Hauptmenü">
|
||
{links}
|
||
</nav>
|
||
<a class="book-btn" href="{PW}"{EXT}>{I["cal"]}<span class="book-long">Termin buchen</span><span class="book-short" aria-hidden="true">Buchen</span></a>
|
||
<button class="burger" type="button" aria-label="Menü öffnen" aria-expanded="false">{I["menu"]}</button>
|
||
</div>
|
||
</header>
|
||
'''
|
||
|
||
def booking(keys, title="Termin buchen.", text="Freie Termine, Kurse und der Stundenplan – direkt in meinem Buchungsportal."):
|
||
links = "\n".join(f' <a href="{BOOK[k][1]}"{EXT}><span>{BOOK[k][0]}</span>{I["ext"]}</a>' for k in keys)
|
||
return f''' <div class="panel panel--sage panel--auto booking reveal" id="buchen">
|
||
<div class="booking-head">
|
||
<span class="kicker">Online buchen</span>
|
||
<h2 class="display">{title}</h2>
|
||
<p class="big">{text}</p>
|
||
</div>
|
||
<div class="book-links">
|
||
{links}
|
||
</div>
|
||
</div>
|
||
|
||
'''
|
||
|
||
def contact(photo="hund-wald", alt="Schwarze Schäferhündin steht aufmerksam im Wald"):
|
||
go = f'<span>{I["arrow"]}</span>'
|
||
return f''' <div class="row row--wide" id="kontakt">
|
||
<div class="panel panel--ink reveal">
|
||
<span class="kicker">Kontakt</span>
|
||
<h2 class="display">Lass uns<br>sprechen.</h2>
|
||
<div class="contact-links">
|
||
<a class="contact-book" href="{PW}"{EXT}>{I["cal"]}<span>Termin online buchen</span>{go}</a>
|
||
<a href="{WA}" target="_blank" rel="noopener">{I["chat"]}<span>WhatsApp</span>{go}</a>
|
||
<a href="{PHONE_HREF}">{I["phone"]}<span>{PHONE}</span>{go}</a>
|
||
<a href="mailto:{MAIL}">{I["mail"]}<span>{MAIL}</span>{go}</a>
|
||
</div>
|
||
</div>
|
||
<div class="panel panel--photo plain reveal d1">{img(photo, alt, "(max-width: 980px) 100vw, 45vw")}</div>
|
||
</div>
|
||
'''
|
||
|
||
def footer():
|
||
return f''' <footer class="site-footer">
|
||
<div class="footer-brand">
|
||
<a class="footer-logo" href="index.html"><img src="{LOGO}" alt="Schmacko Napf & Hundetraining by Katha" width="88" height="88" loading="lazy"></a>
|
||
<span>Ernährung, Gesundheit und Training –<br>mit Herz und Verstand.</span>
|
||
<img class="footer-cert" src="{CERT}" alt="{CERT_ALT}" width="480" height="329" loading="lazy">
|
||
</div>
|
||
<nav class="footer-links" aria-label="Footer">
|
||
<a href="hundeschule.html">Hundetraining</a>
|
||
<a href="ernaehrung.html">Ernährung</a>
|
||
<a href="shop.html">Shop</a>
|
||
<a href="transportboxen.html">Transportboxen</a>
|
||
<a href="ueber-mich.html">Über mich</a>
|
||
<a href="impressum.html">Impressum</a>
|
||
<a href="datenschutz.html">Datenschutz</a>
|
||
</nav>
|
||
<div class="footer-meta"><span>© 2026 Schmacko Napf & Hundetraining by Katha</span><span>Fotos: Steffi Biller, KK-Fotografie · Unsplash</span></div>
|
||
</footer>
|
||
</main>
|
||
<script src="assets/site.js?v={JS_V}"></script>
|
||
</body>
|
||
</html>
|
||
'''
|
||
|
||
def page_hero(photo, kicker, title, text, alt):
|
||
return f''' <section class="panel panel--photo page-hero">
|
||
{img(photo, alt, "100vw", lazy=False)}
|
||
<span class="kicker">{kicker}</span>
|
||
<h1>{title}</h1>
|
||
<p class="big">{text}</p>
|
||
</section>
|
||
'''
|
||
|
||
def page(name, title, desc, current, body, robots=""):
|
||
write(name, head(title, desc, name, robots) + "<body>\n" + header(current) + ' <main class="mosaic" id="inhalt">\n' + body + footer())
|
||
|
||
def write(name, html):
|
||
open(os.path.join(OUT, name), "w").write(html)
|
||
|
||
PAGES = [] # für die Sitemap
|
||
|
||
# ================================================================ Startseite
|
||
tiles = [
|
||
("hundeschule.html", "Hundeschule", "", "katha-abendlicht", "Katha mit ihrem Hund auf einer Wiese im Abendlicht"),
|
||
("ernaehrung.html", "Ernährungsberatung", "", "futternapf", "Hund schnuppert an einem Napf mit Trockenfutter"),
|
||
("shop.html", "Shop", "", "laden", "Hund in einem Laden mit Hundezubehör"),
|
||
("transportboxen.html", "Transportboxen", "Maßanfertigung fürs Auto", "kofferraum", "Hund sitzt im offenen Kofferraum hinter einem Trenngitter"),
|
||
]
|
||
tile_html = ""
|
||
for href, name, sub, photo, alt in tiles:
|
||
small = f"<small>{sub}</small>" if sub else ""
|
||
tile_html += f''' <a class="tile" href="{href}">
|
||
{img(photo, alt, "(max-width: 767px) 100vw, 50vw", lazy=False)}
|
||
<span class="tile-foot">
|
||
<span class="tile-label">{name}{small}</span>
|
||
<span class="tile-arrow">{I["arrow"]}</span>
|
||
</span>
|
||
</a>
|
||
'''
|
||
|
||
index = head("Schmacko Napf & Hundetraining by Katha",
|
||
"Hundetraining, Ernährungs- und Gesundheitsberatung, Shop und maßgefertigte Transportboxen – Schmacko Napf by Katha in Wörth a.d. Isar.",
|
||
"index.html") + '<body class="is-home">\n' + header() + f''' <section class="hero">
|
||
<nav class="tiles" aria-label="Bereiche">
|
||
<svg class="seal-joint" aria-hidden="true"><path/></svg>
|
||
<h1 class="seal"><img src="{LOGO}" alt="Schmacko Napf & Hundetraining by Katha" width="300" height="300"></h1>
|
||
{tile_html} <a class="scroll-hint" href="#inhalt" aria-label="Weiter nach unten">{I["down"]}</a>
|
||
</nav>
|
||
</section>
|
||
|
||
<main class="mosaic" id="inhalt">
|
||
<div class="row row--wide-r">
|
||
<a class="panel panel--cream reveal" href="ueber-mich.html">
|
||
<span class="panel-arrow panel-arrow--ink">{I["arrow"]}</span>
|
||
<span class="kicker">Über mich</span>
|
||
<h2 class="display">Hallo,<br>ich bin Katha.</h2>
|
||
<p class="big">Hundetrainerin und Ernährungsberaterin – mit Herz und Verstand. Für beide Seiten der Leine.</p>
|
||
<div class="facts">
|
||
<span class="fact">§ 11 TierSchG zertifiziert</span>
|
||
<span class="fact">Ernährungs- & Gesundheitsberaterin</span>
|
||
</div>
|
||
</a>
|
||
<div class="panel panel--photo plain reveal d1">{img("katha-heide", "Katha sitzt mit ihrer Schäferhündin im Grünen")}</div>
|
||
</div>
|
||
|
||
<a class="panel panel--photo tall reveal" href="hundeschule.html">
|
||
{img("hund-rennt", "Schwarzer Schäferhund rennt freudig über einen Feldweg", "100vw")}
|
||
{ARROW_BADGE}
|
||
<span class="kicker">Hundetraining</span>
|
||
<h2 class="display">Entspannt durch<br>den Alltag.</h2>
|
||
<p class="big">Einzeltraining, Hausbesuch und Außentraining in der Gruppe.</p>
|
||
<div class="facts">
|
||
<span class="fact">Einzeltraining 60 € / Std.</span>
|
||
<span class="fact">Gruppe 18 €</span>
|
||
<span class="fact">10er-Karte 165 €</span>
|
||
</div>
|
||
</a>
|
||
|
||
<div class="row">
|
||
<div class="panel panel--sage plate-panel reveal"><img src="{BARF}" alt="Teller mit frischem Fleisch, Gemüse und Obst für die Rohfütterung" width="900" height="900" loading="lazy"></div>
|
||
<a class="panel panel--cream reveal d1" href="ernaehrung.html">
|
||
<span class="panel-arrow panel-arrow--ink">{I["arrow"]}</span>
|
||
<span class="kicker">Ernährungsberatung</span>
|
||
<h2 class="display">Gesund<br>gefüttert.</h2>
|
||
<p class="big">Individuelle Futterpläne – für jedes Alter, auch bei Magen-Darm- oder Pankreas-Problemen.</p>
|
||
<div class="facts"><span class="fact">BARF</span><span class="fact">Koch-BARF</span><span class="fact">Nass- & Trockenfutter</span></div>
|
||
</a>
|
||
</div>
|
||
|
||
<div class="panel panel--plain panel--mid panel--center reveal">
|
||
<p class="statement">„Futter ist mehr als nur Nahrung – es ist Fürsorge in Napfform.“</p>
|
||
<span class="statement-by">— Katha</span>
|
||
</div>
|
||
|
||
<div class="panel panel--ink panel--auto reveal">
|
||
<span class="kicker">Meine Philosophie · die 5 Säulen</span>
|
||
<ul class="words">
|
||
<li><small>01</small>Respekt<span>Den Hund als eigenständiges Wesen ernst nehmen.</span></li>
|
||
<li><small>02</small>Ehrlichkeit<span>Klare Signale schaffen Vertrauen.</span></li>
|
||
<li><small>03</small>Geduld<span>Jeder Hund lernt in seinem Tempo.</span></li>
|
||
<li><small>04</small>Konsequenz<span>Klare Regeln – fair und ohne Druck.</span></li>
|
||
<li><small>05</small>Verständnis<span>Bedürfnisse und Gefühle verstehen.</span></li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="row">
|
||
<a class="panel panel--photo reveal" href="shop.html">
|
||
{img("laden", "Hund in einem Laden mit Hundezubehör", "(max-width: 980px) 100vw, 50vw")}
|
||
{ARROW_BADGE}
|
||
<span class="kicker">Shop</span>
|
||
<h2 class="title">Futter, Snacks<br>& Zubehör.</h2>
|
||
</a>
|
||
<a class="panel panel--photo reveal d1" href="transportboxen.html">
|
||
{img("kofferraum", "Hund sitzt im Kofferraum hinter einem Trenngitter", "(max-width: 980px) 100vw, 50vw")}
|
||
{ARROW_BADGE}
|
||
<span class="kicker">Maßanfertigung</span>
|
||
<h2 class="title">Transportboxen<br>fürs Auto.</h2>
|
||
</a>
|
||
</div>
|
||
|
||
{booking(["coach", "groups", "courses", "food", "buy", "cal"])}{contact()}''' + footer()
|
||
write("index.html", index)
|
||
PAGES.append("index.html")
|
||
|
||
# ================================================================ Hundetraining
|
||
page("hundeschule.html", "Hundetraining – Schmacko Napf",
|
||
"Einzeltraining, Hausbesuche und Gruppentraining im Außenbereich mit Katha, zertifizierte Hundetrainerin nach § 11 TierSchG.",
|
||
"hundeschule.html",
|
||
page_hero("katha-abendlicht", "Hundetraining", "Für beide Seiten<br>der Leine.",
|
||
"Vertrauen, klare Kommunikation und Training, das im Alltag funktioniert.",
|
||
"Katha mit ihrem Hund auf einer Wiese im Abendlicht") + f'''
|
||
<div class="row row--wide-r">
|
||
<div class="panel panel--cream reveal">
|
||
<span class="kicker">Einzeltraining & Hausbesuch</span>
|
||
<h2 class="title">Individuell.<br>Bei dir zu Hause.</h2>
|
||
<p class="big">Für Grundgehorsam, Unsicherheit, Leinenführigkeit oder einen neuen Hund im Haus.</p>
|
||
<div class="price-big"><strong>60 €</strong><span>pro Stunde · nach dem Erstgespräch (120 €, ca. 2 Std.)</span></div>
|
||
<div class="btn-row"><a class="btn btn--ink" href="{BOOK['coach'][1]}"{EXT}>Einzelcoaching buchen {I["ext"]}</a></div>
|
||
</div>
|
||
<div class="panel panel--photo plain reveal d1">{img("hund-wald", "Schwarze Schäferhündin steht aufmerksam im Wald")}</div>
|
||
</div>
|
||
|
||
<div class="row row--wide">
|
||
<div class="panel panel--photo plain reveal">{img("hund-rennt", "Schwarzer Schäferhund rennt über einen Feldweg")}</div>
|
||
<div class="panel panel--ink reveal d1">
|
||
<span class="kicker">Gruppe & Außentraining</span>
|
||
<h2 class="title">Training da, wo<br>das Leben ist.</h2>
|
||
<p class="big">In der Stadt, im Grünen, in Geschäften – mit max. 6 Mensch-Hund-Teams.</p>
|
||
<div class="price-big"><strong>18 €</strong><span>pro Mensch-Hund-Team</span></div>
|
||
<div class="btn-row">
|
||
<a class="btn btn--sage" href="{BOOK['groups'][1]}"{EXT}>Gruppenstunde buchen {I["ext"]}</a>
|
||
<a class="btn btn--line" href="{BOOK['cal'][1]}"{EXT}>Stundenplan {I["ext"]}</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel panel--ink panel--auto reveal">
|
||
<span class="kicker">Die 5 Säulen</span>
|
||
<ul class="words">
|
||
<li><small>01</small>Respekt<span>Hunde wollen ernst genommen werden.</span></li>
|
||
<li><small>02</small>Ehrlichkeit<span>Hunde lesen unsere Körpersprache sofort.</span></li>
|
||
<li><small>03</small>Geduld<span>Lernen braucht Zeit und Wiederholung.</span></li>
|
||
<li><small>04</small>Konsequenz<span>Klare Regeln, ganz ohne Gewalt.</span></li>
|
||
<li><small>05</small>Verständnis<span>Realistische Erwartungen an jeden Hund.</span></li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="panel panel--cream panel--auto reveal">
|
||
<span class="kicker">Preise</span>
|
||
<h2 class="title">Fair und klar.</h2>
|
||
<div class="price-rows">
|
||
<div><span>Erstgespräch Einzeltraining<small>ca. 2 Stunden · zzgl. 0,30 € / km</small></span><strong>120 €</strong></div>
|
||
<div><span>Einzeltraining<small>pro Stunde · zzgl. 0,30 € / km</small></span><strong>60 €</strong></div>
|
||
<div><span>Gruppentraining<small>pro Mensch-Hund-Team · max. 2 Hunde pro Halter</small></span><strong>18 €</strong></div>
|
||
<div><span>10er-Karte<small>Gruppe & Einzel frei kombinierbar</small></span><strong>165 €</strong></div>
|
||
</div>
|
||
</div>
|
||
|
||
{booking(["coach", "groups", "courses", "buy", "cal"])}{contact("katha-heide", "Katha sitzt mit ihrer Schäferhündin im Grünen")}''')
|
||
PAGES.append("hundeschule.html")
|
||
|
||
# ================================================================ Ernährung
|
||
page("ernaehrung.html", "Ernährungsberatung – Schmacko Napf",
|
||
"Individuelle Futterpläne und Gesundheitsberatung für Hunde jeden Alters – BARF, Koch-BARF, Nass- und Trockenfutter.",
|
||
"ernaehrung.html",
|
||
page_hero("futternapf", "Ernährungs- & Gesundheitsberatung", "Fürsorge<br>in Napfform.",
|
||
"Individuelle Futterpläne – gesund, sensibel oder mit Diagnose.",
|
||
"Hund schnuppert an einem Napf mit Trockenfutter") + f'''
|
||
<div class="row">
|
||
<div class="panel panel--cream reveal">
|
||
<span class="kicker">Kennst du das?</span>
|
||
<h2 class="title">Jeder sagt<br>etwas anderes.</h2>
|
||
<p class="big">Ich bringe Klarheit in die Futter-Frage – und erstelle einen Plan, der zu deinem Hund passt.</p>
|
||
<div class="facts"><span class="fact">BARF</span><span class="fact">Teil-BARF</span><span class="fact">Koch-BARF</span><span class="fact">Nassfutter</span><span class="fact">Trockenfutter</span></div>
|
||
<img class="cert" src="{CERT}" alt="{CERT_ALT}" width="480" height="329" loading="lazy">
|
||
</div>
|
||
<div class="panel panel--sage plate-panel reveal d1"><img src="{BARF}" alt="Teller mit frischem Fleisch, Gemüse und Obst" width="900" height="900" loading="lazy"></div>
|
||
</div>
|
||
|
||
<div class="panel panel--ink panel--auto reveal">
|
||
<span class="kicker">Ablauf</span>
|
||
<h2 class="title">So starten wir.</h2>
|
||
<ol class="steps">
|
||
<li><b>01</b><strong>Erstgespräch</strong><span>Vor Ort, am Telefon oder online.</span></li>
|
||
<li><b>02</b><strong>Futterplan</strong><span>Genau auf deinen Hund abgestimmt.</span></li>
|
||
<li><b>03</b><strong>Fragen klären</strong><span>Nach 3 Tagen gehen wir alles durch.</span></li>
|
||
<li><b>04</b><strong>Nachbesprechung</strong><span>Nach 4 Wochen schauen wir gemeinsam drauf.</span></li>
|
||
</ol>
|
||
</div>
|
||
|
||
<div class="row row--3">
|
||
<div class="panel panel--cream panel--mid reveal">
|
||
<span class="kicker">Rationsprüfung</span>
|
||
<h2 class="title">Passt das<br>Futter?</h2>
|
||
<div class="price-big"><strong>kostenlos</strong></div>
|
||
</div>
|
||
<div class="panel panel--sage panel--mid reveal d1">
|
||
<span class="kicker">Erstgespräch</span>
|
||
<h2 class="title">Kennen­lernen</h2>
|
||
<div class="price-big"><strong>ab 45 €</strong><span>ca. 60 Minuten</span></div>
|
||
</div>
|
||
<div class="panel panel--ink panel--mid reveal d2">
|
||
<span class="kicker">Futterplan</span>
|
||
<h2 class="title">Dein<br>Plan</h2>
|
||
<div class="price-big"><strong>ab 75 €</strong><span>inkl. Folgegespräch nach 4 Wochen</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
{booking(["food"], "Beratung buchen.", "Erstgespräch und Futterplan direkt online buchen – vor Ort, am Telefon oder online.")}{contact()}''')
|
||
PAGES.append("ernaehrung.html")
|
||
|
||
# ================================================================ Shop
|
||
page("shop.html", "Shop – Schmacko Napf", "Ausgewähltes Futter, Snacks und Zubehör für deinen Hund.", "shop.html",
|
||
page_hero("laden", "Shop", "Ausgewählt<br>mit Herz.",
|
||
"Futter, Snacks und Zubehör, hinter denen ich stehe.",
|
||
"Hund in einem Laden mit Hundezubehör") + f'''
|
||
<div class="row row--3">
|
||
<div class="panel panel--cream panel--mid reveal"><div class="panel-icon">{I["bowl"]}</div><h2 class="title">Futter</h2><p class="big">Passend zu deinem Futterplan.</p></div>
|
||
<div class="panel panel--sage panel--mid reveal d1"><div class="panel-icon">{I["bone"]}</div><h2 class="title">Snacks</h2><p class="big">Natürlich – fürs Training und zum Belohnen.</p></div>
|
||
<div class="panel panel--ink panel--mid reveal d2"><div class="panel-icon">{I["leash"]}</div><h2 class="title">Zubehör</h2><p class="big">Robust und durchdacht für den Alltag.</p></div>
|
||
</div>
|
||
|
||
<div class="panel panel--cream panel--mid panel--center reveal">
|
||
<p class="statement">Der Online-Shop ist bald da.<br>Bis dahin: schreib mir einfach.</p>
|
||
</div>
|
||
|
||
{contact()}''')
|
||
PAGES.append("shop.html")
|
||
|
||
# ================================================================ Transportboxen
|
||
page("transportboxen.html", "Transportboxen nach Maß – Schmacko Napf",
|
||
"Maßgefertigte Hunde-Transportboxen fürs Auto – passgenau für Fahrzeug und Hund.", "transportboxen.html",
|
||
page_hero("kofferraum", "Maßanfertigung", "Transportboxen<br>fürs Auto.",
|
||
"Passgenau für dein Fahrzeug und deinen Hund.",
|
||
"Hund sitzt im offenen Kofferraum hinter einem Trenngitter") + f'''
|
||
<div class="row row--3">
|
||
<div class="panel panel--cream panel--mid reveal"><div class="panel-icon">{I["car"]}</div><h2 class="title">Passgenau</h2><p class="big">Exakt für deinen Kofferraum gebaut.</p></div>
|
||
<div class="panel panel--sage panel--mid reveal d1"><div class="panel-icon">{I["shield"]}</div><h2 class="title">Sicher</h2><p class="big">Stabil – für jede Fahrt.</p></div>
|
||
<div class="panel panel--ink panel--mid reveal d2"><div class="panel-icon">{I["wind"]}</div><h2 class="title">Bequem</h2><p class="big">Luftig und mit genug Platz.</p></div>
|
||
</div>
|
||
|
||
<div class="panel panel--ink panel--auto reveal">
|
||
<span class="kicker">Ablauf</span>
|
||
<h2 class="title">In 4 Schritten zur eigenen Box.</h2>
|
||
<ol class="steps">
|
||
<li><b>01</b><strong>Beratung</strong><span>Auto, Hund und Wünsche.</span></li>
|
||
<li><b>02</b><strong>Ausmessen</strong><span>Kofferraum und Hund genau vermessen.</span></li>
|
||
<li><b>03</b><strong>Fertigung</strong><span>Deine Box entsteht nach Maß.</span></li>
|
||
<li><b>04</b><strong>Übergabe</strong><span>Einbau – und los geht’s.</span></li>
|
||
</ol>
|
||
</div>
|
||
|
||
{contact()}''')
|
||
PAGES.append("transportboxen.html")
|
||
|
||
# ================================================================ Über mich
|
||
page("ueber-mich.html", "Über mich – Schmacko Napf",
|
||
"Katha – zertifizierte Hundetrainerin nach § 11 TierSchG sowie Hunde-Ernährungs- und Gesundheitsberaterin. Ausbildungen und Weiterbildungen.",
|
||
"ueber-mich.html",
|
||
page_hero("katha-heide", "Über mich", "Hallo,<br>ich bin Katha.",
|
||
"Mein Herz gehört den Tieren – an meiner Seite meine Holländische Schäferhündin Elina.",
|
||
"Katha sitzt mit ihrer Schäferhündin im Grünen") + f'''
|
||
<div class="row row--wide-r">
|
||
<div class="panel panel--cream reveal">
|
||
<span class="kicker">Warum ich das mache</span>
|
||
<h2 class="title">Tiere sind die<br>ehrlichsten Wesen.</h2>
|
||
<p class="big">Und trotzdem werden sie oft missverstanden. Ich möchte meine Erfahrung teilen und ihre Welt ein Stück besser machen.</p>
|
||
</div>
|
||
<div class="panel panel--photo plain reveal d1">{img("hund-wald", "Schwarze Schäferhündin steht aufmerksam im Wald")}</div>
|
||
</div>
|
||
|
||
<div class="row row--wide">
|
||
<div class="panel panel--photo plain reveal">{img("hund-rennt", "Schwarzer Schäferhund rennt über einen Feldweg")}</div>
|
||
<div class="panel panel--sage reveal d1">
|
||
<span class="kicker">Wie alles begann</span>
|
||
<h2 class="title">Mit der Frage nach<br>dem richtigen Futter.</h2>
|
||
<p class="big">Für meine eigene Hündin suchte ich die beste Ernährung – daraus wurde eine Leidenschaft und schließlich mein Beruf.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel panel--ink panel--auto reveal">
|
||
<div class="quals-head">
|
||
<span class="kicker">Ausbildungen</span>
|
||
<img class="cert" src="{CERT}" alt="{CERT_ALT}" width="480" height="329" loading="lazy">
|
||
</div>
|
||
<ul class="quals">
|
||
<li><small>2021 – 2023</small><strong>Hundetrainerin</strong><span>Diane Bartlog, Hundeschule Mengkofen</span></li>
|
||
<li><small>2022 – 2023</small><strong>Hunde-Ernährungsberaterin</strong><span>Heidi Herrmann, G&H Tierernährung</span></li>
|
||
<li><small>2024</small><strong>Hunde-Gesundheitsberaterin</strong><span>G&H Tierernährung</span></li>
|
||
<li><small>Okt. 2024</small><strong>Erlaubnis nach § 11 TierSchG</strong><span>Veterinäramt Landshut</span></li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="panel panel--cream panel--auto reveal">
|
||
<span class="kicker">Weiterbildungen</span>
|
||
<ul class="list-big">
|
||
<li><small>2025</small>Webinar „Pankreas – ein Drüsenorgan mit vielen Aufgaben“</li>
|
||
<li><small>2025</small>Roundtable der BIG FIVE – Problemverhalten richtig einschätzen</li>
|
||
<li><small>2024</small>Workshop „Einschätzen von 8 Malinois“</li>
|
||
<li><small>2024</small>Workshop „Arbeiten mit schwierigen Hunden & Selbstschutz“</li>
|
||
<li><small>2023</small>Blutbilder verstehen · Äußere Anzeichen – innere Organe</li>
|
||
<li><small>2023</small>Blickschulung – Hunde ganzheitlich betrachtet</li>
|
||
<li><small>2023</small>Zusatzqualifikation Katzen-Ernährungsberaterin</li>
|
||
<li><small>2021</small>D.O.Q.-Test 2.0 (Hundeführerschein)</li>
|
||
</ul>
|
||
</div>
|
||
|
||
{contact("katha-abendlicht", "Katha mit ihrem Hund auf einer Wiese im Abendlicht")}''')
|
||
PAGES.append("ueber-mich.html")
|
||
|
||
# ================================================================ Impressum
|
||
page("impressum.html", "Impressum – Schmacko Napf", "Impressum von Schmacko Napf & Hundetraining by Katha.", None, f''' <div class="panel panel--cream panel--auto">
|
||
<span class="kicker">Rechtliches</span>
|
||
<h1 class="display">Impressum</h1>
|
||
<div class="legal">
|
||
<p><b>Angaben gemäß § 5 DDG</b>Katharina Schulz<br>Schmacko Napf & Hundetraining by Katha<br>Seewiese 19<br>84109 Wörth a.d. Isar</p>
|
||
<p><b>Kontakt</b>Telefon: <a href="{PHONE_HREF}">{PHONE}</a><br>E-Mail: <a href="mailto:{MAIL}">{MAIL}</a></p>
|
||
<p><b>Erlaubnis und Aufsichtsbehörde</b>Erlaubnis zur gewerbsmäßigen Ausbildung von Hunden für Dritte nach § 11 Abs. 1 Nr. 8 f TierSchG, erteilt im Oktober 2024 durch das Veterinäramt Landshut.</p>
|
||
<p><b>Verantwortlich für den Inhalt nach § 18 Abs. 2 MStV</b>Katharina Schulz, Anschrift wie oben</p>
|
||
<p><b>Verbraucherstreitbeilegung</b>Ich bin nicht bereit und nicht verpflichtet, an Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teilzunehmen.</p>
|
||
<p><b>Bildnachweis</b>Fotos von Katha und ihren Hunden: Steffi Biller, KK-Fotografie. Weitere Bilder: Unsplash.</p>
|
||
</div>
|
||
</div>
|
||
''', robots="noindex")
|
||
PAGES.append("impressum.html")
|
||
|
||
# ================================================================ Datenschutz
|
||
page("datenschutz.html", "Datenschutz – Schmacko Napf", "Datenschutzerklärung von Schmacko Napf & Hundetraining by Katha.", None, f''' <div class="panel panel--cream panel--auto">
|
||
<span class="kicker">Rechtliches</span>
|
||
<h1 class="display">Datenschutz</h1>
|
||
<div class="legal">
|
||
<p>Der Schutz deiner Daten ist mir wichtig. Diese Website kommt ohne Cookies, ohne Tracking und ohne Inhalte von Drittanbietern aus. Schriften und Bilder liegen auf dem eigenen Server.</p>
|
||
|
||
<h2>1. Verantwortliche</h2>
|
||
<p>Katharina Schulz<br>Seewiese 19<br>84109 Wörth a.d. Isar<br>E-Mail: <a href="mailto:{MAIL}">{MAIL}</a><br>Telefon: <a href="{PHONE_HREF}">{PHONE}</a></p>
|
||
|
||
<h2>2. Aufruf der Website (Server-Logfiles)</h2>
|
||
<p>Beim Aufruf dieser Website verarbeitet der Hosting-Anbieter automatisch technische Daten, die dein Browser übermittelt: IP-Adresse, Datum und Uhrzeit, aufgerufene Seite, Referrer-URL, Browsertyp und Betriebssystem. Das ist nötig, um die Website sicher und stabil auszuliefern (Art. 6 Abs. 1 lit. f DSGVO). Die Daten werden nicht mit anderen Daten zusammengeführt und nach kurzer Zeit gelöscht. Mit dem Hosting-Anbieter besteht ein Vertrag zur Auftragsverarbeitung.</p>
|
||
|
||
<h2>3. Verschlüsselung</h2>
|
||
<p>Die Website wird über eine verschlüsselte Verbindung (HTTPS/TLS) ausgeliefert. Du erkennst das am Schloss-Symbol in der Adresszeile deines Browsers.</p>
|
||
|
||
<h2>4. Kontakt per E-Mail, Telefon oder WhatsApp</h2>
|
||
<p>Wenn du mich kontaktierst, verarbeite ich deine Angaben (z. B. Name, Kontaktdaten, Informationen zu deinem Hund), um deine Anfrage zu beantworten und gegebenenfalls einen Termin oder Vertrag durchzuführen (Art. 6 Abs. 1 lit. b DSGVO). Die Daten werden gelöscht, sobald sie nicht mehr erforderlich sind und keine gesetzlichen Aufbewahrungspflichten bestehen.</p>
|
||
<p>Der WhatsApp-Link öffnet erst nach deinem Klick die App bzw. Website von WhatsApp (WhatsApp Ireland Ltd.). Dabei gelten die Datenschutzbestimmungen von WhatsApp. Wenn du das nicht möchtest, schreib mir gern per E-Mail oder ruf an.</p>
|
||
|
||
<h2>5. Online-Terminbuchung</h2>
|
||
<p>Für Terminbuchungen nutze ich das Buchungsportal PetWorkers (schmacko-napf.petworkers.app). Erst wenn du auf „Termin buchen“ klickst, wirst du dorthin weitergeleitet. Die Daten, die du bei der Buchung angibst, verarbeite ich zur Durchführung deines Termins (Art. 6 Abs. 1 lit. b DSGVO). Für die Verarbeitung auf dem Portal gelten ergänzend die Datenschutzhinweise von PetWorkers.</p>
|
||
|
||
<h2>6. Deine Rechte</h2>
|
||
<p>Du hast das Recht auf Auskunft (Art. 15 DSGVO), Berichtigung (Art. 16), Löschung (Art. 17), Einschränkung der Verarbeitung (Art. 18), Datenübertragbarkeit (Art. 20) und Widerspruch gegen Verarbeitungen auf Grundlage berechtigter Interessen (Art. 21). Eine Einwilligung kannst du jederzeit für die Zukunft widerrufen. Eine formlose Nachricht an die oben genannte Adresse genügt.</p>
|
||
<p>Außerdem kannst du dich bei einer Datenschutz-Aufsichtsbehörde beschweren, zum Beispiel beim Bayerischen Landesamt für Datenschutzaufsicht (BayLDA), Promenade 18, 91522 Ansbach.</p>
|
||
|
||
<h2>7. Stand</h2>
|
||
<p>Oktober 2026</p>
|
||
</div>
|
||
</div>
|
||
''', robots="noindex")
|
||
PAGES.append("datenschutz.html")
|
||
|
||
# ================================================================ 404
|
||
page("404.html", "Seite nicht gefunden – Schmacko Napf", "Diese Seite gibt es leider nicht.", None, f''' <div class="panel panel--ink panel--mid panel--center">
|
||
<span class="kicker">Fehler 404</span>
|
||
<h1 class="display">Hier ist leider<br>nichts zu finden.</h1>
|
||
<p class="big">Vielleicht hat ein Hund die Seite vergraben. Über die Startseite findest du alles wieder.</p>
|
||
<div class="btn-row"><a class="btn btn--sage" href="index.html">Zur Startseite {I["arrow"]}</a></div>
|
||
</div>
|
||
''', robots="noindex")
|
||
|
||
# 404 wird vom Server unter beliebigen Pfaden ausgeliefert – Links und Bilder relativ zur Wurzel auflösen
|
||
p404 = os.path.join(OUT, "404.html")
|
||
html404 = open(p404).read().replace("<head>", '<head>\n <base href="/">', 1)
|
||
open(p404, "w").write(html404)
|
||
|
||
# ================================================================ robots.txt & sitemap.xml
|
||
write("robots.txt", f"User-agent: *\nAllow: /\n\nSitemap: {SITE}/sitemap.xml\n")
|
||
urls = "\n".join(f" <url><loc>{SITE}/{'' if p == 'index.html' else p}</loc></url>" for p in PAGES if p not in ("impressum.html", "datenschutz.html"))
|
||
write("sitemap.xml", f'<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n{urls}\n</urlset>\n')
|
||
print("ok")
|