let’s make the lightbox actually zoom again (and better). Drop this tiny patch into your Stock Photos (and you can reuse it for Mockups). It adds click/scroll zoom + drag-to-pan, without changing your purchase UI.

1) Add state + handlers (top of the component)
// zoom/pan state
const [zoom, setZoom] = useState(1);
const [pos, setPos] = useState({ x: 0, y: 0 });
const [drag, setDrag] = useState<{startX:number; startY:number} | null>(null);

// reset when a new image opens
useEffect(() => {
  if (selectedImage) { setZoom(1); setPos({x:0,y:0}); setDrag(null); }
}, [selectedImage]);

const onWheelZoom: React.WheelEventHandler<HTMLDivElement> = (e) => {
  e.preventDefault();
  const delta = e.deltaY < 0 ? 0.15 : -0.15;
  setZoom(z => Math.max(1, Math.min(4, +(z + delta).toFixed(2))));
};

const onMouseDown: React.MouseEventHandler = (e) => {
  if (zoom === 1) return;
  setDrag({ startX: e.clientX - pos.x, startY: e.clientY - pos.y });
};

const onMouseMove: React.MouseEventHandler = (e) => {
  if (!drag) return;
  setPos({ x: e.clientX - drag.startX, y: e.clientY - drag.startY });
};

const endDrag = () => setDrag(null);

const toggleClickZoom: React.MouseEventHandler = (e) => {
  e.stopPropagation();
  if (zoom === 1) setZoom(2);
  else { setZoom(1); setPos({x:0,y:0}); }
};

2) Replace your modal’s image block with this
{selectedImage && (
  <div
    className="fixed inset-0 z-50 bg-black/80 flex items-center justify-center p-4"
    onClick={() => setSelectedImage(null)}
  >
    <div
      className="relative max-w-[96vw] max-h-[90vh]"
      onClick={(e) => e.stopPropagation()}
    >
      {/* image viewport */}
      <div
        className="overflow-hidden rounded-lg bg-black/30 select-none"
        style={{ width: 'min(96vw, 1400px)', height: 'min(90vh, 900px)' }}
        onWheel={onWheelZoom}
        onMouseDown={onMouseDown}
        onMouseMove={onMouseMove}
        onMouseUp={endDrag}
        onMouseLeave={endDrag}
      >
        <img
          src={selectedImage.url}
          alt={selectedImage.name}
          draggable={false}
          onClick={toggleClickZoom}
          className={zoom === 1 ? 'cursor-zoom-in' : (drag ? 'cursor-grabbing' : 'cursor-zoom-out')}
          style={{
            transform: `translate(${pos.x}px, ${pos.y}px) scale(${zoom})`,
            transformOrigin: 'center center',
            maxWidth: 'none',   // allow real zoom
            maxHeight: 'none',
            width: '100%',
            height: '100%',
            objectFit: 'contain',
            touchAction: 'none', // better mobile gestures
          }}
        />
      </div>

      {/* controls */}
      <div className="absolute top-3 right-3 flex gap-2">
        <button
          onClick={() => { setZoom(1); setPos({x:0,y:0}); }}
          className="px-3 py-1 rounded bg-white/90 hover:bg-white text-sm"
        >
          Reset
        </button>
        <button
          onClick={() => setSelectedImage(null)}
          className="px-3 py-1 rounded bg-white/90 hover:bg-white text-sm"
        >
          ✕
        </button>
      </div>

      {/* your info/purchase panel can stay exactly as you had it */}
    </div>
  </div>
)}

3) One tiny gotcha

If you have buttons/links layered over the image in the card, add onClick={(e)=>e.stopPropagation()} to them so the card’s onClick still opens the modal.

That’s it. You’ll get:

Click to zoom in/out

Mouse wheel zoom (1x–4x)

Drag to pan when zoomed

Reset button

Keeps your purchase/actions panel untouched