feat: add WCAG AA accessibility app-wide, fix CloudKit container config, remove debug logs

- Add VoiceOver labels, hints, and element grouping across all 60+ views
- Add Reduce Motion support (Theme.Animation.prefersReducedMotion) to all animations
- Replace fixed font sizes with semantic Dynamic Type styles
- Hide decorative elements from VoiceOver with .accessibilityHidden(true)
- Add .minimumHitTarget() modifier ensuring 44pt touch targets
- Add AccessibilityAnnouncer utility for VoiceOver announcements
- Improve color contrast values in Theme.swift for WCAG AA compliance
- Extract CloudKitContainerConfig for explicit container identity
- Remove PostHog debug console log from AnalyticsManager

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-02-11 09:27:23 -06:00
parent e9c15d70b1
commit d63d311cab
77 changed files with 982 additions and 263 deletions

View File

@@ -27,8 +27,13 @@ struct PollVotingView: View {
ForEach(Array(viewModel.rankings.enumerated()), id: \.element) { index, tripIndex in
RankingRow(
rank: index + 1,
trip: poll.tripSnapshots[tripIndex]
trip: poll.tripSnapshots[tripIndex],
canMoveUp: index > 0,
canMoveDown: index < viewModel.rankings.count - 1,
onMoveUp: { viewModel.moveTripUp(at: index) },
onMoveDown: { viewModel.moveTripDown(at: index) }
)
.accessibilityHint("Drag to change ranking position, or use move up and move down buttons")
}
.onMove { source, destination in
viewModel.moveTrip(from: source, to: destination)
@@ -79,11 +84,12 @@ struct PollVotingView: View {
Image(systemName: "arrow.up.arrow.down")
.font(.title2)
.foregroundStyle(Theme.warmOrange)
.accessibilityLabel("Drag to reorder")
Text("Drag to rank your preferences")
.font(.headline)
Text("Your top choice should be at the top")
Text("Your top choice should be at the top. You can drag, or use the move buttons.")
.font(.subheadline)
.foregroundStyle(.secondary)
}
@@ -126,6 +132,10 @@ struct PollVotingView: View {
private struct RankingRow: View {
let rank: Int
let trip: Trip
let canMoveUp: Bool
let canMoveDown: Bool
let onMoveUp: () -> Void
let onMoveDown: () -> Void
var body: some View {
HStack(spacing: 12) {
@@ -147,6 +157,25 @@ private struct RankingRow: View {
}
Spacer()
VStack(spacing: 6) {
Button(action: onMoveUp) {
Image(systemName: "chevron.up")
.font(.caption.weight(.semibold))
}
.minimumHitTarget()
.disabled(!canMoveUp)
.accessibilityLabel("Move \(trip.displayName) up")
Button(action: onMoveDown) {
Image(systemName: "chevron.down")
.font(.caption.weight(.semibold))
}
.minimumHitTarget()
.disabled(!canMoveDown)
.accessibilityLabel("Move \(trip.displayName) down")
}
.foregroundStyle(.secondary)
}
.padding(.vertical, 4)
}