diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/superpowers/plans/2026-06-26-slackware-projects-section.md | 778 |
1 files changed, 778 insertions, 0 deletions
diff --git a/docs/superpowers/plans/2026-06-26-slackware-projects-section.md b/docs/superpowers/plans/2026-06-26-slackware-projects-section.md new file mode 100644 index 0000000..8213367 --- /dev/null +++ b/docs/superpowers/plans/2026-06-26-slackware-projects-section.md @@ -0,0 +1,778 @@ +# Slackware Projects Section 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:** Add a `slackware` Hugo section with a clickable hub page that aggregates per-project deep-dive pages (styled rows), restructure the main menu (rename two entries, add nested "Slackware" parent with desktop hover + mobile indented submenu), reuse the shared `tags` taxonomy for project tech, and index projects in site search. + +**Architecture:** New Hugo section `content/{en,it}/slackware/` with `_index.md` (hub) and `<project>/index.md` pages. Hub list layout loops project pages into full-width alternating rows (option #3 shape, #2 styling). Project single layout reuses the `repository/single.html` shell plus a project-header partial. Menu nesting via `parent =` in `hugo.toml`; desktop submenu is CSS-only (`group-hover` + `group-focus-within`), mobile shows indented children. Tech tags use the existing `tags` taxonomy. + +**Tech Stack:** Hugo (extended), Tailwind CSS (npm build → `main.min.css`), Alpine.js (existing, unchanged here), Hugo i18n YAML. + +**Verification model:** No unit-test runner exists for templates. Each task verifies with `hugo` build/render checks (build succeeds, expected HTML/text present in output) and ends with a commit. Theme files commit inside the `themes/danix-xyz-hacker/` submodule; content/config/i18n commit in the content repo, per CLAUDE.md Git workflow. + +**Pre-flight (run once before Task 1):** +- Content repo root: `/home/danix/Programming/GIT/danix.xyz-hacker-theme` +- Confirm theme submodule is on master: `cd themes/danix-xyz-hacker && git checkout master && cd ../..` +- All `hugo` build checks below run from the content repo root. + +--- + +### Task 1: Scaffold the slackware section content (EN + IT) + +Creates the section so later layout work has real pages to render. Includes one sample project used by every later render check. + +**Files:** +- Create: `content/en/slackware/_index.md` +- Create: `content/it/slackware/_index.md` +- Create: `content/en/slackware/sample-project/index.md` +- Create: `content/it/slackware/sample-project/index.md` + +- [ ] **Step 1: Create EN hub index** + +`content/en/slackware/_index.md`: +```toml ++++ +title = "Slackware" +date = 2026-06-26T00:00:00Z ++++ + +I build and run everything on **Slackware**. This page collects the projects +I maintain around it, and the reasons I keep choosing it: simplicity, +transparency, and staying out of my way. +``` + +- [ ] **Step 2: Create IT hub index** + +`content/it/slackware/_index.md`: +```toml ++++ +title = "Slackware" +date = 2026-06-26T00:00:00Z ++++ + +Costruisco e uso tutto su **Slackware**. Questa pagina raccoglie i progetti +che mantengo intorno ad essa, e i motivi per cui continuo a sceglierla: +semplicità, trasparenza, e non mettersi in mezzo. +``` + +- [ ] **Step 3: Create EN sample project** + +`content/en/slackware/sample-project/index.md`: +```toml ++++ +title = "Sample Project" +tagline = "A placeholder project to validate the section layout." +status = "active" +repo_url = "https://git.danix.xyz/sample-project" +tags = ["bash", "slackbuild", "python"] ++++ + +## What it is + +Freeform body content for the sample project. + +## How it works + +Details here. + +## Rationale + +Why it exists. +``` + +- [ ] **Step 4: Create IT sample project** + +`content/it/slackware/sample-project/index.md`: +```toml ++++ +title = "Progetto di Esempio" +tagline = "Un progetto segnaposto per validare il layout della sezione." +status = "active" +repo_url = "https://git.danix.xyz/sample-project" +tags = ["bash", "slackbuild", "python"] ++++ + +## Cos'è + +Contenuto libero per il progetto di esempio. + +## Come funziona + +Dettagli qui. + +## Motivazione + +Perché esiste. +``` + +- [ ] **Step 5: Verify build succeeds and pages exist** + +Run: `hugo --quiet && ls public/en/slackware/sample-project/index.html public/it/slackware/sample-project/index.html` +Expected: build completes with no errors; both files listed. (Pages render with Hugo's default `_default` layouts for now — that's fine; dedicated layouts come in Tasks 5–6.) + +- [ ] **Step 6: Commit (content repo)** + +```bash +git add content/en/slackware content/it/slackware +git commit -m "feat: scaffold slackware projects section (EN/IT) with sample project" +``` + +--- + +### Task 2: Add i18n keys and rename menu labels + +Renames "Git Repository"→Projects and "Repo"→Packages via i18n values (menu labels render through `i18n .Name`), and adds all new keys the later layouts need. + +**Files:** +- Modify: `i18n/en.yaml` +- Modify: `i18n/it.yaml` + +- [ ] **Step 1: Rename + add EN keys** + +In `i18n/en.yaml`, change the existing values: +```yaml +gitrepo: "Projects" +repo: "Packages" +``` +Then add these new keys (anywhere in the file): +```yaml +slackware: "Slackware" +slackwareTitle: "Slackware" +slackwareSubtitle: "Projects I build and maintain on Slackware." +projectStatus: "Status" +viewRepo: "View repository" +status-active: "active" +status-maintained: "maintained" +status-wip: "wip" +status-archived: "archived" +``` + +- [ ] **Step 2: Rename + add IT keys** + +In `i18n/it.yaml`, change the existing values: +```yaml +gitrepo: "Progetti" +repo: "Pacchetti" +``` +Then add: +```yaml +slackware: "Slackware" +slackwareTitle: "Slackware" +slackwareSubtitle: "Progetti che costruisco e mantengo su Slackware." +projectStatus: "Stato" +viewRepo: "Vedi repository" +status-active: "attivo" +status-maintained: "mantenuto" +status-wip: "in corso" +status-archived: "archiviato" +``` + +- [ ] **Step 3: Verify build + label rendering** + +Run: `hugo --quiet && grep -o "Projects\|Packages" public/en/index.html | sort -u` +Expected: build succeeds; output contains both `Projects` and `Packages` (the renamed desktop menu labels). + +- [ ] **Step 4: Commit (content repo)** + +```bash +git add i18n/en.yaml i18n/it.yaml +git commit -m "feat: rename menu labels (Projects/Packages) and add slackware i18n keys" +``` + +--- + +### Task 3: Restructure menu config (nest Packages + Slackware hub) + +Adds the Slackware parent (→ hub) and nests Packages under it, in both language menus. Keeps Projects external. + +**Files:** +- Modify: `hugo.toml` (Italian menu block ~lines 76–94; English menu block ~lines 122–140) + +- [ ] **Step 1: Add Slackware parent + nest repository (IT)** + +In `hugo.toml`, in the `languages.it.menus.main` block: leave the `gitrepo` (external) entry as-is. Replace the existing `repository` entry with a new Slackware parent plus the nested Packages entry: + +```toml + [[languages.it.menus.main]] + identifier = "slackware" + pageRef = "/slackware" + name = "slackware" + weight = 5 + + [[languages.it.menus.main]] + identifier = "repository" + pageRef = "/repository" + name = "repo" + parent = "slackware" + weight = 1 +``` +(Leave the `legal` entry at weight 6.) + +- [ ] **Step 2: Add Slackware parent + nest repository (EN)** + +In the `languages.en.menus.main` block, make the identical change: + +```toml + [[languages.en.menus.main]] + identifier = "slackware" + pageRef = "/slackware" + name = "slackware" + weight = 5 + + [[languages.en.menus.main]] + identifier = "repository" + pageRef = "/repository" + name = "repo" + parent = "slackware" + weight = 1 +``` + +- [ ] **Step 2b: Add project pages into the submenu (both languages)** + +Hugo does not auto-add section pages to a menu. To make project pages appear in the Slackware submenu, add `menu` front-matter to each project. Update both sample project files from Task 1 by adding to their front-matter: + +`content/en/slackware/sample-project/index.md` and `content/it/slackware/sample-project/index.md`, add inside the `+++`: +```toml +[menus.main] + parent = "slackware" + weight = 10 +``` + +- [ ] **Step 3: Verify menu nesting** + +Run: `hugo --quiet && hugo list all >/dev/null 2>&1; echo "build ok"` +Then confirm the parent renders without breaking the existing top-level menu: `grep -c "Slackware" public/en/index.html` +Expected: build ok; count >= 1. (Submenu HTML wiring is added in Tasks 4 & 7; here we only assert config builds and the parent label appears.) + +- [ ] **Step 4: Commit (content repo)** + +```bash +git add hugo.toml content/en/slackware/sample-project/index.md content/it/slackware/sample-project/index.md +git commit -m "feat: nest Packages under new Slackware menu parent (both languages)" +``` + +--- + +### Task 4: Desktop header submenu (CSS-only hover + focus-within) + +Makes the desktop nav render children as a centered row below the bar on hover/focus, for any menu item that has children. Items without children are unchanged. + +**Files:** +- Modify: `themes/danix-xyz-hacker/layouts/partials/header.html:13-27` + +- [ ] **Step 1: Replace the desktop menu loop** + +In `header.html`, replace the desktop menu block (the `<div class="hidden md:flex items-center gap-8">` … `</div>` containing the `range .Site.Menus.main`) with a parent-aware version: + +```html + <!-- Desktop menu (hidden on mobile) --> + <div class="hidden md:flex items-center gap-8"> + {{ $currentPath := strings.TrimSuffix "/" .RelPermalink }} + {{ range .Site.Menus.main }} + {{ $menuPath := strings.TrimSuffix "/" .URL }} + {{ $isActive := eq $menuPath $currentPath }} + {{ $isExternal := .Params.external }} + {{ if .HasChildren }} + <div class="relative group"> + <a + href="{{ .URL }}" + class="text-sm transition-colors inline-flex items-center gap-1 {{ if $isActive }}text-accent font-bold{{ else }}hover:text-accent{{ end }}" + aria-haspopup="true" + {{ if $isActive }}aria-current="page"{{ end }} + > + {{ i18n .Name }} + <i data-feather="chevron-down" class="w-3 h-3" aria-hidden="true"></i> + </a> + <!-- Submenu: padding-top bridges the hover gap --> + <div class="absolute left-1/2 -translate-x-1/2 top-full pt-3 hidden group-hover:flex group-focus-within:flex"> + <ul class="frosted-bar border border-border rounded-lg px-4 py-3 flex flex-col gap-2 min-w-max shadow-lg" role="menu"> + {{ range .Children }} + {{ $childExternal := .Params.external }} + <li role="none"> + <a + href="{{ .URL }}" + role="menuitem" + class="block text-sm whitespace-nowrap hover:text-accent transition-colors" + {{ if $childExternal }}target="_blank" rel="noopener noreferrer"{{ end }} + > + {{ if $childExternal }}{{ .Name }}{{ else }}{{ i18n .Name }}{{ end }} + </a> + </li> + {{ end }} + </ul> + </div> + </div> + {{ else }} + <a + href="{{ .URL }}" + class="text-sm transition-colors {{ if $isActive }}text-accent font-bold{{ else }}hover:text-accent{{ end }}" + {{ if $isActive }}aria-current="page"{{ end }} + {{ if $isExternal }}target="_blank" rel="noopener noreferrer"{{ end }} + > + {{ if $isExternal }}{{ .Name }}{{ else }}{{ i18n .Name }}{{ end }} + </a> + {{ end }} + {{ end }} + </div> +``` + +Note: this also fixes the pre-existing bug where external top-level items (Projects) rendered `i18n .Name` and lacked `target="_blank"` in the desktop bar. Now external items use `.Name` + new tab, matching the overlay. + +- [ ] **Step 2: Verify submenu HTML renders** + +Run: `hugo --quiet && grep -o "group-hover:flex" public/en/index.html | head -1` +Expected: build succeeds; `group-hover:flex` present (submenu wrapper emitted). Also confirm Packages link is inside: `grep -A30 "aria-haspopup" public/en/index.html | grep -c "/en/repository/"` → >= 1. + +- [ ] **Step 3: Commit (theme submodule)** + +```bash +cd themes/danix-xyz-hacker +git add layouts/partials/header.html +git commit -m "feat: desktop nav submenu for nested menu items (CSS hover + focus-within)" +git push origin master +cd ../.. +``` + +--- + +### Task 5: Project header partial + +Renders the light-schema header (tagline, status badge, repo link, optional image, tech pills) above project body. Used by the single layout (Task 6). + +**Files:** +- Create: `themes/danix-xyz-hacker/layouts/partials/project-header.html` + +- [ ] **Step 1: Write the partial** + +`themes/danix-xyz-hacker/layouts/partials/project-header.html`: +```html +{{ $status := .Params.status | default "active" }} +{{ $statusColor := "var(--color-accent, #a855f7)" }} +{{ if eq $status "maintained" }}{{ $statusColor = .Site.Params.secondaryAccent }}{{ end }} +{{ if eq $status "wip" }}{{ $statusColor = "#f59e0b" }}{{ end }} +{{ if eq $status "archived" }}{{ $statusColor = "#9ca3af" }}{{ end }} + +{{ $imageURL := "" }} +{{ if .Params.image }} + {{ $res := .Resources.GetMatch .Params.image }} + {{ if $res }}{{ $imageURL = $res.RelPermalink }}{{ else }}{{ $imageURL = .Params.image }}{{ end }} +{{ end }} + +<header class="mb-10"> + {{ if $imageURL }} + <img src="{{ $imageURL }}" alt="{{ .Title }}" class="w-24 h-24 object-contain rounded-lg mb-4 bg-surface/50" loading="lazy" /> + {{ end }} + + <div class="flex flex-wrap items-center gap-3 mb-2"> + <h1 class="text-4xl md:text-5xl font-bold text-accent font-oxanium">{{ .Title }}</h1> + <span class="px-3 py-1 rounded-full text-xs font-semibold" style="background-color: {{ $statusColor }}; color: #0b0b0b;"> + {{ i18n (printf "status-%s" $status) }} + </span> + </div> + + {{ with .Params.tagline }} + <p class="text-xl text-text-dim mb-4">{{ . }}</p> + {{ end }} + + <div class="flex flex-wrap items-center gap-3"> + {{ with .Params.repo_url }} + <a href="{{ . }}" target="_blank" rel="noopener noreferrer" class="btn btn-sm inline-flex items-center gap-2"> + {{ i18n "viewRepo" }} + <i data-feather="external-link" class="w-4 h-4" aria-hidden="true"></i> + </a> + {{ end }} + {{ with .Params.tags }} + <ul class="flex flex-wrap gap-2"> + {{ range . }} + <li><a href="/tags/{{ . | urlize }}/" class="px-2 py-1 rounded text-xs bg-surface text-text-dim hover:text-accent transition-colors">{{ . }}</a></li> + {{ end }} + </ul> + {{ end }} + </div> +</header> +``` + +- [ ] **Step 2: Commit (theme submodule)** + +(Partial is rendered by Task 6's layout; verification happens there. Commit now to keep tasks atomic.) +```bash +cd themes/danix-xyz-hacker +git add layouts/partials/project-header.html +git commit -m "feat: add project-header partial (status badge, repo link, tech pills)" +git push origin master +cd ../.. +``` + +--- + +### Task 6: Project single layout + +Wires `project-header.html` above the freeform body, reusing the `repository/single.html` shell idiom (breadcrumb, content-grid, prose, social-share). + +**Files:** +- Create: `themes/danix-xyz-hacker/layouts/slackware/single.html` + +- [ ] **Step 1: Write the single layout** + +`themes/danix-xyz-hacker/layouts/slackware/single.html`: +```html +{{ define "main" }} +<article class="mx-auto px-4 py-12 max-w-4xl"> + <div class="content-grid"> + {{ partial "breadcrumb.html" . }} + + {{ partial "project-header.html" . }} + + <div class="prose dark:prose-invert max-w-none mb-12"> + {{ .Content }} + </div> + + <div class="mb-12"> + {{ partial "social-share.html" (dict "page" . "mode" "inline") }} + </div> + </div> +</article> +{{ end }} +``` + +- [ ] **Step 2: Verify project page renders header + body** + +Run: `hugo --quiet && grep -o "status-active\|active" public/en/slackware/sample-project/index.html | head -1 && grep -c "View repository" public/en/slackware/sample-project/index.html` +Expected: build succeeds; the status badge text (`active`) present; `View repository` count >= 1. Also `grep -c "What it is" public/en/slackware/sample-project/index.html` → >= 1 (freeform body rendered). + +- [ ] **Step 3: Commit (theme submodule)** + +```bash +cd themes/danix-xyz-hacker +git add layouts/slackware/single.html +git commit -m "feat: slackware project single layout with project header" +git push origin master +cd ../.. +``` + +--- + +### Task 7: Mobile overlay indented children + +Renders child links indented under their parent in the hamburger overlay. Items without children unchanged. + +**Files:** +- Modify: `themes/danix-xyz-hacker/layouts/partials/hamburger-menu.html:30-45` + +- [ ] **Step 1: Replace the overlay menu loop** + +In `hamburger-menu.html`, replace the `{{ range .Site.Menus.main }}…{{ end }}` block inside `<nav class="p-6" …>` with: + +```html + {{ $currentPath := strings.TrimSuffix "/" .RelPermalink }} + {{ range .Site.Menus.main }} + {{ $menuPath := strings.TrimSuffix "/" .URL }} + {{ $isActive := eq $menuPath $currentPath }} + {{ $isExternal := .Params.external }} + <a + href="{{ .URL }}" + @click="menuOpen = false" + class="block py-4 text-lg font-medium transition-colors border-b border-border/30 {{ if $isActive }}text-accent font-bold{{ else }}hover:text-accent{{ end }}" + {{ if $isActive }}aria-current="page"{{ end }} + {{ if $isExternal }}target="_blank" rel="noopener noreferrer"{{ end }} + > + {{ if $isExternal }}{{ .Name }}{{ else }}{{ i18n .Name }}{{ end }} + {{ if $isExternal }}<span class="sr-only">{{ i18n "opensInNewTab" }}</span>{{ end }} + </a> + {{ if .HasChildren }} + <div class="pl-4 border-l-2 border-accent/40 ml-2"> + {{ range .Children }} + {{ $childExternal := .Params.external }} + <a + href="{{ .URL }}" + @click="menuOpen = false" + class="block py-3 text-base text-text-dim hover:text-accent transition-colors" + {{ if $childExternal }}target="_blank" rel="noopener noreferrer"{{ end }} + > + {{ if $childExternal }}{{ .Name }}{{ else }}{{ i18n .Name }}{{ end }} + </a> + {{ end }} + </div> + {{ end }} + {{ end }} +``` + +- [ ] **Step 2: Verify indented children render** + +Run: `hugo --quiet && grep -c "border-accent/40" public/en/index.html` +Expected: build succeeds; count >= 1 (the indented child container is emitted because Slackware has children). + +- [ ] **Step 3: Commit (theme submodule)** + +```bash +cd themes/danix-xyz-hacker +git add layouts/partials/hamburger-menu.html +git commit -m "feat: indented submenu children in mobile overlay" +git push origin master +cd ../.. +``` + +--- + +### Task 8: Project row partial + +One full-width hub row: option #3 shape (alternating image side), option #2 styling (accent stripe, oxanium title, status badge, tagline, tech pills, hover lift). Mono-glyph fallback when no image. + +**Files:** +- Create: `themes/danix-xyz-hacker/layouts/partials/project-row.html` + +- [ ] **Step 1: Write the row partial** + +Receives a dict: `{ "page": <Page>, "index": <int> }`. Even index → image left; odd → image right. + +`themes/danix-xyz-hacker/layouts/partials/project-row.html`: +```html +{{ $p := .page }} +{{ $reverse := eq (mod .index 2) 1 }} + +{{ $status := $p.Params.status | default "active" }} +{{ $statusColor := "var(--color-accent, #a855f7)" }} +{{ if eq $status "maintained" }}{{ $statusColor = $p.Site.Params.secondaryAccent }}{{ end }} +{{ if eq $status "wip" }}{{ $statusColor = "#f59e0b" }}{{ end }} +{{ if eq $status "archived" }}{{ $statusColor = "#9ca3af" }}{{ end }} + +{{ $imageURL := "" }} +{{ if $p.Params.image }} + {{ $res := $p.Resources.GetMatch $p.Params.image }} + {{ if $res }}{{ $imageURL = $res.RelPermalink }}{{ else }}{{ $imageURL = $p.Params.image }}{{ end }} +{{ end }} +{{ $glyph := substr (upper $p.Title) 0 2 }} + +<article class="group flex flex-col md:flex-row {{ if $reverse }}md:flex-row-reverse{{ end }} gap-6 items-stretch border-l-4 border-accent bg-surface/30 rounded-lg overflow-hidden transition-all duration-200 hover:-translate-y-1 hover:shadow-lg hover:bg-surface/50"> + <!-- Visual --> + <a href="{{ $p.RelPermalink }}" tabindex="-1" class="md:w-1/3 flex-shrink-0 flex items-center justify-center bg-bg/40 min-h-[10rem]"> + {{ if $imageURL }} + <img src="{{ $imageURL }}" alt="{{ $p.Title }}" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-200" loading="lazy" /> + {{ else }} + <span class="text-5xl font-bold font-oxanium text-accent/80 select-none">{{ $glyph }}</span> + {{ end }} + </a> + + <!-- Body --> + <div class="flex-1 p-6 flex flex-col gap-3"> + <div class="flex items-start justify-between gap-3"> + <h3 class="text-2xl font-bold font-oxanium"> + <a href="{{ $p.RelPermalink }}" class="group-hover:text-accent transition-colors">{{ $p.Title }}</a> + </h3> + <span class="flex-shrink-0 px-3 py-1 rounded-full text-xs font-semibold" style="background-color: {{ $statusColor }}; color: #0b0b0b;"> + {{ i18n (printf "status-%s" $status) }} + </span> + </div> + + {{ with $p.Params.tagline }} + <p class="text-text-dim">{{ . }}</p> + {{ end }} + + {{ with $p.Params.tags }} + <ul class="flex flex-wrap gap-2 mt-1"> + {{ range . }} + <li class="px-2 py-1 rounded text-xs bg-bg/60 text-text-dim">{{ . }}</li> + {{ end }} + </ul> + {{ end }} + + <div class="flex flex-wrap items-center gap-3 mt-auto pt-2"> + <a href="{{ $p.RelPermalink }}" class="btn btn-sm inline-flex items-center gap-2"> + {{ i18n "readMore" }} + <i data-feather="arrow-right" class="w-4 h-4" aria-hidden="true"></i> + </a> + {{ with $p.Params.repo_url }} + <a href="{{ . }}" target="_blank" rel="noopener noreferrer" class="text-sm text-text-dim hover:text-accent inline-flex items-center gap-1 transition-colors"> + {{ i18n "viewRepo" }} + <i data-feather="external-link" class="w-3 h-3" aria-hidden="true"></i> + </a> + {{ end }} + </div> + </div> +</article> +``` + +- [ ] **Step 2: Commit (theme submodule)** + +(Rendered by Task 9's list layout; verify there.) +```bash +cd themes/danix-xyz-hacker +git add layouts/partials/project-row.html +git commit -m "feat: add project-row partial (alternating rows, status, tech pills)" +git push origin master +cd ../.. +``` + +--- + +### Task 9: Slackware hub list layout + +Renders hero (i18n title/subtitle), the `_index.md` freeform body, then the project rows. Links to Packages. + +**Files:** +- Create: `themes/danix-xyz-hacker/layouts/slackware/list.html` + +- [ ] **Step 1: Write the list layout** + +`themes/danix-xyz-hacker/layouts/slackware/list.html`: +```html +{{ define "main" }} +<section class="mx-auto px-4 py-12 max-w-5xl"> + <div class="content-grid"> + {{ partial "breadcrumb.html" . }} + + <div class="mb-10"> + <h1 class="text-5xl md:text-6xl font-bold mb-4 text-accent font-oxanium animate-fade-in"> + {{ i18n "slackwareTitle" }} + </h1> + <p class="text-xl text-text-dim animate-fade-in-delay"> + {{ i18n "slackwareSubtitle" }} + </p> + </div> + + {{ with .Content }} + <div class="prose dark:prose-invert max-w-none mb-12"> + {{ . }} + </div> + {{ end }} + + <div class="flex flex-col gap-8"> + {{ range $index, $p := .Pages }} + {{ partial "project-row.html" (dict "page" $p "index" $index) }} + {{ end }} + </div> + </div> +</section> +{{ end }} +``` + +- [ ] **Step 2: Verify hub renders rows** + +Run: `hugo --quiet && grep -c "Sample Project" public/en/slackware/index.html && grep -c "border-l-4 border-accent" public/en/slackware/index.html` +Expected: build succeeds; `Sample Project` count >= 1 (row rendered); accent stripe class present. Confirm IT too: `grep -c "Progetto di Esempio" public/it/slackware/index.html` → >= 1. + +- [ ] **Step 3: Commit (theme submodule)** + +```bash +cd themes/danix-xyz-hacker +git add layouts/slackware/list.html +git commit -m "feat: slackware hub list layout with project rows" +git push origin master +cd ../.. +``` + +--- + +### Task 10: Index projects in site search + +Adds the `slackware` section to the JSON search index so the search box returns projects. + +**Files:** +- Modify: `themes/danix-xyz-hacker/layouts/index.json` + +- [ ] **Step 1: Union articles + slackware pages** + +Replace the first two lines of `index.json`: +``` +{{- $articles := where .Site.RegularPages "Section" "articles" -}} +{{- $articles = $articles.ByDate.Reverse -}} +``` +with: +``` +{{- $articles := where .Site.RegularPages "Section" "articles" -}} +{{- $projects := where .Site.RegularPages "Section" "slackware" -}} +{{- $articles = ($articles | append $projects).ByDate.Reverse -}} +``` +(The rest of the template is unchanged; project pages expose `.Title`, `.Permalink`, `.Date`, `.Summary` like articles.) + +- [ ] **Step 2: Verify project is in the index** + +Run: `hugo --quiet && grep -c "Sample Project" public/index.json` +Expected: build succeeds; count >= 1 (sample project present in EN search index). Confirm IT: `grep -c "Progetto di Esempio" public/it/index.json` → >= 1. + +- [ ] **Step 3: Commit (theme submodule)** + +```bash +cd themes/danix-xyz-hacker +git add layouts/index.json +git commit -m "feat: include slackware projects in search index" +git push origin master +cd ../.. +``` + +--- + +### Task 11: Build CSS and verify full integration + +Recompiles Tailwind (new classes from the new partials/layouts) and runs the cross-cutting checks from the spec. + +**Files:** +- Modify: `themes/danix-xyz-hacker/assets/css/main.min.css` (generated) + +- [ ] **Step 1: Rebuild CSS** + +Run (from content repo root): `npm run build` +Expected: completes, writes `themes/danix-xyz-hacker/assets/css/main.min.css`. + +- [ ] **Step 2: Full render verification** + +Run: `hugo --quiet` +Then confirm each spec requirement: +- Hub EN/IT: `test -f public/en/slackware/index.html && test -f public/it/slackware/index.html && echo hub-ok` +- Project page: `grep -c "View repository" public/en/slackware/sample-project/index.html` → >= 1 +- Taxonomy unification: `grep -c "Sample Project" public/tags/python/index.html` → >= 1 (project appears on the shared tag term page) +- Search: `grep -c "Sample Project" public/index.json` → >= 1 +- Menu labels: `grep -o "Projects\|Packages\|Slackware" public/en/index.html | sort -u` → all three +- Desktop submenu: `grep -c "group-hover:flex" public/en/index.html` → >= 1 +- Mobile children: `grep -c "border-accent/40" public/en/index.html` → >= 1 + +Expected: every check passes. + +- [ ] **Step 3: Commit compiled CSS (theme submodule)** + +```bash +cd themes/danix-xyz-hacker +git add assets/css/main.min.css +git commit -m "build: recompile CSS for slackware section" +git push origin master +cd ../.. +``` + +- [ ] **Step 4: Bump submodule pointer (content repo)** + +```bash +git add themes/danix-xyz-hacker +git commit -m "chore: bump theme submodule (slackware projects section)" +``` + +--- + +### Task 12: Manual browser check (user) + +Automated grep checks can't see hover/layout. The user verifies interactively before deploy. + +- [ ] **Step 1: Run dev server** + +Run: `hugo server` +Open `http://localhost:1313/en/slackware/` and `/it/slackware/`. + +- [ ] **Step 2: Confirm visually** + +- Desktop: hover "Slackware" → centered submenu row appears with Packages (+ sample project); Tab key also reveals it; "Projects" opens git.danix.xyz in a new tab with external glyph. +- Mobile (narrow window): hamburger → "Slackware" shows indented children beneath it. +- Hub rows alternate image side L/R; status badge top-right; hover lifts the row; mono-glyph fallback shows for the imageless sample project. +- Switch EN/IT; everything symmetric, no raw i18n keys visible. + +- [ ] **Step 3: Deploy when satisfied** + +Per CLAUDE.md: `git checkout production && git merge master && git push origin production` (content repo), after which the post-receive hook clones the theme master tip and builds. Then `git checkout master`. + +--- + +## Self-Review Notes + +- **Spec coverage:** menu restructure (T2/T3/T4/T7), section + sample (T1), light schema header (T5/T6), hub rows #3+#2 (T8/T9), shared `tags` taxonomy (T1 front-matter, verified T11), search indexing (T10), status badge string not git-fetch (T5/T8), CSS-only submenu + focus-within (T4), i18n EN/IT (T2), CSS build + submodule workflow (T11), deploy (T12). All covered. +- **No placeholders:** every code step shows full content; no TBD/TODO. +- **Type/name consistency:** status color logic and `status-<x>` i18n keys identical in project-header (T5) and project-row (T8); `dict "page" … "index" …` produced in T9 matches `.page`/`.index` consumed in T8; `slackwareTitle`/`slackwareSubtitle`/`viewRepo`/`status-*` defined in T2 and used in T5/T6/T8/T9. +- **Discovered simplification:** menu rename is i18n-value-only (labels render via `i18n .Name`); no `name=` churn needed. Captured in T2. +- **Bonus fix:** T4 corrects a pre-existing desktop-bar bug where external items lacked `target="_blank"` and wrongly ran `i18n .Name`. |
