import SwiftUI struct GroupDetailView: View { @Bindable var model: ScanViewModel let group: SimilarityGroup private let columns = [GridItem(.adaptive(minimum: 168, maximum: 168), spacing: 18, alignment: .top)] var body: some View { ScrollView { LazyVGrid(columns: columns, alignment: .leading, spacing: 20) { ForEach(group.members) { member in PhotoTileView( member: member, isRepresentative: member.id == group.representativeID, isMarked: model.markedForDeletion.contains(member.id), canMark: model.canMark(member.id, in: group), onToggle: { model.toggleMark(member.id, in: group) } ) } } .padding(20) } .safeAreaInset(edge: .top) { header } .navigationTitle(group.representative.fileName) .navigationSubtitle("\(group.members.count) 枚") } private var header: some View { VStack(alignment: .leading, spacing: 4) { HStack(spacing: 8) { Text(group.kindText) .font(.caption.weight(.semibold)) .padding(.horizontal, 7) .padding(.vertical, 2) .background( group.isAllExact ? Color.orange.opacity(0.22) : Color.accentColor.opacity(0.18), in: Capsule() ) Text("\(group.members.count) 枚・合計 \(group.totalBytesText)") Text("1枚残すと \(group.reclaimableBytesText) 削減") .foregroundStyle(.secondary) } .font(.callout) Text(group.representative.url.deletingLastPathComponent().path) .font(.caption) .foregroundStyle(.tertiary) .lineLimit(1) .truncationMode(.head) } .frame(maxWidth: .infinity, alignment: .leading) .padding(.horizontal, 20) .padding(.vertical, 10) .background(.bar) } }