ui: Header/Footer/Journal/Dialog überarbeitet + Logo

Header/Masthead:
- neuer Wortmark logo.svg; Home als Full-Height-Flex (zwei eigenständig
  scrollbare Journal-Spalten, Footer klebt unten)
- kompakte Masthead; scrollbar-gutter:stable auf html → kein weißer Streifen
  links und kein Logo/Menü-Versatz zwischen den Seiten

Journal-Home:
- zwei Spalten, eckige Karten in natürlicher Höhe; Bild als Block (Inline-
  Whitespace-Lücke behoben)

Footer:
- Lizenzen AGPL-3.0 / CC BY-SA verlinken auf /lizenz/ (eigene Seite);
  „Hosted in Lucerne" (Link zur Autor-URL); keine Underlines; flush unten;
  kein Open-Source-Fließtext mehr, kein Name im Copyright

Dialog:
- schlichte Foren-Auflistung statt Karten; kompaktes Login; kleinerer
  „→ Dialog"-Button (nur noch auf Library-Artikeln); einheitliche Fontgrößen;
  weniger Abstand zum Header, Trennlinien entfernt

Config: CODE-Menü → git.openbureau.ch; params.author.url

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-01 04:47:36 +02:00
parent f146fc7cff
commit f82214719a
8 changed files with 272 additions and 225 deletions
+197 -122
View File
@@ -76,6 +76,14 @@
Base body — serif editorial, 3-col grid so header/footer can full-bleed
while content stays boxed
------------------------------------------------------------------------ */
/* Theme setzt html{margin-left:calc(100vw - 100%)} (Anti-Scrollbar-Sprung) —
das schiebt die GANZE Seite um die Scrollbar-Breite nach rechts → weißer
Streifen links. Zurücknehmen: alles bündig am linken Rand. */
/* Scrollbalken-Platz auf der Wurzel reservieren UND horizontalen Überlauf hier
kappen → Inhaltsbreite identisch auf ALLEN Seiten (auch Home ohne Scrollbar),
damit das zentrierte Logo/Menü nirgends springt. */
html { margin: 0; overflow-x: hidden; scrollbar-gutter: stable; }
body {
font-family: var(--font-family-serif);
font-size: var(--font-size-base);
@@ -83,10 +91,15 @@ body {
padding: 0;
margin: 0;
min-height: 100vh;
overflow-x: hidden;
gap: var(--spacing-sm);
/* overflow-x + scrollbar-gutter liegen jetzt auf html (Wurzel) → Body füllt
konsistent die gleiche Breite auf allen Seiten. */
/* nur Zeilen-Abstand (Header/Main/Footer); KEIN Spalten-Gap, sonst entstehen
ungleiche Ränder an der Inhaltsspalte (der „weiße Spalt"). */
row-gap: var(--spacing-sm);
column-gap: 0;
display: grid;
grid-template-rows: auto 1fr auto;
justify-content: stretch;
/* Boxed content column = 72ch with 1.75rem gutters, side columns absorb the rest */
grid-template-columns:
1fr
@@ -129,9 +142,10 @@ a:hover {
.site-header {
background: var(--color-dark-panel);
color: var(--color-dark-panel-text);
padding: 0.9rem 0;
/* oben etwas Luft über dem Logo, unten nur 12px unter dem Menü */
padding: 0.4rem 0 2px;
border-bottom: none;
margin-bottom: var(--spacing-md);
margin-bottom: 0;
/* inner 3-col grid matches body so wordmark/nav align with content column */
display: grid;
grid-template-columns:
@@ -139,7 +153,7 @@ a:hover {
min(var(--container-width), 100% - 3.5rem)
1fr;
align-items: center;
row-gap: 0.6rem;
row-gap: 0;
}
.site-header > * { grid-column: 2; }
.site-header .wordmark-link,
@@ -160,10 +174,10 @@ a:hover {
padding: 0;
display: block;
justify-self: center;
width: clamp(170px, 24vw, 280px);
aspect-ratio: 1772 / 284;
width: clamp(140px, 18vw, 200px);
aspect-ratio: 1412 / 231;
height: auto;
background-image: url("/logo/LOGO-OB.svg");
background-image: url("/logo/logo.svg");
background-repeat: no-repeat;
background-position: center;
background-size: contain;
@@ -179,6 +193,8 @@ a:hover {
.site-header .site-nav {
justify-self: center;
/* etwas Luft zwischen Logo und Menü. */
margin-top: 0.1em;
}
.wordmark-link:focus-visible { outline: 2px dotted var(--color-text-muted); outline-offset: 4px; }
@@ -278,38 +294,101 @@ a:hover {
gap: 0;
}
/* ── Journal: 2-Spalten-MASONRY (Multi-Column) — Spalten packen UNABHÄNGIG ──
Multi-Column statt Grid: jede Karte fließt frei, links und rechts sind nicht
auf gemeinsame Zeilenhöhen gekoppelt (ein hoher Eintrag links lässt rechts
eigenständig weiterlaufen). break-inside:avoid hält Karten zusammen. */
/* ── Journal: ZWEI eigenständig scrollbare Spalten, eckige Karten aneinander ──
.journal-cols = zwei Spalten nebeneinander (kein Abstand). Jede .journal-list
ist EINE Spalte, die für sich scrollt (overflow-y). Karten ohne Rundung und
ohne Abstände — direkt aneinander, nur eine Hairline als Trenner. */
/* Volle Breite (aus der 72ch-Spalte ausbrechen) */
.journal { width: 100vw; position: relative; left: 50%; margin-left: -50vw; }
.journal-header { padding: 0 10px; }
.journal-list {
columns: 2;
column-gap: 10px;
padding: 0 10px 10px;
margin: 0;
.journal-cols {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0;
}
.journal-list { /* eine Spalte — eigenständig scrollbar */
margin: 0;
padding: 0;
max-height: 82vh;
overflow-y: auto;
}
.journal-cols > .journal-list:first-child { border-right: 1px solid var(--color-border); }
.journal-entry {
border: none;
border-radius: 12px;
border-radius: 0;
background: var(--color-bg-secondary);
padding: 1.5rem;
margin: 0 0 10px;
break-inside: avoid;
-webkit-column-break-inside: avoid;
margin: 0;
}
.journal-entry:last-child { border: none; }
.journal-entry + .journal-entry { border-top: 1px solid var(--color-border); }
/* In den Karten links bündig statt zentriert */
.journal-list .journal-entry .journal-entry-body { justify-items: start; text-align: left; }
.journal-list .journal-entry .journal-entry-body > * { max-width: none; }
.journal-list .journal-bg-image {
width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover;
border-radius: 8px; margin-bottom: 0.9rem;
border-radius: 0; margin-bottom: 0.9rem;
}
@media (max-width: 720px) {
.journal-list { columns: 1; }
.journal-cols { grid-template-columns: 1fr; }
.journal-cols > .journal-list:first-child { border-right: none; }
.journal-list { max-height: none; overflow: visible; }
}
/* ── Startseite: Full-Height-Layout ──────────────────────────────────────────
Masthead oben, zwei eigenständig scrollbare Spalten in der Mitte, Footer klebt
unten. Die Seite selbst scrollt nicht — nur die Spalten (overflow-y). Kette
definierter Höhen: body 100dvh → main (1fr) → .journal → .journal-cols → Spalte. */
/* Flexbox statt Grid für die Home-Höhenverteilung: flex:none hält Header und
Footer exakt auf Inhaltshöhe (im Grid wurde der Header gestreckt → Menü
rutschte nach unten). Nur main füllt die Mitte. */
body.is-home {
height: 100dvh;
overflow: hidden;
display: flex;
flex-direction: column;
gap: 0;
}
body.is-home > header.site-header { margin-bottom: 0; flex: none; }
body.is-home > footer { flex: none; }
body.is-home > main {
flex: 1 1 auto; /* füllt die Mitte */
min-height: 0;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* Kein Text über den Spalten: Intro + „Journal"-Header weg → Spalten beginnen
direkt unter der Masthead und füllen die volle weiße Höhe. */
body.is-home > main > p { display: none; }
body.is-home .journal-header { display: none; }
body.is-home .journal {
width: auto; left: auto; margin: 0; /* 100vw-Ausbruch zurücknehmen */
flex: 1; min-height: 0;
display: flex; flex-direction: column;
}
body.is-home .journal-cols { flex: 1; min-height: 0; }
body.is-home .journal-list {
display: flex; flex-direction: column;
max-height: none; height: 100%; min-height: 0; overflow-y: auto;
scrollbar-width: none; /* Firefox: Scrollbar aus */
-ms-overflow-style: none; /* alte Edge */
}
body.is-home .journal-list::-webkit-scrollbar { width: 0; height: 0; display: none; }
/* Karten in NATÜRLICHER Höhe (kein Stretch) → Bild + Headline bleiben kompakt
zusammen; die Spalte scrollt bei Überlauf. Kein Auseinanderreißen mehr. */
body.is-home .journal-entry { flex: 0 0 auto; }
body.is-home .more { flex: none; padding: 0.4rem 10px; margin: 0; }
/* Footer kompakt (~1/3): kein großer Außenabstand, knappes Padding. */
body.is-home > footer { margin-top: 0; padding: 0.55rem 0; }
body.is-home > footer .footer-grid { row-gap: 0.2rem; }
@media (max-width: 720px) {
/* Mobil: kein Full-Height-Zwang — normal scrollen, eine Spalte. */
body.is-home { height: auto; overflow: visible; }
body.is-home > main { display: block; overflow: visible; }
body.is-home .journal { display: block; }
body.is-home .journal-cols { min-height: 0; }
body.is-home .journal-list { height: auto; overflow: visible; }
}
/* Card link: image (optional) + body block */
@@ -457,20 +536,21 @@ a.byline-author:hover, a.journal-author:hover { color: var(--accent); }
/* Link am Ende des Beitrags (der Beitrag selbst bleibt sauber) */
.dialog-link {
display: inline-block;
margin-top: var(--spacing-lg);
margin-top: var(--spacing-md);
font-family: var(--font-family-display);
font-weight: 500;
font-size: 0.82rem;
color: var(--accent);
text-decoration: none;
border: 1px solid var(--accent);
border-radius: 999px;
padding: 0.45em 1.2em;
padding: 0.28em 0.85em;
}
.dialog-link:hover { background: var(--accent); color: #fff; }
/* Eigene Dialog-Seite (/dialog/?thread=…) */
/* Füllt die normale Inhaltsspalte (kein eigenes max-width/Seiten-Padding → gleiche Breite wie andere Seiten) */
.dialog-page { padding: var(--spacing-lg) 0; }
.dialog-page { padding: var(--spacing-sm) 0 var(--spacing-xl); }
.dialog-overview { display: flex; flex-direction: column; gap: 0.6em; }
.dialog-overview-item {
display: flex; justify-content: space-between; align-items: baseline; gap: 1em;
@@ -481,14 +561,13 @@ a.byline-author:hover, a.journal-author:hover { color: var(--accent); }
.dialog-ov-title { font-family: var(--font-family-serif); font-weight: 600; }
.dialog-ov-meta { font-size: var(--font-size-small); color: var(--color-text-muted); flex: none; }
.dialog-back { margin: 0 0 var(--spacing-sm); }
.dialog-back:empty { margin: 0; }
.dialog-back a { color: var(--color-text-muted); text-decoration: none; }
.dialog-back a:hover { color: var(--accent); }
.dialog-title {
font-family: var(--font-family-serif);
border-top: 1px solid var(--color-border);
padding-top: var(--spacing-md);
margin-bottom: var(--spacing-md);
margin: 0 0 var(--spacing-md);
}
.dialog-list { display: flex; flex-direction: column; gap: var(--spacing-md); margin-bottom: var(--spacing-lg); }
.dialog-empty { color: var(--color-text-muted); font-style: italic; }
@@ -520,21 +599,25 @@ a.byline-author:hover, a.journal-author:hover { color: var(--accent); }
color: var(--color-text-muted); text-decoration: underline; text-underline-offset: 3px;
}
.dialog-loginlink:hover { color: var(--accent); }
.dialog-loginform { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5em; }
.dialog-loginform .dialog-input { width: auto; flex: 1 1 9em; min-width: 8em; padding: 0.45em 0.7em; }
.dialog-loginform .dialog-send { padding: 0.45em 1em; }
.dialog-loginform { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4em; font-size: var(--font-size-small); max-width: 30em; }
.dialog-loginform .dialog-input { width: auto; flex: 1 1 8em; min-width: 7em; padding: 0.35em 0.6em; font-size: inherit; border-radius: 7px; }
.dialog-loginform .dialog-send { padding: 0.35em 0.9em; font-size: inherit; }
.dialog-logincancel { align-self: center; }
/* ── Übersicht: Split-View (links letzte Wortmeldungen, rechts Foren) ── */
.dialog-split { display: grid; grid-template-columns: 1.2fr 1fr; gap: 2.4em; align-items: start; }
@media (max-width: 720px) { .dialog-split { grid-template-columns: 1fr; gap: 1.6em; } }
.dialog-recent-list, .dialog-forum-list, .dialog-thread-list { display: flex; flex-direction: column; gap: 0.7em; }
/* Schlichte Auflistung statt Karten: nur Trennlinien + großzügiger Abstand. */
.dialog-recent-list, .dialog-forum-list, .dialog-thread-list { display: flex; flex-direction: column; }
.dialog-recent-item, .dialog-forum-item, .dialog-thread-item {
display: block; text-decoration: none; color: inherit;
border: 1px solid var(--color-border); border-radius: 12px; padding: 0.85em 1em; background: var(--color-bg-primary);
transition: border-color .12s, transform .12s;
padding: 1.05em 0;
border-bottom: 1px solid var(--color-border);
transition: color .12s;
}
.dialog-recent-item:hover, .dialog-forum-item:hover, .dialog-thread-item:hover { border-color: var(--accent); }
.dialog-recent-item:first-child, .dialog-forum-item:first-child, .dialog-thread-item:first-child { padding-top: 0.3em; }
.dialog-recent-item:last-child, .dialog-forum-item:last-child, .dialog-thread-item:last-child { border-bottom: none; }
.dialog-recent-item:hover, .dialog-thread-item:hover { color: var(--accent); }
.dialog-recent-top { display: flex; justify-content: space-between; gap: 1em; align-items: baseline; }
.dialog-recent-author { font-weight: 600; }
.dialog-recent-meta, .dialog-thread-meta, .dialog-forum-meta { color: var(--color-text-muted); font-size: var(--font-size-small); }
@@ -542,9 +625,17 @@ a.byline-author:hover, a.journal-author:hover { color: var(--accent); }
.dialog-recent-body { color: var(--color-text-muted); font-size: var(--font-size-small);
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* Foren-Karten — linke Akzentkante aus der Forum-Farbe */
.dialog-forum-item { border-left: 3px solid var(--forum-accent, var(--accent)); }
.dialog-forum-name { display: block; font-weight: 600; font-size: 1.05em; }
/* Foren-Auflistung: Name mit kleinem Farbpunkt (Forum-Farbe), Meta darunter. */
.dialog-forum-name {
display: flex; align-items: center; gap: 0.55em;
font-family: var(--font-family-serif); font-weight: 600; font-size: var(--font-size-base);
}
.dialog-forum-name::before {
content: ""; flex: none; width: 0.6em; height: 0.6em; border-radius: 2px;
background: var(--forum-accent, var(--accent));
}
.dialog-forum-item:hover .dialog-forum-name { color: var(--accent); }
.dialog-forum-meta { display: block; margin-top: 0.15em; }
.dialog-forum-desc { display: block; color: var(--color-text-muted); font-size: var(--font-size-small); margin-top: 0.2em; }
/* Forum-Ansicht */
@@ -661,31 +752,10 @@ a.byline-author:hover, a.journal-author:hover { color: var(--accent); }
background: #1a1a1a;
color: #fff;
}
.journal-entry--layout-image .journal-entry-link {
display: flex;
flex-direction: column;
justify-content: flex-end;
min-height: 70vh;
}
.journal-bg-image {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
z-index: 0;
margin: 0;
filter: none;
}
.journal-bg-image:hover { filter: none; }
.journal-entry--layout-image .journal-entry-body {
position: relative;
z-index: 2;
max-width: 60ch;
padding-top: 3rem;
background: transparent;
color: #fff;
}
/* (Alte Vollflächen-Mechanik entfernt: Link war display:flex + min-height:70vh
+ justify-content:flex-end, Bild position:absolute, Body padding-top:3rem —
das zog Bild und Headline in der Karte auseinander. Karten-Layout läuft jetzt
ausschließlich über die .journal-list-Regeln weiter oben.) */
/* Solid white text — no shadow halo. Legibility comes from the slight
darkening of the image at the bottom (where the body sits). */
.journal-entry--layout-image .journal-title,
@@ -792,22 +862,35 @@ a.byline-author:hover, a.journal-author:hover { color: var(--accent); }
.journal-list .journal-entry--layout-image,
.journal-list .journal-entry--layout-icon,
.journal-list .journal-entry--layout-text {
margin: 0 0 10px;
padding: 1.25rem;
margin: 0;
/* oben/unten 20% knapper (1.25rem → 1rem), links/rechts unverändert */
padding: 1rem 1.25rem;
position: relative;
overflow: hidden;
border-radius: 12px;
break-inside: avoid;
-webkit-column-break-inside: avoid;
border-radius: 0;
}
.journal-list .journal-entry--layout-image {
background: var(--color-bg-secondary);
color: var(--color-text-primary);
}
.journal-list .journal-entry-link { display: block; min-height: 0; }
/* Inhalt oben-bündig (kein altes justify-content:flex-end/min-height:70vh mehr,
das Bild und Text in der gewachsenen Karte auseinanderzog). */
/* Flexbox-Spalte: Bild oben, Body darunter, oben-bündig. In Flex werden reine
Whitespace-Textknoten NICHT gerendert → die 78px-Inline-Lücke ist unmöglich. */
.journal-list .journal-entry-link {
display: flex;
flex-direction: column;
justify-content: flex-start;
min-height: 0;
height: auto;
}
/* Bild: normaler Block oben statt absolutem Hintergrund-Overlay */
/* Bild: normaler Block oben statt absolutem Hintergrund-Overlay.
display:block + vertical-align:bottom killen die Inline-Baseline-Lücke
(der „whitespace" unter dem Bild, den du im DevTools gesehen hast). */
.journal-list .journal-bg-image {
display: block;
vertical-align: bottom;
position: static;
inset: auto;
z-index: auto;
@@ -815,8 +898,8 @@ a.byline-author:hover, a.journal-author:hover { color: var(--accent); }
height: auto;
aspect-ratio: 16 / 9;
object-fit: cover;
border-radius: 8px;
margin: 0 0 0.9rem;
border-radius: 0; /* eckig */
margin: 0 0 0.7rem;
}
/* Body: linksbündig, normaler Textfluss, kompakt, dunkle Schrift */
@@ -1054,11 +1137,16 @@ a.byline-author:hover, a.journal-author:hover { color: var(--accent); }
object-fit: cover;
margin-left: calc(50% - 50vw);
margin-right: calc(50% - 50vw);
margin-top: calc(-1 * (var(--spacing-md) + var(--spacing-sm)));
margin-bottom: var(--spacing-md);
/* bündig direkt unter die Masthead (kein Überlappen) — gleicht nur den
Body-Grid-Gap aus, nicht mehr (sonst rutscht das Bild über den Header). */
margin-top: calc(-1 * var(--spacing-sm));
margin-bottom: var(--spacing-sm);
filter: none;
}
.single-hero-image:hover { filter: none; }
/* Nach einem Hero-Bild: Artikel + Header bündig → kein Riesenabstand Bild↔Headline */
.single-hero-image + .single { margin-top: 0; }
.single-hero-image + .single .single-header { margin-top: 0; }
.single-header {
position: relative;
@@ -1254,9 +1342,9 @@ a.byline-author:hover, a.journal-author:hover { color: var(--accent); }
------------------------------------------------------------------------ */
footer {
background: var(--color-dark-panel);
color: var(--color-dark-panel-muted);
margin-top: var(--spacing-xl);
padding: var(--spacing-lg) 0;
color: var(--color-dark-panel-text); /* hell & lesbar auf Schwarz */
margin-top: 0; /* kein Ablöse-Abstand → klebt flush unten (sticky via Body-Grid) */
padding: var(--spacing-md) 0;
border-top: none;
/* inner grid aligns with content column, same trick as header */
display: grid;
@@ -1266,70 +1354,57 @@ footer {
1fr;
}
footer > * { grid-column: 2; }
footer a { color: #d4d4d4; border: none; }
footer a, footer a:hover, footer a:focus { border: none; border-bottom: none; text-decoration: none; }
footer a { color: var(--color-dark-panel-text); }
footer a:hover { color: var(--accent-soft); }
footer p { text-align: left; margin: 0; }
footer p { margin: 0; }
/* Zwei Zeilen: oben Inhalts-Absatz (links) | Links (rechts),
unten Lizenz/Copyright (links). */
.footer-grid {
display: grid;
grid-template-columns: auto 1fr;
align-items: baseline;
column-gap: 2rem;
grid-template-columns: 1fr auto;
align-items: start;
column-gap: var(--spacing-lg);
row-gap: var(--spacing-sm);
}
.footer-mark {
grid-column: 1;
font-family: var(--font-family-serif);
font-weight: 700;
font-size: 1.05rem;
letter-spacing: 0.02em;
color: #fff;
.footer-legal { grid-row: 1; grid-column: 1; }
.footer-licenses {
font-family: var(--font-family-mono);
font-size: 0.8rem;
color: var(--color-dark-panel-text);
}
.footer-hosted {
font-family: var(--font-family-mono);
font-size: 0.75rem;
color: var(--color-dark-panel-muted);
margin-top: 0.35rem;
}
.footer-nav {
grid-column: 2;
.footer-links {
grid-row: 1; grid-column: 2;
justify-self: end;
}
.footer-nav ul {
list-style: none;
margin-left: 0;
display: flex;
flex-wrap: wrap;
gap: 0.4rem 1.2rem;
gap: 0.4rem 1.3rem;
font-family: var(--font-family-display);
font-size: 0.85rem;
font-size: 0.9rem;
font-weight: 500;
letter-spacing: 0.01em;
}
.footer-nav li { margin: 0; }
.footer-tagline {
grid-column: 1;
font-family: var(--font-family-serif);
font-style: italic;
font-size: var(--font-size-small);
line-height: 1.4;
max-width: 36ch;
}
.footer-credit {
grid-column: 2;
justify-self: end;
font-family: var(--font-family-mono);
font-size: 0.78rem;
}
.footer-legal a { color: inherit; text-decoration: none; }
.footer-legal a:hover { color: var(--accent-soft); }
/* Mobile: stack everything left */
/* Mobile: alles linksbündig stapeln */
@media (max-width: 720px) {
.footer-grid { grid-template-columns: 1fr; }
.footer-mark,
.footer-nav,
.footer-tagline,
.footer-credit {
.footer-legal,
.footer-links {
grid-column: 1;
justify-self: start;
}
.footer-legal { grid-row: 1; }
.footer-links { grid-row: 2; }
}
/* ------------------------------------------------------------------------
+2 -1
View File
@@ -76,13 +76,14 @@ menus:
pageRef: /dialog
weight: 40
- name: CODE
url: https://gitea.kgva.ch
url: https://git.openbureau.ch
weight: 50
params:
author:
name: "Karim Gabriele Varano"
email: "karim@gabrielevarano.ch"
url: "https://gabrielevarano.ch"
showreadingtime: true
showlastmod: true
comments: false
+2 -4
View File
@@ -6,12 +6,10 @@
<head>
{{ partial "head.html" . }}
</head>
<body>
<body{{ if .IsHome }} class="is-home"{{ end }}>
<a href="#main-content" class="skip-link">Skip to content</a>
<header role="banner" class="site-header">
<a href="{{ "/" | relURL }}" class="wordmark-link" aria-label="openbureau">
<span class="wordmark-text">openbureau</span>
</a>
<a href="{{ "/" | relURL }}" class="wordmark-link" aria-label="openbureau"></a>
<nav class="site-nav" aria-label="Site">
{{ partial "menu.html" (dict "menuID" "main" "page" .) }}
</nav>
+13 -11
View File
@@ -63,17 +63,19 @@
</ul>
{{- end }}
{{/* Dialog liegt auf eigener Seite — der Beitrag bleibt sauber */}}
<a class="dialog-link" id="dialog-link" data-thread="{{ .RelPermalink }}" href="/dialog/?thread={{ .RelPermalink }}">→ Dialog</a>
<script>
(function () {
var l = document.getElementById('dialog-link'); if (!l) return;
fetch('/api/comments?thread=' + encodeURIComponent(l.dataset.thread))
.then(function (r) { return r.ok ? r.json() : []; })
.then(function (d) { var n = d.filter(function (c) { return !c.deleted; }).length; if (n) l.textContent = '→ Dialog · ' + n; })
.catch(function () {});
})();
</script>
{{/* Dialog nur bei Artikeln (Library), nicht auf Seiten wie Spenden/Manifest. */}}
{{ if eq .Section "library" }}
<a class="dialog-link" id="dialog-link" data-thread="{{ .RelPermalink }}" href="/dialog/?thread={{ .RelPermalink }}">→ Dialog</a>
<script>
(function () {
var l = document.getElementById('dialog-link'); if (!l) return;
fetch('/api/comments?thread=' + encodeURIComponent(l.dataset.thread))
.then(function (r) { return r.ok ? r.json() : []; })
.then(function (d) { var n = d.filter(function (c) { return !c.deleted; }).length; if (n) l.textContent = '→ Dialog · ' + n; })
.catch(function () {});
})();
</script>
{{ end }}
</article>
{{ end }}
+14 -14
View File
@@ -1,17 +1,17 @@
<div class="footer-grid">
<div class="footer-mark">OPENBUREAU</div>
<nav class="footer-nav" aria-label="Footer">
<ul>
<li><a href="/manifest/">Manifest</a></li>
<li><a href="/colophon/">Colophon</a></li>
<li><a href="/dialog/">Dialog</a></li>
<li><a href="https://gitea.kgva.ch">Code ↗</a></li>
<li><a href="/index.xml">RSS</a></li>
</ul>
<div class="footer-legal">
<p class="footer-licenses">
Code <a href="/lizenz/agpl-3.0/">AGPL-3.0</a>
· Inhalte <a href="/lizenz/cc-by-sa-4.0/">CC BY-SA 4.0</a>
</p>
<p class="footer-hosted">
{{ with site.Params.author.url }}<a href="{{ . }}">Hosted in Lucerne</a>{{ else }}Hosted in Lucerne{{ end }}
</p>
</div>
<nav class="footer-links" aria-label="Footer">
<a href="/colophon/">Colophon</a>
<a href="mailto:karim@gabrielevarano.ch">Kontakt</a>
<a href="/index.xml">RSS</a>
<a href="/spenden/">Spenden</a>
</nav>
<p class="footer-tagline">
Sammlung, Plattform, Praxis.<br>
Texte unter <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>.
</p>
<p class="footer-credit">© {{ now.Year }} · Karim Gabriele Varano</p>
</div>
+33
View File
@@ -0,0 +1,33 @@
{{/* Eine Journal-Karte. Kontext (.) = die Library-Seite. */}}
{{ $section := "" }}
{{ with .Parent }}{{ $section = path.Base .RelPermalink }}{{ end }}
{{ $author := .Params.author | default site.Params.author.name }}
{{ $cover := .Params.cover_image }}
{{ $layout := .Params.layout }}
{{ if not $layout }}{{ $layout = cond (ne $cover nil) "image" "text" }}{{ end }}
<li class="journal-entry journal-entry--layout-{{ $layout }}"
data-section="{{ $section }}"
{{ with .Params.color }}data-color="{{ . }}"{{ end }}>
<a class="journal-entry-link" href="{{ .RelPermalink }}">
{{ if and $cover (eq $layout "image") }}
<img class="journal-bg-image" src="{{ $cover | relURL }}" alt="" loading="eager" />
{{ end }}
<div class="journal-entry-body">
{{ if and $cover (eq $layout "icon") }}
<img class="journal-icon-image" src="{{ $cover | relURL }}" alt="" loading="lazy" />
{{ end }}
{{ with .Parent }}
<p class="journal-rubric"><span class="journal-section">{{ .Title }}</span></p>
{{ end }}
<h3 class="journal-title">{{ .LinkTitle }}</h3>
{{ with .Params.summary }}
<p class="journal-summary">{{ . }}</p>
{{ end }}
<p class="journal-byline">
{{- with $author -}}<span class="journal-author">{{ . }}</span>{{- end -}}
{{- if and $author .Date -}}, {{ end -}}
<time class="journal-date" datetime="{{ .Date.Format "2006-01-02" }}">{{ .Date.Format "02.01.2006" }}</time>
</p>
</div>
</a>
</li>
+10 -41
View File
@@ -10,47 +10,16 @@
<p class="text-muted">Was zuletzt geschrieben wurde.</p>
</header>
<ol class="journal-list">
{{ range $journal }}
{{ $section := "" }}
{{ with .Parent }}{{ $section = path.Base .RelPermalink }}{{ end }}
{{ $author := .Params.author | default site.Params.author.name }}
{{ $cover := .Params.cover_image }}
{{/* Layout: explicit `layout:` in front matter, else derive:
- cover_image present → image
- none → text */}}
{{ $layout := .Params.layout }}
{{ if not $layout }}
{{ $layout = cond (ne $cover nil) "image" "text" }}
{{ end }}
<li class="journal-entry journal-entry--layout-{{ $layout }}"
data-section="{{ $section }}"
{{ with .Params.color }}data-color="{{ . }}"{{ end }}>
<a class="journal-entry-link" href="{{ .RelPermalink }}">
{{ if and $cover (eq $layout "image") }}
<img class="journal-bg-image" src="{{ $cover | relURL }}" alt="" loading="eager" />
{{ end }}
<div class="journal-entry-body">
{{ if and $cover (eq $layout "icon") }}
<img class="journal-icon-image" src="{{ $cover | relURL }}" alt="" loading="lazy" />
{{ end }}
{{ with .Parent }}
<p class="journal-rubric"><span class="journal-section">{{ .Title }}</span></p>
{{ end }}
<h3 class="journal-title">{{ .LinkTitle }}</h3>
{{ with .Params.summary }}
<p class="journal-summary">{{ . }}</p>
{{ end }}
<p class="journal-byline">
{{- with $author -}}<span class="journal-author">{{ . }}</span>{{- end -}}
{{- if and $author .Date -}}, {{ end -}}
<time class="journal-date" datetime="{{ .Date.Format "2006-01-02" }}">{{ .Date.Format "02.01.2006" }}</time>
</p>
</div>
</a>
</li>
{{ end }}
</ol>
{{/* Zwei eigenständig scrollbare Spalten: Einträge abwechselnd verteilt
(gerade Indizes links, ungerade rechts) → Lese-Reihenfolge links-rechts. */}}
<div class="journal-cols">
<ol class="journal-list">
{{ range $i, $e := $journal }}{{ if eq (mod $i 2) 0 }}{{ partial "journal-card.html" $e }}{{ end }}{{ end }}
</ol>
<ol class="journal-list">
{{ range $i, $e := $journal }}{{ if eq (mod $i 2) 1 }}{{ partial "journal-card.html" $e }}{{ end }}{{ end }}
</ol>
</div>
{{ if gt (len $library) 20 }}
<p class="more"><a href="/library/">→ Alle Beiträge in der Library</a></p>
+1 -32
View File
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB