diff --git a/crates/tools/src/bbox.rs b/crates/tools/src/bbox.rs
--- a/crates/tools/src/bbox.rs
+++ b/crates/tools/src/bbox.rs
@@ -91,9 +91,11 @@ pub fn scale_for_drag(r: Rect, handle: Handle, p: Point, proportional: bool, fro
     let mut sy = if ay && d0.y.abs() > 1e-9 { d1.y / d0.y } else { 1.0 };
     if proportional {
         if handle.is_corner() {
-            let s = if sx.abs() > sy.abs() { sx } else { sy };
-            sx = s.abs() * sx.signum();
-            sy = s.abs() * sy.signum();
+            // Follow the axis the pointer moved further along (a drag along one axis must still
+            // resize), and mirror both axes together when it crosses the origin.
+            let s = if (sx - 1.0).abs() >= (sy - 1.0).abs() { sx } else { sy };
+            sx = s;
+            sy = s;
         } else if ax {
             sy = sx.abs();
         } else {
@@ -151,6 +153,25 @@ mod tests {
         assert_eq!(a.transform_rect_bbox(R), Rect::new(0.0, 0.0, 200.0, 100.0));
     }
 
+    #[test]
+    fn proportional_corner_follows_a_drag_along_one_axis() {
+        let scale = |p: Point, from_center: bool| {
+            let a = scale_for_drag(R, Handle::BottomRight, p, true, from_center).as_coeffs();
+            (a[0], a[3])
+        };
+        for from_center in [false, true] {
+            let o = if from_center { R.center() } else { Point::new(0.0, 0.0) };
+            let (hx, hy) = (100.0 - o.x, 50.0 - o.y);
+            // Horizontal drag, then vertical drag: the size follows the pointer, uniformly.
+            for (t, want) in [(0.5, 0.5), (0.25, 0.25), (-0.5, -0.5), (-1.0, -1.0)] {
+                for p in [Point::new(o.x + hx * t, 50.0), Point::new(100.0, o.y + hy * t)] {
+                    let (sx, sy) = scale(p, from_center);
+                    assert!((sx - want).abs() < 1e-9 && (sy - want).abs() < 1e-9, "{p:?} center={from_center}: got ({sx}, {sy}), want {want}");
+                }
+            }
+        }
+    }
+
     #[test]
     fn scale_side_and_center() {
         let a = scale_for_drag(R, Handle::Right, Point::new(150.0, 999.0), false, false);
