ui: Artikel-Fuß neu — zitieren als Link, Tags neben Dialog, Versionen-Liste

- zitieren: schlichter Link direkt unter den Quellen (statt Pill); klappt eine
  dezente, gesamthaft kopierbare Quellenangabe auf — wahlweise APA oder DIN
- Tags raus von unter den Quellen → in die Aktionsreihe, ganz rechts neben Dialog
- „Versionen" als Link eine Zeile darunter; Liste in voller Inhaltsbreite und
  normaler Schrift/Größe (statt mono-Box). Auswahl öffnet Diff/Fassung oben.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 02:19:27 +02:00
parent f2aef5c89a
commit 6aa88a07a6
4 changed files with 162 additions and 147 deletions
+68 -82
View File
@@ -1475,106 +1475,92 @@ img:hover { filter: grayscale(0%); }
Herkunft / Zitieren — „lebendes Dokument": Version (→ Commit), Verlauf, Herkunft / Zitieren — „lebendes Dokument": Version (→ Commit), Verlauf,
Zitieren-Knopf. Dezent unter dem Beitrag. Zitieren-Knopf. Dezent unter dem Beitrag.
------------------------------------------------------------------------ */ ------------------------------------------------------------------------ */
.provenance { /* ------------------------------------------------------------------------
Artikel-Fuß: zitieren (Link + dezente Angabe), Aktionsreihe, Versionen.
------------------------------------------------------------------------ */
/* Zitieren: schlichter Link direkt unter den Quellen. */
.cite { margin-top: var(--spacing-md); }
.cite-toggle,
.versions-toggle,
.cite-copy {
font: inherit;
font-size: var(--font-size-small);
color: var(--color-text-muted);
background: none;
border: none;
padding: 0;
cursor: pointer;
text-decoration: underline;
text-underline-offset: 0.2em;
}
.cite-toggle:hover,
.versions-toggle:hover,
.versions-toggle[aria-expanded="true"],
.cite-copy:hover { color: var(--accent); }
.cite-box { margin-top: 0.7em; }
.cite-text {
margin: 0 0 0.5em;
font-family: var(--font-family-serif);
font-size: var(--font-size-small);
line-height: 1.6;
color: var(--color-text-muted);
user-select: all; /* ein Klick markiert die ganze Angabe */
}
.cite-actions { display: flex; align-items: center; gap: 0.9em; font-size: var(--font-size-small); }
.cite-fmt {
font: inherit;
font-size: var(--font-size-small);
color: var(--color-text-muted);
background: none;
border: none;
padding: 0;
cursor: pointer;
}
.cite-fmt:hover { color: var(--accent); }
.cite-fmt.is-active { color: var(--accent); font-weight: 600; }
.cite-status { color: var(--color-text-muted); }
/* Aktionsreihe: Dialog links, Tags ganz rechts; darüber eine Trennlinie. */
.article-actions {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
gap: 0.5em; justify-content: space-between;
gap: 0.8em 1em;
margin-top: var(--spacing-lg); margin-top: var(--spacing-lg);
padding-top: var(--spacing-sm); padding-top: var(--spacing-md);
border-top: 1px solid var(--color-border); border-top: 1px solid var(--color-border);
font-family: var(--font-family-mono);
font-size: var(--font-size-small);
color: var(--color-text-muted);
}
/* Version/Zitieren im Tag-Look (gefüllt, weich); Dialog separat (Akzent-Outline). */
.prov-version,
.prov-cite {
display: inline-block;
padding: 0.35rem 0.85rem;
line-height: 1.3;
font-family: var(--font-family-display);
font-size: 0.78rem;
font-weight: 500;
letter-spacing: 0.02em;
text-transform: lowercase;
color: var(--color-text-primary);
background: color-mix(in oklab, var(--section-color, var(--accent)) 14%, transparent);
border: none;
border-radius: 999px;
text-decoration: none;
cursor: pointer;
}
.prov-version:hover,
.prov-cite:hover,
.prov-version[aria-expanded="true"],
.prov-cite[aria-expanded="true"] {
background: color-mix(in oklab, var(--section-color, var(--accent)) 30%, transparent);
} }
.article-actions .tag-pills { margin: 0; }
/* Aufklappendes Zitat-Panel: zeigt die Quellenangabe lesbar + Kopieren. */ /* Versionen: eine Zeile darunter, öffnet die Liste auf der Seite. */
.prov-citation { .article-versions { margin-top: var(--spacing-sm); }
margin-top: var(--spacing-sm);
padding: var(--spacing-sm) var(--spacing-md);
border: 1px solid var(--color-border);
border-radius: 8px;
background: var(--color-bg-secondary);
}
.prov-citation-text {
margin: 0 0 0.6em;
font-family: var(--font-family-serif);
font-size: var(--font-size-small);
line-height: 1.5;
user-select: all; /* ein Klick markiert die ganze Angabe */
}
.prov-citation-actions { display: flex; align-items: center; gap: 0.8em; }
.prov-citation-copy {
font-family: var(--font-family-mono);
font-size: var(--font-size-small);
color: var(--color-text-primary);
background: none;
border: 1px solid var(--color-border);
border-radius: 6px;
padding: 0.2em 0.7em;
cursor: pointer;
}
.prov-citation-copy:hover { border-color: var(--accent); color: var(--accent); }
.prov-citation-status {
font-family: var(--font-family-mono);
font-size: var(--font-size-small);
color: var(--color-text-muted);
}
/* ------------------------------------------------------------------------ /* Versionsliste: volle Inhaltsbreite, normale Schrift/Größe wie der Text. */
Versions-Marke + Verlauf — alte Fassungen direkt auf der Seite anzeigen. .version-panel { margin-top: 0.8rem; }
------------------------------------------------------------------------ */
.version-panel {
margin-top: 0.5rem;
border: 1px solid var(--color-border);
border-radius: 8px;
background: var(--color-bg-secondary);
padding: 0.3rem;
}
.version-list { list-style: none; margin: 0; padding: 0; } .version-list { list-style: none; margin: 0; padding: 0; }
.version-list button { .version-list button {
display: flex; display: flex;
gap: 0.9em; gap: 1em;
width: 100%; width: 100%;
text-align: left; text-align: left;
font-family: var(--font-family-mono); font-family: var(--font-family-serif);
font-size: var(--font-size-small); font-size: 1rem;
line-height: 1.5;
color: var(--color-text-primary); color: var(--color-text-primary);
background: none; background: none;
border: none; border: none;
border-radius: 6px; border-bottom: 1px solid var(--color-border);
padding: 0.45em 0.6em; padding: 0.7em 0;
cursor: pointer; cursor: pointer;
} }
.version-list button:hover { background: var(--color-bg-primary); } .version-list li:first-child button { border-top: 1px solid var(--color-border); }
.version-list .v-date { white-space: nowrap; } .version-list button:hover { color: var(--accent); }
.version-list .v-subject { flex: 1; color: var(--color-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .version-list .v-date { white-space: nowrap; min-width: 6em; }
.version-list .v-hash { white-space: nowrap; color: var(--color-text-muted); } .version-list .v-subject { flex: 1; color: var(--color-text-muted); }
.version-empty { margin: 0.4rem 0.6rem; font-size: var(--font-size-small); color: var(--color-text-muted); } .version-list .v-hash { white-space: nowrap; color: var(--color-text-muted); font-family: var(--font-family-mono); font-size: 0.85em; }
.version-empty { margin: 0.6rem 0; color: var(--color-text-muted); }
.version-banner { .version-banner {
display: flex; display: flex;
+10 -7
View File
@@ -60,14 +60,17 @@
{{ .Content }} {{ .Content }}
</div> </div>
{{/* Tags as small pills at the bottom — Republik-style, no hash symbol */}} {{/* Tags: bei Seiten (nicht-Library) wie bisher unter dem Text. Bei Library
{{- with .Params.tags }} wandern sie in die Aktionsreihe (rechts neben Dialog) im Partial. */}}
<ul class="tag-pills" aria-label="Tags"> {{ if ne .Section "library" }}
{{- range . -}}<li><a href="/tags/{{ . | urlize }}/">{{ . }}</a></li>{{- end -}} {{- with .Params.tags }}
</ul> <ul class="tag-pills" aria-label="Tags">
{{- end }} {{- range . -}}<li><a href="/tags/{{ . | urlize }}/">{{ . }}</a></li>{{- end -}}
</ul>
{{- end }}
{{ end }}
{{/* Herkunft/Zitieren/Dialog — nur bei Library-Beiträgen (lebendes Dokument). */}} {{/* Artikel-Fuß (zitieren, Dialog, Tags, Versionen) — nur bei Library. */}}
{{ if eq .Section "library" }} {{ if eq .Section "library" }}
{{ partial "provenance.html" . }} {{ partial "provenance.html" . }}
<script src="/version-history.js"></script> <script src="/version-history.js"></script>
+82 -56
View File
@@ -1,74 +1,100 @@
{{/* Herkunft eines Beitrags: Version (→ Commit), Verlauf, Zitieren. {{/* Artikel-Fuß für Library-Beiträge: Quellenangabe (zitieren), Aktionsreihe
Version/Verlauf nur, wenn Git-Info da ist (enableGitInfo) und repoURL gesetzt. (Dialog links, Tags rechts) und der Versionsverlauf (eine Zeile darunter). */}}
„Zitieren" kopiert eine Quellenangabe in die Zwischenablage. */}}
{{ $author := .Params.author | default site.Params.author.name }} {{ $author := .Params.author | default site.Params.author.name }}
<div class="provenance" aria-label="Herkunft">
{{/* Dialog: gleiche Pill-Reihe, sticht durch Pfeil + Akzentfarbe hervor. */}} {{/* Zitieren: schlichter Link direkt unter den Quellen. */}}
<a class="prov-dialog" id="dialog-link" data-thread="{{ .RelPermalink }}" href="/dialog/?thread={{ .RelPermalink }}">→ Dialog</a> <div class="cite">
{{/* „Version vom <Datum>" öffnet den Verlauf direkt auf der Seite (Diff rot/grün). */}} <button type="button" class="cite-toggle" aria-expanded="false">zitieren</button>
<button type="button" class="prov-version" id="version-badge" aria-expanded="false" <div class="cite-box" hidden
data-path="{{ .File.Path }}">Version vom {{ .Lastmod.Format "02.01.2006" }}</button>
<button type="button" class="prov-cite" aria-expanded="false"
data-title="{{ .Title }}" data-title="{{ .Title }}"
data-author="{{ $author }}" data-author="{{ $author }}"
data-url="{{ .Permalink }}" data-url="{{ .Permalink }}"
{{ with .GitInfo }}data-version="{{ .AbbreviatedHash }}"{{ end }}>Zitieren</button> data-year="{{ .Date.Format "2006" }}">
</div> <p class="cite-text"></p>
<div class="prov-citation" hidden> <div class="cite-actions">
<p class="prov-citation-text"></p> <button type="button" class="cite-fmt is-active" data-fmt="apa">APA</button>
<div class="prov-citation-actions"> <button type="button" class="cite-fmt" data-fmt="din">DIN</button>
<button type="button" class="prov-citation-copy">Kopieren</button> <button type="button" class="cite-copy">kopieren</button>
<span class="prov-citation-status" role="status"></span> <span class="cite-status" role="status"></span>
</div>
</div> </div>
</div> </div>
{{/* Aktionsreihe: Dialog links, Tags ganz rechts. */}}
<div class="article-actions">
<a class="prov-dialog" id="dialog-link" data-thread="{{ .RelPermalink }}" href="/dialog/?thread={{ .RelPermalink }}">→ Dialog</a>
{{ with .Params.tags }}
<ul class="tag-pills" aria-label="Tags">
{{- range . -}}<li><a href="/tags/{{ . | urlize }}/">{{ . }}</a></li>{{- end -}}
</ul>
{{ end }}
</div>
{{/* Versionen: eine Zeile darunter; öffnet den Verlauf direkt auf der Seite. */}}
<div class="article-versions">
<button type="button" class="versions-toggle" id="version-badge" aria-expanded="false"
data-path="{{ .File.Path }}">Versionen</button>
</div>
<script> <script>
/* Zitieren: APA/DIN umschaltbar, gesamthaft kopierbar. */
(function () { (function () {
if (window.__provCite) return; window.__provCite = 1; if (window.__cite) return; window.__cite = 1;
var btn = document.querySelector('.prov-cite'); var toggle = document.querySelector('.cite-toggle');
var panel = document.querySelector('.prov-citation'); var box = document.querySelector('.cite-box');
if (!btn || !panel) return; if (!toggle || !box) return;
var textEl = panel.querySelector('.prov-citation-text'); var textEl = box.querySelector('.cite-text');
var copyBtn = panel.querySelector('.prov-citation-copy'); var statusEl = box.querySelector('.cite-status');
var statusEl = panel.querySelector('.prov-citation-status'); var d = box.dataset;
var fmt = 'apa';
var d = btn.dataset; function nameParts(n) {
var today = new Date().toLocaleDateString('de-CH'); var p = (n || '').trim().split(/\s+/);
var v = d.version ? ', Version ' + d.version : ''; var last = p.pop() || '';
// Format: Autor: Titel. OPENBUREAU, Version xxx. Abgerufen am TT.MM.JJJJ, URL return { last: last, first: p.join(' '), initials: p.map(function (w) { return w.charAt(0) + '.'; }).join(' ') };
var cite = d.author + ': ' + d.title + '. OPENBUREAU' + v + '. Abgerufen am ' + today + ', ' + d.url;
textEl.textContent = cite;
function selectText() {
var r = document.createRange(); r.selectNodeContents(textEl);
var sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(r);
} }
function copy() { function today() { return new Date().toLocaleDateString('de-CH'); }
if (navigator.clipboard && navigator.clipboard.writeText) { function build() {
return navigator.clipboard.writeText(cite); var n = nameParts(d.author);
if (fmt === 'din') {
return (n.last ? n.last.toUpperCase() + ', ' + n.first + ': ' : '')
+ d.title + '. OPENBUREAU. ' + d.url + ' (abgerufen am ' + today() + ').';
} }
// Fallback für unsichere Kontexte (HTTP/LAN): execCommand auf Auswahl. return (n.last ? n.last + ', ' + n.initials + ' ' : '')
return new Promise(function (resolve, reject) { + '(' + d.year + '). ' + d.title + '. OPENBUREAU. Abgerufen am ' + today() + ', von ' + d.url;
}
function render() { textEl.textContent = build(); }
function copy() {
var t = build();
if (navigator.clipboard && navigator.clipboard.writeText) return navigator.clipboard.writeText(t);
return new Promise(function (res, rej) {
try { try {
var ta = document.createElement('textarea'); var ta = document.createElement('textarea'); ta.value = t; ta.style.position = 'fixed'; ta.style.opacity = '0';
ta.value = cite; ta.style.position = 'fixed'; ta.style.opacity = '0'; document.body.appendChild(ta); ta.select();
document.body.appendChild(ta); ta.focus(); ta.select(); var ok = document.execCommand('copy'); document.body.removeChild(ta); ok ? res() : rej();
var ok = document.execCommand('copy'); } catch (e) { rej(e); }
document.body.removeChild(ta);
ok ? resolve() : reject();
} catch (e) { reject(e); }
}); });
} }
toggle.addEventListener('click', function () {
btn.addEventListener('click', function () { var open = box.hasAttribute('hidden');
var open = panel.hasAttribute('hidden'); if (open) { box.removeAttribute('hidden'); render(); } else { box.setAttribute('hidden', ''); }
if (open) { panel.removeAttribute('hidden'); selectText(); } toggle.setAttribute('aria-expanded', String(open));
else { panel.setAttribute('hidden', ''); }
btn.setAttribute('aria-expanded', String(open));
}); });
copyBtn.addEventListener('click', function () { box.querySelectorAll('.cite-fmt').forEach(function (b) {
copy().then(function () { statusEl.textContent = 'Kopiert ✓'; }) b.addEventListener('click', function () {
.catch(function () { statusEl.textContent = 'Markiert — bitte mit Strg/⌘+C kopieren.'; selectText(); }); fmt = b.dataset.fmt;
setTimeout(function () { statusEl.textContent = ''; }, 3000); box.querySelectorAll('.cite-fmt').forEach(function (x) { x.classList.toggle('is-active', x === b); });
render();
});
});
box.querySelector('.cite-copy').addEventListener('click', function () {
copy().then(function () { statusEl.textContent = 'kopiert ✓'; })
.catch(function () {
statusEl.textContent = 'markieren & kopieren';
var r = document.createRange(); r.selectNodeContents(textEl);
var s = window.getSelection(); s.removeAllRanges(); s.addRange(r);
});
setTimeout(function () { statusEl.textContent = ''; }, 2500);
}); });
})(); })();
</script> </script>
+2 -2
View File
@@ -109,8 +109,8 @@
}); });
panel.appendChild(ol); panel.appendChild(ol);
} }
var prov = trigger.closest('.provenance') || trigger; var host = trigger.closest('.article-versions') || trigger;
prov.parentNode.insertBefore(panel, prov.nextSibling); host.parentNode.insertBefore(panel, host.nextSibling);
trigger.setAttribute('aria-expanded', 'true'); trigger.setAttribute('aria-expanded', 'true');
}); });
} }