/* sections2.jsx — audience-focused trust sections for hospitals, villas & NRIs.
Uses window shared primitives (Icon, Reveal, Overline, SectionHead, CountUp, Cta). */
const { useState: s2S, useEffect: s2E, useRef: s2R } = React;
/* subtle 3D tilt on hover (respects reduced-motion) */
function useTilt(max = 7) {
const ref = s2R(null);
s2E(() => {
const el = ref.current; if (!el) return;
if (window.matchMedia("(prefers-reduced-motion:reduce)").matches) return;
if (window.matchMedia("(hover:none)").matches) return;
let raf = 0, tx = 0, ty = 0, cx = 0, cy = 0;
const loop = () => { cx += (tx - cx) * 0.12; cy += (ty - cy) * 0.12; el.style.transform = `perspective(900px) rotateX(${cy}deg) rotateY(${cx}deg)`; raf = requestAnimationFrame(loop); };
const move = (e) => { const r = el.getBoundingClientRect(); tx = ((e.clientX - r.left) / r.width - 0.5) * 2 * max; ty = -((e.clientY - r.top) / r.height - 0.5) * 2 * max; el.style.setProperty("--gx", (e.clientX - r.left) + "px"); el.style.setProperty("--gy", (e.clientY - r.top) + "px"); };
const leave = () => { tx = 0; ty = 0; };
el.addEventListener("mousemove", move); el.addEventListener("mouseleave", leave);
loop();
return () => { el.removeEventListener("mousemove", move); el.removeEventListener("mouseleave", leave); cancelAnimationFrame(raf); };
}, []);
return ref;
}
/* ---- trust signal strip (compact, sits under hero) ----------------------- */
function TrustStrip({ lang }) {
const T = (v) => window.t(v, lang);
return (
{window.OLV.trust.map((t, i) => (
{T(t.value)}{T(t.label)}
))}
);
}
/* ---- audience paths (3 tilt cards) --------------------------------------- */
function AudiencePaths({ lang, onPickCat, onNavigate }) {
const T = (v) => window.t(v, lang);
const A = window.OLV.audiences;
return (
{A.items.map((it, i) =>
)}
);
}
function AudCard({ it, lang, delay, onPickCat, onNavigate }) {
const T = (v) => window.t(v, lang);
const ref = useTilt(6);
const go = () => { if (it.cat) onPickCat(it.cat); else onNavigate("contact"); };
return (
);
}
/* ---- NRI promise band ---------------------------------------------------- */
function NRIBand({ lang, onNavigate }) {
const T = (v) => window.t(v, lang);
const N = window.OLV.nri;
return (
{T(N.overline)}
{T(N.title)}
{T(N.lead)}
{T(N.statLine)}
onNavigate("contact")}>{T({ en: "Speak With the NRI Desk", hi: "एनआरआई डेस्क से बात करें" })}
{N.pledges.map((p, i) => (
))}
);
}
/* ---- transparency / reporting (device mockup + animated report) ---------- */
function Transparency({ lang }) {
const T = (v) => window.t(v, lang);
const X = window.OLV.transparency;
const ref = s2R(null);
const [seen, setSeen] = s2S(false);
s2E(() => {
const el = ref.current; if (!el) return;
const reveal = () => setSeen(true);
const io = new IntersectionObserver(([e]) => { if (e.isIntersecting) { reveal(); io.disconnect(); } }, { threshold: 0.25 });
io.observe(el);
// safety: if already visible or observer is throttled, reveal shortly after mount
const r = el.getBoundingClientRect();
if (r.top < window.innerHeight && r.bottom > 0) reveal();
const t = setTimeout(reveal, 1200);
return () => { io.disconnect(); clearTimeout(t); };
}, []);
return (
{T(X.overline)}
{T(X.title)}
{T(X.lead)}
{X.channels.map((c, i) => (
))}
{T(X.reportTitle)}
{T(X.sampleTag)}
{T(X.onSchedule)} · Aug 2025
{X.reportRows.map((r, i) => (
{T(r.label)}
{seen ? : "0%"}
))}
{[52, 63, 58, 74, 80, 88].map((h, i) => )}
{T({ en: "6-month S-curve", hi: "6-माह एस-कर्व" })}+88%
);
}
/* ---- hospital specialist band -------------------------------------------- */
function HospitalBand({ lang, onNavigate }) {
const T = (v) => window.t(v, lang);
const H = window.OLV.hospitalBand;
return (
{T({ en: "Indian Building Congress — Awarded", hi: "इंडियन बिल्डिंग कांग्रेस — पुरस्कृत" })}
{T(H.overline)}
{T(H.title)}
{T(H.lead)}
{H.stats.map((s, i) => (
))}
{H.points.map((p, i) => - {T(p)}
)}
onNavigate("contact")}>{T({ en: "Discuss a Healthcare Project", hi: "स्वास्थ्य प्रोजेक्ट पर चर्चा करें" })}
);
}
/* ---- AMC / post-handover ------------------------------------------------- */
function AMC({ lang }) {
const T = (v) => window.t(v, lang);
const A = window.OLV.amc;
return (
{A.items.map((it, i) => (
{T(it.title)}
{T(it.body)}
))}
{T(A.guaranteeNote)}
);
}
Object.assign(window, { TrustStrip, AudiencePaths, NRIBand, Transparency, HospitalBand, AMC });