diff --git a/ROADMAP.md b/ROADMAP.md
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -137,6 +137,7 @@ app's JSON control channel (`deckcraft --control PORT`).
 
 | Date | What landed |
 |---|---|
+| 2026-10-26 | A space, digit or punctuation after a symbol-font character (`a:sym`, e.g. a Wingdings arrow typed in a run) draws in the run's own font, as PowerPoint does; it stayed in the symbol font, whose space is about four times as wide (synthetic probe) |
 | 2026-10-25 | Windows installer: the Start menu shortcut takes the icon embedded in `deckcraft.exe` instead of an MSI `<Icon>`, so a taskbar pin keeps its icon after an update (#1114); a pin that already lost it has to be unpinned and pinned again once |
 | 2026-10-24 | AutoFormat as you type: a paragraph that starts with `*`, `-`, `--`, `>`, `<>`, `1.`, `1)`, `I.`, `i.`, `A.`, `a.` or `a)` and a space or tab becomes a bulleted or numbered list in that style; Backspace right after puts the typed text back, and Tools ▸ AutoCorrect and `text.autocorrect {lists}` turn it off |
 | 2026-10-24 | Tables: while the caret is in a cell, dragging into another cell selects that range of cells (shaded, merged cells taken in whole), and Shift+arrow grows or shrinks it; formatting applies to the selected cells only, and Delete clears their text and keeps the table |
@@ -312,6 +313,7 @@ app's JSON control channel (`deckcraft --control PORT`).
 | 2026-10-15 | trivial | Progress log: PPTX trigger click-step round trip. Feature scores and milestone names unchanged |
 | 2026-10-16 | trivial | Progress log: PNG export with a transparent background (#784) |
 | 2026-10-16 | trivial | Progress log: a `.ppsx` from the system starts the slide show (#862) |
+| 2026-10-26 | trivial | Progress log: spaces after symbol-font characters |
 | 2026-10-24 | trivial | Progress log: picture and embedded object fills |
 | 2026-10-22 | trivial | Progress log: table text takes the master's other-text style |
 | 2026-10-16 | trivial | Progress log: responsive mouse-wheel navigation on the fitted canvas |
diff --git a/crates/text/src/lib.rs b/crates/text/src/lib.rs
--- a/crates/text/src/lib.rs
+++ b/crates/text/src/lib.rs
@@ -867,7 +867,9 @@ fn shape_cells(
         let Some(st) = styles.get(si) else { continue };
         let (sc, slot) = scripts.get(a).copied().unwrap_or((None, FontSlot::Latin));
         // Spaces, digits and punctuation stay in the face of the text before them when it can
-        // draw them, so a phrase isn't cut into items at every space.
+        // draw them, so a phrase isn't cut into items at every space; not in a symbol font
+        // (`a:sym`), which PowerPoint uses for the symbol codes alone (Wingdings' space is about
+        // four times a text font's).
         // Emoji, and pictographs asked to look like text (U+FE0E), pick their own face.
         let neutral =
             cluster.iter().all(|c| script::script_of(*c).is_none()) && !deckcraft_fonts::is_emoji_cluster(cluster) && !cluster.contains(&'\u{FE0E}');
@@ -884,7 +886,11 @@ fn shape_cells(
         let face = match (sym_face, prev.as_ref()) {
             (Some(f), _) => f,
             (None, Some(p))
-                if neutral && !p.is_color() && deckcraft_fonts::covers_cluster(p, cluster) && char_style.get(a.wrapping_sub(1)) == Some(&si) =>
+                if neutral
+                    && !p.is_color()
+                    && !is_symbol_font(&p.family)
+                    && deckcraft_fonts::covers_cluster(p, cluster)
+                    && char_style.get(a.wrapping_sub(1)) == Some(&si) =>
             {
                 p.clone()
             }
diff --git a/crates/text/src/tests.rs b/crates/text/src/tests.rs
--- a/crates/text/src/tests.rs
+++ b/crates/text/src/tests.rs
@@ -1255,6 +1255,43 @@ fn symbol_font_characters_draw_in_the_sym_font() {
     assert!(families.iter().all(|(f, c)| c.0 == 1 || !f.eq_ignore_ascii_case(symbol)), "{families:?}");
 }
 
+#[test]
+fn a_space_after_a_symbol_font_character_keeps_the_runs_font() {
+    // PowerPoint stores "→ Only" typed in a Wingdings run as U+F0E0, a space and the words, all
+    // with `<a:sym typeface="Wingdings"/>`: only the symbol code draws in Wingdings. The space
+    // stayed in the arrow's face, and Wingdings' space is about four times as wide. Skipped
+    // without Wingdings.
+    let db = FontDb::global();
+    if !db.has_family("Wingdings") || !covers_symbol(&db.face("Wingdings", "Regular"), '\u{F0E0}') {
+        eprintln!("skipped: no installed Wingdings face draws U+F0E0");
+        return;
+    }
+    let laid = |split: bool| {
+        let (p, mut sh) = setup("\u{F0E0} Only", 900.0, 300.0);
+        let para = &mut sh.text.as_mut().unwrap().paragraphs[0];
+        para.props.bullet = Some(Bullet::None);
+        para.runs[0].props.font = Some("Arial".into());
+        para.runs[0].props.font_sym = Some("Wingdings".into());
+        if split {
+            // The arrow alone carries the symbol font.
+            let mut rest = para.runs[0].clone();
+            rest.text = " Only".into();
+            rest.props.font_sym = None;
+            para.runs[0].text = "\u{F0E0}".into();
+            para.runs.push(rest);
+        }
+        lay(&p, &sh, 900.0, 300.0)
+    };
+    let whole = laid(false);
+    let families: Vec<(String, (usize, usize))> = whole.runs.iter().map(|r| (r.face.family.clone(), r.chars)).collect();
+    assert!(families.iter().any(|(f, c)| f.eq_ignore_ascii_case("Wingdings") && c.0 == 0), "the arrow: {families:?}");
+    let in_wingdings = |i: usize| families.iter().any(|(f, c)| (c.0..c.1).contains(&i) && f.eq_ignore_ascii_case("Wingdings"));
+    assert!(!in_wingdings(1) && !in_wingdings(2), "the space and words: {families:?}");
+    // "Only" starts where it does when the arrow alone is in Wingdings.
+    let o = |l: &TextLayout| l.lines[0].caret_x[2];
+    assert!((o(&whole) - o(&laid(true))).abs() < 0.01, "{} vs {}", o(&whole), o(&laid(true)));
+}
+
 #[test]
 fn small_capitals_draw_smaller_than_the_capitals_beside_them() {
     let (p, mut sh) = setup("HxHx", 2000.0, 300.0);
