/* Dentist site — shared atoms */
const { useEffect: dUE, useRef: dUR, useState: dUS } = React;

function Reveal({ as = "div", delay = 0, className = "", style = {}, children, ...rest }) {
  const ref = dUR(null);
  dUE(() => {
    const el = ref.current; if (!el) return;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { el.classList.add("is-in"); io.unobserve(el); }
    }, { threshold: 0.1, rootMargin: "0px 0px -6% 0px" });
    io.observe(el);
    const fallback = setTimeout(() => el && el.classList.add("is-in"), 1600);
    return () => { io.disconnect(); clearTimeout(fallback); };
  }, []);
  const Tag = as;
  return (
    <Tag ref={ref} className={`reveal ${className}`}
      style={{ ...style, "--reveal-delay": `${delay}ms` }} {...rest}>{children}</Tag>
  );
}

function Slot({ caption, ratio = "4 / 5", style = {}, className = "", children }) {
  return (
    <div className={`slot ${className}`} style={{ aspectRatio: ratio, ...style }}>
      <span className="slot__caption">{caption}</span>{children}
    </div>
  );
}

function Wordmark({ size = 18, color = "currentColor" }) {
  const h = Math.round(size * 1.15);
  return (
    <a href="#top" aria-label="360 Whitening"
      style={{ display: "inline-block", color, height: h, width: Math.round(h * 5.2517), lineHeight: 0 }}
      dangerouslySetInnerHTML={{ __html: window.LOGO_360_SVG }} />
  );
}

const I = {
  Arrow: (p) => <svg width="14" height="14" viewBox="0 0 14 14" fill="none" {...p}><path d="M1 7h12M8 2l5 5-5 5" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Plus:  (p) => <svg width="14" height="14" viewBox="0 0 14 14" fill="none" {...p}><path d="M7 1v12M1 7h12" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/></svg>,
  Minus: (p) => <svg width="14" height="14" viewBox="0 0 14 14" fill="none" {...p}><path d="M1 7h12" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/></svg>,
  Close: (p) => <svg width="14" height="14" viewBox="0 0 14 14" fill="none" {...p}><path d="M2 2l10 10M12 2L2 12" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/></svg>,
  Check: (p) => <svg width="12" height="12" viewBox="0 0 12 12" fill="none" {...p}><path d="M2 6.5 5 9.5 10 3" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Download: (p) => <svg width="14" height="14" viewBox="0 0 14 14" fill="none" {...p}><path d="M7 1v8M3 6l4 4 4-4M2 13h10" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round"/></svg>,
};

/* Brand pattern from the packaging — gold lines on black (dark mode)
   or gold/dark on white (light mode). */
function ShatterLines({ mode, opacity, stroke, lines, seed, ...rest }) {
  const isDark = mode === "dark" || (stroke && stroke.includes("239"));
  const src = isDark ? "uploads/black-box-web.png" : "uploads/white-box-web.png";
  const op = opacity ?? (isDark ? 0.28 : 0.16);
  return (
    <div aria-hidden="true" style={{
      position: "absolute", inset: 0, pointerEvents: "none", zIndex: 0,
      backgroundImage: `url("${src}")`,
      backgroundSize: "cover",
      backgroundPosition: "center",
      backgroundRepeat: "no-repeat",
      opacity: op,
      mixBlendMode: isDark ? "screen" : "multiply",
    }} />
  );
}

/* Spec-row helper */
function SpecRow({ k, v }) {
  return (
    <div style={{
      display: "grid", gridTemplateColumns: "minmax(120px, 0.6fr) minmax(0, 1fr)",
      gap: 16, padding: "12px 0",
      borderBottom: "1px solid var(--on-light-15)",
      alignItems: "baseline",
    }}>
      <span style={{
        fontFamily: "var(--font-mono)", fontSize: 10,
        letterSpacing: "0.18em", textTransform: "uppercase",
        color: "var(--on-light-60)",
      }}>{k}</span>
      <span style={{ fontSize: 14, color: "var(--ink)" }}>{v}</span>
    </div>
  );
}

Object.assign(window, { Reveal, Slot, Wordmark, I, ShatterLines, SpecRow });
