- ScheduleDocument/Schedule gain optional reminderMinutes (minutes from
midnight; decode-compatible, no schema bump)
- New Workout form gets a Reminder section (toggle + time picker, hidden
for Now; footer warns when notifications are denied)
- ReminderPlanner (pure, tested) derives notification triggers: daily
repeating, per-weekday repeating for fixed days, one-shot for once
- ReminderScheduler resyncs pending requests from the cache on every
change, multiplexed onto onCacheChanged after the watch push; asks
notification permission only once a reminder actually exists
- When section moves to the top as a segmented control (3 or 4 segments
depending on whether Now is offered)
- Routine selection is a pushed list with each routine's symbol and color,
checkmark on the current pick, select-and-pop
- Goal "None" reserves the symbol slot so all goal labels align
- Due-filter schedules: daily always, fixed days by weekday, one-offs on
their date; rest days get an empty state
- Workouts with no due schedule row (ad hoc or off-day starts) now render
as their own board rows
- The + sheet is now "New Workout" with a "When" picker; "Now" (offered
when adding on today) skips the schedule and starts the workout directly
- Remove the times-per-week scheduling mode everywhere (enum, document,
entity, mappers, planner, seeds, tests)
The decorated-days set was built from dateComponents([.year, .month,
.day], from:) output, which also sets isLeapMonth = false; the day
picker probes it with bare y/m/d components (isLeapMonth nil). The two
compare == but hash differently, so Set.contains missed essentially
every member and dots appeared only on chance hash collisions. Build
the set from bare y/m/d components matching the probe's shape.
Claude-Session: https://claude.ai/code/session_012qw2itfzKyEJ1HpsFt8Ex4
Back/forward chevrons step the board a day at a time around the
existing calendar button, and a Today button — shown only when the
board is off today — jumps back. Also add the missing changelog
entries for the Today board itself.
Claude-Session: https://claude.ai/code/session_012qw2itfzKyEJ1HpsFt8Ex4
The UX redesign's first landing (spec in UX-REDESIGN.md): ContentView
becomes a Today / Progress / Settings TabView, "Routine" replaces
"Split" in every user-facing string and view name (code-level types
keep their names), and workout starting moves to shared
WorkoutStarter / StartedWorkoutNavigator plumbing.
- New Progress tab: weekly goal streaks, workout trends, per-exercise
weight progression, achievements, and the full history list
(WorkoutLogsView -> WorkoutHistoryView).
- Goals: stable categories workouts roll up to, managed from Settings.
- New Meditation exercise + starter routine; timed sits record to
Apple Health as Mind & Body sessions.
Claude-Session: https://claude.ai/code/session_012qw2itfzKyEJ1HpsFt8Ex4