plans/README.md: index, execution order 000->005, executor ground rules (test gate, DSL landmines) 000: shared craft crate (easing/duration/color tokens, Pressable, CraftToast, motion math + units) 001: HIGH press contract - feedback on down, commit on up-if-over, 0.96 scale (all 3 crates) 002: MEDIUM toast enter/exit, interruptible, reduced-motion aware (all 3 crates) 003: MEDIUM insurance sheet momentum projection + velocity-handoff settle, rubber-band 004: MEDIUM koboyo drawer slide, origin-aware popovers, animated camera fit 005: LOW polish - color tokens, concentric radii, real icons, tabular figures
83 lines
4.8 KiB
Markdown
83 lines
4.8 KiB
Markdown
# 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.
|