Files
pi-weekly-newspaper/docs/superpowers/specs/2026-04-06-cover-refinements-design.md
cottongin c4300b02b8 Add cover refinements design spec
Spec for three cover generation improvements: omit obituaries
from headlines, increase font size, and use pixel-width truncation.

Made-with: Cursor
2026-04-06 18:54:49 -04:00

64 lines
3.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Cover Refinements Design
**Date:** 2026-04-06
**Scope:** Three targeted changes to the weekly newspaper cover generation
## Context
The cover is a 480×800 JPEG with a masthead bar at the top and a translucent headline strip at the bottom. Headlines are currently rendered at font size 14 and truncated by character count (45 chars), which doesn't correspond to actual pixel width — causing text to be cut short before filling the available space. Obituary articles also appear in the headline list, which is undesirable.
## Changes
### 1. Omit Obituaries from Cover Headlines
**Problem:** Obituary articles appear as cover headlines alongside news stories.
**Solution:** Filter articles whose `categories` JSON array contains `"Obituaries"` when building the `headlines` list. This applies at the three call sites that construct headlines before calling `generate_cover`:
- `src/routes/publish.py` — manual publish
- `src/routes/issues.py` — regenerate issue cover
- `src/scheduler.py` — auto-publish
Each site already iterates articles to build `categories_list` for AI prompt selection. The obituary filter will be applied when building both `headlines` and `categories_list` (excluding "Obituaries" from the prompt category pool is harmless since it has no matching prompt entry).
**Identification:** Category string match on `"Obituaries"` (case-sensitive, matching the RSS feed tag).
### 2. Increase Headline Font Size
**Problem:** Font size 14 is too small to read comfortably on the cover.
**Solution:** In `_draw_text_overlays` in `src/cover.py`:
- Headline font: `_get_font(14)``_get_font(18)`
- Line spacing: `22px``26px`
- Strip height formula: `28 + max_headlines * 22``28 + max_headlines * 26`
### 3. Dynamic Pixel-Width Truncation
**Problem:** Character-count truncation (`len(text) > 45`) doesn't account for variable-width font glyphs. Headlines get truncated well before reaching the edge of the 480px canvas.
**Solution:** Replace character-count truncation with pixel-width measurement using Pillow's `textbbox`:
- Compute `max_width = width - 32` (16px left padding + 16px right margin)
- For each headline string (with bullet prefix), measure its rendered width via `draw.textbbox((0, 0), text, font=headline_font)`
- If it exceeds `max_width`, find the longest prefix that fits (iterating from the end) and append `"…"`
- The ellipsis itself must be included in the width measurement
This makes truncation adapt to actual font metrics and canvas dimensions automatically.
## Files Modified
| File | Change |
|------|--------|
| `src/cover.py` | Font size 14→18, line spacing 22→26, strip height formula, replace char truncation with pixel-width truncation |
| `src/routes/publish.py` | Filter obituaries from headlines list |
| `src/routes/issues.py` | Filter obituaries from headlines list |
| `src/scheduler.py` | Filter obituaries from headlines list |
| `tests/test_cover.py` | Update tests for new truncation behavior |
## Testing
- Existing cover generation tests updated to reflect new font/spacing values
- Verify pixel-width truncation produces headlines that fill available width without overflow
- Verify obituary articles are excluded from cover headlines