/* Shared UI components for Sham-e-Mehfil */ const { useState, useEffect, useRef } = React; /* ---- Inline icons (thin, editorial) ---- */ const Icon = { arrow: (p) => , arrowUp: (p) => , quote: (p) => , feather: (p) => , check: (p) => , pin: (p) => , clock: (p) => , seat: (p) => , ig: (p) => , }; /* ---- Editorial image (real photo) or placeholder ---- */ function Ph({ label, pic, src, alt, dark, style, className = "", ratio, w = 1100, overlay }) { const s = { ...(ratio ? { aspectRatio: ratio } : {}), ...style }; const imgSrc = src ? src : (pic ? (pic.indexOf("/") >= 0 ? pic : IMG(pic, w)) : null); if (imgSrc) { return (
{alt {overlay &&
}
); } return (
{label && {label}}
); } /* ---- Classical Indian ornamental divider (lotus + line) ---- */ function Ornament({ color = "var(--gold)", width = 240, style }) { return ( {/* central paisley/lotus */} ); } /* ---- Mughal cusped arch outline (decorative frame top) ---- */ function ArchTop({ color = "var(--gold)", style, w = 320 }) { return ( ); } /* ---- Scroll reveal hook ---- */ function useReveal() { useEffect(() => { const els = document.querySelectorAll(".reveal:not(.in)"); const io = new IntersectionObserver((entries) => { entries.forEach((e) => { if (e.isIntersecting) { e.target.classList.add("in"); io.unobserve(e.target); } }); }, { threshold: 0.12, rootMargin: "0px 0px -8% 0px" }); els.forEach((el) => io.observe(el)); return () => io.disconnect(); }); } /* ---- Eyebrow label ---- */ function Eyebrow({ children, ink, style }) { return
{children}
; } /* ---- Section heading block ---- */ function SectionHead({ eyebrow, title, lede, align = "left", max }) { return (
{eyebrow && {eyebrow}}

{title}

{lede &&

{lede}

}
); } /* ---- Status pill for events ---- */ function SeatPill({ status, seats }) { if (status === "wait") return Waitlist; if (status === "few") return {seats} seats left; return {seats} seats; } /* ---- Event card ---- */ function EventCard({ ev, onRegister, d }) { return (
{ev.theme}

{ev.title}

{ev.blurb}

{ev.date} · {ev.time} {ev.venue}
{ev.price}
); } /* ---- Navigation ---- */ const NAV_ITEMS = [ { to: "events", label: "Events" }, { to: "poets", label: "Poets" }, { to: "journal", label: "Journal" }, { to: "library", label: "Library" }, { to: "membership", label: "Membership" }, { to: "about", label: "About" }, ]; const DRAWER_ITEMS = [...NAV_ITEMS, { to: "community", label: "Community" }, { to: "perform", label: "Perform" }, { to: "partners", label: "Partners" }, { to: "contact", label: "Contact" }]; function Nav({ route, go }) { const [solid, setSolid] = useState(false); const [open, setOpen] = useState(false); const overHero = route === "home" && !solid && !open; useEffect(() => { const onScroll = () => setSolid(window.scrollY > 24); onScroll(); window.addEventListener("scroll", onScroll); return () => window.removeEventListener("scroll", onScroll); }, []); useEffect(() => { document.body.style.overflow = open ? "hidden" : ""; }, [open]); const nav = (to) => { go(to); setOpen(false); }; return (
nav("home")} style={{ cursor: "pointer" }}>Sham-e-Mehfil
{DRAWER_ITEMS.map((i, k) => ( nav(i.to)}>{String(k + 1).padStart(2, "0")}{i.label} ))}
); } /* ---- Footer ---- */ function Footer({ go }) { const cols = [ { h: "Attend", links: [["events", "Upcoming events"], ["membership", "Membership"], ["community", "Community"]] }, { h: "Read", links: [["journal", "Stories & Journal"], ["library", "Shayari library"], ["poets", "Featured poets"]] }, { h: "Take part", links: [["perform", "Perform at SEM"], ["partners", "Partnerships"], ["contact", "Contact"]] }, ]; return ( ); } Object.assign(window, { Icon, Ph, Ornament, ArchTop, useReveal, Eyebrow, SectionHead, SeatPill, EventCard, Nav, Footer });