// Soul MVNT — shared components
const { useState, useEffect, useRef } = React;
// ---------- Logo ----------
function Logo({ size = 20 }) {
return (
{ e.preventDefault(); window.__nav && window.__nav("home"); }}>
SOUL
MVNT
);
}
// ---------- Nav ----------
function Nav({ route, onNav, cartCount, onOpenCart }) {
const links = [
["home", "Home"],
["classes", "Classes"],
["schedule", "Schedule"],
["pricing", "Starter Pack"],
["trainers", "Trainers"],
["studio", "The Studio"],
["shop", "Shop"],
["faq", "FAQ"],
];
return (
);
}
// ---------- Trust marquee ----------
function TrustStrip() {
const items = [
"IDA Design Awards 2025 — Bronze",
"Dubai Design District",
"Lagree on the Mega Pro",
"Founder-led & community-driven",
"Six official class formats",
"AHI award-winning interior",
];
const renderRow = (k) => (
{items.map((t, i) => (
{t}
))}
);
return (
{renderRow(0)}{renderRow(1)}
);
}
// ---------- Eyebrow ----------
function Eyebrow({ children }) {
return {children}
;
}
// ---------- Section header ----------
function SectionHead({ eyebrow, title, lede, action }) {
return (
{eyebrow && {eyebrow}}
{lede &&
{lede}
}
{action}
);
}
// ---------- Format card ----------
function FormatCard({ format, onClick, feature }) {
return (
{format.icon ? (

) : (
)}
{format.intensity}
{format.duration}
{format.name}
"{format.tag}"
{format.desc}
Book / Learn more →
);
}
// SVG glyph for Sound Healing placeholder (concentric rings)
function SoundHealingGlyph() {
return (
);
}
// ---------- Class detail modal ----------
function FormatModal({ format, onClose, onBook }) {
useEffect(() => {
const onEsc = (e) => e.key === "Escape" && onClose();
document.addEventListener("keydown", onEsc);
document.body.style.overflow = "hidden";
return () => {
document.removeEventListener("keydown", onEsc);
document.body.style.overflow = "";
};
}, []);
return (
e.stopPropagation()}>
Class Format
{format.name}
"{format.tag}"
{format.desc}
Intensity
{format.intensity}
Duration
{format.duration}
First-timer note — {format.firstTimer}
{format.placeholder && (
Copy with client to confirm
)}
Booking + memberships managed in the Soul MVNT app · iOS & Google Play
);
}
// ---------- Booking confirmation ----------
function BookConfirmModal({ slot, onClose }) {
useEffect(() => {
const onEsc = (e) => e.key === "Escape" && onClose();
document.addEventListener("keydown", onEsc);
document.body.style.overflow = "hidden";
return () => { document.removeEventListener("keydown", onEsc); document.body.style.overflow = ""; };
}, []);
return (
e.stopPropagation()}>
✓
Spot reserved (preview)
{slot.format}
{slot.day} · {slot.time} · {slot.trainer}
In the live experience, this opens the Soul MVNT app to confirm and pay from your active pack or membership.
);
}
// ---------- Cart drawer (simple modal) ----------
function CartModal({ items, onClose, onChange }) {
useEffect(() => {
document.body.style.overflow = "hidden";
return () => { document.body.style.overflow = ""; };
}, []);
const subtotal = items.reduce((s, i) => s + i.price * i.qty, 0);
return (
e.stopPropagation()}>
Your bag
Soul MVNT shop
{items.length === 0 && (
Your bag is empty. Browse the activewear collection to add pieces.
)}
{items.map((it) => (
{it.name}
{it.type}
{it.qty}
AED {it.price * it.qty}
))}
{items.length > 0 && (
<>
Subtotal
AED {subtotal}
Shipping and taxes calculated at Shopify checkout.
>
)}
);
}
// ---------- Trainer card ----------
function TrainerCard({ trainer }) {
return (
{trainer.photo ? (

) : (
{trainer.name[0]}
)}
{trainer.name}
{trainer.specialty}
);
}
// ---------- Footer ----------
function Footer({ onNav }) {
return (
);
}
// ---------- Whatsapp FAB ----------
function WhatsAppFab() {
return (
);
}
// ---------- Animated wave decoration ----------
function WaveDecor({ style }) {
return (
);
}
Object.assign(window, {
Logo, Nav, TrustStrip, Eyebrow, SectionHead, FormatCard, FormatModal, BookConfirmModal,
CartModal, TrainerCard, Footer, WhatsAppFab, WaveDecor, SoundHealingGlyph,
});