grisemonster image variants
===========================

Source: grisemonster-lossless-original.png (2048x1024 RGBA PNG, 2.0M)

Files in use
------------
grisemonster-2048.png  443K  desktop (>1280px viewport)
grisemonster-1280.png  227K  tablet  (601-1280px)
grisemonster-800.png    97K  mobile  (<=600px)

The previous single grisemonster.png was 624K served to every device.
Mobile now downloads 97K (-84%); desktop downloads 443K (-29%).

How they were generated
-----------------------
For each width W in {2048, 1280, 800}:

    magick grisemonster-lossless-original.png -resize ${W}x base.png
    pngquant 64 --quality=50-80 --speed 1 --output grisemonster-${W}.png base.png
    oxipng -o max --strip safe grisemonster-${W}.png

pngquant reduces to a 64-colour palette (the image is a flat
illustration with very few distinct colours, so this is visually
lossless at the displayed scale). oxipng then does a lossless
re-encode pass to squeeze the PNG further.

Wired up in src/components/layout/footer.module.scss via two
min-width media queries on `.pigPattern`'s background-image.

Why PNG, not WebP/AVIF
----------------------
Tested at 2048 width:

    PNG  (pngquant 64 + oxipng)   443K   <-- chosen
    PNG  (pngquant 256 + oxipng)  522K
    AVIF q50                      493K
    AVIF q60                      598K
    AVIF q75                      718K
    WebP q75                      829K   larger than current PNG
    WebP q85                      903K   larger than current PNG
    WebP lossless                 1.0M   larger than current PNG

For this kind of content -- a flat, limited-palette illustration with
large transparent regions -- palette PNG is the smallest format.
WebP and AVIF are tuned for photographic content and lose to a
well-quantised PNG here. Visual quality of the three PNG/AVIF options
above was indistinguishable at the rendered scale.

Conclusion: the win came from responsive sizing, not from changing
format. Stayed on PNG to keep the CSS simple (no image-set() needed).
