From 8892124b8e4f8f9fd70e9d7709659cef34c84db3 Mon Sep 17 00:00:00 2001 From: Yusuf Suleman Date: Fri, 3 Apr 2026 16:35:39 -0500 Subject: [PATCH] revert: restore warm Atelier design, remove Liquid Glass changes Reverts all Liquid Glass styling back to the original warm beige/brown Atelier design system. Deployment target back to iOS 17.0. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../Platform.xcodeproj/project.pbxproj | 4 +- ios/Platform/Platform/ContentView.swift | 20 +++--- .../Assistant/AssistantChatView.swift | 28 +++++--- .../Platform/Features/Auth/LoginView.swift | 4 +- .../Features/Feedback/FeedbackView.swift | 22 +++--- .../Features/Fitness/Views/AddFoodSheet.swift | 22 +++--- .../Fitness/Views/EntryDetailView.swift | 22 ++++-- .../Fitness/Views/FitnessTabView.swift | 71 ++++++++++--------- .../Fitness/Views/FoodLibraryView.swift | 4 +- .../Fitness/Views/FoodSearchView.swift | 11 ++- .../Features/Fitness/Views/GoalsView.swift | 11 +-- .../Fitness/Views/MealSectionView.swift | 29 ++++---- .../Fitness/Views/TemplatesView.swift | 5 +- .../Features/Fitness/Views/TodayView.swift | 9 ++- .../Platform/Features/Home/HomeView.swift | 13 +++- .../Shared/Extensions/Color+Extensions.swift | 18 ++--- 16 files changed, 179 insertions(+), 114 deletions(-) diff --git a/ios/Platform/Platform.xcodeproj/project.pbxproj b/ios/Platform/Platform.xcodeproj/project.pbxproj index 9f8025e..fcda963 100644 --- a/ios/Platform/Platform.xcodeproj/project.pbxproj +++ b/ios/Platform/Platform.xcodeproj/project.pbxproj @@ -427,7 +427,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 26.0; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -484,7 +484,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 26.0; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; diff --git a/ios/Platform/Platform/ContentView.swift b/ios/Platform/Platform/ContentView.swift index 78c7413..ca992cf 100644 --- a/ios/Platform/Platform/ContentView.swift +++ b/ios/Platform/Platform/ContentView.swift @@ -9,6 +9,7 @@ struct ContentView: View { if auth.isCheckingAuth { ProgressView() .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color.canvas) } else if auth.isLoggedIn { MainTabView() } else { @@ -38,26 +39,27 @@ struct MainTabView: View { .tag(1) } .tint(Color.accentWarm) - .tabBarMinimizeBehavior(.onScrollDown) // Floating buttons VStack { Spacer() HStack(alignment: .bottom) { + // Feedback button (subtle, bottom-left) FeedbackButton() .padding(.leading, 20) Spacer() + // Add food button (prominent, bottom-right) Button { showAssistant = true } label: { Image(systemName: "plus") .font(.title2.weight(.semibold)) .foregroundStyle(.white) .frame(width: 56, height: 56) + .background(Color.accentWarm) + .clipShape(Circle()) + .shadow(color: .black.opacity(0.2), radius: 8, y: 4) } - .buttonStyle(.glassProminent) - .tint(Color.accentWarm) - .clipShape(Circle()) .padding(.trailing, 20) } .padding(.bottom, 70) @@ -110,11 +112,12 @@ struct AssistantSheetView: View { tabButton("Quick Add", icon: "magnifyingglass", index: 1) } .padding(4) - .background(.ultraThinMaterial) + .background(Color.textTertiary.opacity(0.08)) .clipShape(Capsule()) .padding(.horizontal, 40) } .padding(.bottom, 12) + .background(Color.canvas) if selectedMode == 0 { AssistantChatView(onFoodAdded: onFoodAdded) @@ -122,6 +125,7 @@ struct AssistantSheetView: View { FoodSearchView(isSheet: true, onFoodAdded: onFoodAdded) } } + .background(Color.canvas) .presentationDetents([.large]) } @@ -136,11 +140,7 @@ struct AssistantSheetView: View { .foregroundStyle(selectedMode == index ? Color.textPrimary : Color.textTertiary) .padding(.horizontal, 16) .padding(.vertical, 8) - .background { - if selectedMode == index { - Capsule().fill(.thinMaterial) - } - } + .background(selectedMode == index ? Color.surfaceCard : Color.clear) .clipShape(Capsule()) } } diff --git a/ios/Platform/Platform/Features/Assistant/AssistantChatView.swift b/ios/Platform/Platform/Features/Assistant/AssistantChatView.swift index 6c5bd76..eb80eff 100644 --- a/ios/Platform/Platform/Features/Assistant/AssistantChatView.swift +++ b/ios/Platform/Platform/Features/Assistant/AssistantChatView.swift @@ -11,6 +11,7 @@ struct AssistantChatView: View { ScrollViewReader { proxy in ScrollView { LazyVStack(spacing: 8) { + // Welcome state when no messages if vm.messages.isEmpty { VStack(spacing: 16) { Spacer(minLength: 60) @@ -36,10 +37,12 @@ struct AssistantChatView: View { .id(message.id) } + // Draft card if let draft = vm.currentDraft, !vm.applied { draftCard(draft) } + // Multiple drafts if vm.currentDrafts.count > 1 && !vm.applied { multipleDraftsCard } @@ -110,8 +113,9 @@ struct AssistantChatView: View { } .padding(.horizontal, 16) .padding(.vertical, 10) - .background(.bar) + .background(Color.surfaceCard) } + .background(Color.canvas) .onChange(of: vm.selectedPhoto) { Task { await vm.handlePhotoSelection() } } @@ -137,10 +141,10 @@ struct AssistantChatView: View { .padding(.vertical, 10) .background( message.role == "user" - ? AnyShapeStyle(Color.accentWarm) - : AnyShapeStyle(.thinMaterial) + ? Color.accentWarm + : Color.surfaceSheet ) - .clipShape(RoundedRectangle(cornerRadius: 18)) + .clipShape(RoundedRectangle(cornerRadius: 16)) if message.role == "assistant" { Spacer(minLength: 60) } } @@ -185,12 +189,14 @@ struct AssistantChatView: View { .foregroundStyle(.white) .frame(maxWidth: .infinity) .padding(.vertical, 10) + .background(Color.emerald) + .clipShape(RoundedRectangle(cornerRadius: 10)) } - .buttonStyle(.glassProminent) - .tint(Color.emerald) } .padding() - .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 20)) + .background(Color.surfaceCard) + .clipShape(RoundedRectangle(cornerRadius: 14)) + .shadow(color: .black.opacity(0.06), radius: 6, y: 2) .padding(.horizontal, 12) } @@ -229,12 +235,14 @@ struct AssistantChatView: View { .foregroundStyle(.white) .frame(maxWidth: .infinity) .padding(.vertical, 10) + .background(Color.emerald) + .clipShape(RoundedRectangle(cornerRadius: 10)) } - .buttonStyle(.glassProminent) - .tint(Color.emerald) } .padding() - .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 20)) + .background(Color.surfaceCard) + .clipShape(RoundedRectangle(cornerRadius: 14)) + .shadow(color: .black.opacity(0.06), radius: 6, y: 2) .padding(.horizontal, 12) } diff --git a/ios/Platform/Platform/Features/Auth/LoginView.swift b/ios/Platform/Platform/Features/Auth/LoginView.swift index 801e52b..5682ed2 100644 --- a/ios/Platform/Platform/Features/Auth/LoginView.swift +++ b/ios/Platform/Platform/Features/Auth/LoginView.swift @@ -57,8 +57,9 @@ struct LoginView: View { } .frame(maxWidth: .infinity) .frame(height: 48) + .background(Color.accentWarm) .foregroundStyle(.white) - .background(Color.accentWarm, in: RoundedRectangle(cornerRadius: 14)) + .clipShape(RoundedRectangle(cornerRadius: 12)) .disabled(username.isEmpty || password.isEmpty || isLoading) .opacity(username.isEmpty || password.isEmpty ? 0.6 : 1) } @@ -67,5 +68,6 @@ struct LoginView: View { Spacer() Spacer() } + .background(Color.canvas) } } diff --git a/ios/Platform/Platform/Features/Feedback/FeedbackView.swift b/ios/Platform/Platform/Features/Feedback/FeedbackView.swift index 03eb7e1..091fd69 100644 --- a/ios/Platform/Platform/Features/Feedback/FeedbackView.swift +++ b/ios/Platform/Platform/Features/Feedback/FeedbackView.swift @@ -10,9 +10,10 @@ struct FeedbackButton: View { .font(.system(size: 14)) .foregroundStyle(Color.textTertiary) .frame(width: 32, height: 32) + .background(Color.surfaceCard.opacity(0.8)) + .clipShape(Circle()) + .shadow(color: .black.opacity(0.08), radius: 4, y: 2) } - .buttonStyle(.glass) - .clipShape(Circle()) .sheet(isPresented: $showSheet) { FeedbackSheet() .presentationDetents([.large, .medium]) @@ -60,7 +61,12 @@ struct FeedbackSheet: View { .font(.body) .scrollContentBackground(.hidden) .padding(12) - .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 14)) + .background(Color.canvas) + .clipShape(RoundedRectangle(cornerRadius: 12)) + .overlay( + RoundedRectangle(cornerRadius: 12) + .stroke(Color.textTertiary.opacity(0.2), lineWidth: 1) + ) // Photo attachment HStack { @@ -74,7 +80,8 @@ struct FeedbackSheet: View { .foregroundStyle(Color.accentWarm) .padding(.horizontal, 12) .padding(.vertical, 8) - .background(Color.accentWarm.opacity(0.1), in: Capsule()) + .background(Color.accentWarm.opacity(0.1)) + .clipShape(Capsule()) } if let preview = photoPreview { @@ -116,15 +123,14 @@ struct FeedbackSheet: View { } .frame(maxWidth: .infinity) .frame(height: 48) + .background(text.trimmingCharacters(in: .whitespaces).isEmpty ? Color.textTertiary : Color.accentWarm) .foregroundStyle(.white) - .background( - text.trimmingCharacters(in: .whitespaces).isEmpty ? Color.textTertiary : Color.accentWarm, - in: RoundedRectangle(cornerRadius: 14) - ) + .clipShape(RoundedRectangle(cornerRadius: 12)) .disabled(text.trimmingCharacters(in: .whitespaces).isEmpty || isSending) } } .padding() + .background(Color.surfaceCard) .onChange(of: selectedPhoto) { Task { if let item = selectedPhoto, diff --git a/ios/Platform/Platform/Features/Fitness/Views/AddFoodSheet.swift b/ios/Platform/Platform/Features/Fitness/Views/AddFoodSheet.swift index 6f0b632..0fe38cb 100644 --- a/ios/Platform/Platform/Features/Fitness/Views/AddFoodSheet.swift +++ b/ios/Platform/Platform/Features/Fitness/Views/AddFoodSheet.swift @@ -80,6 +80,7 @@ struct AddFoodSheet: View { } .frame(maxWidth: .infinity) + // Serving picker if let servings = food.servings, !servings.isEmpty { Picker("Serving", selection: $selectedServingId) { Text("Base (\(food.baseUnit))").tag(nil as String?) @@ -91,7 +92,8 @@ struct AddFoodSheet: View { } } .padding() - .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 16)) + .background(Color.surfaceCard) + .clipShape(RoundedRectangle(cornerRadius: 12)) // Meal picker VStack(alignment: .leading, spacing: 8) { @@ -114,15 +116,15 @@ struct AddFoodSheet: View { .padding(.vertical, 10) .background(selectedMeal == meal ? Color.mealColor(for: meal.rawValue).opacity(0.15) - : .clear + : Color.surfaceCard ) .foregroundStyle(selectedMeal == meal ? Color.mealColor(for: meal.rawValue) : Color.textSecondary ) - .clipShape(RoundedRectangle(cornerRadius: 12)) + .clipShape(RoundedRectangle(cornerRadius: 10)) .overlay( - RoundedRectangle(cornerRadius: 12) + RoundedRectangle(cornerRadius: 10) .stroke(selectedMeal == meal ? Color.mealColor(for: meal.rawValue).opacity(0.3) : Color.clear, lineWidth: 1 @@ -133,7 +135,8 @@ struct AddFoodSheet: View { } } .padding() - .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 16)) + .background(Color.surfaceCard) + .clipShape(RoundedRectangle(cornerRadius: 12)) // Nutrition preview VStack(spacing: 8) { @@ -154,7 +157,8 @@ struct AddFoodSheet: View { } } .padding() - .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 16)) + .background(Color.surfaceCard) + .clipShape(RoundedRectangle(cornerRadius: 12)) if let error { Text(error) @@ -165,6 +169,7 @@ struct AddFoodSheet: View { .padding() } .scrollDismissesKeyboard(.immediately) + .background(Color.canvas) .safeAreaInset(edge: .bottom) { Button { addEntry() @@ -179,12 +184,13 @@ struct AddFoodSheet: View { } .frame(maxWidth: .infinity) .frame(height: 50) + .background(Color.accentWarm) .foregroundStyle(.white) - .background(Color.accentWarm, in: RoundedRectangle(cornerRadius: 16)) + .clipShape(RoundedRectangle(cornerRadius: 12)) .disabled(isAdding) .padding(.horizontal) .padding(.bottom, 8) - .background(.bar) + .background(Color.canvas) } .navigationTitle("Add Food") .navigationBarTitleDisplayMode(.inline) diff --git a/ios/Platform/Platform/Features/Fitness/Views/EntryDetailView.swift b/ios/Platform/Platform/Features/Fitness/Views/EntryDetailView.swift index 1a263e0..d947568 100644 --- a/ios/Platform/Platform/Features/Fitness/Views/EntryDetailView.swift +++ b/ios/Platform/Platform/Features/Fitness/Views/EntryDetailView.swift @@ -48,6 +48,7 @@ struct EntryDetailView: View { .foregroundStyle(Color.textPrimary) .frame(maxWidth: .infinity, alignment: .leading) + // Meal type picker VStack(alignment: .leading, spacing: 8) { Text("Meal") .font(.subheadline.weight(.medium)) @@ -61,6 +62,7 @@ struct EntryDetailView: View { .pickerStyle(.segmented) } + // Quantity field VStack(alignment: .leading, spacing: 8) { Text("Quantity (\(entry.unit))") .font(.subheadline.weight(.medium)) @@ -83,7 +85,8 @@ struct EntryDetailView: View { .keyboardType(.decimalPad) .frame(width: 80) .padding(.vertical, 8) - .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 10)) + .background(Color.canvas) + .clipShape(RoundedRectangle(cornerRadius: 8)) Button { if let val = Double(editQuantity) { @@ -130,13 +133,15 @@ struct EntryDetailView: View { .foregroundStyle(.white) .frame(maxWidth: .infinity) .padding(.vertical, 12) + .background(Color.emerald) + .clipShape(RoundedRectangle(cornerRadius: 10)) } - .buttonStyle(.glassProminent) - .tint(Color.emerald) .disabled(isSaving) } .padding() - .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 20)) + .background(Color.surfaceCard) + .clipShape(RoundedRectangle(cornerRadius: 14)) + .shadow(color: .black.opacity(0.04), radius: 6, y: 2) // Nutrition grid LazyVGrid(columns: [ @@ -152,7 +157,8 @@ struct EntryDetailView: View { nutritionCell("Fiber", value: entry.fiber, unit: "g", color: .green) } .padding() - .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 20)) + .background(Color.surfaceCard) + .clipShape(RoundedRectangle(cornerRadius: 14)) // Metadata VStack(spacing: 8) { @@ -164,7 +170,8 @@ struct EntryDetailView: View { } } .padding() - .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 20)) + .background(Color.surfaceCard) + .clipShape(RoundedRectangle(cornerRadius: 14)) // Delete button Button(role: .destructive) { @@ -175,11 +182,12 @@ struct EntryDetailView: View { .frame(maxWidth: .infinity) .frame(height: 48) } - .buttonStyle(.glass) + .buttonStyle(.borderedProminent) .tint(.red) } .padding() } + .background(Color.canvas) .navigationTitle("Entry Detail") .navigationBarTitleDisplayMode(.inline) .alert("Delete Entry?", isPresented: $showDeleteConfirmation) { diff --git a/ios/Platform/Platform/Features/Fitness/Views/FitnessTabView.swift b/ios/Platform/Platform/Features/Fitness/Views/FitnessTabView.swift index 7a5adde..1962bd8 100644 --- a/ios/Platform/Platform/Features/Fitness/Views/FitnessTabView.swift +++ b/ios/Platform/Platform/Features/Fitness/Views/FitnessTabView.swift @@ -5,45 +5,46 @@ struct FitnessTabView: View { var body: some View { NavigationStack { - VStack(spacing: 0) { - // Sub-tab selector - HStack(spacing: 0) { - ForEach(Array(fitnessSubTabs.enumerated()), id: \.offset) { index, tab in - Button { - withAnimation(.easeInOut(duration: 0.2)) { - selectedSubTab = index - } - } label: { - Text(tab) - .font(.subheadline.weight(selectedSubTab == index ? .semibold : .regular)) - .foregroundStyle(selectedSubTab == index ? Color.accentWarm : Color.textSecondary) - .padding(.vertical, 10) - .padding(.horizontal, 16) - .background { - if selectedSubTab == index { - Capsule() - .fill(.ultraThinMaterial) - } - } + VStack(spacing: 0) { + // Sub-tab selector + HStack(spacing: 0) { + ForEach(Array(fitnessSubTabs.enumerated()), id: \.offset) { index, tab in + Button { + withAnimation(.easeInOut(duration: 0.2)) { + selectedSubTab = index } + } label: { + Text(tab) + .font(.subheadline.weight(selectedSubTab == index ? .semibold : .regular)) + .foregroundStyle(selectedSubTab == index ? Color.accentWarm : Color.textSecondary) + .padding(.vertical, 10) + .padding(.horizontal, 16) + .background { + if selectedSubTab == index { + Capsule() + .fill(Color.accentWarm.opacity(0.12)) + } + } } } - .padding(.horizontal) - .padding(.top, 8) - - Group { - switch selectedSubTab { - case 0: TodayView() - case 1: TemplatesView() - case 2: GoalsView() - case 3: FoodLibraryView() - default: TodayView() - } - } - .animation(.easeInOut(duration: 0.2), value: selectedSubTab) } - .navigationTitle("Fitness") - .navigationBarTitleDisplayMode(.large) + .padding(.horizontal) + .padding(.top, 8) + + // Content — tap tabs to switch (no page swipe, preserves swipe-to-delete) + Group { + switch selectedSubTab { + case 0: TodayView() + case 1: TemplatesView() + case 2: GoalsView() + case 3: FoodLibraryView() + default: TodayView() + } + } + .animation(.easeInOut(duration: 0.2), value: selectedSubTab) + } + .background(Color.canvas) + .navigationBarHidden(true) } } diff --git a/ios/Platform/Platform/Features/Fitness/Views/FoodLibraryView.swift b/ios/Platform/Platform/Features/Fitness/Views/FoodLibraryView.swift index cdb43fa..e5303cc 100644 --- a/ios/Platform/Platform/Features/Fitness/Views/FoodLibraryView.swift +++ b/ios/Platform/Platform/Features/Fitness/Views/FoodLibraryView.swift @@ -24,7 +24,8 @@ struct FoodLibraryView: View { } } .padding(12) - .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 12)) + .background(Color.surfaceCard) + .clipShape(RoundedRectangle(cornerRadius: 10)) .padding(.horizontal) .padding(.top, 8) @@ -81,6 +82,7 @@ struct FoodLibraryView: View { } } } + .background(Color.canvas) .task { await vm.loadInitial() } diff --git a/ios/Platform/Platform/Features/Fitness/Views/FoodSearchView.swift b/ios/Platform/Platform/Features/Fitness/Views/FoodSearchView.swift index f6da33f..9079103 100644 --- a/ios/Platform/Platform/Features/Fitness/Views/FoodSearchView.swift +++ b/ios/Platform/Platform/Features/Fitness/Views/FoodSearchView.swift @@ -26,18 +26,22 @@ struct FoodSearchView: View { } } .padding(12) - .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 12)) + .background(Color.surfaceCard) + .clipShape(RoundedRectangle(cornerRadius: 10)) .padding(.horizontal) .padding(.top, 8) if vm.isLoadingInitial { LoadingView() } else if !vm.searchText.isEmpty { + // Search results searchResultsList } else { + // Recent + All defaultList } } + .background(Color.canvas) .task { await vm.loadInitial() } @@ -128,11 +132,14 @@ struct FoodSearchView: View { private func recentFoodRow(_ recent: RecentFood) -> some View { Button { + // Navigate to add sheet by loading the full food Task { do { let food = try await FitnessAPI().getFood(id: recent.foodId) selectedFood = food - } catch {} + } catch { + // Silently fail + } } } label: { HStack { diff --git a/ios/Platform/Platform/Features/Fitness/Views/GoalsView.swift b/ios/Platform/Platform/Features/Fitness/Views/GoalsView.swift index bf9dc59..f1a47f0 100644 --- a/ios/Platform/Platform/Features/Fitness/Views/GoalsView.swift +++ b/ios/Platform/Platform/Features/Fitness/Views/GoalsView.swift @@ -23,6 +23,7 @@ struct GoalsView: View { .padding(.horizontal) .padding(.top, 8) } + .background(Color.canvas) .task { await vm.load() } @@ -91,13 +92,15 @@ struct GoalsView: View { .foregroundStyle(.white) .frame(maxWidth: .infinity) .padding(.vertical, 12) + .background(Color.emerald) + .clipShape(RoundedRectangle(cornerRadius: 10)) } - .buttonStyle(.glassProminent) - .tint(Color.emerald) .disabled(vm.isSaving) } .padding() - .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 20)) + .background(Color.surfaceCard) + .clipShape(RoundedRectangle(cornerRadius: 14)) + .shadow(color: .black.opacity(0.04), radius: 6, y: 2) } private func goalField(_ label: String, text: Binding, unit: String, color: Color) -> some View { @@ -117,6 +120,6 @@ struct GoalsView: View { .frame(maxWidth: .infinity) .padding(.vertical, 12) .background(color.opacity(0.06)) - .clipShape(RoundedRectangle(cornerRadius: 12)) + .clipShape(RoundedRectangle(cornerRadius: 10)) } } diff --git a/ios/Platform/Platform/Features/Fitness/Views/MealSectionView.swift b/ios/Platform/Platform/Features/Fitness/Views/MealSectionView.swift index 9639642..a56c4f4 100644 --- a/ios/Platform/Platform/Features/Fitness/Views/MealSectionView.swift +++ b/ios/Platform/Platform/Features/Fitness/Views/MealSectionView.swift @@ -20,11 +20,13 @@ struct MealSectionView: View { } } label: { HStack(spacing: 0) { + // Colored accent bar RoundedRectangle(cornerRadius: 2) .fill(Color.mealColor(for: mealType.rawValue)) .frame(width: 4, height: 40) .padding(.trailing, 12) + // Meal icon in tinted circle Image(systemName: mealType.icon) .font(.title3.weight(.semibold)) .foregroundStyle(Color.mealColor(for: mealType.rawValue)) @@ -45,14 +47,12 @@ struct MealSectionView: View { Spacer() - HStack(spacing: 2) { - Text("\(Int(totalCalories))") - .font(.title3.weight(.bold)) - .foregroundStyle(Color.mealColor(for: mealType.rawValue)) - Text("kcal") - .font(.caption.weight(.medium)) - .foregroundStyle(Color.textSecondary) - } + Text("\(Int(totalCalories))") + .font(.title3.weight(.bold)) + .foregroundStyle(Color.mealColor(for: mealType.rawValue)) + + Text(" kcal") + .font(.caption.weight(.medium)) + .foregroundStyle(Color.textSecondary) Image(systemName: "chevron.right") .font(.caption.weight(.medium)) @@ -63,14 +63,14 @@ struct MealSectionView: View { .padding(.horizontal, 16) .padding(.vertical, 14) .background(Color.mealColor(for: mealType.rawValue).opacity(0.04)) - .clipShape(RoundedRectangle(cornerRadius: 16)) + .clipShape(RoundedRectangle(cornerRadius: 14)) } if isExpanded { ForEach(entries) { entry in SwipeToDeleteRow( onDelete: { onDelete(entry) }, - onTap: { }, + onTap: { /* handled by NavigationLink */ }, destination: { EntryDetailView(entry: entry, onDelete: { onDelete(entry) }) } ) { entryRow(entry) @@ -78,7 +78,9 @@ struct MealSectionView: View { } } } - .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 20)) + .background(Color.surfaceCard) + .clipShape(RoundedRectangle(cornerRadius: 14)) + .shadow(color: .black.opacity(0.04), radius: 6, y: 2) .padding(.horizontal) } @@ -110,7 +112,7 @@ struct MealSectionView: View { } .padding(.horizontal, 16) .padding(.vertical, 10) - .background(Color(.systemBackground)) + .background(Color.surfaceCard) } } @@ -128,6 +130,7 @@ struct SwipeToDeleteRow: View { var body: some View { ZStack(alignment: .trailing) { + // Delete button background HStack { Spacer() Button { @@ -145,6 +148,7 @@ struct SwipeToDeleteRow: View { .background(Color.red) } + // Content row content() .offset(x: offset) .navigationDestination(isPresented: $showDetail) { @@ -154,6 +158,7 @@ struct SwipeToDeleteRow: View { if !isSwiping { showDetail = true } else { + // Close swipe withAnimation(.easeOut(duration: 0.2)) { offset = 0 isSwiping = false diff --git a/ios/Platform/Platform/Features/Fitness/Views/TemplatesView.swift b/ios/Platform/Platform/Features/Fitness/Views/TemplatesView.swift index 65a8621..bcff6b0 100644 --- a/ios/Platform/Platform/Features/Fitness/Views/TemplatesView.swift +++ b/ios/Platform/Platform/Features/Fitness/Views/TemplatesView.swift @@ -39,6 +39,7 @@ struct TemplatesView: View { .padding(.horizontal) .padding(.top, 8) } + .background(Color.canvas) .task { await vm.load() } @@ -117,6 +118,8 @@ struct TemplatesView: View { } } .padding() - .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 16)) + .background(Color.surfaceCard) + .clipShape(RoundedRectangle(cornerRadius: 12)) + .shadow(color: .black.opacity(0.04), radius: 4, y: 2) } } diff --git a/ios/Platform/Platform/Features/Fitness/Views/TodayView.swift b/ios/Platform/Platform/Features/Fitness/Views/TodayView.swift index be5cc3e..dc9c4a9 100644 --- a/ios/Platform/Platform/Features/Fitness/Views/TodayView.swift +++ b/ios/Platform/Platform/Features/Fitness/Views/TodayView.swift @@ -6,9 +6,13 @@ struct TodayView: View { var body: some View { ScrollView { VStack(spacing: 16) { + // Date selector dateSelector + + // Macro summary macroSummary + // Meal sections if vm.entries.isEmpty && !vm.isLoading { EmptyStateView( icon: "fork.knife", @@ -34,6 +38,7 @@ struct TodayView: View { .refreshable { await vm.load() } + .background(Color.canvas) .task { await vm.load() } @@ -123,7 +128,9 @@ struct TodayView: View { } } .padding(16) - .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 20)) + .background(Color.surfaceCard) + .clipShape(RoundedRectangle(cornerRadius: 14)) + .shadow(color: .black.opacity(0.04), radius: 6, y: 2) .padding(.horizontal) } } diff --git a/ios/Platform/Platform/Features/Home/HomeView.swift b/ios/Platform/Platform/Features/Home/HomeView.swift index b7dd77a..ab5cb2a 100644 --- a/ios/Platform/Platform/Features/Home/HomeView.swift +++ b/ios/Platform/Platform/Features/Home/HomeView.swift @@ -64,7 +64,7 @@ struct HomeView: View { .padding(.horizontal) .padding(.top, 16) - // Widget grid + // Widget grid — half width, tap to go to fitness HStack(spacing: 12) { Button { selectedTab = 1 } label: { calorieWidget @@ -99,6 +99,7 @@ struct HomeView: View { .textCase(.uppercase) .tracking(0.5) + // Animated ring ZStack { Circle() .stroke(Color.emerald.opacity(0.15), lineWidth: 9) @@ -129,8 +130,14 @@ struct HomeView: View { .frame(maxWidth: .infinity) .aspectRatio(1, contentMode: .fit) .background { - RoundedRectangle(cornerRadius: 20) - .fill(.ultraThinMaterial) + if vm.hasBackground { + RoundedRectangle(cornerRadius: 16) + .fill(.ultraThinMaterial) + } else { + RoundedRectangle(cornerRadius: 16) + .fill(Color.surfaceCard) + .shadow(color: .black.opacity(0.05), radius: 8, y: 2) + } } } } diff --git a/ios/Platform/Platform/Shared/Extensions/Color+Extensions.swift b/ios/Platform/Platform/Shared/Extensions/Color+Extensions.swift index 165c68f..56b3eba 100644 --- a/ios/Platform/Platform/Shared/Extensions/Color+Extensions.swift +++ b/ios/Platform/Platform/Shared/Extensions/Color+Extensions.swift @@ -1,21 +1,21 @@ import SwiftUI extension Color { - // MARK: - Canvas / Background (system-adaptive for Liquid Glass) - static let canvas = Color(.systemBackground) + // MARK: - Canvas / Background + static let canvas = Color(red: 0.96, green: 0.94, blue: 0.90) // #F5EFE6 // MARK: - Accent static let accentWarm = Color(red: 0.545, green: 0.412, blue: 0.078) // #8B6914 static let emerald = Color(red: 0.020, green: 0.588, blue: 0.412) // #059669 - // MARK: - Surfaces (system-adaptive) - static let surfaceCard = Color(.secondarySystemGroupedBackground) - static let surfaceSheet = Color(.systemGroupedBackground) + // MARK: - Surfaces + static let surfaceCard = Color(red: 255/255, green: 252/255, blue: 248/255) // warm white + static let surfaceSheet = Color(red: 0.98, green: 0.97, blue: 0.95) - // MARK: - Text (system-adaptive for Liquid Glass + dark mode) - static let textPrimary = Color(.label) - static let textSecondary = Color(.secondaryLabel) - static let textTertiary = Color(.tertiaryLabel) + // MARK: - Text + static let textPrimary = Color(red: 0.12, green: 0.12, blue: 0.12) + static let textSecondary = Color(red: 0.45, green: 0.45, blue: 0.45) + static let textTertiary = Color(red: 0.65, green: 0.65, blue: 0.65) // MARK: - Meal Colors static let mealBreakfast = Color(red: 1.0, green: 0.72, blue: 0.27) // warm orange