update-launcher-icon
Use when /logo.svg changes or when asked to update, replace, or apply the Android launcher app icon in femto-car-launcher. Triggers on "update the app icon", "apply the new logo", "make logo.svg the l
SKILL.md.claude/skills/update-launcher-icon/SKILL.md
GitHubUpdating the launcher icon from logo.svg
/logo.svg (512×512, project root) is the brand-mark SSOT. The
launcher icon is an adaptive icon derived from it; never edit
the derived drawables as the design source — change logo.svg
first, then re-run this procedure.
Layer mapping
| logo.svg element | Android resource | Rule |
|---|---|---|
Full-bleed background <rect> |
drawable/ic_launcher_background.xml |
Full-canvas fill of the rect's colour only. Drop the corner radius — the launcher applies its own mask shape. |
| Everything else (the mark) | drawable/ic_launcher_foreground.xml |
Scaled into the safe zone (math below), centred on the canvas. |
| (same paths) | <monochrome> in mipmap-anydpi/*.xml |
Shares the foreground drawable. Opacity differences survive as alpha in themed icons. |
mipmap-anydpi/ic_launcher.xml and ic_launcher_round.xml only
reference the two drawables — they normally need no edit.
Safe-zone scaling (the step everyone skips)
The adaptive-icon safe zone is the centre circle of diameter 66 on the 108 canvas. Copying logo.svg coordinates 1:1 into the foreground is always wrong — the full-bleed logo art reaches the canvas edge and the launcher mask clips it.
Keep the foreground viewport at 512 (matching logo.svg) and shrink the mark into the safe circle:
- Safe radius in 512 units:
512 × 33 / 108 ≈ 156. - Find the mark's farthest extent from its own centre
c, including stroke:r_max = max(|p − c|) + strokeWidth / 2over all path end/corner pointsp. scale = 150 / r_max(use ~150, not 156, for breathing room).- Transform every coordinate
p' = 256 + (p − c) × scaleand multiply everystrokeWidthby the samescale. This also re-centres the mark's optical centre on (256, 256). - Re-verify after transforming (arithmetic slips here are
common): recompute
r'_max = max(|p' − (256, 256)|) + strokeWidth' / 2over the transformed points with a calculator/script — do not do the square roots in your head. The procedure is only complete whenr'_max ≤ 156.
Procedure
- Read
/logo.svgand classify elements per the layer-mapping table. - Write the background: 108 viewport, single
M0,0h108v108h-108zpath filled with the logo's background colour. Nothing else. - Write the foreground: 512 viewport, one
<path>per SVG element, coordinates transformed by the safe-zone math. Attribute translation:stroke→android:strokeColor,stroke-width→android:strokeWidth,opacityon a stroked path →android:strokeAlpha(on a filled path →android:fillAlpha),stroke-linecap/-linejoin→android:strokeLineCap/LineJoin, no fill →android:fillColor="#00000000". - Monochrome: keep sharing the foreground drawable. Create a dedicated white-stroke drawable only if the mark encodes its hierarchy in colour rather than opacity (alpha is all the themed-icon pipeline keeps).
- No rasters:
minSdk = 33, somipmap-anydpialways wins. Do not generatemipmap-*dpiwebp/png fallbacks; delete any that exist. - Verify with the
verify-android-buildskill.
Nightly channel
app/src/nightly/res/drawable/ic_launcher_foreground.xml is the
stable foreground plus a two-path "N" badge (filled disc + glyph)
appended inside <vector>, so the two channels stay visually
distinguishable when both are installed side by side. Source-set
precedence lets it override the stable drawable — including the
shared monochrome icon — with no other wiring.
Regenerate it whenever logo.svg changes: re-run the procedure
above for the stable foreground, then re-append the two badge paths
unchanged. The badge geometry (disc centre 357.5,336.5, r 20.5) is
bound by the chevron ink, the tighter of its two clearance limits —
see the derivation in the comment above those paths in the drawable
— so treat it as fixed rather than rescaling or repositioning it by
eye.
Skill-specific anti-patterns
- Copying logo.svg coordinates or stroke widths 1:1 into the foreground — the mask clips the mark (see safe-zone math).
- Reproducing the logo's rounded corners in the background layer.
- Generating density-bucket PNG/webp fallbacks "for older devices".
- Editing
ic_launcher_foreground.xmldirectly to change the design —logo.svgis the SSOT.