const { useEffect, useRef, useState } = React;

function Container({ children, style, ...rest }) {
  return (
    <div style={{ width: "100%", maxWidth: 1440, margin: "0 auto", padding: "0 clamp(20px, 5vw, 32px)", ...style }} {...rest}>
      {children}
    </div>
  );
}

function Rule({ style }) {
  return <div style={{ height: 1, background: "var(--rule-2)", width: "100%", ...style }} />;
}

function Kicker({ children, dot = true, style }) {
  return (
    <div className="mono" style={{ display: "inline-flex", alignItems: "center", gap: 8, color: "var(--fg-mute)", ...style }}>
      {dot && <span style={{ width: 6, height: 6, borderRadius: 999, background: "var(--accent)", animation: "pulse 2s ease-in-out infinite" }} />}
      {children}
    </div>
  );
}

function Btn({ children, variant = "accent", onClick, as = "button", href, style, size = "lg", ...rest }) {
  const sizes = {
    lg: { height: 56, padding: "0 28px", fontSize: 16 },
    md: { height: 44, padding: "0 20px", fontSize: 14 },
  };
  const variants = {
    accent: { background: "var(--accent)", color: "var(--accent-ink)", border: "1px solid var(--accent)" },
    solid:  { background: "var(--fg)", color: "var(--bg)", border: "1px solid var(--fg)" },
    ghost:  { background: "transparent", color: "var(--fg)", border: "1px solid var(--rule-2)" },
  };
  const Tag = as;
  return (
    <Tag
      href={href} onClick={onClick}
      style={{
        display: "inline-flex", alignItems: "center", gap: 10,
        fontFamily: "var(--sans)", fontWeight: 600, letterSpacing: "-0.01em",
        borderRadius: 999, whiteSpace: "nowrap",
        transition: "transform .15s ease, filter .15s ease",
        ...sizes[size], ...variants[variant], ...style,
      }}
      onMouseDown={(e) => (e.currentTarget.style.transform = "scale(0.98)")}
      onMouseUp={(e) => (e.currentTarget.style.transform = "")}
      onMouseLeave={(e) => (e.currentTarget.style.transform = "")}
      {...rest}
    >
      {children}
    </Tag>
  );
}

function Arrow({ size = 14, angle = 0 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 14 14" fill="none" style={{ transform: `rotate(${angle}deg)` }}>
      <path d="M2 12L12 2M12 2H4.5M12 2V9.5" stroke="currentColor" strokeWidth="1.6" strokeLinecap="square" />
    </svg>
  );
}

function Plus({ size = 14 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 14 14">
      <path d="M7 0v14M0 7h14" stroke="currentColor" strokeWidth="1.5" />
    </svg>
  );
}

function Check({ size = 14 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 14 14" fill="none">
      <path d="M2 7.5L6 11L12 3" stroke="currentColor" strokeWidth="1.75" strokeLinecap="square" />
    </svg>
  );
}

// Striped placeholder
function ImgPH({ label = "image", aspect = "4/5", style }) {
  return (
    <div style={{
      aspectRatio: aspect,
      width: "100%",
      background: "repeating-linear-gradient(135deg, var(--rule) 0 10px, transparent 10px 22px)",
      border: "1px solid var(--rule-2)",
      borderRadius: 8,
      position: "relative",
      ...style,
    }}>
      <div className="mono" style={{ position: "absolute", left: 14, bottom: 12, color: "var(--fg-mute)" }}>
        [ {label} ]
      </div>
    </div>
  );
}

function Reveal({ children, delay = 0, y = 16 }) {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    const r = el.getBoundingClientRect();
    if (r.top < window.innerHeight && r.bottom > 0) { setShown(true); return; }
    const io = new IntersectionObserver(
      (entries) => entries.forEach((e) => e.isIntersecting && setShown(true)),
      { threshold: 0 }
    );
    io.observe(el);
    const t = setTimeout(() => setShown(true), 900);
    return () => { io.disconnect(); clearTimeout(t); };
  }, []);
  return (
    <div ref={ref} style={{
      opacity: shown ? 1 : 0,
      transform: shown ? "translateY(0)" : `translateY(${y}px)`,
      transition: `opacity .7s ease ${delay}ms, transform .7s ease ${delay}ms`,
    }}>
      {children}
    </div>
  );
}

// Counter
function Counter({ to, decimals = 0, duration = 1600, prefix = "", suffix = "" }) {
  const ref = useRef(null);
  const [v, setV] = useState(0);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    const fire = () => {
      const start = performance.now();
      const tick = (now) => {
        const t = Math.min(1, (now - start) / duration);
        setV((1 - Math.pow(1 - t, 3)) * to);
        if (t < 1) requestAnimationFrame(tick);
      };
      requestAnimationFrame(tick);
    };
    const r = el.getBoundingClientRect();
    if (r.top < window.innerHeight && r.bottom > 0) { fire(); return; }
    const io = new IntersectionObserver((es) => es.forEach((e) => e.isIntersecting && (fire(), io.disconnect())), { threshold: 0.2 });
    io.observe(el); return () => io.disconnect();
  }, [to]);
  return <span ref={ref} className="tabular">{prefix}{v.toFixed(decimals)}{suffix}</span>;
}

Object.assign(window, { Container, Rule, Kicker, Btn, Arrow, Plus, Check, ImgPH, Reveal, Counter });
