diff --git a/Andromida.xcodeproj/xcshareddata/xcschemes/Andromida.xcscheme b/Andromida.xcodeproj/xcshareddata/xcschemes/Andromida.xcscheme
new file mode 100644
index 0000000..3cf4e0b
--- /dev/null
+++ b/Andromida.xcodeproj/xcshareddata/xcschemes/Andromida.xcscheme
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Andromida.xcodeproj/xcshareddata/xcschemes/AndromidaWidgetExtension.xcscheme b/Andromida.xcodeproj/xcshareddata/xcschemes/AndromidaWidgetExtension.xcscheme
new file mode 100644
index 0000000..d761e6c
--- /dev/null
+++ b/Andromida.xcodeproj/xcshareddata/xcschemes/AndromidaWidgetExtension.xcscheme
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Andromida.xcodeproj/xcuserdata/mattbruce.xcuserdatad/xcschemes/xcschememanagement.plist b/Andromida.xcodeproj/xcuserdata/mattbruce.xcuserdatad/xcschemes/xcschememanagement.plist
index 9ef0618..16ae3f5 100644
--- a/Andromida.xcodeproj/xcuserdata/mattbruce.xcuserdatad/xcschemes/xcschememanagement.plist
+++ b/Andromida.xcodeproj/xcuserdata/mattbruce.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -7,7 +7,7 @@
Andromida.xcscheme_^#shared#^_
orderHint
- 1
+ 2
AndromidaWidgetExtension.xcscheme_^#shared#^_
@@ -15,5 +15,18 @@
1
+ SuppressBuildableAutocreation
+
+ EAC04A972F26BAE8007F87EA
+
+ primary
+
+
+ EAC04D2E2F298D9B007F87EA
+
+ primary
+
+
+
diff --git a/Andromida/App/Localization/Localizable.xcstrings b/Andromida/App/Localization/Localizable.xcstrings
index e56d0a7..ba0c9e2 100644
--- a/Andromida/App/Localization/Localizable.xcstrings
+++ b/Andromida/App/Localization/Localizable.xcstrings
@@ -2734,6 +2734,94 @@
}
}
}
+ },
+ "Widgets" : {
+ "comment" : "Title for the widgets discovery card in onboarding.",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "Widgets"
+ }
+ }
+ }
+ },
+ "Add Andromida to your Home Screen for quick check-ins." : {
+ "comment" : "Description on the widget discovery card in onboarding.",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "Add Andromida to your Home Screen for quick check-ins."
+ }
+ }
+ }
+ },
+ "How to add" : {
+ "comment" : "CTA button label to show widget setup steps.",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "How to add"
+ }
+ }
+ }
+ },
+ "Add the widget" : {
+ "comment" : "Title for the widget setup sheet in onboarding.",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "Add the widget"
+ }
+ }
+ }
+ },
+ "Keep your rituals visible at a glance." : {
+ "comment" : "Subtitle for the widget setup sheet in onboarding.",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "Keep your rituals visible at a glance."
+ }
+ }
+ }
+ },
+ "Touch and hold your Home Screen." : {
+ "comment" : "Widget setup step: long-press Home Screen.",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "Touch and hold your Home Screen."
+ }
+ }
+ }
+ },
+ "Tap Edit, then Add Widget." : {
+ "comment" : "Widget setup step: tap Edit and Add Widget.",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "Tap Edit, then Add Widget."
+ }
+ }
+ }
+ },
+ "Search for Andromida and pick a size." : {
+ "comment" : "Widget setup step: search for the app and choose size.",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "Search for Andromida and pick a size."
+ }
+ }
+ }
}
},
"version" : "1.1"
diff --git a/Andromida/App/Views/Onboarding/WhatsNextStepView.swift b/Andromida/App/Views/Onboarding/WhatsNextStepView.swift
index 2aebab6..eb8260a 100644
--- a/Andromida/App/Views/Onboarding/WhatsNextStepView.swift
+++ b/Andromida/App/Views/Onboarding/WhatsNextStepView.swift
@@ -6,6 +6,7 @@ struct WhatsNextStepView: View {
let onComplete: () -> Void
@State private var animateContent = false
+ @State private var isShowingWidgetHelp = false
var body: some View {
VStack(spacing: Design.Spacing.xxLarge) {
@@ -55,6 +56,11 @@ struct WhatsNextStepView: View {
.opacity(animateContent ? 1 : 0)
.offset(y: animateContent ? 0 : 20)
.animation(.easeOut(duration: 0.4).delay(0.3), value: animateContent)
+
+ WidgetDiscoveryCard(onLearnMore: { isShowingWidgetHelp = true })
+ .opacity(animateContent ? 1 : 0)
+ .offset(y: animateContent ? 0 : 20)
+ .animation(.easeOut(duration: 0.4).delay(0.4), value: animateContent)
}
.padding(.horizontal, Design.Spacing.large)
@@ -80,6 +86,9 @@ struct WhatsNextStepView: View {
animateContent = true
}
}
+ .sheet(isPresented: $isShowingWidgetHelp) {
+ WidgetSetupSheet()
+ }
}
}
@@ -112,6 +121,87 @@ private struct FeatureHelpCard: View {
}
}
+/// A feature card with a CTA to learn how to add widgets.
+private struct WidgetDiscoveryCard: View {
+ let onLearnMore: () -> Void
+
+ var body: some View {
+ VStack(alignment: .leading, spacing: Design.Spacing.small) {
+ HStack(spacing: Design.Spacing.medium) {
+ SymbolIcon("square.grid.2x2.fill", size: .row, color: AppAccent.primary)
+ .frame(width: 44, height: 44)
+ .background(AppAccent.primary.opacity(0.15))
+ .clipShape(.rect(cornerRadius: Design.CornerRadius.medium))
+
+ VStack(alignment: .leading, spacing: Design.Spacing.xSmall) {
+ Text(String(localized: "Widgets")).styled(.heading, emphasis: .primary)
+ Text(String(localized: "Add Andromida to your Home Screen for quick check-ins."))
+ .styled(.caption, emphasis: .secondary)
+ }
+
+ Spacer()
+ }
+
+ Button(action: onLearnMore) {
+ Text(String(localized: "How to add")).styled(.caption, emphasis: .primary)
+ .padding(.vertical, Design.Spacing.xSmall)
+ .padding(.horizontal, Design.Spacing.small)
+ .background(AppAccent.primary.opacity(0.15))
+ .clipShape(.capsule)
+ }
+ .buttonStyle(.plain)
+ }
+ .padding(Design.Spacing.medium)
+ .background(AppSurface.card)
+ .clipShape(.rect(cornerRadius: Design.CornerRadius.large))
+ }
+}
+
+private struct WidgetSetupSheet: View {
+ var body: some View {
+ VStack(spacing: Design.Spacing.large) {
+ VStack(spacing: Design.Spacing.small) {
+ Text(String(localized: "Add the widget")).styled(.title2Bold, emphasis: .primary)
+ Text(String(localized: "Keep your rituals visible at a glance."))
+ .styled(.subheading, emphasis: .secondary)
+ .multilineTextAlignment(.center)
+ }
+
+ VStack(alignment: .leading, spacing: Design.Spacing.medium) {
+ WidgetStepRow(number: "1", text: String(localized: "Touch and hold your Home Screen."))
+ WidgetStepRow(number: "2", text: String(localized: "Tap Edit, then Add Widget."))
+ WidgetStepRow(number: "3", text: String(localized: "Search for Andromida and pick a size."))
+ }
+ .padding(.horizontal, Design.Spacing.large)
+
+ Spacer()
+ }
+ .padding(.top, Design.Spacing.xxLarge)
+ .presentationDetents([.medium])
+ }
+}
+
+private struct WidgetStepRow: View {
+ let number: String
+ let text: String
+
+ var body: some View {
+ HStack(alignment: .top, spacing: Design.Spacing.medium) {
+ Text(number).styled(.caption, emphasis: .inverse)
+ .frame(width: 28, height: 28)
+ .background(AppAccent.primary)
+ .clipShape(.circle)
+
+ Text(text).styled(.body, emphasis: .primary)
+
+ Spacer()
+ }
+ .padding(Design.Spacing.medium)
+ .background(AppSurface.card)
+ .clipShape(.rect(cornerRadius: Design.CornerRadius.large))
+ }
+}
+
#Preview {
ZStack {
LinearGradient(