diff --git a/crates/pptx/src/read/timing.rs b/crates/pptx/src/read/timing.rs
--- a/crates/pptx/src/read/timing.rs
+++ b/crates/pptx/src/read/timing.rs
@@ -94,6 +94,13 @@ fn max_dur(e: &El, depth: usize) -> Option<u32> {
     best
 }
 
+/// Does any behaviour time node (`p:cBhvr/p:cTn`) under the effect node `c` carry `autoRev`?
+fn behaviour_auto_reverses(c: &El) -> bool {
+    let mut behaviours = vec![];
+    c.find_all("cBhvr", &mut behaviours);
+    behaviours.iter().any(|b| b.child("cTn").and_then(|t| t.bool("autoRev")).unwrap_or(false))
+}
+
 /// Flatten the timing tree into the Animation Pane list.
 pub fn animations(imp: &mut Imp, part: &Part, ctx: &IdCtx, timing: &El, shapes: &[Shape]) -> Vec<Animation> {
     let _ = (imp, part);
@@ -144,7 +151,9 @@ pub fn animations(imp: &mut Imp, part: &Part, ctx: &IdCtx, timing: &El, shapes:
             trigger: f.trigger.and_then(|t| ctx.lookup(t)),
             preset_id: Some(preset),
             preset_subtype: Some(sub),
-            auto_reverse: c.bool("autoRev").unwrap_or(false),
+            // PowerPoint's "Auto-reverse" is `autoRev` on the behaviour nodes (`p:cBhvr/p:cTn`); Color Pulse
+            // always writes it there and plays back and forth on its own, so it isn't read as the option.
+            auto_reverse: c.bool("autoRev").unwrap_or(false) || (effect != "colorPulse" && behaviour_auto_reverses(c)),
             // PowerPoint's "Rewind when done playing" is `fill="remove"` on the effect node.
             rewind: c.attr("fill") == Some("remove"),
             smooth_start: c.f64("accel").map(|v| v / 100_000.0).unwrap_or(0.0),
diff --git a/crates/pptx/tests/it/anim_auto_reverse.rs b/crates/pptx/tests/it/anim_auto_reverse.rs
new file mode 100644
--- /dev/null
+++ b/crates/pptx/tests/it/anim_auto_reverse.rs
@@ -0,0 +1,44 @@
+//! "Auto-reverse" is written by PowerPoint on the behaviour time nodes, not on the effect node.
+
+use std::io::{Cursor, Read, Write};
+
+use deckcraft_geom::Xfrm;
+use deckcraft_model::anim::{AnimClass, Animation};
+use deckcraft_model::{Shape, ShapeId, defaults};
+
+fn deck_with(effect: &str, behaviour: &str) -> Vec<bool> {
+    let mut p = defaults::new_presentation(None);
+    let id = ShapeId(p.alloc_id().expect("id"));
+    let shape = Shape { id, name: "Box".into(), xfrm: Some(Xfrm::new(10.0, 10.0, 200.0, 100.0)), ..Default::default() };
+    let sl = std::sync::Arc::make_mut(&mut p.slides[0]);
+    sl.shapes = vec![shape];
+    sl.animations.push(Animation { shape: id, class: AnimClass::Emphasis, effect: effect.into(), duration_ms: 1000, ..Default::default() });
+    let mut z = zip::ZipArchive::new(Cursor::new(deckcraft_pptx::export(&p).expect("export"))).expect("zip");
+    let mut out = zip::ZipWriter::new(Cursor::new(Vec::new()));
+    for i in 0..z.len() {
+        let mut f = z.by_index(i).expect("entry");
+        let name = f.name().to_string();
+        let mut d = vec![];
+        f.read_to_end(&mut d).expect("read");
+        if name == "ppt/slides/slide1.xml" {
+            let xml = String::from_utf8(d).expect("utf8");
+            let at = xml.find(behaviour).expect("behaviour written");
+            let cb = at + xml[at..].find("<p:cTn ").expect("behaviour node");
+            d = format!("{}<p:cTn autoRev=\"1\" {}", &xml[..cb], &xml[cb + "<p:cTn ".len()..]).into_bytes();
+        }
+        out.start_file(name, zip::write::SimpleFileOptions::default()).expect("start");
+        out.write_all(&d).expect("write");
+    }
+    let q = deckcraft_pptx::import(&out.finish().expect("finish").into_inner()).expect("import");
+    q.slides[0].animations.iter().map(|a| a.auto_reverse).collect()
+}
+
+#[test]
+fn grow_shrink_reads_auto_reverse_from_its_behaviour_node() {
+    assert_eq!(deck_with("growShrink", "<p:animScale>"), [true]);
+}
+
+#[test]
+fn color_pulse_behaviour_auto_reverse_is_not_the_option() {
+    assert_eq!(deck_with("colorPulse", "<p:animClr "), [false]);
+}
diff --git a/crates/pptx/tests/it/main.rs b/crates/pptx/tests/it/main.rs
--- a/crates/pptx/tests/it/main.rs
+++ b/crates/pptx/tests/it/main.rs
@@ -1,4 +1,5 @@
 mod anchor;
+mod anim_auto_reverse;
 mod chart_embed;
 mod comments;
 mod corpus;
