/* =========================
APP — main router + cart + tweaks
========================= */
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"palette": "ivory",
"accent": "bloom",
"occasionLayout": "grid",
"showAnnouncement": true
}/*EDITMODE-END*/;
const PALETTES = {
ivory: {
label: "Ivory",
"--ivory": "#FBF6F0",
"--paper": "#F7EFE7",
"--blush": "#F3E3DD",
"--ink": "#2A2320",
"--line": "#EBDDD2",
},
blush: {
label: "Blush",
"--ivory": "#F7E9E3",
"--paper": "#EFD9D0",
"--blush": "#E4C5BB",
"--ink": "#2A2320",
"--line": "#DCC0B5",
},
noir: {
label: "Noir",
"--ivory": "#1B1714",
"--paper": "#23201B",
"--blush": "#2D2924",
"--ink": "#FBF6F0",
"--ink-soft": "#D8C7B9",
"--line": "#3A332D",
"--line-strong": "#4A413A",
"--muted": "#A89A8A",
},
};
const ACCENTS = {
bloom: { label: "Bloom", color: "#B4566B", deep: "#93465A" },
rose: { label: "Rose", color: "#C98B8B", deep: "#A66E6E" },
leaf: { label: "Leaf", color: "#7E8C6A", deep: "#5F6B4D" },
ink: { label: "Ink", color: "#2A2320", deep: "#000000" },
};
function App() {
const [tweaks, setTweaks] = useTweaks(TWEAK_DEFAULTS);
const [route, setRoute] = useState({ name: "home", params: {} });
const [cart, setCart] = useState([]);
const [cartOpen, setCartOpen] = useState(false);
const [toast, setToast] = useState({ show: false, msg: "" });
const [lang, setLang] = useState("EN");
// Apply palette CSS vars to the root
useEffect(() => {
const root = document.documentElement.style;
const p = PALETTES[tweaks.palette] || PALETTES.ivory;
Object.entries(p).forEach(([k, v]) => {
if (k.startsWith("--")) root.setProperty(k, v);
});
// Accent
const a = ACCENTS[tweaks.accent] || ACCENTS.bloom;
root.setProperty("--bloom", a.color);
root.setProperty("--bloom-deep", a.deep);
root.setProperty("--focus", a.color);
}, [tweaks.palette, tweaks.accent]);
// RTL when AR
const dir = lang === "AR" ? "rtl" : "ltr";
useEffect(() => {
document.documentElement.setAttribute("dir", dir);
document.documentElement.setAttribute("lang", lang.toLowerCase());
}, [dir, lang]);
// Dismiss splash
useEffect(() => {
const t = setTimeout(() => {
const s = document.getElementById("splash");
if (s) {
s.style.opacity = "0";
setTimeout(() => s.remove(), 500);
}
}, 250);
return () => clearTimeout(t);
}, []);
const go = useCallback((name, params = {}) => {
setRoute({ name, params });
window.scrollTo({ top: 0, behavior: "instant" });
}, []);
const addToBag = useCallback((p, qty = 1) => {
setCart((c) => {
const existing = c.find((i) => i.id === p.id);
if (existing) {
return c.map((i) => (i.id === p.id ? { ...i, qty: i.qty + qty } : i));
}
return [
...c,
{
id: p.id,
name: p.name,
sub: p.sub,
price: p.price,
image: p.image,
qty,
},
];
});
setToast({ show: true, msg: `${p.name} added to bag` });
setTimeout(() => setToast({ show: false, msg: "" }), 2200);
}, []);
const cartCount = cart.reduce((s, i) => s + i.qty, 0);
let page;
if (route.name === "home") page =