Back to Developer Logs

Build Log — March 1, 2026

Build Log — March 1, 2026

What We Shipped

New Features

  • Fitbit integration — body metrics sync — Fitbit users now get body composition data (weight, BMI, body fat) synced alongside activity data.
  • Compliance badges on mobile calendar — Workout cards now show green/yellow/red badges indicating how closely you hit your planned workout. Badge only appears when a planned workout exists — Garmin syncs without a plan stay clean.
  • Calendar overflow days — Previous and next month's days now show greyed out in the calendar grid, and tapping them navigates to that month.
  • Imperial/metric unit toggle — Added to the mobile Settings page. Athletes can now switch units without digging into account settings.
  • Calendar drag handle — A drag-to-resize handle on the calendar day panel lets you expand it all the way to full screen, collapsing the calendar grid entirely.
  • Sleep time range in recovery tile — The total sleep tile now shows bedtime–wake time (e.g. "10:32 PM – 6:14 AM") alongside sleep hours.
  • PWA hard reload — Added a hard reload option in the Settings menu for PWA standalone mode. Final resting place after several layout iterations.

Fixes & Polish

  • Recovery tile ordering — Standardized the tile order to RHR → HRV → Sleep → REM+Deep across the Home screen, Calendar, and Metrics page. Was inconsistent everywhere.
  • Metrics data source sync — ATL/CTL/TSB and recovery tiles on the Metrics page now use the same data source as the Home screen. No more diverging numbers.
  • Mobile header padding — Standardized pt-3 + 22px title size across all mobile screens. Small but it was visibly inconsistent.
  • InfoTip rendering — Tooltip now renders as a fixed overlay instead of inline, so it doesn't cramp chart layouts or float over screen center.
  • Export sheet scroll — Added flex-1 min-h-0 and max-height constraints so the export sheet scrolls internally and doesn't block main content.
  • iOS export scroll — Applied overflow-y: scroll + -webkit-overflow-scrolling: touch for proper momentum scrolling on iOS.
  • Unread badge suppression — Coach tab unread badge no longer appears until the user has actually visited the tab. No more phantom notifications on first launch.
  • Garmin null laps — Filtered out null-only lap rows so the splits chart doesn't render with empty data on Garmin activities.
  • Approximate distance prefix — The ~ prefix on estimated distances was being stripped. It's back.
  • Weekly Volume W3 grayed out — A hardcoded index === 2 check was always graying out the third week. Fixed to use actual data state.
  • Intervals.icu ID truncation — Applied the same calendar ID truncation fix from the integrations modal to /settings/integrations.
  • Mobile calendar week start — Calendar now correctly starts weeks on Monday.
  • AI coach layout — Used position: fixed container to track the visual viewport properly on mobile.
  • Health dashboard performance — Parallelized dashboard queries with Promise.all and added prefetching in MobileHomeView to eliminate the recovery widget waterfall delay.

What We Learned

Data consistency across screens is surprisingly hard to maintain. ATL/CTL, recovery tiles, and weekly volume all had subtle divergences because different components were hitting different data sources or applying different filters. The fix is always the same: one source of truth, shared hook, done.

What's Next

The mobile experience is now in solid shape. Next focus: production error visibility (Sentry) and stress-testing the AI coach across different athlete profiles and training phases.