+
@@ -64,7 +65,29 @@ const tagCounts = countTags(articles.map((article) => article.tags).flat().filte
>
- No Articles Found
-
+
+
+ {Array.from({ length: 5 }).map((_, i) => (
+
+ ))}
+
+
+
+ -
{
articles.map((article) => {
const articleTags = article.tags ? article.tags.join(' ').toLowerCase() : '';
diff --git a/src/pages/homelab/index.astro b/src/pages/homelab/index.astro
index 28fc7b3..7b4ca93 100644
--- a/src/pages/homelab/index.astro
+++ b/src/pages/homelab/index.astro
@@ -4,6 +4,8 @@ import Layout from "../../layouts/Layout.astro";
import Section from "../../components/common/Section.astro";
import SearchBar from "../../components/common/SearchBar.astro";
import CategorySection from "../../components/homelab/CategorySection.astro";
+import ServiceCardSkeleton from "../../components/common/ServiceCardSkeleton.astro";
+import SkeletonLoader from "../../components/common/SkeletonLoader.astro";
import { services } from "./services.ts";
import { initializeSearch } from "../../components/common/searchUtils.js";
---
@@ -28,7 +30,7 @@ import { initializeSearch } from "../../components/common/searchUtils.js";
+
@@ -53,8 +55,38 @@ import { initializeSearch } from "../../components/common/searchUtils.js";
-
- No Results
+
+
+ {Object.entries(services).map(([category, apps]) => (
+
+
+
+
+
+ ))}
+
+
+
+
+ {Array.from({ length: apps.length || 4 }).map((_, i) => (
+
+ ))}
+
+
{Object.entries(services).map(([category, apps]) => (
))}
diff --git a/src/pages/projects/index.astro b/src/pages/projects/index.astro
index 9466b5f..c282184 100644
--- a/src/pages/projects/index.astro
+++ b/src/pages/projects/index.astro
@@ -2,6 +2,7 @@
import { projects } from "../../lib/list";
import Section from "../../components/common/Section.astro";
import ProjectSnippet from "../../components/ProjectSnippet.astro";
+import ProjectSnippetSkeleton from "../../components/ProjectSnippetSkeleton.astro";
import SearchBar from "../../components/common/SearchBar.astro";
import Layout from "../../layouts/Layout.astro";
import { GLOBAL } from "../../lib/variables";
@@ -37,7 +38,7 @@ import { initializeSearch } from "../../components/common/searchUtils.js";
-
+
@@ -61,7 +62,29 @@ import { initializeSearch } from "../../components/common/searchUtils.js";
- No Projects Found
-
+
+
+ {Array.from({ length: 3 }).map((_, i) => (
+
+ ))}
+
+
+
+ -
{
projects.map((project) => {
const projectTags = project.tags ? project.tags.join(' ').toLowerCase() : '';
diff --git a/src/pages/projects/zaggonaut.md b/src/pages/projects/zaggonaut.md
index 2f1d1d0..009d076 100644
--- a/src/pages/projects/zaggonaut.md
+++ b/src/pages/projects/zaggonaut.md
@@ -1,8 +1,8 @@
---
layout: ../../layouts/ProjectLayout.astro
title: This Website
-description: My personal blog and portfolio, built using TypeScript, TailwindCSS, and Astro.
-tags: ["astro", "typescript", "web-development"]
+description: My personal blog, portfolio, and homelab dashboard built with Astro, TypeScript, TailwindCSS, and Alpine.js featuring smart loading, advanced search, and accessibility features.
+tags: ["astro", "typescript", "tailwindcss", "alpinejs", "responsive-design", "accessibility", "dark-mode", "gruvbox-theme"]
githubUrl: https://code.justin.deal
timestamp: 2025-02-24T02:39:03+00:00
featured: true
@@ -11,17 +11,59 @@ filename: zaggonaut
## The Details
-Zaggonaut is a retro-inspired theme for Astro, built using TypeScript, TailwindCSS, and Astro. Use this theme to power your own personal website, blog, or portfolio with flexibility and customization.
+This website serves as my personal digital space, combining a blog, project portfolio, and homelab dashboard in one cohesive experience. Built on Astro for performance and flexibility, it leverages TypeScript for type safety, TailwindCSS for styling, and Alpine.js for interactive components.
+
+The architecture follows a component-based approach with a focus on reusability and maintainability. The site features a custom Gruvbox-inspired theme system that supports both dark and light modes while maintaining accessibility standards. The responsive design ensures a seamless experience across all device sizes.
## The Features
-- Dark & light mode
-- Customizable colors
-- 100 / 100 Lighthouse score
-- Fully accessible
-- Fully responsive
-- Type-safe
+### Content & Navigation
+- **Multi-purpose platform**: Blog, portfolio, and homelab dashboard integration
+- **Dark & light mode** with smooth transitions and flash prevention
+- **Gruvbox-inspired color scheme** with customizable theme variables
+- **Fully responsive design** optimized for all screen sizes
-## The Future
+### Performance & User Experience
+- **Smart loading system**:
+ - Connection-aware loading states that adapt to network speed
+ - Skeleton loaders that match content layout during loading
+ - Extended loading fallback UI for slow connections
+ - Navigation API integration for accurate loading states
-Check out [the theme website](https://zaggonaut.dev) to see it in action!
\ No newline at end of file
+- **Advanced search functionality**:
+ - Real-time content filtering across all sections
+ - Keyboard navigation with arrow keys and shortcuts
+ - Category-aware filtering for structured content
+ - Accessible search results with screen reader support
+
+### Technical Implementation
+- **Component architecture**:
+ - Reusable UI components with TypeScript interfaces
+ - Consistent styling patterns using CSS custom properties
+ - Modular structure for easy maintenance and extension
+
+- **Accessibility features**:
+ - ARIA attributes for screen reader compatibility
+ - Keyboard navigation throughout the site
+ - Reduced motion support for animations
+ - High contrast theme options
+
+- **Performance optimizations**:
+ - Optimized page transitions with minimal flicker
+ - Network-aware resource loading
+ - Efficient DOM updates using Alpine.js
+ - Astro's static site generation for fast initial loads
+
+### Homelab Integration
+- **Self-hosted services dashboard** with categorized listings
+- **Service search and filtering** by name, category, and tags
+- **Visual indicators** for service status and information
+
+## The Technology Stack
+
+- **Framework**: Astro 5.6
+- **Languages**: TypeScript, JavaScript
+- **Styling**: TailwindCSS 4.1, Custom CSS Variables
+- **Interactivity**: Alpine.js
+- **Build Tools**: Vite, npm/pnpm
+- **Deployment**: Self-hosted
diff --git a/src/styles/global.css b/src/styles/global.css
index e73557b..cb5338e 100644
--- a/src/styles/global.css
+++ b/src/styles/global.css
@@ -13,6 +13,17 @@ html.theme-loaded body {
transition: background-color 0.3s ease, color 0.3s ease;
}
+/* Hide elements with x-cloak until Alpine.js is loaded */
+[x-cloak] {
+ display: none !important;
+}
+
+/* Add keyboard focus styling for keyboard navigation */
+.keyboard-focus {
+ outline: 2px solid var(--color-zag-accent-dark);
+ outline-offset: 2px;
+}
+
@font-face {
font-family: "Literata Variable";
font-style: normal;