d1615a9e01
Reported: dragging toward an image edge (e.g. to reveal a cropped-off head) stopped short of what the reference preview showed was possible — the two panels visibly disagreed. Root cause: transform-origin was set to match the pan position (X%,Y%) instead of staying at the CSS default (50% 50%, the box's own center). CSS object-position places the *unzoomed* crop; transform:scale then magnifies around transform-origin. Tying that origin to X/Y meant zoom dragged its own anchor point toward whichever edge you'd panned to, instead of always magnifying what's actually centered in the frame — harmless near the middle (why initial testing looked fine) but increasingly wrong the closer you drag to an edge, exactly where you'd need to go to reach a cropped head. A second, smaller error was in how the reference-rectangle preview converted focal position to natural-image coordinates (didn't account for the zoom-independent anchor point). Fixed both the crop editor's own math and includes/photo.php's photo_crop_style() (used for every final render — cards, previews) to drop the origin back to the CSS default and use the correct geometry. clampFocal() also simplifies to a plain [0,100] clamp — under real object-position semantics that's always a valid, fully-covered crop at any zoom >= 1, no image-dimension-dependent math needed. Verified in a standalone test harness: dragging now reaches all the way to an image's edges, zoom stays synced between the editor's live frame and its reference-rectangle preview, and the applied result matches the editor's preview exactly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>