Render CoreInk brand icons as dithered gray via the gray4 atlas
The CoreInk compiled the mono (hard 1-bit) brand family, so credential
logos rendered as harsh 1-bit masks. Switch the board to the purpose-built
gray4 (2-bpp, 4-tone) atlas and add the device-side decode + ordered-dither
blit that turns each gray tone into an ink/paper stipple on the 1-bit
e-paper, so mid grays read as smooth gray marks while list text and
navigation stay crisp 1-bit.
- Add mono_dither.h: the shared 8x8 Bayer ordered-dither matrix + a pure
monoBayerInk() predicate, keyed to absolute panel position so redraws
reproduce the same stipple. text_renderer now consumes it (byte-identical
matrix, dedup).
- Add bitmap::decodeGray4ToCoverage(): RLE + 2-bpp MSB-first ladder decode
to per-pixel ink coverage (0/85/170/255), with native §24 tests.
- brand_renderer: gray4 branch decodes to coverage, area-averages any
downscale on the tone, then dithers to ink/paper at the final panel
position (nearest-neighbor would wreck the stipple).
- registry: the mono-oriented styles accept the gray4 (Palette4) family so
monochrome boards resolve it.
- favicon_tile: fall back to the S24 asset when the preferred size is
absent, so the detail badge shows the logo instead of the letter tile.
- CoreInk variant: KLEIDOS_BRANDS_FAMILY 2 -> 3 (mono dropped by the CMake
routing, no double-carry; flash 54.1%).
- Debug MOCKVAULT preview seeds the brand cache + brand-domain names so the
e-ink screenshot path demonstrates the gray icons (debug-only).
Claude-Session: https://claude.ai/code/session_01P6BNTpbgrvnZXSJnNuj8ZJ