// ============================================================ // MONOGRAM — App root, routing, tweaks // ============================================================ const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "hero": "plate", "paper": false, "gold": "default", "typePair": "cormorant-inter", "density": "comfortable", "rtl": false }/*EDITMODE-END*/; function App() { const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS); const [route, setRoute] = useState({ name: "home" }); const [locale, _setLocale] = useState("en"); // Sync paper / gold / typePair / density / rtl to dataset useEffect(() => { const html = document.documentElement; html.dataset.paper = String(!!tweaks.paper); html.dataset.gold = tweaks.gold; html.dataset.typePair = tweaks.typePair; html.dataset.density = tweaks.density; }, [tweaks.paper, tweaks.gold, tweaks.typePair, tweaks.density]); // Sync locale → const setLocale = (next) => { _setLocale(next); const html = document.documentElement; html.lang = next; html.dir = next === "ar" ? "rtl" : "ltr"; html.dataset.locale = next; }; // RTL tweak toggle mirrors locale switcher (preview only — does not translate copy) useEffect(() => { if (tweaks.rtl && locale !== "ar") setLocale("ar"); if (!tweaks.rtl && locale === "ar") setLocale("en"); // eslint-disable-next-line }, [tweaks.rtl]); // Scroll-reveal observer (re-attaches per route) useReveal(); // Route → fresh observer pickup useEffect(() => { const t = setTimeout(() => { document.querySelectorAll(".reveal").forEach((el) => el.classList.add("in")); // and reset, so IntersectionObserver can re-trigger: document.querySelectorAll(".reveal").forEach((el) => { const rect = el.getBoundingClientRect(); if (rect.top > window.innerHeight) el.classList.remove("in"); }); }, 80); return () => clearTimeout(t); }, [route.name, route.id]); let screen; if (route.name === "collection") { screen = ; } else if (route.name === "bespoke") { screen = ; } else { screen = ; } return (
); } const root = ReactDOM.createRoot(document.getElementById("root")); root.render();