patx/afterdarklabs

revert to safe version

Commit 948ed32 · patx · 2026-09-04T20:13:25-04:00

Changeset
948ed3292e8eca25be36fdafaaad231e307ffac5
Parents
22c117d00ed4b0bfa29ecedba05b0e16a02b6fcc

View source at this commit

Comments

No comments yet.

Log in to comment

Diff

diff --git a/docs/index.html b/docs/index.html
index a7bc8c0..b1c33a1 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -30,6 +30,7 @@
     <meta name="twitter:image:alt" content="After Dark Labs. Custom websites and apps.">
     <link rel="preload" href="https://afterdarklabs.io/fonts/ubuntu-400-latin.woff2" as="font" type="font/woff2" crossorigin>
     <link rel="preload" href="https://afterdarklabs.io/fonts/ubuntu-700-latin.woff2" as="font" type="font/woff2" crossorigin>
+    <link rel="stylesheet" href="https://afterdarklabs.io/index.tailwind.css?v=4">
     <style>
         @font-face {
             font-family: 'Ubuntu';
@@ -58,19 +59,11 @@
         :root {
             --neon: #ccff00;
             --page-bg: #000000;
+            --page-bg-rgb: 0, 0, 0;
             --site-nav-height: 5.75rem;
         }
 
-        *,
-        *::before,
-        *::after {
-            box-sizing: border-box;
-        }
-
         html {
-            line-height: 1.5;
-            -webkit-text-size-adjust: 100%;
-            tab-size: 4;
             max-width: 100%;
             overflow-x: hidden;
             overflow-x: clip;
@@ -86,140 +79,142 @@
             html {
                 font-size: 125%;
             }
+
+            nav img[src*="/logo_assets/mark"] {
+                width: 3rem;
+                height: 3rem;
+            }
+
+            .hero-content h1 {
+                font-size: 4.5rem;
+            }
+        }
+
+        @media (min-width: 1600px) {
+            .hero-content h1 {
+                font-size: 6rem;
+            }
         }
 
         body {
-            margin: 0;
             max-width: 100%;
             overflow-x: hidden;
             overflow-x: clip;
             overscroll-behavior-x: none;
             background: var(--page-bg);
-            color: #fff;
             font-family: 'Ubuntu', system-ui, sans-serif;
         }
 
-        h1,
-        h2,
-        p {
-            margin: 0;
+        nav {
+            -webkit-backdrop-filter: none !important;
+            backdrop-filter: none !important;
         }
 
-        a {
-            color: inherit;
-            text-decoration: none;
-        }
+        .heading,
+        .logo-font { font-family: inherit; color: #fff; }
 
-        img,
-        svg {
-            display: block;
-            vertical-align: middle;
-        }
+        .hero-bg { background: var(--page-bg); }
 
-        img {
-            max-width: 100%;
-            height: auto;
+        .bg-black,
+        .bg-zinc-950 {
+            background-color: var(--page-bg) !important;
         }
 
-        .site-nav {
-            position: fixed;
-            top: 0;
-            z-index: 50;
-            width: 100%;
-            background: var(--page-bg);
+        .neon-ink {
+            color: #fff;
         }
 
-        .nav-container {
-            max-width: 80rem;
-            margin-inline: auto;
-            padding: 1rem;
+        .bg-black\/90 {
+            background-color: #000 !important;
         }
 
-        .nav-row {
-            display: flex;
-            align-items: center;
-            justify-content: space-between;
+        .neon-text {
+            position: relative;
+            isolation: isolate;
+            display: inline-flex;
+            align-items: baseline;
+            font: inherit;
+            letter-spacing: inherit;
+            line-height: inherit;
+            color: var(--neon);
+            white-space: nowrap;
         }
 
-        .nav-row--mobile {
-            gap: 0.75rem;
+        .neon-text::before {
+            content: "";
+            position: absolute;
+            inset: -0.24em -0.42em -0.18em;
+            background: radial-gradient(ellipse at 50% 58%, rgba(204,255,0,0.38), rgba(204,255,0,0.16) 42%, transparent 74%);
+            filter: blur(0.18em);
+            opacity: 0.9;
+            pointer-events: none;
+            z-index: -2;
         }
 
-        .nav-row--desktop {
-            display: none;
+        .neon-letter,
+        .neon-gap {
+            position: relative;
+            display: inline-block;
+            font: inherit;
+            letter-spacing: inherit;
+            line-height: inherit;
+        }
+
+        .neon-letter {
+            color: #ccff00;
+            -webkit-text-fill-color: currentColor;
+            -webkit-text-stroke: 0.006em rgba(235,255,120,0.58);
+            filter:
+                drop-shadow(0 0 0.012em rgba(235,255,120,0.54))
+                drop-shadow(0 0 0.045em rgba(204,255,0,0.72))
+                drop-shadow(0 0 0.105em rgba(204,255,0,0.28))
+                drop-shadow(0 0 0.24em rgba(204,255,0,0.16));
+            text-shadow:
+                0 0 0.026em rgba(235,255,120,0.38),
+                0 0 0.095em rgba(204,255,0,0.42);
         }
 
-        @media (min-width: 640px) {
-            .nav-container {
-                padding-inline: 1.5rem;
-            }
+        .neon-letter::after {
+            content: attr(data-letter);
+            position: absolute;
+            inset: 0;
+            color: transparent;
+            -webkit-text-fill-color: transparent;
+            -webkit-text-stroke: 0.018em rgba(4,8,10,0.46);
+            transform: translate(0.01em, 0.012em);
+            opacity: 0.45;
+            z-index: -1;
         }
 
-        @media (min-width: 1024px) {
-            .nav-container {
-                padding-block: 1.25rem;
-            }
-
-            .nav-row--mobile {
-                display: none;
-            }
+        .neon-letter--flicker {
+            animation: neon-letter-flicker var(--flicker-duration, 12s) steps(1, end) infinite;
+            animation-delay: var(--flicker-delay, 0s);
+        }
 
-            .nav-row--desktop {
-                display: flex;
-            }
+        .neon-gap {
+            width: 0.18em;
         }
 
         .hero-content {
             position: relative;
             z-index: 2;
-            display: grid;
-            width: 100%;
-            justify-items: center;
-            gap: 2.5rem;
-            margin-inline: auto;
-            text-align: center;
+            max-width: none;
+            padding-inline: 0;
+            padding-block: 0;
         }
 
         #hero {
-            position: relative;
-            display: flex;
+            box-sizing: border-box;
             height: 100svh;
             min-height: 100svh;
-            align-items: center;
-            overflow: hidden;
             padding-top: var(--site-nav-height);
             padding-bottom: 0;
-            background: var(--page-bg);
         }
 
         .nav-brand {
-            display: flex;
-            align-items: center;
-            gap: 0.75rem;
             transform-origin: left center;
         }
 
-        .nav-row--mobile .nav-brand {
-            min-width: 0;
-            border-radius: 1rem;
-            padding: 0.375rem 0.75rem 0.375rem 0.375rem;
-            text-align: left;
-            transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1);
-        }
-
-        .nav-row--mobile .nav-brand:hover {
-            background-color: rgba(255, 255, 255, 0.1);
-        }
-
-        .nav-row--mobile .nav-brand:focus {
-            outline: 2px solid transparent;
-            outline-offset: 2px;
-        }
-
-        .nav-row--mobile .nav-brand:focus-visible {
-            box-shadow: 0 0 0 2px var(--neon);
-        }
-
         .nav-brand-ready .nav-brand {
             visibility: hidden;
             opacity: 1;
@@ -235,25 +230,20 @@
         .nav-cta {
             display: inline-flex;
             min-height: 3.25rem;
-            flex-shrink: 0;
             align-items: center;
             justify-content: center;
-            border-radius: 1rem;
             padding: 0.75rem 1.15rem;
-            background-color: #000;
-            color: #fff;
+            background-color: #000 !important;
+            color: #fff !important;
             font-size: clamp(1.05rem, 5vw, 1.3rem);
-            font-weight: 600;
             line-height: 1;
             letter-spacing: -0.035em;
-            transition: color 150ms cubic-bezier(0.4, 0, 0.2, 1),
-                background-color 150ms cubic-bezier(0.4, 0, 0.2, 1);
         }
 
         .nav-cta:hover,
         .nav-cta:focus-visible {
-            background-color: #fff;
-            color: #000;
+            background-color: #fff !important;
+            color: #000 !important;
         }
 
         .nav-brand-word {
@@ -261,7 +251,6 @@
             gap: 0.22em;
             padding-right: 0.08em;
             font-size: clamp(1.25rem, 5.8vw, 1.7rem);
-            font-weight: 600;
             line-height: 0.9;
             letter-spacing: -0.055em;
             white-space: nowrap;
@@ -320,6 +309,12 @@
                 gap: 0;
                 padding-block: clamp(1.25rem, 4svh, 2rem);
             }
+
+            .hero-content h1 {
+                font-size: clamp(2.75rem, 17vw, 4.5rem);
+                font-size: clamp(2.75rem, min(17vw, 9.5svh), 4.5rem);
+            }
+
         }
 
         .hero-content h1 {
@@ -330,7 +325,6 @@
             padding-right: 0.1em;
             font-size: 31vw;
             font-size: min(31vw, calc((100svh - var(--site-nav-height)) * 0.4));
-            font-weight: 700;
             line-height: 0.8;
             letter-spacing: -0.075em;
         }
@@ -390,6 +384,30 @@
             50% { transform: translateY(0.2rem) rotate(45deg); }
         }
 
+        @keyframes neon-letter-flicker {
+            0%, 4.8%, 5.4%, 5.9%, 37.5%, 38%, 38.6%, 100% {
+                opacity: 1;
+                -webkit-text-stroke-color: rgba(235,255,120,0.58);
+                filter:
+                    drop-shadow(0 0 0.012em rgba(235,255,120,0.54))
+                    drop-shadow(0 0 0.045em rgba(204,255,0,0.72))
+                    drop-shadow(0 0 0.105em rgba(204,255,0,0.28))
+                    drop-shadow(0 0 0.24em rgba(204,255,0,0.16));
+            }
+            5%, 37.8% {
+                opacity: 0.08;
+                -webkit-text-stroke-color: rgba(204,255,0,0.18);
+                filter: none;
+            }
+            5.7%, 38.3% {
+                opacity: 0.38;
+                -webkit-text-stroke-color: rgba(204,255,0,0.36);
+                filter:
+                    drop-shadow(0 0 0.012em rgba(204,255,0,0.34))
+                    drop-shadow(0 0 0.036em rgba(204,255,0,0.20));
+            }
+        }
+
         .work-intro {
             position: relative;
             height: 100svh;
@@ -483,7 +501,7 @@
             height: auto;
             align-items: flex-start;
             padding-top: 48px;
-            padding-bottom: calc(56px + env(safe-area-inset-bottom));
+            padding-bottom: 56px;
         }
 
         .work-intro.is-scroll-ready .work-heading-word {
@@ -514,6 +532,11 @@
                 will-change: auto;
             }
 
+            .neon-letter,
+            .neon-letter--flicker {
+                animation: none;
+            }
+
             .hero-letter {
                 opacity: 1;
                 filter: none;
@@ -545,12 +568,6 @@
             }
         }
 
-        #work {
-            scroll-margin-top: 6rem;
-            border-top: 1px solid rgba(255, 255, 255, 0.1);
-            background: var(--page-bg);
-        }
-
         .work-stage {
             box-sizing: border-box;
             padding: clamp(0rem, 0.5vw, 0.5rem) clamp(1rem, 2vw, 2rem);
@@ -578,9 +595,7 @@
             width: 100%;
             min-width: 0;
             aspect-ratio: 16 / 9;
-            overflow: hidden;
             border-radius: 0;
-            background: var(--page-bg);
         }
 
         #work-scroller > article > .portfolio-media {
@@ -726,7 +741,7 @@
 
         }
 
-        @media (hover: hover) {
+        @media (min-width: 768px) and (hover: hover) {
             #work-scroller > article:hover > .portfolio-details {
                 opacity: 1;
                 clip-path: inset(0);
@@ -831,38 +846,38 @@
     }
     </script>
 </head>
-<body>
-    <nav class="site-nav">
-        <div class="nav-container">
-            <div class="nav-row nav-row--mobile">
-                <a href="#hero" class="nav-brand" aria-label="After Dark Labs — go to top">
-                    <span class="nav-brand-word" aria-hidden="true"><span class="nav-brand-letter">After</span><span class="nav-brand-letter">Dark</span><span class="nav-brand-letter">Labs</span></span>
+<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">
+                <a href="#hero" class="nav-brand flex min-w-0 items-center 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="After Dark Labs — go to top">
+                    <span class="nav-brand-word logo-font font-semibold" aria-hidden="true"><span class="nav-brand-letter">After</span><span class="nav-brand-letter">Dark</span><span class="nav-brand-letter">Labs</span></span>
                 </a>
-                <a href="mailto:[email protected]" class="nav-cta">Let's Talk</a>
+                <a href="/cdn-cgi/l/email-protection#d9b1bcb5b5b699b8bfadbcabbdb8abb2b5b8bbaaf7b0b6" class="nav-cta neon-ink shrink-0 rounded-2xl bg-[#fff] font-semibold transition-colors hover:bg-white">Let's Talk</a>
             </div>
 
-            <div class="nav-row nav-row--desktop">
-                <a href="#hero" class="nav-brand" aria-label="After Dark Labs — go to top">
+            <div class="hidden items-center justify-between lg:flex">
+                <a href="#hero" class="nav-brand flex items-center gap-3" aria-label="After Dark Labs — go to top">
                     <div>
-                        <span class="nav-brand-word" aria-hidden="true"><span class="nav-brand-letter">After</span><span class="nav-brand-letter">Dark</span><span class="nav-brand-letter">Labs</span></span>
+                        <span class="nav-brand-word logo-font font-semibold" aria-hidden="true"><span class="nav-brand-letter">After</span><span class="nav-brand-letter">Dark</span><span class="nav-brand-letter">Labs</span></span>
                     </div>
                 </a>
-                <a href="mailto:[email protected]" class="nav-cta">Let's Talk</a>
+                <a href="/cdn-cgi/l/email-protection#69010c05050629080f1d0c1b0d081b0205080b1a470006" class="nav-cta neon-ink rounded-2xl bg-[#fff] font-semibold transition-colors hover:bg-white">Let's Talk</a>
             </div>
         </div>
     </nav>
 
     <main>
-        <section id="hero">
+        <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">
+            <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 aria-label="After Dark Labs - Custom websites and apps"><span class="hero-word hero-letter" aria-hidden="true">After</span><span class="hero-word hero-letter" aria-hidden="true">Dark</span><span class="hero-word hero-letter" aria-hidden="true">Labs</span></h1>
+                    <h1 class="heading text-7xl font-bold leading-none tracking-tighter md:text-8xl lg:text-7xl xl:text-8xl" aria-label="After Dark Labs - Custom websites and apps"><span class="hero-word hero-letter" aria-hidden="true">After</span><span class="hero-word hero-letter" aria-hidden="true">Dark</span><span class="hero-word hero-letter" aria-hidden="true">Labs</span></h1>
                 </div>
             </div>
 
-            <a class="hero-scroll-hint" href="#work-heading" aria-label="Explore our work"></a>
+            <a class="hero-scroll-hint" href="#work-heading"></a>
 
         </section>
 
@@ -889,86 +904,86 @@
             </div>
         </section>
 
-        <section id="work" aria-label="Featured work">
+        <section id="work" class="scroll-mt-24 border-t border-white/10 bg-black" aria-label="Featured work">
             <div class="work-stage">
                 <div class="work-stage-content">
-                <div id="work-scroller">
-                    <article>
+                <div id="work-scroller" class="portfolio-grid">
+                    <article class="w-[82vw] shrink-0 snap-start overflow-hidden rounded-3xl bg-zinc-950 sm:w-[28rem] md:w-[38rem]">
                         <div class="portfolio-media">
-                            <img src="https://afterdarklabs.io/gardenfresh.webp?v=2" width="1200" height="702" loading="lazy" decoding="async" alt="Garden Fresh Wholesale ecommerce web app project by After Dark Labs">
+                            <img src="https://afterdarklabs.io/gardenfresh.webp?v=2" width="1200" height="702" loading="lazy" decoding="async" class="aspect-video w-full object-cover" alt="Garden Fresh Wholesale ecommerce web app project by After Dark Labs">
                         </div>
-                        <div class="portfolio-details">
-                            <p>
+                        <div class="portfolio-details p-6">
+                            <p class="text-sm font-medium text-white">
                                 <span class="portfolio-description">We built <span class="portfolio-name">Garden Fresh Wholesale</span>'s business website and local SEO strategy that increased customer acquisition by 48% since launch. <a class="portfolio-live-link" href="https://gardenfreshwholesale.com" target="_blank" rel="noopener noreferrer">View project <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-up-right" viewBox="0 0 16 16" aria-hidden="true"><path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5"/><path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0z"/></svg></a></span>
                             </p>
                         </div>
                     </article>
-                    <article>
+                    <article class="w-[82vw] shrink-0 snap-start overflow-hidden rounded-3xl bg-zinc-950 sm:w-[28rem] md:w-[38rem]">
                         <div class="portfolio-media">
-                            <img src="https://afterdarklabs.io/miadruck.webp?v=3" width="1200" height="681" loading="lazy" decoding="async" alt="Mia Druck real estate website project by After Dark Labs">
+                            <img src="https://afterdarklabs.io/miadruck.webp?v=3" width="1200" height="681" loading="lazy" decoding="async" class="aspect-video w-full object-cover" alt="Mia Druck real estate website project by After Dark Labs">
                         </div>
-                        <div class="portfolio-details">
-                            <p>
+                        <div class="portfolio-details p-6">
+                            <p class="text-sm font-medium text-white">
                                 <span class="portfolio-description"><span class="portfolio-name">Mia Druck</span> needed a real estate website with heavy local SEO and a custom API for the most up-to-date listings and sales. We delivered this custom site in under a week. <a class="portfolio-live-link" href="https://miadruck.com" target="_blank" rel="noopener noreferrer">View project <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-up-right" viewBox="0 0 16 16" aria-hidden="true"><path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5"/><path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0z"/></svg></a></span>
                             </p>
                         </div>
                     </article>
-                    <article>
+                    <article class="w-[82vw] shrink-0 snap-start overflow-hidden rounded-3xl bg-zinc-950 sm:w-[28rem] md:w-[38rem]">
                         <div class="portfolio-media">
-                            <img src="https://afterdarklabs.io/coralvibe.webp?v=1" width="1200" height="678" loading="lazy" decoding="async" alt="Shopify store for Coral Vibe Florida project by After Dark Labs">
+                            <img src="https://afterdarklabs.io/coralvibe.webp?v=1" width="1200" height="678" loading="lazy" decoding="async" class="aspect-video w-full object-cover" alt="Shopify store for Coral Vibe Florida project by After Dark Labs">
                         </div>
-                        <div class="portfolio-details">
-                            <p>
+                        <div class="portfolio-details p-6">
+                            <p class="text-sm font-medium text-white">
                                 <span class="portfolio-description"><span class="portfolio-name">Coral Vibe</span> hired us to design their Shopify store and provide support for ecommerce operations, product management, and social media marketing. Since launch, store visits resulting in sales have increased by 86%. <a class="portfolio-live-link" href="https://coralvibefl.com" target="_blank" rel="noopener noreferrer">View project <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-up-right" viewBox="0 0 16 16" aria-hidden="true"><path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5"/><path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0z"/></svg></a></span>
                             </p>
                         </div>
                     </article>
-                    <article>
+                    <article class="w-[82vw] shrink-0 snap-start overflow-hidden rounded-3xl bg-zinc-950 sm:w-[28rem] md:w-[38rem]">
                         <div class="portfolio-media">
-                            <img src="https://afterdarklabs.io/frontlineboats.webp?v=1" width="1200" height="700" loading="lazy" decoding="async" alt="Frontline Boat Services marine services website project by After Dark Labs">
+                            <img src="https://afterdarklabs.io/frontlineboats.webp?v=1" width="1200" height="700" loading="lazy" decoding="async" class="aspect-video w-full object-cover" alt="Frontline Boat Services marine services website project by After Dark Labs">
                         </div>
-                        <div class="portfolio-details">
-                            <p>
+                        <div class="portfolio-details p-6">
+                            <p class="text-sm font-medium text-white">
                                 <span class="portfolio-description">For <span class="portfolio-name">Frontline Boat Services</span>, we built a highly focused business website with local SEO, custom payment links for customers, and an owner-managed photo gallery. <a class="portfolio-live-link" href="https://frontlineboats.com" target="_blank" rel="noopener noreferrer">View project <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-up-right" viewBox="0 0 16 16" aria-hidden="true"><path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5"/><path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0z"/></svg></a></span>
                             </p>
                         </div>
                     </article>
-                    <article>
+                    <article class="w-[82vw] shrink-0 snap-start overflow-hidden rounded-3xl bg-zinc-950 sm:w-[28rem] md:w-[38rem]">
                         <div class="portfolio-media">
-                            <img src="https://afterdarklabs.io/voldservices.webp" width="1200" height="702" loading="lazy" decoding="async" alt="Vold Services exterior cleaning website with a scroll-animated hero, designed by After Dark Labs">
+                            <img src="https://afterdarklabs.io/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">
                         </div>
-                        <div class="portfolio-details">
-                            <p>
+                        <div class="portfolio-details p-6">
+                            <p class="text-sm font-medium text-white">
                                 <span class="portfolio-description"><span class="portfolio-name">Vold Services</span> hired us to create their business website with a scroll-animated hero, local SEO/GEO and an owner-managed photo gallery. <a class="portfolio-live-link" href="https://voldservices.com" target="_blank" rel="noopener noreferrer">View project <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-up-right" viewBox="0 0 16 16" aria-hidden="true"><path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5"/><path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0z"/></svg></a></span>
                             </p>
                         </div>
                     </article>
-                    <article>
+                    <article class="w-[82vw] shrink-0 snap-start overflow-hidden rounded-3xl bg-zinc-950 sm:w-[28rem] md:w-[38rem]">
                         <div class="portfolio-media">
-                            <img src="https://afterdarklabs.io/vegy.webp?v=1" width="1200" height="702" loading="lazy" decoding="async" alt="Vegy wholesale ordering platform project by After Dark Labs">
+                            <img src="https://afterdarklabs.io/vegy.webp?v=1" width="1200" height="702" loading="lazy" decoding="async" class="aspect-video w-full object-cover" alt="Vegy wholesale ordering platform project by After Dark Labs">
                         </div>
-                        <div class="portfolio-details">
-                            <p>
+                        <div class="portfolio-details p-6">
+                            <p class="text-sm font-medium text-white">
                                 <span class="portfolio-description">We have partnered with <span class="portfolio-name">Vegy</span> since 2023 to create a white-label web app for wholesale ordering with AI and email integrations, real-time updates, and advanced analytics. The app processed over $2 million in orders in the first year. <a class="portfolio-live-link" href="https://vegy.app/" target="_blank" rel="noopener noreferrer">View project <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-up-right" viewBox="0 0 16 16" aria-hidden="true"><path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5"/><path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0z"/></svg></a></span>
                             </p>
                         </div>
                     </article>
-                    <article>
+                    <article class="w-[82vw] shrink-0 snap-start overflow-hidden rounded-3xl bg-zinc-950 sm:w-[28rem] md:w-[38rem]">
                         <div class="portfolio-media">
-                            <img src="https://afterdarklabs.io/prima.webp?v=1" width="1200" height="702" loading="lazy" decoding="async" alt="Prima Produce business website project by After Dark Labs">
+                            <img src="https://afterdarklabs.io/prima.webp?v=1" width="1200" height="702" loading="lazy" decoding="async" class="aspect-video w-full object-cover" alt="Prima Produce business website project by After Dark Labs">
                         </div>
-                        <div class="portfolio-details">
-                            <p>
+                        <div class="portfolio-details p-6">
+                            <p class="text-sm font-medium text-white">
                                 <span class="portfolio-description">Our partner <span class="portfolio-name">Prima Produce</span> hired us to build their business website with custom online ordering and cohesive branding. Working with their existing logo, we created a complete online experience for Prima's customers. <a class="portfolio-live-link" href="https://prima.vegy.app/" target="_blank" rel="noopener noreferrer">View project <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-up-right" viewBox="0 0 16 16" aria-hidden="true"><path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5"/><path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0z"/></svg></a></span>
                             </p>
                         </div>
                     </article>
-                    <article>
+                    <article class="w-[82vw] shrink-0 snap-start overflow-hidden rounded-3xl bg-zinc-950 sm:w-[28rem] md:w-[38rem]">
                         <div class="portfolio-media">
-                            <img src="https://afterdarklabs.io/invoiceotter.webp?v=1" width="1200" height="673" loading="lazy" decoding="async" alt="Invoice Otter SaaS project by After Dark Labs">
+                            <img src="https://afterdarklabs.io/invoiceotter.webp?v=1" width="1200" height="673" loading="lazy" decoding="async" class="aspect-video w-full object-cover" alt="Invoice Otter SaaS project by After Dark Labs">
                         </div>
-                        <div class="portfolio-details">
-                            <p>
+                        <div class="portfolio-details p-6">
+                            <p class="text-sm font-medium text-white">
                                 <span class="portfolio-description">We built the mobile app, web interface, and the APIs for <span class="portfolio-name">Invoice Otter</span>'s contractor invoicing and estimating solutions with subscriptions, integrated payments, a custom AI chatbot, and per-user customization. <a class="portfolio-live-link" href="https://invoiceotter.com" target="_blank" rel="noopener noreferrer">View project <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-up-right" viewBox="0 0 16 16" aria-hidden="true"><path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5"/><path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0z"/></svg></a></span>
                             </p>
                         </div>
@@ -981,7 +996,7 @@
                 <div class="work-intro-stage">
                     <h2 id="closing-heading" class="work-heading">
                         <span class="work-heading-words">
-                          <a class="work-heading-word work-heading-email" href="mailto:[email protected]">
+                          <a class="work-heading-word work-heading-email" href="/cdn-cgi/l/email-protection#6f070a0303002f0e091b0a1d0b0e1d04030e0d1c410600">
                             <span class="work-heading-word">Let’s</span>
                             <span class="work-heading-word">move</span>
                             <span class="work-heading-word">your</span>
@@ -1001,7 +1016,7 @@
 
     </main>
 
-    <script>
+    <script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script><script>
         (function () {
             const hero = document.getElementById('hero');
             if (!hero) return;
@@ -1438,7 +1453,6 @@
             if (!closingStatement || !words.length) return;
 
             const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
-            const animatedLayout = window.matchMedia('(min-width: 768px) and (hover: hover) and (pointer: fine)');
             let revealStart = 0;
             let revealDistance = 1;
             let revealedWords = -1;
@@ -1452,7 +1466,7 @@
             function updateClosingIntro() {
                 updateFrame = 0;
 
-                if (reduceMotion.matches || !animatedLayout.matches) {
+                if (reduceMotion.matches) {
                     words.forEach(word => word.classList.add('is-revealed'));
                     revealedWords = words.length;
                     return;
@@ -1470,18 +1484,11 @@
 
             function measureClosingIntro() {
                 resizeFrame = 0;
-                const shouldAnimate = animatedLayout.matches && !reduceMotion.matches;
-                closingStatement.classList.toggle('is-scroll-ready', shouldAnimate);
+                closingStatement.classList.toggle('is-scroll-ready', !reduceMotion.matches);
                 closingStatement.classList.remove('is-motion-ready');
 
-                if (!shouldAnimate) {
-                    words.forEach(word => word.classList.add('is-revealed'));
-                    revealedWords = words.length;
-                    return;
-                }
-
                 const statementTop = closingStatement.getBoundingClientRect().top + window.scrollY;
-                const viewportHeight = document.documentElement.clientHeight || window.innerHeight;
+                const viewportHeight = window.visualViewport?.height || window.innerHeight;
                 const statementHeight = closingStatement.offsetHeight;
                 const maximumScroll = Math.max(0, document.documentElement.scrollHeight - viewportHeight);
                 revealStart = Math.min(maximumScroll, statementTop - viewportHeight + statementHeight * 0.05);
@@ -1509,7 +1516,6 @@
             window.visualViewport?.addEventListener('resize', scheduleClosingIntroMeasure);
             window.addEventListener('pageshow', scheduleClosingIntroMeasure);
             reduceMotion.addEventListener('change', scheduleClosingIntroMeasure);
-            animatedLayout.addEventListener('change', scheduleClosingIntroMeasure);
             document.fonts?.ready.then(scheduleClosingIntroMeasure);
             measureClosingIntro();
         })();