// Facette — shared UI atoms const { BRANCHES, WHATSAPP, BRAND_PARTNERS } = window.FacetteData; // ────────────────────────────────────────────────────────── // Logo // ────────────────────────────────────────────────────────── function FFMark({ size = 28, color = 'var(--gold)' }) { // Reproduces the FACETTE mark: two mirrored Fs sharing a top bar. return ( ); } function FacetteLogo({ size = 'md', wordmarkOnly = false, vertical = false }) { const compact = size === 'sm'; if (vertical) { return (
Facette
); } return (
{!wordmarkOnly && }
Facette
); } // ────────────────────────────────────────────────────────── // Nav / header // ────────────────────────────────────────────────────────── function Header({ page, setPage, branch, setBranch, openBook, isMobile }) { return (
{!isMobile && } {isMobile && ( )}
); } function Pageset({ items, active, onChange }) { return ( ); } function BranchToggle({ branch, setBranch }) { return (
{Object.values(BRANCHES).map((b) => ( ))}
); } // ────────────────────────────────────────────────────────── // Trust strip — sits below nav // ────────────────────────────────────────────────────────── function TrustStrip({ branch }) { const b = BRANCHES[branch]; return (
4.9
Fresha · 794 reviews
2019
Dubai’s first facial bar
2 branches
Jumeirah · Business Bay
{b.short}
{b.hours}
); } // ────────────────────────────────────────────────────────── // Brand row // ────────────────────────────────────────────────────────── function BrandRow() { return (
The premium brands
behind every protocol
{BRAND_PARTNERS.map((p, i) => (
{p.name} {p.sub}
))}
); } // ────────────────────────────────────────────────────────── // Footer // ────────────────────────────────────────────────────────── function Footer({ setPage, branch, setBranch }) { const b = BRANCHES[branch]; return ( ); } function SocialIcon({ kind, href }) { const inner = { ig: , tt: , wa: , }[kind]; const C = href ? 'a' : 'div'; const props = href ? { href, target: '_blank', rel: 'noopener' } : {}; return ( {inner} ); } // ────────────────────────────────────────────────────────── // Flyout (WhatsApp + sticky book on desktop) // ────────────────────────────────────────────────────────── function Flyout({ openBook, showSticky, stickyTreatment }) { return (
Ready when you are
{stickyTreatment || 'Book your facial'}
); } // ────────────────────────────────────────────────────────── // Mobile bottom bar (inside iPhone frame) // ────────────────────────────────────────────────────────── function MobileBottomBar({ branch, openBook }) { const b = BRANCHES[branch]; return (
Booking at
{b.short}
); } // ────────────────────────────────────────────────────────── // Striped image with optional real img // ────────────────────────────────────────────────────────── function Img({ src, alt, label, style, className }) { if (src) { return {alt; } return (
{label || 'Photo TBC'}
); } // ────────────────────────────────────────────────────────── // Section head // ────────────────────────────────────────────────────────── function SectionHead({ eyebrow, title, lede, action, center }) { return (
{eyebrow &&
{eyebrow}
}

{(lede || action) && (
{lede &&
{lede}
} {action}
)}

); } // ────────────────────────────────────────────────────────── // Price formatter // ────────────────────────────────────────────────────────── function formatPrice(item) { if (item.tbc) { return Price on request; } const value = item.price ?? item.priceFrom; const showFrom = item.priceFrom != null; return (
{showFrom && From} {' '}{value.toLocaleString()}AED
); } // Export everything Object.assign(window, { FFMark, FacetteLogo, Header, BranchToggle, TrustStrip, BrandRow, Footer, Flyout, MobileBottomBar, Img, SectionHead, formatPrice, });