import SwiftUI /// Compact horizontal strip of all live games — scores, innings, outs at a glance struct LiveSituationBar: View { let games: [Game] var onTapGame: ((Game) -> Void)? = nil var body: some View { ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: DS.Spacing.cardGap) { ForEach(games) { game in liveTile(game) } } .padding(.horizontal, DS.Spacing.edgeInset) } } @ViewBuilder private func liveTile(_ game: Game) -> some View { Button { onTapGame?(game) } label: { DataPanel(.compact) { HStack(spacing: tileSpacing) { // Teams + scores VStack(alignment: .leading, spacing: 3) { teamScoreRow(code: game.awayTeam.code, score: game.awayTeam.score) teamScoreRow(code: game.homeTeam.code, score: game.homeTeam.score) } // Situation VStack(alignment: .trailing, spacing: 3) { if let inning = game.currentInningDisplay ?? game.status.liveInning { Text(inning) .font(inningFont) .foregroundStyle(DS.Colors.textSecondary) } if let linescore = game.linescore { HStack(spacing: 2) { ForEach(0..<3, id: \.self) { i in Circle() .fill(i < (linescore.outs ?? 0) ? DS.Colors.warning : DS.Colors.textQuaternary) .frame(width: outDotSize, height: outDotSize) } } } } } } } .platformCardStyle() } @ViewBuilder private func teamScoreRow(code: String, score: Int?) -> some View { HStack(spacing: 6) { TeamLogoView(team: TeamInfo(code: code, name: "", score: nil), size: logoSize) Text(code) .font(teamFont.weight(.bold)) .foregroundStyle(DS.Colors.textPrimary) .frame(width: codeWidth, alignment: .leading) Text(score.map { "\($0)" } ?? "-") .font(scoreFont.weight(.black).monospacedDigit()) .foregroundStyle(DS.Colors.textPrimary) .frame(width: scoreWidth, alignment: .trailing) } } #if os(tvOS) private var tileSpacing: CGFloat { 20 } private var logoSize: CGFloat { 28 } private var codeWidth: CGFloat { 44 } private var scoreWidth: CGFloat { 30 } private var outDotSize: CGFloat { 8 } private var teamFont: Font { .system(size: 18, design: .rounded) } private var scoreFont: Font { .system(size: 20, design: .rounded) } private var inningFont: Font { .system(size: 15, weight: .semibold, design: .rounded) } #else private var tileSpacing: CGFloat { 14 } private var logoSize: CGFloat { 22 } private var codeWidth: CGFloat { 34 } private var scoreWidth: CGFloat { 24 } private var outDotSize: CGFloat { 6 } private var teamFont: Font { .system(size: 14, design: .rounded) } private var scoreFont: Font { .system(size: 16, design: .rounded) } private var inningFont: Font { .system(size: 12, weight: .semibold, design: .rounded) } #endif } // MARK: - GameStatus helper private extension GameStatus { var liveInning: String? { if case .live(let info) = self { return info } return nil } }