diff --git a/README.md b/README.md
index 6dc4247..e9708cf 100644
--- a/README.md
+++ b/README.md
@@ -1220,7 +1220,7 @@ commit and timestamp come from `src/build_info.cpp`, generated by CMake at confi
regenerated on every build — so the commit and the timestamp always belong to the binary that is
running, and `git` absent leaves the commit as `"unknown"` without breaking the build.
-**The shortcut overview** (toolbar **?** button, or Ctrl+?) lists all keyboard and mouse controls
+**The shortcut overview** (overflow menu, or Ctrl+/) lists all keyboard and mouse controls
in two groups — application actions and plot controls — and is an `AdwShortcutsDialog` rather
than GTK4's deprecated `GtkShortcutsWindow`. libadwaita ≥ 1.8 is therefore a hard dependency;
`CLAUDE.md` records the one consequence worth knowing before editing (the stylesheet it installs
@@ -1236,8 +1236,11 @@ reaches every widget). The full key table:
| `g` | show / hide math channels |
| `l` | show / hide the layout editor |
| `s` | show / hide the side panel |
-| `f` | fit to data |
-| `e` | export visible range |
+| `f` | fit to data (the plot's own key, not an application accelerator) |
+| `Ctrl+E` | export visible range |
+| `F1` | open the help window |
+| `Ctrl+/` | open the shortcut overview |
+| `Ctrl+Q` | quit |
| `+` / `-` | zoom in / out (both axes) |
| `Ctrl+` / `Ctrl-` | zoom in / out (x axis only) |
| `Alt+` / `Alt-` | zoom in / out (y axis only) |
@@ -1252,8 +1255,8 @@ The six "Plot mouse" rows (wheel, drag, right-click) carry no accelerator key
syntax has no member for pointer gestures — and put the prose in the `subtitle` field instead,
which `AdwShortcutsItem` renders as free text.
-**The 14-page help window** (overflow menu, F1, or the toolbar **?** button long-press) is a
-scrollable text view that opens on the page nearest to what the user was doing: the help pages
+**The 14-page help window** (overflow menu or F1) is a scrollable text view that opens on the
+Overview page, so it never comes up blank: the help pages
are compiled into the binary as a GResource (`src/help/udpscope_help.gresource.xml`,
`--c-name=udpscope_help`) for the same reason the icons are — udpscope is run straight out of the
build tree with no install step, so a search path would have to be found at runtime and a missing
diff --git a/src/help/01-overview.txt b/src/help/01-overview.txt
index ba3924c..05b4c23 100644
--- a/src/help/01-overview.txt
+++ b/src/help/01-overview.txt
@@ -23,4 +23,4 @@ one on in the side panel (s) and drag it onto a row.
Example
A 3-signal source at 10 kS/s with a 200 MB buffer holds 1677 s of history. Enable all three,
-drop them on row 1, and the status bar reads ● live · 10.0 kS/s · 2 s window.
+drop them on row 1, and the status bar reads ● live · 10 kS/s · 2 s window.
diff --git a/src/help_window.hpp b/src/help_window.hpp
index ccaff88..8571e29 100644
--- a/src/help_window.hpp
+++ b/src/help_window.hpp
@@ -29,12 +29,14 @@ struct HelpReport {
HelpReport help_self_check();
/// The shortcut overview: the application accelerators and the plot's own interactions,
-/// in the sections the tables name. Hand-rolled because GtkShortcutsWindow is deprecated
-/// as of GTK 4.18 and this project builds warning-free.
+/// in the sections the tables name. An AdwShortcutsDialog, because GtkShortcutsWindow is
+/// deprecated as of GTK 4.18 and this project builds warning-free.
void show_shortcuts(GtkWindow* parent);
-/// Closes whichever of the three windows are open, via gtk_window_close() so the
-/// close-request handlers run and the pointers are nulled. Used by the probe.
+/// Closes whichever of the three windows are open. The About dialog and the help window are
+/// GtkWindows and close with gtk_window_close(), so their close-request handlers run; the
+/// shortcut overview is an AdwDialog and closes with adw_dialog_close(), which emits ::closed.
+/// Either way the file-scope pointer is nulled by the handler. Used by the probe.
void close_help_windows();
} // namespace udpscope
diff --git a/src/status_text.hpp b/src/status_text.hpp
index 7e9d698..8c6426a 100644
--- a/src/status_text.hpp
+++ b/src/status_text.hpp
@@ -46,7 +46,7 @@ struct StatusSnapshot {
int reconnects = 0;
};
-/// The bar: "live · 10.0 kS/s · 2 s window", plus " · event 4.2 s ago" in trigger mode and
+/// The bar: "live · 10 kS/s · 2 s window", plus " · event 4.2 s ago" in trigger mode and
/// nothing else ever. The badge glyph is a separate widget and is not part of this string.
std::string format_glance(const StatusSnapshot& s);
@@ -55,7 +55,8 @@ std::string format_glance(const StatusSnapshot& s);
/// their order must not change without updating it.
std::string format_detail(const StatusSnapshot& s);
-/// A sample rate as "10.0 kS/s". Moved here from ui.cpp, which still calls it.
+/// A sample rate as "10 kS/s" — `%.3g`, so a trailing zero is dropped and the field's width
+/// cannot track the stream. Moved here from ui.cpp, which still calls it.
std::string format_rate(double hz);
/// An elapsed time, stepping to a coarser unit rather than growing digits, so its width