// LongtailIQ marketing, premium interaction FX (original, on-brand)
(function init(){
if(!window.LongtailIQDesignSystem_ae8f12){return setTimeout(init,30);}
const React = window.React;
const DS = window.LongtailIQDesignSystem_ae8f12;
const { Icon } = DS;

// Track pointer for spotlight: sets --mx/--my on the element
function useSpotlight() {
  return React.useCallback((e) => {
    const r = e.currentTarget.getBoundingClientRect();
    e.currentTarget.style.setProperty('--mx', (e.clientX - r.left) + 'px');
    e.currentTarget.style.setProperty('--my', (e.clientY - r.top) + 'px');
  }, []);
}

// Magnetic wrapper, element eases toward the cursor (rAF-smoothed), springs back.
// `inner` also parallaxes the label slightly for depth.
function Magnetic({ children, strength = 0.4, inner = 0.18, style = {} }) {
  const ref = React.useRef(null);
  const innerRef = React.useRef(null);
  const target = React.useRef({ x: 0, y: 0 });
  const cur = React.useRef({ x: 0, y: 0 });
  const raf = React.useRef(0);
  const tick = () => {
    cur.current.x += (target.current.x - cur.current.x) * 0.18;
    cur.current.y += (target.current.y - cur.current.y) * 0.18;
    if (ref.current) ref.current.style.transform = `translate(${cur.current.x.toFixed(2)}px, ${cur.current.y.toFixed(2)}px)`;
    if (innerRef.current) innerRef.current.style.transform = `translate(${(cur.current.x * inner).toFixed(2)}px, ${(cur.current.y * inner).toFixed(2)}px)`;
    if (Math.abs(target.current.x - cur.current.x) > 0.1 || Math.abs(target.current.y - cur.current.y) > 0.1) raf.current = requestAnimationFrame(tick);
  };
  const start = () => { cancelAnimationFrame(raf.current); raf.current = requestAnimationFrame(tick); };
  const onMove = (e) => {
    const el = ref.current; if (!el) return;
    const r = el.getBoundingClientRect();
    target.current = { x: (e.clientX - (r.left + r.width / 2)) * strength, y: (e.clientY - (r.top + r.height / 2)) * strength };
    start();
  };
  const onLeave = () => { target.current = { x: 0, y: 0 }; start(); };
  React.useEffect(() => () => cancelAnimationFrame(raf.current), []);
  return (
    <span ref={ref} onMouseMove={onMove} onMouseLeave={onLeave} style={{ display: 'inline-flex', ...style }}>
      <span ref={innerRef} style={{ display: 'inline-flex' }}>{children}</span>
    </span>
  );
}

// 3D tilt card with a cursor-following glare highlight
function Tilt({ children, max = 7, glare = true, style = {}, className = '' }) {
  const ref = React.useRef(null);
  const glareRef = React.useRef(null);
  const onMove = (e) => {
    const el = ref.current; if (!el) return;
    const r = el.getBoundingClientRect();
    const px = (e.clientX - r.left) / r.width - 0.5;
    const py = (e.clientY - r.top) / r.height - 0.5;
    el.style.transform = `perspective(900px) rotateX(${(-py * max).toFixed(2)}deg) rotateY(${(px * max).toFixed(2)}deg)`;
    el.style.setProperty('--mx', (e.clientX - r.left) + 'px');
    el.style.setProperty('--my', (e.clientY - r.top) + 'px');
    if (glareRef.current) {
      glareRef.current.style.opacity = '1';
      glareRef.current.style.background = `radial-gradient(280px circle at ${e.clientX - r.left}px ${e.clientY - r.top}px, rgba(255,255,255,0.18), transparent 60%)`;
    }
  };
  const onLeave = () => {
    if (ref.current) ref.current.style.transform = 'perspective(900px) rotateX(0) rotateY(0)';
    if (glareRef.current) glareRef.current.style.opacity = '0';
  };
  return (
    <div ref={ref} className={className} onMouseMove={onMove} onMouseLeave={onLeave}
      style={{ position: 'relative', transition: 'transform 0.45s var(--ease-out)', transformStyle: 'preserve-3d', ...style }}>
      {children}
      {glare && <div ref={glareRef} style={{ position: 'absolute', inset: 0, borderRadius: 'inherit', pointerEvents: 'none', opacity: 0, transition: 'opacity 0.3s var(--ease-out)', zIndex: 5 }} />}
    </div>
  );
}

// Word-by-word reveal headline (uses lt-reveal so the page observer +
// its safety fallback guarantee visibility even when animation is throttled)
function RevealWords({ text, gray = '', style = {} }) {
  const words = text.split(' ');
  const grayWords = gray ? gray.split(' ') : [];
  return (
    <h1 style={style}>
      {words.map((w, k) => (
        <span key={k} className="lt-reveal" style={{ display: 'inline-block', marginRight: '0.28em' }}>{w}</span>
      ))}
      {grayWords.length > 0 && <br/>}
      {grayWords.map((w, k) => (
        <span key={'g'+k} className="lt-reveal" style={{ display: 'inline-block', marginRight: '0.28em', color: 'var(--ink-400)' }}>{w}</span>
      ))}
    </h1>
  );
}

// Marquee row of platform chips
function PlatformMarquee() {
  const items = ["Google","AI Overviews","ChatGPT","Perplexity","Reddit","YouTube","TikTok","Amazon","Shopify","Gemini","Bing Copilot","Local Pack"];
  const Chip = ({ t }) => (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 8, height: 38, padding: "0 16px", flex: "none",
      border: "1px solid var(--border-subtle)", borderRadius: 999, background: "var(--paper)", fontSize: 13, fontWeight: 500, color: "var(--text-body)" }}>
      <span style={{ width: 6, height: 6, borderRadius: 999, background: "var(--ink-300)" }} />{t}
    </span>
  );
  return (
    <div style={{ borderTop: "1px solid var(--border-subtle)", borderBottom: "1px solid var(--border-subtle)", background: "var(--ink-50)", padding: "22px 0" }}>
      <div style={{ textAlign: "center", fontSize: 12, color: "var(--text-faint)", marginBottom: 16, letterSpacing: "0.02em" }}>One seed keyword, mapped across every surface people search</div>
      <div className="fx-marquee">
        <div className="fx-marquee-track">
          {[...items, ...items].map((t, i) => <Chip key={i} t={t} />)}
        </div>
      </div>
    </div>
  );
}

// Meteor field, N glowing diagonal streaks with varied size + speed
function Meteors({ count = 14 }) {
  const items = React.useMemo(() => Array.from({ length: count }, () => ({
    left: Math.random() * 130 - 15,
    delay: (Math.random() * 7).toFixed(2),
    dur: (3 + Math.random() * 4.5).toFixed(2),
    scale: (0.7 + Math.random() * 0.9).toFixed(2),
    op: (0.5 + Math.random() * 0.5).toFixed(2),
  })), [count]);
  return (
    <div style={{ position: "absolute", inset: 0, overflow: "hidden", pointerEvents: "none" }}>
      {items.map((m, i) => (
        <span key={i} className="fx-meteor" style={{ left: m.left + "%", animationDelay: m.delay + "s", animationDuration: m.dur + "s", height: (90 * m.scale) + "px", opacity: m.op }} />
      ))}
    </div>
  );
}

// Typewriter, cycles through phrases with natural, slightly varied timing
function Typewriter({ phrases, speed = 72, pause = 1500, style = {} }) {
  const [i, setI] = React.useState(0);
  const [sub, setSub] = React.useState(0);
  const [del, setDel] = React.useState(false);
  React.useEffect(() => {
    const cur = phrases[i];
    if (!del && sub === cur.length) { const t = setTimeout(() => setDel(true), pause); return () => clearTimeout(t); }
    if (del && sub === 0) { setDel(false); setI((i + 1) % phrases.length); return; }
    // jitter typing speed; pause a beat on spaces for a human cadence
    const justTyped = cur[sub - 1];
    const base = del ? speed * 0.45 : speed;
    const jitter = del ? 0 : (Math.random() * 50 - 18);
    const spacePause = (!del && justTyped === ' ') ? 90 : 0;
    const t = setTimeout(() => setSub(s => s + (del ? -1 : 1)), Math.max(24, base + jitter) + spacePause);
    return () => clearTimeout(t);
  }, [sub, del, i, phrases, speed, pause]);
  return (
    <span style={style}>{phrases[i].slice(0, sub)}<span className="fx-caret" /></span>
  );
}

// Scroll progress bar
function ScrollProgress() {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const onScroll = () => {
      const el = ref.current; if (!el) return;
      const h = document.documentElement;
      const p = h.scrollTop / (h.scrollHeight - h.clientHeight || 1);
      el.style.width = Math.max(0, Math.min(1, p)) * 100 + "%";
    };
    window.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return <div ref={ref} className="fx-scrollbar" />;
}

// Ripple click helper, attach to onMouseDown of a positioned element
function useRipple() {
  return React.useCallback((e) => {
    const host = e.currentTarget;
    const r = host.getBoundingClientRect();
    const span = document.createElement("span");
    const size = Math.max(r.width, r.height) * 2.2;
    span.className = "fx-ripple-ink";
    span.style.width = span.style.height = size + "px";
    span.style.left = (e.clientX - r.left) + "px";
    span.style.top = (e.clientY - r.top) + "px";
    host.appendChild(span);
    setTimeout(() => span.remove(), 650);
  }, []);
}

window.LTQM = window.LTQM || {};
Object.assign(window.LTQM, { useSpotlight, Magnetic, Tilt, RevealWords, PlatformMarquee, Meteors, Typewriter, ScrollProgress, useRipple });
})();
