Drag gesture is dragging all the images vs the tap and long press gestures just work off clicked image

I would like to be able to use multiple gestures against a number of images. In the code below, when I use the tap (3 times) gesture, it works correctly off the clicked card, same with the long press. However, when I try to drag 1 image, all of them are dragged together. I guess it has something to do with being in the ForEach view?

Thanks for looking at this and helping me get out of the rut I have dragged myself into!

Here is the code (you can use any image to test, I used playing cards):

import SwiftUI

struct ContentView: View {
    enum DragState {
        case inactive
        case dragging(translation: CGSize)
        var translation: CGSize {
            switch self {
            case .dragging(let translation): return translation
                default:return CGSize.zero}}}
    
    @GestureState var pressing: Bool = false
    @GestureState var dragState = DragState.inactive
    @State var viewDragState = CGSize.zero
    @State var p1Hand: [String] = ["2_of_hearts", "3_of_hearts", "4_of_hearts", "5_of_hearts"]
    @State var discardDeck: [String] = []
    @State var p1TM1: [String] = []
    @State var expand: Bool = false
    var translationOffset: CGSize {
        return CGSize(width: viewDragState.width + dragState.translation.width, height: viewDragState.height + dragState.translation.height)}
    
    var body: some View {
        ZStack {
            ForEach(0..<p1Hand.count, id: \.self) {
                cardIndex in CardView (card: p1Hand[cardIndex], cardIndex: cardIndex)
// 3 taps to move to different array
                    .onTapGesture(count: 3, perform: {
                        discardDeck.append(p1Hand[cardIndex])
                        print("discard: \(discardDeck)")
                    })
//  long press put in another array
                    .gesture(LongPressGesture(minimumDuration: 1)
                        .updating($pressing)
                             {value,state,transaction in state = value
                        transaction.animation = Animation.easeInOut(duration: 0.5)
                    }
                        .onEnded {
                            value in expand = true
                            p1TM1.append(p1Hand[cardIndex])
                            print("p1TM1: \(p1TM1)")
                        })
//  drag card to group
                    .gesture(DragGesture(minimumDistance: 5)
                        .updating($dragState) { value, state, translation in state = .dragging(translation: value.translation)
                        }.onEnded { value in
                            self.viewDragState.height += value.translation.height
                            self.viewDragState.width += value.translation.width
                            print("card(s) dragged")
                        })
                    .offset(translationOffset)
            }
        }
    }
}

struct CardView: View {
    var card: String
    var cardIndex: Int
    var body: some View {
            Image(card)
                .resizable()
                .frame(width: 40, height: 60)
                .position(x: 40 + CGFloat(cardIndex * 25), y:75)
    }
}

#Preview {
    ContentView()
}