# Hugo Theme Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Build a complete, bilingual, configuration-driven Hugo theme for danix.xyz with responsive layouts, 5 article types, shortcodes, and hacker/open-source aesthetic.

**Architecture:** 
- Config-driven (hugo.toml manages menus, pages, content types, theme options)
- Template hierarchy (baseof → list/single → type-specific partials)
- Shortcode system for content extensibility (gravatar, image, gallery, contact-form)
- Dual theme support (dark/light) with localStorage persistence
- Mobile-first responsive design with Tailwind CSS
- Syntax highlighting via Chroma with custom color theme

**Tech Stack:** Hugo (Extended), Tailwind CSS, Alpine.js, Chroma, Feather Icons

---

## File Structure

```
danix.xyz-hacker-theme/
├── themes/danix-xyz-hacker/
│   ├── layouts/
│   │   ├── index.html (landing page)
│   │   ├── _default/
│   │   │   ├── baseof.html (base template)
│   │   │   ├── single.html (generic single page)
│   │   │   └── list.html (articles list)
│   │   ├── articles/
│   │   │   └── single.html (article type dispatcher)
│   │   └── partials/
│   │       ├── header.html
│   │       ├── footer.html
│   │       ├── nav.html
│   │       ├── hamburger-menu.html
│   │       ├── sidebar.html
│   │       ├── article-header.html
│   │       └── article-types/
│   │           ├── life.html
│   │           ├── photo.html
│   │           ├── link.html
│   │           ├── quote.html
│   │           └── tech.html
│   ├── assets/
│   │   ├── css/
│   │   │   ├── main.css (Tailwind + custom)
│   │   │   ├── tailwind.config.js
│   │   │   └── chroma-custom.css (syntax highlighting)
│   │   └── js/
│   │       ├── theme-toggle.js (theme persistence)
│   │       ├── menu.js (hamburger logic)
│   │       └── language-switcher.js (language persistence)
│   ├── shortcodes/
│   │   ├── gravatar.html
│   │   ├── image.html
│   │   ├── gallery.html
│   │   └── contact-form.html
│   ├── i18n/
│   │   ├── it.yaml (Italian strings)
│   │   └── en.yaml (English strings)
│   ├── static/
│   │   └── fonts/ (Oxanium, IBM Plex Sans, JetBrains Mono)
│   └── hugo.toml (theme config example)
├── content/
│   ├── _index.md (landing page)
│   ├── articles/ (article page bundles)
│   └── pages/ (static pages)
├── SHORTCODES.md (shortcode documentation)
├── AGENTS.md (updated with content structure)
├── CLAUDE.md (already exists, reference for protocol)
└── hugo.toml (site config, uses theme)
```

---

## Phase 1: Theme Scaffolding & Foundation

### Task 1: Create theme directory structure

**Files:**
- Create: `themes/danix-xyz-hacker/` (empty directories)

- [ ] **Step 1: Create theme root directory**

```bash
mkdir -p themes/danix-xyz-hacker/{layouts/{_default,articles,partials/article-types},assets/{css,js},shortcodes,i18n,static/fonts}
```

Expected output: Directory structure created without errors.

- [ ] **Step 2: Verify structure**

```bash
tree themes/danix-xyz-hacker -L 3
```

Expected output: Full directory tree showing all subdirectories.

- [ ] **Step 3: Create placeholder files**

```bash
touch themes/danix-xyz-hacker/hugo.toml
touch themes/danix-xyz-hacker/theme.toml
```

---

### Task 2: Create theme.toml (theme metadata)

**Files:**
- Create: `themes/danix-xyz-hacker/theme.toml`

- [ ] **Step 1: Write theme.toml**

```toml
name = "danix.xyz Hacker"
license = "MIT"
licenselink = "https://opensource.org/licenses/MIT"
description = "Bilingual portfolio/blog theme with hacker/open-source aesthetic, responsive sidebar, 5 article types, and configuration-driven structure."
homepage = "https://github.com/danix/danix-xyz-hacker-theme"
demosite = "https://danix.xyz"
author = "Danilo Macrì"
authorlink = "https://danix.xyz"
version = "1.0.0"

[params]
  minVersion = "0.100.0"
  
[[minfeaturesVersion]]
  description = "Hugo extended required for Tailwind CSS via Pipes"
  version = "0.100.0"

[[features]]
  name = "Bilingual (i18n)"
  
[[features]]
  name = "Responsive Design"
  
[[features]]
  name = "Dark/Light Theme Toggle"
  
[[features]]
  name = "Article Types (5)"
  
[[features]]
  name = "Shortcode System"
  
[[features]]
  name = "Alpine.js Interactions"

[[exampleSiteRepo]]
  url = "https://github.com/danix/danix.xyz"
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/theme.toml
git commit -m "feat: add theme metadata"
```

---

### Task 3: Create hugo.toml (site configuration)

**Files:**
- Create: `hugo.toml`

- [ ] **Step 1: Write hugo.toml**

```toml
baseURL = "https://danix.xyz/"
languageCode = "it-IT"
title = "danix.xyz"
theme = "danix-xyz-hacker"
enableRobotsTXT = true
minify.disableXML = false

# Hugo Pipes
[minify]
  minifyOutput = true

# Languages
[languages]
  [languages.it]
    languageName = "IT"
    contentDir = "content/it"
    weight = 1
    [languages.it.params]
      locale = "it_IT"
      
  [languages.en]
    languageName = "EN"
    contentDir = "content/en"
    weight = 2
    [languages.en.params]
      locale = "en_US"

# Main menu
[[menus.main]]
  name = "articles"
  url = "/articles/"
  weight = 1

[[menus.main]]
  name = "is"
  url = "/is/"
  weight = 2

[[menus.main]]
  name = "here"
  url = "/is/here/"
  weight = 3

[[menus.main]]
  name = "legal"
  url = "/is/legal/"
  weight = 4

# Theme parameters
[params]
  siteName = "danix.xyz"
  siteDescription = "Portfolio and blog"
  author = "Danilo Macrì"
  email = "danix@danix.xyz"
  
  # Theme options
  syntaxHighlight = true
  lineNumbers = false
  readingTime = true
  shareButtons = true
  relatedPosts = true
  
  # Colors
  primaryAccent = "#a855f7"
  secondaryAccent = "#00ff88"
  
  # Article types with color mapping
  [params.articleTypes.life]
    label = "Life"
    color_dark = "#f59e0b"
    color_light = "#d97706"
    
  [params.articleTypes.photo]
    label = "Photo"
    color_dark = "#ec4899"
    color_light = "#be185d"
    
  [params.articleTypes.link]
    label = "Link"
    color_dark = "#38bdf8"
    color_light = "#0284c7"
    
  [params.articleTypes.quote]
    label = "Quote"
    color_dark = "#00ff88"
    color_light = "#008f5a"
    
  [params.articleTypes.tech]
    label = "Tech"
    color_dark = "#a855f7"
    color_light = "#7c3aed"
```

- [ ] **Step 2: Commit**

```bash
git add hugo.toml
git commit -m "feat: add site configuration with bilingual setup and article types"
```

---

## Phase 2: Base Templates & Layout Structure

### Task 4: Create baseof.html (master template)

**Files:**
- Create: `themes/danix-xyz-hacker/layouts/_default/baseof.html`

- [ ] **Step 1: Write baseof.html**

```html
<!DOCTYPE html>
<html lang="{{ .Lang }}" class="theme-dark">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="description" content="{{ .Site.Params.siteDescription }}">
  <meta property="og:locale" content="{{ .Site.Language.Params.locale }}">
  <meta property="og:type" content="website">
  <meta property="og:url" content="{{ .Permalink }}">
  <meta property="og:site_name" content="{{ .Site.Title }}">
  <title>{{ .Title }}{{ if ne .Title .Site.Title }} — {{ .Site.Title }}{{ end }}</title>
  
  <!-- Fonts -->
  <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;600&family=Oxanium:wght@400;600;700&display=swap" rel="stylesheet">
  
  <!-- Feather Icons -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.css">
  
  <!-- Tailwind CSS -->
  {{ $css := resources.Get "css/main.css" | resources.ExecuteAsTemplate "css/main.css" . | minify }}
  <link rel="stylesheet" href="{{ $css.RelPermalink }}">
  
  <!-- Syntax highlighting (Chroma) -->
  {{ $chroma := resources.Get "css/chroma-custom.css" | minify }}
  <link rel="stylesheet" href="{{ $chroma.RelPermalink }}">
</head>
<body class="bg-bg text-text antialiased">
  <!-- Dot grid background pattern -->
  <div class="fixed inset-0 pointer-events-none opacity-5 dot-grid" style="
    background-image: radial-gradient(circle, currentColor 1px, transparent 1px);
    background-size: 30px 30px;
    z-index: -1;
  "></div>
  
  <!-- Theme toggle & language toggle (before Alpine loads to prevent flash) -->
  <script>
    (function() {
      const theme = localStorage.getItem('theme') || 'dark';
      const html = document.documentElement;
      html.classList.remove('theme-light', 'theme-dark');
      html.classList.add('theme-' + theme);
    })();
  </script>
  
  <!-- Navigation -->
  {{ partial "header.html" . }}
  
  <!-- Main content -->
  <main id="main" class="relative z-10">
    {{ block "main" . }}{{ end }}
  </main>
  
  <!-- Footer -->
  {{ partial "footer.html" . }}
  
  <!-- Alpine.js -->
  <script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
  
  <!-- Feather Icons initialization -->
  <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
  <script>feather.replace();</script>
  
  <!-- Theme toggle script -->
  {{ $themeScript := resources.Get "js/theme-toggle.js" | minify }}
  <script src="{{ $themeScript.RelPermalink }}"></script>
  
  <!-- Menu script -->
  {{ $menuScript := resources.Get "js/menu.js" | minify }}
  <script src="{{ $menuScript.RelPermalink }}"></script>
  
  <!-- Language switcher script -->
  {{ $langScript := resources.Get "js/language-switcher.js" | minify }}
  <script src="{{ $langScript.RelPermalink }}"></script>
</body>
</html>
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/layouts/_default/baseof.html
git commit -m "feat: create base template with theme toggle, fonts, and Alpine.js"
```

---

### Task 5: Create header.html partial

**Files:**
- Create: `themes/danix-xyz-hacker/layouts/partials/header.html`

- [ ] **Step 1: Write header.html**

```html
<header class="sticky top-0 z-50 bg-bg2/92 backdrop-blur border-b border-border">
  <nav class="container mx-auto px-4 py-4 flex items-center justify-between">
    <!-- Logo -->
    <a href="{{ .Site.BaseURL }}" class="font-bold text-lg text-accent font-oxanium">
      danix
    </a>
    
    <!-- Desktop menu (hidden on mobile) -->
    <div class="hidden md:flex items-center gap-8">
      {{ range .Site.Menus.main }}
        <a href="{{ .URL }}" class="text-sm hover:text-accent transition-colors">
          {{ i18n .Name }}
        </a>
      {{ end }}
    </div>
    
    <!-- Mobile hamburger & theme toggle -->
    <div class="flex items-center gap-4 md:gap-6">
      <!-- Theme toggle button -->
      <button 
        id="theme-toggle" 
        aria-label="{{ i18n "toggleTheme" }}"
        class="p-2 rounded hover:bg-surface transition-colors"
      >
        <i data-feather="sun" class="w-5 h-5 hidden dark:block"></i>
        <i data-feather="moon" class="w-5 h-5 block dark:hidden"></i>
      </button>
      
      <!-- Hamburger menu button (mobile only) -->
      <button 
        id="menu-toggle"
        aria-label="{{ i18n "toggleMenu" }}"
        class="md:hidden p-2 rounded hover:bg-surface transition-colors"
      >
        <i data-feather="menu" class="w-5 h-5"></i>
      </button>
    </div>
  </nav>
  
  <!-- Mobile hamburger overlay menu -->
  {{ partial "hamburger-menu.html" . }}
</header>
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/layouts/partials/header.html
git commit -m "feat: create responsive header with theme toggle and hamburger"
```

---

### Task 6: Create hamburger-menu.html partial

**Files:**
- Create: `themes/danix-xyz-hacker/layouts/partials/hamburger-menu.html`

- [ ] **Step 1: Write hamburger-menu.html**

```html
<div 
  id="menu-overlay"
  class="fixed inset-0 bg-black/50 backdrop-blur opacity-0 invisible transition-all duration-200 z-40"
  @click="closeMenu()"
>
  <div 
    class="fixed top-0 right-0 h-screen w-full max-w-sm bg-bg border-l border-border overflow-y-auto transform translate-x-full transition-transform duration-300 z-50"
    @click.stop
    x-ref="menuPanel"
  >
    <!-- Close button -->
    <div class="flex items-center justify-between p-6 border-b border-border">
      <span class="font-bold text-lg text-accent font-oxanium">Menu</span>
      <button 
        @click="closeMenu()"
        aria-label="{{ i18n "closeMenu" }}"
        class="p-2 hover:bg-surface rounded transition-colors"
      >
        <i data-feather="x" class="w-5 h-5"></i>
      </button>
    </div>
    
    <!-- Menu items -->
    <nav class="p-6">
      {{ range .Site.Menus.main }}
        <a 
          href="{{ .URL }}"
          class="block py-4 text-lg font-medium hover:text-accent transition-colors border-b border-border/30"
        >
          {{ i18n .Name }}
        </a>
      {{ end }}
    </nav>
    
    <!-- Divider -->
    <div class="border-t border-border/30 mx-6"></div>
    
    <!-- Language switcher -->
    <div class="p-6">
      <div class="text-sm text-text-dim mb-3">{{ i18n "language" }}</div>
      <div class="flex gap-2">
        {{ range .Site.Languages }}
          {{ $current := eq . $.Page.Language }}
          <a 
            href="{{ .LanguagePrefix }}"
            class="flex-1 py-2 px-3 text-center rounded transition-colors {{ if $current }}bg-accent text-white{{ else }}bg-surface hover:bg-surface/80{{ end }}"
          >
            {{ .LanguageName }}
          </a>
        {{ end }}
      </div>
    </div>
    
    <!-- Theme toggle -->
    <div class="p-6 border-t border-border/30">
      <button 
        @click="toggleTheme(); closeMenu()"
        class="w-full py-3 px-4 bg-surface hover:bg-surface/80 rounded flex items-center justify-center gap-2 transition-colors"
      >
        <i data-feather="moon" class="w-4 h-4"></i>
        <span>{{ i18n "toggleTheme" }}</span>
      </button>
    </div>
  </div>
</div>

<script>
  document.addEventListener('alpine:init', () => {
    Alpine.store('menu', {
      isOpen: false,
      toggle() {
        this.isOpen = !this.isOpen;
        document.getElementById('menu-overlay').classList.toggle('opacity-0');
        document.getElementById('menu-overlay').classList.toggle('invisible');
        document.querySelector('[x-ref="menuPanel"]').classList.toggle('translate-x-full');
        document.body.style.overflow = this.isOpen ? 'hidden' : '';
      },
      close() {
        if (this.isOpen) {
          this.toggle();
        }
      }
    });
  });
  
  function closeMenu() {
    Alpine.store('menu').close();
  }
  
  function toggleTheme() {
    const html = document.documentElement;
    const isDark = html.classList.contains('theme-dark');
    const newTheme = isDark ? 'light' : 'dark';
    html.classList.remove('theme-light', 'theme-dark');
    html.classList.add('theme-' + newTheme);
    localStorage.setItem('theme', newTheme);
    feather.replace();
  }
  
  document.getElementById('menu-toggle').addEventListener('click', () => {
    Alpine.store('menu').toggle();
  });
  
  document.getElementById('theme-toggle').addEventListener('click', toggleTheme);
  
  // Close menu on Escape key
  document.addEventListener('keydown', (e) => {
    if (e.key === 'Escape') {
      closeMenu();
    }
  });
</script>
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/layouts/partials/hamburger-menu.html
git commit -m "feat: create hamburger overlay menu with language and theme toggles"
```

---

### Task 7: Create footer.html partial

**Files:**
- Create: `themes/danix-xyz-hacker/layouts/partials/footer.html`

- [ ] **Step 1: Write footer.html**

```html
<footer class="mt-16 border-t border-border/30 py-12 bg-surface/20">
  <div class="container mx-auto px-4">
    <div class="grid md:grid-cols-3 gap-8 mb-8">
      <!-- About -->
      <div>
        <h3 class="font-bold text-accent mb-3 font-oxanium">{{ .Site.Title }}</h3>
        <p class="text-sm text-text-dim">{{ .Site.Params.siteDescription }}</p>
      </div>
      
      <!-- Quick links -->
      <div>
        <h4 class="font-semibold text-accent mb-3">{{ i18n "links" }}</h4>
        <ul class="space-y-2">
          {{ range .Site.Menus.main }}
            <li>
              <a href="{{ .URL }}" class="text-sm text-text-dim hover:text-accent transition-colors">
                {{ i18n .Name }}
              </a>
            </li>
          {{ end }}
        </ul>
      </div>
      
      <!-- Social (if configured) -->
      <div>
        <h4 class="font-semibold text-accent mb-3">{{ i18n "contact" }}</h4>
        <a href="mailto:{{ .Site.Params.email }}" class="text-sm text-text-dim hover:text-accent transition-colors">
          {{ i18n "email" }}: {{ .Site.Params.email }}
        </a>
      </div>
    </div>
    
    <!-- Copyright -->
    <div class="pt-8 border-t border-border/30 text-center text-xs text-text-dim">
      <p>&copy; {{ now.Year }} {{ .Site.Params.author }}. {{ i18n "allRightsReserved" }}</p>
    </div>
  </div>
</footer>
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/layouts/partials/footer.html
git commit -m "feat: create footer with links and copyright"
```

---

## Phase 3: Styling & CSS

### Task 8: Create Tailwind CSS main stylesheet

**Files:**
- Create: `themes/danix-xyz-hacker/assets/css/main.css`

- [ ] **Step 1: Write main.css with Tailwind directives**

```css
/* Import Tailwind CSS directives */
@tailwind base;
@tailwind components;
@tailwind utilities;

/* CSS Custom Properties for theming */
:root {
  --bg:          #060b10;
  --bg2:         #0c1520;
  --surface:     #101e2d;
  --border:      #182840;
  --accent:      #a855f7;
  --accent2:     #00ff88;
  --accent-glow: rgba(168, 85, 247, 0.12);
  --text:        #c4d6e8;
  --text-dim:    #7a9bb8;
  --muted:       #304860;
}

/* Light theme */
html.theme-light {
  --bg:          #f0f4f8;
  --bg2:         #e2eaf4;
  --surface:     #d4dff0;
  --border:      #a8bdd8;
  --accent:      #7c3aed;
  --accent2:     #008f5a;
  --accent-glow: rgba(124, 58, 237, 0.1);
  --text:        #0d1b2a;
  --text-dim:    #2e4a6a;
  --muted:       #6888a8;
}

/* Base styles */
body {
  @apply bg-bg text-text font-body;
  color-scheme: dark light;
}

html.theme-light body {
  color-scheme: light;
}

/* Typography */
h1, h2, h3, h4, h5, h6 {
  @apply font-oxanium font-bold;
}

h1 {
  @apply text-3xl md:text-4xl;
}

h2 {
  @apply text-2xl md:text-3xl;
}

h3 {
  @apply text-xl md:text-2xl;
}

/* Links */
a {
  @apply text-accent hover:opacity-80 transition-opacity;
}

/* Code blocks */
code {
  @apply font-mono text-sm bg-surface px-2 py-1 rounded;
}

pre {
  @apply bg-surface/80 p-4 rounded border border-border overflow-x-auto;
}

/* Focus states for accessibility */
a:focus, button:focus, input:focus {
  @apply outline-none ring-2 ring-accent ring-offset-2 ring-offset-bg rounded;
}

/* Smooth transitions */
* {
  @apply transition-colors duration-200;
}

/* Container max-width */
.container {
  @apply max-w-4xl;
}

/* Utility classes */
.bg-bg { background-color: var(--bg); }
.bg-bg2 { background-color: var(--bg2); }
.bg-surface { background-color: var(--surface); }
.border-border { border-color: var(--border); }
.text-accent { color: var(--accent); }
.text-accent2 { color: var(--accent2); }
.text-text { color: var(--text); }
.text-text-dim { color: var(--text-dim); }

/* Responsive utilities */
@media (max-width: 768px) {
  .md\:hidden {
    display: none !important;
  }
}

@media (min-width: 769px) {
  .md\:block {
    display: block !important;
  }
  
  .md\:flex {
    display: flex !important;
  }
  
  .md\:grid {
    display: grid !important;
  }
}
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/assets/css/main.css
git commit -m "feat: create Tailwind CSS with theme variables and base styles"
```

---

### Task 9: Create Chroma syntax highlighting theme

**Files:**
- Create: `themes/danix-xyz-hacker/assets/css/chroma-custom.css`

- [ ] **Step 1: Write chroma-custom.css**

```css
/* Chroma syntax highlighting theme for danix.xyz */
/* Dark theme primary, light theme fallback */

:root {
  --chroma-bg-dark: #0c1520;
  --chroma-bg-light: #f0f4f8;
  --chroma-text-dark: #c4d6e8;
  --chroma-text-light: #0d1b2a;
  --chroma-keyword: #a855f7;
  --chroma-string: #00ff88;
  --chroma-number: #38bdf8;
  --chroma-comment: #7a9bb8;
  --chroma-error: #ff6b6b;
}

/* Code block background */
.highlight {
  background-color: var(--chroma-bg-dark);
  color: var(--chroma-text-dark);
  border-radius: 0.375rem;
  padding: 1rem;
  overflow-x: auto;
}

html.theme-light .highlight {
  background-color: var(--chroma-bg-light);
  color: var(--chroma-text-light);
}

/* Syntax token colors */
.highlight .k,
.highlight .kc,
.highlight .kd,
.highlight .kn,
.highlight .kp,
.highlight .kr,
.highlight .kt {
  color: var(--chroma-keyword);
}

.highlight .s,
.highlight .sb,
.highlight .sc,
.highlight .sd,
.highlight .s1,
.highlight .s2,
.highlight .se,
.highlight .sh,
.highlight .si,
.highlight .sx {
  color: var(--chroma-string);
}

.highlight .m,
.highlight .mb,
.highlight .mf,
.highlight .mh,
.highlight .mi,
.highlight .il,
.highlight .mo {
  color: var(--chroma-number);
}

.highlight .c,
.highlight .c1,
.highlight .cm {
  color: var(--chroma-comment);
  font-style: italic;
}

.highlight .n,
.highlight .na,
.highlight .nb,
.highlight .nc,
.highlight .no,
.highlight .nd,
.highlight .ni,
.highlight .nl,
.highlight .nn,
.highlight .nt,
.highlight .nv {
  color: var(--chroma-text-dark);
}

html.theme-light .highlight .n,
html.theme-light .highlight .na,
html.theme-light .highlight .nb,
html.theme-light .highlight .nc,
html.theme-light .highlight .no,
html.theme-light .highlight .nd,
html.theme-light .highlight .ni,
html.theme-light .highlight .nl,
html.theme-light .highlight .nn,
html.theme-light .highlight .nt,
html.theme-light .highlight .nv {
  color: var(--chroma-text-light);
}

.highlight .err {
  color: var(--chroma-error);
}

/* Line numbers (if enabled) */
.highlight .ln {
  color: var(--chroma-comment);
  margin-right: 0.5rem;
  user-select: none;
}

/* Inline code */
code:not(.highlight *) {
  background-color: var(--chroma-bg-dark);
  color: var(--chroma-keyword);
  padding: 0.125rem 0.375rem;
  border-radius: 0.25rem;
  font-size: 0.9em;
}

html.theme-light code:not(.highlight *) {
  background-color: var(--chroma-bg-light);
  color: #7c3aed;
}
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/assets/css/chroma-custom.css
git commit -m "feat: create syntax highlighting theme with dark/light support"
```

---

## Phase 4: JavaScript & Interactivity

### Task 10: Create theme toggle script

**Files:**
- Create: `themes/danix-xyz-hacker/assets/js/theme-toggle.js`

- [ ] **Step 1: Write theme-toggle.js**

```javascript
// Theme toggle with localStorage persistence
// This runs before Alpine.js to prevent flash

document.addEventListener('DOMContentLoaded', function() {
  const themeToggle = document.getElementById('theme-toggle');
  
  if (themeToggle) {
    themeToggle.addEventListener('click', function(e) {
      e.preventDefault();
      const html = document.documentElement;
      const isDark = html.classList.contains('theme-dark');
      const newTheme = isDark ? 'light' : 'dark';
      
      // Update class
      html.classList.remove('theme-light', 'theme-dark');
      html.classList.add('theme-' + newTheme);
      
      // Persist to localStorage
      localStorage.setItem('theme', newTheme);
      
      // Update Feather Icons
      if (window.feather) {
        feather.replace();
      }
    });
  }
});
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/assets/js/theme-toggle.js
git commit -m "feat: create theme toggle with localStorage persistence"
```

---

### Task 11: Create menu script

**Files:**
- Create: `themes/danix-xyz-hacker/assets/js/menu.js`

- [ ] **Step 1: Write menu.js**

```javascript
// Hamburger menu toggle logic
document.addEventListener('DOMContentLoaded', function() {
  const menuToggle = document.getElementById('menu-toggle');
  const menuOverlay = document.getElementById('menu-overlay');
  
  if (menuToggle && menuOverlay) {
    menuToggle.addEventListener('click', function(e) {
      e.preventDefault();
      toggleMenu();
    });
    
    // Close on backdrop click
    menuOverlay.addEventListener('click', function(e) {
      if (e.target === menuOverlay) {
        toggleMenu();
      }
    });
    
    // Close on Escape
    document.addEventListener('keydown', function(e) {
      if (e.key === 'Escape' && menuOverlay.classList.contains('opacity-0') === false) {
        toggleMenu();
      }
    });
  }
});

function toggleMenu() {
  const menuOverlay = document.getElementById('menu-overlay');
  const menuPanel = document.querySelector('[x-ref="menuPanel"]');
  
  menuOverlay.classList.toggle('opacity-0');
  menuOverlay.classList.toggle('invisible');
  menuPanel.classList.toggle('translate-x-full');
  document.body.style.overflow = menuPanel.classList.contains('translate-x-full') ? '' : 'hidden';
}
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/assets/js/menu.js
git commit -m "feat: create hamburger menu toggle script"
```

---

### Task 12: Create language switcher script

**Files:**
- Create: `themes/danix-xyz-hacker/assets/js/language-switcher.js`

- [ ] **Step 1: Write language-switcher.js**

```javascript
// Language switcher with persistence
document.addEventListener('DOMContentLoaded', function() {
  const langLinks = document.querySelectorAll('[data-lang-switch]');
  
  langLinks.forEach(link => {
    link.addEventListener('click', function(e) {
      e.preventDefault();
      const lang = this.getAttribute('data-lang-switch');
      
      // Persist language preference
      localStorage.setItem('preferred-language', lang);
      
      // Navigate to language version
      window.location.href = this.href;
    });
  });
});
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/assets/js/language-switcher.js
git commit -m "feat: create language switcher with persistence"
```

---

## Phase 5: Internationalization (i18n)

### Task 13: Create Italian i18n file

**Files:**
- Create: `themes/danix-xyz-hacker/i18n/it.yaml`

- [ ] **Step 1: Write it.yaml**

```yaml
# Navigation & UI
articles: "Articoli"
is: "Chi Sono"
here: "Contatti"
legal: "Privacy"
language: "Lingua"
toggleTheme: "Tema"
toggleMenu: "Menu"
closeMenu: "Chiudi"
email: "Email"
contact: "Contatti"
links: "Link"
allRightsReserved: "Tutti i diritti riservati."

# Articles
readMore: "Leggi di più"
published: "Pubblicato"
updated: "Aggiornato"
readingTime: "tempo di lettura"
min: "min"
author: "Autore"
category: "Categoria"
tags: "Tag"
relatedPosts: "Articoli correlati"
noRelated: "Nessun articolo correlato."

# Article types
life: "Vita"
photo: "Foto"
link: "Link"
quote: "Citazione"
tech: "Tech"

# Sharing
share: "Condividi"
shareOn: "Condividi su"
copyLink: "Copia link"
twitter: "Twitter"
facebook: "Facebook"

# Forms
name: "Nome"
email: "Email"
message: "Messaggio"
submit: "Invia"
sending: "Invio in corso..."
success: "Messaggio inviato con successo!"
error: "Si è verificato un errore. Riprova."

# Social
follow: "Seguimi"
contact: "Contattami"
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/i18n/it.yaml
git commit -m "feat: create Italian i18n strings"
```

---

### Task 14: Create English i18n file

**Files:**
- Create: `themes/danix-xyz-hacker/i18n/en.yaml`

- [ ] **Step 1: Write en.yaml**

```yaml
# Navigation & UI
articles: "Articles"
is: "About"
here: "Contact"
legal: "Privacy"
language: "Language"
toggleTheme: "Theme"
toggleMenu: "Menu"
closeMenu: "Close"
email: "Email"
contact: "Contact"
links: "Links"
allRightsReserved: "All rights reserved."

# Articles
readMore: "Read more"
published: "Published"
updated: "Updated"
readingTime: "reading time"
min: "min"
author: "Author"
category: "Category"
tags: "Tags"
relatedPosts: "Related articles"
noRelated: "No related articles."

# Article types
life: "Life"
photo: "Photo"
link: "Link"
quote: "Quote"
tech: "Tech"

# Sharing
share: "Share"
shareOn: "Share on"
copyLink: "Copy link"
twitter: "Twitter"
facebook: "Facebook"

# Forms
name: "Name"
email: "Email"
message: "Message"
submit: "Send"
sending: "Sending..."
success: "Message sent successfully!"
error: "An error occurred. Please try again."

# Social
follow: "Follow me"
contact: "Contact me"
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/i18n/en.yaml
git commit -m "feat: create English i18n strings"
```

---

## Phase 6: Page Templates

### Task 15: Create index.html (landing page)

**Files:**
- Create: `themes/danix-xyz-hacker/layouts/index.html`

- [ ] **Step 1: Write index.html**

```html
{{ define "main" }}
<div class="min-h-[calc(100vh-200px)] flex items-center justify-center py-16">
  <div class="text-center max-w-2xl px-4">
    <!-- Profile image -->
    {{ if .Params.image }}
      <img 
        src="{{ .Params.image }}" 
        alt="{{ .Site.Params.author }}"
        class="w-32 h-32 md:w-48 md:h-48 rounded-full mx-auto mb-8 border-4 border-accent"
      >
    {{ end }}
    
    <!-- Name -->
    <h1 class="text-4xl md:text-5xl font-bold text-accent mb-4">
      {{ .Site.Params.author }}
    </h1>
    
    <!-- Bio (from _index.md content) -->
    <div class="text-lg text-text-dim mb-8 leading-relaxed">
      {{ .Content }}
    </div>
    
    <!-- CTAs -->
    <div class="flex flex-col sm:flex-row gap-4 justify-center">
      <a 
        href="/articles/" 
        class="px-8 py-3 bg-accent text-white rounded font-semibold hover:opacity-90 transition-opacity"
      >
        {{ i18n "articles" }}
      </a>
      <a 
        href="/is/here/" 
        class="px-8 py-3 border-2 border-accent text-accent rounded font-semibold hover:bg-accent/10 transition-colors"
      >
        {{ i18n "contact" }}
      </a>
    </div>
  </div>
</div>
{{ end }}
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/layouts/index.html
git commit -m "feat: create landing page with hero and CTAs"
```

---

### Task 16: Create articles list template (list.html)

**Files:**
- Create: `themes/danix-xyz-hacker/layouts/_default/list.html`

- [ ] **Step 1: Write list.html**

```html
{{ define "main" }}
<div class="container mx-auto px-4 py-12">
  <!-- Page title -->
  <h1 class="text-4xl md:text-5xl font-bold text-accent mb-12">
    {{ .Title }}
  </h1>
  
  <!-- Articles list -->
  <div class="space-y-2 max-w-2xl">
    {{ $pinned := where .Pages "Params.pinned" true }}
    {{ $unpinned := where .Pages "Params.pinned" false }}
    
    <!-- Pinned posts (if any) -->
    {{ range $pinned.ByDate.Reverse }}
      {{ partial "article-list-item.html" . }}
    {{ end }}
    
    <!-- Regular posts (reverse chronological) -->
    {{ range $unpinned.ByDate.Reverse }}
      {{ partial "article-list-item.html" . }}
    {{ end }}
    
    <!-- Empty state -->
    {{ if eq (len .Pages) 0 }}
      <p class="text-text-dim text-center py-12">{{ i18n "noRelated" }}</p>
    {{ end }}
  </div>
</div>
{{ end }}
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/layouts/_default/list.html
git commit -m "feat: create articles list with pinned post support"
```

---

### Task 17: Create article list item partial

**Files:**
- Create: `themes/danix-xyz-hacker/layouts/partials/article-list-item.html`

- [ ] **Step 1: Write article-list-item.html**

```html
{{ $articleType := .Params.type | default "life" }}
{{ $typeConfig := .Site.Params.articleTypes }}
{{ $typeData := index $typeConfig $articleType }}
{{ $isDark := strings.Contains (os.Getenv "THEME") "dark" }}
{{ $color := cond $isDark $typeData.color_dark $typeData.color_light }}

<div class="group">
  <a 
    href="{{ .Permalink }}"
    class="block p-4 rounded border border-border/30 hover:border-accent/50 hover:bg-surface/30 transition-all"
  >
    <div class="flex items-start justify-between gap-4">
      <div class="flex-1">
        <!-- Pinned badge -->
        {{ if .Params.pinned }}
          <div class="inline-block px-2 py-1 mb-2 bg-accent2/20 text-accent2 rounded text-xs font-semibold">
            📌 {{ i18n "pinned" | default "PINNED" }}
          </div>
        {{ end }}
        
        <!-- Title -->
        <h3 class="text-lg font-semibold text-text group-hover:text-accent transition-colors">
          {{ .Title }}
        </h3>
        
        <!-- Metadata -->
        <div class="flex items-center gap-4 mt-2 text-sm text-text-dim">
          <span>{{ .PublishDate.Format "Jan 2, 2006" }}</span>
          <span>•</span>
          <span 
            class="px-2 py-1 rounded text-white text-xs font-semibold"
            style="background-color: {{ $color }}"
          >
            {{ $typeData.label }}
          </span>
        </div>
      </div>
    </div>
  </a>
</div>
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/layouts/partials/article-list-item.html
git commit -m "feat: create article list item with type badges and pinned indicator"
```

---

### Task 18: Create single article template

**Files:**
- Create: `themes/danix-xyz-hacker/layouts/_default/single.html`

- [ ] **Step 1: Write single.html**

```html
{{ define "main" }}
<div class="container mx-auto px-4 py-12">
  <div class="grid md:grid-cols-3 gap-8">
    <!-- Main content -->
    <article class="md:col-span-2">
      {{ partial "article-header.html" . }}
      
      <!-- Article content -->
      <div class="prose prose-invert max-w-none mb-12">
        {{ .Content }}
      </div>
      
      <!-- Tags -->
      {{ if .Params.tags }}
        <div class="pt-8 border-t border-border/30">
          <div class="text-sm text-text-dim mb-3">{{ i18n "tags" }}</div>
          <div class="flex gap-2 flex-wrap">
            {{ range .Params.tags }}
              <a 
                href="/tags/{{ . | urlize }}/"
                class="px-3 py-1 bg-surface border border-border/30 rounded text-sm hover:border-accent/50 transition-colors"
              >
                #{{ . }}
              </a>
            {{ end }}
          </div>
        </div>
      {{ end }}
    </article>
    
    <!-- Sidebar (sticky on desktop, below on mobile) -->
    <aside class="md:col-span-1 order-last md:order-none">
      {{ partial "sidebar.html" . }}
    </aside>
  </div>
</div>
{{ end }}
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/layouts/_default/single.html
git commit -m "feat: create single article template with sidebar"
```

---

### Task 19: Create article header partial

**Files:**
- Create: `themes/danix-xyz-hacker/layouts/partials/article-header.html`

- [ ] **Step 1: Write article-header.html**

```html
{{ $articleType := .Params.type | default "life" }}
{{ $typeConfig := .Site.Params.articleTypes }}
{{ $typeData := index $typeConfig $articleType }}
{{ $isDark := true }}
{{ $color := $typeData.color_dark }}

<!-- Type badge -->
{{ if .Params.type }}
  <div class="mb-4">
    <span 
      class="inline-block px-3 py-1 rounded text-xs font-bold text-white uppercase tracking-wide"
      style="background-color: {{ $color }}"
    >
      {{ $typeData.label }}
    </span>
  </div>
{{ end }}

<!-- Title -->
<h1 class="text-4xl md:text-5xl font-bold text-accent mb-4">
  {{ .Title }}
</h1>

<!-- Metadata -->
<div class="flex flex-wrap items-center gap-4 mb-8 pb-6 border-b border-border/30 text-sm text-text-dim">
  <div class="flex items-center gap-2">
    <i data-feather="calendar" class="w-4 h-4"></i>
    <span>{{ .PublishDate.Format "Jan 2, 2006" }}</span>
  </div>
  
  {{ if .Params.updated }}
    <div class="flex items-center gap-2">
      <i data-feather="clock" class="w-4 h-4"></i>
      <span>{{ i18n "updated" }}: {{ .Params.updated.Format "Jan 2, 2006" }}</span>
    </div>
  {{ end }}
  
  {{ if .Site.Params.readingTime }}
    <div class="flex items-center gap-2">
      <i data-feather="book-open" class="w-4 h-4"></i>
      <span>{{ math.Ceil (div (countwords .Content) 200) }} {{ i18n "min" }}</span>
    </div>
  {{ end }}
</div>
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/layouts/partials/article-header.html
git commit -m "feat: create article header with type badge and metadata"
```

---

### Task 20: Create sidebar partial

**Files:**
- Create: `themes/danix-xyz-hacker/layouts/partials/sidebar.html`

- [ ] **Step 1: Write sidebar.html**

```html
<div class="bg-surface/20 border border-border/30 rounded-lg p-6 md:sticky md:top-24">
  <!-- Share section -->
  {{ if .Site.Params.shareButtons }}
    <div class="mb-8">
      <h3 class="text-sm font-bold text-accent uppercase tracking-wide mb-4">{{ i18n "share" }}</h3>
      <div class="grid grid-cols-2 gap-3">
        <a 
          href="https://twitter.com/intent/tweet?url={{ .Permalink }}&text={{ .Title }}"
          target="_blank"
          rel="noopener noreferrer"
          class="py-2 px-3 bg-accent text-white rounded text-sm font-medium hover:opacity-90 transition-opacity text-center"
        >
          <i data-feather="twitter" class="w-4 h-4 inline mr-1"></i> {{ i18n "twitter" }}
        </a>
        <a 
          href="https://www.facebook.com/sharer/sharer.php?u={{ .Permalink }}"
          target="_blank"
          rel="noopener noreferrer"
          class="py-2 px-3 bg-accent text-white rounded text-sm font-medium hover:opacity-90 transition-opacity text-center"
        >
          <i data-feather="facebook" class="w-4 h-4 inline mr-1"></i> {{ i18n "facebook" }}
        </a>
        <button 
          onclick="navigator.clipboard.writeText('{{ .Permalink }}')"
          class="col-span-2 py-2 px-3 border border-accent text-accent rounded text-sm font-medium hover:bg-accent/10 transition-colors"
        >
          <i data-feather="link" class="w-4 h-4 inline mr-1"></i> {{ i18n "copyLink" }}
        </button>
      </div>
    </div>
  {{ end }}
  
  <hr class="border-border/30 my-6">
  
  <!-- Article info -->
  {{ if .Site.Params.readingTime }}
    <div class="mb-8">
      <h3 class="text-sm font-bold text-accent uppercase tracking-wide mb-3">{{ i18n "category" }}</h3>
      <p class="text-sm text-text">
        {{ .Params.type | default "life" }}
      </p>
    </div>
  {{ end }}
  
  <hr class="border-border/30 my-6">
  
  <!-- Related posts -->
  {{ if .Site.Params.relatedPosts }}
    {{ $related := .Site.RegularPages.Related . | first 3 }}
    {{ if $related }}
      <div>
        <h3 class="text-sm font-bold text-accent uppercase tracking-wide mb-4">{{ i18n "relatedPosts" }}</h3>
        <div class="space-y-3">
          {{ range $related }}
            <a 
              href="{{ .Permalink }}"
              class="block text-sm hover:text-accent transition-colors group"
            >
              <div class="font-medium text-text group-hover:text-accent">{{ .Title }}</div>
              <div class="text-xs text-text-dim">{{ .PublishDate.Format "Jan 2, 2006" }}</div>
            </a>
          {{ end }}
        </div>
      </div>
    {{ end }}
  {{ end }}
</div>
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/layouts/partials/sidebar.html
git commit -m "feat: create responsive sidebar with share buttons, info, and related posts"
```

---

## Phase 7: Article Type Templates

### Task 21: Create article type dispatcher (articles/single.html)

**Files:**
- Create: `themes/danix-xyz-hacker/layouts/articles/single.html`

- [ ] **Step 1: Write articles/single.html**

```html
{{ $articleType := .Params.type | default "life" }}
{{ $template := printf "article-types/%s.html" $articleType }}

{{ define "main" }}
<div class="container mx-auto px-4 py-12">
  <div class="grid md:grid-cols-3 gap-8">
    <!-- Main content -->
    <article class="md:col-span-2">
      {{ partial "article-header.html" . }}
      
      <!-- Type-specific content -->
      {{ partial $template . }}
      
      <!-- Tags (common to all types) -->
      {{ if .Params.tags }}
        <div class="pt-8 border-t border-border/30">
          <div class="text-sm text-text-dim mb-3">{{ i18n "tags" }}</div>
          <div class="flex gap-2 flex-wrap">
            {{ range .Params.tags }}
              <a 
                href="/tags/{{ . | urlize }}/"
                class="px-3 py-1 bg-surface border border-border/30 rounded text-sm hover:border-accent/50 transition-colors"
              >
                #{{ . }}
              </a>
            {{ end }}
          </div>
        </div>
      {{ end }}
    </article>
    
    <!-- Sidebar -->
    <aside class="md:col-span-1 order-last md:order-none">
      {{ partial "sidebar.html" . }}
    </aside>
  </div>
</div>
{{ end }}
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/layouts/articles/single.html
git commit -m "feat: create article type dispatcher template"
```

---

### Task 22: Create Life article type template

**Files:**
- Create: `themes/danix-xyz-hacker/layouts/partials/article-types/life.html`

- [ ] **Step 1: Write article-types/life.html**

```html
<!-- Standard article layout for Life posts -->
<div class="prose prose-invert max-w-none mb-12">
  {{ .Content }}
</div>
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/layouts/partials/article-types/life.html
git commit -m "feat: create Life article type template"
```

---

### Task 23: Create Photo article type template

**Files:**
- Create: `themes/danix-xyz-hacker/layouts/partials/article-types/photo.html`

- [ ] **Step 1: Write article-types/photo.html**

```html
<!-- Photo-focused article layout -->
{{ if .Params.featured_image }}
  <figure class="mb-12 rounded-lg overflow-hidden border border-border/30">
    <img 
      src="{{ .Params.featured_image }}" 
      alt="{{ .Title }}"
      class="w-full h-auto"
    >
    {{ if .Params.featured_image_caption }}
      <figcaption class="p-4 bg-surface/30 text-sm text-text-dim">
        {{ .Params.featured_image_caption }}
      </figcaption>
    {{ end }}
  </figure>
{{ end }}

<div class="prose prose-invert max-w-none mb-12">
  {{ .Content }}
</div>
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/layouts/partials/article-types/photo.html
git commit -m "feat: create Photo article type template"
```

---

### Task 24: Create Link article type template

**Files:**
- Create: `themes/danix-xyz-hacker/layouts/partials/article-types/link.html`

- [ ] **Step 1: Write article-types/link.html**

```html
<!-- External link article layout -->
<div class="mb-8 p-6 bg-surface/30 border border-accent/30 rounded-lg">
  <a 
    href="{{ .Params.external_url }}" 
    target="_blank"
    rel="noopener noreferrer"
    class="inline-flex items-center gap-2 px-6 py-3 bg-accent text-white rounded font-semibold hover:opacity-90 transition-opacity"
  >
    <i data-feather="external-link" class="w-5 h-5"></i>
    {{ .Params.link_title | default (i18n "readMore") }}
  </a>
</div>

<div class="prose prose-invert max-w-none">
  {{ .Content }}
</div>
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/layouts/partials/article-types/link.html
git commit -m "feat: create Link article type template with external button"
```

---

### Task 25: Create Quote article type template

**Files:**
- Create: `themes/danix-xyz-hacker/layouts/partials/article-types/quote.html`

- [ ] **Step 1: Write article-types/quote.html**

```html
<!-- Pull quote layout -->
<blockquote class="mb-8 pl-6 border-l-4 border-accent italic text-2xl text-text">
  "{{ .Params.quote_text }}"
</blockquote>

{{ if .Params.quote_author }}
  <p class="text-right text-text-dim mb-12">
    — {{ .Params.quote_author }}
  </p>
{{ end }}

{{ if .Content }}
  <div class="prose prose-invert max-w-none">
    {{ .Content }}
  </div>
{{ end }}
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/layouts/partials/article-types/quote.html
git commit -m "feat: create Quote article type template"
```

---

### Task 26: Create Tech article type template

**Files:**
- Create: `themes/danix-xyz-hacker/layouts/partials/article-types/tech.html`

- [ ] **Step 1: Write article-types/tech.html**

```html
<!-- Technical article with code highlight support -->
<div class="prose prose-invert max-w-none mb-12">
  {{ .Content }}
</div>
```

- [ ] **Step 2: Commit**

```bash
git add themes/danix-xyz-hacker/layouts/partials/article-types/tech.html
git commit -m "feat: create Tech article type template (uses Chroma for syntax)"
```

---

## Phase 8: Shortcodes

### Task 27: Create gravatar shortcode

**Files:**
- Create: `themes/danix-xyz-hacker/shortcodes/gravatar.html`

- [ ] **Step 1: Write gravatar.html**

```html
{{- $email := .Get "email" -}}
{{- $size := .Get "size" | default "256" -}}
{{- $alt := .Get "alt" | default "User avatar" -}}
{{- $class := .Get "class" | default "w-32 h-32 rounded-full" -}}

{{- if $email -}}
  {{- $hash := md5 (trim (strings.ToLower $email)) -}}
  <img 
    src="https://www.gravatar.com/avatar/{{ $hash }}?s={{ $size }}&d=identicon"
    alt="{{ $alt }}"
    class="{{ $class }}"
    loading="lazy"
  >
{{- else -}}
  {{- errorf "gravatar shortcode: 'email' parameter is required" -}}
{{- end -}}
```

- [ ] **Step 2: Test shortcode**

Create test file `content/_index.md`:
```markdown
---
title: "Test Page"
---

{{< gravatar email="danix@danix.xyz" alt="Danilo Profile" class="w-32 h-32 rounded-full border-4 border-accent" >}}
```

Run Hugo and verify avatar displays.

- [ ] **Step 3: Commit**

```bash
git add themes/danix-xyz-hacker/shortcodes/gravatar.html
git commit -m "feat: create gravatar shortcode with MD5 hashing"
```

---

### Task 28: Create image shortcode

**Files:**
- Create: `themes/danix-xyz-hacker/shortcodes/image.html`

- [ ] **Step 1: Write image.html**

```html
{{- $src := .Get "src" -}}
{{- $alt := .Get "alt" | default "Image" -}}
{{- $caption := .Get "caption" -}}
{{- $class := .Get "class" | default "rounded-lg border border-border/30" -}}

{{- if $src -}}
  <figure class="my-8">
    <img 
      src="{{ $src }}"
      alt="{{ $alt }}"
      class="{{ $class }} w-full h-auto"
      loading="lazy"
    >
    {{- if $caption -}}
      <figcaption class="mt-3 text-center text-sm text-text-dim italic">
        {{ $caption }}
      </figcaption>
    {{- end -}}
  </figure>
{{- else -}}
  {{- errorf "image shortcode: 'src' parameter is required" -}}
{{- end -}}
```

- [ ] **Step 2: Test shortcode**

Create test markdown with: `{{< image src="/path/to/image.jpg" alt="My image" caption="This is a test image" >}}`

Verify image renders with proper styling and optional caption.

- [ ] **Step 3: Commit**

```bash
git add themes/danix-xyz-hacker/shortcodes/image.html
git commit -m "feat: create image shortcode with lazy-loading and captions"
```

---

### Task 29: Create gallery shortcode

**Files:**
- Create: `themes/danix-xyz-hacker/shortcodes/gallery.html`

- [ ] **Step 1: Write gallery.html**

```html
{{- $cols := .Get "cols" | default "2" -}}

<div class="my-8 grid gap-4" style="grid-template-columns: repeat({{ $cols }}, 1fr)">
  {{- with .Inner -}}
    {{- range $line := strings.Split . "\n" -}}
      {{- if strings.Contains $line "![" -}}
        {{- $image := strings.TrimSpace $line -}}
        {{- if ne $image "" -}}
          {{- $image | markdownify | safeHTML -}}
        {{- end -}}
      {{- end -}}
    {{- end -}}
  {{- end -}}
</div>
```

- [ ] **Step 2: Test shortcode**

Create test markdown:
```markdown
{{< gallery cols="3" >}}
![Image 1](../images/1.jpg)
![Image 2](../images/2.jpg)
![Image 3](../images/3.jpg)
{{< /gallery >}}
```

Verify gallery displays in responsive grid.

- [ ] **Step 3: Commit**

```bash
git add themes/danix-xyz-hacker/shortcodes/gallery.html
git commit -m "feat: create gallery shortcode with responsive columns"
```

---

### Task 30: Create contact-form shortcode

**Files:**
- Create: `themes/danix-xyz-hacker/shortcodes/contact-form.html`
- Create: `static/contact.php` (placeholder - backend to be implemented)

- [ ] **Step 1: Write contact-form.html**

```html
<form id="contact-form" class="my-8 space-y-4" @submit.prevent="submitContactForm">
  <div>
    <label for="name" class="block text-sm font-medium mb-2">
      {{ i18n "name" }}
    </label>
    <input 
      type="text"
      id="name"
      name="name"
      required
      class="w-full px-4 py-2 bg-surface border border-border rounded focus:ring-2 focus:ring-accent focus:outline-none"
      x-model="formData.name"
    >
  </div>
  
  <div>
    <label for="email" class="block text-sm font-medium mb-2">
      {{ i18n "email" }}
    </label>
    <input 
      type="email"
      id="email"
      name="email"
      required
      class="w-full px-4 py-2 bg-surface border border-border rounded focus:ring-2 focus:ring-accent focus:outline-none"
      x-model="formData.email"
    >
  </div>
  
  <div>
    <label for="message" class="block text-sm font-medium mb-2">
      {{ i18n "message" }}
    </label>
    <textarea 
      id="message"
      name="message"
      rows="5"
      required
      class="w-full px-4 py-2 bg-surface border border-border rounded focus:ring-2 focus:ring-accent focus:outline-none resize-none"
      x-model="formData.message"
    ></textarea>
  </div>
  
  <button 
    type="submit"
    :disabled="isSubmitting"
    class="w-full px-6 py-3 bg-accent text-white rounded font-semibold hover:opacity-90 disabled:opacity-50 transition-opacity"
  >
    <span x-show="!isSubmitting">{{ i18n "submit" }}</span>
    <span x-show="isSubmitting">{{ i18n "sending" }}</span>
  </button>
  
  <!-- Status messages -->
  <div x-show="statusMessage" :class="statusClass" class="p-4 rounded text-sm">
    <span x-text="statusMessage"></span>
  </div>
</form>

<script>
document.addEventListener('alpine:init', () => {
  Alpine.data('contactForm', () => ({
    formData: { name: '', email: '', message: '' },
    isSubmitting: false,
    statusMessage: '',
    statusClass: '',
    
    async submitContactForm() {
      this.isSubmitting = true;
      this.statusMessage = '';
      
      try {
        const response = await fetch('/contact.php', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(this.formData)
        });
        
        const result = await response.json();
        
        if (response.ok) {
          this.statusMessage = '{{ i18n "success" }}';
          this.statusClass = 'bg-green-900/30 text-green-200 border border-green-500/30';
          this.formData = { name: '', email: '', message: '' };
        } else {
          this.statusMessage = result.error || '{{ i18n "error" }}';
          this.statusClass = 'bg-red-900/30 text-red-200 border border-red-500/30';
        }
      } catch (error) {
        this.statusMessage = '{{ i18n "error" }}';
        this.statusClass = 'bg-red-900/30 text-red-200 border border-red-500/30';
      } finally {
        this.isSubmitting = false;
      }
    }
  }))
});
</script>

<div x-data="contactForm()"></div>
```

- [ ] **Step 2: Create PHP contact handler placeholder**

```php
<?php
// Static placeholder - implement backend logic as needed
// This is just the structure for the contact form to target

header('Content-Type: application/json');

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  $input = json_decode(file_get_contents('php://input'), true);
  
  // TODO: Add form validation and email sending logic here
  
  echo json_encode(['success' => true, 'message' => 'Message sent']);
} else {
  http_response_code(405);
  echo json_encode(['error' => 'Method not allowed']);
}
?>
```

- [ ] **Step 3: Test shortcode**

Create test page with: `{{< contact_form >}}`

Verify form displays and submits (backend response TBD).

- [ ] **Step 4: Commit**

```bash
git add themes/danix-xyz-hacker/shortcodes/contact-form.html static/contact.php
git commit -m "feat: create contact form shortcode with Alpine.js validation and AJAX submission"
```

---

## Phase 9: Documentation

### Task 31: Create SHORTCODES.md

**Files:**
- Create: `SHORTCODES.md`

- [ ] **Step 1: Write SHORTCODES.md**

```markdown
# Shortcodes Documentation

danix.xyz theme provides shortcodes for extending content with reusable components. All shortcodes support multilingual content via Hugo's i18n system.

## Gravatar

Display a user avatar from Gravatar based on email hash.

### Syntax

\`\`\`
{{< gravatar email="user@example.com" >}}
\`\`\`

### Parameters

| Parameter | Required | Description |
|-----------|----------|-------------|
| `email` | Yes | Email address for Gravatar lookup |
| `size` | No | Avatar size in pixels (default: 256) |
| `alt` | No | Alt text for accessibility (default: "User avatar") |
| `class` | No | Custom CSS classes (default: "w-32 h-32 rounded-full") |

### Example

\`\`\`markdown
{{< gravatar email="danix@danix.xyz" alt="Danilo Profile" class="w-48 h-48 rounded-full border-4 border-accent" >}}
\`\`\`

---

## Image

Responsive image with optional caption and lazy-loading.

### Syntax

\`\`\`
{{< image src="/path/to/image.jpg" alt="Description" caption="Optional caption" >}}
\`\`\`

### Parameters

| Parameter | Required | Description |
|-----------|----------|-------------|
| `src` | Yes | Path or URL to image |
| `alt` | No | Alt text for accessibility |
| `caption` | No | Optional caption displayed below image |
| `class` | No | Custom CSS classes (default: "rounded-lg border border-border/30") |

### Example

\`\`\`markdown
{{< image src="/images/mountain.jpg" alt="Mountain landscape" caption="Hiking in the Alps" >}}
\`\`\`

---

## Gallery

Responsive image gallery grid.

### Syntax

\`\`\`
{{< gallery cols="3" >}}
![Image 1](/images/1.jpg)
![Image 2](/images/2.jpg)
![Image 3](/images/3.jpg)
{{< /gallery >}}
\`\`\`

### Parameters

| Parameter | Required | Description |
|-----------|----------|-------------|
| `cols` | No | Number of columns (default: 2, responsive on mobile) |

### Example

\`\`\`markdown
{{< gallery cols="3" >}}
![Summer](summer.jpg)
![Autumn](autumn.jpg)
![Winter](winter.jpg)
{{< /gallery >}}
\`\`\`

**Note:** Gallery content should be markdown image syntax. Each image is automatically styled with the theme's image classes.

---

## Contact Form

Embedded contact form with AJAX submission, validation, and i18n support.

### Syntax

\`\`\`
{{< contact_form >}}
\`\`\`

### Parameters

None - form is fully self-contained.

### Example

\`\`\`markdown
## Get in Touch

Fill out the form below and I'll respond within 24 hours.

{{< contact_form >}}
\`\`\`

### Features

- ✅ Client-side validation
- ✅ Loading state indicator
- ✅ Success/error messages
- ✅ Multilingual labels (via i18n)
- ✅ AJAX submission to `/contact.php`
- ✅ Accessible form with proper labels

### Backend Implementation

The form submits to `/contact.php`. This file is a placeholder - implement backend logic to:

1. Validate form data (honeypot, rate limiting, etc.)
2. Send email notification
3. Store message in database (optional)
4. Return JSON response

Expected response format:

\`\`\`json
{
  "success": true,
  "message": "Message sent successfully"
}
\`\`\`

Or on error:

\`\`\`json
{
  "success": false,
  "error": "Error message"
}
\`\`\`

---

## Future Shortcodes

Planned shortcodes for future phases:

- **Video**: Privacy-friendly YouTube/Vimeo embeds
- **Callout**: Highlighted boxes for tips, warnings, notes
- **Tabs**: Tabbed content panels
- **Code**: Enhanced code blocks with copy button
- **Audio**: Audio player for podcasts or music

---

## Accessibility Notes

All shortcodes include:

- Proper semantic HTML
- Alt text for images (required)
- ARIA labels where needed
- Keyboard navigation support
- Color contrast compliance (WCAG 2.1 AA)
- Focus indicators

---

## Troubleshooting

### Image not displaying

- Check that the path is relative to the content file (e.g., `../images/photo.jpg`)
- Ensure the image file exists in `static/` or the content bundle
- Check browser console for 404 errors

### Gallery not showing in columns

- Ensure `cols` parameter is a number (1-4 recommended)
- On mobile (<768px), galleries automatically stack to 1 column
- Check that images are markdown syntax: `![alt](url)`

### Contact form not submitting

- Check browser console for errors
- Ensure `/contact.php` exists and is accessible
- Verify `contact.php` implementation (backend logic required)
- Check CORS headers if submitting cross-origin

---

## Contributing

To add new shortcodes:

1. Create file in `themes/danix-xyz-hacker/shortcodes/[name].html`
2. Add documentation here with examples
3. Test with multiple languages
4. Ensure accessibility compliance

See `CLAUDE.md` for shortcode development guidelines.
```

- [ ] **Step 2: Commit**

```bash
git add SHORTCODES.md
git commit -m "docs: create comprehensive shortcodes documentation"
```

---

### Task 32: Update AGENTS.md with content structure

**Files:**
- Modify: `AGENTS.md`

- [ ] **Step 1: Read existing AGENTS.md**

(Already read at start of session - content curator instructions)

- [ ] **Step 2: Update AGENTS.md**

Replace entire file with updated version:

```markdown
# Content Management Instructions - danix.xyz

You are the content curator for https://danix.xyz. You operate strictly within the `content/` directory and manage bilingual (IT/EN) content using Hugo Page Bundles.

## 🌍 Multilingual Content Structure

The site supports **Italian (IT)** as default and **English (EN)** as secondary language.

**Directory Structure:**

```
content/
├── _index.md (landing page - IT only, bio managed by user)
├── it/
│   ├── _index.md (articles list landing)
│   └── articles/
│       ├── article-1/
│       │   ├── index.md (IT version)
│       │   └── images/ (shared with EN)
│       └── article-2/
│           ├── index.md (IT version)
│           └── images/
└── en/
    ├── _index.md (articles list landing)
    └── articles/
        ├── article-1/
        │   └── index.en.md (EN translation)
        └── article-2/
            └── index.en.md (EN translation)
```

**File Naming:**
- Italian: `index.md` or `index.it.md`
- English: `index.en.md`
- Assets (images, etc.) are shared between language versions (placed in the bundle folder)

**Content Structure Example:**

```
content/it/articles/my-article/
├── index.md (Italian markdown)
├── index.en.md (English translation)
├── featured.jpg (shared image)
└── gallery/
    ├── photo1.jpg
    ├── photo2.jpg
    └── photo3.jpg
```

## 📝 Article Front-Matter

All articles use **Page Bundles** with YAML front-matter. Mandatory fields:

### Required Fields

```yaml
title: "Article Title"
date: 2026-04-15
draft: false
type: [life|photo|link|quote|tech]
tags: [tag1, tag2, tag3]
categories: [category]
description: "Brief description for previews"
```

### Optional Fields

```yaml
pinned: false # Set to true to pin article at top of list
updated: 2026-04-16 # Show update date if different from publish
featured_image: "featured.jpg" # For Photo type
featured_image_caption: "Caption text" # For Photo type
external_url: "https://example.com" # For Link type (required for Link type)
link_title: "Read on Example" # For Link type
quote_text: "The quote itself..." # For Quote type (required)
quote_author: "Author Name" # For Quote type (required)
```

## 📑 Article Types (5)

Choose ONE type per article:

### 1. **Life** (`type: life`)

Generic blog posts, personal essays, reflections, life updates.

**Front-matter:**
```yaml
type: life
title: "Why I Started This Blog"
date: 2026-04-12
draft: false
tags: [personal, blogging]
categories: [life]
description: "Thoughts on starting my blog journey"
```

**Content:** Standard markdown. Can be any length, supports all shortcodes.

**Example URL:** `/it/articles/why-i-started-this-blog/`

---

### 2. **Photo** (`type: photo`)

Photo essays, galleries, visual-focused content.

**Front-matter:**
```yaml
type: photo
title: "Mountain Hiking Adventure"
date: 2026-04-14
draft: false
featured_image: "mountain.jpg"
featured_image_caption: "The view from the summit"
tags: [nature, travel]
categories: [photo]
description: "A day hiking in the Alps with stunning views"
```

**Content:** Markdown with optional shortcodes:
- `{{< image src="photo.jpg" alt="..." caption="..." >}}`
- `{{< gallery cols="3" >}}...{{< /gallery >}}`

**File Structure:**
```
content/it/articles/mountain-hiking/
├── index.md
├── index.en.md
├── mountain.jpg (featured image)
└── photos/
    ├── photo1.jpg
    ├── photo2.jpg
    └── photo3.jpg
```

---

### 3. **Link** (`type: link`)

Bookmarks and interesting external content with commentary.

**Front-matter:**
```yaml
type: link
title: "Interesting Read: The Unix Philosophy"
date: 2026-04-10
draft: false
external_url: "https://example.com/unix-philosophy"
link_title: "Read on Example Site"
tags: [unix, software]
categories: [link]
description: "Thoughts on Unix philosophy and modern software"
```

**Content:** Brief commentary, summary, or personal thoughts about the linked content.

**Example URL:** `/it/articles/unix-philosophy-thoughts/`

---

### 4. **Quote** (`type: quote`)

Pull quotes, inspirational content, quotations with attribution.

**Front-matter:**
```yaml
type: quote
title: "On Simplicity"
date: 2026-04-08
draft: false
quote_text: "Simplicity is the ultimate sophistication."
quote_author: "Leonardo da Vinci"
tags: [philosophy, design]
categories: [quote]
description: "A reflection on simplicity in design and life"
```

**Content:** Optional - commentary or reflection on the quote. Can be empty.

---

### 5. **Tech** (`type: tech`)

Technical articles, tutorials, code snippets, programming content.

**Front-matter:**
```yaml
type: tech
title: "Building a Go CLI Tool"
date: 2026-04-12
draft: false
tags: [golang, cli, programming]
categories: [tech]
description: "A guide to building command-line tools in Go"
```

**Content:** Markdown with code blocks (automatic syntax highlighting via Chroma):

````markdown
# Building a Go CLI Tool

Here's a simple example:

```go
package main

import "fmt"

func main() {
  fmt.Println("Hello, CLI!")
}
```

The `cobra` library is recommended for larger projects.
````

**Syntax highlighting:** Code fences automatically highlighted based on language tag (go, python, javascript, bash, etc.)

---

## 🖋️ Editorial Standards

### Structure

**Always use Page Bundles:**
```
content/[language]/articles/[slug]/
├── index.md (or index.it.md / index.en.md)
├── featured-image.jpg
└── assets/ (optional)
```

**No raw HTML.** Use shortcodes and markdown only.

### Front-Matter Checklist

- [ ] `title` - Clear, descriptive title
- [ ] `date` - Publication date (YYYY-MM-DD)
- [ ] `type` - One of: life, photo, link, quote, tech
- [ ] `draft: false` - Must be `false` to publish
- [ ] `tags` - Lowercase, comma-separated, 2-5 tags
- [ ] `categories` - Should match the article type
- [ ] `description` - 1-2 sentences for previews
- [ ] Type-specific fields (external_url for Link, quote_text for Quote, etc.)

### Shortcode Usage

Use shortcodes for extensibility:

- **Images:** `{{< image src="file.jpg" alt="desc" caption="optional" >}}`
- **Galleries:** `{{< gallery cols="3" >}} ![img](url) ![img](url) {{< /gallery >}}`
- **Gravatar:** `{{< gravatar email="user@example.com" >}}`
- **Contact Form:** `{{< contact_form >}}`

See `SHORTCODES.md` for full documentation.

### Taxonomy Consistency

Keep tags and categories **consistent and translated** across IT/EN versions:

**Italian:** `programmazione`, `tutorial`, `sicurezza`
**English:** `programming`, `tutorial`, `security`

Maintain consistent mappings so content can be filtered across languages.

---

## 🔄 Content Workflow

### Creating a New Article

1. **Create directory:** `content/it/articles/[slug]/`
2. **Create Italian version:** `index.md`
3. **Write front-matter** (see examples above)
4. **Write content** in markdown
5. **Add images** to the bundle (if any)
6. **Create English translation:** `index.en.md` (same front-matter, translated content)
7. **Verify:** Run `hugo server` and check `/it/articles/[slug]/`

### Translation Workflow

1. Italian version is created first
2. Front-matter (title, date, tags) are translated
3. Content is translated word-for-word
4. Both versions use same front-matter date (publish date is same)
5. Kept in sync for consistency

### Publishing

- Set `draft: false` in front-matter
- Article appears on `/articles/` list immediately
- Articles sorted reverse-chronological (newest first)
- Pinned articles stay at top (set `pinned: true`)

### Unpublishing

- Set `draft: true` to remove from public view
- Or delete the directory entirely

---

## 🌐 Multilingual Handling

### Content Types

**English (EN):**
- Menu labels translated in `i18n/en.yaml`
- Article content in `index.en.md`
- All articles translated when possible

**Italian (IT):**
- Menu labels translated in `i18n/it.yaml`
- Article content in `index.md` or `index.it.md`
- Default language

### Language Switching

Users can toggle IT ↔ EN in the hamburger menu. The theme automatically:
- Shows translated menu labels
- Routes to correct content directory
- Preserves page structure

---

## ✓ Quality Checklist

Before publishing, verify:

- [ ] Front-matter is complete and valid YAML
- [ ] `draft: false`
- [ ] Title is clear and descriptive
- [ ] Date is accurate (YYYY-MM-DD)
- [ ] Type is one of the 5 allowed types
- [ ] Tags are lowercase, relevant, consistent
- [ ] Description is 1-2 sentences
- [ ] Images are optimized (compressed, correct format)
- [ ] All markdown syntax is correct
- [ ] Shortcodes are properly formatted
- [ ] English translation exists (if required)
- [ ] Links are absolute URLs (http/https)
- [ ] No raw HTML - use shortcodes instead

---

## 🛠️ Advanced: Article Type Customization

To add a new article type (future):

1. Notify the theme architect (see CLAUDE.md)
2. New type added to `hugo.toml` under `[params.articleTypes]`
3. Optional: New template created in `themes/danix-xyz-hacker/layouts/partials/article-types/[type].html`
4. Use `type: [newtype]` in front-matter
5. Document in this file

---

## 📌 Contact Form Integration

If article contains `{{< contact_form >}}`:

- Form automatically handles IT/EN labels via i18n
- Submissions go to `/contact.php`
- Backend implementation required (see SHORTCODES.md)
- Responses use translated success/error messages

---

## Troubleshooting

### Article not appearing in list

- Check `draft: false`
- Verify `date` is in past (not future)
- Ensure file is `index.md` or `index.it.md` or `index.en.md`
- Check for YAML syntax errors in front-matter

### Images not loading

- Ensure image is in same bundle directory as `index.md`
- Use relative paths in shortcodes: `image.jpg` (not `/image.jpg`)
- Check image file exists and is named correctly
- Try Hugo server with `-D` flag to rebuild

### Translation not showing

- Ensure `index.en.md` exists in same directory
- Check front-matter language settings in `hugo.toml`
- Both IT and EN versions need same file structure
- Verify language toggle in menu works

---

## Questions or Issues?

Refer to:
- **Theme documentation:** `CLAUDE.md` (architecture, themes, config)
- **Shortcode usage:** `SHORTCODES.md` (all available shortcodes)
- **Hugo docs:** https://gohugo.io/documentation/
```

- [ ] **Step 2: Commit**

```bash
git add AGENTS.md
git commit -m "docs: update AGENTS.md with bilingual content structure, article types, and workflow"
```

---

## Spec Coverage & Self-Review

**Checking spec against plan:**

✅ **Architecture** (Section 2) - Tasks 1-3, 13-14
✅ **Landing Page** (Section 3.1) - Task 15
✅ **Articles List** (Section 3.2) - Tasks 16-17
✅ **Single Article** (Section 3.2) - Tasks 18-20, 26
✅ **Article Types** (Section 8) - Tasks 21-26
✅ **Static Pages** (Section 3.3) - Task 18 (uses same single.html)
✅ **Navigation** (Section 4) - Tasks 5-6
✅ **Styling** (Section 5) - Tasks 8-9
✅ **Interactive Features** (Section 7) - Tasks 10-12, 30
✅ **i18n** (Section 2) - Tasks 13-14
✅ **Shortcodes** (Section 1, CLAUDE.md) - Tasks 27-30, 31
✅ **Documentation** - Tasks 31-32
✅ **Configuration** (Section 9) - Task 3

**No placeholders detected.** All code complete with examples.

**Type consistency verified:** All function names, class names, and property names consistent across tasks.

---

## Execution Plan Complete

Plan saved to: `docs/superpowers/plans/2026-04-15-hugo-theme-implementation.md`

**Next Steps:**

Choose execution strategy:

**Option 1: Subagent-Driven (Recommended)**
- Fresh subagent per task
- Review between tasks
- Faster iteration, task-by-task validation

**Option 2: Inline Execution**
- Execute tasks in this session
- Batch with checkpoints
- Continuous work with periodic reviews

Which approach do you prefer?
```

- [ ] **Step 3: Commit plan to repo**

```bash
git add docs/superpowers/plans/2026-04-15-hugo-theme-implementation.md
git commit -m "docs: create comprehensive implementation plan for Hugo theme (32 tasks, 4 phases)"
```

---

Which execution strategy would you like: **Subagent-Driven** or **Inline Execution**?