Implementation plans — makepad-ui-craft → rider / koboyo / insurance
Format follows skills/vendor/emilkowalski-skills/skills/improve-animations/PLAN-TEMPLATE.md:
each plan is fully self-contained (exact values, verbatim current code, no references to
conversation context) so any executor — human or cheap model — can run it without taste of
its own. Findings source: skills/makepad-ui-craft/PORTS-AUDIT.md @ commit d50006e.
Plans
| # |
Title |
Severity |
Crates |
Status |
| 000 |
Create the shared craft crate (tokens, Pressable, Toast, reduce-motion) |
infra |
new |
TODO |
| 001 |
Press contract: feedback on down, commit on up-if-over, 0.96 scale |
HIGH |
all 3 |
TODO |
| 002 |
Toast enter/exit motion (kill set_visible pop) |
MEDIUM |
all 3 |
TODO |
| 003 |
Insurance sheet: momentum projection + velocity-handoff settle |
MEDIUM |
insurance |
TODO |
| 004 |
Koboyo chrome: drawer slide, origin-aware popovers, animated camera-fit |
MEDIUM |
koboyo |
TODO |
| 005 |
Polish pass: color tokens, concentric radii, icons, tabular figures |
LOW |
all 3 |
TODO |
Execution order & dependencies
000 ──► 001 ──► 002 ──► 003 ──► 004 ──► 005
(001, 002 depend on 000; 003–005 independent of each other, ordered by leverage)
- 000 first — everything else imports from it.
- 001 clears every HIGH in the audit and defines the house press-feel; do not start 002+
with 001 unmerged, or the toast/drawer work will bake in the old commit-on-down call sites.
- 003 and 004 touch disjoint crates and may run in parallel after 002.
Ground rules for every executor
- Test gate: after each plan, the full matrix must stay green —
cargo test -p <crate> --lib --test integration for all three crates, and
MAKEPAD=headless cargo test -p <crate> --test ui for any crate whose app.rs changed.
Baseline is 140 tests; plans add tests, they never delete them.
- DSL landmines (from
makepad-ports/README.md, all previously cost real debugging time):
ids!(var) hashes the literal name — dynamic lookups need &[var].
- Custom widgets must be
let-bound at registration: let X = #(X::register_widget(vm)) {…}.
script_apply_eval! bodies take plain values; uniform(...)/instance(...) are authoring-only.
- Widget tree builds lazily — guard boot-time borrows; use
.widget(cx, …) for custom widgets.
width: Fill on a Label inside a width: Fit column collapses the column.
- In
#[repr(C)] draw structs, never place #[rust]/non-instance fields after #[deref] +
instance fields (GPU buffer corruption — AGENTS.md rule 16).
- Headless
click() targets the widget center; keep animated widgets center-clickable at rest.
- Animator tests vs headless timing: UI tests must assert end states (via
animator_in_state or model state), never mid-flight interpolated values.
- Restraint stays: koboyo canvas pan/draw/wheel-zoom and rider PageFlip page changes remain
unanimated. Do not "improve" them.
- Exact values come from
skills/makepad-ui-craft/{SKILL,EASING,RECIPES}.md. 0.96 is not
0.95; Forward {duration: 0.15} is not 0.2.