Merge feature/add-blog-section into main

Add complete blog section with German and English support.
Includes first blog post "KI Generierte Website - ein Praxisbeispiel"
about building this site with AI-assisted development.

Features:
- Blog list and single post templates
- Multilingual content structure
- Navigation integration
- Responsive design with Bootstrap
- Semantic HTML and accessibility

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-31 09:31:23 +01:00
co-authored by Claude
12 changed files with 580 additions and 0 deletions
+6
View File
@@ -12,3 +12,9 @@
// }
// Add your custom styles here
.highlight {
pre {
padding: 1em;
}
}
+4
View File
@@ -0,0 +1,4 @@
---
title: "Blog"
description: "Artikel und Gedanken zu Softwareentwicklung, KI und digitalen Themen"
---
+4
View File
@@ -0,0 +1,4 @@
---
title: "Blog"
description: "Articles and thoughts about software development, AI and digital topics"
---
@@ -0,0 +1,64 @@
---
title: "KI Generierte Website - ein Praxisbeispiel"
date: 2025-10-30
description: "Meine Erfahrungen beim Aufbau dieser Website mit KI-unterstützter Entwicklung und OpenSpec statt unstrukturiertem 'Vibe Coding'."
---
### TL;DR
Meine persönliche Website war über vier Jahre veraltet und schwer zu pflegen. Für die Neugestaltung setzte ich auf KI-unterstützte Entwicklung mit OpenSpec statt unstrukturiertem „Vibe Coding". Der spezifikationsgetriebene Ansatz erwies sich als effizienter: Zunächst wurde das Projekt grob beschrieben, dann in kleinen Schritten umgesetzt von der Initialisierung über Content-Migration bis zur mehrsprachigen Unterstützung. Die offenen Proposals erlaubten flexible Korrekturen während der Umsetzung. Mit Sub-Agents in Claude Code liess sich das Deployment automatisieren. Fazit: KI-gestützte Entwicklung erfordert Struktur und Dokumentation, fühlt sich aber wie produktive Teamarbeit an man prüft mehr Code als man schreibt.
## Ausgangslage
Über mehr als vier Jahre blieb meine persönliche Website unverändert online. Die Inhalte waren veraltet, das statische HTML mühsam zu pflegen wenig motivierend. Mit dem Ziel, mich beruflich neu zu positionieren und meine Sichtbarkeit zu erhöhen, habe ich das Projekt neu aufgesetzt.
## Warum KI aber nicht „Vibe Coding"
Ich experimentiere seit einiger Zeit mit KIunterstützter Softwareentwicklung. In einfachen Fällen sind die Ergebnisse brauchbar, bei komplexeren Aufgaben jedoch häufig unzuverlässig. Diese Erfahrung hat mich davon überzeugt, auf unstrukturiertes „Vibe Coding" zu verzichten und stattdessen spezifikationsgetrieben vorzugehen.
## SpecDriven Development in der Praxis
Die Grundidee: Nicht Code direkt generieren lassen, sondern zuerst eine präzise Beschreibung dessen erstellen, was die Software leisten soll. Diese Spezifikation dient der KI als Leitplanke für wartbaren, qualitativ hochwertigen Code.
Ein erstes Experiment war eine [Webapplikation](https://codeberg.org/gurix/Reklamator) zur Zusammenfassung und Übersetzung von Benutzerfeedback. Die Resultate waren gut, jedoch erzeugte speckit sehr viele Artefakte und verbrauchte unverhältnismässig viele Tokens. Für meine neue Website setze ich daher auf [OpenSpec](https://openspec.dev/): spürbar leichter, schneller und deutlich effizienter im TokenVerbrauch.
## „Das grosse Ganze" beschreiben
Ich habe auf der grünen Wiese begonnen, OpenSpec installiert und in einem leeren Projekt initialisiert. Als AITool nutze ich Claude Code. Direkt im Anschluss beschrieb ich das Projekt in openspec/project.md. Dabei genügte eine grobe Skizze vieles wurde vom Agenten automatisch sinnvoll strukturiert und korrekt ergänzt.
```markdown
# Project Context
## Purpose
Converting the existing static HTML website at markusgraf.ch
into a Hugo-based static site...
```
## Vorschläge statt starre Spezifikationen
OpenSpec unterscheidet sich von speckit insofern, als Spezifikationen bewusster offener formuliert werden eher als Proposal denn als in Stein gemeisselte Vorgabe. In der Umsetzung erwies sich dieser schlankere Plan als leichter anpassbar. Bei speckit ist das schwieriger, weil mehrere Dokumente parallel gepflegt werden müssen.
Aus den speckitErfahrungen habe ich bewusst auf sehr kleine Iterationen gesetzt: Zunächst nur die Initialisierung einer leeren Seite mit dem statischen Generator Hugo. Danach habe ich den Inhalt der bestehenden Seite übernommen, als erste Erweiterung eine LebenslaufSeite ergänzt und anschliessend eine optionale englische Übersetzung eingeführt.
Diese Schritte blieben überschaubar und erforderten keine Änderungen am initialen Plan. Beim Deployment geriet ich jedoch ins Stocken. Ursprünglich wollte ich ein Skript erstellen lassen, das per FTPS auf den Server lädt naheliegend beim ResellerHosting, aber veraltet und in der Praxis unzuverlässig. Ich wechselte deshalb zu OpenSSH Secure Copy (scp). Schnell zeigte sich: Dateien wurden zwar übertragen, aber nicht sauber gespiegelt. Es drohte Chaos auf dem Server.
Die Lösung war ein Umstieg auf rsync über SSH, um die Zielstruktur exakt zu spiegeln. Proposal, Spezifikationen und Tasks habe ich entsprechend anpassen lassen danach funktionierte die angepasste Implementation reibungslos. Der Mehrwert kleiner, offen formulierter Proposals wurde hier besonders deutlich: Der Plan kann während der Umsetzung an neue Erkenntnisse angepasst werden.
## Aufräumen und automatisieren
Nach erfolgreichem Rollout archiviere ich die umgesetzten Anpassungen: Artefakte wandern in einen Archivordner mit Zeitstempel, die Spezifikationen als „Single Source of Truth" in openspec/specs/. Damit bleiben aktuelle Spezifikationen klar getrennt von vorgeschlagenen Änderungen in openspec/changes/.
Zum Schluss habe ich SubAgents in Claude Code getestet ein naheliegender Anwendungsfall ist das Deployment.
```markdown
## Workflow
1. Verify current branch is 'main'
2. Build Hugo site
3. Verify build success
4. Execute scripts/deploy.sh
```
Bei einem entsprechenden Hinweis („Änderungen ausrollen") prüft der Agent automatisch die Voraussetzungen, baut die statischen Seiten und veröffentlicht die Resultate. Fehlt eine Voraussetzung, etwa ein ausstehender Commit, wartet der Agent und setzt anschliessend fort.
## Fazit: Ungewohnt und gerade deshalb spannend
KIunterstützte Entwicklung zwingt zu Struktur: spezifizieren, dokumentieren, prüfen. Dass man am Ende überwiegend Code überprüft statt selbst zu schreiben, ist ungewohnt aber produktiv. Der Dialog mit dem System fühlt sich an wie Zusammenarbeit im Team: Man diskutiert sinnvolle Implementierungswege, stellt Rückfragen und kommt so zügig zu belastbaren Ergebnissen. Und ganz ehrlich: Es macht einfach auch Spass, sich so ungezwungen mit dem Computer zu unterhalten, als wäre es ein guter Freund.
@@ -0,0 +1,64 @@
---
title: "AI-Generated Website - A Practical Example"
date: 2025-10-30
description: "My experience building this website with AI-assisted development and OpenSpec instead of unstructured 'vibe coding'."
---
### TL;DR
My personal website was outdated for over four years and difficult to maintain. For the redesign, I relied on AI-assisted development with OpenSpec instead of unstructured "vibe coding". The specification-driven approach proved more efficient: First, the project was roughly described, then implemented in small steps from initialization through content migration to multilingual support. The open proposals allowed flexible corrections during implementation. With sub-agents in Claude Code, deployment could be automated. Conclusion: AI-assisted development requires structure and documentation, but feels like productive teamwork you review more code than you write.
## Starting Point
For more than four years, my personal website remained unchanged online. The content was outdated, maintaining the static HTML was tedious hardly motivating. With the goal of repositioning myself professionally and increasing my visibility, I restarted the project.
## Why AI But Not "Vibe Coding"
I've been experimenting with AI-assisted software development for some time. In simple cases, the results are usable, but in more complex tasks they're often unreliable. This experience convinced me to abandon unstructured "vibe coding" and instead proceed in a specification-driven manner.
## Spec-Driven Development in Practice
The basic idea: Don't have code generated directly, but first create a precise description of what the software should do. This specification serves the AI as a guardrail for maintainable, high-quality code.
A first experiment was a [web application](https://codeberg.org/gurix/Reklamator) for summarizing and translating user feedback. The results were good, but spec-kit generated too many artifacts and consumed disproportionately many tokens. For my new website, I therefore use [OpenSpec](https://openspec.dev/): noticeably lighter, faster, and significantly more efficient in token consumption.
## Describing "The Big Picture"
I started from scratch, installed OpenSpec and initialized it in an empty project. I use Claude Code as my AI tool. Immediately afterward, I described the project in openspec/project.md. A rough sketch was sufficient much was automatically structured sensibly and correctly supplemented by the agent.
```markdown
# Project Context
## Purpose
Converting the existing static HTML website at markusgraf.ch
into a Hugo-based static site...
```
## Proposals Instead of Rigid Specifications
OpenSpec differs from spec-kit in that specifications are deliberately formulated more openly more as proposals than set in stone. In implementation, this leaner plan proved easier to adapt. With spec-kit this is more difficult because multiple documents must be maintained in parallel.
From the spec-kit experiences, I deliberately focused on very small iterations: First just the initialization of an empty page with the static generator Hugo. Then I adopted the content of the existing page, added a CV page as the first extension, and subsequently introduced an optional English translation.
These steps remained manageable and required no changes to the initial plan. However, I got stuck with deployment. Originally, I wanted to have a script created that uploads via FTPS obvious for reseller hosting, but outdated and unreliable in practice. I therefore switched to OpenSSH Secure Copy (scp). It quickly became apparent: Files were transferred but not cleanly mirrored. Chaos threatened on the server.
The solution was switching to rsync over SSH to mirror the target structure exactly. I had the proposal, specifications and tasks adjusted accordingly after that the adapted implementation worked smoothly. The added value of small, openly formulated proposals became particularly clear here: The plan can be adjusted to new insights during implementation.
## Cleaning Up and Automating
After successful rollout, I archive the implemented adjustments: Artifacts go into an archive folder with timestamp, the specifications as "single source of truth" into openspec/specs/. This keeps current specifications clearly separated from proposed changes in openspec/changes/.
Finally, I tested sub-agents in Claude Code an obvious use case is deployment.
```markdown
## Workflow
1. Verify current branch is 'main'
2. Build Hugo site
3. Verify build success
4. Execute scripts/deploy.sh
```
With an appropriate hint ("deploy changes"), the agent automatically checks the prerequisites, builds the static pages and publishes the results. If a prerequisite is missing, such as an outstanding commit, the agent waits and then continues.
## Conclusion: Unfamiliar And Precisely Therefore Exciting
AI-assisted development forces structure: specify, document, verify. That you end up predominantly reviewing code rather than writing it yourself is unfamiliar but productive. The dialogue with the system feels like collaboration in a team: You discuss sensible implementation paths, ask questions and thus quickly arrive at reliable results. And quite honestly: It's simply fun to converse so casually with the computer as if it were a good friend.
+10
View File
@@ -33,11 +33,21 @@ disableKinds = ['taxonomy', 'term']
description = 'Personal website of Markus Graf'
# Language-specific menus
[[languages.de.menu.main]]
name = 'Blog'
url = '/de/blog/'
weight = 5
[[languages.de.menu.main]]
name = 'Lebenslauf'
url = '/de/cv/'
weight = 10
[[languages.en.menu.main]]
name = 'Blog'
url = '/en/blog/'
weight = 5
[[languages.en.menu.main]]
name = 'Curriculum Vitae'
url = '/en/cv/'
+45
View File
@@ -0,0 +1,45 @@
{{ define "main" }}
<div class="container py-5">
<div class="row">
<div class="col-lg-8 mx-auto">
<header class="mb-5">
<h1>{{ .Title }}</h1>
{{ if .Description }}
<p class="lead text-muted">{{ .Description }}</p>
{{ end }}
</header>
<div class="blog-list">
{{ range .Pages }}
<article class="mb-5 pb-5 border-bottom">
<header class="mb-3">
<h2 class="h3">
<a href="{{ .RelPermalink }}" class="text-decoration-none">{{ .Title }}</a>
</h2>
<time datetime="{{ .Date.Format "2006-01-02" }}" class="text-muted">
{{ .Date.Format "2. January 2006" }}
</time>
</header>
{{ if .Description }}
<p class="lead">{{ .Description }}</p>
{{ else if .Summary }}
<div class="summary">
{{ .Summary }}
</div>
{{ end }}
<a href="{{ .RelPermalink }}" class="btn btn-outline-primary">
{{ if eq $.Language.Lang "de" }}
Weiterlesen
{{ else }}
Read more
{{ end }}
</a>
</article>
{{ end }}
</div>
</div>
</div>
</div>
{{ end }}
+35
View File
@@ -0,0 +1,35 @@
{{ define "main" }}
<article class="container py-5">
<div class="row">
<div class="col-lg-8 mx-auto">
<header class="mb-5">
<h1>{{ .Title }}</h1>
<div class="text-muted mb-3">
<time datetime="{{ .Date.Format "2006-01-02" }}">
{{ .Date.Format "2. January 2006" }}
</time>
</div>
{{ if .Description }}
<p class="lead">{{ .Description }}</p>
{{ end }}
</header>
<div class="blog-content">
{{ .Content }}
</div>
<footer class="mt-5 pt-4 border-top">
<a href="{{ "/blog/" | relLangURL }}" class="btn btn-outline-secondary">
{{ if eq .Language.Lang "de" }}
← Zurück zum Blog
{{ else }}
← Back to Blog
{{ end }}
</a>
</footer>
</div>
</div>
</article>
{{ end }}
@@ -0,0 +1,57 @@
# Add Blog Section
## Problem
The website currently lacks a blog section for publishing articles and sharing knowledge. There is existing content (article "KI Generierte Website - ein Praxisbeispiel" in Notion) ready to be published, but no structure to support blog posts.
## Proposed Solution
Add a blog section to the Hugo site that:
- Provides a dedicated blog listing page showing all published articles
- Supports individual blog post pages with proper formatting
- Maintains multilingual support (German/English) consistent with the rest of the site
- Includes navigation links to access the blog
- Uses Hugo's content organization and templating for maintainability
The first article to be published will be "KI Generierte Website - ein Praxisbeispiel" (available in Notion), which discusses the experience of building this website using AI-assisted development with OpenSpec.
## Scope
**In Scope:**
- Blog list page template (showing all blog posts)
- Blog post single page template
- Blog content structure in Hugo
- Navigation menu integration for blog
- First blog post: "KI Generierte Website - ein Praxisbeispiel" (German version)
- Multilingual support for blog posts
**Out of Scope:**
- Taxonomies/categories/tags (site currently has these disabled)
- Comments system
- RSS feed (can be added later if needed)
- Search functionality
- Blog post pagination (can be added when needed)
## Success Criteria
- Blog section is accessible from main navigation
- Blog listing page shows published articles with title, date, and excerpt
- Individual blog posts display with proper formatting and styling
- First article "KI Generierte Website - ein Praxisbeispiel" is published in German
- Blog supports both German and English content structure (even if English translation comes later)
- Blog pages follow site's responsive design and accessibility standards
- Lighthouse score remains >90
## Dependencies
- Existing Hugo site infrastructure (already in place)
- Internationalization system (already implemented)
- Bootstrap styling (already in place)
## Risks & Mitigations
**Risk:** Blog content structure might conflict with existing content organization
**Mitigation:** Use Hugo sections (`content/blog/`) which is the standard Hugo pattern
**Risk:** Blog post styling might need specific customization beyond current templates
**Mitigation:** Start with minimal styling, iterate based on actual needs
## Timeline Estimate
Small change, estimated 2-3 hours of implementation work:
- Blog templates: 1 hour
- Content structure and first article: 1 hour
- Testing and refinement: 30-60 minutes
@@ -0,0 +1,81 @@
# Blog Content Structure
## ADDED Requirements
### Requirement: Blog Section Organization
Blog posts SHALL be organized in a dedicated `content/blog/` directory following Hugo's content organization conventions.
#### Scenario: Blog section exists in content directory
**Given** the Hugo site structure
**When** examining the content directory
**Then** a `content/blog/` directory SHALL exist
**And** section index files `_index.de.md` and `_index.en.md` SHALL exist in `content/blog/`
**And** these index files SHALL contain appropriate front matter (title, description)
#### Scenario: Blog posts use page bundles
**Given** a blog post to be published
**When** adding the post to the site
**Then** the post SHALL be organized as a page bundle (directory with `index.de.md` or `index.en.md`)
**And** the bundle directory name SHALL be URL-friendly (lowercase, hyphens, no special characters)
**And** any post-specific assets (images, files) CAN be stored within the bundle directory
---
### Requirement: Blog Post Front Matter
Each blog post SHALL include properly structured front matter with essential metadata.
#### Scenario: Blog post front matter is complete
**Given** a blog post markdown file
**When** the post is processed by Hugo
**Then** the front matter SHALL include a `title` field
**And** the front matter SHALL include a `date` field in ISO 8601 format (YYYY-MM-DD)
**And** the front matter MAY include a `description` or `summary` field for excerpts
**And** the front matter MAY include a `draft` field to control publication status
#### Scenario: First blog post is ready
**Given** the Notion article "KI Generierte Website - ein Praxisbeispiel"
**When** converting it to Hugo format
**Then** a blog post SHALL exist at `content/blog/ki-generierte-website-praxisbeispiel/index.de.md`
**And** the post SHALL contain the full article content from Notion
**And** the front matter SHALL include title "KI Generierte Website - ein Praxisbeispiel"
**And** the front matter SHALL include an appropriate publication date
---
### Requirement: Multilingual Blog Support
Blog content SHALL support both German and English following the site's internationalization pattern.
#### Scenario: Blog section metadata is multilingual
**Given** the blog section
**When** accessing the blog in different languages
**Then** `content/blog/_index.de.md` SHALL exist with German metadata
**And** `content/blog/_index.en.md` SHALL exist with English metadata
**And** both SHALL have appropriate translated titles and descriptions
#### Scenario: Blog posts can exist in multiple languages
**Given** a blog post
**When** translations are available
**Then** the post MAY have both `index.de.md` and `index.en.md` in the same bundle
**And** Hugo SHALL serve the appropriate language version based on the URL path
**And** language switching SHALL work between translated blog posts
---
### Requirement: Content Formatting
Blog post content SHALL be written in Markdown with proper formatting support.
#### Scenario: Markdown content renders correctly
**Given** a blog post with Markdown content
**When** Hugo processes the post
**Then** headings (H1-H6) SHALL be rendered correctly
**And** paragraphs, lists, and emphasis SHALL be formatted properly
**And** code blocks with syntax highlighting SHALL be supported
**And** links and images SHALL be rendered correctly
**And** HTML content SHALL be allowed (Hugo's unsafe renderer is enabled in config)
#### Scenario: Special characters and formatting are preserved
**Given** blog post content with German special characters (ä, ö, ü, ß)
**When** the post is rendered
**Then** all special characters SHALL display correctly
**And** quotation marks and em dashes SHALL be preserved
**And** UTF-8 encoding SHALL be maintained throughout
@@ -0,0 +1,122 @@
# Blog Templates
## ADDED Requirements
### Requirement: Blog List Template
A blog list template SHALL display all published blog posts in a organized, user-friendly format.
#### Scenario: Blog list page renders with posts
**Given** published blog posts exist in `content/blog/`
**When** a user navigates to `/de/blog/` or `/en/blog/`
**Then** a blog list page SHALL be rendered using `layouts/blog/list.html`
**And** the page SHALL display all non-draft blog posts
**And** posts SHALL be sorted by date (most recent first)
#### Scenario: Blog list shows post metadata
**Given** the blog list page
**When** displaying each blog post entry
**Then** each entry SHALL show the post title as a link to the full post
**And** each entry SHALL show the publication date
**And** each entry MAY show a summary or excerpt of the post
**And** the title link SHALL navigate to the full blog post page
#### Scenario: Blog list is responsive
**Given** the blog list page
**When** viewed on different screen sizes
**Then** the layout SHALL be responsive using Bootstrap grid
**And** the page SHALL be readable on mobile devices (≥320px width)
**And** the page SHALL adapt to tablet and desktop viewports
**And** spacing and typography SHALL remain consistent with site design
---
### Requirement: Blog Post Single Template
Individual blog posts SHALL be displayed with a dedicated single post template providing optimal reading experience.
#### Scenario: Blog post page renders content
**Given** a blog post at `content/blog/ki-generierte-website-praxisbeispiel/index.de.md`
**When** a user navigates to `/de/blog/ki-generierte-website-praxisbeispiel/`
**Then** the post SHALL be rendered using `layouts/blog/single.html`
**And** the page SHALL display the post title as the main heading (H1)
**And** the page SHALL display the publication date
**And** the page SHALL display the full post content with proper formatting
#### Scenario: Blog post content is readable
**Given** a rendered blog post
**When** viewing the post content
**Then** headings SHALL use appropriate hierarchy (H2, H3, etc. for sections)
**And** paragraphs SHALL have readable line height and spacing
**And** code blocks SHALL be distinguishable with appropriate styling
**And** links SHALL be clearly identifiable and accessible
**And** images SHALL be responsive and properly sized
#### Scenario: Blog post has navigation
**Given** a blog post page
**When** a user finishes reading
**Then** the page SHALL include a link back to the blog list
**And** the navigation link SHALL be clearly visible
**And** the site's main navigation SHALL remain accessible
---
### Requirement: Blog Navigation Integration
The blog section SHALL be accessible through the site's main navigation.
#### Scenario: Blog link in main navigation
**Given** the site configuration
**When** rendering the main navigation menu
**Then** a "Blog" link SHALL appear in the navigation for German pages
**And** a "Blog" link SHALL appear in the navigation for English pages
**And** the link SHALL point to `/de/blog/` for German
**And** the link SHALL point to `/en/blog/` for English
#### Scenario: Active state for blog pages
**Given** a user is on a blog page (list or single post)
**When** viewing the navigation menu
**Then** the "Blog" link SHALL have an active state indicator
**And** the active state SHALL use the same styling as other active navigation items
**And** the active state SHALL be maintained on both blog list and single post pages
---
### Requirement: Blog Template Semantic HTML
Blog templates SHALL use semantic HTML5 elements for accessibility and SEO.
#### Scenario: Blog list uses semantic structure
**Given** the blog list template
**When** rendering the page
**Then** the main content SHALL be wrapped in a `<main>` element
**And** individual blog post entries SHALL use `<article>` elements
**And** post metadata SHALL use appropriate semantic tags (e.g., `<time>` for dates)
**And** heading hierarchy SHALL be logical and sequential
#### Scenario: Blog post uses article structure
**Given** a blog post template
**When** rendering the page
**Then** the post SHALL be wrapped in an `<article>` element
**And** the post SHALL have a `<header>` with title and metadata
**And** the post content SHALL be in a `<div>` or `<section>` with clear semantic structure
**And** all headings SHALL follow proper hierarchy
---
### Requirement: Blog Styling Consistency
Blog templates SHALL maintain visual consistency with the rest of the site.
#### Scenario: Blog pages use site styling
**Given** any blog page (list or single)
**When** the page is rendered
**Then** the page SHALL use the site's base layout (`baseof.html`)
**And** the page SHALL include the site's header and footer partials
**And** the page SHALL use Bootstrap classes for styling
**And** typography SHALL be consistent with other site pages
**And** color scheme SHALL match the site's design
#### Scenario: Blog pages are accessible
**Given** any blog page
**When** evaluated for accessibility
**Then** the page SHALL meet WCAG 2.1 AA standards
**And** all interactive elements SHALL be keyboard accessible
**And** color contrast ratios SHALL meet minimum requirements
**And** images SHALL have appropriate alt text (if any)
**And** the page SHALL have appropriate semantic structure for screen readers
@@ -0,0 +1,88 @@
# Tasks for add-blog-section
## Implementation Tasks
### 1. Create blog content structure
- [x] Create `content/blog/` directory for German blog posts
- [x] Create `content/blog/_index.de.md` for German blog section metadata
- [x] Create `content/blog/_index.en.md` for English blog section metadata
- [x] Convert Notion article "KI Generierte Website - ein Praxisbeispiel" to Markdown format
- [x] Create `content/blog/ki-generierte-website-praxisbeispiel/index.de.md` with article content
- [x] Add proper front matter (title, date, description) to blog post
**Validation:** Files exist in correct locations, front matter is properly formatted
**Dependencies:** None
**Parallelizable:** Can be done independently
---
### 2. Create blog list template
- [x] Create `layouts/blog/list.html` template for blog listing page
- [x] Display blog post titles, dates, and excerpts/summaries
- [x] Add proper semantic HTML structure
- [x] Apply Bootstrap styling for consistent look
- [x] Ensure responsive design (mobile-first)
- [x] Add pagination structure (even if not needed yet, for future)
**Validation:** Running `hugo server` shows blog list page at `/de/blog/` with article listed
**Dependencies:** Task 1 (content structure)
**Parallelizable:** No (requires content structure)
---
### 3. Create blog post single template
- [x] Create `layouts/blog/single.html` template for individual blog posts
- [x] Display post title, date, and full content
- [x] Add article metadata (author, date, reading time if desired)
- [x] Style content appropriately (headings, paragraphs, code blocks, etc.)
- [x] Ensure responsive design
- [x] Add navigation back to blog list
**Validation:** Blog post accessible at `/de/blog/ki-generierte-website-praxisbeispiel/` with proper formatting
**Dependencies:** Task 1 (content structure)
**Parallelizable:** Can be done in parallel with Task 2
---
### 4. Add blog navigation
- [x] Add "Blog" link to navigation menu (German: "Blog", English: "Blog")
- [x] Update `hugo.toml` with blog menu items for both languages
- [x] Verify navigation links work correctly
- [x] Ensure active state highlighting works on blog pages
**Validation:** Blog link appears in navigation, clicking it navigates to blog list page
**Dependencies:** Tasks 1, 2 (blog structure and list page)
**Parallelizable:** No (requires blog pages to exist)
---
### 5. Verify and test
- [x] Build site with `hugo` command (no errors)
- [x] Test blog list page rendering
- [x] Test blog post page rendering
- [x] Verify multilingual structure (German blog accessible, English structure ready)
- [x] Test navigation and links
- [x] Verify responsive design on mobile/tablet/desktop viewports
- [ ] Run Lighthouse audit (score should remain >90)
- [ ] Check accessibility (WCAG 2.1 AA compliance)
**Validation:** All tests pass, site builds successfully, Lighthouse score >90
**Dependencies:** All previous tasks
**Parallelizable:** No (final verification step)
---
## Implementation Order
Tasks should be completed in sequence: 1 → 2, 3 (parallel) → 4 → 5
Total estimated time: 2-3 hours