const { useState, useEffect, useRef, useCallback } = React;

/* ── Router (vanilla History API + custom event) ─────────────────────────── */
function useRoute() {
  const [path, setPath] = useState(() => window.location.pathname);
  useEffect(() => {
    const on = () => setPath(window.location.pathname);
    window.addEventListener('popstate', on);
    window.addEventListener('route-change', on);
    return () => {
      window.removeEventListener('popstate', on);
      window.removeEventListener('route-change', on);
    };
  }, []);
  return path;
}
function navigate(to) {
  if (window.location.pathname === to) {
    window.scrollTo({ top: 0, behavior: 'smooth' });
    return;
  }
  window.history.pushState(null, '', to);
  window.dispatchEvent(new Event('route-change'));
  window.scrollTo(0, 0);
}
function Link({ to, children, className, onClick, ...rest }) {
  function click(e) {
    if (e.metaKey || e.ctrlKey || e.shiftKey || e.button === 1) return;
    if (to.startsWith('http') || to.startsWith('mailto:') || to.startsWith('tel:')) return;
    e.preventDefault();
    if (onClick) onClick(e);
    navigate(to);
  }
  return <a href={to} onClick={click} className={className} {...rest}>{children}</a>;
}

/* ── PricingCard — ported from shadcn, adapted to Vertex design system ── */
const PricingCard = {};

PricingCard.Card = function({ className, featured, children, ...props }) {
  return (
    <div className={`pc-card${featured ? ' pc-card--featured' : ''}${className ? ' '+className : ''}`} {...props}>
      {children}
    </div>
  );
};

PricingCard.Header = function({ className, children, ...props }) {
  return (
    <div className={`pc-header${className ? ' '+className : ''}`} {...props}>
      <div className="pc-header-glow" aria-hidden="true" />
      {children}
    </div>
  );
};

PricingCard.Plan = function({ className, children, ...props }) {
  return <div className={`pc-plan${className ? ' '+className : ''}`} {...props}>{children}</div>;
};

PricingCard.PlanName = function({ className, children, ...props }) {
  return <div className={`pc-plan-name${className ? ' '+className : ''}`} {...props}>{children}</div>;
};

PricingCard.Badge = function({ className, children, ...props }) {
  return <span className={`pc-badge${className ? ' '+className : ''}`} {...props}>{children}</span>;
};

PricingCard.Price = function({ className, children, ...props }) {
  return <div className={`pc-price${className ? ' '+className : ''}`} {...props}>{children}</div>;
};

PricingCard.MainPrice = function({ className, children, ...props }) {
  return <span className={`pc-main-price${className ? ' '+className : ''}`} {...props}>{children}</span>;
};

PricingCard.Period = function({ className, children, ...props }) {
  return <span className={`pc-period${className ? ' '+className : ''}`} {...props}>{children}</span>;
};

PricingCard.OriginalPrice = function({ className, children, ...props }) {
  return <span className={`pc-original${className ? ' '+className : ''}`} {...props}>{children}</span>;
};

PricingCard.Body = function({ className, children, ...props }) {
  return <div className={`pc-body${className ? ' '+className : ''}`} {...props}>{children}</div>;
};

PricingCard.Description = function({ className, children, ...props }) {
  return <p className={`pc-description${className ? ' '+className : ''}`} {...props}>{children}</p>;
};

PricingCard.List = function({ className, children, ...props }) {
  return <ul className={`pc-list${className ? ' '+className : ''}`} {...props}>{children}</ul>;
};

PricingCard.ListItem = function({ on = true, addon = false, addonPrice = '', className, children, ...props }) {
  if (addon) {
    return (
      <li className={`pc-list-item pc-list-item--addon${className ? ' '+className : ''}`} {...props}>
        <span className="pc-check pc-check--addon" aria-hidden="true">+</span>
        <span>{children}</span>
        <span className="pc-addon-price">{addonPrice}</span>
      </li>
    );
  }
  return (
    <li className={`pc-list-item${on ? '' : ' pc-list-item--off'}${className ? ' '+className : ''}`} {...props}>
      <span className={`pc-check${on ? '' : ' pc-check--off'}`} aria-hidden="true">{on ? '✓' : '–'}</span>
      <span>{children}</span>
    </li>
  );
};

PricingCard.Separator = function({ children = 'Upgrade to access', className, ...props }) {
  return (
    <div className={`pc-separator${className ? ' '+className : ''}`} {...props}>
      <span className="pc-sep-line" />
      <span className="pc-sep-text">{children}</span>
      <span className="pc-sep-line" />
    </div>
  );
};

function Carousel({ children, className = '', hint = false }) {
  const trackRef = useRef(null);
  const wrapRef = useRef(null);
  const [active, setActive] = useState(0);
  const hintDone = useRef(false);
  const slides = React.Children.toArray(children);

  const handleScroll = useCallback(() => {
    const el = trackRef.current;
    if (!el) return;
    const slideW = el.scrollWidth / slides.length;
    setActive(Math.round(el.scrollLeft / slideW));
  }, [slides.length]);

  const goTo = (i) => {
    const el = trackRef.current;
    if (!el) return;
    el.scrollTo({ left: (el.scrollWidth / slides.length) * i, behavior: 'smooth' });
  };

  useEffect(() => {
    if (!hint) return;
    const wrap = wrapRef.current;
    if (!wrap) return;
    const observer = new IntersectionObserver(([entry]) => {
      if (!entry.isIntersecting || hintDone.current) return;
      if (window.innerWidth > 640) return;
      hintDone.current = true;
      const el = trackRef.current;
      if (!el) return;
      setTimeout(() => {
        el.scrollTo({ left: 72, behavior: 'smooth' });
        setTimeout(() => {
          el.scrollTo({ left: 0, behavior: 'smooth' });
        }, 480);
      }, 700);
    }, { threshold: 0.5 });
    observer.observe(wrap);
    return () => observer.disconnect();
  }, [hint]);

  return (
    <div className={`carousel ${className}`} ref={wrapRef}>
      <div className="carousel-track" ref={trackRef} onScroll={handleScroll}>
        {slides.map((child, i) => (
          <div className="carousel-slide" key={i}>{child}</div>
        ))}
      </div>
      <div className="carousel-dots">
        {slides.map((_, i) => (
          <button key={i} className={`carousel-dot${active === i ? ' active' : ''}`} onClick={() => goTo(i)} aria-label={`Slide ${i + 1}`} />
        ))}
      </div>
    </div>
  );
}

const DIENSTEN = [
  { icon:'🌐', title:'Websites op maat',          text:'Van strakke one-pager tot volledige B2B-site. Ontwerp, bouw en lancering onder één dak.',                               tags:['One-pager','Bedrijfssite','B2B'] },
  { icon:'🛒', title:'Webshops',                  text:'Snelle checkouts, slimme productpagina\'s en betalingen die gewoon werken.',                                             tags:['E-commerce','Betalingen'] },
  { icon:'📍', title:'Google Business Profile',   text:'Jouw bedrijf bovenaan in Google Maps en zoekresultaten. Volledig ingesteld en geoptimaliseerd.',                        tags:['Local SEO','Google Maps'] },
  { icon:'📈', title:'SEO & vindbaarheid',         text:'Meer bezoekers via Google. Technische SEO, zoekwoordstrategie en maandelijkse rapportage.',                             tags:['SEO','Analytics','Rapport'] },
  { icon:'🔧', title:'Hosting & onderhoud',        text:'Hosting, domein, back-ups en updates. Eén bericht en het is geregeld.',                                                tags:['Hosting','Domein','Updates'] },
  { icon:'✉️', title:'Zakelijk e-mail',            text:'Professioneel e-mailadres op jouw eigen domeinnaam. Serieus overkomen vanaf dag één.',                               tags:['Eigen domein','Professioneel'] },
  { icon:'🤖', title:'AI-receptionist',            text:'Slimme AI die 24/7 telefoon opneemt, vragen beantwoordt en afspraken inboekt. Nooit meer gemiste klanten.',           tags:['24/7','Telefoon','Afspraken'] },
];

// ── Vervang elke FORMSPREE_ID door jouw eigen Formspree form-ID ──
const TIERS = [
  {
    id: 'onepage', name: 'Launch', price: '€289', per: 'eenmalig',
    desc: 'Voor starters en kleine bedrijven die professioneel online zichtbaar willen zijn.',
    features: [
      { label: 'Professionele one page website', on: true },
      { label: 'Modern en mobielvriendelijk design', on: true },
      { label: 'Contactformulier', on: true },
      { label: 'Basis SEO', on: true },
      { label: 'Instellen Google Search Console', on: true },
      { label: 'WhatsApp integratie', on: true },
      { label: '1 revisie ronde inbegrepen', on: true },
      { label: 'Snelle oplevering', on: true },
      { label: 'Boekingssysteem', addon: true, addonPrice: '+€79' },
      { label: 'Beheerdersdashboard', addon: true, addonPrice: '+€89' },
    ],
  },
  {
    id: 'business', name: 'Business', price: '€449', per: 'eenmalig',
    desc: 'Voor bedrijven die meer functionaliteit en een sterkere online aanwezigheid willen.',
    featured: true,
    features: [
      { label: 'Meerdere pagina\'s', on: true },
      { label: 'Professioneel modern design', on: true },
      { label: 'Kleine webshop mogelijk', on: true },
      { label: 'Boekingssysteem inbegrepen', on: true },
      { label: 'Mobiel + tablet optimalisatie', on: true },
      { label: 'Contactformulieren', on: true },
      { label: 'Basis SEO', on: true },
      { label: 'Instellen Google Search Console', on: true },
      { label: 'Social media integratie', on: true },
      { label: '3 revisie rondes inbegrepen', on: true },
      { label: 'Beheerdersdashboard', addon: true, addonPrice: '+€89' },
    ],
  },
  {
    id: 'premium', name: 'Premium Custom', price: 'Custom', per: '',
    desc: 'Volledig professionele website op maat met maximale uitstraling en functionaliteit.',
    promo: {
      tag: '🎁 Promo',
      title: '3 maanden gratis Care abonnement',
      sub: 'Twv. €147 — inclusief hosting, support en updates',
    },
    features: [
      { label: 'Volledig custom premium design', on: true },
      { label: 'Geavanceerde functionaliteiten', on: true },
      { label: 'Boekingssysteem inbegrepen', on: true },
      { label: 'Beheerdersdashboard inbegrepen', on: true },
      { label: 'Performance optimalisatie', on: true },
      { label: 'SEO optimalisatie', on: true },
      { label: 'Instellen Google Search Console', on: true },
      { label: 'Google Business Profiel inbegrepen', on: true },
      { label: 'Mobiel + tablet optimalisatie', on: true },
      { label: 'Tot 5 revisie rondes inbegrepen', on: true },
    ],
  },
];

// ─────────────────────────────────────────────────────────────────────────────

function Nav() {
  const [open, setOpen] = useState(false);
  const path = useRoute();

  useEffect(() => {
    document.body.style.overflow = open ? 'hidden' : '';
    return () => { document.body.style.overflow = ''; };
  }, [open]);

  const close = () => setOpen(false);
  const isActive = (p) => path === p;

  return (
    <>
      <nav className="nav">
        <div className="nav-inner">
          <Link to="/" className="nav-logo" onClick={close}>
            <img src="assets/vertex-logo.jpeg" alt="Vertex Studios" />
          </Link>
          <div className="nav-links">
            <Link to="/diensten" className={isActive('/diensten') ? 'active' : ''}>Diensten</Link>
            <Link to="/prijzen"  className={isActive('/prijzen')  ? 'active' : ''}>Prijzen</Link>
            <Link to="/cases"    className={isActive('/cases')    ? 'active' : ''}>Cases</Link>
            <Link to="/contact"  className={isActive('/contact')  ? 'active' : ''}>Contact</Link>
          </div>
          <Link to="/contact" className="nav-cta">
            Vraag info <span className="arr">→</span>
          </Link>
          <button
            className={`nav-hamburger${open ? ' open' : ''}`}
            onClick={() => setOpen(o => !o)}
            aria-label={open ? 'Menu sluiten' : 'Menu openen'}
          >
            <span /><span /><span />
          </button>
        </div>
      </nav>

      {open && (
        <>
          <div className="mob-backdrop" onClick={close} />
          <div className="mob-sheet">
            <div className="mob-sheet-handle" />
            <nav className="mob-sheet-links">
              <Link to="/diensten" onClick={close}>Diensten</Link>
              <Link to="/prijzen"  onClick={close}>Prijzen</Link>
              <Link to="/cases"    onClick={close}>Cases</Link>
              <Link to="/contact"  onClick={close}>Contact</Link>
            </nav>
            <Link to="/contact" className="btn btn-primary mob-sheet-cta" onClick={close}>
              Vraag info <span className="arr">→</span>
            </Link>
          </div>
        </>
      )}
    </>
  );
}

const HERO_TRUST_ITEMS = [
  'Geen verplichtingen',
  'Vaste prijs, geen verborgen kosten',
  'Reactie binnen 24 uur op werkdagen',
  'Live binnen 48 uur na akkoord',
  'Op maat gebouwd, geen templates',
  'Mobiel-eerst design',
  'SEO-klaar bij oplevering',
];

function HeroTrustCarousel() {
  // Dupliceer items 2x voor naadloze loop
  const items = [...HERO_TRUST_ITEMS, ...HERO_TRUST_ITEMS];
  return (
    <div className="hero-trust-marquee reveal" style={{transitionDelay:'.22s'}} aria-hidden="true">
      <div className="htm-track">
        {items.map((text, i) => (
          <span key={i} className="htm-item">
            <span className="htm-dot">★</span>
            {text}
          </span>
        ))}
      </div>
    </div>
  );
}

function Hero() {
  return (
    <section className="hero" id="top">
      <div className="hero-inner">
        <div className="hero-left">
          <Link to="/prijzen" className="hero-ai-pill reveal" style={{transitionDelay:'.04s'}}>
            <span className="hero-ai-pill-dot" />
            <span className="hero-ai-pill-tag">NIEUW</span>
            <span className="hero-ai-pill-text">AI-receptionist · 24/7 telefoon · vanaf €49/mnd</span>
            <span className="hero-ai-pill-arr">→</span>
          </Link>
          <h1 className="reveal r-blur" style={{transitionDelay:'.08s'}}>
            Jouw nieuwe website.<br/><em>Live in 48 uur</em>.
          </h1>
          <p className="hero-sub reveal r-d2" style={{transitionDelay:'.18s'}}>
            Snelle, mobiel-sterke websites op maat voor Belgische KMO's. Vanaf <strong style={{color:'var(--ink)'}}>€289</strong> — vaste prijs, geen verborgen kosten.
          </p>

          <div className="hero-ctas reveal" style={{transitionDelay:'.19s'}}>
            <Link to="/contact" className="btn btn-primary btn-lg">
              Vraag info aan <span className="arr">→</span>
            </Link>
            <Link to="/prijzen" className="btn btn-secondary btn-lg">
              Bekijk prijzen
            </Link>
          </div>

          <ul className="hero-checks reveal" style={{transitionDelay:'.26s'}}>
            <li><span className="ck">✓</span>Live binnen 48 uur na akkoord</li>
            <li><span className="ck">✓</span>Op maat ontworpen, geen templates</li>
            <li><span className="ck">✓</span>Eerlijke prijs vanaf €289, BTW incl. mogelijk</li>
          </ul>
        </div>

        <div className="hero-right reveal" style={{transitionDelay:'.11s'}}>
          <div className="hero-glow" />
          <div className="hero-mockup">
            <div className="hm-bar">
              <div className="hm-dot" style={{background:'#ff5f57'}} />
              <div className="hm-dot" style={{background:'#febc2e'}} />
              <div className="hm-dot" style={{background:'#28c840'}} />
              <div className="hm-url">jouwwebsite.be</div>
            </div>
            <div className="hm-body">
              <div className="hm-hero-block" />
              <div className="hm-row">
                <div className="hm-card" /><div className="hm-card" /><div className="hm-card" />
              </div>
              <div className="hm-line" />
              <div className="hm-line s" />
              <div className="hm-line t" />
              <div className="hm-cursor">
                <svg viewBox="0 0 24 24" fill="var(--accent)"><path d="M3 2l7 18 2.5-7.5L20 10z"/></svg>
              </div>
            </div>
          </div>
          <div className="hero-pills">
            <span className="h-pill"><span className="pi">⚡</span>Vanaf 48 uur live</span>
            <span className="h-pill"><span className="pi">★</span>SEO-klaar</span>
            <span className="h-pill"><span className="pi">↗</span>Mobiel-vriendelijk</span>
          </div>
        </div>
      </div>
    </section>
  );
}

const DIENSTEN_ITEMS = [
  { title: 'Websites op maat',    subtitle: 'Van one-pager tot volledige B2B-site met eigen beheerdersdashboard', icon: '🌐' },
  { title: 'Basis SEO',           subtitle: 'Goede technische basis om vindbaar te zijn in Google', icon: '📈' },
  { title: 'Webshops',            subtitle: 'Eigen online winkel met productbeheer en veilige betalingen', icon: '🛒' },
  { title: 'Hosting & onderhoud', subtitle: 'Snel, veilig en altijd online',             icon: '⚡' },
  { title: 'Zakelijk e-mail',     subtitle: 'Professioneel adres op jouw eigen domein',   icon: '✉️' },
  { title: 'Google Business',     subtitle: 'Instellen & optimaliseren Google Business Profiel', icon: '📍' },
  { title: 'AI-receptionist',     subtitle: '24/7 telefoon opnemen, vragen beantwoorden en afspraken inboeken', icon: '🤖' },
];

// Uitgebreide uitleg per dienst voor /diensten detail-grid
const DIENSTEN_DETAIL = [
  {
    icon: '🌐',
    title: 'Websites op maat',
    body: 'Elke site bouwen we volledig op maat — geen templates, geen page builders. Van strakke one-pager tot uitgebreide B2B-site, mét optioneel eigen beheerdersdashboard zodat je zelf teksten, afbeeldingen of producten kan aanpassen zonder ons te bellen.',
  },
  {
    icon: '📈',
    title: 'Basis SEO',
    body: 'Elke website krijgt standaard een solide technische SEO-basis: snelle laadtijden, correcte metadata, sitemap, robots.txt, juiste headings en mobiel-vriendelijke structuur. Geen maandelijkse abonnementen of trucs — gewoon de fundamenten waar Google van houdt.',
  },
  {
    icon: '🛒',
    title: 'Webshops',
    body: 'Een eigen online winkel met overzichtelijk productbeheer, veilige betalingen (Bancontact, Visa, Mastercard), bestellingsstatus en automatische facturatie. Geschikt voor lokale handelaars die controle willen over hun verkoop zonder afhankelijk te zijn van platforms.',
  },
  {
    icon: '⚡',
    title: 'Hosting & onderhoud',
    body: 'Wij regelen alles wat technisch is: hosting bij een snelle Europese provider, SSL-certificaten, dagelijkse back-ups, updates en monitoring. Stuur ons een berichtje voor aanpassingen — meestal binnen 24 uur live. Inbegrepen in onze maandabonnementen.',
  },
  {
    icon: '✉️',
    title: 'Zakelijk e-mail',
    body: 'Een professioneel e-mailadres op jouw eigen domein (jij@jouwbedrijf.be) ipv generiek Gmail of Outlook. Inclusief setup, configuratie op al je toestellen, spamfilter en mogelijkheid tot extra mailboxen voor team of afdelingen.',
  },
  {
    icon: '📍',
    title: 'Google Business Profiel',
    body: 'We zetten je Google Business Profiel volledig in orde: openingsuren, foto\'s, diensten, locaties, beoordelingen-link en eerste content. Zo verschijn je correct in Google Maps en lokale zoekresultaten — essentieel voor elk lokaal bedrijf.',
  },
  {
    icon: '🤖',
    title: 'AI-receptionist',
    body: 'Een slimme AI die 24/7 jouw telefoon opneemt, veelgestelde vragen beantwoordt, afspraken inboekt en boodschappen doorgeeft. Klinkt natuurlijk, spreekt Nederlands en mist nooit een oproep — ideaal voor zelfstandigen en KMO\'s die geen klanten meer willen verliezen aan een voicemail.',
  },
];

function Diensten() {
  return (
    <section id="diensten">
      <div className="sec-head reveal">
        <div>
          <h2>Alles wat een <em>bedrijf</em><br/>online nodig heeft.</h2>
        </div>
        <p className="lead">Van het eerste schetsje tot de knop die 's nachts om drie uur nog moet werken — wij regelen het end-to-end.</p>
      </div>
      <div className="wrap">
        <div className="diensten-feature reveal">
          <div className="diensten-scroll-card">
            <div className="diensten-fade-top" />
            <div className="diensten-scroll-track">
              {[...DIENSTEN_ITEMS, ...DIENSTEN_ITEMS].map((item, i) => (
                <div className="diensten-scroll-item" key={i}>
                  <div className="diensten-scroll-icon">{item.icon}</div>
                  <div>
                    <p className="diensten-scroll-title">{item.title}</p>
                    <p className="diensten-scroll-sub">{item.subtitle}</p>
                  </div>
                </div>
              ))}
            </div>
            <div className="diensten-fade-bottom" />
          </div>
          <div className="diensten-content">
            <h3>Eén partner voor je <em>volledige</em> website.</h3>
            <p>Van eerste schets tot live website — wij ontwerpen, bouwen en onderhouden alles. Geen freelancer-chaos, één aanspreekpunt dat weet wat je nodig hebt.</p>
            <div className="diensten-tags">
              <span className="dtag">Op maat</span>
              <span className="dtag">Snel live</span>
              <span className="dtag">End-to-end</span>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

function WebsitePrijzen() {
  return (
    <div className="prijzen-block reveal">
      <span className="eb prijzen-label">Bouwen · eenmalig</span>
      <h3 className="prijzen-title">Een nieuwe website, op jouw maat.</h3>
      <Carousel className="tier-carousel" hint={true}>
        {TIERS.map((t) => (
          <PricingCard.Card key={t.id} featured={t.featured}>
            <PricingCard.Header>
              <PricingCard.Plan>
                <PricingCard.PlanName>{t.name}</PricingCard.PlanName>
                {t.featured && <PricingCard.Badge>★ Aanbevolen</PricingCard.Badge>}
              </PricingCard.Plan>
              <PricingCard.Price>
                <PricingCard.MainPrice>{t.price}</PricingCard.MainPrice>
                {t.per && t.per !== 'op aanvraag' && <PricingCard.Period>{`· ${t.per}`}</PricingCard.Period>}
                {t.per === 'op aanvraag' && <PricingCard.Period>op aanvraag</PricingCard.Period>}
              </PricingCard.Price>
            </PricingCard.Header>
            <PricingCard.Body>
              <PricingCard.Description>{t.desc}</PricingCard.Description>
              {t.promo && (
                <div className="tier-promo">
                  <span className="tier-promo-tag">{t.promo.tag}</span>
                  <div className="tier-promo-title">{t.promo.title}</div>
                  <div className="tier-promo-sub">{t.promo.sub}</div>
                </div>
              )}
              <PricingCard.List>
                {t.features.map((f, j) => (
                  <PricingCard.ListItem key={j} on={f.on} addon={f.addon} addonPrice={f.addonPrice}>{f.label}</PricingCard.ListItem>
                ))}
              </PricingCard.List>
            </PricingCard.Body>
          </PricingCard.Card>
        ))}
      </Carousel>
    </div>
  );
}

function OnderhoudPrijzen() {
  const [billing, setBilling] = useState('monthly');
  const [changing, setChanging] = useState(false);

  function switchBilling(val) {
    if (val === billing) return;
    setChanging(true);
    setTimeout(() => { setBilling(val); setChanging(false); }, 160);
  }

  const monthlyPrice = '€49';
  const annualPriceEffective = '€39'; // €49 × 12 × 0.8 ÷ 12 ≈ €39 (20% korting)
  const annualBilledTotal = '€468'; // €39 × 12

  const baseFeatures = [
    'Hosting & SSL',
    'Website onderhoud & updates',
    'Aanpassingen binnen 8 uur',
    'Google Business Profiel setup & optimalisatie',
  ];
  const annualBonus = [
    'Gratis domeinnaam',
    'Gratis zakelijke e-mail op eigen domein',
  ];

  return (
    <div className="prijzen-block reveal">
      <h3 className="prijzen-title">Hosting, onderhoud & <em>support</em> in één.</h3>

      <div className="billing-toggle-wrap">
        <div className="billing-toggle">
          <div className={`billing-opt${billing === 'monthly' ? ' active' : ''}`} onClick={() => switchBilling('monthly')}>
            Maandelijks
          </div>
          <div className={`billing-opt${billing === 'annual' ? ' active' : ''}`} onClick={() => switchBilling('annual')}>
            Jaarlijks
          </div>
        </div>
        <span className={`billing-save${billing === 'annual' ? '' : ' hidden'}`}>Bespaar 20%</span>
      </div>

      <div className="care-single">
        <div className="care-card">
          <div className="care-tier-label">Care abonnement</div>
          <div className="care-price">
            <span className={`care-price-num${changing ? ' changing' : ''}`}>
              {billing === 'annual' ? annualPriceEffective : monthlyPrice}
            </span>
            <sub> / mnd</sub>
          </div>
          <div className="care-billing-note">
            {billing === 'annual'
              ? `Jaarlijks gefactureerd · ${annualBilledTotal}/jaar`
              : 'Maandelijks opzegbaar · minimum 3 maanden'}
          </div>
          <div className="care-desc">Alles wat je nodig hebt om je site live en up-to-date te houden, met snelle support.</div>
          <div className="care-divider" />
          <div className="care-features">
            {baseFeatures.map((label, i) => (
              <div key={i} className="care-feat"><span className="si on">✓</span>{label}</div>
            ))}
            {billing === 'annual' && (
              <>
                <div className="care-feat care-bonus-label">🎁 Extra bij jaarlijkse betaling:</div>
                {annualBonus.map((label, i) => (
                  <div key={'b'+i} className="care-feat care-bonus"><span className="si on">✓</span>{label}</div>
                ))}
              </>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

function AIReceptionistPrijzen() {
  const features = [
    '24/7 telefoon opnemen — nooit meer gemiste oproepen',
    'Spreekt natuurlijk Nederlands',
    'Beantwoordt veelgestelde vragen over jouw bedrijf',
    'Boekt afspraken rechtstreeks in je agenda',
    'Stuurt boodschappen door via e-mail of WhatsApp',
    'Volledig getraind op jouw business',
    'Eenmalige setup-kost €149 (training + integratie)',
    'Maandelijks opzegbaar',
  ];
  return (
    <div className="prijzen-block reveal">
      <span className="eb prijzen-label">Nieuw · abonnement</span>
      <h3 className="prijzen-title">AI-receptionist die <em>nooit</em> een klant mist.</h3>
      <p className="prijzen-sub">Een slimme AI-assistent die 24/7 je telefoon opneemt, vragen beantwoordt en afspraken inboekt. Klinkt natuurlijk, werkt continu, kost een fractie van een receptioniste.</p>
      <div className="care-single">
        <div className="care-card">
          <div className="care-tier-label">AI-receptionist</div>
          <div className="care-price">
            <span className="care-price-num">€49 – €99</span>
            <sub> / mnd</sub>
          </div>
          <div className="care-billing-note">Afhankelijk van belgebruik · Maandelijks opzegbaar · <strong style={{color:'var(--ink)'}}>€149 eenmalige setup</strong></div>
          <div className="care-desc">Een digitale receptioniste die nooit ziek is, nooit op vakantie gaat en altijd professioneel klinkt.</div>
          <div className="care-divider" />
          <div className="care-features">
            {features.map((label, i) => (
              <div key={i} className="care-feat"><span className="si on">✓</span>{label}</div>
            ))}
          </div>
          <div className="care-divider" />
          <div style={{background:'rgba(255,122,69,0.06)',border:'1px solid rgba(255,122,69,0.2)',borderRadius:'12px',padding:'16px 18px',margin:'4px 0 16px'}}>
            <div style={{fontSize:'13px',fontWeight:700,letterSpacing:'.06em',textTransform:'uppercase',color:'var(--accent)',marginBottom:'8px'}}>💡 Waarom varieert de prijs?</div>
            <p style={{fontSize:'14px',lineHeight:'1.6',color:'var(--ink2)',margin:0}}>
              De AI-receptionist draait op een gespecialiseerd telefonie-platform dat <strong style={{color:'var(--ink)'}}>per gesprekminuut</strong> rekent. Je maandbedrag past zich aan je werkelijke belvolume aan:
            </p>
            <ul style={{listStyle:'none',padding:0,margin:'12px 0 0',display:'flex',flexDirection:'column',gap:'6px'}}>
              <li style={{fontSize:'13px',color:'var(--ink2)',display:'flex',gap:'10px'}}><strong style={{color:'var(--accent)',minWidth:'70px'}}>€49/mnd</strong> rustige maand — beperkt belverkeer</li>
              <li style={{fontSize:'13px',color:'var(--ink2)',display:'flex',gap:'10px'}}><strong style={{color:'var(--accent)',minWidth:'70px'}}>€79/mnd</strong> gemiddeld gebruik — typische maand</li>
              <li style={{fontSize:'13px',color:'var(--ink2)',display:'flex',gap:'10px'}}><strong style={{color:'var(--accent)',minWidth:'70px'}}>€99/mnd</strong> druk belverkeer — plafond, je betaalt nooit meer</li>
            </ul>
            <p style={{fontSize:'13px',lineHeight:'1.55',color:'var(--ink3)',margin:'12px 0 0',fontStyle:'italic'}}>
              Eerlijk en transparant: je betaalt wat je gebruikt, met een vast plafond zodat je nooit voor verrassingen komt te staan. Maandelijks krijg je een overzicht van het aantal gesprekken en minuten.
            </p>
          </div>
          <a href="https://intake.vertexstudios.info" target="_blank" rel="noopener" className="btn btn-primary btn-lg" style={{marginTop:'4px',justifyContent:'center'}}>
            Start intake <span className="arr">→</span>
          </a>
          <p className="care-billing-note" style={{textAlign:'center',marginTop:'10px'}}>
            Vul het intakeformulier in zodat we je AI-receptionist op maat kunnen trainen.
          </p>
        </div>
      </div>
    </div>
  );
}

function Prijzen() {
  return (
    <section id="prijzen">
      <div className="sec-head reveal">
        <div>
          <h2>Eerlijke <em>pakketten</em>,<br/>geen verborgen kosten.</h2>
        </div>
        <p className="lead">Kies een bouwpakket dat past bij je doel en koppel er optioneel een onderhoudsabonnement of AI-receptionist aan. Transparant, opzegbaar.</p>
      </div>
      <div className="hosting-notice reveal">
        <span className="hosting-notice-icon">⚡</span>
        <p>Inclusief <strong>1 maand gratis hosting</strong> zodat jouw website meteen live kan bij oplevering.</p>
      </div>
      <div className="wrap">
        <WebsitePrijzen />
        <OnderhoudPrijzen />
        <AIReceptionistPrijzen />
      </div>
    </section>
  );
}

function Footer({ onPrivacy, onTerms, onCookies }) {
  return (
    <footer>
      <div className="footer-row">
        <div className="footer-logo">
          <img src="assets/vertex-logo.jpeg" alt="Vertex Studios" />
        </div>
        <nav className="footer-links">
          <a href="mailto:oliver@vertexstudios.info">oliver@vertexstudios.info</a>
          <a href="#" onClick={e => { e.preventDefault(); onPrivacy(); }}>Privacybeleid</a>
          <a href="#" onClick={e => { e.preventDefault(); onTerms(); }}>Algemene voorwaarden</a>
          <a href="#" onClick={e => { e.preventDefault(); onCookies(); }}>Cookiebeleid</a>
        </nav>
        <span className="footer-copy">© 2026 Vertex Studios · KBO 0777.834.189 · BTW BE0777834189 · RPR Antwerpen, afd. Hasselt</span>
      </div>
    </footer>
  );
}

function LegalIdBlock() {
  return (
    <p style={{fontSize:12.5,color:'rgba(237,233,227,.55)',lineHeight:1.65,margin:'0 0 18px'}}>
      <strong style={{color:'var(--ink)'}}>Vertex Studios</strong> — eenmanszaak Oliver Silot<br/>
      KBO/ondernemingsnummer: 0777.834.189 · BTW: BE0777834189<br/>
      RPR Antwerpen, afdeling Hasselt · Maatschappelijke zetel op aanvraag<br/>
      E-mail: <a href="mailto:oliver@vertexstudios.info" style={{color:'var(--accent)'}}>oliver@vertexstudios.info</a> · Website: vertexstudios.info
    </p>
  );
}

function PrivacyModal({ onClose }) {
  return (
    <div className="privacy-backdrop" onClick={onClose}>
      <div className="privacy-box" onClick={e => e.stopPropagation()}>
        <h2>Privacybeleid</h2>
        <LegalIdBlock />

        <h3>1. Verwerkingsverantwoordelijke</h3>
        <p>Vertex Studios is verantwoordelijk voor de verwerking van persoonsgegevens via deze website, conform de Algemene Verordening Gegevensbescherming (AVG / GDPR).</p>

        <h3>2. Welke gegevens verzamelen wij?</h3>
        <ul>
          <li>Naam, bedrijfsnaam en e-mailadres via het contactformulier</li>
          <li>Telefoonnummer (optioneel) en interesse-pakket via het contactformulier</li>
          <li>Inhoud van je bericht / projectbeschrijving</li>
          <li>Technische logs (IP-adres, browsertype) via Vercel hosting voor beveiligings- en performancedoeleinden</li>
        </ul>

        <h3>3. Doeleinden en rechtsgrond</h3>
        <ul>
          <li>Contact opnemen over jouw aanvraag — grondslag: <em>uitvoering overeenkomst / gerechtvaardigd belang</em></li>
          <li>Beantwoorden van vragen en opmaken van offertes — grondslag: <em>uitvoering precontractuele maatregelen</em></li>
          <li>Wettelijke verplichtingen (boekhouding, fiscaal)</li>
          <li>We verkopen jouw gegevens nooit aan derden</li>
        </ul>

        <h3>4. Bewaartermijn</h3>
        <p>Jouw gegevens worden bewaard zolang nodig voor de afhandeling van jouw aanvraag, en daarna maximaal 2 jaar (commerciële opvolging). Facturatie-data: 7 jaar conform fiscale wetgeving.</p>

        <h3>5. Verwerkers (derden)</h3>
        <p>We delen je gegevens uitsluitend met onderstaande verwerkers die voor ons noodzakelijke diensten leveren:</p>
        <ul>
          <li><strong>Vercel</strong> (hosting) — VS, gebruikt EU-data residency</li>
          <li><strong>Formspree</strong> (contactformulier verwerking) — verwerkt formulierdata</li>
          <li><strong>Hostinger</strong> (e-mailhosting oliver@vertexstudios.info) — EU-server</li>
        </ul>

        <h3>6. Jouw rechten</h3>
        <p>Je hebt onder de AVG het recht op: inzage, rectificatie, verwijdering (<em>right to be forgotten</em>), beperking, overdraagbaarheid en bezwaar. Mail je verzoek naar <a href="mailto:oliver@vertexstudios.info" style={{color:'var(--accent)'}}>oliver@vertexstudios.info</a> — we reageren binnen 30 dagen.</p>
        <p>Niet tevreden? Je kan klacht indienen bij de <a href="https://www.gegevensbeschermingsautoriteit.be" target="_blank" rel="noopener" style={{color:'var(--accent)'}}>Gegevensbeschermingsautoriteit</a> (Drukpersstraat 35, 1000 Brussel).</p>

        <h3>7. Cookies</h3>
        <p>Zie ons <strong>Cookiebeleid</strong> in de footer voor details.</p>

        <h3>8. Wijzigingen</h3>
        <p>Dit beleid kan aangepast worden. De versie hieronder is van kracht: <strong>18 mei 2026</strong>.</p>

        <button className="privacy-close" onClick={onClose}>Sluiten</button>
      </div>
    </div>
  );
}

function TermsModal({ onClose }) {
  return (
    <div className="privacy-backdrop" onClick={onClose}>
      <div className="privacy-box" onClick={e => e.stopPropagation()}>
        <h2>Algemene voorwaarden</h2>
        <LegalIdBlock />
        <p style={{fontSize:13,color:'rgba(237,233,227,.6)',marginBottom:14}}>Versie van 18 mei 2026. Van toepassing op alle overeenkomsten met Vertex Studios.</p>

        <h3>1. Definities</h3>
        <ul>
          <li><strong>Vertex Studios:</strong> de eenmanszaak Oliver Silot, KBO 0777.834.189.</li>
          <li><strong>Klant:</strong> elke natuurlijke of rechtspersoon die een overeenkomst sluit met Vertex Studios.</li>
          <li><strong>Diensten:</strong> webdesign, webontwikkeling, hosting, onderhoud, SEO, en aanverwante digitale diensten.</li>
          <li><strong>Website:</strong> de digitale oplevering die het voorwerp uitmaakt van de overeenkomst.</li>
        </ul>

        <h3>2. Toepasselijkheid</h3>
        <p>Deze voorwaarden zijn van toepassing op elke offerte, opdracht en overeenkomst. Afwijkende voorwaarden van de Klant zijn enkel geldig na uitdrukkelijk schriftelijk akkoord van Vertex Studios.</p>

        <h3>3. Offertes en overeenkomst</h3>
        <ul>
          <li>Offertes zijn 30 dagen geldig en vrijblijvend.</li>
          <li>De overeenkomst komt tot stand bij schriftelijke bevestiging of betaling van de eerste factuur.</li>
          <li>Wijzigingen in de scope na bevestiging worden afzonderlijk gefactureerd.</li>
        </ul>

        <h3>4. Prijzen en betaling</h3>
        <ul>
          <li>Prijzen zijn exclusief 21% BTW, tenzij anders vermeld.</li>
          <li><strong>Eenmalige projecten:</strong> 50% voorschot bij aanvang, 50% bij oplevering vóór ingebruikname.</li>
          <li><strong>Onderhoudsabonnementen:</strong> maandelijks of jaarlijks vooraf gefactureerd. Minimumduur: 3 maanden.</li>
          <li>Facturen zijn betaalbaar binnen <strong>14 dagen</strong> na factuurdatum.</li>
          <li>Bij laattijdige betaling: van rechtswege en zonder ingebrekestelling een verwijlintrest van 10% per jaar én een forfaitaire schadevergoeding van 10% (min. €50) conform art. XX.5 e.v. WER.</li>
        </ul>

        <h3>5. Uitvoering en termijnen</h3>
        <ul>
          <li>Opgegeven termijnen zijn streefdata, geen bindende deadlines, tenzij uitdrukkelijk schriftelijk overeengekomen.</li>
          <li>De Klant levert tijdig content (teksten, beelden, logo's, toegangen). Vertraging in aanlevering verlengt de oplevertermijn proportioneel.</li>
          <li>Goedkeuring van designs of milestones gebeurt binnen 7 kalenderdagen; bij stilzwijgen wordt het werk als goedgekeurd beschouwd.</li>
        </ul>

        <h3>6. Oplevering en aanvaarding</h3>
        <p>Na oplevering heeft de Klant 7 kalenderdagen om gebreken schriftelijk te melden. Daarna wordt de Website geacht aanvaard te zijn. Kleine wijzigingen na aanvaarding vallen onder onderhoud of worden apart gefactureerd.</p>

        <h3>7. Eigendom en gebruiksrecht</h3>
        <ul>
          <li>Vertex Studios behoudt het auteursrecht op alle creaties tot volledige betaling.</li>
          <li>Na volledige betaling krijgt de Klant een onbeperkt gebruiksrecht op de opgeleverde Website.</li>
          <li>Broncode, design-systeem en gebruikte libraries blijven eigendom van Vertex Studios; de Klant ontvangt het recht om de site te gebruiken, niet om door te verkopen.</li>
          <li>Vertex Studios mag de Website opnemen in haar portfolio en als case study gebruiken, tenzij anders schriftelijk overeengekomen.</li>
        </ul>

        <h3>8. Hosting & onderhoud</h3>
        <ul>
          <li>Onderhoudsabonnementen lopen automatisch maandelijks/jaarlijks door tot opzegging.</li>
          <li><strong>Opzegtermijn:</strong> 1 maand, schriftelijk per e-mail, na minimum 3 maanden.</li>
          <li>Vertex Studios garandeert geen 100% uptime maar streeft naar minimaal 99,5%.</li>
        </ul>

        <h3>9. Aansprakelijkheid</h3>
        <ul>
          <li>Vertex Studios is aansprakelijk voor directe schade door zware fout, opzet of bedrog, beperkt tot het bedrag van de overeenkomst over de laatste 6 maanden.</li>
          <li>Vertex Studios is niet aansprakelijk voor indirecte schade, gevolgschade, gederfde winst, gegevensverlies of imagoschade.</li>
          <li>Vertex Studios is niet aansprakelijk voor schade door content aangeleverd door de Klant, voor problemen bij derde leveranciers (hosting, domeinregistratie), of voor overmacht.</li>
        </ul>

        <h3>10. Annulatie</h3>
        <ul>
          <li>Bij annulatie door de Klant vóór aanvang: 25% van het projectbedrag verschuldigd.</li>
          <li>Bij annulatie tijdens uitvoering: reeds uitgevoerd werk + 25% van het resterende bedrag.</li>
          <li>Reeds betaalde voorschotten zijn niet-terugvorderbaar.</li>
        </ul>

        <h3>11. Vertrouwelijkheid</h3>
        <p>Beide partijen behandelen alle bedrijfsinformatie van de andere partij vertrouwelijk en gebruiken die uitsluitend voor de uitvoering van de overeenkomst.</p>

        <h3>12. Toepasselijk recht en geschillen</h3>
        <p>Op deze overeenkomst is uitsluitend het <strong>Belgisch recht</strong> van toepassing. Geschillen worden in eerste instantie minnelijk besproken. Bij gebrek aan akkoord zijn enkel de rechtbanken van het arrondissement <strong>Antwerpen, afdeling Hasselt</strong> bevoegd.</p>

        <h3>13. Geschillenbeslechting (B2C)</h3>
        <p>Indien de Klant een consument is, kan deze ook beroep doen op het <a href="https://ec.europa.eu/consumers/odr" target="_blank" rel="noopener" style={{color:'var(--accent)'}}>ODR-platform van de Europese Commissie</a> voor online geschillenbeslechting.</p>

        <button className="privacy-close" onClick={onClose}>Sluiten</button>
      </div>
    </div>
  );
}

function CookiesModal({ onClose }) {
  return (
    <div className="privacy-backdrop" onClick={onClose}>
      <div className="privacy-box" onClick={e => e.stopPropagation()}>
        <h2>Cookiebeleid</h2>
        <LegalIdBlock />
        <p style={{fontSize:13,color:'rgba(237,233,227,.6)',marginBottom:14}}>Versie van 18 mei 2026 — conform de ePrivacy-richtlijn en de Belgische Wet Elektronische Communicatie.</p>

        <h3>1. Wat zijn cookies?</h3>
        <p>Cookies zijn kleine tekstbestanden die door je browser worden opgeslagen wanneer je een website bezoekt. Ze laten de site toe om informatie te onthouden (bv. taalvoorkeur, sessie, cookievoorkeur).</p>

        <h3>2. Welke cookies gebruiken wij?</h3>
        <p>Vertex Studios gebruikt momenteel <strong>uitsluitend strikt noodzakelijke en functionele cookies</strong>:</p>
        <ul>
          <li><strong>vertex-cookies-v1</strong> (functioneel, 1 jaar) — onthoudt jouw cookievoorkeur zodat we de banner niet opnieuw tonen</li>
        </ul>
        <p>We plaatsen <strong>geen</strong> tracking-, analytics-, advertising- of social media-cookies.</p>

        <h3>3. Toestemming</h3>
        <p>Strikt noodzakelijke en functionele cookies vereisen onder de ePrivacy-richtlijn geen voorafgaande toestemming. We tonen toch een cookiebanner zodat je transparant geïnformeerd wordt.</p>

        <h3>4. Cookies beheren</h3>
        <p>Je kan op elk moment cookies wissen via je browserinstellingen:</p>
        <ul>
          <li><strong>Chrome:</strong> Instellingen → Privacy en beveiliging → Cookies en andere sitegegevens</li>
          <li><strong>Safari:</strong> Voorkeuren → Privacy → Cookies en websitegegevens beheren</li>
          <li><strong>Firefox:</strong> Instellingen → Privacy & Beveiliging → Cookies en websitegegevens</li>
          <li><strong>Edge:</strong> Instellingen → Cookies en sitemachtigingen</li>
        </ul>

        <h3>5. Wijzigingen</h3>
        <p>Bij wijzigingen aan dit cookiebeleid (bv. toevoeging analytics) wordt dit document bijgewerkt en wordt de cookiebanner opnieuw getoond met de bijgewerkte categorieën.</p>

        <h3>6. Contact</h3>
        <p>Vragen? Mail naar <a href="mailto:oliver@vertexstudios.info" style={{color:'var(--accent)'}}>oliver@vertexstudios.info</a>.</p>

        <button className="privacy-close" onClick={onClose}>Sluiten</button>
      </div>
    </div>
  );
}

function CookieBanner() {
  const [visible, setVisible] = useState(false);
  const [showCookies, setShowCookies] = useState(false);

  useEffect(() => {
    if (!localStorage.getItem('vx_cookie_consent')) {
      const t = setTimeout(() => setVisible(true), 1200);
      return () => clearTimeout(t);
    }
  }, []);

  function accept() {
    localStorage.setItem('vx_cookie_consent', 'accepted');
    setVisible(false);
  }

  function decline() {
    localStorage.setItem('vx_cookie_consent', 'declined');
    setVisible(false);
  }

  return (
    <>
      {visible && (
        <div className="cookie-banner">
          <p className="cookie-text">
            We gebruiken functionele cookies voor een goede werking van de site.{' '}
            <a href="#" onClick={e => { e.preventDefault(); setShowCookies(true); }}>Meer info</a>
          </p>
          <div className="cookie-btns">
            <button className="cookie-decline" onClick={decline}>Weigeren</button>
            <button className="cookie-accept" onClick={accept}>Accepteren</button>
          </div>
        </div>
      )}
      {showCookies && <CookiesModal onClose={() => setShowCookies(false)} />}
    </>
  );
}

/* ── Page hero (gedeeld door subpaginas) ─────────────────────────────────── */
function PageHero({ eb, title, lead, children }) {
  return (
    <section className="page-hero">
      <div className="page-hero-inner">
        {eb && <span className="eb">{eb}</span>}
        <h1 className="page-hero-title">{title}</h1>
        {lead && <p className="page-hero-lead">{lead}</p>}
        {children && <div className="page-hero-cta">{children}</div>}
      </div>
    </section>
  );
}

/* ── Per-pagina meta (titel) ─────────────────────────────────────────────── */
function usePageMeta(title, desc) {
  useEffect(() => {
    if (title) document.title = title;
    if (desc) {
      let m = document.querySelector('meta[name="description"]');
      if (m) m.setAttribute('content', desc);
    }
  }, [title, desc]);
}

/* ── Cases data ──────────────────────────────────────────────────────────── */
const CASES = [
  {
    name: 'Calvena',
    url:  'https://calvena.be',
    status: 'Live',
    sector: 'Sanitair & technieken',
    summary: 'Heldere, vertrouwenwekkende website voor sanitair en technische installaties, met focus op leadgeneratie.',
    accent: '#7aa9d9',
  },
  {
    name: 'Fixd Bike',
    url:  'https://fixd-bike.be',
    status: 'Live',
    sector: 'Fietsen & reparatie',
    summary: 'Snelle, mobiel-eerst website met direct boekingssysteem voor on-site fietsreparaties.',
    accent: '#ff7a45',
  },
  {
    name: 'Michel Peeters',
    url:  'https://wellnessconsult.be',
    status: 'Live',
    sector: 'Wellness & coaching',
    summary: 'Professionele presentatiesite met persoonlijke uitstraling voor zelfstandig wellness-consulent.',
    accent: '#9b8cff',
  },
  {
    name: 'Altered Carbon',
    url:  'https://altered-carbon-vert.vercel.app',
    status: 'In ontwikkeling',
    sector: 'Duurzaamheid & CO₂',
    summary: 'Volledig nieuwe website voor CO₂-berekeningen en duurzaamheidsrapportage. Momenteel in afwerking.',
    accent: '#56c690',
  },
];

// Microlink levert gratis screenshots; geen API-key nodig voor lage volumes
function screenshotUrl(url) {
  return `https://api.microlink.io/?url=${encodeURIComponent(url)}&screenshot=true&meta=false&embed=screenshot.url&viewport.width=1280&viewport.height=800`;
}

function CasesGrid() {
  return (
    <div className="cases-grid wrap">
      {CASES.map((c) => (
        <a
          key={c.name}
          href={c.url}
          target="_blank"
          rel="noopener noreferrer"
          className="case-card reveal"
        >
          <div className="case-thumb" style={{background:`linear-gradient(135deg, ${c.accent}33, ${c.accent}11)`}}>
            <div className="case-thumb-glow" style={{background:c.accent}} />
            <img
              className="case-thumb-img"
              src={screenshotUrl(c.url)}
              alt={`${c.name} website screenshot`}
              loading="lazy"
              onError={(e) => { e.currentTarget.style.display = 'none'; }}
            />
          </div>
          <div className="case-card-body">
            <div className="case-meta">
              <span className="case-status">{c.status}</span>
              <span className="case-sector">{c.sector}</span>
            </div>
            <h3>{c.name}</h3>
            <p>{c.summary}</p>
            <span className="case-url">{c.url.replace(/^https?:\/\//, '')} <span className="case-url-arr">↗</span></span>
          </div>
        </a>
      ))}
    </div>
  );
}

/* ── Home: lichte versie, leidt door naar subpaginas ─────────────────────── */
/* ── Feature cards met mock visuals (azzuro-stijl) ───────────────────────── */
function FeatCardConversion({ inMarquee }) {
  return (
    <article className={`feat-card${inMarquee ? '' : ' reveal'}`}>
      <div className="feat-visual">
        <div className="feat-browser">
          <div className="feat-browser-bar">
            <span className="fb-dot" style={{background:'#ff5f57'}} />
            <span className="fb-dot" style={{background:'#febc2e'}} />
            <span className="fb-dot" style={{background:'#28c840'}} />
            <span className="fb-url">jouwwebsite.be</span>
          </div>
          <div className="feat-browser-body">
            <div className="fb-chip fb-chip-active">Lead generation <span className="fb-tick">✓</span></div>
            <div className="fb-chip fb-chip-ghost">Conversie funnel</div>
            <div className="fb-chip fb-chip-ghost">On-page SEO</div>
          </div>
        </div>
      </div>
      <div className="feat-icon">↗</div>
      <h3>Bezoekers naar klanten.</h3>
      <p>Elke sectie en knop is gebouwd om bezoekers naar contact te leiden — niet om mooi te zijn.</p>
      <div className="feat-tags">
        <span className="feat-tag">#CONVERSION</span>
        <span className="feat-tag">#UX</span>
      </div>
    </article>
  );
}
function FeatCardCustom({ inMarquee }) {
  return (
    <article className={`feat-card${inMarquee ? '' : ' reveal'}`} style={inMarquee ? null : {transitionDelay:'.08s'}}>
      <div className="feat-visual">
        <div className="feat-terminal">
          <div className="feat-terminal-bar">
            <span className="ft-dotline" />
            LIVE SYSTEM FEED
          </div>
          <div className="feat-terminal-body">
            <span className="ft-prompt">{'> '}</span>booting vertex-engine<span className="ft-cur" />
          </div>
          <div className="feat-terminal-foot">
            <span>sys.log</span>
            <span>vx-01-core</span>
          </div>
        </div>
      </div>
      <div className="feat-icon">⚙</div>
      <h3>Volledig op maat.</h3>
      <p>Geen templates, geen page builders. Elke site is met de hand gebouwd rond jouw bedrijf en jouw klanten.</p>
      <div className="feat-tags">
        <span className="feat-tag">#CUSTOM</span>
        <span className="feat-tag">#KMO</span>
      </div>
    </article>
  );
}
function FeatCardFast({ inMarquee }) {
  return (
    <article className={`feat-card${inMarquee ? '' : ' reveal'}`} style={inMarquee ? null : {transitionDelay:'.16s'}}>
      <div className="feat-visual">
        <div className="feat-browser">
          <div className="feat-browser-bar">
            <span className="fb-dot" style={{background:'#ff5f57'}} />
            <span className="fb-dot" style={{background:'#febc2e'}} />
            <span className="fb-dot" style={{background:'#28c840'}} />
            <span className="fb-url">jouwwebsite.be</span>
          </div>
          <div className="feat-browser-body feat-browser-body-cta">
            <div className="fb-line" />
            <div className="fb-line s" />
            <div className="fb-cta">
              Vraag offerte <span className="fb-cta-arr">→</span>
            </div>
          </div>
        </div>
      </div>
      <div className="feat-icon">⚡</div>
      <h3>Snel live, geen complexiteit.</h3>
      <p>We focussen op wat werkt: snel laden, mobiel sterk, helder verhaal. Live vanaf 48 uur.</p>
      <div className="feat-tags">
        <span className="feat-tag">#FAST</span>
        <span className="feat-tag">#MOBILE</span>
      </div>
    </article>
  );
}

function FeatureCards() {
  const trackRef = useRef(null);

  useEffect(() => {
    const el = trackRef.current;
    if (!el) return;
    let rafId = 0;
    let paused = false;
    let resumeTimer = null;
    let direction = 1;      // 1 = naar links (scrollLeft++), -1 = naar rechts
    let pauseStartScroll = 0;
    const speedMag = 0.6;

    function tick() {
      if (!paused) {
        const half = el.scrollWidth / 2;
        el.scrollLeft += speedMag * direction;
        // Naadloze wrap in beide richtingen
        if (el.scrollLeft >= half) el.scrollLeft -= half;
        else if (el.scrollLeft < 0) el.scrollLeft += half;
      }
      rafId = requestAnimationFrame(tick);
    }
    function pause() {
      if (!paused) pauseStartScroll = el.scrollLeft;
      paused = true;
      clearTimeout(resumeTimer);
      resumeTimer = setTimeout(() => {
        // Bepaal richting op basis van delta tussen start en eind van interactie
        const delta = el.scrollLeft - pauseStartScroll;
        if (Math.abs(delta) > 4) {
          // Negatieve delta = user scrollde naar rechts (content moves right) → direction -1
          // Positieve delta = user scrollde naar links → direction 1
          direction = delta > 0 ? 1 : -1;
        }
        paused = false;
      }, 1400);
    }
    el.addEventListener('touchstart', pause, { passive: true });
    el.addEventListener('mousedown', pause);
    el.addEventListener('wheel', pause, { passive: true });
    el.addEventListener('keydown', pause);
    rafId = requestAnimationFrame(tick);
    return () => {
      cancelAnimationFrame(rafId);
      clearTimeout(resumeTimer);
      el.removeEventListener('touchstart', pause);
      el.removeEventListener('mousedown', pause);
      el.removeEventListener('wheel', pause);
      el.removeEventListener('keydown', pause);
    };
  }, []);

  // Set wordt 2× herhaald voor naadloze loop
  const cardSet = (key) => (
    <React.Fragment key={key}>
      <FeatCardConversion inMarquee />
      <FeatCardCustom inMarquee />
      <FeatCardFast inMarquee />
    </React.Fragment>
  );

  return (
    <section className="features-section">
      <div className="sec-head reveal">
        <div>
          <h2>Niet zomaar een website.<br/><em>Een groeimotor</em>.</h2>
        </div>
        <p className="lead">Drie principes die elk Vertex-project anders maken dan een standaard websitebureau.</p>
      </div>

      {/* Oneindige carousel — user kan zelf scrollen, auto resumes na 1.4s */}
      <div className="features-marquee">
        <div className="fmt-track" ref={trackRef} tabIndex="0" aria-label="Vertex principes carousel">
          {cardSet('a')}
          {cardSet('b')}
        </div>
      </div>
    </section>
  );
}

function AIReceptionistCTA() {
  return (
    <section className="ai-cta-section reveal">
      <div className="ai-cta-card">
        <div className="ai-cta-glow" />
        <div className="ai-cta-content">
          <span className="ai-cta-eb">🤖 Nieuw · vanaf €49/mnd + €149 setup</span>
          <h2 className="ai-cta-title">Mis nooit meer een klant.<br/><em>Onze AI-receptionist</em> neemt 24/7 op.</h2>
          <p className="ai-cta-sub">Spreekt natuurlijk Nederlands, beantwoordt vragen, boekt afspraken en stuurt boodschappen door. Klaar binnen een week, getraind op jouw business.</p>
          <div className="ai-cta-actions">
            <a href="https://intake.vertexstudios.info" target="_blank" rel="noopener" className="btn btn-primary btn-lg">
              Start intake <span className="arr">→</span>
            </a>
            <Link to="/prijzen" className="btn btn-secondary btn-lg">Meer info</Link>
          </div>
        </div>
        <div className="ai-cta-visual" aria-hidden="true">
          <div className="ai-cta-orb" />
          <div className="ai-cta-wave w1" />
          <div className="ai-cta-wave w2" />
          <div className="ai-cta-wave w3" />
        </div>
      </div>
    </section>
  );
}

function HomePage() {
  usePageMeta(
    'Vertex Studios — Webdesign & AI-Receptionist België',
    'Slimme websites voor groeiende KMO\'s, plus een 24/7 AI-receptionist die telefoon opneemt en afspraken inboekt in natuurlijk Nederlands. Op maat, snel live, vaste prijzen.'
  );
  return (
    <>
      <Hero />
      <HeroTrustCarousel />
      <FeatureCards />
      <section className="manifesto-section reveal r-fast">
        <p className="manifesto-eb">Geen template-fabriek</p>
        <h2 className="manifesto-text scroll-words">
          We bouwen websites voor lokale bedrijven die <em>écht</em> willen groeien — snel live, mobiel-sterk, op maat, zonder eindeloos vergaderen.
        </h2>
      </section>
      <section className="services-section">
        <div className="sec-head reveal">
          <div>
            <h2>Wat we <em>maken</em>.</h2>
          </div>
          <p className="lead">Alles wat een bedrijf nodig heeft om online sterker te staan — kort en krachtig.</p>
        </div>
        <div className="services-grid wrap">
          {DIENSTEN_ITEMS.map((d, i) => (
            <div key={i} className="service-card reveal" style={{transitionDelay:`${i*0.04}s`}}>
              <div className="service-icon">{d.icon}</div>
              <div>
                <h3>{d.title}</h3>
                <p>{d.subtitle}</p>
              </div>
            </div>
          ))}
        </div>
        <div className="services-cta reveal">
          <Link to="/diensten" className="btn btn-secondary">Bekijk alle diensten <span className="arr">→</span></Link>
        </div>
      </section>
      <AIReceptionistCTA />
      <section className="home-cases">
        <div className="sec-head reveal">
          <div>
            <h2>Recent <em>opgeleverd</em>.</h2>
          </div>
          <p className="lead">Een greep uit projecten die live staan of in eindfase zitten.</p>
        </div>
        <CasesGrid />
        <div className="home-cases-cta reveal">
          <Link to="/cases" className="btn btn-secondary">Bekijk alle cases <span className="arr">→</span></Link>
        </div>
      </section>
      <section className="home-contact-section">
        <div className="sec-head reveal">
          <div>
            <h2>Klaar om te <em>starten</em>?</h2>
          </div>
          <p className="lead">Laat hier je gegevens achter en we nemen binnen 24 uur contact op. Geen verplichtingen, gewoon een kennismaking.</p>
        </div>
        <div className="home-contact-wrap reveal" style={{transitionDelay:'.08s'}}>
          <ContactForm />
        </div>
      </section>
    </>
  );
}

/* ── Diensten subpagina ──────────────────────────────────────────────────── */
function DienstenPage() {
  usePageMeta(
    'Diensten — Webdesign & AI-Receptionist | Vertex Studios',
    'Websites, webshops, hosting, SEO, zakelijk e-mail, Google Business én een 24/7 AI-receptionist die telefoon opneemt en afspraken inboekt. Alles onder één dak.'
  );
  return (
    <>
      <PageHero
        eb="Diensten"
        title={<>Alles voor je website, <em>onder één dak</em>.</>}
        lead="Van eerste schets tot live website — wij ontwerpen, bouwen en onderhouden alles. Geen freelancer-chaos, één aanspreekpunt."
      >
        <Link to="/prijzen" className="btn btn-primary">Bekijk prijzen <span className="arr">→</span></Link>
        <Link to="/contact" className="btn btn-secondary">Vraag info aan</Link>
      </PageHero>
      <Diensten />
      <section className="dienst-detail">
        <div className="sec-head reveal">
          <div>
            <h2>Wat valt er <em>onder</em> elke dienst?</h2>
          </div>
          <p className="lead">Korte uitleg per onderdeel zodat je weet wat je krijgt.</p>
        </div>
        <div className="dienst-detail-grid wrap">
          {DIENSTEN_DETAIL.map((d, i) => (
            <div key={i} className="dienst-detail-card reveal" style={{transitionDelay:`${i*0.05}s`}}>
              <div className="dienst-detail-icon">{d.icon}</div>
              <h3>{d.title}</h3>
              <p>{d.body}</p>
            </div>
          ))}
        </div>
      </section>
    </>
  );
}

/* ── Prijzen subpagina ───────────────────────────────────────────────────── */
function PrijzenPage() {
  usePageMeta(
    'Prijzen Websites & AI-Receptionist — Vertex Studios',
    'Eerlijke pakketten voor websites, onderhoud en de AI-receptionist (24/7 telefoon opnemen in Nederlands). Vaste prijzen, geen verborgen kosten. Websites vanaf €289, AI-receptionist vanaf €49/mnd.'
  );
  return (
    <>
      <PageHero
        eb="Prijzen"
        title={<>Eerlijke <em>pakketten</em>, geen verborgen kosten.</>}
        lead="Kies een bouwpakket dat past bij je doel en koppel optioneel een onderhoudsabonnement. Transparant, opzegbaar."
      >
        <Link to="/contact" className="btn btn-primary">Vraag info aan <span className="arr">→</span></Link>
        <Link to="/diensten" className="btn btn-secondary">Bekijk diensten</Link>
      </PageHero>
      <Prijzen />
      <section className="pricing-cta-section">
        <div className="pricing-cta-card reveal">
          <h3>Niet zeker welk pakket?</h3>
          <p>Vraag vrijblijvend info aan en we helpen je kiezen op basis van je doelen en budget.</p>
          <Link to="/contact" className="btn btn-primary">Vraag info aan <span className="arr">→</span></Link>
        </div>
      </section>
    </>
  );
}

/* ── Cases subpagina ─────────────────────────────────────────────────────── */
function CasesPage() {
  usePageMeta(
    'Cases — Vertex Studios',
    'Een overzicht van recente websites en projecten gebouwd door Vertex Studios.'
  );
  return (
    <>
      <PageHero
        eb="Cases"
        title={<>Recent <em>opgeleverd</em>.</>}
        lead="Websites die we live hebben gezet of in de eindfase zitten — voor lokale KMO's en persoonlijke merken."
      >
        <Link to="/contact" className="btn btn-primary">Wil jij ook? Vraag info aan <span className="arr">→</span></Link>
      </PageHero>
      <section style={{paddingTop:0}}>
        <CasesGrid />
      </section>
    </>
  );
}

/* ── Contact subpagina (info-aanvraag) ───────────────────────────────────── */
const CONTACT_FORMSPREE_URL = 'https://formspree.io/f/xlgvgeng';

/* ── Herbruikbaar contactformulier ──────────────────────────────────────── */
function ContactForm({ defaultPakket = '' }) {
  const [form, setForm] = useState({ naam:'', bedrijf:'', email:'', telefoon:'', pakket:defaultPakket, bericht:'' });
  const [sent, setSent] = useState(false);
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState('');
  const upd = (k) => (e) => setForm(f => ({ ...f, [k]: e.target.value }));

  async function submit(e) {
    e.preventDefault();
    setBusy(true); setErr('');
    try {
      const res = await fetch(CONTACT_FORMSPREE_URL, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
        body: JSON.stringify(form),
      });
      if (!res.ok) throw new Error('Versturen mislukt');
      setSent(true);
    } catch (e) {
      setErr('Iets ging mis. Probeer opnieuw of mail rechtstreeks naar oliver@vertexstudios.info.');
    } finally {
      setBusy(false);
    }
  }

  if (sent) {
    return (
      <div className="success-state">
        <div className="success-icon">✓</div>
        <h2><em>Bedankt, {form.naam || 'vriend'}!</em></h2>
        <p>We hebben je bericht ontvangen. Je krijgt binnen <strong>24 uur op werkdagen</strong> een reactie op <strong>{form.email}</strong>.</p>
      </div>
    );
  }
  return (
    <form onSubmit={submit}>
      <div className="form-grid-2">
        <div className="form-row">
          <label>Naam *</label>
          <input required value={form.naam} onChange={upd('naam')} placeholder="Voornaam achternaam" />
        </div>
        <div className="form-row">
          <label>Bedrijf *</label>
          <input required value={form.bedrijf} onChange={upd('bedrijf')} placeholder="Naam van je zaak" />
        </div>
        <div className="form-row">
          <label>E-mail *</label>
          <input required type="email" value={form.email} onChange={upd('email')} placeholder="jij@bedrijf.be" />
        </div>
        <div className="form-row">
          <label>Telefoon</label>
          <input type="tel" value={form.telefoon} onChange={upd('telefoon')} placeholder="+32 4xx xx xx xx" />
        </div>
      </div>
      <div className="form-row">
        <label>Interesse in pakket</label>
        <select value={form.pakket} onChange={upd('pakket')}>
          <option value="">Geen voorkeur / algemeen</option>
          <option value="Launch">Launch — one-pager (€289)</option>
          <option value="Business">Business — multi-page (€449)</option>
          <option value="Premium">Premium Custom (op maat)</option>
          <option value="Care">Care abonnement (€49/mnd)</option>
          <option value="AI-receptionist">AI-receptionist (vanaf €49/mnd + €149 setup)</option>
          <option value="Webshop">Webshop</option>
          <option value="Andere">Andere / nog niet zeker</option>
        </select>
      </div>
      <div className="form-row">
        <label>Bericht *</label>
        <textarea required value={form.bericht} onChange={upd('bericht')} rows={4} placeholder="Wat wil je weten? Schrijf hier je vraag of beschrijf je project kort." />
      </div>
      {err && <p className="form-error">{err}</p>}
      <button type="submit" className="btn btn-primary btn-lg form-submit" disabled={busy}>
        {busy ? 'Versturen…' : 'Verstuur bericht'} <span className="arr">→</span>
      </button>
      <p className="form-note">We reageren binnen 24 uur op werkdagen. Liever bellen? <a href="mailto:oliver@vertexstudios.info">oliver@vertexstudios.info</a></p>
    </form>
  );
}

function ContactPage() {
  usePageMeta(
    'Contact — Vertex Studios',
    'Een vraag over een pakket of dienst? Vraag vrijblijvend info aan via het contactformulier. We reageren binnen 24u op werkdagen.'
  );
  return (
    <>
      <PageHero
        eb="Contact"
        title={<>Vraag <em>vrijblijvend</em> info aan.</>}
        lead="Een vraag over een pakket, dienst of project? Laat hier je gegevens achter — we reageren binnen 24 uur op werkdagen."
      />
      <section className="contact-form-section">
        <div className="contact-form-wrap">
          <div className="contact-form-card reveal">
            <ContactForm />
          </div>

          <aside className="contact-aside reveal" style={{transitionDelay:'.08s'}}>
            <h3>Liever direct contact?</h3>
            <div className="contact-meta">
              <div className="row">
                <span className="lbl">E-mail</span>
                <a className="val" href="mailto:oliver@vertexstudios.info">oliver@vertexstudios.info</a>
              </div>
              <div className="row">
                <span className="lbl">Reactietijd</span>
                <span className="val">Binnen 24 uur op werkdagen</span>
              </div>
              <div className="row">
                <span className="lbl">BTW</span>
                <span className="val">BE 0777.834.189</span>
              </div>
            </div>
            <div className="contact-aside-cta">
              <p>Liever eerst bekijken wat we bouwen? Neem een kijkje bij <strong>onze cases</strong>.</p>
              <Link to="/cases" className="btn btn-secondary">Bekijk cases <span className="arr">→</span></Link>
            </div>
          </aside>
        </div>
      </section>
    </>
  );
}

/* ── 404 ─────────────────────────────────────────────────────────────────── */
function NotFoundPage() {
  usePageMeta('404 — Pagina niet gevonden | Vertex Studios');
  return (
    <PageHero
      eb="404"
      title={<>Pagina niet <em>gevonden</em>.</>}
      lead="Deze pagina bestaat niet (meer). Klik op een van de links om verder te gaan."
    >
      <Link to="/" className="btn btn-primary">Naar home <span className="arr">→</span></Link>
      <Link to="/contact" className="btn btn-secondary">Contact</Link>
    </PageHero>
  );
}

function App() {
  const path = useRoute();
  const [showPrivacy, setShowPrivacy] = useState(false);
  const [showTerms,   setShowTerms]   = useState(false);
  const [showCookies, setShowCookies] = useState(false);

  useEffect(() => {
    const id = setTimeout(() => { window.__initReveals && window.__initReveals(); }, 60);
    return () => clearTimeout(id);
  }, [path]);

  let page;
  if      (path === '/')          page = <HomePage />;
  else if (path === '/diensten')  page = <DienstenPage />;
  else if (path === '/prijzen')   page = <PrijzenPage />;
  else if (path === '/cases')     page = <CasesPage />;
  else if (path === '/contact')   page = <ContactPage />;
  else                            page = <NotFoundPage />;

  return (
    <>
      <Nav />
      {page}
      <Footer
        onPrivacy={() => setShowPrivacy(true)}
        onTerms={() => setShowTerms(true)}
        onCookies={() => setShowCookies(true)}
      />
      <CookieBanner />
      {showPrivacy && <PrivacyModal onClose={() => setShowPrivacy(false)} />}
      {showTerms   && <TermsModal   onClose={() => setShowTerms(false)} />}
      {showCookies && <CookiesModal onClose={() => setShowCookies(false)} />}
    </>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
