// primitives.jsx — shared tiny components + hooks
const { useState, useEffect, useRef, useMemo, useCallback } = React;

// IntersectionObserver reveal
function useReveal(threshold = 0.15) {
  const ref = useRef(null);
  const [inView, setInView] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const el = ref.current;
    // Fallback: if an element is already in viewport on mount, reveal immediately.
    const r = el.getBoundingClientRect();
    if (r.top < (window.innerHeight || 0) && r.bottom > 0) {
      setInView(true);
      return;
    }
    const io = new IntersectionObserver(
      ([entry]) => { if (entry.isIntersecting) { setInView(true); io.disconnect(); } },
      { threshold, rootMargin: "0px 0px -5% 0px" }
    );
    io.observe(el);
    // Safety net: reveal after 600ms regardless, so the page never ends up invisible.
    const t = setTimeout(() => { setInView(true); io.disconnect(); }, 600);
    return () => { io.disconnect(); clearTimeout(t); };
  }, [threshold]);
  return [ref, inView];
}

function Reveal({ children, delay = 0, as: Tag = "div", className = "", ...rest }) {
  const [ref, inView] = useReveal();
  return (
    <Tag
      ref={ref}
      className={`reveal ${inView ? "is-in" : ""} ${className}`}
      style={{ transitionDelay: `${delay}ms` }}
      {...rest}
    >
      {children}
    </Tag>
  );
}

// Tiny inline icons
const Icon = {
  arrow: (p) => (<svg className="arrow" width="14" height="14" viewBox="0 0 14 14" fill="none" {...p}><path d="M3 7h8m0 0L7.5 3.5M11 7l-3.5 3.5" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/></svg>),
  signal: (p) => (<svg width="18" height="18" viewBox="0 0 18 18" fill="none" {...p}><path d="M2 12h2m3-3h2m3-3h2m-10 9h14" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/></svg>),
  calendar: (p) => (<svg width="18" height="18" viewBox="0 0 18 18" fill="none" {...p}><rect x="2.5" y="4" width="13" height="11" rx="1.5" stroke="currentColor" strokeWidth="1.3"/><path d="M2.5 8h13M6 2.5v3M12 2.5v3" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/></svg>),
  wrench: (p) => (<svg width="18" height="18" viewBox="0 0 18 18" fill="none" {...p}><path d="M12.5 2.5a3 3 0 0 0-2.8 4.1L3 13.3a1.5 1.5 0 1 0 2.1 2.1l6.7-6.7a3 3 0 0 0 4-3.6l-2 2-1.8-.5-.5-1.8 2-2a3 3 0 0 0-1-.3z" stroke="currentColor" strokeWidth="1.2" strokeLinejoin="round"/></svg>),
  chat: (p) => (<svg width="18" height="18" viewBox="0 0 18 18" fill="none" {...p}><path d="M3 4.5h12v8H9l-3 2.5v-2.5H3v-8z" stroke="currentColor" strokeWidth="1.3" strokeLinejoin="round"/></svg>),
  dot: (p) => (<svg width="6" height="6" viewBox="0 0 6 6" {...p}><circle cx="3" cy="3" r="3" fill="currentColor"/></svg>),
  plus: (p) => (<svg width="14" height="14" viewBox="0 0 14 14" fill="none" {...p}><path d="M7 2v10M2 7h10" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/></svg>),
};

// Content
const TAGLINES = {
  headline_primary: {
    headline: (<>The AI shift is already happening. <em>Your team can't see it yet.</em></>),
    plain: "The AI shift is already happening. Your team can't see it yet.",
  },
  headline_urgent: {
    headline: (<>AI is rewriting how companies work. <em>Most brands are missing it.</em></>),
    plain: "AI is rewriting how companies work. Most brands are missing it.",
  },
  headline_ships: {
    headline: (<>A two-year head start is up for grabs. <em>Take yours.</em></>),
    plain: "A two-year head start is up for grabs. Take yours.",
  },
};

const PHASES = {
  install_solve_embed: [
    { name: "Install", italic: "Install",
      when: "Week 1–2",
      desc: "We bring in the tools that actually work. Claude Code, MCP servers, Obsidian, the integrations that wire your stack together.",
      items: [
        "Claude Code + MCP servers on team laptops",
        "Obsidian vault wired to Notion / Linear / Slack",
        "Access audit, secrets, model routing",
        "One workflow lift selected with you",
      ]
    },
    { name: "Solve", italic: "Solve",
      when: "Day 1 live session",
      desc: "We pick one real problem from your backlog and solve it in front of your team. Tom's was three shipped outcomes in an hour.",
      items: [
        "1-hour working session, your team watching",
        "Ship at least one real outcome that day",
        "Hand over the recording + the prompts",
        "Their first 'oh, this is different' moment",
      ]
    },
    { name: "Embed", italic: "Embed",
      when: "Month 2 onward",
      desc: "The retainer. One person who filters the noise, keeps your stack current, shows up on Tuesdays, ships the next thing.",
      items: [
        "Weekly office hours with your team",
        "Monthly build day on a real workflow",
        "Signal filter: the 2 things that matter this month",
        "Stack upkeep as models / tools change",
      ]
    },
  ],
  integrate_audit_distribute: [
    { name: "Integrate", italic: "Integrate",
      when: "Week 1–2",
      desc: "We bring in the tools that actually work. Claude Code, MCP servers, Obsidian, the integrations that wire your stack together.",
      items: [
        "Claude Code + MCP servers on team laptops",
        "Obsidian vault wired to Notion / Linear / Slack",
        "Access audit, secrets, model routing",
        "One workflow lift selected with you",
      ]
    },
    { name: "Audit", italic: "Audit",
      when: "Day 1 live session",
      desc: "We pick one real problem from your backlog and solve it in front of your team. Tom's was three shipped outcomes in an hour.",
      items: [
        "1-hour working session, your team watching",
        "Ship at least one real outcome that day",
        "Hand over the recording + the prompts",
        "Their first 'oh, this is different' moment",
      ]
    },
    { name: "Distribute", italic: "Distribute",
      when: "Month 2 onward",
      desc: "The retainer. One person who filters the noise, keeps your stack current, shows up on Tuesdays, ships the next thing.",
      items: [
        "Weekly office hours with your team",
        "Monthly build day on a real workflow",
        "Signal filter: the 2 things that matter this month",
        "Stack upkeep as models / tools change",
      ]
    },
  ],
};

Object.assign(window, { useReveal, Reveal, Icon, TAGLINES, PHASES });
