import SwiftUI enum DS { enum Colors { static let background = Color(red: 0.03, green: 0.05, blue: 0.10) static let backgroundElevated = Color(red: 0.06, green: 0.10, blue: 0.18) static let navFill = Color(red: 0.07, green: 0.10, blue: 0.18).opacity(0.94) static let panelFill = Color(red: 0.08, green: 0.11, blue: 0.18).opacity(0.94) static let panelFillMuted = Color(red: 0.10, green: 0.14, blue: 0.23).opacity(0.84) static let panelStroke = Color.white.opacity(0.09) static let live = Color(red: 0.94, green: 0.25, blue: 0.28) static let positive = Color(red: 0.24, green: 0.86, blue: 0.63) static let warning = Color(red: 0.98, green: 0.76, blue: 0.24) static let interactive = Color(red: 1.00, green: 0.75, blue: 0.20) static let media = Color(red: 0.35, green: 0.78, blue: 0.95) static let textPrimary = Color.white.opacity(0.96) static let textSecondary = Color.white.opacity(0.76) static let textTertiary = Color.white.opacity(0.50) static let textQuaternary = Color.white.opacity(0.24) static let onDarkPrimary = textPrimary static let onDarkSecondary = textSecondary static let onDarkTertiary = textTertiary } enum Shadows { static let card = Color.black.opacity(0.30) static let cardRadius: CGFloat = 28 static let cardY: CGFloat = 14 static let cardLifted = Color.black.opacity(0.44) static let cardLiftedRadius: CGFloat = 42 static let cardLiftedY: CGFloat = 18 } enum Fonts { static let heroScore = Font.system(size: 72, weight: .black, design: .rounded).monospacedDigit() static let largeScore = Font.system(size: 42, weight: .black, design: .rounded).monospacedDigit() static let score = Font.system(size: 28, weight: .black, design: .rounded).monospacedDigit() static let scoreCompact = Font.system(size: 22, weight: .bold, design: .rounded).monospacedDigit() static let sectionTitle = Font.system(size: 30, weight: .bold, design: .rounded) static let cardTitle = Font.system(size: 20, weight: .bold, design: .rounded) static let cardTitleCompact = Font.system(size: 17, weight: .bold, design: .rounded) static let dataValue = Font.system(size: 18, weight: .bold, design: .rounded).monospacedDigit() static let dataValueCompact = Font.system(size: 15, weight: .semibold, design: .rounded).monospacedDigit() static let body = Font.system(size: 15, weight: .medium) static let bodySmall = Font.system(size: 13, weight: .medium) static let caption = Font.system(size: 11, weight: .bold, design: .rounded) #if os(tvOS) static let tvHeroScore = Font.system(size: 94, weight: .black, design: .rounded).monospacedDigit() static let tvSectionTitle = Font.system(size: 40, weight: .bold, design: .rounded) static let tvCardTitle = Font.system(size: 28, weight: .bold, design: .rounded) static let tvScore = Font.system(size: 36, weight: .black, design: .rounded).monospacedDigit() static let tvDataValue = Font.system(size: 24, weight: .bold, design: .rounded).monospacedDigit() static let tvBody = Font.system(size: 22, weight: .medium) static let tvCaption = Font.system(size: 20, weight: .bold, design: .rounded) #endif } enum Spacing { #if os(tvOS) static let panelPadCompact: CGFloat = 18 static let panelPadStandard: CGFloat = 24 static let panelPadFeatured: CGFloat = 32 static let sectionGap: CGFloat = 42 static let cardGap: CGFloat = 20 static let itemGap: CGFloat = 12 static let edgeInset: CGFloat = 50 #else static let panelPadCompact: CGFloat = 12 static let panelPadStandard: CGFloat = 16 static let panelPadFeatured: CGFloat = 24 static let sectionGap: CGFloat = 28 static let cardGap: CGFloat = 14 static let itemGap: CGFloat = 8 static let edgeInset: CGFloat = 20 #endif } enum Radii { static let compact: CGFloat = 16 static let standard: CGFloat = 24 static let featured: CGFloat = 30 } } struct BroadcastBackground: View { var body: some View { ZStack { LinearGradient( colors: [ Color(red: 0.03, green: 0.05, blue: 0.10), Color(red: 0.04, green: 0.08, blue: 0.16), Color(red: 0.02, green: 0.04, blue: 0.09), ], startPoint: .topLeading, endPoint: .bottomTrailing ) // Subtle color washes — radial gradients instead of blurred circles for performance RadialGradient( colors: [Color(red: 0.00, green: 0.46, blue: 0.72).opacity(0.12), .clear], center: UnitPoint(x: 0.1, y: 0.15), startRadius: 50, endRadius: 500 ) RadialGradient( colors: [DS.Colors.interactive.opacity(0.10), .clear], center: UnitPoint(x: 0.85, y: 0.15), startRadius: 50, endRadius: 450 ) RadialGradient( colors: [DS.Colors.live.opacity(0.06), .clear], center: UnitPoint(x: 0.8, y: 0.85), startRadius: 50, endRadius: 400 ) BroadcastGridOverlay() .opacity(0.30) } } } private struct BroadcastGridOverlay: View { var body: some View { GeometryReader { proxy in let size = proxy.size Path { path in let verticalSpacing: CGFloat = 110 let horizontalSpacing: CGFloat = 90 var x: CGFloat = 0 while x <= size.width { path.move(to: CGPoint(x: x, y: 0)) path.addLine(to: CGPoint(x: x, y: size.height)) x += verticalSpacing } var y: CGFloat = 0 while y <= size.height { path.move(to: CGPoint(x: 0, y: y)) path.addLine(to: CGPoint(x: size.width, y: y)) y += horizontalSpacing } } .stroke(Color.white.opacity(0.05), lineWidth: 1) } .allowsHitTesting(false) } } struct DataLabelStyle: ViewModifier { func body(content: Content) -> some View { content #if os(tvOS) .font(DS.Fonts.tvCaption) .kerning(1.0) #else .font(DS.Fonts.caption) .kerning(1.5) #endif .foregroundStyle(DS.Colors.textTertiary) .textCase(.uppercase) } } extension View { func dataLabelStyle() -> some View { modifier(DataLabelStyle()) } }