import SwiftUI enum KTheme { static let background = Color(red: 5/255, green: 6/255, blue: 12/255) static let panel = Color(red: 28/255, green: 28/255, blue: 38/255) static let orange = Color(red: 1, green: 106/255, blue: 0) static let pink = Color(red: 242/255, green: 29/255, blue: 167/255) static let purple = Color(red: 111/255, green: 60/255, blue: 1) static let cyan = Color(red: 41/255, green: 209/255, blue: 1) } struct AmbientBackground: View { @Environment(\.accessibilityReduceMotion) private var reduceMotion @State private var isMoving = false var body: some View { ZStack { KTheme.background RadialGradient( colors: [KTheme.purple.opacity(0.32), .clear], center: .topLeading, startRadius: 10, endRadius: 420 ) .scaleEffect(isMoving ? 1.18 : 0.92) .offset(x: isMoving ? 36 : -28, y: isMoving ? 70 : -50) Circle() .fill(KTheme.pink.opacity(0.22)) .frame(width: 260, height: 260) .blur(radius: 42) .offset(x: isMoving ? 150 : 95, y: isMoving ? -250 : -190) Circle() .fill(KTheme.orange.opacity(0.20)) .frame(width: 220, height: 220) .blur(radius: 48) .offset(x: isMoving ? -150 : -90, y: isMoving ? 320 : 250) Circle() .fill(KTheme.cyan.opacity(0.12)) .frame(width: 180, height: 180) .blur(radius: 40) .offset(x: isMoving ? -120 : -165, y: isMoving ? -40 : 80) LinearGradient( colors: [.white.opacity(0.045), .clear, .black.opacity(0.25)], startPoint: .top, endPoint: .bottom ) } .ignoresSafeArea() .onAppear { guard !reduceMotion else { return } withAnimation(.easeInOut(duration: 9).repeatForever(autoreverses: true)) { isMoving = true } } } } struct GlassDepthDeck: View { private let cornerRadius: CGFloat private let content: Content init(cornerRadius: CGFloat = 26, @ViewBuilder content: () -> Content) { self.cornerRadius = cornerRadius self.content = content() } var body: some View { ZStack { RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) .fill(.ultraThinMaterial) .overlay { RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) .stroke(KTheme.cyan.opacity(0.22), lineWidth: 1) } .scaleEffect(x: 0.80, y: 0.91) .offset(y: 38) .blur(radius: 2) .opacity(0.42) RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) .fill(.ultraThinMaterial) .overlay { RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) .stroke(KTheme.purple.opacity(0.34), lineWidth: 1) } .scaleEffect(x: 0.88, y: 0.95) .offset(y: 27) .blur(radius: 1.2) .opacity(0.62) RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) .fill(.thinMaterial) .overlay { RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) .stroke(KTheme.pink.opacity(0.32), lineWidth: 1) } .scaleEffect(x: 0.95, y: 0.98) .offset(y: 15) .opacity(0.80) content .shadow(color: .black.opacity(0.58), radius: 38, y: 26) .shadow(color: KTheme.pink.opacity(0.34), radius: 26, y: 10) RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) .stroke( LinearGradient( colors: [.white.opacity(0.62), .clear, KTheme.purple.opacity(0.42)], startPoint: .topLeading, endPoint: .bottomTrailing ), lineWidth: 1.3 ) .allowsHitTesting(false) } .padding(.bottom, 38) } } struct PanelModifier: ViewModifier { func body(content: Content) -> some View { content .padding(18) .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 22, style: .continuous)) .overlay { RoundedRectangle(cornerRadius: 22, style: .continuous) .stroke( LinearGradient( colors: [.white.opacity(0.30), .white.opacity(0.06), KTheme.pink.opacity(0.16)], startPoint: .topLeading, endPoint: .bottomTrailing ), lineWidth: 1 ) } .shadow(color: .black.opacity(0.22), radius: 24, y: 14) } } extension View { func kasztelanPanel() -> some View { modifier(PanelModifier()) } func glassSurface(cornerRadius: CGFloat = 18) -> some View { background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: cornerRadius, style: .continuous)) .overlay { RoundedRectangle(cornerRadius: cornerRadius, style: .continuous) .stroke(.white.opacity(0.20), lineWidth: 1) } } } struct PrimaryButtonStyle: ButtonStyle { func makeBody(configuration: Configuration) -> some View { configuration.label .font(.headline) .foregroundStyle(.white) .frame(maxWidth: .infinity, minHeight: 54) .background( LinearGradient( colors: [KTheme.pink, KTheme.purple, KTheme.orange], startPoint: .topLeading, endPoint: .bottomTrailing ) .opacity(configuration.isPressed ? 0.72 : 1) ) .clipShape(RoundedRectangle(cornerRadius: 16, style: .continuous)) .overlay { RoundedRectangle(cornerRadius: 16, style: .continuous) .stroke(.white.opacity(configuration.isPressed ? 0.12 : 0.30), lineWidth: 1) } .shadow(color: KTheme.pink.opacity(configuration.isPressed ? 0.10 : 0.30), radius: 18, y: 9) .scaleEffect(configuration.isPressed ? 0.975 : 1) .animation(.spring(response: 0.24, dampingFraction: 0.72), value: configuration.isPressed) } } struct GlassButtonStyle: ButtonStyle { func makeBody(configuration: Configuration) -> some View { configuration.label .foregroundStyle(.white) .frame(maxWidth: .infinity, minHeight: 52) .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16, style: .continuous)) .overlay { RoundedRectangle(cornerRadius: 16, style: .continuous) .stroke(.white.opacity(configuration.isPressed ? 0.10 : 0.24), lineWidth: 1) } .scaleEffect(configuration.isPressed ? 0.975 : 1) .animation(.spring(response: 0.24, dampingFraction: 0.72), value: configuration.isPressed) } } struct KasztelanField: View { @EnvironmentObject private var model: AppModel let title: String @Binding var text: String var secure = false var keyboard: UIKeyboardType = .default var contentType: UITextContentType? @FocusState private var isFocused: Bool var body: some View { Group { if secure { SecureField(title, text: $text) } else { TextField(title, text: $text) .keyboardType(keyboard) } } .focused($isFocused) .textContentType(contentType) .textInputAutocapitalization(keyboard == .emailAddress ? .never : .sentences) .autocorrectionDisabled(keyboard == .emailAddress) .padding(.horizontal, 16) .frame(maxWidth: .infinity, minHeight: 54) .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 14, style: .continuous)) .overlay { RoundedRectangle(cornerRadius: 14, style: .continuous) .stroke(isFocused ? KTheme.orange.opacity(0.75) : .white.opacity(0.18), lineWidth: 1) } .shadow(color: isFocused ? KTheme.orange.opacity(0.14) : .clear, radius: 12) .foregroundStyle(.white) .toolbar { ToolbarItemGroup(placement: .keyboard) { Spacer() Button(model.text("Gotowe", "Done")) { isFocused = false } .fontWeight(.semibold) } } } }