@maccesar/titools 4.4.2 → 4.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/commands/doctor.js +1 -1
- package/lib/commands/list.js +151 -40
- package/lib/commands/skills.js +1 -4
- package/lib/commands/status.js +1 -2
- package/lib/commands/update.js +1 -1
- package/lib/installer.js +0 -1
- package/lib/prompts/checkboxCancel.js +0 -6
- package/lib/symlink.js +1 -1
- package/package.json +4 -2
- package/skills/purgetss/SKILL.md +3 -2
- package/skills/purgetss/references/app-branding.md +406 -323
- package/skills/purgetss/references/cli-commands.md +76 -92
- package/skills/purgetss/references/customization-deep-dive.md +39 -39
- package/skills/purgetss/references/launch-background.md +102 -0
- package/skills/purgetss/references/migration-guide.md +92 -7
- package/skills/purgetss/references/version-history.md +29 -0
- package/skills/ti-api/references/api-media.md +210 -58
- package/skills/ti-api/references/api-modules-map.md +28 -18
- package/skills/ti-api/references/api-modules-social-misc.md +23 -3
- package/skills/ti-api/references/api-ui-extras.md +79 -16
- package/skills/ti-api/references/api-ui-lists.md +89 -22
- package/skills/ti-api/references/api-ui-windows-navigation.md +78 -50
- package/skills/ti-guides/SKILL.md +5 -1
- package/skills/ti-guides/references/compatibility-matrix.md +89 -0
- package/skills/ti-guides/references/resources.md +7 -1
- package/skills/ti-guides/references/sdk-release-notes.md +75 -0
- package/skills/ti-ui/references/scrolling-views.md +7 -1
|
@@ -1,32 +1,38 @@
|
|
|
1
1
|
# App Icons & Branding
|
|
2
2
|
|
|
3
|
-
The `purgetss brand` command (introduced in
|
|
3
|
+
The `purgetss brand` command (introduced in v7.6.0, grouped config in v7.7.0, restructured into per-piece blocks in v7.13.0) regenerates **every image the Titanium template ships**, from one main SVG or PNG logo: launcher icons, adaptive icons, iOS 18+ Dark/Tinted variants, marketplace artwork, and both the iOS and Android splash sets. Per-piece overrides are there when you need them. Alloy and Classic layouts are auto-detected.
|
|
4
|
+
|
|
5
|
+
The rule is simple: **if the template ships the file, `brand` updates it.** You should never have to know which API still reads which file to avoid shipping an app with the grey Alloy logo somewhere in it.
|
|
4
6
|
|
|
5
7
|
For the terse flag reference, see the [`brand` command reference](./cli-commands.md#brand-command). For sibling UI assets, see [Multi-Density Images](./multi-density-images.md).
|
|
6
8
|
|
|
7
|
-
> **
|
|
9
|
+
> **WARNING**
|
|
8
10
|
>
|
|
9
|
-
>
|
|
10
|
-
> `
|
|
11
|
+
> Breaking changes in v7.13.0
|
|
12
|
+
> `--splash` → `--splash-icon`, `--notification` → `--notification-icon`, `--splash-logo` → `--splash-icon-logo`, `--feature-logo` → `--feature-graphic-logo`. `--icon-logo` now feeds the `icon` piece (the Android launcher source is `--adaptive-logo`). `--legacy-splash` is gone: the per-qualifier Android splashes belong to `android-splash` and are always generated. **No flag aliases were kept.** The `brand:` config block also changed shape, but that one updates itself — see [Older configs update themselves](#older-configs-update-themselves).
|
|
11
13
|
|
|
12
14
|
<!-- TOC-START -->
|
|
13
15
|
## Contents
|
|
14
16
|
|
|
15
17
|
- [Quick start](#quick-start)
|
|
16
18
|
- [The `purgetss/brand/` convention](#the-purgetssbrand-convention)
|
|
17
|
-
- [The `brand:` config section
|
|
19
|
+
- [The `brand:` config section](#the-brand-config-section)
|
|
20
|
+
- [Brand config reference](#brand-config-reference)
|
|
18
21
|
- [Overwrite confirmation](#overwrite-confirmation)
|
|
19
22
|
- [What gets generated](#what-gets-generated)
|
|
23
|
+
- [Shrinking the generated files](#shrinking-the-generated-files)
|
|
24
|
+
- [Regenerating a single piece with `--only`](#regenerating-a-single-piece-with---only)
|
|
20
25
|
- [Android dark mode](#android-dark-mode)
|
|
21
26
|
- [Android 12+ splash artwork](#android-12-splash-artwork)
|
|
22
|
-
- [Android
|
|
27
|
+
- [Android pre-12 splash](#android-pre-12-splash)
|
|
28
|
+
- [The iOS launch screen and LaunchLogo.png](#the-ios-launch-screen-and-launchlogopng)
|
|
29
|
+
- [iPhone launch images](#iphone-launch-images)
|
|
23
30
|
- [iOS 18+ Dark and Tinted variants](#ios-18-dark-and-tinted-variants)
|
|
24
|
-
- [Google Play Feature Graphic (v7.10.0)](#google-play-feature-graphic-v7100)
|
|
25
31
|
- [Brand color](#brand-color)
|
|
26
32
|
- [Padding guidance](#padding-guidance)
|
|
27
33
|
- [Cleanup legacy branding artifacts](#cleanup-legacy-branding-artifacts)
|
|
28
34
|
- [Troubleshooting](#troubleshooting)
|
|
29
|
-
- [
|
|
35
|
+
- [Flag reference](#flag-reference)
|
|
30
36
|
- [Community-Discovered Patterns](#community-discovered-patterns)
|
|
31
37
|
- [See also](#see-also)
|
|
32
38
|
|
|
@@ -34,7 +40,7 @@ For the terse flag reference, see the [`brand` command reference](./cli-commands
|
|
|
34
40
|
|
|
35
41
|
## Quick start
|
|
36
42
|
|
|
37
|
-
Drop a logo file into `purgetss/brand/`, then run the command.
|
|
43
|
+
Drop a logo file into `purgetss/brand/`, then run the command.
|
|
38
44
|
|
|
39
45
|
```bash
|
|
40
46
|
mkdir -p purgetss/brand # if the folder doesn't exist yet
|
|
@@ -59,45 +65,48 @@ purgetss brand --dry-run
|
|
|
59
65
|
|
|
60
66
|
`init` creates `purgetss/brand/` (alongside `fonts/` and `images/`) so the folder is already there the first time you look for it, even before you've dropped in a logo.
|
|
61
67
|
|
|
62
|
-
PurgeTSS auto-discovers logo files under this folder, the same way `purgetss/fonts/` works for fonts.
|
|
68
|
+
PurgeTSS auto-discovers logo files under this folder, the same way `purgetss/fonts/` works for fonts. The naming rule is `logo-<piece>`, using the same piece names the CLI and the config use. Drop a file in and you're done:
|
|
63
69
|
|
|
64
70
|
```text
|
|
65
71
|
purgetss/brand/
|
|
66
|
-
├── logo.svg
|
|
67
|
-
├── logo-
|
|
68
|
-
├── logo-
|
|
69
|
-
├── logo-
|
|
70
|
-
├── logo-
|
|
71
|
-
├── logo-tinted.svg
|
|
72
|
-
|
|
72
|
+
├── logo.svg required — main logo (or logo.png), source for every piece
|
|
73
|
+
├── logo-mono.svg optional — monochrome layer + notification icons
|
|
74
|
+
├── logo-icon.svg optional — DefaultIcon.png + DefaultIcon-ios.png
|
|
75
|
+
├── logo-adaptive.svg optional — square Android launcher mark
|
|
76
|
+
├── logo-dark.svg optional — iOS 18+ dark variant
|
|
77
|
+
├── logo-tinted.svg optional — iOS 18+ tinted variant
|
|
78
|
+
├── logo-launch.svg optional — iOS launch screen logotype (LaunchLogo.png)
|
|
79
|
+
├── logo-splash-icon.svg optional — Android 12+ splash icon override
|
|
80
|
+
├── logo-android-splash.svg optional — Android <12 splash artwork
|
|
81
|
+
├── logo-ios-splash.svg optional — iPhone launch images
|
|
82
|
+
├── logo-marketplace.svg optional — App Store / Play Store artwork
|
|
83
|
+
├── logo-feature-graphic.svg optional — Google Play Feature Graphic override
|
|
84
|
+
├── logo-legacy-icon.svg optional — legacy ic_launcher.png
|
|
85
|
+
├── logo-appicon.svg optional — appicon.png
|
|
86
|
+
└── logo-notification-icon.svg optional — notification icons
|
|
73
87
|
```
|
|
74
88
|
|
|
75
|
-
Only `logo.svg` (or `logo.png`) is required.
|
|
76
|
-
|
|
77
|
-
| File | Required? | What it's for | Fallback when omitted |
|
|
78
|
-
| --- | --- | --- | --- |
|
|
79
|
-
| `logo.svg` / `logo.png` | **Required** | Main colored logo. Feeds every density and variant. | — |
|
|
80
|
-
| `logo-icon.svg` / `.png` | Optional | Square Android launcher mark — use when `logo.svg` is a wide wordmark or non-square lockup. | Main logo is reused for Android launcher icons. |
|
|
81
|
-
| `logo-mono.svg` / `.png` | Optional | Android adaptive monochrome layer (themed icons on Android 13+) and notification icons. | Main logo is whitened automatically. |
|
|
82
|
-
| `logo-splash.svg` / `.png` | Optional | Android 12+ `splash_icon.png` artwork (only used when `--splash` / `android.splash: true`). | Falls back to the launcher artwork. |
|
|
83
|
-
| `logo-dark.svg` / `.png` | Optional | iOS 18+ Dark appearance variant. | Main logo on a transparent background (Apple HIG default). |
|
|
84
|
-
| `logo-tinted.svg` / `.png` | Optional | iOS 18+ Tinted appearance variant. | Grayscale of the main logo on black. |
|
|
85
|
-
| `logo-feature.svg` / `.png` | Optional | Google Play Feature Graphic (1024×500). Use when the Play Store banner should differ from the main app icon (e.g. logo + tagline lockup that fills the wider rectangular canvas). | Main logo is centered inside the banner with configured vertical padding. |
|
|
86
|
-
|
|
87
|
-
Provide a dedicated `logo-icon` when the main logo is a horizontal wordmark, a vertical lockup, or anything else that looks fine in a 1024×1024 branding canvas but feels cramped inside an Android launcher mask.
|
|
89
|
+
Only `logo.svg` (or `logo.png`) is required. Every other file is an override for one piece, and dropping it in is all it takes. There is no syntax to remember, and opening the folder shows what has been customized.
|
|
88
90
|
|
|
89
|
-
|
|
91
|
+
Every one of them has a CLI equivalent, `--<piece>-logo <path>`, and a config equivalent, `brand.<piece>.logo`, for artwork that lives outside `purgetss/brand/`.
|
|
90
92
|
|
|
91
|
-
|
|
93
|
+
The ones worth knowing about:
|
|
92
94
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
| File | What it's for | Fallback when omitted |
|
|
96
|
+
| --- | --- | --- |
|
|
97
|
+
| `logo-icon` | Alternate artwork for `DefaultIcon.png` / `DefaultIcon-ios.png`, when the universal icon should differ from the main logo. | Main logo. |
|
|
98
|
+
| `logo-adaptive` | A separate **square** mark for Android launcher icons. Use it when the main logo is a horizontal wordmark, a vertical lockup, or anything else that looks fine on a 1024×1024 canvas but feels cramped inside an Android launcher mask. | Main logo. |
|
|
99
|
+
| `logo-mono` | Silhouette for the Android adaptive monochrome layer (themed icons on Android 13+) and for notification icons. | Main logo, whitened automatically. |
|
|
100
|
+
| `logo-dark` | iOS 18+ dark mode. Provide your own when dark-mode brand guidelines use a different lockup or color treatment. | Main logo on a transparent background (Apple's recommended approach). |
|
|
101
|
+
| `logo-tinted` | iOS 18+ tinted mode. Provide your own when a simpler silhouette tints better than a grayscale of the colored version. | Grayscale of the main logo. |
|
|
102
|
+
| `logo-launch` | The only file that also **activates** a piece. Drop it in and `brand` writes `LaunchLogo.png`, so the iOS launch screen shows your logotype instead of the app icon. See [The iOS launch screen and LaunchLogo.png](#the-ios-launch-screen-and-launchlogopng). | Piece is not generated. |
|
|
103
|
+
| `logo-splash-icon` | Alternate artwork for Android 12+ `splash_icon.png`, when the splash should use a different composition than the launcher icon. | Launcher artwork. |
|
|
104
|
+
| `logo-feature-graphic` | Alternate logo for the Google Play Feature Graphic (1024×500 banner) — a logo-plus-tagline lockup, say, or wider artwork that uses the rectangular canvas instead of staying inside the centered square. | Main logo, centered with the configured vertical padding. |
|
|
96
105
|
|
|
97
106
|
> **INFO**
|
|
98
107
|
>
|
|
99
108
|
> Prefer SVG for the master
|
|
100
|
-
> SVG scales
|
|
109
|
+
> SVG scales cleanly to every density Sharp needs to emit. A single `logo.svg` can be rasterized at every `res-*dpi` output. PNG masters should be at least **1024×1024** to avoid upscaling artifacts.
|
|
101
110
|
|
|
102
111
|
### Overriding auto-discovery
|
|
103
112
|
|
|
@@ -107,143 +116,146 @@ You can also pass a path directly or point to a logo from the config. Useful whe
|
|
|
107
116
|
purgetss brand ./docs/snap-logo.svg
|
|
108
117
|
```
|
|
109
118
|
|
|
110
|
-
Or in `purgetss/config.cjs`:
|
|
119
|
+
Or in `purgetss/config.cjs`, where each piece takes its own `logo`:
|
|
111
120
|
|
|
112
121
|
```javascript
|
|
113
122
|
brand: {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
monochrome: './docs/snap-logo-mono.svg',
|
|
118
|
-
featureGraphic: './docs/snap-feature.svg' // optional — Google Play Feature Graphic
|
|
119
|
-
}
|
|
123
|
+
adaptive: { logo: './docs/snap-app-icon.svg' },
|
|
124
|
+
featureGraphic: { logo: './docs/snap-feature.svg' },
|
|
125
|
+
monochromeLogo: './docs/snap-logo-mono.svg'
|
|
120
126
|
}
|
|
121
127
|
```
|
|
122
128
|
|
|
123
129
|
Precedence: **CLI flags win over config values, and config values win over auto-discovery.**
|
|
124
130
|
|
|
125
|
-
|
|
131
|
+
### How the work is divided between files and config
|
|
132
|
+
|
|
133
|
+
- **Files decide the artwork.** Dropping `logo-dark.svg` next to `logo.svg` is enough; open the folder and you can see what has been customized. This is the main path.
|
|
134
|
+
- **Config decides numbers, colors and activation**, none of which can be expressed with a filename.
|
|
135
|
+
- `logo:` inside a piece is there for artwork that lives outside `purgetss/brand/`.
|
|
136
|
+
|
|
137
|
+
## The `brand:` config section
|
|
126
138
|
|
|
127
|
-
On the first run, `purgetss brand`
|
|
139
|
+
On the first run, `purgetss brand` adds a `brand:` block to your existing `purgetss/config.cjs`, between `purge:` and `theme:`. It has **one block per piece**:
|
|
128
140
|
|
|
129
141
|
```javascript
|
|
130
142
|
brand: {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
//
|
|
138
|
-
|
|
139
|
-
},
|
|
140
|
-
padding:
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
},
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
// Optional iOS overrides:
|
|
154
|
-
// ios: {
|
|
155
|
-
// dark: false, // skip DefaultIcon-Dark.png
|
|
156
|
-
// tinted: false, // skip DefaultIcon-Tinted.png
|
|
157
|
-
// darkBackground: '#111' // opaque dark bg for DefaultIcon-Dark.png (null = transparent per Apple HIG)
|
|
158
|
-
// },
|
|
159
|
-
confirmOverwrites: true // prompt before overwriting files (set false to skip)
|
|
143
|
+
background: '#FFFFFF', // inherited by every piece that doesn't set its own
|
|
144
|
+
confirmOverwrites: true, // prompt before overwriting files (set false to skip)
|
|
145
|
+
optimize: false, // true = quantize the generated PNGs to a palette (lossy, ~71% smaller)
|
|
146
|
+
|
|
147
|
+
// One block per piece. Artwork comes from purgetss/brand/logo-<piece>.{svg,png};
|
|
148
|
+
// these keys are for numbers, colors and activation. Padding is never inherited.
|
|
149
|
+
icon: { padding: '4%' }, // DefaultIcon.png + DefaultIcon-ios.png
|
|
150
|
+
dark: { background: null }, // DefaultIcon-Dark.png
|
|
151
|
+
tinted: {}, // DefaultIcon-Tinted.png
|
|
152
|
+
iosSplash: { padding: '26%' }, // assets/iphone/Default*.png × 16
|
|
153
|
+
launchLogo: { padding: '12%' }, // LaunchLogo.png (1024×1024)
|
|
154
|
+
marketplace: {}, // iTunesConnect.png + MarketplaceArtwork.png
|
|
155
|
+
featureGraphic: { padding: '12%' }, // MarketplaceArtworkFeature.png (1024×500)
|
|
156
|
+
adaptive: { padding: '18%' }, // ic_launcher_{foreground,background,monochrome}.png × 5 + ic_launcher.xml
|
|
157
|
+
legacyIcon: { padding: '10%' }, // ic_launcher.png × 5
|
|
158
|
+
appicon: {}, // appicon.png (128×128)
|
|
159
|
+
androidSplash: { padding: '26%' }, // assets/android/default.png + images/res-*/default.png × 11
|
|
160
|
+
|
|
161
|
+
// Opt-in: inert until you edit the Android theme / FCM meta-data by hand.
|
|
162
|
+
splashIcon: { enabled: false }, // drawable-*/splash_icon.png × 5
|
|
163
|
+
notificationIcon: { enabled: false }, // drawable-*/ic_stat_notify.png × 5
|
|
164
|
+
ninePatch: { enabled: false } // background.9.png (not implemented yet)
|
|
160
165
|
}
|
|
161
166
|
```
|
|
162
167
|
|
|
163
|
-
|
|
168
|
+
Change only what you want to keep as a project default. CLI flags still win for one-off runs.
|
|
164
169
|
|
|
165
|
-
###
|
|
170
|
+
### Older configs update themselves
|
|
166
171
|
|
|
167
|
-
|
|
172
|
+
PurgeTSS keeps `config.cjs` current the same way it renamed `config.js` to `config.cjs`: **on the file, once**. When the `brand:` block uses a shape from an earlier version, the next run rewrites it to the per-piece structure and carries over everything that had been customized (paddings, colors, logo paths, enabled flags), then lists each value it moved:
|
|
168
173
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
| `logos.featureGraphic` | `purgetss/brand/logo-feature.svg` | Google Play Feature Graphic source (1024×500 rectangular canvas). |
|
|
178
|
-
|
|
179
|
-
### `brand.padding`
|
|
180
|
-
|
|
181
|
-
All padding values accept either numbers or percentage strings like `'19%'`.
|
|
174
|
+
```text
|
|
175
|
+
::PurgeTSS:: Updated the brand: structure in ./purgetss/config.cjs.
|
|
176
|
+
Your values were carried over:
|
|
177
|
+
• brand.logos.androidLauncher → brand.adaptive.logo
|
|
178
|
+
• brand.padding.androidAdaptive → brand.adaptive.padding
|
|
179
|
+
• brand.android.splash → brand.splashIcon.enabled
|
|
180
|
+
• brand.colors.background → brand.background
|
|
181
|
+
```
|
|
182
182
|
|
|
183
|
-
|
|
184
|
-
| --- | --- | --- |
|
|
185
|
-
| `padding.ios` | `'4%'` | Visual inset for `DefaultIcon-ios.png`, `DefaultIcon-Dark.png`, `DefaultIcon-Tinted.png`, marketplace artwork. |
|
|
186
|
-
| `padding.androidLegacy` | `'10%'` | Visual inset for legacy `ic_launcher.png`. |
|
|
187
|
-
| `padding.androidAdaptive` | `'19%'` | Visual inset for adaptive Android foreground (`ic_launcher_foreground.png`). Adjust this first when icons look cropped inside launcher masks. |
|
|
188
|
-
| `padding.featureGraphic` | `'12%'` | Vertical padding (top + bottom) for `MarketplaceArtworkFeature.png` (1024×500 Google Play banner). The logo is rendered as a square block of side `500 - 2 × pad` centered horizontally and vertically. Lower it for a more impactful banner; raise it if the logo looks cramped against the top or bottom edge on smaller Play Store crops. |
|
|
183
|
+
This happens on `purgetss brand`, and on any command that goes through the config: `build`, `watch`, `purge`, `shades`. Values that already matched a default are not written, so a block that was never customized comes out clean rather than cluttered with redundant keys.
|
|
189
184
|
|
|
190
|
-
|
|
185
|
+
Both earlier shapes are recognized: the original flat keys (`brand.padding` as a number, `brand.iosPadding`, `brand.bgColor`, `brand.darkBgColor`, top-level `brand.notification` / `brand.splash`) and the grouped sections from v7.7.0 (`logos` / `padding` / `android` / `ios` / `colors`). One key is dropped rather than moved: `brand.android.legacySplash`, because the per-qualifier splashes belong to `androidSplash` now and are always generated. The run says so when it happens.
|
|
191
186
|
|
|
192
|
-
|
|
193
|
-
| --- | --- | --- |
|
|
194
|
-
| `android.splash` | `false` | When `true`, also generates `drawable-*/splash_icon.png`. |
|
|
195
|
-
| `android.notification` | `false` | When `true`, also generates `drawable-*/ic_stat_notify.png`. |
|
|
187
|
+
The command itself understands exactly one structure. Nothing translates on the fly, so the day this migration is removed, nothing else changes.
|
|
196
188
|
|
|
197
|
-
|
|
189
|
+
> **INFO**
|
|
190
|
+
>
|
|
191
|
+
> This replaced the in-memory translation that ran from v7.10.2 to v7.12.1. Back then `normalizeLegacyBrand()` re-translated the old shape on **every** config read — every purge, watch and build, forever. Now the file is fixed once and every command afterwards reads one shape.
|
|
198
192
|
|
|
199
|
-
|
|
193
|
+
### Unknown keys are an error
|
|
200
194
|
|
|
201
|
-
|
|
202
|
-
| --- | --- | --- |
|
|
203
|
-
| `ios.dark` | `true` | Set to `false` to skip `DefaultIcon-Dark.png`. |
|
|
204
|
-
| `ios.tinted` | `true` | Set to `false` to skip `DefaultIcon-Tinted.png`. |
|
|
205
|
-
| `ios.darkBackground` | `null` | When `null`, `DefaultIcon-Dark.png` stays transparent per Apple HIG. Set a hex to bake in an opaque dark background. |
|
|
195
|
+
A key `brand:` does not define stops the run before a single file is written, at both levels:
|
|
206
196
|
|
|
207
|
-
|
|
197
|
+
```text
|
|
198
|
+
Unknown key(s) in the brand: section of purgetss/config.cjs:
|
|
199
|
+
• brand.adaptive.paddig
|
|
208
200
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
201
|
+
Top-level keys: background, confirmOverwrites, logo, monochromeLogo
|
|
202
|
+
Piece blocks: icon, dark, tinted, iosSplash, launchLogo, marketplace, featureGraphic,
|
|
203
|
+
adaptive, legacyIcon, appicon, androidSplash, splashIcon,
|
|
204
|
+
notificationIcon, ninePatch
|
|
205
|
+
Inside a piece: logo, padding, background, enabled
|
|
212
206
|
|
|
213
|
-
|
|
207
|
+
Check the spelling. Nothing was written.
|
|
208
|
+
```
|
|
214
209
|
|
|
215
|
-
|
|
216
|
-
| --- | --- | --- |
|
|
217
|
-
| `confirmOverwrites` | `true` | When `false`, the `[y/N/a]` prompt is skipped. |
|
|
210
|
+
A typo is deliberately **not** treated as an old structure: rewriting the block would drop it silently. And ignoring a misspelled `paddig` would be worse than stopping — the whole icon set would render at the wrong size and look perfectly plausible.
|
|
218
211
|
|
|
219
|
-
|
|
212
|
+
## Brand config reference
|
|
220
213
|
|
|
221
|
-
|
|
214
|
+
Every piece accepts the same four keys, where they apply:
|
|
222
215
|
|
|
223
|
-
|
|
|
216
|
+
| Key | What it does |
|
|
224
217
|
| --- | --- |
|
|
225
|
-
| `
|
|
226
|
-
| `
|
|
227
|
-
| `
|
|
228
|
-
| `
|
|
229
|
-
| `brand.notification` | `brand.android.notification` |
|
|
230
|
-
| `brand.splash` | `brand.android.splash` |
|
|
231
|
-
|
|
232
|
-
If both legacy and grouped keys are present for the same property, the **grouped key wins**.
|
|
218
|
+
| `logo` | Path to this piece's artwork, when it lives outside `purgetss/brand/`. |
|
|
219
|
+
| `padding` | Inset per side, as a number or a percentage string like `'19%'`. **Never inherited.** |
|
|
220
|
+
| `background` | Hex color, or `null` for transparent. Inherited from `brand.background`. |
|
|
221
|
+
| `enabled` | `false` turns a default piece off; `true` turns an opt-in piece on. |
|
|
233
222
|
|
|
234
|
-
|
|
223
|
+
And these live at the top level:
|
|
235
224
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
The
|
|
245
|
-
|
|
246
|
-
|
|
225
|
+
| Key | Default | Purpose |
|
|
226
|
+
| --- | --- | --- |
|
|
227
|
+
| `background` | `'#FFFFFF'` | The background every piece inherits unless it declares its own: the Android adaptive background layer, the `DefaultIcon-ios.png` flatten, the splash canvases, and the marketplace flatten when a background is explicitly configured. |
|
|
228
|
+
| `confirmOverwrites` | `true` | Whether `brand` asks before overwriting project files in place. |
|
|
229
|
+
| `optimize` | `false` | Quantize the generated PNGs to a palette. Lossy — see [Shrinking the generated files](#shrinking-the-generated-files). |
|
|
230
|
+
| `logo` | — | Path override for the main logo. |
|
|
231
|
+
| `monochromeLogo` | — | Path override for the silhouette shared by the adaptive monochrome layer and the notification icons. |
|
|
232
|
+
|
|
233
|
+
### The pieces
|
|
234
|
+
|
|
235
|
+
| Piece | Config key | Generates | Default padding | On by default |
|
|
236
|
+
| --- | --- | --- | --- | --- |
|
|
237
|
+
| `icon` | `icon` | `DefaultIcon.png` + `DefaultIcon-ios.png` | `4%` | yes |
|
|
238
|
+
| `dark` | `dark` | `DefaultIcon-Dark.png` | `4%` | yes |
|
|
239
|
+
| `tinted` | `tinted` | `DefaultIcon-Tinted.png` | `4%` | yes |
|
|
240
|
+
| `ios-splash` | `iosSplash` | `assets/iphone/Default*.png` × 16 | `26%` | yes |
|
|
241
|
+
| `launch-logo` | `launchLogo` | `LaunchLogo.png` (1024×1024) | `12%` | when `logo-launch.*` exists |
|
|
242
|
+
| `marketplace` | `marketplace` | `iTunesConnect.png` + `MarketplaceArtwork.png` | `4%` | yes |
|
|
243
|
+
| `feature-graphic` | `featureGraphic` | `MarketplaceArtworkFeature.png` (1024×500) | `12%` | yes |
|
|
244
|
+
| `adaptive` | `adaptive` | `ic_launcher_{foreground,background,monochrome}.png` × 5 + `ic_launcher.xml` | `18%` | yes |
|
|
245
|
+
| `legacy-icon` | `legacyIcon` | `ic_launcher.png` × 5 | `10%` | yes |
|
|
246
|
+
| `appicon` | `appicon` | `appicon.png` (128×128) | `10%` | yes |
|
|
247
|
+
| `android-splash` | `androidSplash` | `assets/android/default.png` + `images/res-*/default.png` × 11 | `26%` | yes |
|
|
248
|
+
| `splash-icon` | `splashIcon` | `drawable-*/splash_icon.png` × 5 | — | `--splash-icon` |
|
|
249
|
+
| `notification-icon` | `notificationIcon` | `drawable-*/ic_stat_notify.png` × 5 | — | `--notification-icon` |
|
|
250
|
+
| `nine-patch` | `ninePatch` | `background.9.png` | — | `--nine-patch` (not implemented yet) |
|
|
251
|
+
|
|
252
|
+
`ic_launcher.xml` always travels inside `adaptive`; it is never generated on its own.
|
|
253
|
+
|
|
254
|
+
Only three pieces are opt-in, and for one reason: they produce nothing useful until you edit XML by hand. `splash_icon.png` is inert without `windowSplashScreenAnimatedIcon` in the theme, and `ic_stat_notify.png` is inert without the FCM `meta-data` entry.
|
|
255
|
+
|
|
256
|
+
### `background` is inherited, `padding` is not
|
|
257
|
+
|
|
258
|
+
Set `brand.background` once and every piece picks it up. Padding works the other way on purpose: the defaults answer to different constraints. The adaptive `18%` answers to the Android launcher mask, while the iOS `4%` is an aesthetic choice with no mask behind it. A single inherited number would let `8%` quietly break the launcher mask, so padding is set per piece or not at all.
|
|
247
259
|
|
|
248
260
|
## Overwrite confirmation
|
|
249
261
|
|
|
@@ -279,24 +291,29 @@ The output is automatically routed to the right directory for your project layou
|
|
|
279
291
|
```text
|
|
280
292
|
<project>/
|
|
281
293
|
├── DefaultIcon.png ← 1024×1024, universal fallback (Android-safe padding)
|
|
282
|
-
├── DefaultIcon-ios.png ← 1024×1024, iOS flattened on
|
|
294
|
+
├── DefaultIcon-ios.png ← 1024×1024, iOS flattened on brand.background
|
|
283
295
|
├── DefaultIcon-Dark.png ← 1024×1024, iOS 18+ dark (transparent per Apple HIG)
|
|
284
296
|
├── DefaultIcon-Tinted.png ← 1024×1024, iOS 18+ tinted (grayscale on black)
|
|
285
297
|
├── iTunesConnect.png ← 1024×1024, App Store submission
|
|
286
298
|
├── MarketplaceArtwork.png ← 512×512, Google Play submission
|
|
287
|
-
├── MarketplaceArtworkFeature.png ← 1024×500, Google Play Feature Graphic
|
|
299
|
+
├── MarketplaceArtworkFeature.png ← 1024×500, Google Play Feature Graphic
|
|
288
300
|
└── app/
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
301
|
+
├── assets/iphone/
|
|
302
|
+
│ ├── Default*.png ← the 16 launch images the template ships
|
|
303
|
+
│ └── LaunchLogo.png ← 1024×1024, only when logo-launch.* exists
|
|
304
|
+
├── assets/android/
|
|
305
|
+
│ ├── appicon.png ← 128×128
|
|
306
|
+
│ ├── default.png ← Android <12 splash
|
|
307
|
+
│ └── images/res-*/default.png ← the 11 per-qualifier splashes
|
|
308
|
+
└── platform/android/res/
|
|
309
|
+
├── mipmap-mdpi/ ← 108×108 foreground + background + monochrome + legacy
|
|
310
|
+
├── mipmap-hdpi/ ← 162×162
|
|
311
|
+
├── mipmap-xhdpi/ ← 216×216
|
|
312
|
+
├── mipmap-xxhdpi/ ← 324×324
|
|
313
|
+
├── mipmap-xxxhdpi/ ← 432×432
|
|
314
|
+
├── drawable-*/ ← optional splash_icon.png with --splash-icon
|
|
315
|
+
└── mipmap-anydpi-v26/
|
|
316
|
+
└── ic_launcher.xml ← adaptive-icon binder
|
|
300
317
|
```
|
|
301
318
|
|
|
302
319
|
**Classic layout:**
|
|
@@ -304,21 +321,102 @@ The output is automatically routed to the right directory for your project layou
|
|
|
304
321
|
```text
|
|
305
322
|
<project>/
|
|
306
323
|
├── DefaultIcon.png DefaultIcon-ios.png ... ← same root-level files as Alloy
|
|
307
|
-
├── MarketplaceArtworkFeature.png ← 1024×500, Google Play Feature Graphic
|
|
324
|
+
├── MarketplaceArtworkFeature.png ← 1024×500, Google Play Feature Graphic
|
|
308
325
|
├── Resources/
|
|
309
|
-
│
|
|
326
|
+
│ ├── iphone/Default*.png ← the launch images the template ships
|
|
327
|
+
│ └── android/
|
|
328
|
+
│ ├── appicon.png ← 128×128
|
|
329
|
+
│ └── default.png ← Android <12 splash
|
|
310
330
|
└── platform/
|
|
311
331
|
└── android/res/
|
|
312
332
|
├── mipmap-*/ ← same 5 densities as Alloy
|
|
313
|
-
├── drawable-*/ ← optional splash_icon.png
|
|
333
|
+
├── drawable-*/ ← optional splash_icon.png with --splash-icon
|
|
314
334
|
└── mipmap-anydpi-v26/ic_launcher.xml
|
|
315
335
|
```
|
|
316
336
|
|
|
337
|
+
A Classic project has no `images/res-*` folders, so the per-qualifier splashes are simply skipped there.
|
|
338
|
+
|
|
317
339
|
The Android outputs are related, but they are not interchangeable:
|
|
318
340
|
|
|
319
|
-
- `ic_launcher*` drives the app icon, and by default also feeds the Android 12+ system splash
|
|
320
|
-
- `splash_icon.png` is only generated when you ask for it with `--splash`
|
|
321
|
-
- `default.png`
|
|
341
|
+
- `ic_launcher*` drives the app icon, and by default it also feeds the Android 12+ system splash
|
|
342
|
+
- `splash_icon.png` is only generated when you ask for it with `--splash-icon`
|
|
343
|
+
- `default.png` and `images/res-*/default.png` are the Android <12 splash path
|
|
344
|
+
- `appicon.png` is the fallback Titanium uses for `tiapp.xml`'s `<icon>` when the manifest declares no `android:icon`
|
|
345
|
+
|
|
346
|
+
### Why files that "no longer matter" are regenerated
|
|
347
|
+
|
|
348
|
+
Several of these are read by nothing in a modern build. With `<enable-launch-screen-storyboard>` enabled — the default since Titanium 8 — iOS draws the storyboard and never opens the 16 `Default*.png`. `appicon.png` only comes into play when the Android manifest declares no `android:icon`.
|
|
349
|
+
|
|
350
|
+
They are regenerated anyway, because the alternative is worse: the template ships them with the grey Alloy logo, and deciding which ones to skip would mean asking you to keep track of which Titanium and OS version reads which file. If it is in the project tree, it carries your logo.
|
|
351
|
+
|
|
352
|
+
To skip the ones you know you don't need, use [`--only`](#regenerating-a-single-piece-with---only). To delete them outright, see [Cleanup legacy branding artifacts](#cleanup-legacy-branding-artifacts).
|
|
353
|
+
|
|
354
|
+
## Shrinking the generated files
|
|
355
|
+
|
|
356
|
+
`brand` writes truecolor PNGs. Logos are flat artwork with few distinct colors, which is exactly the case where a 256-color palette is indistinguishable from truecolor at a fraction of the size — the same trick TinyPNG and pngquant use.
|
|
357
|
+
|
|
358
|
+
It is off by default because it is lossy. Turn it on per run or for the project:
|
|
359
|
+
|
|
360
|
+
```bash
|
|
361
|
+
purgetss brand --optimize
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
```javascript
|
|
365
|
+
brand: {
|
|
366
|
+
optimize: true
|
|
367
|
+
}
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
`--no-optimize` skips the pass on a single run even when the config asks for it.
|
|
371
|
+
|
|
372
|
+
On the reference project, the full set of 56 PNGs goes from **1.6 MB to 476 KB, 71% smaller**. Measured on the visible pixels of the generated icons, the difference against the truecolor version averages 0.08–0.19 out of 255, with no channel exceeding 16/255: indistinguishable in practice on flat artwork. Transparency survives too — `DefaultIcon-Dark.png` keeps its alpha channel and the same 67% transparent pixels.
|
|
373
|
+
|
|
374
|
+
### What "lossy" means here, in numbers
|
|
375
|
+
|
|
376
|
+
The loss is real: the generated icons carry between 950 and 4,300 distinct visible colors, not because the logo has that many, but because every curved edge and every letter of small text produces hundreds of intermediate tones through antialiasing. Quantization reduces all of that to at most 256.
|
|
377
|
+
|
|
378
|
+
Those intermediate tones are gradations between two or three base colors, which is exactly what a palette approximates well, and Sharp dithers the result. Measured on the visible pixels:
|
|
379
|
+
|
|
380
|
+
| Source | Colors | Average difference | Channels over 16/255 |
|
|
381
|
+
| --- | --- | --- | --- |
|
|
382
|
+
| Flat logo (the usual case) | 950–4,300 | 0.08–0.19 / 255 | 0% |
|
|
383
|
+
| Three-stop gradient (stress test) | 1,215 | 0.74 / 255 | 0.01% |
|
|
384
|
+
|
|
385
|
+
Even a full-circle gradient does not band measurably. Still, quantization is lossy by definition, so if your mark leans on wide, smooth gradients, compare a generated file before turning it on for the whole project. A file is only ever rewritten when the palette version comes out smaller.
|
|
386
|
+
|
|
387
|
+
> **WARNING**
|
|
388
|
+
>
|
|
389
|
+
> This is tuned for logo artwork. It is not meant for photographic sources.
|
|
390
|
+
|
|
391
|
+
For context on what the platforms already do: iOS re-encodes every PNG in the bundle with `pngcrush -iphone` when it packages the app, but that is **lossless**, so this saving is not something the SDK would have done for you. On Android, nothing in Titanium touches these files.
|
|
392
|
+
|
|
393
|
+
## Regenerating a single piece with `--only`
|
|
394
|
+
|
|
395
|
+
A full run rewrites every branding file. That is what you want the first time, and it is exactly what you don't want when only one piece changed and the others were tweaked by hand.
|
|
396
|
+
|
|
397
|
+
`--only` takes a comma-separated list of pieces, groups, or both:
|
|
398
|
+
|
|
399
|
+
```bash
|
|
400
|
+
purgetss brand # everything
|
|
401
|
+
purgetss brand --only icon # just the DefaultIcon pair
|
|
402
|
+
purgetss brand --only ios # icon, dark, tinted, ios-splash
|
|
403
|
+
purgetss brand --only ios,notification-icon
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
Groups are shorthand for the obvious sets:
|
|
407
|
+
|
|
408
|
+
| Group | Expands to |
|
|
409
|
+
| --- | --- |
|
|
410
|
+
| `ios` | `icon`, `dark`, `tinted`, `ios-splash` |
|
|
411
|
+
| `store` | `marketplace`, `feature-graphic` |
|
|
412
|
+
| `android` | `adaptive`, `legacy-icon`, `appicon`, `android-splash` |
|
|
413
|
+
|
|
414
|
+
Details worth knowing:
|
|
415
|
+
|
|
416
|
+
- Naming a piece generates it **even when its opt-in flag is absent**: `--only notification-icon` is enough on its own.
|
|
417
|
+
- A name that doesn't exist aborts the run before anything is written, printing the valid pieces and groups.
|
|
418
|
+
- `--dry-run` honors the same filter, so you can check the plan first.
|
|
419
|
+
- The order you type doesn't matter; generation always follows the pipeline order.
|
|
322
420
|
|
|
323
421
|
## Android dark mode
|
|
324
422
|
|
|
@@ -340,49 +438,80 @@ The monochrome layer is pure white (`RGB 255,255,255`) with alpha preserved. And
|
|
|
340
438
|
|
|
341
439
|
## Android 12+ splash artwork
|
|
342
440
|
|
|
343
|
-
If you pass `--splash`, PurgeTSS generates `drawable-*/splash_icon.png` across Android densities.
|
|
441
|
+
If you pass `--splash-icon`, PurgeTSS generates `drawable-*/splash_icon.png` across Android densities.
|
|
344
442
|
|
|
345
443
|
```bash
|
|
346
|
-
purgetss brand --splash
|
|
444
|
+
purgetss brand --splash-icon
|
|
347
445
|
```
|
|
348
446
|
|
|
349
|
-
If you want that artwork to differ from the launcher icon, provide `logo-splash.svg` or set `brand.
|
|
447
|
+
If you want that artwork to differ from the launcher icon, provide `logo-splash-icon.svg` or set `brand.splashIcon.logo`:
|
|
350
448
|
|
|
351
449
|
```javascript
|
|
352
450
|
brand: {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
logos: {
|
|
357
|
-
androidSplash: './docs/snap-splash-mark.svg'
|
|
451
|
+
splashIcon: {
|
|
452
|
+
enabled: true,
|
|
453
|
+
logo: './docs/snap-splash-mark.svg'
|
|
358
454
|
}
|
|
359
455
|
}
|
|
360
456
|
```
|
|
361
457
|
|
|
362
458
|
> **INFO**
|
|
363
459
|
>
|
|
364
|
-
> Generating `splash_icon.png` does not automatically switch Titanium to use it for the Android 12+ system splash. Titanium still needs a custom splash theme that points `android:windowSplashScreenAnimatedIcon` to `@drawable/splash_icon`. If you do nothing, Android keeps using `ic_launcher`.
|
|
460
|
+
> Generating `splash_icon.png` does not automatically switch Titanium to use it for the Android 12+ system splash. Titanium still needs a custom splash theme that points `android:windowSplashScreenAnimatedIcon` to `@drawable/splash_icon`. If you do nothing, Android keeps using `ic_launcher`. That inertness is exactly why the piece is opt-in.
|
|
461
|
+
|
|
462
|
+
Keep the theme already assigned to `<application>`. Define a launcher-only theme that inherits from `Theme.Titanium`, then assign it to Titanium's generated launcher Activity. The complete setup is in [Matching the launch background](#matching-the-launch-background).
|
|
365
463
|
|
|
366
464
|
> **WARNING**
|
|
367
465
|
>
|
|
368
|
-
>
|
|
369
|
-
>
|
|
466
|
+
> Android masks this icon into a circle
|
|
467
|
+
> The Android 12+ splash icon is drawn inside a circular mask. A wide wordmark that fills the canvas loses its corners. Use a square mark for `logo-splash-icon`, the same advice that applies to launcher icons.
|
|
370
468
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
469
|
+
Also, if you still see a brief flash during splash exit even with correct assets, do not assume the PNGs are wrong. That artifact can come from Titanium's splash theme or the system splash transition itself.
|
|
470
|
+
|
|
471
|
+
## Android pre-12 splash
|
|
472
|
+
|
|
473
|
+
Below Android 12 there is no system splash: the launch screen comes from the image Titanium maps into `drawable-*/background.png`, and that image comes from the project's own splash artwork.
|
|
375
474
|
|
|
376
|
-
|
|
475
|
+
`brand` regenerates the whole set on every run. It is the `android-splash` piece, on by default:
|
|
377
476
|
|
|
378
|
-
|
|
477
|
+
- `app/assets/android/default.png` (`Resources/android/default.png` in Classic)
|
|
478
|
+
- `app/assets/android/images/res-*/default.png` — the 11 per-qualifier images the Alloy template ships
|
|
379
479
|
|
|
380
|
-
|
|
480
|
+
Earlier versions regenerated only the first file and hid the other 11 behind a `--legacy-splash` flag, which is why a freshly branded project could still flash the grey Alloy logo on an older phone. That flag is gone: its output is part of `android-splash` and always generated.
|
|
381
481
|
|
|
382
482
|
> **INFO**
|
|
383
483
|
>
|
|
384
|
-
>
|
|
385
|
-
>
|
|
484
|
+
> A solid `windowBackground` wins
|
|
485
|
+
> If the launch theme sets `android:windowBackground` to a plain color — which is what [Matching the launch background](#matching-the-launch-background) recommends — that color takes precedence over this artwork on Android <12. Drop the `windowBackground` item if you want the image to show instead.
|
|
486
|
+
|
|
487
|
+
## The iOS launch screen and LaunchLogo.png
|
|
488
|
+
|
|
489
|
+
Titanium builds `LaunchLogo.imageset` itself on every iOS build, resizing one source into the five sizes it needs. It looks for `LaunchLogo.png` first and falls back to `DefaultIcon.png`.
|
|
490
|
+
|
|
491
|
+
So there is nothing for PurgeTSS to generate there, but there is something to choose. With only `DefaultIcon.png` around, the launch screen shows your app icon, safe-zone padding and all. Dropping a `logo-launch.svg` (or `.png`) into `purgetss/brand/` makes `brand` write a `LaunchLogo.png`, and the launch screen shows the full logotype instead:
|
|
492
|
+
|
|
493
|
+
```bash
|
|
494
|
+
cp docs/my-wordmark.svg purgetss/brand/logo-launch.svg
|
|
495
|
+
purgetss brand
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
The file is written at exactly **1024×1024**. That is not a style choice: the SDK validates the size and discards the file with a warning when it does not match.
|
|
499
|
+
|
|
500
|
+
The piece activates by convention (the presence of `logo-launch.*`) rather than through a flag, because `--<piece>-logo` already means "the source for this piece" everywhere else in the command. To generate it from a path without adding the file:
|
|
501
|
+
|
|
502
|
+
```bash
|
|
503
|
+
purgetss brand --launch-logo docs/my-wordmark.svg
|
|
504
|
+
purgetss brand --only launch-logo
|
|
505
|
+
purgetss brand --launch-logo-padding 18 # more breathing room around the logotype
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
The output keeps its alpha, so the storyboard's `<default-background-color>` shows through.
|
|
509
|
+
|
|
510
|
+
## iPhone launch images
|
|
511
|
+
|
|
512
|
+
The Alloy and Classic templates ship 16 `Default*.png` launch images under `assets/iphone/`, from the 320×480 original iPhone size up to 2688×1242. `brand` regenerates all of them, scaling the logo against the **shorter side** of each canvas so portrait and landscape carry the same visual weight.
|
|
513
|
+
|
|
514
|
+
With `<enable-launch-screen-storyboard>` enabled (the default), iOS never reads these files. They are regenerated because they are in your project, they ship with the Alloy logo, and no one should have to audit their `tiapp.xml` to know whether that matters. If you are sure your project doesn't need them, [`--cleanup-legacy`](#cleanup-legacy-branding-artifacts) deletes them instead.
|
|
386
515
|
|
|
387
516
|
## iOS 18+ Dark and Tinted variants
|
|
388
517
|
|
|
@@ -410,99 +539,109 @@ purgetss brand --no-dark --no-tinted
|
|
|
410
539
|
>
|
|
411
540
|
> Until that PR lands, after your first iOS build you may need to add the two PNGs manually into `build/iphone/Assets.xcassets/AppIcon.appiconset/` in Xcode (via the "Appearance" column in the asset catalog editor). Once #14122 merges, the command becomes fully end-to-end.
|
|
412
541
|
|
|
413
|
-
##
|
|
414
|
-
|
|
415
|
-
Since v7.10.0, `purgetss brand` also generates `MarketplaceArtworkFeature.png` — the **1024×500** banner that Google Play shows above the app description on the Play Store listing. It's submission artwork only: the file is written to the project root for upload via Play Console; it is **not** bundled into the APK.
|
|
416
|
-
|
|
417
|
-
### How the source is chosen
|
|
542
|
+
## Brand color
|
|
418
543
|
|
|
419
|
-
|
|
544
|
+
The `--bg-color` flag (or `brand.background` in config) controls the background across the generated branding assets:
|
|
420
545
|
|
|
421
|
-
1.
|
|
422
|
-
2. `
|
|
423
|
-
3.
|
|
424
|
-
4.
|
|
546
|
+
1. The **Android adaptive background layer**: a solid color that fills the full 108dp canvas behind your logo.
|
|
547
|
+
2. The **iOS alpha flatten** for `DefaultIcon-ios.png`. Apple rejects transparent App Store icons, so the logo is flattened on this color.
|
|
548
|
+
3. The **marketplace flatten** for `iTunesConnect.png`, `MarketplaceArtwork.png`, and `MarketplaceArtworkFeature.png`.
|
|
549
|
+
4. **Every splash canvas**: `default.png`, the 11 `res-*/default.png`, and the 16 iPhone launch images.
|
|
550
|
+
5. `appicon.png`.
|
|
425
551
|
|
|
426
552
|
```bash
|
|
427
|
-
purgetss brand --
|
|
553
|
+
purgetss brand --bg-color "#0B1326"
|
|
428
554
|
```
|
|
429
555
|
|
|
430
|
-
|
|
556
|
+
Any piece can opt out with its own `background`. That is what `dark: { background: null }` does in the default config, which keeps `DefaultIcon-Dark.png` transparent per Apple HIG.
|
|
431
557
|
|
|
432
|
-
|
|
558
|
+
If you never pass the flag, background stays `#FFFFFF`. `iTunesConnect.png` and `MarketplaceArtwork.png` keep their alpha channel to match Titanium's default; `MarketplaceArtworkFeature.png` is always flattened for Google Play.
|
|
433
559
|
|
|
434
|
-
|
|
560
|
+
### Matching the launch background
|
|
435
561
|
|
|
436
|
-
|
|
437
|
-
purgetss brand --feature-graphic-padding 8
|
|
438
|
-
```
|
|
562
|
+
`brand.background` bakes into the generated image pixels. It does **not** edit `tiapp.xml` or an Android theme. Carrying the same color into the native launch surfaces takes an iOS `<default-background-color>` entry plus a launcher-only Android theme — the complete, copy-ready setup is in [Matching the Launch Background](./launch-background.md).
|
|
439
563
|
|
|
440
|
-
|
|
441
|
-
brand: {
|
|
442
|
-
padding: {
|
|
443
|
-
featureGraphic: '8%'
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
```
|
|
564
|
+
`purgetss brand --notes` prints that setup with the project's current `brand.background` already filled in.
|
|
447
565
|
|
|
448
|
-
The logo is rendered as a square block of side `500 - 2 × pad` and centered horizontally on the 1024-wide canvas. Lower the padding for a more impactful banner; raise it if the logo looks cramped against the top or bottom edge on smaller Play Store crops.
|
|
449
566
|
|
|
450
|
-
##
|
|
567
|
+
## Padding guidance
|
|
451
568
|
|
|
452
|
-
|
|
569
|
+
Padding belongs to the piece, not to the project. Each piece has its own key and its own flag:
|
|
453
570
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
571
|
+
| Piece | Config | Flag | Default |
|
|
572
|
+
| --- | --- | --- | --- |
|
|
573
|
+
| `adaptive` | `brand.adaptive.padding` | `--android-adaptive-padding` | `18%` |
|
|
574
|
+
| `legacy-icon` | `brand.legacyIcon.padding` | `--android-legacy-padding` | `10%` |
|
|
575
|
+
| `icon` | `brand.icon.padding` | `--ios-padding` | `4%` |
|
|
576
|
+
| `feature-graphic` | `brand.featureGraphic.padding` | `--feature-graphic-padding` | `12%` |
|
|
577
|
+
| `launch-logo` | `brand.launchLogo.padding` | `--launch-logo-padding` | `12%` |
|
|
578
|
+
| `android-splash` | `brand.androidSplash.padding` | `--android-splash-padding` | `26%` |
|
|
579
|
+
| `ios-splash` | `brand.iosSplash.padding` | `--ios-splash-padding` | `26%` |
|
|
457
580
|
|
|
458
|
-
|
|
459
|
-
|
|
581
|
+
`--padding` is a shortcut for the two Android launcher paddings in a single run, and `--splash-padding` for the two splash paddings. `--ios-padding` moves the four square iOS/marketplace pieces together (`icon`, `dark`, `tinted`, `marketplace`); in config each of them has its own key.
|
|
582
|
+
|
|
583
|
+
There is deliberately **no global padding value that cascades down**. The defaults answer to different constraints: `18%` answers to the Android launcher mask, while `4%` is an aesthetic choice for a canvas with no mask behind it. One inherited number would let a reasonable-looking `8%` silently break the launcher mask. `background`, which has no such trap, is inherited from `brand.background`.
|
|
584
|
+
|
|
585
|
+
### How the source is read, and how sharp the output is
|
|
586
|
+
|
|
587
|
+
Two things are worth knowing about what happens to your `logo.svg` or `logo.png` before any padding is applied.
|
|
588
|
+
|
|
589
|
+
**The container is what counts, not the artwork's bounding box.** An SVG is read at its `viewBox`, a raster at its full canvas, and neither is trimmed to where the pixels actually are. So whatever margin a designer baked into the file **adds** to the padding configured per piece. A round logo exported inside a 2048×2048 PNG with 25% of its own air, generated at `adaptive: { padding: '18%' }`, ends up covering about 32% of the icon canvas, not 64%. If a mark comes out smaller than the numbers suggest, that is almost always why: crop the source or lower the padding.
|
|
590
|
+
|
|
591
|
+
**The masters are sized to the run.** The source is rasterized once into two intermediate masters, and every piece scales down from them, so their resolution is the ceiling on output sharpness. Rather than a fixed size, `brand` measures the largest number of pixels any selected piece will ask for and builds the masters at exactly that. A default run reports it:
|
|
592
|
+
|
|
593
|
+
```text
|
|
594
|
+
• Masters at 942 px — the largest any selected piece asks for
|
|
460
595
|
```
|
|
461
596
|
|
|
462
|
-
|
|
597
|
+
Lower a padding and the figure rises with it (`--splash-padding 4` needs 1413 px), so output never goes soft against a fixed ceiling. Every destination is a reduction, never an upscale.
|
|
463
598
|
|
|
464
|
-
|
|
599
|
+
The one case this cannot fix is a raster source that is simply too small: a 512-px PNG cannot produce a sharp 942-px icon. Prefer SVG, or a PNG of at least 1024×1024.
|
|
465
600
|
|
|
466
|
-
|
|
601
|
+
### Splash padding
|
|
467
602
|
|
|
468
|
-
|
|
469
|
-
- `brand.padding.androidLegacy` or `--android-legacy-padding` for `ic_launcher.png`
|
|
470
|
-
- `--padding` is a one-shot **shortcut** that sets both Android paddings to the same value for one run
|
|
603
|
+
The 28 splash images (`default.png`, the 11 `res-*`, and the 16 iPhone launch images) share one rule: the logo is fitted into a square whose side is a share of the canvas's **shorter** side.
|
|
471
604
|
|
|
472
|
-
|
|
605
|
+
Measuring against the shorter side is what lets a single number work across canvases as different as 1440×2560 and 800×480: at 800×480 the limit comes from the height, at 240×400 from the width, and the logo keeps the same visual weight in portrait and in landscape.
|
|
473
606
|
|
|
474
|
-
|
|
607
|
+
| `androidSplash.padding` / `iosSplash.padding` | Logo | `default.png` (1440×2560) | `res-notlong-port-mdpi` (320×480) |
|
|
608
|
+
| --- | --- | --- | --- |
|
|
609
|
+
| `20%` | 60% of the shorter side | 864 px | 192 px |
|
|
610
|
+
| `26%` (default) | 48% | 691 px | 153 px |
|
|
611
|
+
| `30%` | 40% | 576 px | 128 px |
|
|
612
|
+
| `35%` | 30% | 432 px | 96 px |
|
|
475
613
|
|
|
476
|
-
|
|
477
|
-
| ------- | --------- | ------------------------------------------------------------------------------------------------------ |
|
|
478
|
-
| `15%` | 70% | Aggressive. Better for square symbols with lots of built-in breathing room. |
|
|
479
|
-
| `18%` | 64% | Defensive: for intricate logos, fine serifs, multi-element designs. |
|
|
480
|
-
| `19%` | 62% | **Default**. Close to the Android safe-zone and safer for adaptive masks. |
|
|
481
|
-
| `20%` | 60% | Conservative, spec-compliant. Safe on every launcher, including aggressive masks. |
|
|
614
|
+
The `26%` default is calibrated against the Titanium template itself: the Alloy logo in the stock `default.png` measures 665×488 px on a 1440×2560 canvas, so `26%` lands within 4% of the size Titanium ships.
|
|
482
615
|
|
|
483
|
-
|
|
616
|
+
Before v7.13.0 none of this was configurable: `default.png` used a hardcoded box of 72% × 26% of its own canvas, and the `res-*` set a separate hardcoded 60%. Two rules for the same piece, neither adjustable.
|
|
484
617
|
|
|
485
|
-
|
|
618
|
+
### Adaptive icon padding
|
|
486
619
|
|
|
487
|
-
|
|
620
|
+
Android's adaptive canvas is 108 dp. The mask leaves roughly 72 dp visible, and the **guaranteed** safe area is a 66 dp circle inscribed in it. What each padding means in those terms:
|
|
621
|
+
|
|
622
|
+
| Padding | Logo | vs. the 66 dp safe circle | vs. the ~72 dp the mask shows |
|
|
623
|
+
| --- | --- | --- | --- |
|
|
624
|
+
| `15%` | 75.6 dp | outside | **outside** — clipped on any launcher |
|
|
625
|
+
| `16%` | 73.4 dp | outside | **outside** |
|
|
626
|
+
| `18%` | 69.1 dp | corners outside | inside — **the default** |
|
|
627
|
+
| `19.44%` | 66.0 dp | exactly on it | inside |
|
|
628
|
+
| `20%` | 64.8 dp | inside | inside — most conservative |
|
|
488
629
|
|
|
489
|
-
|
|
630
|
+
`18%` sits between the guaranteed circle and the mask edge: a logo that carries its own margin never reaches those corners, which is why it is a safe default in practice. Drop to `20%` if your mark runs edge to edge and you see clipping on a circular launcher.
|
|
490
631
|
|
|
491
|
-
|
|
632
|
+
A useful visual check is the "corners" heuristic: imagine a circle inscribed in your 1024×1024 canvas with the given padding. If your logo's outermost corners fit inside that circle, you're safe on circular launchers (Pixel default, Oppo Android 15). If they poke out, they'll be clipped.
|
|
492
633
|
|
|
493
|
-
|
|
634
|
+
The official Android spec floor is `19.44%` (108dp canvas, 66dp inscribed safe-zone circle). That is the theoretical worst-case for aggressive adaptive masks, which is why the adaptive default sits close to it.
|
|
494
635
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
| `4%` | **Default**. Balanced aesthetic. |
|
|
499
|
-
| `8%` | Conservative, generous whitespace around the mark. |
|
|
636
|
+
### Legacy icon padding
|
|
637
|
+
|
|
638
|
+
Legacy `ic_launcher.png` does not go through the same adaptive mask, so it can usually run tighter. That is why the default for `brand.legacyIcon.padding` is `10%`.
|
|
500
639
|
|
|
501
640
|
## Cleanup legacy branding artifacts
|
|
502
641
|
|
|
503
|
-
Projects that predate Android adaptive icons (API 26+) or modern iOS launch storyboards often accumulate obsolete assets: `res-long-*/res-notlong-*` qualifiers dead since Android 3.0, legacy `Default-*.png` launch images ignored when the storyboard is enabled, pre-adaptive `appicon.png`, and
|
|
642
|
+
Projects that predate Android adaptive icons (API 26+) or modern iOS launch storyboards often accumulate obsolete assets: `res-long-*/res-notlong-*` qualifiers dead since Android 3.0, legacy `Default-*.png` launch images ignored when the storyboard is enabled, pre-adaptive `appicon.png`, and similar files.
|
|
504
643
|
|
|
505
|
-
The `--cleanup-legacy` flag removes them with context-aware safety rules: it reads `tiapp.xml` to decide what
|
|
644
|
+
The `--cleanup-legacy` flag removes them with context-aware safety rules: it reads `tiapp.xml` to decide what is actually safe to delete for your project. Always preview first:
|
|
506
645
|
|
|
507
646
|
```bash
|
|
508
647
|
purgetss brand --cleanup-legacy --dry-run
|
|
@@ -525,15 +664,23 @@ purgetss brand --cleanup-legacy --aggressive
|
|
|
525
664
|
> Commit first
|
|
526
665
|
> `--cleanup-legacy` deletes files permanently. Commit your project to git before running without `--dry-run` so `git restore` is available as a rollback.
|
|
527
666
|
|
|
667
|
+
Files kept on purpose:
|
|
668
|
+
|
|
669
|
+
- `app/assets/android/default.png` in Alloy projects
|
|
670
|
+
- `Resources/android/default.png` in Classic projects
|
|
671
|
+
|
|
672
|
+
Those files are still valid Android <12 splash artwork.
|
|
673
|
+
|
|
528
674
|
> **INFO**
|
|
529
675
|
>
|
|
530
|
-
>
|
|
531
|
-
> `--cleanup-legacy`
|
|
676
|
+
> `--cleanup-legacy` never deletes what the same run just generated
|
|
677
|
+
> Three cleanup rules target files `brand` now regenerates by default: the `res-long-*`/`res-notlong-*` folders (`android-splash`), the iPhone `Default*.png` images (`ios-splash`) and `appicon.png` (`appicon`). When `--cleanup-legacy` runs as part of a generating pass, those paths are skipped and the run reports how many it spared:
|
|
532
678
|
>
|
|
533
|
-
>
|
|
534
|
-
>
|
|
679
|
+
> ```text
|
|
680
|
+
> Keeping 28 path(s) this run just regenerated with your artwork.
|
|
681
|
+
> ```
|
|
535
682
|
>
|
|
536
|
-
>
|
|
683
|
+
> To actually delete them, exclude the piece that writes them. For example, `purgetss brand --only android --cleanup-legacy` regenerates the Android icons while letting cleanup remove the iPhone launch images.
|
|
537
684
|
|
|
538
685
|
## Troubleshooting
|
|
539
686
|
|
|
@@ -549,9 +696,7 @@ Or set it in the config:
|
|
|
549
696
|
|
|
550
697
|
```javascript
|
|
551
698
|
brand: {
|
|
552
|
-
padding:
|
|
553
|
-
androidAdaptive: '20%'
|
|
554
|
-
}
|
|
699
|
+
adaptive: { padding: '20%' }
|
|
555
700
|
}
|
|
556
701
|
```
|
|
557
702
|
|
|
@@ -565,7 +710,7 @@ purgetss brand --android-adaptive-padding 17
|
|
|
565
710
|
|
|
566
711
|
### The monochrome version looks like a white blob
|
|
567
712
|
|
|
568
|
-
Your colored logo likely has multi-color detail that
|
|
713
|
+
Your colored logo likely has multi-color detail that does not survive automatic whitening. Provide a dedicated silhouette:
|
|
569
714
|
|
|
570
715
|
```bash
|
|
571
716
|
cp docs/my-logo-mono.svg purgetss/brand/logo-mono.svg
|
|
@@ -574,7 +719,7 @@ purgetss brand
|
|
|
574
719
|
|
|
575
720
|
### iOS rejects the app icon upload ("contains transparency")
|
|
576
721
|
|
|
577
|
-
|
|
722
|
+
Apple requires App Store icons to have no alpha channel. `DefaultIcon-ios.png` is always flattened on `brand.background` for that reason. If you edited the file manually and reintroduced alpha, re-run `purgetss brand`.
|
|
578
723
|
|
|
579
724
|
### The dark variant doesn't show on my iPhone
|
|
580
725
|
|
|
@@ -582,101 +727,39 @@ Dark variants require iOS 18+ and Titanium SDK automatic wiring (tracked upstrea
|
|
|
582
727
|
|
|
583
728
|
### I get "Input image exceeds pixel limit" on an SVG from Affinity / Illustrator
|
|
584
729
|
|
|
585
|
-
Affinity Designer and Adobe Illustrator often bake transforms into the exported SVG's `viewBox`, so the intrinsic dimensions end up at something
|
|
730
|
+
Affinity Designer and Adobe Illustrator often bake transforms into the exported SVG's `viewBox`, so the intrinsic dimensions can end up at something like `29559×13542 pt`. Rasterized at 1× density, that exceeds Sharp's pixel limit and the command crashes.
|
|
586
731
|
|
|
587
732
|
PurgeTSS checks the `viewBox` on every SVG. When either side is over `4096 pt`, it prints a warning with the actual dimensions and switches to an adaptive density that caps the output pixel count regardless of input size. The warning tells you the source is oversized; the command still finishes.
|
|
588
733
|
|
|
589
734
|
If you want to clean up the source, re-export from the vector editor with a canvas-sized viewBox (`0 0 1024 1024`, for example). The rasterized output is identical either way, but a normalized viewBox keeps the SVG portable for other tools.
|
|
590
735
|
|
|
736
|
+
### A key in `brand:` aborts the run
|
|
737
|
+
|
|
738
|
+
`brand` rejects unknown keys instead of ignoring them. Check the spelling against the piece table above — see [Unknown keys are an error](#unknown-keys-are-an-error).
|
|
739
|
+
|
|
591
740
|
### I changed my bg color — do I need to regenerate the Android densities too?
|
|
592
741
|
|
|
593
|
-
Yes. `
|
|
742
|
+
Yes. `brand.background` bakes into every Android background layer, every splash canvas, and the iOS flatten. Re-run:
|
|
594
743
|
|
|
595
744
|
```bash
|
|
596
745
|
purgetss brand --bg-color "#NEW_COLOR"
|
|
597
746
|
```
|
|
598
747
|
|
|
599
|
-
All 5 Android densities, marketplace artwork, and iOS variants regenerate in one pass.
|
|
600
|
-
|
|
601
|
-
## Full flag reference
|
|
602
|
-
|
|
603
|
-
**Project & output**
|
|
604
|
-
|
|
605
|
-
| Flag | Purpose |
|
|
606
|
-
| --- | --- |
|
|
607
|
-
| `--project <path>` | Project root (defaults to cwd). |
|
|
608
|
-
| `--dry-run` | Preview what would be generated without writing any files. |
|
|
609
|
-
| `--output <dir>` | Stage into `<dir>` instead of writing in place. |
|
|
610
|
-
| `-y`, `--yes` | Skip the overwrite confirmation prompt for this invocation. |
|
|
611
|
-
|
|
612
|
-
**Visual customization**
|
|
613
|
-
|
|
614
|
-
| Flag | Purpose |
|
|
615
|
-
| --- | --- |
|
|
616
|
-
| `--bg-color <hex>` | Background color for Android adaptive + iOS/marketplace flatten. |
|
|
617
|
-
| `--padding <n>` | Shortcut: sets BOTH Android paddings to the same value for one run. Fixed in v7.10.0 — previously only fed `androidAdaptivePadding`, leaving `androidLegacyPadding` at its own config value. |
|
|
618
|
-
| `--android-adaptive-padding <n>` | Adaptive icon safe-zone % (default `19`). |
|
|
619
|
-
| `--android-legacy-padding <n>` | Legacy `ic_launcher.png` padding % (default `10`). |
|
|
620
|
-
| `--ios-padding <n>` | iOS aesthetic padding % (range `2–8`, default `4`). |
|
|
621
|
-
| `--feature-graphic-padding <n>` | (v7.10.0) Vertical padding for `MarketplaceArtworkFeature.png` (range `0-40`, default `12`). |
|
|
622
|
-
|
|
623
|
-
**Optional asset types**
|
|
624
|
-
|
|
625
|
-
| Flag | Purpose |
|
|
626
|
-
| --- | --- |
|
|
627
|
-
| `--notification` | Also emit `ic_stat_notify.png × 5`. |
|
|
628
|
-
| `--splash` | Also emit `splash_icon.png × 5`. |
|
|
629
|
-
|
|
630
|
-
**Logo variants & overrides**
|
|
631
|
-
|
|
632
|
-
| Flag | Purpose |
|
|
633
|
-
| --- | --- |
|
|
634
|
-
| `--icon-logo <path>` | Override `purgetss/brand/logo-icon.{svg,png}` for Android launcher icons. |
|
|
635
|
-
| `--monochrome-logo <path>` | Override `purgetss/brand/logo-mono.{svg,png}`. |
|
|
636
|
-
| `--dark-logo <path>` | Override `purgetss/brand/logo-dark.{svg,png}`. |
|
|
637
|
-
| `--dark-bg-color <hex>` | Opaque dark bg for `DefaultIcon-Dark.png` (default: transparent per Apple HIG). |
|
|
638
|
-
| `--splash-logo <path>` | Override `purgetss/brand/logo-splash.{svg,png}` for Android 12+ splash artwork. |
|
|
639
|
-
| `--tinted-logo <path>` | Override `purgetss/brand/logo-tinted.{svg,png}`. |
|
|
640
|
-
| `--feature-logo <path>` | (v7.10.0) Override `purgetss/brand/logo-feature.{svg,png}` for the Google Play Feature Graphic. |
|
|
641
|
-
| `--no-dark` | Skip `DefaultIcon-Dark.png`. |
|
|
642
|
-
| `--no-tinted` | Skip `DefaultIcon-Tinted.png`. |
|
|
643
|
-
|
|
644
|
-
**Legacy cleanup**
|
|
645
|
-
|
|
646
|
-
| Flag | Purpose |
|
|
647
|
-
| --- | --- |
|
|
648
|
-
| `--cleanup-legacy` | Remove obsolete branding artifacts (reads `tiapp.xml` for safety rules). Keeps `default.png` on purpose. |
|
|
649
|
-
| `--aggressive` | With `--cleanup-legacy`, also remove `ldpi` density folders. |
|
|
748
|
+
All 5 Android densities, marketplace artwork, splash canvases, and iOS variants regenerate in one pass.
|
|
650
749
|
|
|
651
|
-
|
|
750
|
+
## Flag reference
|
|
652
751
|
|
|
653
|
-
|
|
654
|
-
| --- | --- |
|
|
655
|
-
| `--notes` | Print full `tiapp.xml` snippets + padding tuning guide. |
|
|
656
|
-
| `--debug` | Print extra diagnostics. |
|
|
657
|
-
|
|
658
|
-
### Examples
|
|
659
|
-
|
|
660
|
-
```bash
|
|
661
|
-
purgetss brand # uses purgetss/brand/logo.svg + config
|
|
662
|
-
purgetss brand --bg-color "#0B1326" # override bg color
|
|
663
|
-
purgetss brand --icon-logo ./docs/app-icon.svg # dedicated square Android launcher mark
|
|
664
|
-
purgetss brand --splash --splash-logo ./docs/splash.svg # custom Android 12+ splash artwork
|
|
665
|
-
purgetss brand --feature-logo ./docs/feature.svg # custom Google Play Feature Graphic (v7.10.0)
|
|
666
|
-
purgetss brand --feature-graphic-padding 8 # tighter Feature Graphic padding (v7.10.0)
|
|
667
|
-
purgetss brand --notification --splash # add notification + splash
|
|
668
|
-
purgetss brand --no-tinted # skip iOS 18+ tinted variant
|
|
669
|
-
purgetss brand --dry-run # preview without writing
|
|
670
|
-
purgetss brand --cleanup-legacy --dry-run # preview legacy cleanup
|
|
671
|
-
```
|
|
752
|
+
Every flag lives in the terse reference: [`brand` command](./cli-commands.md#brand-command) — project & output, `--only`, padding, optional asset types, the `--<piece>-logo` overrides, `--optimize`, appearance, legacy cleanup and diagnostics, with examples.
|
|
672
753
|
|
|
673
754
|
## Community-Discovered Patterns
|
|
674
755
|
|
|
675
|
-
- **
|
|
676
|
-
- **
|
|
677
|
-
- **
|
|
756
|
+
- **Wordmark logos need a separate launcher mark.** When `logo.svg` is a wide wordmark or vertical lockup, it tends to look cramped inside Android launcher masks. Drop a square `logo-adaptive.svg` (or set `brand.adaptive.logo`) and the launcher icons get the dedicated mark while the rest of the brand set still uses the main logo. The same idea applies to the Android 12+ splash with `logo-splash-icon.svg`, which Android additionally masks into a circle. **Note the v7.13.0 rename:** the file that used to do this was `logo-icon.svg`; that name now feeds `DefaultIcon.png` instead.
|
|
757
|
+
- **Verify with `--dry-run` before a real run on a project with hand-tweaked assets.** A full `brand` run rewrites every branding file, so any icon touched by hand outside PurgeTSS is overwritten. Since v7.13.0 the surgical alternative is `--only <piece>`, which honors `--dry-run` too. Before v7.13.0 the only options were a full run or nothing.
|
|
758
|
+
- **The `[y/N/a]` prompt disappears in non-TTY contexts, including the `alloy.jmk` hook.** That is by design, but it means a `brand` invocation wired into the build pipeline silently overwrites without asking. Keep the project committed before wiring `brand` into `alloy.jmk`.
|
|
678
759
|
|
|
679
760
|
## See also
|
|
680
761
|
|
|
681
762
|
- [`brand` command reference](./cli-commands.md#brand-command) — terse flag list.
|
|
682
763
|
- [Multi-Density Images](./multi-density-images.md) — sibling `images` command for UI assets.
|
|
764
|
+
- [Customization Deep Dive](./customization-deep-dive.md) — the full `config.cjs` structure.
|
|
765
|
+
- [Version History](./version-history.md) — what changed in each release.
|