// ============================================================
// app.jsx — Root component, router, tweaks integration
// ============================================================
const { useState, useEffect } = React;
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"palette": "ivory-navy",
"displayFont": "Cormorant Garamond",
"goldIntensity": "subtle",
"locale": "en",
"showFlags": true
}/*EDITMODE-END*/;
const PALETTES = {
"ivory-navy": {
"--cream": "#FAF7F1",
"--royal": "#1B2A4A",
"--royal-deep": "#131e36",
"--gold": "#B8975A"
},
"porcelain-navy": {
"--cream": "#FFFFFF",
"--royal": "#162447",
"--royal-deep": "#0f1a35",
"--gold": "#B8975A"
},
"warm-bordeaux": {
"--cream": "#F8F1E7",
"--royal": "#3B1F2B",
"--royal-deep": "#2A1620",
"--gold": "#C4A572"
},
"noir": {
"--cream": "#F2EDE3",
"--royal": "#1A1A1A",
"--royal-deep": "#0E0E0E",
"--gold": "#C8A864"
}
};
const GOLD_LEVELS = {
"muted": "#A88B54",
"subtle": "#B8975A",
"richer": "#C9A363"
};
function App() {
const [route, setRoute] = useState({ page: "home", params: {} });
const [tweaks, setTweaks] = useState(TWEAK_DEFAULTS);
// Apply tweaks to CSS variables
useEffect(() => {
const root = document.documentElement;
const palette = PALETTES[tweaks.palette] || PALETTES["ivory-navy"];
Object.entries(palette).forEach(([k, v]) => root.style.setProperty(k, v));
// gold intensity override
if (GOLD_LEVELS[tweaks.goldIntensity]) {
root.style.setProperty("--gold", GOLD_LEVELS[tweaks.goldIntensity]);
}
// display font
const fontMap = {
"Cormorant Garamond": '"Cormorant Garamond", Garamond, serif',
"Fraunces": '"Fraunces", Georgia, serif',
"Playfair Display": '"Playfair Display", Georgia, serif',
"EB Garamond": '"EB Garamond", Garamond, serif'
};
if (fontMap[tweaks.displayFont]) {
root.style.setProperty("--font-display", fontMap[tweaks.displayFont]);
}
// RTL
document.body.dir = tweaks.locale === "ar" ? "rtl" : "ltr";
document.body.classList.toggle("rtl", tweaks.locale === "ar");
}, [tweaks]);
// Persist tweak changes to host
function setTweak(key, value) {
let next;
if (typeof key === "object") {
next = { ...tweaks, ...key };
} else {
next = { ...tweaks, [key]: value };
}
setTweaks(next);
try {
window.parent.postMessage({ type: "__edit_mode_set_keys", edits: typeof key === "object" ? key : { [key]: value } }, "*");
} catch (e) {}
}
function go(page, params = {}) {
setRoute({ page, params });
window.scrollTo({ top: 0, behavior: "instant" });
}
// Sync locale tweak with nav locale switcher
function setLocale(loc) {
setTweak("locale", loc);
}
// Build current page
let pageEl;
switch (route.page) {
case "home": pageEl = ; break;
case "treatments": pageEl = ; break;
case "treatment": pageEl = ; break;
case "dentists": pageEl = ; break;
case "dentist": pageEl = ; break;
case "about": pageEl = ; break;
case "contact": pageEl = ; break;
case "book": pageEl = ; break;
case "gallery": pageEl = ; break;
case "tourism": pageEl = ; break;
default: pageEl = ;
}
return (
{pageEl}
);
}
// ============================================================
// Tweaks panel
// ============================================================
function Tweaks({ tweaks, setTweak }) {
return (
setTweak("palette", v)}
options={[
{ value: "ivory-navy", label: "Ivory + Versailles navy (default)" },
{ value: "porcelain-navy", label: "Porcelain + deep navy" },
{ value: "warm-bordeaux", label: "Warm bordeaux + ochre" },
{ value: "noir", label: "Noir + champagne" }
]}
/>
setTweak("displayFont", v)}
options={[
{ value: "Cormorant Garamond", label: "Cormorant Garamond (default)" },
{ value: "Fraunces", label: "Fraunces" },
{ value: "Playfair Display", label: "Playfair Display" },
{ value: "EB Garamond", label: "EB Garamond" }
]}
/>
setTweak("goldIntensity", v)}
options={[
{ value: "muted", label: "Muted" },
{ value: "subtle", label: "Subtle" },
{ value: "richer", label: "Richer" }
]}
/>
setTweak("locale", v)}
options={[
{ value: "en", label: "EN (LTR)" },
{ value: "ar", label: "AR (RTL)" }
]}
/>
);
}
// Mount
ReactDOM.createRoot(document.getElementById("root")).render();