- Handle loading, unauthenticated, permission-denied, and unavailable states truthfully in metric-card-lean (Peak Lean Angle KPI) rather than falling back to '--' and 'No IMU roll data'
- Reset metrics state to null on auth change and in onStatusChange loading/error branches to prevent stale metrics retention
- Add race condition guard in AppCloudData.loadData to discard in-flight results if firebaseAuth.currentUser changed during asynchronous fetch
- Prioritize Disconnected and Connecting states over sample example messages in real club mode in founder-chat.tsx
- Clear chat messages on channel switch in founder-chat.tsx to eliminate cross-channel message bleed, and fix invalid py-0.2 Tailwind classes to py-0.5
- Add regression tests in account-metrics-truthfulness.test.tsx and founder-routes-chat.test.tsx
- Replace false zero metrics (0 miles / 0 rides / 100% Cloud Synced) on loading, unauthenticated, permission-denied, or network errors with truthful states
- Update AppCloudData to query motorcycles and rides via Promise.allSettled and report granular CloudDataStatus
- Update AccountPage KPI cards to display Loading…, —, or Unavailable with explicit contextual status and error recovery
- Fix founder demo chat to permanently preserve Example thread and example badges during preview=demo simulation instead of flipping to Live Connected
- Add 8 unit/component tests in account-metrics-truthfulness.test.tsx and 6 tests in founder-routes-chat.test.tsx
When a club has no curated routes or a chat channel has no messages, the data layer
returned fixture content with no indication it was sample data, so riders could mistake
MotorSignal's "Coastal Marshes" route or canned chat messages for their club's real data.
Flag fixture-sourced content and label it in the UI:
- Add isExample to ClubRoute and ChatMessage; set it on every fixture fallback path
(empty Firestore collection/channel and the dev demo preview).
- Founder Routes: amber "Examples" count, an explanatory banner, and a per-card "Example"
badge when the routes shown are samples.
- Founder Chat: an "Example thread" pill (instead of "Live Connected") and a banner when
the only messages are examples, so the header never claims a live conversation that
does not exist.
Tests: example-labelled routes render the banner/badge/count; example-labelled chat
renders the banner and "Example thread" pill and does not claim "Live Connected".
Existing route/chat tests (real data, no isExample) remain green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>