// site-kit.jsx — shared brand kit for the Binderow Law single-page site.
// Exports: makeTheme, Eyebrow, Btn, Mark, Lockup, Reveal
// (all attached to window at the end so the page script can use them).

function makeTheme(t) {
  const navy = ({
    classic: { navy: "#15268a", navyDeep: "#0e1a5e", abyss: "#0a1242" },
    deep:    { navy: "#111d63", navyDeep: "#0a1440", abyss: "#070e2e" },
  })[t.navy || "classic"];
  const acc = t.accent || ["#c4983f", "#ddb878", "#9c7730"];
  return {
    linen: "#fbf6ec", sand: "#f3ead9", card: "#ffffff",
    ink: "#1b2440", muted: "#7b7668",
    line: "rgba(21,38,138,0.14)",
    ...navy,
    gold: acc[0], goldLight: acc[1], goldDeep: acc[2],
    serif: (t.heading === "playfair")
      ? "'Playfair Display', Georgia, serif"
      : "Garamond, 'Garamond Premier Pro', 'EB Garamond', Georgia, serif",
    sans: "Garamond, 'Garamond Premier Pro', 'EB Garamond', Georgia, serif",
    mark: t.mark || "heritage",
    hWeight: (t.heading === "playfair") ? 700 : 600,
    hScale: (t.heading === "playfair") ? 1 : 1.08,
  };
}

function Eyebrow({ children, C, color, ls = 2.6, size = 12, style }) {
  return (
    <div style={{ fontFamily: C.sans, fontWeight: 600, fontSize: size, letterSpacing: ls, textTransform: "uppercase", color: color || C.gold, ...style }}>
      {children}
    </div>
  );
}

function Btn({ children, variant, C, href, onClick, style, target, rel }) {
  const map = {
    solid: { bg: C.navy, fg: "#fff", bd: C.navy },
    gold: { bg: C.gold, fg: C.navyDeep, bd: C.gold },
    ghost: { bg: "transparent", fg: C.navy, bd: "rgba(21,38,138,0.4)" },
    ghostLight: { bg: "transparent", fg: "#fff", bd: "rgba(255,255,255,0.6)" },
  };
  const s = map[variant || "solid"];
  return (
    <a href={href || "#"} target={target} rel={rel} onClick={onClick} className="btn-lift" style={{ display: "inline-block", textDecoration: "none", fontFamily: C.sans, fontWeight: 600, fontSize: 14.5, letterSpacing: 0.3, padding: "15px 30px", borderRadius: 999, color: s.fg, background: s.bg, border: `1.5px solid ${s.bd}`, whiteSpace: "nowrap", cursor: "pointer", ...style }}>
      {children}
    </a>
  );
}

// ---- THE MARK -------------------------------------------------------------
const LB_L = "M0,0 L0.34,0 L0.34,0.74 L1,0.74 L1,1 L0,1 Z";
const LB_B = "M0,0 L0.55,0 C0.82,0 0.96,0.13 0.96,0.30 C0.96,0.42 0.88,0.49 0.75,0.50 C0.90,0.51 1.0,0.60 1.0,0.74 C1.0,0.90 0.85,1 0.55,1 L0,1 Z M0.30,0.16 L0.30,0.42 L0.54,0.42 C0.64,0.42 0.70,0.37 0.70,0.29 C0.70,0.21 0.64,0.16 0.54,0.16 Z M0.30,0.58 L0.30,0.84 L0.56,0.84 C0.67,0.84 0.74,0.78 0.74,0.71 C0.74,0.64 0.67,0.58 0.56,0.58 Z";
function MarkFlat({ C, size, on }) {
  const topF = C.gold;
  const leftF = on === "dark" ? C.linen : C.navy;
  const rightF = on === "dark" ? "rgba(251,246,236,0.62)" : C.navyDeep;
  const gap = on === "dark" ? C.navyDeep : C.linen;
  const lFill = on === "dark" ? C.navy : C.linen;
  const bFill = on === "dark" ? C.navyDeep : C.linen;
  return (
    <svg width={size} height={size * 1.04} viewBox="0 0 100 104" style={{ flex: "none", display: "block" }} aria-hidden="true">
      <polygon points="50,8 90,30 50,52 10,30" fill={topF} />
      <polygon points="10,30 50,52 50,94 10,72" fill={leftF} />
      <polygon points="90,30 50,52 50,94 90,72" fill={rightF} />
      <path d="M50 8 L90 30 L50 52 L10 30 Z M10 30 L10 72 L50 94 L90 72 L90 30 M50 52 L50 94" stroke={gap} strokeWidth="1.4" strokeLinejoin="round" fill="none" />
      <g transform="matrix(40,22,0,42,10,30)" fill={lFill}><g transform="translate(0.2,0.14) scale(0.6,0.7)"><path d={LB_L} /></g></g>
      <g transform="matrix(40,-22,0,42,50,52)" fill={bFill}><g transform="translate(0.2,0.14) scale(0.6,0.7)"><path d={LB_B} fillRule="evenodd" /></g></g>
    </svg>
  );
}
function MarkHeritage({ size, on, C }) {
  // The real business-card cube reads as navy line-art on light. On dark
  // backgrounds a recolor flattens its detail, so we seat it on a small
  // linen chip instead — keeps the heritage cube crisp and legible.
  if (on === "dark") {
    const pad = Math.round(size * 0.22);
    return (
      <span style={{ display: "inline-flex", alignItems: "center", justifyContent: "center", width: size + pad * 2, height: size + pad * 2, borderRadius: Math.round(size * 0.28), background: C.linen, flex: "none", boxShadow: "0 6px 18px rgba(7,14,46,0.28)" }}>
        <img src={(typeof window !== "undefined" && window.__resources && window.__resources.logoCube) || "logo-cube.png"} alt="Binderow cube mark" style={{ width: size, height: "auto", display: "block" }} />
      </span>
    );
  }
  return (
    <img src={(typeof window !== "undefined" && window.__resources && window.__resources.logoCube) || "logo-cube.png"} alt="Binderow cube mark" style={{ width: size, height: "auto", display: "block", flex: "none" }} />
  );
}
function MarkPlain({ C, size, on }) {
  const fg = on === "dark" ? C.linen : C.navy;
  return <span style={{ fontFamily: C.serif, fontWeight: 600, fontSize: size * 0.96, color: fg, lineHeight: 1, display: "inline-block" }}>B</span>;
}
function Mark({ C, size = 44, on = "light" }) {
  if (C.mark === "flat") return <MarkFlat C={C} size={size} on={on} />;
  if (C.mark === "plain") return <MarkPlain C={C} size={size} on={on} />;
  return <MarkHeritage C={C} size={size} on={on} />;
}

function Lockup({ C, size = 44, on = "light" }) {
  const fg = on === "dark" ? C.linen : C.ink;
  const sub = on === "dark" ? "rgba(251,246,236,0.66)" : "rgba(27,36,64,0.62)";
  const subLabel = "LAW OFFICES";
  const track = size * 0.04; // proportional tracking on the wordmark
  const wordRef = React.useRef(null);
  const [wordW, setWordW] = React.useState(null);
  React.useLayoutEffect(() => {
    const measure = () => {
      if (wordRef.current) {
        // box width includes one trailing letter-spacing; subtract it so the
        // sub-label matches BINDEROW's *visible* glyph run exactly.
        setWordW(Math.max(0, wordRef.current.getBoundingClientRect().width - track));
      }
    };
    measure();
    if (document.fonts && document.fonts.ready) document.fonts.ready.then(measure);
  }, [size, C.serif, track]);
  return (
    <div style={{ display: "flex", alignItems: "center", gap: size * 0.34 }}>
      <Mark C={C} size={size} on={on} />
      <div style={{ display: "inline-flex", flexDirection: "column", lineHeight: 1 }}>
        <span ref={wordRef} style={{ fontFamily: C.serif, fontSize: size * 0.62, fontWeight: 600, fontStyle: "italic", color: fg, textTransform: "uppercase", letterSpacing: track, whiteSpace: "nowrap" }}>Binderow</span>
        <div style={{ display: "flex", justifyContent: "space-between", width: wordW != null ? wordW : "100%", marginTop: size * 0.18 }}>
          {subLabel.split("").map((ch, i) => (
            <span key={i} style={{ fontFamily: "Garamond", fontWeight: 600, fontStyle: "italic", fontSize: size * 0.232, color: sub, textTransform: "uppercase" }}>{ch === " " ? "\u2002" : ch}</span>
          ))}
        </div>
      </div>
    </div>
  );
}

// ---- SCROLL REVEAL --------------------------------------------------------
// Fades + lifts children in when they enter the viewport. Respects
// prefers-reduced-motion and falls back to visible if IO is unavailable.
function Reveal({ children, delay = 0, y = 26, style, as = "div" }) {
  const ref = React.useRef(null);
  const [shown, setShown] = React.useState(false);
  React.useEffect(() => {
    const reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const el = ref.current;
    if (reduce || !el) { setShown(true); return; }
    let done = false;
    const reveal = () => { if (!done) { done = true; setShown(true); } };
    // Reveal the moment any part of the element is within the viewport.
    const check = () => {
      if (done) return true;
      const r = el.getBoundingClientRect();
      const vh = window.innerHeight || document.documentElement.clientHeight || 800;
      if (r.top < vh * 0.94 && r.bottom > 0) { reveal(); return true; }
      return false;
    };
    let io;
    if ("IntersectionObserver" in window) {
      io = new IntersectionObserver((entries) => {
        if (entries.some((e) => e.isIntersecting)) reveal();
      }, { threshold: 0.1, rootMargin: "0px 0px -6% 0px" });
      io.observe(el);
    }
    window.addEventListener("scroll", check, { passive: true });
    window.addEventListener("resize", check, { passive: true });
    window.addEventListener("load", check);
    // Run the first check after layout settles (fonts/images can shift it).
    check();
    const raf = requestAnimationFrame(() => { requestAnimationFrame(check); });
    const t = setTimeout(check, 250);
    return () => {
      if (io) io.disconnect();
      cancelAnimationFrame(raf);
      clearTimeout(t);
      window.removeEventListener("scroll", check);
      window.removeEventListener("resize", check);
      window.removeEventListener("load", check);
    };
  }, []);
  const Tag = as;
  return (
    <Tag ref={ref} style={{
      opacity: shown ? 1 : 0,
      transform: shown ? "none" : `translateY(${y}px)`,
      transition: `opacity 0.7s cubic-bezier(0.22,1,0.36,1) ${delay}ms, transform 0.7s cubic-bezier(0.22,1,0.36,1) ${delay}ms`,
      ...style,
    }}>
      {children}
    </Tag>
  );
}

Object.assign(window, { makeTheme, Eyebrow, Btn, Mark, Lockup, Reveal });
