--- /dev/null
+# 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>© {{ 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" >}}
+
+
+
+{{< /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" >}}
+
+
+
+{{< /gallery >}}
+\`\`\`
+
+### Parameters
+
+| Parameter | Required | Description |
+|-----------|----------|-------------|
+| `cols` | No | Number of columns (default: 2, responsive on mobile) |
+
+### Example
+
+\`\`\`markdown
+{{< gallery cols="3" >}}
+
+
+
+{{< /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: ``
+
+### 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" >}}   {{< /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**?
\ No newline at end of file
--- /dev/null
+# danix.xyz Hugo Theme Design Specification
+
+**Date**: April 15, 2026
+**Project**: Hugo theme for personal portfolio/blog (https://danix.xyz)
+**Philosophy**: Slackware-style (clean, essential, no bloat) with hacker/open-source aesthetic
+
+---
+
+## 1. Project Overview
+
+danix.xyz is a **portfolio/blog site** with bilingual support (Italian/English). The theme must:
+- Deliver a modern, distinctive visual experience
+- Reuse font stack and color palette foundations from danix.me (but not replicate the design)
+- Support flexible, easy-to-configure content structure
+- Maintain accessibility (WCAG 2.1 AA)
+- Be responsive (mobile-first)
+
+---
+
+## 2. Architecture & Tech Stack
+
+### Theme Foundation
+- **Hugo (Extended)** with Hugo Pipes for asset processing and minification
+- **Tailwind CSS** (utility-first, @apply for semantic components)
+- **Alpine.js** for interactive elements (menu toggle, language switching, theme switching)
+- **Vanilla JS** for minimal optimizations where Alpine isn't needed
+- **Chroma** (Hugo's built-in syntax highlighter) for code blocks
+
+### Configuration-Driven Design
+**All major configuration** (menus, static pages, content types, theme options) lives in **hugo.toml**. This enables:
+- Easy addition of new static pages without touching code
+- Extensible article type system
+- Theme option management in one place
+
+### Multilingual Support (i18n)
+- **Structure**: `i18n/it.yaml` and `i18n/en.yaml` for all UI strings
+- **Default**: Italian (IT)
+- **Supported**: English (EN)
+- **Scope**: Navigation labels, button text, page headings, form labels, error messages
+- **Language switching**: Toggle in hamburger menu with state persistence
+
+---
+
+## 3. Content Structure
+
+### 3.1 Landing Page (`/`)
+**Source**: `content/_index.md` (front-matter + markdown)
+
+**Components**:
+- Hero section: Profile photo, name, brief bio (multilingual)
+- Two CTAs: "Read Articles" → `/articles/` | "Get in Touch" → `/is/here/`
+- Clean, centered layout
+- No feed or preview content
+
+**Layout**: Full-width, centered, vertical spacing emphasizes simplicity
+
+---
+
+### 3.2 Articles Section (`/articles/`)
+
+#### List View
+- **Sorting**: Reverse chronological (newest first)
+- **Pinned posts**: One post can stay at top via `pinned: true` in front-matter
+- **Display**: Title + date + type badge + excerpt (optional)
+- **Type badge colors**: Each article type has a distinct visual identifier
+
+#### Article Types (5)
+1. **Life** — Generic blog posts, personal thoughts, reflections
+2. **Photo** — Single image or gallery, visual-focused
+3. **Link** — External URL with commentary
+4. **Quote** — Pull quote with author attribution
+5. **Tech** — Code snippets, technical content, tutorials
+
+Color mapping:
+
+| Type | Dark Mode | Light Mode | Use |
+|---|---|---|---|
+| **Life** | `#f59e0b` (Amber) | `#d97706` (Amber) | Personal essays, life updates |
+| **Photo** | `#ec4899` (Pink) | `#be185d` (Pink) | Photo essays, galleries |
+| **Link** | `#38bdf8` (Cyan) | `#0284c7` (Cyan) | Bookmarks, external links |
+| **Quote** | `#00ff88` (Green) | `#008f5a` (Green) | Quotes, inspirational content |
+| **Tech** | `#a855f7` (Purple) | `#7c3aed` (Purple) | Technical articles, tutorials |
+
+Each type gets an optimized single-article template.
+
+#### Single Article View
+**Source**: `content/articles/[slug]/index.md` (Page Bundles)
+
+**Layout**:
+- **Desktop (1024px+)**: Two-column (main content + sticky sidebar)
+- **Mobile (<768px)**: Single column (sidebar moves to bottom)
+
+**Main Content**:
+- Type badge (e.g., "TECH")
+- Title (h1)
+- Metadata: Published date, updated date (if applicable), reading time
+- Article content (markdown with syntax-highlighted code blocks)
+- Tags (bottom of content)
+
+**Sidebar** (responsive positioning):
+- **Share section**: Twitter, Facebook, Copy Link buttons
+- **Article info**: Published date, updated date, reading time, category
+- **Related posts**: Links to 2-3 related articles
+- Desktop: Sticky positioning (stays visible during scroll)
+- Mobile: Flows to bottom of page
+
+**Syntax Highlighting**:
+- Language: Chroma (built-in Hugo)
+- Trigger: Markdown code fences with language tag (```go, ```python, etc.)
+- Theme: Custom CSS matching danix.xyz colors (purple accent #a855f7, green highlights #00ff88)
+- Options: Line numbers configurable in hugo.toml
+
+---
+
+### 3.3 Static Pages
+
+**URLs & Examples**:
+- `/is/` — About page
+- `/is/here/` — Contact page
+- `/is/legal/` — Privacy policy
+
+**Configuration**: All static page URLs defined in `hugo.toml` menus section. Adding new pages:
+1. Create markdown file in `content/pages/[slug]/index.md`
+2. Add menu entry to hugo.toml
+3. Theme automatically routes and renders
+
+**Layout**: Same two-column + sidebar structure as articles (desktop/mobile responsive)
+
+**Sidebar content** (per page):
+- About: Social links, skills, CV download, contact info
+- Contact: Email, response time, availability, social profiles
+- Legal: Last updated date, version info
+
+---
+
+## 4. Navigation & Menu System
+
+### Top Navigation (Desktop)
+- Logo/brand name on left
+- Menu items on right: Articles | About | Contact | Hamburger icon
+- Sticky positioning (stays visible while scrolling)
+- Light hover states
+
+### Hamburger Menu (Mobile + Desktop Open)
+**Trigger**: Hamburger icon (≡) top right
+
+**Full-screen overlay with**:
+- Main menu (Articles, About, Contact, Privacy, etc.)
+- Language switcher (IT/EN) with flag icons
+- Theme toggle (☀️ / 🌙)
+- Close button (X or backdrop click)
+
+**Alpine.js handling**:
+- Toggle class on `<html>` element to show/hide overlay
+- Language change: Update current language variable, navigate or reload
+- Theme change: Toggle `theme-light` / `theme-dark` class on `<html>`
+
+---
+
+## 5. Design & Visual Identity
+
+### Color Palette
+
+#### Dark Mode (Primary)
+- **Background**: #060b10 (deepest), #0c1520 (bg2), #101e2d (surface)
+- **Borders**: #182840
+- **Text**: #c4d6e8 (primary), #7a9bb8 (dim)
+- **Accent**: #a855f7 (purple primary), #00ff88 (green secondary)
+- **Glow**: rgba(168, 85, 247, 0.12)
+
+#### Light Mode
+- **Background**: #f0f4f8 (lightest), #e2eaf4 (bg2), #d4dff0 (surface)
+- **Borders**: #a8bdd8
+- **Text**: #0d1b2a (primary), #2e4a6a (dim)
+- **Accent**: #7c3aed (purple primary), #008f5a (green secondary)
+- **Glow**: rgba(124, 58, 237, 0.1)
+
+### Typography
+
+- **Headings**: Oxanium (sans-serif, distinctive, hacker-like)
+- **Body text**: IBM Plex Sans (modern, readable, professional)
+- **Code/Monospace**: JetBrains Mono (code blocks, inline code, terminal-style elements)
+
+**Font stack fallback**:
+```
+Oxanium, sans-serif
+IBM Plex Sans, system-ui, sans-serif
+JetBrains Mono, Courier New, monospace
+```
+
+### Visual Elements
+
+- **Dot-grid background**: Subtle radial-gradient pattern (repeating dots)
+ - Dark: rgba(168, 85, 247, 0.07) dots on #060b10
+ - Light: rgba(124, 58, 237, 0.07) dots on #f0f4f8
+
+- **Smooth transitions**: All interactive elements (200ms ease)
+
+- **Minimal glow effects**: Accent color glows on headings, badges, links (0 0 40px with low opacity)
+
+- **Clean borders**: 1px solid with accent color at 15-30% opacity
+
+- **Card/container styling**:
+ - Subtle background tint (accent color at 8-12% opacity)
+ - Border with accent at 20% opacity
+ - Border-radius: 0.4rem
+ - Shadow: None (keep clean)
+
+### Aesthetic Direction
+
+**Inspiration**: Open-source/hacker community aesthetic + Slackware philosophy
+
+**Characteristics**:
+- Clean, minimal, no unnecessary decoration
+- Modern but with technical roots (monospace touches, terminal vibes)
+- Purple + green color combination (distinctive, hacker-like)
+- Clear hierarchy and purpose for every element
+- Responsive and fast (no bloat)
+
+---
+
+## 5.1 Icons & Icon Fonts
+
+### Philosophy: Premium Monochrome Design
+
+Icons are part of the visual language, not decorative afterthoughts. The danix.xyz icon system uses **Feather Icons** for consistency:
+
+**Why Feather Icons:**
+- Minimalist aesthetic, premium appearance (not clipart-style)
+- Monochrome by default (pairs with any color)
+- Perfect stroke weight (1.5px) for clarity without heaviness
+- Comprehensive library (290+ icons covering common use cases)
+- Themeable via CSS (color, stroke, size all controllable)
+- Responsive at any size (crisp from 16px to 48px+)
+
+**Design principle:** Icons should be subtle, functional, and never draw more attention than the content they support.
+
+### Icon Sizing Scale
+
+Icons scale responsively based on context:
+
+```
+16px (0.85rem) — Small metadata, secondary actions
+20px (1.15rem) — Default, most contexts
+24px (1.4rem) — Buttons, interactive elements
+32px (1.9rem) — Large buttons, featured actions
+48px (2.8rem) — Hero elements, major CTAs
+```
+
+### Icon Colors: Context-Dependent Theming
+
+Icons inherit or explicitly use colors based on context. **Never use hard-coded colors—always use CSS custom properties:**
+
+### Icon Stroke: Weight and Line Style
+
+**Feather icons use consistent stroke properties:**
+
+**When to adjust stroke:**
+- Keep stroke-width at 1.5 for almost all cases
+- Only adjust if icon appears too thin or thick at specific sizes
+- Test at actual display size before adjusting
+
+### Article Metadata Icons
+
+**Common metadata icons:**
+
+| Icon | Name | Usage | Example |
+|---|---|---|---|
+| 📅 | `calendar` | Publication date | "2026-04-08" |
+| ⏱️ | `clock` | Read time | "5 min read" |
+| ✍️ | `user` | Author name | "By Danilo M." |
+| 🏷️ | `tag` | Article category/type | "TECH" badge |
+| 🔗 | `link` | External link | "Read on source" |
+
+## 6. Responsive Design
+
+### Breakpoints
+
+- **Mobile**: < 768px
+- **Tablet**: 768px - 1023px
+- **Desktop**: 1024px+
+
+### Mobile-First Approach
+
+**Default (mobile)**:
+- Single column layout
+- Hamburger menu for navigation
+- Sidebar content (articles) moves to bottom
+- Touch-friendly button sizes
+
+**Tablet (768px+)**:
+- Slightly increased padding/spacing
+- Wider content area
+- Sidebar still below on tablets
+
+**Desktop (1024px+)**:
+- Two-column layout (main + sidebar)
+- Full navigation visible
+- Sidebar sticky positioning (desktop articles/pages)
+- Optimized spacing and readability
+
+---
+
+## 7. Interactive Features
+
+### Alpine.js Interactions
+
+1. **Hamburger Menu Toggle**
+ - Click hamburger icon → overlay slides in / fades
+ - Click backdrop or close button → overlay closes
+ - Escape key closes overlay
+ - Body scroll disabled while overlay open
+
+2. **Language Switcher**
+ - Click language button (IT/EN) → switch language
+ - Persist preference to localStorage
+ - Page reloads with new language (or client-side routing if SPA-like)
+
+3. **Theme Toggle**
+ - Click sun/moon icon → toggle between dark/light
+ - Persist to localStorage
+ - Immediate class change on `<html>` element (no flash via inline script)
+
+4. **Contact Form** (shortcode-based)
+ - AJAX submission to `contact.php` (backend)
+ - Show loading state, success message, error handling
+ - Translated labels and error messages via i18n
+
+### No-JS Fallback
+
+- Navigation: Form-based or server-side page reload
+- Theme: CSS media query `prefers-color-scheme` as fallback
+- Menu: Full-page navigation links
+
+---
+
+## 8. Article Type Templates
+
+### Life
+**Layout**: Standard article (title, content, metadata, tags, sidebar)
+
+**Front-matter**:
+```yaml
+type: life
+title: Article Title
+date: 2026-04-12
+pinned: false
+draft: false
+tags: [tag1, tag2]
+categories: [life]
+description: Short description
+```
+
+### Photo
+**Layout**: Standard article with image/gallery focus
+**Front-matter**: Same as Life, but emphasizes `featured_image`
+
+### Link
+**Layout**: Title + external link button + commentary
+**Front-matter**:
+```yaml
+type: link
+title: Interesting Read
+external_url: https://example.com
+link_title: Read on Example Site
+```
+
+### Quote
+**Layout**: Large blockquote, author attribution, minimal text
+**Front-matter**:
+```yaml
+type: quote
+title: Quote Title
+quote_text: "The quote itself..."
+quote_author: Author Name
+```
+
+### Tech
+**Layout**: Standard article with code blocks, syntax-highlighted
+**Front-matter**: Same as Life, supports multiple code blocks
+
+---
+
+## 9. Configuration (hugo.toml)
+
+### Key Sections
+
+#### Languages
+```toml
+[languages.it]
+languageName = "IT"
+contentDir = "content/it"
+
+[languages.en]
+languageName = "EN"
+contentDir = "content/en"
+```
+
+#### Menus
+```toml
+[[menus.main]]
+name = "Articles"
+url = "/articles/"
+weight = 1
+
+[[menus.main]]
+name = "About"
+url = "/is/"
+weight = 2
+
+[[menus.footer]]
+name = "Privacy"
+url = "/is/legal/"
+```
+
+#### Theme Params
+```toml
+[params]
+# Site metadata
+siteName = "danix.xyz"
+author = "Danilo Macrì"
+description = "Portfolio and blog"
+
+# Theme options
+syntaxHighlight = true
+lineNumbers = false
+readingTime = true
+shareButtons = true
+relatedPosts = true
+
+# Colors (optional overrides)
+primaryAccent = "#a855f7"
+secondaryAccent = "#00ff88"
+```
+
+---
+
+## 10. Accessibility (WCAG 2.1 AA)
+
+- **Color contrast**: All text meets 4.5:1 (AA) for body text, 3:1 for larger text
+- **Semantic HTML**: Proper heading hierarchy, landmark regions, form labels
+- **Keyboard navigation**: All interactive elements accessible via keyboard
+- **Focus indicators**: Visible focus states on links and buttons
+- **Alt text**: Images have descriptive alt text
+- **Skip link**: Skip to main content link (hidden but keyboard-accessible)
+- **ARIA labels**: Where needed for icon buttons (hamburger, theme toggle)
+
+---
+
+## 11. Implementation Priorities
+
+### Phase 1 (MVP)
+- Basic layout (landing, articles list, single article, static pages)
+- Navigation and menu system
+- Bilingual support (i18n)
+- Dark/light theme toggle
+- Mobile responsive
+
+### Phase 2
+- Article type-specific templates
+- Pinned post support
+- Sidebar with metadata and sharing
+- Related posts section
+- Syntax highlighting
+
+### Phase 3 (Nice to have)
+- Contact form (AJAX)
+- Comment system (optional)
+- Search functionality
+- Analytics integration
+- Sitemap and RSS feeds
+
+---
+
+## 12. Extensibility
+
+### Adding New Static Pages
+1. Create file in `content/pages/[slug]/index.md`
+2. Add menu entry in hugo.toml
+3. Theme automatically routes (no template changes needed)
+
+### Adding New Article Types
+1. Define in hugo.toml under `[params.articleTypes]`
+2. Create partial template if special layout needed
+3. Use in front-matter `type: newtype`
+
+### Customizing Sidebar
+1. Define per-page in front-matter (e.g., `showSharing: true`, `showMetadata: true`)
+2. Sidebar partial checks flags and renders accordingly
+3. No CSS changes needed
+
+---
+
+## 13. File Structure (Overview)
+
+```
+themes/danix-xyz-hacker/
+├── layouts/
+│ ├── index.html (landing page)
+│ ├── _default/
+│ │ ├── baseof.html
+│ │ ├── single.html (articles/pages)
+│ │ └── list.html (articles list)
+│ ├── articles/
+│ │ ├── single.html (article types dispatch)
+│ │ └── [type]/single.html (type-specific)
+│ └── partials/
+│ ├── header.html
+│ ├── footer.html
+│ ├── nav.html
+│ ├── sidebar.html
+│ └── article-types/
+│ ├── life.html
+│ ├── photo.html
+│ ├── link.html
+│ ├── quote.html
+│ └── tech.html
+├── assets/
+│ ├── css/
+│ │ ├── main.scss
+│ │ ├── tailwind.css
+│ │ └── chroma-custom.css
+│ └── js/
+│ ├── main.js
+│ └── alpine-setup.js
+├── static/
+│ └── (images, fonts, files)
+├── i18n/
+│ ├── it.yaml
+│ └── en.yaml
+└── hugo.toml
+```
+
+---
+
+## 14. Success Criteria
+
+- ✅ Landing page with hero + CTAs
+- ✅ Articles list (reverse chrono, pinned support)
+- ✅ 5 article types with optimized templates
+- ✅ Static pages with custom URLs (all from config)
+- ✅ Bilingual (IT/EN) with language switcher
+- ✅ Dark/light theme toggle
+- ✅ Responsive (mobile-first, desktop sidebar)
+- ✅ Syntax highlighting for code blocks
+- ✅ Sidebar with share/metadata (sticky desktop, bottom mobile)
+- ✅ WCAG 2.1 AA accessibility
+- ✅ Zero unnecessary dependencies (Slackware philosophy)