From aee220e6b8176bbc95823676bf64a2076a16f5fa Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sun, 24 May 2026 00:01:03 -0500 Subject: [PATCH] Regenerate favicons as full RGBA to remove tab outline The 16x16 favicon frame and favicon-16.png were saved as 8bpp indexed images with binary alpha. Antialiased edges of the orange logo got quantized to opaque palette entries, baking in a dark halo that browser tab strips revealed as an ugly outline around the glyph. Re-render from public/logo.svg, preserving its native 720:880 aspect on a transparent square canvas (the previous fix squished the logo into a square), downsampling with Lanczos to each target size, forcing PNG color-type 6 (RGBA) and a multi-frame ICO where every size is 32bpp. Add scripts/generate-favicons.sh so the next logo change can't silently reintroduce palette quantization or aspect-ratio stretching. --- public/apple-touch-icon.png | Bin 13738 -> 8520 bytes public/favicon-16.png | Bin 1098 -> 414 bytes public/favicon-32.png | Bin 1933 -> 985 bytes public/favicon.ico | Bin 5686 -> 15086 bytes scripts/generate-favicons.sh | 113 +++++++++++++++++++++++++++++++++++ 5 files changed, 113 insertions(+) create mode 100755 scripts/generate-favicons.sh diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png index 2d6643ee2d4bc0bf2864ef31e1a9db0e4ca8b35f..c9a1a33345b75daf2ad23ef14a9636cc52251339 100644 GIT binary patch literal 8520 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 literal 13738 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 literal 1098 zcma)4e@s(X6uysAO6ghwp&%QxjM8@2!lNs7HVg~4^feWNEps?UT1pEQ3J4EbkvT*} zP@G!LrV$l??3YWIY|H)-U9tsQNzj;p;+&X~Y&yeSwq!0_mMv%JZp)JWVX~Wd@45Fo z-?``ea^G-OrA?ZYl|%@U+Bu68V=|qI0$eq^B`ypKFXyZvq(?;x zMK>X)V}xY1kB+Y|CWHxBt*f>o0ZwfJ9D_x0n1gp)0g+w#Fti$K2=wQ}={iWqO#!44 zSVdqr3q}HMOMuUSo*W210WC?;$iP++_!(#sLt`9lO@QvFphW`BiEzjUAq6yx;jj%x z%&=`Kw8`Lz1CCa}{uf}+bFkM4BWvJQ6)iyyYB*qq9l6k+LT^TVr-l*^lu{5c9P>a& z+FwT{1mY=zgjN~!D(U^WQUN09QP6Tfp{fvUil@g{meW*cI+fijrOa)qF!Vg^D~8wC z!fPuih)l%MU2h&7w7~W!sXJ_h-`_S7$Bwv1W|M$gMq1Z02neZVl#QCvBWCv)pgWs_ z@3g=!9o?hBK_dhu|7gP$%0mlSh5S}2KF7W9-OPbhJiuysUVB(J^>+Iaa@vCWKdF}-FMQlfR_DjE(-1%COJaMPQJpYlv zf46KQB%fI*S-JhIwaRf@oR3?oAImv<2AebW4x5Dx39~soh}*f1orK8q=w$3p<&Ox8 zczcCav?!E`vYtKv&C^8)PKIt4w;M$xx_eSrf}H zTlf3ue+q(a4FP}X@dZsO76le){_VgAg1%1P6KsEc&6;>0{?$ZAYg}!9zT4B`Bjtg{ zpy$+wZ+J2DrQK3mojL1ulelt~ze_6LkdWza@ZP#HbAO>>;HQf`|MMg1vD=Dg=8G>6 zmd8|Y`|n@womVhB8Od~(w)sSsL&B6E>g$WtMn2tr&Q%-vI6}D3qMyuNtDTydoxU`8 zQ>a{U)qVS&`r-2A%o|ld2vQSefkdg~VDj+D1&KI8JXC(gV2sA1YJ*xe+#f$VdBnBo zoSoUE4@aZsxYYXa@r}1vUkn`&*QdJQv~$DvGScMf4u{=*H$NwLlk;Vjx`6rRWLe1i n*4c3J==HJ9FGkK@Nbm^Aqx0Gglkb1-Lzl#Et+ael=I;L!Jom1B diff --git a/public/favicon-32.png b/public/favicon-32.png index 4a6132cb4b29d38c40be6ba7f13447b8a3330026..a35a0bae42b0b01dc1270cec49066fd2f0dc88e7 100644 GIT binary patch delta 964 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 diff --git a/public/favicon.ico b/public/favicon.ico index 4436fa4f36cc718a6f5a74e344092f390421fdba..46b2c2e9e64a90bd95187f31e8e5762f37d866fd 100644 GIT binary patch literal 15086 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 literal 5686 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 diff --git a/scripts/generate-favicons.sh b/scripts/generate-favicons.sh new file mode 100755 index 00000000..63e3339f --- /dev/null +++ b/scripts/generate-favicons.sh @@ -0,0 +1,113 @@ +#!/bin/bash +# Regenerate the web tab favicon assets from public/logo.svg. +# +# Why this script exists: +# The 16x16 favicon edge antialiasing must survive small-size rendering. +# Saving as palette/indexed PNG or 8bpp ICO bakes the editor's background +# into the antialiased edge pixels, producing the "ugly outline" halo +# you see in browser tab strips. We render at high resolution, downsample +# with Lanczos, and force full 32-bit RGBA output. +# +# Outputs (overwrites in place): +# public/favicon-16.png — 16x16 RGBA +# public/favicon-32.png — 32x32 RGBA +# public/favicon.ico — multi-size ICO, every frame 32bpp +# public/apple-touch-icon.png — 180x180 RGBA +set -e + +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +# Pick an SVG renderer (inkscape preferred, rsvg-convert fallback) +if command -v inkscape &> /dev/null; then + SVG_RENDERER="inkscape" +elif command -v rsvg-convert &> /dev/null; then + SVG_RENDERER="rsvg" +else + echo -e "${YELLOW}Error: install inkscape or rsvg-convert.${NC}" >&2 + exit 1 +fi + +# ImageMagick: v7 uses `magick`, v6 uses `convert`. +if command -v magick &> /dev/null; then + MAGICK="magick" +elif command -v convert &> /dev/null; then + MAGICK="convert" +else + echo -e "${YELLOW}Error: install ImageMagick.${NC}" >&2 + exit 1 +fi + +SOURCE_SVG="public/logo.svg" +if [ ! -f "$SOURCE_SVG" ]; then + echo -e "${YELLOW}Error: $SOURCE_SVG not found.${NC}" >&2 + exit 1 +fi + +# Agora brand orange. Keep in sync with the preloader / theme. +LOGO_COLOR="#FF6600" + +TMPDIR=$(mktemp -d) +trap 'rm -rf "$TMPDIR"' EXIT + +COLORED_SVG="$TMPDIR/logo_colored.svg" +RAW_PNG="$TMPDIR/raw.png" +MASTER_PNG="$TMPDIR/master.png" + +# Recolor the SVG's black fill to the brand color, on transparent background. +sed 's/fill="black"/fill="'"$LOGO_COLOR"'"/g' "$SOURCE_SVG" > "$COLORED_SVG" + +# The SVG's viewBox is 720x880 (taller than wide). Render at its native +# aspect ratio first so we don't squish the logo horizontally. +MASTER_BOX=512 # final square canvas size +MASTER_H=$MASTER_BOX # render the longer side at full size +MASTER_W=$(( MASTER_BOX * 720 / 880 )) # preserve 720:880 aspect + +echo "Rendering ${MASTER_W}x${MASTER_H} from $SOURCE_SVG (preserving 720:880 aspect)..." +if [ "$SVG_RENDERER" = "inkscape" ]; then + inkscape --export-type=png --export-filename="$RAW_PNG" \ + -w "$MASTER_W" -h "$MASTER_H" --export-background-opacity=0 \ + "$COLORED_SVG" 2>/dev/null +else + rsvg-convert -w "$MASTER_W" -h "$MASTER_H" -b none "$COLORED_SVG" -o "$RAW_PNG" +fi + +# Centre the rendered logo on a transparent square canvas so downstream +# square targets (favicons, apple-touch-icon) don't restretch it. +$MAGICK -size "${MASTER_BOX}x${MASTER_BOX}" "xc:none" \ + "$RAW_PNG" -gravity center -compose over -composite \ + "$MASTER_PNG" + +# Downsample to a target size with a quality filter, forcing RGBA output. +# `png:color-type=6` is PNG RGBA (8 bits per channel, with alpha). +# `-strip` removes metadata to keep files small. +render_png() { + local size=$1 + local dest=$2 + $MAGICK "$MASTER_PNG" \ + -filter Lanczos \ + -resize "${size}x${size}" \ + -background none -alpha on \ + -define png:color-type=6 \ + -strip \ + "$dest" + echo -e " ${GREEN}✓${NC} $dest ($(file -b "$dest" | head -c 80))" +} + +echo "Generating PNG variants..." +render_png 16 public/favicon-16.png +render_png 32 public/favicon-32.png +render_png 180 public/apple-touch-icon.png + +# Multi-size ICO. Building from the high-res master with auto-resize keeps +# every frame 32bpp RGBA. Verified with `file public/favicon.ico`. +echo "Generating multi-size favicon.ico (16, 32, 48)..." +$MAGICK "$MASTER_PNG" \ + -filter Lanczos \ + -background none -alpha on \ + -define icon:auto-resize=16,32,48 \ + public/favicon.ico +echo -e " ${GREEN}✓${NC} public/favicon.ico ($(file -b public/favicon.ico | head -c 120))" + +echo -e "\n${GREEN}Favicons regenerated.${NC}"