import SwiftUI struct FreeCellBoardView: View { @Bindable var viewModel: GameViewModel let layout: CardLayout let theme: GameTheme let cardFaceStyle: CardFaceStyle let cardBackDesign: CardBackDesign var body: some View { VStack(spacing: layout.horizontalPadding) { HStack(spacing: layout.horizontalPadding) { ForEach(0.. some View { let card = viewModel.state.freeCells[index] return CardView(card: card, cardFaceStyle: cardFaceStyle, cardBackDesign: cardBackDesign, size: layout.cardSize()) .dropTarget(.freeCell(index)) .accessibilityLabel(card != nil ? Text("Free cell \(index + 1), \(card!.rank.displayName) of \(card!.suit.displayName)") : Text("Free cell \(index + 1), empty")) .onTapGesture { viewModel.tapCard(at: .freeCell(index), cardIndex: 0) } .simultaneousGesture(freeCellDragGesture(index: index)) } private func foundationView(index: Int) -> some View { let topCard = viewModel.state.foundations[index].last return CardView(card: topCard, cardFaceStyle: cardFaceStyle, cardBackDesign: cardBackDesign, size: layout.cardSize()) .dropTarget(.foundation(index)) .accessibilityLabel(topCard != nil ? Text("Foundation \(index + 1), \(topCard!.rank.displayName) of \(topCard!.suit.displayName)") : Text("Foundation \(index + 1), empty")) } private func freeCellDragGesture(index: Int) -> some Gesture { LongPressGesture(minimumDuration: 0.15) .sequenced(before: DragGesture(coordinateSpace: .named("board"))) .onChanged { value in if case .second(true, let drag?) = value { if viewModel.draggedCards.isEmpty, let card = viewModel.state.freeCells[index] { viewModel.beginDrag(cards: [card], from: .freeCell(index)) } viewModel.dragPosition = drag.location } } .onEnded { value in if case .second(true, let drag?) = value { viewModel.endDrag(at: drag.location) } else { viewModel.cancelDrag() } } } }