// ── Helpers ───────────────────────────────────────────────────────────────── const CHF = (n) => "CHF " + n.toFixed(2).replace(".", "."); const cx = (...a) => a.filter(Boolean).join(" "); // IntersectionObserver scroll-reveal hook function useReveal() { React.useEffect(() => { const els = document.querySelectorAll(".reveal:not(.in)"); if (!("IntersectionObserver" in window) || !els.length) { els.forEach((e) => e.classList.add("in")); return; } const io = new IntersectionObserver( (entries) => { entries.forEach((en) => { if (en.isIntersecting) { en.target.classList.add("in"); io.unobserve(en.target); } }); }, { threshold: 0.12, rootMargin: "0px 0px -8% 0px" } ); els.forEach((e) => io.observe(e)); return () => io.disconnect(); }); } // ── Icons (simple line set) ────────────────────────────────────────────────── const Ico = { bag: (p) => ( ), plus: (p) => ( ), minus: (p) => ( ), close: (p) => ( ), clock: (p) => ( ), pin: (p) => ( ), phone: (p) => ( ), check: (p) => ( ), arrow: (p) => ( ), leaf: (p) => ( ), flame: (p) => ( ), menu: (p) => ( ), }; // ── Toned texture placeholder (steht für ein Food-Foto) ───────────────────── function FoodPlaceholder({ tone = 30, label, className = "", rounded = "rounded-xl2", showLabel = true }) { const bg = `linear-gradient(150deg, hsl(${tone} 42% 64%) 0%, hsl(${tone - 8} 38% 48%) 48%, hsl(${tone - 14} 34% 34%) 100%)`; return (
{/* dezente Teller-/Lichtandeutung */}
{showLabel && label && ( Foto · {label} )}
); } // ── Diet / Allergen badges ─────────────────────────────────────────────────── function DietBadge({ tag }) { const map = { vegi: { t: "Vegetarisch", Icon: Ico.leaf, cls: "text-olive border-olive/40 bg-olive/8" }, vegan: { t: "Vegan", Icon: Ico.leaf, cls: "text-olive border-olive/40 bg-olive/8" }, scharf:{ t: "Scharf", Icon: Ico.flame, cls: "text-terra border-terra/40 bg-terra/8" }, }; const m = map[tag]; if (!m) return null; return ( {m.t} ); } function AllergenList({ codes }) { if (!codes || !codes.length) return null; return ( {codes.join(" · ")} ); } // Section heading w/ kicker function SectionHead({ kicker, title, sub, light = false, center = false }) { return (
{kicker && (
{kicker}
)}

{title}

{sub &&

{sub}

}
); } Object.assign(window, { CHF, cx, useReveal, Ico, FoodPlaceholder, DietBadge, AllergenList, SectionHead });