/* Royal Yachts — main app */ const { useState: useS, useEffect: useE, useRef: useR } = React; const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "palette": "editorial", "density": "comfortable", "displayItalic": true, "showFavBar": true, "displayFont": "cormorant" }/*EDITMODE-END*/; const PALETTES = { editorial: { /* warm paper editorial — DEFAULT */ "--paper": "#F8F6F1", "--mist": "#ECE7DD", "--ink": "#10202E", "--marine":"#123A5A", "--noir": "#07121C", "--foam": "#FAFAF7", "--brass": "#B89263", "--brass-deep": "#8E6B3F" }, marine: { /* cool marine — paper white + deep navy */ "--paper": "#F2F4F6", "--mist": "#E3E9EE", "--ink": "#0E2032", "--marine":"#143C5C", "--noir": "#05111C", "--foam": "#F8FAFB", "--brass": "#9CB1C4", "--brass-deep": "#5A748A" }, midnight: { /* full dark editorial */ "--paper": "#0A1620", "--mist": "#0F1F2C", "--ink": "#E8EEF2", "--marine":"#7BA3C9", "--noir": "#040A12", "--foam": "#0D1A24", "--brass": "#D3AC74", "--brass-deep": "#B89263" } }; const DISPLAY_FONTS = { cormorant: '"Cormorant Garamond", "EB Garamond", Georgia, serif', playfair: '"Playfair Display", "EB Garamond", Georgia, serif', ebgaramond:'"EB Garamond", Georgia, serif' }; function applyTweaks(t) { const r = document.documentElement; const p = PALETTES[t.palette] || PALETTES.editorial; Object.entries(p).forEach(([k, v]) => r.style.setProperty(k, v)); // Recompute line/muted from ink so they stay readable if (t.palette === "midnight") { r.style.setProperty("--line", "rgba(232,238,242,0.14)"); r.style.setProperty("--line-strong", "rgba(232,238,242,0.34)"); r.style.setProperty("--muted", "rgba(232,238,242,0.62)"); } else { r.style.setProperty("--line", "rgba(16,32,46,0.14)"); r.style.setProperty("--line-strong", "rgba(16,32,46,0.32)"); r.style.setProperty("--muted", "rgba(16,32,46,0.62)"); } r.style.setProperty("--font-display", DISPLAY_FONTS[t.displayFont] || DISPLAY_FONTS.cormorant); r.style.setProperty("--section-pad", t.density === "tight" ? "72px" : t.density === "lavish" ? "128px" : "96px"); } /* ---------- Toast ---------- */ function Toast({ msg, show }) { return (
{msg}
); } /* ---------- Main App ---------- */ function App() { const [tweaks, setTweaks] = useTweaks(TWEAK_DEFAULTS); const [lang, setLang] = useS("en"); const [favs, setFavs] = useS(() => { try { return JSON.parse(localStorage.getItem("ry_favs") || "[]"); } catch { return []; } }); const [enquire, setEnquire] = useS({ open: false, payload: null }); const [drawer, setDrawer] = useS({ open: false, yacht: null }); const [toast, setToast] = useS({ show: false, msg: "" }); const t = I18N[lang]; useE(() => { applyTweaks(tweaks); }, [tweaks]); useE(() => { document.body.setAttribute("dir", t.dir); }, [lang]); useE(() => { localStorage.setItem("ry_favs", JSON.stringify(favs)); }, [favs]); const toggleFav = (id) => { setFavs((f) => { const has = f.includes(id); if (has) { setToast({ show: true, msg: "Removed from shortlist" }); } else { setToast({ show: true, msg: "Added to shortlist · check the bottom-left" }); } setTimeout(() => setToast((tt) => ({ ...tt, show: false })), 2400); return has ? f.filter((x) => x !== id) : [...f, id]; }); }; const openEnquire = (payload = {}) => setEnquire({ open: true, payload }); const closeEnquire = () => setEnquire({ open: false, payload: null }); const openYacht = (yacht) => { setDrawer({ open: true, yacht }); document.body.style.overflow = "hidden"; }; const closeYacht = () => { setDrawer({ open: false, yacht: drawer.yacht }); document.body.style.overflow = ""; }; return (