diff --git a/node_modules/.vite/deps/_metadata.json b/node_modules/.vite/deps/_metadata.json
index c250581..b035c65 100644
--- a/node_modules/.vite/deps/_metadata.json
+++ b/node_modules/.vite/deps/_metadata.json
@@ -1,25 +1,25 @@
 {
-  "hash": "6c87a632",
-  "configHash": "e55fbbff",
+  "hash": "7113b21e",
+  "configHash": "2cd4a4ea",
   "lockfileHash": "53cd0e09",
-  "browserHash": "e114ea7e",
+  "browserHash": "f4d46c12",
   "optimized": {
     "astro > cssesc": {
       "src": "../../.pnpm/cssesc@3.0.0/node_modules/cssesc/cssesc.js",
       "file": "astro___cssesc.js",
-      "fileHash": "7ff5e5f3",
+      "fileHash": "dc615560",
       "needsInterop": true
     },
     "astro > aria-query": {
       "src": "../../.pnpm/aria-query@5.3.2/node_modules/aria-query/lib/index.js",
       "file": "astro___aria-query.js",
-      "fileHash": "c7870714",
+      "fileHash": "53d05d83",
       "needsInterop": true
     },
     "astro > axobject-query": {
       "src": "../../.pnpm/axobject-query@4.1.0/node_modules/axobject-query/lib/index.js",
       "file": "astro___axobject-query.js",
-      "fileHash": "dc6eafc6",
+      "fileHash": "35e7ec58",
       "needsInterop": true
     }
   },
diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro
index bb76cbc..e93b614 100644
--- a/src/layouts/Layout.astro
+++ b/src/layouts/Layout.astro
@@ -16,6 +16,7 @@ import "../styles/global.css";
       href="https://fonts.bunny.net/css?family=ibm-plex-mono:400,400i,500,500i,600,600i,700,700i"
       rel="stylesheet"
     />
+    <script src="https://unpkg.com/alpinejs" defer></script>
     <slot name="head" />
   </head>
   <body class="zag-bg zag-text zag-transition font-mono">
diff --git a/src/pages/homelab/index.astro b/src/pages/homelab/index.astro
index de51974..5b286d9 100644
--- a/src/pages/homelab/index.astro
+++ b/src/pages/homelab/index.astro
@@ -28,25 +28,43 @@ import { services } from "./services.ts";
       <h1 class="font-display text-3xl sm:text-4xl leading-loose">Homelab</h1>
     </div>
 
-    {Object.entries(services).map(([category, apps]) => (
-      <div class="mb-8">
-        <h3 class="text-xl font-semibold mb-4">{category}</h3>
-        <div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4">
-          {apps.length > 0 ? (
-            apps.map(app => (
-              <ServiceCard
-                name={app.name}
-                href={app.link}
-                img={app.icon}
-                alt={app.name}
-                key={app.link}
-              />
-            ))
-          ) : (
-            <p class="text-center col-span-full">Coming soon...</p>
-          )}
+    {Object.entries(services).map(([category, apps], index) => (
+      <div class="mb-8" x-data="{ open: true }" key={index}>
+        <button
+          @click="open = !open"
+          class="text-xl font-semibold mb-4 w-full text-left flex items-center justify-between"
+        >
+          {category}
+          <svg
+            :class="{ 'rotate-180': open }"
+            class="w-5 h-5 transform transition-transform duration-300"
+            fill="none"
+            stroke="currentColor"
+            viewBox="0 0 24 24"
+          >
+            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
+          </svg>
+        </button>
+    
+        <div x-show="open" x-transition>
+          <div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4">
+            {apps.length > 0 ? (
+              apps.map(app => (
+                <ServiceCard
+                  name={app.name}
+                  href={app.link}
+                  img={app.icon}
+                  alt={app.name}
+                  key={app.link}
+                />
+              ))
+            ) : (
+              <p class="text-center col-span-full">Coming soon...</p>
+            )}
+          </div>
         </div>
       </div>
     ))}
+    
   </Section>
 </Layout>