diff --git a/themes/minimal-black/.gitignore b/themes/minimal-black/.gitignore
new file mode 100644
index 0000000..f3c4ca1
--- /dev/null
+++ b/themes/minimal-black/.gitignore
@@ -0,0 +1,33 @@
+# Hugo
+public/
+resources/
+.hugo_build.lock
+hugo_stats.json
+
+# Node.js
+node_modules/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+package-lock.json
+
+# IDE & Editor
+.vscode/
+.idea/
+*.swp
+*.swo
+*~
+.DS_Store
+
+# Build artifacts
+*.log
+*.tmp
+*.temp
+
+# Backup files
+*.backup
+*.bak
+
+# OS files
+Thumbs.db
+Desktop.ini
diff --git a/themes/minimal-black/CHANGELOG.md b/themes/minimal-black/CHANGELOG.md
new file mode 100644
index 0000000..b80da5c
--- /dev/null
+++ b/themes/minimal-black/CHANGELOG.md
@@ -0,0 +1,111 @@
+# Changelog
+
+All notable changes to the Minimal Black theme will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+### Added
+- Initial theme release
+- Dark and light mode with automatic switching
+- True black dark mode with purple accents
+- Responsive design for mobile, tablet, and desktop
+- Built-in search functionality with keyboard shortcuts (Ctrl/Cmd+K)
+- Table of contents for blog posts with active section tracking
+- Syntax highlighting with copy button and language labels
+- Multiple page layouts: home, blog, projects, about, about-alternative
+- Mermaid diagram support
+- Gallery shortcode with lightbox
+- GitHub-style alerts (note, tip, warning, danger, important)
+- Analytics support (Google Analytics, Plausible, Umami, Fathom)
+- Font Awesome and Devicon icon support
+- Technology stack marquee on home page
+- Project portfolio with featured projects
+- Blog with tags and categories
+- SEO optimized meta tags
+- RSS feed generation
+- JSON output for search indexing
+- Modular CSS architecture
+- Configurable stats and skills for about-alternative page
+- Favicon and touch icon support
+- Social links configuration
+- Hero section with customizable badge, title, and CTAs
+- "Now" section for quick facts
+- Floating action dock
+- Mobile-friendly navigation
+- Theme toggle button
+- Custom 404 page
+- Markdown enhancements:
+ - Enhanced blockquotes with gradient backgrounds
+ - Improved list styling with hover effects
+ - Task list support with checkboxes
+ - Definition lists
+ - Footnotes
+ - Table styling with responsive wrapper
+ - Image captions (optional)
+ - External link indicators
+ - Heading anchor links
+
+### Changed
+- N/A (initial release)
+
+### Deprecated
+- N/A (initial release)
+
+### Removed
+- N/A (initial release)
+
+### Fixed
+- N/A (initial release)
+
+### Security
+- N/A (initial release)
+
+## Release Notes
+
+### Version 1.0.0 (Unreleased)
+
+Initial release of Minimal Black theme for Hugo. A minimal, dark-mode first theme designed for developers, designers, and writers who value simplicity and performance.
+
+**Key Features:**
+- ⚡ Fast and lightweight
+- 🎨 Beautiful dark mode with true black backgrounds
+- 📱 Fully responsive design
+- 🔍 Built-in search
+- 💻 Excellent code highlighting
+- 📚 Comprehensive documentation
+
+---
+
+## Version History Format
+
+Each version entry should follow this structure:
+
+```markdown
+## [X.Y.Z] - YYYY-MM-DD
+
+### Added
+- New features
+
+### Changed
+- Changes in existing functionality
+
+### Deprecated
+- Soon-to-be removed features
+
+### Removed
+- Removed features
+
+### Fixed
+- Bug fixes
+
+### Security
+- Security patches
+```
+
+---
+
+[Unreleased]: https://gitlab.com/jimchr12/hugo-minimal-black/-/compare/v1.0.0...main
+[1.0.0]: https://gitlab.com/jimchr12/hugo-minimal-black/-/releases/v1.0.0
diff --git a/themes/minimal-black/CONTRIBUTING.md b/themes/minimal-black/CONTRIBUTING.md
new file mode 100644
index 0000000..60e1ec4
--- /dev/null
+++ b/themes/minimal-black/CONTRIBUTING.md
@@ -0,0 +1,249 @@
+# Contributing to Minimal Black
+
+Thank you for your interest in contributing to Minimal Black! This document provides guidelines and instructions for contributing to the theme.
+
+## Code of Conduct
+
+By participating in this project, you agree to maintain a respectful and collaborative environment. Be kind, be professional, and be constructive in your feedback.
+
+## How Can I Contribute?
+
+### Reporting Bugs
+
+Before creating a bug report, please check the [existing issues](https://gitlab.com/jimchr12/hugo-minimal-black/-/issues) to avoid duplicates.
+
+When creating a bug report, include:
+
+- **Clear title** — Descriptive and specific
+- **Steps to reproduce** — Minimal steps needed to reproduce the issue
+- **Expected behavior** — What you expected to happen
+- **Actual behavior** — What actually happened
+- **Screenshots** — If applicable
+- **Environment:**
+ - Hugo version (`hugo version`)
+ - Operating system
+ - Browser (if frontend issue)
+ - Node.js version (`node --version`)
+
+### Suggesting Enhancements
+
+Enhancement suggestions are welcome! Please:
+
+1. **Check existing issues** — Your idea might already be proposed
+2. **Provide clear use case** — Explain why this would be useful
+3. **Consider alternatives** — Mention any alternative solutions you've considered
+4. **Keep it minimal** — The theme prioritizes simplicity
+
+### Pull Requests
+
+1. **Fork the repository** and create your branch from `main`
+2. **Make your changes** following the code style guidelines below
+3. **Test your changes** thoroughly
+4. **Update documentation** if you're changing functionality
+5. **Commit with clear messages** following the commit conventions
+6. **Submit a pull request** with a comprehensive description
+
+## Development Setup
+
+### Prerequisites
+
+- Hugo Extended v0.120.0+
+- Node.js 18+
+- npm or yarn
+
+### Local Development
+
+1. **Clone your fork:**
+ ```bash
+ git clone https://gitlab.com/YOUR-USERNAME/hugo-minimal-black.git
+ cd hugo-minimal-black
+ ```
+
+2. **Install dependencies:**
+ ```bash
+ npm install
+ ```
+
+3. **Run the example site:**
+ ```bash
+ cd exampleSite
+ hugo server -D --themesDir ../..
+ ```
+
+4. **Build CSS** (if modifying styles):
+ ```bash
+ npx tailwindcss -i ./assets/css/main.css -o ./static/css/main.css
+ ```
+
+### Making Changes
+
+#### CSS/Styling
+
+- CSS files are in `assets/css/`
+- The theme uses Tailwind CSS with a modular structure
+- See [CSS-STRUCTURE.md](CSS-STRUCTURE.md) for architecture details
+- Follow the existing pattern: one component per file
+- Use CSS custom properties for theme colors
+- Ensure changes work in both light and dark modes
+
+#### HTML/Templates
+
+- Templates are in `layouts/`
+- Follow Hugo's template best practices
+- Use semantic HTML5 elements
+- Test responsiveness on mobile, tablet, and desktop
+
+#### JavaScript
+
+- Keep JavaScript minimal
+- Use vanilla JavaScript (no frameworks)
+- Ensure compatibility with all modern browsers
+- Add comments for complex logic
+- Test with JavaScript disabled for core functionality
+
+### HTML/Templates
+
+- **2 spaces** for indentation
+- **Semantic HTML** — Use appropriate elements
+- **Accessibility** — Include ARIA labels where needed
+- **Hugo conventions** — Follow Hugo's best practices
+
+```html
+{{ define "main" }}
+
+
+ {{ .Title }}
+ {{ .Content }}
+
+
+{{ end }}
+```
+
+### CSS
+
+- **2 spaces** for indentation
+- **BEM-inspired** naming for custom classes
+- **Mobile-first** responsive design
+- **CSS custom properties** for theme values
+- **Comments** for complex styles
+
+```css
+/* Component name */
+.component-name {
+ property: value;
+}
+
+/* Component variant */
+.component-name--variant {
+ property: value;
+}
+
+/* Component element */
+.component-name__element {
+ property: value;
+}
+```
+
+### JavaScript
+
+- **2 spaces** for indentation
+- **camelCase** for variables and functions
+- **Descriptive names** — Avoid abbreviations
+- **Comments** for non-obvious code
+- **Modern syntax** — Use ES6+ features
+
+```javascript
+function handleSearchInput(event) {
+ const query = event.target.value;
+ const results = filterPages(query);
+ renderResults(results);
+}
+```
+
+## Commit Messages
+
+Follow the [Conventional Commits](https://www.conventionalcommits.org/) specification:
+
+```
+type(scope): subject
+
+body (optional)
+
+footer (optional)
+```
+
+### Types
+
+- `feat`: New feature
+- `fix`: Bug fix
+- `docs`: Documentation changes
+- `style`: Code style changes (formatting, etc.)
+- `refactor`: Code refactoring
+- `perf`: Performance improvements
+- `test`: Adding or updating tests
+- `chore`: Maintenance tasks
+
+### Examples
+
+```
+feat(search): add keyboard navigation to search results
+
+fix(toc): correct active link highlighting on scroll
+
+docs(readme): update installation instructions
+
+style(css): reorganize markdown styles into modules
+
+refactor(cards): simplify project card component
+
+perf(images): optimize image loading with lazy loading
+```
+
+## Testing Checklist
+
+Before submitting a pull request, ensure:
+
+- [ ] Hugo builds without errors (`hugo`)
+- [ ] No console errors in browser
+- [ ] Works in latest Chrome, Firefox, Safari
+- [ ] Responsive on mobile, tablet, desktop
+- [ ] Dark and light modes both work
+- [ ] Accessibility: Keyboard navigation works
+- [ ] Performance: Lighthouse score >90
+- [ ] Documentation updated (if applicable)
+- [ ] No breaking changes (or clearly documented)
+
+## File Structure
+
+```
+minimal-black/
+├── archetypes/ # Content templates
+├── assets/
+│ └── css/ # Modular CSS files
+├── layouts/
+│ ├── _default/ # Default layouts
+│ ├── partials/ # Reusable components
+│ └── shortcodes/ # Custom shortcodes
+├── static/
+│ └── js/ # JavaScript files
+├── exampleSite/ # Example site for testing
+├── images/ # Theme screenshots
+├── CSS-STRUCTURE.md # CSS architecture docs
+├── CONTRIBUTING.md # This file
+├── LICENSE # MIT License
+├── README.md # Main documentation
+└── theme.toml # Theme metadata
+```
+
+## Questions?
+
+- **Issues:** [GitLab Issues](https://gitlab.com/jimchr12/hugo-minimal-black/-/issues)
+- **Discussions:** [GitLab Discussions](https://gitlab.com/jimchr12/hugo-minimal-black/-/issues)
+
+## License
+
+By contributing, you agree that your contributions will be licensed under the MIT License.
+
+---
+
+Thank you for contributing to Minimal Black! 🎉
diff --git a/themes/minimal-black/CSS-STRUCTURE.md b/themes/minimal-black/CSS-STRUCTURE.md
new file mode 100644
index 0000000..f840b8f
--- /dev/null
+++ b/themes/minimal-black/CSS-STRUCTURE.md
@@ -0,0 +1,106 @@
+# CSS Architecture
+
+The Minimal Black theme uses a modular CSS architecture for better maintainability and organization.
+
+## Directory Structure
+
+```
+assets/css/
+├── main.css # Entry point (imports all modules)
+├── base.css # Tailwind imports & theme variables
+├── utilities.css # Utility classes & animations
+├── responsive.css # Global responsive styles
+├── components/
+│ ├── dock.css # Floating action dock
+│ ├── cards.css # Card variants (home, project, post, CTA)
+│ ├── navigation.css # Header, footer, nav links
+│ ├── search.css # Search overlay & results
+│ └── tech-marquee.css # Technology carousel
+├── content/
+│ ├── markdown.css # Typography, blockquotes, lists, code
+│ └── toc.css # Table of contents sidebar
+└── pages/
+ ├── about.css # About page with timeline
+ └── about-alternative.css # Alternative about page layout
+```
+
+## Module Descriptions
+
+### Base Layer
+- **base.css**: Tailwind directives, CSS custom properties for theming (light/dark mode), and base body styles
+
+### Utilities
+- **utilities.css**: Color utilities, animation classes, and helper classes used throughout the theme
+
+### Components
+Reusable UI components that appear across multiple pages:
+- **dock.css**: Floating action button dock with expandable panel
+- **cards.css**: All card variants including home cards, project/post cards, CTA cards, and badges
+- **navigation.css**: Page layouts, header, footer, navigation links, and theme toggle
+- **search.css**: Search modal overlay, search results, empty states, and keyboard hints
+- **tech-marquee.css**: Animated technology/skills carousel component
+
+### Content
+Styles specific to content rendering:
+- **markdown.css**: Complete markdown styling including typography, blockquotes, lists, code blocks, tables, GitHub-style alerts, and syntax highlighting
+- **toc.css**: Table of contents sidebar with sticky positioning and active link tracking
+
+### Pages
+Page-specific styles:
+- **about.css**: Standard about page with timeline visualization
+- **about-alternative.css**: Alternative about layout with sidebar profile card and stats
+
+### Responsive
+- **responsive.css**: All media queries and mobile optimizations for global components
+
+## Import Order
+
+The import order in `main.css` is important:
+1. Base styles (Tailwind + variables)
+2. Utilities (available to all components)
+3. Components (dock → cards → navigation → search → tech)
+4. Content styles (markdown → TOC)
+5. Page-specific styles
+6. Responsive overrides
+
+## Development Guidelines
+
+### Adding New Styles
+- Component styles → `components/`
+- Content/typography → `content/`
+- Page-specific → `pages/`
+- Utilities → `utilities.css`
+- Theme variables → `base.css`
+
+### Modifying Existing Styles
+Each file is focused on a specific concern. Find the relevant module and edit it directly. Hugo will automatically rebuild the combined CSS.
+
+### Theme Colors
+All theme colors are defined as CSS custom properties in `base.css`:
+```css
+--color-bg /* Background */
+--color-surface /* Card/surface backgrounds */
+--color-text /* Primary text */
+--color-text-muted /* Secondary text */
+--color-border /* Borders */
+--color-accent /* Primary accent color */
+```
+
+These variables automatically switch between light and dark themes.
+
+### Responsive Breakpoints
+- Mobile: `max-width: 640px`
+- Tablet: `641px - 1023px`
+- Desktop: `min-width: 1024px`
+- Large Desktop: `min-width: 1536px`
+- XL Desktop: `min-width: 1920px`
+
+## Build Process
+
+Hugo processes `main.css` through:
+1. Resolves `@import` statements
+2. Processes Tailwind directives (@tailwind, @apply)
+3. Minifies for production
+4. Outputs to `public/css/main.css`
+
+The modular structure is development-only; users receive a single optimized CSS file.
diff --git a/themes/minimal-black/LICENSE b/themes/minimal-black/LICENSE
new file mode 100644
index 0000000..7a4e610
--- /dev/null
+++ b/themes/minimal-black/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 Jim Christopoulos
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/themes/minimal-black/README.md b/themes/minimal-black/README.md
new file mode 100644
index 0000000..b7a7876
--- /dev/null
+++ b/themes/minimal-black/README.md
@@ -0,0 +1,457 @@
+# Minimal Black
+
+A minimal, dark-mode first Hugo theme with true black backgrounds, purple accents, and comprehensive content styling. Perfect for developers, writers and everyone in general who want a clean, fast, and beautiful personal site.
+
+
+
+
+
+## Features
+
+- ✨ **Dark & Light Mode** — Auto-switching themes with manual toggle
+- 🎨 **True Black Dark Mode** — OLED-friendly with purple (`#a855f7`) accents
+- 📱 **Fully Responsive** — Mobile-first design that works on all devices
+- 🔍 **Built-in Search** — Fast client-side search with keyboard shortcuts (Ctrl/Cmd+K)
+- 📑 **Table of Contents** — Auto-generated TOC for blog posts with active section tracking
+- 💻 **Beautiful Code Blocks** — Syntax highlighting with copy button and language labels
+- 🎯 **Multiple Layouts** — Home, blog, projects, and two about page variants
+- 📊 **Mermaid Diagrams** — Native support for flowcharts and diagrams
+- 🖼️ **Image Gallery** — Gallery shortcode with lightbox functionality
+- 🏷️ **GitHub-Style Alerts** — Support for note, tip, warning, danger, and important callouts
+- 📈 **Analytics Ready** — Built-in support for Google Analytics, Plausible, Umami, and Fathom
+- ⚡ **Performance Optimized** — Minimal JavaScript, CSS, and fast load times
+- 🎭 **Icon Support** — Font Awesome and Devicon integration
+
+## Demo
+
+**Live Demo:** [minimal-black-demo.netlify.app](https://minimal-black-demo.netlify.app)
+
+## Quick Start
+
+### Prerequisites
+
+- Hugo Extended v0.120.0 or higher
+- Node.js and npm (for Tailwind CSS compilation)
+
+### Installation
+
+1. **Create a new Hugo site** (or use existing):
+ ```bash
+ hugo new site my-site
+ cd my-site
+ ```
+
+2. **Install the theme** using Git submodule:
+ ```bash
+ git init
+ git submodule add https://gitlab.com/jimchr12/hugo-minimal-black.git themes/minimal-black
+ ```
+
+ Or clone it directly:
+ ```bash
+ git clone https://gitlab.com/jimchr12/hugo-minimal-black.git themes/minimal-black
+ ```
+
+3. **Install Node dependencies** (for Tailwind CSS):
+ ```bash
+ cd themes/minimal-black
+ npm install
+ cd ../..
+ ```
+
+4. **Configure your site** — Copy the example configuration:
+ ```bash
+ cp themes/minimal-black/exampleSite/hugo.toml ./hugo.toml
+ ```
+
+5. **Start Hugo server**:
+ ```bash
+ hugo server -D
+ ```
+
+6. **Visit** `http://localhost:1313` in your browser.
+
+## Configuration
+
+### Basic Configuration
+
+Edit your `hugo.toml` file:
+
+```toml
+baseURL = 'https://yoursite.com/'
+languageCode = 'en-us'
+title = 'Your Name'
+theme = 'minimal-black'
+
+[params]
+ brand = "Your Name"
+
+ # Favicon (place files in /static/)
+ favicon = "favicon.svg"
+ appleTouchIcon = "apple-touch-icon.png"
+
+ # Theme Configuration
+ [params.theme]
+ defaultTheme = "dark" # "light", "dark", or "system"
+
+ # Hero Section
+ [params.hero]
+ badge = "Software Engineer"
+ title = "Hi, I'm Your Name."
+ role = "Building minimal, fast web experiences."
+ summary = "Brief description of what you do."
+ avatar = "images/avatar.jpg" # Optional
+ location = "City, Country"
+
+ [params.hero.primary]
+ label = "View projects"
+ href = "/projects/"
+
+ [params.hero.secondary]
+ label = "Read the blog"
+ href = "/blog/"
+
+ # Social Links
+ [[params.social]]
+ label = "GitHub"
+ url = "https://github.com/yourusername"
+ icon = "fa-brands fa-github"
+
+ [[params.social]]
+ label = "LinkedIn"
+ url = "https://linkedin.com/in/yourusername"
+ icon = "fa-brands fa-linkedin-in"
+
+[menu]
+ [[menu.main]]
+ name = "Home"
+ url = "/"
+ weight = 1
+
+ [[menu.main]]
+ name = "About"
+ url = "/about/"
+ weight = 2
+
+ [[menu.main]]
+ name = "Projects"
+ url = "/projects/"
+ weight = 3
+
+ [[menu.main]]
+ name = "Blog"
+ url = "/blog/"
+ weight = 4
+
+[markup]
+ [markup.tableOfContents]
+ startLevel = 2
+ endLevel = 4
+
+ [markup.goldmark.renderer]
+ unsafe = true
+
+ [markup.highlight]
+ codeFences = true
+ guessSyntax = true
+ style = "monokai"
+```
+
+### Advanced Configuration
+
+#### Analytics
+
+Google Analytics (GA4):
+```toml
+[params.analytics]
+ googleAnalytics = "G-XXXXXXXXXX"
+```
+
+Plausible Analytics:
+```toml
+[params.analytics.plausible]
+ enabled = true
+ domain = "yourdomain.com"
+```
+
+Umami Analytics:
+```toml
+[params.analytics.umami]
+ enabled = true
+ scriptUrl = "https://analytics.yourdomain.com/script.js"
+ websiteId = "your-website-id"
+```
+
+#### Technology Stack Display
+
+Show your tech stack on the home page:
+```toml
+[params.home]
+ [[params.home.tech]]
+ label = "Python"
+ icon = "devicon-python-plain"
+
+ [[params.home.tech]]
+ label = "Docker"
+ icon = "devicon-docker-plain"
+```
+
+#### About Page Customization
+
+For the alternative about page layout:
+```toml
+[params.about.alt]
+ # Stats in profile card
+ [[params.about.alt.stats]]
+ value = "5+"
+ label = "Years Coding"
+
+ [[params.about.alt.stats]]
+ value = "20+"
+ label = "Projects"
+
+ # Skills with icons
+ [[params.about.alt.skills]]
+ label = "JavaScript"
+ icon = "devicon-javascript-plain"
+```
+
+## Content Organization
+
+### Creating Content
+
+**Blog Post:**
+```bash
+hugo new blog/my-first-post.md
+```
+
+```markdown
++++
+title = "My First Post"
+date = "2025-01-01"
+author = "Your Name"
+tags = ["hugo", "web development"]
+categories = ["tutorials"]
+draft = false
++++
+
+Your content here...
+```
+
+**Project:**
+```bash
+hugo new projects/my-project.md
+```
+
+```markdown
++++
+title = "My Project"
+date = "2025-01-01"
+description = "Brief project description"
+github = "https://github.com/username/project"
+demo = "https://project-demo.com"
+tags = ["react", "typescript"]
+featured = true
++++
+
+Project details...
+```
+
+### About Page
+
+Create `content/about.md`:
+
+```markdown
++++
+title = "About Me"
+subtitle = "Software Engineer | Open Source Contributor"
+layout = "about" # or "about-alternative"
++++
+
+Your introduction here.
+
+---
+
+**Job Title** — [Company](https://company.com)
+*Dates • Location*
+
+Description of role...
+
+---
+
+**Another Role** — Company
+*Dates • Location*
+
+Description...
+```
+
+The `---` separators create timeline entries in the standard about layout, or experience cards in the alternative layout.
+
+## Shortcodes
+
+### Gallery
+
+Create image galleries with lightbox:
+
+```markdown
+{{< gallery >}}
+
+
+
+{{< /gallery >}}
+```
+
+### Alert
+
+Create GitHub-style callouts:
+
+```markdown
+{{< alert type="note" >}}
+This is a note alert.
+{{< /alert >}}
+
+{{< alert type="warning" >}}
+This is a warning alert.
+{{< /alert >}}
+```
+
+Available types: `note`, `tip`, `important`, `warning`, `danger`
+
+### Mermaid Diagrams
+
+````markdown
+```mermaid
+graph TD
+ A[Start] --> B[Process]
+ B --> C[End]
+```
+````
+
+## Customization
+
+### Colors
+
+Theme colors are defined in `assets/css/base.css`:
+
+```css
+:root {
+ --color-bg: #f9fafb; /* Light background */
+ --color-accent: #a855f7; /* Purple accent */
+}
+
+html[data-theme="dark"] {
+ --color-bg: #000000; /* True black */
+ --color-accent: #c084fc; /* Lighter purple */
+}
+```
+
+### CSS Architecture
+
+The theme uses a modular CSS structure:
+
+```
+assets/css/
+├── main.css # Imports all modules
+├── base.css # Tailwind & variables
+├── utilities.css # Utility classes
+├── components/ # Reusable components
+├── content/ # Content styling
+├── pages/ # Page-specific styles
+└── responsive.css # Media queries
+```
+
+See [CSS-STRUCTURE.md](CSS-STRUCTURE.md) for details.
+
+### Adding Custom CSS
+
+Create `assets/css/custom.css` in your site root and import it in your config:
+
+```toml
+[params]
+ customCSS = ["css/custom.css"]
+```
+
+## Deployment
+
+### Netlify
+
+1. Push your site to GitHub
+2. Connect to Netlify
+3. Build command: `hugo --minify`
+4. Publish directory: `public`
+5. Environment variables:
+ ```
+ HUGO_VERSION = 0.120.0
+ NODE_VERSION = 18
+ ```
+
+## Browser Support
+
+- Chrome/Edge (last 2 versions)
+- Firefox (last 2 versions)
+- Safari (last 2 versions)
+- Mobile browsers (iOS Safari, Chrome Mobile)
+
+## Troubleshooting
+
+### CSS not loading
+
+Ensure Tailwind dependencies are installed:
+```bash
+cd themes/minimal-black
+npm install
+```
+
+Also ensure css is compiled:
+```bash
+npx tailwindcss -i ./assets/css/main.css -o ./static/css/main.css
+```
+
+### Search not working
+
+Check that `[outputs]` includes JSON in `hugo.toml`:
+```toml
+[outputs]
+ home = ["HTML", "RSS", "JSON"]
+```
+
+### Icons not showing
+
+Verify icon library is enabled:
+```toml
+[params.icons]
+ useFontAwesome = true
+ useDevicon = true
+```
+
+## Contributing
+
+Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
+
+1. Fork the repository
+2. Create a feature branch
+3. Make your changes
+4. Submit a pull request
+
+## License
+
+This theme is released under the MIT License. See [LICENSE](LICENSE) for details.
+
+## Credits
+
+- Built with [Hugo](https://gohugo.io/)
+- Styled with [Tailwind CSS](https://tailwindcss.com/)
+- Icons from [Font Awesome](https://fontawesome.com/) and [Devicon](https://devicon.dev/)
+- Typography plugin by [@tailwindcss/typography](https://github.com/tailwindlabs/tailwindcss-typography)
+
+## Changelog
+
+See [CHANGELOG.md](CHANGELOG.md) for version history and updates.
+
+---
+
+**Made with ❤️ by [Jim Christopoulos](https://jimchristopoulos.com/)**
+
+If you find this theme useful, consider giving it a ⭐ and/or supporting its development!
+
+[](https://ko-fi.com/jimchr)
diff --git a/themes/minimal-black/assets/css/base.css b/themes/minimal-black/assets/css/base.css
new file mode 100644
index 0000000..c31d77d
--- /dev/null
+++ b/themes/minimal-black/assets/css/base.css
@@ -0,0 +1,35 @@
+/* ==========================================================================
+ BASE STYLES
+ Tailwind imports, CSS variables, theme colors, and base styles
+ ========================================================================== */
+
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+/* Theme Variables */
+:root {
+ /* LIGHT THEME */
+ --color-bg: #f9fafb;
+ --color-surface: #ffffff;
+ --color-text: #111827;
+ --color-text-muted: #6b7280;
+ --color-border: #e5e7eb;
+ --color-accent: #a855f7;
+}
+
+html[data-theme="dark"] {
+ /* DARK THEME */
+ --color-bg: #000000; /* TRUE BLACK */
+ --color-surface: #0a0a0a;
+ --color-text: #f9fafb;
+ --color-text-muted: #9ca3af;
+ --color-border: #27272a;
+ --color-accent: #c084fc;
+}
+
+/* Base Styles */
+body {
+ background: var(--color-bg);
+ color: var(--color-text);
+}
diff --git a/themes/minimal-black/assets/css/components/cards.css b/themes/minimal-black/assets/css/components/cards.css
new file mode 100644
index 0000000..59b34ac
--- /dev/null
+++ b/themes/minimal-black/assets/css/components/cards.css
@@ -0,0 +1,271 @@
+/* ==========================================================================
+ CARD COMPONENTS
+ Home cards, project cards, post cards, CTA cards, badges
+ ========================================================================== */
+
+ .card-home {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ gap: 0.5rem;
+ background-color: color-mix(in srgb, var(--color-surface) 96%, transparent);
+ box-shadow: 0 18px 40px rgba(0, 0, 0, 0.55);
+ }
+
+ .card-home--project {
+ position: relative;
+ overflow: hidden;
+ transition:
+ transform 0.18s ease-out,
+ box-shadow 0.18s ease-out,
+ border-color 0.18s ease-out,
+ background-color 0.18s ease-out;
+ }
+
+ .card-home--project::after {
+ content: "";
+ position: absolute;
+ inset: -40%;
+ background: radial-gradient(
+ circle at 120% 50%,
+ color-mix(in srgb, var(--color-accent) 70%, transparent),
+ transparent 60%
+ );
+ opacity: 0;
+ transform: translateX(-8px);
+ transition:
+ opacity 0.22s ease-out,
+ transform 0.22s ease-out;
+ pointer-events: none;
+ }
+
+ .card-home--project:hover {
+ transform: translateY(-4px) translateX(3px);
+ border-color: color-mix(in srgb, var(--color-accent) 40%, var(--color-border));
+ box-shadow:
+ 0 18px 40px rgba(0, 0, 0, 0.7),
+ 16px 0 38px rgba(124, 58, 237, 0.45); /* purple-ish accent on right */
+ background-color: color-mix(in srgb, var(--color-surface) 99%, transparent);
+ }
+
+ .card-home--project:hover::after {
+ opacity: 0.22;
+ transform: translateX(0);
+ }
+
+ .card-home-body {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ text-decoration: none;
+ color: inherit;
+ }
+
+ .card-home--post {
+ background-color: color-mix(in srgb, var(--color-surface) 94%, transparent);
+ }
+
+ .card-home-header {
+ display: flex;
+ align-items: flex-start;
+ gap: 0.6rem;
+ }
+
+ .card-home-icon {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 2.1rem;
+ height: 2.1rem;
+ border-radius: 999px;
+ border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-bg) 92%, transparent);
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
+ font-size: 0.85rem;
+ }
+
+ .card-badge {
+ margin-left: 0.25rem;
+ padding: 0.05rem 0.35rem;
+ border-radius: 999px;
+ background-color: color-mix(in srgb, var(--color-accent) 22%, transparent);
+ color: var(--color-accent);
+ font-size: 0.6rem;
+ font-weight: 600;
+ }
+
+ .card-home-footer {
+ margin-top: 0.5rem;
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ justify-content: space-between;
+ }
+
+ .card-home-footer--buttons {
+ padding-top: 0.4rem;
+ border-top: 1px solid color-mix(in srgb, var(--color-border) 80%, transparent);
+ }
+
+ .card-tag-row {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.25rem;
+ }
+
+ .card-tag-pill {
+ padding: 0.1rem 0.45rem;
+ border-radius: 999px;
+ border: 1px solid color-mix(in srgb, var(--color-border) 80%, transparent);
+ background-color: color-mix(in srgb, var(--color-bg) 92%, transparent);
+ font-size: 0.65rem;
+ color: var(--color-text-muted);
+ }
+
+ .card-cta {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.35rem;
+ font-size: 0.7rem;
+ color: var(--color-text-muted);
+ text-decoration: none;
+ padding: 0.25rem 0.6rem;
+ border-radius: 999px;
+ border: 1px solid transparent;
+ transition:
+ color 0.15s ease-out,
+ border-color 0.15s ease-out,
+ background-color 0.15s ease-out,
+ transform 0.15s ease-out;
+ }
+
+ .card-cta-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.35rem;
+ padding: 0.25rem 0.6rem;
+ border-radius: 8px;
+ font-size: 0.68rem;
+ color: var(--color-text-muted);
+ background-color: color-mix(in srgb, var(--color-bg) 92%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 80%, transparent);
+ text-decoration: none;
+ transition:
+ color 0.15s ease-out,
+ background-color 0.15s ease-out,
+ border-color 0.15s ease-out,
+ transform 0.15s ease-out,
+ box-shadow 0.15s ease-out;
+ }
+
+ .card-cta-btn:hover {
+ color: var(--color-accent);
+ background-color: color-mix(in srgb, var(--color-surface) 96%, transparent);
+ border-color: color-mix(in srgb, var(--color-accent) 50%, transparent);
+ transform: translateY(-1px);
+ box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
+ }
+
+ .card-cta-repo {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.4rem;
+ padding: 0.25rem 0.7rem;
+ border-radius: 999px;
+ border: 1px solid color-mix(in srgb, var(--color-border) 85%, transparent);
+ background-color: color-mix(in srgb, var(--color-bg) 94%, transparent);
+ font-size: 0.7rem;
+ color: var(--color-text-muted);
+ text-decoration: none;
+ transition:
+ color 0.15s ease-out,
+ border-color 0.15s ease-out,
+ background-color 0.15s ease-out,
+ transform 0.15s ease-out,
+ box-shadow 0.15s ease-out;
+ }
+
+ .card-cta-repo:hover {
+ color: var(--color-accent);
+ border-color: color-mix(in srgb, var(--color-accent) 55%, transparent);
+ background-color: color-mix(in srgb, var(--color-surface) 96%, transparent);
+ transform: translateY(-1px);
+ box-shadow: 0 10px 28px rgba(0, 0, 0, 0.5);
+ }
+
+
+ .card-cta:hover {
+ color: var(--color-accent);
+ border-color: color-mix(in srgb, var(--color-accent) 40%, transparent);
+ background-color: color-mix(in srgb, var(--color-surface) 94%, transparent);
+ transform: translateY(-1px);
+ }
+
+ .card-home--post {
+ position: relative;
+ overflow: hidden;
+ background-color: color-mix(in srgb, var(--color-surface) 94%, transparent);
+ border-left-width: 2px;
+ border-left-color: color-mix(in srgb, var(--color-border) 80%, transparent);
+ transition:
+ transform 0.18s ease-out,
+ box-shadow 0.18s ease-out,
+ border-color 0.18s ease-out,
+ background-color 0.18s ease-out;
+ }
+
+ .card-home--post::before {
+ content: "";
+ position: absolute;
+ left: -4px;
+ top: -20%;
+ bottom: -20%;
+ width: 10px;
+ background: linear-gradient(
+ to bottom,
+ transparent,
+ color-mix(in srgb, var(--color-accent) 70%, transparent),
+ transparent
+ );
+ opacity: 0;
+ transform: translateX(-6px);
+ transition:
+ opacity 0.22s ease-out,
+ transform 0.22s ease-out;
+ pointer-events: none;
+ }
+
+ .card-home--post:hover {
+ transform: translateY(-3px);
+ background-color: color-mix(in srgb, var(--color-surface) 98%, transparent);
+ border-left-color: color-mix(in srgb, var(--color-accent) 55%, var(--color-border));
+ box-shadow: 0 16px 34px rgba(0, 0, 0, 0.65);
+ }
+
+ .card-home--post:hover::before {
+ opacity: 0.55;
+ transform: translateX(0);
+ }
+
+ .card-home-icon--post {
+ background-color: color-mix(in srgb, var(--color-bg) 94%, transparent);
+ }
+
+ .card-badge--soft {
+ background-color: color-mix(in srgb, var(--color-accent) 16%, transparent);
+ color: color-mix(in srgb, var(--color-accent) 85%, white);
+ }
+
+ .card {
+ border-radius: 0.75rem;
+ transition: all 0.2s ease-out;
+ }
+
+ .card-pad {
+ padding: 1rem;
+ }
+
+ .card:hover {
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
+ border-color: color-mix(in srgb, var(--color-accent) 40%, transparent);
+ }
\ No newline at end of file
diff --git a/themes/minimal-black/assets/css/components/dock.css b/themes/minimal-black/assets/css/components/dock.css
new file mode 100644
index 0000000..46580b8
--- /dev/null
+++ b/themes/minimal-black/assets/css/components/dock.css
@@ -0,0 +1,134 @@
+/* ==========================================================================
+ DOCK COMPONENT
+ Floating action dock with toggle and panel
+ ========================================================================== */
+
+@layer components {
+ .dock {
+ position: fixed;
+ right: 1.5rem;
+ bottom: 1.6rem;
+ z-index: 50;
+ }
+
+ .dock-inner {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.45rem;
+ padding: 0.3rem 0.5rem;
+ border-radius: 9999px;
+ /* border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-surface) 92%, transparent);
+ box-shadow: 0 14px 40px rgba(0, 0, 0, 0.55); */
+ backdrop-filter: blur(16px);
+ }
+
+ .dock-panel {
+ @apply p-1;
+ display: inline-flex;
+ align-items: center;
+ gap: 0.35rem;
+ max-width: 0;
+ opacity: 0;
+ transform: translateX(6px);
+ overflow: hidden;
+ transition: max-width 0.18s ease-out, opacity 0.18s ease-out,
+ transform 0.18s ease-out;
+ }
+
+ .dock--open .dock-panel {
+ max-width: 10rem;
+ opacity: 1;
+ transform: translateX(0);
+ }
+
+ .dock-divider {
+ width: 1px;
+ height: 1.4rem;
+ background: linear-gradient(
+ to bottom,
+ transparent,
+ color-mix(in srgb, var(--color-border) 80%, transparent),
+ transparent
+ );
+ }
+
+ .dock-action {
+ @apply flex items-center justify-center;
+ width: 2rem;
+ height: 2rem;
+ border-radius: 9999px;
+ border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-bg) 75%, transparent);
+ color: var(--color-text-muted);
+ cursor: pointer;
+ transition: background-color 0.16s ease-out, border-color 0.16s ease-out,
+ color 0.16s ease-out, transform 0.16s ease-out, box-shadow 0.16s ease-out;
+ }
+
+ .dock-action:hover {
+ border-color: var(--color-accent);
+ color: var(--color-accent);
+ transform: translateY(-1px);
+ /* box-shadow: 0 8px 26px rgba(0, 0, 0, 0.55); */
+ }
+
+ .dock-toggle {
+ @apply flex items-center justify-center;
+ width: 2.1rem;
+ height: 2.1rem;
+ border-radius: 9999px;
+ border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-bg) 85%, transparent);
+ color: var(--color-text-muted);
+ cursor: pointer;
+ transition: background-color 0.16s ease-out, border-color 0.16s ease-out,
+ transform 0.16s ease-out, box-shadow 0.16s ease-out;
+ }
+
+ .dock-toggle:hover {
+ border-color: var(--color-accent);
+ color: var(--color-accent);
+ transform: translateY(-1px);
+ box-shadow: 0 10px 24px rgba(0, 0, 0, 0.5);
+ }
+
+ .dock-toggle-dots {
+ position: relative;
+ display: inline-block;
+ width: 0.8rem;
+ height: 0.16rem;
+ border-radius: 999px;
+ background-color: var(--color-text-muted);
+ }
+
+ .dock-toggle-dots::before,
+ .dock-toggle-dots::after {
+ content: "";
+ position: absolute;
+ inset-y: 0;
+ width: 0.16rem;
+ border-radius: 999px;
+ background-color: var(--color-text-muted);
+ }
+
+ .dock-toggle-dots::before {
+ left: -0.18rem;
+ }
+
+ .dock-toggle-dots::after {
+ right: -0.18rem;
+ }
+
+ .dock--open .dock-toggle-dots,
+ .dock--open .dock-toggle-dots::before,
+ .dock--open .dock-toggle-dots::after {
+ background-color: var(--color-accent);
+ }
+
+ .btn-primary-sm {
+ font-size: 0.75rem;
+ padding: 0.35rem 0.9rem;
+ border-radius: 999px;
+ }
+}
\ No newline at end of file
diff --git a/themes/minimal-black/assets/css/components/navigation.css b/themes/minimal-black/assets/css/components/navigation.css
new file mode 100644
index 0000000..9e9bd57
--- /dev/null
+++ b/themes/minimal-black/assets/css/components/navigation.css
@@ -0,0 +1,203 @@
+/* ==========================================================================
+ LAYOUT & NAVIGATION
+ Page layouts, headers, footers, navigation links
+ ========================================================================== */
+
+ .layout-page {
+ @apply mx-auto max-w-7xl px-4 py-6 sm:px-6 lg:py-12;
+ }
+
+ .layout-page-tight {
+ @apply mx-auto max-w-6xl px-4 py-4 sm:px-6 lg:py-10;
+ }
+
+ .section-stack {
+ @apply space-y-10;
+ }
+
+ .section-stack--home > * + * {
+ margin-top: 1.75rem;
+ }
+
+ .section-stack > div + div.posts-section {
+ border-top: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ padding-top: 1.5rem;
+ }
+
+ /* Headings */
+ .heading-page {
+ @apply text-3xl font-semibold tracking-tight sm:text-4xl;
+ }
+
+ .heading-section {
+ @apply text-sm font-semibold tracking-tight;
+ }
+
+ .eyebrow {
+ @apply text-[0.65rem] uppercase tracking-[0.22em];
+ }
+
+ /* Cards */
+ .card {
+ @apply border border-border bg-surface rounded-xl shadow-sm;
+ }
+
+ .card-pad {
+ @apply p-4 sm:p-5;
+ }
+
+ .card-hover {
+ @apply transition-transform transition-shadow duration-150 ease-out;
+ }
+
+ .card-hover:hover {
+ @apply shadow-lg;
+ transform: translateY(-1px);
+ border-color: var(--color-accent);
+ }
+
+ /* Buttons */
+ .btn-primary {
+ @apply inline-flex items-center rounded-full bg-accent px-4 py-2 text-xs font-medium text-white shadow-sm transition-transform duration-150 ease-out;
+ }
+
+ .btn-primary:hover {
+ transform: translateY(-1px);
+ }
+
+ .btn-ghost {
+ @apply inline-flex items-center text-xs font-medium text-muted;
+ }
+
+ .nav-shell {
+ @apply rounded-full border border-border shadow-md backdrop-blur p-3;
+ background-color: color-mix(in srgb, var(--color-surface) 82%, transparent);
+ }
+
+ .nav-shell::before {
+ content: "";
+ position: absolute;
+ inset-inline: 0;
+ top: 0;
+ bottom: 0;
+ height: 1px;
+ background: linear-gradient(
+ 90deg,
+ transparent,
+ color-mix(in srgb, var(--color-accent) 80%, transparent),
+ transparent
+ );
+ opacity: 0.8;
+ pointer-events: none;
+ }
+
+ .nav-inner {
+ @apply flex items-center justify-between px-4 py-2 sm:px-5 sm:py-2.5;
+ }
+
+ /* Brand logo badge (fallback) */
+ .logo-badge {
+ @apply flex h-8 w-8 items-center justify-center rounded-full bg-accent text-[0.65rem] font-semibold text-white;
+ }
+
+ /* Nav links */
+ .nav-link {
+ @apply text-[0.78rem] font-medium text-muted;
+ }
+
+ .nav-link:hover {
+ color: var(--color-accent);
+ }
+
+ /* Theme toggle */
+ .theme-toggle {
+ @apply inline-flex h-8 w-8 items-center justify-center rounded-full border border-border bg-bg text-muted shadow-sm text-[0.7rem];
+ transition: background-color 0.15s ease-out, color 0.15s ease-out,
+ transform 0.15s ease-out;
+ }
+
+ .theme-toggle:hover {
+ @apply text-accent;
+ transform: translateY(-1px);
+ }
+
+ html[data-theme="dark"] .theme-toggle {
+ background-color: var(--color-surface);
+ }
+
+ /* Fancy underline link */
+ .link-underline {
+ position: relative;
+ display: inline-block;
+ }
+
+ .link-underline::after {
+ content: "";
+ position: absolute;
+ left: 0;
+ bottom: -0.15rem;
+ width: 0;
+ height: 1px;
+ background-color: var(--color-accent);
+ transition: width 0.16s ease-out;
+ }
+
+ .link-underline:hover::after {
+ width: 100%;
+ }
+
+ /* Footer shell */
+ .footer-shell {
+ @apply rounded-2xl border border-border shadow-md backdrop-blur;
+ position: relative;
+ overflow: hidden;
+ background-color: color-mix(in srgb, var(--color-surface) 86%, transparent);
+ }
+
+ .footer-shell::before {
+ content: "";
+ position: absolute;
+ inset-inline: 0;
+ top: 0;
+ height: 1px;
+ background: linear-gradient(
+ 90deg,
+ transparent,
+ color-mix(in srgb, var(--color-accent) 80%, transparent),
+ transparent
+ );
+ opacity: 0.8;
+ pointer-events: none;
+ }
+
+ .footer-inner {
+ @apply flex flex-col gap-3 px-4 py-3 text-[0.72rem] sm:flex-row sm:items-center sm:justify-between sm:px-5;
+ }
+
+ .footer-links {
+ @apply flex flex-wrap items-center gap-3;
+ }
+
+ .footer-link {
+ @apply inline-flex items-center gap-1 text-[0.75rem] font-medium text-muted transition-all duration-150 ease-out;
+ }
+
+ .footer-link:hover {
+ color: var(--color-accent);
+ }
+
+ .footer-small {
+ @apply text-[0.72rem] text-muted leading-relaxed;
+ }
+
+ .footer-float:hover {
+ color: var(--color-accent);
+ transform: translateY(-1px);
+ }
+
+ .footer-float:hover i {
+ filter: drop-shadow(
+ 0 0 2px color-mix(in srgb, var(--color-accent) 60%, transparent)
+ );
+ }
+
diff --git a/themes/minimal-black/assets/css/components/search.css b/themes/minimal-black/assets/css/components/search.css
new file mode 100644
index 0000000..6842705
--- /dev/null
+++ b/themes/minimal-black/assets/css/components/search.css
@@ -0,0 +1,289 @@
+/* ==========================================================================
+ SEARCH OVERLAY
+ Search modal, search results, empty states
+ ========================================================================== */
+
+ .search-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 40;
+ display: none;
+ align-items: center;
+ justify-content: center;
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.18s ease-out;
+ }
+
+ .search-overlay--open {
+ opacity: 1;
+ display: block;
+ pointer-events: auto;
+ }
+
+ .search-overlay-backdrop {
+ position: absolute;
+ inset: 0;
+ background: radial-gradient(
+ circle at top,
+ rgba(0, 0, 0, 0.4),
+ transparent 55%
+ ),
+ rgba(0, 0, 0, 0.7);
+ backdrop-filter: blur(12px);
+ }
+
+ .search-panel {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+
+ width: 100%;
+ max-width: 36rem;
+ margin-inline: 1.5rem;
+
+ border-radius: 1.1rem;
+ border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-bg) 96%, transparent);
+ box-shadow: 0 26px 70px rgba(0, 0, 0, 0.85);
+ padding: 0.8rem 0.9rem 0.6rem;
+ display: flex;
+ flex-direction: column;
+ gap: 0.6rem;
+ }
+
+ .search-overlay--open .search-panel {
+ animation: search-panel-in 0.18s ease-out;
+ }
+
+ .search-overlay-backdrop {
+ position: absolute;
+ inset: 0;
+ background: radial-gradient(
+ circle at top,
+ rgba(0, 0, 0, 0.4),
+ transparent 55%
+ ),
+ rgba(0, 0, 0, 0.7);
+ backdrop-filter: blur(12px);
+ }
+
+ .search-overlay .search-overlay--open .search-overlay-backdrop {
+ animation: search-backdrop-in 0.18s ease-out;
+ }
+
+ .search-overlay--closing .search-panel {
+ animation: search-panel-out 0.18s ease-in forwards;
+ }
+
+ .search-overlay--closing .search-overlay-backdrop {
+ animation: search-backdrop-out 0.18s ease-in forwards;
+ }
+
+ .search-panel-header {
+ display: flex;
+ align-items: center;
+ gap: 0.6rem;
+ }
+
+ .search-input-wrap {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.45rem 0.8rem;
+ border-radius: 999px;
+ border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-surface) 96%, transparent);
+ }
+
+ .search-input {
+ flex: 1;
+ border: none;
+ outline: none;
+ font-size: 0.82rem;
+ background: transparent;
+ color: var(--color-text);
+ }
+
+ .search-input::placeholder {
+ color: var(--color-text-muted);
+ }
+
+ .search-close {
+ width: 2rem;
+ height: 2rem;
+ border-radius: 999px;
+ border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-bg) 90%, transparent);
+ color: var(--color-text-muted);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: background-color 0.16s ease-out, border-color 0.16s ease-out,
+ color 0.16s ease-out, transform 0.16s ease-out;
+ }
+
+ .search-close:hover {
+ border-color: var(--color-accent);
+ color: var(--color-accent);
+ transform: translateY(-1px);
+ }
+
+ .search-panel-body {
+ border-radius: 0.9rem;
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ background-color: color-mix(in srgb, var(--color-surface) 96%, transparent);
+ padding: 0.5rem 0.4rem 0.4rem;
+ display: flex;
+ flex-direction: column;
+ }
+
+ .search-results {
+ max-height: 18rem;
+ padding: 0.25rem 0.15rem 0.4rem;
+ overflow-y: auto;
+ }
+
+ .search-empty-state {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 1.2rem 0.5rem 1.4rem;
+ gap: 0.4rem;
+ }
+
+ .search-empty-icon {
+ width: 2.3rem;
+ height: 2.3rem;
+ border-radius: 999px;
+ border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-bg) 92%, transparent);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ .search-empty-title {
+ font-size: 0.86rem;
+ font-weight: 600;
+ color: var(--color-text);
+ }
+
+ .search-empty-subtitle {
+ font-size: 0.76rem;
+ color: var(--color-text-muted);
+ }
+
+ .search-footer-hints {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.45rem;
+ border-top: 1px solid
+ color-mix(in srgb, var(--color-border) 75%, transparent);
+ padding: 0.4rem 0.5rem 0.1rem;
+ margin-top: 0.1rem;
+ }
+
+ .search-hint-key {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.25rem;
+ font-size: 0.68rem;
+ color: var(--color-text-muted);
+ }
+
+ .search-hint-key span:first-child,
+ .search-hint-key span:nth-child(2) {
+ padding: 0.1rem 0.3rem;
+ border-radius: 0.3rem;
+ border: 1px solid color-mix(in srgb, var(--color-border) 80%, transparent);
+ background-color: color-mix(in srgb, var(--color-bg) 96%, transparent);
+ font-size: 0.65rem;
+ }
+
+ .search-hint-key.search-hint-right {
+ margin-left: auto;
+ }
+
+ .search-result-item {
+ display: block;
+ padding: 0.42rem 0.55rem;
+ border-radius: 0.6rem;
+ text-decoration: none;
+ transition: background-color 0.12s ease-out, transform 0.12s ease-out;
+ }
+
+ .search-result-item:hover {
+ background-color: color-mix(in srgb, var(--color-surface) 92%, transparent);
+ transform: translateY(-1px);
+ }
+
+ .search-result-title {
+ font-size: 0.8rem;
+ font-weight: 500;
+ color: var(--color-text);
+ }
+
+ .search-result-meta {
+ margin-top: 0.15rem;
+ font-size: 0.7rem;
+ color: var(--color-text-muted);
+ }
+ .search-footer-hints {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.45rem;
+ border-top: 1px solid
+ color-mix(in srgb, var(--color-border) 75%, transparent);
+ padding: 0.4rem 0.5rem 0.1rem;
+ margin-top: 0.1rem;
+ }
+
+ .search-hint-key {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.25rem;
+ font-size: 0.68rem;
+ color: var(--color-text-muted);
+ }
+
+ .search-hint-key span:first-child,
+ .search-hint-key span:nth-child(2) {
+ padding: 0.1rem 0.3rem;
+ border-radius: 0.3rem;
+ border: 1px solid color-mix(in srgb, var(--color-border) 80%, transparent);
+ background-color: color-mix(in srgb, var(--color-bg) 96%, transparent);
+ font-size: 0.65rem;
+ }
+
+ .search-hint-key.search-hint-right {
+ margin-left: auto;
+ }
+
+ .search-result-item {
+ display: block;
+ padding: 0.42rem 0.55rem;
+ border-radius: 0.6rem;
+ text-decoration: none;
+ transition: background-color 0.12s ease-out, transform 0.12s ease-out;
+ }
+
+ .search-result-item:hover {
+ background-color: color-mix(in srgb, var(--color-surface) 92%, transparent);
+ transform: translateY(-1px);
+ }
+
+ .search-result-title {
+ font-size: 0.8rem;
+ font-weight: 500;
+ color: var(--color-text);
+ }
+
+ .search-result-meta {
+ margin-top: 0.15rem;
+ font-size: 0.7rem;
+ color: var(--color-text-muted);
+ }
diff --git a/themes/minimal-black/assets/css/components/tech-marquee.css b/themes/minimal-black/assets/css/components/tech-marquee.css
new file mode 100644
index 0000000..b42c905
--- /dev/null
+++ b/themes/minimal-black/assets/css/components/tech-marquee.css
@@ -0,0 +1,111 @@
+/* ==========================================================================
+ TECH MARQUEE
+ Technology carousel/strip component
+ ========================================================================== */
+
+ .tech-carousel {
+ display: flex;
+ gap: 0.5rem;
+ padding: 0.3rem 0.1rem 0.1rem;
+ overflow-x: auto;
+ scroll-snap-type: x mandatory;
+ }
+
+ .tech-carousel::-webkit-scrollbar {
+ height: 4px;
+ }
+
+ .tech-carousel::-webkit-scrollbar-thumb {
+ border-radius: 999px;
+ background-color: rgba(255, 255, 255, 0.12);
+ }
+
+ .tech-pill {
+ scroll-snap-align: start;
+ display: inline-flex;
+ align-items: center;
+ gap: 0.4rem;
+ padding: 0.35rem 0.7rem;
+ border-radius: 999px;
+ border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-surface) 92%, transparent);
+ box-shadow: 0 10px 28px rgba(0, 0, 0, 0.28);
+ white-space: nowrap;
+ }
+
+ .badge-available {
+ @apply inline-flex items-center gap-1.5;
+ padding: 0.25rem 0.7rem;
+ border-radius: 999px;
+ background-color: var(--color-accent);
+ color: white;
+ font-size: 0.7rem;
+ font-weight: 600;
+ box-shadow: 0 0 0.4rem rgba(0, 0, 0, 0.4);
+ }
+
+ /* --- Tech marquee --- */
+ .tech-icon {
+ font-size: 1.5rem;
+ }
+
+ .tech-strip {
+ position: relative;
+ overflow: hidden;
+ padding-block: 0.4rem;
+ }
+
+ .tech-strip-track {
+ @apply py-2;
+ display: inline-flex;
+ align-items: center;
+ white-space: nowrap;
+ animation-name: tech-marquee;
+ animation-timing-function: linear;
+ animation-iteration-count: infinite;
+ animation-play-state: running;
+ }
+
+ .tech-strip-track {
+ gap: 1.5rem;
+ }
+
+ .tech-strip--wide .tech-strip-track--primary {
+ animation-duration: 40s;
+ }
+
+ .tech-strip--wide .tech-strip-track--secondary {
+ animation-duration: 40s;
+ animation-direction: reverse;
+ }
+
+ .tech-strip--compact .tech-strip-track--primary {
+ animation-duration: 40s;
+ }
+
+ .tech-strip--compact .tech-strip-track--secondary {
+ animation-duration: 48s;
+ animation-direction: reverse;
+ }
+
+ .tech-strip--compact .tech-strip-track {
+ gap: 1.1rem;
+ }
+
+ /* pause both rows on hover */
+ .tech-strip:hover .tech-strip-track {
+ animation-play-state: paused;
+ }
+
+ .tech-strip-item {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.4rem;
+ opacity: 0.88;
+ transition: opacity 0.15s ease-out, transform 0.15s ease-out;
+ }
+
+ .tech-strip-item:hover {
+ opacity: 1;
+ transform: translateY(-1px);
+ }
diff --git a/themes/minimal-black/assets/css/content/markdown.css b/themes/minimal-black/assets/css/content/markdown.css
new file mode 100644
index 0000000..f5b8252
--- /dev/null
+++ b/themes/minimal-black/assets/css/content/markdown.css
@@ -0,0 +1,1372 @@
+/* ==========================================================================
+ MARKDOWN CONTENT STYLES
+ Typography, blockquotes, lists, code blocks, tables, alerts
+ ========================================================================== */
+
+ .markdown-body {
+ max-width: 85ch;
+ margin-inline: auto;
+ font-size: 0.95rem;
+ line-height: 1.75;
+ color: var(--color-text);
+ overflow-wrap: break-word;
+ word-wrap: break-word;
+ min-width: 0;
+ }
+
+ /* rhythm */
+ .markdown-body > * {
+ margin-top: 0;
+ margin-bottom: 0;
+ }
+
+ .markdown-body > * + * {
+ margin-top: 1.25rem;
+ }
+
+ /* paragraphs */
+ .markdown-body p {
+ color: var(--color-text);
+ line-height: 1.75;
+ }
+
+ /* headings */
+ .markdown-body h1,
+ .markdown-body h2,
+ .markdown-body h3,
+ .markdown-body h4,
+ .markdown-body h5,
+ .markdown-body h6 {
+ color: var(--color-text);
+ font-weight: 650;
+ line-height: 1.3;
+ letter-spacing: -0.01em;
+ margin-top: 2rem;
+ margin-bottom: 0.75rem;
+ }
+
+ .markdown-body h1 {
+ font-size: 2rem;
+ margin-top: 0;
+ }
+
+ .markdown-body h2 {
+ font-size: 1.5rem;
+ padding-bottom: 0.4rem;
+ border-bottom: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ margin-top: 2.5rem;
+ }
+
+ .markdown-body h3 {
+ font-size: 1.25rem;
+ margin-top: 2rem;
+ }
+
+ .markdown-body h4 {
+ font-size: 1.1rem;
+ }
+
+ .markdown-body h5 {
+ font-size: 1rem;
+ }
+
+ .markdown-body h6 {
+ font-size: 0.85rem;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ color: var(--color-text-muted);
+ }
+
+ /* links */
+ .markdown-body a {
+ color: var(--color-accent);
+ text-decoration: none;
+ border-bottom: 1px solid color-mix(in srgb, var(--color-accent) 35%, transparent);
+ padding-bottom: 0.05rem;
+ transition: color 0.15s ease-out, border-color 0.15s ease-out;
+ word-wrap: break-word;
+ overflow-wrap: break-word;
+ word-break: break-word;
+ }
+
+ .markdown-body a:hover {
+ color: color-mix(in srgb, var(--color-accent) 85%, white);
+ border-bottom-color: var(--color-accent);
+ }
+
+ /* strong and emphasis */
+ .markdown-body strong {
+ font-weight: 650;
+ color: var(--color-text);
+ }
+
+ .markdown-body em {
+ font-style: italic;
+ }
+
+ /* lists */
+ .markdown-body ul,
+ .markdown-body ol {
+ padding-left: 1.75rem;
+ margin-top: 1rem;
+ margin-bottom: 1rem;
+ }
+
+ .markdown-body li {
+ margin: 0.5rem 0;
+ line-height: 1.7;
+ padding-left: 0.5rem;
+ position: relative;
+ transition: background-color 0.15s ease-out;
+ }
+
+ .markdown-body li:hover {
+ background-color: color-mix(in srgb, var(--color-surface) 30%, transparent);
+ border-radius: 0.35rem;
+ }
+
+ .markdown-body li > ul,
+ .markdown-body li > ol {
+ margin-top: 0.5rem;
+ margin-bottom: 0.5rem;
+ }
+
+ /* Unordered list markers */
+ .markdown-body ul li::marker {
+ color: var(--color-accent);
+ font-size: 1.1em;
+ }
+
+ .markdown-body ul {
+ list-style-type: disc;
+ }
+
+ .markdown-body ul ul {
+ list-style-type: circle;
+ }
+
+ .markdown-body ul ul ul {
+ list-style-type: square;
+ }
+
+ /* Ordered list markers */
+ .markdown-body ol {
+ list-style-type: decimal;
+ }
+
+ .markdown-body ol li::marker {
+ color: var(--color-accent);
+ font-weight: 700;
+ font-size: 0.95em;
+ }
+
+ .markdown-body ol ol {
+ list-style-type: lower-alpha;
+ }
+
+ .markdown-body ol ol ol {
+ list-style-type: lower-roman;
+ }
+
+ /* Better spacing for nested lists */
+ .markdown-body li > p {
+ margin-top: 0.35rem;
+ margin-bottom: 0.35rem;
+ }
+
+ .markdown-body li:first-child {
+ margin-top: 0;
+ }
+
+ .markdown-body li:last-child {
+ margin-bottom: 0;
+ }
+
+ /* definition lists */
+ .markdown-body dl {
+ margin: 1.5rem 0;
+ padding: 1.25rem;
+ border-left: 3px solid var(--color-accent);
+ background: linear-gradient(
+ to right,
+ color-mix(in srgb, var(--color-accent) 8%, transparent),
+ color-mix(in srgb, var(--color-surface) 40%, transparent) 3rem
+ );
+ border-radius: 0.6rem;
+ }
+
+ .markdown-body dt {
+ font-weight: 650;
+ color: var(--color-text);
+ margin-top: 1rem;
+ margin-bottom: 0.5rem;
+ font-size: 1rem;
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ }
+
+ .markdown-body dt:first-child {
+ margin-top: 0;
+ }
+
+ .markdown-body dt::before {
+ content: '▸';
+ color: var(--color-accent);
+ font-size: 0.9em;
+ font-weight: bold;
+ }
+
+ .markdown-body dd {
+ margin-left: 1.5rem;
+ margin-bottom: 0.75rem;
+ padding-left: 1rem;
+ border-left: 2px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ color: var(--color-text-muted);
+ line-height: 1.7;
+ }
+
+ .markdown-body dd:last-child {
+ margin-bottom: 0;
+ }
+
+ .markdown-body dd > p {
+ margin: 0.25rem 0;
+ }
+
+ .markdown-body dd > p:first-child {
+ margin-top: 0;
+ }
+
+ .markdown-body dd > p:last-child {
+ margin-bottom: 0;
+ }
+
+ /* task lists */
+ .markdown-body ul.contains-task-list {
+ list-style: none;
+ padding-left: 0;
+ }
+
+ .markdown-body .task-list-item {
+ display: flex;
+ align-items: flex-start;
+ gap: 0.65rem;
+ padding: 0.5rem 0.75rem;
+ margin: 0.35rem 0;
+ border-radius: 0.45rem;
+ transition: all 0.15s ease-out;
+ background-color: color-mix(in srgb, var(--color-surface) 20%, transparent);
+ }
+
+ .markdown-body .task-list-item:hover {
+ background-color: color-mix(in srgb, var(--color-surface) 50%, transparent);
+ transform: translateX(3px);
+ }
+
+ .markdown-body .task-list-item input[type="checkbox"] {
+ margin-top: 0.35rem;
+ flex-shrink: 0;
+ width: 1.1rem;
+ height: 1.1rem;
+ cursor: pointer;
+ accent-color: var(--color-accent);
+ border-radius: 0.25rem;
+ }
+
+ .markdown-body .task-list-item input[type="checkbox"]:checked {
+ accent-color: #22c55e;
+ }
+
+ .markdown-body .task-list-item input[type="checkbox"]:checked + * {
+ color: var(--color-text-muted);
+ text-decoration: line-through;
+ text-decoration-color: var(--color-text-muted);
+ }
+
+ /* blockquote */
+ .markdown-body blockquote,
+ .markdown-body .md-blockquote {
+ margin: 1.75rem 0;
+ padding: 1.25rem 1.5rem;
+ border-left: 4px solid var(--color-accent);
+ background: linear-gradient(
+ to right,
+ color-mix(in srgb, var(--color-accent) 8%, transparent),
+ color-mix(in srgb, var(--color-surface) 60%, transparent) 3rem
+ );
+ border-radius: 0.6rem;
+ color: var(--color-text);
+ font-style: italic;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+ position: relative;
+ }
+
+ .markdown-body blockquote::before,
+ .markdown-body .md-blockquote::before {
+ content: '"';
+ position: absolute;
+ left: 0.75rem;
+ top: 0.5rem;
+ font-size: 2.5rem;
+ line-height: 1;
+ color: color-mix(in srgb, var(--color-accent) 25%, transparent);
+ font-family: Georgia, serif;
+ font-weight: bold;
+ }
+
+ .markdown-body blockquote p,
+ .markdown-body .md-blockquote p {
+ color: var(--color-text);
+ font-size: 0.98rem;
+ line-height: 1.7;
+ }
+
+ .markdown-body blockquote p + p,
+ .markdown-body .md-blockquote p + p {
+ margin-top: 0.85rem;
+ }
+
+ .markdown-body blockquote strong,
+ .markdown-body .md-blockquote strong {
+ color: var(--color-text);
+ font-weight: 650;
+ }
+
+ /* GitHub-style alerts */
+ .markdown-body .md-alert {
+ margin: 1.75rem 0;
+ padding: 1rem 1.25rem 1rem 3rem;
+ border-radius: 0.6rem;
+ border-left: 4px solid;
+ position: relative;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+ }
+
+ .markdown-body .md-alert::before {
+ content: '';
+ position: absolute;
+ left: 1rem;
+ top: 1.1rem;
+ width: 1.25rem;
+ height: 1.25rem;
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+ }
+
+ .markdown-body .md-alert p:first-child {
+ margin-top: 0;
+ }
+
+ .markdown-body .md-alert p:last-child {
+ margin-bottom: 0;
+ }
+
+ /* Note alert (blue) */
+ .markdown-body .md-alert-note {
+ background: linear-gradient(
+ to right,
+ color-mix(in srgb, #3b82f6 10%, transparent),
+ color-mix(in srgb, var(--color-surface) 60%, transparent) 3rem
+ );
+ border-left-color: #3b82f6;
+ }
+
+ .markdown-body .md-alert-note::before {
+ content: 'ℹ';
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 1rem;
+ font-weight: bold;
+ color: #3b82f6;
+ background: none;
+ }
+
+ /* Tip alert (green) */
+ .markdown-body .md-alert-tip {
+ background: linear-gradient(
+ to right,
+ color-mix(in srgb, #22c55e 10%, transparent),
+ color-mix(in srgb, var(--color-surface) 60%, transparent) 3rem
+ );
+ border-left-color: #22c55e;
+ }
+
+ .markdown-body .md-alert-tip::before {
+ content: '💡';
+ font-size: 1.1rem;
+ }
+
+ /* Important alert (purple) */
+ .markdown-body .md-alert-important {
+ background: linear-gradient(
+ to right,
+ color-mix(in srgb, var(--color-accent) 12%, transparent),
+ color-mix(in srgb, var(--color-surface) 60%, transparent) 3rem
+ );
+ border-left-color: var(--color-accent);
+ }
+
+ .markdown-body .md-alert-important::before {
+ content: '⚡';
+ font-size: 1.1rem;
+ }
+
+ /* Warning alert (yellow/orange) */
+ .markdown-body .md-alert-warning {
+ background: linear-gradient(
+ to right,
+ color-mix(in srgb, #f59e0b 10%, transparent),
+ color-mix(in srgb, var(--color-surface) 60%, transparent) 3rem
+ );
+ border-left-color: #f59e0b;
+ }
+
+ .markdown-body .md-alert-warning::before {
+ content: '⚠';
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 1.1rem;
+ color: #f59e0b;
+ background: none;
+ }
+
+ /* Danger/Caution alert (red) */
+ .markdown-body .md-alert-danger,
+ .markdown-body .md-alert-caution {
+ background: linear-gradient(
+ to right,
+ color-mix(in srgb, #ef4444 10%, transparent),
+ color-mix(in srgb, var(--color-surface) 60%, transparent) 3rem
+ );
+ border-left-color: #ef4444;
+ }
+
+ .markdown-body .md-alert-danger::before,
+ .markdown-body .md-alert-caution::before {
+ content: '🛑';
+ font-size: 1.1rem;
+ }
+
+ /* inline code */
+ .markdown-body :not(pre) > code {
+ font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
+ font-size: 0.88em;
+ padding: 0.15rem 0.4rem;
+ border-radius: 0.35rem;
+ background: color-mix(in srgb, var(--color-surface) 80%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ color: color-mix(in srgb, var(--color-accent) 90%, white);
+ }
+
+ html[data-theme="light"] .markdown-body :not(pre) > code {
+ background: #f3f4f6;
+ border-color: #d1d5db;
+ color: #7c3aed;
+ }
+
+ /* CODE BLOCKS - This is the important part */
+ .markdown-body pre {
+ margin: 1.5rem 0;
+ padding: 0;
+ overflow: hidden;
+ overflow-x: auto;
+ border-radius: 0.75rem;
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ background: color-mix(in srgb, var(--color-surface) 40%, transparent);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
+ max-width: 100%;
+ }
+
+ html[data-theme="light"] .markdown-body pre {
+ background: #f9fafb;
+ border-color: #e5e7eb;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+ }
+
+ .markdown-body pre code {
+ display: block;
+ padding: 1.25rem 1.5rem;
+ overflow-x: auto;
+ font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
+ font-size: 0.88rem;
+ line-height: 1.6;
+ color: var(--color-text);
+ background: transparent;
+ border: none;
+ }
+
+ /* Code block with header (language badge) */
+ .markdown-body .highlight {
+ position: relative;
+ background: color-mix(in srgb, var(--color-surface) 40%, transparent);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
+ overflow: hidden;
+ }
+
+ .markdown-body .highlight pre {
+ margin: 0;
+ border: none;
+ border-radius: 0;
+ box-shadow: none;
+ }
+
+ /* Custom code block wrapper (if you want header with language/copy button) */
+ .mb-codeblock {
+ margin: 1.5rem 0;
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ border-radius: 0.75rem;
+ overflow: hidden;
+ background: color-mix(in srgb, var(--color-surface) 40%, transparent);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
+ }
+
+ .mb-codeblock-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0.75rem 1rem;
+ border-bottom: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ background: color-mix(in srgb, var(--color-bg) 50%, transparent);
+ }
+
+ .mb-codeblock-left {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ }
+
+ .mb-codeblock-label {
+ color: var(--color-text-muted);
+ font-size: 0.75rem;
+ font-weight: 500;
+ letter-spacing: 0.02em;
+ }
+
+ .mb-codeblock-badge {
+ font-size: 0.7rem;
+ font-weight: 600;
+ padding: 0.2rem 0.5rem;
+ border-radius: 0.35rem;
+ background: color-mix(in srgb, var(--color-accent) 20%, transparent);
+ color: var(--color-accent);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ }
+
+ .mb-codeblock-actions {
+ display: flex;
+ gap: 0.25rem;
+ }
+
+ .mb-codeblock-actions button {
+ background: transparent;
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ color: var(--color-text-muted);
+ cursor: pointer;
+ font-size: 0.7rem;
+ padding: 0.3rem 0.6rem;
+ border-radius: 0.35rem;
+ transition: all 0.15s ease-out;
+ display: flex;
+ align-items: center;
+ gap: 0.35rem;
+ }
+
+ .mb-codeblock-actions button:hover {
+ color: var(--color-accent);
+ background: color-mix(in srgb, var(--color-accent) 15%, transparent);
+ border-color: var(--color-accent);
+ }
+
+ .mb-codeblock-content {
+ position: relative;
+ }
+
+ .mb-codeblock-content pre {
+ margin: 0;
+ padding: 1.25rem 1.5rem;
+ overflow-x: auto;
+ border: none;
+ border-radius: 0;
+ background: transparent;
+ box-shadow: none;
+ }
+
+ .mb-codeblock-content code {
+ font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
+ font-size: 0.88rem;
+ line-height: 1.6;
+ }
+
+ /* tables */
+ .markdown-body table {
+ width: 100%;
+ margin: 1.5rem 0;
+ border-collapse: collapse;
+ font-size: 0.9rem;
+ border-radius: 0.75rem;
+ overflow: hidden;
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ }
+
+ .markdown-body thead {
+ background: color-mix(in srgb, var(--color-surface) 60%, transparent);
+ }
+
+ .markdown-body th {
+ padding: 0.75rem 1rem;
+ text-align: left;
+ font-weight: 600;
+ color: var(--color-text);
+ border-bottom: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ }
+
+ .markdown-body td {
+ padding: 0.75rem 1rem;
+ border-bottom: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ }
+
+ .markdown-body tbody tr:last-child td {
+ border-bottom: none;
+ }
+
+ .markdown-body tbody tr:hover {
+ background: color-mix(in srgb, var(--color-surface) 30%, transparent);
+ }
+
+ /* hr */
+ .markdown-body hr {
+ border: 0;
+ border-top: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ margin: 2rem 0;
+ }
+
+ /* Custom link with external indicator */
+ .markdown-body .md-link {
+ position: relative;
+ }
+
+ .markdown-body a.md-link[target="_blank"]::after {
+ display: inline-block;
+ margin-left: 0.25rem;
+ font-size: 0.85em;
+ opacity: 0.6;
+ transition: all 0.15s ease-out;
+ }
+
+ .markdown-body a.md-link[target="_blank"]:hover::after {
+ opacity: 1;
+ transform: translate(2px, -2px);
+ }
+
+ /* Heading anchors with hover effect */
+ .markdown-body .md-heading-anchor {
+ position: relative;
+ color: inherit;
+ text-decoration: none;
+ border-bottom: none;
+ padding-bottom: 0;
+ }
+
+ .markdown-body .md-heading-anchor::before {
+ content: '#';
+ position: absolute;
+ left: -1.5rem;
+ opacity: 0;
+ color: var(--color-accent);
+ font-weight: 400;
+ transition: opacity 0.15s ease-out;
+ }
+
+ .markdown-body h1:hover .md-heading-anchor::before,
+ .markdown-body h2:hover .md-heading-anchor::before,
+ .markdown-body h3:hover .md-heading-anchor::before,
+ .markdown-body h4:hover .md-heading-anchor::before,
+ .markdown-body h5:hover .md-heading-anchor::before,
+ .markdown-body h6:hover .md-heading-anchor::before {
+ opacity: 1;
+ }
+
+ .markdown-body .md-heading-anchor:hover {
+ color: var(--color-accent);
+ }
+
+ /* Table wrapper for horizontal scrolling */
+ .markdown-body .table-wrap {
+ margin: 1.75rem 0;
+ overflow-x: auto;
+ border-radius: 0.75rem;
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+ }
+
+ .markdown-body .table-wrap table {
+ margin: 0;
+ border: none;
+ border-radius: 0;
+ }
+
+ /* Custom scrollbar for table wrapper */
+ .markdown-body .table-wrap::-webkit-scrollbar {
+ height: 8px;
+ }
+
+ .markdown-body .table-wrap::-webkit-scrollbar-track {
+ background: color-mix(in srgb, var(--color-bg) 30%, transparent);
+ border-radius: 0 0 0.75rem 0.75rem;
+ }
+
+ .markdown-body .table-wrap::-webkit-scrollbar-thumb {
+ background: color-mix(in srgb, var(--color-accent) 50%, transparent);
+ border-radius: 4px;
+ }
+
+ .markdown-body .table-wrap::-webkit-scrollbar-thumb:hover {
+ background: var(--color-accent);
+ }
+
+ /* images */
+ .markdown-body img {
+ display: block;
+ max-width: 100%;
+ height: auto;
+ margin: 1.5rem auto;
+ border-radius: 0.75rem;
+ border: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ }
+
+ .markdown-body figure {
+ margin: 1.5rem 0;
+ text-align: center;
+ }
+
+ .markdown-body figcaption {
+ margin-top: 0.5rem;
+ font-size: 0.85rem;
+ color: var(--color-text-muted);
+ font-style: italic;
+ }
+
+ /* Custom image wrapper with lightbox */
+ .markdown-body .md-image {
+ margin: 2rem 0;
+ text-align: center;
+ }
+
+ .markdown-body .md-image a {
+ display: inline-block;
+ position: relative;
+ overflow: hidden;
+ border-radius: 0.85rem;
+ border: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ transition: all 0.25s ease-out;
+ border-bottom: none;
+ padding-bottom: 0;
+ }
+
+ .markdown-body .md-image a::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(
+ 135deg,
+ color-mix(in srgb, var(--color-accent) 0%, transparent),
+ color-mix(in srgb, var(--color-accent) 15%, transparent)
+ );
+ opacity: 0;
+ transition: opacity 0.25s ease-out;
+ pointer-events: none;
+ z-index: 1;
+ }
+
+ .markdown-body .md-image a::after {
+ content: '🔍';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%) scale(0.8);
+ font-size: 2.5rem;
+ opacity: 0;
+ transition: all 0.25s ease-out;
+ z-index: 2;
+ pointer-events: none;
+ filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.5));
+ }
+
+ .markdown-body .md-image a:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 12px 28px rgba(0, 0, 0, 0.25);
+ border-color: color-mix(in srgb, var(--color-accent) 50%, transparent);
+ }
+
+ .markdown-body .md-image a:hover::before {
+ opacity: 1;
+ }
+
+ .markdown-body .md-image a:hover::after {
+ opacity: 1;
+ transform: translate(-50%, -50%) scale(1);
+ }
+
+ .markdown-body .md-image img {
+ margin: 0;
+ border: none;
+ border-radius: 0.75rem;
+ display: block;
+ transition: all 0.25s ease-out;
+ }
+
+ .markdown-body .md-image a:hover img {
+ filter: brightness(0.85);
+ }
+
+ .markdown-body .md-image figcaption {
+ display: none;
+ }
+
+ /* SYNTAX HIGHLIGHTING - Dark theme colors */
+ /* These will be applied by Hugo's Chroma */
+ .markdown-body .chroma {
+ background: transparent;
+ }
+
+ .markdown-body .chroma .err { color: #f87171; }
+ .markdown-body .chroma .lntd { padding: 0; }
+ .markdown-body .chroma .lntable { border-spacing: 0; }
+
+ /* Chroma syntax colors for dark theme */
+ html[data-theme="dark"] .markdown-body .chroma .k { color: #c084fc; } /* keyword - purple */
+ html[data-theme="dark"] .markdown-body .chroma .kc { color: #c084fc; }
+ html[data-theme="dark"] .markdown-body .chroma .kd { color: #c084fc; }
+ html[data-theme="dark"] .markdown-body .chroma .kn { color: #c084fc; }
+ html[data-theme="dark"] .markdown-body .chroma .kp { color: #c084fc; }
+ html[data-theme="dark"] .markdown-body .chroma .kr { color: #c084fc; }
+ html[data-theme="dark"] .markdown-body .chroma .kt { color: #c084fc; }
+
+ html[data-theme="dark"] .markdown-body .chroma .n { color: #e5e7eb; }
+ html[data-theme="dark"] .markdown-body .chroma .na { color: #fbbf24; }
+ html[data-theme="dark"] .markdown-body .chroma .nb { color: #60a5fa; }
+ html[data-theme="dark"] .markdown-body .chroma .nc { color: #fbbf24; }
+ html[data-theme="dark"] .markdown-body .chroma .nf { color: #60a5fa; }
+ html[data-theme="dark"] .markdown-body .chroma .nn { color: #fbbf24; }
+
+ html[data-theme="dark"] .markdown-body .chroma .s { color: #86efac; }
+ html[data-theme="dark"] .markdown-body .chroma .s1 { color: #86efac; }
+ html[data-theme="dark"] .markdown-body .chroma .s2 { color: #86efac; }
+ html[data-theme="dark"] .markdown-body .chroma .sb { color: #86efac; }
+ html[data-theme="dark"] .markdown-body .chroma .sc { color: #86efac; }
+ html[data-theme="dark"] .markdown-body .chroma .sd { color: #86efac; }
+ html[data-theme="dark"] .markdown-body .chroma .se { color: #fbbf24; }
+ html[data-theme="dark"] .markdown-body .chroma .si { color: #fbbf24; }
+ html[data-theme="dark"] .markdown-body .chroma .sr { color: #86efac; }
+ html[data-theme="dark"] .markdown-body .chroma .ss { color: #86efac; }
+
+ html[data-theme="dark"] .markdown-body .chroma .m { color: #fb923c; }
+ html[data-theme="dark"] .markdown-body .chroma .mb { color: #fb923c; }
+ html[data-theme="dark"] .markdown-body .chroma .mf { color: #fb923c; }
+ html[data-theme="dark"] .markdown-body .chroma .mh { color: #fb923c; }
+ html[data-theme="dark"] .markdown-body .chroma .mi { color: #fb923c; }
+ html[data-theme="dark"] .markdown-body .chroma .mo { color: #fb923c; }
+
+ html[data-theme="dark"] .markdown-body .chroma .o { color: #c084fc; }
+ html[data-theme="dark"] .markdown-body .chroma .ow { color: #c084fc; }
+
+ html[data-theme="dark"] .markdown-body .chroma .c { color: #6b7280; font-style: italic; }
+ html[data-theme="dark"] .markdown-body .chroma .c1 { color: #6b7280; font-style: italic; }
+ html[data-theme="dark"] .markdown-body .chroma .cm { color: #6b7280; font-style: italic; }
+
+ html[data-theme="dark"] .markdown-body .chroma .p { color: #9ca3af; }
+
+ html[data-theme="dark"] .markdown-body .chroma .g { color: #ef4444; }
+ html[data-theme="dark"] .markdown-body .chroma .gd { color: #ef4444; }
+ html[data-theme="dark"] .markdown-body .chroma .ge { font-style: italic; }
+ html[data-theme="dark"] .markdown-body .chroma .gi { color: #22c55e; }
+ html[data-theme="dark"] .markdown-body .chroma .gs { font-weight: bold; }
+
+ /* SYNTAX HIGHLIGHTING - Light theme colors */
+ html[data-theme="light"] .markdown-body .chroma .k { color: #7c3aed; } /* keyword - purple */
+ html[data-theme="light"] .markdown-body .chroma .kc { color: #7c3aed; }
+ html[data-theme="light"] .markdown-body .chroma .kd { color: #7c3aed; }
+ html[data-theme="light"] .markdown-body .chroma .kn { color: #7c3aed; }
+ html[data-theme="light"] .markdown-body .chroma .kp { color: #7c3aed; }
+ html[data-theme="light"] .markdown-body .chroma .kr { color: #7c3aed; }
+ html[data-theme="light"] .markdown-body .chroma .kt { color: #7c3aed; }
+
+ html[data-theme="light"] .markdown-body .chroma .n { color: #1f2937; }
+ html[data-theme="light"] .markdown-body .chroma .na { color: #d97706; }
+ html[data-theme="light"] .markdown-body .chroma .nb { color: #2563eb; }
+ html[data-theme="light"] .markdown-body .chroma .nc { color: #d97706; }
+ html[data-theme="light"] .markdown-body .chroma .nf { color: #2563eb; }
+ html[data-theme="light"] .markdown-body .chroma .nn { color: #d97706; }
+
+ html[data-theme="light"] .markdown-body .chroma .s { color: #16a34a; }
+ html[data-theme="light"] .markdown-body .chroma .s1 { color: #16a34a; }
+ html[data-theme="light"] .markdown-body .chroma .s2 { color: #16a34a; }
+ html[data-theme="light"] .markdown-body .chroma .sb { color: #16a34a; }
+ html[data-theme="light"] .markdown-body .chroma .sc { color: #16a34a; }
+ html[data-theme="light"] .markdown-body .chroma .sd { color: #16a34a; }
+ html[data-theme="light"] .markdown-body .chroma .se { color: #d97706; }
+ html[data-theme="light"] .markdown-body .chroma .si { color: #d97706; }
+ html[data-theme="light"] .markdown-body .chroma .sr { color: #16a34a; }
+ html[data-theme="light"] .markdown-body .chroma .ss { color: #16a34a; }
+
+ html[data-theme="light"] .markdown-body .chroma .m { color: #dc2626; }
+ html[data-theme="light"] .markdown-body .chroma .mb { color: #dc2626; }
+ html[data-theme="light"] .markdown-body .chroma .mf { color: #dc2626; }
+ html[data-theme="light"] .markdown-body .chroma .mh { color: #dc2626; }
+ html[data-theme="light"] .markdown-body .chroma .mi { color: #dc2626; }
+ html[data-theme="light"] .markdown-body .chroma .mo { color: #dc2626; }
+
+ html[data-theme="light"] .markdown-body .chroma .o { color: #7c3aed; }
+ html[data-theme="light"] .markdown-body .chroma .ow { color: #7c3aed; }
+
+ html[data-theme="light"] .markdown-body .chroma .c { color: #6b7280; font-style: italic; }
+ html[data-theme="light"] .markdown-body .chroma .c1 { color: #6b7280; font-style: italic; }
+ html[data-theme="light"] .markdown-body .chroma .cm { color: #6b7280; font-style: italic; }
+
+ html[data-theme="light"] .markdown-body .chroma .p { color: #4b5563; }
+
+ html[data-theme="light"] .markdown-body .chroma .g { color: #dc2626; }
+ html[data-theme="light"] .markdown-body .chroma .gd { color: #dc2626; }
+ html[data-theme="light"] .markdown-body .chroma .ge { font-style: italic; }
+ html[data-theme="light"] .markdown-body .chroma .gi { color: #16a34a; }
+ html[data-theme="light"] .markdown-body .chroma .gs { font-weight: bold; }
+
+
+ .mb-codeblock {
+ margin: 1.75rem 0;
+ border: 1px solid color-mix(in srgb, var(--color-border) 65%, transparent);
+ border-radius: 0.85rem;
+ overflow: hidden;
+ background: color-mix(in srgb, var(--color-surface) 35%, transparent);
+ box-shadow:
+ 0 4px 6px rgba(0, 0, 0, 0.1),
+ 0 10px 20px rgba(0, 0, 0, 0.15);
+ transition: box-shadow 0.2s ease-out;
+ }
+
+ .mb-codeblock:hover {
+ box-shadow:
+ 0 4px 6px rgba(0, 0, 0, 0.15),
+ 0 12px 24px rgba(0, 0, 0, 0.2);
+ }
+
+ html[data-theme="light"] .mb-codeblock {
+ background: #f9fafb;
+ border-color: #e5e7eb;
+ box-shadow:
+ 0 2px 4px rgba(0, 0, 0, 0.05),
+ 0 4px 8px rgba(0, 0, 0, 0.08);
+ }
+
+ html[data-theme="light"] .mb-codeblock:hover {
+ box-shadow:
+ 0 4px 8px rgba(0, 0, 0, 0.08),
+ 0 8px 16px rgba(0, 0, 0, 0.12);
+ }
+
+ .mb-codeblock-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0.7rem 1rem;
+ border-bottom: 1px solid color-mix(in srgb, var(--color-border) 55%, transparent);
+ background: color-mix(in srgb, var(--color-bg) 45%, transparent);
+ gap: 1rem;
+ }
+
+ html[data-theme="light"] .mb-codeblock-header {
+ background: #f3f4f6;
+ border-bottom-color: #e5e7eb;
+ }
+
+ .mb-codeblock-left {
+ display: flex;
+ align-items: center;
+ gap: 0.6rem;
+ min-width: 0;
+ flex: 1;
+ }
+
+ .mb-codeblock-badge {
+ font-size: 0.68rem;
+ font-weight: 700;
+ padding: 0.25rem 0.55rem;
+ border-radius: 0.35rem;
+ background: color-mix(in srgb, var(--color-accent) 22%, transparent);
+ color: var(--color-accent);
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
+ white-space: nowrap;
+ border: 1px solid color-mix(in srgb, var(--color-accent) 35%, transparent);
+ }
+
+ .mb-codeblock-filename {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.4rem;
+ color: var(--color-text);
+ font-size: 0.75rem;
+ font-weight: 500;
+ padding: 0.2rem 0.65rem;
+ border-radius: 0.35rem;
+ background: color-mix(in srgb, var(--color-bg) 35%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 20rem;
+ }
+
+ .mb-codeblock-actions {
+ display: flex;
+ gap: 0.4rem;
+ flex-shrink: 0;
+ }
+
+ .mb-action-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.35rem;
+ background: transparent;
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ color: var(--color-text-muted);
+ cursor: pointer;
+ font-size: 0.7rem;
+ font-weight: 500;
+ padding: 0.35rem 0.7rem;
+ border-radius: 0.4rem;
+ transition: all 0.15s ease-out;
+ font-family: inherit;
+ white-space: nowrap;
+ }
+
+ .mb-action-btn:hover {
+ color: var(--color-accent);
+ background: color-mix(in srgb, var(--color-accent) 12%, transparent);
+ border-color: var(--color-accent);
+ transform: translateY(-1px);
+ box-shadow: 0 2px 8px rgba(168, 85, 247, 0.2);
+ }
+
+ .mb-action-btn:active {
+ transform: translateY(0);
+ }
+
+ .mb-action-btn i {
+ font-size: 0.7rem;
+ }
+
+ .mb-btn-success {
+ color: #22c55e !important;
+ border-color: #22c55e !important;
+ background: color-mix(in srgb, #22c55e 15%, transparent) !important;
+ }
+
+ .mb-codeblock-content {
+ position: relative;
+ background: color-mix(in srgb, var(--color-bg) 20%, transparent);
+ transition: max-height 0.3s ease-out;
+ }
+
+ html[data-theme="light"] .mb-codeblock-content {
+ background: #ffffff;
+ }
+
+ .mb-codeblock-content pre {
+ margin: 0;
+ padding: 1.25rem 1.5rem;
+ overflow-x: auto;
+ background: transparent;
+ border: none;
+ }
+
+ .mb-codeblock-content pre code {
+ font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
+ font-size: 0.88rem;
+ line-height: 1.65;
+ font-weight: 400;
+ }
+
+ /* Custom scrollbar for code blocks */
+ .mb-codeblock-content pre::-webkit-scrollbar {
+ height: 8px;
+ }
+
+ .mb-codeblock-content pre::-webkit-scrollbar-track {
+ background: color-mix(in srgb, var(--color-bg) 30%, transparent);
+ border-radius: 4px;
+ }
+
+ .mb-codeblock-content pre::-webkit-scrollbar-thumb {
+ background: color-mix(in srgb, var(--color-border) 70%, transparent);
+ border-radius: 4px;
+ }
+
+ .mb-codeblock-content pre::-webkit-scrollbar-thumb:hover {
+ background: var(--color-accent);
+ }
+
+ /* Collapse overlay */
+ .mb-collapse-overlay {
+ display: none;
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(
+ to bottom,
+ transparent 0%,
+ rgba(0, 0, 0, 0.25) 35%,
+ rgba(0, 0, 0, 0.88) 100%
+ );
+ align-items: flex-end;
+ justify-content: center;
+ padding-bottom: 1.2rem;
+ cursor: pointer;
+ z-index: 10;
+ backdrop-filter: blur(1px);
+ }
+
+ .mb-expand-trigger {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.45rem;
+ padding: 0.5rem 1rem;
+ border-radius: 0.5rem;
+ border: 1px solid var(--color-accent);
+ background: color-mix(in srgb, var(--color-accent) 18%, transparent);
+ color: var(--color-accent);
+ font-size: 0.75rem;
+ font-weight: 650;
+ cursor: pointer;
+ transition: all 0.15s ease-out;
+ backdrop-filter: blur(10px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
+ }
+
+ .mb-expand-trigger:hover {
+ background: color-mix(in srgb, var(--color-accent) 28%, transparent);
+ transform: translateY(-2px);
+ box-shadow: 0 6px 16px rgba(168, 85, 247, 0.35);
+ border-color: color-mix(in srgb, var(--color-accent) 90%, white);
+ }
+
+ .mb-expand-trigger i {
+ font-size: 0.7rem;
+ animation: bounce-icon 1.8s ease-in-out infinite;
+ }
+
+ @keyframes bounce-icon {
+ 0%, 100% {
+ transform: translateY(0);
+ }
+ 50% {
+ transform: translateY(4px);
+ }
+ }
+
+ .mb-codeblock[data-lang="javascript"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="js"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #f7df1e 28%, transparent);
+ color: #f7df1e;
+ border-color: color-mix(in srgb, #f7df1e 40%, transparent);
+ }
+
+ .mb-codeblock[data-lang="typescript"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="ts"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #3178c6 28%, transparent);
+ color: #60a5fa;
+ border-color: color-mix(in srgb, #3178c6 40%, transparent);
+ }
+
+ .mb-codeblock[data-lang="python"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="py"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #3776ab 28%, transparent);
+ color: #60a5fa;
+ border-color: color-mix(in srgb, #3776ab 40%, transparent);
+ }
+
+ .mb-codeblock[data-lang="go"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #00add8 28%, transparent);
+ color: #22d3ee;
+ border-color: color-mix(in srgb, #00add8 40%, transparent);
+ }
+
+ .mb-codeblock[data-lang="rust"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="rs"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #ce422b 28%, transparent);
+ color: #fb923c;
+ border-color: color-mix(in srgb, #ce422b 40%, transparent);
+ }
+
+ .mb-codeblock[data-lang="html"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #e34c26 28%, transparent);
+ color: #f87171;
+ border-color: color-mix(in srgb, #e34c26 40%, transparent);
+ }
+
+ .mb-codeblock[data-lang="css"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #264de4 28%, transparent);
+ color: #60a5fa;
+ border-color: color-mix(in srgb, #264de4 40%, transparent);
+ }
+
+ .mb-codeblock[data-lang="bash"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="sh"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="shell"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #4eaa25 28%, transparent);
+ color: #86efac;
+ border-color: color-mix(in srgb, #4eaa25 40%, transparent);
+ }
+
+ .mb-codeblock[data-lang="json"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #888888 28%, transparent);
+ color: #d1d5db;
+ border-color: color-mix(in srgb, #888888 40%, transparent);
+ }
+
+ .mb-codeblock[data-lang="yaml"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="yml"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #cb171e 28%, transparent);
+ color: #fca5a5;
+ border-color: color-mix(in srgb, #cb171e 40%, transparent);
+ }
+
+ .mb-codeblock[data-lang="java"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #f89820 28%, transparent);
+ color: #fbbf24;
+ border-color: color-mix(in srgb, #f89820 40%, transparent);
+ }
+
+ .mb-codeblock[data-lang="cpp"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="c++"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #00599c 28%, transparent);
+ color: #60a5fa;
+ border-color: color-mix(in srgb, #00599c 40%, transparent);
+ }
+
+ .mb-codeblock[data-lang="c"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #555555 28%, transparent);
+ color: #9ca3af;
+ border-color: color-mix(in srgb, #555555 40%, transparent);
+ }
+
+ .mb-codeblock[data-lang="ruby"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="rb"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #cc342d 28%, transparent);
+ color: #f87171;
+ border-color: color-mix(in srgb, #cc342d 40%, transparent);
+ }
+
+ .mb-codeblock[data-lang="php"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #777bb4 28%, transparent);
+ color: #a78bfa;
+ border-color: color-mix(in srgb, #777bb4 40%, transparent);
+ }
+
+ .mb-codeblock[data-lang="sql"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #e38c00 28%, transparent);
+ color: #fbbf24;
+ border-color: color-mix(in srgb, #e38c00 40%, transparent);
+ }
+
+ /* Responsive adjustments */
+ @media (max-width: 640px) {
+ .mb-codeblock-header {
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 0.6rem;
+ }
+
+ .mb-codeblock-actions {
+ width: 100%;
+ justify-content: flex-end;
+ }
+
+ .mb-action-btn span {
+ display: none;
+ }
+
+ .mb-action-btn {
+ padding: 0.4rem;
+ width: 2rem;
+ height: 2rem;
+ justify-content: center;
+ }
+
+ .mb-codeblock-filename {
+ max-width: 100%;
+ }
+ }
+
+ @keyframes tech-marquee {
+ 0% {
+ transform: translateX(0);
+ }
+ 100% {
+ transform: translateX(-50%);
+ }
+ }
+
+ @media (prefers-reduced-motion: reduce) {
+ .tech-strip-track {
+ animation: none;
+ }
+ }
+
+ /* gallery */
+ .markdown-body .gallery-container {
+ margin: 2rem 0;
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
+ gap: 1rem;
+ }
+
+ @media (max-width: 640px) {
+ .markdown-body .gallery-container {
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+ gap: 0.75rem;
+ }
+ }
+
+ .markdown-body .gallery-container a {
+ display: block;
+ border: none !important;
+ padding: 0;
+ margin: 0;
+ border-radius: 0.5rem;
+ overflow: hidden;
+ transition: all 0.2s ease-out;
+ position: relative;
+ cursor: zoom-in;
+ aspect-ratio: 4/3;
+ }
+
+ .markdown-body .gallery-container a:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
+ }
+
+ .markdown-body .gallery-container img {
+ display: block;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ margin: 0;
+ border: none;
+ border-radius: 0.5rem;
+ transition: all 0.2s ease-out;
+ }
+
+ .markdown-body .gallery-container a:hover img {
+ filter: brightness(0.9);
+ }
+
+ /* ==================== */
+ /* ABOUT PAGE */
+ /* ==================== */
+
diff --git a/themes/minimal-black/assets/css/content/toc.css b/themes/minimal-black/assets/css/content/toc.css
new file mode 100644
index 0000000..deb3284
--- /dev/null
+++ b/themes/minimal-black/assets/css/content/toc.css
@@ -0,0 +1,211 @@
+/* ==========================================================================
+ TABLE OF CONTENTS
+ TOC sidebar, active link tracking, responsive behavior
+ ========================================================================== */
+
+ .article-layout {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 2rem;
+ position: relative;
+ min-width: 0;
+ }
+
+ @media (min-width: 1024px) {
+ .article-layout {
+ grid-template-columns: 260px 1fr;
+ gap: 3rem;
+ }
+
+ .article-toc {
+ order: 1;
+ }
+
+ .article-main {
+ order: 2;
+ }
+ }
+
+ .article-main {
+ min-width: 0;
+ overflow-x: hidden;
+ }
+
+ .article-toc {
+ width: 100%;
+ }
+
+ .toc-wrapper {
+ position: sticky;
+ top: 2rem;
+ background: color-mix(in srgb, var(--color-surface) 50%, transparent);
+ border: 1px solid var(--color-border);
+ border-radius: 0.85rem;
+ padding: 1rem;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ backdrop-filter: blur(10px);
+ transition: all 0.2s ease-out;
+ max-height: calc(100vh - 24rem);
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ }
+
+ .toc-wrapper:hover {
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
+ border-color: color-mix(in srgb, var(--color-accent) 40%, transparent);
+ }
+
+ .toc-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 0.75rem;
+ padding-bottom: 0.75rem;
+ border-bottom: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ }
+
+ .toc-title {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ font-size: 0.85rem;
+ font-weight: 650;
+ color: var(--color-text);
+ margin: 0;
+ }
+
+ .toc-title i {
+ color: var(--color-accent);
+ font-size: 0.75rem;
+ }
+
+ .toc-toggle {
+ display: flex;
+ background: transparent;
+ border: 1px solid var(--color-border);
+ color: var(--color-text-muted);
+ width: 1.75rem;
+ height: 1.75rem;
+ border-radius: 0.4rem;
+ cursor: pointer;
+ transition: all 0.15s ease-out;
+ align-items: center;
+ justify-content: center;
+ }
+
+ .toc-toggle:hover {
+ color: var(--color-accent);
+ border-color: var(--color-accent);
+ background: color-mix(in srgb, var(--color-accent) 10%, transparent);
+ }
+
+ .toc-toggle i {
+ font-size: 0.7rem;
+ transition: transform 0.2s ease-out;
+ }
+
+ .toc-wrapper.collapsed .toc-toggle i {
+ transform: rotate(-90deg);
+ }
+
+ .toc-wrapper.collapsed .toc-nav {
+ max-height: 0;
+ opacity: 0;
+ overflow: hidden;
+ }
+
+ @media (max-width: 1023px) {
+ .toc-wrapper {
+ position: relative;
+ top: 0;
+ }
+ }
+
+ .toc-nav {
+ font-size: 0.8rem;
+ line-height: 1.6;
+ transition: all 0.3s ease-out;
+ overflow-y: auto;
+ overflow-x: hidden;
+ flex: 1;
+ min-height: 0;
+ }
+
+ /* Custom scrollbar for TOC */
+ .toc-nav::-webkit-scrollbar {
+ width: 6px;
+ }
+
+ .toc-nav::-webkit-scrollbar-track {
+ background: color-mix(in srgb, var(--color-bg) 30%, transparent);
+ border-radius: 3px;
+ }
+
+ .toc-nav::-webkit-scrollbar-thumb {
+ background: color-mix(in srgb, var(--color-border) 70%, transparent);
+ border-radius: 3px;
+ }
+
+ .toc-nav::-webkit-scrollbar-thumb:hover {
+ background: var(--color-accent);
+ }
+
+ .toc-nav > ul {
+ list-style: none;
+ padding-left: 0;
+ margin: 0;
+ }
+
+ .toc-nav ul {
+ list-style: none;
+ margin: 0;
+ }
+
+ .toc-nav ul ul {
+ padding-left: 1rem;
+ margin-top: 0.25rem;
+ border-left: 1px solid color-mix(in srgb, var(--color-border) 50%, transparent);
+ }
+
+ .toc-nav li {
+ margin: 0.35rem 0;
+ padding-left: 0;
+ }
+
+ .toc-nav li:hover {
+ background: none;
+ }
+
+ .toc-nav a {
+ display: block;
+ padding: 0.35rem 0.5rem;
+ color: var(--color-text-muted);
+ text-decoration: none;
+ border-left: 2px solid transparent;
+ border-radius: 0.35rem;
+ transition: all 0.15s ease-out;
+ border-bottom: none;
+ }
+
+ .toc-nav a:hover {
+ color: var(--color-text);
+ background: color-mix(in srgb, var(--color-surface) 40%, transparent);
+ border-left-color: var(--color-accent);
+ transform: translateX(3px);
+ }
+
+ .toc-nav a.active {
+ color: var(--color-accent);
+ background: color-mix(in srgb, var(--color-accent) 12%, transparent);
+ border-left-color: var(--color-accent);
+ font-weight: 600;
+ }
+
+ /* Mobile: TOC appears at top */
+ @media (max-width: 1023px) {
+ .article-toc {
+ order: -1;
+ margin-bottom: 1.5rem;
+ }
+ }
\ No newline at end of file
diff --git a/themes/minimal-black/assets/css/main.css b/themes/minimal-black/assets/css/main.css
new file mode 100644
index 0000000..6e2e8b0
--- /dev/null
+++ b/themes/minimal-black/assets/css/main.css
@@ -0,0 +1,28 @@
+/* ==========================================================================
+ MINIMAL BLACK THEME - MAIN STYLESHEET
+ A minimal, dark-mode first Hugo theme
+ ========================================================================== */
+
+/* Base Styles & Tailwind */
+@import "base.css";
+
+/* Utility Classes */
+@import "utilities.css";
+
+/* Components */
+@import "components/dock.css";
+@import "components/cards.css";
+@import "components/navigation.css";
+@import "components/search.css";
+@import "components/tech-marquee.css";
+
+/* Content */
+@import "content/markdown.css";
+@import "content/toc.css";
+
+/* Pages */
+@import "pages/about.css";
+@import "pages/about-alternative.css";
+
+/* Responsive Styles */
+@import "responsive.css";
diff --git a/themes/minimal-black/assets/css/pages/about-alternative.css b/themes/minimal-black/assets/css/pages/about-alternative.css
new file mode 100644
index 0000000..0cac851
--- /dev/null
+++ b/themes/minimal-black/assets/css/pages/about-alternative.css
@@ -0,0 +1,363 @@
+/* ==========================================================================
+ ABOUT ALTERNATIVE PAGE STYLES
+ Alternative about page with sidebar profile card
+ ========================================================================== */
+
+ .page-int, .about-alt-page {
+ max-width: 1200px;
+ margin-inline: auto;
+ }
+
+ .about-alt-layout {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 2rem;
+ padding: 2rem 0;
+ }
+
+ @media (min-width: 1024px) {
+ .about-alt-layout {
+ grid-template-columns: 320px 1fr;
+ gap: 3rem;
+ }
+ }
+
+ /* Profile Card - Left Sidebar */
+ .about-alt-sidebar {
+ position: relative;
+ }
+
+ .about-alt-profile-card {
+ background: linear-gradient(
+ 135deg,
+ color-mix(in srgb, var(--color-surface) 70%, transparent),
+ color-mix(in srgb, var(--color-surface) 50%, transparent)
+ );
+ border: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ border-radius: 1.5rem;
+ padding: 2rem;
+ text-align: center;
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
+ position: sticky;
+ top: 2rem;
+ }
+
+ .about-alt-avatar,
+ .about-alt-avatar-placeholder {
+ width: 120px;
+ height: 120px;
+ border-radius: 50%;
+ margin: 0 auto 1.5rem;
+ overflow: hidden;
+ border: 4px solid var(--color-accent);
+ box-shadow: 0 0 0 8px color-mix(in srgb, var(--color-accent) 15%, transparent);
+ transition: all 0.3s ease-out;
+ }
+
+ .about-alt-avatar:hover,
+ .about-alt-avatar-placeholder:hover {
+ transform: scale(1.05);
+ box-shadow: 0 0 0 12px color-mix(in srgb, var(--color-accent) 20%, transparent);
+ }
+
+ .about-alt-avatar img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ }
+
+ .about-alt-avatar-placeholder {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: linear-gradient(
+ 135deg,
+ color-mix(in srgb, var(--color-accent) 30%, transparent),
+ color-mix(in srgb, var(--color-accent) 15%, transparent)
+ );
+ }
+
+ .about-alt-avatar-placeholder i {
+ font-size: 3rem;
+ color: var(--color-accent);
+ }
+
+ .about-alt-name {
+ font-size: 1.75rem;
+ font-weight: 700;
+ color: var(--color-text);
+ margin-bottom: 0.5rem;
+ }
+
+ .about-alt-role {
+ font-size: 0.9rem;
+ color: var(--color-text-muted);
+ line-height: 1.5;
+ margin-bottom: 1rem;
+ }
+
+ .about-alt-meta {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ font-size: 0.85rem;
+ color: var(--color-text-muted);
+ margin-bottom: 1.5rem;
+ }
+
+ .about-alt-meta i {
+ color: var(--color-accent);
+ }
+
+ /* Stats Grid */
+ .about-alt-stats {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 1rem;
+ margin: 2rem 0;
+ padding: 1.5rem 0;
+ border-top: 1px solid color-mix(in srgb, var(--color-border) 50%, transparent);
+ border-bottom: 1px solid color-mix(in srgb, var(--color-border) 50%, transparent);
+ }
+
+ .about-alt-stat {
+ text-align: center;
+ }
+
+ .about-alt-stat-value {
+ font-size: 1.75rem;
+ font-weight: 700;
+ color: var(--color-accent);
+ margin-bottom: 0.25rem;
+ }
+
+ .about-alt-stat-label {
+ font-size: 0.7rem;
+ color: var(--color-text-muted);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ }
+
+ /* Social Icons */
+ .about-alt-social {
+ display: flex;
+ justify-content: center;
+ gap: 0.75rem;
+ margin-top: 1.5rem;
+ }
+
+ .about-alt-social-icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 2.5rem;
+ height: 2.5rem;
+ border-radius: 50%;
+ background: color-mix(in srgb, var(--color-bg) 50%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ color: var(--color-text-muted);
+ transition: all 0.2s ease-out;
+ }
+
+ .about-alt-social-icon:hover {
+ background: var(--color-accent);
+ border-color: var(--color-accent);
+ color: white;
+ transform: translateY(-3px);
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.3);
+ }
+
+ .about-alt-social-icon i {
+ font-size: 1rem;
+ }
+
+ /* Content Area */
+ .about-alt-content {
+ display: flex;
+ flex-direction: column;
+ gap: 2rem;
+ }
+
+ .about-alt-section {
+ background: color-mix(in srgb, var(--color-surface) 40%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ border-radius: 1.25rem;
+ padding: 2rem;
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
+ }
+
+ .about-alt-section-title {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ font-size: 1.5rem;
+ font-weight: 700;
+ color: var(--color-text);
+ margin-bottom: 1.5rem;
+ padding-bottom: 1rem;
+ border-bottom: 2px solid color-mix(in srgb, var(--color-accent) 20%, transparent);
+ }
+
+ .about-alt-section-title i {
+ color: var(--color-accent);
+ font-size: 1.25rem;
+ }
+
+ /* Experience Cards Grid */
+ .about-alt-experience-grid {
+ display: grid;
+ gap: 1.5rem;
+ }
+
+ .about-alt-experience-card {
+ background: color-mix(in srgb, var(--color-bg) 40%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 50%, transparent);
+ border-left: 4px solid var(--color-accent);
+ border-radius: 0.85rem;
+ padding: 1.5rem;
+ transition: all 0.3s ease-out;
+ position: relative;
+ overflow: hidden;
+ }
+
+ .about-alt-experience-card::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 100px;
+ height: 100px;
+ background: radial-gradient(
+ circle at center,
+ color-mix(in srgb, var(--color-accent) 10%, transparent),
+ transparent 70%
+ );
+ opacity: 0;
+ transition: opacity 0.3s ease-out;
+ }
+
+ .about-alt-experience-card:hover {
+ border-left-width: 6px;
+ transform: translateX(6px);
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
+ }
+
+ .about-alt-experience-card:hover::before {
+ opacity: 1;
+ }
+
+ .about-alt-experience-card p:first-child {
+ margin-top: 0;
+ }
+
+ .about-alt-experience-card p:last-child {
+ margin-bottom: 0;
+ }
+
+ .about-alt-experience-card strong {
+ font-size: 1.1rem;
+ color: var(--color-text);
+ display: block;
+ margin-bottom: 0.25rem;
+ }
+
+ .about-alt-experience-card em {
+ font-size: 0.85rem;
+ color: var(--color-text-muted);
+ font-style: normal;
+ display: block;
+ margin-bottom: 0.75rem;
+ }
+
+ /* Skills Badge Cloud */
+ .about-alt-skills {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.75rem;
+ }
+
+ .about-alt-skill {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.5rem 1rem;
+ background: color-mix(in srgb, var(--color-bg) 50%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ border-radius: 999px;
+ font-size: 0.85rem;
+ font-weight: 500;
+ color: var(--color-text);
+ transition: all 0.2s ease-out;
+ cursor: default;
+ }
+
+ .about-alt-skill i {
+ font-size: 1.1em;
+ opacity: 0.9;
+ }
+
+ .about-alt-skill:hover {
+ background: var(--color-accent);
+ border-color: var(--color-accent);
+ color: white;
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
+ }
+
+ .about-alt-skill:hover i {
+ opacity: 1;
+ }
+
+ /* Responsive */
+ @media (max-width: 1023px) {
+ .about-alt-profile-card {
+ position: relative;
+ top: 0;
+ }
+
+ .about-alt-layout {
+ grid-template-columns: 1fr;
+ }
+ }
+
+ @media (max-width: 640px) {
+ .about-alt-profile-card {
+ padding: 1.5rem;
+ }
+
+ .about-alt-avatar,
+ .about-alt-avatar-placeholder {
+ width: 100px;
+ height: 100px;
+ }
+
+ .about-alt-name {
+ font-size: 1.5rem;
+ }
+
+ .about-alt-stats {
+ gap: 0.75rem;
+ }
+
+ .about-alt-stat-value {
+ font-size: 1.5rem;
+ }
+
+ .about-alt-section {
+ padding: 1.5rem;
+ }
+
+ .about-alt-section-title {
+ font-size: 1.25rem;
+ }
+
+ .about-alt-experience-card {
+ padding: 1.25rem;
+ }
+ }
+
+ /* ==================== */
+ /* TABLE OF CONTENTS */
+ /* ==================== */
+
diff --git a/themes/minimal-black/assets/css/pages/about.css b/themes/minimal-black/assets/css/pages/about.css
new file mode 100644
index 0000000..ff516fd
--- /dev/null
+++ b/themes/minimal-black/assets/css/pages/about.css
@@ -0,0 +1,380 @@
+/* ==========================================================================
+ ABOUT PAGE STYLES
+ Standard about page with timeline
+ ========================================================================== */
+
+ .about-page {
+ max-width: 900px;
+ margin-inline: auto;
+ }
+
+ .about-hero {
+ text-align: center;
+ padding: 3rem 0 4rem;
+ position: relative;
+ }
+
+ .about-hero::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 60px;
+ height: 3px;
+ background: linear-gradient(
+ 90deg,
+ transparent,
+ var(--color-accent),
+ transparent
+ );
+ border-radius: 999px;
+ }
+
+ .about-hero-content {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 1.5rem;
+ }
+
+ .about-avatar,
+ .about-avatar-placeholder {
+ width: 140px;
+ height: 140px;
+ border-radius: 50%;
+ overflow: hidden;
+ border: 3px solid var(--color-accent);
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2),
+ 0 0 0 8px color-mix(in srgb, var(--color-accent) 15%, transparent);
+ transition: all 0.3s ease-out;
+ }
+
+ .about-avatar:hover,
+ .about-avatar-placeholder:hover {
+ transform: translateY(-4px) scale(1.02);
+ box-shadow: 0 12px 32px rgba(0, 0, 0, 0.3),
+ 0 0 0 12px color-mix(in srgb, var(--color-accent) 20%, transparent);
+ }
+
+ .about-avatar img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ }
+
+ .about-avatar-placeholder {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: linear-gradient(
+ 135deg,
+ color-mix(in srgb, var(--color-accent) 20%, transparent),
+ color-mix(in srgb, var(--color-accent) 10%, transparent)
+ );
+ backdrop-filter: blur(10px);
+ }
+
+ .about-avatar-placeholder i {
+ font-size: 4rem;
+ color: var(--color-accent);
+ }
+
+ .about-title {
+ font-size: 2.5rem;
+ font-weight: 700;
+ letter-spacing: -0.02em;
+ color: var(--color-text);
+ margin: 0;
+ line-height: 1.2;
+ }
+
+ .about-subtitle {
+ font-size: 1.1rem;
+ color: var(--color-text-muted);
+ max-width: 600px;
+ line-height: 1.6;
+ margin: 0;
+ }
+
+ .about-content {
+ margin-bottom: 4rem;
+ }
+
+ .about-content .card {
+ background: color-mix(in srgb, var(--color-surface) 60%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
+ padding: 2rem;
+ }
+
+ .about-content .markdown-body h3 {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ margin-top: 2.5rem;
+ padding-bottom: 0.5rem;
+ border-bottom: 2px solid color-mix(in srgb, var(--color-accent) 30%, transparent);
+ }
+
+ .about-content .markdown-body h3::before {
+ content: '';
+ display: inline-block;
+ width: 4px;
+ height: 1.5rem;
+ background: var(--color-accent);
+ border-radius: 999px;
+ }
+
+ /* Timeline */
+ .timeline {
+ position: relative;
+ padding: 2rem 0 1rem 0;
+ margin-top: 2rem;
+ }
+
+ .timeline::before {
+ content: '';
+ position: absolute;
+ left: 20px;
+ top: 0;
+ bottom: 0;
+ width: 2px;
+ background: linear-gradient(
+ to bottom,
+ transparent,
+ var(--color-accent) 10%,
+ var(--color-accent) 90%,
+ transparent
+ );
+ }
+
+ .timeline-item {
+ position: relative;
+ padding-left: 60px;
+ margin-bottom: 3rem;
+ }
+
+ .timeline-item:last-child {
+ margin-bottom: 0;
+ }
+
+ .timeline-marker {
+ position: absolute;
+ left: 0;
+ top: 8px;
+ width: 42px;
+ height: 42px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 2;
+ }
+
+ .timeline-marker::before {
+ content: '';
+ position: absolute;
+ width: 16px;
+ height: 16px;
+ background: var(--color-accent);
+ border-radius: 50%;
+ border: 3px solid var(--color-bg);
+ box-shadow:
+ 0 0 0 4px color-mix(in srgb, var(--color-accent) 20%, transparent),
+ 0 4px 12px rgba(0, 0, 0, 0.3);
+ transition: all 0.3s ease-out;
+ }
+
+ .timeline-item:hover .timeline-marker::before {
+ transform: scale(1.3);
+ box-shadow:
+ 0 0 0 6px color-mix(in srgb, var(--color-accent) 30%, transparent),
+ 0 6px 16px rgba(0, 0, 0, 0.4);
+ }
+
+ .timeline-content {
+ background: color-mix(in srgb, var(--color-surface) 30%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 50%, transparent);
+ border-radius: 0.85rem;
+ padding: 1.5rem;
+ transition: all 0.3s ease-out;
+ position: relative;
+ overflow: hidden;
+ }
+
+ .timeline-content::before {
+ content: '';
+ position: absolute;
+ left: 0;
+ top: 0;
+ bottom: 0;
+ width: 4px;
+ background: var(--color-accent);
+ opacity: 0;
+ transition: opacity 0.3s ease-out;
+ }
+
+ .timeline-item:hover .timeline-content {
+ background: color-mix(in srgb, var(--color-surface) 50%, transparent);
+ border-color: color-mix(in srgb, var(--color-accent) 40%, transparent);
+ transform: translateX(4px);
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
+ }
+
+ .timeline-item:hover .timeline-content::before {
+ opacity: 1;
+ }
+
+ .timeline-content > p:first-child {
+ margin-top: 0;
+ }
+
+ .timeline-content > p:last-child {
+ margin-bottom: 0;
+ }
+
+ .timeline-content strong {
+ font-size: 1.1rem;
+ color: var(--color-text);
+ display: block;
+ margin-bottom: 0.25rem;
+ }
+
+ .timeline-content em {
+ font-size: 0.85rem;
+ color: var(--color-text-muted);
+ font-style: normal;
+ display: block;
+ margin-bottom: 0.75rem;
+ }
+
+ .timeline-content a {
+ color: var(--color-accent);
+ }
+
+ /* Remove hr from timeline */
+ .timeline hr {
+ display: none;
+ }
+
+ .about-social {
+ text-align: center;
+ padding: 3rem 2rem;
+ background: color-mix(in srgb, var(--color-surface) 40%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ border-radius: 1.25rem;
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
+ }
+
+ .about-social-title {
+ font-size: 1.25rem;
+ font-weight: 650;
+ color: var(--color-text);
+ margin-bottom: 1.5rem;
+ }
+
+ .about-social-links {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 1rem;
+ }
+
+ .about-social-link {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.75rem 1.5rem;
+ border-radius: 999px;
+ background: color-mix(in srgb, var(--color-bg) 60%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ color: var(--color-text-muted);
+ text-decoration: none;
+ font-size: 0.9rem;
+ font-weight: 500;
+ transition: all 0.2s ease-out;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+ }
+
+ .about-social-link:hover {
+ transform: translateY(-2px);
+ background: color-mix(in srgb, var(--color-surface) 80%, transparent);
+ border-color: var(--color-accent);
+ color: var(--color-accent);
+ box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
+ }
+
+ .about-social-link i {
+ font-size: 1.1rem;
+ }
+
+ /* Responsive about page */
+ @media (max-width: 640px) {
+ .about-hero {
+ padding: 2rem 0 3rem;
+ }
+
+ .about-avatar,
+ .about-avatar-placeholder {
+ width: 110px;
+ height: 110px;
+ }
+
+ .about-avatar-placeholder i {
+ font-size: 3rem;
+ }
+
+ .about-title {
+ font-size: 2rem;
+ }
+
+ .about-subtitle {
+ font-size: 1rem;
+ }
+
+ .about-social {
+ padding: 2rem 1.25rem;
+ }
+
+ .about-social-links {
+ flex-direction: column;
+ align-items: stretch;
+ }
+
+ .about-social-link {
+ justify-content: center;
+ }
+
+ /* Timeline responsive */
+ .timeline::before {
+ left: 12px;
+ }
+
+ .timeline-item {
+ padding-left: 40px;
+ }
+
+ .timeline-marker {
+ left: -5px;
+ width: 34px;
+ height: 34px;
+ }
+
+ .timeline-marker::before {
+ width: 12px;
+ height: 12px;
+ }
+
+ .timeline-content {
+ padding: 1rem;
+ }
+
+ .timeline-content strong {
+ font-size: 1rem;
+ }
+
+ .timeline-content em {
+ font-size: 0.8rem;
+ }
+ }
+
diff --git a/themes/minimal-black/assets/css/responsive.css b/themes/minimal-black/assets/css/responsive.css
new file mode 100644
index 0000000..a209c7c
--- /dev/null
+++ b/themes/minimal-black/assets/css/responsive.css
@@ -0,0 +1,277 @@
+/* ==========================================================================
+ RESPONSIVE STYLES
+ Global responsive breakpoints and mobile optimizations
+ ========================================================================== */
+
+ /* Mobile - Small screens (up to 640px) */
+ @media (max-width: 640px) {
+ .card-pad {
+ padding: 1.25rem;
+ }
+
+ .layout-page {
+ padding-inline: 1rem;
+ padding-block: 1.5rem;
+ }
+
+ .layout-page-tight {
+ padding-inline: 1rem;
+ padding-block: 1rem;
+ }
+
+ /* Markdown body */
+ .markdown-body {
+ font-size: 0.9rem;
+ padding: 0;
+ }
+
+ /* Headings - scale down for mobile */
+ .markdown-body h1 {
+ font-size: 1.75rem;
+ }
+
+ .markdown-body h2 {
+ font-size: 1.35rem;
+ margin-top: 2rem;
+ }
+
+ .markdown-body h3 {
+ font-size: 1.15rem;
+ margin-top: 1.5rem;
+ }
+
+ .markdown-body h4 {
+ font-size: 1rem;
+ }
+
+ .markdown-body h5,
+ .markdown-body h6 {
+ font-size: 0.9rem;
+ }
+
+ /* Heading anchors - adjust for smaller screens */
+ .markdown-body .md-heading-anchor::before {
+ left: -1rem;
+ font-size: 0.85em;
+ }
+
+ /* Blockquotes */
+ .markdown-body blockquote,
+ .markdown-body .md-blockquote {
+ margin: 1.25rem 0;
+ padding: 1rem;
+ border-left-width: 3px;
+ }
+
+ .markdown-body blockquote::before,
+ .markdown-body .md-blockquote::before {
+ font-size: 2rem;
+ left: 0.5rem;
+ top: 0.25rem;
+ }
+
+ /* Alerts */
+ .markdown-body .md-alert {
+ padding: 0.85rem 1rem 0.85rem 2.5rem;
+ }
+
+ .markdown-body .md-alert::before {
+ left: 0.75rem;
+ top: 0.95rem;
+ font-size: 0.95rem;
+ }
+
+ /* Lists */
+ .markdown-body ul,
+ .markdown-body ol {
+ padding-left: 1.25rem;
+ }
+
+ /* Code blocks */
+ .markdown-body pre {
+ margin: 1rem -1rem;
+ border-radius: 0.5rem;
+ }
+
+ .markdown-body pre code {
+ font-size: 0.8rem;
+ padding: 1rem;
+ }
+
+ .mb-codeblock {
+ margin: 1.25rem -1rem;
+ border-radius: 0.5rem;
+ }
+
+ .mb-codeblock-content pre {
+ padding: 1rem;
+ }
+
+ .mb-codeblock-content pre code {
+ font-size: 0.8rem;
+ }
+
+ /* Inline code */
+ .markdown-body :not(pre) > code {
+ font-size: 0.85em;
+ padding: 0.1rem 0.35rem;
+ }
+
+ /* Tables - full bleed on mobile */
+ .markdown-body table {
+ font-size: 0.85rem;
+ }
+
+ .markdown-body th,
+ .markdown-body td {
+ padding: 0.5rem 0.65rem;
+ }
+
+ .markdown-body .table-wrap {
+ margin: 1.25rem -1rem;
+ border-radius: 0.5rem;
+ }
+
+ /* Images */
+ .markdown-body img,
+ .markdown-body .md-image {
+ margin: 1.25rem 0;
+ }
+
+ .markdown-body .md-image a {
+ border-radius: 0.5rem;
+ }
+
+ .markdown-body .md-image a::after {
+ font-size: 2rem;
+ }
+
+ .markdown-body .md-image figcaption {
+ font-size: 0.82rem;
+ padding: 0.4rem 0.75rem;
+ }
+
+ /* Page heading */
+ .heading-page {
+ font-size: 1.75rem !important;
+ line-height: 1.2;
+ }
+
+ /* Article header */
+ .article-main header {
+ padding: 0;
+ }
+
+ /* TOC on mobile */
+ .toc-wrapper {
+ border-radius: 0.75rem;
+ padding: 0.85rem;
+ }
+
+ .toc-nav {
+ font-size: 0.85rem;
+ }
+ }
+
+ /* Tablet - Medium screens (641px to 1023px) */
+ @media (min-width: 641px) and (max-width: 1023px) {
+ .article-layout {
+ display: flex;
+ flex-wrap: wrap;
+ }
+
+ .article-main {
+ max-width: -webkit-fill-available;
+ }
+
+ .layout-page {
+ padding-inline: 1.5rem;
+ padding-block: 2rem;
+ }
+
+ .markdown-body {
+ font-size: 0.93rem;
+ }
+
+ .markdown-body h1 {
+ font-size: 1.85rem;
+ }
+
+ .markdown-body h2 {
+ font-size: 1.4rem;
+ }
+
+ .markdown-body h3 {
+ font-size: 1.2rem;
+ }
+ }
+
+ /* Larger screens - Adjust max-widths */
+ @media (min-width: 1536px) {
+ .article-layout {
+ padding-inline: 2rem;
+ }
+ }
+
+ /* Ultra-wide screens */
+ @media (min-width: 1920px) {
+ .markdown-body {
+ font-size: 1rem;
+ }
+ }
+
+ /* Touch device improvements */
+ @media (hover: none) and (pointer: coarse) {
+ /* Increase tap targets for touch */
+ .toc-nav a {
+ padding: 0.5rem 0.65rem;
+ margin: 0.15rem 0;
+ }
+
+ .toc-toggle {
+ width: 2.5rem;
+ height: 2.5rem;
+ }
+
+ .mb-action-btn {
+ padding: 0.5rem 0.85rem;
+ font-size: 0.75rem;
+ }
+
+ /* Remove hover effects on touch devices */
+ .markdown-body li:hover {
+ background: none;
+ }
+
+ .card-hover:hover {
+ transform: none;
+ box-shadow: none;
+ }
+ }
+
+ /* Landscape mobile */
+ @media (max-height: 500px) and (orientation: landscape) {
+ .toc-wrapper {
+ position: relative;
+ top: 0;
+ }
+
+ .layout-page {
+ padding-block: 1rem;
+ }
+ }
+
+@layer base {
+ .prose {
+ color: var(--color-text);
+ }
+
+ .prose a {
+ color: var(--color-accent);
+ text-decoration-color: var(--color-accent);
+ }
+
+ .prose strong {
+ color: var(--color-text);
+ }
+}
diff --git a/themes/minimal-black/assets/css/utilities.css b/themes/minimal-black/assets/css/utilities.css
new file mode 100644
index 0000000..763d8e4
--- /dev/null
+++ b/themes/minimal-black/assets/css/utilities.css
@@ -0,0 +1,95 @@
+/* ==========================================================================
+ UTILITY CLASSES
+ Color utilities, animations, helper classes
+ ========================================================================== */
+
+ .bg-bg {
+ background-color: var(--color-bg);
+ }
+ .bg-surface {
+ background-color: var(--color-surface);
+ }
+
+ .text-text {
+ color: var(--color-text);
+ }
+ .text-muted {
+ color: var(--color-text-muted);
+ }
+ .text-accent {
+ color: var(--color-accent);
+ }
+
+ .border-border {
+ border-color: var(--color-border);
+ }
+ .border-accent {
+ border-color: var(--color-accent);
+ }
+
+ .bg-accent {
+ background-color: var(--color-accent);
+ }
+ .underline-accent {
+ text-decoration-color: var(--color-accent);
+ }
+
+ /* Simple fade-up animation */
+ @keyframes fade-up {
+ 0% {
+ opacity: 0;
+ transform: translateY(8px);
+ }
+ 100% {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ }
+
+ .animate-fade-up {
+ animation: fade-up 0.45s ease-out both;
+ }
+
+ @keyframes search-panel-in {
+ 0% {
+ opacity: 0;
+ transform: translate(-50%, -48%) scale(0.97);
+ }
+ 100% {
+ opacity: 1;
+ transform: translate(-50%, -50%) scale(1);
+ }
+ }
+
+ @keyframes search-backdrop-in {
+ 0% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: 1;
+ }
+ }
+
+ @keyframes search-panel-out {
+ 0% {
+ opacity: 1;
+ transform: translate(-50%, -50%) scale(1);
+ }
+ 100% {
+ opacity: 0;
+ transform: translate(-50%, -48%) scale(0.97);
+ }
+ }
+
+ @keyframes search-backdrop-out {
+ 0% {
+ opacity: 1;
+ }
+ 100% {
+ opacity: 0;
+ }
+ }
+
+
+@layer components { }
+ /* Layout helpers */
diff --git a/themes/minimal-black/exampleSite/content/_index.md b/themes/minimal-black/exampleSite/content/_index.md
new file mode 100644
index 0000000..e69de29
diff --git a/themes/minimal-black/exampleSite/content/about-alternative/_index.md b/themes/minimal-black/exampleSite/content/about-alternative/_index.md
new file mode 100644
index 0000000..b26d19b
--- /dev/null
+++ b/themes/minimal-black/exampleSite/content/about-alternative/_index.md
@@ -0,0 +1,128 @@
++++
+title = "About Me"
+subtitle = "Software Engineer | Full Stack Developer | Open Source Enthusiast"
+layout = "about-alternative"
++++
+
+I'm a software engineer passionate about building elegant solutions to complex problems. Currently working on modern web applications and exploring the intersection of design, performance, and developer experience.
+
+## What I Do
+
+I work across the full stack with expertise in:
+
+- **Backend Development** — Scalable APIs, microservices, database design
+- **Frontend Engineering** — React, Vue, modern JavaScript frameworks
+- **Cloud & DevOps** — AWS, Docker, Kubernetes, CI/CD pipelines
+- **Open Source** — Contributing to projects and building developer tools
+
+## Current Projects
+
+Right now I'm focused on:
+
+- Building minimal Hugo themes for personal sites
+- Exploring dark-mode design patterns and accessibility
+- Writing about web performance and developer experience
+- Contributing to open-source projects in the web ecosystem
+
+## About This Layout
+
+> This page demonstrates the **alternative about layout** with a sidebar profile card.
+
+### Key Features
+
+This layout includes:
+
+1. **Left Sidebar Profile Card** with:
+ - Avatar/profile image (or placeholder icon)
+ - Name and role
+ - Location indicator
+ - Customizable stats (configured in `hugo.toml`)
+ - Social media links
+
+2. **Main Content Area** with:
+ - Introduction section
+ - Experience cards (from `---` separators)
+ - Tech stack badges (configured in `hugo.toml`)
+
+### How to Configure
+
+**Stats and Skills** are parametrized in your `hugo.toml`:
+
+```toml
+[params.about.alt]
+ # Custom stats
+ [[params.about.alt.stats]]
+ value = "5+"
+ label = "Years Coding"
+
+ # Tech stack with icons
+ [[params.about.alt.skills]]
+ label = "JavaScript"
+ icon = "devicon-javascript-plain"
+```
+
+This makes it easy to update your stats and skills without editing this page!
+
+---
+
+**Lead Developer** — [Modern Tech Co](https://example.com)
+*2022 – Present • Remote*
+
+Leading development of cloud-native applications and mentoring engineering teams. Focus on scalable architecture, clean code practices, and continuous delivery.
+
+---
+
+**Senior Engineer** — Startup Ventures
+*2020 – 2022 • San Francisco*
+
+Built full-stack applications from scratch. Worked with React, Node.js, PostgreSQL, and AWS to deliver features serving hundreds of thousands of users.
+
+---
+
+**Software Engineer** — Digital Solutions
+*2018 – 2020 • New York*
+
+Developed enterprise applications using Java, Spring Boot, and modern frontend frameworks. Collaborated with cross-functional teams to ship quality software.
+
+---
+
+**Junior Developer** — Tech Academy
+*2016 – 2018 • Boston*
+
+Started my career building web applications and learning industry best practices. Contributed to client projects and internal tooling.
+
+---
+
+## Layout Comparison
+
+| Feature | Standard About | Alternative About |
+|---------|---------------|-------------------|
+| Layout | Centered, single column | Sidebar + content |
+| Profile Info | Top hero section | Left sidebar card |
+| Stats | Not included | Configurable stats grid |
+| Tech Stack | Not included | Icon badges |
+| Timeline | Vertical with markers | Card-based grid |
+| Best For | Traditional resumes | Modern portfolios |
+
+Try both layouts to see which fits your style! Switch by changing `layout = "about"` or `layout = "about-alternative"` in the frontmatter.
+
+### Responsive Design
+
+Both layouts are fully responsive:
+- **Desktop:** Sidebar + content (alternative) or centered (standard)
+- **Tablet:** Stacked layout with adjusted spacing
+- **Mobile:** Single column, optimized for small screens
+
+---
+
+## Get Started
+
+To use this layout on your site:
+
+1. Copy this content file structure
+2. Set `layout = "about-alternative"` in frontmatter
+3. Configure stats and skills in `hugo.toml`
+4. Add your own content and experience
+5. Optionally add an avatar image to `static/images/`
+
+That's it! The theme handles all the styling and responsive behavior automatically.
diff --git a/themes/minimal-black/exampleSite/content/about/_index.md b/themes/minimal-black/exampleSite/content/about/_index.md
new file mode 100644
index 0000000..315cd6c
--- /dev/null
+++ b/themes/minimal-black/exampleSite/content/about/_index.md
@@ -0,0 +1,111 @@
++++
+title = "About Me"
+subtitle = "Software Engineer | Full Stack Developer | Open Source Enthusiast"
+layout = "about"
++++
+
+I'm a passionate software engineer with expertise in building scalable web applications and developer tools. With a focus on clean code, performance optimization, and user experience, I help teams ship products that users love.
+
+## What I Do
+
+I specialize in full-stack development with a keen interest in:
+
+- **Backend Engineering** — Building robust APIs and microservices with modern frameworks
+- **Frontend Development** — Creating responsive, accessible user interfaces
+- **DevOps & Infrastructure** — Container orchestration, CI/CD, and cloud platforms
+- **Open Source** — Contributing to and maintaining open-source projects
+
+## Timeline Demonstration
+
+> This page demonstrates the **standard about layout** with a timeline feature. Use horizontal rules (`---`) to separate timeline entries. Each section becomes a card in the timeline visualization.
+
+### Current Focus
+
+Right now, I'm exploring minimal design patterns, modern web frameworks, and building tools that make developers' lives easier. I believe in writing code that is simple, maintainable, and well-documented.
+
+---
+
+**Senior Software Engineer** — [Tech Company](https://example.com)
+*January 2022 – Present • Remote*
+
+Leading the development of cloud-native applications using modern frameworks and best practices. Mentoring junior developers and driving technical decisions for large-scale projects.
+
+Key achievements:
+- Architected microservices platform serving 1M+ users
+- Reduced deployment time by 60% through CI/CD improvements
+- Led migration from monolith to distributed architecture
+
+**Technologies:** React, Node.js, PostgreSQL, Docker, Kubernetes, AWS
+
+---
+
+**Full Stack Developer** — Startup Inc.
+*March 2020 – December 2021 • San Francisco, CA*
+
+Developed and maintained multiple web applications from concept to production. Collaborated with cross-functional teams to deliver features that increased user engagement by 40%.
+
+- Built RESTful APIs serving 500K+ daily requests
+- Implemented real-time features using WebSockets
+- Optimized database queries reducing response time by 50%
+
+**Technologies:** Python, Django, Vue.js, Redis, MySQL, GCP
+
+---
+
+**Software Engineer** — Digital Solutions Corp.
+*June 2018 – February 2020 • New York, NY*
+
+Worked on enterprise solutions for Fortune 500 clients. Focused on backend development, database design, and system integration.
+
+- Developed internal tools that saved 200+ hours monthly
+- Integrated third-party APIs for payment processing
+- Maintained legacy systems while modernizing architecture
+
+**Technologies:** Java, Spring Boot, Oracle DB, Angular, Jenkins
+
+---
+
+**Junior Developer** — Code Academy
+*January 2017 – May 2018 • Boston, MA*
+
+Started my professional journey building web applications and learning industry best practices. Contributed to various client projects and internal tooling.
+
+- Developed responsive web interfaces
+- Wrote automated tests achieving 90%+ coverage
+- Participated in code reviews and agile ceremonies
+
+**Technologies:** JavaScript, PHP, Laravel, MySQL, Git
+
+---
+
+## Education & Certifications
+
+**Bachelor of Science in Computer Science**
+University of Technology • 2013-2017
+
+**Certifications:**
+- AWS Certified Solutions Architect
+- Google Cloud Professional Developer
+- Certified Kubernetes Administrator (CKA)
+
+---
+
+## How This Layout Works
+
+This about page uses the **timeline layout**. Here's how to customize it:
+
+1. Set `layout = "about"` in the frontmatter
+2. Write your introduction before the first `---` separator
+3. Each section after `---` becomes a timeline card
+4. Use markdown formatting: **bold** for job titles, *italic* for dates
+5. Add links using `[text](url)` syntax
+6. Timeline items appear in chronological order (newest first)
+
+### Features Demonstrated
+
+- ✅ Hero section with avatar and subtitle
+- ✅ Timeline visualization with markers and cards
+- ✅ Markdown content with formatting
+- ✅ Links and emphasis
+- ✅ Responsive design
+- ✅ Social links in footer
diff --git a/themes/minimal-black/exampleSite/content/blog/_index.md b/themes/minimal-black/exampleSite/content/blog/_index.md
new file mode 100644
index 0000000..e69de29
diff --git a/themes/minimal-black/exampleSite/content/blog/theme-guide.md b/themes/minimal-black/exampleSite/content/blog/theme-guide.md
new file mode 100644
index 0000000..bd6bcfc
--- /dev/null
+++ b/themes/minimal-black/exampleSite/content/blog/theme-guide.md
@@ -0,0 +1,592 @@
++++
+title = "Complete Guide to Minimal Black Theme"
+date = "2025-01-15"
+author = "Jim Christopoulos"
+tags = ["hugo", "tutorial", "guide", "theme"]
+categories = ["documentation"]
+description = "A comprehensive guide to all features and capabilities of the Minimal Black Hugo theme"
+draft = false
++++
+
+Welcome to the complete guide for the Minimal Black Hugo theme!
+
+This post demonstrates all the features, components, and customization options available in the theme.
+
+## Introduction
+
+Minimal Black is designed for developers, designers, and everybody who want a clean, fast, and beautiful personal website.
+
+This guide will walk you through every feature with examples you can use in your own content.
+
+## Typography & Text Formatting
+
+### Headings
+
+The theme supports all six heading levels with proper hierarchy and spacing:
+
+# Heading 1
+## Heading 2
+### Heading 3
+#### Heading 4
+##### Heading 5
+###### Heading 6
+
+Each heading automatically gets an anchor link (hover to see the # symbol) for easy linking.
+
+### Text Emphasis
+
+Use standard Markdown for text formatting:
+
+- **Bold text** for emphasis
+- *Italic text* for subtle emphasis
+- ***Bold and italic*** for strong emphasis
+- ~~Strikethrough~~ for deleted content
+- `Inline code` for code references
+
+You can also ==highlight text== using the mark syntax (if enabled in your config).
+
+### Links
+
+Links are styled with subtle hover effects:
+
+- [External link](https://example.com)
+
+## Lists
+
+### Unordered Lists
+
+Simple bullet lists:
+
+- First item
+- Second item
+ - Nested item 1
+ - Nested item 2
+ - Deeply nested item
+- Third item
+
+### Ordered Lists
+
+Numbered lists:
+
+1. First step
+2. Second step
+ 1. Sub-step A
+ 2. Sub-step B
+3. Third step
+
+### Task Lists
+
+Interactive checkboxes:
+
+- [x] Completed task
+- [x] Another completed item
+- [ ] Pending task
+- [ ] Another pending item
+ - [x] Nested completed
+ - [ ] Nested pending
+
+Task lists are great for project planning, feature tracking, or tutorial steps.
+
+### Definition Lists
+
+For glossary-style content:
+
+Hugo
+: A fast static site generator written in Go
+
+Markdown
+: A lightweight markup language for formatting text
+
+Tailwind CSS
+: A utility-first CSS framework
+
+## Blockquotes
+
+### Standard Blockquotes
+
+Simple quotes with gradient background:
+
+> This is a standard blockquote. It has a subtle gradient background and a colored left border for visual distinction.
+
+> Multi-paragraph blockquotes work too.
+>
+> They maintain proper spacing between paragraphs while keeping the unified look.
+
+### Nested Blockquotes
+
+You can nest quotes:
+
+> This is the outer quote.
+>
+> > This is a nested quote inside.
+> >
+> > > You can nest multiple levels.
+
+### GitHub-Style Alerts
+
+The theme supports GitHub-flavored alert callouts:
+
+> [!NOTE]
+> This is a note callout. Use it for informational content that readers should be aware of.
+
+> [!TIP]
+> This is a tip callout. Perfect for helpful suggestions and best practices.
+
+> [!IMPORTANT]
+> This is an important callout. Use it for critical information that must not be missed.
+
+> [!WARNING]
+> This is a warning callout. Great for cautionary information and potential pitfalls.
+
+> [!CAUTION]
+> This is a caution callout. Use for dangerous actions or critical warnings.
+
+## Code Blocks
+
+### Inline Code
+
+Reference code inline with `backticks`.
+
+Great for mentioning `variables`, `functions()`, or `file-names.txt`.
+
+### Basic Code Blocks
+
+Simple code blocks without syntax highlighting:
+
+```
+This is a plain code block.
+No syntax highlighting.
+Perfect for plain text or output.
+```
+
+### Syntax Highlighted Code
+
+The theme supports syntax highlighting for dozens of languages:
+
+**JavaScript:**
+```javascript
+
+const greet = (name) => {
+ console.log(`Hello, ${name}!`);
+ return `Welcome to the Minimal Black theme`;
+};
+
+// Async/await example
+async function fetchData(url) {
+ try {
+ const response = await fetch(url);
+ const data = await response.json();
+ return data;
+ } catch (error) {
+ console.error('Error fetching data:', error);
+ }
+}
+```
+
+**Python:**
+```python
+def fibonacci(n):
+ """Calculate fibonacci number recursively."""
+ if n <= 1:
+ return n
+ return fibonacci(n-1) + fibonacci(n-2)
+
+# List comprehension example
+squares = [x**2 for x in range(10)]
+print(squares)
+```
+
+**Go:**
+```go
+package main
+
+import "fmt"
+
+func main() {
+ // Simple HTTP server
+ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+ fmt.Fprintf(w, "Hello, World!")
+ })
+
+ http.ListenAndServe(":8080", nil)
+}
+```
+
+**Bash:**
+```bash
+#!/bin/bash
+
+# Deploy script
+hugo --minify
+rsync -avz public/ user@server:/var/www/
+echo "Deployment complete!"
+```
+
+**CSS:**
+```css
+/* Dark theme variables */
+:root {
+ --color-bg: #000000;
+ --color-accent: #c084fc;
+ --transition: all 0.2s ease;
+}
+
+.button {
+ background: var(--color-accent);
+ transition: var(--transition);
+}
+```
+
+**HTML:**
+```html
+
+
+
+
+ Minimal Black
+
+
+ Welcome!
+
+
+```
+
+### Code Block Features
+
+All code blocks include:
+
+- **Language Label** — Shows the language in top-right corner
+- **Copy Button** — Click to copy code to clipboard
+- **Line Numbers** — Optional (configure in hugo.toml)
+- **Syntax Highlighting** — Powered by Hugo's Chroma
+
+## Tables
+
+### Basic Tables
+
+| Feature | Supported | Notes |
+|---------|-----------|-------|
+| Dark Mode | ✅ | True black backgrounds |
+| Search | ✅ | Client-side, fast |
+| TOC | ✅ | Auto-generated |
+| Analytics | ✅ | Multiple providers |
+
+### Aligned Columns
+
+| Left Aligned | Center Aligned | Right Aligned |
+|:-------------|:--------------:|--------------:|
+| Left | Center | Right |
+| Text | Text | 100 |
+| More | Data | 250 |
+
+### Complex Tables
+
+| Language | Supported | Syntax Highlighting | Code Blocks |
+|----------|:---------:|:-------------------:|-------------|
+| JavaScript | ✅ | ✅ | Yes |
+| Python | ✅ | ✅ | Yes |
+| Go | ✅ | ✅ | Yes |
+| Rust | ✅ | ✅ | Yes |
+| TypeScript | ✅ | ✅ | Yes |
+
+Tables are responsive and scroll horizontally on small screens.
+
+## Images
+
+### Basic Image
+
+
+
+### Image with Caption
+
+Images automatically get a lightbox overlay on hover (magnifying glass icon appears).
+
+### Multiple Images
+
+
+
+
+> [!NOTE]
+> *Stock Images obtained from pexels.com*
+
+Images are responsive and scale to fit the content width.
+
+## Gallery Shortcode
+
+Use the gallery shortcode for image collections:
+
+{{< gallery >}}
+
+
+
+{{< /gallery >}}
+
+The gallery includes:
+- Lightbox functionality
+- Click to view full size
+- Navigate between images
+- Responsive grid layout
+
+## Mermaid Diagrams
+
+### Flowchart
+
+```mermaid
+graph TD
+ A[Start] --> B{Is it dark mode?}
+ B -->|Yes| C[Load dark theme]
+ B -->|No| D[Load light theme]
+ C --> E[Render page]
+ D --> E
+ E --> F[User sees beautiful site]
+```
+
+### Sequence Diagram
+
+```mermaid
+sequenceDiagram
+ participant User
+ participant Browser
+ participant Hugo
+ participant Theme
+
+ User->>Browser: Visit site
+ Browser->>Hugo: Request page
+ Hugo->>Theme: Render template
+ Theme->>Hugo: Return HTML
+ Hugo->>Browser: Serve page
+ Browser->>User: Display site
+```
+
+### Class Diagram
+
+```mermaid
+classDiagram
+ class Theme {
+ +String name
+ +String version
+ +render()
+ +configure()
+ }
+ class Config {
+ +Object params
+ +validate()
+ }
+ class Content {
+ +String title
+ +Date date
+ +render()
+ }
+
+ Theme --> Config
+ Theme --> Content
+```
+
+## Horizontal Rules
+
+Separate sections with horizontal rules:
+
+---
+
+Like this one above. They create clear visual breaks in content.
+
+## Footnotes
+
+You can add footnotes[^1] to your content. They appear at the bottom of the page[^2].
+
+[^1]: This is a footnote. It provides additional context without interrupting the flow.
+[^2]: Footnotes are automatically numbered and linked.
+
+## Shortcodes
+
+### Alert Shortcode
+
+Use the alert shortcode for callouts:
+
+{{< alert type="note" >}}
+This is a custom alert using the shortcode syntax. It's an alternative to GitHub-style alerts.
+{{< /alert >}}
+
+{{< alert type="warning" >}}
+Warning alerts grab attention for important notices.
+{{< /alert >}}
+
+## Table of Contents
+
+This page demonstrates the automatic table of contents:
+
+- **Desktop:** TOC appears in left sidebar
+- **Tablet:** TOC is hidden for more reading space
+- **Mobile:** TOC is completely hidden
+
+The TOC automatically:
+- Tracks your scroll position
+- Highlights the current section
+- Links to all headings (H2-H4)
+- Stays visible while scrolling (sticky)
+
+## Dark & Light Mode
+
+The theme supports both dark and light modes:
+
+### Dark Mode (Default)
+- True black backgrounds (#000000)
+- OLED-friendly
+- Purple accents (#c084fc)
+- Reduced eye strain in low light
+
+### Light Mode
+- Clean white backgrounds
+- High contrast for daylight reading
+- Purple accents (#a855f7)
+- Print-friendly
+
+### System Mode
+- Automatically matches OS preference
+- Respects user's system settings
+- Seamless switching
+
+Users can toggle between modes using the theme switcher in the navigation.
+
+## Search Functionality
+
+Press **Ctrl/Cmd + K** to try the search:
+
+1. Type your query
+2. Results appear instantly
+3. Use arrow keys to navigate
+4. Press Enter to visit page
+5. ESC to close
+
+The search:
+- Is client-side (no server needed)
+- Searches titles and summaries
+- Highlights matching text
+- Works offline
+
+## Navigation
+
+The theme includes:
+
+### Header Navigation
+- Logo/brand name
+- Main menu links
+- Theme toggle
+
+### Footer
+- Copyright notice
+- Social links
+- Attribution
+
+### Floating Dock (Bottom Right)
+- Quick actions
+- Scroll to top
+
+## Responsive Design
+
+The theme is fully responsive:
+
+### Mobile (< 640px)
+- Single column layout
+- Collapsible menu
+- Touch-friendly buttons
+- Optimized images
+
+### Tablet (641px - 1023px)
+- Two column where appropriate
+- Adjusted spacing
+- Tablet-optimized navigation
+
+### Desktop (1024px+)
+- Full layout with TOC sidebar
+- Wider content area
+- Hover effects
+- Keyboard shortcuts
+
+## Performance
+
+The theme is optimized for performance:
+
+- **Minimal JavaScript**
+- **Optimized CSS**
+- **Fast Loading**
+- **SEO Optimized** — Meta tags, structured data
+
+## Customization Examples
+
+### Changing Accent Color
+
+Edit `assets/css/base.css`:
+
+```css
+:root {
+ --color-accent: #10b981; /* Green instead of purple */
+}
+```
+
+### Adding Custom Fonts
+
+In your `hugo.toml`:
+
+```toml
+[params]
+ customFonts = ["https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap"]
+```
+
+### Custom CSS
+
+Create `assets/css/custom.css`:
+
+```css
+.my-custom-element {
+ /* Your styles */
+}
+```
+
+## Best Practices
+
+### Content Organization
+
+1. Use clear, descriptive titles
+2. Break content into sections with headings
+3. Add tags and categories
+4. Include descriptions in frontmatter
+5. Use featured images for posts
+
+### Performance
+
+1. Optimize images before uploading
+2. Use SVG for logos and icons
+3. Minimize custom JavaScript
+4. Leverage Hugo's asset pipeline
+
+### SEO
+
+1. Write descriptive meta descriptions
+2. Use semantic HTML headings
+3. Add alt text to images
+4. Create an XML sitemap
+5. Submit to search engines
+
+## Conclusion
+
+This guide covered all major features of the Minimal Black theme. You now know how to:
+
+- ✅ Format text and create rich content
+- ✅ Use code blocks with syntax highlighting
+- ✅ Add images and galleries
+- ✅ Create diagrams with Mermaid
+- ✅ Organize content with TOC
+- ✅ Customize colors and styles
+- ✅ Optimize for performance
+- ✅ Make content SEO-friendly
+
+Start creating amazing content with Minimal Black!
+
+---
+
+**Documentation:** [Full Docs](https://gitlab.com/jimchr12/hugo-minimal-black)
+
+**Repository:** [GitLab](https://gitlab.com/jimchr12/hugo-minimal-black)
+
+**Issues:** [Report a Bug](https://gitlab.com/jimchr12/hugo-minimal-black/issues)
diff --git a/themes/minimal-black/exampleSite/content/projects/_index.md b/themes/minimal-black/exampleSite/content/projects/_index.md
new file mode 100644
index 0000000..e69de29
diff --git a/themes/minimal-black/exampleSite/content/projects/sample-project.md b/themes/minimal-black/exampleSite/content/projects/sample-project.md
new file mode 100644
index 0000000..7a6a04c
--- /dev/null
+++ b/themes/minimal-black/exampleSite/content/projects/sample-project.md
@@ -0,0 +1,321 @@
++++
+title = "Minimal Black Hugo Theme"
+date = "2025-01-15"
+description = "A minimal, dark-mode first Hugo theme"
+github = "https://gitlab.com/jimchr12/hugo-minimal-black"
+demo = "https://minimal-black-demo.netlify.app"
+tags = ["hugo", "theme", "web-development", "open-source"]
+categories = ["web"]
+featured = true
++++
+
+A comprehensive Hugo theme designed for developers, designers, and everyone in general who value simplicity, performance, and beautiful dare I say dark mode design (maybe?).
+
+## Overview
+
+Minimal Black is a modern Hugo theme that combines aesthetic appeal with practical functionality.
+
+Built with Tailwind CSS and a modular architecture, it provides everything you need for a professional personal website, portfolio or blog.
+
+### Key Features
+
+- **True Black Dark Mode** — With purple accents
+- **Responsive Design** — Perfect on mobile, tablet, and desktop
+- **Search Functionality** — Fast client-side search with Ctrl/Cmd+K
+- **Table of Contents** — Auto-generated
+- **Syntax Highlighting** — Beautiful code blocks with copy functionality
+- **Multiple Layouts** — Flexible page templates for different content types (more to come hopefully).
+
+## Technical Architecture
+
+### Frontend Stack
+
+- **Hugo Extended** (v0.120.0+) — Static site generator
+- **Tailwind CSS** — Utility-first CSS framework
+- **Vanilla JS** — Minimal JS used - no framework
+- **PostCSS** — CSS processing and optimization
+
+### CSS Modular Structure
+
+The CSS is organized into logical modules:
+
+```
+assets/css/
+├── base.css # Theme variables & Tailwind
+├── utilities.css # Helper classes
+├── components/ # Reusable UI components
+│ ├── dock.css
+│ ├── cards.css
+│ ├── navigation.css
+│ ├── search.css
+│ └── tech-marquee.css
+├── content/ # Content-specific styles
+│ ├── markdown.css
+│ └── toc.css
+└── pages/ # Page-specific styles
+ ├── about.css
+ └── about-alternative.css
+```
+
+This modular approach makes the theme:
+- Easy to maintain and extend
+- Simple to customize specific components
+- Clear separation of concerns
+- Better developer experience
+
+## Design Philosophy
+
+### Minimalism First
+
+The theme embraces minimalism without sacrificing functionality:
+
+1. **Clean Typography** — Careful font choices and spacing
+2. **Focused Content** — Remove distractions, highlight what matters
+3. **Subtle Animations** — Smooth transitions that enhance UX
+4. **Dark Mode Priority** — True black backgrounds
+
+## Feature Showcase
+
+### Search Functionality
+
+Built-in search with keyboard shortcuts:
+
+- Press **Ctrl/Cmd + K** to open search
+- Type to filter results in real-time
+- Use **Arrow keys** to navigate
+- Press **Enter** to visit page
+- **ESC** to close
+
+The search is client-side, fast, and requires no external services.
+
+### Code Blocks
+
+Beautiful syntax highlighting with practical features:
+
+```javascript
+// Copy button on hover
+function greet(name) {
+ console.log(`Hello, ${name}!`);
+ return `Welcome to Minimal Black Theme`;
+}
+
+greet("Developer");
+```
+
+Features include:
+
+- Language labels
+- Copy to clipboard button
+- Line highlighting
+- Collapsible / Expandable block
+
+### GitHub-Style Alerts
+
+Support for callout boxes:
+
+> [!NOTE]
+> This is a note alert for informational content.
+
+> [!TIP]
+> This is a tip alert with helpful suggestions.
+
+> [!WARNING]
+> This is a warning alert for important notices.
+
+> [!IMPORTANT]
+> This is an important alert for critical information.
+
+### Table of Contents
+
+MD content automatically gets a TOC:
+
+- **Sticky Positioning** — Stays visible while scrolling
+- **Active Tracking** — Highlights current section
+- **Smooth Scrolling** — Click to jump to section
+- **Responsive** — Hides on mobile, shows on desktop
+
+You're seeing it in action on this **page**!
+
+### Mermaid Diagrams
+
+Native support for flowcharts and diagrams:
+
+```mermaid
+graph TD
+ A[User visits site] --> B{Dark mode?}
+ B -->|Yes| C[Load dark theme]
+ B -->|No| D[Load light theme]
+ C --> E[Render content]
+ D --> E
+ E --> F[Fast, beautiful site]
+```
+
+Perfect for technical documentation.
+
+## Configuration
+
+The theme is highly configurable via `hugo.toml`:
+
+### Basic Setup
+
+```toml
+[params]
+ brand = "Your Name"
+ description = "Your site description"
+
+ [params.theme]
+ defaultTheme = "dark" # or "light" or "system"
+```
+
+### Hero Section
+
+```toml
+[params.hero]
+ badge = "Software Engineer"
+ title = "Hi, I'm Your Name."
+ role = "Building things."
+ summary = "Description of what you do."
+ location = "City, Country"
+```
+
+### Tech Stack Display
+
+```toml
+[[params.home.tech]]
+ label = "Python"
+ icon = "devicon-python-plain"
+
+[[params.home.tech]]
+ label = "Docker"
+ icon = "devicon-docker-plain"
+```
+
+### Analytics
+
+Support for multiple providers:
+
+```toml
+[params.analytics]
+ googleAnalytics = "G-XXXXXXXXXX"
+
+ # Or use Plausible, Umami, Fathom
+```
+
+## Customization Guide
+
+### Colors
+
+Theme colors are CSS custom properties in `assets/css/base.css`:
+
+```css
+:root {
+ --color-bg: #f9fafb; /* Light background */
+ --color-accent: #a855f7; /* Purple accent */
+}
+
+html[data-theme="dark"] {
+ --color-bg: #000000; /* True black */
+ --color-accent: #c084fc; /* Lighter purple */
+}
+```
+
+### Adding Custom Styles
+
+Create `assets/css/custom.css` in your site:
+
+```css
+/* Your custom styles */
+.my-custom-class {
+ /* ... */
+}
+```
+
+Then reference it in your config:
+
+```toml
+[params]
+ customCSS = ["css/custom.css"]
+```
+
+## Content Organization
+
+### Recommended Structure
+
+```
+content/
+├── _index.md # Homepage
+├── about.md # About page
+├── blog/
+│ ├── _index.md
+│ └── posts/
+├── projects/
+│ ├── _index.md
+│ └── individual-projects/
+└── pages/
+ └── custom-pages/
+```
+
+### Frontmatter Examples
+
+**Blog Post:**
+```yaml
++++
+title = "Post Title"
+date = "2025-01-15"
+tags = ["hugo", "web-dev"]
+categories = ["tutorials"]
+draft = false
++++
+```
+
+**Project:**
+```yaml
++++
+title = "Project Name"
+description = "Brief description"
+github = "https://github.com/..." # Optional
+demo = "https://demo.com" # Optional
+featured = true
++++
+```
+
+## Deployment
+
+### Netlify
+
+1. Connect your Git repository
+2. Build command: `hugo --minify`
+3. Publish directory: `public`
+4. Environment: `HUGO_VERSION=0.120.0`
+
+### Vercel
+
+1. Import repository
+2. Framework: Hugo
+3. Build command: `cd themes/minimal-black && npm install && cd ../.. && hugo --minify`
+4. Output: `public`
+
+## Contributing
+
+Contributions are welcome! See [CONTRIBUTING.md](https://gitlab.com/jimchr12/hugo-minimal-black/blob/main/CONTRIBUTING.md) for guidelines.
+
+## License
+
+Released under the MIT License. See [LICENSE](https://gitlab.com/jimchr12/hugo-minimal-black/blob/main/LICENSE) for details.
+
+## Acknowledgments
+
+Built with:
+
+- [Hugo](https://gohugo.io/) — Static site generator
+- [Tailwind CSS](https://tailwindcss.com/) — CSS framework
+- [Font Awesome](https://fontawesome.com/) — Icons
+- [Devicon](https://devicon.dev/) — Technology icons
+
+---
+
+**Repository:** [GitLab](https://gitlab.com/jimchr12/hugo-minimal-black)
+
+**Demo:** [Live Preview](https://minimal-black-demo.netlify.app)
+
+**Documentation:** [Full Docs](https://gitlab.com/jimchr12/hugo-minimal-black#readme)
diff --git a/themes/minimal-black/exampleSite/hugo.toml b/themes/minimal-black/exampleSite/hugo.toml
new file mode 100644
index 0000000..5ced6ee
--- /dev/null
+++ b/themes/minimal-black/exampleSite/hugo.toml
@@ -0,0 +1,362 @@
+baseURL = 'https://minimal-black-demo.netlify.app'
+languageCode = 'en-us'
+title = 'Minimal Black Theme'
+theme = "minimal-black"
+
+# Enable search index generation and web app manifest
+[outputs]
+ home = ["HTML", "RSS", "JSON", "WebAppManifest"]
+
+[outputFormats.WebAppManifest]
+ mediaType = "application/manifest+json"
+ rel = "manifest"
+ baseName = "manifest"
+ isPlainText = true
+ notAlternative = true
+
+[params]
+ brand = "Hugo Minimal Black"
+ description = "A minimal, dark-mode first personal site, or whatever else you want it to be about"
+
+ # Favicon - Place your favicon files in /static/ directory
+ # Supported formats: .ico, .png, .svg
+ favicon = "icons/favicon.svg"
+ appleTouchIcon = "apple-touch-icon.png"
+
+ # Logo (optional)
+ logo = "images/logo.png"
+
+ # Project and blog intro text
+ projectsIntro = "Selected projects to display list." # Can be empty
+ blogIntro = "" # Can be empty
+
+ # Web App Manifest Configuration (PWA support)
+ [params.manifest]
+ themeColor = "#a855f7"
+ backgroundColor = "#000000"
+ categories = ["blog", "portfolio", "developer"]
+
+ # Custom icon configuration (optional)
+ # If not specified, defaults to /icons/android-chrome-*.png
+ # [[params.manifest.icons]]
+ # src = "/icons/android-chrome-192x192.png"
+ # sizes = "192x192"
+ # type = "image/png"
+ # purpose = "any maskable"
+
+ # Theme Configuration
+ [params.theme]
+ defaultTheme = "dark" # Options: "light", "dark", "system"
+
+ # Home Page Configuration
+ [params.home]
+ sections = ["hero", "now", "tech-marquee", "projects", "posts"]
+ showNowSection = true
+ showFeaturedProjects = true
+ showLatestPosts = true
+ featuredProjectsLimit = 3
+ latestPostsLimit = 3
+ projectsTitle = "Selected Work"
+ projectsSubtitle = ""
+ blogTitle = "Latest Writing"
+ blogSubtitle = ""
+ techMarqueeLabel = "Experienced In"
+
+ # Technology Stack Display
+ [[params.home.tech]]
+ label = "Python"
+ icon = "devicon-python-plain"
+
+ [[params.home.tech]]
+ label = "Java"
+ icon = "devicon-java-plain"
+
+ [[params.home.tech]]
+ label = "Spring"
+ icon = "devicon-spring-plain"
+
+ [[params.home.tech]]
+ label = "Vaadin"
+ icon = "devicon-vaadin-plain"
+
+ [[params.home.tech]]
+ label = "Debian"
+ icon = "devicon-debian-plain"
+
+ [[params.home.tech]]
+ label = "GitLab"
+ icon = "devicon-gitlab-plain"
+
+ [[params.home.tech]]
+ label = "Docker"
+ icon = "devicon-docker-plain"
+
+ [[params.home.techReverse]]
+ label = "PostgreSQL"
+ icon = "devicon-postgresql-plain"
+
+ [[params.home.techReverse]]
+ label = "MongoDB"
+ icon = "devicon-mongodb-plain"
+
+ [[params.home.techReverse]]
+ label = "Git"
+ icon = "devicon-git-plain"
+
+ [[params.home.techReverse]]
+ label = "Hugo"
+ icon = "devicon-hugo-plain"
+
+ [[params.home.techReverse]]
+ label = "Jenkins"
+ icon = "devicon-jenkins-plain"
+
+ [[params.home.techReverse]]
+ label = "JetBrains"
+ icon = "devicon-jetbrains-plain"
+
+ [[params.home.techReverse]]
+ label = "Json"
+ icon = "devicon-json-plain"
+
+ [[params.home.techReverse]]
+ label = "Linux"
+ icon = "devicon-linux-plain"
+
+ [[params.home.techReverse]]
+ label = "Liquibase"
+ icon = "devicon-liquibase-plain"
+
+ [[params.home.techReverse]]
+ label = "Markdown"
+ icon = "devicon-markdown-original"
+
+ [[params.home.techReverse]]
+ label = "YAML"
+ icon = "devicon-yaml-plain"
+
+ [[params.home.techReverse]]
+ label = "Wordpress"
+ icon = "devicon-wordpress-plain"
+
+ [[params.home.techReverse]]
+ label = "WooCommerce"
+ icon = "devicon-woocommerce-plain"
+
+ [[params.home.techReverse]]
+ label = "Traefik"
+ icon = "devicon-traefikproxy-plain"
+
+ [[params.home.techReverse]]
+ label = "pfSense"
+ icon = "devicon-pfsense-plain"
+
+ # About Page Alternative Layout Configuration - Optional
+ [params.about.alt]
+ # Stats displayed in the profile card sidebar
+ [[params.about.alt.stats]]
+ value = "5+"
+ label = "Years Coding"
+
+ [[params.about.alt.stats]]
+ value = "20+"
+ label = "Projects"
+
+ [[params.about.alt.stats]]
+ value = "∞"
+ label = "Hours Spent"
+
+ # Skills/Tech Stack badges with icons
+ [[params.about.alt.skills]]
+ label = "JavaScript"
+ icon = "devicon-javascript-plain"
+
+ [[params.about.alt.skills]]
+ label = "Python"
+ icon = "devicon-python-plain"
+
+ [[params.about.alt.skills]]
+ label = "React"
+ icon = "devicon-react-original"
+
+ [[params.about.alt.skills]]
+ label = "Docker"
+ icon = "devicon-docker-plain"
+
+ [[params.about.alt.skills]]
+ label = "PostgreSQL"
+ icon = "devicon-postgresql-plain"
+
+ [[params.about.alt.skills]]
+ label = "AWS"
+ icon = "devicon-amazonwebservices-plain"
+
+ # Hero Section Configuration
+ [params.hero]
+ badge = "Software Engineer"
+ title = "Hi, I'm Your Name or your interesting title."
+ role = "Subtitle for title with role perspective"
+ summary = "You can write your summary to be displayed here."
+ # avatar = "images/avatar.jpg" # Optional: 400x400px recommended
+ location = "City, Country"
+ focus = "Currently focused on Hugo themes & developer experience."
+ available = true
+ availableLabel = "Available for work"
+
+ nowLabel = "Quick Facts"
+ nowIntro = "Right now I'm mainly:"
+ now = [
+ "Building minimal Hugo themes",
+ "Exploring dark-mode design patterns",
+ "Writing about web performance"
+ ]
+
+ [params.hero.primary]
+ label = "View Projects"
+ href = "/projects/"
+
+ [params.hero.secondary]
+ label = "Read the Blog"
+ href = "/blog/"
+
+ # Icon Libraries
+ [params.icons]
+ useFontAwesome = true
+ useDevicon = true
+
+ # Social Links
+ [[params.social]]
+ label = "GitLab"
+ url = "https://gitlab.com/jimchr12"
+ icon = "fa-brands fa-gitlab"
+
+ [[params.social]]
+ label = "LinkedIn"
+ url = "https://www.linkedin.com/in/jimchristopoulos-542512221/"
+ icon = "fa-brands fa-linkedin-in"
+
+ [[params.social]]
+ label = "Email"
+ url = "mailto:you@example.com"
+ icon = "fa-regular fa-envelope"
+
+ # Analytics Configuration
+ [params.analytics]
+ # Google Analytics (GA4)
+ # googleAnalytics = "G-XXXXXXXXXX"
+
+ # Plausible Analytics (privacy-friendly)
+ # [params.analytics.plausible]
+ # enabled = true
+ # domain = "yourdomain.com"
+ # scriptUrl = "https://plausible.io/js/script.js"
+
+ # Umami Analytics (self-hosted option)
+ # [params.analytics.umami]
+ # enabled = true
+ # scriptUrl = "https://analytics.yourdomain.com/script.js"
+ # websiteId = "your-website-id"
+
+ # Fathom Analytics
+ # [params.analytics.fathom]
+ # enabled = true
+ # scriptUrl = "https://cdn.usefathom.com/script.js"
+ # siteId = "YOUR-SITE-ID"
+
+# Navigation Menu
+[menu]
+ [[menu.main]]
+ name = "Home"
+ pageRef = "/"
+ url = "/"
+ weight = 1
+ identifier = "home"
+ [menu.main.params]
+ icon = "fa-solid fa-house"
+
+ [[menu.main]]
+ name = "About"
+ pageRef = "about"
+ url = "/about/"
+ weight = 2
+ identifier = "about"
+ [menu.main.params]
+ icon = "fa-regular fa-user"
+
+ [[menu.main]]
+ name = "About Alt"
+ pageRef = "about-alternative"
+ url = "/about-alternative/"
+ weight = 2
+ identifier = "about-alternative"
+ [menu.main.params]
+ icon = "fa-solid fa-user"
+
+ [[menu.main]]
+ name = "Projects"
+ pageRef = "projects"
+ url = "/projects/"
+ weight = 3
+ identifier = "projects"
+ [menu.main.params]
+ icon = "fa-regular fa-folder-open"
+
+ [[menu.main]]
+ name = "Blog"
+ pageRef = "blog"
+ url = "/blog/"
+ weight = 4
+ identifier = "blog"
+ [menu.main.params]
+ icon = "fa-regular fa-note-sticky"
+
+# Markup Configuration
+[markup]
+ # Table of Contents
+ [markup.tableOfContents]
+ startLevel = 2
+ endLevel = 4
+
+ # Goldmark Renderer (Markdown)
+ [markup.goldmark.renderer]
+ unsafe = true
+
+ [markup.goldmark.parser]
+ [markup.goldmark.parser.attribute]
+ block = true
+
+ [markup.goldmark.extensions]
+ typographer = true
+ linkify = true
+ table = true
+ strikethrough = true
+ taskList = true
+ definitionList = true
+ footnote = true
+
+ [markup.goldmark.extensions.extras.delete]
+ enable = true
+ [markup.goldmark.extensions.extras.insert]
+ enable = true
+ [markup.goldmark.extensions.extras.mark]
+ enable = true
+
+ # Syntax Highlighting
+ [markup.highlight]
+ codeFences = true
+ guessSyntax = true
+ lineNos = false
+ lineNumbersInTable = false
+ noClasses = false
+ style = "monokai"
+ tabWidth = 2
+
+# Taxonomies
+[taxonomies]
+ tag = "tags"
+ category = "categories"
+
+# Privacy Configuration
+[privacy]
+ [privacy.youtube]
+ privacyEnhanced = true
diff --git a/themes/minimal-black/images/about-alt.png b/themes/minimal-black/images/about-alt.png
new file mode 100644
index 0000000..09a2462
Binary files /dev/null and b/themes/minimal-black/images/about-alt.png differ
diff --git a/themes/minimal-black/images/about.png b/themes/minimal-black/images/about.png
new file mode 100644
index 0000000..3c074b1
Binary files /dev/null and b/themes/minimal-black/images/about.png differ
diff --git a/themes/minimal-black/images/screenshot.png b/themes/minimal-black/images/screenshot.png
new file mode 100644
index 0000000..01f70cf
Binary files /dev/null and b/themes/minimal-black/images/screenshot.png differ
diff --git a/themes/minimal-black/images/tn.png b/themes/minimal-black/images/tn.png
new file mode 100644
index 0000000..d3c5092
Binary files /dev/null and b/themes/minimal-black/images/tn.png differ
diff --git a/themes/minimal-black/layouts/404.html b/themes/minimal-black/layouts/404.html
new file mode 100644
index 0000000..b5433cc
--- /dev/null
+++ b/themes/minimal-black/layouts/404.html
@@ -0,0 +1,308 @@
+{{ define "main" }}
+
+
+
+
+
404
+
+
+
Page Not Found
+
+ The page you're looking for doesn't exist or has been moved.
+
+
+
+
+
+ Try searching for what you need, or return to the homepage.
+
+
+
+
+
+
+
You might be interested in:
+
+
+
+
+ {{ $recentPages := where .Site.RegularPages "Section" "in" (slice "blog" "projects") }}
+ {{ $recentPages = first 3 $recentPages }}
+ {{ if $recentPages }}
+
+ {{ end }}
+
+
+
+
+
+{{ end }}
diff --git a/themes/minimal-black/layouts/_default/_markup/render-blockquote-mermaid.html b/themes/minimal-black/layouts/_default/_markup/render-blockquote-mermaid.html
new file mode 100644
index 0000000..9016162
--- /dev/null
+++ b/themes/minimal-black/layouts/_default/_markup/render-blockquote-mermaid.html
@@ -0,0 +1,7 @@
+
+
+
+{{ .Text | safeHTML }}
+
+
+
diff --git a/themes/minimal-black/layouts/_default/_markup/render-blockquote.html b/themes/minimal-black/layouts/_default/_markup/render-blockquote.html
new file mode 100644
index 0000000..0a43e6c
--- /dev/null
+++ b/themes/minimal-black/layouts/_default/_markup/render-blockquote.html
@@ -0,0 +1,10 @@
+{{- /* Check if this is a GitHub-style alert */ -}}
+{{- if eq .Type "alert" -}}
+
+ {{ .Text | safeHTML }}
+
+{{- else -}}
+
+ {{ .Text | safeHTML }}
+
+{{- end -}}
diff --git a/themes/minimal-black/layouts/_default/_markup/render-codeblock-mermaid.html b/themes/minimal-black/layouts/_default/_markup/render-codeblock-mermaid.html
new file mode 100644
index 0000000..0b638e9
--- /dev/null
+++ b/themes/minimal-black/layouts/_default/_markup/render-codeblock-mermaid.html
@@ -0,0 +1,5 @@
+
+
+{{ .Inner | safeHTML }}
+
+
diff --git a/themes/minimal-black/layouts/_default/_markup/render-codeblock.html b/themes/minimal-black/layouts/_default/_markup/render-codeblock.html
new file mode 100644
index 0000000..17f4e66
--- /dev/null
+++ b/themes/minimal-black/layouts/_default/_markup/render-codeblock.html
@@ -0,0 +1,337 @@
+{{- $lang := .Type | default "text" -}}
+{{- $filename := .Attributes.filename | default "" -}}
+{{- $label := cond (ne $filename "") $filename ($lang | upper) -}}
+{{- $id := printf "cb-%s" (printf "%d" .Ordinal | sha256 | truncate 8 "") -}}
+
+{{- $collapseEnabled := site.Params.codeblock.collapse.enabled | default true -}}
+{{- $defaultState := site.Params.codeblock.collapse.defaultState | default "expanded" -}}
+{{- $collapsedHeight := site.Params.codeblock.collapse.collapsedHeight | default 200 -}}
+
+{{- $highlighted := transform.HighlightCodeBlock . -}}
+
+
+
+
+
+
+
+ {{ $highlighted.Wrapped }}
+
+ {{- if $collapseEnabled -}}
+
+
+
+ Click to expand
+
+
+ {{- end -}}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/themes/minimal-black/layouts/_default/_markup/render-heading.html b/themes/minimal-black/layouts/_default/_markup/render-heading.html
new file mode 100644
index 0000000..f522faf
--- /dev/null
+++ b/themes/minimal-black/layouts/_default/_markup/render-heading.html
@@ -0,0 +1,5 @@
+
+
+ {{ .Text | safeHTML }}
+
+
diff --git a/themes/minimal-black/layouts/_default/_markup/render-image.html b/themes/minimal-black/layouts/_default/_markup/render-image.html
new file mode 100644
index 0000000..521c3c6
--- /dev/null
+++ b/themes/minimal-black/layouts/_default/_markup/render-image.html
@@ -0,0 +1,12 @@
+
+
+
+
+ {{ with .Title }}
+ {{ . }}
+ {{ end }}
+
diff --git a/themes/minimal-black/layouts/_default/_markup/render-link.html b/themes/minimal-black/layouts/_default/_markup/render-link.html
new file mode 100644
index 0000000..c5c0368
--- /dev/null
+++ b/themes/minimal-black/layouts/_default/_markup/render-link.html
@@ -0,0 +1,7 @@
+
+ {{ .Text | safeHTML }}
+
diff --git a/themes/minimal-black/layouts/_default/_markup/render-table.html b/themes/minimal-black/layouts/_default/_markup/render-table.html
new file mode 100644
index 0000000..173f355
--- /dev/null
+++ b/themes/minimal-black/layouts/_default/_markup/render-table.html
@@ -0,0 +1,39 @@
+
+
+
+ {{- range .THead }}
+
+ {{- range . }}
+
+ {{- .Text -}}
+
+ {{- end }}
+
+ {{- end }}
+
+
+ {{- range .TBody }}
+
+ {{- range . }}
+
+ {{- .Text -}}
+
+ {{- end }}
+
+ {{- end }}
+
+
+
diff --git a/themes/minimal-black/layouts/_default/_shortcodes/alert.html b/themes/minimal-black/layouts/_default/_shortcodes/alert.html
new file mode 100644
index 0000000..10c8789
--- /dev/null
+++ b/themes/minimal-black/layouts/_default/_shortcodes/alert.html
@@ -0,0 +1,4 @@
+{{- $type := .Get "type" | default "note" -}}
+
+ {{ .Inner | markdownify }}
+
diff --git a/themes/minimal-black/layouts/_default/_shortcodes/gallery.html b/themes/minimal-black/layouts/_default/_shortcodes/gallery.html
new file mode 100644
index 0000000..e9ec640
--- /dev/null
+++ b/themes/minimal-black/layouts/_default/_shortcodes/gallery.html
@@ -0,0 +1,35 @@
+{{- $images := split (.Get "images") "," -}}
+{{- $captions := split (default "" (.Get "captions")) "," -}}
+
+
+ {{- if .Inner -}}
+ {{- /* If Inner content is provided, convert markdown images to lightbox-ready anchors */ -}}
+ {{- $content := .Inner -}}
+ {{- $content = replaceRE `!\[([^\]]*)\]\(([^\)]+)\)` `
` $content -}}
+ {{ $content | safeHTML }}
+ {{- else if $images -}}
+ {{- /* Otherwise, generate from images parameter */ -}}
+ {{- range $index, $image := $images -}}
+ {{- $imagePath := trim $image " " -}}
+ {{- $caption := "" -}}
+ {{- if $captions -}}
+ {{- $caption = index $captions $index | default "" | trim " " -}}
+ {{- end -}}
+ {{- if $imagePath -}}
+
+
+
+ {{- end -}}
+ {{- end -}}
+ {{- else -}}
+ {{- /* Fallback: try to get images from page resources */ -}}
+ {{- $resources := .Page.Resources.Match "images/*" -}}
+ {{- if $resources -}}
+ {{- range $resources -}}
+
+
+
+ {{- end -}}
+ {{- end -}}
+ {{- end -}}
+
diff --git a/themes/minimal-black/layouts/_default/about-alternative.html b/themes/minimal-black/layouts/_default/about-alternative.html
new file mode 100644
index 0000000..20f492a
--- /dev/null
+++ b/themes/minimal-black/layouts/_default/about-alternative.html
@@ -0,0 +1,156 @@
+{{ define "main" }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $content := .Content }}
+ {{ $content = replace $content "
" "|||SPLIT|||" }}
+ {{ $content = replace $content " " "|||SPLIT|||" }}
+ {{ $content = replace $content " " "|||SPLIT|||" }}
+ {{ $parts := split $content "|||SPLIT|||" }}
+
+ {{ index $parts 0 | safeHTML }}
+
+
+
+
+ {{ if gt (len $parts) 1 }}
+ {{- $experienceParts := slice -}}
+ {{- $additionalContent := "" -}}
+ {{- $foundNonExperience := false -}}
+
+ {{- range $index, $part := after 1 $parts -}}
+ {{- $trimmed := trim $part " \n\t" -}}
+ {{- if $trimmed -}}
+ {{- /* Check if this looks like an experience card (starts with
) or is additional content (starts with ") (hasPrefix $trimmed "\n
+
+
+ Experience
+
+
+
+ {{- range $experienceParts -}}
+
+ {{ . | safeHTML }}
+
+ {{- end -}}
+
+
+ {{- end -}}
+
+ {{- /* Render additional content sections */ -}}
+ {{- if $additionalContent -}}
+ {{- $additionalParts := split $additionalContent "|||SPLIT|||" -}}
+ {{- range $additionalParts -}}
+ {{- $trimmed := trim . " \n\t" -}}
+ {{- if $trimmed -}}
+
+
+ {{ . | safeHTML }}
+
+
+ {{- end -}}
+ {{- end -}}
+ {{- end -}}
+ {{ end }}
+
+
+ {{ with $.Site.Params.about.alt.skills }}
+
+
+
+ Tech Stack
+
+
+ {{ range . }}
+
+ {{ with .icon }} {{ end }}
+ {{ .label }}
+
+ {{ end }}
+
+
+ {{ end }}
+
+
+
+
+
+{{ end }}
diff --git a/themes/minimal-black/layouts/_default/about.html b/themes/minimal-black/layouts/_default/about.html
new file mode 100644
index 0000000..468010f
--- /dev/null
+++ b/themes/minimal-black/layouts/_default/about.html
@@ -0,0 +1,77 @@
+{{ define "main" }}
+
+
+
+
+
+
+
+
+ {{ $content := .Content }}
+ {{ $content = replace $content "
" "|||SPLIT|||" }}
+ {{ $content = replace $content "
" "|||SPLIT|||" }}
+ {{ $content = replace $content "
" "|||SPLIT|||" }}
+ {{ $parts := split $content "|||SPLIT|||" }}
+
+ {{ if eq (len $parts) 1 }}
+
+ {{ .Content }}
+ {{ else }}
+
+ {{ index $parts 0 | safeHTML }}
+
+
+
+ {{ range after 1 $parts }}
+ {{ $trimmed := trim . " \n\t" }}
+ {{ if $trimmed }}
+
+
+
+ {{ . | safeHTML }}
+
+
+ {{ end }}
+ {{ end }}
+
+ {{ end }}
+
+
+
+
+ {{ with .Site.Params.social }}
+
+ {{ end }}
+
+
+{{ end }}
diff --git a/themes/minimal-black/layouts/_default/baseof.html b/themes/minimal-black/layouts/_default/baseof.html
new file mode 100644
index 0000000..39ebf71
--- /dev/null
+++ b/themes/minimal-black/layouts/_default/baseof.html
@@ -0,0 +1,30 @@
+
+
+
+ {{ partial "head.html" . }}
+
+
+
+ {{ partial "header.html" . }}
+
+
+ {{ block "main" . }}{{ end }}
+
+
+ {{ partial "footer.html" . }}
+
+ {{ partial "search-overlay.html" . }}
+ {{ partial "dock.html" . }}
+
+
+
+
+
+
+
+
diff --git a/themes/minimal-black/layouts/_default/list.html b/themes/minimal-black/layouts/_default/list.html
new file mode 100644
index 0000000..0ddef5f
--- /dev/null
+++ b/themes/minimal-black/layouts/_default/list.html
@@ -0,0 +1,30 @@
+{{ define "main" }}
+
+
+
+ {{ .Title }}
+ {{ with .Description }}
+ {{ . }}
+ {{ end }}
+
+
+
+
+ {{ end }}
+
+
\ No newline at end of file
diff --git a/themes/minimal-black/layouts/_default/single.html b/themes/minimal-black/layouts/_default/single.html
new file mode 100644
index 0000000..7ca425d
--- /dev/null
+++ b/themes/minimal-black/layouts/_default/single.html
@@ -0,0 +1,154 @@
+{{ define "main" }}
+
+
+
+
+
+
+
+
+ {{ if .TableOfContents }}
+
+
+
+
+ {{ .TableOfContents }}
+
+
+
+
+
+ {{ end }}
+
+
+{{ end }}
diff --git a/themes/minimal-black/layouts/blog/list.html b/themes/minimal-black/layouts/blog/list.html
new file mode 100644
index 0000000..35ae38e
--- /dev/null
+++ b/themes/minimal-black/layouts/blog/list.html
@@ -0,0 +1,48 @@
+{{ define "main" }}
+
+
+
+ Blog
+ {{ with .Site.Params.blogIntro }}
+
+ {{ . }}
+
+ {{ else }}
+
+ Notes on engineering, design, and building small, thoughtful tools.
+
+ {{ end }}
+
+
+ {{/* Paginate all posts in this section */}}
+ {{ $paginator := .Paginate .Pages }}
+
+
+ {{ range $paginator.Pages.ByDate.Reverse }}
+ {{ partial "components/post-card.html" (dict "Page" . "Root" $) }}
+ {{ end }}
+
+
+ {{/* Simple pagination controls */}}
+ {{ if gt $paginator.TotalPages 1 }}
+
+ {{ if $paginator.HasPrev }}
+
+ ← Newer posts
+
+ {{ else }}
+
+ {{ end }}
+
+ {{ if $paginator.HasNext }}
+
+ Older posts →
+
+ {{ else }}
+
+ {{ end }}
+
+ {{ end }}
+
+
+{{ end }}
diff --git a/themes/minimal-black/layouts/index.html b/themes/minimal-black/layouts/index.html
new file mode 100644
index 0000000..459e3aa
--- /dev/null
+++ b/themes/minimal-black/layouts/index.html
@@ -0,0 +1,12 @@
+{{ define "main" }}
+
+
+ {{ $default := slice "hero" "now" "tech-marquee" "projects" "posts" }}
+ {{ $sections := .Site.Params.home.sections | default $default }}
+
+ {{ range $sections }}
+ {{ partial (printf "home/%s.html" .) $ }}
+ {{ end }}
+
+
+{{ end }}
diff --git a/themes/minimal-black/layouts/index.json b/themes/minimal-black/layouts/index.json
new file mode 100644
index 0000000..f821f1a
--- /dev/null
+++ b/themes/minimal-black/layouts/index.json
@@ -0,0 +1,17 @@
+{{- $pages := slice -}}
+
+{{- range .Site.RegularPages -}}
+ {{- $summary := .Summary -}}
+ {{- if not $summary -}}
+ {{- $summary = .Description -}}
+ {{- end -}}
+
+ {{- $pages = $pages | append (dict
+ "title" .Title
+ "permalink" .Permalink
+ "section" .Section
+ "summary" (plainify $summary)
+ ) -}}
+{{- end -}}
+
+{{- dict "pages" $pages | jsonify -}}
diff --git a/themes/minimal-black/layouts/index.webappmanifest b/themes/minimal-black/layouts/index.webappmanifest
new file mode 100644
index 0000000..8a48504
--- /dev/null
+++ b/themes/minimal-black/layouts/index.webappmanifest
@@ -0,0 +1,61 @@
+{{- $title := .Site.Title -}}
+{{- $shortName := .Site.Params.brand | default .Site.Title -}}
+{{- $description := .Site.Params.description | default "A minimal, dark-mode first personal site" -}}
+{{- $themeColor := .Site.Params.manifest.themeColor | default "#a855f7" -}}
+{{- $bgColor := .Site.Params.manifest.backgroundColor | default "#000000" -}}
+{{- $lang := .Site.Language.Lang | default "en" -}}
+{
+ "name": "{{ $title }}",
+ "short_name": "{{ $shortName }}",
+ "description": "{{ $description }}",
+ "start_url": "{{ "/" | relURL }}",
+ "scope": "{{ "/" | relURL }}",
+ "display": "standalone",
+ "background_color": "{{ $bgColor }}",
+ "theme_color": "{{ $themeColor }}",
+ "orientation": "portrait-primary",
+ "icons": [
+ {{- if .Site.Params.manifest.icons }}
+ {{- range $i, $icon := .Site.Params.manifest.icons }}
+ {{- if $i }},{{ end }}
+ {
+ "src": "{{ $icon.src | relURL }}",
+ "sizes": "{{ $icon.sizes }}",
+ "type": "{{ $icon.type | default "image/png" }}"
+ {{- with $icon.purpose }},"purpose": "{{ . }}"{{ end }}
+ }
+ {{- end }}
+ {{- else }}
+ {
+ "src": "/icons/android-chrome-192x192.png",
+ "sizes": "192x192",
+ "type": "image/png",
+ "purpose": "any maskable"
+ },
+ {
+ "src": "/icons/android-chrome-512x512.png",
+ "sizes": "512x512",
+ "type": "image/png",
+ "purpose": "any maskable"
+ },
+ {
+ "src": "/icons/apple-touch-icon.png",
+ "sizes": "180x180",
+ "type": "image/png"
+ },
+ {
+ "src": "/icons/favicon-32x32.png",
+ "sizes": "32x32",
+ "type": "image/png"
+ },
+ {
+ "src": "/icons/favicon-16x16.png",
+ "sizes": "16x16",
+ "type": "image/png"
+ }
+ {{- end }}
+ ],
+ "categories": "{{ .Site.Params.manifest.categories | default (slice "blog" "portfolio" "developer") }}",
+ "lang": "{{ $lang }}",
+ "dir": "ltr"
+}
diff --git a/themes/minimal-black/layouts/partials/analytics.html b/themes/minimal-black/layouts/partials/analytics.html
new file mode 100644
index 0000000..a2c5535
--- /dev/null
+++ b/themes/minimal-black/layouts/partials/analytics.html
@@ -0,0 +1,46 @@
+{{- if not hugo.IsServer -}}
+
+
+{{ with .Site.Params.analytics.googleAnalytics }}
+ {{ if . }}
+
+
+ {{ end }}
+{{ end }}
+
+
+{{ with .Site.Params.analytics.plausible }}
+ {{ if .enabled }}
+
+ {{ end }}
+{{ end }}
+
+
+{{ with .Site.Params.analytics.umami }}
+ {{ if .enabled }}
+
+ {{ end }}
+{{ end }}
+
+
+{{ with .Site.Params.analytics.fathom }}
+ {{ if .enabled }}
+
+ {{ end }}
+{{ end }}
+
+
+{{ with .Site.Params.analytics.custom }}
+ {{ if .head }}
+ {{ range .head }}
+ {{ . | safeHTML }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+
+{{- end -}}
diff --git a/themes/minimal-black/layouts/partials/components/post-card.html b/themes/minimal-black/layouts/partials/components/post-card.html
new file mode 100644
index 0000000..587558e
--- /dev/null
+++ b/themes/minimal-black/layouts/partials/components/post-card.html
@@ -0,0 +1,53 @@
+{{/* props: Page (post page) */}}
+{{- $p := .Page -}}
+{{- $icon := $p.Params.icon | default "fa-regular fa-file-lines" -}}
+{{- $category := $p.Params.category | default "Article" -}}
+
+
+
+
+
+ {{ with $p.Params.description }}
+
+ {{ . }}
+
+ {{ end }}
+
+ {{ with $p.Params.tags }}
+
+ {{ range first 3 . }}
+ {{ . }}
+ {{ end }}
+
+ {{ end }}
+
+
diff --git a/themes/minimal-black/layouts/partials/components/project-card.html b/themes/minimal-black/layouts/partials/components/project-card.html
new file mode 100644
index 0000000..ba40a4d
--- /dev/null
+++ b/themes/minimal-black/layouts/partials/components/project-card.html
@@ -0,0 +1,87 @@
+{{/* props: Page (project page) */}}
+{{- $p := .Page -}}
+
+{{- $icon := $p.Params.icon | default "fa-solid fa-folder-tree" -}}
+{{- $badge := cond ($p.Params.featured) "Featured" "" -}}
+
+{{- $repo := $p.Params.repo -}}
+{{- $repoIcon := $p.Params.repoIcon | default "fa-brands fa-github" -}}
+{{- $repoLabel := $p.Params.repoLabel | default "Repo" -}}
+
+{{- $demo := $p.Params.demo -}}
+{{- $demoIcon := $p.Params.demoIcon | default "fa-solid fa-play" -}}
+{{- $demoLabel := $p.Params.demoLabel | default "Demo" -}}
+
+{{- $website := $p.Params.website -}}
+{{- $websiteIcon := $p.Params.websiteIcon | default "fa-solid fa-globe" -}}
+{{- $websiteLabel := $p.Params.websiteLabel | default "Website" -}}
+
+
+
+
+
+
+ {{ with $p.Params.description }}
+
+ {{ . }}
+
+ {{ end }}
+
+ {{ with $p.Params.stack }}
+
+ {{ range . }}
+ {{ . }}
+ {{ end }}
+
+ {{ end }}
+
+
+
+
+
diff --git a/themes/minimal-black/layouts/partials/components/section-header.html b/themes/minimal-black/layouts/partials/components/section-header.html
new file mode 100644
index 0000000..18dac2e
--- /dev/null
+++ b/themes/minimal-black/layouts/partials/components/section-header.html
@@ -0,0 +1,12 @@
+{{/* props: Title, Url, Small (bool) */}} {{- $title := .Title | default
+"Section" -}} {{- $url := .Url -}} {{- $small := .Small | default false -}}
+
+
diff --git a/themes/minimal-black/layouts/partials/dark-toggle.html b/themes/minimal-black/layouts/partials/dark-toggle.html
new file mode 100644
index 0000000..25cb113
--- /dev/null
+++ b/themes/minimal-black/layouts/partials/dark-toggle.html
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/themes/minimal-black/layouts/partials/dock.html b/themes/minimal-black/layouts/partials/dock.html
new file mode 100644
index 0000000..98abf40
--- /dev/null
+++ b/themes/minimal-black/layouts/partials/dock.html
@@ -0,0 +1,55 @@
+{{- $isHome := .IsHome -}}
+
+
+
+
+
+ {{ if not $isHome }}
+
+
+
+
+
+ {{ end }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/themes/minimal-black/layouts/partials/footer.html b/themes/minimal-black/layouts/partials/footer.html
new file mode 100644
index 0000000..777202f
--- /dev/null
+++ b/themes/minimal-black/layouts/partials/footer.html
@@ -0,0 +1,56 @@
+
diff --git a/themes/minimal-black/layouts/partials/head.html b/themes/minimal-black/layouts/partials/head.html
new file mode 100644
index 0000000..d19a90c
--- /dev/null
+++ b/themes/minimal-black/layouts/partials/head.html
@@ -0,0 +1,103 @@
+{{- $title := cond (ne .Title "") (printf "%s | %s" .Title .Site.Title)
+.Site.Title -}}
+
+
+
+{{ $title }}
+
+{{ partial "meta.html" . }}
+
+
+{{ with .Site.Params.favicon }}
+
+{{ else }}
+
+ {{ if fileExists "static/favicon.ico" }}
+
+ {{ end }}
+ {{ if fileExists "static/favicon.png" }}
+
+ {{ end }}
+ {{ if fileExists "static/favicon.svg" }}
+
+ {{ end }}
+{{ end }}
+
+
+{{ if .Site.Params.appleTouchIcon }}
+
+{{ else if fileExists "static/apple-touch-icon.png" }}
+
+{{ end }}
+
+
+{{ with .Site.GetPage "/" }}
+ {{ range .OutputFormats }}
+ {{ if eq .Name "webappmanifest" }}
+
+ {{ end }}
+ {{ end }}
+{{ end }}
+
+
+
+{{ if .Site.Params.icons.useFontAwesome }}
+
+{{ end }}
+
+{{ if .Site.Params.icons.useDevicon }}
+
+{{ end }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+{{ partial "analytics.html" . }}
diff --git a/themes/minimal-black/layouts/partials/header.html b/themes/minimal-black/layouts/partials/header.html
new file mode 100644
index 0000000..aa368f6
--- /dev/null
+++ b/themes/minimal-black/layouts/partials/header.html
@@ -0,0 +1,86 @@
+
+ {{/* Brand string for logo/monogram */}}
+ {{- $brand := .Site.Params.brand | default .Site.Title}}
+ {{- $mono := upper (substr $brand 0 2) -}}
+
+
+
+
+
+
diff --git a/themes/minimal-black/layouts/partials/home/hero.html b/themes/minimal-black/layouts/partials/home/hero.html
new file mode 100644
index 0000000..155360f
--- /dev/null
+++ b/themes/minimal-black/layouts/partials/home/hero.html
@@ -0,0 +1,94 @@
+{{- $hero := .Site.Params.hero -}}
+
+
+
+
+
+ {{ with $hero.badge }}
+
{{ . }}
+ {{ end }}
+
+ {{ if $hero.available }}
+
+
+ {{ default "Available for work" $hero.availableLabel }}
+
+ {{ end }}
+
+
+
+
+ {{ default "Hi, I’m Your Name." $hero.title }}
+
+ {{ with $hero.role }}
+
+ {{ . }}
+
+ {{ end }}
+
+
+ {{ with $hero.summary }}
+
+ {{ . }}
+
+ {{ end }}
+
+
+
+ {{ with $hero.location }}
+
+
+ {{ . }}
+
+ {{ end }}
+
+ {{ with $hero.focus }}
+
+
+ {{ . }}
+
+ {{ end }}
+
+
+
+ {{ with $hero.highlights }}
+
+ {{ range . }}
+
+ {{ .label }}
+
+ {{ end }}
+
+ {{ end }}
+
+
+
+
+
+
+ {{ with $hero.avatar }}
+
+
+
+
+
+
+
+ {{ end }}
+
diff --git a/themes/minimal-black/layouts/partials/home/now.html b/themes/minimal-black/layouts/partials/home/now.html
new file mode 100644
index 0000000..2aa3809
--- /dev/null
+++ b/themes/minimal-black/layouts/partials/home/now.html
@@ -0,0 +1,28 @@
+{{- $hero := .Site.Params.hero -}}
+{{- $home := .Site.Params.home -}}
+
+{{ if $home.showNowSection }}
+
+
+
{{ default "Now" $hero.nowLabel }}
+
+ {{ with $hero.nowIntro }}
+
{{ . }}
+ {{ end }}
+
+ {{ with $hero.now }}
+
+ {{ range . }}
+ {{ . }}
+ {{ end }}
+
+ {{ else }}
+
+ Add a hero.now list in your config to describe what you’re
+ focused on right now.
+
+ {{ end }}
+
+
+
+{{ end }}
diff --git a/themes/minimal-black/layouts/partials/home/posts.html b/themes/minimal-black/layouts/partials/home/posts.html
new file mode 100644
index 0000000..1c3b35c
--- /dev/null
+++ b/themes/minimal-black/layouts/partials/home/posts.html
@@ -0,0 +1,38 @@
+{{- $home := .Site.Params.home -}}
+{{ if ne $home.showLatestPosts false }}
+
+
+
+ {{ default "Latest writing" $home.blogTitle }}
+
+ {{ with $home.blogSubtitle }}
+
+ {{ . }}
+
+ {{ end }}
+
+
+ {{ $limit := cond (gt (int $home.latestPostsLimit) 0) (int $home.latestPostsLimit) 3 }}
+ {{ $posts := first $limit (where .Site.RegularPages "Section" "blog") }}
+
+
+ {{ range $posts }}
+ {{ partial "components/post-card.html" (dict "Page" . "Root" $) }}
+ {{ else }}
+
+ No posts yet. Add some under content/blog.
+
+ {{ end }}
+
+
+
+
+{{ end }}
diff --git a/themes/minimal-black/layouts/partials/home/projects.html b/themes/minimal-black/layouts/partials/home/projects.html
new file mode 100644
index 0000000..bb3e5b7
--- /dev/null
+++ b/themes/minimal-black/layouts/partials/home/projects.html
@@ -0,0 +1,43 @@
+{{- $home := .Site.Params.home -}}
+{{ if ne $home.showFeaturedProjects false }}
+
+
+
+ {{ default "Selected work" $home.projectsTitle }}
+
+ {{ with $home.projectsSubtitle }}
+
+ {{ . }}
+
+ {{ end }}
+
+
+ {{ $limit := cond (gt (int $home.featuredProjectsLimit) 0) (int $home.featuredProjectsLimit) 3 }}
+ {{ $allProjects := where .Site.RegularPages "Section" "projects" }}
+ {{ $featured := where $allProjects "Params.featured" true }}
+ {{ if not (gt (len $featured) 0) }}
+ {{ $featured = $allProjects }}
+ {{ end }}
+ {{ $list := first $limit $featured }}
+
+
+ {{ range $list }}
+ {{ partial "components/project-card.html" (dict "Page" . "Root" $) }}
+ {{ else }}
+
+ No projects yet. Add some under content/projects.
+
+ {{ end }}
+
+
+
+
+{{ end }}
diff --git a/themes/minimal-black/layouts/partials/home/tech-marquee.html b/themes/minimal-black/layouts/partials/home/tech-marquee.html
new file mode 100644
index 0000000..588ee82
--- /dev/null
+++ b/themes/minimal-black/layouts/partials/home/tech-marquee.html
@@ -0,0 +1,59 @@
+{{- $home := .Site.Params.home -}}
+{{- $hero := .Site.Params.hero -}}
+{{- $techMain := $home.tech -}}
+{{- $techReverse := $home.techReverse -}}
+{{- $variant := $home.techVariant | default "wide" -}}
+
+{{ with $techMain }}
+
+
+
+ {{ default "What I Work With" $hero.techMarqueeLabel }}
+
+
+
+
+
+ {{ range . }}
+
+ {{ with .icon }}
+
+ {{ end }}
+ {{ .label }}
+
+ {{ end }}
+ {{ range . }}
+
+ {{ with .icon }}
+
+ {{ end }}
+ {{ .label }}
+
+ {{ end }}
+
+
+
+ {{ with $techReverse }}
+
+ {{ range . }}
+
+ {{ with .icon }}
+
+ {{ end }}
+ {{ .label }}
+
+ {{ end }}
+ {{ range . }}
+
+ {{ with .icon }}
+
+ {{ end }}
+ {{ .label }}
+
+ {{ end }}
+
+ {{ end }}
+
+
+
+{{ end }}
diff --git a/themes/minimal-black/layouts/partials/meta.html b/themes/minimal-black/layouts/partials/meta.html
new file mode 100644
index 0000000..bd9813b
--- /dev/null
+++ b/themes/minimal-black/layouts/partials/meta.html
@@ -0,0 +1,7 @@
+{{- with .Description -}}
+
+{{- else -}}
+
+{{- end }} {{- with .Site.Params.author }}
+
+{{- end }}
diff --git a/themes/minimal-black/layouts/partials/search-overlay.html b/themes/minimal-black/layouts/partials/search-overlay.html
new file mode 100644
index 0000000..89c673a
--- /dev/null
+++ b/themes/minimal-black/layouts/partials/search-overlay.html
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
Start searching
+
+ Enter keywords to search articles.
+
+
+
+
+
+
+
+
diff --git a/themes/minimal-black/layouts/projects/list.html b/themes/minimal-black/layouts/projects/list.html
new file mode 100644
index 0000000..5fb2d97
--- /dev/null
+++ b/themes/minimal-black/layouts/projects/list.html
@@ -0,0 +1,50 @@
+{{ define "main" }}
+
+
+
+
+
+ {{/* you can tweak sorting if you want; this is newest first */}}
+ {{ $paginator := .Paginate (.Pages.ByDate.Reverse) }}
+
+
+ {{ range $paginator.Pages }}
+ {{ partial "components/project-card.html" (dict "Page" . "Root" $) }}
+ {{ end }}
+
+
+
+ {{ if gt $paginator.TotalPages 1 }}
+
+ {{ if $paginator.HasPrev }}
+
+ ← Newer projects
+
+ {{ else }}
+
+ {{ end }}
+
+ {{ if $paginator.HasNext }}
+
+ Older projects →
+
+ {{ else }}
+
+ {{ end }}
+
+ {{ end }}
+
+
+{{ end }}
diff --git a/themes/minimal-black/netlify.toml b/themes/minimal-black/netlify.toml
new file mode 100644
index 0000000..82a6db3
--- /dev/null
+++ b/themes/minimal-black/netlify.toml
@@ -0,0 +1,29 @@
+[build]
+ publish = "public"
+ command = "mkdir -p hugo-minimal-black && rsync -av --exclude='hugo-minimal-black' --exclude='.git' --exclude='public' . ./hugo-minimal-black/ && cd hugo-minimal-black/exampleSite && hugo --gc --minify --themesDir ../.. --theme hugo-minimal-black && mv public ../../public"
+
+[build.environment]
+ HUGO_VERSION = "0.152.2"
+ HUGO_ENV = "production"
+ HUGO_ENABLEGITINFO = "true"
+
+[context.production.environment]
+ HUGO_VERSION = "0.152.2"
+ HUGO_ENV = "production"
+
+[context.deploy-preview]
+ command = "mkdir -p hugo-minimal-black && rsync -av --exclude='hugo-minimal-black' --exclude='.git' --exclude='public' . ./hugo-minimal-black/ && cd hugo-minimal-black/exampleSite && hugo --gc --minify --buildFuture --themesDir ../.. --theme hugo-minimal-black && mv public ../../public"
+
+[context.deploy-preview.environment]
+ HUGO_VERSION = "0.152.2"
+
+[context.branch-deploy]
+ command = "mkdir -p hugo-minimal-black && rsync -av --exclude='hugo-minimal-black' --exclude='.git' --exclude='public' . ./hugo-minimal-black/ && cd hugo-minimal-black/exampleSite && hugo --themesDir ../.. --theme hugo-minimal-black && mv public ../../public"
+
+[context.branch-deploy.environment]
+ HUGO_VERSION = "0.152.2"
+
+[[redirects]]
+ from = "/*"
+ to = "/404.html"
+ status = 404
diff --git a/themes/minimal-black/package.json b/themes/minimal-black/package.json
new file mode 100644
index 0000000..90293f5
--- /dev/null
+++ b/themes/minimal-black/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "minimal-black",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "Jim Christopoulos",
+ "license": "ISC",
+ "type": "commonjs",
+ "devDependencies": {
+ "@tailwindcss/typography": "^0.5.19",
+ "autoprefixer": "^10.4.22",
+ "postcss": "^8.5.6",
+ "tailwindcss": "^3.4.18"
+ }
+}
diff --git a/themes/minimal-black/postcss.config.js b/themes/minimal-black/postcss.config.js
new file mode 100644
index 0000000..12a703d
--- /dev/null
+++ b/themes/minimal-black/postcss.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+};
diff --git a/themes/minimal-black/static/css/main.css b/themes/minimal-black/static/css/main.css
new file mode 100644
index 0000000..e6f9ff4
--- /dev/null
+++ b/themes/minimal-black/static/css/main.css
@@ -0,0 +1,5434 @@
+/* ==========================================================================
+ MINIMAL BLACK THEME - MAIN STYLESHEET
+ A minimal, dark-mode first Hugo theme
+ ========================================================================== */
+
+/* Base Styles & Tailwind */
+
+/* ==========================================================================
+ BASE STYLES
+ Tailwind imports, CSS variables, theme colors, and base styles
+ ========================================================================== */
+
+*, ::before, ::after {
+ --tw-border-spacing-x: 0;
+ --tw-border-spacing-y: 0;
+ --tw-translate-x: 0;
+ --tw-translate-y: 0;
+ --tw-rotate: 0;
+ --tw-skew-x: 0;
+ --tw-skew-y: 0;
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ --tw-pan-x: ;
+ --tw-pan-y: ;
+ --tw-pinch-zoom: ;
+ --tw-scroll-snap-strictness: proximity;
+ --tw-gradient-from-position: ;
+ --tw-gradient-via-position: ;
+ --tw-gradient-to-position: ;
+ --tw-ordinal: ;
+ --tw-slashed-zero: ;
+ --tw-numeric-figure: ;
+ --tw-numeric-spacing: ;
+ --tw-numeric-fraction: ;
+ --tw-ring-inset: ;
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: rgb(59 130 246 / 0.5);
+ --tw-ring-offset-shadow: 0 0 #0000;
+ --tw-ring-shadow: 0 0 #0000;
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ --tw-blur: ;
+ --tw-brightness: ;
+ --tw-contrast: ;
+ --tw-grayscale: ;
+ --tw-hue-rotate: ;
+ --tw-invert: ;
+ --tw-saturate: ;
+ --tw-sepia: ;
+ --tw-drop-shadow: ;
+ --tw-backdrop-blur: ;
+ --tw-backdrop-brightness: ;
+ --tw-backdrop-contrast: ;
+ --tw-backdrop-grayscale: ;
+ --tw-backdrop-hue-rotate: ;
+ --tw-backdrop-invert: ;
+ --tw-backdrop-opacity: ;
+ --tw-backdrop-saturate: ;
+ --tw-backdrop-sepia: ;
+ --tw-contain-size: ;
+ --tw-contain-layout: ;
+ --tw-contain-paint: ;
+ --tw-contain-style: ;
+}
+
+::backdrop {
+ --tw-border-spacing-x: 0;
+ --tw-border-spacing-y: 0;
+ --tw-translate-x: 0;
+ --tw-translate-y: 0;
+ --tw-rotate: 0;
+ --tw-skew-x: 0;
+ --tw-skew-y: 0;
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ --tw-pan-x: ;
+ --tw-pan-y: ;
+ --tw-pinch-zoom: ;
+ --tw-scroll-snap-strictness: proximity;
+ --tw-gradient-from-position: ;
+ --tw-gradient-via-position: ;
+ --tw-gradient-to-position: ;
+ --tw-ordinal: ;
+ --tw-slashed-zero: ;
+ --tw-numeric-figure: ;
+ --tw-numeric-spacing: ;
+ --tw-numeric-fraction: ;
+ --tw-ring-inset: ;
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: rgb(59 130 246 / 0.5);
+ --tw-ring-offset-shadow: 0 0 #0000;
+ --tw-ring-shadow: 0 0 #0000;
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ --tw-blur: ;
+ --tw-brightness: ;
+ --tw-contrast: ;
+ --tw-grayscale: ;
+ --tw-hue-rotate: ;
+ --tw-invert: ;
+ --tw-saturate: ;
+ --tw-sepia: ;
+ --tw-drop-shadow: ;
+ --tw-backdrop-blur: ;
+ --tw-backdrop-brightness: ;
+ --tw-backdrop-contrast: ;
+ --tw-backdrop-grayscale: ;
+ --tw-backdrop-hue-rotate: ;
+ --tw-backdrop-invert: ;
+ --tw-backdrop-opacity: ;
+ --tw-backdrop-saturate: ;
+ --tw-backdrop-sepia: ;
+ --tw-contain-size: ;
+ --tw-contain-layout: ;
+ --tw-contain-paint: ;
+ --tw-contain-style: ;
+}
+
+/* ! tailwindcss v3.4.18 | MIT License | https://tailwindcss.com */
+
+/*
+1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
+2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
+*/
+
+*,
+::before,
+::after {
+ box-sizing: border-box;
+ /* 1 */
+ border-width: 0;
+ /* 2 */
+ border-style: solid;
+ /* 2 */
+ border-color: #e5e7eb;
+ /* 2 */
+}
+
+::before,
+::after {
+ --tw-content: '';
+}
+
+/*
+1. Use a consistent sensible line-height in all browsers.
+2. Prevent adjustments of font size after orientation changes in iOS.
+3. Use a more readable tab size.
+4. Use the user's configured `sans` font-family by default.
+5. Use the user's configured `sans` font-feature-settings by default.
+6. Use the user's configured `sans` font-variation-settings by default.
+7. Disable tap highlights on iOS
+*/
+
+html,
+:host {
+ line-height: 1.5;
+ /* 1 */
+ -webkit-text-size-adjust: 100%;
+ /* 2 */
+ -moz-tab-size: 4;
+ /* 3 */
+ -o-tab-size: 4;
+ tab-size: 4;
+ /* 3 */
+ font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ /* 4 */
+ font-feature-settings: normal;
+ /* 5 */
+ font-variation-settings: normal;
+ /* 6 */
+ -webkit-tap-highlight-color: transparent;
+ /* 7 */
+}
+
+/*
+1. Remove the margin in all browsers.
+2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
+*/
+
+body {
+ margin: 0;
+ /* 1 */
+ line-height: inherit;
+ /* 2 */
+}
+
+/*
+1. Add the correct height in Firefox.
+2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
+3. Ensure horizontal rules are visible by default.
+*/
+
+hr {
+ height: 0;
+ /* 1 */
+ color: inherit;
+ /* 2 */
+ border-top-width: 1px;
+ /* 3 */
+}
+
+/*
+Add the correct text decoration in Chrome, Edge, and Safari.
+*/
+
+abbr:where([title]) {
+ -webkit-text-decoration: underline dotted;
+ text-decoration: underline dotted;
+}
+
+/*
+Remove the default font size and weight for headings.
+*/
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ font-size: inherit;
+ font-weight: inherit;
+}
+
+/*
+Reset links to optimize for opt-in styling instead of opt-out.
+*/
+
+a {
+ color: inherit;
+ text-decoration: inherit;
+}
+
+/*
+Add the correct font weight in Edge and Safari.
+*/
+
+b,
+strong {
+ font-weight: bolder;
+}
+
+/*
+1. Use the user's configured `mono` font-family by default.
+2. Use the user's configured `mono` font-feature-settings by default.
+3. Use the user's configured `mono` font-variation-settings by default.
+4. Correct the odd `em` font sizing in all browsers.
+*/
+
+code,
+kbd,
+samp,
+pre {
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+ /* 1 */
+ font-feature-settings: normal;
+ /* 2 */
+ font-variation-settings: normal;
+ /* 3 */
+ font-size: 1em;
+ /* 4 */
+}
+
+/*
+Add the correct font size in all browsers.
+*/
+
+small {
+ font-size: 80%;
+}
+
+/*
+Prevent `sub` and `sup` elements from affecting the line height in all browsers.
+*/
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+/*
+1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
+2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
+3. Remove gaps between table borders by default.
+*/
+
+table {
+ text-indent: 0;
+ /* 1 */
+ border-color: inherit;
+ /* 2 */
+ border-collapse: collapse;
+ /* 3 */
+}
+
+/*
+1. Change the font styles in all browsers.
+2. Remove the margin in Firefox and Safari.
+3. Remove default padding in all browsers.
+*/
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ font-family: inherit;
+ /* 1 */
+ font-feature-settings: inherit;
+ /* 1 */
+ font-variation-settings: inherit;
+ /* 1 */
+ font-size: 100%;
+ /* 1 */
+ font-weight: inherit;
+ /* 1 */
+ line-height: inherit;
+ /* 1 */
+ letter-spacing: inherit;
+ /* 1 */
+ color: inherit;
+ /* 1 */
+ margin: 0;
+ /* 2 */
+ padding: 0;
+ /* 3 */
+}
+
+/*
+Remove the inheritance of text transform in Edge and Firefox.
+*/
+
+button,
+select {
+ text-transform: none;
+}
+
+/*
+1. Correct the inability to style clickable types in iOS and Safari.
+2. Remove default button styles.
+*/
+
+button,
+input:where([type='button']),
+input:where([type='reset']),
+input:where([type='submit']) {
+ -webkit-appearance: button;
+ /* 1 */
+ background-color: transparent;
+ /* 2 */
+ background-image: none;
+ /* 2 */
+}
+
+/*
+Use the modern Firefox focus style for all focusable elements.
+*/
+
+:-moz-focusring {
+ outline: auto;
+}
+
+/*
+Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
+*/
+
+:-moz-ui-invalid {
+ box-shadow: none;
+}
+
+/*
+Add the correct vertical alignment in Chrome and Firefox.
+*/
+
+progress {
+ vertical-align: baseline;
+}
+
+/*
+Correct the cursor style of increment and decrement buttons in Safari.
+*/
+
+::-webkit-inner-spin-button,
+::-webkit-outer-spin-button {
+ height: auto;
+}
+
+/*
+1. Correct the odd appearance in Chrome and Safari.
+2. Correct the outline style in Safari.
+*/
+
+[type='search'] {
+ -webkit-appearance: textfield;
+ /* 1 */
+ outline-offset: -2px;
+ /* 2 */
+}
+
+/*
+Remove the inner padding in Chrome and Safari on macOS.
+*/
+
+::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/*
+1. Correct the inability to style clickable types in iOS and Safari.
+2. Change font properties to `inherit` in Safari.
+*/
+
+::-webkit-file-upload-button {
+ -webkit-appearance: button;
+ /* 1 */
+ font: inherit;
+ /* 2 */
+}
+
+/*
+Add the correct display in Chrome and Safari.
+*/
+
+summary {
+ display: list-item;
+}
+
+/*
+Removes the default spacing and border for appropriate elements.
+*/
+
+blockquote,
+dl,
+dd,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+hr,
+figure,
+p,
+pre {
+ margin: 0;
+}
+
+fieldset {
+ margin: 0;
+ padding: 0;
+}
+
+legend {
+ padding: 0;
+}
+
+ol,
+ul,
+menu {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+/*
+Reset default styling for dialogs.
+*/
+
+dialog {
+ padding: 0;
+}
+
+/*
+Prevent resizing textareas horizontally by default.
+*/
+
+textarea {
+ resize: vertical;
+}
+
+/*
+1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
+2. Set the default placeholder color to the user's configured gray 400 color.
+*/
+
+input::-moz-placeholder, textarea::-moz-placeholder {
+ opacity: 1;
+ /* 1 */
+ color: #9ca3af;
+ /* 2 */
+}
+
+input::placeholder,
+textarea::placeholder {
+ opacity: 1;
+ /* 1 */
+ color: #9ca3af;
+ /* 2 */
+}
+
+/*
+Set the default cursor for buttons.
+*/
+
+button,
+[role="button"] {
+ cursor: pointer;
+}
+
+/*
+Make sure disabled buttons don't get the pointer cursor.
+*/
+
+:disabled {
+ cursor: default;
+}
+
+/*
+1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
+2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
+ This can trigger a poorly considered lint error in some tools but is included by design.
+*/
+
+img,
+svg,
+video,
+canvas,
+audio,
+iframe,
+embed,
+object {
+ display: block;
+ /* 1 */
+ vertical-align: middle;
+ /* 2 */
+}
+
+/*
+Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
+*/
+
+img,
+video {
+ max-width: 100%;
+ height: auto;
+}
+
+/* Make elements with the HTML hidden attribute stay hidden by default */
+
+[hidden]:where(:not([hidden="until-found"])) {
+ display: none;
+}
+
+.container {
+ width: 100%;
+}
+
+@media (min-width: 640px) {
+ .container {
+ max-width: 640px;
+ }
+}
+
+@media (min-width: 768px) {
+ .container {
+ max-width: 768px;
+ }
+}
+
+@media (min-width: 1024px) {
+ .container {
+ max-width: 1024px;
+ }
+}
+
+@media (min-width: 1280px) {
+ .container {
+ max-width: 1280px;
+ }
+}
+
+@media (min-width: 1536px) {
+ .container {
+ max-width: 1536px;
+ }
+}
+
+.dock {
+ position: fixed;
+ right: 1.5rem;
+ bottom: 1.6rem;
+ z-index: 50;
+}
+
+.dock-inner {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.45rem;
+ padding: 0.3rem 0.5rem;
+ border-radius: 9999px;
+ /* border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-surface) 92%, transparent);
+ box-shadow: 0 14px 40px rgba(0, 0, 0, 0.55); */
+ backdrop-filter: blur(16px);
+}
+
+.dock-panel {
+ padding: 0.25rem;
+ display: inline-flex;
+ align-items: center;
+ gap: 0.35rem;
+ max-width: 0;
+ opacity: 0;
+ transform: translateX(6px);
+ overflow: hidden;
+ transition: max-width 0.18s ease-out, opacity 0.18s ease-out,
+ transform 0.18s ease-out;
+}
+
+.dock--open .dock-panel {
+ max-width: 10rem;
+ opacity: 1;
+ transform: translateX(0);
+}
+
+.dock-divider {
+ width: 1px;
+ height: 1.4rem;
+ background: linear-gradient(
+ to bottom,
+ transparent,
+ color-mix(in srgb, var(--color-border) 80%, transparent),
+ transparent
+ );
+}
+
+.dock-action {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 2rem;
+ height: 2rem;
+ border-radius: 9999px;
+ border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-bg) 75%, transparent);
+ color: var(--color-text-muted);
+ cursor: pointer;
+ transition: background-color 0.16s ease-out, border-color 0.16s ease-out,
+ color 0.16s ease-out, transform 0.16s ease-out, box-shadow 0.16s ease-out;
+}
+
+.dock-action:hover {
+ border-color: var(--color-accent);
+ color: var(--color-accent);
+ transform: translateY(-1px);
+ /* box-shadow: 0 8px 26px rgba(0, 0, 0, 0.55); */
+}
+
+.dock-toggle {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 2.1rem;
+ height: 2.1rem;
+ border-radius: 9999px;
+ border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-bg) 85%, transparent);
+ color: var(--color-text-muted);
+ cursor: pointer;
+ transition: background-color 0.16s ease-out, border-color 0.16s ease-out,
+ transform 0.16s ease-out, box-shadow 0.16s ease-out;
+}
+
+.dock-toggle:hover {
+ border-color: var(--color-accent);
+ color: var(--color-accent);
+ transform: translateY(-1px);
+ box-shadow: 0 10px 24px rgba(0, 0, 0, 0.5);
+}
+
+.dock-toggle-dots {
+ position: relative;
+ display: inline-block;
+ width: 0.8rem;
+ height: 0.16rem;
+ border-radius: 999px;
+ background-color: var(--color-text-muted);
+}
+
+.dock-toggle-dots::before,
+ .dock-toggle-dots::after {
+ content: "";
+ position: absolute;
+ inset-y: 0;
+ width: 0.16rem;
+ border-radius: 999px;
+ background-color: var(--color-text-muted);
+}
+
+.dock-toggle-dots::before {
+ left: -0.18rem;
+}
+
+.dock-toggle-dots::after {
+ right: -0.18rem;
+}
+
+.dock--open .dock-toggle-dots,
+ .dock--open .dock-toggle-dots::before,
+ .dock--open .dock-toggle-dots::after {
+ background-color: var(--color-accent);
+}
+
+.btn-primary-sm {
+ font-size: 0.75rem;
+ padding: 0.35rem 0.9rem;
+ border-radius: 999px;
+}
+
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ white-space: nowrap;
+ border-width: 0;
+}
+
+.visible {
+ visibility: visible;
+}
+
+.invisible {
+ visibility: hidden;
+}
+
+.collapse {
+ visibility: collapse;
+}
+
+.static {
+ position: static;
+}
+
+.fixed {
+ position: fixed;
+}
+
+.absolute {
+ position: absolute;
+}
+
+.sticky {
+ position: sticky;
+}
+
+.order-first {
+ order: -9999;
+}
+
+.mx-auto {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.mb-2 {
+ margin-bottom: 0.5rem;
+}
+
+.mb-8 {
+ margin-bottom: 2rem;
+}
+
+.ml-1 {
+ margin-left: 0.25rem;
+}
+
+.mt-0\.5 {
+ margin-top: 0.125rem;
+}
+
+.mt-1 {
+ margin-top: 0.25rem;
+}
+
+.mt-2 {
+ margin-top: 0.5rem;
+}
+
+.mt-3 {
+ margin-top: 0.75rem;
+}
+
+.mt-4 {
+ margin-top: 1rem;
+}
+
+.mt-6 {
+ margin-top: 1.5rem;
+}
+
+.block {
+ display: block;
+}
+
+.inline {
+ display: inline;
+}
+
+.flex {
+ display: flex;
+}
+
+.inline-flex {
+ display: inline-flex;
+}
+
+.table {
+ display: table;
+}
+
+.grid {
+ display: grid;
+}
+
+.contents {
+ display: contents;
+}
+
+.hidden {
+ display: none;
+}
+
+.h-1\.5 {
+ height: 0.375rem;
+}
+
+.h-24 {
+ height: 6rem;
+}
+
+.h-4 {
+ height: 1rem;
+}
+
+.h-8 {
+ height: 2rem;
+}
+
+.h-full {
+ height: 100%;
+}
+
+.min-h-screen {
+ min-height: 100vh;
+}
+
+.w-1\.5 {
+ width: 0.375rem;
+}
+
+.w-24 {
+ width: 6rem;
+}
+
+.w-4 {
+ width: 1rem;
+}
+
+.w-8 {
+ width: 2rem;
+}
+
+.w-full {
+ width: 100%;
+}
+
+.min-w-0 {
+ min-width: 0px;
+}
+
+.max-w-7xl {
+ max-width: 80rem;
+}
+
+.max-w-xl {
+ max-width: 36rem;
+}
+
+.flex-1 {
+ flex: 1 1 0%;
+}
+
+.flex-shrink {
+ flex-shrink: 1;
+}
+
+.transform {
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.list-disc {
+ list-style-type: disc;
+}
+
+.flex-col {
+ flex-direction: column;
+}
+
+.flex-wrap {
+ flex-wrap: wrap;
+}
+
+.items-start {
+ align-items: flex-start;
+}
+
+.items-center {
+ align-items: center;
+}
+
+.items-baseline {
+ align-items: baseline;
+}
+
+.justify-end {
+ justify-content: flex-end;
+}
+
+.justify-center {
+ justify-content: center;
+}
+
+.justify-between {
+ justify-content: space-between;
+}
+
+.gap-1 {
+ gap: 0.25rem;
+}
+
+.gap-1\.5 {
+ gap: 0.375rem;
+}
+
+.gap-2 {
+ gap: 0.5rem;
+}
+
+.gap-3 {
+ gap: 0.75rem;
+}
+
+.gap-4 {
+ gap: 1rem;
+}
+
+.gap-5 {
+ gap: 1.25rem;
+}
+
+.gap-8 {
+ gap: 2rem;
+}
+
+.space-y-1 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));
+}
+
+.space-y-2 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
+}
+
+.space-y-3 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(0.75rem * var(--tw-space-y-reverse));
+}
+
+.space-y-4 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(1rem * var(--tw-space-y-reverse));
+}
+
+.space-y-5 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(1.25rem * var(--tw-space-y-reverse));
+}
+
+.space-y-6 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
+}
+
+.overflow-hidden {
+ overflow: hidden;
+}
+
+.truncate {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.rounded-2xl {
+ border-radius: 1rem;
+}
+
+.rounded-full {
+ border-radius: 9999px;
+}
+
+.border {
+ border-width: 1px;
+}
+
+.border-b {
+ border-bottom-width: 1px;
+}
+
+.border-border {
+ border-color: var(--color-border);
+}
+
+.bg-bg {
+ background-color: var(--color-bg);
+}
+
+.bg-surface {
+ background-color: var(--color-surface);
+}
+
+.bg-white\/95 {
+ background-color: rgb(255 255 255 / 0.95);
+}
+
+.object-cover {
+ -o-object-fit: cover;
+ object-fit: cover;
+}
+
+.p-2 {
+ padding: 0.5rem;
+}
+
+.px-3 {
+ padding-left: 0.75rem;
+ padding-right: 0.75rem;
+}
+
+.px-4 {
+ padding-left: 1rem;
+ padding-right: 1rem;
+}
+
+.py-1 {
+ padding-top: 0.25rem;
+ padding-bottom: 0.25rem;
+}
+
+.py-1\.5 {
+ padding-top: 0.375rem;
+ padding-bottom: 0.375rem;
+}
+
+.py-3 {
+ padding-top: 0.75rem;
+ padding-bottom: 0.75rem;
+}
+
+.pb-6 {
+ padding-bottom: 1.5rem;
+}
+
+.pl-4 {
+ padding-left: 1rem;
+}
+
+.pt-10 {
+ padding-top: 2.5rem;
+}
+
+.pt-6 {
+ padding-top: 1.5rem;
+}
+
+.text-2xl {
+ font-size: 1.5rem;
+ line-height: 2rem;
+}
+
+.text-3xl {
+ font-size: 1.875rem;
+ line-height: 2.25rem;
+}
+
+.text-\[0\.68rem\] {
+ font-size: 0.68rem;
+}
+
+.text-\[0\.72rem\] {
+ font-size: 0.72rem;
+}
+
+.text-\[0\.75rem\] {
+ font-size: 0.75rem;
+}
+
+.text-\[0\.7rem\] {
+ font-size: 0.7rem;
+}
+
+.text-\[0\.8rem\] {
+ font-size: 0.8rem;
+}
+
+.text-\[1rem\] {
+ font-size: 1rem;
+}
+
+.text-base {
+ font-size: 1rem;
+ line-height: 1.5rem;
+}
+
+.text-lg {
+ font-size: 1.125rem;
+ line-height: 1.75rem;
+}
+
+.text-sm {
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+}
+
+.text-xs {
+ font-size: 0.75rem;
+ line-height: 1rem;
+}
+
+.font-medium {
+ font-weight: 500;
+}
+
+.font-semibold {
+ font-weight: 600;
+}
+
+.italic {
+ font-style: italic;
+}
+
+.tracking-tight {
+ letter-spacing: -0.025em;
+}
+
+.tracking-wide {
+ letter-spacing: 0.025em;
+}
+
+.text-accent {
+ color: var(--color-accent);
+}
+
+.text-muted {
+ color: var(--color-text-muted);
+}
+
+.text-text {
+ color: var(--color-text);
+}
+
+.underline {
+ text-decoration-line: underline;
+}
+
+.antialiased {
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.shadow-md {
+ --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
+ --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.shadow-sm {
+ --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
+ --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.blur {
+ --tw-blur: blur(8px);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.filter {
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.backdrop-filter {
+ backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
+}
+
+.transition {
+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+}
+
+/* Theme Variables */
+
+:root {
+ /* LIGHT THEME */
+ --color-bg: #f9fafb;
+ --color-surface: #ffffff;
+ --color-text: #111827;
+ --color-text-muted: #6b7280;
+ --color-border: #e5e7eb;
+ --color-accent: #a855f7;
+}
+
+html[data-theme="dark"] {
+ /* DARK THEME */
+ --color-bg: #000000;
+ /* TRUE BLACK */
+ --color-surface: #0a0a0a;
+ --color-text: #f9fafb;
+ --color-text-muted: #9ca3af;
+ --color-border: #27272a;
+ --color-accent: #c084fc;
+}
+
+/* Base Styles */
+
+body {
+ background: var(--color-bg);
+ color: var(--color-text);
+}
+
+/* Utility Classes */
+
+/* ==========================================================================
+ UTILITY CLASSES
+ Color utilities, animations, helper classes
+ ========================================================================== */
+
+.bg-bg {
+ background-color: var(--color-bg);
+}
+
+.bg-surface {
+ background-color: var(--color-surface);
+}
+
+.text-text {
+ color: var(--color-text);
+}
+
+.text-muted {
+ color: var(--color-text-muted);
+}
+
+.text-accent {
+ color: var(--color-accent);
+}
+
+.border-border {
+ border-color: var(--color-border);
+}
+
+.border-accent {
+ border-color: var(--color-accent);
+}
+
+.bg-accent {
+ background-color: var(--color-accent);
+}
+
+.underline-accent {
+ text-decoration-color: var(--color-accent);
+}
+
+/* Simple fade-up animation */
+
+@keyframes fade-up {
+ 0% {
+ opacity: 0;
+ transform: translateY(8px);
+ }
+
+ 100% {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+.animate-fade-up {
+ animation: fade-up 0.45s ease-out both;
+}
+
+@keyframes search-panel-in {
+ 0% {
+ opacity: 0;
+ transform: translate(-50%, -48%) scale(0.97);
+ }
+
+ 100% {
+ opacity: 1;
+ transform: translate(-50%, -50%) scale(1);
+ }
+}
+
+@keyframes search-backdrop-in {
+ 0% {
+ opacity: 0;
+ }
+
+ 100% {
+ opacity: 1;
+ }
+}
+
+@keyframes search-panel-out {
+ 0% {
+ opacity: 1;
+ transform: translate(-50%, -50%) scale(1);
+ }
+
+ 100% {
+ opacity: 0;
+ transform: translate(-50%, -48%) scale(0.97);
+ }
+}
+
+@keyframes search-backdrop-out {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ }
+}
+
+/* Layout helpers */
+
+/* Components */
+
+/* ==========================================================================
+ DOCK COMPONENT
+ Floating action dock with toggle and panel
+ ========================================================================== */
+
+/* ==========================================================================
+ CARD COMPONENTS
+ Home cards, project cards, post cards, CTA cards, badges
+ ========================================================================== */
+
+.card-home {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ gap: 0.5rem;
+ background-color: color-mix(in srgb, var(--color-surface) 96%, transparent);
+ box-shadow: 0 18px 40px rgba(0, 0, 0, 0.55);
+}
+
+.card-home--project {
+ position: relative;
+ overflow: hidden;
+ transition:
+ transform 0.18s ease-out,
+ box-shadow 0.18s ease-out,
+ border-color 0.18s ease-out,
+ background-color 0.18s ease-out;
+}
+
+.card-home--project::after {
+ content: "";
+ position: absolute;
+ inset: -40%;
+ background: radial-gradient(
+ circle at 120% 50%,
+ color-mix(in srgb, var(--color-accent) 70%, transparent),
+ transparent 60%
+ );
+ opacity: 0;
+ transform: translateX(-8px);
+ transition:
+ opacity 0.22s ease-out,
+ transform 0.22s ease-out;
+ pointer-events: none;
+}
+
+.card-home--project:hover {
+ transform: translateY(-4px) translateX(3px);
+ border-color: color-mix(in srgb, var(--color-accent) 40%, var(--color-border));
+ box-shadow:
+ 0 18px 40px rgba(0, 0, 0, 0.7),
+ 16px 0 38px rgba(124, 58, 237, 0.45);
+ /* purple-ish accent on right */
+ background-color: color-mix(in srgb, var(--color-surface) 99%, transparent);
+}
+
+.card-home--project:hover::after {
+ opacity: 0.22;
+ transform: translateX(0);
+}
+
+.card-home-body {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ text-decoration: none;
+ color: inherit;
+}
+
+.card-home--post {
+ background-color: color-mix(in srgb, var(--color-surface) 94%, transparent);
+}
+
+.card-home-header {
+ display: flex;
+ align-items: flex-start;
+ gap: 0.6rem;
+}
+
+.card-home-icon {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 2.1rem;
+ height: 2.1rem;
+ border-radius: 999px;
+ border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-bg) 92%, transparent);
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
+ font-size: 0.85rem;
+}
+
+.card-badge {
+ margin-left: 0.25rem;
+ padding: 0.05rem 0.35rem;
+ border-radius: 999px;
+ background-color: color-mix(in srgb, var(--color-accent) 22%, transparent);
+ color: var(--color-accent);
+ font-size: 0.6rem;
+ font-weight: 600;
+}
+
+.card-home-footer {
+ margin-top: 0.5rem;
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ justify-content: space-between;
+}
+
+.card-home-footer--buttons {
+ padding-top: 0.4rem;
+ border-top: 1px solid color-mix(in srgb, var(--color-border) 80%, transparent);
+}
+
+.card-tag-row {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.25rem;
+}
+
+.card-tag-pill {
+ padding: 0.1rem 0.45rem;
+ border-radius: 999px;
+ border: 1px solid color-mix(in srgb, var(--color-border) 80%, transparent);
+ background-color: color-mix(in srgb, var(--color-bg) 92%, transparent);
+ font-size: 0.65rem;
+ color: var(--color-text-muted);
+}
+
+.card-cta {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.35rem;
+ font-size: 0.7rem;
+ color: var(--color-text-muted);
+ text-decoration: none;
+ padding: 0.25rem 0.6rem;
+ border-radius: 999px;
+ border: 1px solid transparent;
+ transition:
+ color 0.15s ease-out,
+ border-color 0.15s ease-out,
+ background-color 0.15s ease-out,
+ transform 0.15s ease-out;
+}
+
+.card-cta-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.35rem;
+ padding: 0.25rem 0.6rem;
+ border-radius: 8px;
+ font-size: 0.68rem;
+ color: var(--color-text-muted);
+ background-color: color-mix(in srgb, var(--color-bg) 92%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 80%, transparent);
+ text-decoration: none;
+ transition:
+ color 0.15s ease-out,
+ background-color 0.15s ease-out,
+ border-color 0.15s ease-out,
+ transform 0.15s ease-out,
+ box-shadow 0.15s ease-out;
+}
+
+.card-cta-btn:hover {
+ color: var(--color-accent);
+ background-color: color-mix(in srgb, var(--color-surface) 96%, transparent);
+ border-color: color-mix(in srgb, var(--color-accent) 50%, transparent);
+ transform: translateY(-1px);
+ box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
+}
+
+.card-cta-repo {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.4rem;
+ padding: 0.25rem 0.7rem;
+ border-radius: 999px;
+ border: 1px solid color-mix(in srgb, var(--color-border) 85%, transparent);
+ background-color: color-mix(in srgb, var(--color-bg) 94%, transparent);
+ font-size: 0.7rem;
+ color: var(--color-text-muted);
+ text-decoration: none;
+ transition:
+ color 0.15s ease-out,
+ border-color 0.15s ease-out,
+ background-color 0.15s ease-out,
+ transform 0.15s ease-out,
+ box-shadow 0.15s ease-out;
+}
+
+.card-cta-repo:hover {
+ color: var(--color-accent);
+ border-color: color-mix(in srgb, var(--color-accent) 55%, transparent);
+ background-color: color-mix(in srgb, var(--color-surface) 96%, transparent);
+ transform: translateY(-1px);
+ box-shadow: 0 10px 28px rgba(0, 0, 0, 0.5);
+}
+
+.card-cta:hover {
+ color: var(--color-accent);
+ border-color: color-mix(in srgb, var(--color-accent) 40%, transparent);
+ background-color: color-mix(in srgb, var(--color-surface) 94%, transparent);
+ transform: translateY(-1px);
+}
+
+.card-home--post {
+ position: relative;
+ overflow: hidden;
+ background-color: color-mix(in srgb, var(--color-surface) 94%, transparent);
+ border-left-width: 2px;
+ border-left-color: color-mix(in srgb, var(--color-border) 80%, transparent);
+ transition:
+ transform 0.18s ease-out,
+ box-shadow 0.18s ease-out,
+ border-color 0.18s ease-out,
+ background-color 0.18s ease-out;
+}
+
+.card-home--post::before {
+ content: "";
+ position: absolute;
+ left: -4px;
+ top: -20%;
+ bottom: -20%;
+ width: 10px;
+ background: linear-gradient(
+ to bottom,
+ transparent,
+ color-mix(in srgb, var(--color-accent) 70%, transparent),
+ transparent
+ );
+ opacity: 0;
+ transform: translateX(-6px);
+ transition:
+ opacity 0.22s ease-out,
+ transform 0.22s ease-out;
+ pointer-events: none;
+}
+
+.card-home--post:hover {
+ transform: translateY(-3px);
+ background-color: color-mix(in srgb, var(--color-surface) 98%, transparent);
+ border-left-color: color-mix(in srgb, var(--color-accent) 55%, var(--color-border));
+ box-shadow: 0 16px 34px rgba(0, 0, 0, 0.65);
+}
+
+.card-home--post:hover::before {
+ opacity: 0.55;
+ transform: translateX(0);
+}
+
+.card-home-icon--post {
+ background-color: color-mix(in srgb, var(--color-bg) 94%, transparent);
+}
+
+.card-badge--soft {
+ background-color: color-mix(in srgb, var(--color-accent) 16%, transparent);
+ color: color-mix(in srgb, var(--color-accent) 85%, white);
+}
+
+.card {
+ border-radius: 0.75rem;
+ transition: all 0.2s ease-out;
+}
+
+.card-pad {
+ padding: 1rem;
+}
+
+.card:hover {
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
+ border-color: color-mix(in srgb, var(--color-accent) 40%, transparent);
+}
+
+/* ==========================================================================
+ LAYOUT & NAVIGATION
+ Page layouts, headers, footers, navigation links
+ ========================================================================== */
+
+.layout-page {
+ margin-left: auto;
+ margin-right: auto;
+ max-width: 80rem;
+ padding-left: 1rem;
+ padding-right: 1rem;
+ padding-top: 1.5rem;
+ padding-bottom: 1.5rem;
+}
+
+@media (min-width: 640px) {
+ .layout-page {
+ padding-left: 1.5rem;
+ padding-right: 1.5rem;
+ }
+}
+
+@media (min-width: 1024px) {
+ .layout-page {
+ padding-top: 3rem;
+ padding-bottom: 3rem;
+ }
+}
+
+.layout-page-tight {
+ margin-left: auto;
+ margin-right: auto;
+ max-width: 72rem;
+ padding-left: 1rem;
+ padding-right: 1rem;
+ padding-top: 1rem;
+ padding-bottom: 1rem;
+}
+
+@media (min-width: 640px) {
+ .layout-page-tight {
+ padding-left: 1.5rem;
+ padding-right: 1.5rem;
+ }
+}
+
+@media (min-width: 1024px) {
+ .layout-page-tight {
+ padding-top: 2.5rem;
+ padding-bottom: 2.5rem;
+ }
+}
+
+.section-stack > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(2.5rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(2.5rem * var(--tw-space-y-reverse));
+}
+
+.section-stack--home > * + * {
+ margin-top: 1.75rem;
+}
+
+.section-stack > div + div.posts-section {
+ border-top: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ padding-top: 1.5rem;
+}
+
+/* Headings */
+
+.heading-page {
+ font-size: 1.875rem;
+ line-height: 2.25rem;
+ font-weight: 600;
+ letter-spacing: -0.025em;
+}
+
+@media (min-width: 640px) {
+ .heading-page {
+ font-size: 2.25rem;
+ line-height: 2.5rem;
+ }
+}
+
+.heading-section {
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+ font-weight: 600;
+ letter-spacing: -0.025em;
+}
+
+.eyebrow {
+ font-size: 0.65rem;
+ text-transform: uppercase;
+ letter-spacing: 0.22em;
+}
+
+/* Cards */
+
+.card {
+ border-radius: 0.75rem;
+ border-width: 1px;
+ --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
+ --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+ background-color: var(--color-surface);
+ border-color: var(--color-border);
+}
+
+.card-pad {
+ padding: 1rem;
+}
+
+@media (min-width: 640px) {
+ .card-pad {
+ padding: 1.25rem;
+ }
+}
+
+.card-hover {
+ transition-property: transform;
+ transition-property: box-shadow;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+ transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
+}
+
+.card-hover:hover {
+ --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
+ --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+ transform: translateY(-1px);
+ border-color: var(--color-accent);
+}
+
+/* Buttons */
+
+.btn-primary {
+ display: inline-flex;
+ align-items: center;
+ border-radius: 9999px;
+ padding-left: 1rem;
+ padding-right: 1rem;
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ font-size: 0.75rem;
+ line-height: 1rem;
+ font-weight: 500;
+ --tw-text-opacity: 1;
+ color: rgb(255 255 255 / var(--tw-text-opacity, 1));
+ --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
+ --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+ transition-property: transform;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+ transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
+ background-color: var(--color-accent);
+}
+
+.btn-primary:hover {
+ transform: translateY(-1px);
+}
+
+.btn-ghost {
+ display: inline-flex;
+ align-items: center;
+ font-size: 0.75rem;
+ line-height: 1rem;
+ font-weight: 500;
+ color: var(--color-text-muted);
+}
+
+.nav-shell {
+ border-radius: 9999px;
+ border-width: 1px;
+ padding: 0.75rem;
+ --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
+ --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+ --tw-backdrop-blur: blur(8px);
+ backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
+ border-color: var(--color-border);
+ background-color: color-mix(in srgb, var(--color-surface) 82%, transparent);
+}
+
+.nav-shell::before {
+ content: "";
+ position: absolute;
+ inset-inline: 0;
+ top: 0;
+ bottom: 0;
+ height: 1px;
+ background: linear-gradient(
+ 90deg,
+ transparent,
+ color-mix(in srgb, var(--color-accent) 80%, transparent),
+ transparent
+ );
+ opacity: 0.8;
+ pointer-events: none;
+}
+
+.nav-inner {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding-left: 1rem;
+ padding-right: 1rem;
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+}
+
+@media (min-width: 640px) {
+ .nav-inner {
+ padding-left: 1.25rem;
+ padding-right: 1.25rem;
+ padding-top: 0.625rem;
+ padding-bottom: 0.625rem;
+ }
+}
+
+/* Brand logo badge (fallback) */
+
+.logo-badge {
+ display: flex;
+ height: 2rem;
+ width: 2rem;
+ align-items: center;
+ justify-content: center;
+ border-radius: 9999px;
+ font-size: 0.65rem;
+ font-weight: 600;
+ --tw-text-opacity: 1;
+ color: rgb(255 255 255 / var(--tw-text-opacity, 1));
+ background-color: var(--color-accent);
+}
+
+/* Nav links */
+
+.nav-link {
+ font-size: 0.78rem;
+ font-weight: 500;
+ color: var(--color-text-muted);
+}
+
+.nav-link:hover {
+ color: var(--color-accent);
+}
+
+/* Theme toggle */
+
+.theme-toggle {
+ display: inline-flex;
+ height: 2rem;
+ width: 2rem;
+ align-items: center;
+ justify-content: center;
+ border-radius: 9999px;
+ border-width: 1px;
+ font-size: 0.7rem;
+ --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
+ --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+ background-color: var(--color-bg);
+ color: var(--color-text-muted);
+ border-color: var(--color-border);
+ transition: background-color 0.15s ease-out, color 0.15s ease-out,
+ transform 0.15s ease-out;
+}
+
+.theme-toggle:hover {
+ color: var(--color-accent);
+ transform: translateY(-1px);
+}
+
+html[data-theme="dark"] .theme-toggle {
+ background-color: var(--color-surface);
+}
+
+/* Fancy underline link */
+
+.link-underline {
+ position: relative;
+ display: inline-block;
+}
+
+.link-underline::after {
+ content: "";
+ position: absolute;
+ left: 0;
+ bottom: -0.15rem;
+ width: 0;
+ height: 1px;
+ background-color: var(--color-accent);
+ transition: width 0.16s ease-out;
+}
+
+.link-underline:hover::after {
+ width: 100%;
+}
+
+/* Footer shell */
+
+.footer-shell {
+ border-radius: 1rem;
+ border-width: 1px;
+ --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
+ --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+ --tw-backdrop-blur: blur(8px);
+ backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
+ border-color: var(--color-border);
+ position: relative;
+ overflow: hidden;
+ background-color: color-mix(in srgb, var(--color-surface) 86%, transparent);
+}
+
+.footer-shell::before {
+ content: "";
+ position: absolute;
+ inset-inline: 0;
+ top: 0;
+ height: 1px;
+ background: linear-gradient(
+ 90deg,
+ transparent,
+ color-mix(in srgb, var(--color-accent) 80%, transparent),
+ transparent
+ );
+ opacity: 0.8;
+ pointer-events: none;
+}
+
+.footer-inner {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+ padding-left: 1rem;
+ padding-right: 1rem;
+ padding-top: 0.75rem;
+ padding-bottom: 0.75rem;
+ font-size: 0.72rem;
+}
+
+@media (min-width: 640px) {
+ .footer-inner {
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+ padding-left: 1.25rem;
+ padding-right: 1.25rem;
+ }
+}
+
+.footer-links {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 0.75rem;
+}
+
+.footer-link {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.25rem;
+ font-size: 0.75rem;
+ font-weight: 500;
+ transition-property: all;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+ transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
+ color: var(--color-text-muted);
+}
+
+.footer-link:hover {
+ color: var(--color-accent);
+}
+
+.footer-small {
+ font-size: 0.72rem;
+ line-height: 1.625;
+ color: var(--color-text-muted);
+}
+
+.footer-float:hover {
+ color: var(--color-accent);
+ transform: translateY(-1px);
+}
+
+.footer-float:hover i {
+ filter: drop-shadow(
+ 0 0 2px color-mix(in srgb, var(--color-accent) 60%, transparent)
+ );
+}
+
+/* ==========================================================================
+ SEARCH OVERLAY
+ Search modal, search results, empty states
+ ========================================================================== */
+
+.search-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 40;
+ display: none;
+ align-items: center;
+ justify-content: center;
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.18s ease-out;
+}
+
+.search-overlay--open {
+ opacity: 1;
+ display: block;
+ pointer-events: auto;
+}
+
+.search-overlay-backdrop {
+ position: absolute;
+ inset: 0;
+ background: radial-gradient(
+ circle at top,
+ rgba(0, 0, 0, 0.4),
+ transparent 55%
+ ),
+ rgba(0, 0, 0, 0.7);
+ backdrop-filter: blur(12px);
+}
+
+.search-panel {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 100%;
+ max-width: 36rem;
+ margin-inline: 1.5rem;
+ border-radius: 1.1rem;
+ border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-bg) 96%, transparent);
+ box-shadow: 0 26px 70px rgba(0, 0, 0, 0.85);
+ padding: 0.8rem 0.9rem 0.6rem;
+ display: flex;
+ flex-direction: column;
+ gap: 0.6rem;
+}
+
+.search-overlay--open .search-panel {
+ animation: search-panel-in 0.18s ease-out;
+}
+
+.search-overlay-backdrop {
+ position: absolute;
+ inset: 0;
+ background: radial-gradient(
+ circle at top,
+ rgba(0, 0, 0, 0.4),
+ transparent 55%
+ ),
+ rgba(0, 0, 0, 0.7);
+ backdrop-filter: blur(12px);
+}
+
+.search-overlay .search-overlay--open .search-overlay-backdrop {
+ animation: search-backdrop-in 0.18s ease-out;
+}
+
+.search-overlay--closing .search-panel {
+ animation: search-panel-out 0.18s ease-in forwards;
+}
+
+.search-overlay--closing .search-overlay-backdrop {
+ animation: search-backdrop-out 0.18s ease-in forwards;
+}
+
+.search-panel-header {
+ display: flex;
+ align-items: center;
+ gap: 0.6rem;
+}
+
+.search-input-wrap {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.45rem 0.8rem;
+ border-radius: 999px;
+ border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-surface) 96%, transparent);
+}
+
+.search-input {
+ flex: 1;
+ border: none;
+ outline: none;
+ font-size: 0.82rem;
+ background: transparent;
+ color: var(--color-text);
+}
+
+.search-input::-moz-placeholder {
+ color: var(--color-text-muted);
+}
+
+.search-input::placeholder {
+ color: var(--color-text-muted);
+}
+
+.search-close {
+ width: 2rem;
+ height: 2rem;
+ border-radius: 999px;
+ border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-bg) 90%, transparent);
+ color: var(--color-text-muted);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: background-color 0.16s ease-out, border-color 0.16s ease-out,
+ color 0.16s ease-out, transform 0.16s ease-out;
+}
+
+.search-close:hover {
+ border-color: var(--color-accent);
+ color: var(--color-accent);
+ transform: translateY(-1px);
+}
+
+.search-panel-body {
+ border-radius: 0.9rem;
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ background-color: color-mix(in srgb, var(--color-surface) 96%, transparent);
+ padding: 0.5rem 0.4rem 0.4rem;
+ display: flex;
+ flex-direction: column;
+}
+
+.search-results {
+ max-height: 18rem;
+ padding: 0.25rem 0.15rem 0.4rem;
+ overflow-y: auto;
+}
+
+.search-empty-state {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 1.2rem 0.5rem 1.4rem;
+ gap: 0.4rem;
+}
+
+.search-empty-icon {
+ width: 2.3rem;
+ height: 2.3rem;
+ border-radius: 999px;
+ border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-bg) 92%, transparent);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.search-empty-title {
+ font-size: 0.86rem;
+ font-weight: 600;
+ color: var(--color-text);
+}
+
+.search-empty-subtitle {
+ font-size: 0.76rem;
+ color: var(--color-text-muted);
+}
+
+.search-footer-hints {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.45rem;
+ border-top: 1px solid
+ color-mix(in srgb, var(--color-border) 75%, transparent);
+ padding: 0.4rem 0.5rem 0.1rem;
+ margin-top: 0.1rem;
+}
+
+.search-hint-key {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.25rem;
+ font-size: 0.68rem;
+ color: var(--color-text-muted);
+}
+
+.search-hint-key span:first-child,
+ .search-hint-key span:nth-child(2) {
+ padding: 0.1rem 0.3rem;
+ border-radius: 0.3rem;
+ border: 1px solid color-mix(in srgb, var(--color-border) 80%, transparent);
+ background-color: color-mix(in srgb, var(--color-bg) 96%, transparent);
+ font-size: 0.65rem;
+}
+
+.search-hint-key.search-hint-right {
+ margin-left: auto;
+}
+
+.search-result-item {
+ display: block;
+ padding: 0.42rem 0.55rem;
+ border-radius: 0.6rem;
+ text-decoration: none;
+ transition: background-color 0.12s ease-out, transform 0.12s ease-out;
+}
+
+.search-result-item:hover {
+ background-color: color-mix(in srgb, var(--color-surface) 92%, transparent);
+ transform: translateY(-1px);
+}
+
+.search-result-title {
+ font-size: 0.8rem;
+ font-weight: 500;
+ color: var(--color-text);
+}
+
+.search-result-meta {
+ margin-top: 0.15rem;
+ font-size: 0.7rem;
+ color: var(--color-text-muted);
+}
+
+.search-footer-hints {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.45rem;
+ border-top: 1px solid
+ color-mix(in srgb, var(--color-border) 75%, transparent);
+ padding: 0.4rem 0.5rem 0.1rem;
+ margin-top: 0.1rem;
+}
+
+.search-hint-key {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.25rem;
+ font-size: 0.68rem;
+ color: var(--color-text-muted);
+}
+
+.search-hint-key span:first-child,
+ .search-hint-key span:nth-child(2) {
+ padding: 0.1rem 0.3rem;
+ border-radius: 0.3rem;
+ border: 1px solid color-mix(in srgb, var(--color-border) 80%, transparent);
+ background-color: color-mix(in srgb, var(--color-bg) 96%, transparent);
+ font-size: 0.65rem;
+}
+
+.search-hint-key.search-hint-right {
+ margin-left: auto;
+}
+
+.search-result-item {
+ display: block;
+ padding: 0.42rem 0.55rem;
+ border-radius: 0.6rem;
+ text-decoration: none;
+ transition: background-color 0.12s ease-out, transform 0.12s ease-out;
+}
+
+.search-result-item:hover {
+ background-color: color-mix(in srgb, var(--color-surface) 92%, transparent);
+ transform: translateY(-1px);
+}
+
+.search-result-title {
+ font-size: 0.8rem;
+ font-weight: 500;
+ color: var(--color-text);
+}
+
+.search-result-meta {
+ margin-top: 0.15rem;
+ font-size: 0.7rem;
+ color: var(--color-text-muted);
+}
+
+/* ==========================================================================
+ TECH MARQUEE
+ Technology carousel/strip component
+ ========================================================================== */
+
+.tech-carousel {
+ display: flex;
+ gap: 0.5rem;
+ padding: 0.3rem 0.1rem 0.1rem;
+ overflow-x: auto;
+ scroll-snap-type: x mandatory;
+}
+
+.tech-carousel::-webkit-scrollbar {
+ height: 4px;
+}
+
+.tech-carousel::-webkit-scrollbar-thumb {
+ border-radius: 999px;
+ background-color: rgba(255, 255, 255, 0.12);
+}
+
+.tech-pill {
+ scroll-snap-align: start;
+ display: inline-flex;
+ align-items: center;
+ gap: 0.4rem;
+ padding: 0.35rem 0.7rem;
+ border-radius: 999px;
+ border: 1px solid var(--color-border);
+ background-color: color-mix(in srgb, var(--color-surface) 92%, transparent);
+ box-shadow: 0 10px 28px rgba(0, 0, 0, 0.28);
+ white-space: nowrap;
+}
+
+.badge-available {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.375rem;
+ padding: 0.25rem 0.7rem;
+ border-radius: 999px;
+ background-color: var(--color-accent);
+ color: white;
+ font-size: 0.7rem;
+ font-weight: 600;
+ box-shadow: 0 0 0.4rem rgba(0, 0, 0, 0.4);
+}
+
+/* --- Tech marquee --- */
+
+.tech-icon {
+ font-size: 1.5rem;
+}
+
+.tech-strip {
+ position: relative;
+ overflow: hidden;
+ padding-block: 0.4rem;
+}
+
+.tech-strip-track {
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ display: inline-flex;
+ align-items: center;
+ white-space: nowrap;
+ animation-name: tech-marquee;
+ animation-timing-function: linear;
+ animation-iteration-count: infinite;
+ animation-play-state: running;
+ gap: 1.5rem;
+}
+
+.tech-strip--wide .tech-strip-track--primary {
+ animation-duration: 40s;
+}
+
+.tech-strip--wide .tech-strip-track--secondary {
+ animation-duration: 40s;
+ animation-direction: reverse;
+}
+
+.tech-strip--compact .tech-strip-track--primary {
+ animation-duration: 40s;
+}
+
+.tech-strip--compact .tech-strip-track--secondary {
+ animation-duration: 48s;
+ animation-direction: reverse;
+}
+
+.tech-strip--compact .tech-strip-track {
+ gap: 1.1rem;
+}
+
+/* pause both rows on hover */
+
+.tech-strip:hover .tech-strip-track {
+ animation-play-state: paused;
+}
+
+.tech-strip-item {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.4rem;
+ opacity: 0.88;
+ transition: opacity 0.15s ease-out, transform 0.15s ease-out;
+}
+
+.tech-strip-item:hover {
+ opacity: 1;
+ transform: translateY(-1px);
+}
+
+/* Content */
+
+/* ==========================================================================
+ MARKDOWN CONTENT STYLES
+ Typography, blockquotes, lists, code blocks, tables, alerts
+ ========================================================================== */
+
+.markdown-body {
+ max-width: 85ch;
+ margin-inline: auto;
+ font-size: 0.95rem;
+ line-height: 1.75;
+ color: var(--color-text);
+ overflow-wrap: break-word;
+ word-wrap: break-word;
+ min-width: 0;
+}
+
+/* rhythm */
+
+.markdown-body > * {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+.markdown-body > * + * {
+ margin-top: 1.25rem;
+}
+
+/* paragraphs */
+
+.markdown-body p {
+ color: var(--color-text);
+ line-height: 1.75;
+}
+
+/* headings */
+
+.markdown-body h1,
+ .markdown-body h2,
+ .markdown-body h3,
+ .markdown-body h4,
+ .markdown-body h5,
+ .markdown-body h6 {
+ color: var(--color-text);
+ font-weight: 650;
+ line-height: 1.3;
+ letter-spacing: -0.01em;
+ margin-top: 2rem;
+ margin-bottom: 0.75rem;
+}
+
+.markdown-body h1 {
+ font-size: 2rem;
+ margin-top: 0;
+}
+
+.markdown-body h2 {
+ font-size: 1.5rem;
+ padding-bottom: 0.4rem;
+ border-bottom: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ margin-top: 2.5rem;
+}
+
+.markdown-body h3 {
+ font-size: 1.25rem;
+ margin-top: 2rem;
+}
+
+.markdown-body h4 {
+ font-size: 1.1rem;
+}
+
+.markdown-body h5 {
+ font-size: 1rem;
+}
+
+.markdown-body h6 {
+ font-size: 0.85rem;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ color: var(--color-text-muted);
+}
+
+/* links */
+
+.markdown-body a {
+ color: var(--color-accent);
+ text-decoration: none;
+ border-bottom: 1px solid color-mix(in srgb, var(--color-accent) 35%, transparent);
+ padding-bottom: 0.05rem;
+ transition: color 0.15s ease-out, border-color 0.15s ease-out;
+ word-wrap: break-word;
+ overflow-wrap: break-word;
+ word-break: break-word;
+}
+
+.markdown-body a:hover {
+ color: color-mix(in srgb, var(--color-accent) 85%, white);
+ border-bottom-color: var(--color-accent);
+}
+
+/* strong and emphasis */
+
+.markdown-body strong {
+ font-weight: 650;
+ color: var(--color-text);
+}
+
+.markdown-body em {
+ font-style: italic;
+}
+
+/* lists */
+
+.markdown-body ul,
+ .markdown-body ol {
+ padding-left: 1.75rem;
+ margin-top: 1rem;
+ margin-bottom: 1rem;
+}
+
+.markdown-body li {
+ margin: 0.5rem 0;
+ line-height: 1.7;
+ padding-left: 0.5rem;
+ position: relative;
+ transition: background-color 0.15s ease-out;
+}
+
+.markdown-body li:hover {
+ background-color: color-mix(in srgb, var(--color-surface) 30%, transparent);
+ border-radius: 0.35rem;
+}
+
+.markdown-body li > ul,
+ .markdown-body li > ol {
+ margin-top: 0.5rem;
+ margin-bottom: 0.5rem;
+}
+
+/* Unordered list markers */
+
+.markdown-body ul li::marker {
+ color: var(--color-accent);
+ font-size: 1.1em;
+}
+
+.markdown-body ul {
+ list-style-type: disc;
+}
+
+.markdown-body ul ul {
+ list-style-type: circle;
+}
+
+.markdown-body ul ul ul {
+ list-style-type: square;
+}
+
+/* Ordered list markers */
+
+.markdown-body ol {
+ list-style-type: decimal;
+}
+
+.markdown-body ol li::marker {
+ color: var(--color-accent);
+ font-weight: 700;
+ font-size: 0.95em;
+}
+
+.markdown-body ol ol {
+ list-style-type: lower-alpha;
+}
+
+.markdown-body ol ol ol {
+ list-style-type: lower-roman;
+}
+
+/* Better spacing for nested lists */
+
+.markdown-body li > p {
+ margin-top: 0.35rem;
+ margin-bottom: 0.35rem;
+}
+
+.markdown-body li:first-child {
+ margin-top: 0;
+}
+
+.markdown-body li:last-child {
+ margin-bottom: 0;
+}
+
+/* definition lists */
+
+.markdown-body dl {
+ margin: 1.5rem 0;
+ padding: 1.25rem;
+ border-left: 3px solid var(--color-accent);
+ background: linear-gradient(
+ to right,
+ color-mix(in srgb, var(--color-accent) 8%, transparent),
+ color-mix(in srgb, var(--color-surface) 40%, transparent) 3rem
+ );
+ border-radius: 0.6rem;
+}
+
+.markdown-body dt {
+ font-weight: 650;
+ color: var(--color-text);
+ margin-top: 1rem;
+ margin-bottom: 0.5rem;
+ font-size: 1rem;
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+
+.markdown-body dt:first-child {
+ margin-top: 0;
+}
+
+.markdown-body dt::before {
+ content: '▸';
+ color: var(--color-accent);
+ font-size: 0.9em;
+ font-weight: bold;
+}
+
+.markdown-body dd {
+ margin-left: 1.5rem;
+ margin-bottom: 0.75rem;
+ padding-left: 1rem;
+ border-left: 2px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ color: var(--color-text-muted);
+ line-height: 1.7;
+}
+
+.markdown-body dd:last-child {
+ margin-bottom: 0;
+}
+
+.markdown-body dd > p {
+ margin: 0.25rem 0;
+}
+
+.markdown-body dd > p:first-child {
+ margin-top: 0;
+}
+
+.markdown-body dd > p:last-child {
+ margin-bottom: 0;
+}
+
+/* task lists */
+
+.markdown-body ul.contains-task-list {
+ list-style: none;
+ padding-left: 0;
+}
+
+.markdown-body .task-list-item {
+ display: flex;
+ align-items: flex-start;
+ gap: 0.65rem;
+ padding: 0.5rem 0.75rem;
+ margin: 0.35rem 0;
+ border-radius: 0.45rem;
+ transition: all 0.15s ease-out;
+ background-color: color-mix(in srgb, var(--color-surface) 20%, transparent);
+}
+
+.markdown-body .task-list-item:hover {
+ background-color: color-mix(in srgb, var(--color-surface) 50%, transparent);
+ transform: translateX(3px);
+}
+
+.markdown-body .task-list-item input[type="checkbox"] {
+ margin-top: 0.35rem;
+ flex-shrink: 0;
+ width: 1.1rem;
+ height: 1.1rem;
+ cursor: pointer;
+ accent-color: var(--color-accent);
+ border-radius: 0.25rem;
+}
+
+.markdown-body .task-list-item input[type="checkbox"]:checked {
+ accent-color: #22c55e;
+}
+
+.markdown-body .task-list-item input[type="checkbox"]:checked + * {
+ color: var(--color-text-muted);
+ text-decoration: line-through;
+ text-decoration-color: var(--color-text-muted);
+}
+
+/* blockquote */
+
+.markdown-body blockquote,
+ .markdown-body .md-blockquote {
+ margin: 1.75rem 0;
+ padding: 1.25rem 1.5rem;
+ border-left: 4px solid var(--color-accent);
+ background: linear-gradient(
+ to right,
+ color-mix(in srgb, var(--color-accent) 8%, transparent),
+ color-mix(in srgb, var(--color-surface) 60%, transparent) 3rem
+ );
+ border-radius: 0.6rem;
+ color: var(--color-text);
+ font-style: italic;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+ position: relative;
+}
+
+.markdown-body blockquote::before,
+ .markdown-body .md-blockquote::before {
+ content: '"';
+ position: absolute;
+ left: 0.75rem;
+ top: 0.5rem;
+ font-size: 2.5rem;
+ line-height: 1;
+ color: color-mix(in srgb, var(--color-accent) 25%, transparent);
+ font-family: Georgia, serif;
+ font-weight: bold;
+}
+
+.markdown-body blockquote p,
+ .markdown-body .md-blockquote p {
+ color: var(--color-text);
+ font-size: 0.98rem;
+ line-height: 1.7;
+}
+
+.markdown-body blockquote p + p,
+ .markdown-body .md-blockquote p + p {
+ margin-top: 0.85rem;
+}
+
+.markdown-body blockquote strong,
+ .markdown-body .md-blockquote strong {
+ color: var(--color-text);
+ font-weight: 650;
+}
+
+/* GitHub-style alerts */
+
+.markdown-body .md-alert {
+ margin: 1.75rem 0;
+ padding: 1rem 1.25rem 1rem 3rem;
+ border-radius: 0.6rem;
+ border-left: 4px solid;
+ position: relative;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+}
+
+.markdown-body .md-alert::before {
+ content: '';
+ position: absolute;
+ left: 1rem;
+ top: 1.1rem;
+ width: 1.25rem;
+ height: 1.25rem;
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+}
+
+.markdown-body .md-alert p:first-child {
+ margin-top: 0;
+}
+
+.markdown-body .md-alert p:last-child {
+ margin-bottom: 0;
+}
+
+/* Note alert (blue) */
+
+.markdown-body .md-alert-note {
+ background: linear-gradient(
+ to right,
+ color-mix(in srgb, #3b82f6 10%, transparent),
+ color-mix(in srgb, var(--color-surface) 60%, transparent) 3rem
+ );
+ border-left-color: #3b82f6;
+}
+
+.markdown-body .md-alert-note::before {
+ content: 'ℹ';
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 1rem;
+ font-weight: bold;
+ color: #3b82f6;
+ background: none;
+}
+
+/* Tip alert (green) */
+
+.markdown-body .md-alert-tip {
+ background: linear-gradient(
+ to right,
+ color-mix(in srgb, #22c55e 10%, transparent),
+ color-mix(in srgb, var(--color-surface) 60%, transparent) 3rem
+ );
+ border-left-color: #22c55e;
+}
+
+.markdown-body .md-alert-tip::before {
+ content: '💡';
+ font-size: 1.1rem;
+}
+
+/* Important alert (purple) */
+
+.markdown-body .md-alert-important {
+ background: linear-gradient(
+ to right,
+ color-mix(in srgb, var(--color-accent) 12%, transparent),
+ color-mix(in srgb, var(--color-surface) 60%, transparent) 3rem
+ );
+ border-left-color: var(--color-accent);
+}
+
+.markdown-body .md-alert-important::before {
+ content: '⚡';
+ font-size: 1.1rem;
+}
+
+/* Warning alert (yellow/orange) */
+
+.markdown-body .md-alert-warning {
+ background: linear-gradient(
+ to right,
+ color-mix(in srgb, #f59e0b 10%, transparent),
+ color-mix(in srgb, var(--color-surface) 60%, transparent) 3rem
+ );
+ border-left-color: #f59e0b;
+}
+
+.markdown-body .md-alert-warning::before {
+ content: '⚠';
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 1.1rem;
+ color: #f59e0b;
+ background: none;
+}
+
+/* Danger/Caution alert (red) */
+
+.markdown-body .md-alert-danger,
+ .markdown-body .md-alert-caution {
+ background: linear-gradient(
+ to right,
+ color-mix(in srgb, #ef4444 10%, transparent),
+ color-mix(in srgb, var(--color-surface) 60%, transparent) 3rem
+ );
+ border-left-color: #ef4444;
+}
+
+.markdown-body .md-alert-danger::before,
+ .markdown-body .md-alert-caution::before {
+ content: '🛑';
+ font-size: 1.1rem;
+}
+
+/* inline code */
+
+.markdown-body :not(pre) > code {
+ font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
+ font-size: 0.88em;
+ padding: 0.15rem 0.4rem;
+ border-radius: 0.35rem;
+ background: color-mix(in srgb, var(--color-surface) 80%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ color: color-mix(in srgb, var(--color-accent) 90%, white);
+}
+
+html[data-theme="light"] .markdown-body :not(pre) > code {
+ background: #f3f4f6;
+ border-color: #d1d5db;
+ color: #7c3aed;
+}
+
+/* CODE BLOCKS - This is the important part */
+
+.markdown-body pre {
+ margin: 1.5rem 0;
+ padding: 0;
+ overflow: hidden;
+ overflow-x: auto;
+ border-radius: 0.75rem;
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ background: color-mix(in srgb, var(--color-surface) 40%, transparent);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
+ max-width: 100%;
+}
+
+html[data-theme="light"] .markdown-body pre {
+ background: #f9fafb;
+ border-color: #e5e7eb;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+}
+
+.markdown-body pre code {
+ display: block;
+ padding: 1.25rem 1.5rem;
+ overflow-x: auto;
+ font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
+ font-size: 0.88rem;
+ line-height: 1.6;
+ color: var(--color-text);
+ background: transparent;
+ border: none;
+}
+
+/* Code block with header (language badge) */
+
+.markdown-body .highlight {
+ position: relative;
+ background: color-mix(in srgb, var(--color-surface) 40%, transparent);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
+ overflow: hidden;
+}
+
+.markdown-body .highlight pre {
+ margin: 0;
+ border: none;
+ border-radius: 0;
+ box-shadow: none;
+}
+
+/* Custom code block wrapper (if you want header with language/copy button) */
+
+.mb-codeblock {
+ margin: 1.5rem 0;
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ border-radius: 0.75rem;
+ overflow: hidden;
+ background: color-mix(in srgb, var(--color-surface) 40%, transparent);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
+}
+
+.mb-codeblock-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0.75rem 1rem;
+ border-bottom: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ background: color-mix(in srgb, var(--color-bg) 50%, transparent);
+}
+
+.mb-codeblock-left {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+
+.mb-codeblock-label {
+ color: var(--color-text-muted);
+ font-size: 0.75rem;
+ font-weight: 500;
+ letter-spacing: 0.02em;
+}
+
+.mb-codeblock-badge {
+ font-size: 0.7rem;
+ font-weight: 600;
+ padding: 0.2rem 0.5rem;
+ border-radius: 0.35rem;
+ background: color-mix(in srgb, var(--color-accent) 20%, transparent);
+ color: var(--color-accent);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+
+.mb-codeblock-actions {
+ display: flex;
+ gap: 0.25rem;
+}
+
+.mb-codeblock-actions button {
+ background: transparent;
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ color: var(--color-text-muted);
+ cursor: pointer;
+ font-size: 0.7rem;
+ padding: 0.3rem 0.6rem;
+ border-radius: 0.35rem;
+ transition: all 0.15s ease-out;
+ display: flex;
+ align-items: center;
+ gap: 0.35rem;
+}
+
+.mb-codeblock-actions button:hover {
+ color: var(--color-accent);
+ background: color-mix(in srgb, var(--color-accent) 15%, transparent);
+ border-color: var(--color-accent);
+}
+
+.mb-codeblock-content {
+ position: relative;
+}
+
+.mb-codeblock-content pre {
+ margin: 0;
+ padding: 1.25rem 1.5rem;
+ overflow-x: auto;
+ border: none;
+ border-radius: 0;
+ background: transparent;
+ box-shadow: none;
+}
+
+.mb-codeblock-content code {
+ font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
+ font-size: 0.88rem;
+ line-height: 1.6;
+}
+
+/* tables */
+
+.markdown-body table {
+ width: 100%;
+ margin: 1.5rem 0;
+ border-collapse: collapse;
+ font-size: 0.9rem;
+ border-radius: 0.75rem;
+ overflow: hidden;
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+}
+
+.markdown-body thead {
+ background: color-mix(in srgb, var(--color-surface) 60%, transparent);
+}
+
+.markdown-body th {
+ padding: 0.75rem 1rem;
+ text-align: left;
+ font-weight: 600;
+ color: var(--color-text);
+ border-bottom: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+}
+
+.markdown-body td {
+ padding: 0.75rem 1rem;
+ border-bottom: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+}
+
+.markdown-body tbody tr:last-child td {
+ border-bottom: none;
+}
+
+.markdown-body tbody tr:hover {
+ background: color-mix(in srgb, var(--color-surface) 30%, transparent);
+}
+
+/* hr */
+
+.markdown-body hr {
+ border: 0;
+ border-top: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ margin: 2rem 0;
+}
+
+/* Custom link with external indicator */
+
+.markdown-body .md-link {
+ position: relative;
+}
+
+.markdown-body a.md-link[target="_blank"]::after {
+ display: inline-block;
+ margin-left: 0.25rem;
+ font-size: 0.85em;
+ opacity: 0.6;
+ transition: all 0.15s ease-out;
+}
+
+.markdown-body a.md-link[target="_blank"]:hover::after {
+ opacity: 1;
+ transform: translate(2px, -2px);
+}
+
+/* Heading anchors with hover effect */
+
+.markdown-body .md-heading-anchor {
+ position: relative;
+ color: inherit;
+ text-decoration: none;
+ border-bottom: none;
+ padding-bottom: 0;
+}
+
+.markdown-body .md-heading-anchor::before {
+ content: '#';
+ position: absolute;
+ left: -1.5rem;
+ opacity: 0;
+ color: var(--color-accent);
+ font-weight: 400;
+ transition: opacity 0.15s ease-out;
+}
+
+.markdown-body h1:hover .md-heading-anchor::before,
+ .markdown-body h2:hover .md-heading-anchor::before,
+ .markdown-body h3:hover .md-heading-anchor::before,
+ .markdown-body h4:hover .md-heading-anchor::before,
+ .markdown-body h5:hover .md-heading-anchor::before,
+ .markdown-body h6:hover .md-heading-anchor::before {
+ opacity: 1;
+}
+
+.markdown-body .md-heading-anchor:hover {
+ color: var(--color-accent);
+}
+
+/* Table wrapper for horizontal scrolling */
+
+.markdown-body .table-wrap {
+ margin: 1.75rem 0;
+ overflow-x: auto;
+ border-radius: 0.75rem;
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+}
+
+.markdown-body .table-wrap table {
+ margin: 0;
+ border: none;
+ border-radius: 0;
+}
+
+/* Custom scrollbar for table wrapper */
+
+.markdown-body .table-wrap::-webkit-scrollbar {
+ height: 8px;
+}
+
+.markdown-body .table-wrap::-webkit-scrollbar-track {
+ background: color-mix(in srgb, var(--color-bg) 30%, transparent);
+ border-radius: 0 0 0.75rem 0.75rem;
+}
+
+.markdown-body .table-wrap::-webkit-scrollbar-thumb {
+ background: color-mix(in srgb, var(--color-accent) 50%, transparent);
+ border-radius: 4px;
+}
+
+.markdown-body .table-wrap::-webkit-scrollbar-thumb:hover {
+ background: var(--color-accent);
+}
+
+/* images */
+
+.markdown-body img {
+ display: block;
+ max-width: 100%;
+ height: auto;
+ margin: 1.5rem auto;
+ border-radius: 0.75rem;
+ border: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+}
+
+.markdown-body figure {
+ margin: 1.5rem 0;
+ text-align: center;
+}
+
+.markdown-body figcaption {
+ margin-top: 0.5rem;
+ font-size: 0.85rem;
+ color: var(--color-text-muted);
+ font-style: italic;
+}
+
+/* Custom image wrapper with lightbox */
+
+.markdown-body .md-image {
+ margin: 2rem 0;
+ text-align: center;
+}
+
+.markdown-body .md-image a {
+ display: inline-block;
+ position: relative;
+ overflow: hidden;
+ border-radius: 0.85rem;
+ border: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ transition: all 0.25s ease-out;
+ border-bottom: none;
+ padding-bottom: 0;
+}
+
+.markdown-body .md-image a::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(
+ 135deg,
+ color-mix(in srgb, var(--color-accent) 0%, transparent),
+ color-mix(in srgb, var(--color-accent) 15%, transparent)
+ );
+ opacity: 0;
+ transition: opacity 0.25s ease-out;
+ pointer-events: none;
+ z-index: 1;
+}
+
+.markdown-body .md-image a::after {
+ content: '🔍';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%) scale(0.8);
+ font-size: 2.5rem;
+ opacity: 0;
+ transition: all 0.25s ease-out;
+ z-index: 2;
+ pointer-events: none;
+ filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.5));
+}
+
+.markdown-body .md-image a:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 12px 28px rgba(0, 0, 0, 0.25);
+ border-color: color-mix(in srgb, var(--color-accent) 50%, transparent);
+}
+
+.markdown-body .md-image a:hover::before {
+ opacity: 1;
+}
+
+.markdown-body .md-image a:hover::after {
+ opacity: 1;
+ transform: translate(-50%, -50%) scale(1);
+}
+
+.markdown-body .md-image img {
+ margin: 0;
+ border: none;
+ border-radius: 0.75rem;
+ display: block;
+ transition: all 0.25s ease-out;
+}
+
+.markdown-body .md-image a:hover img {
+ filter: brightness(0.85);
+}
+
+.markdown-body .md-image figcaption {
+ display: none;
+}
+
+/* SYNTAX HIGHLIGHTING - Dark theme colors */
+
+/* These will be applied by Hugo's Chroma */
+
+.markdown-body .chroma {
+ background: transparent;
+}
+
+.markdown-body .chroma .err {
+ color: #f87171;
+}
+
+.markdown-body .chroma .lntd {
+ padding: 0;
+}
+
+.markdown-body .chroma .lntable {
+ border-spacing: 0;
+}
+
+/* Chroma syntax colors for dark theme */
+
+html[data-theme="dark"] .markdown-body .chroma .k {
+ color: #c084fc;
+}
+
+/* keyword - purple */
+
+html[data-theme="dark"] .markdown-body .chroma .kc {
+ color: #c084fc;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .kd {
+ color: #c084fc;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .kn {
+ color: #c084fc;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .kp {
+ color: #c084fc;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .kr {
+ color: #c084fc;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .kt {
+ color: #c084fc;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .n {
+ color: #e5e7eb;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .na {
+ color: #fbbf24;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .nb {
+ color: #60a5fa;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .nc {
+ color: #fbbf24;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .nf {
+ color: #60a5fa;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .nn {
+ color: #fbbf24;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .s {
+ color: #86efac;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .s1 {
+ color: #86efac;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .s2 {
+ color: #86efac;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .sb {
+ color: #86efac;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .sc {
+ color: #86efac;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .sd {
+ color: #86efac;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .se {
+ color: #fbbf24;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .si {
+ color: #fbbf24;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .sr {
+ color: #86efac;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .ss {
+ color: #86efac;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .m {
+ color: #fb923c;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .mb {
+ color: #fb923c;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .mf {
+ color: #fb923c;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .mh {
+ color: #fb923c;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .mi {
+ color: #fb923c;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .mo {
+ color: #fb923c;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .o {
+ color: #c084fc;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .ow {
+ color: #c084fc;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .c {
+ color: #6b7280;
+ font-style: italic;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .c1 {
+ color: #6b7280;
+ font-style: italic;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .cm {
+ color: #6b7280;
+ font-style: italic;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .p {
+ color: #9ca3af;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .g {
+ color: #ef4444;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .gd {
+ color: #ef4444;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .ge {
+ font-style: italic;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .gi {
+ color: #22c55e;
+}
+
+html[data-theme="dark"] .markdown-body .chroma .gs {
+ font-weight: bold;
+}
+
+/* SYNTAX HIGHLIGHTING - Light theme colors */
+
+html[data-theme="light"] .markdown-body .chroma .k {
+ color: #7c3aed;
+}
+
+/* keyword - purple */
+
+html[data-theme="light"] .markdown-body .chroma .kc {
+ color: #7c3aed;
+}
+
+html[data-theme="light"] .markdown-body .chroma .kd {
+ color: #7c3aed;
+}
+
+html[data-theme="light"] .markdown-body .chroma .kn {
+ color: #7c3aed;
+}
+
+html[data-theme="light"] .markdown-body .chroma .kp {
+ color: #7c3aed;
+}
+
+html[data-theme="light"] .markdown-body .chroma .kr {
+ color: #7c3aed;
+}
+
+html[data-theme="light"] .markdown-body .chroma .kt {
+ color: #7c3aed;
+}
+
+html[data-theme="light"] .markdown-body .chroma .n {
+ color: #1f2937;
+}
+
+html[data-theme="light"] .markdown-body .chroma .na {
+ color: #d97706;
+}
+
+html[data-theme="light"] .markdown-body .chroma .nb {
+ color: #2563eb;
+}
+
+html[data-theme="light"] .markdown-body .chroma .nc {
+ color: #d97706;
+}
+
+html[data-theme="light"] .markdown-body .chroma .nf {
+ color: #2563eb;
+}
+
+html[data-theme="light"] .markdown-body .chroma .nn {
+ color: #d97706;
+}
+
+html[data-theme="light"] .markdown-body .chroma .s {
+ color: #16a34a;
+}
+
+html[data-theme="light"] .markdown-body .chroma .s1 {
+ color: #16a34a;
+}
+
+html[data-theme="light"] .markdown-body .chroma .s2 {
+ color: #16a34a;
+}
+
+html[data-theme="light"] .markdown-body .chroma .sb {
+ color: #16a34a;
+}
+
+html[data-theme="light"] .markdown-body .chroma .sc {
+ color: #16a34a;
+}
+
+html[data-theme="light"] .markdown-body .chroma .sd {
+ color: #16a34a;
+}
+
+html[data-theme="light"] .markdown-body .chroma .se {
+ color: #d97706;
+}
+
+html[data-theme="light"] .markdown-body .chroma .si {
+ color: #d97706;
+}
+
+html[data-theme="light"] .markdown-body .chroma .sr {
+ color: #16a34a;
+}
+
+html[data-theme="light"] .markdown-body .chroma .ss {
+ color: #16a34a;
+}
+
+html[data-theme="light"] .markdown-body .chroma .m {
+ color: #dc2626;
+}
+
+html[data-theme="light"] .markdown-body .chroma .mb {
+ color: #dc2626;
+}
+
+html[data-theme="light"] .markdown-body .chroma .mf {
+ color: #dc2626;
+}
+
+html[data-theme="light"] .markdown-body .chroma .mh {
+ color: #dc2626;
+}
+
+html[data-theme="light"] .markdown-body .chroma .mi {
+ color: #dc2626;
+}
+
+html[data-theme="light"] .markdown-body .chroma .mo {
+ color: #dc2626;
+}
+
+html[data-theme="light"] .markdown-body .chroma .o {
+ color: #7c3aed;
+}
+
+html[data-theme="light"] .markdown-body .chroma .ow {
+ color: #7c3aed;
+}
+
+html[data-theme="light"] .markdown-body .chroma .c {
+ color: #6b7280;
+ font-style: italic;
+}
+
+html[data-theme="light"] .markdown-body .chroma .c1 {
+ color: #6b7280;
+ font-style: italic;
+}
+
+html[data-theme="light"] .markdown-body .chroma .cm {
+ color: #6b7280;
+ font-style: italic;
+}
+
+html[data-theme="light"] .markdown-body .chroma .p {
+ color: #4b5563;
+}
+
+html[data-theme="light"] .markdown-body .chroma .g {
+ color: #dc2626;
+}
+
+html[data-theme="light"] .markdown-body .chroma .gd {
+ color: #dc2626;
+}
+
+html[data-theme="light"] .markdown-body .chroma .ge {
+ font-style: italic;
+}
+
+html[data-theme="light"] .markdown-body .chroma .gi {
+ color: #16a34a;
+}
+
+html[data-theme="light"] .markdown-body .chroma .gs {
+ font-weight: bold;
+}
+
+.mb-codeblock {
+ margin: 1.75rem 0;
+ border: 1px solid color-mix(in srgb, var(--color-border) 65%, transparent);
+ border-radius: 0.85rem;
+ overflow: hidden;
+ background: color-mix(in srgb, var(--color-surface) 35%, transparent);
+ box-shadow:
+ 0 4px 6px rgba(0, 0, 0, 0.1),
+ 0 10px 20px rgba(0, 0, 0, 0.15);
+ transition: box-shadow 0.2s ease-out;
+}
+
+.mb-codeblock:hover {
+ box-shadow:
+ 0 4px 6px rgba(0, 0, 0, 0.15),
+ 0 12px 24px rgba(0, 0, 0, 0.2);
+}
+
+html[data-theme="light"] .mb-codeblock {
+ background: #f9fafb;
+ border-color: #e5e7eb;
+ box-shadow:
+ 0 2px 4px rgba(0, 0, 0, 0.05),
+ 0 4px 8px rgba(0, 0, 0, 0.08);
+}
+
+html[data-theme="light"] .mb-codeblock:hover {
+ box-shadow:
+ 0 4px 8px rgba(0, 0, 0, 0.08),
+ 0 8px 16px rgba(0, 0, 0, 0.12);
+}
+
+.mb-codeblock-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0.7rem 1rem;
+ border-bottom: 1px solid color-mix(in srgb, var(--color-border) 55%, transparent);
+ background: color-mix(in srgb, var(--color-bg) 45%, transparent);
+ gap: 1rem;
+}
+
+html[data-theme="light"] .mb-codeblock-header {
+ background: #f3f4f6;
+ border-bottom-color: #e5e7eb;
+}
+
+.mb-codeblock-left {
+ display: flex;
+ align-items: center;
+ gap: 0.6rem;
+ min-width: 0;
+ flex: 1;
+}
+
+.mb-codeblock-badge {
+ font-size: 0.68rem;
+ font-weight: 700;
+ padding: 0.25rem 0.55rem;
+ border-radius: 0.35rem;
+ background: color-mix(in srgb, var(--color-accent) 22%, transparent);
+ color: var(--color-accent);
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
+ white-space: nowrap;
+ border: 1px solid color-mix(in srgb, var(--color-accent) 35%, transparent);
+}
+
+.mb-codeblock-filename {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.4rem;
+ color: var(--color-text);
+ font-size: 0.75rem;
+ font-weight: 500;
+ padding: 0.2rem 0.65rem;
+ border-radius: 0.35rem;
+ background: color-mix(in srgb, var(--color-bg) 35%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 20rem;
+}
+
+.mb-codeblock-actions {
+ display: flex;
+ gap: 0.4rem;
+ flex-shrink: 0;
+}
+
+.mb-action-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.35rem;
+ background: transparent;
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ color: var(--color-text-muted);
+ cursor: pointer;
+ font-size: 0.7rem;
+ font-weight: 500;
+ padding: 0.35rem 0.7rem;
+ border-radius: 0.4rem;
+ transition: all 0.15s ease-out;
+ font-family: inherit;
+ white-space: nowrap;
+}
+
+.mb-action-btn:hover {
+ color: var(--color-accent);
+ background: color-mix(in srgb, var(--color-accent) 12%, transparent);
+ border-color: var(--color-accent);
+ transform: translateY(-1px);
+ box-shadow: 0 2px 8px rgba(168, 85, 247, 0.2);
+}
+
+.mb-action-btn:active {
+ transform: translateY(0);
+}
+
+.mb-action-btn i {
+ font-size: 0.7rem;
+}
+
+.mb-btn-success {
+ color: #22c55e !important;
+ border-color: #22c55e !important;
+ background: color-mix(in srgb, #22c55e 15%, transparent) !important;
+}
+
+.mb-codeblock-content {
+ position: relative;
+ background: color-mix(in srgb, var(--color-bg) 20%, transparent);
+ transition: max-height 0.3s ease-out;
+}
+
+html[data-theme="light"] .mb-codeblock-content {
+ background: #ffffff;
+}
+
+.mb-codeblock-content pre {
+ margin: 0;
+ padding: 1.25rem 1.5rem;
+ overflow-x: auto;
+ background: transparent;
+ border: none;
+}
+
+.mb-codeblock-content pre code {
+ font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
+ font-size: 0.88rem;
+ line-height: 1.65;
+ font-weight: 400;
+}
+
+/* Custom scrollbar for code blocks */
+
+.mb-codeblock-content pre::-webkit-scrollbar {
+ height: 8px;
+}
+
+.mb-codeblock-content pre::-webkit-scrollbar-track {
+ background: color-mix(in srgb, var(--color-bg) 30%, transparent);
+ border-radius: 4px;
+}
+
+.mb-codeblock-content pre::-webkit-scrollbar-thumb {
+ background: color-mix(in srgb, var(--color-border) 70%, transparent);
+ border-radius: 4px;
+}
+
+.mb-codeblock-content pre::-webkit-scrollbar-thumb:hover {
+ background: var(--color-accent);
+}
+
+/* Collapse overlay */
+
+.mb-collapse-overlay {
+ display: none;
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(
+ to bottom,
+ transparent 0%,
+ rgba(0, 0, 0, 0.25) 35%,
+ rgba(0, 0, 0, 0.88) 100%
+ );
+ align-items: flex-end;
+ justify-content: center;
+ padding-bottom: 1.2rem;
+ cursor: pointer;
+ z-index: 10;
+ backdrop-filter: blur(1px);
+}
+
+.mb-expand-trigger {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.45rem;
+ padding: 0.5rem 1rem;
+ border-radius: 0.5rem;
+ border: 1px solid var(--color-accent);
+ background: color-mix(in srgb, var(--color-accent) 18%, transparent);
+ color: var(--color-accent);
+ font-size: 0.75rem;
+ font-weight: 650;
+ cursor: pointer;
+ transition: all 0.15s ease-out;
+ backdrop-filter: blur(10px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
+}
+
+.mb-expand-trigger:hover {
+ background: color-mix(in srgb, var(--color-accent) 28%, transparent);
+ transform: translateY(-2px);
+ box-shadow: 0 6px 16px rgba(168, 85, 247, 0.35);
+ border-color: color-mix(in srgb, var(--color-accent) 90%, white);
+}
+
+.mb-expand-trigger i {
+ font-size: 0.7rem;
+ animation: bounce-icon 1.8s ease-in-out infinite;
+}
+
+@keyframes bounce-icon {
+ 0%, 100% {
+ transform: translateY(0);
+ }
+
+ 50% {
+ transform: translateY(4px);
+ }
+}
+
+.mb-codeblock[data-lang="javascript"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="js"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #f7df1e 28%, transparent);
+ color: #f7df1e;
+ border-color: color-mix(in srgb, #f7df1e 40%, transparent);
+}
+
+.mb-codeblock[data-lang="typescript"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="ts"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #3178c6 28%, transparent);
+ color: #60a5fa;
+ border-color: color-mix(in srgb, #3178c6 40%, transparent);
+}
+
+.mb-codeblock[data-lang="python"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="py"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #3776ab 28%, transparent);
+ color: #60a5fa;
+ border-color: color-mix(in srgb, #3776ab 40%, transparent);
+}
+
+.mb-codeblock[data-lang="go"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #00add8 28%, transparent);
+ color: #22d3ee;
+ border-color: color-mix(in srgb, #00add8 40%, transparent);
+}
+
+.mb-codeblock[data-lang="rust"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="rs"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #ce422b 28%, transparent);
+ color: #fb923c;
+ border-color: color-mix(in srgb, #ce422b 40%, transparent);
+}
+
+.mb-codeblock[data-lang="html"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #e34c26 28%, transparent);
+ color: #f87171;
+ border-color: color-mix(in srgb, #e34c26 40%, transparent);
+}
+
+.mb-codeblock[data-lang="css"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #264de4 28%, transparent);
+ color: #60a5fa;
+ border-color: color-mix(in srgb, #264de4 40%, transparent);
+}
+
+.mb-codeblock[data-lang="bash"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="sh"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="shell"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #4eaa25 28%, transparent);
+ color: #86efac;
+ border-color: color-mix(in srgb, #4eaa25 40%, transparent);
+}
+
+.mb-codeblock[data-lang="json"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #888888 28%, transparent);
+ color: #d1d5db;
+ border-color: color-mix(in srgb, #888888 40%, transparent);
+}
+
+.mb-codeblock[data-lang="yaml"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="yml"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #cb171e 28%, transparent);
+ color: #fca5a5;
+ border-color: color-mix(in srgb, #cb171e 40%, transparent);
+}
+
+.mb-codeblock[data-lang="java"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #f89820 28%, transparent);
+ color: #fbbf24;
+ border-color: color-mix(in srgb, #f89820 40%, transparent);
+}
+
+.mb-codeblock[data-lang="cpp"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="c++"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #00599c 28%, transparent);
+ color: #60a5fa;
+ border-color: color-mix(in srgb, #00599c 40%, transparent);
+}
+
+.mb-codeblock[data-lang="c"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #555555 28%, transparent);
+ color: #9ca3af;
+ border-color: color-mix(in srgb, #555555 40%, transparent);
+}
+
+.mb-codeblock[data-lang="ruby"] .mb-codeblock-badge,
+ .mb-codeblock[data-lang="rb"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #cc342d 28%, transparent);
+ color: #f87171;
+ border-color: color-mix(in srgb, #cc342d 40%, transparent);
+}
+
+.mb-codeblock[data-lang="php"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #777bb4 28%, transparent);
+ color: #a78bfa;
+ border-color: color-mix(in srgb, #777bb4 40%, transparent);
+}
+
+.mb-codeblock[data-lang="sql"] .mb-codeblock-badge {
+ background: color-mix(in srgb, #e38c00 28%, transparent);
+ color: #fbbf24;
+ border-color: color-mix(in srgb, #e38c00 40%, transparent);
+}
+
+/* Responsive adjustments */
+
+@media (max-width: 640px) {
+ .mb-codeblock-header {
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 0.6rem;
+ }
+
+ .mb-codeblock-actions {
+ width: 100%;
+ justify-content: flex-end;
+ }
+
+ .mb-action-btn span {
+ display: none;
+ }
+
+ .mb-action-btn {
+ padding: 0.4rem;
+ width: 2rem;
+ height: 2rem;
+ justify-content: center;
+ }
+
+ .mb-codeblock-filename {
+ max-width: 100%;
+ }
+}
+
+@keyframes tech-marquee {
+ 0% {
+ transform: translateX(0);
+ }
+
+ 100% {
+ transform: translateX(-50%);
+ }
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .tech-strip-track {
+ animation: none;
+ }
+}
+
+/* gallery */
+
+.markdown-body .gallery-container {
+ margin: 2rem 0;
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
+ gap: 1rem;
+}
+
+@media (max-width: 640px) {
+ .markdown-body .gallery-container {
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+ gap: 0.75rem;
+ }
+}
+
+.markdown-body .gallery-container a {
+ display: block;
+ border: none !important;
+ padding: 0;
+ margin: 0;
+ border-radius: 0.5rem;
+ overflow: hidden;
+ transition: all 0.2s ease-out;
+ position: relative;
+ cursor: zoom-in;
+ aspect-ratio: 4/3;
+}
+
+.markdown-body .gallery-container a:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
+}
+
+.markdown-body .gallery-container img {
+ display: block;
+ width: 100%;
+ height: 100%;
+ -o-object-fit: cover;
+ object-fit: cover;
+ margin: 0;
+ border: none;
+ border-radius: 0.5rem;
+ transition: all 0.2s ease-out;
+}
+
+.markdown-body .gallery-container a:hover img {
+ filter: brightness(0.9);
+}
+
+/* ==================== */
+
+/* ABOUT PAGE */
+
+/* ==================== */
+
+/* ==========================================================================
+ TABLE OF CONTENTS
+ TOC sidebar, active link tracking, responsive behavior
+ ========================================================================== */
+
+.article-layout {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 2rem;
+ position: relative;
+ min-width: 0;
+}
+
+@media (min-width: 1024px) {
+ .article-layout {
+ grid-template-columns: 260px 1fr;
+ gap: 3rem;
+ }
+
+ .article-toc {
+ order: 1;
+ }
+
+ .article-main {
+ order: 2;
+ }
+}
+
+.article-main {
+ min-width: 0;
+ overflow-x: hidden;
+}
+
+.article-toc {
+ width: 100%;
+}
+
+.toc-wrapper {
+ position: sticky;
+ top: 2rem;
+ background: color-mix(in srgb, var(--color-surface) 50%, transparent);
+ border: 1px solid var(--color-border);
+ border-radius: 0.85rem;
+ padding: 1rem;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ backdrop-filter: blur(10px);
+ transition: all 0.2s ease-out;
+ max-height: calc(100vh - 24rem);
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+}
+
+.toc-wrapper:hover {
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
+ border-color: color-mix(in srgb, var(--color-accent) 40%, transparent);
+}
+
+.toc-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 0.75rem;
+ padding-bottom: 0.75rem;
+ border-bottom: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+}
+
+.toc-title {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ font-size: 0.85rem;
+ font-weight: 650;
+ color: var(--color-text);
+ margin: 0;
+}
+
+.toc-title i {
+ color: var(--color-accent);
+ font-size: 0.75rem;
+}
+
+.toc-toggle {
+ display: flex;
+ background: transparent;
+ border: 1px solid var(--color-border);
+ color: var(--color-text-muted);
+ width: 1.75rem;
+ height: 1.75rem;
+ border-radius: 0.4rem;
+ cursor: pointer;
+ transition: all 0.15s ease-out;
+ align-items: center;
+ justify-content: center;
+}
+
+.toc-toggle:hover {
+ color: var(--color-accent);
+ border-color: var(--color-accent);
+ background: color-mix(in srgb, var(--color-accent) 10%, transparent);
+}
+
+.toc-toggle i {
+ font-size: 0.7rem;
+ transition: transform 0.2s ease-out;
+}
+
+.toc-wrapper.collapsed .toc-toggle i {
+ transform: rotate(-90deg);
+}
+
+.toc-wrapper.collapsed .toc-nav {
+ max-height: 0;
+ opacity: 0;
+ overflow: hidden;
+}
+
+@media (max-width: 1023px) {
+ .toc-wrapper {
+ position: relative;
+ top: 0;
+ }
+}
+
+.toc-nav {
+ font-size: 0.8rem;
+ line-height: 1.6;
+ transition: all 0.3s ease-out;
+ overflow-y: auto;
+ overflow-x: hidden;
+ flex: 1;
+ min-height: 0;
+}
+
+/* Custom scrollbar for TOC */
+
+.toc-nav::-webkit-scrollbar {
+ width: 6px;
+}
+
+.toc-nav::-webkit-scrollbar-track {
+ background: color-mix(in srgb, var(--color-bg) 30%, transparent);
+ border-radius: 3px;
+}
+
+.toc-nav::-webkit-scrollbar-thumb {
+ background: color-mix(in srgb, var(--color-border) 70%, transparent);
+ border-radius: 3px;
+}
+
+.toc-nav::-webkit-scrollbar-thumb:hover {
+ background: var(--color-accent);
+}
+
+.toc-nav > ul {
+ list-style: none;
+ padding-left: 0;
+ margin: 0;
+}
+
+.toc-nav ul {
+ list-style: none;
+ margin: 0;
+}
+
+.toc-nav ul ul {
+ padding-left: 1rem;
+ margin-top: 0.25rem;
+ border-left: 1px solid color-mix(in srgb, var(--color-border) 50%, transparent);
+}
+
+.toc-nav li {
+ margin: 0.35rem 0;
+ padding-left: 0;
+}
+
+.toc-nav li:hover {
+ background: none;
+}
+
+.toc-nav a {
+ display: block;
+ padding: 0.35rem 0.5rem;
+ color: var(--color-text-muted);
+ text-decoration: none;
+ border-left: 2px solid transparent;
+ border-radius: 0.35rem;
+ transition: all 0.15s ease-out;
+ border-bottom: none;
+}
+
+.toc-nav a:hover {
+ color: var(--color-text);
+ background: color-mix(in srgb, var(--color-surface) 40%, transparent);
+ border-left-color: var(--color-accent);
+ transform: translateX(3px);
+}
+
+.toc-nav a.active {
+ color: var(--color-accent);
+ background: color-mix(in srgb, var(--color-accent) 12%, transparent);
+ border-left-color: var(--color-accent);
+ font-weight: 600;
+}
+
+/* Mobile: TOC appears at top */
+
+@media (max-width: 1023px) {
+ .article-toc {
+ order: -1;
+ margin-bottom: 1.5rem;
+ }
+}
+
+/* Pages */
+
+/* ==========================================================================
+ ABOUT PAGE STYLES
+ Standard about page with timeline
+ ========================================================================== */
+
+.about-page {
+ max-width: 900px;
+ margin-inline: auto;
+}
+
+.about-hero {
+ text-align: center;
+ padding: 3rem 0 4rem;
+ position: relative;
+}
+
+.about-hero::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 60px;
+ height: 3px;
+ background: linear-gradient(
+ 90deg,
+ transparent,
+ var(--color-accent),
+ transparent
+ );
+ border-radius: 999px;
+}
+
+.about-hero-content {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 1.5rem;
+}
+
+.about-avatar,
+ .about-avatar-placeholder {
+ width: 140px;
+ height: 140px;
+ border-radius: 50%;
+ overflow: hidden;
+ border: 3px solid var(--color-accent);
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2),
+ 0 0 0 8px color-mix(in srgb, var(--color-accent) 15%, transparent);
+ transition: all 0.3s ease-out;
+}
+
+.about-avatar:hover,
+ .about-avatar-placeholder:hover {
+ transform: translateY(-4px) scale(1.02);
+ box-shadow: 0 12px 32px rgba(0, 0, 0, 0.3),
+ 0 0 0 12px color-mix(in srgb, var(--color-accent) 20%, transparent);
+}
+
+.about-avatar img {
+ width: 100%;
+ height: 100%;
+ -o-object-fit: cover;
+ object-fit: cover;
+}
+
+.about-avatar-placeholder {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: linear-gradient(
+ 135deg,
+ color-mix(in srgb, var(--color-accent) 20%, transparent),
+ color-mix(in srgb, var(--color-accent) 10%, transparent)
+ );
+ backdrop-filter: blur(10px);
+}
+
+.about-avatar-placeholder i {
+ font-size: 4rem;
+ color: var(--color-accent);
+}
+
+.about-title {
+ font-size: 2.5rem;
+ font-weight: 700;
+ letter-spacing: -0.02em;
+ color: var(--color-text);
+ margin: 0;
+ line-height: 1.2;
+}
+
+.about-subtitle {
+ font-size: 1.1rem;
+ color: var(--color-text-muted);
+ max-width: 600px;
+ line-height: 1.6;
+ margin: 0;
+}
+
+.about-content {
+ margin-bottom: 4rem;
+}
+
+.about-content .card {
+ background: color-mix(in srgb, var(--color-surface) 60%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
+ padding: 2rem;
+}
+
+.about-content .markdown-body h3 {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ margin-top: 2.5rem;
+ padding-bottom: 0.5rem;
+ border-bottom: 2px solid color-mix(in srgb, var(--color-accent) 30%, transparent);
+}
+
+.about-content .markdown-body h3::before {
+ content: '';
+ display: inline-block;
+ width: 4px;
+ height: 1.5rem;
+ background: var(--color-accent);
+ border-radius: 999px;
+}
+
+/* Timeline */
+
+.timeline {
+ position: relative;
+ padding: 2rem 0 1rem 0;
+ margin-top: 2rem;
+}
+
+.timeline::before {
+ content: '';
+ position: absolute;
+ left: 20px;
+ top: 0;
+ bottom: 0;
+ width: 2px;
+ background: linear-gradient(
+ to bottom,
+ transparent,
+ var(--color-accent) 10%,
+ var(--color-accent) 90%,
+ transparent
+ );
+}
+
+.timeline-item {
+ position: relative;
+ padding-left: 60px;
+ margin-bottom: 3rem;
+}
+
+.timeline-item:last-child {
+ margin-bottom: 0;
+}
+
+.timeline-marker {
+ position: absolute;
+ left: 0;
+ top: 8px;
+ width: 42px;
+ height: 42px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 2;
+}
+
+.timeline-marker::before {
+ content: '';
+ position: absolute;
+ width: 16px;
+ height: 16px;
+ background: var(--color-accent);
+ border-radius: 50%;
+ border: 3px solid var(--color-bg);
+ box-shadow:
+ 0 0 0 4px color-mix(in srgb, var(--color-accent) 20%, transparent),
+ 0 4px 12px rgba(0, 0, 0, 0.3);
+ transition: all 0.3s ease-out;
+}
+
+.timeline-item:hover .timeline-marker::before {
+ transform: scale(1.3);
+ box-shadow:
+ 0 0 0 6px color-mix(in srgb, var(--color-accent) 30%, transparent),
+ 0 6px 16px rgba(0, 0, 0, 0.4);
+}
+
+.timeline-content {
+ background: color-mix(in srgb, var(--color-surface) 30%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 50%, transparent);
+ border-radius: 0.85rem;
+ padding: 1.5rem;
+ transition: all 0.3s ease-out;
+ position: relative;
+ overflow: hidden;
+}
+
+.timeline-content::before {
+ content: '';
+ position: absolute;
+ left: 0;
+ top: 0;
+ bottom: 0;
+ width: 4px;
+ background: var(--color-accent);
+ opacity: 0;
+ transition: opacity 0.3s ease-out;
+}
+
+.timeline-item:hover .timeline-content {
+ background: color-mix(in srgb, var(--color-surface) 50%, transparent);
+ border-color: color-mix(in srgb, var(--color-accent) 40%, transparent);
+ transform: translateX(4px);
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
+}
+
+.timeline-item:hover .timeline-content::before {
+ opacity: 1;
+}
+
+.timeline-content > p:first-child {
+ margin-top: 0;
+}
+
+.timeline-content > p:last-child {
+ margin-bottom: 0;
+}
+
+.timeline-content strong {
+ font-size: 1.1rem;
+ color: var(--color-text);
+ display: block;
+ margin-bottom: 0.25rem;
+}
+
+.timeline-content em {
+ font-size: 0.85rem;
+ color: var(--color-text-muted);
+ font-style: normal;
+ display: block;
+ margin-bottom: 0.75rem;
+}
+
+.timeline-content a {
+ color: var(--color-accent);
+}
+
+/* Remove hr from timeline */
+
+.timeline hr {
+ display: none;
+}
+
+.about-social {
+ text-align: center;
+ padding: 3rem 2rem;
+ background: color-mix(in srgb, var(--color-surface) 40%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ border-radius: 1.25rem;
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
+}
+
+.about-social-title {
+ font-size: 1.25rem;
+ font-weight: 650;
+ color: var(--color-text);
+ margin-bottom: 1.5rem;
+}
+
+.about-social-links {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 1rem;
+}
+
+.about-social-link {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.75rem 1.5rem;
+ border-radius: 999px;
+ background: color-mix(in srgb, var(--color-bg) 60%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
+ color: var(--color-text-muted);
+ text-decoration: none;
+ font-size: 0.9rem;
+ font-weight: 500;
+ transition: all 0.2s ease-out;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+}
+
+.about-social-link:hover {
+ transform: translateY(-2px);
+ background: color-mix(in srgb, var(--color-surface) 80%, transparent);
+ border-color: var(--color-accent);
+ color: var(--color-accent);
+ box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
+}
+
+.about-social-link i {
+ font-size: 1.1rem;
+}
+
+/* Responsive about page */
+
+@media (max-width: 640px) {
+ .about-hero {
+ padding: 2rem 0 3rem;
+ }
+
+ .about-avatar,
+ .about-avatar-placeholder {
+ width: 110px;
+ height: 110px;
+ }
+
+ .about-avatar-placeholder i {
+ font-size: 3rem;
+ }
+
+ .about-title {
+ font-size: 2rem;
+ }
+
+ .about-subtitle {
+ font-size: 1rem;
+ }
+
+ .about-social {
+ padding: 2rem 1.25rem;
+ }
+
+ .about-social-links {
+ flex-direction: column;
+ align-items: stretch;
+ }
+
+ .about-social-link {
+ justify-content: center;
+ }
+
+ /* Timeline responsive */
+
+ .timeline::before {
+ left: 12px;
+ }
+
+ .timeline-item {
+ padding-left: 40px;
+ }
+
+ .timeline-marker {
+ left: -5px;
+ width: 34px;
+ height: 34px;
+ }
+
+ .timeline-marker::before {
+ width: 12px;
+ height: 12px;
+ }
+
+ .timeline-content {
+ padding: 1rem;
+ }
+
+ .timeline-content strong {
+ font-size: 1rem;
+ }
+
+ .timeline-content em {
+ font-size: 0.8rem;
+ }
+}
+
+/* ==========================================================================
+ ABOUT ALTERNATIVE PAGE STYLES
+ Alternative about page with sidebar profile card
+ ========================================================================== */
+
+.page-int, .about-alt-page {
+ max-width: 1200px;
+ margin-inline: auto;
+}
+
+.about-alt-layout {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 2rem;
+ padding: 2rem 0;
+}
+
+@media (min-width: 1024px) {
+ .about-alt-layout {
+ grid-template-columns: 320px 1fr;
+ gap: 3rem;
+ }
+}
+
+/* Profile Card - Left Sidebar */
+
+.about-alt-sidebar {
+ position: relative;
+}
+
+.about-alt-profile-card {
+ background: linear-gradient(
+ 135deg,
+ color-mix(in srgb, var(--color-surface) 70%, transparent),
+ color-mix(in srgb, var(--color-surface) 50%, transparent)
+ );
+ border: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ border-radius: 1.5rem;
+ padding: 2rem;
+ text-align: center;
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
+ position: sticky;
+ top: 2rem;
+}
+
+.about-alt-avatar,
+ .about-alt-avatar-placeholder {
+ width: 120px;
+ height: 120px;
+ border-radius: 50%;
+ margin: 0 auto 1.5rem;
+ overflow: hidden;
+ border: 4px solid var(--color-accent);
+ box-shadow: 0 0 0 8px color-mix(in srgb, var(--color-accent) 15%, transparent);
+ transition: all 0.3s ease-out;
+}
+
+.about-alt-avatar:hover,
+ .about-alt-avatar-placeholder:hover {
+ transform: scale(1.05);
+ box-shadow: 0 0 0 12px color-mix(in srgb, var(--color-accent) 20%, transparent);
+}
+
+.about-alt-avatar img {
+ width: 100%;
+ height: 100%;
+ -o-object-fit: cover;
+ object-fit: cover;
+}
+
+.about-alt-avatar-placeholder {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: linear-gradient(
+ 135deg,
+ color-mix(in srgb, var(--color-accent) 30%, transparent),
+ color-mix(in srgb, var(--color-accent) 15%, transparent)
+ );
+}
+
+.about-alt-avatar-placeholder i {
+ font-size: 3rem;
+ color: var(--color-accent);
+}
+
+.about-alt-name {
+ font-size: 1.75rem;
+ font-weight: 700;
+ color: var(--color-text);
+ margin-bottom: 0.5rem;
+}
+
+.about-alt-role {
+ font-size: 0.9rem;
+ color: var(--color-text-muted);
+ line-height: 1.5;
+ margin-bottom: 1rem;
+}
+
+.about-alt-meta {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ font-size: 0.85rem;
+ color: var(--color-text-muted);
+ margin-bottom: 1.5rem;
+}
+
+.about-alt-meta i {
+ color: var(--color-accent);
+}
+
+/* Stats Grid */
+
+.about-alt-stats {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 1rem;
+ margin: 2rem 0;
+ padding: 1.5rem 0;
+ border-top: 1px solid color-mix(in srgb, var(--color-border) 50%, transparent);
+ border-bottom: 1px solid color-mix(in srgb, var(--color-border) 50%, transparent);
+}
+
+.about-alt-stat {
+ text-align: center;
+}
+
+.about-alt-stat-value {
+ font-size: 1.75rem;
+ font-weight: 700;
+ color: var(--color-accent);
+ margin-bottom: 0.25rem;
+}
+
+.about-alt-stat-label {
+ font-size: 0.7rem;
+ color: var(--color-text-muted);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+
+/* Social Icons */
+
+.about-alt-social {
+ display: flex;
+ justify-content: center;
+ gap: 0.75rem;
+ margin-top: 1.5rem;
+}
+
+.about-alt-social-icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 2.5rem;
+ height: 2.5rem;
+ border-radius: 50%;
+ background: color-mix(in srgb, var(--color-bg) 50%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ color: var(--color-text-muted);
+ transition: all 0.2s ease-out;
+}
+
+.about-alt-social-icon:hover {
+ background: var(--color-accent);
+ border-color: var(--color-accent);
+ color: white;
+ transform: translateY(-3px);
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.3);
+}
+
+.about-alt-social-icon i {
+ font-size: 1rem;
+}
+
+/* Content Area */
+
+.about-alt-content {
+ display: flex;
+ flex-direction: column;
+ gap: 2rem;
+}
+
+.about-alt-section {
+ background: color-mix(in srgb, var(--color-surface) 40%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ border-radius: 1.25rem;
+ padding: 2rem;
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
+}
+
+.about-alt-section-title {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ font-size: 1.5rem;
+ font-weight: 700;
+ color: var(--color-text);
+ margin-bottom: 1.5rem;
+ padding-bottom: 1rem;
+ border-bottom: 2px solid color-mix(in srgb, var(--color-accent) 20%, transparent);
+}
+
+.about-alt-section-title i {
+ color: var(--color-accent);
+ font-size: 1.25rem;
+}
+
+/* Experience Cards Grid */
+
+.about-alt-experience-grid {
+ display: grid;
+ gap: 1.5rem;
+}
+
+.about-alt-experience-card {
+ background: color-mix(in srgb, var(--color-bg) 40%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 50%, transparent);
+ border-left: 4px solid var(--color-accent);
+ border-radius: 0.85rem;
+ padding: 1.5rem;
+ transition: all 0.3s ease-out;
+ position: relative;
+ overflow: hidden;
+}
+
+.about-alt-experience-card::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 100px;
+ height: 100px;
+ background: radial-gradient(
+ circle at center,
+ color-mix(in srgb, var(--color-accent) 10%, transparent),
+ transparent 70%
+ );
+ opacity: 0;
+ transition: opacity 0.3s ease-out;
+}
+
+.about-alt-experience-card:hover {
+ border-left-width: 6px;
+ transform: translateX(6px);
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
+}
+
+.about-alt-experience-card:hover::before {
+ opacity: 1;
+}
+
+.about-alt-experience-card p:first-child {
+ margin-top: 0;
+}
+
+.about-alt-experience-card p:last-child {
+ margin-bottom: 0;
+}
+
+.about-alt-experience-card strong {
+ font-size: 1.1rem;
+ color: var(--color-text);
+ display: block;
+ margin-bottom: 0.25rem;
+}
+
+.about-alt-experience-card em {
+ font-size: 0.85rem;
+ color: var(--color-text-muted);
+ font-style: normal;
+ display: block;
+ margin-bottom: 0.75rem;
+}
+
+/* Skills Badge Cloud */
+
+.about-alt-skills {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.75rem;
+}
+
+.about-alt-skill {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.5rem 1rem;
+ background: color-mix(in srgb, var(--color-bg) 50%, transparent);
+ border: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
+ border-radius: 999px;
+ font-size: 0.85rem;
+ font-weight: 500;
+ color: var(--color-text);
+ transition: all 0.2s ease-out;
+ cursor: default;
+}
+
+.about-alt-skill i {
+ font-size: 1.1em;
+ opacity: 0.9;
+}
+
+.about-alt-skill:hover {
+ background: var(--color-accent);
+ border-color: var(--color-accent);
+ color: white;
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
+}
+
+.about-alt-skill:hover i {
+ opacity: 1;
+}
+
+/* Responsive */
+
+@media (max-width: 1023px) {
+ .about-alt-profile-card {
+ position: relative;
+ top: 0;
+ }
+
+ .about-alt-layout {
+ grid-template-columns: 1fr;
+ }
+}
+
+@media (max-width: 640px) {
+ .about-alt-profile-card {
+ padding: 1.5rem;
+ }
+
+ .about-alt-avatar,
+ .about-alt-avatar-placeholder {
+ width: 100px;
+ height: 100px;
+ }
+
+ .about-alt-name {
+ font-size: 1.5rem;
+ }
+
+ .about-alt-stats {
+ gap: 0.75rem;
+ }
+
+ .about-alt-stat-value {
+ font-size: 1.5rem;
+ }
+
+ .about-alt-section {
+ padding: 1.5rem;
+ }
+
+ .about-alt-section-title {
+ font-size: 1.25rem;
+ }
+
+ .about-alt-experience-card {
+ padding: 1.25rem;
+ }
+}
+
+/* ==================== */
+
+/* TABLE OF CONTENTS */
+
+/* ==================== */
+
+/* Responsive Styles */
+
+/* ==========================================================================
+ RESPONSIVE STYLES
+ Global responsive breakpoints and mobile optimizations
+ ========================================================================== */
+
+/* Mobile - Small screens (up to 640px) */
+
+@media (max-width: 640px) {
+ .card-pad {
+ padding: 1.25rem;
+ }
+
+ .layout-page {
+ padding-inline: 1rem;
+ padding-block: 1.5rem;
+ }
+
+ .layout-page-tight {
+ padding-inline: 1rem;
+ padding-block: 1rem;
+ }
+
+ /* Markdown body */
+
+ .markdown-body {
+ font-size: 0.9rem;
+ padding: 0;
+ }
+
+ /* Headings - scale down for mobile */
+
+ .markdown-body h1 {
+ font-size: 1.75rem;
+ }
+
+ .markdown-body h2 {
+ font-size: 1.35rem;
+ margin-top: 2rem;
+ }
+
+ .markdown-body h3 {
+ font-size: 1.15rem;
+ margin-top: 1.5rem;
+ }
+
+ .markdown-body h4 {
+ font-size: 1rem;
+ }
+
+ .markdown-body h5,
+ .markdown-body h6 {
+ font-size: 0.9rem;
+ }
+
+ /* Heading anchors - adjust for smaller screens */
+
+ .markdown-body .md-heading-anchor::before {
+ left: -1rem;
+ font-size: 0.85em;
+ }
+
+ /* Blockquotes */
+
+ .markdown-body blockquote,
+ .markdown-body .md-blockquote {
+ margin: 1.25rem 0;
+ padding: 1rem;
+ border-left-width: 3px;
+ }
+
+ .markdown-body blockquote::before,
+ .markdown-body .md-blockquote::before {
+ font-size: 2rem;
+ left: 0.5rem;
+ top: 0.25rem;
+ }
+
+ /* Alerts */
+
+ .markdown-body .md-alert {
+ padding: 0.85rem 1rem 0.85rem 2.5rem;
+ }
+
+ .markdown-body .md-alert::before {
+ left: 0.75rem;
+ top: 0.95rem;
+ font-size: 0.95rem;
+ }
+
+ /* Lists */
+
+ .markdown-body ul,
+ .markdown-body ol {
+ padding-left: 1.25rem;
+ }
+
+ /* Code blocks */
+
+ .markdown-body pre {
+ margin: 1rem -1rem;
+ border-radius: 0.5rem;
+ }
+
+ .markdown-body pre code {
+ font-size: 0.8rem;
+ padding: 1rem;
+ }
+
+ .mb-codeblock {
+ margin: 1.25rem -1rem;
+ border-radius: 0.5rem;
+ }
+
+ .mb-codeblock-content pre {
+ padding: 1rem;
+ }
+
+ .mb-codeblock-content pre code {
+ font-size: 0.8rem;
+ }
+
+ /* Inline code */
+
+ .markdown-body :not(pre) > code {
+ font-size: 0.85em;
+ padding: 0.1rem 0.35rem;
+ }
+
+ /* Tables - full bleed on mobile */
+
+ .markdown-body table {
+ font-size: 0.85rem;
+ }
+
+ .markdown-body th,
+ .markdown-body td {
+ padding: 0.5rem 0.65rem;
+ }
+
+ .markdown-body .table-wrap {
+ margin: 1.25rem -1rem;
+ border-radius: 0.5rem;
+ }
+
+ /* Images */
+
+ .markdown-body img,
+ .markdown-body .md-image {
+ margin: 1.25rem 0;
+ }
+
+ .markdown-body .md-image a {
+ border-radius: 0.5rem;
+ }
+
+ .markdown-body .md-image a::after {
+ font-size: 2rem;
+ }
+
+ .markdown-body .md-image figcaption {
+ font-size: 0.82rem;
+ padding: 0.4rem 0.75rem;
+ }
+
+ /* Page heading */
+
+ .heading-page {
+ font-size: 1.75rem !important;
+ line-height: 1.2;
+ }
+
+ /* Article header */
+
+ .article-main header {
+ padding: 0;
+ }
+
+ /* TOC on mobile */
+
+ .toc-wrapper {
+ border-radius: 0.75rem;
+ padding: 0.85rem;
+ }
+
+ .toc-nav {
+ font-size: 0.85rem;
+ }
+}
+
+/* Tablet - Medium screens (641px to 1023px) */
+
+@media (min-width: 641px) and (max-width: 1023px) {
+ .article-layout {
+ display: flex;
+ flex-wrap: wrap;
+ }
+
+ .article-main {
+ max-width: -webkit-fill-available;
+ }
+
+ .layout-page {
+ padding-inline: 1.5rem;
+ padding-block: 2rem;
+ }
+
+ .markdown-body {
+ font-size: 0.93rem;
+ }
+
+ .markdown-body h1 {
+ font-size: 1.85rem;
+ }
+
+ .markdown-body h2 {
+ font-size: 1.4rem;
+ }
+
+ .markdown-body h3 {
+ font-size: 1.2rem;
+ }
+}
+
+/* Larger screens - Adjust max-widths */
+
+@media (min-width: 1536px) {
+ .article-layout {
+ padding-inline: 2rem;
+ }
+}
+
+/* Ultra-wide screens */
+
+@media (min-width: 1920px) {
+ .markdown-body {
+ font-size: 1rem;
+ }
+}
+
+/* Touch device improvements */
+
+@media (hover: none) and (pointer: coarse) {
+ /* Increase tap targets for touch */
+
+ .toc-nav a {
+ padding: 0.5rem 0.65rem;
+ margin: 0.15rem 0;
+ }
+
+ .toc-toggle {
+ width: 2.5rem;
+ height: 2.5rem;
+ }
+
+ .mb-action-btn {
+ padding: 0.5rem 0.85rem;
+ font-size: 0.75rem;
+ }
+
+ /* Remove hover effects on touch devices */
+
+ .markdown-body li:hover {
+ background: none;
+ }
+
+ .card-hover:hover {
+ transform: none;
+ box-shadow: none;
+ }
+}
+
+/* Landscape mobile */
+
+@media (max-height: 500px) and (orientation: landscape) {
+ .toc-wrapper {
+ position: relative;
+ top: 0;
+ }
+
+ .layout-page {
+ padding-block: 1rem;
+ }
+}
+
+.last\:border-0:last-child {
+ border-width: 0px;
+}
+
+.hover\:text-accent:hover {
+ color: var(--color-accent);
+}
+
+.group:hover .group-hover\:text-accent {
+ color: var(--color-accent);
+}
+
+@media (min-width: 640px) {
+ .sm\:h-28 {
+ height: 7rem;
+ }
+
+ .sm\:w-28 {
+ width: 7rem;
+ }
+
+ .sm\:px-6 {
+ padding-left: 1.5rem;
+ padding-right: 1.5rem;
+ }
+
+ .sm\:text-3xl {
+ font-size: 1.875rem;
+ line-height: 2.25rem;
+ }
+
+ .sm\:text-4xl {
+ font-size: 2.25rem;
+ line-height: 2.5rem;
+ }
+}
+
+@media (min-width: 768px) {
+ .md\:order-none {
+ order: 0;
+ }
+
+ .md\:flex {
+ display: flex;
+ }
+
+ .md\:hidden {
+ display: none;
+ }
+
+ .md\:grid-cols-2 {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ }
+
+ .md\:grid-cols-\[minmax\(0\2c 2fr\)_minmax\(0\2c 1\.2fr\)\] {
+ grid-template-columns: minmax(0,2fr) minmax(0,1.2fr);
+ }
+
+ .md\:justify-end {
+ justify-content: flex-end;
+ }
+}
diff --git a/themes/minimal-black/static/icons/apple-touch-icon.png b/themes/minimal-black/static/icons/apple-touch-icon.png
new file mode 100644
index 0000000..0cb3ba6
Binary files /dev/null and b/themes/minimal-black/static/icons/apple-touch-icon.png differ
diff --git a/themes/minimal-black/static/icons/favicon-96x96.png b/themes/minimal-black/static/icons/favicon-96x96.png
new file mode 100644
index 0000000..7ad42ae
Binary files /dev/null and b/themes/minimal-black/static/icons/favicon-96x96.png differ
diff --git a/themes/minimal-black/static/icons/favicon.ico b/themes/minimal-black/static/icons/favicon.ico
new file mode 100644
index 0000000..c04a684
Binary files /dev/null and b/themes/minimal-black/static/icons/favicon.ico differ
diff --git a/themes/minimal-black/static/icons/favicon.svg b/themes/minimal-black/static/icons/favicon.svg
new file mode 100644
index 0000000..0774ac6
--- /dev/null
+++ b/themes/minimal-black/static/icons/favicon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/themes/minimal-black/static/icons/site.webmanifest b/themes/minimal-black/static/icons/site.webmanifest
new file mode 100644
index 0000000..0a0d4c8
--- /dev/null
+++ b/themes/minimal-black/static/icons/site.webmanifest
@@ -0,0 +1,21 @@
+{
+ "name": "Minimal Black",
+ "short_name": "M-BLK",
+ "icons": [
+ {
+ "src": "/web-app-manifest-192x192.png",
+ "sizes": "192x192",
+ "type": "image/png",
+ "purpose": "maskable"
+ },
+ {
+ "src": "/web-app-manifest-512x512.png",
+ "sizes": "512x512",
+ "type": "image/png",
+ "purpose": "maskable"
+ }
+ ],
+ "theme_color": "#ffffff",
+ "background_color": "#ffffff",
+ "display": "standalone"
+}
\ No newline at end of file
diff --git a/themes/minimal-black/static/icons/web-app-manifest-192x192.png b/themes/minimal-black/static/icons/web-app-manifest-192x192.png
new file mode 100644
index 0000000..72b6fc1
Binary files /dev/null and b/themes/minimal-black/static/icons/web-app-manifest-192x192.png differ
diff --git a/themes/minimal-black/static/icons/web-app-manifest-512x512.png b/themes/minimal-black/static/icons/web-app-manifest-512x512.png
new file mode 100644
index 0000000..350104d
Binary files /dev/null and b/themes/minimal-black/static/icons/web-app-manifest-512x512.png differ
diff --git a/themes/minimal-black/static/images/logo.png b/themes/minimal-black/static/images/logo.png
new file mode 100644
index 0000000..9551900
Binary files /dev/null and b/themes/minimal-black/static/images/logo.png differ
diff --git a/themes/minimal-black/static/js/gallery.js b/themes/minimal-black/static/js/gallery.js
new file mode 100644
index 0000000..290b493
--- /dev/null
+++ b/themes/minimal-black/static/js/gallery.js
@@ -0,0 +1,16 @@
+document.addEventListener("DOMContentLoaded", function () {
+ if (typeof window.$ === "undefined" && typeof window.JustifiedGallery === "undefined") {
+ // using vanilla JustifiedGallery from CDN, globally exposed
+ }
+
+ var roots = document.querySelectorAll("[data-jg]");
+ if (!roots.length || typeof window.JustifiedGallery === "undefined") return;
+
+ roots.forEach(function (el) {
+ new window.JustifiedGallery(el, {
+ rowHeight: 260,
+ lastRow: "center",
+ margin: 16,
+ });
+ });
+});
diff --git a/themes/minimal-black/static/js/lightbox.js b/themes/minimal-black/static/js/lightbox.js
new file mode 100644
index 0000000..72c9c7a
--- /dev/null
+++ b/themes/minimal-black/static/js/lightbox.js
@@ -0,0 +1,11 @@
+document.addEventListener("DOMContentLoaded", function () {
+ if (typeof GLightbox === "undefined") return;
+
+ GLightbox({
+ selector: ".glightbox",
+ loop: true,
+ touchNavigation: true,
+ zoomable: true,
+ draggable: true,
+ });
+});
diff --git a/themes/minimal-black/static/js/main.js b/themes/minimal-black/static/js/main.js
new file mode 100644
index 0000000..8d6951d
--- /dev/null
+++ b/themes/minimal-black/static/js/main.js
@@ -0,0 +1,137 @@
+(function () {
+ var STORAGE_KEY = "theme";
+ /* ---------- Theme ---------- */
+
+ function getStoredTheme() {
+ try {
+ return localStorage.getItem(STORAGE_KEY);
+ } catch (e) {
+ return null;
+ }
+ }
+
+ function storeTheme(theme) {
+ try {
+ localStorage.setItem(STORAGE_KEY, theme);
+ } catch (e) {}
+ }
+
+ function getSystemTheme() {
+ return window.matchMedia &&
+ window.matchMedia("(prefers-color-scheme: dark)").matches
+ ? "dark"
+ : "light";
+ }
+
+ function applyTheme(theme) {
+ document.documentElement.setAttribute("data-theme", theme);
+
+ var isDark = theme === "dark";
+ var lightIcons = document.querySelectorAll("[data-theme-icon-light]");
+ var darkIcons = document.querySelectorAll("[data-theme-icon-dark]");
+
+ lightIcons.forEach(function (el) {
+ el.style.display = isDark ? "" : "none";
+ });
+ darkIcons.forEach(function (el) {
+ el.style.display = isDark ? "none" : "";
+ });
+ }
+
+ function initThemeFromDOM() {
+ var attr = document.documentElement.getAttribute("data-theme");
+ if (attr === "dark" || attr === "light") {
+ applyTheme(attr);
+ return;
+ }
+ var stored = getStoredTheme();
+ applyTheme(stored || getSystemTheme());
+ }
+
+ function toggleTheme() {
+ var current =
+ document.documentElement.getAttribute("data-theme") || "light";
+ var next = current === "dark" ? "light" : "dark";
+ applyTheme(next);
+ storeTheme(next);
+ }
+
+ function initThemeToggle() {
+ var btns = document.querySelectorAll("[data-theme-toggle]");
+ if (!btns.length) return;
+ btns.forEach(function (btn) {
+ btn.addEventListener("click", toggleTheme);
+ });
+ }
+
+ /* ---------- Mobile nav ---------- */
+
+ function initMobileNav() {
+ var toggle = document.querySelector("[data-mobile-nav-toggle]");
+ var nav = document.querySelector("[data-mobile-nav]");
+ if (!toggle || !nav) return;
+
+ var open = false;
+ function setOpen(next) {
+ open = next;
+ nav.style.display = open ? "block" : "none";
+ }
+
+ toggle.addEventListener("click", function () {
+ setOpen(!open);
+ });
+
+ nav.addEventListener("click", function (e) {
+ if (e.target.tagName === "A") setOpen(false);
+ });
+ }
+
+ /* ---------- Dock ---------- */
+
+ function initDock() {
+ var dock = document.querySelector("[data-dock]");
+ if (!dock) return;
+
+ var toggle = dock.querySelector("[data-dock-toggle]");
+ var backTop = dock.querySelector('[data-dock-action="top"]');
+ var backBtn = dock.querySelector('[data-dock-action="back"]');
+ var open = false;
+
+ function setOpen(next) {
+ open = next;
+ dock.classList.toggle("dock--open", open);
+ }
+
+ if (toggle) {
+ toggle.addEventListener("click", function () {
+ setOpen(!open);
+ });
+ }
+
+ if (backTop) {
+ backTop.addEventListener("click", function (e) {
+ e.preventDefault();
+ window.scrollTo({
+ top: 0,
+ behavior: "smooth",
+ });
+ });
+ }
+
+ if (backBtn) {
+ backBtn.addEventListener("click", function (e) {
+ e.preventDefault();
+ window.history.back();
+ });
+ }
+ }
+
+ /* ---------- Init ---------- */
+
+ document.addEventListener("DOMContentLoaded", function () {
+ initThemeFromDOM();
+ initThemeToggle();
+ initMobileNav();
+ initDock();
+ });
+})();
diff --git a/themes/minimal-black/static/js/search.js b/themes/minimal-black/static/js/search.js
new file mode 100644
index 0000000..68496c2
--- /dev/null
+++ b/themes/minimal-black/static/js/search.js
@@ -0,0 +1,253 @@
+(function () {
+ var overlay, inputEl, resultsEl;
+ var indexLoaded = false;
+ var pages = [];
+
+ function ensureElements() {
+ if (!overlay) {
+ overlay = document.querySelector("[data-search-overlay]");
+ }
+ if (!inputEl && overlay) {
+ inputEl = overlay.querySelector("[data-search-input]");
+ }
+ if (!resultsEl && overlay) {
+ resultsEl = overlay.querySelector("[data-search-results]");
+ }
+ }
+
+ function loadIndex() {
+ if (indexLoaded) return;
+ indexLoaded = true;
+
+ fetch("/index.json")
+ .then(function (r) {
+ if (!r.ok) throw new Error("index.json not found");
+ return r.json();
+ })
+ .then(function (data) {
+ pages = (data && data.pages) || [];
+ })
+ .catch(function () {
+ pages = [];
+ });
+ }
+
+ function openOverlay() {
+ ensureElements();
+ if (!overlay) return;
+
+ overlay.classList.remove("search-overlay");
+ overlay.classList.add("search-overlay--open");
+ loadIndex();
+
+ if (inputEl) {
+ setTimeout(function () {
+ inputEl.focus();
+ }, 20);
+ }
+ }
+
+ function closeOverlay() {
+ ensureElements();
+ if (!overlay) return;
+
+ if (overlay.classList.contains("search-overlay--closing")) return;
+
+ overlay.classList.add("search-overlay--closing");
+
+ setTimeout(function () {
+ overlay.classList.remove("search-overlay--open");
+ overlay.classList.remove("search-overlay--closing");
+ overlay.classList.add("search-overlay");
+
+ if (inputEl) inputEl.value = "";
+
+ if (resultsEl) {
+ resultsEl.innerHTML =
+ '' +
+ '
' +
+ '
Start searching
' +
+ '
Enter keywords to search articles.
' +
+ "
";
+ }
+ }, 180);
+ }
+
+ function filterPages(query) {
+ if (!pages.length) return [];
+ var q = (query || "").toLowerCase().trim();
+ if (!q) return [];
+ return pages
+ .filter(function (p) {
+ var t = (p.title || "").toLowerCase();
+ var s = (p.summary || "").toLowerCase();
+ return t.indexOf(q) !== -1 || s.indexOf(q) !== -1;
+ })
+ .slice(0, 20);
+ }
+
+ function highlightText(text, query) {
+ if (!query) return text;
+ var regex = new RegExp("(" + query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + ")", "gi");
+ return text.replace(regex, '$1 ');
+ }
+
+ function getSectionIcon(section) {
+ var icons = {
+ blog: "fa-regular fa-note-sticky",
+ projects: "fa-regular fa-folder-open",
+ posts: "fa-regular fa-note-sticky",
+ };
+ return icons[section.toLowerCase()] || "fa-regular fa-file";
+ }
+
+ function truncateText(text, maxLength) {
+ if (!text || text.length <= maxLength) return text;
+ return text.substring(0, maxLength) + "...";
+ }
+
+ function renderResults(query) {
+ ensureElements();
+ if (!resultsEl) return;
+
+ var q = (query || "").trim();
+ if (!q) {
+ resultsEl.innerHTML =
+ '' +
+ '
' +
+ '
Start searching
' +
+ '
Enter keywords to search articles.
' +
+ "
";
+ return;
+ }
+
+ var matches = filterPages(q);
+ if (!matches.length) {
+ resultsEl.innerHTML =
+ '' +
+ '
' +
+ '
No results found
' +
+ '
Try different keywords or check your spelling.
' +
+ "
";
+ return;
+ }
+
+ var html = matches
+ .map(function (p, index) {
+ var title = highlightText(p.title || "Untitled", q);
+ var section = p.section || "";
+ var summary = truncateText(p.summary || "", 120);
+ var highlightedSummary = highlightText(summary, q);
+ var icon = getSectionIcon(section);
+ var date = p.date ? new Date(p.date).toLocaleDateString("en-US", {
+ year: "numeric",
+ month: "short",
+ day: "numeric"
+ }) : "";
+
+ return (
+ '' +
+ '" +
+ (highlightedSummary ? '' + highlightedSummary + "
" : "") +
+ " "
+ );
+ })
+ .join("");
+
+ resultsEl.innerHTML = html;
+
+ // Add keyboard navigation
+ addKeyboardNavigation();
+ }
+
+ var selectedIndex = -1;
+
+ function addKeyboardNavigation() {
+ ensureElements();
+ if (!inputEl) return;
+
+ var items = resultsEl.querySelectorAll(".search-result-item");
+
+ inputEl.addEventListener("keydown", function(e) {
+ if (e.key === "ArrowDown") {
+ e.preventDefault();
+ selectedIndex = Math.min(selectedIndex + 1, items.length - 1);
+ updateSelection(items);
+ } else if (e.key === "ArrowUp") {
+ e.preventDefault();
+ selectedIndex = Math.max(selectedIndex - 1, -1);
+ updateSelection(items);
+ } else if (e.key === "Enter" && selectedIndex >= 0) {
+ e.preventDefault();
+ items[selectedIndex].click();
+ }
+ });
+ }
+
+ function updateSelection(items) {
+ items.forEach(function(item, index) {
+ if (index === selectedIndex) {
+ item.classList.add("search-result-item--selected");
+ item.scrollIntoView({ block: "nearest", behavior: "smooth" });
+ } else {
+ item.classList.remove("search-result-item--selected");
+ }
+ });
+ }
+
+ function initSearch() {
+ ensureElements();
+ if (!overlay) return;
+
+ // Close and ESC
+ overlay.querySelectorAll("[data-search-close]").forEach(function (el) {
+ el.addEventListener("click", closeOverlay);
+ });
+
+ document.addEventListener("keydown", function (e) {
+ if (e.key === "Escape") closeOverlay();
+ });
+
+ // Typing
+ if (inputEl) {
+ inputEl.addEventListener("input", function (e) {
+ renderResults(e.target.value || "");
+ });
+ }
+
+ // Ctrl/Cmd + K to open
+ document.addEventListener("keydown", function (e) {
+ if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "k") {
+ e.preventDefault();
+ openOverlay();
+ }
+ });
+
+ // Expose global API for inline onclick
+ window.MinimalSearch = {
+ open: openOverlay,
+ close: closeOverlay,
+ };
+ }
+
+ if (document.readyState === "loading") {
+ document.addEventListener("DOMContentLoaded", initSearch);
+ } else {
+ initSearch();
+ }
+})();
diff --git a/themes/minimal-black/tailwind.config.js b/themes/minimal-black/tailwind.config.js
new file mode 100644
index 0000000..359a385
--- /dev/null
+++ b/themes/minimal-black/tailwind.config.js
@@ -0,0 +1,25 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ darkMode: ["class", '[data-theme="dark"]'],
+ content: [
+ "./layouts/**/*.html",
+ "./exampleSite/content/**/*.{md,html}",
+ "../../content/**/*.{md,html}",
+ ],
+ theme: {
+ extend: {
+ colors: {
+ bg: "var(--color-bg)",
+ surface: "var(--color-surface)",
+ text: "var(--color-text)",
+ muted: "var(--color-text-muted)",
+ border: "var(--color-border)",
+ accent: "var(--color-accent)",
+ },
+ maxWidth: {
+ "3xl": "48rem",
+ },
+ },
+ },
+ plugins: [require("@tailwindcss/typography")],
+};
diff --git a/themes/minimal-black/theme.toml b/themes/minimal-black/theme.toml
new file mode 100644
index 0000000..300d3f7
--- /dev/null
+++ b/themes/minimal-black/theme.toml
@@ -0,0 +1,29 @@
+name = "Minimal Black"
+license = "MIT"
+licenselink = "https://gitlab.com/jimchr12/hugo-minimal-black/blob/main/LICENSE"
+description = "A minimal, dark-mode first Hugo theme with true black backgrounds, purple accents, and comprehensive content styling. Features responsive design, search, TOC, and multiple page layouts."
+homepage = "https://gitlab.com/jimchr12/hugo-minimal-black"
+demosite = "https://minimal-black-demo.netlify.app"
+tags = ["blog", "portfolio", "minimal", "dark", "tailwind", "responsive", "clean", "modern", "personal"]
+features = [
+ "Dark Mode",
+ "Light Mode",
+ "Responsive Design",
+ "Search",
+ "Table of Contents",
+ "Syntax Highlighting",
+ "Google Analytics",
+ "Font Awesome Icons",
+ "Devicon Support",
+ "Multiple About Page Layouts",
+ "Project Portfolio",
+ "Blog",
+ "Gallery Shortcode",
+ "Mermaid Diagrams",
+ "GitHub Flavored Markdown"
+]
+min_version = "0.120.0"
+
+[author]
+ name = "Jim Christopoulos"
+ homepage = "https://jimchristopoulos.com/"