diff --git a/crates/ui-egui/src/app.rs b/crates/ui-egui/src/app.rs
--- a/crates/ui-egui/src/app.rs
+++ b/crates/ui-egui/src/app.rs
@@ -62,6 +62,9 @@ pub trait Host {
     fn quit(&mut self) {}
 }
 
+/// How far the interface zooms out and in: the bounds egui's own zoom keys keep to.
+pub(crate) const ZOOM_RANGE: (f32, f32) = (0.2, 5.0);
+
 pub(crate) struct Toast {
     pub text: String,
     pub error: bool,
@@ -506,6 +509,15 @@ impl LauncherUi {
             theme::apply(&ctx, self.settings.theme);
             self.applied_theme = Some(self.settings.theme);
         }
+        // Ctrl + mouse wheel (⌘ on macOS) and a trackpad pinch zoom the interface, like egui's own
+        // Ctrl +, Ctrl − and Ctrl 0, and the Interface size row in Settings. eframe remembers the
+        // zoom between runs. Where egui leaves zooming to the browser, so does this (#25, #302).
+        if ctx.options(|o| o.zoom_with_keyboard) {
+            let delta = ctx.input(|i| i.zoom_delta());
+            if delta != 1.0 {
+                ctx.set_zoom_factor((ctx.zoom_factor() * delta).clamp(ZOOM_RANGE.0, ZOOM_RANGE.1));
+            }
+        }
         let now = ctx.input(|i| i.time);
         if now >= self.motion_recheck {
             self.reduce_motion = host.reduce_motion();
diff --git a/crates/ui-egui/src/dialogs.rs b/crates/ui-egui/src/dialogs.rs
--- a/crates/ui-egui/src/dialogs.rs
+++ b/crates/ui-egui/src/dialogs.rs
@@ -365,5 +365,28 @@ impl LauncherUi {
             widgets::cells(ui, &mut theme_choice, &ThemeChoice::ALL.map(|c| (c, Cell { label: c.label(), tip: c.label(), count: None })));
         });
         self.settings.theme = theme_choice;
+
+        // The zoom egui keeps (Ctrl +, Ctrl −, Ctrl 0, and Ctrl + wheel through `LauncherUi::ui`),
+        // which eframe remembers between runs, for those who won't find the keys (#25).
+        ui.add_space(10.0);
+        let zoom = ui.ctx().zoom_factor();
+        row(ui, tl!("Interface size"), 36.0 + 72.0 + 36.0 + 2.0 * ui.spacing().item_spacing.x, &mut |ui| {
+            if widgets::button(ui, "+", Kind::Secondary, 36.0).clicked() {
+                egui::gui_zoom::zoom_in(ui.ctx());
+            }
+            let percent = format!("{}%", (zoom * 100.0).round() as i32);
+            if widgets::button(ui, &percent, Kind::Secondary, 72.0).on_hover_text(tl!("Back to 100%")).clicked() {
+                ui.ctx().set_zoom_factor(1.0);
+            }
+            if widgets::button(ui, "−", Kind::Secondary, 36.0).clicked() {
+                egui::gui_zoom::zoom_out(ui.ctx());
+            }
+        });
+        // The web build leaves zooming to the browser, keys and all.
+        if ui.ctx().options(|o| o.zoom_with_keyboard) {
+            let key = if cfg!(target_os = "macos") { "⌘" } else { "Ctrl" };
+            let hint = fmt(tl!("Or press {mod} + or {mod} −, {mod} 0 for 100%, or hold {mod} and scroll."), &[("mod", key)]);
+            ui.label(RichText::new(hint).size(12.0).color(t.muted));
+        }
     }
 }
diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv
--- a/crates/ui-egui/src/i18n/cs.tsv
+++ b/crates/ui-egui/src/i18n/cs.tsv
@@ -86,6 +86,9 @@
 	Community	Komunita
 	Questions, ideas and news from the ArtCraft team	Dotazy, nápady a novinky od týmu ArtCraft
 	Appearance	Vzhled
+	Interface size	Velikost rozhraní
+	Back to 100%	Zpět na 100 %
+	Or press {mod} + or {mod} −, {mod} 0 for 100%, or hold {mod} and scroll.	Nebo stiskněte {mod} + či {mod} −, {mod} 0 vrátí 100 %, nebo rolujte kolečkem s podrženým {mod}.
 	Quit ArtCraft Launcher	Ukončit ArtCraft Launcher
 	Done	Hotovo
 	Uninstall {name}?	Odinstalovat {name}?
diff --git a/crates/ui-egui/src/i18n/de.tsv b/crates/ui-egui/src/i18n/de.tsv
--- a/crates/ui-egui/src/i18n/de.tsv
+++ b/crates/ui-egui/src/i18n/de.tsv
@@ -99,6 +99,9 @@
 	Community	Community
 	Questions, ideas and news from the ArtCraft team	Fragen, Ideen und Neuigkeiten vom ArtCraft-Team
 	Appearance	Erscheinungsbild
+	Interface size	Größe der Oberfläche
+	Back to 100%	Zurück auf 100 %
+	Or press {mod} + or {mod} −, {mod} 0 for 100%, or hold {mod} and scroll.	Oder {mod} + bzw. {mod} − drücken, {mod} 0 für 100 %, oder mit gedrückter {mod}-Taste scrollen.
 	Quit ArtCraft Launcher	ArtCraft Launcher beenden
 	Done	Fertig
 	Uninstall {name}?	{name} deinstallieren?
diff --git a/crates/ui-egui/src/i18n/es.tsv b/crates/ui-egui/src/i18n/es.tsv
--- a/crates/ui-egui/src/i18n/es.tsv
+++ b/crates/ui-egui/src/i18n/es.tsv
@@ -99,6 +99,9 @@
 	Community	Comunidad
 	Questions, ideas and news from the ArtCraft team	Preguntas, ideas y noticias del equipo de ArtCraft
 	Appearance	Apariencia
+	Interface size	Tamaño de la interfaz
+	Back to 100%	Volver al 100 %
+	Or press {mod} + or {mod} −, {mod} 0 for 100%, or hold {mod} and scroll.	O pulsa {mod} + o {mod} −, {mod} 0 para volver al 100 %, o desplázate manteniendo {mod}.
 	Quit ArtCraft Launcher	Salir de ArtCraft Launcher
 	Done	Listo
 	Uninstall {name}?	¿Desinstalar {name}?
diff --git a/crates/ui-egui/src/i18n/fr.tsv b/crates/ui-egui/src/i18n/fr.tsv
--- a/crates/ui-egui/src/i18n/fr.tsv
+++ b/crates/ui-egui/src/i18n/fr.tsv
@@ -97,6 +97,9 @@
 	Community	Communauté
 	Questions, ideas and news from the ArtCraft team	Questions, idées et actualités de l'équipe ArtCraft
 	Appearance	Apparence
+	Interface size	Taille de l'interface
+	Back to 100%	Revenir à 100 %
+	Or press {mod} + or {mod} −, {mod} 0 for 100%, or hold {mod} and scroll.	Ou appuyez sur {mod} + ou {mod} −, {mod} 0 pour revenir à 100 %, ou faites défiler en maintenant {mod}.
 	Quit ArtCraft Launcher	Quitter ArtCraft Launcher
 	Done	Terminé
 	Uninstall {name}?	Désinstaller {name} ?
diff --git a/crates/ui-egui/src/i18n/hu.tsv b/crates/ui-egui/src/i18n/hu.tsv
--- a/crates/ui-egui/src/i18n/hu.tsv
+++ b/crates/ui-egui/src/i18n/hu.tsv
@@ -99,6 +99,9 @@
 	Community	Közösség
 	Questions, ideas and news from the ArtCraft team	Kérdések, ötletek és hírek az ArtCraft csapatától
 	Appearance	Megjelenés
+	Interface size	Felület mérete
+	Back to 100%	Vissza 100%-ra
+	Or press {mod} + or {mod} −, {mod} 0 for 100%, or hold {mod} and scroll.	Vagy nyomja meg a {mod} + vagy {mod} − billentyűt, {mod} 0 visszaállítja 100%-ra, vagy görgessen a {mod} nyomva tartásával.
 	Quit ArtCraft Launcher	Kilépés az ArtCraft Launcherből
 	Done	Kész
 	Uninstall {name}?	{name} eltávolítása?
diff --git a/crates/ui-egui/src/i18n/ja.tsv b/crates/ui-egui/src/i18n/ja.tsv
--- a/crates/ui-egui/src/i18n/ja.tsv
+++ b/crates/ui-egui/src/i18n/ja.tsv
@@ -101,6 +101,9 @@
 	Community	コミュニティ
 	Questions, ideas and news from the ArtCraft team	ArtCraft チームからの質問、アイデア、ニュース
 	Appearance	外観
+	Interface size	インターフェースの大きさ
+	Back to 100%	100% に戻す
+	Or press {mod} + or {mod} −, {mod} 0 for 100%, or hold {mod} and scroll.	{mod} + / {mod} − でも変えられます。{mod} 0 で 100% に戻り、{mod} を押しながらホイールを回しても変えられます。
 	Quit ArtCraft Launcher	ArtCraft Launcher を終了
 	Done	完了
 	Uninstall {name}?	{name} をアンインストールしますか？
diff --git a/crates/ui-egui/src/i18n/pl.tsv b/crates/ui-egui/src/i18n/pl.tsv
--- a/crates/ui-egui/src/i18n/pl.tsv
+++ b/crates/ui-egui/src/i18n/pl.tsv
@@ -100,6 +100,9 @@
 	Community	Społeczność
 	Questions, ideas and news from the ArtCraft team	Pytania, pomysły i nowości od zespołu ArtCraft
 	Appearance	Motyw
+	Interface size	Rozmiar interfejsu
+	Back to 100%	Wróć do 100%
+	Or press {mod} + or {mod} −, {mod} 0 for 100%, or hold {mod} and scroll.	Albo naciśnij {mod} + lub {mod} −, {mod} 0 przywraca 100%, albo przewijaj kółkiem, trzymając {mod}.
 	Quit ArtCraft Launcher	Wyjdź z ArtCraft Launcher
 	Done	Gotowe
 	Uninstall {name}?	Odinstalować {name}?
diff --git a/crates/ui-egui/src/i18n/pt-BR.tsv b/crates/ui-egui/src/i18n/pt-BR.tsv
--- a/crates/ui-egui/src/i18n/pt-BR.tsv
+++ b/crates/ui-egui/src/i18n/pt-BR.tsv
@@ -87,6 +87,9 @@
 	Community	Comunidade
 	Questions, ideas and news from the ArtCraft team	Dúvidas, ideias e novidades da equipe ArtCraft
 	Appearance	Aparência
+	Interface size	Tamanho da interface
+	Back to 100%	Voltar a 100%
+	Or press {mod} + or {mod} −, {mod} 0 for 100%, or hold {mod} and scroll.	Ou pressione {mod} + ou {mod} −, {mod} 0 para 100%, ou role a roda do mouse segurando {mod}.
 	Quit ArtCraft Launcher	Sair do ArtCraft Launcher
 	Done	Concluído
 	Uninstall {name}?	Desinstalar {name}?
diff --git a/crates/ui-egui/src/i18n/ru.tsv b/crates/ui-egui/src/i18n/ru.tsv
--- a/crates/ui-egui/src/i18n/ru.tsv
+++ b/crates/ui-egui/src/i18n/ru.tsv
@@ -97,6 +97,9 @@
 	Community	Сообщество
 	Questions, ideas and news from the ArtCraft team	Вопросы, идеи и новости от команды ArtCraft
 	Appearance	Внешний вид
+	Interface size	Размер интерфейса
+	Back to 100%	Вернуть 100 %
+	Or press {mod} + or {mod} −, {mod} 0 for 100%, or hold {mod} and scroll.	Или нажмите {mod} + или {mod} −, {mod} 0 для 100 %, или прокручивайте колесо, удерживая {mod}.
 	Quit ArtCraft Launcher	Выйти из ArtCraft Launcher
 	Done	Готово
 	Uninstall {name}?	Удалить {name}?
diff --git a/crates/ui-egui/src/i18n/zh-CN.tsv b/crates/ui-egui/src/i18n/zh-CN.tsv
--- a/crates/ui-egui/src/i18n/zh-CN.tsv
+++ b/crates/ui-egui/src/i18n/zh-CN.tsv
@@ -81,6 +81,9 @@
 	Community	社区
 	Questions, ideas and news from the ArtCraft team	与 ArtCraft 团队交流问题、想法和动态
 	Appearance	外观
+	Interface size	界面大小
+	Back to 100%	恢复 100%
+	Or press {mod} + or {mod} −, {mod} 0 for 100%, or hold {mod} and scroll.	也可以按 {mod} + 或 {mod} −，按 {mod} 0 恢复 100%，或按住 {mod} 滚动鼠标滚轮。
 	Quit ArtCraft Launcher	退出 ArtCraft Launcher
 	Done	完成
 	Uninstall {name}?	卸载 {name}？
diff --git a/crates/ui-egui/tests/ui.rs b/crates/ui-egui/tests/ui.rs
--- a/crates/ui-egui/tests/ui.rs
+++ b/crates/ui-egui/tests/ui.rs
@@ -583,6 +583,44 @@ fn every_table_column_sorts_both_ways() {
     assert_eq!(o.first().map(String::as_str), Some("WordCraft"), "{o:?}");
 }
 
+#[test]
+fn the_interface_size_is_stepped_in_settings_and_zoomed_with_the_wheel() {
+    let (mut h, _) = harness(ViewMode::Grid, egui::Theme::Dark, true);
+    h.run_steps(6);
+    assert_eq!(h.ctx.zoom_factor(), 1.0);
+    h.get_by_label("Settings").click();
+    h.run_steps(4);
+    h.get_by_label("Interface size");
+    h.get_by_label_contains("0 for 100%");
+    // + and − step by a tenth, as egui's own Ctrl + and Ctrl − do; the number goes back to 100%.
+    h.get_by_label("+").click();
+    h.run_steps(3);
+    assert!((h.ctx.zoom_factor() - 1.1).abs() < 1e-3, "{}", h.ctx.zoom_factor());
+    snapshot(&mut h, "settings-interface-size");
+    h.get_by_label("110%").click();
+    h.run_steps(3);
+    assert_eq!(h.ctx.zoom_factor(), 1.0);
+    h.get_by_label("−").click();
+    h.run_steps(3);
+    assert!((h.ctx.zoom_factor() - 0.9).abs() < 1e-3, "{}", h.ctx.zoom_factor());
+    h.get_by_label("90%");
+    // Ctrl + wheel (⌘ on macOS) zooms too, and egui's Ctrl 0 still resets (#302).
+    h.hover_at(egui::pos2(590.0, 300.0));
+    h.run_steps(2);
+    h.input_mut().events.push(egui::Event::MouseWheel {
+        unit: egui::MouseWheelUnit::Line,
+        delta: egui::vec2(0.0, 3.0),
+        phase: egui::TouchPhase::Move,
+        modifiers: egui::Modifiers::COMMAND,
+    });
+    h.run_steps(5);
+    assert!(h.ctx.zoom_factor() > 0.9, "{}", h.ctx.zoom_factor());
+    h.key_press_modifiers(egui::Modifiers::COMMAND, egui::Key::Num0);
+    h.run_steps(3);
+    assert_eq!(h.ctx.zoom_factor(), 1.0);
+    h.get_by_label("100%");
+}
+
 #[test]
 fn settings_link_to_discord() {
     let (mut h, _) = harness(ViewMode::Grid, egui::Theme::Dark, true);
