From 778d0fd6ed1ee49136171b863eb0f32d0a2d8723 Mon Sep 17 00:00:00 2001 From: Kai Moritz Date: Fri, 5 Jun 2026 14:54:06 +0000 Subject: [PATCH] =?utf8?q?Spec-Dokumentation=20f=C3=BCr=20Navigations-Konz?= =?utf8?q?ept=20und=20Classic-Bildsprache?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit CLAUDE.md um zwei Spec-Abschnitte erweitert, die das Design-Intent festhalten und als Messlatte für künftige Implementierungen dienen: - Spec: Navigations-Menü — Ziele (Navigation + SEO-Sitemap), Canonical-Placement-Prinzip (jede Seite genau einmal an ihrem festen Ort), NONE als semantische Baseline, Breadcrumb-Hervorhebung per - Spec: Classic-Layout Menü-Bildsprache — vollständiges Präfix-System (V für aufklappbar/geöffnet, > für ausgewählt-aber-terminal), Regel dass `sub` nur bei tatsächlich sichtbaren Kindern vergeben wird, Sichtbarkeitslogik (aktiver Ast), Blog-Archiv-Ausnahme (alle Jahre immer sichtbar) Implementierungsabschnitte in eigenständige Sektion ausgelagert, sodass Spec (Warum/Was) und Implementierung (Wie) klar getrennt sind. Co-Authored-By: Claude Sonnet 4.6 --- CLAUDE.md | 146 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 126 insertions(+), 20 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 78b947e0..f7445e0c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -27,6 +27,7 @@ hugo-juplo/ │ │ ├── terms.html ← Taxonomie-Terms in der Marginalspalte │ │ └── menu/ │ │ ├── default.html ← Standard-Menü (nutzt tree.html) +│ │ ├── blog.html ← Blog-Menü für alle Blog-Seiten │ │ └── tree.html ← Rekursives Partial für den Seitenbaum │ ├── _shortcodes/ ← Shortcodes für Content-Dateien │ │ ├── marginalcontent-html.html ← HTML-Content in Marginalspalte @@ -101,34 +102,135 @@ Resurrection ist natives CSS). Wird relevant, wenn Classic auf Custom Properties umgestellt wird. Installation: `npm install --save-dev sass` oder standalone Binary von sass-lang.com. Hugo erkennt Dart Sass automatisch, wenn im PATH. -## Menü-System +--- -Das Menü (`nav#nav`) ist bewusst am HTML-Ende platziert und funktioniert gleichzeitig als SEO-Sitemap. Details zum Konzept: siehe CLAUDE.md im Content-Repo. +## Spec: Navigations-Menü -### Grundprinzip: HTML immer vollständig, CSS steuert Sichtbarkeit +### Konzept und Ziele -Das HTML enthält **immer alle Einträge** (vollständige Sitemap). Die Sichtbarkeit im Classic-Layout wird ausschließlich über CSS-Klassen gesteuert: +Das Menü (`nav#nav`) verfolgt gleichzeitig zwei Ziele: + +1. **Nutzer-Navigation**: Der Nutzer soll sich durch die Seite bewegen können und immer verstehen, wo er sich befindet. +2. **SEO-Sitemap**: Alle Seiten sind in einem strukturierten HTML-Block verlinkt, damit Suchmaschinen die vollständige Seitenstruktur erfassen können. + +Aus diesen Zielen folgt ein Kernprinzip: **Das Menü-HTML ist auf jeder Seite vollständig** — es enthält alle Seiten der Site in ihrer vollständigen Hierarchie. Welche Einträge in einem gestalteten Layout sichtbar sind, steuert ausschließlich CSS. Das Layout `none` (kein CSS, Browser-Defaults) zeigt deshalb auf jeder Seite die vollständige Sitemap. + +Das Menü ist bewusst **am Ende des HTML** platziert (im `.marginal`-Bereich nach dem Hauptinhalt). In gestalteten Layouts erscheint es optisch neben dem Inhalt (float/grid), ohne die inhaltliche Lesereihenfolge zu unterbrechen. Suchmaschinen und Screen-Reader begegnen zuerst dem Inhalt. + +### Kanonischer Platz (Canonical Placement) + +Jede Seite erscheint im Menü **genau einmal**, an ihrem festen kanonischen Platz in der Hierarchie. Es gibt keine Duplikate: + +- Blog-Artikel erscheinen **nur unter dem Archiv** (ihr chronologischer Ablageort), niemals noch einmal unter Kategorien oder Tags. +- Kategorien und Tags erscheinen als navigierbare Einträge im Menü, aber **ohne** die ihnen zugeordneten Artikel darunter. Die Artikel gehören ins Archiv, nicht in die Taxonomie. +- Taxonomie-Seiten (Kategorien, Tags) sind aus Sicht des Menüs Inhalts-Seiten, die man besuchen kann — kein zweiter Weg zu denselben Artikeln. + +Diese Regel hält die Sitemap-Funktion des Menüs sauber: Es ist eine Karte der Inhalts-Hierarchie, keine mehrdimensionale Inhaltsindizierung. + +### NONE-Layout als semantische Baseline + +Das `none`-Layout ist **nicht** ein degradierter Fallback, sondern die **semantische Grundform** des Menü-HTML. Es zeigt: + +- Die vollständige Sitemap aller Seiten +- Den aktiven Breadcrumb-Pfad durch fette Schrift (`` im HTML) +- Die Hierarchie durch geschachtelte HTML-Listen + +Das Classic-Layout ist eine **gestaltete Interpretation** dieses HTML. Das Resurrection-Layout wird ebenfalls eine gestaltete Interpretation desselben HTML sein. Kein Layout soll das HTML verändern, um ein bestimmtes visuelles Ergebnis zu erreichen — das HTML drückt die Semantik aus, CSS die Gestaltung. + +**Konsequenz für die Implementierung**: Wenn eine CSS-Klasse für ein bestimmtes Layout benötigt wird, wird sie zum HTML hinzugefügt (als semantisch neutraler Marker). Wenn das ``-Element in einem Layout unerwünscht ist, wird es per CSS neutralisiert — nicht aus dem HTML entfernt. + +### Breadcrumb-Hervorhebung im Menü + +Der aktive Pfad — die aktuelle Seite und alle ihre Vorfahren bis Home — ist im Menü-HTML durch `` innerhalb des ``-Elements markiert: + +```html +2021 +``` + +Diese Markierung ist **semantisch**, nicht nur dekorativ: Sie drückt aus, dass dieser Eintrag Teil des aktuellen Kontexts ist. Im NONE-Layout rendert der Browser `` als fett — der Nutzer sieht ohne jedes CSS den kompletten Breadcrumb-Pfad fett hervorgehoben. + +In gestalteten Layouts wird `` je nach Bedarf neutralisiert oder anders gestaltet. Im Classic-Layout erfolgt die Neutralisierung über `display: contents` (s. Implementierungsabschnitt unten). + +--- + +## Spec: Classic-Layout — Menü-Bildsprache + +### Überblick + +Das Classic-Layout zeigt das Menü als selektiv aufgeklappten Baum. Die visuelle Sprache kommuniziert auf einen Blick: +- Wo man sich befindet (Breadcrumb-Pfad durch Farbe und Präfix) +- Was man noch navigieren/aufklappen kann (Präfix `V` als Affordanz) +- Welche Einträge Terminal-Links sind (Präfix `>` ohne Aufklapp-Option) + +### Präfix-System + +Vor jedem Eintrag kann ein Präfix erscheinen, der seinen Zustand kommuniziert: + +| Situation | Präfix | Wann | +|---|---|---| +| Eintrag hat sichtbare Untereinträge und man hovert darüber | `V ` | Hover/Fokus/Aktiv auf `li.sub > a` | +| Eintrag liegt auf dem Breadcrumb-Pfad **und** hat sichtbare Untereinträge | `V ` | `li.sub > a.selected` | +| Eintrag liegt auf dem Breadcrumb-Pfad, hat aber **keine** sichtbaren Untereinträge | `> ` | `li:not(.sub) > a.selected` | +| Eintrag hat keine sichtbaren Untereinträge, man hovert darüber | `> ` | Hover/Fokus/Aktiv auf `li:not(.sub) > a` | + +**Das `V` signalisiert immer eine Möglichkeit**, entweder zu navigieren (Hover) oder eine bereits geöffnete Ebene (Selected mit sichtbaren Kindern). Das `>` zeigt, dass dieser Eintrag zwar ausgewählt oder navigierbar ist, aber keine weitere Ebene öffnet. + +### Sichtbarkeit und "Sub": die Bildsprache folgt dem tatsächlichen Verhalten + +Der Präfix `V` erscheint nur, wenn ein Eintrag **tatsächlich sichtbare** Untereinträge hat. Sind alle HTML-Untereinträge durch CSS unsichtbar (Klasse `nav-leaf`), gilt der Eintrag visuell als Terminal-Link — unabhängig davon, ob im HTML Sub-Elemente existieren. + +**Beispiel**: Jahres-Items (z.B. "2021") haben im HTML Artikel als Kinder. Im Classic-Layout sind diese Artikel aber alle `nav-leaf` und damit unsichtbar. Der Nutzer kann "2021" nicht "aufklappen" — es gibt nichts zu sehen. Deshalb hat "2021" keine `sub`-Klasse, und der Präfix ist `>` (ausgewählt, aber terminal) statt `V` (scheinbar aufklappbar). + +**Regel**: `sub` wird nur vergeben, wenn im Classic-Layout tatsächlich sichtbare Kinder existieren. Die Bildsprache darf den Nutzer nicht täuschen. + +### Sichtbarkeitslogik: der aktive Ast + +Das Classic-Menü zeigt immer genau den **aktiven Ast** — wie ein Dateimanager, der nur den aktuellen Ordner und seine direkten Geschwister anzeigt: + +- Einträge **außerhalb** des aktiven Pfads werden durch die CSS-Klasse `off` ausgeblendet (`display: none`) +- Einträge **auf** dem aktiven Pfad sind immer sichtbar +- Einträge, die im Menü strukturell vorhanden, aber prinzipiell nie sichtbar sein sollen (z.B. Blog-Artikel), erhalten `nav-leaf` (`display: none`) +- Aufgeklappte Sub-Listen erhalten `active` und bekommen einen sichtbaren `margin-top` als visuellen Abstand zur übergeordneten Ebene + +### Besonderheit: Blog-Archiv + +Im Blog-Archiv-Bereich weicht die Sichtbarkeitslogik bewusst ab: **Alle Jahre sind immer sichtbar** (nie `off`), egal ob ein Jahr, ein Artikel darunter oder die Archiv-Übersicht aktiv ist. Der Nutzer kann jederzeit zwischen Jahrgängen wechseln, ohne zuerst zurücknavigieren zu müssen. + +Diese Ausnahme gilt nur für die **Jahre**. Die Artikel unter jedem Jahr sind immer `nav-leaf` (in Classic unsichtbar) — sie erscheinen nur im Inhaltsbereich der Seite, nicht im Menü. + +--- + +## Implementierung: Menü-HTML und CSS-Klassen + +### CSS-Marker-Klassen + +Das HTML enthält **immer alle Einträge**. Die Sichtbarkeit im Classic-Layout wird ausschließlich über CSS-Klassen gesteuert: | CSS-Klasse | Bedeutung | Classic | NONE | |---|---|---|---| | `off` | Item liegt außerhalb des aktiven Navigationspfads | `display: none` | sichtbar | -| `nav-leaf` | Blatt-Item, das im Menü nicht angezeigt werden soll (z.B. Blog-Artikel, einzelne Kategorien/Tags in der Blog-Navigation) | `display: none` | sichtbar | -| `active` | Sub-Liste ist aufgeklappt (auf dem aktiven Pfad) | sichtbarer Margin-Top | keine CSS-Wirkung | -| `selected` | Link gehört zum aktiven Breadcrumb-Pfad | andere Farbe + Präfix | keine CSS-Wirkung | +| `nav-leaf` | Blatt-Item, das im Menü nie angezeigt werden soll (Blog-Artikel, einzelne Taxonomie-Namen in der Blog-Navigation) | `display: none` | sichtbar | +| `sub` | Item hat **sichtbare** Untereinträge im Classic-Layout | `V`-Präfix auf Hover/Selected | keine Wirkung | +| `active` | Sub-Liste ist aufgeklappt (liegt auf dem aktiven Pfad) | `margin-top: 1.5em` | keine Wirkung | +| `selected` | Link gehört zum aktiven Breadcrumb-Pfad | Akzentfarbe + Präfix | keine Wirkung | -### Breadcrumb-Markierung im NONE-Layout +### ``-Neutralisierung in Classic -Items auf dem aktiven Breadcrumb-Pfad (current + ancestors) bekommen `` innerhalb des ``-Elements: -```html -Titel +Da `` im HTML semantisch die Breadcrumb-Items markiert (s. Spec oben), muss das Classic-Layout seine visuellen Effekte neutralisieren. Die Regel: + +```scss +#submenu li.s > a.s > strong { + display: contents; +} ``` -Im Classic-Layout wird das `` durch die CSS-Regel -`#submenu li.s > a.s > strong { display: contents; }` -vollständig neutralisiert (`display: contents` entfernt die Box des Elements, sodass Font, Spacing und Box-Modell identisch wie ohne `` sind). -Im NONE-Layout (kein CSS) rendert der Browser `` als fett → sichtbare Pfad-Hervorhebung. +`display: contents` entfernt die Box des ``-Elements vollständig: Font, Spacing und Box-Modell sind identisch zum Text ohne ``. Das ist robuster als `font-weight: normal`, weil es alle möglichen Nebeneffekte (`line-height`, Inline-Formatting-Context etc.) in einem Schritt ausschließt. + +--- -### Aktueller Stand der Menü-Templates +## Implementierung: Menü-Templates + +### Aktueller Stand - `_partials/menu/default.html`: Generisches Menü für nicht-Blog-Seiten (nutzt `tree.html`) - `_partials/menu/tree.html`: Rekursives Partial für den Seitenbaum (mit Projects-Sichtbarkeitslogik); setzt `` für aktive Pfad-Items @@ -137,11 +239,15 @@ Im NONE-Layout (kein CSS) rendert der Browser `` als fett → sichtbare ### Blog-Menü-Logik (`blog.html`) -- **Jahres-Items**: Nie `sub` und nie `off` (immer sichtbar in Classic, kein "V"-Indikator), außer auf der `/blog/`-Übersichtsseite (`off`). Die Sub-Liste der Jahres-Items erhält auch keine `active`-Klasse, da ihre Kinder (Artikel) in Classic immer `nav-leaf` sind und keine `active`-Margin benötigt wird. -- **Artikel-Items**: Immer `nav-leaf` (in Classic ausgeblendet, in NONE sichtbar) -- **Kategorien/Tags**: `off` auf allen Blog-Seiten außer `/blog/` selbst; im NONE-Layout trotzdem sichtbar, inklusive der einzelnen Kategorie-/Tag-Namen als `nav-leaf`-Items (ohne die jeweiligen Artikel darunter) +- **Blog-Item**: `sub` (hat sichtbare Kinder: Archiv, Kategorien, Tags); `selected` wenn auf beliebiger Blog-Unterseite +- **Archiv-Item**: `sub` (hat sichtbare Kinder: die Jahre); `selected` wenn auf Archiv-Seite oder darunter +- **Jahres-Items**: Weder `sub` noch `off` (immer sichtbar, kein `V`-Indikator, da Kinder alle `nav-leaf`). Ausnahme: `off` auf `/blog/` selbst. Die Sub-Liste der Jahre erhält keine `active`-Klasse, da ihre Kinder (`nav-leaf`) in Classic unsichtbar sind und kein Margin benötigt wird. +- **Artikel-Items**: Immer `nav-leaf` (in Classic ausgeblendet, in NONE vollständig sichtbar) +- **Kategorien/Tags-Items**: `off` auf allen Blog-Seiten außer `/blog/` selbst; die einzelnen Kategorie-/Tag-Namen als `nav-leaf`-Items darunter (ohne die zugeordneten Artikel — Canonical Placement) + +**Offene Aufgabe:** Den `menu`-Block aus den Categories/Tags-Templates (`categories/taxonomy.html`, `categories/term.html`, `tags/taxonomy.html`, `tags/term.html`) in das `blog.html`-Partial konsolidieren, damit auch diese Seiten die vollständige Blog-Navigation und das korrekte NONE-Sitemap-Verhalten erhalten. -**Offene Aufgabe:** Den `menu`-Block aus den Categories/Tags-Templates in das `blog.html`-Partial oder ein weiteres Partial konsolidieren. +--- ## Shortcodes -- 2.39.5