# 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](000-craft-crate.md) | Create the shared `craft` crate (tokens, Pressable, Toast, reduce-motion) | infra | new | TODO | | [001](001-press-contract.md) | Press contract: feedback on down, commit on up-if-over, 0.96 scale | HIGH | all 3 | TODO | | [002](002-toast-motion.md) | Toast enter/exit motion (kill `set_visible` pop) | MEDIUM | all 3 | TODO | | [003](003-sheet-settle.md) | Insurance sheet: momentum projection + velocity-handoff settle | MEDIUM | insurance | TODO | | [004](004-koboyo-chrome.md) | Koboyo chrome: drawer slide, origin-aware popovers, animated camera-fit | MEDIUM | koboyo | TODO | | [005](005-polish-pass.md) | 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 1. **Test gate**: after each plan, the full matrix must stay green — `cargo test -p --lib --test integration` for all three crates, and `MAKEPAD=headless cargo test -p --test ui` for any crate whose `app.rs` changed. Baseline is 140 tests; plans add tests, they never delete them. 2. **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. 3. **Animator tests vs headless timing**: UI tests must assert *end states* (via `animator_in_state` or model state), never mid-flight interpolated values. 4. **Restraint stays**: koboyo canvas pan/draw/wheel-zoom and rider PageFlip page changes remain unanimated. Do not "improve" them. 5. 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`.