// ============================================================
// 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 =