Compare commits
2 Commits
bd85570259
...
c2dd9d3ffb
| Author | SHA1 | Date | |
|---|---|---|---|
| c2dd9d3ffb | |||
| 70a6798404 |
+108
-15
@@ -153,30 +153,35 @@ a:hover {
|
||||
}
|
||||
|
||||
/* Logo as background image (paths-only SVG, no font dependency) */
|
||||
/* Wordmark-Schrift: Honk (expressive Color-Font, COLRv1), self-gehostet.
|
||||
Bei fehlender Color-Font-Unterstützung greift die Fallback-Farbe unten. */
|
||||
@font-face {
|
||||
font-family: 'Honk';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("/fonts/honk-latin.woff2") format("woff2");
|
||||
}
|
||||
|
||||
.wordmark-link {
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
justify-self: center;
|
||||
width: clamp(140px, 18vw, 200px);
|
||||
height: clamp(22px, 2.8vw, 32px);
|
||||
background-image: url("/logo/logo.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
color: transparent;
|
||||
font-size: 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
font-family: 'Honk', var(--font-family-display), system-ui, sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: clamp(2rem, 5vw, 3.1rem);
|
||||
line-height: 1;
|
||||
letter-spacing: 0.01em;
|
||||
text-transform: lowercase;
|
||||
color: #fff; /* Fallback, falls Color-Font nicht unterstützt wird */
|
||||
}
|
||||
.wordmark-sr {
|
||||
position: absolute;
|
||||
width: 1px; height: 1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0 0 0 0);
|
||||
}
|
||||
.wordmark-text { display: inline-block; }
|
||||
.wordmark-link:hover,
|
||||
.wordmark-link:focus { color: #fff; border: none; opacity: 0.85; }
|
||||
.wordmark-link:focus { border: none; opacity: 0.85; }
|
||||
|
||||
.site-header .site-nav {
|
||||
justify-self: center;
|
||||
@@ -778,6 +783,94 @@ a.byline-author:hover, a.journal-author:hover { color: var(--accent); }
|
||||
|
||||
.journal-tags { /* extends .tag-pills */ }
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════════════
|
||||
Journal-Startseite: KARTEN-Kontext. Nimmt die Vollflächen-Panel-Regeln von
|
||||
oben innerhalb von .journal-list zurück — kompakte 2-Spalten-Karten:
|
||||
Bild als 16/9-Block OBEN (kein absolutes Overlay), dunkle Schrift,
|
||||
natürliche Höhe (align-items:start → keine Zeilen-Stretchung; ein hoher
|
||||
Eintrag zieht den Nachbarn NICHT mit).
|
||||
════════════════════════════════════════════════════════════════════════ */
|
||||
.journal-list { align-items: start; }
|
||||
|
||||
.journal-list .journal-entry,
|
||||
.journal-list .journal-entry--layout-image,
|
||||
.journal-list .journal-entry--layout-icon,
|
||||
.journal-list .journal-entry--layout-text {
|
||||
margin: 0;
|
||||
padding: 1.25rem;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: 12px;
|
||||
align-self: start;
|
||||
}
|
||||
.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; }
|
||||
|
||||
/* Bild: normaler Block oben statt absolutem Hintergrund-Overlay */
|
||||
.journal-list .journal-bg-image {
|
||||
position: static;
|
||||
inset: auto;
|
||||
z-index: auto;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
aspect-ratio: 16 / 9;
|
||||
object-fit: cover;
|
||||
border-radius: 8px;
|
||||
margin: 0 0 0.9rem;
|
||||
}
|
||||
|
||||
/* Body: linksbündig, normaler Textfluss, kompakt, dunkle Schrift */
|
||||
.journal-list .journal-entry-body {
|
||||
position: static;
|
||||
z-index: auto;
|
||||
max-width: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: grid;
|
||||
justify-items: start;
|
||||
text-align: left;
|
||||
row-gap: 0.55rem;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
.journal-list .journal-entry-body > * { max-width: none; }
|
||||
|
||||
/* Bild-Layout: Schrift wieder dunkel (kein Weiß-auf-Bild) */
|
||||
.journal-list .journal-entry--layout-image .journal-title,
|
||||
.journal-list .journal-entry--layout-image .journal-rubric,
|
||||
.journal-list .journal-entry--layout-image .journal-summary,
|
||||
.journal-list .journal-entry--layout-image .journal-byline,
|
||||
.journal-list .journal-entry--layout-image .journal-byline .journal-author,
|
||||
.journal-list .journal-entry--layout-image .journal-byline .journal-date,
|
||||
.journal-list .journal-entry--layout-image .journal-byline .journal-author::before {
|
||||
color: var(--color-text-primary);
|
||||
text-shadow: none;
|
||||
}
|
||||
.journal-list .journal-entry--layout-image .journal-section {
|
||||
background: color-mix(in oklab, var(--section-color, var(--accent)) 35%, transparent);
|
||||
color: var(--color-text-primary);
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
}
|
||||
|
||||
/* Kompaktere Karten-Typografie (nicht Hero-Größe) */
|
||||
.journal-list .journal-title { font-size: 1.4rem; line-height: 1.2; font-weight: 700; letter-spacing: -0.02em; }
|
||||
.journal-list .journal-summary { font-size: 1rem; line-height: 1.45; max-width: none; }
|
||||
.journal-list .journal-byline { font-size: 0.9rem; }
|
||||
|
||||
/* Icon-Bild kleiner und linksbündig */
|
||||
.journal-list .journal-icon-image { max-width: 96px; max-height: 96px; margin: 0 0 0.6rem; }
|
||||
|
||||
/* Tags innerhalb der Karte links, kompakt */
|
||||
.journal-list .journal-entry > .tag-pills {
|
||||
margin: 0.6rem 0 0;
|
||||
padding: 0;
|
||||
max-width: none;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.more {
|
||||
margin-top: var(--spacing-md);
|
||||
font-family: var(--font-family-mono);
|
||||
|
||||
@@ -5,18 +5,28 @@ import {
|
||||
forumsWithCounts, forumWithThreads, recentComments, createThread, recentForModeration, threadMeta,
|
||||
} from '../dialog-store.js';
|
||||
|
||||
// Fehlt die Tabelle (Migration noch nicht eingespielt), nicht mit einem rohen
|
||||
// SQL-Fehler antworten — leer zurückgeben und server-seitig laut loggen.
|
||||
function softFail(c, e, fallback) {
|
||||
console.error('[dialog]', e?.message || e);
|
||||
return c.json(fallback);
|
||||
}
|
||||
|
||||
// ── Öffentliche Lese-Handler ─────────────────────────────────────────────
|
||||
export async function listForums(c) {
|
||||
try { return c.json(await forumsWithCounts()); }
|
||||
catch (e) { return c.json({ error: String(e) }, 500); }
|
||||
catch (e) { return softFail(c, e, []); }
|
||||
}
|
||||
export async function showForum(c) {
|
||||
const data = await forumWithThreads(c.req.param('slug'));
|
||||
if (!data) return c.json({ error: 'Forum nicht gefunden' }, 404);
|
||||
return c.json(data);
|
||||
try {
|
||||
const data = await forumWithThreads(c.req.param('slug'));
|
||||
if (!data) return c.json({ error: 'Forum nicht gefunden' }, 404);
|
||||
return c.json(data);
|
||||
} catch (e) { return softFail(c, e, { forum: null, threads: [] }); }
|
||||
}
|
||||
export async function recent(c) {
|
||||
return c.json(await recentComments(Number(c.req.query('limit')) || 20));
|
||||
try { return c.json(await recentComments(Number(c.req.query('limit')) || 20)); }
|
||||
catch (e) { return softFail(c, e, []); }
|
||||
}
|
||||
export async function threadInfo(c) {
|
||||
const key = c.req.query('key');
|
||||
|
||||
@@ -41,6 +41,30 @@ services:
|
||||
retries: 20
|
||||
start_period: 30s
|
||||
|
||||
# ════════════════════════════════════════════════════════════════════════
|
||||
# Migrate — spielt das (idempotente) Schema bei jedem `up` nach, damit neue
|
||||
# Tabellen/Spalten auch in eine BESTEHENDE DB kommen (Init-Scripts laufen nur
|
||||
# beim allerersten Start). Läuft einmal und beendet sich. supabase_admin =
|
||||
# Superuser → keine Owner-Konflikte. schema.sql ist idempotent.
|
||||
# ════════════════════════════════════════════════════════════════════════
|
||||
migrate:
|
||||
image: supabase/postgres:15.8.1.020
|
||||
container_name: openbureau-migrate
|
||||
restart: "no"
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
PGPASSWORD: ${POSTGRES_PASSWORD}
|
||||
volumes:
|
||||
- ./db/schema.sql:/openbureau-schema.sql:ro
|
||||
entrypoint: ["bash", "-c"]
|
||||
command:
|
||||
- >
|
||||
psql -h db -U supabase_admin -d postgres -v ON_ERROR_STOP=1 -f /openbureau-schema.sql &&
|
||||
psql -h db -U supabase_admin -d postgres -c "notify pgrst, 'reload schema';" &&
|
||||
echo '✓ Schema migriert.'
|
||||
|
||||
# ════════════════════════════════════════════════════════════════════════
|
||||
# GoTrue — Auth (Login für das CMS)
|
||||
# ════════════════════════════════════════════════════════════════════════
|
||||
@@ -124,6 +148,8 @@ services:
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
migrate:
|
||||
condition: service_completed_successfully
|
||||
kong:
|
||||
condition: service_started
|
||||
environment:
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
<body>
|
||||
<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-sr">OPENBUREAU</span>
|
||||
<a href="{{ "/" | relURL }}" class="wordmark-link" aria-label="openbureau">
|
||||
<span class="wordmark-text">openbureau</span>
|
||||
</a>
|
||||
<nav class="site-nav" aria-label="Site">
|
||||
{{ partial "menu.html" (dict "menuID" "main" "page" .) }}
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user