diff options
13 files changed, 3947 insertions, 0 deletions
diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..467f827 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,7 @@ +{ + "permissions": { + "allow": [ + "Bash(/home/danix/.claude/plugins/cache/superpowers-marketplace/superpowers/5.0.6/skills/brainstorming/scripts/start-server.sh *)" + ] + } +} diff --git a/.superpowers/brainstorm/26102-1776256459/content/article-types.html b/.superpowers/brainstorm/26102-1776256459/content/article-types.html new file mode 100644 index 0000000..71f8533 --- /dev/null +++ b/.superpowers/brainstorm/26102-1776256459/content/article-types.html @@ -0,0 +1,93 @@ +<h2>Article Types & Sorting Strategy</h2> +<p class="subtitle">Five distinct content formats with intelligent ordering</p> + +<div class="section"> + <h3>Article Types</h3> + <div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.2rem;"> + <div style="padding: 1.2rem; background: rgba(168, 85, 247, 0.08); border-left: 3px solid #a855f7; border-radius: 0.4rem;"> + <h4 style="color: #a855f7; margin-bottom: 0.5rem;">📝 Life</h4> + <p style="font-size: 0.85rem; line-height: 1.6;">Generic blog posts. Personal thoughts, reflections, stories.</p> + <p style="font-size: 0.8rem; color: #7a9bb8; margin-top: 0.5rem;"><code>type: life</code></p> + </div> + <div style="padding: 1.2rem; background: rgba(0, 255, 136, 0.08); border-left: 3px solid #00ff88; border-radius: 0.4rem;"> + <h4 style="color: #00ff88; margin-bottom: 0.5rem;">📸 Photo</h4> + <p style="font-size: 0.85rem; line-height: 1.6;">Single photo or gallery. Visual-focused content with captions.</p> + <p style="font-size: 0.8rem; color: #7a9bb8; margin-top: 0.5rem;"><code>type: photo</code></p> + </div> + <div style="padding: 1.2rem; background: rgba(168, 85, 247, 0.08); border-left: 3px solid #a855f7; border-radius: 0.4rem;"> + <h4 style="color: #a855f7; margin-bottom: 0.5rem;">🔗 Link</h4> + <p style="font-size: 0.85rem; line-height: 1.6;">Interesting external URL. Commentary + link to external content.</p> + <p style="font-size: 0.8rem; color: #7a9bb8; margin-top: 0.5rem;"><code>type: link</code></p> + </div> + <div style="padding: 1.2rem; background: rgba(0, 255, 136, 0.08); border-left: 3px solid #00ff88; border-radius: 0.4rem;"> + <h4 style="color: #00ff88; margin-bottom: 0.5rem;">💬 Quote</h4> + <p style="font-size: 0.85rem; line-height: 1.6;">Pull quote with attribution. Emphasis on the quote itself.</p> + <p style="font-size: 0.8rem; color: #7a9bb8; margin-top: 0.5rem;"><code>type: quote</code></p> + </div> + <div style="padding: 1.2rem; background: rgba(168, 85, 247, 0.08); border-left: 3px solid #a855f7; border-radius: 0.4rem; grid-column: 1 / -1;"> + <h4 style="color: #a855f7; margin-bottom: 0.5rem;">💻 Tech</h4> + <p style="font-size: 0.85rem; line-height: 1.6;">Code snippets & technical content. Syntax-highlighted code, technical explanations.</p> + <p style="font-size: 0.8rem; color: #7a9bb8; margin-top: 0.5rem;"><code>type: tech</code></p> + </div> + </div> +</div> + +<div class="section"> + <h3>Articles List Sorting</h3> + <div class="mockup" style="padding: 1.5rem;"> + <div class="mockup-header">Articles Page (/articles/)</div> + <div class="mockup-body" style="padding: 1.5rem; background: rgba(6, 11, 16, 0.5); border-radius: 0.4rem;"> + <div style="font-family: 'IBM Plex Sans', sans-serif; line-height: 2;"> + <div style="padding: 0.8rem; background: rgba(168, 85, 247, 0.12); border: 1px solid rgba(168, 85, 247, 0.3); border-radius: 0.3rem; margin-bottom: 1rem;"> + <div style="font-size: 0.8rem; color: #00ff88; font-weight: bold; margin-bottom: 0.4rem;">📌 PINNED</div> + <div style="font-weight: bold; color: #a855f7;">Interesting Article Title</div> + <div style="font-size: 0.85rem; color: #7a9bb8;">Apr 14, 2026 • Life</div> + </div> + <div style="padding: 0.8rem; border-bottom: 1px solid rgba(168, 85, 247, 0.15); margin-bottom: 0.8rem;"> + <div style="font-weight: bold; color: #c4d6e8;">Another Great Post</div> + <div style="font-size: 0.85rem; color: #7a9bb8;">Apr 12, 2026 • Tech</div> + </div> + <div style="padding: 0.8rem; border-bottom: 1px solid rgba(168, 85, 247, 0.15); margin-bottom: 0.8rem;"> + <div style="font-weight: bold; color: #c4d6e8;">Photo Moments</div> + <div style="font-size: 0.85rem; color: #7a9bb8;">Apr 10, 2026 • Photo</div> + </div> + <div style="padding: 0.8rem; border-bottom: 1px solid rgba(168, 85, 247, 0.15); margin-bottom: 0.8rem;"> + <div style="font-weight: bold; color: #c4d6e8;">Inspiring Quote</div> + <div style="font-size: 0.85rem; color: #7a9bb8;">Apr 8, 2026 • Quote</div> + </div> + <div style="padding: 0.8rem;"> + <div style="font-weight: bold; color: #c4d6e8;">Link to Cool Thing</div> + <div style="font-size: 0.85rem; color: #7a9bb8;">Apr 5, 2026 • Link</div> + </div> + </div> + </div> + </div> + <div style="margin-top: 1.5rem; padding: 1rem; background: rgba(0, 255, 136, 0.05); border-left: 3px solid #00ff88; border-radius: 0.3rem;"> + <p style="font-size: 0.85rem;"><strong>Order:</strong> Pinned post (if exists) at top → then reverse chronological (newest first)</p> + <p style="font-size: 0.85rem; margin-top: 0.5rem;"><strong>Implementation:</strong> Front-matter field <code>pinned: true</code> in post metadata</p> + </div> +</div> + +<div class="section"> + <h3>Single Article View</h3> + <p style="font-size: 0.85rem; margin-bottom: 1rem;">Each article type gets a dedicated template with appropriate styling and metadata display.</p> + <div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem;"> + <div style="padding: 1rem; background: rgba(168, 85, 247, 0.08); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.3rem;"> + <h4 style="color: #a855f7; font-size: 0.9rem; margin-bottom: 0.5rem;">Life / Tech / Photo</h4> + <p style="font-size: 0.8rem; line-height: 1.6;">Standard article layout: title, date, content, tags</p> + </div> + <div style="padding: 1rem; background: rgba(0, 255, 136, 0.08); border: 1px solid rgba(0, 255, 136, 0.2); border-radius: 0.3rem;"> + <h4 style="color: #00ff88; font-size: 0.9rem; margin-bottom: 0.5rem;">Quote</h4> + <p style="font-size: 0.8rem; line-height: 1.6;">Large blockquote styling, author attribution, minimal text</p> + </div> + <div style="padding: 1rem; background: rgba(168, 85, 247, 0.08); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.3rem; grid-column: 1 / -1;"> + <h4 style="color: #a855f7; font-size: 0.9rem; margin-bottom: 0.5rem;">Link</h4> + <p style="font-size: 0.8rem; line-height: 1.6;">Preview/commentary + prominent link button, embed preview (if possible)</p> + </div> + </div> +</div> + +<div class="section" style="border-top: 2px solid rgba(168, 85, 247, 0.2); padding-top: 1.5rem;"> + <h3>Configuration in hugo.toml</h3> + <p style="font-size: 0.85rem; margin-bottom: 1rem;">All article types defined in config, making it easy to add new types or customize existing ones later.</p> +</div>
\ No newline at end of file diff --git a/.superpowers/brainstorm/26102-1776256459/content/layout-mockups.html b/.superpowers/brainstorm/26102-1776256459/content/layout-mockups.html new file mode 100644 index 0000000..776b786 --- /dev/null +++ b/.superpowers/brainstorm/26102-1776256459/content/layout-mockups.html @@ -0,0 +1,154 @@ +<h2>Page Layouts & Visual Hierarchy</h2> +<p class="subtitle">Desktop and mobile layouts for key pages</p> + +<div class="section"> + <h3>Landing Page (Homepage)</h3> + <div class="mockup" style="padding: 0;"> + <div class="mockup-header">Homepage / _index.md</div> + <div class="mockup-body" style="background: linear-gradient(180deg, rgba(6, 11, 16, 0.8), rgba(16, 30, 45, 0.8)); padding: 2rem;"> + <div style="text-align: center; padding: 3rem 0;"> + <div style="width: 80px; height: 80px; margin: 0 auto 1.5rem; background: rgba(168, 85, 247, 0.3); border-radius: 50%; border: 2px solid #a855f7; display: flex; align-items: center; justify-content: center;"> + <span style="font-size: 2rem;">📷</span> + </div> + <h1 style="font-family: 'Oxanium', sans-serif; font-size: 2rem; margin-bottom: 0.5rem; color: #a855f7;">Danilo Macrì</h1> + <p style="color: #c4d6e8; font-size: 1rem; margin-bottom: 2rem; max-width: 600px; margin-left: auto; margin-right: auto; line-height: 1.8;">Brief introduction about yourself, your focus, what you do. Keep it concise and personal. (From _index.md)</p> + <div style="display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap;"> + <div style="padding: 0.6rem 1.5rem; background: #a855f7; color: white; border-radius: 0.3rem; font-size: 0.9rem; cursor: pointer;">Read Articles</div> + <div style="padding: 0.6rem 1.5rem; border: 1px solid #a855f7; color: #a855f7; border-radius: 0.3rem; font-size: 0.9rem; cursor: pointer;">Get in Touch</div> + </div> + </div> + </div> + </div> +</div> + +<div class="section"> + <h3>Articles List Page</h3> + <div class="mockup" style="padding: 0;"> + <div class="mockup-header">Articles / List View</div> + <div class="mockup-body" style="background: rgba(6, 11, 16, 0.5); padding: 2rem;"> + <div style="max-width: 800px; margin: 0 auto;"> + <h1 style="font-size: 1.8rem; color: #a855f7; margin-bottom: 2rem; font-family: 'Oxanium', sans-serif;">Articles</h1> + + <!-- Pinned post --> + <div style="padding: 1.2rem; background: rgba(168, 85, 247, 0.12); border: 1px solid rgba(168, 85, 247, 0.3); border-radius: 0.4rem; margin-bottom: 1.5rem;"> + <div style="display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem;"> + <span style="font-size: 0.75rem; color: #00ff88; font-weight: bold;">📌 PINNED</span> + </div> + <h3 style="color: #c4d6e8; margin-bottom: 0.5rem; cursor: pointer;">Why I Started This Blog</h3> + <div style="display: flex; gap: 1rem; font-size: 0.8rem; color: #7a9bb8;"> + <span>Apr 14, 2026</span> + <span>•</span> + <span style="color: #a855f7;">Life</span> + </div> + </div> + + <!-- Regular posts --> + <div style="border-top: 1px solid rgba(168, 85, 247, 0.15); padding: 1.2rem 0;"> + <h3 style="color: #c4d6e8; margin-bottom: 0.5rem; cursor: pointer;">Building a Go CLI Tool</h3> + <div style="display: flex; gap: 1rem; font-size: 0.8rem; color: #7a9bb8;"> + <span>Apr 12, 2026</span> + <span>•</span> + <span style="color: #00ff88;">Tech</span> + </div> + </div> + + <div style="border-top: 1px solid rgba(168, 85, 247, 0.15); padding: 1.2rem 0;"> + <h3 style="color: #c4d6e8; margin-bottom: 0.5rem; cursor: pointer;">Mountain Hiking Adventure</h3> + <div style="display: flex; gap: 1rem; font-size: 0.8rem; color: #7a9bb8;"> + <span>Apr 10, 2026</span> + <span>•</span> + <span style="color: #a855f7;">Photo</span> + </div> + </div> + + <div style="border-top: 1px solid rgba(168, 85, 247, 0.15); padding: 1.2rem 0;"> + <h3 style="color: #c4d6e8; margin-bottom: 0.5rem; cursor: pointer;">On Simplicity</h3> + <div style="display: flex; gap: 1rem; font-size: 0.8rem; color: #7a9bb8;"> + <span>Apr 8, 2026</span> + <span>•</span> + <span style="color: #a855f7;">Quote</span> + </div> + </div> + + <div style="border-top: 1px solid rgba(168, 85, 247, 0.15); padding: 1.2rem 0;"> + <h3 style="color: #c4d6e8; margin-bottom: 0.5rem; cursor: pointer;">Interesting Read: The Unix Philosophy</h3> + <div style="display: flex; gap: 1rem; font-size: 0.8rem; color: #7a9bb8;"> + <span>Apr 5, 2026</span> + <span>•</span> + <span style="color: #00ff88;">Link</span> + </div> + </div> + </div> + </div> + </div> +</div> + +<div class="section"> + <h3>Single Article Page (Tech Example)</h3> + <div class="mockup" style="padding: 0;"> + <div class="mockup-header">Article View / Single</div> + <div class="mockup-body" style="background: rgba(6, 11, 16, 0.5); padding: 2rem;"> + <div style="max-width: 700px; margin: 0 auto;"> + <div style="margin-bottom: 1.5rem;"> + <span style="display: inline-block; padding: 0.3rem 0.8rem; background: rgba(0, 255, 136, 0.15); color: #00ff88; border-radius: 0.3rem; font-size: 0.75rem; font-weight: bold;">TECH</span> + </div> + <h1 style="font-size: 1.8rem; color: #a855f7; margin-bottom: 1rem; font-family: 'Oxanium', sans-serif;">Building a Go CLI Tool</h1> + <div style="display: flex; gap: 1rem; font-size: 0.85rem; color: #7a9bb8; margin-bottom: 2rem; padding-bottom: 1.5rem; border-bottom: 1px solid rgba(168, 85, 247, 0.15);"> + <span>Apr 12, 2026</span> + <span>•</span> + <span>5 min read</span> + </div> + + <div style="line-height: 1.8; color: #c4d6e8; font-size: 0.95rem;"> + <p>Article content goes here. This is where your markdown is rendered with proper typography and spacing.</p> + + <div style="margin: 1.5rem 0; padding: 1rem; background: rgba(6, 11, 16, 0.8); border-left: 3px solid #00ff88; border-radius: 0.3rem; font-family: 'JetBrains Mono', monospace; font-size: 0.8rem; color: #00ff88; overflow-x: auto;"> + <div>$ go run main.go</div> + <div>Hello, CLI!</div> + </div> + + <p>More content and explanation about the code...</p> + </div> + + <div style="margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(168, 85, 247, 0.15);"> + <div style="font-size: 0.8rem; color: #7a9bb8;">Tags:</div> + <div style="display: flex; gap: 0.5rem; margin-top: 0.5rem; flex-wrap: wrap;"> + <span style="padding: 0.3rem 0.8rem; background: rgba(168, 85, 247, 0.1); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.3rem; font-size: 0.8rem;">#golang</span> + <span style="padding: 0.3rem 0.8rem; background: rgba(168, 85, 247, 0.1); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.3rem; font-size: 0.8rem;">#cli</span> + <span style="padding: 0.3rem 0.8rem; background: rgba(168, 85, 247, 0.1); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.3rem; font-size: 0.8rem;">#programming</span> + </div> + </div> + </div> + </div> + </div> +</div> + +<div class="section"> + <h3>Static Pages (About, Contact, Privacy)</h3> + <div style="padding: 1.5rem; background: rgba(168, 85, 247, 0.08); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.4rem;"> + <p style="font-size: 0.85rem; line-height: 1.8;">Static pages use a clean single-column layout. Content managed via markdown files in <code>content/</code>. All pages share the same template with consistent styling.</p> + <p style="font-size: 0.85rem; margin-top: 1rem;"><strong>Example:</strong> <code>/is</code> (About), <code>/is/here</code> (Contact), <code>/is/legal</code> (Privacy) — all defined in hugo.toml for easy management.</p> + </div> +</div> + +<div class="section" style="border-top: 2px solid rgba(168, 85, 247, 0.2); padding-top: 1.5rem;"> + <h3>Responsive Behavior</h3> + <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;"> + <div style="padding: 1rem; background: rgba(0, 255, 136, 0.08); border: 1px solid rgba(0, 255, 136, 0.2); border-radius: 0.3rem;"> + <h4 style="color: #00ff88; font-size: 0.9rem; margin-bottom: 0.5rem;">Desktop (1024px+)</h4> + <ul style="font-size: 0.8rem; line-height: 1.8; margin-left: 1.2rem;"> + <li>Full navigation visible</li> + <li>Max content width ~800px</li> + <li>Comfortable spacing</li> + </ul> + </div> + <div style="padding: 1rem; background: rgba(168, 85, 247, 0.08); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.3rem;"> + <h4 style="color: #a855f7; font-size: 0.9rem; margin-bottom: 0.5rem;">Mobile (<768px)</h4> + <ul style="font-size: 0.8rem; line-height: 1.8; margin-left: 1.2rem;"> + <li>Hamburger menu toggle</li> + <li>Full-screen overlay on tap</li> + <li>Optimized spacing</li> + </ul> + </div> + </div> +</div>
\ No newline at end of file diff --git a/.superpowers/brainstorm/26102-1776256459/content/layout-with-sidebar.html b/.superpowers/brainstorm/26102-1776256459/content/layout-with-sidebar.html new file mode 100644 index 0000000..894751a --- /dev/null +++ b/.superpowers/brainstorm/26102-1776256459/content/layout-with-sidebar.html @@ -0,0 +1,188 @@ +<h2>Article & Static Page Layouts with Sidebar</h2> +<p class="subtitle">Two-column desktop layout, responsive sidebar that moves to bottom on mobile</p> + +<div class="section"> + <h3>Single Article Page (Tech Example) — Desktop View</h3> + <div class="mockup" style="padding: 0;"> + <div class="mockup-header">Article View / Single (Desktop 1024px+)</div> + <div class="mockup-body" style="background: rgba(6, 11, 16, 0.5); padding: 2rem;"> + <div style="display: grid; grid-template-columns: 1fr 300px; gap: 2rem; max-width: 1100px; margin: 0 auto;"> + <!-- Main Content --> + <div> + <div style="margin-bottom: 1.5rem;"> + <span style="display: inline-block; padding: 0.3rem 0.8rem; background: rgba(0, 255, 136, 0.15); color: #00ff88; border-radius: 0.3rem; font-size: 0.75rem; font-weight: bold;">TECH</span> + </div> + <h1 style="font-size: 1.8rem; color: #a855f7; margin-bottom: 1rem; font-family: 'Oxanium', sans-serif;">Building a Go CLI Tool</h1> + <div style="display: flex; gap: 1rem; font-size: 0.85rem; color: #7a9bb8; margin-bottom: 2rem; padding-bottom: 1.5rem; border-bottom: 1px solid rgba(168, 85, 247, 0.15);"> + <span>Apr 12, 2026</span> + <span>•</span> + <span>5 min read</span> + </div> + + <div style="line-height: 1.8; color: #c4d6e8; font-size: 0.95rem;"> + <p>Building command-line tools in Go is straightforward and powerful. Let's explore how to create a simple CLI application.</p> + + <div style="margin: 1.5rem 0; padding: 1rem; background: rgba(6, 11, 16, 0.8); border-left: 3px solid #00ff88; border-radius: 0.3rem; font-family: 'JetBrains Mono', monospace; font-size: 0.8rem; overflow-x: auto;"> + <div style="color: #a855f7;">package</div><div style="display: inline; color: #c4d6e8;"> main</div> + <br><br> + <div style="color: #a855f7;">import</div><div style="display: inline; color: #c4d6e8;"> (</div> + <br><div style="margin-left: 2rem;"><span style="color: #00ff88;">"fmt"</span></div> + <br><div style="color: #c4d6e8;">)</div> + <br><br> + <div style="color: #a855f7;">func</div><div style="display: inline; color: #c4d6e8;"> main() {</div> + <br><div style="margin-left: 2rem; color: #a855f7;">fmt</div><div style="display: inline; color: #c4d6e8;">.Println(</div><div style="display: inline; color: #00ff88;">"Hello, CLI!"</div><div style="display: inline; color: #c4d6e8;">)</div> + <br><div style="color: #c4d6e8;">}</div> + </div> + + <p>This simple example demonstrates the basics. For larger projects, consider using the <code style="background: rgba(168, 85, 247, 0.2); padding: 0.2rem 0.4rem; border-radius: 0.2rem; color: #a855f7;">cobra</code> library for more advanced CLI features.</p> + + <p style="margin-top: 1rem;">The key advantages of Go for CLI tools are:</p> + <ul style="margin-left: 1.5rem; margin-top: 0.5rem;"> + <li style="margin-bottom: 0.5rem;">Single binary compilation (no runtime dependencies)</li> + <li style="margin-bottom: 0.5rem;">Cross-platform builds</li> + <li style="margin-bottom: 0.5rem;">Fast execution</li> + <li>Rich standard library</li> + </ul> + </div> + + <div style="margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(168, 85, 247, 0.15);"> + <div style="font-size: 0.8rem; color: #7a9bb8;">Tags:</div> + <div style="display: flex; gap: 0.5rem; margin-top: 0.5rem; flex-wrap: wrap;"> + <span style="padding: 0.3rem 0.8rem; background: rgba(168, 85, 247, 0.1); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.3rem; font-size: 0.8rem;">#golang</span> + <span style="padding: 0.3rem 0.8rem; background: rgba(168, 85, 247, 0.1); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.3rem; font-size: 0.8rem;">#cli</span> + <span style="padding: 0.3rem 0.8rem; background: rgba(168, 85, 247, 0.1); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.3rem; font-size: 0.8rem;">#programming</span> + </div> + </div> + </div> + + <!-- Sidebar --> + <aside style="padding: 1.5rem; background: rgba(168, 85, 247, 0.08); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.4rem; height: fit-content; position: sticky; top: 2rem;"> + <h3 style="font-size: 0.85rem; font-weight: bold; color: #a855f7; text-transform: uppercase; margin-bottom: 1rem; letter-spacing: 0.5px;">Share</h3> + <div style="display: flex; flex-direction: column; gap: 0.6rem; margin-bottom: 1.5rem;"> + <div style="padding: 0.5rem 0.8rem; background: rgba(0, 85, 200, 0.15); border: 1px solid rgba(0, 85, 200, 0.3); border-radius: 0.3rem; font-size: 0.8rem; cursor: pointer; text-align: center; color: #5ba3e8;">𝕏 / Twitter</div> + <div style="padding: 0.5rem 0.8rem; background: rgba(30, 144, 255, 0.15); border: 1px solid rgba(30, 144, 255, 0.3); border-radius: 0.3rem; font-size: 0.8rem; cursor: pointer; text-align: center; color: #5ba3e8;">📘 Facebook</div> + <div style="padding: 0.5rem 0.8rem; background: rgba(168, 85, 247, 0.1); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.3rem; font-size: 0.8rem; cursor: pointer; text-align: center; color: #a855f7;">🔗 Copy Link</div> + </div> + + <hr style="border: none; border-top: 1px solid rgba(168, 85, 247, 0.15); margin: 1.5rem 0;"> + + <h3 style="font-size: 0.85rem; font-weight: bold; color: #a855f7; text-transform: uppercase; margin-bottom: 1rem; letter-spacing: 0.5px;">Article Info</h3> + <div style="font-size: 0.8rem; line-height: 2; color: #7a9bb8;"> + <div><strong style="color: #c4d6e8;">Published:</strong> Apr 12, 2026</div> + <div><strong style="color: #c4d6e8;">Updated:</strong> Apr 14, 2026</div> + <div><strong style="color: #c4d6e8;">Reading Time:</strong> 5 min</div> + <div><strong style="color: #c4d6e8;">Category:</strong> <span style="color: #00ff88;">Tech</span></div> + </div> + + <hr style="border: none; border-top: 1px solid rgba(168, 85, 247, 0.15); margin: 1.5rem 0;"> + + <h3 style="font-size: 0.85rem; font-weight: bold; color: #a855f7; text-transform: uppercase; margin-bottom: 1rem; letter-spacing: 0.5px;">Related</h3> + <div style="font-size: 0.8rem; color: #c4d6e8; line-height: 1.8;"> + <div style="margin-bottom: 0.8rem; padding-bottom: 0.8rem; border-bottom: 1px solid rgba(168, 85, 247, 0.15);"> + <div style="cursor: pointer; color: #a855f7;">Rust vs Go</div> + <div style="font-size: 0.75rem; color: #7a9bb8;">Apr 5, 2026</div> + </div> + <div> + <div style="cursor: pointer; color: #a855f7;">Python CLI Tools</div> + <div style="font-size: 0.75rem; color: #7a9bb8;">Mar 28, 2026</div> + </div> + </div> + </aside> + </div> + </div> + </div> +</div> + +<div class="section"> + <h3>Mobile View (Sidebar → Bottom)</h3> + <div class="mockup" style="padding: 0;"> + <div class="mockup-header">Article View / Mobile (<768px)</div> + <div class="mockup-body" style="background: rgba(6, 11, 16, 0.5); padding: 1.5rem; max-width: 500px; margin: 0 auto;"> + <div style="margin-bottom: 1.5rem;"> + <span style="display: inline-block; padding: 0.3rem 0.8rem; background: rgba(0, 255, 136, 0.15); color: #00ff88; border-radius: 0.3rem; font-size: 0.75rem; font-weight: bold;">TECH</span> + </div> + <h1 style="font-size: 1.5rem; color: #a855f7; margin-bottom: 1rem; font-family: 'Oxanium', sans-serif;">Building a Go CLI Tool</h1> + <div style="display: flex; gap: 1rem; font-size: 0.85rem; color: #7a9bb8; margin-bottom: 1.5rem; padding-bottom: 1.5rem; border-bottom: 1px solid rgba(168, 85, 247, 0.15);"> + <span>Apr 12, 2026</span> + <span>•</span> + <span>5 min</span> + </div> + + <div style="line-height: 1.8; color: #c4d6e8; font-size: 0.95rem; margin-bottom: 2rem;"> + <p>Building command-line tools in Go is straightforward and powerful...</p> + <p style="margin-top: 1rem;">[Article content continues...]</p> + </div> + + <!-- Sidebar content moved to bottom on mobile --> + <div style="padding: 1.5rem; background: rgba(168, 85, 247, 0.08); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.4rem; margin-top: 2rem;"> + <h3 style="font-size: 0.85rem; font-weight: bold; color: #a855f7; text-transform: uppercase; margin-bottom: 1rem; letter-spacing: 0.5px;">Share This</h3> + <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 0.6rem; margin-bottom: 1.5rem;"> + <div style="padding: 0.5rem 0.8rem; background: rgba(0, 85, 200, 0.15); border: 1px solid rgba(0, 85, 200, 0.3); border-radius: 0.3rem; font-size: 0.75rem; cursor: pointer; text-align: center; color: #5ba3e8;">𝕏</div> + <div style="padding: 0.5rem 0.8rem; background: rgba(30, 144, 255, 0.15); border: 1px solid rgba(30, 144, 255, 0.3); border-radius: 0.3rem; font-size: 0.75rem; cursor: pointer; text-align: center; color: #5ba3e8;">FB</div> + </div> + + <hr style="border: none; border-top: 1px solid rgba(168, 85, 247, 0.15); margin: 1rem 0;"> + + <h3 style="font-size: 0.85rem; font-weight: bold; color: #a855f7; text-transform: uppercase; margin-bottom: 0.8rem; letter-spacing: 0.5px;">Info</h3> + <div style="font-size: 0.75rem; line-height: 1.8; color: #7a9bb8;"> + <div><strong style="color: #c4d6e8;">Published:</strong> Apr 12, 2026</div> + <div><strong style="color: #c4d6e8;">Category:</strong> Tech</div> + </div> + </div> + </div> + </div> +</div> + +<div class="section"> + <h3>Static Page Layout (Same Structure)</h3> + <p style="font-size: 0.85rem; margin-bottom: 1rem;">Static pages (/is, /is/here, /is/legal) use the same two-column layout with sidebar. The sidebar can contain:</p> + <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;"> + <div style="padding: 1rem; background: rgba(0, 255, 136, 0.08); border: 1px solid rgba(0, 255, 136, 0.2); border-radius: 0.3rem;"> + <h4 style="color: #00ff88; font-size: 0.9rem; margin-bottom: 0.5rem;">About Page Sidebar</h4> + <ul style="font-size: 0.8rem; line-height: 1.8; margin-left: 1.2rem;"> + <li>Social links</li> + <li>Contact info</li> + <li>Skills/expertise</li> + <li>CV download</li> + </ul> + </div> + <div style="padding: 1rem; background: rgba(168, 85, 247, 0.08); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.3rem;"> + <h4 style="color: #a855f7; font-size: 0.9rem; margin-bottom: 0.5rem;">Contact Page Sidebar</h4> + <ul style="font-size: 0.8rem; line-height: 1.8; margin-left: 1.2rem;"> + <li>Email address</li> + <li>Social profiles</li> + <li>Response time</li> + <li>Availability</li> + </ul> + </div> + </div> +</div> + +<div class="section"> + <h3>Syntax Highlighting</h3> + <div style="padding: 1.5rem; background: rgba(0, 255, 136, 0.08); border-left: 3px solid #00ff88; border-radius: 0.3rem;"> + <p style="font-size: 0.85rem; margin-bottom: 1rem;"><strong>Implementation:</strong> Hugo + Chroma syntax highlighter (built-in)</p> + <ul style="font-size: 0.85rem; line-height: 1.8; margin-left: 1.5rem;"> + <li>Automatically highlights code blocks marked with language (```go, ```python, etc.)</li> + <li>Custom CSS theme integrated with danix.xyz color scheme (purple accent, green highlights for keywords)</li> + <li>Line numbers optional (configurable in hugo.toml)</li> + <li>Supports all major languages: Go, Python, Rust, JavaScript, Bash, etc.</li> + </ul> + <div style="margin-top: 1rem; padding: 1rem; background: rgba(6, 11, 16, 0.8); border-radius: 0.3rem; font-family: 'JetBrains Mono', monospace; font-size: 0.75rem;"> + <div style="color: #a855f7;">```go</div> + <div style="color: #7a9bb8;">// Code here gets automatic syntax highlighting</div> + <div style="color: #a855f7;">```</div> + </div> + </div> +</div> + +<div class="section" style="border-top: 2px solid rgba(168, 85, 247, 0.2); padding-top: 1.5rem;"> + <h3>Sidebar Implementation Details</h3> + <div style="padding: 1rem; background: rgba(168, 85, 247, 0.05); border: 1px solid rgba(168, 85, 247, 0.15); border-radius: 0.3rem;"> + <p style="font-size: 0.85rem; line-height: 1.8;"> + <strong>Desktop (1024px+):</strong> CSS Grid layout with main content + sticky sidebar. Sidebar remains visible while scrolling.<br><br> + <strong>Tablet/Mobile:</strong> Single column. Sidebar content rendered after main content using CSS <code>order</code> property or media query flexbox reorder.<br><br> + <strong>Content Source:</strong> Sidebar content defined via optional front-matter fields or template logic (e.g., <code>show_sharing: true</code>, <code>show_metadata: true</code>). + </p> + </div> +</div>
\ No newline at end of file diff --git a/.superpowers/brainstorm/26102-1776256459/content/theme-architecture.html b/.superpowers/brainstorm/26102-1776256459/content/theme-architecture.html new file mode 100644 index 0000000..4d4c225 --- /dev/null +++ b/.superpowers/brainstorm/26102-1776256459/content/theme-architecture.html @@ -0,0 +1,112 @@ +<h2>danix.xyz Theme Architecture</h2> +<p class="subtitle">Hugo theme with config-driven structure, bilingual support, and hacker aesthetic</p> + +<div class="section"> + <h3>Core Design Principles</h3> + <ul style="margin-left: 1.5rem; line-height: 1.8;"> + <li><strong>Slackware Philosophy:</strong> Clean, essential, no bloat</li> + <li><strong>Config-Driven:</strong> All structure (menus, pages, URLs) defined in hugo.toml</li> + <li><strong>Bilingual (IT/EN):</strong> i18n files for all UI strings</li> + <li><strong>Dark/Light Toggle:</strong> Theme switcher in hamburger menu</li> + <li><strong>Hacker Aesthetic:</strong> Purple accent (#a855f7), monospace typography, subtle dot-grid background, terminal-style elements</li> + </ul> +</div> + +<div class="section"> + <h3>Page Structure</h3> + <div class="mockup" style="padding: 1.5rem; background: rgba(168, 85, 247, 0.05); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.5rem;"> + <div style="font-family: 'JetBrains Mono', monospace; font-size: 0.9rem; line-height: 1.8; color: #a855f7;"> + <div><strong>1. Home / Landing</strong></div> + <div style="margin-left: 2rem; margin-top: 0.5rem;"> + <div>→ Hero section (name, bio, photo)</div> + <div>→ CTA: Articles | Contact</div> + <div>→ Content from _index.md</div> + </div> + <div style="margin-top: 1rem;"><strong>2. Articles Section</strong></div> + <div style="margin-left: 2rem; margin-top: 0.5rem;"> + <div>→ List of posts (chronological)</div> + <div>→ Single article view</div> + <div>→ Content from content/ (Page Bundles)</div> + </div> + <div style="margin-top: 1rem;"><strong>3. Static Pages (config-driven)</strong></div> + <div style="margin-left: 2rem; margin-top: 0.5rem;"> + <div>→ /is (About)</div> + <div>→ /is/here (Contact)</div> + <div>→ /is/legal (Privacy)</div> + <div style="font-size: 0.85rem; color: #7a9bb8; margin-top: 0.5rem;">(Easy to add more via hugo.toml)</div> + </div> + </div> + </div> +</div> + +<div class="section"> + <h3>Navigation Structure</h3> + <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin-top: 1rem;"> + <div class="mockup" style="padding: 1rem;"> + <div class="mockup-header">Top Navigation (Desktop)</div> + <div class="mockup-body" style="padding: 1rem; background: rgba(6, 11, 16, 0.5); border-radius: 0.4rem;"> + <div style="display: flex; justify-content: space-between; align-items: center; font-size: 0.9rem;"> + <div style="font-weight: bold; color: #a855f7;">danix</div> + <div style="display: flex; gap: 2rem; font-size: 0.85rem;"> + <span>Articles</span> + <span>Contact</span> + <span>≡</span> + </div> + </div> + </div> + </div> + <div class="mockup" style="padding: 1rem;"> + <div class="mockup-header">Hamburger Overlay Menu</div> + <div class="mockup-body" style="padding: 1rem; background: rgba(6, 11, 16, 0.5); border-radius: 0.4rem; font-size: 0.85rem;"> + <div style="display: flex; flex-direction: column; gap: 1rem;"> + <div style="font-weight: bold;">Articles</div> + <div style="font-weight: bold;">About (/is)</div> + <div style="font-weight: bold;">Contact (/is/here)</div> + <div style="font-weight: bold;">Privacy (/is/legal)</div> + <hr style="border: none; border-top: 1px solid rgba(168, 85, 247, 0.2); margin: 0.5rem 0;"> + <div style="display: flex; gap: 1rem; font-size: 0.75rem;"> + <span>🇮🇹 IT</span> + <span>🇬🇧 EN</span> + </div> + <div style="font-size: 0.75rem;">☀️ / 🌙</div> + </div> + </div> + </div> + </div> +</div> + +<div class="section"> + <h3>Key Features</h3> + <div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem;"> + <div style="padding: 1rem; background: rgba(0, 255, 136, 0.05); border: 1px solid rgba(0, 255, 136, 0.2); border-radius: 0.4rem;"> + <h4 style="color: #00ff88; margin-bottom: 0.5rem;">Alpine.js Integration</h4> + <p style="font-size: 0.85rem; line-height: 1.6;">Overlay menu toggle, language switching, theme toggle, contact form AJAX</p> + </div> + <div style="padding: 1rem; background: rgba(168, 85, 247, 0.05); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.4rem;"> + <h4 style="color: #a855f7; margin-bottom: 0.5rem;">Responsive Design</h4> + <p style="font-size: 0.85rem; line-height: 1.6;">Mobile-first Tailwind CSS, hamburger on mobile, full nav on desktop</p> + </div> + <div style="padding: 1rem; background: rgba(0, 255, 136, 0.05); border: 1px solid rgba(0, 255, 136, 0.2); border-radius: 0.4rem;"> + <h4 style="color: #00ff88; margin-bottom: 0.5rem;">i18n Ready</h4> + <p style="font-size: 0.85rem; line-height: 1.6;">Hugo i18n system for all UI strings (buttons, labels, menus)</p> + </div> + <div style="padding: 1rem; background: rgba(168, 85, 247, 0.05); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.4rem;"> + <h4 style="color: #a855f7; margin-bottom: 0.5rem;">Easy Extensibility</h4> + <p style="font-size: 0.85rem; line-height: 1.6;">Add static pages just by adding menu entries in hugo.toml</p> + </div> + </div> +</div> + +<div class="section"> + <h3>Visual Direction</h3> + <div style="padding: 1.5rem; background: linear-gradient(135deg, rgba(168, 85, 247, 0.05), rgba(0, 255, 136, 0.05)); border: 1px solid rgba(168, 85, 247, 0.2); border-radius: 0.5rem;"> + <p><strong>Color Palette:</strong> Dark blue-grey backgrounds (#060b10, #0c1520), purple accent (#a855f7), green highlights (#00ff88), light blue-grey text (#c4d6e8)</p> + <p style="margin-top: 0.8rem;"><strong>Typography:</strong> Headings: Oxanium | Body: IBM Plex Sans | Monospace: JetBrains Mono</p> + <p style="margin-top: 0.8rem;"><strong>Visual Elements:</strong> Subtle dot-grid background, smooth transitions, minimal glow effects, clean borders, hacker/open-source aesthetic</p> + <p style="margin-top: 0.8rem;"><strong>Unique Touch:</strong> Fresh layout design (not a copy of danix.me), modern with hints of hacker/open-source/Slackware philosophy</p> + </div> +</div> + +<div class="section" style="border-top: 2px solid rgba(168, 85, 247, 0.2); padding-top: 1.5rem;"> + <h3>Does this direction align with your vision?</h3> +</div>
\ No newline at end of file diff --git a/.superpowers/brainstorm/26102-1776256459/content/waiting.html b/.superpowers/brainstorm/26102-1776256459/content/waiting.html new file mode 100644 index 0000000..814be13 --- /dev/null +++ b/.superpowers/brainstorm/26102-1776256459/content/waiting.html @@ -0,0 +1,3 @@ +<div style="display:flex;align-items:center;justify-content:center;min-height:60vh"> + <p class="subtitle">Finalizing design in terminal...</p> +</div>
\ No newline at end of file diff --git a/.superpowers/brainstorm/26102-1776256459/state/server-stopped b/.superpowers/brainstorm/26102-1776256459/state/server-stopped new file mode 100644 index 0000000..c60fbed --- /dev/null +++ b/.superpowers/brainstorm/26102-1776256459/state/server-stopped @@ -0,0 +1 @@ +{"reason":"idle timeout","timestamp":1776259280204} diff --git a/.superpowers/brainstorm/26102-1776256459/state/server.log b/.superpowers/brainstorm/26102-1776256459/state/server.log new file mode 100644 index 0000000..b102cc7 --- /dev/null +++ b/.superpowers/brainstorm/26102-1776256459/state/server.log @@ -0,0 +1,7 @@ +{"type":"server-started","port":54271,"host":"127.0.0.1","url_host":"localhost","url":"http://localhost:54271","screen_dir":"/home/danix/Programming/GIT/danix.xyz-hacker-theme/.superpowers/brainstorm/26102-1776256459/content","state_dir":"/home/danix/Programming/GIT/danix.xyz-hacker-theme/.superpowers/brainstorm/26102-1776256459/state"} +{"type":"screen-added","file":"/home/danix/Programming/GIT/danix.xyz-hacker-theme/.superpowers/brainstorm/26102-1776256459/content/theme-architecture.html"} +{"type":"screen-added","file":"/home/danix/Programming/GIT/danix.xyz-hacker-theme/.superpowers/brainstorm/26102-1776256459/content/article-types.html"} +{"type":"screen-added","file":"/home/danix/Programming/GIT/danix.xyz-hacker-theme/.superpowers/brainstorm/26102-1776256459/content/layout-mockups.html"} +{"type":"screen-added","file":"/home/danix/Programming/GIT/danix.xyz-hacker-theme/.superpowers/brainstorm/26102-1776256459/content/layout-with-sidebar.html"} +{"type":"screen-added","file":"/home/danix/Programming/GIT/danix.xyz-hacker-theme/.superpowers/brainstorm/26102-1776256459/content/waiting.html"} +{"type":"server-stopped","reason":"idle timeout"} diff --git a/.superpowers/brainstorm/26102-1776256459/state/server.pid b/.superpowers/brainstorm/26102-1776256459/state/server.pid new file mode 100644 index 0000000..8ce317a --- /dev/null +++ b/.superpowers/brainstorm/26102-1776256459/state/server.pid @@ -0,0 +1 @@ +26110 diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..1ba87e7 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,26 @@ +# Content Management Instructions - opencode + +You are the content curator for https://danix.xyz. You operate strictly within the `content/` directory. + +## 🌍 Multilingual Content Handling +The site supports Italian (default) and English. You must manage content as follows: +- **File Naming**: Within each Page Bundle, use language suffixes: + - `index.md` or `index.it.md` for Italian content. + - `index.en.md` for the English translation. +- **Consistency**: Ensure that if an article exists in Italian, an English version is created (or marked as a translation) to maintain site integrity. +- **Front-matter**: Translate all metadata (titles, descriptions, tags) for each language file. + +## 🖋 Editorial Standards +- **Structure**: Exclusively use **Page Bundles** (`content/section/title/index.md`). +- **Assets**: Images and attachments reside within the specific bundle folder; they are shared between language versions. +- **Front-matter**: YAML format. Mandatory fields: `title`, `date`, `draft: false`, `tags`, `categories`, `description`. + +## 🛠 Shortcode Usage +Raw HTML is forbidden. Use the shortcodes provided by the theme: +- **Contact**: Use `{{< contact_form >}}`. +- **Media**: Use specific shortcodes for images, galleries, and videos. +- **Reference**: Consult `SHORTCODES.md` for parameters. + +## 🤝 Workflow +1. **Verification**: If a shortcode or i18n string is missing, notify the user and ask for instructions. +2. **Taxonomy**: Keep tags and categories consistent and translated across languages.
\ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..21335b2 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,36 @@ +# Hugo Theme Architecture Instructions - danix.xyz + +You are the lead software architect for https://danix.xyz. Your code must follow a "Slackware-style" philosophy: clean, essential, and free of bloat. + +## 🌍 Multilingual Support (IT/EN) +The site is bilingual (Italian and English). You must: +- **i18n Framework**: Use Hugo’s translation folders (`i18n/it.yaml`, `i18n/en.yaml`) for all UI strings (e.g., "Read more", "Contact me", "Menu"). +- **Language Switcher**: Implement a clean language toggle within the hamburger overlay. +- **Logic**: Ensure all templates (Home, Lists, Singles) correctly handle multilingual variables and menus defined in `hugo.toml`. + +## 🛠 Tech Stack +- **Hugo (Extended)**: Use Hugo Pipes for asset processing and minification. +- **Tailwind CSS**: Utility-first styling (use `@apply` for semantic components). +- **Alpine.js**: Logic for the overlay menu, language switching, and asynchronous form handling. +- **Vanilla JS**: For minimal optimizations and scripts where Alpine is not required. + +## 🧩 Shortcode System (Consensual) +DO NOT write code for shortcodes without consulting the user first. Implement: +1. **Contact Form**: `{{< contact_form >}}` with AJAX handling via Alpine.js targeting `contact.php`. Must support translated labels for fields and error messages. +2. **Gravatar**: Profile image retrieval via email hash. +3. **Images & Galleries**: Responsive, lazy-loading, and caption support. +4. **Video Embeds**: Privacy-friendly YouTube/Vimeo. + +**Documentation**: Update `SHORTCODES.md` with usage examples for every tool. + +## 🎨 Design & UX +- **Identity**: Maintain the font stack and palettes from `danix.me`. +- **Accent**: Primary Purple. Modern aesthetic with an open-source/hacker soul. +- **Hero**: Full-screen, dynamic text, bio, and profile photo (multilingual bio). +- **Navigation**: Top hamburger menu -> Full-screen overlay (Articles + Pages + Language Toggle - dark/light theme toggle). +- **A11y**: Target WCAG 2.1 AA. + +## 📝 Work Protocol +1. **Pianification**: Propose the `i18n` structure and partials layout before writing. +2. **Consultation**: Always ask before implementing complex logic or shortcodes. +3. **KISS**: Keep It Simple, Stupid.
\ No newline at end of file diff --git a/docs/superpowers/plans/2026-04-15-hugo-theme-implementation.md b/docs/superpowers/plans/2026-04-15-hugo-theme-implementation.md new file mode 100644 index 0000000..c4026da --- /dev/null +++ b/docs/superpowers/plans/2026-04-15-hugo-theme-implementation.md @@ -0,0 +1,2771 @@ +# 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 diff --git a/docs/superpowers/specs/2026-04-15-hugo-theme-design.md b/docs/superpowers/specs/2026-04-15-hugo-theme-design.md new file mode 100644 index 0000000..2aa1ea1 --- /dev/null +++ b/docs/superpowers/specs/2026-04-15-hugo-theme-design.md @@ -0,0 +1,548 @@ +# 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) |
