@maccesar/titools 5.0.0 → 5.1.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 (41) hide show
  1. package/README.md +26 -3
  2. package/package.json +1 -1
  3. package/skills/purgetss/SKILL.md +27 -24
  4. package/skills/purgetss/references/EXAMPLES.md +52 -41
  5. package/skills/purgetss/references/adopting-purgetss.md +137 -0
  6. package/skills/purgetss/references/animation-advanced.md +18 -5
  7. package/skills/purgetss/references/animation-system.md +21 -9
  8. package/skills/purgetss/references/app-branding.md +36 -97
  9. package/skills/purgetss/references/appearance-module.md +70 -5
  10. package/skills/purgetss/references/apply-directive.md +14 -6
  11. package/skills/purgetss/references/arbitrary-values.md +59 -23
  12. package/skills/purgetss/references/brand-padding-geometry.md +105 -0
  13. package/skills/purgetss/references/class-categories.md +684 -272
  14. package/skills/purgetss/references/class-index-properties.md +713 -607
  15. package/skills/purgetss/references/class-index.md +149 -84
  16. package/skills/purgetss/references/classic-projects.md +3 -3
  17. package/skills/purgetss/references/cli-commands.md +27 -213
  18. package/skills/purgetss/references/color-commands.md +218 -0
  19. package/skills/purgetss/references/configurable-properties.md +17 -2
  20. package/skills/purgetss/references/custom-fonts.md +21 -16
  21. package/skills/purgetss/references/custom-rules.md +7 -7
  22. package/skills/purgetss/references/customization-deep-dive.md +14 -11
  23. package/skills/purgetss/references/dynamic-component-creation.md +104 -61
  24. package/skills/purgetss/references/grid-layout.md +21 -24
  25. package/skills/purgetss/references/icon-fonts.md +37 -20
  26. package/skills/purgetss/references/installation-setup.md +1 -1
  27. package/skills/purgetss/references/ios-large-titles.md +12 -11
  28. package/skills/purgetss/references/migration-guide.md +101 -10
  29. package/skills/purgetss/references/multi-density-images.md +44 -24
  30. package/skills/purgetss/references/opacity-modifier.md +1 -1
  31. package/skills/purgetss/references/performance-tips.md +5 -4
  32. package/skills/purgetss/references/platform-modifiers.md +2 -2
  33. package/skills/purgetss/references/purgetss-ui-classic.md +21 -5
  34. package/skills/purgetss/references/semantic-colors.md +20 -13
  35. package/skills/purgetss/references/smart-mappings.md +8 -7
  36. package/skills/purgetss/references/svg-pipeline.md +21 -13
  37. package/skills/purgetss/references/tikit-components.md +2 -2
  38. package/skills/purgetss/references/titanium-resets.md +27 -17
  39. package/skills/purgetss/references/ui-ux-design.md +38 -26
  40. package/skills/purgetss/references/values-and-units.md +1 -2
  41. package/skills/purgetss/references/version-history.md +32 -4
@@ -5,7 +5,7 @@ When you need a one-off value that is not in the defaults, use arbitrary values
5
5
  > **INFO**
6
6
  > To generate an arbitrary style, use parentheses notation with almost any default utility class.
7
7
  >
8
- > Square bracket notation (`[10px]`) is **not supported** because Titanium handles platform and conditional statements in `.tss` files differently. Use parentheses (`(10px)`) instead.
8
+ > Square bracket notation (`[10]`) is **not supported** because Titanium already uses square brackets for platform and conditional statements in `.tss` files. Use parentheses (`(10)`) instead.
9
9
 
10
10
  <!-- TOC-START -->
11
11
  ## Contents
@@ -26,19 +26,25 @@ Starting with PurgeTSS v7.8.0, the build runs a pre-validation pass over class n
26
26
 
27
27
  Each error block includes:
28
28
 
29
- - The file path where the offending class lives
30
- - The line number inside that file
31
- - The offending class name (as authored)
32
- - A `Fix:` suggestion with the corrected class name
29
+ - `Class:` the offending class name (as authored)
30
+ - `File:` the first file where it appears (plus a count of other locations, if any)
31
+ - `Line:` the line number inside that file
32
+ - `Content:` the full content of that line
33
+ - `Issue:` what is wrong
34
+ - `Fix:` a suggestion with the corrected class name
33
35
 
34
- Example shape:
36
+ Example output:
35
37
 
36
38
  ```
37
- Class Syntax Error
38
- File: app/views/index.xml
39
- Line: 12
40
- Found: top-(-10)
41
- Fix: -top-(10)
39
+ ::PurgeTSS:: Class Syntax Error
40
+ Class: "top-(-10)"
41
+ File: "app/views/index.xml"
42
+ Line: 12
43
+ Content: <View class="top-(-10)" />
44
+
45
+ Issue: Negative sign is inside the parentheses
46
+ Fix: Use "-top-(10)" — PurgeTSS expects the "-" prefix BEFORE the rule, not inside the value
47
+ ::PurgeTSS:: Found 1 class syntax error — fix the class above and re-run purgetss
42
48
  ```
43
49
 
44
50
  ### Detected patterns
@@ -48,7 +54,7 @@ The validator catches five narrow, actionable mistakes:
48
54
  | Pattern | Offending input | Suggested fix | Notes |
49
55
  | ----------------------------- | --------------- | ------------- | ---------------------------------------------------------------- |
50
56
  | Inverted negative sign | `top-(-10)` | `-top-(10)` | The `-` prefix goes before the rule, not inside the value |
51
- | Square-bracket notation | `top-[10px]` | `top-(10px)` | PurgeTSS uses parentheses, not square brackets, for arbitrary values (v7.10.1 reworded the error from `Tailwind-style brackets "[ ]"` to `Square brackets "[ ]" are not supported`) |
57
+ | Square-bracket notation | `top-[10]` | `top-(10)` | PurgeTSS uses parentheses, not square brackets, for arbitrary values (v7.10.1 reworded the error from `Tailwind-style brackets "[ ]"` to `Square brackets "[ ]" are not supported`) |
52
58
  | Empty parentheses | `wh-()` | (flagged, no auto-fix) | Add a value such as `wh-(10)` |
53
59
  | Whitespace inside parentheses | `wh-( 200 )` | `wh-(200)` | No spaces allowed between `(`, the value, and `)` |
54
60
  | Redundant `px` unit | `top-(10px)` | `top-(10)` | PurgeTSS treats unit-less arbitrary values as pixels |
@@ -57,9 +63,11 @@ The validator catches five narrow, actionable mistakes:
57
63
 
58
64
  The pre-validator only fires on the five patterns above. Any other unknown class — typos, custom utilities not yet declared, vendor classes that are not enabled in `config.cjs` — is **not** reported as a `Class Syntax Error`. Those classes continue to flow into the `// Unused or unsupported classes` comment block in `app.tss`, exactly like before. This keeps the validator focused on actionable mistakes and avoids noise while you sketch out class names.
59
65
 
66
+ > **Units: write arbitrary values unitless.** Because of the redundant-`px` rule, any class like `m-(50px)`, `w-(2300px)` or `text-(48px)` halts the purge. Write `m-(50)`, `w-(2300)`, `text-(48)` instead; other units such as `rem`, `in` or `%` are not flagged.
67
+
60
68
  ### v7.8.0 parser fix for negatives inside parentheses
61
69
 
62
- Before v7.8.0, an inverted negative such as `top-(-10)` could be silently misparsed by the arbitrary-value pipeline (the `-` inside the parentheses confused the token matcher, producing wrong or missing TSS output without any warning). v7.8.0 hardens that path: the parser now correctly recognizes `top-(-10)` as authored, classifies it as an inverted-negative-sign error, and surfaces the `Class Syntax Error` block with the `-top-(10)` fix instead of producing silent garbage.
70
+ Before v7.8.0, a hyphen inside the value (e.g. `top-(-10)`, `mt-(-5)`, `rotate-(-45)`, `origin-(-10,-20)`) crashed the arbitrary-value parser with an unhandled `Cannot read properties of null (reading 'pop')` exception. v7.8.0 rewrote the parser to extract the `(...)` part first, so the value can contain any characters, and classes with empty values (`wh-()`) or unbalanced parentheses (`wh-(`) now produce a "not yet supported" comment instead of invalid TSS. `top-(-10)` itself is now caught by the pre-validator as an inverted negative sign, with the `-top-(10)` fix.
63
71
 
64
72
  ## Arbitrary nesting depth in `theme` objects (v7.10.0)
65
73
 
@@ -168,23 +176,32 @@ You can set an arbitrary value for any of the following color properties:
168
176
  - `active-tint-` (*hex-rgb-or-rgba-value*)
169
177
  - `active-title-` (*hex-rgb-or-rgba-value*)
170
178
  - `badge-` (*hex-rgb-or-rgba-value*)
179
+ - `badge-bg-` (*hex-rgb-or-rgba-value*)
180
+ - `badge-text-` (*hex-rgb-or-rgba-value*)
171
181
  - `bar-` (*hex-rgb-or-rgba-value*)
172
182
  - `bg-` (*hex-rgb-or-rgba-value*)
183
+ - `bg-disabled-` (*hex-rgb-or-rgba-value*)
173
184
  - `bg-focused-` (*hex-rgb-or-rgba-value*)
174
185
  - `bg-selected-` (*hex-rgb-or-rgba-value*)
175
186
  - `bg-selected-from-` (*hex-rgb-or-rgba-value*)
176
187
  - `bg-selected-to-` (*hex-rgb-or-rgba-value*)
177
188
  - `border-` (*hex-rgb-or-rgba-value*)
189
+ - `colors-` (*hex-rgb-or-rgba-value*)
190
+ - `content-scrim-` (*hex-rgb-or-rgba-value*)
178
191
  - `current-page-indicator-` (*hex-rgb-or-rgba-value*)
179
192
  - `date-time-` (*hex-rgb-or-rgba-value*)
180
193
  - `disabled-` (*hex-rgb-or-rgba-value*)
181
194
  - `drop-shadow-` (*hex-rgb-or-rgba-value*)
182
195
  - `from-` (*hex-rgb-or-rgba-value*)
183
196
  - `highlighted-` (*hex-rgb-or-rgba-value*)
197
+ - `hint-text-` (*hex-rgb-or-rgba-value*)
198
+ - `icon-` (*hex-rgb-or-rgba-value*)
184
199
  - `image-touch-feedback-` (*hex-rgb-or-rgba-value*)
185
200
  - `indicator-` (*hex-rgb-or-rgba-value*)
186
201
  - `keyboard-toolbar-` (*hex-rgb-or-rgba-value*)
202
+ - `light-` (*hex-rgb-or-rgba-value*)
187
203
  - `nav-tint-` (*hex-rgb-or-rgba-value*)
204
+ - `navigation-icon-` (*hex-rgb-or-rgba-value*)
188
205
  - `on-tint-` (*hex-rgb-or-rgba-value*)
189
206
  - `page-indicator-` (*hex-rgb-or-rgba-value*)
190
207
  - `paging-control-` (*hex-rgb-or-rgba-value*)
@@ -193,17 +210,21 @@ You can set an arbitrary value for any of the following color properties:
193
210
  - `results-bg-` (*hex-rgb-or-rgba-value*)
194
211
  - `results-separator-` (*hex-rgb-or-rgba-value*)
195
212
  - `selected-` (*hex-rgb-or-rgba-value*)
213
+ - `selected-bg-` (*hex-rgb-or-rgba-value*)
196
214
  - `selected-button-` (*hex-rgb-or-rgba-value*)
197
215
  - `selected-subtitle-` (*hex-rgb-or-rgba-value*)
198
216
  - `selected-text-` (*hex-rgb-or-rgba-value*)
199
217
  - `separator-` (*hex-rgb-or-rgba-value*)
200
218
  - `shadow-` (*hex-rgb-or-rgba-value*)
219
+ - `status-bar-bg-` (*hex-rgb-or-rgba-value*)
201
220
  - `subtitle-` (*hex-rgb-or-rgba-value*)
221
+ - `subtitle-text-` (*hex-rgb-or-rgba-value*)
202
222
  - `tabs-bg-` (*hex-rgb-or-rgba-value*)
203
223
  - `tabs-bg-selected-` (*hex-rgb-or-rgba-value*)
204
224
  - `text-` (*hex-rgb-or-rgba-value*)
205
225
  - `thumb-tint-` (*hex-rgb-or-rgba-value*)
206
226
  - `tint-` (*hex-rgb-or-rgba-value*)
227
+ - `tint-color-` (*hex-rgb-or-rgba-value*)
207
228
  - `title-` (*hex-rgb-or-rgba-value*)
208
229
  - `title-attributes-` (*hex-rgb-or-rgba-value*)
209
230
  - `title-attributes-shadow-` (*hex-rgb-or-rgba-value*)
@@ -211,10 +232,11 @@ You can set an arbitrary value for any of the following color properties:
211
232
  - `to-` (*hex-rgb-or-rgba-value*)
212
233
  - `touch-feedback-` (*hex-rgb-or-rgba-value*)
213
234
  - `track-tint-` (*hex-rgb-or-rgba-value*)
235
+ - `view-shadow-` (*hex-rgb-or-rgba-value*)
214
236
 
215
237
  ## Spacing Properties
216
238
 
217
- You can set arbitrary values for most size and dimension properties using `rem`, `px`, or `pt` values, directly in XML files or in `config.cjs`.
239
+ You can set arbitrary values for most size and dimension properties using unitless numbers or units such as `rem`, `in`, or `%`, directly in XML files or in `config.cjs`. A `px` suffix is rejected by the pre-validator (see above).
218
240
 
219
241
  ```xml
220
242
  <Alloy>
@@ -274,6 +296,7 @@ You can set arbitrary values for most size and dimension properties using `rem`,
274
296
  - Width and height
275
297
  - `h-` (*any-size-value-and-unit*)
276
298
  - `w-` (*any-size-value-and-unit*)
299
+ - `wh-` (*any-size-value-and-unit*)
277
300
  - `indentation-level-` (*any-size-value-and-unit*)
278
301
  - `keyboard-toolbar-h-` (*any-size-value-and-unit*)
279
302
  - Left and right button padding
@@ -327,10 +350,15 @@ You can set arbitrary values for most size and dimension properties using `rem`,
327
350
  - `rounded-t-` (*any-size-value-and-unit*)
328
351
  - `rounded-tl-` (*any-size-value-and-unit*)
329
352
  - `rounded-tr-` (*any-size-value-and-unit*)
353
+ - `rounded-corners-` (*four-comma-separated-values*), e.g. `rounded-corners-(1,2,3,4)` → `borderRadius: [1, 2, 3, 4]`
354
+ - `rounded-full-` (*any-size-value-and-unit*), e.g. `rounded-full-(40)` → `width: 40, height: 40, borderRadius: 20`
330
355
  - `row-h-` (*any-size-value-and-unit*)
331
356
  - `section-header-top-padding-` (*any-size-value-and-unit*)
332
357
  - `separator-h-` (*any-size-value-and-unit*)
333
358
  - `shadow-radius-` (*any-size-value-and-unit*)
359
+ - Target image height and width
360
+ - `target-image-h-` (*any-size-value-and-unit*)
361
+ - `target-image-w-` (*any-size-value-and-unit*)
334
362
  - xOffset and yOffset
335
363
  - `x-offset-` (*any-size-value-and-unit*)
336
364
  - `y-offset-` (*any-size-value-and-unit*)
@@ -344,36 +372,44 @@ You can set arbitrary values for the following properties, like border radius an
344
372
  - `active-tab-` (*number-value*)
345
373
  - `border-width-` (*number-value*)
346
374
  - `cache-size-` (*number-value*)
375
+ - `cancel-` (*number-value*)
347
376
  - `count-down-` (*in-milliseconds*)
348
377
  - `delay-` (*in-milliseconds*)
378
+ - `destructive-` (*number-value*)
349
379
  - `duration-` (*in-milliseconds*)
350
380
  - `elevation-` (*number-value*)
351
381
  - `font-` (*valid-font-weight-value*)
352
382
  - `horizontal-margin-` (*decimal-value*)
383
+ - `index-` (*number-value*)
353
384
  - `lines-` (*number-value*)
385
+ - `max-` (*number-value*)
354
386
  - `max-length-` (*number-value*)
355
387
  - `max-lines-` (*number-value*)
356
388
  - `max-zoom-scale-` (*decimal-value*)
389
+ - `maximum-` (*number-value*)
357
390
  - `min-zoom-scale-` (*decimal-value*)
358
391
  - `min-` (*number-value*)
392
+ - `minimum-` (*number-value*)
359
393
  - `minimum-text-` (*number-value*)
360
394
  - `opacity-` (*decimal-value-from-0-to-1*)
361
395
  - `origin-` (*x-and-y-coordinates*)
362
396
  - `paging-control-alpha-` (*decimal-value-from-0-to-1*)
363
397
  - `paging-control-timeout-` (*in-milliseconds*)
398
+ - `preferred-` (*number-value*)
364
399
  - `repeat-count-` (*number-value*)
365
400
  - `repeat-` (*number-value*)
366
401
  - `rotate-` (*number-value*)
367
402
  - `scale-` (*decimal-value*)
368
403
  - `text-size-` (*number-value*)
369
404
  - `timeout-` (*in-milliseconds*)
405
+ - `value-` (*number-value*)
370
406
  - `vertical-margin-` (*decimal-value*)
371
407
  - `z-` (*number-value*)
372
408
  - `zoom-scale-` (*decimal-value*)
373
409
 
374
410
  ## Examples
375
411
 
376
- You can use any supported units depending on the property you are generating. Use `hex` or `rgba` values for any color property, or `rem` or `px` for position and sizing properties.
412
+ You can use any supported units depending on the property you are generating. Use `hex` or `rgba` values for any color property, or unitless numbers or `rem` for position and sizing properties.
377
413
 
378
414
  ### Credit Card
379
415
 
@@ -381,7 +417,7 @@ You can use any supported units depending on the property you are generating. Us
381
417
  <Alloy>
382
418
  <Window class="bg-(#53606b)">
383
419
  <View class="w-(2in) h-(3.5in) bg-(#4C61E4) rounded-(20)">
384
- <View class="m-(50px) h-screen w-screen">
420
+ <View class="m-(50) h-screen w-screen">
385
421
  <View class="horizontal ml-0 mt-0">
386
422
  <View class="w-(3rem) h-(3rem) rounded-(1.5rem) opacity-(0.35) bg-white" />
387
423
  <View class="-ml-(20) w-(3rem) h-(3rem) rounded-(1.5rem) opacity-(0.25) bg-white" />
@@ -407,10 +443,10 @@ Try this example on an iPad or tablet.
407
443
  ```xml
408
444
  <Alloy>
409
445
  <Window class="bg-white">
410
- <View class="bg-(#1B6F3F) w-(2300px) h-(1600px) ml-0 mt-0">
411
- <View class="mt-(100px) h-(200px) left-(150px) horizontal">
412
- <Label class="fas fa-cloud text-(48px) text-white" />
413
- <Label class="ml-(30px) text-(48px) h-(200px) font-bold text-white">ZULTYS</Label>
446
+ <View class="bg-(#1B6F3F) w-(2300) h-(1600) ml-0 mt-0">
447
+ <View class="mt-(100) h-(200) left-(150) horizontal">
448
+ <Label class="fas fa-cloud text-(48) text-white" />
449
+ <Label class="ml-(30) text-(48) h-(200) font-bold text-white">ZULTYS</Label>
414
450
  </View>
415
451
  </View>
416
452
  </Window>
@@ -422,9 +458,9 @@ Try this example on an iPad or tablet.
422
458
  ```xml
423
459
  <Alloy>
424
460
  <Window class="bg-(#53606b)" backgroundImage="https://i.pinimg.com/originals/ab/70/a1/ab70a19f087cc9ba2b03e3bee71acc3e.jpg">
425
- <View class="h-(150px) bg-(#53A500) horizontal mt-0 w-screen">
426
- <Label class="w-(4.5rem) text-(16px) h-(150px) text-(#12681E) text-center font-bold" text="Home" />
427
- <Label class="w-(4.5rem) text-(16px) h-(150px) text-(#12681E) bg-(#6DB400) text-center font-bold" text="News" />
461
+ <View class="h-(150) bg-(#53A500) horizontal mt-0 w-screen">
462
+ <Label class="w-(4.5rem) text-(16) h-(150) text-(#12681E) text-center font-bold" text="Home" />
463
+ <Label class="w-(4.5rem) text-(16) h-(150) text-(#12681E) bg-(#6DB400) text-center font-bold" text="News" />
428
464
  </View>
429
465
  </Window>
430
466
  </Alloy>
@@ -0,0 +1,105 @@
1
+ # Brand Padding & Geometry
2
+
3
+ How `purgetss brand` sizes the logo inside each piece: per-piece padding, how the source is read and how sharp the output is, the shared splash rule, rounded non-icon artwork, and the Android adaptive mask math.
4
+
5
+ For the `brand` command itself, its pieces and config, see [App Icons & Branding](./app-branding.md).
6
+
7
+ ## Padding guidance
8
+
9
+ Padding belongs to the piece, not to the project. Each piece has its own key and its own flag:
10
+
11
+ | Piece | Config | Flag | Default |
12
+ | --- | --- | --- | --- |
13
+ | `adaptive` | `brand.adaptive.padding` | `--android-adaptive-padding` | `18%` |
14
+ | `legacy-icon` | `brand.legacyIcon.padding` | `--android-legacy-padding` | `10%` |
15
+ | `appicon` | `brand.appicon.padding` | `--appicon-padding` | `10%` |
16
+ | `icon` | `brand.icon.padding` | `--ios-padding` | `0%` |
17
+ | `feature-graphic` | `brand.featureGraphic.padding` | `--feature-graphic-padding` | `12%` |
18
+ | `launch-logo` | `brand.launchLogo.padding` | `--launch-logo-padding` | `12%` |
19
+ | `android-splash` | `brand.androidSplash.padding` | `--android-splash-padding` | `26%` |
20
+ | `ios-splash` | `brand.iosSplash.padding` | `--ios-splash-padding` | `26%` |
21
+
22
+ `--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.
23
+
24
+ There is deliberately **no global padding value that cascades down**. The defaults answer to different constraints: `18%` answers to the Android launcher mask, while finished square iOS/store artwork stays full-bleed at `0%`. One inherited number could silently break the launcher mask or add an unwanted frame to finished artwork. `background`, which has no such trap, is inherited from `brand.background`.
25
+
26
+ ### How the source is read, and how sharp the output is
27
+
28
+ Two things are worth knowing about what happens to your `logo.svg` or `logo.png` before any padding is applied.
29
+
30
+ **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.
31
+
32
+ **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:
33
+
34
+ ```text
35
+ • Masters at 1024 px — the largest any selected piece asks for
36
+ ```
37
+
38
+ 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 or the same size, never an upscale.
39
+
40
+ The one case this cannot fix is a raster source that is simply too small: a 512-px PNG cannot produce a sharp 1024-px icon. Prefer SVG, or a PNG of at least 1024×1024.
41
+
42
+ ### Splash padding
43
+
44
+ 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.
45
+
46
+ 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.
47
+
48
+ | `androidSplash.padding` / `iosSplash.padding` | Logo | `default.png` (1440×2560) | `res-notlong-port-mdpi` (320×480) |
49
+ | --- | --- | --- | --- |
50
+ | `20%` | 60% of the shorter side | 864 px | 192 px |
51
+ | `26%` (default) | 48% | 691 px | 153 px |
52
+ | `30%` | 40% | 576 px | 128 px |
53
+ | `35%` | 30% | 432 px | 96 px |
54
+
55
+ 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.
56
+
57
+ 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.
58
+
59
+ ## Rounded non-icon artwork
60
+
61
+ `brand.artworkCornerRadius` rounds artwork only in the 16 iPhone launch images, Android `default.png` plus its 11 qualifier variants, `MarketplaceArtworkFeature.png`, and `LaunchLogo.png`. A piece may override it with `cornerRadius`; `brand.splashCornerRadius` is an optional shared override for the two legacy splash pieces.
62
+
63
+ ```javascript
64
+ brand: {
65
+ artworkCornerRadius: '22%',
66
+ iosSplash: { padding: '26%', cornerRadius: '18%' },
67
+ featureGraphic: { padding: '12%', cornerRadius: '20%' }
68
+ }
69
+ ```
70
+
71
+ Values are integer numbers or percentage strings from `0` through `50`, measured against the shorter side of the resized artwork. `0%` preserves the previous output byte for byte; `50%` makes square artwork circular and a wordmark capsule-shaped. Normal and `--dry-run` summaries report the effective padding and radius.
72
+
73
+ Precedence is:
74
+
75
+ - Feature Graphic / LaunchLogo: piece-specific flag → `--artwork-corner-radius` → piece config → `brand.artworkCornerRadius` → `0%`.
76
+ - Legacy splashes: platform flag → `--splash-corner-radius` → `--artwork-corner-radius` → piece config → `brand.splashCornerRadius` → `brand.artworkCornerRadius` → `0%`.
77
+
78
+ Store and launcher icons remain unmasked for platform processing. Despite their filenames, `iTunesConnect.png` and `MarketplaceArtwork.png` are app icons: Apple asks for square, unmasked artwork and Google Play applies its own rounded mask, so pre-rounding them would be wrong. `cornerRadius` is rejected in `DefaultIcon*`, `iTunesConnect.png`, `MarketplaceArtwork.png`, adaptive, legacy, and app icons, Android 12+ `splash_icon.png`, notification icons, and any other unsupported piece; invalid, fractional, negative, non-numeric, or greater-than-50 values also abort before files are written.
79
+
80
+ ### Adaptive icon padding
81
+
82
+ 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:
83
+
84
+ | Padding | Logo | vs. the 66 dp safe circle | vs. the ~72 dp the mask shows |
85
+ | --- | --- | --- | --- |
86
+ | `15%` | 75.6 dp | outside | **outside** — clipped on any launcher |
87
+ | `16%` | 73.4 dp | outside | **outside** |
88
+ | `18%` | 69.1 dp | corners outside | inside — **the default** |
89
+ | `19.44%` | 66.0 dp | exactly on it | inside |
90
+ | `20%` | 64.8 dp | inside | inside — most conservative |
91
+
92
+ `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. Raise it to `20%` if your mark runs edge to edge and you see clipping on a circular launcher.
93
+
94
+ 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.
95
+
96
+ 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.
97
+
98
+ ### Legacy icon padding
99
+
100
+ 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%`.
101
+
102
+ ## See also
103
+
104
+ - [App Icons & Branding](./app-branding.md) — the `brand` command, its pieces and config.
105
+ - [`brand` command reference](./cli-commands.md#brand-command) — terse flag list, including every padding and corner-radius flag.