// Hero — headline, growing tree, progress bar, CTAs, prayer counter

const { useState, useEffect, useRef } = React;

// --- Zoomable lightbox: click image → opens fullscreen. Wheel to zoom, drag to pan, pinch on touch, Esc or backdrop to close.
function ImageLightbox({ src, alt, onClose }) {
  const [scale, setScale] = useState(1);
  const [offset, setOffset] = useState({ x: 0, y: 0 });
  const [dragging, setDragging] = useState(false);
  const dragState = useRef({ startX: 0, startY: 0, startOffX: 0, startOffY: 0 });
  const pinchState = useRef({ active: false, startDist: 0, startScale: 1 });

  // Esc closes
  useEffect(() => {
    const onKey = (e) => {
      if (e.key === "Escape") onClose();
      else if (e.key === "+" || e.key === "=") setScale(s => Math.min(6, s * 1.2));
      else if (e.key === "-" || e.key === "_") setScale(s => Math.max(1, s / 1.2));
      else if (e.key === "0") { setScale(1); setOffset({ x: 0, y: 0 }); }
    };
    window.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    return () => {
      window.removeEventListener("keydown", onKey);
      document.body.style.overflow = "";
    };
  }, [onClose]);

  const onWheel = (e) => {
    e.preventDefault();
    const delta = -e.deltaY * 0.0015;
    setScale(s => {
      const next = Math.max(1, Math.min(6, s * (1 + delta)));
      if (next === 1) setOffset({ x: 0, y: 0 });
      return next;
    });
  };

  const onPointerDown = (e) => {
    if (e.pointerType === "touch" && e.isPrimary === false) return;
    if (scale <= 1) return;
    setDragging(true);
    e.currentTarget.setPointerCapture(e.pointerId);
    dragState.current = { startX: e.clientX, startY: e.clientY, startOffX: offset.x, startOffY: offset.y };
  };
  const onPointerMove = (e) => {
    if (!dragging) return;
    setOffset({
      x: dragState.current.startOffX + (e.clientX - dragState.current.startX),
      y: dragState.current.startOffY + (e.clientY - dragState.current.startY),
    });
  };
  const onPointerUp = (e) => {
    setDragging(false);
    try { e.currentTarget.releasePointerCapture(e.pointerId); } catch {}
  };

  // Touch pinch-to-zoom
  const touches = useRef(new Map());
  const onTouchStart = (e) => {
    for (const t of e.touches) touches.current.set(t.identifier, { x: t.clientX, y: t.clientY });
    if (e.touches.length === 2) {
      const [a, b] = e.touches;
      const dist = Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY);
      pinchState.current = { active: true, startDist: dist, startScale: scale };
    }
  };
  const onTouchMove = (e) => {
    if (e.touches.length === 2 && pinchState.current.active) {
      e.preventDefault();
      const [a, b] = e.touches;
      const dist = Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY);
      const next = Math.max(1, Math.min(6, pinchState.current.startScale * (dist / pinchState.current.startDist)));
      setScale(next);
      if (next === 1) setOffset({ x: 0, y: 0 });
    }
  };
  const onTouchEnd = (e) => {
    if (e.touches.length < 2) pinchState.current.active = false;
    for (const t of e.changedTouches) touches.current.delete(t.identifier);
  };

  const doubleClick = () => {
    if (scale > 1) { setScale(1); setOffset({ x: 0, y: 0 }); }
    else setScale(2.5);
  };

  return (
    <div
      onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}
      onWheel={onWheel}
      style={{
        position: "fixed", inset: 0, zIndex: 1000,
        background: "rgba(8,17,32,0.96)",
        backdropFilter: "blur(6px)",
        WebkitBackdropFilter: "blur(6px)",
        display: "grid", placeItems: "center",
        animation: "lbFadeIn 220ms ease-out",
      }}
    >
      {/* Close */}
      <button onClick={onClose} aria-label="Close"
        style={{ position: "absolute", top: 22, right: 22, width: 42, height: 42, borderRadius: "50%",
                 border: "1px solid rgba(255,241,212,0.3)", background: "rgba(47,51,29,0.6)",
                 color: "var(--cream-50)", display: "grid", placeItems: "center", cursor: "pointer", zIndex: 2 }}>
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>
      </button>

      {/* Zoom controls */}
      <div style={{
        position: "absolute", bottom: 26, left: "50%", transform: "translateX(-50%)",
        display: "flex", alignItems: "center", gap: 2, padding: 4,
        background: "rgba(47,51,29,0.75)", border: "1px solid rgba(181,168,107,0.3)", borderRadius: 999, zIndex: 2,
      }}>
        {[
          { label: "−", onClick: () => setScale(s => { const n = Math.max(1, s / 1.25); if (n === 1) setOffset({x:0,y:0}); return n; }) },
          { label: "Reset", onClick: () => { setScale(1); setOffset({ x: 0, y: 0 }); }, wide: true },
          { label: "+", onClick: () => setScale(s => Math.min(6, s * 1.25)) },
        ].map((b, i) => (
          <button key={i} onClick={b.onClick}
            style={{ padding: b.wide ? "8px 16px" : "8px 14px", fontFamily: b.wide ? "var(--mono)" : "var(--serif)",
                     fontSize: b.wide ? 10 : 18, letterSpacing: b.wide ? "0.2em" : 0, textTransform: b.wide ? "uppercase" : "none",
                     color: "var(--cream-50)", background: "transparent", border: "none", cursor: "pointer", borderRadius: 999 }}>
            {b.label}
          </button>
        ))}
        <div style={{ padding: "8px 14px 8px 10px", fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.18em",
                      color: "var(--gold-400)", borderLeft: "1px solid rgba(255,241,212,0.15)", marginLeft: 2 }}>
          {Math.round(scale * 100)}%
        </div>
      </div>

      {/* Hint */}
      <div style={{
        position: "absolute", top: 24, left: 24, fontFamily: "var(--mono)", fontSize: 10,
        letterSpacing: "0.22em", textTransform: "uppercase", color: "rgba(255,241,212,0.5)", zIndex: 2,
      }}>
        Scroll to zoom &middot; Drag to pan &middot; Esc to close
      </div>

      {/* Image stage */}
      <div
        onPointerDown={onPointerDown}
        onPointerMove={onPointerMove}
        onPointerUp={onPointerUp}
        onPointerCancel={onPointerUp}
        onTouchStart={onTouchStart}
        onTouchMove={onTouchMove}
        onTouchEnd={onTouchEnd}
        onDoubleClick={doubleClick}
        style={{
          width: "92vw", height: "88vh",
          display: "grid", placeItems: "center",
          cursor: scale > 1 ? (dragging ? "grabbing" : "grab") : "zoom-in",
          overflow: "hidden",
          touchAction: "none",
        }}
      >
        <img src={src} alt={alt} draggable={false}
          style={{
            maxWidth: "100%", maxHeight: "100%",
            transform: `translate(${offset.x}px, ${offset.y}px) scale(${scale})`,
            transformOrigin: "center center",
            transition: dragging ? "none" : "transform 220ms cubic-bezier(0.22, 1, 0.36, 1)",
            userSelect: "none",
            boxShadow: "0 40px 120px -20px rgba(0,0,0,0.8)",
          }}
        />
      </div>

      <style>{`
        @keyframes lbFadeIn { from { opacity: 0; } to { opacity: 1; } }
      `}</style>
    </div>
  );
}

// Architectural rendering of the finished New Eden campus — seen from a gentle elevated angle.
// Hand-drawn SVG: chapel at center (cross on steeple), flanked by academic wings, dining hall,
// dormitories, treed quad with walking paths, sunrise behind. Cream + gold line-art on deep navy.
function CampusRendering() {
  return (
    <svg viewBox="0 0 520 340" style={{ width: "100%", height: "100%", display: "block", overflow: "visible" }}>
      <defs>
        <linearGradient id="sky" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor="rgba(181,168,107,0.14)" />
          <stop offset="60%" stopColor="rgba(181,168,107,0.03)" />
          <stop offset="100%" stopColor="rgba(255,241,212,0)" />
        </linearGradient>
        <radialGradient id="sun" cx="50%" cy="50%" r="50%">
          <stop offset="0%" stopColor="rgba(232,212,163,0.65)" />
          <stop offset="60%" stopColor="rgba(181,168,107,0.15)" />
          <stop offset="100%" stopColor="rgba(181,168,107,0)" />
        </radialGradient>
        <linearGradient id="ground" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor="rgba(181,168,107,0.08)" />
          <stop offset="100%" stopColor="rgba(181,168,107,0)" />
        </linearGradient>
      </defs>

      {/* sky wash */}
      <rect x="0" y="0" width="520" height="260" fill="url(#sky)" />

      {/* distant hills */}
      <path d="M 0 215 Q 70 195 140 205 T 280 200 T 420 208 T 520 200 L 520 260 L 0 260 Z"
            fill="none" stroke="rgba(255,241,212,0.18)" strokeWidth="1" />
      <path d="M 0 225 Q 80 210 160 218 T 310 215 T 440 220 T 520 215"
            fill="none" stroke="rgba(255,241,212,0.12)" strokeWidth="0.8" />

      {/* sun halo behind chapel */}
      <circle cx="260" cy="150" r="78" fill="url(#sun)" />
      <circle cx="260" cy="150" r="14" fill="none" stroke="rgba(232,212,163,0.5)" strokeWidth="0.6" />

      {/* ground plane */}
      <rect x="0" y="255" width="520" height="90" fill="url(#ground)" />
      <line x1="0" y1="255" x2="520" y2="255" stroke="rgba(181,168,107,0.35)" strokeWidth="0.7" />

      {/* === CHAPEL (center) === */}
      <g stroke="rgba(255,241,212,0.88)" strokeWidth="1.1" fill="none" strokeLinecap="round" strokeLinejoin="round">
        {/* chapel body */}
        <rect x="232" y="175" width="56" height="80" fill="rgba(47,51,29,0.3)" />
        {/* arched entrance */}
        <path d="M 250 255 L 250 230 Q 250 218 260 218 Q 270 218 270 230 L 270 255" />
        {/* windows on body (pointed arch) */}
        <path d="M 240 215 L 240 200 Q 240 194 244 194 Q 248 194 248 200 L 248 215" />
        <path d="M 272 215 L 272 200 Q 272 194 276 194 Q 280 194 280 200 L 280 215" />
        {/* pitched roof */}
        <path d="M 226 175 L 260 145 L 294 175 Z" fill="rgba(255,241,212,0.06)" />
        {/* steeple */}
        <path d="M 252 145 L 252 115 L 268 115 L 268 145 Z" fill="rgba(47,51,29,0.4)" />
        <path d="M 248 115 L 260 95 L 272 115 Z" fill="rgba(255,241,212,0.08)" />
        {/* cross on steeple */}
        <line x1="260" y1="95" x2="260" y2="70" stroke="var(--gold-400)" strokeWidth="1.4" />
        <line x1="254" y1="80" x2="266" y2="80" stroke="var(--gold-400)" strokeWidth="1.4" />
        {/* steeple window */}
        <circle cx="260" cy="128" r="3" stroke="var(--gold-400)" />
      </g>

      {/* === LEFT ACADEMIC WING === */}
      <g stroke="rgba(255,241,212,0.78)" strokeWidth="1" fill="none" strokeLinejoin="round">
        <rect x="118" y="205" width="102" height="50" fill="rgba(47,51,29,0.32)" />
        {/* pitched roof */}
        <path d="M 118 205 L 140 188 L 220 188 L 220 205" fill="rgba(255,241,212,0.05)" />
        <line x1="140" y1="188" x2="140" y2="205" />
        {/* windows row — 6 */}
        {[0,1,2,3,4,5].map(i => (
          <rect key={i} x={128 + i * 15} y="218" width="8" height="12" fill="rgba(232,212,163,0.18)" stroke="rgba(232,212,163,0.5)" strokeWidth="0.6" />
        ))}
        {/* door */}
        <rect x="168" y="238" width="10" height="17" fill="rgba(47,51,29,0.5)" />
      </g>

      {/* === RIGHT ACADEMIC WING === */}
      <g stroke="rgba(255,241,212,0.78)" strokeWidth="1" fill="none" strokeLinejoin="round">
        <rect x="300" y="205" width="102" height="50" fill="rgba(47,51,29,0.32)" />
        <path d="M 300 205 L 300 188 L 380 188 L 402 205" fill="rgba(255,241,212,0.05)" />
        <line x1="380" y1="188" x2="380" y2="205" />
        {[0,1,2,3,4,5].map(i => (
          <rect key={i} x={310 + i * 15} y="218" width="8" height="12" fill="rgba(232,212,163,0.18)" stroke="rgba(232,212,163,0.5)" strokeWidth="0.6" />
        ))}
        <rect x="342" y="238" width="10" height="17" fill="rgba(47,51,29,0.5)" />
      </g>

      {/* === DORMITORY (back left) === */}
      <g stroke="rgba(255,241,212,0.55)" strokeWidth="0.9" fill="none" strokeLinejoin="round">
        <rect x="58" y="210" width="56" height="45" fill="rgba(47,51,29,0.4)" />
        <path d="M 58 210 L 72 198 L 114 198 L 114 210" fill="rgba(255,241,212,0.04)" />
        {[0,1,2].map(r =>
          [0,1,2,3].map(c => (
            <rect key={`${r}-${c}`} x={64 + c * 12} y={216 + r * 12} width="6" height="8" fill="rgba(232,212,163,0.14)" stroke="rgba(232,212,163,0.35)" strokeWidth="0.5" />
          ))
        )}
      </g>

      {/* === DINING HALL (back right) === */}
      <g stroke="rgba(255,241,212,0.55)" strokeWidth="0.9" fill="none" strokeLinejoin="round">
        <rect x="406" y="215" width="58" height="40" fill="rgba(47,51,29,0.4)" />
        <path d="M 406 215 L 435 200 L 464 215" fill="rgba(255,241,212,0.05)" />
        {/* tall arched windows */}
        {[0,1,2,3].map(i => (
          <path key={i} d={`M ${414 + i*12} 245 L ${414 + i*12} 228 Q ${414 + i*12} 222 ${418 + i*12} 222 Q ${422 + i*12} 222 ${422 + i*12} 228 L ${422 + i*12} 245`}
                stroke="rgba(232,212,163,0.45)" strokeWidth="0.7" fill="rgba(232,212,163,0.12)" />
        ))}
      </g>

      {/* === QUAD PATHS === */}
      <g stroke="rgba(181,168,107,0.45)" strokeWidth="0.8" fill="none" strokeDasharray="2 2">
        <path d="M 60 285 Q 180 278 260 275 Q 340 278 460 285" />
        <path d="M 260 255 L 260 295" />
      </g>

      {/* === TREES on the quad === */}
      <g fill="rgba(142,163,119,0.38)" stroke="rgba(142,163,119,0.6)" strokeWidth="0.6">
        {[
          { cx: 95, cy: 278, r: 7 },
          { cx: 150, cy: 285, r: 6 },
          { cx: 200, cy: 275, r: 7 },
          { cx: 320, cy: 275, r: 7 },
          { cx: 370, cy: 285, r: 6 },
          { cx: 425, cy: 278, r: 7 },
        ].map((t, i) => (
          <g key={i}>
            <circle cx={t.cx} cy={t.cy} r={t.r} />
            <line x1={t.cx} y1={t.cy + t.r - 1} x2={t.cx} y2={t.cy + t.r + 4} stroke="rgba(47,51,29,0.6)" strokeWidth="1" />
          </g>
        ))}
      </g>

      {/* === TINY FIGURES on the path (scale reference) === */}
      <g fill="rgba(255,241,212,0.6)" stroke="none">
        <circle cx="240" cy="282" r="1.3" />
        <rect x="239.2" y="283" width="1.6" height="4" />
        <circle cx="246" cy="284" r="1.3" />
        <rect x="245.2" y="285" width="1.6" height="4" />
        <circle cx="290" cy="280" r="1.3" />
        <rect x="289.2" y="281" width="1.6" height="4" />
      </g>

      {/* === SURVEY / BLUEPRINT CORNER MARKS === */}
      <g stroke="rgba(181,168,107,0.7)" strokeWidth="0.8" fill="none">
        <path d="M 20 20 L 20 36 M 20 20 L 36 20" />
        <path d="M 500 20 L 500 36 M 500 20 L 484 20" />
        <path d="M 20 320 L 20 304 M 20 320 L 36 320" />
        <path d="M 500 320 L 500 304 M 500 320 L 484 320" />
      </g>

      {/* blueprint label */}
      <text x="260" y="32" textAnchor="middle" fontFamily="JetBrains Mono, monospace" fontSize="8" letterSpacing="3" fill="rgba(181,168,107,0.7)">
        NEW EDEN ACADEMY · CAMPUS RENDERING
      </text>
      <text x="260" y="314" textAnchor="middle" fontFamily="JetBrains Mono, monospace" fontSize="7" letterSpacing="2.5" fill="rgba(255,241,212,0.4)">
        ARCHITECT'S CONCEPT · NOT FINAL · SCALE NTS
      </text>
    </svg>
  );
}

// --- Monthly giving sparkline: dot+line chart of donations since launch ---
function GrowthSparkline({ data }) {
  // data: array of { month: "Jan", amount: number }
  const w = 420, h = 90, pad = { t: 14, r: 10, b: 22, l: 10 };
  const innerW = w - pad.l - pad.r;
  const innerH = h - pad.t - pad.b;

  if (!Array.isArray(data) || data.length === 0) return null;

  const max = Math.max(...data.map(d => d.amount), 1);
  const single = data.length === 1;
  const step = single ? 0 : innerW / (data.length - 1);
  const pts = data.map((d, i) => ({
    x: single ? pad.l + innerW / 2 : pad.l + i * step,
    y: pad.t + innerH - (d.amount / max) * innerH,
    ...d,
  }));
  const linePath = pts.map((p, i) => (i === 0 ? `M ${p.x} ${p.y}` : `L ${p.x} ${p.y}`)).join(" ");
  const areaPath = single
    ? ""
    : `${linePath} L ${pts[pts.length-1].x} ${pad.t + innerH} L ${pts[0].x} ${pad.t + innerH} Z`;
  const latest = pts[pts.length - 1];
  const labelIndices = single
    ? [0]
    : Array.from(new Set([0, Math.floor(pts.length / 2), pts.length - 1]));

  return (
    <svg viewBox={`0 0 ${w} ${h}`} style={{ width: "100%", height: "auto", display: "block" }}>
      <defs>
        <linearGradient id="sparkFill" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor="rgba(181,168,107,0.28)" />
          <stop offset="100%" stopColor="rgba(181,168,107,0)" />
        </linearGradient>
      </defs>

      {/* baseline */}
      <line x1={pad.l} y1={pad.t + innerH} x2={w - pad.r} y2={pad.t + innerH}
            stroke="rgba(255,241,212,0.15)" strokeWidth="0.8" />

      {/* area fill (skipped for single point) */}
      {!single && <path d={areaPath} fill="url(#sparkFill)" />}

      {/* line (only when 2+ points) */}
      {!single && (
        <path d={linePath} fill="none" stroke="var(--gold-400)" strokeWidth="1.5" strokeLinejoin="round" strokeLinecap="round" />
      )}

      {/* dots */}
      {pts.map((p, i) => (
        <circle key={i} cx={p.x} cy={p.y} r={i === pts.length - 1 ? 3.5 : 2}
                fill={i === pts.length - 1 ? "var(--gold-300)" : "var(--gold-500)"}
                stroke={i === pts.length - 1 ? "var(--cream-50)" : "none"}
                strokeWidth="1" />
      ))}

      {/* latest callout */}
      <line x1={latest.x} y1={latest.y + 6} x2={latest.x} y2={pad.t + innerH}
            stroke="rgba(181,168,107,0.35)" strokeWidth="0.6" strokeDasharray="2 2" />

      {/* month labels */}
      {labelIndices.map(i => (
        <text key={i} x={pts[i].x} y={h - 6} textAnchor="middle"
              fontFamily="JetBrains Mono, monospace" fontSize="8" letterSpacing="1.5"
              fill="rgba(255,241,212,0.5)">
          {(pts[i].month || "").toUpperCase()}
        </text>
      ))}
    </svg>
  );
}

function TreeOfGrowth({ progress }) {
  // progress: 0..1
  // Renders an original tree silhouette whose branches "draw in" as progress grows.
  // We animate stroke-dashoffset per path using dynamic `style`.
  const segments = [
    // trunk
    { d: "M 160 320 V 180", w: 4, t: 0 },
    // main left branch
    { d: "M 160 220 Q 120 210 90 180 Q 70 160 55 130", w: 2.5, t: 0.1 },
    // main right branch
    { d: "M 160 220 Q 200 208 230 175 Q 250 150 265 120", w: 2.5, t: 0.18 },
    // upper-left
    { d: "M 160 200 Q 130 185 110 160 Q 95 140 85 115", w: 2, t: 0.28 },
    // upper-right
    { d: "M 160 200 Q 190 182 215 155 Q 232 132 240 105", w: 2, t: 0.36 },
    // top center
    { d: "M 160 200 Q 155 170 150 140 Q 148 115 155 90", w: 2, t: 0.46 },
    { d: "M 160 200 Q 168 175 172 140 Q 174 110 168 85", w: 2, t: 0.54 },
    // outer tips
    { d: "M 85 115 L 70 95", w: 1.5, t: 0.64 },
    { d: "M 85 115 L 95 90", w: 1.5, t: 0.7 },
    { d: "M 240 105 L 250 85", w: 1.5, t: 0.76 },
    { d: "M 240 105 L 228 82", w: 1.5, t: 0.82 },
    { d: "M 155 90 L 145 72", w: 1.5, t: 0.88 },
    { d: "M 168 85 L 176 68", w: 1.5, t: 0.92 },
  ];
  // leaves positions matched to branch tips
  const leaves = [
    { cx: 55, cy: 130, t: 0.32 },
    { cx: 265, cy: 120, t: 0.40 },
    { cx: 85, cy: 115, t: 0.50 },
    { cx: 240, cy: 105, t: 0.58 },
    { cx: 150, cy: 140, t: 0.66 },
    { cx: 172, cy: 140, t: 0.72 },
    { cx: 70, cy: 95, t: 0.80 },
    { cx: 95, cy: 90, t: 0.84 },
    { cx: 250, cy: 85, t: 0.88 },
    { cx: 228, cy: 82, t: 0.92 },
    { cx: 145, cy: 72, t: 0.96 },
    { cx: 176, cy: 68, t: 0.99 },
  ];
  // roots
  const roots = [
    { d: "M 160 320 Q 120 335 90 355", t: 0 },
    { d: "M 160 320 Q 200 335 230 355", t: 0 },
    { d: "M 160 320 Q 140 345 120 368", t: 0 },
    { d: "M 160 320 Q 180 345 200 368", t: 0 },
    { d: "M 160 320 V 360", t: 0 },
  ];

  return (
    <svg viewBox="0 0 320 400" className="tree-svg" style={{ width: "100%", height: "100%", overflow: "visible" }}>
      <defs>
        <linearGradient id="goldGrad" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor="#D3C890" />
          <stop offset="60%" stopColor="#B5A86B" />
          <stop offset="100%" stopColor="#8A7D4D" />
        </linearGradient>
        <radialGradient id="glowGrad" cx="50%" cy="40%" r="60%">
          <stop offset="0%" stopColor="rgba(181,168,107,0.25)" />
          <stop offset="100%" stopColor="rgba(181,168,107,0)" />
        </radialGradient>
      </defs>

      {/* soft glow */}
      <circle cx="160" cy="180" r="160" fill="url(#glowGrad)" />

      {/* roots — always visible, subtle */}
      {roots.map((r, i) => (
        <path key={"r"+i} d={r.d} className="branch"
          stroke="rgba(181,168,107,0.4)" strokeWidth="1"
          style={{ strokeDashoffset: 1 - Math.min(1, progress * 1.4) }} />
      ))}

      {/* branches — drawn in as progress advances past t */}
      {segments.map((s, i) => {
        const local = Math.max(0, Math.min(1, (progress - s.t) / 0.15));
        return (
          <path key={i} d={s.d}
            className={i === 0 ? "trunk" : "branch"}
            strokeWidth={s.w}
            style={{ strokeDashoffset: 1 - local }} />
        );
      })}

      {/* leaves */}
      {leaves.map((l, i) => (
        <g key={"l"+i}>
          <circle cx={l.cx} cy={l.cy} r="6" className={"leaf " + (progress > l.t ? "on" : "")} />
          <circle cx={l.cx} cy={l.cy} r="3" fill="#8ea377" opacity={progress > l.t ? 1 : 0} style={{ transition: "opacity 700ms" }} />
        </g>
      ))}

      {/* base ground line */}
      <path d="M 20 320 H 300" stroke="rgba(181,168,107,0.25)" strokeWidth="1" />
    </svg>
  );
}

function PrayerButton({ count, hasPrayed, onPray }) {
  const [ripples, setRipples] = useState([]);
  const handle = () => {
    if (!hasPrayed) {
      setRipples(rs => [...rs, Date.now()]);
      setTimeout(() => setRipples(rs => rs.slice(1)), 1200);
    }
    onPray();
  };
  return (
    <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 18 }}>
      <button
        onClick={handle}
        aria-pressed={hasPrayed}
        style={{
          position: "relative",
          width: 132, height: 132, borderRadius: "50%",
          border: "1px solid " + (hasPrayed ? "var(--gold-500)" : "rgba(255,241,212,0.3)"),
          background: hasPrayed
            ? "radial-gradient(circle at 50% 40%, rgba(181,168,107,0.35), rgba(181,168,107,0.05) 70%)"
            : "radial-gradient(circle at 50% 40%, rgba(255,241,212,0.06), transparent 70%)",
          color: "var(--cream-50)",
          display: "grid", placeItems: "center",
          transition: "all 280ms",
          boxShadow: hasPrayed ? "0 0 36px rgba(181,168,107,0.35)" : "none",
        }}
      >
        <div style={{ textAlign: "center" }}>
          <div style={{ fontFamily: "var(--serif)", fontSize: 28, fontStyle: "italic", color: "var(--gold-300)" }}>
            {hasPrayed ? "Amen." : "Pray"}
          </div>
          <div style={{ fontFamily: "var(--mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "rgba(255,241,212,0.55)", marginTop: 4 }}>
            {hasPrayed ? "thank you" : "tap to join"}
          </div>
        </div>
        {ripples.map(r => <span key={r} className="ripple" />)}
      </button>
      <div style={{ textAlign: "center" }}>
        <div style={{ fontFamily: "var(--mono)", fontSize: 11, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--gold-400)", marginBottom: 6 }}>
          Praying for this vision
        </div>
        <div style={{ fontFamily: "var(--serif)", fontSize: 36, color: "var(--cream-50)", letterSpacing: "0.02em" }}>
          {count.toLocaleString("en-US")}
        </div>
      </div>
    </div>
  );
}

function Hero({ raised, goal, prayerCount, hasPrayed, onPray, onGive, monthlySeries }) {
  const sparklineData = (Array.isArray(monthlySeries) ? monthlySeries : []).map(m => ({
    month: m.label || m.key,
    amount: (m.amountCents || 0) / 100,
  }));
  const monthCount = sparklineData.length;
  const progress = Math.max(0.015, Math.min(1, raised / goal));
  const pct = (progress * 100).toFixed(2);
  const [starYear] = useState(2026);
  const [lightboxOpen, setLightboxOpen] = useState(false);

  return (
    <section className="night" style={{ position: "relative", minHeight: "100vh", paddingTop: 120, paddingBottom: 80, overflow: "hidden" }}>
      {/* subtle horizon line */}
      <div style={{ position: "absolute", left: 0, right: 0, top: "42%", height: 1, background: "linear-gradient(90deg, transparent, rgba(181,168,107,0.2), transparent)" }} />

      <div className="container" style={{ position: "relative", zIndex: 2 }}>
        <div style={{ display: "grid", gridTemplateColumns: "1.1fr 0.9fr", gap: 60, alignItems: "center" }} className="hero-grid">
          <div>
            <div className="rule left" style={{ marginBottom: 28 }}>Est. {starYear} · Faith-Supported</div>

            <h1 style={{ fontSize: "clamp(48px, 7vw, 96px)", lineHeight: 0.98, letterSpacing: "-0.02em", color: "var(--cream-50)" }}>
              A school,<br/>
              planted <em style={{ fontWeight: 400, color: "var(--gold-400)" }}>seed by seed</em>,<br/>
              <span style={{ fontStyle: "italic", fontWeight: 400 }}>built by believers.</span>
            </h1>

            <p style={{ marginTop: 32, fontSize: 18, lineHeight: 1.6, color: "rgba(255,241,212,0.78)", maxWidth: 520 }}>
              New Eden is a donation-supported, faith-based academy being built step by step — from a single Head Start classroom today to a full K–12 residential school tomorrow. Every dollar, every prayer, every hand is part of the vision.
            </p>

            <div style={{ marginTop: 40, display: "flex", gap: 12, flexWrap: "wrap" }}>
              <button className="btn btn-gold" onClick={onGive}>Give</button>
              <button className="btn btn-ghost-light" onClick={onPray}>Pray</button>
              <button className="btn btn-ghost-light" onClick={() => document.getElementById("wall")?.scrollIntoView({ behavior: "smooth" })}>Leave Encouragement</button>
            </div>

            {/* progress bar */}
            <div style={{ marginTop: 52, maxWidth: 620 }}>
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 12 }}>
                <div>
                  <div style={{ fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--gold-400)" }}>Raised to date</div>
                  <div style={{ fontFamily: "var(--serif)", fontSize: 44, color: "var(--cream-50)", letterSpacing: "0.01em", lineHeight: 1.1 }}>
                    {formatMoney(raised)}
                  </div>
                </div>
                <div style={{ textAlign: "right" }}>
                  <div style={{ fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "rgba(255,241,212,0.55)" }}>Full vision</div>
                  <div style={{ fontFamily: "var(--serif)", fontSize: 28, color: "rgba(255,241,212,0.85)" }}>
                    {formatMoney(goal, { compact: true })}+
                  </div>
                </div>
              </div>

              <div className="hbar-track">
                <div className="hbar-fill shimmer" style={{ width: pct + "%" }} />
              </div>

              <div style={{ display: "flex", justifyContent: "space-between", marginTop: 10, fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.18em", textTransform: "uppercase", color: "rgba(255,241,212,0.5)" }}>
                <span>{pct}% complete</span>
                <span>{formatMoney(goal - raised, { compact: true })} remaining</span>
              </div>
            </div>
          </div>

          <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 36 }}>
            {/* Campus rendering */}
            <div style={{ position: "relative", width: "min(560px, 100%)" }}>
              <button onClick={() => setLightboxOpen(true)} aria-label="View campus rendering fullscreen"
                      style={{ display: "block", padding: 0, width: "100%", cursor: "zoom-in",
                               border: "1px solid rgba(181,168,107,0.3)", background: "rgba(47,51,29,0.4)",
                               boxShadow: "0 30px 80px -30px rgba(0,0,0,0.6)", position: "relative", transition: "transform 260ms, box-shadow 260ms" }}
                      onMouseEnter={e => { e.currentTarget.style.transform = "translateY(-2px)"; e.currentTarget.style.boxShadow = "0 40px 90px -25px rgba(0,0,0,0.75)"; }}
                      onMouseLeave={e => { e.currentTarget.style.transform = ""; e.currentTarget.style.boxShadow = "0 30px 80px -30px rgba(0,0,0,0.6)"; }}>
                <div style={{ padding: 10 }}>
                  <img src="assets/campus-rendering.png?v=2" alt="New Eden Academy campus — aerial architectural rendering at dusk: numbered campus map with main school, early learning center, dining hall, town hall, administration, dormitories, gardens, basketball courts, chapel, stadium, and the prayer altar at the back of the grounds"
                       style={{ width: "100%", height: "auto", display: "block" }} />
                </div>
                {/* zoom hint */}
                <div style={{ position: "absolute", top: 18, right: 18, display: "flex", alignItems: "center", gap: 8,
                              padding: "7px 12px", background: "rgba(47,51,29,0.82)", border: "1px solid rgba(181,168,107,0.4)",
                              color: "var(--gold-300)", fontFamily: "var(--mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase" }}>
                  <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.3-4.3M11 8v6M8 11h6"/></svg>
                  Click to explore
                </div>
              </button>
              {/* corner marks */}
              <svg width="18" height="18" viewBox="0 0 18 18" style={{ position: "absolute", top: -1, left: -1 }}><path d="M 0 0 L 0 14 M 0 0 L 14 0" stroke="var(--gold-500)" strokeWidth="1" fill="none" /></svg>
              <svg width="18" height="18" viewBox="0 0 18 18" style={{ position: "absolute", top: -1, right: -1 }}><path d="M 18 0 L 18 14 M 18 0 L 4 0" stroke="var(--gold-500)" strokeWidth="1" fill="none" /></svg>
              <svg width="18" height="18" viewBox="0 0 18 18" style={{ position: "absolute", bottom: -1, left: -1 }}><path d="M 0 18 L 0 4 M 0 18 L 14 18" stroke="var(--gold-500)" strokeWidth="1" fill="none" /></svg>
              <svg width="18" height="18" viewBox="0 0 18 18" style={{ position: "absolute", bottom: -1, right: -1 }}><path d="M 18 18 L 18 4 M 18 18 L 4 18" stroke="var(--gold-500)" strokeWidth="1" fill="none" /></svg>
              <div style={{ marginTop: 14, textAlign: "center", fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.26em", textTransform: "uppercase", color: "rgba(255,241,212,0.55)" }}>
                The vision &middot; how New Eden will stand, completed
              </div>
            </div>

            {/* Monthly giving growth sparkline */}
            <div style={{ width: "min(520px, 100%)", padding: "16px 20px 14px", background: "rgba(47,51,29,0.35)", border: "1px solid rgba(181,168,107,0.18)" }}>
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 6 }}>
                <div style={{ fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--gold-400)" }}>
                  Monthly giving · growing
                </div>
                <div style={{ fontFamily: "var(--serif)", fontSize: 14, fontStyle: "italic", color: "rgba(255,241,212,0.75)" }}>
                  {monthCount === 1 ? "Launch month" : monthCount + " months"}
                </div>
              </div>
              <GrowthSparkline data={sparklineData} />
            </div>

            <PrayerButton count={prayerCount} hasPrayed={hasPrayed} onPray={onPray} />
          </div>
        </div>
      </div>

      {/* scroll hint */}
      <div style={{ marginTop: 60, display: "flex", justifyContent: "center" }}>
        <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 8, opacity: 0.7 }}>
          <div style={{ fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.3em", textTransform: "uppercase", color: "var(--gold-400)" }}>Scroll · the journey</div>
          <div style={{ width: 1, height: 44, background: "linear-gradient(180deg, var(--gold-500), transparent)" }} />
        </div>
      </div>

      <style>{`
        @media (max-width: 900px) {
          .hero-grid { grid-template-columns: 1fr !important; }
        }
      `}</style>

      {lightboxOpen && (
        <ImageLightbox
          src="assets/campus-rendering.png?v=2"
          alt="New Eden Academy campus rendering"
          onClose={() => setLightboxOpen(false)}
        />
      )}
    </section>
  );
}

Object.assign(window, { Hero });
