ui(archiv+library): Section-Header, mehr Spalten, Kategorie-Pills

Archiv-Unterseiten (Büroführung etc.): .collection-Wrapper mit
--palette-kusa, .collection-title statt .section-header — gleiche
Optik wie Archiv/Library-Übersichten. Artikel-Grid: auto-fill
minmax(220px) → 3+ Spalten. Datum unter Titel (card-layout).

Archiv-Toggle-Pills: font-family-display (wie Dialog-Pill), margin
von spacing-md → 0.5em.

Library-Übersicht: A-Z-Index → Kategorie-Pills (Gruppe ausgeschrieben,
aktiv = ichigo), Atlas als 2-Spalten-Grid (.atlas--grid2), Suche
kombiniert mit Gruppe-Filter.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-06 02:08:02 +02:00
parent 1709dc093c
commit 42f2823ff0
3 changed files with 70 additions and 65 deletions
+19 -8
View File
@@ -745,16 +745,21 @@ a.byline-author:hover, a.journal-author:hover { color: var(--accent); }
.entry-links a:hover { text-decoration: underline; text-underline-offset: 0.2em; } .entry-links a:hover { text-decoration: underline; text-underline-offset: 0.2em; }
.entry-links-label { font-size: var(--font-size-small); font-weight: 600; color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.04em; } .entry-links-label { font-size: var(--font-size-small); font-weight: 600; color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
/* Library-Übersicht: Suchfeld + A-Z-Index */ /* Library-Übersicht: Suchfeld + Kategorie-Pills */
.lib-filter { margin-bottom: var(--spacing-md); display: flex; flex-direction: column; gap: 0.6em; } .lib-filter { margin-bottom: var(--spacing-md); display: flex; flex-direction: column; gap: 0.6em; }
.lib-search { width: 100%; padding: 0.45em 0.8em; border: 1px solid var(--color-border); border-radius: 6px; .lib-search { width: 100%; padding: 0.45em 0.8em; border: 1px solid var(--color-border); border-radius: 6px;
background: var(--color-bg-secondary); color: var(--color-text-primary); font-size: var(--font-size-base); font-family: inherit; } background: var(--color-bg-secondary); color: var(--color-text-primary); font-size: var(--font-size-base); font-family: inherit; }
.lib-search:focus { outline: none; border-color: var(--section-color, var(--accent)); } .lib-search:focus { outline: none; border-color: var(--section-color, var(--accent)); }
.lib-az { display: flex; flex-wrap: wrap; gap: 0.25em; } .lib-pills { display: flex; flex-wrap: wrap; gap: 0.3em; }
.lib-az button { padding: 0.15em 0.45em; border: 1px solid var(--color-border); border-radius: 4px; .lib-pill { font-family: var(--font-family-display); font-size: var(--font-size-small); cursor: pointer;
background: transparent; color: var(--color-text-muted); font-size: var(--font-size-small); cursor: pointer; font-family: inherit; line-height: 1.5; } padding: 0.28em 0.85em; border-radius: 999px;
.lib-az button:hover { border-color: var(--section-color, var(--accent)); color: var(--color-text-primary); } background: none; border: 1px solid var(--color-border); color: var(--color-text-muted); }
.lib-az button.active { background: var(--section-color, var(--accent)); border-color: var(--section-color, var(--accent)); color: white; } .lib-pill:hover { border-color: var(--section-color, var(--accent)); color: var(--color-text-primary); }
.lib-pill.active { background: var(--section-color, var(--accent)); border-color: var(--section-color, var(--accent)); color: white; }
/* Library-Atlas: zwei Kategorien nebeneinander */
.atlas--grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--spacing-md); align-items: start; }
@media (max-width: 600px) { .atlas--grid2 { grid-template-columns: 1fr; } }
/* ── Software-Landing: Werkzeuge getrennt von Texten ── */ /* ── Software-Landing: Werkzeuge getrennt von Texten ── */
.software-h { font-family: var(--font-family-serif); margin: var(--spacing-md) 0 var(--spacing-sm); } .software-h { font-family: var(--font-family-serif); margin: var(--spacing-md) 0 var(--spacing-sm); }
@@ -1149,6 +1154,7 @@ a.byline-author:hover, a.journal-author:hover { color: var(--accent); }
.collection { margin-top: var(--spacing-sm); } .collection { margin-top: var(--spacing-sm); }
.collection-title, .collection-title,
.collection-inner { max-width: 48.5rem; margin-inline: auto; } .collection-inner { max-width: 48.5rem; margin-inline: auto; }
.collection .section-rubric { max-width: 48.5rem; margin-inline: auto; margin-top: var(--spacing-sm); }
.collection-title { .collection-title {
text-align: left; text-align: left;
font-family: var(--font-family-serif); font-family: var(--font-family-serif);
@@ -1163,9 +1169,9 @@ a.byline-author:hover, a.journal-author:hover { color: var(--accent); }
} }
/* Archiv-Umschalter (Kategorie ↔ Jahr) */ /* Archiv-Umschalter (Kategorie ↔ Jahr) */
.archiv-toggle { display: inline-flex; gap: 0.3em; margin: 0 0 var(--spacing-md); } .archiv-toggle { display: inline-flex; gap: 0.3em; margin: 0 0 0.5em; }
.archiv-toggle button { .archiv-toggle button {
font: inherit; font-size: var(--font-size-small); cursor: pointer; font-family: var(--font-family-display); font-size: var(--font-size-small); cursor: pointer;
padding: 0.3em 0.95em; border-radius: 999px; padding: 0.3em 0.95em; border-radius: 999px;
background: none; border: 1px solid var(--color-border); color: var(--color-text-muted); background: none; border: 1px solid var(--color-border); color: var(--color-text-muted);
} }
@@ -1180,6 +1186,8 @@ a.byline-author:hover, a.journal-author:hover { color: var(--accent); }
.time-list ul { .time-list ul {
list-style: none; list-style: none;
margin-left: 0; margin-left: 0;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 1.25rem;
} }
.list-item { .list-item {
border-top: 1px solid var(--color-border); border-top: 1px solid var(--color-border);
@@ -1212,6 +1220,9 @@ a.byline-author:hover, a.journal-author:hover { color: var(--accent); }
font-style: italic; font-style: italic;
line-height: 1.45; line-height: 1.45;
} }
/* Im Grid: Datum unter dem Titel, keine Trennlinie zwischen Cards */
.time-list .list-title-row { flex-direction: column; align-items: flex-start; gap: 0.2em; }
.time-list .list-item, .time-list .list-item:last-child { border-top: none; border-bottom: none; }
/* ------------------------------------------------------------------------ /* ------------------------------------------------------------------------
Software showcase Software showcase
+24 -23
View File
@@ -132,30 +132,31 @@
</section> </section>
{{ else }} {{ else }}
{{/* Archiv-Unterseite (Rubrik): chronologisch */}} {{/* Archiv-Unterseite (Rubrik): gleiche Optik wie Übersichten */}}
{{ $section := path.Base .RelPermalink }} <div class="collection" style="--section-color: var(--palette-kusa)">
<header class="section-header" data-section="{{ $section }}">
<p class="section-rubric">Archiv</p> <p class="section-rubric">Archiv</p>
<h1 class="section-title">{{ .Title }}</h1> <h1 class="collection-title">{{ .Title }}</h1>
{{ with .Params.description }}<p class="section-description">{{ . }}</p>{{ end }} <div class="collection-inner">
</header> {{ with .Params.description }}<p class="section-description">{{ . }}</p>{{ end }}
{{ .Content }} {{ .Content }}
<div class="time-list" data-section="{{ $section }}"> <div class="time-list">
<ul> <ul>
{{ range .RegularPages.ByDate.Reverse }} {{ range .RegularPages.ByDate.Reverse }}
<li class="list-item"> <li class="list-item">
<div class="list-title-row"> <div class="list-title-row">
<div class="list-title"> <div class="list-title">
<a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a> <a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
{{ with .Params.summary }} {{ with .Params.summary }}
<div class="list-summary text-muted">{{ . }}</div> <div class="list-summary text-muted">{{ . }}</div>
{{ end }} {{ end }}
</div> </div>
<div class="list-meta">{{ partial "date.html" .Date }}</div> <div class="list-meta">{{ partial "date.html" .Date }}</div>
</div> </div>
</li> </li>
{{ end }} {{ end }}
</ul> </ul>
</div>
</div>
</div> </div>
{{ end }} {{ end }}
{{ end }} {{ end }}
+27 -34
View File
@@ -7,37 +7,30 @@
{{ $pages := where site.RegularPages "Section" "library" }} {{ $pages := where site.RegularPages "Section" "library" }}
{{ if $pages }} {{ if $pages }}
{{/* A-Z Buchstaben aus vorhandenen Titeln */}} {{/* Gruppen sammeln + sortieren */}}
{{ $letters := slice }}
{{ range $pages }}
{{ $first := substr (upper .Title) 0 1 }}
{{ $first = replace $first "Ä" "A" }}
{{ $first = replace $first "Ö" "O" }}
{{ $first = replace $first "Ü" "U" }}
{{ if not (in $letters $first) }}{{ $letters = $letters | append $first }}{{ end }}
{{ end }}
{{ $letters = sort $letters }}
<div class="lib-filter">
<input id="lib-search" class="lib-search" type="search" placeholder="Suchen …" autocomplete="off" spellcheck="false">
<div class="lib-az">
<button class="lib-az-all active" data-letter="">Alle</button>
{{ range $letters }}<button data-letter="{{ lower . }}">{{ . }}</button>{{ end }}
</div>
</div>
{{/* Gruppen aufbauen */}}
{{ $groups := dict }} {{ $groups := dict }}
{{ range $pages }} {{ range $pages }}
{{ $g := .Params.group | default "Allgemein" }} {{ $g := .Params.group | default "Allgemein" }}
{{ $existing := index $groups $g | default slice }} {{ $existing := index $groups $g | default slice }}
{{ $groups = merge $groups (dict $g ($existing | append .)) }} {{ $groups = merge $groups (dict $g ($existing | append .)) }}
{{ end }} {{ end }}
{{ $groupNames := slice }}
{{ range $g, $_ := $groups }}{{ $groupNames = $groupNames | append $g }}{{ end }}
{{ $groupNames = sort $groupNames }}
<section class="atlas"> <div class="lib-filter">
{{ range $g, $ps := $groups }} <input id="lib-search" class="lib-search" type="search" placeholder="Suchen …" autocomplete="off" spellcheck="false">
<article class="atlas-section"> <div class="lib-pills">
<h2>{{ $g }}</h2> <button class="lib-pill active" data-group="">Alle</button>
{{ range $groupNames }}<button class="lib-pill" data-group="{{ . }}">{{ . }}</button>{{ end }}
</div>
</div>
<section class="atlas atlas--grid2">
{{ range $groupNames }}
{{ $ps := index $groups . }}
<article class="atlas-section" data-group="{{ . }}">
<h2>{{ . }}</h2>
<ul class="atlas-list"> <ul class="atlas-list">
{{ range sort $ps "Title" }} {{ range sort $ps "Title" }}
{{ $norm := lower .Title }} {{ $norm := lower .Title }}
@@ -58,31 +51,31 @@
<script> <script>
(function(){ (function(){
var input = document.getElementById('lib-search'); var input = document.getElementById('lib-search');
var azBtns = document.querySelectorAll('.lib-az button'); var pills = document.querySelectorAll('.lib-pill');
var activeLetter = ''; var activeGroup = '';
function filter() { function filter() {
var q = input.value.trim().toLowerCase() var q = input.value.trim().toLowerCase()
.replace(/ä/g,'a').replace(/ö/g,'o').replace(/ü/g,'u').replace(/ß/g,'ss'); .replace(/ä/g,'a').replace(/ö/g,'o').replace(/ü/g,'u').replace(/ß/g,'ss');
document.querySelectorAll('.atlas-section').forEach(function(sec) { document.querySelectorAll('.atlas-section').forEach(function(sec) {
var groupMatch = !activeGroup || sec.dataset.group === activeGroup;
if (!groupMatch) { sec.style.display = 'none'; return; }
var visible = 0; var visible = 0;
sec.querySelectorAll('li[data-title]').forEach(function(li) { sec.querySelectorAll('li[data-title]').forEach(function(li) {
var t = li.dataset.title; var matchQ = !q || li.dataset.title.indexOf(q) !== -1;
var matchQ = !q || t.indexOf(q) !== -1; li.style.display = matchQ ? '' : 'none';
var matchL = !activeLetter || t.charAt(0) === activeLetter; if (matchQ) visible++;
if (matchQ && matchL) { li.style.display = ''; visible++; }
else li.style.display = 'none';
}); });
sec.style.display = visible ? '' : 'none'; sec.style.display = visible ? '' : 'none';
}); });
} }
input.addEventListener('input', filter); input.addEventListener('input', filter);
azBtns.forEach(function(btn) { pills.forEach(function(btn) {
btn.addEventListener('click', function() { btn.addEventListener('click', function() {
azBtns.forEach(function(b){ b.classList.remove('active'); }); pills.forEach(function(b){ b.classList.remove('active'); });
this.classList.add('active'); this.classList.add('active');
activeLetter = this.dataset.letter || ''; activeGroup = this.dataset.group || '';
filter(); filter();
}); });
}); });