// App — composes the page. Includes the sticky nav, the success modal that // appears when the user submits the hero prompt, and the Tweaks panel. const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "accent": ["#ff6b47", "#ffae9a", "#9c3a1f"], "heroVariant": "owner", "showStopMarker": true, "showLivePill": false }/*EDITMODE-END*/; const ACCENT_PRESETS = { coral: ["#ff6b47", "#ffae9a", "#9c3a1f"], // warm coral (default) amber: ["#ffb347", "#ffd9a3", "#9c6e1f"], // soft amber lime: ["#9ee649", "#d2f3a6", "#3f7a1c"], // electric lime violet: ["#b07cff", "#dabfff", "#5a2fa3"], // violet }; function applyAccent(arr) { // arr[0] is the hero color we map to var(--accent); compute soft + glow + fg. const hero = arr[0]; const soft = `${hero}24`; // 14% alpha const glow = `${hero}59`; // 35% alpha const root = document.documentElement; root.style.setProperty("--accent", hero); root.style.setProperty("--accent-soft", soft); root.style.setProperty("--accent-glow", glow); // Foreground on accent: derive a dark-on-accent for primary buttons. root.style.setProperty("--accent-fg", "#1a0f0a"); } function App() { const [t, setTweak] = useTweaks(TWEAK_DEFAULTS); const [scrolled, setScrolled] = React.useState(false); const [showLaunch, setShowLaunch] = React.useState(null); React.useEffect(() => { applyAccent(t.accent); }, [t.accent]); React.useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 8); onScroll(); window.addEventListener("scroll", onScroll, { passive: true }); return () => window.removeEventListener("scroll", onScroll); }, []); const handleStart = (prompt) => { setShowLaunch(prompt || "Build me a tool for my business."); }; return ( <> {showLaunch !== null && ( setShowLaunch(null)} /> )} setTweak("accent", v)} /> setTweak("heroVariant", v)} /> setTweak("showLivePill", v)} /> setTweak("showStopMarker", v)} /> {/* Tweak-driven CSS overrides */} > ); } function Nav({ scrolled }) { return ( How it works Templates Pricing Stories Sign in Request invite ); } // Modal that fires when the user submits the hero prompt. Reassures them their // vibe will be honored — playfully sells the rest of the flow. function LaunchModal({ prompt, onClose }) { React.useEffect(() => { const onKey = (e) => { if (e.key === "Escape") onClose(); }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, [onClose]); const [step, setStep] = React.useState(0); React.useEffect(() => { if (step >= 4) return undefined; const t = setTimeout(() => setStep(step + 1), 700); return () => clearTimeout(t); }, [step]); return ( e.stopPropagation()}> ✕ Vibn is on it Keep vibing — we've got the rest. "{prompt}" {["Drafting the screens", "Setting up logins", "Saving your stuff", "Putting it online"].map((s, i) => ( {i < step ? ( ) : i === step ? ( ) : ( )} {s} ))} No homework · No setup · No new tools to learn ); } ReactDOM.createRoot(document.getElementById("root")).render();