Skip to content

feat(theme): background pattern library + wallpaper storage - #3

Merged
IceboxDev merged 1 commit into
masterfrom
batch/theme-patterns
Sep 4, 2026
Merged

feat(theme): background pattern library + wallpaper storage#3
IceboxDev merged 1 commit into
masterfrom
batch/theme-patterns

Conversation

@IceboxDev

Copy link
Copy Markdown
Owner

Part of the site-wide personalization batch — the pattern half of the theme system. The theme engine (separate PR on batch/theme-engine) discovers these via import.meta.glob.

What

  • 8 self-contained background-pattern generators in packages/web/src/lib/theme/patterns/: doodles, constellation (Stars), waves, crosshatch (Linen), dotgrid, circuit, petals, diamonds. Each default-exports { key, label, tile, generate(colorHex, opacity) } returning an encoded url("data:image/svg+xml,...") CSS layer.
  • Geometry ported verbatim from the hand-tuned Icebox chatPatterns set (tile sizes and derived per-element opacities preserved). The WhatsApp doodle glyphs are redrawn as board-game icons — card fans, dice, dominoes, a d20, meeple, pawns, hex tiles, hourglass, crown, trophy, VP token — at the same 16 positions/rotations/scales so density matches.
  • packages/web/src/lib/theme/wallpaper.ts: readWallpaper / storeWallpaper / clearWallpaper on the localStorage key bg-theme-wallpaper-v1 (engine contract). Rejects non-image data URLs and payloads over 2MiB after base64 encoding; quota errors return { ok: false } instead of throwing.

Hardening (from code review)

  • generate() clamps opacity to [0,1] and validates colorHex (grey fallback) — encodeURIComponent leaves quotes unescaped, so an arbitrary string could otherwise break out of the SVG attributes.
  • readWallpaper re-applies the data:image/ check so a value planted under the key never reaches the engine.

Verification

  • 14 new vitest cases (contract shape, encoding, clamping, color fallback, tile sizing, wallpaper size/type/quota).
  • Visual proof: all 8 patterns rendered over #08090d at 0.4 and 0.15 opacity in headless Chromium — seamless tiling, doodle glyphs read as board-game icons at zoom.
  • pnpm -r typecheck, pnpm lint, pnpm test all green (core 1239, server 473, web 1109).

Note for the engine worker: the import.meta.glob over patterns/ must exclude *.test.ts (documented in patterns.test.ts).

🤖 Generated with Claude Code

https://claude.ai/code/session_011r16ejkf3HB6tyZfTeA3Eb

@vercel

vercel Bot commented Sep 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
board-games-server Ready Ready Preview Sep 3, 2026 11:53pm UTC

Request Review

@IceboxDev
IceboxDev merged commit 95228dd into master Sep 4, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant