/* Cordish Plaza — page sections. Uses window globals from components.jsx. */ const { useState, useRef } = React; /* ---------------- Header ---------------- */ function Header({ onExpress }) { return React.createElement("header", { style: { position: "sticky", top: 0, zIndex: 30, background: "rgba(255,255,255,.9)", backdropFilter: "blur(8px)", WebkitBackdropFilter: "blur(8px)", borderBottom: "1px solid var(--p-line)" } }, React.createElement("div", { className: "wrap", style: { height: 66, display: "flex", alignItems: "center", justifyContent: "space-between" } }, React.createElement("a", { href: "#top", style: { display: "flex", alignItems: "center", gap: 11, textDecoration: "none" } }, React.createElement("span", { style: { display: "flex", alignItems: "baseline", gap: 7, fontFamily: "var(--font-head)" } }, React.createElement("span", { style: { fontWeight: 700, fontSize: 18, letterSpacing: "-0.02em", color: "var(--p-charcoal)" } }, "Cordish"), React.createElement("span", { style: { width: 1, height: 16, background: "var(--p-line-strong)", display: "inline-block" } }), React.createElement("span", { style: { fontWeight: 600, fontSize: 18, letterSpacing: "-0.01em", color: "var(--p-purple)" } }, "Plaza") ) ), React.createElement(Btn, { size: "sm", onClick: onExpress, iconRight: "arrow-right" }, "Express interest") ) ); } /* ---------------- Gallery (swipeable; click to view full-screen) ---------------- */ function Gallery({ items }) { const [i, setI] = useState(0); const [zoom, setZoom] = useState(null); const startX = useRef(null); const go = (d) => setI(p => (p + d + items.length) % items.length); const onStart = (e) => { startX.current = e.touches[0].clientX; }; const onEnd = (e) => { if (startX.current == null) return; const dx = e.changedTouches[0].clientX - startX.current; if (dx > 44) go(-1); else if (dx < -44) go(1); startX.current = null; }; const arrow = (dir) => React.createElement("button", { onClick: () => go(dir === "next" ? 1 : -1), "aria-label": dir, style: { position: "absolute", top: "50%", transform: "translateY(-50%)", [dir === "next" ? "right" : "left"]: 10, zIndex: 3, width: 40, height: 40, borderRadius: "50%", display: "grid", placeItems: "center", cursor: "pointer", background: "var(--p-white)", border: "1px solid var(--p-line-strong)", color: "var(--p-purple)", transition: "background .15s, color .15s" } }, React.createElement(Icon, { name: "arrow-right", size: 18, style: { transform: dir === "next" ? "none" : "scaleX(-1)" } })); return React.createElement("div", null, React.createElement("div", { onTouchStart: onStart, onTouchEnd: onEnd, style: { position: "relative", border: "1px solid var(--p-line)", overflow: "hidden", borderRadius: "var(--radius-card)", background: "var(--p-lavender-25)", aspectRatio: "4 / 3" } }, React.createElement("div", { style: { display: "flex", height: "100%", transform: "translateX(" + (-i * 100) + "%)", transition: "transform .35s cubic-bezier(.4,0,.2,1)" } }, items.map((it, idx) => React.createElement("div", { key: idx, style: { flex: "0 0 100%", height: "100%", position: "relative", background: it.kind === "plan" ? "var(--p-white)" : "var(--p-lavender-25)" } }, React.createElement("img", { src: it.src, alt: it.alt, draggable: false, onClick: () => setZoom(it.src), style: { width: "100%", height: "100%", objectFit: it.kind === "plan" ? "contain" : "cover", padding: it.kind === "plan" ? 18 : 0, cursor: "zoom-in" } }), React.createElement("span", { style: { position: "absolute", left: 14, top: 14, background: it.kind === "plan" ? "var(--p-charcoal)" : "var(--p-gold)", color: "#fff", fontFamily: "var(--font-head)", fontWeight: 600, fontSize: 11, letterSpacing: ".06em", textTransform: "uppercase", padding: "6px 11px", borderRadius: "var(--radius-pill)" } }, it.kind === "plan" ? "Floor plan" : "3D render") )) ), arrow("prev"), arrow("next"), React.createElement("div", { style: { position: "absolute", left: 0, right: 0, bottom: 12, display: "flex", justifyContent: "center", gap: 7, zIndex: 3 } }, items.map((_, idx) => React.createElement("button", { key: idx, onClick: () => setI(idx), "aria-label": "Slide " + (idx + 1), style: { width: idx === i ? 22 : 8, height: 8, borderRadius: 999, border: "none", cursor: "pointer", padding: 0, transition: "width .2s, background .2s", background: idx === i ? "var(--p-gold)" : "rgba(255,255,255,.75)", boxShadow: idx === i ? "none" : "0 0 0 1px rgba(0,0,0,.08)" } })) ) ), React.createElement("p", { style: { marginTop: 11, fontSize: 12.5, color: "var(--p-grey)" } }, "Cordish Plaza is currently under construction; swipe to view the designs and floor plan." ), zoom ? React.createElement("div", { onClick: () => setZoom(null), style: { position: "fixed", inset: 0, zIndex: 100, background: "rgba(21,32,45,.92)", display: "grid", placeItems: "center", padding: 24, cursor: "zoom-out" } }, React.createElement("img", { src: zoom, alt: "", style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain", borderRadius: 8, boxShadow: "0 18px 50px rgba(0,0,0,.45)" } }), React.createElement("button", { onClick: () => setZoom(null), "aria-label": "Close", style: { position: "absolute", top: 16, right: 18, width: 42, height: 42, borderRadius: "50%", border: "none", background: "rgba(255,255,255,.15)", color: "#fff", fontSize: 24, lineHeight: 1, cursor: "pointer" } }, "×") ) : null ); } /* ---------------- Hero ---------------- */ function Hero({ mode, copy, gallery, onExpress, onViewShops }) { const cta = React.createElement("div", { style: { display: "flex", flexWrap: "wrap", gap: 12, marginTop: 30 } }, React.createElement(Btn, { onClick: onExpress, iconRight: "arrow-right" }, "Express interest"), React.createElement(Btn, { variant: "secondary", onClick: onViewShops }, "View available shops") ); if (mode === "norender") { return React.createElement("section", { id: "top", style: { background: "var(--p-lavender-25)", overflow: "hidden", borderBottom: "1px solid var(--p-line)" } }, React.createElement("div", { className: "wrap", style: { display: "flex", flexWrap: "wrap", gap: "40px 56px", alignItems: "center", paddingTop: 58, paddingBottom: 64, position: "relative" } }, React.createElement("div", { style: { flex: "1 1 420px", minWidth: 0 } }, React.createElement("span", { className: "eyebrow", style: { display: "inline-flex", alignItems: "center", gap: 8 } }, React.createElement(Icon, { name: "map-pin", size: 15 }), "Now leasing · Oyibi, Ghana"), React.createElement("h1", { style: { fontSize: "clamp(38px, 5.6vw, 60px)", fontWeight: 700, lineHeight: 1.02, marginTop: 18, color: "var(--p-charcoal)" } }, copy.headline), React.createElement("p", { style: { marginTop: 20, fontSize: "clamp(16px,2.2vw,19px)", lineHeight: 1.55, color: "var(--p-grey)", maxWidth: "42ch" } }, copy.sub), cta ), React.createElement("div", { style: { flex: "1 1 420px", minWidth: 0 } }, React.createElement("div", { className: "card", style: { padding: 20 } }, React.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 14 } }, React.createElement("span", { style: { fontFamily: "var(--font-head)", fontWeight: 600, fontSize: 13, letterSpacing: ".06em", textTransform: "uppercase", color: "var(--p-purple)" } }, "Ground floor plan"), React.createElement("span", { className: "num", style: { fontSize: 12.5, color: "var(--p-grey)" } }, "Alt 'B'") ), React.createElement("div", { style: { background: "var(--p-lavender-25)", border: "1px solid var(--p-line)", borderRadius: "var(--radius-sm)", padding: 8 } }, React.createElement("img", { src: "assets/floor-plan.png", alt: "Ground floor plan of Cordish Plaza", style: { width: "100%", height: "auto" } }) ) ) ) ) ); } return React.createElement("section", { id: "top", style: { background: "var(--p-white)", overflow: "hidden", borderBottom: "1px solid var(--p-line)" } }, React.createElement("div", { className: "wrap", style: { display: "flex", flexWrap: "wrap", gap: "40px 56px", alignItems: "center", paddingTop: 58, paddingBottom: 64 } }, React.createElement("div", { style: { flex: "1 1 420px", minWidth: 0 } }, React.createElement("span", { className: "eyebrow", style: { display: "inline-flex", alignItems: "center", gap: 8 } }, React.createElement(Icon, { name: "map-pin", size: 15 }), "Now leasing · Oyibi, Ghana"), React.createElement("h1", { style: { fontSize: "clamp(38px, 5.6vw, 60px)", fontWeight: 700, lineHeight: 1.02, marginTop: 18, color: "var(--p-charcoal)" } }, copy.headline), React.createElement("p", { style: { marginTop: 20, fontSize: "clamp(16px,2.2vw,19px)", lineHeight: 1.55, color: "var(--p-grey)", maxWidth: "42ch" } }, copy.sub), cta ), React.createElement("div", { style: { flex: "1 1 420px", minWidth: 0 } }, React.createElement(Gallery, { items: gallery })) ) ); } /* ---------------- Quick facts strip ---------------- */ function Facts({ count, minRent, location, leased }) { const items = leased ? [["map-pin", location], ["store", "All shops currently leased"], ["key-round", "Join the waitlist"]] : [["map-pin", location], ["banknote", "Rent from GHS " + fmt(minRent) + "/mo"]]; return React.createElement("section", { style: { background: "var(--p-purple)", color: "#fff" } }, React.createElement("div", { className: "wrap", style: { display: "flex", flexWrap: "wrap", justifyContent: "center", gap: "14px 0", paddingTop: 18, paddingBottom: 18 } }, items.map(([ic, txt], i) => React.createElement("div", { key: i, style: { display: "flex", alignItems: "center", flex: "0 1 auto" } }, React.createElement("div", { style: { display: "inline-flex", alignItems: "center", gap: 10, padding: "0 28px", fontFamily: "var(--font-head)", fontWeight: 500, fontSize: 15.5 } }, React.createElement(Icon, { name: ic, size: 18, style: { opacity: .85 } }), React.createElement("span", { className: "num" }, txt) ), i < items.length - 1 ? React.createElement("span", { style: { width: 1, height: 22, background: "rgba(255,255,255,.28)" } }) : null ) ) ) ); } /* ---------------- Why Cordish Plaza (condensed) ---------------- */ function Why({ amenities }) { return React.createElement("section", { style: { background: "var(--p-lavender-25)", paddingTop: 64, paddingBottom: 68, overflow: "hidden" } }, React.createElement("div", { className: "wrap", style: { position: "relative" } }, React.createElement(SectionHead, { eyebrow: "Why Cordish Plaza", title: "The essentials, handled", sub: "One service fee keeps every shop running." }), React.createElement("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(190px, 1fr))", gap: 12, marginTop: 28 } }, amenities.map((a, i) => React.createElement("div", { key: i, className: "card", style: { padding: "13px 16px 13px 13px", display: "flex", alignItems: "center", gap: 12 } }, React.createElement(IconChip, { icon: a.icon, tone: "teal" }), React.createElement("span", { style: { fontFamily: "var(--font-head)", fontWeight: 600, fontSize: 14.5, color: "var(--p-charcoal)" } }, a.label) )) ) ) ); } /* ---------------- Businesses interested so far (horizontally scrollable strip) ---------------- */ function WhosHere({ mix }) { if (!mix || !mix.length) return null; return React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 16, marginTop: 24, padding: "14px 18px", background: "var(--p-gold-50)", border: "1px solid var(--p-line)", borderRadius: "var(--radius-card)" } }, React.createElement("span", { style: { flex: "none", fontFamily: "var(--font-head)", fontWeight: 600, fontSize: 12.5, letterSpacing: ".06em", textTransform: "uppercase", color: "var(--p-gold-700)" } }, "Businesses interested so far"), React.createElement("div", { className: "wh-scroll", style: { display: "flex", flexWrap: "nowrap", gap: 8, overflowX: "auto", paddingBottom: 2, scrollbarWidth: "thin", WebkitOverflowScrolling: "touch" } }, mix.map((m, i) => React.createElement(Badge, { key: i, tone: "gold", variant: "subtle", style: { flex: "none", whiteSpace: "nowrap", padding: "6px 12px", fontSize: 13, background: "var(--p-white)", border: "1px solid var(--cd-line)" } }, m.label)) ) ); } /* ---------------- Shop card (interest badge is configurable: position/fill/icon) ---------------- */ function ShopCard({ shop, onExpress, selected, available, badgePos, badgeFill, badgeIcon, btnWide }) { if (!available) { return React.createElement("div", { className: "card", style: { padding: 22, display: "flex", flexDirection: "column", gap: 16, containerType: "inline-size", background: "var(--cd-ground)", boxShadow: "none" } }, React.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10 } }, React.createElement("h3", { style: { fontSize: 24, fontWeight: 700, color: "var(--p-charcoal)" } }, shop.label), React.createElement(Badge, { tone: "neutral", variant: "subtle" }, "Leased") ), React.createElement("div", { style: { display: "flex", borderTop: "1px solid var(--p-line)", borderBottom: "1px solid var(--p-line)" } }, React.createElement("div", { style: { flex: "1.4 1 0", minWidth: 0, padding: "16px 12px 16px 0" } }, React.createElement("div", { style: { fontSize: 11.5, letterSpacing: ".07em", textTransform: "uppercase", color: "var(--p-grey)", fontWeight: 600, fontFamily: "var(--font-head)" } }, "Rent"), React.createElement("div", { style: { marginTop: 4, display: "flex", alignItems: "baseline", gap: 4, flexWrap: "wrap" } }, React.createElement("span", { className: "num", style: { fontFamily: "var(--font-head)", fontWeight: 700, fontSize: "clamp(17px, 4.4cqw, 21px)", color: "var(--p-grey)", whiteSpace: "nowrap" } }, "GHS " + fmt(shop.monthly_rent)), React.createElement("span", { style: { fontSize: 12.5, color: "var(--p-grey)" } }, "/mo") ) ), React.createElement("div", { style: { width: 1, background: "var(--p-line)" } }), React.createElement("div", { style: { flex: "1 1 0", minWidth: 0, padding: "16px 0 16px 18px" } }, React.createElement("div", { style: { fontSize: 11.5, letterSpacing: ".07em", textTransform: "uppercase", color: "var(--p-grey)", fontWeight: 600, fontFamily: "var(--font-head)" } }, "Size"), React.createElement("div", { style: { marginTop: 4, display: "flex", alignItems: "baseline", gap: 4 } }, React.createElement("span", { className: "num", style: { fontFamily: "var(--font-head)", fontWeight: 700, fontSize: "clamp(17px, 4.4cqw, 21px)", color: "var(--p-grey)" } }, shop.size_sqm), React.createElement("span", { style: { fontSize: 12.5, color: "var(--p-grey)" } }, "m²") ) ) ), shop.intended_use ? React.createElement("div", { style: { fontSize: 13, fontWeight: 600, color: "var(--p-grey)", fontFamily: "var(--font-head)" } }, shop.intended_use) : null ); } const hasInterest = shop.interested_count >= 1; const interestLabel = shop.interested_count === 1 ? "Recently enquired" : shop.interested_count + " enquiries"; const interestPill = () => React.createElement("div", { style: { display: "inline-flex", alignItems: "center", gap: 7, alignSelf: badgePos === "top" ? "center" : "flex-start", flex: "none", padding: badgeFill ? "5px 11px" : "0", borderRadius: "var(--radius-pill)", background: badgeFill ? "var(--p-gold-50)" : "transparent", color: "var(--p-gold-700)", fontFamily: "var(--font-head)", fontWeight: 600, fontSize: 12.5, whiteSpace: "nowrap" } }, badgeIcon ? React.createElement(Icon, { name: "users", size: 14 }) : null, React.createElement("span", { className: "num" }, interestLabel) ); return React.createElement("div", { className: "card", style: { padding: 22, display: "flex", flexDirection: "column", gap: 16, containerType: "inline-size", outline: selected ? "2px solid var(--p-purple)" : "none", outlineOffset: -1 } }, React.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10, minHeight: 30 } }, React.createElement("h3", { style: { fontSize: 24, fontWeight: 700, color: "var(--p-charcoal)" } }, shop.label), (badgePos === "top" && hasInterest) ? interestPill() : null ), React.createElement("div", { style: { display: "flex", borderTop: "1px solid var(--p-line)", borderBottom: "1px solid var(--p-line)" } }, React.createElement("div", { style: { flex: "1.4 1 0", minWidth: 0, padding: "16px 12px 16px 0" } }, React.createElement("div", { style: { fontSize: 11.5, letterSpacing: ".07em", textTransform: "uppercase", color: "var(--p-grey)", fontWeight: 600, fontFamily: "var(--font-head)" } }, "Rent"), React.createElement("div", { style: { marginTop: 4, display: "flex", alignItems: "baseline", gap: 4, flexWrap: "wrap" } }, React.createElement("span", { className: "num", style: { fontFamily: "var(--font-head)", fontWeight: 700, fontSize: "clamp(17px, 4.4cqw, 21px)", color: "var(--p-purple)", whiteSpace: "nowrap" } }, "GHS " + fmt(shop.monthly_rent)), React.createElement("span", { style: { fontSize: 12.5, color: "var(--p-grey)" } }, "/mo") ) ), React.createElement("div", { style: { width: 1, background: "var(--p-line)" } }), React.createElement("div", { style: { flex: "1 1 0", minWidth: 0, padding: "16px 0 16px 18px" } }, React.createElement("div", { style: { fontSize: 11.5, letterSpacing: ".07em", textTransform: "uppercase", color: "var(--p-grey)", fontWeight: 600, fontFamily: "var(--font-head)" } }, "Size"), React.createElement("div", { style: { marginTop: 4, display: "flex", alignItems: "baseline", gap: 4 } }, React.createElement("span", { className: "num", style: { fontFamily: "var(--font-head)", fontWeight: 700, fontSize: "clamp(17px, 4.4cqw, 21px)", color: "var(--p-charcoal)" } }, shop.size_sqm), React.createElement("span", { style: { fontSize: 12.5, color: "var(--p-grey)" } }, "m²") ) ) ), (badgePos !== "top" && hasInterest) ? interestPill() : null, React.createElement(Btn, { size: "sm", variant: selected ? "secondary" : "primary", onClick: () => onExpress(shop), iconRight: selected ? "check" : (btnWide ? null : "arrow-right"), style: { alignSelf: "center", width: btnWide ? "80%" : "70%", padding: btnWide ? "11px 16px" : "8px 16px" } }, selected ? "Selected" : "Express interest") ); } /* ---------------- Interest form (lives inside leasing interface) ---------------- */ function InterestForm({ shops, selected, setSelected, leased }) { const [done, setDone] = useState(false); const [name, setName] = useState(""); const [phone, setPhone] = useState(""); const [usage, setUsage] = useState(""); const [msg, setMsg] = useState(""); const [submitting, setSubmitting] = useState(false); const [err, setErr] = useState(""); const [hp, setHp] = useState(""); // honeypot (humans leave empty) const startedAt = useRef(Date.now()); // for the too-fast-submit check const toggle = (id) => { const n = new Set(selected); n.has(id) ? n.delete(id) : n.add(id); setSelected(n); }; const submit = async (e) => { e.preventDefault(); if (submitting) return; setSubmitting(true); setErr(""); const shopStr = (shops || []).filter(s => selected.has(s.id)).map(s => s.label + " (" + s.floor + " floor)").join(", "); try { const r = await fetch("api/interest.php", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name, phone, shop: shopStr, usage, msg, website: hp, elapsed: Date.now() - startedAt.current }) }); const j = await r.json().catch(() => ({})); if (r.ok && j.ok) setDone(true); else setErr(j.error || "Something went wrong. Please email us instead."); } catch (_) { setErr("Could not reach the server. Please email us instead."); } finally { setSubmitting(false); } }; const inputStyle = { width: "100%", padding: "12px 14px", border: "1px solid var(--p-line-strong)", borderRadius: "var(--radius-sm)", fontFamily: "var(--font-body)", fontSize: 15.5, color: "var(--p-charcoal)", background: "var(--p-white)", outline: "none" }; const labelStyle = { display: "block", fontFamily: "var(--font-head)", fontWeight: 600, fontSize: 13, color: "var(--p-charcoal)", marginBottom: 7 }; const intro = React.createElement("div", { style: { flex: "1 1 280px" } }, React.createElement("span", { className: "eyebrow" }, leased ? "Join the waitlist" : "Express interest"), React.createElement("h3", { style: { fontSize: "clamp(24px,3.4vw,30px)", fontWeight: 700, lineHeight: 1.1, marginTop: 8, color: "var(--p-charcoal)" } }, leased ? "Be first when a space opens." : "Tell us which space is yours."), React.createElement("p", { style: { marginTop: 12, fontSize: 16, lineHeight: 1.6, color: "var(--p-grey)", maxWidth: "38ch" } }, "Leave your details and we will follow up. Tell us which space you like."), React.createElement("div", { style: { display: "flex", flexWrap: "wrap", gap: 10, marginTop: 22 } }, // No public number yet. When there is one, set it below and uncomment these (and drop "Email us" if you prefer): // React.createElement(Btn, { href: "https://wa.me/233XXXXXXXXX", icon: "message-circle" }, "Message on WhatsApp"), // React.createElement(Btn, { href: "tel:+233XXXXXXXXX", variant: "secondary", icon: "phone" }, "Call us"), React.createElement(Btn, { href: "mailto:info@cordishgroup.com", variant: "secondary", icon: "mail" }, "Email us") ) ); const formCard = done ? React.createElement("div", { style: { padding: "40px 8px", textAlign: "center" } }, React.createElement("div", { style: { display: "inline-grid", placeItems: "center", width: 58, height: 58, background: "var(--p-purple)", color: "#fff", margin: "0 auto" } }, React.createElement(Icon, { name: "check", size: 28 })), React.createElement("h3", { style: { marginTop: 18, fontSize: 22, fontWeight: 600 } }, "Thank you, " + (name ? name.split(" ")[0] : "we got it") + "."), React.createElement("p", { style: { marginTop: 10, fontSize: 15.5, color: "var(--p-grey)", lineHeight: 1.55, maxWidth: "42ch", marginLeft: "auto", marginRight: "auto" } }, "Your interest is in. The Cordish Plaza team will reach out shortly."), React.createElement("div", { style: { marginTop: 22 } }, React.createElement(Btn, { variant: "secondary", onClick: () => { setDone(false); setName(""); setPhone(""); setUsage(""); setMsg(""); setSelected(new Set()); } }, "Send another")) ) : React.createElement("form", { onSubmit: submit, style: { display: "flex", flexDirection: "column", gap: 16 } }, React.createElement("div", { "aria-hidden": "true", style: { position: "absolute", left: "-9999px", width: 1, height: 1, overflow: "hidden" } }, React.createElement("input", { type: "text", name: "website", tabIndex: -1, autoComplete: "off", value: hp, onChange: e => setHp(e.target.value) }) ), React.createElement("div", { style: { display: "flex", flexWrap: "wrap", gap: 16 } }, React.createElement("div", { style: { flex: "1 1 180px" } }, React.createElement("label", { style: labelStyle }, "Your name"), React.createElement("input", { style: inputStyle, value: name, onChange: e => setName(e.target.value), placeholder: "Full name", required: true })), React.createElement("div", { style: { flex: "1 1 180px" } }, React.createElement("label", { style: labelStyle }, "Phone / WhatsApp"), React.createElement("input", { style: inputStyle, value: phone, onChange: e => setPhone(e.target.value), placeholder: "+233 …", inputMode: "tel", required: true })) ), !leased ? React.createElement("div", null, React.createElement("label", { style: labelStyle }, "Shop(s) of interest"), React.createElement("div", { style: { display: "flex", flexWrap: "wrap", gap: 8 } }, shops.map(s => { const on = selected.has(s.id); return React.createElement("button", { key: s.id, type: "button", onClick: () => toggle(s.id), style: { fontFamily: "var(--font-head)", fontWeight: 600, fontSize: 13, cursor: "pointer", padding: "8px 14px", borderRadius: "var(--radius-pill)", transition: "background .15s,color .15s,border-color .15s", border: "1px solid " + (on ? "var(--p-purple)" : "var(--p-line-strong)"), background: on ? "var(--p-purple)" : "var(--p-white)", color: on ? "#fff" : "var(--p-charcoal)" } }, s.label, React.createElement("span", { style: { opacity: .6, fontWeight: 500, marginLeft: 6 } }, s.floor[0])); }) ) ) : null, React.createElement("div", null, React.createElement("label", { style: labelStyle }, "What will you use the space for?", React.createElement("span", { style: { fontWeight: 400, color: "var(--p-grey)", marginLeft: 6 } }, "keep it short")), React.createElement("input", { style: inputStyle, value: usage, onChange: e => setUsage(e.target.value), placeholder: "e.g. pharmacy, salon, mini-mart" })), React.createElement("div", null, React.createElement("label", { style: labelStyle }, "Questions or anything else?"), React.createElement("textarea", { style: { ...inputStyle, minHeight: 84, resize: "vertical" }, value: msg, onChange: e => setMsg(e.target.value), placeholder: "Ask us anything about the plaza, the units, or the service fee." })), err ? React.createElement("p", { style: { color: "#B4232E", fontSize: 14, lineHeight: 1.45, margin: 0 } }, err) : null, React.createElement(Btn, { type: "submit", block: true, iconRight: "send", style: submitting ? { opacity: .65, pointerEvents: "none" } : null }, submitting ? "Sending…" : (leased ? "Join the waitlist" : "Express interest")) ); return React.createElement("div", { id: "interest", style: { marginTop: 40, scrollMarginTop: 80, border: "1px solid var(--p-line)", borderRadius: "var(--radius-panel)", background: "var(--p-teal-50)", padding: "clamp(22px, 4vw, 38px)", display: "flex", flexWrap: "wrap", gap: "30px 48px", alignItems: "flex-start" } }, intro, React.createElement("div", { style: { flex: "1 1 360px" } }, React.createElement("div", { className: "card", style: { padding: 26, background: "var(--p-white)" } }, formCard)) ); } /* ---------------- Leasing interface (shops + form, unified) ---------------- */ function Leasing({ shops, selected, setSelected, mix, leased, badgePos, perRow, badgeFill, badgeIcon, btnWide }) { const [availOnly, setAvailOnly] = useState(false); const [floor, setFloor] = useState("All"); const isAvail = (s) => !leased && s.status === "Available"; const availableShops = shops.filter(isAvail); const hasLeased = shops.some(s => !isAvail(s)); const showAvailToggle = hasLeased && !leased; const base = (availOnly && showAvailToggle) ? shops.filter(isAvail) : shops; const floorCounts = { All: base.length, Ground: base.filter(s => s.floor === "Ground").length, First: base.filter(s => s.floor === "First").length }; const groups = floor === "All" ? ["Ground", "First"] : [floor]; const segBtn = { fontFamily: "var(--font-head)", fontWeight: 600, fontSize: 13, cursor: "pointer", padding: "9px 15px", border: "none", transition: "background .15s,color .15s" }; const seg = (opts, val, set, counts) => React.createElement("div", { style: { display: "flex", border: "1px solid var(--p-line-strong)", borderRadius: "var(--radius-pill)", overflow: "hidden" } }, opts.map((o, i) => React.createElement("button", { key: o, onClick: () => set(o), style: { ...segBtn, borderLeft: i ? "1px solid var(--p-line-strong)" : "none", background: val === o ? "var(--p-purple)" : "var(--p-white)", color: val === o ? "#fff" : "var(--p-charcoal)" } }, o, counts ? React.createElement("span", { className: "num", style: { opacity: .6, marginLeft: 6, fontWeight: 500 } }, counts[o]) : null))); const gridMin = perRow === 3 ? 330 : 265; const grid = (list) => React.createElement("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(" + gridMin + "px, 1fr))", gap: 36, marginTop: 18 } }, list.map(s => React.createElement(ShopCard, { key: s.id, shop: s, available: isAvail(s), selected: selected.has(s.id), badgePos, badgeFill, badgeIcon, btnWide, onExpress: (shop) => { const n = new Set(selected); n.add(shop.id); setSelected(n); scrollToId("interest"); } }))); return React.createElement("section", { id: "shops", style: { background: "var(--p-white)", paddingTop: 70, paddingBottom: 84, scrollMarginTop: 70 } }, React.createElement("div", { className: "wrap" }, React.createElement("div", { style: { display: "flex", flexWrap: "wrap", gap: "16px 24px", alignItems: "flex-end", justifyContent: "space-between" } }, React.createElement(SectionHead, { eyebrow: "Now leasing", title: "Browse the shops", sub: "Browse the plaza and express interest in the units you like. Prices shown are monthly." }), React.createElement("div", { style: { display: "flex", flexWrap: "wrap", alignItems: "center", gap: 10 } }, showAvailToggle ? React.createElement("button", { onClick: () => setAvailOnly(v => !v), "aria-pressed": availOnly, style: { display: "inline-flex", alignItems: "center", gap: 8, fontFamily: "var(--font-head)", fontWeight: 600, fontSize: 13, cursor: "pointer", padding: "9px 15px", borderRadius: "var(--radius-pill)", transition: "background .15s,color .15s,border-color .15s", border: "1px solid " + (availOnly ? "var(--p-purple)" : "var(--p-line-strong)"), background: availOnly ? "var(--p-purple)" : "var(--p-white)", color: availOnly ? "#fff" : "var(--p-charcoal)" } }, React.createElement(Icon, { name: availOnly ? "check" : "filter", size: 15 }), "Available only", React.createElement("span", { className: "num", style: { opacity: .65, fontWeight: 500 } }, availableShops.length) ) : null, seg(["All", "Ground", "First"], floor, setFloor, floorCounts) ) ), React.createElement(WhosHere, { mix }), base.length === 0 ? React.createElement("div", { className: "card", style: { marginTop: 30, padding: "40px 30px", textAlign: "center", background: "var(--p-lavender-25)" } }, React.createElement("div", { style: { display: "inline-grid", placeItems: "center", width: 56, height: 56, borderRadius: "50%", border: "2px solid var(--p-purple)", color: "var(--p-purple)", margin: "0 auto" } }, React.createElement(Icon, { name: "key-round", size: 26 })), React.createElement("h3", { style: { marginTop: 16, fontSize: 21, fontWeight: 600, color: "var(--p-charcoal)" } }, "No shops available right now"), React.createElement("p", { style: { marginTop: 10, fontSize: 15.5, lineHeight: 1.55, color: "var(--p-grey)", maxWidth: "46ch", marginLeft: "auto", marginRight: "auto" } }, "Every unit is currently leased. Leave your details and we will be in touch the moment one opens up.") ) : groups.map(g => { const list = base.filter(s => s.floor === g); if (!list.length) return null; return React.createElement("div", { key: g, style: { marginTop: 30, paddingTop: 40 } }, React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 14 } }, React.createElement("span", { style: { fontFamily: "var(--font-head)", fontWeight: 600, fontSize: 13.5, letterSpacing: ".06em", textTransform: "uppercase", color: "var(--p-charcoal)" } }, g + " floor"), React.createElement("span", { className: "num", style: { fontSize: 12.5, fontWeight: 600, color: "var(--p-teal-700)", whiteSpace: "nowrap" } }, list.length + ((availOnly && showAvailToggle) ? " available" : " shops")), React.createElement("span", { style: { flex: 1, height: 1, background: "var(--p-line)" } }) ), grid(list) ); }), React.createElement("p", { style: { marginTop: 22, fontSize: 13, lineHeight: 1.6, color: "var(--p-grey)", maxWidth: "80ch" } }, "Rents are monthly, in GHS. A service fee (borehole, generator, security, cleaning, landscaping) applies; ask for details. Shop 4, 5 and 6 sizes are provisional."), React.createElement(InterestForm, { shops: availableShops, selected, setSelected, leased }) ) ); } /* ---------------- Footer ---------------- */ function Footer() { // No public number yet. To re-enable WhatsApp/Call, set the numbers and uncomment: const contacts = [ // ["message-circle", "WhatsApp us", "https://wa.me/233XXXXXXXXX"], // ["phone", "+233 XX XXX XXXX", "tel:+233XXXXXXXXX"], ["mail", "info@cordishgroup.com", "mailto:info@cordishgroup.com"] ]; return React.createElement("footer", { style: { background: "var(--p-violet)", color: "#fff" } }, React.createElement("div", { className: "wrap", style: { paddingTop: 50, paddingBottom: 30 } }, React.createElement("div", { style: { display: "flex", flexWrap: "wrap", gap: "28px 40px", justifyContent: "space-between", alignItems: "flex-start" } }, React.createElement("div", { style: { flex: "1 1 260px" } }, React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 11 } }, React.createElement("span", { style: { display: "flex", alignItems: "baseline", gap: 7, fontFamily: "var(--font-head)" } }, React.createElement("span", { style: { fontWeight: 700, fontSize: 18 } }, "Cordish"), React.createElement("span", { style: { width: 1, height: 15, background: "rgba(255,255,255,.4)" } }), React.createElement("span", { style: { fontWeight: 600, fontSize: 18, color: "var(--p-lavender)" } }, "Plaza")) ), React.createElement("p", { style: { marginTop: 14, fontSize: 14.5, lineHeight: 1.6, color: "rgba(255,255,255,.72)", maxWidth: "32ch" } }, "A retail plaza in Oyibi, Greater Accra, Ghana. A company of the Cordish Group.") ), React.createElement("div", { style: { flex: "0 1 auto" } }, React.createElement("span", { style: { fontFamily: "var(--font-head)", fontWeight: 600, fontSize: 12.5, letterSpacing: ".09em", textTransform: "uppercase", color: "var(--p-lavender)" } }, "Get in touch"), React.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 11, marginTop: 14 } }, contacts.map(([ic, txt, href], i) => React.createElement("a", { key: i, href, style: { display: "flex", alignItems: "center", gap: 10, color: "rgba(255,255,255,.88)", textDecoration: "none", fontSize: 15, fontFamily: "var(--font-head)", fontWeight: 500 } }, React.createElement(Icon, { name: ic, size: 17, style: { opacity: .85 } }), React.createElement("span", { className: "num" }, txt)))) ) ), React.createElement("div", { style: { marginTop: 36, paddingTop: 20, borderTop: "1px solid rgba(255,255,255,.16)", display: "flex", flexWrap: "wrap", gap: "10px 20px", justifyContent: "space-between", alignItems: "center" } }, React.createElement("span", { style: { fontSize: 12.5, color: "rgba(255,255,255,.55)" } }, "© " + new Date().getFullYear() + " Cordish Group. All rights reserved."), React.createElement("span", { style: { fontFamily: "var(--font-head)", fontWeight: 600, fontSize: 11.5, letterSpacing: ".1em", color: "var(--p-lavender)" } }, "CONSULTING | STRATEGY | CAPACITY BUILDING") ) ) ); } Object.assign(window, { Header, Hero, Facts, Why, WhosHere, Leasing, Footer });