// Shared UI atoms for the SME profile.
const { useState, useRef, useEffect, useCallback } = React;

// Fade + rise on scroll into view.
function Reveal({ children, delay = 0, y = 20, style, as = "div", ...rest }) {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    let done = false; const show = () => { if (!done) { done = true; setShown(true); } };
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) { show(); return; }
    // Anything already in (or above) the first viewport reveals immediately.
    if (el.getBoundingClientRect().top < window.innerHeight * 0.96) { show(); return; }
    const io = new IntersectionObserver((es) => { if (es.some((e) => e.isIntersecting)) show(); }, { threshold: 0.1, rootMargin: "0px 0px 12% 0px" });
    io.observe(el);
    const t = setTimeout(show, 1600); // safety net so a section can never stay hidden
    return () => { io.disconnect(); clearTimeout(t); };
  }, []);
  const Tag = as;
  return (
    <Tag ref={ref} style={{ ...style, opacity: shown ? 1 : 0, transform: shown ? "none" : `translateY(${y}px)`, transition: `opacity .7s cubic-bezier(.2,.7,.2,1) ${delay}s, transform .7s cubic-bezier(.2,.7,.2,1) ${delay}s` }} {...rest}>
      {children}
    </Tag>
  );
}

function Eyebrow({ children, style }) {
  return <div className="mono" style={{ fontSize: 12, letterSpacing: "0.16em", textTransform: "uppercase", color: "var(--violet-bright)", fontWeight: 700, marginBottom: 14, ...style }}>{children}</div>;
}

const Ico = {
  check: (p = {}) => (<svg width={p.size || 14} height={p.size || 14} viewBox="0 0 24 24" fill="none" stroke={p.stroke || "currentColor"} strokeWidth={p.sw || 3} strokeLinecap="round" strokeLinejoin="round"><path d="M20 6 9 17l-5-5" /></svg>),
  star: (p = {}) => (<svg width={p.size || 14} height={p.size || 14} viewBox="0 0 24 24" fill="currentColor"><path d="m12 2 2.9 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77 5.82 21l1.18-6.88-5-4.87 7.1-1.01z" /></svg>),
  arrow: (p = {}) => (<svg width={p.size || 16} height={p.size || 16} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={p.sw || 2.4} strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M13 6l6 6-6 6" /></svg>),
  copy: (p = {}) => (<svg width={p.size || 13} height={p.size || 13} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="9" y="9" width="12" height="12" rx="2" /><path d="M5 15V5a2 2 0 0 1 2-2h10" /></svg>),
};

Object.assign(window, { Reveal, Eyebrow, Ico });
