patx/afterdarklabs
another redesign
Commit bc4f84c · patx · 2026-08-23T23:59:43-04:00
Comments
No comments yet.
Diff
diff --git a/docs/index.html b/docs/index.html
index d7f9bf5..db0874e 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -9,12 +9,12 @@
<link rel="icon" type="image/png" sizes="16x16" href="https://afterdarklabs.io/logo_assets/favicon-16.png">
<link rel="apple-touch-icon" sizes="180x180" href="https://afterdarklabs.io/logo_assets/apple-touch-icon.png">
<link rel="manifest" href="https://afterdarklabs.io/site.webmanifest">
- <title>South Florida Website Design and Development | After Dark Labs</title>
- <meta name="description" content="Florida website design and development from After Dark Labs. Custom business websites, Shopify stores, apps, SEO, hosting, and integrations. Free demo in 24 hours.">
- <meta name="robots" content="index,follow">
+ <title>Website Design & Development in South Florida | After Dark Labs</title>
+ <meta name="description" content="South Florida website design and development for custom websites, Shopify stores, mobile apps, SaaS platforms, APIs, AI integrations, and business tools.">
+ <meta name="robots" content="index,follow,max-image-preview:large">
<link rel="canonical" href="https://afterdarklabs.io/">
- <meta property="og:title" content="Website Design and Development | After Dark Labs Florida">
- <meta property="og:description" content="Florida website design and development for businesses that need custom websites, Shopify stores, mobile apps, internal tools, SEO, hosting, and integrations.">
+ <meta property="og:title" content="Website Design & Development in South Florida | After Dark Labs">
+ <meta property="og:description" content="South Florida website design and development for custom websites, Shopify stores, mobile apps, SaaS platforms, APIs, AI integrations, and business tools.">
<meta property="og:image" content="https://afterdarklabs.io/twitter-card.png?v=3">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
@@ -22,9 +22,10 @@
<meta property="og:type" content="website">
<meta property="og:url" content="https://afterdarklabs.io/">
<meta property="og:site_name" content="After Dark Labs">
+ <meta property="og:locale" content="en_US">
<meta name="twitter:card" content="summary_large_image">
- <meta name="twitter:title" content="Website Design and Development | After Dark Labs Florida">
- <meta name="twitter:description" content="Florida website design and development for custom websites, Shopify stores, apps, SEO, hosting, and integrations.">
+ <meta name="twitter:title" content="Website Design & Development in South Florida | After Dark Labs">
+ <meta name="twitter:description" content="South Florida website design and development for custom websites, Shopify stores, mobile apps, SaaS platforms, APIs, AI integrations, and business tools.">
<meta name="twitter:image" content="https://afterdarklabs.io/twitter-card.png?v=3">
<meta name="twitter:image:alt" content="After Dark Labs websites and tools that help businesses stand out">
<link rel="stylesheet" href="https://afterdarklabs.io/index.tailwind.css?v=4">
@@ -138,6 +139,70 @@
z-index: 1;
}
+ .hero-ticker {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 3;
+ overflow: hidden;
+ border-top: 1px solid rgba(255,255,255,0.14);
+ background: rgba(var(--page-bg-rgb),0.92);
+ outline: none;
+ }
+
+ .hero-ticker:focus-visible {
+ border-top-color: var(--neon);
+ box-shadow: inset 0 2px 0 var(--neon);
+ }
+
+ .hero-ticker-track {
+ display: flex;
+ width: max-content;
+ animation: hero-ticker-scroll 70s linear infinite;
+ will-change: transform;
+ }
+
+ .hero-ticker:hover .hero-ticker-track,
+ .hero-ticker:focus-within .hero-ticker-track {
+ animation-play-state: paused;
+ }
+
+ .hero-ticker-group {
+ display: flex;
+ flex: none;
+ align-items: center;
+ gap: 1.25rem;
+ margin: 0;
+ padding: 1.15rem 0.625rem 1.15rem 1.875rem;
+ list-style: none;
+ white-space: nowrap;
+ }
+
+ .hero-ticker-item {
+ display: inline-flex;
+ align-items: center;
+ gap: 1.25rem;
+ color: #f3f4f6;
+ font-size: 0.95rem;
+ font-weight: 600;
+ letter-spacing: 0;
+ }
+
+ .hero-ticker-item::after {
+ content: "";
+ width: 0.35rem;
+ height: 0.35rem;
+ flex: none;
+ border-radius: 50%;
+ background: var(--neon);
+ box-shadow: 0 0 0.5rem rgba(204,255,0,0.3);
+ }
+
+ @keyframes hero-ticker-scroll {
+ to { transform: translate3d(-50%, 0, 0); }
+ }
+
@keyframes neon-letter-flicker {
0%, 4.8%, 5.4%, 5.9%, 37.5%, 38%, 38.6%, 100% {
opacity: 1;
@@ -167,68 +232,93 @@
.neon-letter--flicker {
animation: none;
}
+
+ .hero-ticker {
+ overflow-x: auto;
+ }
+
+ .hero-ticker-track {
+ animation: none;
+ transform: none;
+ will-change: auto;
+ }
+
+ .hero-ticker-group[aria-hidden="true"] {
+ display: none;
+ }
}
- nav a[data-nav-link][aria-current="page"] {
- color: #ccff00;
- font-weight: 600;
+ .work-stage {
+ padding-block: 5rem 5.5rem;
}
- .work-pagination {
- display: none;
+ .work-scroll-ready .work-stage {
+ position: sticky;
+ top: 0;
+ display: flex;
+ height: 100svh;
+ min-height: 34rem;
align-items: center;
- justify-content: center;
- flex-shrink: 0;
+ overflow: hidden;
+ box-sizing: border-box;
+ padding-top: clamp(6rem, 12svh, 8rem);
+ padding-bottom: clamp(2.5rem, 8svh, 5rem);
}
- .work-pagination-dot {
- display: grid;
- width: 1.75rem;
- height: 1.75rem;
- place-items: center;
- border-radius: 9999px;
- color: rgba(255,255,255,0.32);
+ .work-stage-content {
+ width: 100%;
+ min-width: 0;
}
- .work-pagination-dot::before {
- content: "";
- width: 0.425rem;
- height: 0.425rem;
- border-radius: inherit;
- background: currentColor;
- transition: color 160ms ease, transform 160ms ease, box-shadow 160ms ease;
+ #work-scroller {
+ padding-inline: 1rem;
+ scroll-padding-inline: 1rem;
}
- .work-pagination-dot:hover {
- color: rgba(255,255,255,0.72);
+ .work-scroll-ready #work-scroller {
+ overflow: visible;
+ scroll-behavior: auto;
+ touch-action: pan-y;
+ transform: translate3d(var(--work-offset, 0px), 0, 0);
+ will-change: transform;
}
- .work-pagination-dot[aria-current="true"] {
- color: var(--neon);
+ @media (min-width: 768px) {
+ #work-scroller > article {
+ width: 38rem;
+ }
}
- .work-pagination-dot[aria-current="true"]::before {
- transform: scale(1.2);
- box-shadow: 0 0 0.55rem rgba(204,255,0,0.32);
- }
+ @media (prefers-reduced-motion: reduce) {
+ .work-scroll-ready {
+ height: auto !important;
+ }
- .work-pagination-dot:focus-visible {
- outline: 2px solid var(--neon);
- outline-offset: -3px;
- }
+ .work-scroll-ready .work-stage {
+ position: relative;
+ height: auto;
+ min-height: 0;
+ overflow: visible;
+ padding-block: 5rem 5.5rem;
+ }
- @media (min-width: 768px) {
- .work-pagination {
- display: flex;
+ .work-scroll-ready #work-scroller {
+ display: grid;
+ width: auto;
+ grid-template-columns: 1fr;
+ overflow: visible;
+ transform: none !important;
+ will-change: auto;
}
- #work-scroller {
- padding-inline: max(1.5rem, calc((100% - 64rem) / 2 + 1.5rem));
- scroll-padding-inline: max(1.5rem, calc((100% - 64rem) / 2 + 1.5rem));
+ .work-scroll-ready #work-scroller > article {
+ width: auto;
}
+ }
- #work-scroller > article {
- width: 38rem;
+ @media (min-width: 768px) and (prefers-reduced-motion: reduce) {
+ .work-scroll-ready #work-scroller {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@@ -252,13 +342,14 @@
"@type": "Country",
"name": "United States"
},
- "description": "After Dark Labs provides South Florida website design and development for custom business websites, Shopify stores, mobile apps, internal tools, SEO foundations, hosting setup, logo design, backend APIs, and integrations."
+ "description": "After Dark Labs provides South Florida website design and development for custom websites, Shopify stores, mobile apps, SaaS platforms, APIs, AI integrations, branding, hosting, and business tools."
},
{
"@type": "WebSite",
"@id": "https://afterdarklabs.io/#website",
"url": "https://afterdarklabs.io/",
"name": "After Dark Labs",
+ "alternateName": "After Dark Labs Florida",
"publisher": {
"@id": "https://afterdarklabs.io/#organization"
},
@@ -266,8 +357,9 @@
},
{
"@type": "Service",
- "@id": "https://afterdarklabs.io/#custom-web-app-service",
- "name": "Custom website, Shopify store, and mobile app development",
+ "@id": "https://afterdarklabs.io/#digital-services",
+ "name": "Website, ecommerce, app, and business software development",
+ "description": "Custom websites, ecommerce stores, mobile apps, SaaS platforms, branding, hosting, APIs, AI chatbots, and intelligent automation.",
"provider": {
"@id": "https://afterdarklabs.io/#organization"
},
@@ -276,11 +368,13 @@
"name": "United States"
},
"serviceType": [
- "Business website development",
- "Shopify store development",
+ "Custom website design and development",
+ "Shopify and ecommerce development",
"Mobile app development",
- "Internal tool development",
- "SEO and hosting setup"
+ "Custom platforms, dashboards, and API integrations",
+ "Brand identity and digital marketing",
+ "Hosting and business technology",
+ "AI integrations, chatbots, and intelligent automation"
],
"url": "https://afterdarklabs.io/"
}
@@ -292,39 +386,25 @@
<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">
+ <a href="#hero" 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-label="Go to top">
<img src="https://afterdarklabs.io/logo_assets/mark.svg" width="48" height="48" alt="" aria-hidden="true">
<span class="min-w-0">
<span class="logo-font block truncate text-xl font-semibold tracking-tighter">After Dark</span>
<span class="logo-font -mt-1 block text-xs tracking-[3px] text-[#ccff00]">LABS</span>
</span>
- </button>
- <a href="https://cal.com/afterdarklabs/meet" target="_blank" rel="noopener noreferrer" class="shrink-0 rounded-2xl bg-[#ccff00] px-4 py-3 text-sm font-semibold text-black transition-colors hover:bg-white">Book a Consultation</a>
+ </a>
+ <a href="mailto:[email protected]" target="_blank" rel="noopener noreferrer" class="shrink-0 rounded-2xl bg-[#ccff00] px-4 py-3 text-sm font-semibold text-black transition-colors hover:bg-white">Let's Talk</a>
</div>
<div class="hidden items-center justify-between lg:flex">
- <a href="https://afterdarklabs.io/" class="flex items-center gap-3">
+ <a href="#hero" class="flex items-center gap-3" aria-label="Go to top">
<img src="https://afterdarklabs.io/logo_assets/mark.svg" width="48" height="48" alt="" aria-hidden="true">
<div>
<span class="logo-font block text-2xl font-semibold tracking-tighter">After Dark</span>
<span class="logo-font -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="https://afterdarklabs.io/#work" class="transition-colors hover:text-[#ccff00]" data-nav-link>Portfolio</a>
- <a href="https://afterdarklabs.io/#services" class="transition-colors hover:text-[#ccff00]" data-nav-link>Services</a>
- </div>
- <a href="https://cal.com/afterdarklabs/meet" target="_blank" rel="noopener noreferrer" class="rounded-2xl bg-[#ccff00] px-6 py-3 font-semibold text-black transition-colors hover:bg-white">Book a Consultation</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="https://afterdarklabs.io/#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="https://afterdarklabs.io/#work" class="rounded-2xl px-4 py-3 text-gray-200 transition-colors hover:bg-white/10 hover:text-[#ccff00]" data-nav-link>Portfolio</a>
- <a href="https://afterdarklabs.io/#services" class="rounded-2xl px-4 py-3 text-gray-200 transition-colors hover:bg-white/10 hover:text-[#ccff00]" data-nav-link>Services</a>
- </div>
+ <a href="mailto:[email protected]" target="_blank" rel="noopener noreferrer" class="rounded-2xl bg-[#ccff00] px-6 py-3 font-semibold text-black transition-colors hover:bg-white">Let's Talk</a>
</div>
</div>
</nav>
@@ -333,29 +413,73 @@
<section id="hero" class="hero-bg min-h-screen flex items-center pt-20" style="position:relative; overflow:hidden;">
<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 class="hero-content mx-auto grid w-full max-w-7xl justify-items-center gap-10 px-6 py-32 text-center">
<div>
<h1 class="heading text-7xl font-bold leading-none tracking-tighter md:text-8xl lg:text-7xl xl:text-8xl">
- Websites and tools that help businesses<br><span class="neon-text" aria-hidden="true"><span class="neon-letter neon-letter--flicker" data-letter="s" style="--flicker-delay:-1.1s; --flicker-duration:11s;">s</span><span class="neon-letter" data-letter="t">t</span><span class="neon-letter neon-letter--flicker" data-letter="a" style="--flicker-delay:-5.6s; --flicker-duration:13s;">a</span><span class="neon-letter" data-letter="n">n</span><span class="neon-letter neon-letter--flicker" data-letter="d" style="--flicker-delay:-8.4s; --flicker-duration:15s;">d</span><span class="neon-gap"></span><span class="neon-letter" data-letter="o">o</span><span class="neon-letter neon-letter--flicker" data-letter="u" style="--flicker-delay:-3.3s; --flicker-duration:12s;">u</span><span class="neon-letter" data-letter="t">t</span></span><span class="sr-only">stand out</span>
+ Websites and tools that help businesses <span class="neon-text" aria-hidden="true"><span class="neon-letter neon-letter--flicker" data-letter="s" style="--flicker-delay:-1.1s; --flicker-duration:11s;">s</span><span class="neon-letter" data-letter="t">t</span><span class="neon-letter neon-letter--flicker" data-letter="a" style="--flicker-delay:-5.6s; --flicker-duration:13s;">a</span><span class="neon-letter" data-letter="n">n</span><span class="neon-letter neon-letter--flicker" data-letter="d" style="--flicker-delay:-8.4s; --flicker-duration:15s;">d</span><span class="neon-gap"></span><span class="neon-letter" data-letter="o">o</span><span class="neon-letter neon-letter--flicker" data-letter="u" style="--flicker-delay:-3.3s; --flicker-duration:12s;">u</span><span class="neon-letter" data-letter="t">t</span></span><span class="sr-only">stand out</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="https://cal.com/afterdarklabs/meet" target="_blank" rel="noopener noreferrer" 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">
- Book a Consultation
- </a>
- </div>
+ </div>
+
+ <div class="hero-ticker" role="region" aria-label="Services" tabindex="0">
+ <div class="hero-ticker-track">
+ <ul class="hero-ticker-group" aria-label="Services offered">
+ <li class="hero-ticker-item">Custom Websites</li>
+ <li class="hero-ticker-item">Website Redesigns</li>
+ <li class="hero-ticker-item">Shopify Stores</li>
+ <li class="hero-ticker-item">Subscription Platforms</li>
+ <li class="hero-ticker-item">iOS/Android Apps</li>
+ <li class="hero-ticker-item">Customer Portals</li>
+ <li class="hero-ticker-item">Dashboards</li>
+ <li class="hero-ticker-item">Internal Tools</li>
+ <li class="hero-ticker-item">APIs</li>
+ <li class="hero-ticker-item">SaaS MVPs</li>
+ <li class="hero-ticker-item">Logo Design</li>
+ <li class="hero-ticker-item">Brand Identity</li>
+ <li class="hero-ticker-item">Local Search/AI Rankings</li>
+ <li class="hero-ticker-item">Lead Capture</li>
+ <li class="hero-ticker-item">Social Media Marketing</li>
+ <li class="hero-ticker-item">Hosting</li>
+ <li class="hero-ticker-item">Domains</li>
+ <li class="hero-ticker-item">Business Email</li>
+ <li class="hero-ticker-item">Voice AI</li>
+ <li class="hero-ticker-item">LLM Integrations</li>
+ <li class="hero-ticker-item">AI Chatbots</li>
+ <li class="hero-ticker-item">Intelligent Automation</li>
+ </ul>
+ <ul class="hero-ticker-group" aria-hidden="true">
+ <li class="hero-ticker-item">Custom Websites</li>
+ <li class="hero-ticker-item">Website Redesigns</li>
+ <li class="hero-ticker-item">Shopify Stores</li>
+ <li class="hero-ticker-item">Subscription Platforms</li>
+ <li class="hero-ticker-item">iOS/Android Apps</li>
+ <li class="hero-ticker-item">Customer Portals</li>
+ <li class="hero-ticker-item">Dashboards</li>
+ <li class="hero-ticker-item">Internal Tools</li>
+ <li class="hero-ticker-item">APIs</li>
+ <li class="hero-ticker-item">SaaS MVPs</li>
+ <li class="hero-ticker-item">Logo Design</li>
+ <li class="hero-ticker-item">Brand Identity</li>
+ <li class="hero-ticker-item">Local Search/AI Rankings</li>
+ <li class="hero-ticker-item">Lead Capture</li>
+ <li class="hero-ticker-item">Social Media Marketing</li>
+ <li class="hero-ticker-item">Hosting</li>
+ <li class="hero-ticker-item">Domains</li>
+ <li class="hero-ticker-item">Business Email</li>
+ <li class="hero-ticker-item">Voice AI</li>
+ <li class="hero-ticker-item">LLM Integrations</li>
+ <li class="hero-ticker-item">AI Chatbots</li>
+ <li class="hero-ticker-item">Intelligent Automation</li>
+ </ul>
</div>
</div>
</section>
- <section id="work" class="scroll-mt-24 border-t border-white/10 bg-black">
- <div class="py-20 md:py-24">
- <div class="mx-auto mb-10 flex max-w-5xl items-end justify-between gap-6 px-6">
- <h2 class="heading text-4xl font-semibold tracking-tighter md:text-6xl">Recent projects</h2>
- <div id="work-pagination" class="work-pagination" role="group" aria-label="Choose a portfolio project"></div>
- </div>
- <div id="work-scroller" class="no-scrollbar flex snap-x snap-mandatory gap-5 overflow-x-auto scroll-smooth px-6 pb-2 scroll-px-6">
+ <section id="work" class="scroll-mt-24 border-t border-white/10 bg-black" aria-labelledby="work-heading">
+ <h2 id="work-heading" class="sr-only">Selected website and software projects</h2>
+ <div class="work-stage">
+ <div class="work-stage-content">
+ <div id="work-scroller" class="no-scrollbar flex snap-x snap-mandatory gap-5 overflow-x-auto scroll-smooth pb-2">
<article class="w-[82vw] shrink-0 snap-start overflow-hidden rounded-3xl bg-zinc-950 sm:w-[28rem] md:w-[38rem]">
<a href="https://voldservices.com" target="_blank" rel="noopener noreferrer" class="block w-full 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]" aria-label="Visit Vold Services website">
<img src="voldservices.webp" width="1200" height="702" loading="lazy" decoding="async" class="aspect-video w-full object-cover" alt="Vold Services exterior cleaning website with a scroll-animated hero, designed by After Dark Labs">
@@ -453,32 +577,6 @@
</div>
</article>
</div>
- </div>
- </section>
-
- <section id="services" 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">
- <h2 class="heading text-4xl font-semibold leading-none tracking-tighter md:text-6xl">Technology built around your business</h2>
- <div class="mt-10">
- <div class="grid gap-6 sm:grid-cols-2 md:gap-7">
- <div class="px-6 py-7 md:px-7 md:py-8">
- <h3 class="text-lg font-semibold leading-tight text-[#ccff00]">Websites & E-commerce</h3>
- <p class="mt-3 text-base leading-7 text-gray-300">Custom websites, website redesigns, Shopify stores & subscription platforms</p>
- </div>
- <div class="px-6 py-7 md:px-7 md:py-8">
- <h3 class="text-lg font-semibold leading-tight text-[#ccff00]">Apps & Custom Platforms</h3>
- <p class="mt-3 text-base leading-7 text-gray-300">iOS/Android apps, customer portals, internal tools, APIs & SaaS MVPs</p>
- </div>
- <div class="px-6 py-7 md:px-7 md:py-8">
- <h3 class="text-lg font-semibold leading-tight text-[#ccff00]">Branding & Marketing</h3>
- <p class="mt-3 text-base leading-7 text-gray-300">Logo design, brand identity, local search/AI rankings, lead capture & social media marketing</p>
- </div>
- <div class="px-6 py-7 md:px-7 md:py-8">
- <h3 class="text-lg font-semibold leading-tight text-[#ccff00]">Infrastructure & AI</h3>
- <p class="mt-3 text-base leading-7 text-gray-300">Hosting, domains, business email, voice AI, LLM integrations, & intelligent automation</p>
- </div>
- </div>
- <p class="mt-7 max-w-3xl text-sm leading-6 text-gray-400">Simple business websites typically range from $500–$2,000 as a one-time fee. Shopify stores, apps, and custom tools are quoted based on scope. Hosting is included for most service business websites, which means no monthly website fees.</p>
</div>
</div>
</section>
@@ -501,164 +599,76 @@
<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[data-nav-link]').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 section = document.getElementById('work');
+ const stage = section?.querySelector('.work-stage');
const scroller = document.getElementById('work-scroller');
- const pagination = document.getElementById('work-pagination');
- if (!scroller || !pagination) return;
+ if (!section || !stage || !scroller) return;
const cards = Array.from(scroller.querySelectorAll(':scope > article'));
if (!cards.length) return;
const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
- const dots = cards.map((card, index) => {
- const dot = document.createElement('button');
- const projectName = card.querySelector('.p-6 p')?.textContent.split('•')[0].trim() || `project ${index + 1}`;
-
- dot.type = 'button';
- dot.className = 'work-pagination-dot';
- dot.setAttribute('aria-label', `Show ${projectName} project`);
- dot.setAttribute('aria-controls', 'work-scroller');
- dot.addEventListener('click', () => {
- const maxScroll = scroller.scrollWidth - scroller.clientWidth;
- const target = Math.min(cards[index].offsetLeft - cards[0].offsetLeft, maxScroll);
- scroller.scrollTo({
- left: Math.max(0, target),
- behavior: reduceMotion.matches ? 'auto' : 'smooth'
- });
- });
-
- pagination.appendChild(dot);
- return dot;
- });
-
+ let scrollDistance = 0;
+ let sectionTop = 0;
let updateFrame = 0;
+ let resizeFrame = 0;
+ let keyboardNavigation = false;
- function updatePagination() {
+ function updateWorkPosition() {
updateFrame = 0;
- const maxScroll = scroller.scrollWidth - scroller.clientWidth;
- let activeIndex = 0;
- let closestDistance = Infinity;
-
- cards.forEach((card, index) => {
- const position = Math.min(card.offsetLeft - cards[0].offsetLeft, maxScroll);
- const distance = Math.abs(scroller.scrollLeft - Math.max(0, position));
-
- if (distance < closestDistance) {
- closestDistance = distance;
- activeIndex = index;
- }
- });
-
- dots.forEach((dot, index) => {
- const isActive = index === activeIndex;
- dot.toggleAttribute('aria-current', isActive);
- if (isActive) dot.setAttribute('aria-current', 'true');
- dot.tabIndex = isActive ? 0 : -1;
- });
- }
+ if (reduceMotion.matches || !scrollDistance) return;
- function schedulePaginationUpdate() {
- if (!updateFrame) updateFrame = window.requestAnimationFrame(updatePagination);
+ const progress = Math.min(1, Math.max(0, (window.scrollY - sectionTop) / scrollDistance));
+ scroller.style.setProperty('--work-offset', `${-(scrollDistance * progress)}px`);
}
- pagination.addEventListener('keydown', event => {
- const currentIndex = dots.indexOf(document.activeElement);
- if (currentIndex < 0) return;
-
- let nextIndex = currentIndex;
- if (event.key === 'ArrowLeft') nextIndex = Math.max(0, currentIndex - 1);
- if (event.key === 'ArrowRight') nextIndex = Math.min(dots.length - 1, currentIndex + 1);
- if (event.key === 'Home') nextIndex = 0;
- if (event.key === 'End') nextIndex = dots.length - 1;
- if (nextIndex === currentIndex && !['Home', 'End'].includes(event.key)) return;
-
- event.preventDefault();
- dots[nextIndex].focus();
- dots[nextIndex].click();
- });
-
- scroller.addEventListener('scroll', schedulePaginationUpdate, { passive: true });
- window.addEventListener('resize', schedulePaginationUpdate);
- updatePagination();
- })();
-
- (function () {
- const activeClasses = ['text-[#ccff00]', 'font-semibold'];
- const navLinks = Array.from(document.querySelectorAll('nav a[data-nav-link]'));
-
- if (!navLinks.length) return;
-
- const sections = Array.from(document.querySelectorAll('main section[id]'))
- .map(element => ({ element, href: `#${element.id}` }));
-
- function setActive(href) {
- navLinks.forEach(link => {
- const isActive = new URL(link.href).hash === 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 scheduleWorkUpdate() {
+ if (!updateFrame) updateFrame = window.requestAnimationFrame(updateWorkPosition);
}
- function updateActiveNav() {
- const offset = window.innerHeight * 0.35;
- let currentHref = '';
+ function measureWorkSection() {
+ resizeFrame = 0;
+ section.classList.add('work-scroll-ready');
- for (const section of sections) {
- if (section.element.getBoundingClientRect().top <= offset) {
- currentHref = section.href;
- }
+ if (reduceMotion.matches) {
+ section.style.removeProperty('height');
+ scroller.style.removeProperty('--work-offset');
+ scrollDistance = 0;
+ return;
}
- setActive(currentHref);
+ scrollDistance = Math.max(0, scroller.scrollWidth - stage.clientWidth);
+ section.style.height = `${Math.ceil(window.innerHeight + scrollDistance)}px`;
+ sectionTop = section.getBoundingClientRect().top + window.scrollY;
+ updateWorkPosition();
}
- function activeFromHash() {
- return sections.some(section => section.href === window.location.hash)
- ? window.location.hash
- : '';
+ function scheduleWorkMeasure() {
+ if (!resizeFrame) resizeFrame = window.requestAnimationFrame(measureWorkSection);
}
- setActive(activeFromHash());
- requestAnimationFrame(updateActiveNav);
- window.addEventListener('load', updateActiveNav);
- window.addEventListener('scroll', updateActiveNav, { passive: true });
- window.addEventListener('hashchange', () => {
- setActive(activeFromHash());
- requestAnimationFrame(updateActiveNav);
+ document.addEventListener('keydown', event => {
+ if (event.key === 'Tab') keyboardNavigation = true;
});
+ document.addEventListener('pointerdown', () => {
+ keyboardNavigation = false;
+ }, { passive: true });
+
+ scroller.addEventListener('focusin', event => {
+ if (!keyboardNavigation || reduceMotion.matches) return;
+
+ const card = event.target.closest('article');
+ if (!card) return;
+
+ const target = Math.min(card.offsetLeft - cards[0].offsetLeft, scrollDistance);
+ window.scrollTo({ top: sectionTop + Math.max(0, target), behavior: 'auto' });
+ });
+
+ window.addEventListener('scroll', scheduleWorkUpdate, { passive: true });
+ window.addEventListener('resize', scheduleWorkMeasure);
+ window.addEventListener('load', scheduleWorkMeasure);
+ reduceMotion.addEventListener('change', scheduleWorkMeasure);
+ measureWorkSection();
})();
</script>
diff --git a/docs/index3.html b/docs/index3.html
new file mode 100644
index 0000000..9cd69df
--- /dev/null
+++ b/docs/index3.html
@@ -0,0 +1,574 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width,initial-scale=1">
+ <title>South Florida Website Design & Development | After Dark Labs</title>
+ <meta name="description" content="After Dark Labs is an independent South Florida design and development studio building custom websites, Shopify stores, SaaS products, and business tools.">
+ <meta name="robots" content="index,follow">
+ <link rel="canonical" href="https://afterdarklabs.io/">
+ <meta name="theme-color" content="#111a22">
+
+ <meta property="og:title" content="After Dark Labs — Websites and tools that stand out">
+ <meta property="og:description" content="Custom websites, Shopify stores, SaaS products, and business tools from an independent South Florida studio.">
+ <meta property="og:image" content="https://afterdarklabs.io/twitter-card.png?v=3">
+ <meta property="og:type" content="website">
+ <meta property="og:url" content="https://afterdarklabs.io/">
+ <meta name="twitter:card" content="summary_large_image">
+ <meta name="twitter:title" content="After Dark Labs — Websites and tools that stand out">
+ <meta name="twitter:description" content="Custom websites, Shopify stores, SaaS products, and business tools from an independent South Florida studio.">
+ <meta name="twitter:image" content="https://afterdarklabs.io/twitter-card.png?v=3">
+
+ <link rel="icon" href="https://afterdarklabs.io/logo_assets/favicon.ico">
+ <link rel="icon" type="image/svg+xml" href="https://afterdarklabs.io/logo_assets/badge.svg">
+ <link rel="apple-touch-icon" sizes="180x180" href="https://afterdarklabs.io/logo_assets/apple-touch-icon.png">
+
+ <link rel="preconnect" href="https://fonts.googleapis.com">
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&family=Syne:wght@600;700;800&display=swap" rel="stylesheet">
+
+ <style>
+ :root {
+ --ink: #f7f8f8;
+ --muted: #9ca6ad;
+ --dim: #6f7a82;
+ --page: #111a22;
+ --page-rgb: 17, 26, 34;
+ --surface: #16232d;
+ --surface-2: #1a2934;
+ --line: rgba(255,255,255,.10);
+ --line-soft: rgba(255,255,255,.065);
+ --neon: #ccff00;
+ --max: 1240px;
+ --ease: cubic-bezier(.22,1,.36,1);
+ }
+
+ * { box-sizing: border-box; }
+ html { scroll-behavior: smooth; background: var(--page); }
+ body {
+ margin: 0;
+ color: var(--ink);
+ background:
+ radial-gradient(circle at 78% 5%, rgba(204,255,0,.055), transparent 24rem),
+ var(--page);
+ font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
+ -webkit-font-smoothing: antialiased;
+ overflow-x: hidden;
+ }
+ body::before {
+ content: "";
+ position: fixed;
+ inset: 0;
+ pointer-events: none;
+ z-index: 999;
+ opacity: .14;
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.07'/%3E%3C/svg%3E");
+ mix-blend-mode: soft-light;
+ }
+ a { color: inherit; }
+ img { display: block; width: 100%; }
+ button, a { -webkit-tap-highlight-color: transparent; }
+ ::selection { color: #101600; background: var(--neon); }
+
+ .wrap { width: min(calc(100% - 40px), var(--max)); margin-inline: auto; }
+ .display { font-family: "Space Grotesk", sans-serif; letter-spacing: -.055em; }
+ .logo-font { font-family: Syne, sans-serif; }
+ .eyebrow {
+ display: inline-flex;
+ align-items: center;
+ gap: .65rem;
+ color: var(--muted);
+ font-size: .74rem;
+ font-weight: 600;
+ letter-spacing: .16em;
+ text-transform: uppercase;
+ }
+ .eyebrow::before { content: ""; width: 1.35rem; height: 1px; background: var(--neon); }
+
+ .skip-link {
+ position: fixed; left: 1rem; top: -5rem; z-index: 2000;
+ background: var(--neon); color: #0c1200; padding: .75rem 1rem; border-radius: 999px;
+ font-weight: 700; text-decoration: none;
+ }
+ .skip-link:focus { top: 1rem; }
+
+ nav {
+ position: fixed;
+ inset: 0 0 auto;
+ z-index: 100;
+ border-bottom: 1px solid transparent;
+ transition: background-color .25s ease, border-color .25s ease, backdrop-filter .25s ease;
+ }
+ nav.scrolled {
+ background: rgba(var(--page-rgb), .82);
+ border-color: var(--line-soft);
+ backdrop-filter: blur(16px);
+ }
+ .nav-inner { min-height: 78px; display: flex; align-items: center; justify-content: space-between; gap: 2rem; }
+ .brand { display: inline-flex; align-items: center; gap: .75rem; text-decoration: none; }
+ .brand img { width: 42px; height: 42px; object-fit: contain; }
+ .brand-copy { line-height: .9; }
+ .brand-copy strong { display: block; font-size: 1.03rem; letter-spacing: -.04em; }
+ .brand-copy span { display: block; color: var(--neon); font-size: .58rem; letter-spacing: .28em; margin-top: .28rem; }
+ .nav-links { display: flex; align-items: center; gap: 1.8rem; }
+ .nav-links > a:not(.button) {
+ position: relative; color: #c8d0d5; font-size: .84rem; font-weight: 600; text-decoration: none;
+ }
+ .nav-links > a:not(.button)::after {
+ content: ""; position: absolute; left: 0; right: 100%; bottom: -.35rem; height: 1px; background: var(--neon);
+ transition: right .25s var(--ease);
+ }
+ .nav-links > a:not(.button):hover::after, .nav-links > a:not(.button):focus-visible::after { right: 0; }
+
+ .button {
+ display: inline-flex; align-items: center; justify-content: center; gap: .6rem;
+ min-height: 48px; padding: .82rem 1.3rem; border: 1px solid transparent; border-radius: 999px;
+ background: var(--neon); color: #0f1500; font-weight: 700; font-size: .86rem; text-decoration: none;
+ transition: transform .2s var(--ease), background-color .2s ease, box-shadow .2s ease;
+ }
+ .button:hover { transform: translateY(-2px); background: #fff; box-shadow: 0 0 30px rgba(204,255,0,.12); }
+ .button.secondary { background: transparent; color: var(--ink); border-color: rgba(255,255,255,.18); }
+ .button.secondary:hover { background: rgba(255,255,255,.06); box-shadow: none; }
+ .arrow { width: 1em; height: 1em; transition: transform .25s var(--ease); }
+ a:hover .arrow { transform: translate(3px,-3px); }
+
+ /* HERO */
+ .hero {
+ min-height: 100svh;
+ display: flex;
+ align-items: center;
+ padding: 150px 0 72px;
+ border-bottom: 1px solid var(--line-soft);
+ position: relative;
+ isolation: isolate;
+ }
+ .hero::after {
+ content: "";
+ position: absolute;
+ width: 28rem; height: 28rem; right: -8rem; top: 25%;
+ border-radius: 50%;
+ background: radial-gradient(circle, rgba(204,255,0,.10), rgba(204,255,0,.025) 38%, transparent 68%);
+ filter: blur(10px);
+ z-index: -1;
+ }
+ .hero-grid { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(240px,.45fr); gap: clamp(3rem,7vw,7rem); align-items: end; }
+ .hero h1 {
+ max-width: 980px;
+ margin: 1.6rem 0 0;
+ font-size: clamp(4.45rem, 9.45vw, 9.4rem);
+ line-height: .84;
+ font-weight: 700;
+ }
+ .hero h1 .line { display: block; }
+ .standout { display: inline-flex; position: relative; isolation: isolate; color: var(--neon); white-space: nowrap; }
+ .standout::before {
+ content: ""; position: absolute; inset: -.18em -.18em -.12em;
+ background: radial-gradient(ellipse at 47% 58%, rgba(204,255,0,.32), rgba(204,255,0,.10) 45%, transparent 74%);
+ filter: blur(.13em); z-index: -2; opacity: .82;
+ }
+ .neon-letter { display: inline-block; color: var(--neon); -webkit-text-stroke: .006em rgba(240,255,170,.6); filter: drop-shadow(0 0 .035em rgba(204,255,0,.6)) drop-shadow(0 0 .13em rgba(204,255,0,.22)); }
+ .neon-gap { display: inline-block; width: .20em; }
+ .neon-letter.flicker { animation: flicker var(--duration,13s) steps(1,end) infinite; animation-delay: var(--delay,0s); }
+ @keyframes flicker {
+ 0%, 5%, 5.7%, 38%, 38.7%, 100% { opacity: 1; filter: drop-shadow(0 0 .035em rgba(204,255,0,.62)) drop-shadow(0 0 .13em rgba(204,255,0,.22)); }
+ 5.15%, 38.15% { opacity: .07; filter: none; }
+ 5.43%, 38.43% { opacity: .37; filter: drop-shadow(0 0 .02em rgba(204,255,0,.25)); }
+ }
+ .hero-side { padding-bottom: .55rem; }
+ .hero-side p { margin: 0 0 1.75rem; color: #c6cdd2; font-size: clamp(1.05rem,1.5vw,1.25rem); line-height: 1.55; }
+ .hero-actions { display: flex; flex-wrap: wrap; gap: .7rem; }
+ .hero-meta {
+ margin-top: 4rem; padding-top: 1.2rem; border-top: 1px solid var(--line);
+ display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 1.2rem;
+ color: var(--muted); font-size: .78rem; line-height: 1.5;
+ }
+ .hero-meta strong { display: block; color: var(--ink); font-size: .82rem; margin-bottom: .15rem; }
+
+ /* WORK */
+ .section { padding: clamp(5.5rem,9vw,9rem) 0; border-bottom: 1px solid var(--line-soft); }
+ .section-head { display: flex; align-items: end; justify-content: space-between; gap: 2rem; margin-bottom: 3.2rem; }
+ .section-head h2 { margin: .65rem 0 0; font-size: clamp(3rem,5.7vw,5.8rem); line-height: .93; font-weight: 600; }
+ .section-head p { max-width: 500px; margin: 0; color: var(--muted); line-height: 1.65; }
+
+ .projects { display: grid; gap: 6.5rem; }
+ .project {
+ display: grid;
+ grid-template-columns: minmax(0,1.55fr) minmax(260px,.45fr);
+ gap: clamp(2rem,5vw,5rem);
+ align-items: end;
+ }
+ .project:nth-child(even) { grid-template-columns: minmax(260px,.45fr) minmax(0,1.55fr); }
+ .project:nth-child(even) .project-media { order: 2; }
+ .project:nth-child(even) .project-copy { order: 1; }
+ .project-media {
+ position: relative; overflow: hidden; border-radius: 26px;
+ background: var(--surface); border: 1px solid var(--line-soft);
+ aspect-ratio: 16 / 10;
+ transform: translateZ(0);
+ }
+ .project-media::after {
+ content: ""; position: absolute; inset: 0; border: 1px solid rgba(255,255,255,.05); border-radius: inherit; pointer-events: none;
+ }
+ .project-media img { width: 100%; height: 100%; object-fit: cover; transition: transform .7s var(--ease), filter .5s ease; }
+ .project:hover .project-media img { transform: scale(1.025); }
+ .project-index { color: var(--neon); font-size: .71rem; letter-spacing: .14em; font-weight: 700; }
+ .project-copy h3 { margin: .75rem 0 .8rem; font: 600 clamp(2rem,4vw,3.75rem)/.98 "Space Grotesk", sans-serif; letter-spacing: -.05em; }
+ .project-copy p { margin: 0; color: var(--muted); font-size: .98rem; line-height: 1.7; }
+ .project-tags { display: flex; flex-wrap: wrap; gap: .4rem; margin: 1.25rem 0 1.7rem; }
+ .tag { padding: .42rem .68rem; border: 1px solid var(--line); border-radius: 999px; color: #c7ced3; font-size: .69rem; }
+ .text-link { display: inline-flex; align-items: center; gap: .45rem; color: var(--ink); font-size: .83rem; font-weight: 700; text-decoration: none; }
+ .text-link span { border-bottom: 1px solid rgba(255,255,255,.32); padding-bottom: .16rem; }
+
+ .lab-strip {
+ margin-top: 7rem;
+ display: grid;
+ grid-template-columns: .7fr 1.3fr;
+ gap: 3rem;
+ border-top: 1px solid var(--line);
+ padding-top: 2.25rem;
+ }
+ .lab-strip h3 { margin: 0; font: 600 clamp(2rem,3.4vw,3.25rem)/1 "Space Grotesk",sans-serif; letter-spacing: -.05em; }
+ .lab-list { border-top: 1px solid var(--line); }
+ .lab-item {
+ display: grid; grid-template-columns: 1fr auto; gap: 1rem; align-items: center;
+ padding: 1.1rem 0; border-bottom: 1px solid var(--line); text-decoration: none;
+ }
+ .lab-item strong { display: block; margin-bottom: .25rem; font-size: .95rem; }
+ .lab-item span { color: var(--muted); font-size: .78rem; }
+ .lab-item .go { color: var(--neon); font-size: 1.15rem; transition: transform .2s var(--ease); }
+ .lab-item:hover .go { transform: translate(4px,-4px); }
+
+ /* CAPABILITIES */
+ .cap-grid { display: grid; grid-template-columns: .8fr 1.2fr; gap: clamp(3rem,8vw,8rem); }
+ .cap-intro h2 { margin: .75rem 0 1.5rem; font-size: clamp(3rem,5.4vw,5.4rem); line-height: .95; font-weight: 600; }
+ .cap-intro p { margin: 0; max-width: 460px; color: var(--muted); line-height: 1.7; }
+ .cap-list { border-top: 1px solid var(--line); }
+ .cap-row {
+ display: grid; grid-template-columns: 2.4rem .72fr 1.28fr; gap: 1.3rem;
+ padding: 1.55rem 0; border-bottom: 1px solid var(--line); align-items: start;
+ }
+ .cap-row .num { color: var(--neon); font-size: .72rem; padding-top: .28rem; }
+ .cap-row h3 { margin: 0; font-size: 1rem; font-weight: 650; }
+ .cap-row p { margin: 0; color: var(--muted); line-height: 1.55; font-size: .88rem; }
+ .price-note { margin-top: 1.7rem; color: var(--dim); font-size: .77rem; line-height: 1.6; }
+ .price-note strong { color: #cbd2d6; font-weight: 600; }
+
+ /* STUDIO */
+ .studio { position: relative; overflow: hidden; }
+ .studio::before {
+ content: "ADL";
+ position: absolute; right: -1vw; bottom: -4.2vw;
+ font: 800 min(31vw,440px)/.7 Syne,sans-serif; letter-spacing: -.09em;
+ color: rgba(255,255,255,.025); pointer-events: none;
+ }
+ .studio-grid { display: grid; grid-template-columns: 1.15fr .85fr; gap: clamp(3rem,8vw,8rem); align-items: end; position: relative; z-index: 1; }
+ .studio h2 { margin: .75rem 0 1.5rem; font-size: clamp(3.3rem,6vw,6.1rem); line-height: .92; font-weight: 600; max-width: 800px; }
+ .studio-copy { color: #c4cbd0; font-size: clamp(1.05rem,1.5vw,1.25rem); line-height: 1.7; max-width: 800px; }
+ .studio-facts { display: grid; gap: 0; border-top: 1px solid var(--line); }
+ .fact { display: flex; justify-content: space-between; gap: 1.5rem; padding: 1rem 0; border-bottom: 1px solid var(--line); font-size: .8rem; }
+ .fact span:first-child { color: var(--muted); }
+ .fact span:last-child { text-align: right; color: #d6dcdf; }
+
+ /* CTA */
+ .cta { padding: clamp(6rem,12vw,11rem) 0; }
+ .cta-inner { display: grid; grid-template-columns: 1.5fr .5fr; gap: 3rem; align-items: end; }
+ .cta h2 { margin: 0; max-width: 970px; font-size: clamp(4rem,8.2vw,8rem); line-height: .85; font-weight: 650; }
+ .cta h2 span { color: var(--neon); }
+ .cta-side p { color: var(--muted); line-height: 1.65; margin: 0 0 1.5rem; }
+
+ footer { border-top: 1px solid var(--line-soft); padding: 2.2rem 0 2.5rem; }
+ .footer-grid { display: flex; align-items: center; justify-content: space-between; gap: 2rem; color: var(--dim); font-size: .76rem; }
+ .footer-links { display: flex; flex-wrap: wrap; gap: 1rem; }
+ .footer-links a { color: #a8b1b7; text-decoration: none; }
+ .footer-links a:hover { color: var(--neon); }
+
+ .reveal { opacity: 0; transform: translateY(26px); transition: opacity .75s var(--ease), transform .75s var(--ease); }
+ .reveal.in { opacity: 1; transform: none; }
+
+ @media (max-width: 900px) {
+ .nav-links > a:not(.button) { display: none; }
+ .hero-grid, .project, .project:nth-child(even), .cap-grid, .studio-grid, .cta-inner, .lab-strip { grid-template-columns: 1fr; }
+ .project:nth-child(even) .project-media, .project:nth-child(even) .project-copy { order: initial; }
+ .hero { padding-top: 125px; }
+ .hero-side { max-width: 620px; }
+ .hero-meta { margin-top: 2.6rem; }
+ .project { gap: 1.7rem; }
+ .projects { gap: 5rem; }
+ .project-copy { max-width: 620px; }
+ .cap-grid { gap: 3rem; }
+ .studio-grid { gap: 3rem; }
+ .cta-side { max-width: 500px; }
+ }
+
+ @media (max-width: 620px) {
+ .wrap { width: min(calc(100% - 28px), var(--max)); }
+ .nav-inner { min-height: 68px; }
+ .brand img { width: 38px; height: 38px; }
+ .brand-copy strong { font-size: .94rem; }
+ .nav-links { gap: .6rem; }
+ .nav-links .button { min-height: 42px; padding: .7rem .95rem; font-size: .76rem; }
+ .hero { min-height: auto; padding: 128px 0 70px; }
+ .hero h1 { font-size: clamp(4rem,18.6vw,6.3rem); }
+ .hero-meta { grid-template-columns: 1fr; gap: .7rem; }
+ .hero-meta div { padding-bottom: .75rem; border-bottom: 1px solid var(--line-soft); }
+ .section-head { display: block; }
+ .section-head p { margin-top: 1.25rem; }
+ .project-media { border-radius: 18px; aspect-ratio: 4/3; }
+ .cap-row { grid-template-columns: 2rem 1fr; }
+ .cap-row p { grid-column: 2; margin-top: -.55rem; }
+ .footer-grid { align-items: flex-start; flex-direction: column; gap: 1rem; }
+ }
+
+ @media (prefers-reduced-motion: reduce) {
+ html { scroll-behavior: auto; }
+ *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
+ .reveal { opacity: 1; transform: none; }
+ }
+ </style>
+
+ <script type="application/ld+json">
+ {
+ "@context":"https://schema.org",
+ "@type":"Organization",
+ "name":"After Dark Labs",
+ "url":"https://afterdarklabs.io/",
+ "logo":"https://afterdarklabs.io/logo_assets/icon-512.png",
+ "description":"Independent South Florida design and development studio building custom websites, Shopify stores, SaaS products, and business tools.",
+ "areaServed":"United States"
+ }
+ </script>
+</head>
+<body>
+ <a class="skip-link" href="#main">Skip to content</a>
+
+ <nav id="nav" aria-label="Primary navigation">
+ <div class="wrap nav-inner">
+ <a class="brand" href="#top" aria-label="After Dark Labs home">
+ <img src="https://afterdarklabs.io/logo_assets/mark.svg" alt="" width="42" height="42">
+ <span class="brand-copy logo-font">
+ <strong>After Dark</strong>
+ <span>LABS</span>
+ </span>
+ </a>
+ <div class="nav-links">
+ <a href="#work">Work</a>
+ <a href="#capabilities">Capabilities</a>
+ <a href="#studio">Studio</a>
+ <a class="button" href="https://cal.com/afterdarklabs/meet" target="_blank" rel="noopener noreferrer">Book a consultation</a>
+ </div>
+ </div>
+ </nav>
+
+ <main id="main">
+ <section class="hero" id="top">
+ <div class="wrap">
+ <div class="hero-grid">
+ <div>
+ <div class="eyebrow">Independent design + development studio</div>
+ <h1 class="display">
+ <span class="line">Websites and tools</span>
+ <span class="line">that help businesses</span>
+ <span class="line standout" aria-hidden="true">
+ <span class="neon-letter flicker" style="--delay:-1.1s;--duration:11s">s</span><span class="neon-letter">t</span><span class="neon-letter flicker" style="--delay:-5.6s;--duration:13s">a</span><span class="neon-letter">n</span><span class="neon-letter flicker" style="--delay:-8.4s;--duration:15s">d</span><span class="neon-gap"></span><span class="neon-letter">o</span><span class="neon-letter flicker" style="--delay:-3.3s;--duration:12s">u</span><span class="neon-letter">t</span>
+ </span>
+ <span class="line" style="position:absolute;clip:rect(0,0,0,0);width:1px;height:1px;overflow:hidden">stand out</span>
+ </h1>
+ </div>
+
+ <aside class="hero-side">
+ <p>Custom websites, Shopify stores, SaaS products and internal tools—designed and built without templates, page builders or agency bloat.</p>
+ <div class="hero-actions">
+ <a class="button" href="https://cal.com/afterdarklabs/meet" target="_blank" rel="noopener noreferrer">Book a consultation
+ <svg class="arrow" viewBox="0 0 20 20" fill="none" aria-hidden="true"><path d="M5 15 15 5M7 5h8v8" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg>
+ </a>
+ <a class="button secondary" href="#work">View selected work</a>
+ </div>
+ </aside>
+ </div>
+
+ <div class="hero-meta" aria-label="Studio facts">
+ <div><strong>South Florida</strong>Lighthouse Point, FL</div>
+ <div><strong>Design + development</strong>One studio, one point of contact</div>
+ <div><strong>Built custom</strong>Fast, lean and made for the business</div>
+ </div>
+ </div>
+ </section>
+
+ <section class="section" id="work">
+ <div class="wrap">
+ <header class="section-head reveal">
+ <div>
+ <div class="eyebrow">Selected work</div>
+ <h2 class="display">The work does<br>the talking.</h2>
+ </div>
+ <p>A mix of service businesses, e-commerce, SaaS and internal software. Different problems, same standard: clear thinking and clean execution.</p>
+ </header>
+
+ <div class="projects">
+ <article class="project reveal">
+ <a class="project-media" href="https://voldservices.com" target="_blank" rel="noopener noreferrer" aria-label="Visit Vold Services website">
+ <img src="https://afterdarklabs.io/voldservices.webp" alt="Vold Services website by After Dark Labs" loading="lazy" width="1200" height="702">
+ </a>
+ <div class="project-copy">
+ <div class="project-index">01 / VOLD SERVICES</div>
+ <h3>Making exterior cleaning feel premium.</h3>
+ <p>A conversion-focused service site built around a scroll-driven hero, clear offer hierarchy and the kind of polish that makes a local business look established before the first call.</p>
+ <div class="project-tags"><span class="tag">Web design</span><span class="tag">Development</span><span class="tag">Motion</span></div>
+ <a class="text-link" href="https://voldservices.com" target="_blank" rel="noopener noreferrer"><span>Visit live site</span><svg class="arrow" viewBox="0 0 20 20" fill="none" aria-hidden="true"><path d="M5 15 15 5M7 5h8v8" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg></a>
+ </div>
+ </article>
+
+ <article class="project reveal">
+ <a class="project-media" href="https://frontlineboats.com" target="_blank" rel="noopener noreferrer" aria-label="Visit Frontline Boat Services website">
+ <img src="https://afterdarklabs.io/frontlineboats.webp?v=1" alt="Frontline Boat Services website by After Dark Labs" loading="lazy" width="1200" height="700">
+ </a>
+ <div class="project-copy">
+ <div class="project-index">02 / FRONTLINE BOAT SERVICES</div>
+ <h3>A marine brand with some horsepower.</h3>
+ <p>A sharp, high-contrast site for a South Florida marine shop—built to organize a broad service offering, communicate technical expertise and perform in local search.</p>
+ <div class="project-tags"><span class="tag">Brand direction</span><span class="tag">Web design</span><span class="tag">Local SEO</span></div>
+ <a class="text-link" href="https://frontlineboats.com" target="_blank" rel="noopener noreferrer"><span>Visit live site</span><svg class="arrow" viewBox="0 0 20 20" fill="none" aria-hidden="true"><path d="M5 15 15 5M7 5h8v8" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg></a>
+ </div>
+ </article>
+
+ <article class="project reveal">
+ <a class="project-media" href="https://vegy.app/" target="_blank" rel="noopener noreferrer" aria-label="Visit Vegy website">
+ <img src="https://afterdarklabs.io/vegy.webp?v=1" alt="Vegy wholesale ordering platform by After Dark Labs" loading="lazy" width="1200" height="702">
+ </a>
+ <div class="project-copy">
+ <div class="project-index">03 / VEGY</div>
+ <h3>Wholesale ordering, rebuilt from the workflow up.</h3>
+ <p>A white-label ordering platform for produce wholesalers with role-based experiences, live order updates, operational tools and accounting integrations—software designed around how the business actually runs.</p>
+ <div class="project-tags"><span class="tag">Product design</span><span class="tag">Web app</span><span class="tag">Backend systems</span></div>
+ <a class="text-link" href="https://vegy.app/" target="_blank" rel="noopener noreferrer"><span>Visit product site</span><svg class="arrow" viewBox="0 0 20 20" fill="none" aria-hidden="true"><path d="M5 15 15 5M7 5h8v8" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg></a>
+ </div>
+ </article>
+
+ <article class="project reveal">
+ <a class="project-media" href="https://coralvibefl.com" target="_blank" rel="noopener noreferrer" aria-label="Visit Coral Vibe website">
+ <img src="https://afterdarklabs.io/coralvibe.webp?v=1" alt="Coral Vibe Shopify store by After Dark Labs" loading="lazy" width="1200" height="678">
+ </a>
+ <div class="project-copy">
+ <div class="project-index">04 / CORAL VIBE</div>
+ <h3>E-commerce that lets the product be the color.</h3>
+ <p>A custom Shopify storefront for a coral retailer, balancing dense product information with a clean visual system that keeps browsing, discovery and purchase simple.</p>
+ <div class="project-tags"><span class="tag">Shopify</span><span class="tag">E-commerce</span><span class="tag">UX</span></div>
+ <a class="text-link" href="https://coralvibefl.com" target="_blank" rel="noopener noreferrer"><span>Visit live store</span><svg class="arrow" viewBox="0 0 20 20" fill="none" aria-hidden="true"><path d="M5 15 15 5M7 5h8v8" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg></a>
+ </div>
+ </article>
+
+ <article class="project reveal">
+ <a class="project-media" href="https://invoiceotter.com" target="_blank" rel="noopener noreferrer" aria-label="Visit Invoice Otter website">
+ <img src="https://afterdarklabs.io/invoiceotter.webp?v=1" alt="Invoice Otter SaaS product by After Dark Labs" loading="lazy" width="1200" height="673">
+ </a>
+ <div class="project-copy">
+ <div class="project-index">05 / INVOICE OTTER</div>
+ <h3>A small SaaS product with a clear job.</h3>
+ <p>A focused subscription product with a simple interface, straightforward onboarding and just enough personality to make invoicing feel less like admin.</p>
+ <div class="project-tags"><span class="tag">SaaS</span><span class="tag">Product UI</span><span class="tag">Subscriptions</span></div>
+ <a class="text-link" href="https://invoiceotter.com" target="_blank" rel="noopener noreferrer"><span>Visit product</span><svg class="arrow" viewBox="0 0 20 20" fill="none" aria-hidden="true"><path d="M5 15 15 5M7 5h8v8" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg></a>
+ </div>
+ </article>
+ </div>
+
+ <div class="lab-strip reveal">
+ <div>
+ <div class="eyebrow">From the lab</div>
+ <h3>We build our own things, too.</h3>
+ </div>
+ <div class="lab-list">
+ <a class="lab-item" href="https://makeitpdf.org/" target="_blank" rel="noopener noreferrer"><span><strong>MakeItPDF</strong><span>Privacy-first browser utility</span></span><span class="go">↗</span></a>
+ <a class="lab-item" href="https://harrisonerd.com/micropie" target="_blank" rel="noopener noreferrer"><span><strong>MicroPie</strong><span>Open-source Python / ASGI framework</span></span><span class="go">↗</span></a>
+ <a class="lab-item" href="https://gitman.io" target="_blank" rel="noopener noreferrer"><span><strong>GitMan.io</strong><span>Developer platform and Git hosting</span></span><span class="go">↗</span></a>
+ </div>
+ </div>
+ </div>
+ </section>
+
+ <section class="section" id="capabilities">
+ <div class="wrap cap-grid">
+ <div class="cap-intro reveal">
+ <div class="eyebrow">Capabilities</div>
+ <h2 class="display">Built around the business. Not a template.</h2>
+ <p>Strategy, interface design and engineering stay connected from the first idea to launch, so the final product feels intentional instead of assembled.</p>
+ </div>
+
+ <div class="reveal">
+ <div class="cap-list">
+ <div class="cap-row"><span class="num">01</span><h3>Websites & commerce</h3><p>Custom business websites, redesigns, Shopify storefronts and subscription experiences.</p></div>
+ <div class="cap-row"><span class="num">02</span><h3>Apps & platforms</h3><p>SaaS MVPs, customer portals, internal tools, APIs and workflow software.</p></div>
+ <div class="cap-row"><span class="num">03</span><h3>Brand & growth</h3><p>Visual identity, messaging, local search foundations, lead capture and conversion-minded UX.</p></div>
+ <div class="cap-row"><span class="num">04</span><h3>Infrastructure & AI</h3><p>Hosting, domains, business email, third-party integrations, LLM features and intelligent automation.</p></div>
+ </div>
+ <p class="price-note"><strong>Typical business websites: $500–$2,000 one time.</strong> Larger e-commerce, apps and custom platforms are quoted by scope. Hosting is included for most service-business websites.</p>
+ </div>
+ </div>
+ </section>
+
+ <section class="section studio" id="studio">
+ <div class="wrap studio-grid">
+ <div class="reveal">
+ <div class="eyebrow">The studio</div>
+ <h2 class="display">Small by design.<br>Technical by default.</h2>
+ <div class="studio-copy">After Dark Labs is an independent studio in Lighthouse Point, Florida. You work directly with the person designing and building the project—no account-manager relay race, no theme marketplace, no layers of agency overhead.</div>
+ </div>
+ <div class="studio-facts reveal">
+ <div class="fact"><span>Based in</span><span>Lighthouse Point, Florida</span></div>
+ <div class="fact"><span>Works with</span><span>Local businesses + product teams</span></div>
+ <div class="fact"><span>Build philosophy</span><span>Custom, fast, maintainable</span></div>
+ <div class="fact"><span>Engagement</span><span>Direct collaboration</span></div>
+ </div>
+ </div>
+ </section>
+
+ <section class="cta">
+ <div class="wrap cta-inner reveal">
+ <h2 class="display">Have something worth <span>building?</span></h2>
+ <div class="cta-side">
+ <p>Tell us what you're working on. We'll talk through the problem, scope and the simplest way to make it real.</p>
+ <a class="button" href="https://cal.com/afterdarklabs/meet" target="_blank" rel="noopener noreferrer">Book a consultation
+ <svg class="arrow" viewBox="0 0 20 20" fill="none" aria-hidden="true"><path d="M5 15 15 5M7 5h8v8" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg>
+ </a>
+ </div>
+ </div>
+ </section>
+ </main>
+
+ <footer>
+ <div class="wrap footer-grid">
+ <div>© 2026 After Dark Labs · Lighthouse Point, FL</div>
+ <div class="footer-links">
+ <a href="mailto:[email protected]">Email</a>
+ <a href="#work">Work</a>
+ <a href="#capabilities">Capabilities</a>
+ <a href="https://harrisonerd.com/" target="_blank" rel="noopener noreferrer">Harrison Erd ↗</a>
+ </div>
+ </div>
+ </footer>
+
+ <script>
+ (() => {
+ const nav = document.getElementById('nav');
+ const setNav = () => nav.classList.toggle('scrolled', window.scrollY > 18);
+ setNav();
+ window.addEventListener('scroll', setNav, { passive: true });
+
+ const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
+ const revealEls = [...document.querySelectorAll('.reveal')];
+ if (reduce || !('IntersectionObserver' in window)) {
+ revealEls.forEach(el => el.classList.add('in'));
+ } else {
+ const observer = new IntersectionObserver((entries) => {
+ entries.forEach(entry => {
+ if (entry.isIntersecting) {
+ entry.target.classList.add('in');
+ observer.unobserve(entry.target);
+ }
+ });
+ }, { threshold: .12, rootMargin: '0px 0px -4% 0px' });
+ revealEls.forEach(el => observer.observe(el));
+ }
+ })();
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/sitemap.xml b/docs/sitemap.xml
index 0f3b5fe..f7690c8 100644
--- a/docs/sitemap.xml
+++ b/docs/sitemap.xml
@@ -2,7 +2,7 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://afterdarklabs.io/</loc>
- <lastmod>2026-06-03</lastmod>
+ <lastmod>2026-08-23</lastmod>
</url>
<url>
<loc>https://afterdarklabs.io/websites.html</loc>