/* Dealer-focused single-page site: Vincent Ulin — Lokale Cralux verkoper (gevels: crepi & steenstrips) */

// Asset path helper — allows same components to work from /dealer.html and from /werkgebied/*.html
// Pages in subdirs set window.__ASSET_BASE = "../" before loading this script.
const ASSET_BASE = (typeof window !== "undefined" && window.__ASSET_BASE) || "";
const asset = (path) => `${ASSET_BASE}${path}`;

const DEALER = {
  name: "Vincent Ulin",
  shortName: "Vincent",
  initials: "VU",
  role: "Lokale Cralux verkoper",
  region: "Regio Kempen-Noord",
  towns: ["Zoersel", "Schilde", "Kalmthout", "Essen", "Brasschaat"],
  nearby: ["Wuustwezel", "Kapellen", "Schoten", "'s-Gravenwezel", "Malle"],
  phone: "+32 (0)478 62 14 07",
  email: "vincent@cralux-kempen.be",
  address: "Neerveld 13, 2550 Kontich",
  years: 9,
  projects: 260,
  rating: 4.9,
  reviewCount: 142,
  hobbies: {
    cats: ["Tessa", "Loewie"],
    chess: "Schaakclub De Koningsvleugel, Schilde",
  },
};

/* ---------- Nav ---------- */
const DealerNav = ({ onScrollTo }) => {
  const [scrolled, setScrolled] = React.useState(false);
  React.useEffect(() => {
    const h = () => setScrolled(window.scrollY > 40);
    window.addEventListener("scroll", h); return () => window.removeEventListener("scroll", h);
  }, []);
  const items = [
    { id: "proces", label: "Aanpak" },
    { id: "opties", label: "Gevelopties" },
    { id: "simulator", label: "Prijssimulator" },
    { id: "realisaties", label: "Realisaties" },
    { id: "werkgebied", label: "Werkgebied" },
    { id: "reviews", label: "Klanten" },
    { id: "blog", label: "Blog" },
    { id: "faq", label: "FAQ" },
    { id: "showroom", label: "Showroom" },
    { id: "over", label: "Over Vincent" },
    { id: "contact", label: "Contact" },
  ];
  return (
    <div style={{
      position: "sticky", top: 0, zIndex: 50,
      background: scrolled ? "rgba(250,247,242,0.96)" : "rgba(250,247,242,0.8)",
      backdropFilter: "blur(12px)",
      borderBottom: scrolled ? "1px solid var(--border)" : "1px solid transparent",
      transition: "all 200ms",
    }}>
      <div style={{ maxWidth: 1280, margin: "0 auto", padding: "14px 28px", display: "flex", alignItems: "center", gap: 18, flexWrap: "nowrap" }}>
        <button onClick={() => onScrollTo("top")} style={{ display: "flex", alignItems: "center", gap: 12, flexShrink: 0 }}>
          <div style={{
            width: 34, height: 34, borderRadius: 10, background: "var(--navy)", color: "#fff",
            display: "flex", alignItems: "center", justifyContent: "center",
            fontSize: 13, fontWeight: 600, letterSpacing: "0.02em",
          }}>VU</div>
          <div style={{ textAlign: "left", lineHeight: 1.15, whiteSpace: "nowrap" }}>
            <div style={{ fontSize: 14, fontWeight: 500, color: "var(--navy)" }}>Vincent Ulin</div>
            <div style={{ fontSize: 11, color: "var(--muted)", letterSpacing: "0.03em" }}>Cralux · Kempen-Noord</div>
          </div>
        </button>
        <div className="nav-links" style={{ display: "flex", gap: 2, marginLeft: "auto", flexWrap: "nowrap" }}>
          {items.map(i => (
            <button key={i.id} onClick={() => onScrollTo(i.id)} style={{
              padding: "8px 12px", fontSize: 13, color: "var(--navy)", borderRadius: 9999, whiteSpace: "nowrap",
            }}
              onMouseEnter={e => e.currentTarget.style.background = "rgba(61,64,91,0.06)"}
              onMouseLeave={e => e.currentTarget.style.background = "transparent"}>
              {i.label}
            </button>
          ))}
        </div>
        <a href={`tel:${DEALER.phone.replace(/[^+\d]/g, "")}`} className="nav-phone" style={{
          display: "inline-flex", alignItems: "center", gap: 8, padding: "8px 14px",
          borderRadius: 9999, fontSize: 13, fontWeight: 500, color: "var(--navy)",
          border: "1px solid var(--border)", background: "rgba(255,255,255,0.6)", whiteSpace: "nowrap",
        }}>
          <span style={{ position: "relative", width: 8, height: 8, display: "inline-block" }}>
            <span style={{
              position: "absolute", inset: 0, borderRadius: "50%", background: "var(--sage-deep)",
              animation: "navPulseRing 1.8s ease-out infinite",
            }} />
            <span style={{ position: "absolute", inset: 0, borderRadius: "50%", background: "var(--sage-deep)" }} />
          </span>
          <span className="nav-phone-text">{DEALER.phone}</span>
        </a>
        <Button variant="primary" size="small" onClick={() => onScrollTo("simulator")} style={{ flexShrink: 0 }}>Bereken prijs</Button>
      </div>
      <style>{`
        @keyframes navPulseRing {
          0% { transform: scale(1); opacity: 0.55; }
          80% { transform: scale(2.4); opacity: 0; }
          100% { transform: scale(2.4); opacity: 0; }
        }
        @media (max-width: 1024px) {
          .nav-links { display: none !important; }
        }
        @media (max-width: 760px) {
          .nav-phone-text { display: none !important; }
          .nav-phone { padding: 8px 10px !important; }
        }
      `}</style>
    </div>
  );
};

/* ---------- Hero ---------- */
const DealerHero = ({ onScrollTo }) => (
  <section className="m-hero" style={{ position: "relative", padding: "48px 40px 80px", overflow: "hidden" }}>
    <div style={{ position: "absolute", inset: 0,
      background: "radial-gradient(1100px 480px at 85% 20%, rgba(129,178,154,0.24), transparent 60%), radial-gradient(900px 600px at 0% 90%, rgba(224,122,95,0.14), transparent 60%), var(--cream)",
    }} />
    <div className="m-hero-grid" style={{ position: "relative", maxWidth: 1280, margin: "0 auto", display: "grid", gridTemplateColumns: "1.05fr 1fr", gap: 56, alignItems: "center", paddingTop: 40 }}>
      <div>
        <div style={{ display: "inline-flex", alignItems: "center", gap: 10, padding: "4px 14px 4px 4px", borderRadius: 9999, background: "rgba(255,255,255,0.95)", border: "1px solid rgba(255,255,255,0.9)" }}>
          <img src={asset("assets/cralux-logo.png")} alt="Cralux" style={{ height: 28, width: "auto", borderRadius: 9999, display: "block" }} />
          <span style={{ fontSize: 13, color: "var(--navy)" }}><strong>Erkend partner</strong> · Crepi & steenstrips · Kempen-Noord</span>
        </div>
        {/* Semantic H1 — small coral kicker with keyword, dominant in DOM */}
        <h1 style={{
          fontFamily: '"DM Sans", sans-serif', fontSize: 13, fontWeight: 500,
          letterSpacing: "0.14em", textTransform: "uppercase", color: "var(--terracotta)",
          marginTop: 24, display: "inline-flex", alignItems: "center", gap: 12,
        }}>
          <span style={{ display: "inline-block", width: 28, height: 2, background: "var(--terracotta)" }} />
          Gevelrenovatie Kempen-Noord — crepi & steenstrips
        </h1>
        {/* Visual hero headline, semantic H2 */}
        <h2 className="display m-hero-headline" style={{ fontSize: 68, lineHeight: 1.02, color: "var(--navy)", marginTop: 14, letterSpacing: "-0.025em" }}>
          Jouw gevel.<br />
          <em style={{ fontStyle: "italic", fontWeight: 400, color: "var(--sage-deep)" }}>Persoonlijk begeleid</em><br />
          door Vincent.
        </h2>
        <p style={{ fontSize: 19, lineHeight: 1.55, color: "var(--navy)", marginTop: 22, maxWidth: 540 }}>
          Ik ben <strong>{DEALER.name}</strong>, jouw lokale Cralux-verkoper voor Zoersel, Schilde, Kalmthout, Essen
          en Brasschaat. Gespecialiseerd in <strong>crepi</strong> en <strong>steenstrips</strong> —
          van eerste kennismaking tot ver na de oplevering, altijd hetzelfde gezicht.
        </p>
        <div style={{ display: "flex", alignItems: "center", gap: 20, marginTop: 32, flexWrap: "wrap" }}>
          <Button variant="primary" size="large" onClick={() => onScrollTo("simulator")}>Bereken mijn gevel</Button>
          <a href={`tel:${DEALER.phone.replace(/[^+\d]/g, "")}`} style={{
            display: "inline-flex", alignItems: "center", gap: 10, padding: "12px 18px",
            borderRadius: 9999, fontSize: 15, fontWeight: 500, color: "var(--navy)",
            border: "1px solid rgba(61,64,91,0.2)", background: "transparent",
          }}>
            <Icon name="phone" size={16} stroke="var(--navy)" />
            of bel Vincent direct
          </a>
        </div>
        <div style={{ marginTop: 40, paddingTop: 24, borderTop: "1px solid rgba(61,64,91,0.15)", display: "flex", gap: 44, fontSize: 13, color: "var(--muted)" }}>
          <div><strong style={{ color: "var(--navy)", fontSize: 17, display: "block" }}>{DEALER.years} jaar</strong>met Cralux op de baan</div>
          <div><strong style={{ color: "var(--navy)", fontSize: 17, display: "block" }}>{DEALER.projects}+</strong>gevels begeleid</div>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <div style={{ display: "flex", gap: 2 }}>
              {[0,1,2,3,4].map(i => <Icon key={i} name="star" size={14} stroke="var(--terracotta)" />)}
            </div>
            <div><strong style={{ color: "var(--navy)", fontSize: 17, display: "block" }}>{DEALER.rating.toString().replace(".",",")}/5</strong>{DEALER.reviewCount} reviews</div>
          </div>
        </div>
      </div>
      {/* Portrait card */}
      <div className="m-hero-portrait" style={{ position: "relative", height: 560 }}>
        <div className="m-hero-photo" style={{ position: "absolute", right: 0, top: 0, width: 420, height: 520, borderRadius: 16, overflow: "hidden", boxShadow: "0 40px 80px -30px rgba(61,64,91,0.3)" }}>
          {/* TODO: vervangen door werk-context-foto Vincent (op werf / bij gevel / showroom met stalenbord), min. 800x1000px, 3:4 portret. Huidige foto toont Vincent met magazine — niet ideaal als werk-context. */}
          <img src={asset("assets/vincent.jpg")} alt="Vincent Ulin — gevelrenovatie-specialist Cralux Kempen-Noord" style={{ width: "100%", height: "100%", objectFit: "cover", objectPosition: "center 25%", display: "block" }} />
        </div>
        <div className="m-hero-card" style={{
          position: "absolute", left: 0, bottom: 20, width: 320,
          background: "var(--white)", borderRadius: 18, padding: "20px 22px",
          boxShadow: "0 30px 60px -20px rgba(61,64,91,0.25)",
          border: "1px solid var(--border)",
          display: "flex", gap: 14, alignItems: "center",
        }}>
          <div style={{ width: 64, height: 64, borderRadius: "50%", overflow: "hidden", flexShrink: 0, border: "2px solid var(--cream-2)" }}>
            {/* TODO: vervangen door werk-context-foto (zie hero-comment hierboven) */}
            <img src={asset("assets/vincent.jpg")} alt="Vincent Ulin" style={{ width: "100%", height: "100%", objectFit: "cover", objectPosition: "center 25%" }} />
          </div>
          <div style={{ flex: 1 }}>
            <div className="mono-label" style={{ color: "var(--terracotta)" }}>Jouw aanspreekpunt</div>
            <div style={{ fontSize: 17, fontWeight: 500, color: "var(--navy)", marginTop: 2 }}>{DEALER.name}</div>
            <div style={{ fontSize: 13, color: "var(--muted)" }}>{DEALER.role}</div>
          </div>
        </div>
        <div className="m-hero-region" style={{
          position: "absolute", right: 20, bottom: -24, width: 220,
          background: "var(--navy)", color: "#fff", borderRadius: 16, padding: "16px 20px",
          boxShadow: "0 30px 60px -20px rgba(61,64,91,0.4)",
        }}>
          <div className="mono-label" style={{ color: "rgba(255,255,255,0.6)" }}>Werkt in</div>
          <div style={{ fontSize: 14, marginTop: 6, lineHeight: 1.5 }}>
            {DEALER.towns.join(" · ")}
          </div>
        </div>
      </div>
    </div>
  </section>
);

/* ---------- Breadcrumb (reusable) ---------- */
const Breadcrumb = ({ items = [] }) => {
  // items: [{ label: "Home", href: "/" }, { label: "Werkgebied", href: "/werkgebied" }, { label: "Zoersel" }]
  if (!items.length) return null;
  // JSON-LD for SEO
  const schema = {
    "@context": "https://schema.org",
    "@type": "BreadcrumbList",
    itemListElement: items.map((it, i) => ({
      "@type": "ListItem",
      position: i + 1,
      name: it.label,
      ...(it.href ? { item: it.href } : {}),
    })),
  };
  return (
    <nav aria-label="Broodkruimel" style={{
      padding: "14px 40px", background: "var(--cream)",
      borderBottom: "1px solid var(--border)",
    }}>
      <div style={{ maxWidth: 1280, margin: "0 auto", display: "flex", alignItems: "center", gap: 10, fontSize: 13, flexWrap: "wrap" }}>
        {items.map((it, i) => {
          const last = i === items.length - 1;
          return (
            <React.Fragment key={i}>
              {it.href && !last ? (
                <a href={it.href} style={{ color: "var(--muted)", textDecoration: "none" }}>{it.label}</a>
              ) : (
                <span style={{ color: last ? "var(--navy)" : "var(--muted)", fontWeight: last ? 500 : 400 }}>{it.label}</span>
              )}
              {!last && <span style={{ color: "var(--border)" }}>›</span>}
            </React.Fragment>
          );
        })}
      </div>
      <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }} />
    </nav>
  );
};

/* ---------- Trust bar ---------- */
const TrustBar = () => {
  const items = [
    { icon: "shield", label: "Erkend Cralux-partner", sub: "sinds 2017" },
    { icon: "calc", label: "6% BTW renovatie", sub: "woning > 10 jaar" },
    { icon: "check", label: "Premies geregeld door Vincent", sub: "tot € 5.900" },
    { icon: "leaf", label: "10 jaar fabrieksgarantie", sub: "op pleisterwerk" },
  ];
  return (
    <section aria-label="Garanties" style={{ padding: "0 40px", background: "var(--cream)" }}>
      <div style={{
        maxWidth: 1280, margin: "0 auto", padding: "26px 32px",
        background: "var(--cream-2)", borderRadius: 18, border: "1px solid var(--border)",
        display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 20,
      }} className="trust-bar">
        {items.map((x, i) => (
          <div key={i} style={{
            display: "flex", alignItems: "center", gap: 14,
            borderRight: i < items.length - 1 ? "1px solid var(--border)" : "none",
            paddingRight: i < items.length - 1 ? 20 : 0,
          }}>
            <div style={{
              width: 38, height: 38, borderRadius: 10,
              background: "var(--white)", border: "1px solid var(--border)",
              display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0,
            }}>
              <Icon name={x.icon} size={18} stroke="var(--sage-deep)" />
            </div>
            <div style={{ lineHeight: 1.2, minWidth: 0 }}>
              <div style={{ fontSize: 13, fontWeight: 500, color: "var(--navy)" }}>{x.label}</div>
              <div style={{ fontSize: 11, color: "var(--muted)", marginTop: 3 }}>{x.sub}</div>
            </div>
          </div>
        ))}
      </div>
      <style>{`
        @media (max-width: 860px) {
          .trust-bar { grid-template-columns: 1fr 1fr !important; }
          .trust-bar > div { border-right: none !important; padding-right: 0 !important; }
        }
      `}</style>
    </section>
  );
};

/* ---------- Approach ---------- */
const Approach = () => {
  const steps = [
    { n: "01", t: "Persoonlijke kennismaking", d: "Ik kom bij je thuis langs — kosteloos en zonder verkoopspraatje. Eerst koffie en het project leren kennen, daarna pas meten. Meestal binnen de week." },
    { n: "02", t: "Punctuele opmeting", d: "Laser-opmeting tot op de centimeter, met foto-dossier van elke gevelzijde. Alles wordt exact genoteerd, zodat je offerte klopt en er achteraf geen verrassingen zijn." },
    { n: "03", t: "Voorstel & offerte", d: "Binnen 7 dagen ontvang je een 3D-visualisatie van je nieuwe gevel, stalen om vast te nemen, en een transparante prijsopbouw — premies inbegrepen." },
    { n: "04", t: "Werf-begeleiding", d: "Vaste Cralux-ploeg, dagelijkse opkuis, en ik rij minstens tweemaal per week langs. Één aanspreekpunt voor jou, van dag één tot de oplevering — ik." },
    { n: "05", t: "Nazorg — ook later nog", d: "Na oplevering lopen we samen alles na. En ook drie jaar later neem ik nog op wanneer je belt. Garantie 10 jaar, betrokkenheid onbeperkt." },
  ];
  return (
    <section id="proces" style={{ padding: "96px 40px", scrollMarginTop: 80 }}>
      <div style={{ maxWidth: 1280, margin: "0 auto" }}>
        <div style={{ display: "grid", gridTemplateColumns: "0.9fr 1.1fr", gap: 80, marginBottom: 48, alignItems: "end" }}>
          <div>
            <SectionLabel color="var(--terracotta)">Mijn aanpak</SectionLabel>
            <h2 className="display" style={{ fontSize: 52, color: "var(--navy)", marginTop: 14, lineHeight: 1.05 }}>
              Koffie, opmeting, <em style={{ fontStyle: "italic", color: "var(--sage-deep)", fontWeight: 400 }}>blijvende opvolging</em>.
            </h2>
          </div>
          <p style={{ fontSize: 17, lineHeight: 1.65, color: "var(--muted)" }}>
            Geen keten, geen callcenter. Één contactpersoon die tijd maakt om je project te leren kennen,
            die altijd op tijd op je stoep staat, en die ook drie jaar na de werken nog opneemt.
          </p>
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 16 }}>
          {steps.map(s => (
            <div key={s.n} style={{
              padding: 24, background: "var(--white)", borderRadius: 18, border: "1px solid var(--border)",
              display: "flex", flexDirection: "column", gap: 12, minHeight: 240,
            }}>
              <div className="display" style={{ fontSize: 36, color: "var(--terracotta)", lineHeight: 1 }}>{s.n}</div>
              <h4 className="display" style={{ fontSize: 20, color: "var(--navy)", lineHeight: 1.15 }}>{s.t}</h4>
              <p style={{ fontSize: 13, lineHeight: 1.55, color: "var(--muted)" }}>{s.d}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
};

/* ---------- Gevel options ---------- */
const GEVEL_OPTIONS = [
  { id: "crepi", name: "Crepi afwerking", tagline: "Modern & strak", tone: "warm",
    desc: "Zuivere lijnen, keuze uit 40+ tinten. Perfect voor wie een hedendaags, onderhoudsvriendelijk resultaat wil. Cralux werkt met twee lagen pleister op een versterkt weefsel — scheurvrij voor minstens 10 jaar.",
    m2: 95, isolatie: "EPS 14cm · λ 0,031", warranty: 10, usp: "40+ kleuren · korrel fijn/middel/grof" },
  { id: "steenstrips", name: "Steenstrips", tagline: "Natuursteen-look", tone: "cool",
    desc: "Echt gebakken klei in dun formaat. De uitstraling van volwaardige baksteen, zonder het gewicht of de funderingswerken. Ideaal voor wie de bestaande karakteristiek van de buurt wil respecteren.",
    m2: 135, isolatie: "PIR 12cm · λ 0,022", warranty: 15, usp: "12 formaten · handvorm of strak" },
];

const GevelOptions = ({ onPick }) => {
  const [active, setActive] = React.useState("crepi");
  const a = GEVEL_OPTIONS.find(o => o.id === active);
  return (
    <section id="opties" style={{ padding: "96px 40px", background: "var(--cream-2)", scrollMarginTop: 80 }}>
      <div style={{ maxWidth: 1280, margin: "0 auto" }}>
        <div style={{ maxWidth: 680, marginBottom: 48 }}>
          <SectionLabel color="var(--terracotta)">Gevelopties</SectionLabel>
          <h2 className="display" style={{ fontSize: 52, color: "var(--navy)", marginTop: 14, lineHeight: 1.05 }}>
            Twee specialiteiten. <em style={{ fontStyle: "italic", color: "var(--terracotta)", fontWeight: 400 }}>Eén vakman</em>.
          </h2>
          <p style={{ fontSize: 17, color: "var(--muted)", marginTop: 14, lineHeight: 1.6 }}>
            Ik werk bewust met twee afwerkingen — de twee waarmee ik in Kempen-Noord
            al bijna tien jaar mee werk. Specialisatie boven uitbreiding, zodat elke werf
            tot in de puntjes klopt.
          </p>
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "380px 1fr", gap: 24 }}>
          <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
            {GEVEL_OPTIONS.map(o => {
              const isActive = o.id === active;
              return (
                <button key={o.id} onClick={() => setActive(o.id)} style={{
                  textAlign: "left", padding: "18px 20px", borderRadius: 14,
                  background: isActive ? "var(--navy)" : "var(--white)",
                  color: isActive ? "#fff" : "var(--navy)",
                  border: "1px solid " + (isActive ? "var(--navy)" : "var(--border)"),
                  display: "flex", justifyContent: "space-between", alignItems: "center", gap: 16,
                  transition: "all 180ms",
                }}>
                  <div>
                    <div style={{ fontFamily: "Jost", fontWeight: 500, fontSize: 17 }}>{o.name}</div>
                    <div style={{ fontSize: 13, opacity: 0.75, marginTop: 2 }}>{o.tagline} · vanaf €{o.m2}/m²</div>
                  </div>
                  <Icon name="arrow-right" size={18} stroke={isActive ? "#fff" : "var(--muted)"} />
                </button>
              );
            })}
          </div>
          <div style={{
            background: "var(--white)", borderRadius: 20, overflow: "hidden",
            border: "1px solid var(--border)", display: "grid", gridTemplateColumns: "1fr 1fr",
          }}>
            <Placeholder tone={a.tone} h="100%" radius={0} label={a.name.toLowerCase()} />
            <div style={{ padding: "36px 36px", display: "flex", flexDirection: "column", gap: 16 }}>
              <div className="mono-label" style={{ color: "var(--terracotta)" }}>{a.tagline}</div>
              <h3 className="display" style={{ fontSize: 32, color: "var(--navy)", lineHeight: 1.1 }}>{a.name}</h3>
              <p style={{ fontSize: 15, lineHeight: 1.65, color: "var(--muted)" }}>{a.desc}</p>
              <dl style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14, marginTop: 8, paddingTop: 16, borderTop: "1px solid var(--border)" }}>
                <Spec k="Richtprijs" v={`€${a.m2}/m²`} />
                <Spec k="Isolatie" v={a.isolatie} />
                <Spec k="Garantie" v={`${a.warranty} jaar`} />
                <Spec k="Uitvoering" v="3–5 weken" />
              </dl>
              <div style={{ marginTop: "auto", paddingTop: 16 }}>
                <Button variant="primary" onClick={() => onPick(a.id)}>Reken deze afwerking door</Button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
};

const Spec = ({ k, v }) => (
  <div>
    <div style={{ fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--muted)" }}>{k}</div>
    <div style={{ fontSize: 15, color: "var(--navy)", fontWeight: 500, marginTop: 2 }}>{v}</div>
  </div>
);

/* ---------- Simulator ---------- */
const Simulator = ({ presetOption }) => {
  const [option, setOption] = React.useState(presetOption || "crepi");
  const [surface, setSurface] = React.useState(160);
  const [stories, setStories] = React.useState(2);
  const [condition, setCondition] = React.useState("gewoon");
  const [windows, setWindows] = React.useState("behouden");
  const [premium, setPremium] = React.useState(true);
  const [urgent, setUrgent] = React.useState("3-6m");
  const [lead, setLead] = React.useState({ naam: "", email: "", telefoon: "", postcode: "" });
  const [sent, setSent] = React.useState(false);

  React.useEffect(() => { if (presetOption) setOption(presetOption); }, [presetOption]);

  const selected = GEVEL_OPTIONS.find(o => o.id === option);
  const conditionMult = { goed: 1.0, gewoon: 1.08, slecht: 1.22 }[condition];
  const storiesMult = stories === 1 ? 0.92 : stories === 2 ? 1.0 : stories === 3 ? 1.12 : 1.22;
  const windowsAdd = windows === "vernieuwen" ? 180 * Math.round(surface / 40) : 0;
  const base = selected.m2 * surface * conditionMult * storiesMult;
  const total = base + windowsAdd;
  const premie = premium ? Math.min(total * 0.14, 4600) : 0;
  const net = Math.max(0, total - premie);

  return (
    <section id="simulator" style={{ padding: "96px 40px", scrollMarginTop: 80 }}>
      <div style={{ maxWidth: 1280, margin: "0 auto" }}>
        <div style={{ maxWidth: 680, marginBottom: 40 }}>
          <SectionLabel color="var(--terracotta)">Prijssimulator · gevel</SectionLabel>
          <h2 className="display" style={{ fontSize: 52, color: "var(--navy)", marginTop: 14, lineHeight: 1.05 }}>
            Indicatieve prijs in <em style={{ fontStyle: "italic", color: "var(--sage-deep)", fontWeight: 400 }}>60 seconden</em>.
          </h2>
          <p style={{ fontSize: 16, color: "var(--muted)", marginTop: 12, lineHeight: 1.6 }}>
            De simulator rekent op basis van dezelfde parameters die ik tijdens het plaatsbezoek gebruik.
            Voor een definitieve offerte kom ik altijd ter plaatse meten — dat zit mee inbegrepen.
          </p>
        </div>
        <div style={{
          display: "grid", gridTemplateColumns: "1.25fr 1fr", gap: 24,
          background: "var(--white)", borderRadius: 24, overflow: "hidden",
          border: "1px solid var(--border)",
          boxShadow: "0 40px 80px -40px rgba(61,64,91,0.15)",
        }}>
          {/* Left — inputs */}
          <div style={{ padding: "40px 44px", display: "grid", gap: 28 }}>
            <Field label="Type afwerking">
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
                {GEVEL_OPTIONS.map(o => (
                  <button key={o.id} onClick={() => setOption(o.id)} style={{
                    textAlign: "left", padding: "12px 14px", borderRadius: 12,
                    background: option === o.id ? "var(--navy)" : "var(--white)",
                    color: option === o.id ? "#fff" : "var(--navy)",
                    border: "1px solid " + (option === o.id ? "var(--navy)" : "var(--border)"),
                  }}>
                    <div style={{ fontSize: 14, fontWeight: 500 }}>{o.name}</div>
                    <div style={{ fontSize: 12, opacity: 0.7 }}>€{o.m2}/m²</div>
                  </button>
                ))}
              </div>
            </Field>
            <Field label={`Gevelspoppervlakte · ${surface} m²`}>
              <input type="range" min={40} max={400} step={5} value={surface} onChange={e => setSurface(+e.target.value)} style={{ width: "100%", accentColor: "var(--sage-deep)" }} />
              <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12, color: "var(--muted)", marginTop: 4 }}>
                <span>40 m²</span><span>400 m²</span>
              </div>
            </Field>
            <Field label="Aantal verdiepingen">
              <Chips value={stories} options={[{v:1,l:"1"},{v:2,l:"2"},{v:3,l:"3"},{v:4,l:"4+"}]} onChange={setStories} />
            </Field>
            <Field label="Staat van huidige gevel">
              <Chips value={condition} options={[{v:"goed",l:"Goed"},{v:"gewoon",l:"Gewoon"},{v:"slecht",l:"Slecht / veel herstel"}]} onChange={setCondition} />
            </Field>
            <Field label="Ramen">
              <Chips value={windows} options={[{v:"behouden",l:"Behouden"},{v:"vernieuwen",l:"Mee vernieuwen"}]} onChange={setWindows} />
            </Field>
            <Field label="Wanneer starten?">
              <Chips value={urgent} options={[{v:"asap",l:"ZSM"},{v:"3-6m",l:"3–6 maand"},{v:"6-12m",l:"6–12 maand"},{v:"orient",l:"Oriënterend"}]} onChange={setUrgent} />
            </Field>
            <label style={{ display: "flex", alignItems: "center", gap: 10, fontSize: 14, color: "var(--navy)", cursor: "pointer" }}>
              <input type="checkbox" checked={premium} onChange={e => setPremium(e.target.checked)} style={{ width: 18, height: 18, accentColor: "var(--sage-deep)" }} />
              Ik wil de Vlaamse renovatiepremie laten verrekenen (Tim regelt de aanvraag)
            </label>
          </div>

          {/* Right — live estimate + lead capture */}
          <div style={{ background: "var(--navy)", color: "#fff", padding: "40px 40px", display: "flex", flexDirection: "column", gap: 24 }}>
            <div>
              <div className="mono-label" style={{ color: "rgba(255,255,255,0.6)" }}>Indicatieve prijs</div>
              <div className="display" style={{ fontSize: 64, lineHeight: 1, marginTop: 6, color: "#fff", letterSpacing: "-0.03em" }}>
                € {Math.round(net / 100) * 100 === 0 ? 0 : Math.round(net).toLocaleString("nl-BE")}
              </div>
              <div style={{ fontSize: 13, opacity: 0.7, marginTop: 6 }}>Incl. BTW · premies verrekend</div>
            </div>

            <div style={{ padding: "18px 20px", borderRadius: 14, background: "rgba(255,255,255,0.05)", fontSize: 14, display: "grid", gap: 8 }}>
              <Row2 k="Afwerking" v={selected.name} />
              <Row2 k={`${surface} m² gevel`} v={`€ ${Math.round(base).toLocaleString("nl-BE")}`} />
              {windowsAdd > 0 && <Row2 k="Ramen mee" v={`+ € ${windowsAdd.toLocaleString("nl-BE")}`} />}
              <Row2 k="Subtotaal" v={`€ ${Math.round(total).toLocaleString("nl-BE")}`} />
              {premie > 0 && <Row2 k="Vlaamse premie" v={`− € ${Math.round(premie).toLocaleString("nl-BE")}`} color="var(--sage)" />}
            </div>

            <div style={{ fontSize: 13, opacity: 0.75, lineHeight: 1.55 }}>
              Wil je een precieze offerte? Laat je gegevens achter — ik bel je binnen één werkdag en stuur
              na het plaatsbezoek een definitieve prijs op maat.
            </div>

            {!sent ? (
              <form onSubmit={e => { e.preventDefault(); setSent(true); }} style={{ display: "grid", gap: 10 }}>
                <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
                  <input required placeholder="Naam" value={lead.naam} onChange={e => setLead(l => ({...l, naam: e.target.value}))} style={darkInput} />
                  <input required placeholder="Postcode" value={lead.postcode} onChange={e => setLead(l => ({...l, postcode: e.target.value}))} style={darkInput} />
                </div>
                <input required type="email" placeholder="E-mail" value={lead.email} onChange={e => setLead(l => ({...l, email: e.target.value}))} style={darkInput} />
                <input required placeholder="Telefoon" value={lead.telefoon} onChange={e => setLead(l => ({...l, telefoon: e.target.value}))} style={darkInput} />
                <Button variant="terracotta" iconRight="arrow-right" type="submit">Stuur mij deze berekening</Button>
                <div style={{ fontSize: 11, opacity: 0.55, textAlign: "center" }}>
                  Je gegevens komen rechtstreeks bij Tim terecht — niet bij een callcenter.
                </div>
              </form>
            ) : (
              <div style={{ padding: "24px 20px", background: "var(--sage)", color: "var(--navy)", borderRadius: 14 }}>
                <div className="mono-label" style={{ color: "var(--sage-deep)" }}>Bedankt, {lead.naam}!</div>
                <div className="display" style={{ fontSize: 22, marginTop: 4 }}>Ik bel je binnen één werkdag op {lead.telefoon}.</div>
                <div style={{ fontSize: 13, marginTop: 8, opacity: 0.85 }}>
                  De berekening staat ook in je mailbox ({lead.email}) — samen met drie referentieprojecten uit {lead.postcode || "je buurt"}.
                </div>
              </div>
            )}
          </div>
        </div>
      </div>
    </section>
  );
};

const darkInput = {
  padding: "13px 16px", borderRadius: 10,
  background: "rgba(255,255,255,0.08)", border: "1px solid rgba(255,255,255,0.2)",
  color: "#fff", fontFamily: "Jost", fontSize: 14, outline: "none",
};

const Row2 = ({ k, v, color }) => (
  <div style={{ display: "flex", justifyContent: "space-between", fontSize: 14 }}>
    <span style={{ opacity: 0.7 }}>{k}</span>
    <span style={{ fontWeight: 500, color: color || "#fff" }}>{v}</span>
  </div>
);

const Field = ({ label, children, hint }) => (
  <label style={{ display: "block" }}>
    <div style={{ fontSize: 13, color: "var(--muted)", marginBottom: 8, fontFamily: "Jost", fontWeight: 500, display: "flex", alignItems: "baseline", gap: 10 }}>
      <span>{label}</span>
      {hint && <span style={{ fontSize: 11, opacity: 0.8 }}>· {hint}</span>}
    </div>
    {children}
  </label>
);

const ChipGroup = ({ value, options, onChange }) => (
  <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
    {options.map(o => {
      const active = value === o;
      return (
        <button type="button" key={o} onClick={() => onChange(o)} style={{
          padding: "8px 14px", borderRadius: 9999, fontSize: 13, fontWeight: 500,
          border: "1px solid " + (active ? "var(--sage-deep)" : "var(--border)"),
          background: active ? "var(--sage-deep)" : "var(--white)",
          color: active ? "#fff" : "var(--navy)",
          transition: "all 150ms",
        }}>{o}</button>
      );
    })}
  </div>
);

const Chips = ({ value, options, onChange }) => (
  <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>
    {options.map(o => (
      <button key={o.v} onClick={() => onChange(o.v)} style={{
        padding: "9px 14px", borderRadius: 9999, fontSize: 13, fontFamily: "Jost",
        background: value === o.v ? "var(--navy)" : "var(--white)",
        color: value === o.v ? "#fff" : "var(--navy)",
        border: "1px solid " + (value === o.v ? "var(--navy)" : "var(--border)"),
      }}>{o.l}</button>
    ))}
  </div>
);

/* ---------- Address autocomplete (OpenStreetMap Nominatim — free, no key) ---------- */
const AddressAutocomplete = ({ value, onChange, onSelect }) => {
  const [q, setQ] = React.useState(value || "");
  const [results, setResults] = React.useState([]);
  const [open, setOpen] = React.useState(false);
  const [loading, setLoading] = React.useState(false);
  const [highlight, setHighlight] = React.useState(-1);
  const wrapRef = React.useRef(null);
  const abortRef = React.useRef(null);

  // Keep local q in sync when parent value changes externally
  React.useEffect(() => { setQ(value || ""); }, [value]);

  // Debounced fetch
  React.useEffect(() => {
    if (!q || q.trim().length < 3) { setResults([]); return; }
    const t = setTimeout(async () => {
      try {
        if (abortRef.current) abortRef.current.abort();
        abortRef.current = new AbortController();
        setLoading(true);
        const url = "https://nominatim.openstreetmap.org/search?format=jsonv2&addressdetails=1&countrycodes=be&limit=6&accept-language=nl&q=" + encodeURIComponent(q);
        const res = await fetch(url, { signal: abortRef.current.signal, headers: { "Accept": "application/json" } });
        if (!res.ok) throw new Error("nominatim");
        const data = await res.json();
        const mapped = data.map(d => {
          const a = d.address || {};
          const street = a.road || a.pedestrian || a.footway || "";
          const nr = a.house_number || "";
          const pc = a.postcode || "";
          const muni = a.city || a.town || a.village || a.municipality || a.suburb || a.county || "";
          const line1 = [street, nr].filter(Boolean).join(" ").trim();
          const line2 = [pc, muni].filter(Boolean).join(" ").trim();
          return {
            key: d.place_id,
            line1: line1 || muni || d.display_name.split(",")[0],
            line2: line2,
            formatted: [line1, line2].filter(Boolean).join(", ") || d.display_name,
            gemeente: muni ? (pc ? `${pc} ${muni}` : muni) : "",
            lat: d.lat, lon: d.lon,
          };
        });
        setResults(mapped);
        setOpen(true);
        setHighlight(-1);
      } catch (e) {
        if (e.name !== "AbortError") setResults([]);
      } finally {
        setLoading(false);
      }
    }, 280);
    return () => clearTimeout(t);
  }, [q]);

  // Close on outside click
  React.useEffect(() => {
    const onDocClick = (e) => {
      if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
    };
    document.addEventListener("mousedown", onDocClick);
    return () => document.removeEventListener("mousedown", onDocClick);
  }, []);

  const pick = (r) => {
    setQ(r.formatted);
    setOpen(false);
    setResults([]);
    onChange && onChange(r.formatted);
    onSelect && onSelect(r);
  };

  const onKey = (e) => {
    if (!open || results.length === 0) return;
    if (e.key === "ArrowDown") { e.preventDefault(); setHighlight(h => Math.min(h + 1, results.length - 1)); }
    else if (e.key === "ArrowUp") { e.preventDefault(); setHighlight(h => Math.max(h - 1, 0)); }
    else if (e.key === "Enter" && highlight >= 0) { e.preventDefault(); pick(results[highlight]); }
    else if (e.key === "Escape") setOpen(false);
  };

  return (
    <div ref={wrapRef} style={{ position: "relative" }}>
      <div style={{ position: "relative" }}>
        <div style={{ position: "absolute", left: 14, top: "50%", transform: "translateY(-50%)", pointerEvents: "none", display: "flex", alignItems: "center" }}>
          <Icon name="home" size={16} stroke="var(--muted)" />
        </div>
        <input
          value={q}
          onChange={e => { setQ(e.target.value); onChange && onChange(e.target.value); if (e.target.value.length >= 3) setOpen(true); }}
          onFocus={() => { if (results.length) setOpen(true); }}
          onKeyDown={onKey}
          autoComplete="off"
          style={{ ...lightInput, paddingLeft: 40, paddingRight: 40 }}
          placeholder="bv. Dorpsstraat 12, 2980 Zoersel"
        />
        {loading && (
          <div style={{ position: "absolute", right: 14, top: "50%", transform: "translateY(-50%)" }}>
            <span style={{ display: "inline-block", width: 14, height: 14, border: "2px solid rgba(47,49,72,0.2)", borderTopColor: "var(--sage-deep)", borderRadius: "50%", animation: "addrSpin 700ms linear infinite" }} />
          </div>
        )}
      </div>
      {open && results.length > 0 && (
        <div style={{
          position: "absolute", top: "calc(100% + 6px)", left: 0, right: 0, zIndex: 20,
          background: "var(--white)", border: "1px solid var(--border)", borderRadius: 14,
          boxShadow: "0 30px 60px -20px rgba(47,49,72,0.18)", overflow: "hidden",
          maxHeight: 320, overflowY: "auto",
        }}>
          {results.map((r, i) => (
            <button
              type="button"
              key={r.key}
              onMouseEnter={() => setHighlight(i)}
              onClick={() => pick(r)}
              style={{
                width: "100%", textAlign: "left", padding: "12px 16px",
                display: "flex", gap: 12, alignItems: "flex-start",
                background: highlight === i ? "var(--cream-2)" : "transparent",
                borderBottom: i < results.length - 1 ? "1px solid var(--border)" : "none",
              }}>
              <div style={{ width: 28, height: 28, borderRadius: 8, background: "rgba(34,125,93,0.12)", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0, marginTop: 2 }}>
                <Icon name="home" size={14} stroke="var(--sage-deep)" />
              </div>
              <div style={{ minWidth: 0, flex: 1 }}>
                <div style={{ fontSize: 14, color: "var(--navy)", fontWeight: 500, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{r.line1}</div>
                {r.line2 && <div style={{ fontSize: 12, color: "var(--muted)", marginTop: 2 }}>{r.line2}</div>}
              </div>
            </button>
          ))}
          <div style={{ padding: "8px 16px", fontSize: 10, color: "var(--muted)", letterSpacing: "0.05em", background: "var(--cream-2)", borderTop: "1px solid var(--border)" }}>
            Suggesties via OpenStreetMap · België
          </div>
        </div>
      )}
      <style>{`@keyframes addrSpin { to { transform: translateY(-50%) rotate(360deg); } }`}</style>
    </div>
  );
};

/* ---------- Reviews ---------- */
const REVIEWS = [
  { text: "Vincent heeft echt de tijd genomen om ons project te leren kennen — drie bezoeken voor de offerte één keer af was. Het resultaat in crepi is exact zoals we het voor ogen hadden.", name: "Els & Bart", town: "Zoersel" },
  { text: "Punctueel op de minuut. Bij opmeting, bij start van de werken, bij oplevering. Twee jaar later belde hij zelf nog even om te vragen of alles goed was.", name: "Katrien V.", town: "Schilde" },
  { text: "Onze steenstrip-gevel is een toonbeeld in de straat. Vincent adviseerde een handvorm-formaat dat perfect past bij de oudere woningen in de buurt.", name: "Marc D.", town: "Kalmthout" },
];

const Reviews = () => (
  <section id="reviews" style={{ padding: "96px 40px", background: "var(--cream-2)", scrollMarginTop: 80 }}>
    <div style={{ maxWidth: 1280, margin: "0 auto" }}>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 60, alignItems: "end", marginBottom: 48 }}>
        <div>
          <SectionLabel color="var(--terracotta)">Klanten uit de Kempen</SectionLabel>
          <h2 className="display" style={{ fontSize: 52, color: "var(--navy)", marginTop: 14, lineHeight: 1.05 }}>
            Buren die <em style={{ fontStyle: "italic", color: "var(--sage-deep)", fontWeight: 400 }}>al voor waren</em>.
          </h2>
        </div>
        <div style={{ display: "flex", gap: 40, justifyContent: "flex-end" }}>
          <div style={{ textAlign: "right" }}>
            <div className="display" style={{ fontSize: 48, color: "var(--navy)", lineHeight: 1 }}>4,9</div>
            <div style={{ display: "flex", gap: 2, justifyContent: "flex-end", marginTop: 6 }}>
              {[0,1,2,3,4].map(i => <Icon key={i} name="star" size={14} stroke="var(--terracotta)" />)}
            </div>
            <div style={{ fontSize: 13, color: "var(--muted)", marginTop: 4 }}>{DEALER.reviewCount} Google reviews</div>
          </div>
        </div>
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 20 }}>
        {REVIEWS.map((r, i) => (
          <figure key={i} style={{ padding: 28, background: "var(--white)", borderRadius: 18, border: "1px solid var(--border)", display: "flex", flexDirection: "column", gap: 16 }}>
            <div style={{ display: "flex", gap: 2 }}>
              {[0,1,2,3,4].map(s => <Icon key={s} name="star" size={14} stroke="var(--terracotta)" />)}
            </div>
            <blockquote className="display" style={{ fontSize: 21, lineHeight: 1.3, color: "var(--navy)", fontStyle: "italic", fontWeight: 400 }}>
              "{r.text}"
            </blockquote>
            <figcaption style={{ marginTop: "auto", display: "flex", alignItems: "center", gap: 12 }}>
              <div style={{ width: 40, height: 40, borderRadius: "50%", background: "var(--sage)", color: "#fff", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: 600 }}>
                {r.name.split(" ").map(n => n[0]).slice(0,2).join("")}
              </div>
              <div>
                <div style={{ fontWeight: 500, color: "var(--navy)", fontSize: 14 }}>{r.name}</div>
                <div style={{ fontSize: 12, color: "var(--muted)" }}>{r.town}</div>
              </div>
            </figcaption>
          </figure>
        ))}
      </div>
    </div>
  </section>
);

/* ---------- Recent projects — functional portfolio ---------- */
const PROJECTS = [
  { slug: "herenhuis-dorp-kalkwit", title: "Herenhuis Dorp — kalkwit crepi",    type: "Crepi",       muni: "Zoersel",       buurt: "Zoersel-Centrum",  m2: 215, date: "Mrt 2026", tag: "Crepi · Kalkwit",        tone: "warm" },
  { slug: "halfopen-fermette-warmgrijs", title: "Halfopen fermette — warmgrijs",  type: "Crepi",       muni: "Kalmthout",     buurt: "Heide",             m2: 168, date: "Feb 2026", tag: "Crepi · Warmgrijs",      tone: "terra" },
  { slug: "villa-handvorm-klassiek", title: "Villa — handvorm steenstrips",       type: "Steenstrips", muni: "Schilde",       buurt: "'s-Gravenwezel",    m2: 240, date: "Feb 2026", tag: "Steenstrips · Handvorm", tone: "cool" },
  { slug: "nieuwbouw-strak-antraciet", title: "Nieuwbouw — strakke antraciet-strip", type: "Steenstrips", muni: "Essen",      buurt: "Essen-Centrum",     m2: 195, date: "Jan 2026", tag: "Steenstrips · Strak",    tone: "cool" },
  { slug: "jaren70-renovatie-zandbeige", title: "Jaren '70 — zandbeige crepi",    type: "Crepi",       muni: "Brasschaat",    buurt: "Mariaburg",         m2: 142, date: "Jan 2026", tag: "Crepi · Zandbeige",      tone: "terra" },
  { slug: "combi-crepi-strips",         title: "Combi — crepi + accent-strips",    type: "Combinatie",  muni: "'s-Gravenwezel", buurt: "Centrum",           m2: 178, date: "Dec 2025", tag: "Combinatie",             tone: "warm" },
  { slug: "rijwoning-wit-fijnkorrel",   title: "Rijwoning — wit crepi fijnkorrel", type: "Crepi",       muni: "Zoersel",       buurt: "Halle-Zoersel",    m2: 112, date: "Dec 2025", tag: "Crepi · Fijnkorrel",     tone: "warm" },
  { slug: "bungalow-donkergrijze-strip", title: "Bungalow — donkergrijze strip",   type: "Steenstrips", muni: "Kalmthout",     buurt: "Kalmthoutse Heide", m2: 156, date: "Nov 2025", tag: "Steenstrips · Donkergrijs", tone: "cool" },
  { slug: "herenhuis-crepi-okergeel",   title: "Herenhuis — oker crepi",           type: "Crepi",       muni: "Schilde",       buurt: "Schilde-Centrum",  m2: 198, date: "Nov 2025", tag: "Crepi · Oker",           tone: "terra" },
];

const PROJECT_FILTERS = [
  { id: "all",         label: "Alles" },
  { id: "Crepi",       label: "Crepi" },
  { id: "Steenstrips", label: "Steenstrips" },
  { id: "Zoersel",     label: "Zoersel" },
  { id: "Schilde",     label: "Schilde" },
  { id: "Kalmthout",   label: "Kalmthout" },
  { id: "Essen",       label: "Essen" },
  { id: "Brasschaat",  label: "Brasschaat" },
];

const slugify = s => s.toLowerCase()
  .replace(/'/g, "").replace(/[àáâäå]/g, "a").replace(/[èéêë]/g, "e")
  .replace(/[ìíîï]/g, "i").replace(/[òóôö]/g, "o").replace(/[ùúûü]/g, "u")
  .replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");

const ProjectCard = ({ p }) => {
  const toneBg = {
    warm:  "repeating-linear-gradient(135deg, #E0A985 0 18px, #D8946D 18px 36px)",
    cool:  "repeating-linear-gradient(135deg, #3B4A60 0 18px, #2F3A4C 18px 36px)",
    terra: "repeating-linear-gradient(135deg, #EADFC8 0 18px, #DDD0B1 18px 36px)",
  };
  const href = `/realisaties/${slugify(p.muni)}/${p.slug}`;
  return (
    <a href={href} style={{
      display: "flex", flexDirection: "column", gap: 14,
      background: "var(--white)", borderRadius: 18, overflow: "hidden",
      border: "1px solid var(--border)", textDecoration: "none", color: "inherit",
      transition: "transform 220ms ease, box-shadow 220ms ease",
    }}
    onMouseEnter={e => { e.currentTarget.style.transform = "translateY(-4px)"; e.currentTarget.style.boxShadow = "0 30px 60px -30px rgba(47,49,72,0.22)"; }}
    onMouseLeave={e => { e.currentTarget.style.transform = "translateY(0)"; e.currentTarget.style.boxShadow = "none"; }}
    >
      <div style={{
        position: "relative", height: 200,
        background: toneBg[p.tone] || toneBg.terra,
      }}>
        <div style={{
          position: "absolute", left: 14, top: 14,
          padding: "5px 11px", borderRadius: 9999,
          background: "rgba(255,255,255,0.95)", color: "var(--navy)",
          fontSize: 11, fontWeight: 500, letterSpacing: "0.04em",
        }}>
          {p.tag}
        </div>
        <div style={{
          position: "absolute", right: 14, bottom: 14,
          padding: "4px 10px", borderRadius: 9999,
          background: "rgba(47,49,72,0.6)", color: "rgba(255,255,255,0.9)",
          fontSize: 10, letterSpacing: "0.08em", textTransform: "uppercase",
        }}>foto volgt</div>
      </div>
      <div style={{ padding: "4px 20px 22px" }}>
        <h3 className="display" style={{ fontSize: 21, lineHeight: 1.2, color: "var(--navy)", letterSpacing: "-0.01em" }}>
          {p.title}
        </h3>
        <div style={{ fontSize: 12, color: "var(--muted)", marginTop: 8, letterSpacing: "0.02em" }}>
          {p.buurt} · {p.m2} m² · {p.date}
        </div>
      </div>
    </a>
  );
};

const Projects = () => {
  const [filter, setFilter] = React.useState("all");
  const [mobileExpanded, setMobileExpanded] = React.useState(false);
  const [isMobile, setIsMobile] = React.useState(false);
  React.useEffect(() => {
    const mq = window.matchMedia("(max-width: 760px)");
    const update = () => setIsMobile(mq.matches);
    update();
    mq.addEventListener("change", update);
    return () => mq.removeEventListener("change", update);
  }, []);
  const filtered = PROJECTS.filter(p => {
    if (filter === "all") return true;
    if (["Crepi", "Steenstrips", "Combinatie"].includes(filter)) return p.type === filter;
    return p.muni === filter;
  });
  const visible = (isMobile && !mobileExpanded) ? filtered.slice(0, 6) : filtered;
  const hiddenCount = filtered.length - visible.length;
  return (
    <section id="realisaties" style={{ padding: "96px 40px", scrollMarginTop: 80 }}>
      <div style={{ maxWidth: 1280, margin: "0 auto" }}>
        <div style={{ display: "grid", gridTemplateColumns: "0.9fr 1.1fr", gap: 60, alignItems: "end", marginBottom: 36 }} className="projects-header">
          <div>
            <SectionLabel color="var(--terracotta)">Recente realisaties</SectionLabel>
            <h2 className="display" style={{ fontSize: 52, color: "var(--navy)", marginTop: 14, lineHeight: 1.05 }}>
              Projecten in <em style={{ fontStyle: "italic", color: "var(--sage-deep)", fontWeight: 400 }}>de buurt</em>.
            </h2>
          </div>
          <p style={{ fontSize: 17, color: "var(--muted)", maxWidth: 480, lineHeight: 1.65 }}>
            Een greep uit de laatste twaalf maanden. Elk project in Kempen-Noord, elk persoonlijk begeleid.
            Wil je er eens langs rijden? Ik plan het graag samen in.
          </p>
        </div>
        <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 32 }} className="projects-filter">
          {PROJECT_FILTERS.map(f => {
            const active = filter === f.id;
            return (
              <button key={f.id} onClick={() => setFilter(f.id)} style={{
                padding: "8px 14px", borderRadius: 9999, fontSize: 13, fontWeight: 500,
                border: "1px solid " + (active ? "var(--navy)" : "var(--border)"),
                background: active ? "var(--navy)" : "var(--white)",
                color: active ? "#fff" : "var(--navy)",
                transition: "all 150ms",
              }}>{f.label}</button>
            );
          })}
        </div>
        <div style={{
          display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 20,
        }} className="projects-grid">
          {visible.map(p => <ProjectCard key={p.slug} p={p} />)}
        </div>
        {isMobile && hiddenCount > 0 && (
          <div style={{ display: "flex", justifyContent: "center", marginTop: 20 }}>
            <button onClick={() => setMobileExpanded(true)} style={{
              padding: "12px 22px", borderRadius: 9999,
              border: "1px solid var(--navy)", color: "var(--navy)",
              background: "var(--white)", fontSize: 14, fontWeight: 500,
              fontFamily: "Jost, sans-serif",
            }}>
              Bekijk {hiddenCount} meer realisaties ↓
            </button>
          </div>
        )}
        {filtered.length === 0 && (
          <div style={{ padding: 40, textAlign: "center", color: "var(--muted)", fontSize: 14 }}>
            Geen projecten voor deze filter. <button onClick={() => setFilter("all")} style={{ color: "var(--sage-deep)", fontWeight: 500 }}>Toon alles</button>
          </div>
        )}
        <div style={{ display: "flex", justifyContent: "center", marginTop: 40 }}>
          <a href="/realisaties" style={{
            display: "inline-flex", alignItems: "center", gap: 10, padding: "13px 22px",
            borderRadius: 9999, border: "1px solid var(--navy)", color: "var(--navy)",
            fontSize: 14, fontWeight: 500, textDecoration: "none",
          }}>
            Alle 260+ realisaties bekijken <Icon name="arrow-right" size={14} stroke="var(--navy)" />
          </a>
        </div>
      </div>
      <style>{`
        @media (max-width: 960px) {
          .projects-header { grid-template-columns: 1fr !important; }
          .projects-grid { grid-template-columns: 1fr 1fr !important; }
        }
        @media (max-width: 640px) {
          .projects-grid { grid-template-columns: 1fr !important; }
        }
      `}</style>
    </section>
  );
};

/* ---------- Werkgebied (service area) ---------- */
const SERVICE_AREAS = [
  { name: "Zoersel",    projects: 47, slug: "zoersel" },
  { name: "Schilde",    projects: 52, slug: "schilde" },
  { name: "Kalmthout",  projects: 38, slug: "kalmthout" },
  { name: "Essen",      projects: 29, slug: "essen" },
  { name: "Brasschaat", projects: 64, slug: "brasschaat" },
];

const EXTRA_AREAS = [
  { name: "Wuustwezel",      slug: "wuustwezel" },
  { name: "Kapellen",        slug: "kapellen" },
  { name: "Schoten",         slug: "schoten" },
  { name: "'s-Gravenwezel",  slug: "s-gravenwezel" },
  { name: "Malle",           slug: "malle" },
];

const Werkgebied = () => (
  <section id="werkgebied" style={{ padding: "96px 40px", background: "var(--cream-2)", scrollMarginTop: 80 }}>
    <div style={{ maxWidth: 1280, margin: "0 auto" }}>
      <div style={{ display: "grid", gridTemplateColumns: "0.9fr 1.1fr", gap: 60, alignItems: "end", marginBottom: 48 }} className="werk-header">
        <div>
          <SectionLabel color="var(--terracotta)">Werkgebied Kempen-Noord</SectionLabel>
          <h2 className="display" style={{ fontSize: 52, color: "var(--navy)", marginTop: 14, lineHeight: 1.05 }}>
            Actief in jouw <em style={{ fontStyle: "italic", color: "var(--sage-deep)", fontWeight: 400 }}>gemeente</em>?
          </h2>
        </div>
        <p style={{ fontSize: 17, lineHeight: 1.65, color: "var(--muted)", paddingBottom: 8 }}>
          Vijf kern-gemeentes waar ik wekelijks zit, plus een ring van buur-gemeentes op aanvraag.
          Vanuit de showroom in Kontich kom ik overal binnen 25 minuten.
        </p>
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 16 }} className="werk-grid">
        {SERVICE_AREAS.map(a => (
          <a key={a.slug} href={`werkgebied/${a.slug}.html`} style={{
            display: "block", padding: "24px 22px", borderRadius: 16,
            background: "var(--white)", border: "1px solid var(--border)",
            textDecoration: "none", color: "inherit",
            transition: "all 200ms ease",
          }}
          onMouseEnter={e => { e.currentTarget.style.borderColor = "var(--sage-deep)"; e.currentTarget.style.background = "var(--cream)"; }}
          onMouseLeave={e => { e.currentTarget.style.borderColor = "var(--border)"; e.currentTarget.style.background = "var(--white)"; }}
          >
            <div className="display" style={{ fontSize: 24, color: "var(--navy)", lineHeight: 1.1, letterSpacing: "-0.01em" }}>
              {a.name}
            </div>
            <div style={{ fontSize: 12, color: "var(--muted)", marginTop: 10, display: "flex", alignItems: "center", gap: 8 }}>
              <span style={{ width: 6, height: 6, borderRadius: "50%", background: "var(--sage-deep)" }} />
              {a.projects} realisaties
            </div>
            <div style={{ fontSize: 12, color: "var(--sage-deep)", marginTop: 14, display: "inline-flex", alignItems: "center", gap: 6, fontWeight: 500 }}>
              Bekijk gemeente <Icon name="arrow-right" size={12} stroke="var(--sage-deep)" />
            </div>
          </a>
        ))}
      </div>
      <div style={{
        marginTop: 36, padding: "20px 24px", borderRadius: 14,
        background: "var(--white)", border: "1px dashed var(--border)",
        textAlign: "center", fontSize: 14, color: "var(--muted)", lineHeight: 1.6,
      }}>
        Ook actief in{" "}
        {EXTRA_AREAS.map((a, i) => (
          <React.Fragment key={a.slug}>
            <a href={`werkgebied/${a.slug}.html`} style={{ color: "var(--navy)", fontWeight: 500, textDecoration: "underline", textDecorationColor: "var(--border)", textUnderlineOffset: 3 }}>{a.name}</a>
            {i < EXTRA_AREAS.length - 1 ? " · " : ""}
          </React.Fragment>
        ))}
        {" "}— plus omliggende gemeentes op aanvraag.
      </div>
    </div>
    <style>{`
      @media (max-width: 960px) {
        .werk-header { grid-template-columns: 1fr !important; }
        .werk-grid { grid-template-columns: 1fr 1fr !important; }
      }
    `}</style>
  </section>
);

/* ---------- Blog ---------- */
const BLOG_POSTS = [
  /* ===== GIDSEN (transactional SEO) ===== */
  {
    kind: "guide",
    cat: "Gids · Prijs",
    title: "Prijs crepi-gevel 2026 — volledige breakdown",
    date: "Bijgewerkt apr 2026",
    readTime: "8 min",
    tone: "cool",
    excerpt: "Wat kost een crepi-gevel écht? Per m², per woningtype, met én zonder isolatie — en welke posten je vaak vergeet.",
    body: `Een crepi-gevel is geen product dat je uit de rek pakt. De prijs hangt af van tien dingen, en marketing-tarieven „vanaf € 65 per m²” vertellen je meestal de helft van het verhaal.

Hier de eerlijke bandbreedte voor 2026, gebaseerd op mijn eigen werven in Kempen-Noord:

PRIJS PER M² (inclusief alles: isolatie, pleister in 2 lagen, profielen, plaatsing):
• Rijwoning 110 m² gevel → € 95 – € 120 per m²
• Halfopen 160 m² → € 88 – € 112 per m²
• Vrijstaand 230 m² → € 88 – € 112 per m²

WAT DIE PRIJS BEPAALT:
1. Dikte en type isolatie (EPS 12cm vs. minerale wol 14cm = € 8/m² verschil)
2. Stellingen (rijwoning kan vaak zonder, vrijstaand altijd mét)
3. Kleur/korrel (fijn vs. grof)
4. Voorbereidingswerk op bestaande gevel
5. Toegankelijkheid van de werf

VOORBEELDEN UIT MIJN WERFBOEK:
→ Rijwoning Zoersel 112 m² → € 11.200 (warm wit, middelkorrel)
→ Halfopen Kalmthout 168 m² → € 16.400 (warmgrijs, fijnkorrel)
→ Vrijstaand Essen 230 m² → € 24.600 (okerbeige, met extra voegwerk oud schrijnwerk)

POSTEN DIE MENSEN VERGETEN:
• Afwerking rond ramen/deuren (€ 800–1.400 voor gemiddelde woning)
• Dorpels vernieuwen indien aangetast
• Schilderklus boeiboorden (vaak nodig, vaak vergeten)

Belangrijk: deze prijzen zijn vóór premies. Met Mijn.Verbouwpremie + EPC-premie haal je er € 3.500 tot € 5.900 af.

Wil je een pricing op je eigen gevel? Gebruik de prijssimulator hierboven, of bel me. Ik maak gratis een plaatsbezoek + offerte binnen 7 dagen.

— Vincent`,
  },
  {
    kind: "guide",
    cat: "Gids · Premies",
    title: "Mijn.Verbouwpremie + EPC-premie combineren — tot € 5.900 in 2026",
    date: "Bijgewerkt apr 2026",
    readTime: "6 min",
    tone: "sage",
    excerpt: "Twee Vlaamse premies die samen meer opleveren dan apart. Voorwaarden, valkuilen en de timing die veel mensen missen.",
    body: `Er bestaan in Vlaanderen twee premies voor gevelrenovatie die je kan combineren. Veel mensen kennen er maar één.

PREMIE 1 — MIJN.VERBOUWPREMIE
• Voor gevels die na-isolatie krijgen tot minstens R = 4,5 m²K/W
• Inkomensafhankelijk: € 18/m² (hoog inkomen) tot € 30/m² (laag inkomen)
• Voor 140 m² gevel → € 2.500 – € 4.200

PREMIE 2 — EPC-LABELPREMIE
• Enkel als je EPC-label verbetert met minstens 2 klassen
• Open bebouwing: tot € 2.500 extra
• Halfopen: tot € 1.750
• Rijwoning: tot € 1.250

TOTAAL GECOMBINEERD: € 4.250 – € 5.900

DE TIMING-VALKUIL:
Je MOET het EPC-attest laten opmaken VOOR de werken. Achteraf is er geen referentiepunt.
En de aanvraag moet binnen 1 jaar na oplevering gebeuren.

Ik werk samen met een vaste EPC-deskundige. Hij kent onze dossiers, en voor mijn klanten kost het € 275 (marktprijs € 350–400). Ik regel de aanvraag.

WAT EIND 2026 VERANDERT:
Het huidige systeem loopt af. De opvolger is nog niet definitief. Mijn advies: wie nu twijfelt, offerte laten maken. Je bent nergens aan vastgelegd, maar je staat wel vooraan wanneer het weer meezit.

— Vincent`,
  },
  {
    kind: "guide",
    cat: "Gids · Isolatie",
    title: "EPS vs. minerale wol — welke isolatie voor crepi?",
    date: "Bijgewerkt mrt 2026",
    readTime: "5 min",
    tone: "warm",
    excerpt: "De twee grote isolatiekeuzes bij buitengevelisolatie met crepi. Kostprijs, brandveiligheid, dampopen — en waar ik zelf voor kies.",
    body: `Bij een gecrepiede buitengevelisolatie heb je twee serieuze opties: EPS (polystyreen, geëxpandeerd) of minerale wol (rotswol).

EPS (POLYSTYREEN):
+ Goedkoper (€ 12–18/m² goedkoper dan minerale wol)
+ Lichter → makkelijker plaatsen
+ Hogere isolatiewaarde per cm (λ 0,031)
− Brandklasse lager (moet aan strenge normen voldoen)
− Niet-dampopen

MINERALE WOL (ROTSWOL):
+ Brandveilig — onbrandbaar (klasse A1)
+ Dampopen — interessant bij oude huizen met vochtprobleem
+ Betere geluidsisolatie
− Duurder
− Zwaarder om te plaatsen

MIJN ADVIES PER TYPE WONING:
• Recente woning, geen vochtproblemen → EPS 14 cm
• Oude woning (>50 jaar), vocht in muren → minerale wol 14 cm
• Gebouw met strenge brandnormen → minerale wol

EPS heeft veel onterechte kritiek gekregen. Mits goed geplaatst met gecertificeerde profielen en brandvertragende stroken rond openingen, is het veilig. Ik plaats het al bijna 10 jaar zonder problemen.

Minerale wol is mijn voorkeur bij huizen van voor 1970 waar ik niet 100% zeker ben over het vochtevenwicht in de bestaande muren. Beter voorzichtig.

— Vincent`,
  },
  {
    kind: "guide",
    cat: "Gids · Isolatie",
    title: "Gevel isoleren: buiten of binnen?",
    date: "Bijgewerkt mrt 2026",
    readTime: "4 min",
    tone: "cool",
    excerpt: "Binnenisolatie lijkt goedkoper, maar kent drie grote risico’s. Wanneer je écht buiten isoleert — en wanneer binnen verdedigbaar is.",
    body: `Ik krijg deze vraag elke week: „Vincent, kan ik mijn gevel niet gewoon langs binnen isoleren?”

Het korte antwoord: bijna nooit.

WAAROM BUITEN-ISOLATIE BIJNA ALTIJD WINT:
1. Geen koudebruggen — thermisch continuüm blijft intact
2. Je verliest geen binnenruimte (binnenisolatie kost 10 cm per muur)
3. Bestaande muur blijft deel van de thermische massa → aangenamer binnenklimaat
4. Lost ook vochtproblemen op i.p.v. ze te verplaatsen

WAAROM BINNEN-ISOLATIE RISICOVOL IS:
• Bouwfysisch complex: verkeerd geplaatst → condensatie tussen muur en isolatie → schimmel
• Dampscherm MOET perfect dichten (één stopcontact fout = probleem)
• Koudebruggen aan vloeren en plafonds blijven
• Werkt verstorend voor bewoners (één kamer tegelijk leegmaken)

WANNEER BINNEN WÉL VERDEDIGBAAR IS:
• Beschermd monument met gevel die niet mag wijzigen
• Appartement waar je enkel je eigen gevel wil isoleren
• Gevel die monumentaal is (natuursteen, art deco-details)

In al die gevallen: met capillair-actieve materialen (kalksilicaat-platen bv.), nooit met klassieke EPS langs binnen zonder dampscherm.

Ik plaats zelf geen binnenisolatie — specialisatie boven uitbreiding. Wie twijfelt: bel mij, we kijken samen of buiten bij jou kan. In 95% van de gevallen kan het.

— Vincent`,
  },

  /* ===== UIT DE WERF (persoonlijk) ===== */
  {
    kind: "werf",
    cat: "Uit de werf",
    title: "Waarom ik nooit op een maandagochtend start met crepi",
    date: "12 apr 2026",
    readTime: "3 min",
    tone: "warm",
    excerpt: "Het klinkt bijgelovig, maar na negen jaar weet ik: een werf die op maandag start, loopt vaker vast. Niet door de ploeg — door de leveringen.",
    body: `Ik ben niet bijgelovig. Echt niet. Maar als je mij vraagt wanneer ik het liefst een crepi-werf opstart, dan is het antwoord altijd hetzelfde: dinsdagochtend, 7u30.

Waarom? Niet om de sterren, niet om de maan. Heel prozaïsch: omdat de leveringen op maandag tot vrijdag binnenkomen bij de groothandel, en als er maandagochtend iets ontbreekt — een zak pleister van een specifieke korrel, een bepaalde kleur hoekprofiel — dan zit je tot dinsdag te wachten. Een dag stilstand op een werf kost niet één dag, het kost twee: de ploeg kan niet zomaar een andere werf in want die zijn al ingepland.

Op dinsdag is de kans dat iets ontbreekt véél kleiner. En als het toch misloopt, kan ik nog altijd dezelfde dag reageren.

Dit is het soort detail waar klanten nooit over nadenken — en dat ook niet zouden moeten. Maar als je mij ooit hoort zeggen „we starten volgende week maandag”, dan weet je: ik heb drie keer nagekeken of álles er is.

— Vincent`,
  },
  {
    kind: "werf",
    cat: "Kleuradvies",
    title: "Die ene gevel in Kalmthout die van kleur is veranderd — drie keer",
    date: "28 mrt 2026",
    readTime: "4 min",
    tone: "cool",
    excerpt: "Een klant die twijfelt is géén moeilijke klant. Een klant die níet twijfelt en achteraf toch iets anders wil — dát is een probleem. Hoe ik ermee omga.",
    body: `Patrick uit Kalmthout belde me vorig voorjaar. „Vincent, ik denk toch dat ik van warm grijs naar iets met meer beige wil.” De stalen lagen al klaar, de werf stond gepland voor over drie weken.

Ik had ja kunnen zeggen. Ik had ook kunnen duwen in de richting van „het origineel plan is perfect, blijf erbij”. Ik heb geen van beide gedaan. Ik ben met nieuwe stalen langsgegaan — drie beiges, twee warm-grijzen — en we hebben ze op zijn noordgevel en zuidgevel gezet. Foto’s gemaakt om 8u, om 13u, om 18u.

En dan ga je weg. Je laat de klant ermee slapen. Niet één nacht, drie nachten.

Resultaat: Patrick koos uiteindelijk een tint terug dicht bij het origineel, maar net ietsje warmer. Exact de juiste keuze voor zijn huis. En hij heeft nooit meer getwijfeld.

De les: tijd en licht. Twee dingen die stalen op een folder niet kunnen bieden. Ik reken die bezoeken nooit aan — ik beschouw ze als deel van het werk. Want een klant die na drie jaar nog steeds blij is, dát is wat ik verkoop.

— Vincent`,
  },
  {
    kind: "werf",
    cat: "Seizoen",
    title: "Waarom april mijn drukste én mijn moeilijkste maand is",
    date: "05 apr 2026",
    readTime: "2 min",
    tone: "terra",
    excerpt: "Iedereen wil in het voorjaar zijn gevel doen. Maar april in de Kempen is — laat ik het voorzichtig zeggen — geen Toscane.",
    body: `April is de maand waarin mijn telefoon het hardst staat. Iedereen komt uit de winter, kijkt naar zijn gevel, en denkt: nu.

Het probleem: april in de Kempen is meteorologische tombola. Nachtvorst tot midden april is niet uitzonderlijk, en crepi heeft écht een minimumtemperatuur nodig — zowel overdag als ’s nachts — om goed uit te harden. Onder de 5°C mogen we niet werken. Doen we dat toch, dan zie je dat binnen twee jaar in je gevel: matte plekken, onregelmatige kleur, in het slechtste geval scheurvorming.

Dus als je in april belt en ik zeg „we starten eind mei”, dan is dat geen uitstel. Dat is zorg. Ik plan liever drie weken later en lever een werk dat tien jaar meegaat, dan dat ik drie weken eerder begin en over twee jaar terug moet komen.

Tip: wie écht snel wil, kan het best nú al de offerte laten opmaken. Dan sta ik op één, niet op zeven, wanneer het weer meezit.

— Vincent`,
  },
  {
    kind: "werf",
    cat: "Werf-verhaal",
    title: "De steenstrips-gevel die ik bijna afraadde (en waarom ik toch ja zei)",
    date: "18 mrt 2026",
    readTime: "5 min",
    tone: "warm",
    excerpt: "Mevrouw De Meyer wou steenstrips op een jaren-70 woning met betonnen luifel. Elke vezel in mijn lijf zei: dat gaat niet mooi zijn. Tot ze mij meenam naar binnen.",
    body: `Ik heb op een opmeting één keer bijna een klant weggestuurd. Niet omdat ze onvriendelijk was — integendeel — maar omdat ik dacht: deze keuze gaat niet werken.

Mevrouw De Meyer, 68, weduwe, woonde sinds 1974 in een typisch jaren-70 huis met brede luifel en kleine ramen. Zij wilde steenstrips. Grove, donkere steenstrips. Alles in mij zei: die luifel gaat er log uitzien, het huis wordt te zwaar.

En dan neemt ze mij mee naar binnen. Ze had één muur in haar living, zelf, bekleed met oude recuperatiesteen. Uit de schoorsteen van de boerderij van haar vader. Zij wou dat gevoel aan de buitenkant. Niet omdat het „modern” was. Omdat het háár was.

Ik heb toen even stil gezeten. En toen heb ik ja gezegd — op voorwaarde dat we een smallere steenstrip zouden kiezen, en dat we het voegwerk een tint lichter zouden houden om die luifel visueel te ontlasten.

Het resultaat staat er nu drie jaar. Ik rij er bewust langs wanneer ik in de buurt ben. En elke keer denk ik: goed dat ik heb geluisterd in plaats van geduwd.

— Vincent`,
  },
  {
    kind: "werf",
    cat: "Nazorg",
    title: "Drie jaar later — wat ik doe als je belt met een klacht",
    date: "02 mrt 2026",
    readTime: "3 min",
    tone: "sage",
    excerpt: "Er is een verschil tussen garantie hebben en garantie voelen. Dat verschil is telefoonnummer plus mens plus antwoord.",
    body: `Eén van mijn eerste klanten, Dirk uit Brasschaat, belde mij vorig najaar. Zes jaar na zijn werk. Er zat een haarscheurtje, amper zichtbaar, naast een dakraam.

Ik had kunnen zeggen: „Dirk, zes jaar is lang. Stuur eens foto’s.” En dan een week niks.

Ik heb gezegd: „Donderdag ben ik in de buurt, dan kom ik kijken.” Tien minuten op zijn oprit. Vaststelling: dakraam was een jaar eerder vervangen door een andere firma, het waterafvoerdetail was niet goed aangesloten op mijn crepi, daar was het scheurtje ontstaan.

Ik heb het die donderdag zelf hersteld. Vijftig euro materiaal, anderhalf uur werk. Geen factuur.

Niet omdat dit onder de garantie viel — strikt genomen viel het daar net buiten. Maar omdat Dirk mij vertrouwde toen hij zijn gevel liet doen, en dat vertrouwen stopt niet na tien jaar op papier.

Dat is wat ik bedoel met nazorg. Het is geen clausule, het is een gewoonte.

— Vincent`,
  },
  {
    kind: "werf",
    cat: "Premies",
    title: "Die 5.900 euro premie waar niemand over praat (en die tot eind 2026 loopt)",
    date: "14 feb 2026",
    readTime: "4 min",
    tone: "cool",
    excerpt: "Mijn.Verbouwpremie + EPC-labelpremie combineren doet meer dan de som. Een praktisch overzicht, zonder de marketing-taal.",
    body: `Ik ga hier geen verkooppraatje houden. Gewoon de cijfers, zoals ik ze ook op de keukentafel zou leggen.

Als je in Vlaanderen je gevel laat na-isoleren tot minstens R 4,5 m²K/W, dan heb je recht op Mijn.Verbouwpremie. Voor een gemiddelde woning van 140m² gevel ligt die ergens tussen 2.400 en 3.600 euro, afhankelijk van je inkomen.

Wat veel mensen missen: als je door die isolatie je EPC-label laat zakken met minstens twee klassen (bv. van E naar C), krijg je een EPC-labelpremie erbovenop. Dat is nog eens maximaal 2.500 euro voor een open bebouwing.

Samen gemakkelijk 5.000 tot 5.900 euro. Voorwaarde: aanvraag binnen één jaar na de werken, en correct EPC vóór en na.

Die EPC-berekening is cruciaal. Een fout daar kost je 2.500 euro. Ik werk daarom samen met een vaste EPC-deskundige voor mijn klanten — hij zit op één lijn met onze dossiers, en voor jullie kost het maximaal 275 euro ipv de 350-400 die je elders betaalt.

Eind 2026 loopt dit systeem af in zijn huidige vorm. Wat erna komt weten we nog niet. Voor wie twijfelt: dit jaar is een goed jaar.

— Vincent`,
  },
];

const BlogCard = ({ post, onOpen, large = false }) => {
  const tones = {
    warm: { bg: "var(--terracotta)", text: "#fff", label: "rgba(255,255,255,0.85)" },
    cool: { bg: "var(--navy)", text: "#fff", label: "rgba(255,255,255,0.85)" },
    terra: { bg: "var(--cream-2)", text: "var(--navy)", label: "var(--terracotta)" },
    sage: { bg: "var(--sage)", text: "var(--navy)", label: "var(--navy)" },
  };
  const t = tones[post.tone] || tones.terra;
  const isGuide = post.kind === "guide";
  return (
    <button onClick={() => onOpen(post)} style={{
      textAlign: "left", display: "flex", flexDirection: "column", gap: 18,
      padding: large ? 36 : 28, borderRadius: 20, background: t.bg, color: t.text,
      border: "none", cursor: "pointer", transition: "transform 180ms",
      gridColumn: large ? "span 2" : "span 1", minHeight: large ? 320 : 260,
      position: "relative",
    }}
    onMouseEnter={e => e.currentTarget.style.transform = "translateY(-2px)"}
    onMouseLeave={e => e.currentTarget.style.transform = "translateY(0)"}>
      {isGuide && (
        <div style={{
          position: "absolute", top: 18, left: 18,
          padding: "4px 10px", borderRadius: 9999,
          background: "var(--terracotta)", color: "#fff",
          fontSize: 10, letterSpacing: "0.14em", textTransform: "uppercase", fontWeight: 600,
        }}>GIDS</div>
      )}
      <div style={{ display: "flex", alignItems: "center", gap: 12, fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase", fontWeight: 500, color: t.label, marginTop: isGuide ? 24 : 0 }}>
        <span>{post.cat}</span>
        <span style={{ opacity: 0.5 }}>·</span>
        <span>{post.readTime}</span>
      </div>
      <h3 className="display" style={{ fontSize: large ? 34 : 24, lineHeight: 1.15, fontWeight: 500, letterSpacing: "-0.015em" }}>
        {post.title}
      </h3>
      <p style={{ fontSize: large ? 17 : 14, lineHeight: 1.55, opacity: 0.88, flex: 1 }}>
        {post.excerpt}
      </p>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", fontSize: 12, opacity: 0.75, paddingTop: 12, borderTop: `1px solid ${t.text === "#fff" ? "rgba(255,255,255,0.2)" : "rgba(61,64,91,0.15)"}` }}>
        <span>{post.date}</span>
        <span style={{ display: "inline-flex", alignItems: "center", gap: 6, fontWeight: 500 }}>
          Lezen <Icon name="arrow-right" size={14} stroke={t.text} />
        </span>
      </div>
    </button>
  );
};

const BlogModal = ({ post, onClose }) => {
  React.useEffect(() => {
    const h = e => e.key === "Escape" && onClose();
    window.addEventListener("keydown", h); return () => window.removeEventListener("keydown", h);
  }, [onClose]);
  if (!post) return null;
  return (
    <div onClick={onClose} style={{
      position: "fixed", inset: 0, background: "rgba(47,49,72,0.72)", zIndex: 100,
      display: "flex", alignItems: "flex-start", justifyContent: "center", padding: "40px 20px",
      overflowY: "auto", backdropFilter: "blur(6px)", animation: "fadeIn 180ms ease",
    }}>
      <div onClick={e => e.stopPropagation()} style={{
        maxWidth: 720, width: "100%", background: "var(--cream)", borderRadius: 20,
        padding: "48px 56px 56px", position: "relative",
      }}>
        <button onClick={onClose} aria-label="Sluiten" style={{
          position: "absolute", top: 18, right: 18, width: 38, height: 38, borderRadius: "50%",
          background: "rgba(61,64,91,0.08)", display: "flex", alignItems: "center", justifyContent: "center",
        }}>
          <Icon name="x" size={18} stroke="var(--navy)" />
        </button>
        <div className="mono-label" style={{ color: "var(--terracotta)" }}>{post.cat} · {post.readTime}</div>
        <h2 className="display" style={{ fontSize: 40, lineHeight: 1.12, color: "var(--navy)", marginTop: 14, letterSpacing: "-0.02em" }}>
          {post.title}
        </h2>
        <div style={{ display: "flex", alignItems: "center", gap: 12, marginTop: 20, paddingBottom: 24, borderBottom: "1px solid var(--border)" }}>
          <div style={{ width: 36, height: 36, borderRadius: "50%", background: "var(--sage-deep)", color: "#fff", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 12, fontWeight: 600 }}>
            {DEALER.initials}
          </div>
          <div style={{ fontSize: 13, color: "var(--muted)" }}>
            <div style={{ color: "var(--navy)", fontWeight: 500 }}>{DEALER.name}</div>
            <div>{post.date}</div>
          </div>
        </div>
        <div style={{ marginTop: 28, fontSize: 17, lineHeight: 1.75, color: "var(--navy)", whiteSpace: "pre-wrap", fontFamily: "Newsreader, serif" }}>
          {post.body}
        </div>
        <div style={{ marginTop: 40, padding: "24px 26px", background: "var(--cream-2)", borderRadius: 14, display: "flex", alignItems: "center", gap: 18 }}>
          <Icon name="phone" size={22} stroke="var(--terracotta)" />
          <div style={{ flex: 1, fontSize: 14, lineHeight: 1.55, color: "var(--navy)" }}>
            <strong>Vragen over dit stuk?</strong> Bel of WhatsApp Vincent gerust — <strong>{DEALER.phone}</strong>. Altijd welkom, ook voor advies zonder offerte.
          </div>
        </div>
      </div>
    </div>
  );
};

const BlogGenerator = ({ onDraft }) => {
  const [topic, setTopic] = React.useState("");
  const [loading, setLoading] = React.useState(false);
  const [draft, setDraft] = React.useState(null);
  const [error, setError] = React.useState(null);

  const suggestions = [
    "Het verschil tussen EPS- en minerale-wol-isolatie voor crepi",
    "Hoe je gevel er nog uitziet na 10 jaar",
    "Waarom ik geen offertes via e-mail stuur zonder plaatsbezoek",
    "Gevelrenovatie in combinatie met zonnepanelen — wat eerst?",
  ];

  const generate = async (t) => {
    const subject = (t || topic).trim();
    if (!subject) { setError("Geef eerst een onderwerp in."); return; }
    setError(null); setLoading(true); setDraft(null);
    try {
      const prompt = `Je bent Vincent Ulin, 39, lokale Cralux-gevelverkoper in Kempen-Noord (Zoersel, Schilde, Kalmthout, Essen, Brasschaat). Je bent negen jaar bezig, hebt 260+ gevels begeleid. Je bent geen vlotte copywriter — je schrijft zoals je spreekt: Vlaams-Nederlands, rustig, ambachtelijk, zonder marketing-taal, zonder uitroeptekens, zonder vakjargon dat de klant niet begrijpt. Je vertelt graag een concreet verhaal uit de werf en trekt daaruit een les. Geen bullet points, gewoon paragrafen.

Schrijf een blog-artikel (340-420 woorden) over: "${subject}"

Geef je antwoord terug als geldig JSON, zonder codeblok-markering:
{
  "cat": "korte categorie zoals 'Uit de werf', 'Kleuradvies', 'Nazorg', 'Seizoen', 'Premies' of 'Werf-verhaal'",
  "title": "Titel, klinkt als iets dat Vincent zelf zou zeggen, max 85 tekens",
  "excerpt": "1-2 zinnen hook, 140-180 tekens, geen clickbait",
  "readTime": "bv '3 min'",
  "body": "De volledige tekst. Gebruik \\n\\n tussen paragrafen. Eindig met een regel '— Vincent'.",
  "tone": "warm | cool | terra | sage (kies één die past bij het onderwerp)"
}`;
      const raw = await window.claude.complete(prompt);
      const cleaned = raw.replace(/^```(?:json)?\s*/i, "").replace(/```\s*$/, "").trim();
      const parsed = JSON.parse(cleaned);
      parsed.date = new Date().toLocaleDateString("nl-BE", { day: "2-digit", month: "short", year: "numeric" });
      setDraft(parsed);
    } catch (e) {
      setError("Sorry, dat lukte net niet. Probeer gerust opnieuw — of bel mij, dat werkt ook.");
      console.error(e);
    } finally { setLoading(false); }
  };

  return (
    <div style={{
      padding: 32, borderRadius: 20, background: "var(--navy)", color: "#fff",
      border: "1px solid rgba(255,255,255,0.08)",
    }}>
      <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 8 }}>
        <span style={{ width: 8, height: 8, borderRadius: "50%", background: "var(--sage)", boxShadow: "0 0 0 4px rgba(129,178,154,0.25)" }} />
        <span className="mono-label" style={{ color: "var(--sage)" }}>Vraag Vincent</span>
      </div>
      <h3 className="display" style={{ fontSize: 28, lineHeight: 1.15, color: "#fff", letterSpacing: "-0.015em", maxWidth: 460 }}>
        Benieuwd naar iets specifieks? Vraag mij een stuk.
      </h3>
      <p style={{ fontSize: 14, lineHeight: 1.6, opacity: 0.7, marginTop: 10, maxWidth: 420 }}>
        Geef een onderwerp. Ik schrijf er een kort artikel over — zoals ik het ook aan mijn keukentafel zou uitleggen.
      </p>

      <div style={{ marginTop: 20, display: "flex", gap: 8 }}>
        <input
          value={topic} onChange={e => setTopic(e.target.value)}
          onKeyDown={e => e.key === "Enter" && !loading && generate()}
          placeholder="Bv. ventilatie na gevelisolatie"
          style={{
            flex: 1, padding: "13px 16px", borderRadius: 10,
            background: "rgba(255,255,255,0.08)", border: "1px solid rgba(255,255,255,0.15)",
            color: "#fff", fontSize: 14, fontFamily: "inherit", outline: "none",
          }} />
        <button onClick={() => generate()} disabled={loading} style={{
          padding: "13px 22px", borderRadius: 10, background: "var(--terracotta)",
          color: "#fff", fontSize: 14, fontWeight: 500, whiteSpace: "nowrap",
          opacity: loading ? 0.6 : 1, display: "inline-flex", alignItems: "center", gap: 8,
        }}>
          {loading ? <><span className="spinner" />Schrijft…</> : <>Schrijf <Icon name="arrow-right" size={14} stroke="#fff" /></>}
        </button>
      </div>

      <div style={{ marginTop: 14, display: "flex", gap: 8, flexWrap: "wrap" }}>
        {suggestions.map(s => (
          <button key={s} onClick={() => { setTopic(s); generate(s); }} disabled={loading} style={{
            padding: "6px 12px", borderRadius: 9999, background: "rgba(255,255,255,0.06)",
            border: "1px solid rgba(255,255,255,0.12)", color: "rgba(255,255,255,0.8)",
            fontSize: 12, lineHeight: 1.3,
          }}>{s}</button>
        ))}
      </div>

      {error && (
        <div style={{ marginTop: 16, padding: "10px 14px", borderRadius: 10, background: "rgba(224,122,95,0.15)", color: "#FFC7B5", fontSize: 13 }}>
          {error}
        </div>
      )}

      {draft && (
        <div style={{ marginTop: 24, padding: 24, borderRadius: 14, background: "rgba(255,255,255,0.05)", border: "1px solid rgba(255,255,255,0.12)" }}>
          <div className="mono-label" style={{ color: "var(--sage)" }}>{draft.cat} · {draft.readTime} · concept</div>
          <h4 className="display" style={{ fontSize: 22, lineHeight: 1.2, color: "#fff", marginTop: 8, letterSpacing: "-0.01em" }}>{draft.title}</h4>
          <div style={{ marginTop: 14, maxHeight: 280, overflowY: "auto", paddingRight: 10, fontSize: 14, lineHeight: 1.7, color: "rgba(255,255,255,0.82)", whiteSpace: "pre-wrap", fontFamily: "Newsreader, serif" }}>
            {draft.body}
          </div>
          <div style={{ marginTop: 16, display: "flex", gap: 10, alignItems: "center" }}>
            <button onClick={() => onDraft(draft)} style={{
              padding: "9px 16px", borderRadius: 9999, background: "var(--sage-deep)",
              color: "#fff", fontSize: 13, fontWeight: 500, display: "inline-flex", alignItems: "center", gap: 6,
            }}>
              <Icon name="check" size={14} stroke="#fff" /> Lees volledig
            </button>
            <button onClick={() => generate()} style={{
              padding: "9px 16px", borderRadius: 9999, background: "transparent",
              color: "rgba(255,255,255,0.75)", fontSize: 13, border: "1px solid rgba(255,255,255,0.2)",
            }}>Opnieuw schrijven</button>
            <span style={{ marginLeft: "auto", fontSize: 11, opacity: 0.5 }}>Concept · nog niet gepubliceerd</span>
          </div>
        </div>
      )}
    </div>
  );
};

const Blog = () => {
  const [open, setOpen] = React.useState(null);
  const [tab, setTab] = React.useState("guides");
  const guides = BLOG_POSTS.filter(p => p.kind === "guide");
  const werf   = BLOG_POSTS.filter(p => p.kind !== "guide");
  const shown  = tab === "guides" ? guides : werf;

  // Article schema.org JSON-LD for all gidsen — rich snippets + dateModified signal
  React.useEffect(() => {
    if (document.getElementById("__blog_schema__")) return;
    const parseDate = (d) => {
      // "Bijgewerkt apr 2026" → 2026-04-01 ; "12 apr 2026" → 2026-04-12
      const months = { jan: "01", feb: "02", mrt: "03", apr: "04", mei: "05", jun: "06", jul: "07", aug: "08", sep: "09", okt: "10", nov: "11", dec: "12" };
      const clean = d.toLowerCase().replace("bijgewerkt", "").trim();
      const parts = clean.split(/\s+/);
      if (parts.length === 2) return `${parts[1]}-${months[parts[0].slice(0,3)] || "01"}-01`;
      if (parts.length === 3) return `${parts[2]}-${months[parts[1].slice(0,3)] || "01"}-${parts[0].padStart(2,"0")}`;
      return "2026-01-01";
    };
    const s = document.createElement("script");
    s.type = "application/ld+json";
    s.id = "__blog_schema__";
    s.text = JSON.stringify({
      "@context": "https://schema.org",
      "@graph": guides.map(p => ({
        "@type": "Article",
        headline: p.title,
        description: p.excerpt,
        datePublished: "2025-09-01",
        dateModified: parseDate(p.date),
        author: { "@type": "Person", name: "Vincent Ulin", jobTitle: "Gevelrenovatie-specialist", url: "https://cralux-kempen.be/over" },
        publisher: { "@type": "Organization", name: "Cralux Kempen-Noord", url: "https://cralux-kempen.be" },
        articleSection: p.cat,
        inLanguage: "nl-BE",
      })),
    });
    document.head.appendChild(s);
    return () => { const e = document.getElementById("__blog_schema__"); if (e) e.remove(); };
  }, []);
  return (
    <section id="blog" style={{ padding: "96px 40px", background: "var(--cream)", scrollMarginTop: 80 }}>
      <style>{`
        @keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } }
        .spinner { width: 12px; height: 12px; border-radius: 50%; border: 2px solid rgba(255,255,255,0.3); border-top-color: #fff; display: inline-block; animation: spin 700ms linear infinite; }
        @keyframes spin { to { transform: rotate(360deg) } }
        @media (max-width: 960px) {
          .blog-header { grid-template-columns: 1fr !important; }
          .blog-primary { grid-template-columns: 1fr !important; }
          .blog-primary > a:first-child { grid-column: span 1 !important; }
          .blog-secondary { grid-template-columns: 1fr 1fr !important; }
        }
        @media (max-width: 640px) {
          .blog-secondary { grid-template-columns: 1fr !important; }
        }
      `}</style>
      <div style={{ maxWidth: 1280, margin: "0 auto" }}>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 60, alignItems: "end", marginBottom: 32 }} className="blog-header">
          <div>
            <SectionLabel color="var(--terracotta)">Uit het veld</SectionLabel>
            <h2 className="display" style={{ fontSize: 56, color: "var(--navy)", marginTop: 14, lineHeight: 1.05, letterSpacing: "-0.02em" }}>
              Korte stukjes.<br />
              <em style={{ fontStyle: "italic", color: "var(--sage-deep)", fontWeight: 400 }}>Van mijn hand</em>.
            </h2>
          </div>
          <p style={{ fontSize: 17, lineHeight: 1.65, color: "var(--navy)", opacity: 0.78, paddingBottom: 8 }}>
            Twee soorten: praktische gidsen over prijs, premies en isolatie — en persoonlijke notities uit de werf.
            Lees wat je nodig hebt.
          </p>
        </div>

        {/* Tabs */}
        <div style={{ display: "inline-flex", padding: 4, borderRadius: 9999, background: "var(--cream-2)", border: "1px solid var(--border)", marginBottom: 36 }}>
          {[
            { id: "guides", label: "Gidsen", count: guides.length },
            { id: "werf",   label: "Uit de werf", count: werf.length },
          ].map(t => {
            const active = tab === t.id;
            return (
              <button key={t.id} onClick={() => setTab(t.id)} style={{
                padding: "10px 22px", borderRadius: 9999, fontSize: 14, fontWeight: 500,
                background: active ? "var(--navy)" : "transparent",
                color: active ? "#fff" : "var(--navy)",
                transition: "all 180ms",
                display: "inline-flex", alignItems: "center", gap: 8,
              }}>
                {t.label}
                <span style={{
                  fontSize: 11, padding: "1px 8px", borderRadius: 9999,
                  background: active ? "rgba(255,255,255,0.18)" : "rgba(47,49,72,0.08)",
                  color: active ? "rgba(255,255,255,0.85)" : "var(--muted)",
                }}>{t.count}</span>
              </button>
            );
          })}
        </div>

        {shown.length > 0 && (
          <>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 20, marginBottom: 20 }} className="blog-primary">
              <BlogCard post={shown[0]} onOpen={setOpen} large />
              {shown[1] && <BlogCard post={shown[1]} onOpen={setOpen} />}
            </div>
            {shown.length > 2 && (
              <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 20, marginBottom: 40 }} className="blog-secondary">
                {shown.slice(2).map((p, i) => (
                  <BlogCard key={p.title} post={p} onOpen={setOpen} />
                ))}
              </div>
            )}
          </>
        )}

        <BlogGenerator onDraft={setOpen} />
      </div>

      <BlogModal post={open} onClose={() => setOpen(null)} />
    </section>
  );
};

/* ---------- FAQ ---------- */
const FAQ_ITEMS = [
  { q: "Wat kost een crepi-gevel gemiddeld?",
    a: "Voor 2026 reken je € 88 tot € 120 per m² — inclusief 14 cm isolatie, tweelagige pleister, profielen en plaatsing. Een rijwoning van 110 m² komt op € 10.500 à € 13.200, een vrijstaande woning van 230 m² tussen € 20.300 en € 25.700. Dit is vóór premies — met Mijn.Verbouwpremie + EPC-premie haal je er gemakkelijk € 4.000 à € 5.900 af." },
  { q: "Welke premies kan ik combineren in 2026?",
    a: "In Vlaanderen combineer je Mijn.Verbouwpremie (€ 2.500 – € 4.200) met de EPC-labelpremie (€ 1.250 – € 2.500). Voorwaarde voor de EPC-premie is dat je label met minstens 2 klassen verbetert. Ik regel de aanvragen voor mijn klanten — inclusief het EPC-attest voor én na de werken." },
  { q: "Kan ik mijn gevel isoleren zonder te crepien?",
    a: "Technisch kan, maar zelden verstandig. Buitengevelisolatie zónder afwerking betekent dat je isolatieplaten kwetsbaar zijn voor weer en wind. In de praktijk kies je ofwel crepi, ofwel steenstrips, ofwel gevelcladding — altijd mét afwerking. Wel mogelijk: enkel stucwerk vernieuwen zonder extra isolatie, als je gevel al goed geïsoleerd is." },
  { q: "Hoelang duurt een gevelrenovatie?",
    a: "Voor een gemiddelde woning (160 m² gevel) reken je 2 à 3 weken tussen start en oplevering. De pleisterlagen zelf gaan snel; droogtijden tussen lagen zijn de trage factor. Weer speelt ook mee — onder 5 °C werken we niet, en regen stopt ons tijdelijk. Ik plan altijd een buffer in de offerte." },
  { q: "Werkt crepi ook op oude baksteen?",
    a: "Ja, mits de bestaande gevel stabiel is en geen opstijgend vocht heeft. Bij elke opmeting check ik voegwerk, zettingen en vochtniveau. Bij woningen van voor 1970 adviseer ik meestal minerale wol in plaats van EPS — dampopen, veiliger bij twijfel over vochtevenwicht in de bestaande muren." },
  { q: "Wat is het verschil tussen EPS en minerale wol?",
    a: "EPS (polystyreen) is goedkoper (€ 12 – € 18/m² verschil), lichter en heeft hogere isolatiewaarde per cm. Minerale wol (rotswol) is brandveiliger (klasse A1, onbrandbaar), dampopen en geluidwerender. Voor recente woningen zonder vochtproblemen: EPS. Voor oude huizen of bij brandnormen: minerale wol." },
  { q: "Kan ik offerte per e-mail krijgen zonder plaatsbezoek?",
    a: "Voor een indicatie wel — gebruik de prijssimulator hierboven of stuur foto's plus maten. Voor een definitieve offerte ga ik altijd ter plaatse. Zonder de gevel te zien kan ik geen realistische inschatting maken van voorbereidingswerk, toegankelijkheid en stelling. Het plaatsbezoek is gratis, meestal binnen de week." },
  { q: "Wat als er iets mis gaat na oplevering?",
    a: "Je hebt 10 jaar fabrieksgarantie op het Cralux-systeem, en 5 jaar decennale aansprakelijkheid op mijn plaatsing. In praktijk: bel me. Ik kom langs, we kijken samen wat er is. Zelfs buiten garantie — als het klein is los ik het op zonder factuur. Dat is mijn werkwijze, niet mijn marketing." },
];

const FAQItem = ({ item, open, onToggle, idx }) => (
  <details open={open} onClick={(e) => { e.preventDefault(); onToggle(idx); }} style={{
    background: "var(--white)", borderRadius: 16, border: "1px solid var(--border)",
    padding: 0, overflow: "hidden",
  }}>
    <summary style={{
      listStyle: "none", cursor: "pointer",
      padding: "20px 22px", display: "flex", alignItems: "flex-start", gap: 16,
    }}>
      <div style={{ flex: 1, fontSize: 16, fontWeight: 500, color: "var(--navy)", lineHeight: 1.35, fontFamily: "Jost" }}>
        {item.q}
      </div>
      <div style={{
        width: 28, height: 28, borderRadius: 9999, flexShrink: 0,
        background: open ? "var(--sage-deep)" : "var(--cream-2)",
        color: open ? "#fff" : "var(--navy)",
        display: "flex", alignItems: "center", justifyContent: "center",
        fontSize: 18, fontWeight: 300, lineHeight: 1,
        transform: open ? "rotate(45deg)" : "rotate(0deg)",
        transition: "transform 220ms ease, background 220ms ease, color 220ms ease",
      }}>+</div>
    </summary>
    {open && (
      <div style={{
        padding: "0 22px 22px", fontSize: 14.5, lineHeight: 1.65, color: "var(--muted)",
        animation: "faqFade 220ms ease",
      }}>
        {item.a}
      </div>
    )}
  </details>
);

const FAQ = () => {
  const [openIdx, setOpenIdx] = React.useState(0);
  const toggle = (i) => setOpenIdx(openIdx === i ? -1 : i);

  // FAQPage schema.org JSON-LD injected for SEO
  React.useEffect(() => {
    const existing = document.getElementById("__faq_schema__");
    if (existing) return;
    const s = document.createElement("script");
    s.type = "application/ld+json";
    s.id = "__faq_schema__";
    s.text = JSON.stringify({
      "@context": "https://schema.org",
      "@type": "FAQPage",
      mainEntity: FAQ_ITEMS.map(f => ({
        "@type": "Question",
        name: f.q,
        acceptedAnswer: { "@type": "Answer", text: f.a },
      })),
    });
    document.head.appendChild(s);
    return () => { try { document.head.removeChild(s); } catch(e) {} };
  }, []);

  return (
    <section id="faq" style={{ padding: "96px 40px", background: "var(--cream)", scrollMarginTop: 80 }}>
      <style>{`@keyframes faqFade { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }`}</style>
      <div style={{ maxWidth: 1280, margin: "0 auto" }}>
        <div style={{ display: "grid", gridTemplateColumns: "0.9fr 1.1fr", gap: 60, alignItems: "end", marginBottom: 48 }} className="faq-header">
          <div>
            <SectionLabel color="var(--terracotta)">Veelgestelde vragen</SectionLabel>
            <h2 className="display" style={{ fontSize: 52, color: "var(--navy)", marginTop: 14, lineHeight: 1.05 }}>
              Voor we <em style={{ fontStyle: "italic", color: "var(--sage-deep)", fontWeight: 400 }}>koffie</em> drinken.
            </h2>
          </div>
          <p style={{ fontSize: 17, lineHeight: 1.65, color: "var(--muted)", paddingBottom: 8 }}>
            De acht vragen die ik het vaakst krijg — vóór ik bij iemand op de stoep sta. Staat jouw vraag er niet bij? Bel me, ik pik op.
          </p>
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }} className="faq-grid">
          {FAQ_ITEMS.map((item, i) => (
            <FAQItem key={i} idx={i} item={item} open={openIdx === i} onToggle={toggle} />
          ))}
        </div>
      </div>
      <style>{`
        @media (max-width: 860px) {
          .faq-header { grid-template-columns: 1fr !important; }
          .faq-grid { grid-template-columns: 1fr !important; }
        }
      `}</style>
    </section>
  );
};

/* ---------- About ---------- */
const About = () => (
  <section id="over" style={{ padding: "96px 40px", background: "var(--navy)", color: "#fff", scrollMarginTop: 80 }}>
    <div style={{ maxWidth: 1280, margin: "0 auto" }}>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1.2fr", gap: 64, alignItems: "center" }}>
        <div style={{ position: "relative" }}>
          <div style={{ height: 520, borderRadius: 20, overflow: "hidden", boxShadow: "0 40px 80px -30px rgba(0,0,0,0.4)" }}>
            {/* TODO: vervangen door werk-context-foto Vincent (op werf / bij gevel / showroom met stalenbord), min. 800x1000px */}
            <img src={asset("assets/vincent.jpg")} alt="Vincent Ulin — oprichter Cralux Kempen-Noord" style={{ width: "100%", height: "100%", objectFit: "cover", objectPosition: "center 25%" }} />
          </div>
          {/* Punctuality callout — USP prominent */}
          <div style={{
            position: "absolute", right: -20, bottom: -20, width: 260,
            background: "var(--cream)", color: "var(--navy)",
            borderRadius: 18, padding: "20px 22px",
            boxShadow: "0 30px 60px -20px rgba(0,0,0,0.4)",
          }}>
            <div className="mono-label" style={{ color: "var(--terracotta)", display: "inline-flex", alignItems: "center", gap: 10 }}>
              <span style={{ display: "inline-block", width: 20, height: 2, background: "var(--terracotta)" }} />
              De rode draad
            </div>
            <div className="display" style={{ fontSize: 22, marginTop: 8, lineHeight: 1.15 }}>
              Punctueel <em style={{ fontStyle: "italic", color: "var(--sage-deep)", fontWeight: 400 }}>tot op de minuut</em>.
            </div>
            <div style={{ fontSize: 12, color: "var(--muted)", marginTop: 8, lineHeight: 1.4 }}>
              9u00 is 9u00. Opmeting tot op 0,5 cm.
            </div>
          </div>
          {/* Photo placeholder note */}
          <div style={{
            position: "absolute", left: 12, top: 12,
            padding: "6px 10px", borderRadius: 9999,
            background: "rgba(0,0,0,0.55)", backdropFilter: "blur(6px)",
            fontSize: 10, letterSpacing: "0.08em", textTransform: "uppercase",
            color: "rgba(255,255,255,0.85)",
          }}>
            {/* Te vervangen door werf-foto: Vincent bij een gevel */}
            Placeholder · werf-foto volgt
          </div>
        </div>
        <div>
          <SectionLabel color="var(--sage)">Over Vincent</SectionLabel>
          <h2 className="display" style={{ fontSize: 52, color: "#fff", marginTop: 14, lineHeight: 1.05 }}>
            Al jaren Cralux. <em style={{ fontStyle: "italic", color: "var(--terracotta)", fontWeight: 400 }}>Met dezelfde passie</em>.
          </h2>
          <p style={{ fontSize: 17, lineHeight: 1.7, opacity: 0.88, marginTop: 20, maxWidth: 560 }}>
            Ik werk al verschillende jaren met Cralux aan de mooiste gevels van de regio. Wat begon als een vak,
            werd een echte passie: het verschil zien tussen „wel goed” en „precies juist” — in een voeg, in
            een kleur, in de manier waarop de zon straks op de gevel zal vallen.
          </p>
          <p style={{ fontSize: 15, lineHeight: 1.7, opacity: 0.78, marginTop: 14, maxWidth: 560 }}>
            Wat klanten meestal over me onthouden: ik sta op tijd op de stoep, meet tot op de centimeter, en
            maak graag extra tijd vrij om je project goed te leren kennen vóór we over prijs praten. En na de
            oplevering blijf ik bereikbaar — óók drie jaar later voor een vraag of een kleine retouche.
          </p>
          <div style={{ marginTop: 32, display: "flex", gap: 48, flexWrap: "wrap" }}>
            {[[`${DEALER.years}+`,"Jaar met Cralux"],[`${DEALER.projects}+`,"Gevels begeleid"],["10 jaar","Cralux-garantie"],["∞","Nazorg"]].map(([v,l]) => (
              <div key={l}>
                <div className="display" style={{ fontSize: 34, color: "#fff", lineHeight: 1 }}>{v}</div>
                <div style={{ fontSize: 12, opacity: 0.6, marginTop: 4, letterSpacing: "0.06em", textTransform: "uppercase" }}>{l}</div>
              </div>
            ))}
          </div>
        </div>
      </div>
      {/* Personal trivia strip */}
      <div style={{
        marginTop: 80, paddingTop: 40, borderTop: "1px solid rgba(255,255,255,0.12)",
        display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 32,
      }}>
        <TriviaItem icon="check" label="Reputatie" title="Punctueel tot op de minuut" body="Een afspraak om 9u00 is 9u00. Een opmeting tot op 0,5 cm. Respect voor je tijd is de basis van elk project." />
        <TriviaItem icon="phone" label="Na de verkoop" title="Altijd bereikbaar" body="Een project eindigt niet bij oplevering. Vragen, kleine retouches, premie-documenten — bel of mail gerust, ook jaren later." />
        <TriviaItem icon="leaf" label="Huisdieren" title="Tessa & Loewie" body="Twee katten die meestal de kortste route nemen naar een verse offertemap. Af en toe sluipen ze mee op foto." />
        <TriviaItem icon="calc" label="Passie" title="Schaken" body={`Lid bij ${DEALER.hobbies.chess}. Leert me vooruit denken — iets dat op een werf ook goed van pas komt.`} />
      </div>
    </div>
  </section>
);

const TriviaItem = ({ icon, label, title, body }) => (
  <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
    <div style={{ width: 40, height: 40, borderRadius: 10, background: "rgba(224,122,95,0.18)", display: "flex", alignItems: "center", justifyContent: "center" }}>
      <Icon name={icon} size={18} stroke="var(--terracotta)" />
    </div>
    <div className="mono-label" style={{ color: "rgba(255,255,255,0.5)" }}>{label}</div>
    <div className="display" style={{ fontSize: 22, color: "#fff", lineHeight: 1.2 }}>{title}</div>
    <div style={{ fontSize: 13, opacity: 0.7, lineHeight: 1.55 }}>{body}</div>
  </div>
);

/* ---------- Showroom ---------- */
const Showroom = () => (
  <section id="showroom" style={{ padding: "0 40px 96px", background: "var(--cream)", scrollMarginTop: 80 }}>
    <div style={{ maxWidth: 1280, margin: "0 auto", display: "grid", gridTemplateColumns: "1.1fr 0.9fr", gap: 48, alignItems: "stretch", background: "var(--navy)", borderRadius: 24, overflow: "hidden" }}>
      {/* Te vervangen door echte foto showroom Kontich */}
      <div style={{
        position: "relative", minHeight: 460,
        background: `
          repeating-linear-gradient(135deg, var(--cream) 0 14px, var(--cream-2) 14px 28px)
        `,
      }}>
        <div style={{
          position: "absolute", inset: 0,
          display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center",
          padding: 32, textAlign: "center", gap: 14,
        }}>
          <div style={{
            padding: "6px 12px", borderRadius: 9999,
            background: "var(--navy)", color: "#fff",
            fontSize: 10, letterSpacing: "0.14em", textTransform: "uppercase", fontWeight: 500,
          }}>FOTO · Placeholder</div>
          <div className="display" style={{ fontSize: 24, color: "var(--navy)", maxWidth: 340, lineHeight: 1.2 }}>
            Showroom Kontich — <em style={{ fontStyle: "italic", color: "var(--sage-deep)", fontWeight: 400 }}>echte gevel</em> met 48 stalen.
          </div>
          <div style={{ fontSize: 12, color: "var(--muted)", maxWidth: 280, lineHeight: 1.4 }}>
            Hier komt een echte foto van de showroomgevel.
          </div>
        </div>
        <div style={{ position: "absolute", left: 24, bottom: 24, padding: "10px 16px", borderRadius: 9999, background: "rgba(250,247,242,0.95)", display: "inline-flex", alignItems: "center", gap: 10 }}>
          <span style={{ width: 8, height: 8, borderRadius: "50%", background: "var(--sage-deep)" }} />
          <span style={{ fontSize: 12, color: "var(--navy)", fontWeight: 500 }}>Open op afspraak · Neerveld 13, Kontich</span>
        </div>
      </div>
      <div style={{ padding: "56px 56px 56px 48px", color: "#fff", display: "flex", flexDirection: "column", justifyContent: "center" }}>
        <SectionLabel color="var(--sage)">De showroom</SectionLabel>
        <h2 className="display" style={{ fontSize: 46, color: "#fff", marginTop: 14, lineHeight: 1.05, letterSpacing: "-0.02em" }}>
          40+ kleuren en texturen.<br />
          <em style={{ fontStyle: "italic", color: "var(--terracotta)", fontWeight: 400 }}>Op echte gevel</em>.
        </h2>
        <p style={{ fontSize: 16, lineHeight: 1.65, opacity: 0.82, marginTop: 18, maxWidth: 480 }}>
          De gevel van onze showroom in Kontich is zelf het staalboek. Je ziet elk crepi in drie korrels
          en alle actuele kleuren — niet op een A4 folder, maar op bakstenen-hoog, in echt daglicht.
          Stalen van steenstrips, voegwerken en isolatiepakketten vind je binnen.
        </p>
        <div style={{ marginTop: 32, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 18 }}>
          {[
            { k: "48", l: "crepi-kleuren" },
            { k: "12", l: "steenstrip-types" },
            { k: "3", l: "korrels fijn/middel/grof" },
            { k: "45 min", l: "gemiddeld bezoek" },
          ].map(x => (
            <div key={x.l} style={{ padding: "14px 0", borderTop: "1px solid rgba(255,255,255,0.14)" }}>
              <div className="display" style={{ fontSize: 26, color: "#fff", lineHeight: 1 }}>{x.k}</div>
              <div style={{ fontSize: 12, opacity: 0.65, marginTop: 4 }}>{x.l}</div>
            </div>
          ))}
        </div>
        <div style={{ marginTop: 28, display: "flex", gap: 12, flexWrap: "wrap" }}>
          <Button variant="primary" size="small" onClick={() => { const el = document.getElementById("contact"); if (el) window.scrollTo({ top: el.offsetTop - 80, behavior: "smooth" }); }}>Plan een bezoek</Button>
          <a href={`https://maps.google.com/?q=${encodeURIComponent(DEALER.address)}`} target="_blank" rel="noreferrer" style={{
            padding: "10px 16px", borderRadius: 9999, fontSize: 13, color: "rgba(255,255,255,0.85)",
            border: "1px solid rgba(255,255,255,0.2)", display: "inline-flex", alignItems: "center", gap: 8,
          }}>
            <Icon name="home" size={14} stroke="rgba(255,255,255,0.85)" /> Route berekenen
          </a>
        </div>
        <div style={{ marginTop: 24, fontSize: 12, opacity: 0.55 }}>
          Ma–vr · 9u–17u op afspraak · Zaterdag · 10u–13u (gesloten in augustus)
        </div>
      </div>
    </div>
  </section>
);

/* ---------- Contact ---------- */
const Contact = () => {
  const [form, setForm] = React.useState({ naam: "", email: "", telefoon: "", bericht: "", gemeente: "", adres: "", afwerking: "", timing: "" });
  const [sent, setSent] = React.useState(false);
  return (
    <section id="contact" style={{ padding: "96px 40px", scrollMarginTop: 80 }}>
      <div style={{ maxWidth: 1280, margin: "0 auto" }}>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 64 }}>
          <div>
            <SectionLabel color="var(--terracotta)">Plaatsbezoek</SectionLabel>
            <h2 className="display" style={{ fontSize: 52, color: "var(--navy)", marginTop: 14, lineHeight: 1.05 }}>
              Laten we eens <em style={{ fontStyle: "italic", color: "var(--sage-deep)", fontWeight: 400 }}>koffie drinken</em>.
            </h2>
            <p style={{ fontSize: 17, lineHeight: 1.6, color: "var(--navy)", marginTop: 16, maxWidth: 440 }}>
              Kosteloos plaatsbezoek, meestal binnen de week. Ik kom bij je thuis, meet op, en luister vooral —
              pas daarna praten we over prijs.
            </p>
            <div style={{ marginTop: 32, display: "grid", gap: 18 }}>
              <ContactRow icon="phone" label="Bel of WhatsApp" value={DEALER.phone} sub="ma–za · 8u–19u" />
              <ContactRow icon="mail" label="Mail mij" value={DEALER.email} sub="antwoord binnen 1 werkdag" />
              <ContactRow icon="home" label="Showroom Kontich" value={DEALER.address} sub="op afspraak · ma–vr 9u–17u · za 10u–13u" />
            </div>
            <div style={{
              marginTop: 32, padding: 20, background: "var(--sage)", borderRadius: 14, color: "var(--navy)",
              display: "flex", gap: 14, alignItems: "flex-start",
            }}>
              <Icon name="leaf" size={20} stroke="var(--sage-deep)" />
              <div>
                <div style={{ fontSize: 14, fontWeight: 500 }}>Werkgebied</div>
                <div style={{ fontSize: 13, marginTop: 4, lineHeight: 1.55 }}>
                  {DEALER.towns.join(" · ")} — plus {DEALER.nearby.join(", ")} op aanvraag.
                </div>
              </div>
            </div>
          </div>
          <form onSubmit={e => { e.preventDefault(); setSent(true); }} style={{
            background: "var(--white)", borderRadius: 20, padding: 40, border: "1px solid var(--border)",
            boxShadow: "0 30px 60px -30px rgba(61,64,91,0.12)",
          }}>
            <h3 className="display" style={{ fontSize: 28, color: "var(--navy)", marginBottom: 20 }}>Plan een plaatsbezoek</h3>
            <div style={{ display: "grid", gap: 14 }}>
              <Field label="Naam"><input required value={form.naam} onChange={e => setForm(f => ({...f, naam: e.target.value}))} style={lightInput} /></Field>
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
                <Field label="E-mail"><input type="email" required value={form.email} onChange={e => setForm(f => ({...f, email: e.target.value}))} style={lightInput} /></Field>
                <Field label="Telefoon"><input required value={form.telefoon} onChange={e => setForm(f => ({...f, telefoon: e.target.value}))} style={lightInput} /></Field>
              </div>
              <Field label="Welke afwerking?">
                <ChipGroup
                  value={form.afwerking}
                  onChange={v => setForm(f => ({...f, afwerking: v}))}
                  options={["Crepi", "Steenstrips", "Combinatie", "Weet nog niet"]}
                />
              </Field>
              <Field label="Wanneer starten?">
                <ChipGroup
                  value={form.timing}
                  onChange={v => setForm(f => ({...f, timing: v}))}
                  options={["Binnen 3m", "3–6m", "6m+", "Verkennend"]}
                />
              </Field>
              <Field label="Exact adres" hint="start te typen — suggesties verschijnen">
                <AddressAutocomplete
                  value={form.adres}
                  onChange={v => setForm(f => ({...f, adres: v}))}
                  onSelect={(sel) => setForm(f => ({
                    ...f,
                    adres: sel.formatted,
                    gemeente: sel.gemeente || f.gemeente,
                  }))}
                />
              </Field>
              <Field label="Korte beschrijving (optioneel)">
                <textarea rows={3} value={form.bericht} onChange={e => setForm(f => ({...f, bericht: e.target.value}))} style={{...lightInput, resize: "vertical", fontFamily: "Jost"}} placeholder="Iets wat ik vooraf mag weten? (bv. stellingen, buren, type woning)" />
              </Field>
              <Button variant="primary" type="submit" iconRight="arrow-right">{sent ? "Bedankt — ik bel je binnen 24u!" : "Plan plaatsbezoek"}</Button>
            </div>
          </form>
        </div>
      </div>
    </section>
  );
};

const lightInput = {
  width: "100%", padding: "12px 16px", borderRadius: 10,
  border: "1px solid var(--border)", background: "var(--white)",
  fontSize: 15, fontFamily: "Jost", color: "var(--navy)", outline: "none",
};

const ContactRow = ({ icon, label, value, sub }) => (
  <div style={{ display: "flex", gap: 14, alignItems: "flex-start" }}>
    <div style={{ width: 44, height: 44, borderRadius: 12, background: "rgba(34,125,93,0.1)", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
      <Icon name={icon} size={20} stroke="var(--sage-deep)" />
    </div>
    <div>
      <div className="mono-label" style={{ color: "var(--muted)" }}>{label}</div>
      <div style={{ fontSize: 18, color: "var(--navy)", fontFamily: "Jost", fontWeight: 500, marginTop: 2 }}>{value}</div>
      <div style={{ fontSize: 13, color: "var(--muted)" }}>{sub}</div>
    </div>
  </div>
);

/* ---------- Footer ---------- */
const Footer = () => (
  <footer style={{ padding: "40px 40px 48px" }}>
    <div style={{
      maxWidth: 1280, margin: "0 auto", background: "var(--navy)", color: "#fff",
      borderRadius: 24, padding: "48px 48px",
    }}>
      <div style={{ display: "grid", gridTemplateColumns: "1.4fr 1fr 1fr 1fr", gap: 40 }}>
        <div>
          <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
            <div style={{ width: 38, height: 38, borderRadius: "50%", overflow: "hidden", flexShrink: 0 }}><img src={asset("assets/vincent.jpg")} alt="Vincent" style={{ width: "100%", height: "100%", objectFit: "cover", objectPosition: "center 25%" }} /></div>
            <div>
              <div className="display" style={{ fontSize: 20, color: "#fff", lineHeight: 1.1 }}>{DEALER.name}</div>
              <div style={{ fontSize: 12, opacity: 0.6, letterSpacing: "0.04em" }}>Cralux gevels · {DEALER.region}</div>
            </div>
          </div>
          <div style={{ fontSize: 14, opacity: 0.75, marginTop: 20, lineHeight: 1.65, maxWidth: 320 }}>
            Jouw lokale aanspreekpunt voor gevelrenovatie met crepi of steenstrips. Persoonlijk begeleid,
            punctueel uitgevoerd, en bereikbaar ook na de oplevering.
          </div>
        </div>
        <div>
          <div className="mono-label" style={{ color: "rgba(255,255,255,0.5)" }}>Contact</div>
          <div style={{ marginTop: 10, display: "grid", gap: 6, fontSize: 14 }}>
            <span style={{ opacity: 0.85 }}>{DEALER.address}</span>
            <span style={{ opacity: 0.85 }}>{DEALER.phone}</span>
            <span style={{ color: "var(--sage)" }}>{DEALER.email}</span>
          </div>
        </div>
        <div>
          <div className="mono-label" style={{ color: "rgba(255,255,255,0.5)" }}>Werkgebied</div>
          <div style={{ marginTop: 10, fontSize: 14, lineHeight: 1.7, opacity: 0.85 }}>
            {DEALER.towns.join(" · ")}
          </div>
          <div style={{ fontSize: 12, opacity: 0.55, marginTop: 8, lineHeight: 1.6 }}>
            Op aanvraag: {DEALER.nearby.join(", ")}.
          </div>
        </div>
        <div>
          <div className="mono-label" style={{ color: "rgba(255,255,255,0.5)" }}>Sitemap</div>
          <div style={{ marginTop: 10, display: "grid", gap: 8, fontSize: 14, opacity: 0.85 }}>
            <span>Aanpak</span>
            <span>Gevelopties</span>
            <span>Prijssimulator</span>
            <span>Realisaties</span>
            <span>Contact</span>
          </div>
        </div>
      </div>

      {/* Co-brand strip */}
      <div style={{
        marginTop: 48, padding: "24px 28px", borderRadius: 16,
        background: "rgba(255,255,255,0.04)", border: "1px solid rgba(255,255,255,0.08)",
        display: "flex", alignItems: "center", gap: 20, flexWrap: "wrap",
      }}>
        <div style={{ display: "flex", alignItems: "center", gap: 14 }}>
          {/* Cralux parent brand — real logo */}
          <div style={{
            display: "flex", alignItems: "center", padding: "8px 14px",
            borderRadius: 10, background: "rgba(255,255,255,0.95)",
          }}>
            <img src={asset("assets/cralux-logo.png")} alt="Cralux" style={{ height: 32, width: "auto", display: "block" }} />
          </div>
          <div style={{ fontSize: 13, opacity: 0.65, lineHeight: 1.55, maxWidth: 540 }}>
            In samenwerking met <strong style={{ color: "rgba(255,255,255,0.85)", fontWeight: 500 }}>Cralux</strong>
            — al sinds 1986 Belgisch specialist in gevelrenovatie. Alle werken vallen onder de 10-jarige Cralux-fabrieksgarantie.
          </div>
        </div>
        <div style={{ marginLeft: "auto", fontSize: 12, opacity: 0.5 }}>cralux.be</div>
      </div>

      <div style={{ marginTop: 32, paddingTop: 20, borderTop: "1px solid rgba(255,255,255,0.1)", display: "flex", justifyContent: "space-between", fontSize: 12, opacity: 0.55 }}>
        <span>© 2026 · Vincent Ulin BV · BE 0789.412.503 · Erkend Cralux partner</span>
        <div style={{ display: "flex", gap: 20 }}>
          <button>Privacy policy</button>
          <button>Cookies</button>
          <button>Algemene voorwaarden</button>
        </div>
      </div>
    </div>
  </footer>
);

/* ---------- Sticky CTA bar ---------- */
const StickyBar = ({ onScrollTo }) => {
  const [show, setShow] = React.useState(false);
  React.useEffect(() => {
    const h = () => setShow(window.scrollY > 600);
    window.addEventListener("scroll", h); return () => window.removeEventListener("scroll", h);
  }, []);
  const telHref = `tel:${DEALER.phone.replace(/[^+\d]/g, "")}`;
  return (
    <>
      {/* Desktop floating pill */}
      {show && (
        <div className="sticky-desktop" style={{
          position: "fixed", bottom: 24, left: "50%", transform: "translateX(-50%)", zIndex: 60,
          background: "var(--navy)", color: "#fff", padding: "10px 10px 10px 20px",
          borderRadius: 9999, display: "flex", alignItems: "center", gap: 16,
          boxShadow: "0 20px 40px -10px rgba(61,64,91,0.4)",
        }}>
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <div style={{ width: 32, height: 32, borderRadius: "50%", overflow: "hidden", flexShrink: 0 }}>
              <img src={asset("assets/vincent.jpg")} alt="Vincent" style={{ width: "100%", height: "100%", objectFit: "cover", objectPosition: "center 25%" }} />
            </div>
            <span style={{ fontSize: 14 }}>Direct prijs weten?</span>
          </div>
          <Button variant="terracotta" size="small" onClick={() => onScrollTo("simulator")}>Bereken mijn gevel</Button>
        </div>
      )}
      {/* Mobile bottom-bar (always visible < 760px) */}
      <div className="sticky-mobile" style={{
        position: "fixed", left: 0, right: 0, bottom: 0, zIndex: 60,
        background: "var(--cream)", borderTop: "1px solid var(--border)",
        padding: "12px 14px calc(12px + env(safe-area-inset-bottom, 0px))",
        display: "none", alignItems: "center", gap: 10,
        boxShadow: "0 -12px 30px -15px rgba(61,64,91,0.25)",
      }}>
        <a href={telHref} aria-label="Bel Vincent" style={{
          width: 52, height: 52, borderRadius: "50%", background: "var(--navy)",
          color: "#fff", display: "flex", alignItems: "center", justifyContent: "center",
          flexShrink: 0, textDecoration: "none",
        }}>
          <Icon name="phone" size={22} stroke="#fff" />
        </a>
        <button onClick={() => onScrollTo("simulator")} style={{
          flex: 1, padding: "15px 18px", borderRadius: 9999,
          background: "var(--sage-deep)", color: "#fff",
          fontSize: 15, fontWeight: 500, display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 8,
        }}>
          Bereken mijn gevel <Icon name="arrow-right" size={16} stroke="#fff" />
        </button>
      </div>
      <style>{`
        @media (max-width: 760px) {
          .sticky-desktop { display: none !important; }
          .sticky-mobile { display: flex !important; }
          body { padding-bottom: 84px; }
        }
      `}</style>
    </>
  );
};

/* ---------- Tweaks panel (removed — font keuze vastgezet op Fraunces) ---------- */
const FONT_PRESETS = /*EDITMODE-BEGIN*/{
  "headerFont": "fraunces",
  "bodyFont": "jost"
}/*EDITMODE-END*/;

const Tweaks = () => {
  // Font vast op Fraunces — widget verwijderd per ontwerp-beslissing
  React.useEffect(() => {
    document.documentElement.style.setProperty("--font-display", "Fraunces, serif");
    document.documentElement.style.setProperty("--display-weight", "500");
    document.documentElement.style.setProperty("--display-tracking", "-0.02em");
  }, []);
  return null;
};
const App = () => {
  const [preset, setPreset] = React.useState(null);
  const onScrollTo = (id) => {
    if (id === "top") return window.scrollTo({ top: 0, behavior: "smooth" });
    const el = document.getElementById(id);
    if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
  };
  const onPick = (id) => {
    setPreset(id);
    setTimeout(() => onScrollTo("simulator"), 60);
  };
  return (
    <div>
      <DealerNav onScrollTo={onScrollTo} />
      <DealerHero onScrollTo={onScrollTo} />
      <TrustBar />
      <Approach />
      <GevelOptions onPick={onPick} />
      <PrijsCrepiSimulator />
      <Projects />
      <Werkgebied />
      <Reviews />
      <Blog />
      <FAQ />
      <About />
      <Showroom />
      <Contact />
      <Footer />
      <StickyBar onScrollTo={onScrollTo} />
      <Tweaks />
    </div>
  );
};

if (!window.__SKIP_DEALER_APP_MOUNT) {
  ReactDOM.createRoot(document.getElementById("root")).render(<App />);
}

/* ---------- Export components for subpages (werkgebied/*.html) ---------- */
Object.assign(window, {
  DEALER,
  DealerNav, Breadcrumb, TrustBar, ProjectCard, Contact, Footer, StickyBar,
});
