patx/afterdarklabs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="icon" type="image/svg+xml" href="moon-stars-fill.svg">
    <link rel="apple-touch-icon" href="/moon-stars-fill.svg">
    <link rel="manifest" href="/site.webmanifest">
    <title>After Dark Labs | Free Website Demo in 24 Hours</title>
    <meta name="description" content="After Dark Labs builds custom business websites, Shopify stores, mobile apps, and internal tools with SEO, hosting, logo design, and backend APIs baked in. Get a free demo within 24 hours.">
    <meta name="robots" content="index,follow">
    <link rel="canonical" href="https://afterdarklabs.io/">
    <meta property="og:title" content="After Dark Labs | Free Website Demo in 24 Hours">
    <meta property="og:description" content="Answer a quick questionnaire and get a free demo website within 24 hours. Custom websites, Shopify stores, mobile apps, and business tools.">
    <meta property="og:image" content="https://afterdarklabs.io/twitter-card.png">
    <meta property="og:image:width" content="1536">
    <meta property="og:image:height" content="1024">
    <meta property="og:image:alt" content="After Dark Labs custom websites and mobile apps">
    <meta property="og:type" content="website">
    <meta property="og:url" content="https://afterdarklabs.io/">
    <meta property="og:site_name" content="After Dark Labs">
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:title" content="After Dark Labs | Free Website Demo in 24 Hours">
    <meta name="twitter:description" content="Answer a quick questionnaire and get a free demo website within 24 hours.">
    <meta name="twitter:image" content="https://afterdarklabs.io/twitter-card.png">
    <meta name="twitter:image:alt" content="After Dark Labs custom websites and mobile apps">
    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css">
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Space+Grotesk:wght@500;600;700&display=swap');

        :root {
            --neon: #ccff00;
            --page-bg: #17212b;
            --page-bg-rgb: 23, 33, 43;
        }

        html { scroll-behavior: smooth; }
        body {
            background: var(--page-bg);
            font-family: 'Inter', system-ui, sans-serif;
        }
        .heading { font-family: 'Space Grotesk', sans-serif; }

        .hero-bg { background: var(--page-bg); }

        .bg-black,
        .bg-zinc-950 {
            background-color: var(--page-bg) !important;
        }

        .bg-black\/90 {
            background-color: rgba(var(--page-bg-rgb), 0.92) !important;
        }

        .neon-text {
            color: var(--neon);
            text-shadow: 0 0 10px var(--neon), 0 0 25px var(--neon), 0 0 50px var(--neon);
        }

        #hero-canvas {
            position: absolute;
            inset: 0;
            width: 100%;
            height: 100%;
            display: block;
            z-index: 0;
        }

        .hero-content {
            position: relative;
            z-index: 1;
        }

        .hero-vignette {
            position: absolute;
            inset: 0;
            background:
                radial-gradient(ellipse 80% 70% at 50% 50%, transparent 42%, rgba(var(--page-bg-rgb),0.54) 100%),
                linear-gradient(to bottom, rgba(var(--page-bg-rgb),0.22) 0%, transparent 24%, transparent 78%, rgba(var(--page-bg-rgb),0.34) 100%);
            pointer-events: none;
            z-index: 1;
        }

        .service-chip:has(input:checked) {
            border-color: rgba(204,255,0,0.8);
            background: rgba(204,255,0,0.12);
            color: white;
        }

        .contact-choice:has(input:checked),
        .logo-choice:has(input:checked) {
            border-color: rgba(204,255,0,0.8);
            background: rgba(204,255,0,0.12);
            color: white;
        }

        nav a[data-nav-link][aria-current="page"] {
            color: #ccff00;
            font-weight: 600;
        }
    </style>
    <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@graph": [
        {
          "@type": "Organization",
          "@id": "https://afterdarklabs.io/#organization",
          "name": "After Dark Labs",
          "url": "https://afterdarklabs.io/",
          "logo": "https://afterdarklabs.io/logo.png",
          "founder": {
            "@type": "Person",
            "name": "Harrison Erd",
            "url": "https://harrisonerd.com/"
          },
          "areaServed": {
            "@type": "Country",
            "name": "United States"
          },
          "description": "After Dark Labs builds custom business websites, Shopify stores, mobile apps, internal tools, SEO foundations, hosting setup, logo design, backend APIs, and integrations."
        },
        {
          "@type": "WebSite",
          "@id": "https://afterdarklabs.io/#website",
          "url": "https://afterdarklabs.io/",
          "name": "After Dark Labs",
          "publisher": {
            "@id": "https://afterdarklabs.io/#organization"
          },
          "description": "After Dark Labs builds custom websites, Shopify stores, mobile apps, and business tools for U.S. businesses."
        },
        {
          "@type": "Service",
          "@id": "https://afterdarklabs.io/#custom-web-app-service",
          "name": "Custom website, Shopify store, and mobile app development",
          "provider": {
            "@id": "https://afterdarklabs.io/#organization"
          },
          "areaServed": {
            "@type": "Country",
            "name": "United States"
          },
          "serviceType": [
            "Business website development",
            "Shopify store development",
            "Mobile app development",
            "Internal tool development",
            "SEO and hosting setup"
          ],
          "url": "https://afterdarklabs.io/#questionnaire"
        }
      ]
    }
    </script>
</head>
<body class="bg-black text-white overflow-x-hidden">
    <nav class="fixed top-0 z-50 w-full bg-black/90 backdrop-blur-lg">
        <div class="mx-auto max-w-7xl px-4 py-4 sm:px-6 lg:py-5">
            <div class="flex items-center justify-between gap-3 lg:hidden">
                <button type="button" id="mobile-nav-toggle" class="flex min-w-0 items-center gap-2 rounded-2xl p-1.5 pr-3 text-left text-white transition-colors hover:bg-white/10 focus:outline-none focus-visible:ring-2 focus-visible:ring-[#ccff00]" aria-controls="mobile-nav-menu" aria-expanded="false" aria-label="Open navigation menu">
                    <span class="flex h-9 w-9 shrink-0 items-center justify-center rounded-2xl border-2 border-[#ccff00] bg-black text-lg font-bold">🌑</span>
                    <span class="min-w-0">
                        <span class="heading block truncate text-xl font-semibold tracking-tighter">After Dark</span>
                        <span class="-mt-1 block text-xs tracking-[3px] text-[#ccff00]">LABS</span>
                    </span>
                </button>
                <a href="#questionnaire" class="shrink-0 rounded-2xl bg-[#ccff00] px-4 py-3 text-sm font-semibold text-black transition-colors hover:bg-white">Get Free Demo</a>
            </div>

            <div class="hidden items-center justify-between lg:flex">
                <a href="index.html" class="flex items-center gap-3">
                    <div class="flex h-9 w-9 items-center justify-center rounded-2xl border-2 border-[#ccff00] bg-black text-xl font-bold">🌑</div>
                    <div>
                        <span class="heading block text-2xl font-semibold tracking-tighter">After Dark</span>
                        <span class="-mt-1 block text-sm tracking-[3px] text-[#ccff00]">LABS</span>
                    </div>
                </a>
                <div class="flex items-center gap-6">
                    <div class="flex items-center gap-7 text-sm font-medium">
                        <a href="#how-it-works" class="transition-colors hover:text-[#ccff00]" data-nav-link>How It Works</a>
                        <a href="#about" class="transition-colors hover:text-[#ccff00]" data-nav-link>About</a>
                        <a href="#work" class="transition-colors hover:text-[#ccff00]" data-nav-link>Our Work</a>
                    </div>
                    <a href="#questionnaire" class="rounded-2xl bg-[#ccff00] px-6 py-3 font-semibold text-black transition-colors hover:bg-white">Get Free Demo</a>
                </div>
            </div>

            <div id="mobile-nav-menu" class="hidden lg:hidden">
                <div class="mt-4 grid gap-2 border-t border-white/10 pt-4 text-sm font-semibold">
                    <a href="#hero" class="rounded-2xl px-4 py-3 text-gray-200 transition-colors hover:bg-white/10 hover:text-[#ccff00]" data-nav-link>Home</a>
                    <a href="#how-it-works" class="rounded-2xl px-4 py-3 text-gray-200 transition-colors hover:bg-white/10 hover:text-[#ccff00]" data-nav-link>How It Works</a>
                    <a href="#about" class="rounded-2xl px-4 py-3 text-gray-200 transition-colors hover:bg-white/10 hover:text-[#ccff00]" data-nav-link>About</a>
                    <a href="#work" class="rounded-2xl px-4 py-3 text-gray-200 transition-colors hover:bg-white/10 hover:text-[#ccff00]" data-nav-link>Our Work</a>
                    <a href="#questionnaire" class="rounded-2xl px-4 py-3 text-gray-200 transition-colors hover:bg-white/10 hover:text-[#ccff00]" data-nav-link>Contact</a>
                </div>
            </div>
        </div>
    </nav>

    <main>
        <section id="hero" class="hero-bg min-h-screen flex items-center pt-20" style="position:relative; overflow:hidden;">
            <canvas id="hero-canvas"></canvas>
            <div class="hero-vignette"></div>

            <div class="hero-content mx-auto grid w-full max-w-7xl gap-10 px-6 py-32 text-left lg:grid-cols-[1.3fr_0.7fr] lg:items-end">
                <div>
                    <h1 class="heading text-7xl font-bold leading-none tracking-tighter md:text-8xl lg:text-7xl xl:text-8xl">
                        Custom websites<br>and mobile apps<br>that help businesses<br><span class="neon-text">thrive</span>.
                    </h1>
                </div>
                <div class="mx-auto flex max-w-xl flex-col items-start gap-8 lg:mx-0">
                    <div class="flex flex-wrap gap-5 justify-start">
                        <a href="#questionnaire" class="px-8 py-5 bg-[#ccff00] hover:bg-white text-black font-semibold rounded-3xl text-lg transition-all flex items-center gap-3 group">
                            Get Your Free Demo
                        </a>
                        <a href="#how-it-works" class="px-8 py-5 bg-white/10 hover:bg-white/15 font-medium rounded-3xl text-lg transition-all">
                            See How It Works
                        </a>
                    </div>
                </div>
            </div>
        </section>

        <section id="how-it-works" class="scroll-mt-24 border-t border-white/10 bg-black">
            <div class="mx-auto max-w-5xl px-6 py-20 md:py-24">
                <div class="mb-12 max-w-3xl">
                    <p class="mb-5 text-sm font-bold uppercase tracking-[0.28em] text-[#ccff00]">No upfront cost, no pressure. We prove our work before you pay a dime.</p>
                    <h2 class="heading text-4xl font-semibold leading-none tracking-tighter md:text-6xl">How it Works</h2>
                </div>
                <ol class="space-y-7">
                    <li class="grid gap-4 py-6 md:grid-cols-[4rem_1fr]">
                        <p class="heading text-2xl font-bold text-[#ccff00]">01</p>
                        <p class="text-lg leading-8 text-gray-300">Answer our simple questionnaire <a href="#questionnaire" class="font-semibold text-[#ccff00] underline decoration-[#ccff00]/60 underline-offset-4 transition-colors hover:text-white hover:decoration-white">here</a>. It takes barely any time at all, it's only 5 questions.</p>
                    </li>
                    <li class="grid gap-4 py-6 md:grid-cols-[4rem_1fr]">
                        <p class="heading text-2xl font-bold text-[#ccff00]">02</p>
                        <p class="text-lg leading-8 text-gray-300">Within 24 hours, we send you a free live demo based on your answers.</p>
                    </li>
                    <li class="grid gap-4 py-6 md:grid-cols-[4rem_1fr]">
                        <p class="heading text-2xl font-bold text-[#ccff00]">03</p>
                        <p class="text-lg leading-8 text-gray-300">If you like the demo, we set up a call to discuss pricing and scope.</p>
                    </li>
                    <li class="grid gap-4 py-6 md:grid-cols-[4rem_1fr]">
                        <p class="heading text-2xl font-bold text-[#ccff00]">04</p>
                        <p class="text-lg leading-8 text-gray-300">We build your full website, mobile app, or Shopify store with hosting, domains, logos, and more.</p>
                    </li>
                    <li class="grid gap-4 py-6 md:grid-cols-[4rem_1fr]">
                        <p class="heading text-2xl font-bold text-[#ccff00]">05</p>
                        <p class="text-lg leading-8 text-gray-300">Watch your business boom.</p>
                    </li>
                </ol>
            </div>
        </section>

        <section id="about" class="scroll-mt-24 border-t border-white/10 bg-zinc-950">
            <div class="mx-auto max-w-5xl px-6 py-20 md:py-24">
                <p class="mb-5 text-sm font-bold uppercase tracking-[0.28em] text-[#ccff00]">About</p>
                <h2 class="heading text-4xl font-semibold leading-none tracking-tighter md:text-6xl">Built different, by design.</h2>
                <div class="mt-8 max-w-3xl space-y-6 text-lg leading-8 text-gray-300">
                    <p>After Dark Labs, run by <a href="https://harrisonerd.com/" class="font-semibold text-white underline decoration-[#ccff00]/60 underline-offset-4 transition-colors hover:text-[#ccff00]">Harrison Erd</a>, makes websites and applications for businesses across the United States.</p>
                    <p>Instead of templates, plugins, and cookie-cutter AI site builders that end up costing you tons of money and time, we build real software from the ground up, designed around how your business actually works.</p>
                    <div class="flex flex-wrap gap-3">
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">Business websites</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">Personal websites</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">Shopify stores</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">iOS and Android apps</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">Customer portals</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">Admin dashboards</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">Booking systems</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">Membership sites</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">Subscription platforms</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">Internal tools</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">Custom web applications</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">Online payments</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">Blogs</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">SEO & GEO</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">Domain name & hosting</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">Logo design</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">CRM-style lead capture</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">Email/SMS notifications</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">Backend APIs</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">AI-powered features</span>
                        <span class="rounded-full border border-[#ccff00]/30 bg-[#ccff00]/10 px-4 py-2 text-sm font-semibold text-white shadow-[0_0_24px_rgba(204,255,0,0.08)]">3rd party integrations</span>
                      </div>
                </div>
            </div>
        </section>

        <section id="work" class="scroll-mt-24 border-t border-white/10 bg-black">
            <div class="mx-auto max-w-5xl px-6 py-20 md:py-24">
                <div class="mb-10">
                    <p class="mb-5 text-sm font-bold uppercase tracking-[0.28em] text-[#ccff00]">A sample of what we have shipped. </p>
                    <h2 class="heading text-4xl font-semibold tracking-tighter md:text-6xl">Our Work</h2>
                </div>
                <div class="grid gap-5 md:grid-cols-2">
                    <article class="overflow-hidden rounded-3xl bg-zinc-950">
                        <button type="button" class="block w-full cursor-zoom-in overflow-hidden rounded-t-3xl text-left focus:outline-none focus-visible:ring-2 focus-visible:ring-[#ccff00] focus-visible:ring-offset-2 focus-visible:ring-offset-[#17212b]" data-work-preview>
                            <img src="https://afterdarklabs.io/miadruck.png?v=1" width="1901" height="1079" loading="lazy" class="h-48 w-full object-cover" alt="Mia Druck real estate website project by After Dark Labs">
                        </button>
                        <div class="p-6">
                            <p class="text-sm font-medium text-[#ccff00]">Website • Real estate</p>
                            <p class="mt-4 text-sm leading-6 text-gray-300">"The demo captured my brand quickly, and the final site made it easier for clients to find me and reach out to purchase their dream home." - <a href="https://miadruck.com" class="font-semibold text-white underline decoration-[#ccff00]/60 underline-offset-4 transition-colors hover:text-[#ccff00]">Mia Druck</a></p>
                        </div>
                    </article>
                    <article class="overflow-hidden rounded-3xl bg-zinc-950">
                        <button type="button" class="block w-full cursor-zoom-in overflow-hidden rounded-t-3xl text-left focus:outline-none focus-visible:ring-2 focus-visible:ring-[#ccff00] focus-visible:ring-offset-2 focus-visible:ring-offset-[#17212b]" data-work-preview>
                            <img src="https://afterdarklabs.io/gardenfresh.png?v=1" width="1901" height="1079" loading="lazy" class="h-48 w-full object-cover" alt="Garden Fresh Wholesale ecommerce web app project by After Dark Labs">
                        </button>
                        <div class="p-6">
                            <p class="text-sm font-medium text-[#ccff00]">Business Website • SEO</p>
                            <p class="mt-4 text-sm leading-6 text-gray-300">"The new site gave our team a cleaner way to show products, answer customer questions, and bring in wholesale inquiries. And our mobile app After Dark Labs made for us lets us compete with the big guys by allowing our clients to place orders right from their phone." - <a href="https://gardenfreshwholesale.com" class="font-semibold text-white underline decoration-[#ccff00]/60 underline-offset-4 transition-colors hover:text-[#ccff00]">Garden Fresh Wholesale</a></p>
                        </div>
                    </article>
                    <article class="overflow-hidden rounded-3xl bg-zinc-950">
                        <button type="button" class="block w-full cursor-zoom-in overflow-hidden rounded-t-3xl text-left focus:outline-none focus-visible:ring-2 focus-visible:ring-[#ccff00] focus-visible:ring-offset-2 focus-visible:ring-offset-[#17212b]" data-work-preview>
                            <img src="https://afterdarklabs.io/coralvibe.png?v=3" width="1901" height="1079" loading="lazy" class="h-48 w-full object-cover" alt="Shopify store for Coral Vibe Florida project by After Dark Labs">
                        </button>
                        <div class="p-6">
                            <p class="text-sm font-medium text-[#ccff00]">Shopify • E-Commerce</p>
                            <p class="mt-4 text-sm leading-6 text-gray-300">"Our Shopify store is cleaner, faster, and easier to shop. The product pages finally match my brand. We have seen sales increase 80 percent!" - <a href="https://coralvibefl.com" class="font-semibold text-white underline decoration-[#ccff00]/60 underline-offset-4 transition-colors hover:text-[#ccff00]">Coral Vibe</a></p>
                        </div>
                    </article>
                    <article class="overflow-hidden rounded-3xl bg-zinc-950">
                        <button type="button" class="block w-full cursor-zoom-in overflow-hidden rounded-t-3xl text-left focus:outline-none focus-visible:ring-2 focus-visible:ring-[#ccff00] focus-visible:ring-offset-2 focus-visible:ring-offset-[#17212b]" data-work-preview>
                            <img src="https://afterdarklabs.io/invoiceotter.png?v=3" width="1901" height="1079" loading="lazy" class="h-48 w-full object-cover" alt="Invoice Otter SaaS project by After Dark Labs">
                        </button>
                        <div class="p-6">
                            <p class="text-sm font-medium text-[#ccff00]">SaaS • Subscriptions</p>
                            <p class="mt-4 text-sm leading-6 text-gray-300">"Working with After Dark Labs was a great experience. They helped turn my idea into a real, working invoicing app with a clean design, smooth user experience, payments, quotes, expenses, and mobile-friendly features. They understood what the business needed and built practical solutions that work in the real world. Highly recommend." - <a href="https://invoiceotter.com" class="font-semibold text-white underline decoration-[#ccff00]/60 underline-offset-4 transition-colors hover:text-[#ccff00]">Invoice Otter</a></p>
                        </div>
                    </article>
                </div>
            </div>
        </section>

        <section id="questionnaire" class="scroll-mt-24 border-t border-white/10 bg-zinc-950">
            <div class="mx-auto max-w-5xl px-6 py-20 md:py-24">
                <div class="mb-10 max-w-3xl">
                    <p class="mb-5 text-sm font-bold uppercase tracking-[0.28em] text-[#ccff00]">Get Started</p>
                    <h2 class="heading text-4xl font-semibold leading-none tracking-tighter md:text-6xl">Get your free demo</h2>
                    <p class="mt-8 text-lg leading-8 text-gray-300">Answer a few quick questions and we'll send you a real demo site within 24 hours — free, no strings attached.</p>
                </div>

                <form id="demo-questionnaire" class="space-y-8" action="https://formspree.io/f/xeedjery" method="POST" novalidate>
                    <input type="hidden" name="_gotcha" value="">

                    <div class="space-y-3">
                        <div class="flex items-center justify-between gap-4 text-sm font-semibold uppercase tracking-[0.18em] text-gray-300">
                            <span id="questionnaire-step-label">Question 1 of 5</span>
                            <span id="questionnaire-step-name" class="text-[#ccff00]">Identity</span>
                        </div>
                        <div class="h-2 overflow-hidden rounded-full bg-white/10" aria-hidden="true">
                            <div id="questionnaire-progress" class="h-full w-1/5 rounded-full bg-[#ccff00] transition-all duration-300"></div>
                        </div>
                    </div>

                    <div data-question-step="0">
                        <label for="name" class="mb-3 block text-sm font-semibold uppercase tracking-[0.18em] text-gray-300">Name or Business Name <span class="text-[#ccff00]" aria-hidden="true">*</span><span class="sr-only"> required</span></label>
                        <input id="name" name="name_or_business_name" type="text" autocomplete="name" required class="min-h-12 w-full rounded-2xl border border-white/10 bg-black px-6 py-5 text-white outline-none transition-colors placeholder:text-gray-600 focus:border-[#ccff00]" placeholder="Your name or business">
                    </div>

                    <fieldset data-question-step="1" class="hidden">
                        <legend class="mb-4 text-sm font-semibold uppercase tracking-[0.18em] text-gray-300">Services Needed (select all that apply)<span class="text-[#ccff00]" aria-hidden="true">*</span><span class="sr-only"> required</span></legend>
                        <div class="grid gap-3 sm:grid-cols-2 xl:grid-cols-3">
                            <label class="service-chip cursor-pointer rounded-2xl border border-white/10 bg-black px-4 py-4 text-sm font-semibold text-gray-300 transition-colors"><input type="checkbox" name="services_needed" value="Business website" class="sr-only">Business website</label>
                            <label class="service-chip cursor-pointer rounded-2xl border border-white/10 bg-black px-4 py-4 text-sm font-semibold text-gray-300 transition-colors"><input type="checkbox" name="services_needed" value="Personal website" class="sr-only">Personal website</label>
                            <label class="service-chip cursor-pointer rounded-2xl border border-white/10 bg-black px-4 py-4 text-sm font-semibold text-gray-300 transition-colors"><input type="checkbox" name="services_needed" value="Shopify store" class="sr-only">Shopify store</label>
                            <label class="service-chip cursor-pointer rounded-2xl border border-white/10 bg-black px-4 py-4 text-sm font-semibold text-gray-300 transition-colors"><input type="checkbox" name="services_needed" value="E-commerce" class="sr-only">E-commerce & Online Payments</label>
                            <label class="service-chip cursor-pointer rounded-2xl border border-white/10 bg-black px-4 py-4 text-sm font-semibold text-gray-300 transition-colors"><input type="checkbox" name="services_needed" value="Online bookings" class="sr-only">Online bookings</label>
                            <label class="service-chip cursor-pointer rounded-2xl border border-white/10 bg-black px-4 py-4 text-sm font-semibold text-gray-300 transition-colors"><input type="checkbox" name="services_needed" value="Appointments" class="sr-only">Appointments</label>
                            <label class="service-chip cursor-pointer rounded-2xl border border-white/10 bg-black px-4 py-4 text-sm font-semibold text-gray-300 transition-colors"><input type="checkbox" name="services_needed" value="Subscriptions" class="sr-only">Subscriptions</label>
                            <label class="service-chip cursor-pointer rounded-2xl border border-white/10 bg-black px-4 py-4 text-sm font-semibold text-gray-300 transition-colors"><input type="checkbox" name="services_needed" value="Blog or content site" class="sr-only">Blog or content site</label>
                            <label class="service-chip cursor-pointer rounded-2xl border border-white/10 bg-black px-4 py-4 text-sm font-semibold text-gray-300 transition-colors"><input type="checkbox" name="services_needed" value="Dashboard" class="sr-only">Dashboard or Portal</label>
                            <label class="service-chip cursor-pointer rounded-2xl border border-white/10 bg-black px-4 py-4 text-sm font-semibold text-gray-300 transition-colors"><input type="checkbox" name="services_needed" value="Internal tool" class="sr-only">Internal tool or API</label>
                            <label class="service-chip cursor-pointer rounded-2xl border border-white/10 bg-black px-4 py-4 text-sm font-semibold text-gray-300 transition-colors"><input type="checkbox" name="services_needed" value="Mobile app" class="sr-only">Mobile app</label>
                            <label class="service-chip cursor-pointer rounded-2xl border border-white/10 bg-black px-4 py-4 text-sm font-semibold text-gray-300 transition-colors"><input type="checkbox" name="services_needed" value="Redesign" class="sr-only">Redesign</label>
                            <label class="service-chip cursor-pointer rounded-2xl border border-white/10 bg-black px-4 py-4 text-sm font-semibold text-gray-300 transition-colors"><input type="checkbox" name="services_needed" value="SEO" class="sr-only">SEO</label>
                            <label class="service-chip cursor-pointer rounded-2xl border border-white/10 bg-black px-4 py-4 text-sm font-semibold text-gray-300 transition-colors"><input type="checkbox" name="services_needed" value="Saas MVP" class="sr-only">SaaS MVP</label>
                            <label class="service-chip cursor-pointer rounded-2xl border border-white/10 bg-black px-4 py-4 text-sm font-semibold text-gray-300 transition-colors"><input type="checkbox" name="services_needed" value="Other" class="sr-only">Other</label>
                        </div>
                        <p id="services-error" class="mt-3 hidden text-sm font-medium text-red-300">Select at least one service.</p>
                    </fieldset>

                    <div data-question-step="2" class="hidden">
                        <label for="business-description" class="mb-3 block text-sm font-semibold uppercase tracking-[0.18em] text-gray-300">What you or your business does <span class="text-[#ccff00]" aria-hidden="true">*</span><span class="sr-only"> required</span></label>
                        <textarea id="business-description" name="business_description" rows="6" required class="min-h-36 w-full resize-none rounded-3xl border border-white/10 bg-black px-6 py-5 text-white outline-none transition-colors placeholder:text-gray-600 focus:border-[#ccff00]" placeholder="Tell us what you do, who you sell to, and what the demo should show."></textarea>
                    </div>

                    <fieldset data-question-step="3" class="hidden">
                        <legend class="mb-4 text-sm font-semibold uppercase tracking-[0.18em] text-gray-300">Logo <span class="text-[#ccff00]" aria-hidden="true">*</span><span class="sr-only"> required</span></legend>
                        <div class="grid gap-3 sm:grid-cols-3">
                            <label class="logo-choice cursor-pointer rounded-2xl border border-white/10 bg-black px-4 py-4 text-sm font-semibold text-gray-300 transition-colors"><input type="radio" name="logo_status" value="I already have a logo" required class="sr-only">I have a logo</label>
                            <label class="logo-choice cursor-pointer rounded-2xl border border-white/10 bg-black px-4 py-4 text-sm font-semibold text-gray-300 transition-colors"><input type="radio" name="logo_status" value="Please design a logo" required class="sr-only">Design one</label>
                        </div>
                    </fieldset>

                    <div data-question-step="4" class="hidden">
                        <div class="grid gap-6 md:grid-cols-2">
                            <div>
                                <label for="contact-email" class="mb-3 block text-sm font-semibold uppercase tracking-[0.18em] text-gray-300">Email address <span class="text-[#ccff00]" aria-hidden="true">*</span><span class="sr-only"> required</span></label>
                                <input id="contact-email" name="contact_email" type="email" autocomplete="email" required class="min-h-12 w-full rounded-2xl border border-white/10 bg-black px-6 py-5 text-white outline-none transition-colors placeholder:text-gray-600 focus:border-[#ccff00]" placeholder="[email protected]">
                            </div>
                            <div>
                                <label for="contact-phone" class="mb-3 block text-sm font-semibold uppercase tracking-[0.18em] text-gray-300">Phone number <span class="text-gray-500 normal-case tracking-normal">(optional)</span></label>
                                <input id="contact-phone" name="contact_phone" type="tel" autocomplete="tel" class="min-h-12 w-full rounded-2xl border border-white/10 bg-black px-6 py-5 text-white outline-none transition-colors placeholder:text-gray-600 focus:border-[#ccff00]" placeholder="(555) 555-5555">
                            </div>
                        </div>
                    </div>

                    <div class="flex flex-col gap-3 sm:flex-row">
                        <button type="button" id="questionnaire-back" class="hidden min-h-12 rounded-2xl bg-white/10 px-6 py-4 font-semibold text-white transition-colors hover:bg-white/15 sm:w-40">Back</button>
                        <button type="button" id="questionnaire-next" class="min-h-12 flex-1 rounded-2xl bg-[#ccff00] px-8 py-4 text-lg font-bold text-black transition-colors hover:bg-white">Next</button>
                        <button type="submit" id="questionnaire-submit" class="hidden min-h-12 flex-1 rounded-2xl bg-[#ccff00] px-8 py-4 text-lg font-bold text-black transition-colors hover:bg-white">Send questionnaire</button>
                    </div>
                    <div id="questionnaire-status" class="hidden rounded-3xl border border-white/10 bg-black px-8 py-8" tabindex="-1" aria-live="polite"></div>
                </form>
            </div>
        </section>
    </main>

    <footer class="border-t border-white/10 bg-black py-16">
        <div class="mx-auto max-w-7xl px-6 text-center">
            <a href="index.html" class="mb-6 inline-flex items-center justify-center gap-3">
                <div class="flex h-9 w-9 items-center justify-center rounded-2xl border-2 border-[#ccff00] bg-black text-2xl">🌑</div>
                <span class="heading text-3xl font-semibold tracking-tighter">After Dark Labs</span>
            </a>
            <p class="text-gray-500">© 2026 <a href="https://harrisonerd.com/" class="transition-colors hover:text-[#ccff00]">Harrison Erd</a> • Pompano Beach, FL</p>
            <p class="mt-3 text-gray-500"><a href="mailto:[email protected]" class="transition-colors hover:text-[#ccff00]">[email protected]</a></p>
        </div>
    </footer>

    <div id="work-modal" class="fixed inset-0 z-[100] hidden items-center justify-center bg-black/85 px-4 py-8 backdrop-blur-sm" aria-hidden="true" role="dialog" aria-modal="true" aria-label="Work screenshot preview">
        <button type="button" id="work-modal-close" class="absolute right-5 top-5 h-12 w-12 text-4xl leading-none text-white/70 transition-colors hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-[#ccff00]" aria-label="Close screenshot preview">&times;</button>
        <img id="work-modal-image" class="max-h-[86vh] max-w-[94vw] object-contain shadow-2xl" alt="Selected work screenshot preview">
    </div>

    <script>
        (function () {
            const toggle = document.getElementById('mobile-nav-toggle');
            const menu = document.getElementById('mobile-nav-menu');
            if (!toggle || !menu) return;

            function setMenuOpen(isOpen) {
                menu.classList.toggle('hidden', !isOpen);
                toggle.setAttribute('aria-expanded', String(isOpen));
                toggle.setAttribute('aria-label', isOpen ? 'Close navigation menu' : 'Open navigation menu');
            }

            toggle.addEventListener('click', () => {
                setMenuOpen(toggle.getAttribute('aria-expanded') !== 'true');
            });

            menu.querySelectorAll('a[href^="#"]').forEach(link => {
                link.addEventListener('click', () => setMenuOpen(false));
            });

            window.addEventListener('keydown', event => {
                if (event.key === 'Escape') setMenuOpen(false);
            });

            window.addEventListener('resize', () => {
                if (window.innerWidth >= 1024) setMenuOpen(false);
            });
        })();

        (function () {
            const activeClasses = ['text-[#ccff00]', 'font-semibold'];
            const navLinks = Array.from(document.querySelectorAll('nav a[data-nav-link]'));
            const sections = [
                { id: 'hero', href: '#hero' },
                { id: 'how-it-works', href: '#how-it-works' },
                { id: 'about', href: '#about' },
                { id: 'work', href: '#work' },
                { id: 'questionnaire', href: '#questionnaire' },
            ];

            if (!navLinks.length) return;

            function setActive(href) {
                navLinks.forEach(link => {
                    const isActive = link.getAttribute('href') === href;
                    link.classList.toggle(activeClasses[0], isActive);
                    link.classList.toggle(activeClasses[1], isActive);

                    if (isActive) {
                        link.setAttribute('aria-current', 'page');
                    } else {
                        link.removeAttribute('aria-current');
                    }
                });
            }

            function updateActiveNav() {
                const offset = window.innerHeight * 0.35;
                let currentHref = '';

                for (const section of sections) {
                    const element = document.getElementById(section.id);
                    if (!element) continue;

                    if (element.getBoundingClientRect().top <= offset) {
                        currentHref = section.href;
                    }
                }

                setActive(currentHref);
            }

            function activeFromHash() {
                return sections.some(section => section.href === window.location.hash)
                    ? window.location.hash
                    : '';
            }

            setActive(activeFromHash());
            requestAnimationFrame(updateActiveNav);
            window.addEventListener('load', updateActiveNav);
            window.addEventListener('scroll', updateActiveNav, { passive: true });
            window.addEventListener('hashchange', () => {
                setActive(activeFromHash());
                requestAnimationFrame(updateActiveNav);
            });
        })();

        (function () {
            const form = document.getElementById('demo-questionnaire');
            const status = document.getElementById('questionnaire-status');
            const servicesError = document.getElementById('services-error');
            if (!form || !status || !servicesError) return;

            const steps = Array.from(form.querySelectorAll('[data-question-step]'));
            const backButton = document.getElementById('questionnaire-back');
            const nextButton = document.getElementById('questionnaire-next');
            const submitButton = document.getElementById('questionnaire-submit');
            const stepLabel = document.getElementById('questionnaire-step-label');
            const stepName = document.getElementById('questionnaire-step-name');
            const progress = document.getElementById('questionnaire-progress');
            const stepNames = ['Identity', 'Services', 'Business', 'Logo', 'Contact'];
            let currentStep = 0;

            if (!steps.length || !backButton || !nextButton || !submitButton || !stepLabel || !stepName || !progress) return;

            const defaultButtonText = submitButton.textContent.trim();

            function selectedServices() {
                return Array.from(form.querySelectorAll('input[name="services_needed"]:checked'));
            }

            function fieldsForStep(step) {
                return Array.from(step.querySelectorAll('input, textarea, select')).filter(field => !field.disabled);
            }

            function fieldValue(selector) {
                const field = form.querySelector(selector);
                return field ? field.value.trim() : '';
            }

            function checkedValue(selector) {
                const field = form.querySelector(`${selector}:checked`);
                return field ? field.value : '';
            }

            function buildMessage() {
                const services = selectedServices().map(input => input.value).join(', ');

                return [
                    `Name or business: ${fieldValue('[name="name_or_business_name"]')}`,
                    `Services needed: ${services}`,
                    `Business description: ${fieldValue('[name="business_description"]')}`,
                    `Logo: ${checkedValue('[name="logo_status"]')}`,
                    `Email: ${fieldValue('[name="contact_email"]')}`,
                    `Phone: ${fieldValue('[name="contact_phone"]') || 'Not provided'}`,
                ].join('\n');
            }

            function setStep(index, shouldFocus) {
                currentStep = Math.max(0, Math.min(index, steps.length - 1));

                steps.forEach((step, stepIndex) => {
                    step.classList.toggle('hidden', stepIndex !== currentStep);
                });

                const isFirst = currentStep === 0;
                const isLast = currentStep === steps.length - 1;

                backButton.classList.toggle('hidden', isFirst);
                nextButton.classList.toggle('hidden', isLast);
                submitButton.classList.toggle('hidden', !isLast);
                stepLabel.textContent = `Question ${currentStep + 1} of ${steps.length}`;
                stepName.textContent = stepNames[currentStep] || '';
                progress.style.width = `${((currentStep + 1) / steps.length) * 100}%`;

                if (shouldFocus) {
                    const firstField = fieldsForStep(steps[currentStep])[0];
                    if (firstField) firstField.focus({ preventScroll: true });
                }
            }

            function validateStep(index) {
                const step = steps[index];
                if (!step) return true;

                const servicesStep = step.querySelector('input[name="services_needed"]');
                if (servicesStep) {
                    const hasServices = selectedServices().length > 0;
                    servicesError.classList.toggle('hidden', hasServices);
                    if (!hasServices) {
                        servicesError.scrollIntoView({ behavior: 'smooth', block: 'center' });
                        return false;
                    }
                }

                for (const field of fieldsForStep(step)) {
                    if (!field.checkValidity()) {
                        field.reportValidity();
                        return false;
                    }
                }

                return true;
            }

            function validateAllSteps() {
                for (let index = 0; index < steps.length; index++) {
                    setStep(index, false);
                    if (!validateStep(index)) return false;
                }

                setStep(steps.length - 1, false);
                return true;
            }

            function showStatus(type, title, message) {
                const isSuccess = type === 'success';
                status.className = [
                    'rounded-3xl border px-8 py-8',
                    isSuccess ? 'border-[#ccff00]/50 bg-[#ccff00]/10' : 'border-red-400/40 bg-red-950/30',
                ].join(' ');
                status.setAttribute('role', isSuccess ? 'status' : 'alert');

                const eyebrow = document.createElement('p');
                eyebrow.className = `text-sm font-semibold uppercase tracking-[0.2em] ${isSuccess ? 'text-[#ccff00]' : 'text-red-300'}`;
                eyebrow.textContent = isSuccess ? 'Questionnaire sent' : 'Questionnaire not sent';

                const heading = document.createElement('h3');
                heading.className = 'heading mt-3 text-3xl font-semibold tracking-tighter text-white';
                heading.textContent = title;

                const body = document.createElement('p');
                body.className = 'mt-4 text-lg leading-8 text-gray-300';
                body.textContent = message;

                status.replaceChildren(eyebrow, heading, body);
                status.classList.remove('hidden');
                status.focus({ preventScroll: true });

                if (isSuccess) {
                    form.querySelectorAll(':scope > *:not(#questionnaire-status)').forEach(element => {
                        element.remove();
                    });
                }
            }

            form.addEventListener('submit', async event => {
                event.preventDefault();

                if (!validateAllSteps()) return;

                submitButton.disabled = true;
                submitButton.textContent = 'Sending...';
                submitButton.classList.add('cursor-wait', 'opacity-80');

                try {
                    const formData = new FormData(form);
                    const cleanFormData = new FormData();
                    cleanFormData.append('_gotcha', formData.get('_gotcha') || '');
                    cleanFormData.append('email', fieldValue('[name="contact_email"]'));
                    cleanFormData.append('message', buildMessage());

                    const response = await fetch(form.action, {
                        method: form.method,
                        body: cleanFormData,
                        headers: { Accept: 'application/json' },
                    });
                    const data = await response.json().catch(() => ({}));

                    if (!response.ok) {
                        const errors = Array.isArray(data.errors)
                            ? data.errors.map(error => error.message).filter(Boolean).join(' ')
                            : '';
                        throw new Error(errors || 'The questionnaire could not be submitted.');
                    }

                    showStatus(
                        'success',
                        'Thanks. We will build your demo from this.',
                        'Your questionnaire was sent successfully. We will review it and respond with the next step.'
                    );
                } catch (error) {
                    showStatus(
                        'error',
                        'We could not send your questionnaire.',
                        error.message || 'Please refresh the page and try again in a moment.'
                    );
                } finally {
                    if (!status.getAttribute('role') || status.getAttribute('role') === 'alert') {
                        submitButton.disabled = false;
                    }
                    submitButton.textContent = defaultButtonText;
                    submitButton.classList.remove('cursor-wait', 'opacity-80');
                }
            });

            nextButton.addEventListener('click', () => {
                if (validateStep(currentStep)) {
                    setStep(currentStep + 1, true);
                }
            });

            backButton.addEventListener('click', () => {
                setStep(currentStep - 1, true);
            });

            form.querySelectorAll('input[name="services_needed"]').forEach(input => {
                input.addEventListener('change', () => {
                    if (selectedServices().length > 0) {
                        servicesError.classList.add('hidden');
                    }
                });
            });

            form.addEventListener('keydown', event => {
                if (event.key === 'Enter' && event.target.tagName !== 'TEXTAREA' && currentStep < steps.length - 1) {
                    event.preventDefault();
                    nextButton.click();
                }
            });

            setStep(0, false);
        })();

        (function () {
            const modal = document.getElementById('work-modal');
            const modalImage = document.getElementById('work-modal-image');
            const closeButton = document.getElementById('work-modal-close');
            const previewButtons = document.querySelectorAll('[data-work-preview]');
            let lastFocused = null;

            if (!modal || !modalImage || !closeButton || !previewButtons.length) return;

            function openPreview(button) {
                const image = button.querySelector('img');
                lastFocused = document.activeElement;
                modalImage.src = image.currentSrc || image.src;
                modalImage.alt = image.alt;
                modal.classList.remove('hidden');
                modal.classList.add('flex');
                modal.setAttribute('aria-hidden', 'false');
                document.body.classList.add('overflow-hidden');
                closeButton.focus({ preventScroll: true });
            }

            function closePreview() {
                modal.classList.add('hidden');
                modal.classList.remove('flex');
                modal.setAttribute('aria-hidden', 'true');
                modalImage.removeAttribute('src');
                document.body.classList.remove('overflow-hidden');
                if (lastFocused) lastFocused.focus({ preventScroll: true });
            }

            previewButtons.forEach(button => {
                button.addEventListener('click', () => openPreview(button));
            });

            closeButton.addEventListener('click', closePreview);
            modal.addEventListener('click', event => {
                if (event.target === modal) closePreview();
            });
            window.addEventListener('keydown', event => {
                if (event.key === 'Escape' && !modal.classList.contains('hidden')) closePreview();
            });
        })();

        /* ─── HERO CANVAS ANIMATION ──────────────────────────────── */
        (function () {
            const canvas  = document.getElementById('hero-canvas');
            const section = canvas.closest('section');
            const ctx     = canvas.getContext('2d');

            const NODE_COUNT = 80;
            const LINK_DIST  = 140;
            const PULSE_SPEED = 0.012;

            let W, H, nodes = [], mouse = { x: -9999, y: -9999 };

            function resize() {
                const rect = section.getBoundingClientRect();
                W = canvas.width  = rect.width  * devicePixelRatio;
                H = canvas.height = rect.height * devicePixelRatio;
                canvas.style.width  = rect.width  + 'px';
                canvas.style.height = rect.height + 'px';
            }

            function makeNode() {
                return {
                    x:  Math.random() * W,
                    y:  Math.random() * H,
                    vx: (Math.random() - 0.5) * 0.45,
                    vy: (Math.random() - 0.5) * 0.45,
                    r:  1.5 + Math.random() * 2,
                    phase: Math.random() * Math.PI * 2,
                };
            }

            function init() {
                resize();
                nodes = Array.from({ length: NODE_COUNT }, makeNode);
            }

            const ORBS = [
                { cx: 0.20, cy: 0.35, r: 0.22, spd: 0.0007, off: 0 },
                { cx: 0.75, cy: 0.60, r: 0.18, spd: 0.0011, off: 2.1 },
                { cx: 0.50, cy: 0.25, r: 0.14, spd: 0.0009, off: 4.5 },
                { cx: 0.85, cy: 0.20, r: 0.12, spd: 0.0013, off: 1.3 },
            ];

            function drawOrbs(t) {
                ORBS.forEach(o => {
                    const cx = (o.cx + Math.sin(t * o.spd + o.off) * 0.06) * W;
                    const cy = (o.cy + Math.cos(t * o.spd * 1.3 + o.off) * 0.06) * H;
                    const r  = o.r * Math.min(W, H);
                    const g  = ctx.createRadialGradient(cx, cy, 0, cx, cy, r);
                    g.addColorStop(0,   'rgba(204,255,0,0.10)');
                    g.addColorStop(0.5, 'rgba(204,255,0,0.04)');
                    g.addColorStop(1,   'rgba(204,255,0,0)');
                    ctx.beginPath();
                    ctx.arc(cx, cy, r, 0, Math.PI * 2);
                    ctx.fillStyle = g;
                    ctx.fill();
                });
            }

            let rings = [];
            section.addEventListener('mousemove', e => {
                const rect = section.getBoundingClientRect();
                mouse.x = (e.clientX - rect.left) * devicePixelRatio;
                mouse.y = (e.clientY - rect.top)  * devicePixelRatio;
                if (Math.random() < 0.08) {
                    rings.push({ x: mouse.x, y: mouse.y, r: 0, alpha: 0.5 });
                }
            });
            section.addEventListener('mouseleave', () => { mouse.x = mouse.y = -9999; });

            function drawRings() {
                rings = rings.filter(rg => rg.alpha > 0.01);
                rings.forEach(rg => {
                    rg.r     += 1.8;
                    rg.alpha *= 0.93;
                    ctx.beginPath();
                    ctx.arc(rg.x, rg.y, rg.r, 0, Math.PI * 2);
                    ctx.strokeStyle = `rgba(204,255,0,${rg.alpha})`;
                    ctx.lineWidth = 1;
                    ctx.stroke();
                });
            }

            let t = 0;
            function frame() {
                t++;
                ctx.clearRect(0, 0, W, H);
                ctx.fillStyle = getComputedStyle(document.documentElement).getPropertyValue('--page-bg').trim() || '#17212b';
                ctx.fillRect(0, 0, W, H);

                drawOrbs(t);

                nodes.forEach(n => {
                    n.phase += PULSE_SPEED;
                    n.x += n.vx;
                    n.y += n.vy;
                    if (n.x < 0 || n.x > W) n.vx *= -1;
                    if (n.y < 0 || n.y > H) n.vy *= -1;

                    const dx = n.x - mouse.x, dy = n.y - mouse.y;
                    const d2 = dx * dx + dy * dy;
                    if (d2 < 90000) {
                        const f = (1 - d2 / 90000) * 0.4;
                        n.vx += (dx / Math.sqrt(d2)) * f;
                        n.vy += (dy / Math.sqrt(d2)) * f;
                    }

                    const spd = Math.sqrt(n.vx * n.vx + n.vy * n.vy);
                    if (spd > 1.2) { n.vx /= spd / 1.2; n.vy /= spd / 1.2; }
                });

                ctx.lineWidth = 0.8;
                for (let i = 0; i < nodes.length; i++) {
                    for (let j = i + 1; j < nodes.length; j++) {
                        const a = nodes[i], b = nodes[j];
                        const dx = a.x - b.x, dy = a.y - b.y;
                        const d  = Math.sqrt(dx * dx + dy * dy);
                        if (d < LINK_DIST * devicePixelRatio) {
                            const alpha = (1 - d / (LINK_DIST * devicePixelRatio)) * 0.35;
                            ctx.strokeStyle = `rgba(204,255,0,${alpha})`;
                            ctx.beginPath();
                            ctx.moveTo(a.x, a.y);
                            ctx.lineTo(b.x, b.y);
                            ctx.stroke();
                        }
                    }
                }

                nodes.forEach(n => {
                    const pulse = 0.5 + 0.5 * Math.sin(n.phase);
                    const alpha = 0.55 + 0.45 * pulse;
                    const glow  = ctx.createRadialGradient(n.x, n.y, 0, n.x, n.y, n.r * 4);
                    glow.addColorStop(0,   `rgba(204,255,0,${alpha})`);
                    glow.addColorStop(0.4, `rgba(204,255,0,${alpha * 0.3})`);
                    glow.addColorStop(1,   'rgba(204,255,0,0)');
                    ctx.beginPath();
                    ctx.arc(n.x, n.y, n.r * 4 * devicePixelRatio, 0, Math.PI * 2);
                    ctx.fillStyle = glow;
                    ctx.fill();

                    ctx.beginPath();
                    ctx.arc(n.x, n.y, n.r * devicePixelRatio, 0, Math.PI * 2);
                    ctx.fillStyle = `rgba(204,255,0,${alpha})`;
                    ctx.fill();
                });

                drawRings();

                for (let y = 0; y < H; y += 4) {
                    ctx.fillStyle = 'rgba(255,255,255,0.018)';
                    ctx.fillRect(0, y, W, 1);
                }

                requestAnimationFrame(frame);
            }

            window.addEventListener('resize', () => { resize(); });
            init();
            frame();
        })();
    </script>
</body>
</html>