A minimalist theme for personal websites and blogs built with Astro, React, and TypeScript. Focused on clean design, performance, and accessibility.
- π¨ Modern UI Components - Built on shadcn/ui and Radix primitives
- π Performance First - Static site generation with Astro, instant state changes
- βΏ Accessible - WCAG compliant with full keyboard navigation
- π Dark Mode - Instant theme switching with system preference support
- π± Responsive - Mobile-first design approach
- π SEO Ready - Built-in SEO components and meta tags
- π MDX Support - Write content in MDX with component support
- π― Type Safe - Full TypeScript support
- π³ Docker First - Containerized development environment
- Astro - Static site generation
- React - Interactive components
- TypeScript - Type safety
- Tailwind CSS - Styling
- shadcn/ui - UI components
- Radix UI - Accessible primitives
- react-hook-form - Form handling
- zod - Schema validation
src/
βββ components/ # UI Components
β βββ ui/ # shadcn/ui components
β βββ showcase/ # Component demos
β βββ display/ # Content display components
β βββ forms/ # Form-related components
β βββ interactive/ # Client-side interactive components
β βββ layout/ # Layout components
β βββ media/ # Media handling components
β βββ mdx/ # MDX-specific components
β βββ seo/ # SEO components
βββ content/ # Content collections
β βββ pages/ # Static pages
β βββ posts/ # Blog posts
β βββ showcase/ # Component documentation
βββ styles/ # Global styles
β βββ tokens/ # Design tokens
βββ types/ # TypeScript definitions
We use shadcn/ui as our component foundation, with a focus on:
- Zero-Runtime CSS - All styling through Tailwind
- Accessibility - Built on Radix UI primitives
- Customization - Fully customizable through Tailwind and CSS variables
- Type Safety - Full TypeScript support
Current implementation status:
- β Core components (Accordion, Alert, Button, etc.)
- β Form components (Input, Label, etc.)
- β Navigation components
- π§ Advanced components (ongoing)
See src/content/showcase/shadcn-gallery.mdx for live examples.
Components are organized by responsibility:
ui/- shadcn/ui components and primitivesshowcase/- Component demonstrations and documentationinteractive/- Client-side interactive componentsforms/- Form-related componentsdisplay/- Content display componentsmedia/- Media handling components
Each directory includes its own README with detailed documentation.
-
Start the development environment:
docker compose up -d
-
View logs (optional):
docker compose logs -f
-
Stop the environment:
docker compose down
To add a new shadcn/ui component:
-
Start the development container:
docker compose -f docker-compose.dev.yml up -d
-
Add the component:
docker compose -f docker-compose.dev.yml exec app bun run ui:add $COMPONENT_NAME
See src/content/showcase/theme.mdx for component customization docs.
- Clean Code - Type-safe, elegant solutions without hacks
- Docker First - All development in containers
- Tailwind First - Utility classes over custom CSS
- Component Driven - Consistent patterns with shadcn/ui
- Zero Runtime - No unnecessary JavaScript or animations
- Accessibility - WCAG compliance and screen reader support
Comprehensive documentation in src/content/showcase/:
theme.mdx- Theme system and customizationshadcn-gallery.mdx- Component examplestoken-system.mdx- Design tokensaccessibility.mdx- ARIA implementationkeyboard-navigation.mdx- Keyboard support
We're currently working on:
-
Component System Refinement
- Standardizing file naming conventions
- Simplifying token system
- Aligning closer with shadcn/ui patterns
-
Documentation Improvements
- Expanding component examples
- Adding more usage guidelines
- Improving accessibility documentation
- Fork the repository
- Create a feature branch
- Follow our coding standards:
- Use TypeScript for type safety
- Follow Astro's component patterns
- Use React for interactive components
- Implement proper accessibility
- Write meaningful documentation
- Submit a pull request
MIT License - See LICENSE file for details.
Images are stored in src/assets/ and optimized using Astro's built-in image processing:
src/
βββ assets/ # Image assets
β βββ posts/ # Blog post images
β βββ launches/ # Launch images
β βββ showcase/ # Documentation images
For content collections, use relative paths from the content file:
---
title: My Post
heroImage: "../../assets/posts/my-image.png"
heroImageAlt: "Image description"
---Use the OptimizedImage component for consistent image handling:
---
import OptimizedImage from '@/components/media/OptimizedImage.astro';
import myImage from '@/assets/posts/my-image.png';
---
<OptimizedImage
src={myImage}
alt="Image description"
variant="hero"
/>Images are automatically:
- Converted to WebP
- Optimized for size
- Loaded with zero layout shift
- Properly typed with TypeScript