/* Shared atoms */
const { useEffect, useRef, useState, useCallback } = React;

function Reveal({ as = "div", delay = 0, className = "", style = {}, children, ...rest }) {
  const ref = useRef(null);
  useEffect(() => {
    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.12, rootMargin: "0px 0px -8% 0px" });
    io.observe(el);
    // Safety net: never let content stay invisible if IO doesn't fire
    // (html-to-image capture, print, odd browsers).
    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 = "3 / 4", 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 }} />
  );
}

/* Inline glyphs */
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>,
  Star:   (p) => <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" {...p}><path d="M12 2l2.6 7.4H22l-6 4.6L18 22l-6-4.4L6 22l2-7.9L2 9.4h7.4z"/></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>,
  Play:   (p) => <svg width="22" height="22" viewBox="0 0 22 22" fill="currentColor" {...p}><path d="M7 5l10 6-10 6V5z"/></svg>,
  Pin:    (p) => <svg width="14" height="14" viewBox="0 0 14 14" fill="none" {...p}><path d="M7 13s5-4.5 5-8a5 5 0 1 0-10 0c0 3.5 5 8 5 8z" stroke="currentColor" strokeWidth="1.3"/><circle cx="7" cy="5" r="1.8" stroke="currentColor" strokeWidth="1.3"/></svg>,
};

/* Edition stamp — rotated, foil-y */
function EditionStamp({ label = "Edition 01", number = "MMXXVI", angle = -7 }) {
  return (
    <div style={{
      display: "inline-flex", flexDirection: "column", alignItems: "center",
      transform: `rotate(${angle}deg)`,
      padding: "12px 16px",
      border: "1px solid var(--accent)",
      color: "var(--accent)",
      borderRadius: 4,
      gap: 2,
      fontFamily: "var(--font-mono)",
      fontSize: 9,
      letterSpacing: "0.24em",
      textTransform: "uppercase",
      background: "linear-gradient(135deg, rgba(212,176,122,0.06), rgba(212,176,122,0.0))",
      backdropFilter: "blur(6px)",
    }}>
      <span style={{ opacity: 0.7 }}>★ {label} ★</span>
      <span style={{
        fontFamily: "var(--font-display)", fontStyle: "italic", fontSize: 18,
        letterSpacing: "0.06em",
        fontVariationSettings: '"opsz" 144, "SOFT" 100, "WONK" 1',
      }}>{number}</span>
    </div>
  );
}

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

/* Brand pattern from the packaging — gold lines on black (dark mode)
   or gold/dark on white (light mode). Replaces the synthetic SVG. */
function ShatterLines({ mode, opacity, stroke, lines, seed, ...rest }) {
  // Auto-detect light vs dark from the optional stroke hint, default light
  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.25 : 0.18);
  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",
    }} />
  );
}
