/* MAG Lifestyle Development — interactive prototype Single root component, view-state routed. */ const { useState, useEffect, useRef, useMemo, useCallback } = React; /* ---------------------------------------------------------------- Icons (inline SVG — no external icon font) ---------------------------------------------------------------- */ const I = { arr: (p={}) => , arrL: (p={}) => , arrLong: (p={}) => , close: (p={}) => , whatsapp: (p={}) => , download: (p={}) => , pin: (p={}) => , check: (p={}) => , play: (p={}) => , globe: (p={}) => , }; /* ---------------------------------------------------------------- Helpers ---------------------------------------------------------------- */ const projectBySlug = (slug) => PROJECTS.find(p => p.slug === slug); const safeImg = (p) => p.img || "media/home-og.webp"; const useScroll = () => { const [y, setY] = useState(0); useEffect(() => { const on = () => setY(window.scrollY); on(); window.addEventListener("scroll", on, { passive: true }); return () => window.removeEventListener("scroll", on); }, []); return y; }; /* ---------------------------------------------------------------- Top Nav ---------------------------------------------------------------- */ function TopNav({ view, locale, setLocale, go, onRegister, onBrochure }) { const y = useScroll(); const onHero = view === "home" || view.startsWith("microsite:"); const lightMode = !onHero || y > 80; const L = LOCALES[locale]; return ( ); } /* ---------------------------------------------------------------- Hero ---------------------------------------------------------------- */ function Hero({ locale, onRegister, onScroll, go, heroVariant, showCoords }) { const slides = HERO_SLIDES; const startIdx = useMemo(() => { const i = slides.findIndex(s => s.id === heroVariant); return i >= 0 ? i : 0; }, [heroVariant]); const [idx, setIdx] = useState(startIdx); useEffect(() => setIdx(startIdx), [startIdx]); useEffect(() => { const id = setInterval(() => setIdx(i => (i + 1) % slides.length), 7200); return () => clearInterval(id); }, [slides.length]); const L = LOCALES[locale]; const slide = slides[idx]; const bg = slide.img; return (
{slides.map((s, i) => ( ))}
{slide.eyebrow}

{locale === "en" ? ( <>The art of living
well. ) : ( {L.hero.eyebrow ? L.hero.eyebrow : "—"}
)}

{locale !== "en" && (

{L.hero.lede}

)}
Statement
{locale === "en" ? "Property developers in Dubai building more than luxury homes — communities that can uplift you." : L.hero.lede}
Now showing
{slide.eyebrow}
{showCoords && (
{projectBySlug(slide.project)?.coord || "—"}
)}
); } /* ---------------------------------------------------------------- Section: Current projects ribbon (mixed grid) ---------------------------------------------------------------- */ function CurrentProjectsRibbon({ go, locale }) { const items = PROJECTS.filter(p => p.cat === "current"); // size pattern: 7 / 5 / 4 / 4 / 4 const spans = ["span-7", "span-5", "span-4", "span-4", "span-4"]; return (
{locale === "en" ? "Current Projects" : LOCALES[locale].nav.current}

Five live launches.
One Dubai, many addresses.

MAG Lifestyle's current pipeline spans MBR City, Dubailand, and Jumeirah Lake Towers — each project programmed for its own neighborhood rhythm. RERA/DLD to confirm per project

{items.map((p, i) => ( go(`microsite:${p.slug}`)} /> ))}
); } function ProjectCard({ p, idx, className, onClick }) { return (
{String(idx).padStart(2, "0")} {p.cat === "keturah" && Keturah} {p.cat === "current" && Current} {p.cat === "completed" && Completed} {`${p.name}
{p.location || "Dubai, UAE"}
{p.name}
{p.tagline &&
{p.tagline}
} Read more {I.arr()}
); } /* ---------------------------------------------------------------- Keturah spotlight ---------------------------------------------------------------- */ function KeturahSpotlight({ go }) { return (
Keturah Reserve render
Keturah Resort render
Keturah Reserve Townhouses render
Keturah · Bio Living

A wellness brand,
not a wellness amenity.

Keturah is MAG's flagship lifestyle brand — designed around the proposition that buildings can support how you breathe, move, and sleep. Reserve, Resort, the Ritz-Carlton-branded Creekside residences, and Keturah Tower form the family.

7 + 12
Buildings · Mansions (Creekside)
D7
MBR City Reserve district
AED 3bn*
Reserve scale *press-attributed
"Bio Living" attributed to Keturah. Ritz-Carlton and Marriott are third-party brands — licensing and render rights to be confirmed before launch.
); } /* ---------------------------------------------------------------- Why MAG block ---------------------------------------------------------------- */ function WhyMag() { const pillars = [ { n: "01", h: "Real-estate arm of MAG Group", b: "Founded in 1978 as a multi-sector group; the real-estate arm is commonly described as established in 2003.", attrib: "Press / company profile" }, { n: "02", h: "Scale, attributed", b: "Profiles cite over $5bn portfolio value, 14 completed projects, and 7 in pipeline.", attrib: "Press-attributed — not independently audited" }, { n: "03", h: "Lifestyle, not floorplate", b: "From MBR City to the Creek, projects are programmed around how residents actually live — light, air, water, walkability." }, { n: "04", h: "Investor-credible", b: "Branded residences, transparent CRM-routed lead capture, and bilingual (EN/AR) campaign pages today — RU/ZH on the roadmap." }, ]; return (
Why MAG

Forty-eight years of group legacy.
Twenty-three of building Dubai.

The published figures here are press- and company-attributed. We carry the attribution through to every page so you always know the source.

{pillars.map(p => (
{p.n}
{p.h}
{p.b}
{p.attrib &&
{p.attrib}
}
))}
Recognition IPA — to confirm Luxury Lifestyle Awards — to confirm WELL claim — to confirm Issuer + year — to confirm

Awards / certifications shown as placeholders only. We will not publish logos, issuers, or year claims until rights and dates are client-confirmed.

); } /* ---------------------------------------------------------------- Legacy / Completed strip ---------------------------------------------------------------- */ function LegacyStrip({ go, locale }) { const items = PROJECTS.filter(p => p.cat === "completed"); return (
{LOCALES[locale].nav.legacy}

Built before, still standing.

Completed and legacy assets are clearly separated from current launches across every locale of the site — never collapsed into one "active" list.

{items.slice(0, 8).map((p, i) => ( ))}
); } /* ---------------------------------------------------------------- Contact + Footer ---------------------------------------------------------------- */ function ContactSection({ onRegister, onViewing }) { return (
Contact

Verified channels,
investor-grade response.

Every published contact below is verified against mag.global. Items marked CONFIRM still require client sign-off before publishing.

Head office Verified
Emirates Financial Towers
27th Floor, South Tower, DIFC, Dubai, UAE
PO Box & map coordinates CONFIRM
Opening hours CONFIRM
Telephone Verified
+971 4 355 5580
Toll-free 800 624 (800 MAG)
Sales-specific line CONFIRM
Email Verified
info@mag.global
marketing@mag.global
Dedicated sales/leads inbox CONFIRM
); } function Footer({ go }) { return ( ); } /* ---------------------------------------------------------------- Projects index view ---------------------------------------------------------------- */ function ProjectsView({ go, initialFilter }) { const [filter, setFilter] = useState(initialFilter || "all"); useEffect(() => { setFilter(initialFilter || "all"); }, [initialFilter]); const filters = [ { id: "all", label: "All projects" }, { id: "current", label: "Current" }, { id: "keturah", label: "Keturah" }, { id: "completed", label: "Completed / Legacy" }, ]; const items = filter === "all" ? PROJECTS : PROJECTS.filter(p => p.cat === filter); const counts = { all: PROJECTS.length, current: PROJECTS.filter(p=>p.cat==="current").length, keturah: PROJECTS.filter(p=>p.cat==="keturah").length, completed: PROJECTS.filter(p=>p.cat==="completed").length, }; return (
Portfolio · 2026

Projects.
Honestly categorised.

The official MAG site mixes current launches, Keturah, and completed/legacy assets under one nav. Here, each is filterable. Marriott Residences retained as an asset but kept off the current-launch list until the public status is confirmed.

{filters.map(f => ( ))}
{items.map((p, i) => { // Vary spans for visual rhythm let span = "span-4"; if (filter !== "completed") { if (i % 7 === 0) span = "span-7"; else if (i % 7 === 1) span = "span-5"; else if (i % 5 === 0) span = "span-6"; } if (p.cat === "completed" && !p.img) { // text-only legacy card return (
{String(i+1).padStart(2,"0")} · Completed
{p.name}
{p.location}
Render not in pack
); } return go(`microsite:${p.slug}`)} />; })}
); } /* ---------------------------------------------------------------- Microsite view ---------------------------------------------------------------- */ function Microsite({ slug, go, onRegister, onBrochure, onViewing, showCoords }) { const p = projectBySlug(slug); const [activeSection, setActiveSection] = useState("story"); const [galleryIdx, setGalleryIdx] = useState(0); const trackRef = useRef(null); useEffect(() => { window.scrollTo({ top: 0, behavior: "auto" }); setGalleryIdx(0); }, [slug]); if (!p) { return (

Project not found

); } const isKeturah = p.cat === "keturah"; const gallery = (p.gallery && p.gallery.length ? p.gallery : [safeImg(p)]); const scrollGallery = (dir) => { setGalleryIdx(i => Math.max(0, Math.min(gallery.length - 1, i + dir))); }; return (
{/* HERO */}
/{" "} {" "}/ {p.name}

{p.name.includes("Ritz-Carlton") ? ( <>The Ritz-Carlton
Residences, Creekside. ) : p.name.startsWith("Keturah") ? ( <>{p.name.split(" ")[0]} {p.name.split(" ").slice(1).join(" ")} ) : ( <>{p.name} )}

{p.summary || p.tagline}

{p.rights && (

⚠ {p.rights}

)}
{(p.facts || []).slice(0, 4).map((f, i) => (
{f.k}
{f.v} {f.confirm && CONFIRM}
))}
{showCoords && (
{p.coord || "—"} · {p.location || "Dubai"}
)}
{/* SUBNAV */} {/* STORY */}
{`${p.name}
01 / Story

{isKeturah ? <>Bio Living,
practiced daily. : <>A neighborhood,
not a tower.}

{p.summary}

{(p.pillars || [ { n: "01", h: "Architecture led by light", b: "Floor plates and orientations tuned for daylight and cross-ventilation, not just plan efficiency." }, { n: "02", h: "Public realm first", b: "Landscape, water, and walking circuits programmed before the building footprint is fixed." }, { n: "03", h: "Resident-grade specification", b: "Material specifications tuned for the long stay — not the photoshoot." }, ]).map(pl => (
{pl.n}
{pl.h}
{pl.b}
))}
{/* LOCATION */}
02 / Location

Where it is.

{p.location}.{showCoords && {p.coord}}

{/* abstract roads */} {/* water */} CREEK
{p.name}
{LOC_CONTEXT.map((c, i) => (
{c.k} {c.v} {c.confirm && CONFIRM}
))}
{/* RESIDENCES / CONCEPTS */}
03 / Residences

Residence concepts.

Floor plans, sizes, and unit counts are intentionally not displayed here — they require client and RERA-confirmed source files. Concepts below describe the programme. PLANS NOT PUBLISHED

{(isKeturah ? [ { ix: "Type · 01", ttl: "Reserve residence", desc: "Bio-living apartment formats with private gardens and shaded outdoor rooms.", k: "Configuration", v: "Programme TBC" }, { ix: "Type · 02", ttl: "Townhouse", desc: "Stacked plot-based townhouses with a private courtyard and roof terrace per home.", k: "Configuration", v: "Programme TBC" }, { ix: "Type · 03", ttl: "Villa plot", desc: "Plot purchases with bio-living masterplan guidelines and architectural reviewers.", k: "Configuration", v: "Programme TBC" }, ] : [ { ix: "Type · 01", ttl: "Studio / 1 bed", desc: "Compact residence formats tuned for solo and couple residents.", k: "Configuration", v: "Plans on enquiry" }, { ix: "Type · 02", ttl: "2 bed", desc: "Family-scale floor plans with separated living and sleeping wings.", k: "Configuration", v: "Plans on enquiry" }, { ix: "Type · 03", ttl: "3 bed / penthouse", desc: "Upper-floor formats with extended balconies and city-facing exposures.", k: "Configuration", v: "Plans on enquiry" }, ]).map((u, i) => (
{u.ix}
{u.ttl}
{u.desc}
{u.k}
{u.v}CONFIRM
Pricing
On application
))}
{/* AMENITIES */}
04 / Amenities

{isKeturah ? <>Wellness, scripted in. : <>Amenities specified.}

Amenity programmes are listed from confirmed sources only. Specifics like spa operator, restaurant brand, and certification partners remain to be confirmed per project.

{KETURAH_AMENITIES.map((a, i) => (
{String(i+1).padStart(2,"0")}
{a.ttl}
{a.sub}
))}
{/* GALLERY */} {/* ENQUIRE CTA */}
06 / Enquire

Make {p.name}
the next address.

Register your interest, gate a brochure, or book a private viewing. Every form is project-scoped — leads route to the correct CRM segment with project + locale + source attached.

WhatsApp {I.whatsapp({style:{marginLeft:6}})}
); } /* ---------------------------------------------------------------- Modals ---------------------------------------------------------------- */ function Modal({ children, onClose }) { useEffect(() => { const onKey = (e) => e.key === "Escape" && onClose(); document.addEventListener("keydown", onKey); document.body.style.overflow = "hidden"; return () => { document.removeEventListener("keydown", onKey); document.body.style.overflow = ""; }; }, [onClose]); return (
e.stopPropagation()}> {children}
); } function useForm(initial) { const [v, setV] = useState(initial); const [errs, setErrs] = useState({}); const update = (k) => (e) => setV({ ...v, [k]: e.target.value }); return { v, setV, errs, setErrs, update }; } function RegisterInterestModal({ onClose, project }) { const { v, errs, setErrs, update } = useForm({ name: "", email: "", phone: "", project: project || "", market: "UAE", note: "" }); const [sent, setSent] = useState(false); const submit = (e) => { e.preventDefault(); const er = {}; if (!v.name.trim()) er.name = "Please share your name."; if (!v.email.match(/^\S+@\S+\.\S+$/)) er.email = "Enter a valid email."; if (!v.phone.trim()) er.phone = "Phone or WhatsApp helps us route faster."; setErrs(er); if (Object.keys(er).length) return; setSent(true); }; if (sent) { return (
{I.check()}

Registered. Thank you.

Our investor relations team will reach out within one business day. A confirmation has been sent to {v.email}.

CRM event: register_interest · project={v.project || "general"} · market={v.market}
); } return (
CRM · register_interest

Register interest

Get project briefs, payment-plan summaries, and a personal introduction to our investor relations desk.

{errs.name && {errs.name}}
{errs.email && {errs.email}}
{errs.phone && {errs.phone}}
{/* honeypot */}
); } function BrochureGateModal({ onClose, project }) { const p = projectBySlug(project) || PROJECTS[0]; const { v, errs, setErrs, update } = useForm({ name: "", email: "", phone: "" }); const [sent, setSent] = useState(false); const submit = (e) => { e.preventDefault(); const er = {}; if (!v.name.trim()) er.name = "Required."; if (!v.email.match(/^\S+@\S+\.\S+$/)) er.email = "Valid email required."; setErrs(er); if (Object.keys(er).length) return; setSent(true); }; if (sent) { return (
{I.check()}

Brochure on its way.

{p.name} brochure sent to {v.email}. Investor relations is copied.

CRM event: brochure_gate · project={p.slug}
); } return (
CRM · brochure_gate

Download the brochure

Gated PDFs are sent on request. Final brochure assets are still client-supplied.

{p.cat === "keturah" ? "Keturah" : p.cat === "current" ? "Current" : "Completed"}
{p.name}
{p.tagline || p.summary}
PDF — client-supplied CONFIRM
{errs.name && {errs.name}}
{errs.email && {errs.email}}
); } function PrivateViewingModal({ onClose }) { const { v, errs, setErrs, update } = useForm({ name: "", email: "", phone: "", project: "", date: "", time: "morning", channel: "in-person" }); const [sent, setSent] = useState(false); const submit = (e) => { e.preventDefault(); const er = {}; if (!v.name.trim()) er.name = "Required."; if (!v.email.match(/^\S+@\S+\.\S+$/)) er.email = "Valid email required."; if (!v.phone.trim()) er.phone = "Required for confirmation."; if (!v.date) er.date = "Pick a preferred date."; setErrs(er); if (Object.keys(er).length) return; setSent(true); }; if (sent) { return (
{I.check()}

Viewing requested.

A relationship manager will confirm {v.date} ({v.time}) via {v.channel === "in-person" ? "in-person" : v.channel} within one business day.

CRM event: private_viewing · {v.project || "general"}
); } return (
CRM · private_viewing

Book a private viewing

In-person at the sales gallery, on-site at the development, or virtual via private video call.

{errs.name && {errs.name}}
{errs.email && {errs.email}}
{errs.phone && {errs.phone}}
{errs.date && {errs.date}}
); } /* ---------------------------------------------------------------- Why MAG dedicated view + Brokers + Contact full pages ---------------------------------------------------------------- */ function WhyMagView({ go }) { return (
Why MAG

Forty-eight years
of group legacy.

MAG Group originated in 1978. The real-estate arm — MAG Lifestyle Development — is commonly described as established in 2003. Treat group legacy and the arm's founding as distinct. company-attributed

); } function BrokersView({ onRegister }) { return (
Brokers

For agents,
not against them.

MAG works with a registered broker network across the UAE and internationally. The official site exposes a brokers channel today; we propose deeper agent enablement: gated factsheets, co-branded materials, commission tracking, and event invites.

{[ { ttl: "Gated broker portal", d: "Factsheets, floor plates (where confirmed), and brochures behind a single login." }, { ttl: "Co-branded marketing", d: "Approved imagery, brand-safe co-branded templates, and right-of-use timelines." }, { ttl: "Commission tracking", d: "Lead deduplication, deal pipeline, and commission status visible to your agency." }, ].map((c, i) => (
{String(i+1).padStart(2,"0")}
{c.ttl}
{c.d}
))}
Broker enquiry
Apply for the broker channel
); } function ContactView({ onRegister, onViewing }) { return (
); } /* ---------------------------------------------------------------- Home view ---------------------------------------------------------------- */ function HomeView({ go, locale, onRegister, onBrochure, onViewing, heroVariant, showCoords }) { return ( <> ); } /* ---------------------------------------------------------------- WhatsApp FAB ---------------------------------------------------------------- */ function WhatsAppFab() { return ( {I.whatsapp()} WhatsApp ); } /* ---------------------------------------------------------------- App root ---------------------------------------------------------------- */ function App() { const [view, setView] = useState("home"); const [locale, setLocale] = useState("en"); const [modal, setModal] = useState(null); // { kind, project } const [tweaks, setTweak] = useTweaks(window.__MAG_TWEAK_DEFAULTS__); // Apply tweaks to / useEffect(() => { document.documentElement.setAttribute("data-palette", tweaks.palette || "biophilic"); document.documentElement.setAttribute("data-display", tweaks.displayFont || "cormorant"); document.documentElement.setAttribute("data-density", tweaks.density || "comfortable"); document.documentElement.setAttribute("data-rtl", LOCALES[locale].dir === "rtl" ? "1" : "0"); }, [tweaks, locale]); const go = useCallback((next) => { setView(next); window.scrollTo({ top: 0, behavior: "instant" }); }, []); const openModal = (kind, project) => setModal({ kind, project }); const closeModal = () => setModal(null); // Derive view payload let body = null; if (view === "home") { body = openModal("register")} onBrochure={(p) => openModal("brochure", p)} onViewing={() => openModal("viewing")} heroVariant={tweaks.heroVariant} showCoords={tweaks.showCoordinates} />; } else if (view.startsWith("projects:")) { const cat = view.split(":")[1]; body = ; } else if (view.startsWith("microsite:")) { const slug = view.split(":")[1]; body = openModal("register", slug)} onBrochure={() => openModal("brochure", slug)} onViewing={() => openModal("viewing", slug)} showCoords={tweaks.showCoordinates} />; } else if (view === "why-mag") { body = ; } else if (view === "brokers") { body = openModal("register")} />; } else if (view === "contact") { body = openModal("register")} onViewing={() => openModal("viewing")} />; } return ( <> openModal("register")} onBrochure={(p) => openModal("brochure", p)} />
{body}
{view !== "home" && view !== "contact" && ( <> // (Footer rendered in home etc. below — but we want it on every view) )}