Browser extension: detect and subscribe to standard.site publications on ATProto substandard.blog

feat(panoptiblog): make share pages a reason to keep blogging #580

targeting main from claude/pano-share-incentives
Merged opened by and assigned to affine-nimcha.test.pds.did.bot
targeting main from claude/pano-share-incentives
Every ranked publication gets a stable page at `/b/<key>`, a 1200×630 card at `/b/<key>.png` and a 360×96 badge at `/b/<key>-badge.svg`. The page opens with a large panoptiblog brand and a compact publication badge in the publication's own theme colors. Rank, movement and overall score share one panel with the six composite cards; milestones are pills. The card uses the same aligned grid, with the badge over the rank and score panel and the composite tiles filling the right. Nothing compares or names another publication. The task fetches each publication icon and author avatar, converts them to PNG with `sharp`, and falls back to initials when a fetch fails. Pages share `/b/blog.css` and `/b/blog.js`; each publication also gets a small theme stylesheet. Keys come from the publication at-uri, and existing objects are never deleted, so an embedded badge or a shared page keeps working across daily runs and after a publication leaves the ranking. Nothing in scoring or ranking changes. `npx vitest run scripts/panoptiblog` passes 171 tests. The Alpine image builds and sharp converts WebP there. Deploying the backend image is required for the new objects; the next run writes pages, cards, badges and theme files for every ranked publication. Before: ![share page before](https://tangled.org/blob/did:plc:bz2xb4ejbeeszw6frdcxm3sn/bafkreiazogcvi2vxjwiddcrcmwlnauk7a4z35rlq23q53o2o4shnjhi7ze) After: ![share page after](https://tangled.org/blob/did:plc:bz2xb4ejbeeszw6frdcxm3sn/bafkreidw757a7o6omuxczbmepcnk2z6zzwkfnf3pmczp3tzyi7j7a6w5pm) Card before: ![share card before](https://tangled.org/blob/did:plc:bz2xb4ejbeeszw6frdcxm3sn/bafkreifl5eqioj75ghmisixuop3olarzihcatr2wzgheatih4z2h2bsgfi) Card after: ![share card after](https://tangled.org/blob/did:plc:bz2xb4ejbeeszw6frdcxm3sn/bafkreidljchd57vjme6ayvqiqxjkasquizjzs32xitjjituu6fv2hk2bgm) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Commits 5

feat(panoptiblog): put the share card on one aligned grid
fix(panoptiblog): keep the next-rank gap anonymous and the card neutral
feat(panoptiblog): give share pages leaderboard-style score cards
feat(panoptiblog): dress share pages in the publication's theme
feat(panoptiblog): make share pages a reason to keep blogging