// primitives.jsx — small icon set + reusable bits
// All icons are simple geometric strokes — no brand marks, no copyrighted glyphs.

const Icon = ({ name, size = 20, stroke = 1.6, ...rest }) => {
  const props = {
    width: size, height: size, viewBox: "0 0 24 24",
    fill: "none", stroke: "currentColor", strokeWidth: stroke,
    strokeLinecap: "round", strokeLinejoin: "round",
    ...rest,
  };
  switch (name) {
    case "compass": // brand mark — white lightning in blue disc with black outline
      return (
        <svg width={size} height={size} viewBox="0 0 24 24" fill="none">
          <circle cx="12" cy="12" r="10.5" fill="var(--accent)" stroke="#0B1220" strokeWidth="1.25"/>
          <path d="M13.4 4.5 L7.5 13.4 H11.5 L10.6 19.5 L16.5 10.6 H12.5 L13.4 4.5 Z"
                fill="#fff" stroke="#fff" strokeWidth="0.6" strokeLinejoin="round"
                transform="rotate(18 12 12)"/>
        </svg>
      );
    case "arrow-right":
      return <svg {...props}><path d="M5 12h14M13 5l7 7-7 7"/></svg>;
    case "arrow-down":
      return <svg {...props}><path d="M12 5v14M5 13l7 7 7-7"/></svg>;
    case "menu":
      return <svg {...props}><path d="M4 7h16M4 12h16M4 17h16"/></svg>;
    case "x":
      return <svg {...props}><path d="M6 6l12 12M18 6L6 18"/></svg>;
    case "plus":
      return <svg {...props}><path d="M12 5v14M5 12h14"/></svg>;
    case "check":
      return <svg {...props}><path d="M5 12.5l4.5 4.5L19 7.5"/></svg>;
    case "search":
      return <svg {...props}><circle cx="11" cy="11" r="7"/><path d="M20 20l-3.5-3.5"/></svg>;
    case "ship":
      return <svg {...props}><path d="M3 16l1.5 4h15L21 16"/><path d="M5 16V9l7-3 7 3v7"/><path d="M12 6v10"/></svg>;
    case "doc":
      return <svg {...props}><path d="M7 3h8l4 4v14H7z"/><path d="M14 3v5h5"/><path d="M9 13h7M9 17h5"/></svg>;
    case "wrench":
      return <svg {...props}><path d="M14.5 3.5a5 5 0 0 0-5 6L3 16l3 3 6.5-6.5a5 5 0 0 0 6-5l-3 3-3-1-1-3z"/></svg>;
    case "shield":
      return <svg {...props}><path d="M12 3l8 3v6c0 5-4 8-8 9-4-1-8-4-8-9V6z"/><path d="M9 12l2.2 2.2L15 10"/></svg>;
    case "key":
      return <svg {...props}><circle cx="8" cy="14" r="4"/><path d="M11 12l9-9"/><path d="M17 6l3 3"/></svg>;
    case "phone":
      return <svg {...props}><path d="M5 4h4l2 5-3 2a12 12 0 0 0 5 5l2-3 5 2v4a2 2 0 0 1-2 2A17 17 0 0 1 3 6a2 2 0 0 1 2-2z"/></svg>;
    case "mail":
      return <svg {...props}><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 7l9 6 9-6"/></svg>;
    case "wa":
      return <svg width={size} height={size} viewBox="0 0 24 24" fill="currentColor"><path d="M12.04 2C6.58 2 2.13 6.45 2.13 11.91c0 1.91.5 3.78 1.45 5.42L2 22l4.83-1.55a9.84 9.84 0 0 0 5.21 1.49h.01c5.46 0 9.91-4.45 9.91-9.91A9.84 9.84 0 0 0 12.04 2zm5.6 14.27c-.24.66-1.41 1.27-1.94 1.31-.5.04-1.13.06-1.83-.11-.42-.13-.97-.31-1.67-.61-2.94-1.27-4.86-4.23-5.01-4.42-.15-.2-1.2-1.59-1.2-3.04s.76-2.16 1.04-2.45c.27-.29.6-.37.8-.37l.57.01c.18.01.42-.07.66.5.24.59.83 2.05.9 2.2.07.15.12.32.02.51-.1.2-.15.32-.3.49-.15.18-.32.39-.46.53-.15.15-.31.31-.13.6.18.29.81 1.34 1.74 2.16 1.2 1.06 2.21 1.39 2.5 1.55.29.15.46.13.63-.07.18-.2.73-.85.93-1.14.2-.29.4-.24.66-.15.27.1 1.74.82 2.04.97.29.15.49.22.56.34.07.13.07.74-.17 1.4z"/></svg>;
    case "linkedin":
      return <svg width={size} height={size} viewBox="0 0 24 24" fill="currentColor"><path d="M4.98 3.5C4.98 4.88 3.87 6 2.5 6S0 4.88 0 3.5 1.12 1 2.5 1s2.48 1.12 2.48 2.5zM.22 8h4.55v14H.22zM7.7 8h4.36v1.92h.06c.61-1.15 2.1-2.36 4.32-2.36 4.62 0 5.47 3.04 5.47 7v7.44h-4.55v-6.6c0-1.57-.03-3.6-2.19-3.6-2.2 0-2.53 1.71-2.53 3.49V22H7.7z"/></svg>;
    case "ig":
      return <svg {...props}><rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17" cy="7" r="0.6" fill="currentColor"/></svg>;
    case "yt":
      return <svg {...props}><rect x="2" y="5" width="20" height="14" rx="4"/><path d="M10 9.5l5 2.5-5 2.5z" fill="currentColor"/></svg>;
    default:
      return null;
  }
};

// CarPlaceholder — clean, intentional placeholder. No drawn vehicles.
// Variants give visual variety in the references grid.
const CarPlaceholder = ({ label = "Tesla · placeholder", code = "—", tone = 0, aspect = "wide" }) => {
  const tones = [
    { bg: "linear-gradient(180deg,#F4F6FA,#E5ECF6)", stripe: "rgba(11,18,32,.06)", glow: "rgba(74,144,226,.16)" },
    { bg: "linear-gradient(180deg,#EEF2F8,#DDE5F1)", stripe: "rgba(11,18,32,.05)", glow: "rgba(27,58,95,.18)" },
    { bg: "linear-gradient(180deg,#F8F9FB,#EAEEF5)", stripe: "rgba(11,18,32,.05)", glow: "rgba(10,102,194,.14)" },
    { bg: "linear-gradient(180deg,#F0F0F2,#DEE0E5)", stripe: "rgba(11,18,32,.06)", glow: "rgba(11,18,32,.10)" },
    { bg: "linear-gradient(180deg,#F1F4FA,#E0E7F2)", stripe: "rgba(11,18,32,.05)", glow: "rgba(74,144,226,.20)" },
  ];
  const t = tones[tone % tones.length];
  const ar = aspect === "wide" ? "16/9" : aspect === "square" ? "1/1" : aspect === "tall" ? "4/3" : "5/4";
  return (
    <div style={{
      position: "relative",
      aspectRatio: ar,
      background: t.bg,
      overflow: "hidden",
    }}>
      <div style={{
        position: "absolute", inset: 0,
        backgroundImage: `repeating-linear-gradient(-28deg, ${t.stripe} 0 1px, transparent 1px 14px)`,
      }} />
      <div style={{
        position: "absolute", inset: "auto -10% -30% 40%",
        height: "70%", width: "70%",
        background: `radial-gradient(closest-side, ${t.glow}, transparent 70%)`,
      }} />
      <div style={{
        position: "absolute", left: 14, bottom: 12,
        display: "inline-flex", gap: 8, alignItems: "center",
        background: "rgba(255,255,255,.86)",
        border: "1px solid rgba(11,18,32,.08)",
        padding: "6px 10px", borderRadius: 999,
        fontFamily: "JetBrains Mono, monospace", fontSize: 11,
        color: "#2A3245", backdropFilter: "blur(6px)",
      }}>
        <span style={{ width: 6, height: 6, borderRadius: "50%", background: "var(--accent)" }} />
        {label}
      </div>
      <div style={{
        position: "absolute", right: 14, top: 14,
        fontFamily: "JetBrains Mono, monospace", fontSize: 10,
        color: "#5A6275", letterSpacing: ".06em",
      }}>{code}</div>
    </div>
  );
};

// Reveal — IO-driven fade/slide-up wrapper
const Reveal = ({ children, delay = 0, as = "div", className = "", style }) => {
  const ref = React.useRef(null);
  const [seen, setSeen] = React.useState(false);
  React.useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver((es) => {
      es.forEach(e => { if (e.isIntersecting) { setSeen(true); io.disconnect(); } });
    }, { threshold: 0.12, rootMargin: "0px 0px -40px 0px" });
    io.observe(ref.current);
    return () => io.disconnect();
  }, []);
  const Tag = as;
  return (
    <Tag ref={ref}
      className={`reveal ${seen ? "in" : ""} ${className}`}
      style={{ ...style, "--d": `${delay}ms` }}>
      {children}
    </Tag>
  );
};

// smooth-scroll helper
const scrollToId = (id) => {
  const el = document.getElementById(id);
  if (!el) return;
  const top = el.getBoundingClientRect().top + window.scrollY - 60;
  window.scrollTo({ top, behavior: "smooth" });
};

// CountUp — animates from 0 → target once visible
const CountUp = ({ to = 0, duration = 1400, suffix = "" }) => {
  const ref = React.useRef(null);
  const [val, setVal] = React.useState(0);
  const [run, setRun] = React.useState(false);
  React.useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver((es) => {
      es.forEach(e => { if (e.isIntersecting) { setRun(true); io.disconnect(); } });
    }, { threshold: 0.4 });
    io.observe(ref.current);
    return () => io.disconnect();
  }, []);
  React.useEffect(() => {
    if (!run) return;
    let raf, t0;
    const step = (t) => {
      if (!t0) t0 = t;
      const p = Math.min(1, (t - t0) / duration);
      const eased = 1 - Math.pow(1 - p, 3); // easeOutCubic
      setVal(Math.round(eased * to));
      if (p < 1) raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [run, to, duration]);
  return <span ref={ref}>{val}{suffix}</span>;
};

Object.assign(window, { Icon, CarPlaceholder, Reveal, scrollToId, CountUp });
