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

@@ -72,24 +72,24 @@ struct GameMatchConfirmationView: View {
.frame(width: 80, height: 80)
Image(systemName: "photo.fill")
.font(.system(size: 36))
.font(.largeTitle)
.foregroundStyle(Theme.warmOrange)
}
VStack(spacing: Theme.Spacing.xs) {
if let date = candidate.metadata.captureDate {
Label(formatDate(date), systemImage: "calendar")
.font(.system(size: Theme.FontSize.body, weight: .medium))
.font(.body)
.foregroundStyle(Theme.textPrimary(colorScheme))
}
if candidate.metadata.hasValidLocation {
Label("Location data available", systemImage: "location.fill")
.font(.system(size: Theme.FontSize.caption))
.font(.subheadline)
.foregroundStyle(Theme.textSecondary(colorScheme))
} else {
Label("No location data", systemImage: "location.slash")
.font(.system(size: Theme.FontSize.caption))
.font(.subheadline)
.foregroundStyle(.red)
}
}
@@ -108,7 +108,7 @@ struct GameMatchConfirmationView: View {
Image(systemName: "mappin.circle.fill")
.foregroundStyle(Theme.warmOrange)
Text("Nearest Stadium")
.font(.system(size: Theme.FontSize.body, weight: .semibold))
.font(.body)
.foregroundStyle(Theme.textPrimary(colorScheme))
Spacer()
}
@@ -116,11 +116,11 @@ struct GameMatchConfirmationView: View {
HStack {
VStack(alignment: .leading, spacing: 4) {
Text(match.stadium.name)
.font(.system(size: Theme.FontSize.cardTitle, weight: .bold, design: .rounded))
.font(.headline)
.foregroundStyle(Theme.textPrimary(colorScheme))
Text(match.stadium.fullAddress)
.font(.system(size: Theme.FontSize.caption))
.font(.subheadline)
.foregroundStyle(Theme.textSecondary(colorScheme))
}
@@ -129,11 +129,11 @@ struct GameMatchConfirmationView: View {
// Distance badge
VStack(spacing: 2) {
Text(match.formattedDistance)
.font(.system(size: Theme.FontSize.caption, weight: .medium))
.font(.subheadline)
.foregroundStyle(confidenceColor(match.confidence))
Text(match.confidence.description)
.font(.system(size: 10))
.font(.caption2)
.foregroundStyle(Theme.textMuted(colorScheme))
}
}
@@ -155,7 +155,7 @@ struct GameMatchConfirmationView: View {
Image(systemName: "sportscourt.fill")
.foregroundStyle(Theme.warmOrange)
Text(matchOptionsTitle)
.font(.system(size: Theme.FontSize.body, weight: .semibold))
.font(.body)
.foregroundStyle(Theme.textPrimary(colorScheme))
Spacer()
}
@@ -204,7 +204,7 @@ struct GameMatchConfirmationView: View {
Image(systemName: "exclamationmark.triangle.fill")
.foregroundStyle(.red)
Text(reason.description)
.font(.system(size: Theme.FontSize.body))
.font(.body)
.foregroundStyle(Theme.textSecondary(colorScheme))
}
.padding(Theme.Spacing.md)
@@ -216,7 +216,7 @@ struct GameMatchConfirmationView: View {
VStack(alignment: .leading, spacing: 4) {
HStack {
Text(match.matchupDescription)
.font(.system(size: Theme.FontSize.body, weight: .semibold))
.font(.body)
.foregroundStyle(Theme.textPrimary(colorScheme))
Image(systemName: match.game.sport.iconName)
@@ -225,7 +225,7 @@ struct GameMatchConfirmationView: View {
}
Text(match.gameDateTime)
.font(.system(size: Theme.FontSize.caption))
.font(.subheadline)
.foregroundStyle(Theme.textSecondary(colorScheme))
// Confidence
@@ -234,7 +234,7 @@ struct GameMatchConfirmationView: View {
.fill(combinedConfidenceColor(match.confidence.combined))
.frame(width: 8, height: 8)
Text(match.confidence.combined.description)
.font(.system(size: 10))
.font(.caption2)
.foregroundStyle(Theme.textMuted(colorScheme))
}
}
@@ -272,7 +272,7 @@ struct GameMatchConfirmationView: View {
Image(systemName: "checkmark.circle.fill")
Text("Confirm & Import")
}
.font(.system(size: Theme.FontSize.body, weight: .semibold))
.font(.body)
.foregroundStyle(.white)
.frame(maxWidth: .infinity)
.padding(Theme.Spacing.md)
@@ -287,7 +287,7 @@ struct GameMatchConfirmationView: View {
dismiss()
} label: {
Text("Skip This Photo")
.font(.system(size: Theme.FontSize.body))
.font(.body)
.foregroundStyle(Theme.textSecondary(colorScheme))
}
}