The colophon card: the shelf ends with the piper and the fine print

Eric's idea — the last card in the grid, always visible, carrying the
full piper, the Powered-by-BGG badge, and the legal text. A <div>
rather than an <a>, so the search filter (which selects a.game) can
never hide it: the compliance text is part of the collection, not a
skippable footer. The piper ships from the package's own static art,
credited to Juniper on the card itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqpWSz9g
This commit is contained in:
Eric Wagoner
2026-08-06 19:07:12 -04:00
co-authored by Claude Fable 5
parent c7fdc60f87
commit 47409d0487
2 changed files with 59 additions and 5 deletions
+18 -2
View File
@@ -103,7 +103,8 @@ def test_export_writes_pages_art_and_no_shelf_photos(tmp_path):
assert "rpggeek.com/rpgitem/311654" in rpg
# covers landed locally and pages never hotlink the CDN
assert len(list((out / "art").glob("*"))) == 4 # 2 full + 1 thumb + local art
# 2 full + 1 thumb + local art + the colophon's piper
assert len(list((out / "art").glob("*"))) == 5
all_html = index + detail + rpg
assert "geekdo-images.com" not in all_html
@@ -237,7 +238,7 @@ def test_garbage_200_is_a_failure_not_a_cached_cover(tmp_path):
assert summary["downloaded"] == 0
# only the local-art copy survives; no CDN garbage was cached
names = {f.name for f in (tmp_path / "site" / "art").iterdir()}
assert names == {"abc123.jpg"}
assert names == {"abc123.jpg", "bggpipe-piper.jpg"}
def test_missing_local_art_is_a_counted_failure(tmp_path):
@@ -330,3 +331,18 @@ def test_cli_export_wiring(tmp_path, monkeypatch):
monkeypatch.setattr("bggpipe.export.run_export", failing_run_export)
result = runner.invoke(app, ["export", "--out", str(tmp_path / "s")])
assert result.exit_code == 1 # scripted publishes must see failures
def test_colophon_card_closes_the_shelf(tmp_path):
"""The last card: piper, badge, fine print — a div the search filter
(which selects a.game) can never hide."""
cfg = _cfg(tmp_path)
out = tmp_path / "site"
run_export(cfg, out, title="Test Shelves", fetch=_cdn([]), sleep=lambda s: None)
index = (out / "index.html").read_text()
assert 'class="game colophon"' in index
assert "bggpipe-piper.jpg" in index and "Piper art by Juniper" in index
assert "trademarks of BoardGameGeek" in index
assert (out / "art" / "bggpipe-piper.jpg").exists()
# the filter only ever hides <a class="game"> — the colophon is a div
assert '<div class="game colophon"' in index