diff --git a/app.jsx b/app.jsx new file mode 100644 index 0000000..0ba85d4 --- /dev/null +++ b/app.jsx @@ -0,0 +1,135 @@ +const TWEAKS_DEFAULTS = /*EDITMODE-BEGIN*/{ + "accentPreset": "blue", + "accent": "#3b82f6", + "accentLight": "#60a5fa", + "primary": "#0a0a0a", + "headingFont": "Inter", + "monoFont": "JetBrains Mono", + "imageTreatment": "default", + "density": "comfortable", + "marquee": true, + "cursorGlow": true, + "showPartners": true, + "showStats": true, + "showServices": true, + "showTech": true, + "showOnSet": true, + "ctaLabel": "View Projects" +}/*EDITMODE-END*/; + +const FONT_OPTIONS = ["Inter","Manrope","Space Grotesk","DM Sans","Outfit","Plus Jakarta Sans","IBM Plex Sans","Geist","Fraunces"]; +const MONO_OPTIONS = ["JetBrains Mono","IBM Plex Mono","Space Mono","Roboto Mono","Fira Code","Geist Mono"]; + +const ACCENT_PRESETS = { + blue: { accent:"#3b82f6", accentLight:"#60a5fa", label:"Blue" }, + ember: { accent:"#e25822", accentLight:"#f3895a", label:"Ember" }, + amber: { accent:"#f59e0b", accentLight:"#fbbf24", label:"Amber" }, + ruby: { accent:"#dc2626", accentLight:"#f87171", label:"Ruby" }, + mono: { accent:"#e5e5e5", accentLight:"#ffffff", label:"Mono" }, +}; + +function loadFont(family) { + const id = "wd-font-" + family.replace(/\s/g,"-"); + if (document.getElementById(id)) return; + const l = document.createElement("link"); + l.id = id; l.rel = "stylesheet"; + l.href = `https://fonts.googleapis.com/css2?family=${family.replace(/\s/g,"+")}:wght@300;400;500;600;700&display=swap`; + document.head.appendChild(l); +} + +function App() { + const [tweaks, setTweak] = useTweaks(TWEAKS_DEFAULTS); + const [openSlug, setOpenSlug] = React.useState(() => { + const m = location.hash.match(/#\/projects\/([\w-]+)/); + return m ? m[1] : null; + }); + + React.useEffect(() => { + if (openSlug) location.hash = `#/projects/${openSlug}`; + else if (location.hash.startsWith("#/projects/")) location.hash = ""; + }, [openSlug]); + + React.useEffect(() => { + loadFont(tweaks.headingFont); + loadFont(tweaks.monoFont); + const r = document.documentElement.style; + r.setProperty("--color-accent", tweaks.accent); + r.setProperty("--color-accent-light", tweaks.accentLight); + r.setProperty("--color-primary", tweaks.primary); + r.setProperty("--font-inter", `"${tweaks.headingFont}"`); + r.setProperty("--font-mono-stack", `"${tweaks.monoFont}"`); + }, [tweaks]); + + // Image treatment via class on body + React.useEffect(() => { + document.body.dataset.imgTreat = tweaks.imageTreatment; + document.body.dataset.density = tweaks.density; + }, [tweaks.imageTreatment, tweaks.density]); + + const onAccentPreset = (key) => { + const p = ACCENT_PRESETS[key]; + if (!p) return; + setTweak({ accentPreset: key, accent: p.accent, accentLight: p.accentLight }); + }; + + return ( + + + {tweaks.cursorGlow && } + + + + {tweaks.showPartners && } + + {tweaks.showStats && } + {tweaks.showServices && } + + {tweaks.showTech && } + {tweaks.showOnSet && } + +