Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
76dda638cc
commit
76d484a1b3
@ -21,17 +21,14 @@ struct EmptyStateCardView: View {
|
|||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: Design.Spacing.medium) {
|
VStack(alignment: .leading, spacing: Design.Spacing.medium) {
|
||||||
TitleLabel(title, style: .displaySmall, color: AppTextColors.primary)
|
StyledLabel(title, .title2Bold, emphasis: .custom(AppTextColors.primary))
|
||||||
|
|
||||||
// Exception: Uses .bodyLarge which isn't a standard BodyLabel weight
|
StyledLabel(message, .body, emphasis: .custom(AppTextColors.secondary))
|
||||||
Text(message)
|
|
||||||
.font(Design.Typography.bodyLarge)
|
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
|
||||||
|
|
||||||
Button(action: action) {
|
Button(action: action) {
|
||||||
// Exception: Needs .frame() modifiers
|
// Needs .frame() modifiers
|
||||||
Text(actionTitle)
|
Text(actionTitle)
|
||||||
.font(Design.Typography.headline)
|
.typography(.heading)
|
||||||
.foregroundStyle(AppTextColors.primary)
|
.foregroundStyle(AppTextColors.primary)
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
.frame(height: AppMetrics.Size.buttonHeight)
|
.frame(height: AppMetrics.Size.buttonHeight)
|
||||||
|
|||||||
@ -12,9 +12,9 @@ struct SectionHeaderView: View {
|
|||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: Design.Spacing.xxxSmall) {
|
VStack(alignment: .leading, spacing: Design.Spacing.xxxSmall) {
|
||||||
TitleLabel(title, style: .headline, color: AppTextColors.primary)
|
StyledLabel(title, .heading, emphasis: .custom(AppTextColors.primary))
|
||||||
if let subtitle {
|
if let subtitle {
|
||||||
BodyLabel(subtitle, emphasis: .secondary, color: AppTextColors.secondary)
|
StyledLabel(subtitle, .subheading, emphasis: .custom(AppTextColors.secondary))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
|||||||
@ -22,7 +22,7 @@ struct InsightCardView: View {
|
|||||||
private var cardContent: some View {
|
private var cardContent: some View {
|
||||||
VStack(alignment: .leading, spacing: Design.Spacing.medium) {
|
VStack(alignment: .leading, spacing: Design.Spacing.medium) {
|
||||||
HStack {
|
HStack {
|
||||||
BodyLabel(card.title, weight: .bold, color: AppTextColors.secondary)
|
StyledLabel(card.title, .subheadingEmphasis, emphasis: .custom(AppTextColors.secondary))
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
@ -32,11 +32,11 @@ struct InsightCardView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Show value prominently
|
// Show value prominently
|
||||||
TitleLabel(card.value, style: .displayMedium, color: AppTextColors.primary)
|
StyledLabel(card.value, .titleBold, emphasis: .custom(AppTextColors.primary))
|
||||||
|
|
||||||
// Show caption if present (non-chart cards)
|
// Show caption if present (non-chart cards)
|
||||||
if !card.caption.isEmpty {
|
if !card.caption.isEmpty {
|
||||||
CaptionLabel(card.caption, color: AppTextColors.secondary)
|
StyledLabel(card.caption, .caption, emphasis: .custom(AppTextColors.secondary))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show full-width mini bar chart at bottom (Athlytic style)
|
// Show full-width mini bar chart at bottom (Athlytic style)
|
||||||
|
|||||||
@ -89,7 +89,7 @@ struct InsightDetailSheet: View {
|
|||||||
.foregroundStyle(AppTextColors.primary)
|
.foregroundStyle(AppTextColors.primary)
|
||||||
|
|
||||||
Text(card.caption)
|
Text(card.caption)
|
||||||
.font(Design.Typography.body)
|
.typography(.subheading)
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
.foregroundStyle(AppTextColors.secondary)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
|
|||||||
@ -21,7 +21,7 @@ struct GoalSelectionStepView: View {
|
|||||||
// Header
|
// Header
|
||||||
VStack(spacing: Design.Spacing.small) {
|
VStack(spacing: Design.Spacing.small) {
|
||||||
Text(String(localized: "What would you like to focus on?"))
|
Text(String(localized: "What would you like to focus on?"))
|
||||||
.font(Design.Typography.displaySmall)
|
.typography(.title2Bold)
|
||||||
.foregroundStyle(AppTextColors.primary)
|
.foregroundStyle(AppTextColors.primary)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ struct GoalSelectionStepView: View {
|
|||||||
if !selectedGoals.isEmpty {
|
if !selectedGoals.isEmpty {
|
||||||
Button(action: onContinue) {
|
Button(action: onContinue) {
|
||||||
Text(String(localized: "Continue"))
|
Text(String(localized: "Continue"))
|
||||||
.font(Design.Typography.headline)
|
.typography(.heading)
|
||||||
.foregroundStyle(AppTextColors.inverse)
|
.foregroundStyle(AppTextColors.inverse)
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
.frame(height: AppMetrics.Size.buttonHeight)
|
.frame(height: AppMetrics.Size.buttonHeight)
|
||||||
@ -99,11 +99,11 @@ private struct GoalCardView: View {
|
|||||||
// Text
|
// Text
|
||||||
VStack(spacing: Design.Spacing.xSmall) {
|
VStack(spacing: Design.Spacing.xSmall) {
|
||||||
Text(goal.displayName)
|
Text(goal.displayName)
|
||||||
.font(Design.Typography.headline)
|
.typography(.heading)
|
||||||
.foregroundStyle(AppTextColors.primary)
|
.foregroundStyle(AppTextColors.primary)
|
||||||
|
|
||||||
Text(goal.subtitle)
|
Text(goal.subtitle)
|
||||||
.font(Design.Typography.caption)
|
.typography(.caption)
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
.foregroundStyle(AppTextColors.secondary)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
.lineLimit(2)
|
.lineLimit(2)
|
||||||
|
|||||||
@ -16,7 +16,7 @@ struct TimeSelectionStepView: View {
|
|||||||
// Header
|
// Header
|
||||||
VStack(spacing: Design.Spacing.small) {
|
VStack(spacing: Design.Spacing.small) {
|
||||||
Text(String(localized: "When do you want to build habits?"))
|
Text(String(localized: "When do you want to build habits?"))
|
||||||
.font(Design.Typography.displaySmall)
|
.typography(.title2Bold)
|
||||||
.foregroundStyle(AppTextColors.primary)
|
.foregroundStyle(AppTextColors.primary)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
}
|
}
|
||||||
@ -50,7 +50,7 @@ struct TimeSelectionStepView: View {
|
|||||||
if selectedTime != nil {
|
if selectedTime != nil {
|
||||||
Button(action: onContinue) {
|
Button(action: onContinue) {
|
||||||
Text(String(localized: "Continue"))
|
Text(String(localized: "Continue"))
|
||||||
.font(Design.Typography.headline)
|
.typography(.heading)
|
||||||
.foregroundStyle(AppTextColors.inverse)
|
.foregroundStyle(AppTextColors.inverse)
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
.frame(height: AppMetrics.Size.buttonHeight)
|
.frame(height: AppMetrics.Size.buttonHeight)
|
||||||
@ -87,11 +87,11 @@ private struct TimeCardView: View {
|
|||||||
// Text
|
// Text
|
||||||
VStack(alignment: .leading, spacing: Design.Spacing.xSmall) {
|
VStack(alignment: .leading, spacing: Design.Spacing.xSmall) {
|
||||||
Text(time.displayName)
|
Text(time.displayName)
|
||||||
.font(Design.Typography.headline)
|
.typography(.heading)
|
||||||
.foregroundStyle(AppTextColors.primary)
|
.foregroundStyle(AppTextColors.primary)
|
||||||
|
|
||||||
Text(time.subtitle)
|
Text(time.subtitle)
|
||||||
.font(Design.Typography.body)
|
.typography(.subheading)
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
.foregroundStyle(AppTextColors.secondary)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,12 +21,12 @@ struct WelcomeStepView: View {
|
|||||||
|
|
||||||
VStack(spacing: Design.Spacing.medium) {
|
VStack(spacing: Design.Spacing.medium) {
|
||||||
Text(String(localized: "Welcome to Rituals"))
|
Text(String(localized: "Welcome to Rituals"))
|
||||||
.font(Design.Typography.displayLarge)
|
.typography(.heroBold)
|
||||||
.foregroundStyle(AppTextColors.primary)
|
.foregroundStyle(AppTextColors.primary)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
|
|
||||||
Text(String(localized: "Build lasting habits through focused, time-bound journeys"))
|
Text(String(localized: "Build lasting habits through focused, time-bound journeys"))
|
||||||
.font(Design.Typography.bodyLarge)
|
.typography(.body)
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
.foregroundStyle(AppTextColors.secondary)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
.padding(.horizontal, Design.Spacing.xxLarge)
|
.padding(.horizontal, Design.Spacing.xxLarge)
|
||||||
@ -39,7 +39,7 @@ struct WelcomeStepView: View {
|
|||||||
// Get Started button
|
// Get Started button
|
||||||
Button(action: onContinue) {
|
Button(action: onContinue) {
|
||||||
Text(String(localized: "Get Started"))
|
Text(String(localized: "Get Started"))
|
||||||
.font(Design.Typography.headline)
|
.typography(.heading)
|
||||||
.foregroundStyle(AppTextColors.inverse)
|
.foregroundStyle(AppTextColors.inverse)
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
.frame(height: AppMetrics.Size.buttonHeight)
|
.frame(height: AppMetrics.Size.buttonHeight)
|
||||||
|
|||||||
@ -16,11 +16,11 @@ struct WhatsNextStepView: View {
|
|||||||
SymbolIcon("checkmark.circle.fill", size: .section, color: AppStatus.success)
|
SymbolIcon("checkmark.circle.fill", size: .section, color: AppStatus.success)
|
||||||
|
|
||||||
Text(String(localized: "You're all set!"))
|
Text(String(localized: "You're all set!"))
|
||||||
.font(Design.Typography.displayLarge)
|
.typography(.heroBold)
|
||||||
.foregroundStyle(AppTextColors.primary)
|
.foregroundStyle(AppTextColors.primary)
|
||||||
|
|
||||||
Text(String(localized: "Here's how to get the most from Rituals"))
|
Text(String(localized: "Here's how to get the most from Rituals"))
|
||||||
.font(Design.Typography.body)
|
.typography(.subheading)
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
.foregroundStyle(AppTextColors.secondary)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,16 +35,16 @@ struct RitualCardView: View {
|
|||||||
SymbolIcon(iconName, size: .row, color: hasActiveArc ? AppAccent.primary : AppTextColors.tertiary)
|
SymbolIcon(iconName, size: .row, color: hasActiveArc ? AppAccent.primary : AppTextColors.tertiary)
|
||||||
.accessibilityHidden(true)
|
.accessibilityHidden(true)
|
||||||
|
|
||||||
// Title
|
// Title - conditional color needs Text()
|
||||||
Text(title)
|
Text(title)
|
||||||
.font(Design.Typography.headline)
|
.typography(.heading)
|
||||||
.foregroundStyle(hasActiveArc ? AppTextColors.primary : AppTextColors.tertiary)
|
.foregroundStyle(hasActiveArc ? AppTextColors.primary : AppTextColors.tertiary)
|
||||||
|
|
||||||
Spacer(minLength: Design.Spacing.medium)
|
Spacer(minLength: Design.Spacing.medium)
|
||||||
|
|
||||||
// Day label
|
// Day label - needs padding modifiers
|
||||||
Text(dayLabel)
|
Text(dayLabel)
|
||||||
.font(Design.Typography.caption)
|
.typography(.caption)
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
.foregroundStyle(AppTextColors.secondary)
|
||||||
.padding(.horizontal, Design.Spacing.small)
|
.padding(.horizontal, Design.Spacing.small)
|
||||||
.padding(.vertical, Design.Spacing.xxxSmall)
|
.padding(.vertical, Design.Spacing.xxxSmall)
|
||||||
@ -53,13 +53,12 @@ struct RitualCardView: View {
|
|||||||
.accessibilityLabel(Text(dayLabel))
|
.accessibilityLabel(Text(dayLabel))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Theme - conditional color needs Text()
|
||||||
Text(theme)
|
Text(theme)
|
||||||
.font(Design.Typography.body)
|
.typography(.subheading)
|
||||||
.foregroundStyle(hasActiveArc ? AppTextColors.secondary : AppTextColors.tertiary)
|
.foregroundStyle(hasActiveArc ? AppTextColors.secondary : AppTextColors.tertiary)
|
||||||
|
|
||||||
Text(completionSummary)
|
StyledLabel(completionSummary, .caption, emphasis: .custom(AppTextColors.secondary))
|
||||||
.font(Design.Typography.caption)
|
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
|
||||||
}
|
}
|
||||||
.padding(Design.Spacing.large)
|
.padding(Design.Spacing.large)
|
||||||
.background(AppSurface.card)
|
.background(AppSurface.card)
|
||||||
|
|||||||
@ -206,10 +206,10 @@ struct RitualDetailView: View {
|
|||||||
|
|
||||||
VStack(alignment: .leading, spacing: Design.Spacing.xSmall) {
|
VStack(alignment: .leading, spacing: Design.Spacing.xSmall) {
|
||||||
Text(ritual.title)
|
Text(ritual.title)
|
||||||
.font(Design.Typography.displaySmall)
|
.typography(.title2Bold)
|
||||||
.foregroundStyle(AppTextColors.primary)
|
.foregroundStyle(AppTextColors.primary)
|
||||||
Text(ritual.theme)
|
Text(ritual.theme)
|
||||||
.font(Design.Typography.body)
|
.typography(.subheading)
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
.foregroundStyle(AppTextColors.secondary)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -182,12 +182,10 @@ struct RitualsView: View {
|
|||||||
VStack(spacing: Design.Spacing.large) {
|
VStack(spacing: Design.Spacing.large) {
|
||||||
SymbolIcon("sparkles", size: .hero, color: AppAccent.primary)
|
SymbolIcon("sparkles", size: .hero, color: AppAccent.primary)
|
||||||
|
|
||||||
Text(String(localized: "No Active Rituals"))
|
StyledLabel(String(localized: "No Active Rituals"), .heading, emphasis: .custom(AppTextColors.primary))
|
||||||
.font(Design.Typography.headline)
|
|
||||||
.foregroundStyle(AppTextColors.primary)
|
|
||||||
|
|
||||||
Text(String(localized: "Create a custom ritual or browse our preset library to get started."))
|
Text(String(localized: "Create a custom ritual or browse our preset library to get started."))
|
||||||
.font(Design.Typography.body)
|
.typography(.subheading)
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
.foregroundStyle(AppTextColors.secondary)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
|
|
||||||
@ -210,7 +208,7 @@ struct RitualsView: View {
|
|||||||
|
|
||||||
if !store.pastRituals.isEmpty {
|
if !store.pastRituals.isEmpty {
|
||||||
Text(String(localized: "Or restart a past ritual from the Past tab."))
|
Text(String(localized: "Or restart a past ritual from the Past tab."))
|
||||||
.font(Design.Typography.caption)
|
.typography(.caption)
|
||||||
.foregroundStyle(AppTextColors.tertiary)
|
.foregroundStyle(AppTextColors.tertiary)
|
||||||
.padding(.top, Design.Spacing.small)
|
.padding(.top, Design.Spacing.small)
|
||||||
}
|
}
|
||||||
@ -223,12 +221,10 @@ struct RitualsView: View {
|
|||||||
VStack(spacing: Design.Spacing.large) {
|
VStack(spacing: Design.Spacing.large) {
|
||||||
SymbolIcon("clock.arrow.circlepath", size: .hero, color: AppTextColors.tertiary)
|
SymbolIcon("clock.arrow.circlepath", size: .hero, color: AppTextColors.tertiary)
|
||||||
|
|
||||||
Text(String(localized: "No Past Rituals"))
|
StyledLabel(String(localized: "No Past Rituals"), .heading, emphasis: .custom(AppTextColors.primary))
|
||||||
.font(Design.Typography.headline)
|
|
||||||
.foregroundStyle(AppTextColors.primary)
|
|
||||||
|
|
||||||
Text(String(localized: "Rituals that have ended will appear here. You can restart them anytime."))
|
Text(String(localized: "Rituals that have ended will appear here. You can restart them anytime."))
|
||||||
.font(Design.Typography.body)
|
.typography(.subheading)
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
.foregroundStyle(AppTextColors.secondary)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,12 +66,12 @@ struct ArcRenewalSheet: View {
|
|||||||
SymbolIcon("checkmark.seal.fill", size: .section, color: AppStatus.success)
|
SymbolIcon("checkmark.seal.fill", size: .section, color: AppStatus.success)
|
||||||
|
|
||||||
Text(ritual.title)
|
Text(ritual.title)
|
||||||
.font(Design.Typography.displaySmall)
|
.typography(.title2Bold)
|
||||||
.foregroundStyle(AppTextColors.primary)
|
.foregroundStyle(AppTextColors.primary)
|
||||||
|
|
||||||
if let arc = completedArc {
|
if let arc = completedArc {
|
||||||
Text(String(localized: "Arc \(arc.arcNumber) Complete"))
|
Text(String(localized: "Arc \(arc.arcNumber) Complete"))
|
||||||
.font(Design.Typography.body)
|
.typography(.subheading)
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
.foregroundStyle(AppTextColors.secondary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,13 +82,13 @@ struct ArcRenewalSheet: View {
|
|||||||
private var summaryCard: some View {
|
private var summaryCard: some View {
|
||||||
VStack(alignment: .leading, spacing: Design.Spacing.medium) {
|
VStack(alignment: .leading, spacing: Design.Spacing.medium) {
|
||||||
Text(String(localized: "Your Journey"))
|
Text(String(localized: "Your Journey"))
|
||||||
.font(Design.Typography.headline)
|
.typography(.heading)
|
||||||
.foregroundStyle(AppTextColors.primary)
|
.foregroundStyle(AppTextColors.primary)
|
||||||
|
|
||||||
HStack {
|
HStack {
|
||||||
SymbolIcon("chart.line.uptrend.xyaxis", size: .row, color: AppAccent.primary)
|
SymbolIcon("chart.line.uptrend.xyaxis", size: .row, color: AppAccent.primary)
|
||||||
Text(arcSummary)
|
Text(arcSummary)
|
||||||
.font(Design.Typography.body)
|
.typography(.subheading)
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
.foregroundStyle(AppTextColors.secondary)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ struct ArcRenewalSheet: View {
|
|||||||
HStack {
|
HStack {
|
||||||
SymbolIcon("checkmark.circle.fill", size: .row, color: AppAccent.primary)
|
SymbolIcon("checkmark.circle.fill", size: .row, color: AppAccent.primary)
|
||||||
Text(String(localized: "\(habitCount) habits tracked"))
|
Text(String(localized: "\(habitCount) habits tracked"))
|
||||||
.font(Design.Typography.body)
|
.typography(.subheading)
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
.foregroundStyle(AppTextColors.secondary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,13 +111,13 @@ struct ArcRenewalSheet: View {
|
|||||||
private var durationSection: some View {
|
private var durationSection: some View {
|
||||||
VStack(alignment: .leading, spacing: Design.Spacing.medium) {
|
VStack(alignment: .leading, spacing: Design.Spacing.medium) {
|
||||||
Text(String(localized: "Next Arc Duration"))
|
Text(String(localized: "Next Arc Duration"))
|
||||||
.font(Design.Typography.headline)
|
.typography(.heading)
|
||||||
.foregroundStyle(AppTextColors.primary)
|
.foregroundStyle(AppTextColors.primary)
|
||||||
|
|
||||||
VStack(spacing: Design.Spacing.small) {
|
VStack(spacing: Design.Spacing.small) {
|
||||||
HStack {
|
HStack {
|
||||||
Text(String(localized: "\(Int(durationDays)) days"))
|
Text(String(localized: "\(Int(durationDays)) days"))
|
||||||
.font(Design.Typography.displaySmall)
|
.typography(.title2Bold)
|
||||||
.foregroundStyle(AppAccent.primary)
|
.foregroundStyle(AppAccent.primary)
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
@ -127,11 +127,11 @@ struct ArcRenewalSheet: View {
|
|||||||
|
|
||||||
HStack {
|
HStack {
|
||||||
Text(String(localized: "1 week"))
|
Text(String(localized: "1 week"))
|
||||||
.font(Design.Typography.caption)
|
.typography(.caption)
|
||||||
.foregroundStyle(AppTextColors.tertiary)
|
.foregroundStyle(AppTextColors.tertiary)
|
||||||
Spacer()
|
Spacer()
|
||||||
Text(String(localized: "1 year"))
|
Text(String(localized: "1 year"))
|
||||||
.font(Design.Typography.caption)
|
.typography(.caption)
|
||||||
.foregroundStyle(AppTextColors.tertiary)
|
.foregroundStyle(AppTextColors.tertiary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ struct ArcRenewalSheet: View {
|
|||||||
durationDays = Double(days)
|
durationDays = Double(days)
|
||||||
} label: {
|
} label: {
|
||||||
Text("\(days)")
|
Text("\(days)")
|
||||||
.font(Design.Typography.captionBold)
|
.typography(.captionEmphasis)
|
||||||
.foregroundStyle(Int(durationDays) == days ? AppTextColors.primary : AppTextColors.secondary)
|
.foregroundStyle(Int(durationDays) == days ? AppTextColors.primary : AppTextColors.secondary)
|
||||||
.padding(.horizontal, Design.Spacing.small)
|
.padding(.horizontal, Design.Spacing.small)
|
||||||
.padding(.vertical, Design.Spacing.xSmall)
|
.padding(.vertical, Design.Spacing.xSmall)
|
||||||
@ -170,7 +170,7 @@ struct ArcRenewalSheet: View {
|
|||||||
SymbolIcon("arrow.clockwise", size: .row, color: AppTextColors.primary)
|
SymbolIcon("arrow.clockwise", size: .row, color: AppTextColors.primary)
|
||||||
Text(String(localized: "Continue with Same Habits"))
|
Text(String(localized: "Continue with Same Habits"))
|
||||||
}
|
}
|
||||||
.font(Design.Typography.headline)
|
.typography(.heading)
|
||||||
.foregroundStyle(AppTextColors.primary)
|
.foregroundStyle(AppTextColors.primary)
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
.padding(Design.Spacing.medium)
|
.padding(Design.Spacing.medium)
|
||||||
@ -188,7 +188,7 @@ struct ArcRenewalSheet: View {
|
|||||||
SymbolIcon("pencil", size: .row, color: AppAccent.primary)
|
SymbolIcon("pencil", size: .row, color: AppAccent.primary)
|
||||||
Text(String(localized: "Continue with Changes"))
|
Text(String(localized: "Continue with Changes"))
|
||||||
}
|
}
|
||||||
.font(Design.Typography.headline)
|
.typography(.heading)
|
||||||
.foregroundStyle(AppAccent.primary)
|
.foregroundStyle(AppAccent.primary)
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
.padding(Design.Spacing.medium)
|
.padding(Design.Spacing.medium)
|
||||||
@ -210,7 +210,7 @@ struct ArcRenewalSheet: View {
|
|||||||
SymbolIcon("checkmark.circle", size: .row, color: AppTextColors.secondary)
|
SymbolIcon("checkmark.circle", size: .row, color: AppTextColors.secondary)
|
||||||
Text(String(localized: "End This Ritual"))
|
Text(String(localized: "End This Ritual"))
|
||||||
}
|
}
|
||||||
.font(Design.Typography.body)
|
.typography(.subheading)
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
.foregroundStyle(AppTextColors.secondary)
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
.padding(Design.Spacing.medium)
|
.padding(Design.Spacing.medium)
|
||||||
|
|||||||
@ -203,14 +203,14 @@ struct PresetDetailSheet: View {
|
|||||||
SymbolIcon(preset.iconName, size: .hero, color: AppAccent.primary)
|
SymbolIcon(preset.iconName, size: .hero, color: AppAccent.primary)
|
||||||
|
|
||||||
Text(preset.theme)
|
Text(preset.theme)
|
||||||
.font(Design.Typography.bodyLarge)
|
.typography(.body)
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
.foregroundStyle(AppTextColors.secondary)
|
||||||
|
|
||||||
HStack(spacing: Design.Spacing.large) {
|
HStack(spacing: Design.Spacing.large) {
|
||||||
Label(preset.timeOfDay.displayName, systemImage: preset.timeOfDay.symbolName)
|
Label(preset.timeOfDay.displayName, systemImage: preset.timeOfDay.symbolName)
|
||||||
Label(String(localized: "\(preset.durationDays) days"), systemImage: "calendar")
|
Label(String(localized: "\(preset.durationDays) days"), systemImage: "calendar")
|
||||||
}
|
}
|
||||||
.font(Design.Typography.caption)
|
.typography(.caption)
|
||||||
.foregroundStyle(AppTextColors.tertiary)
|
.foregroundStyle(AppTextColors.tertiary)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
|
|||||||
@ -271,12 +271,6 @@ struct RitualEditSheet: View {
|
|||||||
Section {
|
Section {
|
||||||
ForEach(Array(habits.enumerated()), id: \.element.id) { index, habit in
|
ForEach(Array(habits.enumerated()), id: \.element.id) { index, habit in
|
||||||
HStack(spacing: Design.Spacing.small) {
|
HStack(spacing: Design.Spacing.small) {
|
||||||
// Drag handle
|
|
||||||
Image(systemName: "line.3.horizontal")
|
|
||||||
.font(.caption)
|
|
||||||
.foregroundStyle(AppTextColors.tertiary)
|
|
||||||
.frame(width: 20)
|
|
||||||
|
|
||||||
// Icon picker button
|
// Icon picker button
|
||||||
Button {
|
Button {
|
||||||
editingHabitIndex = index
|
editingHabitIndex = index
|
||||||
|
|||||||
@ -33,13 +33,13 @@ struct RitualFocusCardView: View {
|
|||||||
.accessibilityHidden(true)
|
.accessibilityHidden(true)
|
||||||
|
|
||||||
// Title
|
// Title
|
||||||
TitleLabel(title, style: .headline, color: AppTextColors.primary)
|
StyledLabel(title, .heading, emphasis: .custom(AppTextColors.primary))
|
||||||
|
|
||||||
Spacer(minLength: Design.Spacing.medium)
|
Spacer(minLength: Design.Spacing.medium)
|
||||||
|
|
||||||
// Day label - needs additional modifiers (padding, background)
|
// Day label - needs additional modifiers (padding, background)
|
||||||
Text(dayLabel)
|
Text(dayLabel)
|
||||||
.font(Design.Typography.caption)
|
.typography(.caption)
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
.foregroundStyle(AppTextColors.secondary)
|
||||||
.padding(.horizontal, Design.Spacing.small)
|
.padding(.horizontal, Design.Spacing.small)
|
||||||
.padding(.vertical, Design.Spacing.xxxSmall)
|
.padding(.vertical, Design.Spacing.xxxSmall)
|
||||||
@ -48,12 +48,12 @@ struct RitualFocusCardView: View {
|
|||||||
.accessibilityLabel(Text(dayLabel))
|
.accessibilityLabel(Text(dayLabel))
|
||||||
}
|
}
|
||||||
|
|
||||||
BodyLabel(theme, color: AppTextColors.secondary)
|
StyledLabel(theme, .subheading, emphasis: .custom(AppTextColors.secondary))
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: Design.Spacing.xSmall) {
|
VStack(alignment: .leading, spacing: Design.Spacing.xSmall) {
|
||||||
ProgressView(value: progress)
|
ProgressView(value: progress)
|
||||||
.tint(AppAccent.primary)
|
.tint(AppAccent.primary)
|
||||||
CaptionLabel(completionSummary, color: AppTextColors.secondary)
|
StyledLabel(completionSummary, .caption, emphasis: .custom(AppTextColors.secondary))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(Design.Spacing.large)
|
.padding(Design.Spacing.large)
|
||||||
|
|||||||
@ -20,7 +20,7 @@ struct TodayEmptyStateView: View {
|
|||||||
.padding(.top, Design.Spacing.large)
|
.padding(.top, Design.Spacing.large)
|
||||||
|
|
||||||
Text(String(localized: "Rituals help you build consistent habits through focused, time-bound journeys."))
|
Text(String(localized: "Rituals help you build consistent habits through focused, time-bound journeys."))
|
||||||
.font(Design.Typography.body)
|
.typography(.subheading)
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
.foregroundStyle(AppTextColors.secondary)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
.padding(.horizontal, Design.Spacing.large)
|
.padding(.horizontal, Design.Spacing.large)
|
||||||
@ -34,7 +34,7 @@ struct TodayEmptyStateView: View {
|
|||||||
.fill(AppBorder.subtle)
|
.fill(AppBorder.subtle)
|
||||||
.frame(height: 1)
|
.frame(height: 1)
|
||||||
Text(String(localized: "or"))
|
Text(String(localized: "or"))
|
||||||
.font(Design.Typography.caption)
|
.typography(.caption)
|
||||||
.foregroundStyle(AppTextColors.tertiary)
|
.foregroundStyle(AppTextColors.tertiary)
|
||||||
Rectangle()
|
Rectangle()
|
||||||
.fill(AppBorder.subtle)
|
.fill(AppBorder.subtle)
|
||||||
@ -71,7 +71,7 @@ struct TodayEmptyStateView: View {
|
|||||||
// Past rituals hint
|
// Past rituals hint
|
||||||
if !store.pastRituals.isEmpty {
|
if !store.pastRituals.isEmpty {
|
||||||
Text(String(localized: "You can also restart a past ritual from the Rituals tab."))
|
Text(String(localized: "You can also restart a past ritual from the Rituals tab."))
|
||||||
.font(Design.Typography.caption)
|
.typography(.caption)
|
||||||
.foregroundStyle(AppTextColors.tertiary)
|
.foregroundStyle(AppTextColors.tertiary)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
.padding(.top, Design.Spacing.small)
|
.padding(.top, Design.Spacing.small)
|
||||||
@ -95,7 +95,7 @@ struct TodayEmptyStateView: View {
|
|||||||
private var quickStartSection: some View {
|
private var quickStartSection: some View {
|
||||||
VStack(alignment: .leading, spacing: Design.Spacing.small) {
|
VStack(alignment: .leading, spacing: Design.Spacing.small) {
|
||||||
Text(String(localized: "Quick Start"))
|
Text(String(localized: "Quick Start"))
|
||||||
.font(Design.Typography.captionMedium)
|
.typography(.captionEmphasis)
|
||||||
.foregroundStyle(AppTextColors.tertiary)
|
.foregroundStyle(AppTextColors.tertiary)
|
||||||
.padding(.horizontal, Design.Spacing.medium)
|
.padding(.horizontal, Design.Spacing.medium)
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ private struct QuickStartButton: View {
|
|||||||
SymbolIcon(goal.symbolName, size: .row, color: AppAccent.primary)
|
SymbolIcon(goal.symbolName, size: .row, color: AppAccent.primary)
|
||||||
|
|
||||||
Text(goal.displayName)
|
Text(goal.displayName)
|
||||||
.font(Design.Typography.body)
|
.typography(.subheading)
|
||||||
.foregroundStyle(AppTextColors.primary)
|
.foregroundStyle(AppTextColors.primary)
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|||||||
@ -29,7 +29,7 @@ struct TodayHabitRowView: View {
|
|||||||
.frame(width: AppMetrics.Size.iconLarge)
|
.frame(width: AppMetrics.Size.iconLarge)
|
||||||
.accessibilityHidden(true)
|
.accessibilityHidden(true)
|
||||||
|
|
||||||
BodyLabel(title, color: AppTextColors.primary)
|
StyledLabel(title, .subheading, emphasis: .custom(AppTextColors.primary))
|
||||||
|
|
||||||
Spacer(minLength: Design.Spacing.medium)
|
Spacer(minLength: Design.Spacing.medium)
|
||||||
|
|
||||||
|
|||||||
@ -10,8 +10,8 @@ struct TodayHeaderView: View {
|
|||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: Design.Spacing.xxxSmall) {
|
VStack(alignment: .leading, spacing: Design.Spacing.xxxSmall) {
|
||||||
TitleLabel(String(localized: "Today"), style: .displayLarge, color: AppTextColors.primary)
|
StyledLabel(String(localized: "Today"), .heroBold, emphasis: .custom(AppTextColors.primary))
|
||||||
BodyLabel(dateText, color: AppTextColors.secondary)
|
StyledLabel(dateText, .subheading, emphasis: .custom(AppTextColors.secondary))
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
.accessibilityElement(children: .combine)
|
.accessibilityElement(children: .combine)
|
||||||
|
|||||||
@ -53,12 +53,12 @@ struct TodayNoRitualsForTimeView: View {
|
|||||||
|
|
||||||
VStack(spacing: Design.Spacing.xSmall) {
|
VStack(spacing: Design.Spacing.xSmall) {
|
||||||
Text(String(localized: "No rituals scheduled for \(currentTimePeriod.displayName.lowercased())."))
|
Text(String(localized: "No rituals scheduled for \(currentTimePeriod.displayName.lowercased())."))
|
||||||
.font(Design.Typography.body)
|
.typography(.subheading)
|
||||||
.foregroundStyle(AppTextColors.secondary)
|
.foregroundStyle(AppTextColors.secondary)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
|
|
||||||
Text(currentTimePeriod.timeRange)
|
Text(currentTimePeriod.timeRange)
|
||||||
.font(Design.Typography.caption)
|
.typography(.caption)
|
||||||
.foregroundStyle(AppTextColors.tertiary)
|
.foregroundStyle(AppTextColors.tertiary)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ struct TodayNoRitualsForTimeView: View {
|
|||||||
if !nextRituals.isEmpty {
|
if !nextRituals.isEmpty {
|
||||||
VStack(alignment: .leading, spacing: Design.Spacing.medium) {
|
VStack(alignment: .leading, spacing: Design.Spacing.medium) {
|
||||||
Text(String(localized: "Coming up later:"))
|
Text(String(localized: "Coming up later:"))
|
||||||
.font(Design.Typography.caption)
|
.typography(.caption)
|
||||||
.foregroundStyle(AppTextColors.tertiary)
|
.foregroundStyle(AppTextColors.tertiary)
|
||||||
|
|
||||||
ForEach(nextRituals) { ritual in
|
ForEach(nextRituals) { ritual in
|
||||||
@ -74,13 +74,13 @@ struct TodayNoRitualsForTimeView: View {
|
|||||||
SymbolIcon(ritual.timeOfDay.symbolName, size: .chevron, color: AppTextColors.secondary)
|
SymbolIcon(ritual.timeOfDay.symbolName, size: .chevron, color: AppTextColors.secondary)
|
||||||
|
|
||||||
Text(ritual.title)
|
Text(ritual.title)
|
||||||
.font(Design.Typography.body)
|
.typography(.subheading)
|
||||||
.foregroundStyle(AppTextColors.primary)
|
.foregroundStyle(AppTextColors.primary)
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
Text(ritual.timeOfDay.displayName)
|
Text(ritual.timeOfDay.displayName)
|
||||||
.font(Design.Typography.caption)
|
.typography(.caption)
|
||||||
.foregroundStyle(AppTextColors.tertiary)
|
.foregroundStyle(AppTextColors.tertiary)
|
||||||
}
|
}
|
||||||
.padding(Design.Spacing.small)
|
.padding(Design.Spacing.small)
|
||||||
@ -96,7 +96,7 @@ struct TodayNoRitualsForTimeView: View {
|
|||||||
tomorrowRitual.timeOfDay.displayName,
|
tomorrowRitual.timeOfDay.displayName,
|
||||||
tomorrowRitual.timeOfDay.timeRange
|
tomorrowRitual.timeOfDay.timeRange
|
||||||
))
|
))
|
||||||
.font(Design.Typography.caption)
|
.typography(.caption)
|
||||||
.foregroundStyle(AppTextColors.tertiary)
|
.foregroundStyle(AppTextColors.tertiary)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
.padding(.top, Design.Spacing.small)
|
.padding(.top, Design.Spacing.small)
|
||||||
@ -104,7 +104,7 @@ struct TodayNoRitualsForTimeView: View {
|
|||||||
|
|
||||||
// Motivational message
|
// Motivational message
|
||||||
Text(String(localized: "Enjoy this moment. Your next ritual will appear when it's time."))
|
Text(String(localized: "Enjoy this moment. Your next ritual will appear when it's time."))
|
||||||
.font(Design.Typography.caption)
|
.typography(.caption)
|
||||||
.foregroundStyle(AppTextColors.tertiary)
|
.foregroundStyle(AppTextColors.tertiary)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
.padding(.top, Design.Spacing.small)
|
.padding(.top, Design.Spacing.small)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user