/* ============================================================
   landing-core.jsx - közös komponensek mindkét landinghez
   window-re exportálva, hogy a selfservice.jsx / managed.jsx használhassa
   ============================================================ */
const { useState, useEffect, useRef } = React;

const ORANGE = "#ffa014";
const CALENDLY_URL = "https://calendly.com/d/cvq8-jwh-sq5/netadclick-com-hirlevelkuldo-bemutato-meeting?hide_event_type_details=1&hide_gdpr_banner=1&primary_color=068ee7";

// A Calendly natívan rögzíti az utm_* paramétereket a foglalásnál (Meetings
// fül, webhook, v2 API), ezért a widget URL-jére ráfűzzük az attribúciót.
// Így a foglalás forrása akkor is megvan, ha a látogató elutasította a
// mérési sütiket - lásd attribution.js. Csak az 5 standard utm_* mezőt
// fogadja el, egyéb saját paramétert nem.
const calendlyUrl = () =>
  window.nacAttribution ? window.nacAttribution.decorate(CALENDLY_URL) : CALENDLY_URL;

// ---------- CONVERSION TRACKING (IndiData) ----------
// A látogató fontos műveletét jelzi a mérőrendszernek. Score: 100 = magas
// értékű lead (hívás / bemutatófoglalás), lásd IndiData konverzió-doksi.
const trackConversion = (event, score) => {
  window.eventStorage = window.eventStorage || [];
  window.eventStorage.push('conversion', event, score);
};

// ---------- KÖSZÖNŐOLDAL ----------
// Sikeres foglalás után átvisszük a látogatót egy külön URL-re. Két oka van:
// a Calendly visszaigazolása szűkszavú (nem mondja el, mi következik), és egy
// önálló URL a legegyszerűbb, legmegbízhatóbb konverziós jel a GA4 / Ads
// felé - nem kell postMessage-re triggert építeni.
const THANKS_PATH = "/koszonom";
// A köszönőoldal ebből tudja, melyik csomagról szólt a bemutató. Az attribúció
// utm_content mezője erre NEM jó: azt minden oldal a saját útvonalából állítja
// elő, tehát a köszönőoldalon már "/koszonom" lenne.
const THANKS_SOURCE = { "/": "hirlevelkuldo", "/teljes-koru": "teljes-koru", "/kalkulator": "kalkulator" };
const thanksUrl = () => {
  // Fájlból megnyitva (.html) és éles cleanUrls alatt is ugyanazt adja.
  const path = (window.location.pathname || "/").replace(/\.html$/, "").replace(/\/index$/, "/");
  const url = THANKS_PATH + "?forras=" + encodeURIComponent(THANKS_SOURCE[path] || "egyeb");
  // Az utm_* paramétereket visszük tovább, hogy a köszönőoldali konverzió is
  // a kampányhoz kötődjön - JS-navigációnál ezt a click handler nem intézi el.
  return window.nacAttribution ? window.nacAttribution.internal(url) : url;
};

// ---------- ICONS ----------
const ICONS = {
  editor: () =>
    <svg width="36" height="36" viewBox="0 0 32 32" fill="none"><rect x="4" y="5" width="10" height="7" rx="1.5" stroke="#fff" strokeWidth="2.5"/><rect x="16" y="5" width="12" height="7" rx="1.5" fill={ORANGE}/><rect x="4" y="14" width="24" height="5" rx="1.5" stroke="#fff" strokeWidth="2.5"/><path d="M20 21 L24 30 L21.5 27 L19 28 Z" fill="#fff"/></svg>,
  stats: () =>
    <svg width="36" height="36" viewBox="0 0 32 32" fill="none"><path d="M5 27 V17" stroke="#fff" strokeWidth="2.5" strokeLinecap="round"/><path d="M12 27 V12" stroke="#fff" strokeWidth="2.5" strokeLinecap="round"/><path d="M19 27 V20" stroke="#fff" strokeWidth="2.5" strokeLinecap="round"/><path d="M26 27 V7" stroke={ORANGE} strokeWidth="3" strokeLinecap="round"/><circle cx="26" cy="7" r="2.8" fill={ORANGE}/><path d="M5 27 H28" stroke="#fff" strokeWidth="2.5" strokeLinecap="round"/></svg>,
  segment: () =>
    <svg width="36" height="36" viewBox="0 0 32 32" fill="none"><circle cx="12" cy="16" r="8" stroke="#fff" strokeWidth="2.5"/><circle cx="20" cy="16" r="8" stroke="#fff" strokeWidth="2.5"/><path d="M16 9 A 8 8 0 0 1 16 23 A 8 8 0 0 1 16 9 Z" fill={ORANGE}/></svg>,
  trigger: () =>
    <svg width="36" height="36" viewBox="0 0 32 32" fill="none"><rect x="3" y="9" width="20" height="15" rx="2" stroke="#fff" strokeWidth="2.5"/><path d="M3 11 L13 18 L23 11" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/><path d="M25 2 L18 16 L24 16 L21 30 L30 13 L24 13 Z" fill={ORANGE} stroke="#fff" strokeWidth="1.5" strokeLinejoin="round"/></svg>,
  form: () =>
    <svg width="36" height="36" viewBox="0 0 32 32" fill="none"><rect x="6" y="5" width="20" height="24" rx="2.5" stroke="#fff" strokeWidth="2.5"/><rect x="11" y="2" width="10" height="6" rx="1.5" fill={ORANGE}/><path d="M10 15 H18" stroke="#fff" strokeWidth="2.5" strokeLinecap="round"/><path d="M10 20 H22" stroke="#fff" strokeWidth="2.5" strokeLinecap="round"/><path d="M10 25 H17" stroke="#fff" strokeWidth="2.5" strokeLinecap="round"/></svg>,
  retarget: () =>
    <svg width="36" height="36" viewBox="0 0 32 32" fill="none"><path d="M27 16 A 11 11 0 0 0 5 16" stroke="#fff" strokeWidth="2.5" strokeLinecap="round"/><path d="M5 16 A 11 11 0 0 0 27 16" stroke="#fff" strokeWidth="2.5" strokeLinecap="round"/><path d="M23 12 L27 16 L31 12" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/><path d="M9 20 L5 16 L1 20" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/><circle cx="16" cy="16" r="3.5" fill={ORANGE}/></svg>,
  analytics: () =>
    <svg width="36" height="36" viewBox="0 0 32 32" fill="none"><circle cx="13" cy="13" r="8" stroke="#fff" strokeWidth="2.5"/><path d="M19 19 L27 27" stroke="#fff" strokeWidth="3" strokeLinecap="round"/><path d="M9 15 L12 11 L15 13 L18 9" stroke={ORANGE} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/><circle cx="18" cy="9" r="2" fill={ORANGE}/></svg>,
  sms: () =>
    <svg width="36" height="36" viewBox="0 0 32 32" fill="none"><path d="M4 8 A 2 2 0 0 1 6 6 H22 A 2 2 0 0 1 24 8 V20 A 2 2 0 0 1 22 22 H14 L7 28 V22 A 2 2 0 0 1 4 20 Z" stroke="#fff" strokeWidth="2.5" strokeLinejoin="round"/><circle cx="10" cy="14" r="1.6" fill="#fff"/><circle cx="14" cy="14" r="1.6" fill="#fff"/><circle cx="18" cy="14" r="1.6" fill={ORANGE}/><path d="M27 5 L29 3 M27 10 L30 10 M26 14 L29 15" stroke={ORANGE} strokeWidth="2.5" strokeLinecap="round"/></svg>,
  integrate: () =>
    <svg width="36" height="36" viewBox="0 0 32 32" fill="none"><path d="M11 5 C 7 5 7 9 7 11 C 7 14 4 14 4 16 C 4 18 7 18 7 21 C 7 23 7 27 11 27" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/><path d="M21 5 C 25 5 25 9 25 11 C 25 14 28 14 28 16 C 28 18 25 18 25 21 C 25 23 25 27 21 27" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/><circle cx="16" cy="16" r="3.5" fill={ORANGE}/></svg>
};
const FeatureIcon = ({ iconKey }) => { const r = ICONS[iconKey]; return r ? r() : null; };

// ---------- reveal hook ----------
const useReveal = () => {
  useEffect(() => {
    document.querySelectorAll(".section-label, section .h2").forEach(el => {
      if (!el.classList.contains("reveal")) el.classList.add("title-rv");
    });
    const els = Array.from(document.querySelectorAll(".reveal, .title-rv"));
    const showAll = () => els.forEach(e => e.classList.add("in"));
    if (!("IntersectionObserver" in window)) { showAll(); return; }
    const io = new IntersectionObserver((entries) => {
      entries.forEach(en => { if (en.isIntersecting) { en.target.classList.add("in"); io.unobserve(en.target); } });
    }, { threshold: 0.08, rootMargin: "0px 0px -40px 0px" });
    els.forEach(e => io.observe(e));
    // Fallback 1: if the observer never fires (some embed/iframe contexts),
    // Fallback 1: reveal only what's already in/above the viewport, so initial
    // content is never stuck at opacity:0 - below-fold stays for the observer.
    const revealInView = () => els.forEach(e => {
      if (e.getBoundingClientRect().top < window.innerHeight * 0.95) e.classList.add("in");
    });
    const t = setTimeout(revealInView, 500);
    // Fallback 2 (bulletproof): force-show anything still computed-invisible that
    // has entered the viewport, without pre-revealing off-screen elements.
    const t2 = setTimeout(() => {
      els.forEach(e => {
        if (getComputedStyle(e).opacity === "0" && e.getBoundingClientRect().top < window.innerHeight) { e.style.opacity = "1"; e.style.transform = "none"; }
      });
    }, 1500);
    return () => { clearTimeout(t); clearTimeout(t2); io.disconnect(); };
  }, []);
};

// ---------- LOGO ----------
const Logo = ({ tier, managed }) =>
  <span className="logo" aria-label="NetAdClick.com Hírlevélküldő">
    <img src="assets/netadclick-logo.png" alt="NetAdClick.com" className="logo-img" />
    <span className={"lo-badge" + (managed ? " managed" : "")}>Hírlevél</span>
    {tier && <span className="lo-tier">{tier}</span>}
  </span>;

// ---------- NAV ----------
const Nav = ({ links, onBook, ctaLabel = "Ingyenes bemutató →", tier, managed, otherHref, otherLabel }) => {
  const [open, setOpen] = useState(false);
  const close = () => setOpen(false);
  return (
    <header className="nav">
      <div className="wrap nav-inner">
        <Logo tier={tier} managed={managed} />
        <button
          className={"nav-toggle" + (open ? " open" : "")}
          aria-label="Menü" aria-expanded={open}
          onClick={() => setOpen(o => !o)}>
          <span></span><span></span><span></span>
        </button>
        <nav className={"nav-links" + (open ? " open" : "")}>
          {links.map(l => <a key={l.href} href={l.href} onClick={close}>{l.label}</a>)}
          {otherHref && <a href={otherHref} onClick={close} style={{ color: "var(--ink-muted)" }}>{otherLabel}</a>}
          <button className="btn btn-primary" onClick={() => { close(); onBook(); }}>{ctaLabel}</button>
        </nav>
      </div>
    </header>);
};

// ---------- HERO PREVIEW (dashboard mockup) ----------
const HeroPreview = () => {
  const [tab, setTab] = useState(0);
  useEffect(() => { const t = setInterval(() => setTab(x => (x + 1) % 3), 3800); return () => clearInterval(t); }, []);
  const stats = [
    { l: "Átlag megnyitás", v: "47,2%", d: "+4,1% heti" },
    { l: "Átlag kattintás", v: "12,8%", d: "+1,9% heti" },
    { l: "Leiratkozás", v: "0,23%", d: "−0,02% heti" }
  ];
  return (
    <div className="hero-card">
      <span className="sample-flag">minta adat</span>
      <div className="hero-card-top">
        <div className="dots"><i></i><i></i><i></i></div>
        <span>hirlevelkuldo.netadclick.com / áttekintés</span>
      </div>
      <div className="hero-card-tabs">
        {["Áttekintés", "Szerkesztő", "Automatizmus"].map((n, i) =>
          <button key={n} className={tab === i ? "active" : ""} onClick={() => setTab(i)}>{n}</button>)}
      </div>
      {tab === 0 &&
        <div className="hero-card-body">
          <div className="metric-row">
            {stats.map(s => <div key={s.l} className="metric"><div className="metric-l">{s.l}</div><div className="metric-v">{s.v}</div><div className="metric-d">{s.d}</div></div>)}
          </div>
          <div className="chart-block">
            <svg viewBox="0 0 400 120" width="100%" height="120" preserveAspectRatio="none">
              <defs><linearGradient id="cg" x1="0" x2="0" y1="0" y2="1"><stop offset="0" stopColor="var(--accent)" stopOpacity="0.25"/><stop offset="1" stopColor="var(--accent)" stopOpacity="0"/></linearGradient></defs>
              <path d="M0,92 L30,76 L60,64 L90,72 L120,50 L150,42 L180,54 L210,32 L240,28 L270,40 L300,22 L330,18 L360,28 L400,10 L400,120 L0,120 Z" fill="url(#cg)"/>
              <path d="M0,92 L30,76 L60,64 L90,72 L120,50 L150,42 L180,54 L210,32 L240,28 L270,40 L300,22 L330,18 L360,28 L400,10" fill="none" stroke="var(--accent)" strokeWidth="2"/>
            </svg>
            <div className="chart-axis"><span>hét 1</span><span>hét 2</span><span>hét 3</span><span>hét 4</span><span>hét 5</span></div>
          </div>
          <div className="campaign-row">
            <div className="campaign-cell"><span className="campaign-name">Tavaszi kampány</span><span className="campaign-stat ok">49,1% megnyitás</span></div>
            <div className="campaign-cell"><span className="campaign-name">Hírlevél #42</span><span className="campaign-stat">45,7% megnyitás</span></div>
            <div className="campaign-cell"><span className="campaign-name">Újrakampány</span><span className="campaign-stat">38,2% megnyitás</span></div>
          </div>
        </div>}
      {tab === 1 &&
        <div className="hero-card-body editor-tab">
          <div className="editor-toolbar"><span className="pill">Szöveg</span><span className="pill">Kép</span><span className="pill">Gomb</span><span className="pill">Oszlop</span><span className="pill">Elválasztó</span></div>
          <div className="editor-canvas">
            <div className="block block-header">Üdvözöljük, Anna!</div>
            <div className="block block-image">[ kép blokk ]</div>
            <div className="block block-text">Kedves Anna, szeretnénk megmutatni néhány új ajánlatot, amely pont az Ön érdeklődési körébe vág…</div>
            <div className="block block-cta">Ajánlat megtekintése →</div>
          </div>
        </div>}
      {tab === 2 &&
        <div className="hero-card-body auto-tab">
          <div className="flow">
            <div className="node node-trigger">Feliratkozás</div>
            <div className="arrow"><svg width="10" height="14" viewBox="0 0 10 14" fill="none"><path d="M5 1 V12 M1 8 L5 12 L9 8" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg></div>
            <div className="node">Üdvözlő levél</div>
            <div className="arrow">2 nap <svg width="10" height="14" viewBox="0 0 10 14" fill="none"><path d="M5 1 V12 M1 8 L5 12 L9 8" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg></div>
            <div className="node">Kérdőív</div>
            <div className="arrow">válasz alapján <svg width="10" height="14" viewBox="0 0 10 14" fill="none"><path d="M5 1 V12 M1 8 L5 12 L9 8" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg></div>
            <div className="flow-split"><div className="node node-accent">Érdeklődő sorozat</div><div className="node">Hírlevél lista</div></div>
          </div>
        </div>}
    </div>);
};

// ---------- TESTIMONIALS ----------
const TypeQuote = ({ text }) => {
  const clean = text.replace(/^[„"“]/, "").replace(/[""”]$/, "");
  const ref = useRef(null);
  const [n, setN] = useState(0);
  const [started, setStarted] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) { setN(clean.length); return; }
    const io = new IntersectionObserver((es) => es.forEach(e => { if (e.isIntersecting) { setStarted(true); io.disconnect(); } }), { threshold: 0.35 });
    io.observe(el);
    return () => io.disconnect();
  }, [clean.length]);
  useEffect(() => {
    if (!started || n >= clean.length) return;
    const t = setTimeout(() => setN(x => Math.min(clean.length, x + 3)), 12);
    return () => clearTimeout(t);
  }, [started, n, clean.length]);
  const done = n >= clean.length;
  return (
    <blockquote ref={ref} className={"typeq" + (started && !done ? " typing" : "") + (done ? " done" : "")}>
      <span className="tq-ghost" aria-hidden="true">{clean}</span>
      <span className="tq-live">{clean.slice(0, n)}<span className="tq-caret"></span></span>
    </blockquote>);
};

// ---------- COUNT-UP NUMBER ----------
const CountUpNum = ({ value }) => {
  const ref = useRef(null);
  const digits = String(value).replace(/\s/g, "");
  const isNum = /^\d+$/.test(digits);
  const target = isNum ? parseInt(digits, 10) : 0;
  const [n, setN] = useState(0);
  useEffect(() => {
    if (!isNum) return;
    const el = ref.current; if (!el) return;
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) { setN(target); return; }
    const io = new IntersectionObserver((es) => es.forEach(e => {
      if (!e.isIntersecting) return;
      io.disconnect();
      const dur = 1500, start = performance.now();
      const tick = (t) => {
        const p = Math.min(1, (t - start) / dur);
        setN(Math.round(target * (1 - Math.pow(1 - p, 3))));
        if (p < 1) requestAnimationFrame(tick);
      };
      requestAnimationFrame(tick);
    }), { threshold: 0.5 });
    io.observe(el);
    return () => io.disconnect();
  }, [isNum, target]);
  const fmt = (x) => x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, "\u00a0");
  return <span ref={ref}>{isNum ? fmt(n) : value}</span>;
};

const Testimonials = ({ quotes }) =>
  <div className="quotes">
    {quotes.map((q, i) =>
      <div className="quote-card reveal" key={i}>
        <div className="qc-top">
          <span className="openmark">&ldquo;</span>
          <TypeQuote text={q.text} />
          <span className="bigmark">&rdquo;</span>
        </div>
        <div className="qc-bot">
          <span className="avatar">
            {q.logo
              ? <img src={q.logo} alt={q.name} />
              : <span className="ini">{q.initials}</span>}
          </span>
          <span className="name">{q.name}</span>
          <span className="sub">{q.role || "Partner"}</span>
        </div>
      </div>)}
  </div>;

// ---------- PARTNER STRIP ----------
const PARTNERS = [
  { name: "Focus Medical", logo: "assets/partners/focus-medical.jpg" },
  { name: "SAKKOM Interaktív", logo: "assets/partners/sakkom.png" },
  { name: "Program Turizmus", logo: "assets/partners/programturizmus.jpg" }
];
const PartnerStrip = () =>
  <div className="partner-strip">
    <div className="pl">Néhány partnerünk</div>
    <div className="partner-logos">
      {PARTNERS.map(p => <span className="pw" key={p.name}><img src={p.logo} alt={p.name} /></span>)}
    </div>
  </div>;

// ---------- BOOKING ----------
const Booking = ({ bookRef, title, lead }) => {
  const [calShown, setCalShown] = useState(false);
  useEffect(() => {
    if (!document.querySelector('script[src*="calendly.com/assets/external/widget.js"]')) {
      const s = document.createElement('script'); s.src = 'https://assets.calendly.com/assets/external/widget.js'; s.async = true; document.body.appendChild(s);
    }
    if (!document.querySelector('link[href*="calendly.com/assets/external/widget.css"]')) {
      const l = document.createElement('link'); l.rel = 'stylesheet'; l.href = 'https://assets.calendly.com/assets/external/widget.css'; document.head.appendChild(l);
    }
  }, []);

  // ---- Calendly események: a konverzió a TÉNYLEGES foglalásnál szólal meg ----
  // A Calendly a widget.js-alapú beágyazásnál postMessage-ben jelzi a lépéseket:
  //   profile_page_viewed → event_type_viewed → date_and_time_selected → event_scheduled
  // Nyers <iframe>-nél ez NEM működne; nálunk működik, mert a keretet a widget.js
  // építi (ezt az URL-ben lévő embed_domain paraméter jelzi - ebből tudja a
  // Calendly, hova küldje az üzenetet). Ha a widget.js beágyazást bármikor
  // sima iframe-re cserélnénk, ez a mérés csendben elhallgatna.
  useEffect(() => {
    // Csak ez a négy a tölcsérlépés. FONTOS: a Calendly UGYANEZEN a csatornán
    // küldi az auto-resize üzeneteit is ("page_height"), ráadásul másodpercenként
    // többször - ezek szűrés nélkül elárasztanák a dataLayert és a GA4-et.
    // A tölcsérlépéseket is ismételheti (mérésben event_type_viewed kétszer jött),
    // ezért oldalletöltésenként mindegyiket csak egyszer engedjük át.
    const FUNNEL = ["profile_page_viewed", "event_type_viewed", "date_and_time_selected", "event_scheduled"];
    const seen = {};
    let redirect = null;
    const onMsg = (e) => {
      if (!e.origin || e.origin.indexOf("calendly.com") === -1) return;
      const ev = e.data && e.data.event;
      if (typeof ev !== "string" || ev.indexOf("calendly.") !== 0) return;
      const step = ev.slice("calendly.".length);
      if (FUNNEL.indexOf(step) === -1 || seen[step]) return;
      seen[step] = 1;
      window.dataLayer = window.dataLayer || [];
      window.dataLayer.push({ event: "nac_calendly", nac_calendly_step: step });
      // Konverziót KIZÁRÓLAG a tényleges lefoglalásra.
      if (step === "event_scheduled") {
        trackConversion("Bemutató foglalás", 100);
        // A késleltetés nem kozmetikai: a fenti konverzió a window.eventStorage
        // pufferbe kerül, ahonnan az IndiData manager.js viszi el - navigációkor
        // a puffer elveszne. Ennyi idő alatt a látogató még látja a Calendly
        // saját visszaigazolását is, tehát nem tűnik elkapkodottnak.
        redirect = setTimeout(() => { window.location.href = thanksUrl(); }, 1200);
      }
    };
    window.addEventListener("message", onMsg);
    return () => { window.removeEventListener("message", onMsg); if (redirect) clearTimeout(redirect); };
  }, []);

  // A naptár megnyitása mikrokonverzió (szándék), nem foglalás - ezért külön
  // néven és kisebb súllyal megy. Korábban ez küldte a "Bemutató foglalás"
  // (100) eseményt, ami felfelé tolta a foglalási számokat.
  const openCalendar = () => {
    trackConversion("Naptár megnyitás", 10);
    window.dataLayer = window.dataLayer || [];
    window.dataLayer.push({ event: "nac_calendar_open" });
    setCalShown(true);
  };
  const steps = [
    { l: "01 · Áttekintés", t: "Megnézzük a meglévő listát, kampányokat és használt eszközöket" },
    { l: "02 · Terv", t: "3 konkrét automatizmus az Ön vállalkozására, plusz teljes kommunikációs terv a következő hónapokra" },
    { l: "03 · Lépésterv", t: "Becsült idő, költség és várható eredmény, írásban" },
    { l: "04 · Ön dönt", t: "Szabadon eldöntheti, szüksége van-e bármely megoldásunkra." }
  ];
  return (
    <section id="foglalas" ref={bookRef} className="dark">
      <div className="wrap">
        <div className="book-wrap">
          <div className="book-left">
            <div className="section-label">Ingyenes bemutató</div>
            <h2 className="h2">{title}</h2>
            <p className="lead">{lead}</p>
            <div className="book-cards">
              {steps.map(s => <div className="book-mini" key={s.l}><div className="book-mini-label">{s.l}</div><div className="book-mini-t">{s.t}</div></div>)}
            </div>
            <div className="gabor-card">
              <div className="gabor-person">
                <img className="gabor-photo" src="assets/gabor.jpg" alt="Tóth Gábor" />
                <div className="gi">
                  <div className="gn">Tóth Gábor</div>
                  <div className="gr">NetAdClick.com</div>
                  <div className="gq">Ügyvezető</div>
                </div>
              </div>
              <div className="gabor-contact">
                <div className="gc-label">Mindig elérhető</div>
                <a className="gc-line" href="tel:+36303082358" onClick={() => trackConversion("Telefonhívás", 100)}><span className="gc-k">Telefon</span><b>+36 30 308 2358</b></a>
                <a className="gc-line" href="mailto:t.gabor@netadclick.com"><span className="gc-k">E-mail</span><b>t.gabor@netadclick.com</b></a>
              </div>
            </div>
          </div>
          <div className={"book-card" + (calShown ? " cal-shown" : "")}>
            <div className="book-card-head">
              <div><div className="t">Ingyenes 30 perces bemutató</div><div className="s">calendly.com / netadclick</div></div>
              <div className="s live"><span className="pulse"></span> ÉLŐ NAPTÁR</div>
            </div>
            <div className="cal-wrap">
              <div className="calendly-inline-widget" data-url={calendlyUrl()} style={{ minWidth: 320, height: "100%", minHeight: 640 }}></div>
              {!calShown &&
                <div className="cal-veil">
                  <div className="cal-veil-inner">
                    <span className="cal-veil-ic" aria-hidden="true">
                      <svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
                        <rect x="3" y="5" width="18" height="16" rx="2.5" />
                        <path d="M8 3v4M16 3v4M3 10h18" />
                        <path d="M7.5 14.5h4M7.5 17.5h8" stroke={ORANGE} strokeWidth="2.2" />
                      </svg>
                    </span>
                    <div className="cal-veil-t">Élő naptár &ndash; szabad időpontok</div>
                    <p className="cal-veil-d">Az oldal elhagyása nélkül választhat időpontot a 30 perces bemutatóra.</p>
                    <button className="cal-reveal-btn" onClick={openCalendar}>Nézze meg a naptárat</button>
                    <div className="cal-veil-note">Ingyenes &middot; kötelezettség nélkül</div>
                  </div>
                </div>}
            </div>
          </div>
        </div>
      </div>
    </section>);
};

// ---------- FAQ ----------
const FAQList = ({ faq, label = "Gyakori kérdések", title = "Mire gondolunk, mielőtt belevágunk." }) => {
  const [open, setOpen] = useState(0);
  return (
    <section id="gyik" style={{ background: "var(--bg-alt)" }}>
      <div className="wrap" style={{ maxWidth: 920 }}>
        <div className="section-label">{label}</div>
        <h2 className="h2">{title}</h2>
        <div className="faq-list">
          {faq.map((f, i) =>
            <div key={i} className={"faq-item " + (open === i ? "open" : "")}>
              <div className="faq-q" onClick={() => setOpen(open === i ? -1 : i)}><span>{f.q}</span><span className="ico">+</span></div>
              <div className="faq-a"><div className="faq-a-inner">{f.a}</div></div>
            </div>)}
        </div>
      </div>
    </section>);
};

// ---------- CROSS-LINK ----------
const CrossLink = ({ text, href, label, eyebrow = "Van saját csapata?" }) =>
  <div className="crosslink">
    <div className="wrap crosslink-inner">
      <div className="cl-copy">
        <div className="cl-eyebrow">{eyebrow}</div>
        <div className="cl-text" dangerouslySetInnerHTML={{ __html: text }}></div>
      </div>
      <a className="btn btn-ghost btn-arrow" href={href}>{label}</a>
    </div>
  </div>;

// ---------- FOOTER ----------
const FOOTER_MODULE_DEFAULT = [
  { href: "#funkciok", label: "Funkciók" },
  { href: "#tamogatas", label: "Támogatás" },
  { href: "#ar", label: "Árazás" },
  { href: "#gyik", label: "GYIK" }
];
const Footer = ({ onBook, otherHref, otherLabel, extraLinks = [], moduleLinks = FOOTER_MODULE_DEFAULT, moduleTitle = "Modul" }) =>
  <footer>
    <div className="wrap">
      <div className="foot-grid">
        <div>
          <span className="foot-logo"><img src="assets/netadclick-logo.png" alt="NetAdClick.com" /></span>
          <p>Hírlevélküldő, kérdőív és webanalitika egy rendszerben magyar kkv-knak, magyar nyelvű támogatással.</p>
        </div>
        <div>
          <h5>{moduleTitle}</h5>
          <ul>
            {moduleLinks.map(l => <li key={l.href}><a href={l.href}>{l.label}</a></li>)}
          </ul>
        </div>
        <div>
          <h5>Kapcsolat</h5>
          <ul>
            <li>AD Solutions Kft.</li>
            <li>+36 30 308 2358</li>
            <li>t.gabor@netadclick.com</li>
            <li>Budapest, Magyarország</li>
          </ul>
        </div>
        <div>
          <h5>Kezdjen bele</h5>
          <ul>
            <li><a href="#foglalas" onClick={(e) => { e.preventDefault(); onBook(); }}>Ingyenes bemutató →</a></li>
            {otherHref && <li><a href={otherHref}>{otherLabel}</a></li>}
            {extraLinks.map(l => <li key={l.href}><a href={l.href}>{l.label}</a></li>)}
            <li><a href="https://netadclick.com" target="_blank" rel="noreferrer">netadclick.com</a></li>
          </ul>
        </div>
      </div>
      <div className="foot-bottom">
        <span>© 2026 AD Solutions Kft. · Minden jog fenntartva</span>
        <span>
          <a href="/suti-szabalyzat">Süti-szabályzat</a>
          {" · "}
          <a href="#" onClick={(e) => { e.preventDefault(); if (window.nacConsent) window.nacConsent.reopen(); }}>
            Süti-beállítások
          </a>
          {" · NetAdClick Hírlevélküldő"}
        </span>
      </div>
    </div>
  </footer>;

// ---------- STICKY BOOK ----------
const StickyBook = ({ onBook, visible, label = "Ingyenes bemutató foglalása" }) => {
  if (!visible) return null;
  return (
    <div className="sticky-actions">
      <a className="sticky-call" href="tel:+36303082358" onClick={() => trackConversion("Telefonhívás", 100)}>
        <span className="sc-ic">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.9.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
        </span>
        <span className="sc-txt"><span className="sc-l">Kérdése van? Hívjon:</span><span className="sc-n">+36 30 308 2358</span></span>
      </a>
      <button className="sticky-book" onClick={onBook}><span className="pulse"></span>{label}</button>
    </div>
  );
};

// ---------- scroll helpers ----------
const useScrollToBook = () => {
  // Use getBoundingClientRect (visual coords) rather than offsetTop (unzoomed
  // layout coords) so the target is correct under the desktop html{zoom} — with
  // offsetTop the value overshoots maxScroll and the page jumps to the bottom.
  return () => { const el = document.getElementById("foglalas"); if (el) window.scrollTo({ top: el.getBoundingClientRect().top + window.scrollY - 40, behavior: "smooth" }); };
};
const useStickyVisible = () => {
  const [v, setV] = useState(false);
  useEffect(() => {
    const onScroll = () => setV(window.scrollY > 600 && window.scrollY < document.body.scrollHeight - window.innerHeight - 500);
    window.addEventListener("scroll", onScroll); onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return v;
};

// ---------- COOKIE NOTICE ----------
// A tényleges hozzájárulás-kezelés a /consent.js-ben van (Consent Mode v2 +
// a Clarity/IndiData betöltésének kapuja), ez a komponens csak a felület
// hozzá. Ha a consent.js nem töltődött be, a sáv sem jelenik meg - és mérés
// sem indul, mert a mérőkódokat is az a fájl tölti be.
const CookieNotice = () => {
  const [show, setShow] = useState(false);
  useEffect(() => {
    const c = window.nacConsent;
    if (!c || c.state()) return;          // nincs consent.js, vagy már döntött
    // Kis késleltetés: a látogató előbb lássa az oldalt, csak utána kérdezzünk.
    // A mérőkódok addig is tiltva vannak, tehát ez nem ront a megfelelésen.
    const t = setTimeout(() => setShow(true), 700);
    return () => clearTimeout(t);
  }, []);
  if (!show) return null;
  const decide = (choice) => () => {
    try { window.nacConsent[choice](); } catch (e) {}
    setShow(false);
  };
  return (
    <div className="cookie-notice" role="dialog" aria-label="Süti tájékoztató">
      <div className="cookie-text">
        Sütiket használunk az oldal működéséhez, a feliratkozás kezeléséhez és a
        kampányaink méréséhez. A részletes elemzéshez (Google Analytics, Microsoft
        Clarity) az Ön hozzájárulását kérjük, amit bármikor visszavonhat.
        Részletek: <a href="/suti-szabalyzat">Süti-szabályzat</a>.
      </div>
      <div className="cookie-actions">
        <button className="cookie-btn" onClick={decide("grant")}>Elfogadom</button>
        <button className="cookie-btn cookie-btn-ghost" onClick={decide("deny")}>Csak a szükséges</button>
      </div>
    </div>
  );
};

Object.assign(window, {
  ICONS, FeatureIcon, useReveal, Logo, Nav, HeroPreview, Testimonials, PartnerStrip, CountUpNum,
  Booking, FAQList, CrossLink, Footer, StickyBook, CookieNotice, useScrollToBook, useStickyVisible, CALENDLY_URL, trackConversion
});
