import SwiftUI struct LadillCard: View { @ViewBuilder let content: Content var body: some View { content .padding(16) .frame(maxWidth: .infinity, alignment: .leading) .background(LadillColors.surface) .overlay(RoundedRectangle(cornerRadius: 16).stroke(LadillColors.border, lineWidth: 1)) .clipShape(RoundedRectangle(cornerRadius: 16)) } } struct StatCard: View { let label: String let value: String var accent = false var body: some View { VStack(alignment: .leading, spacing: 4) { Text(label) .font(.ladill(size: 12, weight: .medium)) .foregroundStyle(accent ? LadillColors.indigoText : LadillColors.muted) Text(value) .font(.ladill(size: 22, weight: .semibold)) .foregroundStyle(accent ? LadillColors.money : LadillColors.ink) } .padding(16) .frame(maxWidth: .infinity, alignment: .leading) .background(accent ? LadillColors.indigoSoft : LadillColors.surface) .overlay( RoundedRectangle(cornerRadius: 16) .stroke(accent ? LadillColors.indigo.opacity(0.2) : LadillColors.border, lineWidth: 1) ) .clipShape(RoundedRectangle(cornerRadius: 16)) } } struct UserAvatar: View { let name: String? let photoURL: String? var size: CGFloat = 40 var onTap: (() -> Void)? var body: some View { let content = ZStack { Circle() .fill(LadillColors.indigoSoft) if let initial = name?.trimmingCharacters(in: .whitespaces).first { Text(String(initial).uppercased()) .font(.ladill(size: size * 0.38, weight: .semibold)) .foregroundStyle(LadillColors.indigoText) } else { Image(systemName: "person.fill") .font(.system(size: size * 0.4)) .foregroundStyle(LadillColors.indigoText) } } .frame(width: size, height: size) if let onTap { Button(action: onTap) { content }.buttonStyle(.plain) } else { content } } } struct LoadingView: View { var body: some View { VStack(spacing: 12) { ProgressView().tint(LadillColors.indigo) Text("Loading…") .font(.ladill(size: 14)) .foregroundStyle(LadillColors.muted) } .frame(maxWidth: .infinity) .padding(.vertical, 40) } } struct ErrorView: View { let message: String let onRetry: () -> Void var body: some View { VStack(spacing: 12) { Text(message) .font(.ladill(size: 14)) .foregroundStyle(LadillColors.muted) .multilineTextAlignment(.center) Button("Try again", action: onRetry) .font(.ladill(size: 14, weight: .semibold)) .foregroundStyle(LadillColors.indigo) } .frame(maxWidth: .infinity) .padding(.vertical, 40) .padding(.horizontal, 20) } }