import SwiftUI struct LinescoreView: View { let linescore: StatsLinescore let awayCode: String let homeCode: String private var totalInnings: Int { linescore.scheduledInnings ?? 9 } var body: some View { VStack(spacing: 0) { // Header HStack(spacing: 0) { Text("") .frame(width: 70, alignment: .leading) ForEach(1...totalInnings, id: \.self) { inning in let isCurrent = inning == linescore.currentInning HStack(spacing: 0) { if inning > 1 && inning % 3 == 1 { Divider() .frame(width: 1, height: 18) .background(.secondary.opacity(0.3)) .padding(.trailing, 4) } Text("\(inning)") .font(.callout.weight(.semibold).monospacedDigit()) .foregroundStyle(isCurrent ? .primary : .secondary) .frame(width: 44) } } Divider().frame(width: 1, height: 20).padding(.horizontal, 6) ForEach(["R", "H", "E"], id: \.self) { label in Text(label) .font(.callout.weight(.bold).monospacedDigit()) .foregroundStyle(.secondary) .frame(width: 48) } } .padding(.vertical, 10) .background(.ultraThinMaterial) Divider() teamRow(code: awayCode, innings: linescore.innings ?? [], side: .away, totals: linescore.teams?.away) Divider() teamRow(code: homeCode, innings: linescore.innings ?? [], side: .home, totals: linescore.teams?.home) } .clipShape(RoundedRectangle(cornerRadius: 10)) .background(.regularMaterial) } private enum Side { case away, home } @ViewBuilder private func teamRow(code: String, innings: [StatsInningScore], side: Side, totals: StatsLinescoreTotals?) -> some View { HStack(spacing: 0) { Text(code) .font(.callout.weight(.bold)) .foregroundStyle(TeamAssets.color(for: code)) .frame(width: 70, alignment: .leading) ForEach(1...totalInnings, id: \.self) { inning in let runs = inningRuns(innings: innings, inning: inning, side: side) let isCurrent = inning == linescore.currentInning HStack(spacing: 0) { if inning > 1 && inning % 3 == 1 { Divider() .frame(width: 1, height: 22) .background(.secondary.opacity(0.2)) .padding(.trailing, 4) } Text(runs.map { "\($0)" } ?? "-") .font(.callout.weight(runs != nil ? .semibold : .regular).monospacedDigit()) .foregroundStyle(runs == nil ? .tertiary : isCurrent ? .primary : .secondary) .frame(width: 44) } } Divider().frame(width: 1, height: 24).padding(.horizontal, 6) Text(totals?.runs.map { "\($0)" } ?? "-") .font(.callout.weight(.bold).monospacedDigit()) .frame(width: 48) Text(totals?.hits.map { "\($0)" } ?? "-") .font(.callout.weight(.medium).monospacedDigit()) .foregroundStyle(.secondary) .frame(width: 48) Text(totals?.errors.map { "\($0)" } ?? "-") .font(.callout.weight(.medium).monospacedDigit()) .foregroundStyle(.secondary) .frame(width: 48) } .padding(.vertical, 12) } private func inningRuns(innings: [StatsInningScore], inning: Int, side: Side) -> Int? { guard let data = innings.first(where: { $0.num == inning }) else { return nil } switch side { case .away: return data.away?.runs case .home: return data.home?.runs } } }