/* global React */ const { useState, useEffect, useRef } = React; /* ============================================================ KODIA wordmark — uses the real brand logo ============================================================ */ function KodiaMark({ variant = "blue", height = 22 }) { // variant: "blue" (default light bg) | "white" (dark bg) | "submark" (k only) const R = (typeof window !== "undefined" && window.__resources) || {}; const src = variant === "white" ? (R.logoWhite || "assets/logo-kodia-white.png") : variant === "submark" ? (R.submarkBlue || "assets/submark-k-blue.png") : (R.logoBlue || "assets/logo-kodia-blue.png"); return ; } function KodiaSubmark({ variant = "white", size = 22 }) { const R = (typeof window !== "undefined" && window.__resources) || {}; const src = variant === "white" ? (R.submarkWhite || "assets/submark-k-white.png") : (R.submarkBlue || "assets/submark-k-blue.png"); return ; } /* ============================================================ Top nav ============================================================ */ function SiteNav({ active }) { const links = [ { id: "approach", label: "Approach", href: "approach.html" }, { id: "case", label: "Case studies", href: "case-clearpay.html" }, { id: "about", label: "About", href: "about.html" }, { id: "contact", label: "Contact", href: "contact.html" }]; const isCosmos = typeof document !== "undefined" && document.documentElement.getAttribute("data-theme") === "cosmos"; return ( {links.map((l) => {l.label} )} Book a call ); } /* ============================================================ Footer ============================================================ */ function SiteFooter() { return ( ); } /* ============================================================ Page chrome shell — handles tweaks + density + theme ============================================================ */ function PageShell({ active, children, exposeHeroVariant = false }) { // Read defaults from the per-page EDITMODE block on window.PAGE_TWEAK_DEFAULTS const defaults = window.PAGE_TWEAK_DEFAULTS || { theme: "paper", density: "regular", heroVariant: "diagram" }; // Tweaks panel wiring — leverages window.TweaksPanel etc from tweaks-panel.jsx const [tweaks, setTweak] = window.useTweaks(defaults); // Apply theme + density to useEffect(() => { document.documentElement.setAttribute("data-theme", tweaks.theme); document.documentElement.setAttribute("data-density", tweaks.density); // Persist in localStorage too so cross-page nav keeps them try { localStorage.setItem("kodia.theme", tweaks.theme); localStorage.setItem("kodia.density", tweaks.density); if (exposeHeroVariant) localStorage.setItem("kodia.heroVariant", tweaks.heroVariant); } catch (e) {} // Broadcast hero variant change to listeners on this page window.dispatchEvent(new CustomEvent("kodia:tweaks", { detail: tweaks })); }, [tweaks.theme, tweaks.density, tweaks.heroVariant]); const { TweaksPanel, TweakSection, TweakRadio, TweakColor } = window; // Map theme name → KODIA palette swatches const THEME_PALETTES = [ { name: "light", palette: ["#FFFFFF", "#122A94", "#90AFFC", "#1B1B1D"] }, { name: "cosmos", palette: ["#04081F", "#90AFFC", "#56389E", "#FFFFFF"] }, { name: "content", palette: ["#FFFFFF", "#1F8EA3", "#90AFFC", "#1B1B1D"] }, { name: "care", palette: ["#FFFFFF", "#90AFFC", "#122A94", "#1B1B1D"] }, { name: "next", palette: ["#FFFFFF", "#56389E", "#90AFFC", "#1B1B1D"] }]; const currentPalette = THEME_PALETTES.find((p) => p.name === tweaks.theme)?.palette || THEME_PALETTES[0].palette; const onPaletteChange = (newPal) => { const match = THEME_PALETTES.find((p) => p.palette[0] === newPal[0] && p.palette[1] === newPal[1]); if (match) setTweak("theme", match.name); }; return ( <> {children} p.palette)} /> setTweak("density", v)} options={["compact", "regular", "spacious"]} /> {exposeHeroVariant && setTweak("heroVariant", v)} options={["diagram", "manifesto", "split"]} /> } >); } /* ============================================================ Persist theme/density across page nav (read on load before render) ============================================================ */ (function applyPersistedDefaults() { try { const defs = window.PAGE_TWEAK_DEFAULTS || {}; const t = localStorage.getItem("kodia.theme"); const d = localStorage.getItem("kodia.density"); if (t) { document.documentElement.setAttribute("data-theme", t); defs.theme = t; } else if (defs.theme) { document.documentElement.setAttribute("data-theme", defs.theme); } if (d) { document.documentElement.setAttribute("data-density", d); defs.density = d; } else if (defs.density) { document.documentElement.setAttribute("data-density", defs.density); } const hv = localStorage.getItem("kodia.heroVariant"); if (hv) defs.heroVariant = hv; } catch (e) {} })(); Object.assign(window, { KodiaMark, KodiaSubmark, SiteNav, SiteFooter, PageShell });