@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.
- package/README.md +26 -3
- package/package.json +1 -1
- package/skills/purgetss/SKILL.md +27 -24
- package/skills/purgetss/references/EXAMPLES.md +52 -41
- package/skills/purgetss/references/adopting-purgetss.md +137 -0
- package/skills/purgetss/references/animation-advanced.md +18 -5
- package/skills/purgetss/references/animation-system.md +21 -9
- package/skills/purgetss/references/app-branding.md +36 -97
- package/skills/purgetss/references/appearance-module.md +70 -5
- package/skills/purgetss/references/apply-directive.md +14 -6
- package/skills/purgetss/references/arbitrary-values.md +59 -23
- package/skills/purgetss/references/brand-padding-geometry.md +105 -0
- package/skills/purgetss/references/class-categories.md +684 -272
- package/skills/purgetss/references/class-index-properties.md +713 -607
- package/skills/purgetss/references/class-index.md +149 -84
- package/skills/purgetss/references/classic-projects.md +3 -3
- package/skills/purgetss/references/cli-commands.md +27 -213
- package/skills/purgetss/references/color-commands.md +218 -0
- package/skills/purgetss/references/configurable-properties.md +17 -2
- package/skills/purgetss/references/custom-fonts.md +21 -16
- package/skills/purgetss/references/custom-rules.md +7 -7
- package/skills/purgetss/references/customization-deep-dive.md +14 -11
- package/skills/purgetss/references/dynamic-component-creation.md +104 -61
- package/skills/purgetss/references/grid-layout.md +21 -24
- package/skills/purgetss/references/icon-fonts.md +37 -20
- package/skills/purgetss/references/installation-setup.md +1 -1
- package/skills/purgetss/references/ios-large-titles.md +12 -11
- package/skills/purgetss/references/migration-guide.md +101 -10
- package/skills/purgetss/references/multi-density-images.md +44 -24
- package/skills/purgetss/references/opacity-modifier.md +1 -1
- package/skills/purgetss/references/performance-tips.md +5 -4
- package/skills/purgetss/references/platform-modifiers.md +2 -2
- package/skills/purgetss/references/purgetss-ui-classic.md +21 -5
- package/skills/purgetss/references/semantic-colors.md +20 -13
- package/skills/purgetss/references/smart-mappings.md +8 -7
- package/skills/purgetss/references/svg-pipeline.md +21 -13
- package/skills/purgetss/references/tikit-components.md +2 -2
- package/skills/purgetss/references/titanium-resets.md +27 -17
- package/skills/purgetss/references/ui-ux-design.md +38 -26
- package/skills/purgetss/references/values-and-units.md +1 -2
- 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 (`[
|
|
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
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
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
|
|
36
|
+
Example output:
|
|
35
37
|
|
|
36
38
|
```
|
|
37
|
-
Class Syntax Error
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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-[
|
|
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,
|
|
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`, `
|
|
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
|
|
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-(
|
|
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-(
|
|
411
|
-
<View class="mt-(
|
|
412
|
-
<Label class="fas fa-cloud text-(
|
|
413
|
-
<Label class="ml-(
|
|
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-(
|
|
426
|
-
<Label class="w-(4.5rem) text-(
|
|
427
|
-
<Label class="w-(4.5rem) text-(
|
|
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.
|