/* Mega menu data */ const MEGA_MENUS = { projects: { cols: 1, items: [ { label: "FiveM Scripts", sub: "01", desc: "Server-side systems and tools. The first complete project.", href: "fivem.html" }, { label: "Untitled Tool", sub: "02", desc: "A small utility quietly in development.", href: "#", soon: true }, { label: "Notebook", sub: "03", desc: "Notes, experiments, and writing. Public when ready.", href: "#", soon: true }, ], }, fivem: { cols: 2, left: [ { label: "Overview", desc: "What FiveM scripts we ship and why." }, { label: "Faction", desc: "Group structures, ranks, shared tooling." }, { label: "Sidejobs", desc: "Small, repeatable work for downtime." }, { label: "Robbery", desc: "Heist and stickup systems with real friction." }, ], right: [ { label: "Core", desc: "Foundations the rest of the suite leans on." }, { label: "Jobs", desc: "Whitelisted work — the structured side." }, { label: "Custom work", desc: "Need something specific? Write to us." }, ], footer: { label: "Browse all 18 scripts →", href: "fivem.html" }, }, manifesto: { cols: 1, items: [ { label: "Why after hours?", sub: "i", desc: "Ideas breathe best without a roadmap." }, { label: "How we build", sub: "ii", desc: "One complete thought at a time, shipped when ready." }, { label: "Who it's for", sub: "iii", desc: "Server owners who'd rather read docs than guess." }, ], }, contact: { cols: 1, items: [ { label: "Discord", sub: "↗", desc: "Fastest way to reach us — community + support.", href: "https://discord.gg/afterhoursofficial" }, { label: "Email", sub: "↗", desc: "For custom work and longer conversations.", href: "#" }, { label: "Custom work", sub: "→", desc: "After-hours builds happen after-hours — write us.", href: "#" }, ], }, }; /* Single mega dropdown panel */ const MegaMenu = ({ id, data, visible }) => { if (!data) return null; return (
{data.cols === 2 ? (
{data.left.map((item, i) => ( e.preventDefault() : undefined}> {String(i + 1).padStart(2, "0")} {item.label} {item.desc} ))}
{data.right.map((item, i) => ( e.preventDefault() : undefined}> {String(data.left.length + i + 1).padStart(2, "0")} {item.label} {item.desc} ))} {data.footer && ( {data.footer.label} )}
) : (
{data.items.map((item, i) => ( e.preventDefault() : undefined} > {item.sub || String(i + 1).padStart(2, "0")} {item.label}{item.soon && Soon} {item.desc} ))}
)}
); }; /* Top nav with theme toggle, scroll-state, and mega menus */ const Nav = ({ theme, onToggleTheme }) => { const [scrolled, setScrolled] = React.useState(false); const [openMenu, setOpenMenu] = React.useState(null); const closeTimer = React.useRef(null); const navRef = React.useRef(null); React.useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 24); window.addEventListener("scroll", onScroll, { passive: true }); onScroll(); return () => window.removeEventListener("scroll", onScroll); }, []); // Close on click outside React.useEffect(() => { const handler = (e) => { if (navRef.current && !navRef.current.contains(e.target)) { setOpenMenu(null); } }; document.addEventListener("mousedown", handler); return () => document.removeEventListener("mousedown", handler); }, []); const handleEnter = (id) => { clearTimeout(closeTimer.current); setOpenMenu(id); }; const handleLeave = () => { closeTimer.current = setTimeout(() => setOpenMenu(null), 120); }; const isFivem = typeof location !== "undefined" && /fivem/i.test(location.pathname); const home = isFivem ? "index.html" : "#top"; const link = (anchor) => isFivem ? `index.html${anchor}` : anchor; const isDark = theme === "dark"; const NAV_ITEMS = [ { id: "manifesto", label: "Manifesto", href: link("#manifesto") }, { id: "projects", label: "Projects", href: link("#projects") }, { id: "fivem", label: "FiveM", href: "fivem.html" }, { id: "contact", label: "Contact", href: link("#contact") }, ]; return ( ); }; /* HERO */ const Hero = () => { return (
Studio open · 24/7 est. MMXXVI v 01 — fivem

Built after hours. Released for everyone.

After-Hours is a quiet studio for unusual software. One project at a time, made carefully, shipped without fanfare.

01 / Currently shipping
FiveM scripts
View work
Scroll
); }; /* TICKER */ const Ticker = () => { const items = [ "Built after hours", "Released for everyone", "Scripts. Tools. Strange ideas.", "Quiet software, loud care", "FiveM · Vol. 01", ]; const Row = () => ( {items.map((t, i) => ( {t} ))} ); return ( ); }; Object.assign(window, { Nav, Hero, Ticker });