Escape did not just fail to close the dialog — it reset the dashboard. The shared Dialog routes an escapeKeyDown close to onCancel, and this picker puts Reset to defaults in the cancel slot, so pressing Escape wiped the user's card selection. Dialog gains an optional onEscape so a dialog whose cancel slot carries another action can dismiss properly; without it the behaviour is unchanged for every other caller. The card list is now two columns. Seventeen cards in a single column made the dialog scroll, hiding most of the catalogue behind a scrollbar. Groups flow down the columns and are kept whole with break-inside, so a group is never split across the gap. Single column below the sm breakpoint. Also hardens the selection against silent loss: the persisting effect no longer writes on mount. That write was a no-op in the normal case, since the value had just been read from storage — but if the read ever fell back to the defaults (unparseable value, storage throwing), the effect immediately overwrote the real selection and made the loss permanent. Claude-Session: https://claude.ai/code/session_01AbYLvwpEaZFXktHVcqrFRd
This directory contains the client side (frontend) of Checkmate.