// Shared layout components const { useState, useEffect, useRef } = React; // Image sources — fall back to live Unsplash URL in dev; use bundled // blob URL via window.__resources when running as a standalone file. const _IMG_SRC = { // Real assets from biotope-studio.org logo: "uploads/logo-cdn.webp", leistungenHero: "uploads/MH113901-web.jpg", kartierungen: "uploads/kartierungen-opt.jpg", weiteres: "uploads/weiteres-opt.jpg", baubegleitung: "uploads/baubegleitung-web.jpg", gebaeude: "uploads/gebaeude-web.jpg", kontaktHero: "uploads/kontakt-web.jpg", hero: "uploads/hero-cdn.webp", felix: "uploads/felix-cdn.webp", marsh: "uploads/marsh-cdn.webp", rails: "uploads/rails-cdn.webp", building: "uploads/building-cdn.webp", hedge: "uploads/hedge-cdn.webp", facade: "uploads/facade-cdn.webp", biotop: "uploads/biotop-cdn.webp", woodland: "uploads/woodland-cdn.jpg", }; const IMG = Object.fromEntries( Object.entries(_IMG_SRC).map(([k, v]) => [ k, (window.__resources && window.__resources["img_" + k]) || v, ]) ); // Wavy divider between sections function WaveDivider({ from = "var(--cream)", to = "#fff", flip = false }) { return (
); } function Nav({ page, navigate }) { const [scrolled, setScrolled] = useState(false); const [open, setOpen] = useState(false); useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 30); onScroll(); window.addEventListener("scroll", onScroll, { passive: true }); return () => window.removeEventListener("scroll", onScroll); }, []); const links = [ { id: "start", label: "Start" }, { id: "leistungen", label: "Leistungen" }, { id: "referenzen", label: "Referenzen" }, { id: "ueber", label: "Über mich" }, { id: "kontakt", label: "Kontakt" }, ]; const go = (id) => { setOpen(false); navigate(id); }; return ( ); } function Footer({ navigate }) { const year = new Date().getFullYear(); return ( ); } function CTABanner({ navigate }) { return (
Sprechen wir über Ihr Projekt

Sie haben Fragen zum Artenschutz
oder Ihrer Planung?

navigate("kontakt")}> Jetzt Kontakt aufnehmen
); } function Toast({ message, show }) { return (
{message}
); } window.Nav = Nav; window.Footer = Footer; window.WaveDivider = WaveDivider; window.CTABanner = CTABanner; window.Toast = Toast; window.IMG = IMG;