# Implementation summaries ## help-modal (2026-07-20) Built per `plan/help-modal.md`: `app/bindings.rs` (declarative `BINDINGS` table + `lookup` + `key_label`), `app/help.rs` (overlay), the `App::dispatch`/`DispatchResult` seam, and the rewired event loop in `main.rs`. All 20 tests pass; every gate in `quality/help-modal.md` checked. ### Deviations from plan / architecture - **Two-column modal layout.** The architecture assumed a single-column list; the full table is ~50 rows and would not fit even a 100×40 frame. The modal renders Global in the left column and Library + Queue stacked in the right column, with the close keys as a footer line (`Close help: ?, Esc, q`) derived from the `Scope::Help` bindings instead of a fourth listed group. The open question "scroll vs truncate" stays resolved as truncate — but after the column split the content fits ~34×94, so truncation only kicks in on genuinely small terminals. - **`Scope` derives `Hash`** (not in the stub) so the chord-uniqueness test can use a `HashSet`. - **`QueueInsertHere` description reworded** to "Insert library selection after this track": `crabidy-server`'s `insert_tracks` splices at `position + 1`. Same check confirmed the planned "Queue selection after current track" wording for `LibraryQueueNext`. - **`main.rs`** passes `tx` to `App::new` without the now-unneeded clone; the `KeyCode`/`KeyModifiers`/`UiFocus`/`StatefulList` imports moved out with the old match.