import SwiftUI struct CategoryModel: Identifiable { let id: String let title: String let systemIcon: String? let emojiIcon: String? } struct CategoryChip: View { let title: String let systemIcon: String? let emojiIcon: String? let isActive: Bool var body: some View { HStack(spacing: 8) { if let emojiIcon, emojiIcon.isEmpty == false { Text(emojiIcon) .font(.body) } else if let systemIcon, systemIcon.isEmpty == false { Image(systemName: systemIcon) .font(.caption) } Text(title) .font(AppTypography.heading3) } .foregroundStyle(isActive ? AppColors.textInverse : AppColors.textPrimary) .padding(.horizontal, 16) .padding(.vertical, 10) .background(isActive ? AppColors.primary : AppColors.surface) .clipShape(Capsule()) } } struct SearchBar: View { let placeholder: String @Binding var text: String var onFilterTap: () -> Void = {} var body: some View { HStack(spacing: 12) { Image(systemName: "magnifyingglass") .foregroundStyle(AppColors.textMuted) TextField(placeholder, text: $text) .appNoAutoCap() Spacer() Button(action: onFilterTap) { Image(systemName: "slider.horizontal.3") .foregroundStyle(AppColors.textMuted) } .buttonStyle(.plain) } .padding(.horizontal, 16) .frame(height: 52) .background(AppColors.surface) .clipShape(RoundedRectangle(cornerRadius: AppLayout.radiusLG, style: .continuous)) } } func clamp(value: CGFloat, lower: CGFloat, upper: CGFloat) -> CGFloat { min(max(value, lower), upper) }