feat: implement Dynamic Type with Apple text styles

Replace all custom Theme.FontSize values and hardcoded font sizes with
Apple's built-in text styles (.largeTitle, .title2, .headline, .body,
.subheadline, .caption, .caption2) to support accessibility scaling.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-01-11 10:23:16 -06:00
parent 8affa3ce0d
commit 2d48f1411a
16 changed files with 273 additions and 284 deletions

View File

@@ -65,11 +65,11 @@ struct AchievementsListView: View {
VStack(alignment: .leading, spacing: Theme.Spacing.xs) {
Text("\(earned) / \(total)")
.font(.system(size: Theme.FontSize.heroTitle, weight: .bold, design: .rounded))
.font(.largeTitle)
.foregroundStyle(Theme.textPrimary(colorScheme))
Text("Achievements Earned")
.font(.system(size: Theme.FontSize.body))
.font(.body)
.foregroundStyle(Theme.textSecondary(colorScheme))
if earned == total && total > 0 {
@@ -77,7 +77,7 @@ struct AchievementsListView: View {
Image(systemName: "star.fill")
Text("All achievements unlocked!")
}
.font(.system(size: Theme.FontSize.caption, weight: .semibold))
.font(.subheadline)
.foregroundStyle(Theme.warmOrange)
}
}
@@ -190,9 +190,9 @@ struct CategoryFilterButton: View {
Button(action: action) {
HStack(spacing: Theme.Spacing.xs) {
Image(systemName: icon)
.font(.system(size: 14))
.font(.subheadline)
Text(title)
.font(.system(size: Theme.FontSize.caption, weight: .medium))
.font(.subheadline)
}
.padding(.horizontal, Theme.Spacing.md)
.padding(.vertical, Theme.Spacing.sm)
@@ -233,14 +233,14 @@ struct AchievementCard: View {
.frame(width: 60, height: 60)
Image(systemName: "lock.fill")
.font(.system(size: 14))
.font(.subheadline)
.foregroundStyle(.white)
}
}
// Title
Text(achievement.definition.name)
.font(.system(size: Theme.FontSize.caption, weight: .semibold))
.font(.subheadline)
.foregroundStyle(achievement.isEarned ? Theme.textPrimary(colorScheme) : Theme.textMuted(colorScheme))
.multilineTextAlignment(.center)
.lineLimit(2)
@@ -250,7 +250,7 @@ struct AchievementCard: View {
if achievement.isEarned {
if let earnedAt = achievement.earnedAt {
Text(earnedAt.formatted(date: .abbreviated, time: .omitted))
.font(.system(size: Theme.FontSize.micro))
.font(.caption)
.foregroundStyle(Theme.warmOrange)
}
} else {
@@ -260,7 +260,7 @@ struct AchievementCard: View {
.progressViewStyle(AchievementProgressStyle())
Text(achievement.progressText)
.font(.system(size: Theme.FontSize.micro))
.font(.caption)
.foregroundStyle(Theme.textMuted(colorScheme))
}
}
@@ -371,11 +371,11 @@ struct AchievementDetailSheet: View {
// Title and description
VStack(spacing: Theme.Spacing.sm) {
Text(achievement.definition.name)
.font(.system(size: Theme.FontSize.sectionTitle, weight: .bold, design: .rounded))
.font(.title2)
.foregroundStyle(Theme.textPrimary(colorScheme))
Text(achievement.definition.description)
.font(.system(size: Theme.FontSize.body))
.font(.body)
.foregroundStyle(Theme.textSecondary(colorScheme))
.multilineTextAlignment(.center)
@@ -384,7 +384,7 @@ struct AchievementDetailSheet: View {
Image(systemName: achievement.definition.category.iconName)
Text(achievement.definition.category.displayName)
}
.font(.system(size: Theme.FontSize.caption))
.font(.subheadline)
.foregroundStyle(categoryColor)
.padding(.horizontal, Theme.Spacing.sm)
.padding(.vertical, Theme.Spacing.xs)
@@ -401,7 +401,7 @@ struct AchievementDetailSheet: View {
.foregroundStyle(.green)
Text("Earned on \(earnedAt.formatted(date: .long, time: .omitted))")
.font(.system(size: Theme.FontSize.body, weight: .medium))
.font(.body)
.foregroundStyle(Theme.textPrimary(colorScheme))
}
}
@@ -409,7 +409,7 @@ struct AchievementDetailSheet: View {
// Progress section
VStack(spacing: Theme.Spacing.sm) {
Text("Progress")
.font(.system(size: Theme.FontSize.caption, weight: .medium))
.font(.subheadline)
.foregroundStyle(Theme.textMuted(colorScheme))
ProgressView(value: achievement.progressPercentage)
@@ -417,7 +417,7 @@ struct AchievementDetailSheet: View {
.frame(width: 200)
Text("\(achievement.currentProgress) / \(achievement.totalRequired)")
.font(.system(size: Theme.FontSize.cardTitle, weight: .bold))
.font(.headline)
.foregroundStyle(Theme.textPrimary(colorScheme))
}
}
@@ -428,7 +428,7 @@ struct AchievementDetailSheet: View {
Image(systemName: sport.iconName)
Text(sport.displayName)
}
.font(.system(size: Theme.FontSize.caption, weight: .medium))
.font(.subheadline)
.foregroundStyle(sport.themeColor)
.padding(.horizontal, Theme.Spacing.md)
.padding(.vertical, Theme.Spacing.sm)