diff --git a/crates/engine/src/cmd/para.rs b/crates/engine/src/cmd/para.rs
--- a/crates/engine/src/cmd/para.rs
+++ b/crates/engine/src/cmd/para.rs
@@ -37,7 +37,8 @@ pub fn specs() -> Vec<CommandSpec> {
             .params(r#"{"value"?: bool (false = left to right)}"#),
         CommandSpec::new("para.ltr", "Left-to-Right Text Direction", "Home › Paragraph", |s, v| direction(s, v, false))
             .params(r#"{"value"?: bool (false = right to left)}"#),
-        CommandSpec::new("para.indent", "Increase Indent", "Home › Paragraph", indent).key("Mod+M"),
+        // ⌘M minimizes the window on macOS; Word for Mac indents with Control+Shift+M.
+        CommandSpec::new("para.indent", "Increase Indent", "Home › Paragraph", indent).key(super::mac_or("Ctrl+Shift+M", "Mod+M")),
         CommandSpec::new("para.outdent", "Decrease Indent", "Home › Paragraph", outdent).key("Mod+Shift+M"),
         CommandSpec::new("para.hangingIndent", "Hanging Indent", "Home › Paragraph › Paragraph", |s, _| {
             fmt(s, &|p| {
diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs
--- a/crates/engine/src/tests.rs
+++ b/crates/engine/src/tests.rs
@@ -194,6 +194,14 @@ fn word_default_shortcuts_resolve() {
     assert_eq!(id("Shift+F3"), Some("format.changeCase"));
     assert_eq!(id("F12"), Some("file.saveAs"));
     assert_eq!(id("Mod+Alt+M"), Some("review.newComment"));
+    // Word for Mac indents with Control+Shift+M; ⌘M is the system's Minimize.
+    if cfg!(target_os = "macos") {
+        assert_eq!(id("Ctrl+Shift+M"), Some("para.indent"));
+        assert_eq!(id("Mod+M"), None);
+    } else {
+        assert_eq!(id("Mod+M"), Some("para.indent"));
+    }
+    assert_eq!(id("Mod+Shift+M"), Some("para.outdent"));
     assert_eq!(id("Mod+H"), Some("edit.findReplace"));
 }
 
diff --git a/crates/ui-egui/src/keys.rs b/crates/ui-egui/src/keys.rs
--- a/crates/ui-egui/src/keys.rs
+++ b/crates/ui-egui/src/keys.rs
@@ -115,13 +115,15 @@ pub fn combo(m: Modifiers, key: &str, with_shift: bool) -> String {
 
 /// Shortcuts for interface commands (`ui.*`), which aren't in the engine's keymap: Alt+Q moves
 /// to "Tell me" command search, as in Word for Windows (#819). Not on macOS, where Option+Q types
-/// a character. On macOS ⌘⌥R collapses or expands the ribbon, as in Word for Mac.
+/// a character. On macOS ⌘⌥R collapses or expands the ribbon, as in Word for Mac, and ⌘M
+/// minimizes the window, as in every Mac app.
 fn ui_shortcut(key: Key, m: Modifiers) -> Option<(&'static str, Value)> {
     let alt_only = m.alt && !m.command && !m.ctrl && !m.mac_cmd && !m.shift;
     let mac_cmd_alt = cfg!(target_os = "macos") && m.mac_cmd && m.alt && !m.ctrl && !m.shift;
     match key {
         Key::Q if alt_only && !cfg!(target_os = "macos") => Some(("ui.dialog", json!({"name": "commands"}))),
         Key::R if mac_cmd_alt => Some(("ui.collapseRibbon", json!({}))),
+        Key::M if cfg!(target_os = "macos") && m.mac_cmd && !m.alt && !m.ctrl && !m.shift => Some(("ui.minimize", json!({}))),
         // Ctrl+F1 collapses or expands the ribbon, as in Word for Windows (#1678). Not on macOS,
         // where Ctrl+F1 is the system's keyboard-access switch.
         Key::F1 if m.ctrl && !m.alt && !m.shift && !m.mac_cmd && !cfg!(target_os = "macos") => Some(("ui.collapseRibbon", json!({}))),
@@ -146,7 +148,11 @@ fn dispatch(app: &mut WordApp, key: Key, m: Modifiers) -> bool {
         if m.alt && !crate::widgets::enabled(app, spec.id) {
             return false;
         }
-        let _ = app.run(spec.id, json!({}));
+        if spec.id == "file.close" {
+            app.close_from_key();
+        } else {
+            let _ = app.run(spec.id, json!({}));
+        }
         return true;
     }
     let Some(name) = name else { return false };
@@ -1638,6 +1644,16 @@ mod tests {
         assert_eq!(ui_shortcut(Key::R, m(true, true, true)), None, "Mod+Alt+Shift+R");
     }
 
+    #[test]
+    fn cmd_m_minimizes_on_macos() {
+        let m = |mac_cmd, shift, ctrl| egui::Modifiers { mac_cmd, command: mac_cmd, shift, ctrl, ..Default::default() };
+        let minimize = Some(("ui.minimize", json!({})));
+        assert_eq!(ui_shortcut(Key::M, m(true, false, false)), if cfg!(target_os = "macos") { minimize } else { None });
+        assert_eq!(ui_shortcut(Key::M, m(true, true, false)), None, "⌘⇧M decreases the indent");
+        assert_eq!(ui_shortcut(Key::M, m(false, true, true)), None, "⌃⇧M increases the indent");
+        assert_eq!(ui_shortcut(Key::M, m(false, false, false)), None, "a plain M");
+    }
+
     #[test]
     fn only_plain_paste_releases_paste_a_clipboard_picture() {
         let m = |command, shift, alt| egui::Modifiers { command, shift, alt, ..Default::default() };
diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs
--- a/crates/ui-egui/src/lib.rs
+++ b/crates/ui-egui/src/lib.rs
@@ -1883,6 +1883,13 @@ impl WordApp {
                 json!({"pending": "contextMenu"})
             }
             "ui.paneDock" => return Some(panes::dock_command(self, p)),
+            // ⌘M on macOS: the window goes to the Dock.
+            "ui.minimize" => {
+                if let Some(ctx) = &self.ctx {
+                    ctx.send_viewport_cmd_to(self.active_viewport(), egui::ViewportCommand::Minimized(true));
+                }
+                json!({"minimized": true})
+            }
             "ui.collapseRibbon" => {
                 self.ui.ribbon_collapsed = !self.ui.ribbon_collapsed;
                 json!({"collapsed": self.ui.ribbon_collapsed})
@@ -2446,6 +2453,7 @@ impl WordApp {
 
     /// Per-frame logic before layout: control requests, screenshots, shortcuts, file drops.
     pub fn logic(&mut self, ctx: &egui::Context) {
+        unstick_minimized(ctx);
         updates_ui::tick(self, ctx);
         let lang = i18n::Lang::from_pref(&self.ui.language);
         i18n::set_current(lang);
@@ -3311,6 +3319,18 @@ fn input_dialog(id: &str, params: &Value) -> Option<&'static str> {
 /// Options, the view and interface preferences it sets, Customize Ribbon and Keyboard).
 /// Everything else needs a document, `ui.*` included: only the interface commands listed here
 /// (tabs, Backstage, dialogs, appearance, opening files) work without one.
+/// ⌘M's `Minimized(true)` leaves egui's record of the window saying minimized, and on macOS
+/// egui never reads the window's state back, so after the Dock brings the window back it would
+/// stay "hidden": nothing drawn, no keys. A window with the keyboard isn't minimized, so the
+/// record is put right. (The window's yellow button doesn't go through egui and never sets it.)
+fn unstick_minimized(ctx: &egui::Context) {
+    let stale: Vec<egui::ViewportId> =
+        ctx.input(|i| i.raw.viewports.iter().filter(|(_, v)| v.minimized == Some(true) && v.focused == Some(true)).map(|(id, _)| *id).collect());
+    for id in stale {
+        ctx.send_viewport_cmd_to(id, egui::ViewportCommand::Minimized(false));
+    }
+}
+
 pub(crate) fn works_without_document(id: &str) -> bool {
     matches!(
         id,
@@ -3337,6 +3357,7 @@ pub(crate) fn works_without_document(id: &str) -> bool {
             | "ui.dialog"
             | "ui.closeDialog"
             | "ui.collapseRibbon"
+            | "ui.minimize"
             | "ui.quickAccessToolbar"
             | "ui.keytips"
             | "ui.dark"
@@ -3421,6 +3442,27 @@ mod tests {
         egui::Event::Key { key, physical_key: None, pressed: true, repeat: false, modifiers: egui::Modifiers::COMMAND }
     }
 
+    /// After ⌘M, egui's record says minimized; once the window has the keyboard again the record is
+    /// put right, so the window draws and takes keys. A window still in the Dock is left alone.
+    #[test]
+    fn a_window_back_from_the_dock_is_not_left_minimized() {
+        let ctx = egui::Context::default();
+        let restores = |minimized, focused| {
+            let mut raw = egui::RawInput::default();
+            let root = raw.viewports.entry(egui::ViewportId::ROOT).or_default();
+            root.minimized = Some(minimized);
+            root.focused = Some(focused);
+            let out = ctx.run_ui(raw, |ui| unstick_minimized(ui.ctx()));
+            let commands = out.viewport_output.get(&egui::ViewportId::ROOT).map(|v| v.commands.clone()).unwrap_or_default();
+            // No painter here: dropping the font atlas delta unapplied trips an epaint debug assertion.
+            out.drop_without_applying_deltas();
+            commands.contains(&egui::ViewportCommand::Minimized(false))
+        };
+        assert!(restores(true, true), "back from the Dock");
+        assert!(!restores(true, false), "still in the Dock");
+        assert!(!restores(false, true), "never minimized");
+    }
+
     /// Issue #14: Mod+- (optional hyphen) also zoomed the whole window out, so it read as "zoom out".
     #[test]
     fn word_shortcuts_do_not_zoom_the_window() {
diff --git a/crates/ui-egui/src/windows.rs b/crates/ui-egui/src/windows.rs
--- a/crates/ui-egui/src/windows.rs
+++ b/crates/ui-egui/src/windows.rs
@@ -307,6 +307,18 @@ impl WordApp {
         self.window_count() > 1 && !self.quit_requested
     }
 
+    /// File › Close from its key (⌘W). On macOS it closes the window, as Word for Mac does; in the
+    /// last window, with no menu bar for the app to stay behind in, that quits, asking first about
+    /// unsaved changes as the window's close button does. Elsewhere, and for the Backstage's Close
+    /// and an agent's `file.close`, the last window stays with no page (#1712).
+    pub(crate) fn close_from_key(&mut self) {
+        if cfg!(target_os = "macos") && self.window_count() <= 1 {
+            self.quit();
+        } else if let Err(e) = self.run("file.close", json!({})) {
+            log::warn!("closing: {e}");
+        }
+    }
+
     /// Quit the app (the app menu's Quit): ask about every document with unsaved work, each in
     /// its window, as [`WordApp::close_requested`] does. True when the app may quit now; the
     /// host closes it once `quit_requested` is set.
@@ -1051,6 +1063,28 @@ mod tests {
         assert!(a.quit_requested);
     }
 
+    /// Mod+W in the last window: on macOS it closes the window, as Word for Mac does, and so quits
+    /// once the unsaved changes are answered; elsewhere the window stays with no page (#1712).
+    #[test]
+    fn mod_w_in_the_last_window_closes_it_on_macos() {
+        let ctx = backend();
+        let mut a = app("Only");
+        focus(ViewportId::ROOT);
+        frames(&ctx, &mut a, 4);
+        let mac = cfg!(target_os = "macos");
+        let modifiers = egui::Modifiers { ctrl: !mac, mac_cmd: mac, command: true, ..Default::default() };
+        let key = egui::Event::Key { key: egui::Key::W, physical_key: None, pressed: true, repeat: false, modifiers };
+        EVENTS.with(|e| e.borrow_mut().entry(ViewportId::ROOT).or_default().push(key));
+        frame(&ctx, &mut a);
+        assert_eq!(prompt(&a), Some("saveChanges"), "unsaved changes are asked about first");
+        assert!(!a.quit_requested);
+        a.run("ui.saveChanges", json!({"answer": "dontSave"})).unwrap();
+        assert_eq!(a.quit_requested, mac, "the last window closes on macOS only");
+        if !mac {
+            assert!(!a.has_document(), "elsewhere the window stays with no page");
+        }
+    }
+
     /// Mod+W in a window with no changes closes it; the keys typed after it in the same frame
     /// don't reach the window that comes forward.
     #[test]
