#!/bin/sh
# Rasterise favicon.svg into the icon files clients ask for by path.
#
# favicon.svg alone is not enough. Two families of request arrive at the web
# root for icons no markup ever points at, and both were the top entries in the
# 404 report before these files existed:
#
# /favicon.ico
# The unconditional root-path fallback. A client that cannot use an SVG
# favicon — Safari, historically — ignores the declared
# and asks for this instead, and every non-browser client that never runs
# JS (feed readers, the Slack/Discord/WhatsApp/Telegram unfurlers, crawlers)
# does the same on the static shell where the head is injected by
# catcrafts-head.js rather than served. Nothing declares this file; the
# fix is purely that the path resolves.
#
# /apple-touch-icon.png, /apple-touch-icon-precomposed.png
# What iOS/iPadOS and macOS Safari probe at the root when a page declares
# no — the Add to Home Screen, Favorites and
# Start Page tile. The pages DO declare one now (RenderDocument and
# catcrafts-head.js), so the plain path is the one actually in use, and
# -precomposed is only reached by clients predating that link being
# honoured. ("Precomposed" meant "gloss and rounded corners are already
# baked in", from when iOS <7 applied a glossy overlay to the plain one.)
#
# So only ONE file is produced here: -precomposed is a Caddy rewrite onto
# apple-touch-icon.png (deploy/Caddyfile.example). A byte-identical second
# copy would be a duplicate to keep in sync in git AND a second entry in
# the wasm bundle's VFS — one more file fetched at every boot that nothing
# ever reads. The size-suffixed names (apple-touch-icon-180x180.png and
# friends) are not produced at all: they have never appeared in the logs,
# so shipping them would answer a question nobody asked.
#
# Checked in rather than built, unlike sitemap.xml and feed.xml. Those drift
# with every post; these drift only when favicon.svg is deliberately redrawn,
# and generating them in CI would mean installing librsvg and ImageMagick into
# the deploy container to produce identical bytes on every push.
#
# SO: re-run this after ANY edit to favicon.svg, and commit the results.
#
# Third copy of the same geometry to keep in sync — favicon.svg is the source,
# RenderNav in shared/interfaces/Catcrafts.Shared-Views.cppm inlines it as
# paths with CSS-variable colours, and these rasters fall out of the SVG here.
set -eu
cd "$(dirname "$0")/.."
SRC="favicon.svg"
# The fill from favicon.svg. Only used to flatten the Apple icon: iOS
# composites alpha against black and applies its own squircle mask, so the
# artwork must reach the edges fully opaque instead of carrying the SVG's own
# rounded corners.
BG="#0b0d10"
for cmd in rsvg-convert magick; do
command -v "$cmd" >/dev/null 2>&1 || {
echo "make-icons: $cmd not found (pacman -S librsvg imagemagick)" >&2
exit 1
}
done
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
# favicon.ico: multi-resolution, transparency kept. The rounded corners read
# correctly against both a light and a dark tab bar, and 48px is what Windows
# shortcut and some bookmark surfaces pick.
for px in 16 32 48; do
rsvg-convert -w "$px" -h "$px" "$SRC" -o "$TMP/ico-$px.png"
done
magick "$TMP/ico-16.png" "$TMP/ico-32.png" "$TMP/ico-48.png" favicon.ico
# apple-touch-icon.png: 180x180 is the largest size iOS asks for, and it
# downsamples the rest itself. Opaque, per the note on BG above.
rsvg-convert -w 180 -h 180 "$SRC" -o "$TMP/touch.png"
magick "$TMP/touch.png" -background "$BG" -alpha remove -alpha off \
-strip apple-touch-icon.png
echo "make-icons: wrote favicon.ico apple-touch-icon.png"