What We Shipped
- Mobile recovery metrics —
MobileMetricsViewwas fetching health data but never rendering it. Added a Recovery section with Body Battery, Sleep Score, HRV, Stress tiles, and a recommendation badge. - Workout step pace display —
formatTarget()was ignoring theunitfield entirely. A pace stored asmin_per_kmwas being shown with a/milabel at the wrong value (3:58 instead of 6:29). Fixed with unit-aware conversion. - BQ2 event card clickable on mobile —
CalendarUIwas doing an early return for mobile before mounting theEventDetailModal. The modal simply never existed in the mobile render path. Added it. - Referral "Converted?" column header — Empty
<span>in the table header. One-liner. - Google Calendar ID overflow — Long UUIDs were overflowing the integrations modal. Now truncated to 24 chars with full ID in a tooltip.
- Strava elevation preservation —
elevation_gain=0was being treated as null and dropped. Zwift-logged rides with flat elevation were losing that data. Fixed the null check (!= nullinstead of|| null). - Mobile interactive tour — Full onboarding walkthrough now matches the desktop experience on mobile.
- AI coach chat in onboarding — New users can now interact with the AI coach during the onboarding flow, not just after setup.
- Landing page animations — Animations now trigger on scroll-into-view instead of firing immediately on page load.
- Recovery widget tappable — Tapping the recovery widget on mobile now navigates to
/health/recovery. Compact variant added for the calendar view. - Mobile workout detail sheet — Now matches desktop: actuals, quality score, workout steps, AI adjust button, FIT export. Full parity.
- Admin timezone bug — User growth chart was using UTC instead of CT, causing counts to shift by 6 hours overnight.
- Metrics tab explainer labels — Added labels and info tooltips to the metrics tab so the numbers are self-explanatory.
What We Learned
The mobile path in CalendarUI had an early return that was silently swallowing features that existed on desktop. Always check that mobile code paths mount the same components — "responsive" doesn't mean "equivalent."
What's Next
Mobile audit is mostly done. Next up: Sentry integration for production error visibility, and an AI coach quality test suite to catch regressions across model updates.