# 005 — Polish pass: color tokens, concentric radii, icons, tabular figures - **Status**: TODO - **Commit**: d50006e - **Severity**: LOW (bundled per template rule: same fix pattern across crates) - **Category**: Cohesion & tokens / surfaces / typography - **Estimated scope**: 3 × `app.rs` DSL-only edits (~200 touched lines), no Rust logic changes ## Problem 1. **Hex soup** — brand/status colors are repeated literals: `insurance/src/app.rs:31,108,122,170` (`#ffffff`, `#f7a982`, `#7b5cf6`, `#8a74ff`), and equivalents across rider/koboyo. Unthemable; drift guaranteed. 2. **Radius clashes** — nested rounded surfaces ignore `outer = inner + padding`: ```rust // insurance/src/app.rs:262 — current: outer 20, padding-top 14, inner 13 (concentric ⇒ 27 or 6) draw_bg +: { color: #xffedf3 radius: 20.0 } … RoundedView{ width: 38 height: 38 draw_bg +: { color: #ffffff radius: 13.0 } … } ``` Sibling tiles at `:273+` repeat it. `Card`(20)/`IconTile`(15)/RoundBtn(19) nestings need the same audit. (Side paddings must be measured per tile before changing values.) 3. **Emoji as icons** — `insurance/src/app.rs:139` (`🔔`), `:264` (`❤`), koboyo tool glyphs: no stroke weight, ignore the palette, platform-dependent rendering, no state recoloring. 4. **Numbers that tick aren't tabular** — prices/percentages/timers (e.g. rider ETA, insurance stats column noted in README bug 7) shift layout as digits change. **Not verified** per-label; sweep required. ## Target 1. Every color in the three apps' DSL references a `mod.craft.*` token (added in plan 000's token module): `color_brand` (#7b5cf6), `color_brand_soft` (#8a74ff), `color_accent_warm` (#f7a982), `color_surface`, `color_ink` (#191a24), per-app extras defined once at the top of each app's `script_mod!`. Zero raw hex in widget bodies (data-driven colors from `model.rs` are exempt). 2. Every nested rounded pair within 24px of visible even inset satisfies `outer = inner + padding` (measure the real padding; adjust the *inner* radius first so outer silhouettes don't change screen layout). Flush-nested equal-size pairs (e.g. `app.rs:138–139`, both radius 19, zero inset) are compliant — leave them. 3. Icons: replace emoji labels with SDF-drawn glyphs (Makepad `Icon`/custom `pixel` fn) or packaged SVG assets — one asset per icon, recolored per state via a `color` instance; outline default, fill = active. Match visual stroke weight to adjacent text weight. 4. Any label whose text is numeric-and-changing gets tabular figures (font feature `tnum` via the text style if the shipped font supports it; otherwise a fixed-advance numeric font fallback — report which path the font allows). Ellipsis: `…` character, never `...`. ## Repo conventions to follow - DSL-only: `draw_bg +: { color: mod.craft.color_brand }` merge style, per AGENTS.md. - Keep the `let Card = RoundedView{…}` local-component pattern (`insurance/src/app.rs:28–47`) — tokens feed those definitions, then tiles inherit. - README bug 7: when touching stat columns, labels keep intrinsic width (no `width: Fill` inside `width: Fit` columns). ## Steps 1. Plan-000 token module: add the color roles above (names + values enumerated there). 2. insurance sweep: replace hex → tokens; fix tile radii at `:262`, `:273+` after measuring each tile's real inset; icon swap for `🔔`/`❤`/quick-action glyphs; tabular sweep of the stats/price labels. 3. rider sweep: same (map shader colors stay literal — they're scene data, not chrome). 4. koboyo sweep: same; tool-rail icons get the outline/fill active convention. 5. Screenshot the home screen of each app before/after (headless screenshot or windowed) and attach to the PR — radius and icon changes are eyeball-verified. ## Boundaries - Do NOT change layout sizes, spacing, or copy. - Do NOT restyle the HTML originals' look — tokens must reproduce today's rendered colors exactly (this plan is refactor + correctness, not a redesign). - Do NOT touch `model.rs` in any crate. - If a font lacks `tnum` and no acceptable numeric fallback ships with Makepad, STOP on step 4 and report — do not swap the app font for this. ## Verification - **Mechanical**: full matrix green (DSL changes can break `text_exact` locators — update test strings deliberately, e.g. emoji removed from `"🔋 89% Charged"`-style labels, README bug 9). `grep -En "#[0-9a-fA-F]{3,8}\b" */src/app.rs` → only model-driven/scene exemptions. - **Feel check**: nested corners look concentric at 200% zoom; icons recolor on hover/active instead of swapping glyphs; a ticking number no longer makes its row breathe. - **Done when**: token grep is clean, radius table in the PR lists every nested pair with its measured `inner + padding = outer`, and tests are green.