@maccesar/titools 2.8.0 → 2.9.0

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.
Files changed (28) hide show
  1. package/package.json +1 -1
  2. package/skills/purgetss/SKILL.md +25 -0
  3. package/skills/purgetss/references/EXAMPLES.md +86 -24
  4. package/skills/purgetss/references/app-branding.md +412 -0
  5. package/skills/purgetss/references/appearance-module.md +161 -0
  6. package/skills/purgetss/references/apply-directive.md +87 -31
  7. package/skills/purgetss/references/arbitrary-values.md +4 -0
  8. package/skills/purgetss/references/class-categories.md +10 -7
  9. package/skills/purgetss/references/class-index.md +25 -18
  10. package/skills/purgetss/references/cli-commands.md +219 -8
  11. package/skills/purgetss/references/configurable-properties.md +11 -7
  12. package/skills/purgetss/references/custom-rules.md +7 -3
  13. package/skills/purgetss/references/customization-deep-dive.md +52 -4
  14. package/skills/purgetss/references/dynamic-component-creation.md +29 -14
  15. package/skills/purgetss/references/grid-layout.md +20 -8
  16. package/skills/purgetss/references/icon-fonts.md +4 -0
  17. package/skills/purgetss/references/installation-setup.md +3 -8
  18. package/skills/purgetss/references/ios-large-titles.md +141 -0
  19. package/skills/purgetss/references/migration-guide.md +162 -25
  20. package/skills/purgetss/references/multi-density-images.md +363 -0
  21. package/skills/purgetss/references/opacity-modifier.md +4 -0
  22. package/skills/purgetss/references/performance-tips.md +5 -0
  23. package/skills/purgetss/references/platform-modifiers.md +4 -0
  24. package/skills/purgetss/references/semantic-colors.md +386 -0
  25. package/skills/purgetss/references/smart-mappings.md +50 -28
  26. package/skills/purgetss/references/tikit-components.md +3 -1
  27. package/skills/purgetss/references/titanium-resets.md +46 -15
  28. package/skills/purgetss/references/ui-ux-design.md +32 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maccesar/titools",
3
- "version": "2.8.0",
3
+ "version": "2.9.0",
4
4
  "description": "Titanium SDK skills and agents for AI coding assistants (Claude Code, Gemini CLI, Codex CLI)",
5
5
  "main": "lib/index.js",
6
6
  "type": "module",
@@ -112,6 +112,20 @@ purgetss create 'MyApp' -d -v fa
112
112
  # -v: Copy icon fonts (fa, mi, ms, f7)
113
113
  ```
114
114
 
115
+ ## What's New in v7.6.0
116
+
117
+ - `brand` command — complete Titanium branding set (launcher icons, adaptive, iOS 18+ Dark/Tinted, marketplace) from logos in `./purgetss/brand/`
118
+ - `images` command — multi-density UI images (Android res-*dpi + iPhone @1x/@2x/@3x) from `./purgetss/images/`
119
+ - `semantic` command — Titanium semantic colors for Light/Dark mode (palette mode + single mode)
120
+ - `brand:` and `images:` config sections auto-injected into older configs
121
+ - Percentages as strings (`'15%'`) for self-documenting clarity in brand/images configs
122
+
123
+ ## What's New in v7.5.3
124
+
125
+ - Appearance module — Light/Dark/System mode switching with persistence
126
+ - Default font family classes (`font-sans`, `font-serif`, `font-mono`) generated automatically with platform-appropriate values
127
+ - XML validation — detects illegal `--` inside XML comments during pre-validation
128
+
115
129
  ## What's New in v7.5.0
116
130
 
117
131
  - `extend` support for Window, View, and ImageView in `config.cjs`
@@ -380,6 +394,8 @@ purgetss create 'MyApp' -d -v fa
380
394
  > - **[Class Index](references/class-index.md)** - Naming conventions, 416-property table, prohibited classes, verification commands (LOAD FIRST when unsure about a class)
381
395
  > - **[Class Categories](references/class-categories.md)** - Complete prefix inventory by category (layout, colors, typography, states, etc.)
382
396
  > - **[Dynamic Component Creation](references/dynamic-component-creation.md)** - `$.UI.create()` and `Alloy.createStyle()` for creating components in Controllers (READ FIRST for dynamic components)
397
+ > - **[Appearance Module](references/appearance-module.md)** - Light/Dark/System mode switching with persistence (v7.5.3)
398
+ > - **[Semantic Colors](references/semantic-colors.md)** - Titanium semantic colors for Light/Dark mode via `semantic` command (v7.6.0)
383
399
  >
384
400
  > ### Setup & Configuration
385
401
  > - [Installation & Setup](references/installation-setup.md) - First run, VS Code, LiveView
@@ -392,6 +408,10 @@ purgetss create 'MyApp' -d -v fa
392
408
  > - [Apply Directive](references/apply-directive.md) - Extracting utility combinations
393
409
  > - [Configurable Properties](references/configurable-properties.md) - All 80+ customizable properties
394
410
  >
411
+ > ### Appearance & Theming
412
+ > - **[Appearance Module](references/appearance-module.md)** - Light/Dark/System mode switching with persistence (v7.5.3)
413
+ > - **[Semantic Colors](references/semantic-colors.md)** - `semantic` command + runtime usage for Light/Dark mode (v7.6.0)
414
+ >
395
415
  > ### Layout & Styling
396
416
  > - **[UI/UX Design Patterns](references/ui-ux-design.md)** - Complete guide to mobile UI components with PurgeTSS (cards, lists, forms, buttons, navigation, modals, accessibility)
397
417
  > - [Grid Layout System](references/grid-layout.md) - 12-column grid, responsive layouts
@@ -400,6 +420,11 @@ purgetss create 'MyApp' -d -v fa
400
420
  > - [Platform Modifiers](references/platform-modifiers.md) - ios:, android:, tablet:, handheld:
401
421
  > - [Opacity Modifier](references/opacity-modifier.md) - Color transparency with /50 syntax
402
422
  > - [Titanium Resets](references/titanium-resets.md) - Default styles for Ti elements
423
+ > - [iOS Large Titles](references/ios-large-titles.md) - Best practice for iOS Large Title navigation
424
+ >
425
+ > ### App Assets
426
+ > - [App Branding](references/app-branding.md) - `brand` command for launcher icons, adaptive, iOS 18+ Dark/Tinted, marketplace assets (v7.6.0)
427
+ > - [Multi-Density Images](references/multi-density-images.md) - `images` command for Android res-*dpi + iPhone @1x/@2x/@3x UI images (v7.6.0)
403
428
  >
404
429
  > ### Performance
405
430
  > - [Performance Tips](references/performance-tips.md) - Optimizing PurgeTSS apps (bridge crossings, ListView, animations)
@@ -2,7 +2,11 @@
2
2
 
3
3
  Complete examples of common patterns with anti-patterns and correct implementations.
4
4
 
5
- ## Titanium Layout Patterns
5
+ ## Community-Discovered Patterns
6
+
7
+ The examples below catalog anti-patterns observed in real Titanium + PurgeTSS projects, paired with the correct approach. They are not exhaustive rules from official docs — they reflect pitfalls the community has hit often enough to warrant dedicated guidance.
8
+
9
+ ### Titanium Layout Patterns
6
10
 
7
11
  > **🚨 NO FLEXBOX IN TITANIUM**
8
12
  > Titanium does NOT support CSS Flexbox. All examples use `horizontal`, `vertical`, or `composite` layouts.
@@ -108,7 +112,7 @@ Complete examples of common patterns with anti-patterns and correct implementati
108
112
 
109
113
  ---
110
114
 
111
- ## Manual .tss Files Anti-Pattern
115
+ ### Manual .tss Files Anti-Pattern
112
116
 
113
117
  **❌ WRONG (Creating manual .tss files):**
114
118
  ```xml
@@ -158,7 +162,7 @@ alloy compile
158
162
 
159
163
  ---
160
164
 
161
- ## Grid with Percentages
165
+ ### Grid with Percentages
162
166
 
163
167
  **❌ WRONG (Children with % widths, parent without w-screen):**
164
168
  ```xml
@@ -179,7 +183,7 @@ alloy compile
179
183
 
180
184
  ---
181
185
 
182
- ## Gap Usage
186
+ ### Gap Usage
183
187
 
184
188
  **❌ WRONG (gap adds margin all around, breaks % widths):**
185
189
  ```xml
@@ -200,7 +204,7 @@ alloy compile
200
204
 
201
205
  ---
202
206
 
203
- ## Padding on Container Views
207
+ ### Padding on Container Views
204
208
 
205
209
  **❌ WRONG (Padding on Views doesn't work in Titanium):**
206
210
  ```xml
@@ -220,7 +224,7 @@ alloy compile
220
224
 
221
225
  ---
222
226
 
223
- ## `w-full` vs `w-screen`
227
+ ### `w-full` vs `w-screen`
224
228
 
225
229
  **❌ WRONG (Using percentage-based width):**
226
230
  ```xml
@@ -244,7 +248,7 @@ alloy compile
244
248
 
245
249
  ---
246
250
 
247
- ## `rounded-full` Without Size
251
+ ### `rounded-full` Without Size
248
252
 
249
253
  **❌ WRONG (rounded-full alone doesn't exist):**
250
254
  ```xml
@@ -266,7 +270,7 @@ alloy compile
266
270
 
267
271
  ---
268
272
 
269
- ## Square Brackets for Arbitrary Values
273
+ ### Square Brackets for Arbitrary Values
270
274
 
271
275
  **❌ WRONG (Using square brackets like Tailwind CSS):**
272
276
  ```xml
@@ -288,7 +292,7 @@ alloy compile
288
292
 
289
293
  ---
290
294
 
291
- ## Layout Defaults
295
+ ### Layout Defaults
292
296
 
293
297
  **❌ WRONG (Explicit composite class):**
294
298
  ```xml
@@ -318,18 +322,76 @@ alloy compile
318
322
 
319
323
  ---
320
324
 
321
- ## Quick Reference Table
322
-
323
- | Anti-Pattern | Why It Fails | Correct Approach |
324
- | --------------------- | ------------------------ | ------------------------ |
325
- | `flex-row` | Flexbox not supported | `horizontal` |
326
- | `flex-col` | Flexbox not supported | `vertical` |
327
- | `justify-*` | Flexbox not supported | Use margins/positioning |
328
- | `items-center` | Flexbox mental model | Use layout + positioning |
329
- | `p-4` on View | No padding on containers | `m-4` on children |
330
- | `w-full` | Percentage-based | `w-screen` (Ti.UI.FILL) |
331
- | `rounded-full` | Needs size suffix | `rounded-full-12` |
332
- | `composite` class | Already default | Omit it |
333
- | `w-[100px]` | Wrong syntax | `w-(100px)` |
334
- | Manual `.tss` | Overwritten by PurgeTSS | Use utility classes |
335
- | `gap` with `%` widths | Total exceeds 100% | Use explicit margins |
325
+ ### ScrollView Without `content-w-screen` / `content-h-auto`
326
+
327
+ **WRONG (ScrollView with children that overflow horizontally or never scroll vertically):**
328
+ ```xml
329
+ <ScrollView class="w-screen h-screen">
330
+ <View class="vertical">
331
+ <Label text="Very long content..." />
332
+ <!-- many items -->
333
+ </View>
334
+ </ScrollView>
335
+ ```
336
+
337
+ **CORRECT (Explicit content sizing on the ScrollView itself):**
338
+ ```xml
339
+ <ScrollView class="w-screen h-screen content-w-screen content-h-auto">
340
+ <View class="vertical">
341
+ <Label text="Very long content..." />
342
+ <!-- many items -->
343
+ </View>
344
+ </ScrollView>
345
+ ```
346
+
347
+ **Why:** `content-w-screen` sets `contentWidth: Ti.UI.FILL` so the scroll area matches the viewport horizontally; `content-h-auto` sets `contentHeight: Ti.UI.SIZE` so vertical scroll expands to fit children. Omitting these often produces a ScrollView that never scrolls or clips content unexpectedly.
348
+
349
+ ---
350
+
351
+ ### Deprecated `theme.View.DEFAULT` vs `theme.extend.View`
352
+
353
+ **WRONG (old shape — deprecated in recent PurgeTSS):**
354
+ ```javascript
355
+ // purgetss/config.cjs
356
+ module.exports = {
357
+ theme: {
358
+ View: {
359
+ DEFAULT: { backgroundColor: '#ffffff' }
360
+ }
361
+ }
362
+ }
363
+ ```
364
+
365
+ **CORRECT (new `extend` shape):**
366
+ ```javascript
367
+ // purgetss/config.cjs
368
+ module.exports = {
369
+ theme: {
370
+ extend: {
371
+ View: { backgroundColor: '#ffffff' }
372
+ }
373
+ }
374
+ }
375
+ ```
376
+
377
+ **Why:** The nested `DEFAULT` key is a legacy artifact. Component-level theme overrides now live directly under `theme.extend.<Component>` and are merged with built-in defaults. Using the old shape silently produces unexpected styles on newer PurgeTSS versions.
378
+
379
+ ---
380
+
381
+ ### Quick Reference Table
382
+
383
+ | Anti-Pattern | Why It Fails | Correct Approach |
384
+ | ------------------------------------- | ------------------------------------ | -------------------------------------------- |
385
+ | `flex-row` | Flexbox not supported | `horizontal` |
386
+ | `flex-col` | Flexbox not supported | `vertical` |
387
+ | `justify-*` | Flexbox not supported | Use margins/positioning |
388
+ | `items-center` | Flexbox mental model | Use layout + positioning |
389
+ | `p-4` on View | No padding on containers | `m-4` on children |
390
+ | `w-full` | Percentage-based | `w-screen` (Ti.UI.FILL) |
391
+ | `rounded-full` | Needs size suffix | `rounded-full-12` |
392
+ | `composite` class | Already default | Omit it |
393
+ | `w-[100px]` | Wrong syntax | `w-(100px)` |
394
+ | Manual `.tss` | Overwritten by PurgeTSS | Use utility classes |
395
+ | `gap` with `%` widths | Total exceeds 100% | Use explicit margins |
396
+ | ScrollView without `content-*` sizing | No/unexpected scroll | Add `content-w-screen` + `content-h-auto` |
397
+ | `theme.View.DEFAULT` | Legacy shape in newer PurgeTSS | `theme.extend.View` |
@@ -0,0 +1,412 @@
1
+ # App Icons & Branding
2
+
3
+ The `purgetss brand` command (shipped in PurgeTSS v7.6.0) generates the complete Titanium branding set from a single SVG or PNG logo: launcher icons across every Android density, the adaptive-icon trio (foreground + background + monochrome), iOS 18+ Dark and Tinted variants, marketplace artwork, and optional notification/splash icons. Alloy and Classic layouts are auto-detected.
4
+
5
+ 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
+
7
+ > **INFO**
8
+ >
9
+ > The `brand` command at a glance
10
+ > `purgetss brand` turns one logo into every asset a Titanium app needs to ship — launcher icons, adaptive icons, iOS 18+ Dark/Tinted variants, marketplace artwork, and optional notification/splash icons. Works on both Alloy and Classic projects.
11
+
12
+ ## Quick start
13
+
14
+ Drop a logo file into `purgetss/brand/`, then run the command. That's the whole workflow.
15
+
16
+ ```bash
17
+ mkdir -p purgetss/brand # if the folder doesn't exist yet
18
+ cp docs/my-logo.svg purgetss/brand/logo.svg
19
+
20
+ purgetss brand
21
+ ```
22
+
23
+ On a first run the command:
24
+
25
+ 1. Creates the `brand:` section in `purgetss/config.cjs` with sensible defaults (if missing).
26
+ 2. Generates every branding file directly into the project (in-place).
27
+ 3. Prints a compact summary of what was written.
28
+
29
+ Pass `--dry-run` to preview without writing any files:
30
+
31
+ ```bash
32
+ purgetss brand --dry-run
33
+ ```
34
+
35
+ ## The `purgetss/brand/` convention
36
+
37
+ `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.
38
+
39
+ PurgeTSS auto-discovers logo files under this folder, the same way `purgetss/fonts/` works for fonts. Drop files with these names and you're done — no flags, no config:
40
+
41
+ ```text
42
+ purgetss/brand/
43
+ ├── logo.svg required — main logo (or logo.png)
44
+ ├── logo-mono.svg optional — monochrome layer + notifications
45
+ ├── logo-dark.svg optional — iOS 18+ dark variant
46
+ └── logo-tinted.svg optional — iOS 18+ tinted variant
47
+ ```
48
+
49
+ Only `logo.svg` (or `logo.png`) is required. The other three are **opt-in refinements**:
50
+
51
+ | File | Required? | What it's for | Fallback when omitted |
52
+ | --- | --- | --- | --- |
53
+ | `logo.svg` / `logo.png` | **Required** | Main colored logo. Feeds every density and variant. | — |
54
+ | `logo-mono.svg` / `.png` | Optional | Android adaptive monochrome layer (themed icons on Android 13+) and notification icons. | Main logo is whitened automatically. |
55
+ | `logo-dark.svg` / `.png` | Optional | iOS 18+ Dark appearance variant. | Main logo on a transparent background (Apple HIG default). |
56
+ | `logo-tinted.svg` / `.png` | Optional | iOS 18+ Tinted appearance variant. | Grayscale of the main logo on black. |
57
+
58
+ Provide a dedicated `logo-mono` when the colored logo has detail that would collapse into a featureless blob under naive whitening (e.g. a painter's palette with colored dots — the monochrome variant should have cutouts instead).
59
+
60
+ Provide a dedicated `logo-dark` when dark-mode brand guidelines use a different lockup or color treatment; provide `logo-tinted` when you want a pre-simplified silhouette that tints better than a naive grayscale of the colored version.
61
+
62
+ > **INFO**
63
+ >
64
+ > Prefer SVG for the master
65
+ > SVG scales losslessly to every density Sharp needs to emit. A single `logo.svg` rasterizes perfectly at every `res-*dpi` output. PNG masters should be at least **1024×1024** to avoid upscaling artifacts.
66
+
67
+ ### Overriding auto-discovery
68
+
69
+ You can also pass a path directly or point to a logo from the config. Useful when your masters live in `docs/` or another workflow folder:
70
+
71
+ ```bash
72
+ purgetss brand ./docs/snap-logo.svg
73
+ ```
74
+
75
+ Or in `purgetss/config.cjs`:
76
+
77
+ ```javascript
78
+ brand: {
79
+ logo: './docs/snap-logo.svg',
80
+ monochromeLogo: './docs/snap-logo-mono.svg'
81
+ }
82
+ ```
83
+
84
+ Precedence: **CLI flags win over config values, and config values win over auto-discovery.**
85
+
86
+ ## The `brand:` config section
87
+
88
+ On the first run, `purgetss brand` injects a `brand:` block into your existing `purgetss/config.cjs` (between `purge:` and `theme:`) with these defaults:
89
+
90
+ ```javascript
91
+ brand: {
92
+ splash: false, // also generate splash_icon.png × 5
93
+ padding: '15%', // Android safe-zone. Range: 12% tight (mature logos) — 20% conservative. Spec floor 19.44%.
94
+ iosPadding: '4%', // iOS aesthetic. Range: 2% bold — 8% conservative. No launcher mask.
95
+ darkBgColor: null, // opaque dark bg for DefaultIcon-Dark.png (null = transparent per Apple HIG)
96
+ bgColor: '#FFFFFF', // Android adaptive bg + iOS/marketplace flatten
97
+ notification: false, // also generate ic_stat_notify.png × 5
98
+ confirmOverwrites: true // prompt before overwriting files (set false to skip)
99
+ }
100
+ ```
101
+
102
+ | Key | Default | Purpose |
103
+ | --- | --- | --- |
104
+ | `splash` | `false` | When `true`, also emits `splash_icon.png` × 5 densities. |
105
+ | `padding` | `'15%'` | Per-side safe-zone padding inside the 1024×1024 Android canvas. |
106
+ | `iosPadding` | `'4%'` | Aesthetic padding for the iOS square icon. Smaller than Android because iOS has no launcher mask. |
107
+ | `darkBgColor` | `null` | Opaque background baked into `DefaultIcon-Dark.png`. `null` = transparent per Apple HIG (iOS paints its own gradient). |
108
+ | `bgColor` | `'#FFFFFF'` | Triple-purpose (see [Brand color](#brand-color) below). |
109
+ | `notification` | `false` | When `true`, also emits `ic_stat_notify.png` × 5 densities. |
110
+ | `confirmOverwrites` | `true` | When `false`, the `[y/N/a]` prompt is skipped. |
111
+
112
+ Change whatever you want to override globally; CLI flags still win for one-off runs.
113
+
114
+ ## Overwrite confirmation
115
+
116
+ `brand` writes directly into the project, so it asks before overwriting anything:
117
+
118
+ ```text
119
+ In-place mode will OVERWRITE files in <project>. Commit first if you want a rollback.
120
+ Continue? [y/N/a]
121
+ ```
122
+
123
+ - `y` / `yes` — write this time
124
+ - `N` / `no` / `Enter` — abort (nothing is written)
125
+ - `a` / `always` — write, then add `confirmOverwrites: false` to the `brand:` section of `config.cjs` so the prompt stays quiet on future runs
126
+
127
+ The prompt is skipped automatically when:
128
+
129
+ - `stdin` is not a TTY (the `alloy.jmk` hook, CI, a pipe)
130
+ - you pass `-y` / `--yes` — one-shot bypass
131
+ - `PURGETSS_YES=1` is set in the environment — lasts the whole shell session
132
+ - `confirmOverwrites: false` is already in the `brand:` config
133
+
134
+ ```bash
135
+ purgetss brand -y # skip prompt once
136
+ PURGETSS_YES=1 purgetss brand # skip for the whole session
137
+ ```
138
+
139
+ ## What gets generated
140
+
141
+ The output is automatically routed to the right directory for your project layout.
142
+
143
+ **Alloy layout:**
144
+
145
+ ```text
146
+ <project>/
147
+ ├── DefaultIcon.png ← 1024×1024, universal fallback (Android-safe padding)
148
+ ├── DefaultIcon-ios.png ← 1024×1024, iOS flattened on bgColor
149
+ ├── DefaultIcon-Dark.png ← 1024×1024, iOS 18+ dark (transparent per Apple HIG)
150
+ ├── DefaultIcon-Tinted.png ← 1024×1024, iOS 18+ tinted (grayscale on black)
151
+ ├── iTunesConnect.png ← 1024×1024, App Store submission
152
+ ├── MarketplaceArtwork.png ← 512×512, Google Play submission
153
+ └── app/
154
+ └── assets/android/res/
155
+ ├── mipmap-mdpi/ ← 108×108 foreground + background + monochrome + legacy
156
+ ├── mipmap-hdpi/ ← 162×162
157
+ ├── mipmap-xhdpi/ ← 216×216
158
+ ├── mipmap-xxhdpi/ ← 324×324
159
+ ├── mipmap-xxxhdpi/ ← 432×432
160
+ └── mipmap-anydpi-v26/
161
+ └── ic_launcher.xml ← adaptive-icon binder
162
+ ```
163
+
164
+ **Classic layout:**
165
+
166
+ ```text
167
+ <project>/
168
+ ├── DefaultIcon.png DefaultIcon-ios.png ... ← same root-level files as Alloy
169
+ └── platform/
170
+ └── android/res/
171
+ ├── mipmap-*/ ← same 5 densities as Alloy
172
+ └── mipmap-anydpi-v26/ic_launcher.xml
173
+ ```
174
+
175
+ ## Android dark mode
176
+
177
+ > **INFO**
178
+ >
179
+ > No separate "dark icon" file on Android
180
+ > Unlike iOS 18+, Android has no dedicated dark-mode icon file. Instead, Android 13+ uses the **monochrome layer** of the adaptive icon and tints it based on the user's wallpaper + theme.
181
+ >
182
+ > The `brand` command generates `ic_launcher_monochrome.png` at every density by default — you don't need any extra flags to get themed icon support.
183
+
184
+ If you want to provide a dedicated silhouette (recommended for detailed logos):
185
+
186
+ ```bash
187
+ cp docs/my-logo-mono.svg purgetss/brand/logo-mono.svg
188
+ purgetss brand
189
+ ```
190
+
191
+ The monochrome layer is pure white (`RGB 255,255,255`) with alpha preserved. Android applies the user's tint on top at render time.
192
+
193
+ ## iOS 18+ Dark and Tinted variants
194
+
195
+ iOS 18 added two appearance variants on top of the standard app icon: **Dark** (for the dark appearance of the Home Screen) and **Tinted** (for the user-accent-colored mode).
196
+
197
+ The `brand` command generates both by default:
198
+
199
+ - **`DefaultIcon-Dark.png`**: 1024×1024, **transparent by default** per Apple HIG. The system paints its own dark gradient behind the icon at render time. Override with `--dark-bg-color <hex>` to bake in an opaque dark tint instead.
200
+ - **`DefaultIcon-Tinted.png`**: 1024×1024, **grayscale on black (`#000000`)** per Apple HIG. iOS composites its own gradient background and multiplies the luminance by the user-selected accent color at render time.
201
+
202
+ ### Skipping Dark or Tinted
203
+
204
+ ```bash
205
+ purgetss brand --no-dark
206
+ purgetss brand --no-tinted
207
+ purgetss brand --no-dark --no-tinted
208
+ ```
209
+
210
+ ### Titanium SDK wiring status
211
+
212
+ > **WARNING**
213
+ >
214
+ > Upstream work in progress
215
+ > As of April 2026, Titanium SDK picks up `DefaultIcon-ios.png` automatically but does **not** yet wire `DefaultIcon-Dark.png` / `DefaultIcon-Tinted.png` into the generated iOS appiconset. Upstream tracking: [tidev/titanium-sdk#14122](https://github.com/tidev/titanium-sdk/issues/14122).
216
+ >
217
+ > 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.
218
+
219
+ ## Brand color
220
+
221
+ The `--bg-color` flag (or `brand.bgColor` in config) controls three things at once:
222
+
223
+ 1. The **Android adaptive background layer**: a solid color that fills the full 108dp canvas behind your logo.
224
+ 2. The **iOS alpha flatten** for `DefaultIcon-ios.png`. Apple rejects transparent App Store icons, so the logo is flattened on this color.
225
+ 3. The **marketplace flatten** for `iTunesConnect.png` and `MarketplaceArtwork.png` when you pass a non-default value explicitly.
226
+
227
+ ```bash
228
+ purgetss brand --bg-color "#0B1326"
229
+ ```
230
+
231
+ If you never pass the flag, background stays `#FFFFFF` and the marketplace artwork keeps its alpha channel (matches Titanium's default).
232
+
233
+ ## Padding guidance
234
+
235
+ `--padding` controls how much safe-zone padding (per side, expressed as a percentage) surrounds the logo inside the Android adaptive canvas. The default `15%` matches real-world production apps like Gmail and Chrome.
236
+
237
+ | Padding | Logo fill | When to use |
238
+ | ------- | --------- | ------------------------------------------------------------------------------------------------------ |
239
+ | `12%` | 76% | Logos with built-in breathing room (circular wordmarks, letterforms inside a shape). Tight, bold look. |
240
+ | `15%` | 70% | **Default**. Balanced, safe on Pixel, Oppo, Samsung, OneUI, and Nova. |
241
+ | `18%` | 64% | Defensive: for intricate logos, fine serifs, multi-element designs. |
242
+ | `20%` | 60% | Conservative, spec-compliant. Safe on every launcher, including legacy aggressive masks. |
243
+
244
+ 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.
245
+
246
+ The official Android spec floor is `19.44%` (108dp canvas, 66dp inscribed safe-zone circle). Modern launchers are more permissive: Gmail and Chrome ship at 10–14%, which is why `15%` is the default. The 19.44% floor is the theoretical worst-case for aggressive masks; if you're worried about legacy Samsung teardrop masks or similar, bump to `--padding 20` to stay inside the spec.
247
+
248
+ `--ios-padding` is a separate lever — iOS has no launcher mask, so the range is different:
249
+
250
+ | iOS padding | When to use |
251
+ | --- | --- |
252
+ | `2%` | Bold, edge-to-edge logos. |
253
+ | `4%` | **Default**. Balanced aesthetic. |
254
+ | `8%` | Conservative, generous whitespace around the mark. |
255
+
256
+ ## Cleanup legacy branding artifacts
257
+
258
+ 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 so on.
259
+
260
+ The `--cleanup-legacy` flag removes them with context-aware safety rules: it reads `tiapp.xml` to decide what's safe to delete based on your project's configuration. Always preview first:
261
+
262
+ ```bash
263
+ purgetss brand --cleanup-legacy --dry-run
264
+ ```
265
+
266
+ Review the output, then remove `--dry-run` to apply:
267
+
268
+ ```bash
269
+ purgetss brand --cleanup-legacy
270
+ ```
271
+
272
+ Add `--aggressive` to also remove `ldpi` density folders (less than 1% of active Android devices globally in 2026):
273
+
274
+ ```bash
275
+ purgetss brand --cleanup-legacy --aggressive
276
+ ```
277
+
278
+ > **DANGER**
279
+ >
280
+ > Commit first
281
+ > `--cleanup-legacy` deletes files permanently. Commit your project to git before running without `--dry-run` so `git restore` is available as a rollback.
282
+
283
+ ## Troubleshooting
284
+
285
+ ### The icon looks cropped or cramped on my phone
286
+
287
+ Your logo is probably landing too close to the launcher mask. Increase `--padding`:
288
+
289
+ ```bash
290
+ purgetss brand --padding 20
291
+ ```
292
+
293
+ Or set it in the config:
294
+
295
+ ```javascript
296
+ brand: { padding: '20%' }
297
+ ```
298
+
299
+ ### The icon looks tiny / lost in the middle
300
+
301
+ Padding is too generous. Lower it:
302
+
303
+ ```bash
304
+ purgetss brand --padding 12
305
+ ```
306
+
307
+ ### The monochrome version looks like a white blob
308
+
309
+ Your colored logo likely has multi-color detail that doesn't survive a naive whitening. Provide a dedicated silhouette:
310
+
311
+ ```bash
312
+ cp docs/my-logo-mono.svg purgetss/brand/logo-mono.svg
313
+ purgetss brand
314
+ ```
315
+
316
+ ### iOS rejects the app icon upload ("contains transparency")
317
+
318
+ That's Apple's rule: App Store icons must have no alpha channel. `DefaultIcon-ios.png` is always flattened on `bgColor` for that reason. If you edited the file manually and reintroduced alpha, re-run `purgetss brand` to regenerate.
319
+
320
+ ### The dark variant doesn't show on my iPhone
321
+
322
+ Dark variants require iOS 18+ and Titanium SDK automatic wiring (tracked upstream in [titanium-sdk#14122](https://github.com/tidev/titanium-sdk/issues/14122)). Until that PR merges, you may need to add `DefaultIcon-Dark.png` and `DefaultIcon-Tinted.png` manually into the Xcode appiconset after the first iOS build.
323
+
324
+ ### I get "Input image exceeds pixel limit" on an SVG from Affinity / Illustrator
325
+
326
+ Affinity Designer and Adobe Illustrator often bake transforms into the exported SVG's `viewBox`, so the intrinsic dimensions end up at something absurd like `29559×13542 pt`. Rasterized at 1× density, that blows past Sharp's pixel limit and the command crashes.
327
+
328
+ 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.
329
+
330
+ 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.
331
+
332
+ ### I changed my bg color — do I need to regenerate the Android densities too?
333
+
334
+ Yes. `bgColor` bakes into every Android background layer and the iOS flatten. Re-run:
335
+
336
+ ```bash
337
+ purgetss brand --bg-color "#NEW_COLOR"
338
+ ```
339
+
340
+ All 5 Android densities, marketplace artwork, and iOS variants regenerate in one pass.
341
+
342
+ ## Full flag reference
343
+
344
+ **Project & output**
345
+
346
+ | Flag | Purpose |
347
+ | --- | --- |
348
+ | `--project <path>` | Project root (defaults to cwd). |
349
+ | `--dry-run` | Preview what would be generated without writing any files. |
350
+ | `--output <dir>` | Stage into `<dir>` instead of writing in place. |
351
+ | `-y`, `--yes` | Skip the overwrite confirmation prompt for this invocation. |
352
+
353
+ **Visual customization**
354
+
355
+ | Flag | Purpose |
356
+ | --- | --- |
357
+ | `--bg-color <hex>` | Background color for Android adaptive + iOS/marketplace flatten. |
358
+ | `--padding <n>` | Android safe-zone % (range `12–20`, default `15`). |
359
+ | `--ios-padding <n>` | iOS aesthetic padding % (range `2–8`, default `4`). |
360
+
361
+ **Optional asset types**
362
+
363
+ | Flag | Purpose |
364
+ | --- | --- |
365
+ | `--notification` | Also emit `ic_stat_notify.png × 5`. |
366
+ | `--splash` | Also emit `splash_icon.png × 5`. |
367
+
368
+ **Logo variants & overrides**
369
+
370
+ | Flag | Purpose |
371
+ | --- | --- |
372
+ | `--monochrome-logo <path>` | Override `purgetss/brand/logo-mono.{svg,png}`. |
373
+ | `--dark-logo <path>` | Override `purgetss/brand/logo-dark.{svg,png}`. |
374
+ | `--dark-bg-color <hex>` | Opaque dark bg for `DefaultIcon-Dark.png` (default: transparent per Apple HIG). |
375
+ | `--tinted-logo <path>` | Override `purgetss/brand/logo-tinted.{svg,png}`. |
376
+ | `--no-dark` | Skip `DefaultIcon-Dark.png`. |
377
+ | `--no-tinted` | Skip `DefaultIcon-Tinted.png`. |
378
+
379
+ **Legacy cleanup**
380
+
381
+ | Flag | Purpose |
382
+ | --- | --- |
383
+ | `--cleanup-legacy` | Remove obsolete branding artifacts (reads `tiapp.xml` for safety rules). |
384
+ | `--aggressive` | With `--cleanup-legacy`, also remove `ldpi` density folders. |
385
+
386
+ **Diagnostics**
387
+
388
+ | Flag | Purpose |
389
+ | --- | --- |
390
+ | `--notes` | Print full `tiapp.xml` snippets + padding tuning guide. |
391
+ | `--debug` | Print extra diagnostics. |
392
+
393
+ ### Examples
394
+
395
+ ```bash
396
+ purgetss brand # uses purgetss/brand/logo.svg + config
397
+ purgetss brand --bg-color "#0B1326" # override bg color
398
+ purgetss brand --notification --splash # add notification + splash
399
+ purgetss brand --no-tinted # skip iOS 18+ tinted variant
400
+ purgetss brand --dry-run # preview without writing
401
+ purgetss brand --cleanup-legacy --dry-run # preview legacy cleanup
402
+ ```
403
+
404
+ ## Community-Discovered Patterns
405
+
406
+ - **Titanium SDK wiring lag for iOS 18+ variants.** Titanium SDK currently wires `DefaultIcon-ios.png` into the generated appiconset automatically, but `DefaultIcon-Dark.png` and `DefaultIcon-Tinted.png` are not picked up yet. Until [tidev/titanium-sdk#14122](https://github.com/tidev/titanium-sdk/issues/14122) merges, the practical workaround is: run `ti build -p ios` once, then open `build/iphone/Assets.xcassets/AppIcon.appiconset/` in Xcode and drag the two PNGs into the "Appearance" column of the asset catalog editor. The generated PNGs are already named and sized correctly — no resizing needed.
407
+ - **Modern launchers ship tighter than the spec.** The Android adaptive-icon spec floor is `19.44%` padding, but shipped apps like Gmail and Chrome use `10–14%`. PurgeTSS's `15%` default sits in that real-world range rather than the conservative spec floor, which is why icons look tight-but-balanced out of the box.
408
+
409
+ ## See also
410
+
411
+ - [`brand` command reference](./cli-commands.md#brand-command) — terse flag list.
412
+ - [Multi-Density Images](./multi-density-images.md) — sibling `images` command for UI assets.