diff --git a/crates/ui-egui/src/app/prefs.rs b/crates/ui-egui/src/app/prefs.rs
--- a/crates/ui-egui/src/app/prefs.rs
+++ b/crates/ui-egui/src/app/prefs.rs
@@ -147,6 +147,7 @@ impl PdfCraftApp {
         v["organize_zoom"] = serde_json::json!(self.organize_zoom);
         // Canonical names survive changes to the order of PAPERS and do not depend on UI language.
         v["print_paper"] = serde_json::json!(pdfcraft_engine::print::PAPERS.get(self.print_draft.paper).map(|(name, _)| *name));
+        v["print_eco_mode"] = serde_json::Value::Bool(self.print_draft.eco_mode);
         v.to_string()
     }
 
@@ -227,6 +228,13 @@ impl PdfCraftApp {
         {
             self.print_draft.paper = paper;
         }
+        if let Some(on) = v.get("print_eco_mode").and_then(serde_json::Value::as_bool) {
+            self.print_draft.eco_mode = on;
+            if on {
+                self.print_draft.grayscale = true;
+                self.print_draft.duplex = Some(pdfcraft_engine::print::spool::Duplex::LongEdge);
+            }
+        }
         if let Some(on) = v["highlight_fields"].as_bool() {
             self.view_defaults.highlight_fields = on;
         }
diff --git a/crates/ui-egui/src/workflows/print_ui/body.rs b/crates/ui-egui/src/workflows/print_ui/body.rs
--- a/crates/ui-egui/src/workflows/print_ui/body.rs
+++ b/crates/ui-egui/src/workflows/print_ui/body.rs
@@ -173,7 +173,9 @@ pub(crate) fn body(
                     ui.horizontal(|ui| {
                         ui.add(egui::DragValue::new(&mut d.copies).range(1..=999)).labelled_by(copies_label.id);
                         ui.add(widgets::checkbox(&mut d.collate, tl!("Collate")));
-                        ui.add(widgets::checkbox(&mut d.grayscale, tl!("Print in grayscale")));
+                        if ui.add(widgets::checkbox(&mut d.grayscale, tl!("Print in grayscale"))).changed() {
+                            d.eco_mode = d.grayscale && d.duplex == Some(spool::Duplex::LongEdge);
+                        }
                     });
                 });
                 ui.end_row();
@@ -182,19 +184,34 @@ pub(crate) fn body(
                 if d.handling != Handling::Booklet {
                     ui.label(tl!("Two-sided:"));
                     ui.add_enabled_ui(!browser, |ui| {
-                        combo(
-                            ui,
-                            "duplex",
-                            tl!("Two-sided:"),
-                            &mut d.duplex,
-                            &[
-                                (None, tl!("Printer default")),
-                                (Some(spool::Duplex::Off), tl!("Off")),
-                                (Some(spool::Duplex::LongEdge), tl!("Flip on long edge")),
-                                (Some(spool::Duplex::ShortEdge), tl!("Flip on short edge")),
-                            ],
-                            160.0,
-                        );
+                        ui.horizontal(|ui| {
+                            let before_duplex = d.duplex;
+                            combo(
+                                ui,
+                                "duplex",
+                                tl!("Two-sided:"),
+                                &mut d.duplex,
+                                &[
+                                    (None, tl!("Printer default")),
+                                    (Some(spool::Duplex::Off), tl!("Off")),
+                                    (Some(spool::Duplex::LongEdge), tl!("Flip on long edge")),
+                                    (Some(spool::Duplex::ShortEdge), tl!("Flip on short edge")),
+                                ],
+                                160.0,
+                            );
+                            if d.duplex != before_duplex {
+                                d.eco_mode = d.grayscale && d.duplex == Some(spool::Duplex::LongEdge);
+                            }
+                            if ui.add(widgets::checkbox(&mut d.eco_mode, tl!("Eco mode (Grayscale, two-sided)"))).changed() {
+                                if d.eco_mode {
+                                    d.grayscale = true;
+                                    d.duplex = Some(spool::Duplex::LongEdge);
+                                } else {
+                                    d.grayscale = false;
+                                    d.duplex = None;
+                                }
+                            }
+                        });
                     });
                     ui.end_row();
                 }
diff --git a/crates/ui-egui/src/workflows/print_ui/draft.rs b/crates/ui-egui/src/workflows/print_ui/draft.rs
--- a/crates/ui-egui/src/workflows/print_ui/draft.rs
+++ b/crates/ui-egui/src/workflows/print_ui/draft.rs
@@ -33,6 +33,8 @@ pub struct PrintDraft {
     pub copies: u32,
     pub collate: bool,
     pub grayscale: bool,
+    /// Eco print mode: quickly enables grayscale and duplex (two-sided) printing to save ink and paper.
+    pub eco_mode: bool,
     /// `None` = the printer's own default (its Properties), as Acrobat does.
     pub duplex: Option<spool::Duplex>,
     pub which: Which,
@@ -96,6 +98,7 @@ impl Default for PrintDraft {
             copies: 1,
             collate: true,
             grayscale: false,
+            eco_mode: false,
             duplex: None,
             which: Which::All,
             range: String::new(),
diff --git a/crates/ui-egui/tests/it/print.rs b/crates/ui-egui/tests/it/print.rs
--- a/crates/ui-egui/tests/it/print.rs
+++ b/crates/ui-egui/tests/it/print.rs
@@ -913,3 +913,56 @@ fn a_booklet_decides_two_sided_itself() {
     assert!(h.query_by_role_and_label(Role::ComboBox, "Two-sided:").is_some());
     assert_eq!(h.state().print_draft.job("x").duplex, Some(Duplex::LongEdge), "back to the choice");
 }
+
+#[test]
+fn eco_mode_enables_grayscale_and_duplex_and_persists() {
+    use pdfcraft_engine::print::spool::Duplex;
+    let mut h = harness();
+    assert!(h.state_mut().execute("print.dialog"));
+    h.run_steps(3);
+
+    // Initial state: eco_mode is false, grayscale is false, duplex is None.
+    assert!(!h.state().print_draft.eco_mode);
+    assert!(!h.state().print_draft.grayscale);
+    assert_eq!(h.state().print_draft.duplex, None);
+
+    // Click Eco mode checkbox in the dialog.
+    h.get_by_label("Eco mode (Grayscale, two-sided)").click();
+    h.run_steps(2);
+
+    assert!(h.state().print_draft.eco_mode);
+    assert!(h.state().print_draft.grayscale);
+    assert_eq!(h.state().print_draft.duplex, Some(Duplex::LongEdge));
+
+    // Persist and verify JSON serialization.
+    let saved = h.state().persist();
+    let json: serde_json::Value = serde_json::from_str(&saved).unwrap();
+    assert_eq!(json["print_eco_mode"], true);
+
+    // Restore into a fresh app and verify settings are applied.
+    let mut app = PdfCraftApp::new();
+    app.restore(&saved);
+    assert!(app.print_draft.eco_mode);
+    assert!(app.print_draft.grayscale);
+    assert_eq!(app.print_draft.duplex, Some(Duplex::LongEdge));
+
+    // In the dialog, unticking grayscale unsets eco_mode.
+    h.get_by_label("Print in grayscale").click();
+    h.run_steps(2);
+    assert!(!h.state().print_draft.grayscale);
+    assert!(!h.state().print_draft.eco_mode);
+
+    // Clicking Eco mode again re-enables both.
+    h.get_by_label("Eco mode (Grayscale, two-sided)").click();
+    h.run_steps(2);
+    assert!(h.state().print_draft.eco_mode);
+    assert!(h.state().print_draft.grayscale);
+    assert_eq!(h.state().print_draft.duplex, Some(Duplex::LongEdge));
+
+    // Unticking Eco mode resets grayscale and duplex.
+    h.get_by_label("Eco mode (Grayscale, two-sided)").click();
+    h.run_steps(2);
+    assert!(!h.state().print_draft.eco_mode);
+    assert!(!h.state().print_draft.grayscale);
+    assert_eq!(h.state().print_draft.duplex, None);
+}
