import SwiftUI struct StatusIndicator: View { let isProtected: Bool let isProcessing: Bool @Environment(\.colorScheme) private var colorScheme @State private var pulseScale: CGFloat = 1.0 @State private var glowOpacity: Double = 0.4 @State private var rotationAngle: Double = 0 private var accentColor: Color { if colorScheme == .light { return isProtected ? Color(hue: 0.38, saturation: 0.85, brightness: 0.40) : Color(hue: 0.05, saturation: 0.90, brightness: 0.45) } else { return isProtected ? Color(hue: 0.38, saturation: 0.75, brightness: 0.80) : Color(hue: 0.06, saturation: 0.75, brightness: 0.85) } } private var statusText: String { if isProcessing { return "Processing..." } return isProtected ? "PROTECTED" : "EXPOSED" } var body: some View { VStack(spacing: 20) { ZStack { ForEach(0..<3, id: \.self) { ring in Circle() .stroke( accentColor.opacity(colorScheme == .light ? (0.28 - Double(ring) * 0.07) : (0.15 - Double(ring) * 0.04)), lineWidth: colorScheme == .light ? 2.0 : 1.5 ) .frame( width: 140 + CGFloat(ring) * 22, height: 140 + CGFloat(ring) * 22 ) .scaleEffect(pulseScale + CGFloat(ring) * 0.02) } Circle() .fill( RadialGradient( colors: [ accentColor.opacity(0.25), accentColor.opacity(0.08), .clear ], center: .center, startRadius: 20, endRadius: 75 ) ) .frame(width: 130, height: 130) .scaleEffect(pulseScale) // Antenna icon Image(systemName: isProtected ? "antenna.radiowaves.left.and.right" : "antenna.radiowaves.left.and.right.slash") .font(.system(size: 52, weight: .light)) .foregroundStyle(accentColor) .symbolEffect(.bounce, value: isProtected) .contentTransition(.symbolEffect(.replace.magic(fallback: .replace))) .shadow(color: accentColor.opacity(0.5), radius: 16) // Processing spinner if isProcessing { Circle() .trim(from: 0, to: 0.7) .stroke( accentColor, style: StrokeStyle(lineWidth: 2, lineCap: .round) ) .frame(width: 125, height: 125) .rotationEffect(.degrees(rotationAngle)) } } .animation(.easeInOut(duration: 0.8), value: isProtected) .animation(.easeInOut(duration: 0.4), value: isProcessing) // Status text Text(statusText) .font(.system(size: 16, weight: .semibold, design: .rounded)) .tracking(3) .foregroundStyle(accentColor) .contentTransition(.numericText()) .animation(.easeInOut, value: statusText) } .onAppear { withAnimation( .easeInOut(duration: 2.0) .repeatForever(autoreverses: true) ) { pulseScale = 1.04 glowOpacity = 0.7 } withAnimation( .linear(duration: 1.0) .repeatForever(autoreverses: false) ) { rotationAngle = 360 } } } }