Files
scrabble-game/docs/ICONS.md
T
Ilia Denisov dbe2c4cb94
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Successful in 11s
CI / integration (pull_request) Successful in 23s
CI / ui (pull_request) Successful in 1m13s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m54s
feat(icons): rebrand app icon; slice the full set from one master
The SVG tracer export failed, so the icon was designed collaboratively from
scratch: a wooden «Э» tile with a ✻ score-subscript in Spectral Bold, wood
grain and diagonal light/shadow. Construction is specified in fractions of the
side in docs/ICON_BRANDBOOK.md; the reference generator, pinned Spectral font
and committed masters live in assets/icons/brand/.

One master -> the whole set (assets/icons/brand/build-set.mjs + build-android-res.mjs):
- web (ui/public): favicon.svg (light+dark via prefers-color-scheme), favicon.ico,
  apple-touch, PWA any + maskable (+ dark variants), og-image reskinned to
  «Эрудит» / Игра в слова
- Capacitor layers: ui/assets/{icon,icon-foreground,icon-background}.png
- Android launcher res, all densities, NO inset, + monochrome themed layer
  (anydpi xml: background+foreground+monochrome)
- manual-upload art: assets/icons/brand/{vk,tg,store} (square, no rounding)

Primary variant light; dark where the platform can theme (favicon.svg). The old
LiberationSans generator (assets/icons/build) is removed; docs/ICONS.md retargeted
onto the single master. ANDROID_PLAN icon-rebrand item marked done.
2026-07-13 21:49:29 +02:00

4.7 KiB
Raw Permalink Blame History

Icon & logo asset map

The whole shipped icon set is sliced from one master. This file is the per-platform target map (which file goes where, at what size). How the mark itself is constructed — proportions, palette, wood grain, the light/shadow gradients, the «Э» + ✻ placement, all in fractions of the side — is specified in ICON_BRANDBOOK.md. The reference generator, the pinned Spectral font and the committed masters live in ../assets/icons/brand/.

The master (one source, six layers)

brand/build-icon.mjs emits any --variant light|dark in any --layer:

Layer What Feeds
full rounded tile + master mark favicon.svg
flat square tile + master mark (OS rounds) apple-touch, PWA "any", VK, TG, store
background square tile only, full-bleed Android adaptive background
foreground mark only, transparent, re-placed for the round mask Android adaptive foreground
maskable square tile + foreground-placed mark PWA maskable
monochrome foreground-placed silhouette, flat colour Android 13+ themed layer

brand/build-set.mjs renders every raster below; brand/build-android-res.mjs renders the Android launcher resources.

Generated targets

Web — ui/public/ (via brand/build-set.mjs)

File Size Note
favicon.svg vector light + dark in one file via prefers-color-scheme
favicon.ico 32×32 PNG-in-ICO; answers the blind /favicon.ico probe
apple-touch-icon.png 180×180 opaque full-bleed (iOS masks its own corners)
icon-192.png / icon-512.png 192 / 512 PWA any, light
icon-192-dark.png / icon-512-dark.png 192 / 512 dark variants (generated; see PWA note)
icon-maskable-512.png 512×512 PWA maskable, light
icon-maskable-512-dark.png 512×512 dark variant (generated; see PWA note)
og-image.png 1200×630 board-green card: master tile + «Эрудит» / Игра в слова

PWA — ui/public/manifest.webmanifest

Referenced icons are the light set (icon-192, icon-512 = any; icon-maskable-512 = maskable). The manifest has no reliable way to pick an icon by colour scheme, so the dark PNGs are generated but not referenced — theming the in-browser tab is handled by favicon.svg instead. Wire the dark files in only if a concrete installer target is known to honour them.

Android — ui/android/app/src/main/res/ (via brand/build-android-res.mjs)

Capacitor layer inputs are ui/assets/{icon,icon-foreground,icon-background}.png. The resources are hand-generated from the layers, not capacitor-assets — our layers already fill the 108 dp canvas (foreground inside the 61 % safe zone, background full-bleed), so they must be placed with no inset, and we add the monochrome themed layer, neither of which capacitor-assets does. Per density mdpi→xxxhdpi (+ldpi):

  • mipmap-*/ic_launcher.png / ic_launcher_round.png — legacy square / round (composite)
  • mipmap-*/ic_launcher_foreground.png + ic_launcher_background.png — adaptive layers
  • mipmap-*/ic_launcher_monochrome.png — themed layer
  • mipmap-anydpi-v26/ic_launcher.xml + ic_launcher_round.xmlno <inset>, with <background> + <foreground> + <monochrome> (committed by hand)

iOS / iPhone / iPad — FUTURE

No iOS shell today. When one exists, flat (opaque, no alpha, no rounded corners; the OS masks) drives the asset catalog — a single 1024×1024 marketing icon (Xcode derives the rest), plus light/dark/tinted where the catalog supports it.

VK / Telegram / store — manual upload (brand/{vk,tg,store}/)

Square, no rounding (each platform crops/rounds itself), light flat:

Folder Files Use
vk/ vk-576/278/150/32.png VK community / app icons
tg/ tg-512.png Telegram bot avatar + Mini App icon (512, square; TG crops circular)
tg/ tg-demo-640x360.png BotFather /newapp demo banner (tile + wordmark)
store/ rustore-512.png RuStore app icon
RuStore screenshots / feature graphic per the RuStore listing spec (uploaded by hand)
Google Play (future) icon / feature graphic 512×512 / 1024×500
App Store (future) marketing icon / screenshots 1024×1024 / per device class

Regenerate

cd assets/icons/brand
npm i                        # opentype.js (rasterisation reuses the ui package's chromium)
node build-set.mjs           # web (ui/public) + Capacitor layers (ui/assets) + vk/ tg/ store/ + og
node build-android-res.mjs   # Android launcher resources (all densities + monochrome)