/* ========================================================================= SHARED — Header, Footer, Lightbox, Icons, atoms Exposed via window.MV at the bottom so both pages can use them. ========================================================================= */ const { useState: useStateS, useEffect: useEffectS, useRef: useRefS } = React; /* ---------- HEADER (contextual) ---------- */ function Header({ variant = "famille" }) { const familleLinks = [ { href: "#comment", label: "Comment ça marche" }, { href: "#demo", label: "Démonstration" }, ]; const familleCTA = { href: "pro.html", label: "Espace Pro" }; const proLinks = [ { href: "#avantages", label: "Avantages pour l'agence" }, { href: "#espace-pro", label: "Votre Espace Pro" }, ]; const proCTA = { href: "index.html", label: "Espace Famille" }; const links = variant === "pro" ? proLinks : familleLinks; const cta = variant === "pro" ? proCTA : familleCTA; return (
Mémoire Vive
); } /* ---------- FOOTER (shared) ---------- */ function Footer() { return ( ); } /* ---------- ATOMS ---------- */ function SectionLabel({ n, children, numbering = "arabic" }) { const numStr = numbering === "roman" ? toRoman(n) : String(n).padStart(2, "0"); return (
Section {numStr} {children}
); } function toRoman(num) { const map = [[10,"X"],[9,"IX"],[5,"V"],[4,"IV"],[1,"I"]]; let s = ""; for (const [v, r] of map) { while (num >= v) { s += r; num -= v; } } return s; } function Ornament() { return (
); } function Stat({ label, value }) { return (
{value}
{label}
); } function PhoneFrame({ children }) { return (
{children}
); } function FigCaption({ children, show = true }) { if (!show) return null; return
{children}
; } /* ---------- LIGHTBOX ---------- */ function openLightbox(src, alt) { window.dispatchEvent(new CustomEvent("open-lightbox", { detail: { src, alt } })); } function Lightbox() { const [item, setItem] = useStateS(null); useEffectS(() => { const onOpen = (e) => setItem(e.detail); const onKey = (e) => { if (e.key === "Escape") setItem(null); }; window.addEventListener("open-lightbox", onOpen); window.addEventListener("keydown", onKey); return () => { window.removeEventListener("open-lightbox", onOpen); window.removeEventListener("keydown", onKey); }; }, []); useEffectS(() => { document.body.style.overflow = item ? "hidden" : ""; return () => { document.body.style.overflow = ""; }; }, [item]); if (!item) return null; return (
setItem(null)}>
e.stopPropagation()}> {item.alt {item.alt &&
{item.alt}
}
); } function Zoomable({ src, alt, children, className = "" }) { return ( ); } /* ---------- ICONS ---------- */ function ArrowRight() { return ( ); } function ArrowDown() { return ( ); } function ArrowUpRight() { return ( ); } function IconDownloadSmall() { return ( ); } function Check() { return ( ); } function IconWebsite() { return ( ); } function IconDownload() { return ( ); } function IconBook() { return ( ); } function IconShield() { return ( ); } function IconLock() { return ( ); } function IconClock() { return ( ); } /* Pro page icons */ function IconHeart() { return ( ); } function IconSparkle() { return ( ); } function IconPalette() { return ( ); } function IconConnect() { return ( ); } function IconQR() { return ( ); } function IconHands() { return ( ); } function IconSeed() { return ( ); } function IconMail() { return ( ); } function IconPhone() { return ( ); } /* ---------- BACK TO TOP ---------- */ function BackToTop() { const [visible, setVisible] = useStateS(false); useEffectS(() => { const onScroll = () => { setVisible(window.scrollY > 600); }; onScroll(); window.addEventListener("scroll", onScroll, { passive: true }); return () => window.removeEventListener("scroll", onScroll); }, []); const toTop = () => { window.scrollTo({ top: 0, behavior: "smooth" }); }; return ( ); } /* ---------- EXPOSE ---------- */ Object.assign(window, { MV_Header: Header, MV_Footer: Footer, MV_BackToTop: BackToTop, MV_SectionLabel: SectionLabel, MV_Ornament: Ornament, MV_Stat: Stat, MV_PhoneFrame: PhoneFrame, MV_FigCaption: FigCaption, MV_Lightbox: Lightbox, MV_Zoomable: Zoomable, MV_ArrowRight: ArrowRight, MV_ArrowDown: ArrowDown, MV_ArrowUpRight: ArrowUpRight, MV_IconDownloadSmall: IconDownloadSmall, MV_Check: Check, MV_IconWebsite: IconWebsite, MV_IconDownload: IconDownload, MV_IconBook: IconBook, MV_IconShield: IconShield, MV_IconLock: IconLock, MV_IconClock: IconClock, MV_IconHeart: IconHeart, MV_IconSparkle: IconSparkle, MV_IconPalette: IconPalette, MV_IconConnect: IconConnect, MV_IconQR: IconQR, MV_IconHands: IconHands, MV_IconSeed: IconSeed, MV_IconMail: IconMail, MV_IconPhone: IconPhone, });