fix(geschichten): scale list row typography to the full-width layout
All checks were successful
CI / Unit & Component Tests (pull_request) Successful in 3m57s
CI / OCR Service Tests (pull_request) Successful in 23s
CI / Backend Unit Tests (pull_request) Successful in 4m9s
CI / fail2ban Regex (pull_request) Successful in 47s
CI / Semgrep Security Scan (pull_request) Successful in 22s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m6s

Rows kept their compact sizes (15px titles, 12px excerpts/meta) after
the overview widened to max-w-7xl, leaving the text undersized in
full-width rows. Title is now text-lg, excerpt and meta text-sm; R-1
impl-ref updated.

Closes #802
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-06-10 22:53:40 +02:00
parent 264d7268c4
commit 50def73d80
3 changed files with 30 additions and 10 deletions

View File

@@ -426,11 +426,11 @@
<tr><td>List row</td><td>flex gap-0 border-b border-brand-sand last:border-0 hover:bg-surface</td><td>min-h-[44px] auf Mobile</td></tr>
<tr><td>Meta column</td><td>w-[88px] shrink-0 flex flex-col gap-1 p-3 border-r border-brand-sand</td><td>feste Breite</td></tr>
<tr><td>Author avatar</td><td>w-7 h-7 rounded-full text-[9px] font-bold text-white flex items-center justify-center</td><td>personAvatarColor(userId)</td></tr>
<tr><td>Author name</td><td>font-sans text-xs font-semibold text-ink</td><td></td></tr>
<tr><td>Date</td><td>font-sans text-xs text-ink-3</td><td>formatDate(publishedAt)</td></tr>
<tr><td>Author name</td><td>font-sans text-sm font-semibold text-ink</td><td></td></tr>
<tr><td>Date</td><td>font-sans text-sm text-ink-3</td><td>formatDate(publishedAt)</td></tr>
<tr><td>Person chip</td><td>inline-flex items-center gap-1 rounded-full bg-surface border border-line px-2 py-0.5 text-[10px] font-medium text-ink</td><td>links zu /persons/[id]; optional</td></tr>
<tr><td>Story title</td><td>font-serif text-[15px] text-ink leading-snug mb-1 hover:text-primary</td><td>link zu /geschichten/[id]</td></tr>
<tr><td>Excerpt</td><td>font-sans text-xs text-ink-3 line-clamp-2</td><td>max. 150 Zeichen aus body</td></tr>
<tr><td>Story title</td><td>font-serif text-lg text-ink leading-snug mb-1 hover:text-primary</td><td>link zu /geschichten/[id]</td></tr>
<tr><td>Excerpt</td><td>font-sans text-sm text-ink-3 line-clamp-2</td><td>max. 150 Zeichen aus body</td></tr>
<tr class="grp"><td colspan="3">Filter</td></tr>
<tr><td>Filter pill (inaktiv)</td><td>rounded-full border border-line px-3 py-1 text-xs font-semibold text-ink-2 hover:bg-muted</td><td>aria-pressed="false"</td></tr>
<tr><td>Filter pill (aktiv)</td><td>rounded-full bg-primary text-primary-fg px-3 py-1 text-xs font-semibold</td><td>aria-pressed="true"</td></tr>

View File

@@ -32,9 +32,9 @@ const authorName = $derived(formatAuthorName(geschichte.author));
>
{getInitials(authorName)}
</span>
<span class="font-sans text-xs leading-tight font-semibold text-ink">{authorName}</span>
<span class="font-sans text-sm leading-tight font-semibold text-ink">{authorName}</span>
{#if publishedAt}
<span class="font-sans text-xs text-ink-3">{publishedAt}</span>
<span class="font-sans text-sm text-ink-3">{publishedAt}</span>
{/if}
{#if isJourney}
<span
@@ -59,14 +59,14 @@ const authorName = $derived(formatAuthorName(geschichte.author));
>
{getInitials(authorName)}
</span>
<span class="font-sans text-xs font-semibold text-ink">{authorName}</span>
<span class="font-sans text-sm font-semibold text-ink">{authorName}</span>
{#if publishedAt}
<span class="ml-auto font-sans text-xs text-ink-3">{publishedAt}</span>
<span class="ml-auto font-sans text-sm text-ink-3">{publishedAt}</span>
{/if}
</div>
<div class="mb-1 flex items-center gap-1.5">
<h2 class="font-serif text-[15px] leading-snug text-ink group-hover:underline">
<h2 class="font-serif text-lg leading-snug text-ink group-hover:underline">
{geschichte.title}
</h2>
{#if isJourney}
@@ -82,7 +82,7 @@ const authorName = $derived(formatAuthorName(geschichte.author));
</div>
{#if geschichte.body}
<!-- plaintext for JOURNEY, sanitised-HTML→text for STORY; never {@html} -->
<p class="line-clamp-2 font-sans text-xs leading-relaxed text-ink-3">
<p class="line-clamp-2 font-sans text-sm leading-relaxed text-ink-3">
{plainExcerpt(geschichte.body, 150)}
</p>
{/if}

View File

@@ -25,6 +25,26 @@ describe('GeschichteListRow', () => {
.toHaveTextContent('Die Reise nach Berlin');
});
it('row text sizes suit the full-width list: title text-lg, excerpt/meta text-sm (#802)', async () => {
render(GeschichteListRow, { props: { geschichte: baseRow() } });
const title = document.querySelector('h2');
expect(title!.className).toContain('text-lg');
expect(title!.className).not.toContain('text-[15px]');
const excerpt = document.querySelector('p');
expect(excerpt!.className).toContain('text-sm');
expect(excerpt!.className).not.toContain('text-xs');
const meta = Array.from(document.querySelectorAll('span')).filter((s) =>
s.textContent?.includes('Anna Schmidt')
);
expect(meta.length).toBeGreaterThan(0);
for (const span of meta) {
expect(span.className).toContain('text-sm');
}
});
it('shows no badge for STORY type', async () => {
render(GeschichteListRow, { props: { geschichte: baseRow({ type: 'STORY' }) } });
expect(document.querySelector('[data-testid="journey-badge"]')).toBeNull();