Recovery coach for the wearable you already own: daily recovery, sleep and strain scores, habit insights and an AI coach.
Live demo: https://www.freelancerportfoliohub.com/jameslee/projects/evenly/index.html
Evenly reads the data people's watches and rings already collect and turns it into three numbers every morning: recovery, sleep and strain, each measured against the member's own 30-day baseline. This repository holds both halves of the product:
/(Next.js) — the launch site: home, features, AI Coach, pricing and an interactive app preview where visitors tap or swipe through the real Today, Sleep, Strain, Habits and Coach screens.mobile/(Expo) — the iOS and Android app built with Expo Router. Its five tabs are the same screens the site previews, driven by typed sample data until the health-store sync is connected.
- Morning rings — recovery, sleep and strain as SVG rings with metric colours shared across web and app
- Interactive phone preview — tab list, in-phone tab bar, dots, arrow keys and swipe all drive one carousel
- Hand-rolled charts — hypnogram, 24h heart-rate trace, sparklines and weekly bars rendered from data arrays
- Scoring rules — recovery zones, sleep need (baseline + strain + debt − naps) and strain targets in
lib/scoring.ts - Coach API —
POST /api/coachvalidates with zod and answers from the member's own metrics - Scores API —
GET /api/scoresreturns the sample member's day in the same shape the app consumes - Pricing — plan cards, Free vs. Plus comparison table and an accessible FAQ built on
<details> - Mobile app — Expo Router tabs,
react-native-svgcharts, habit check-offs with haptics and a working coach composer
| Layer | Tools |
|---|---|
| Web | Next.js 15 (App Router), React 19, TypeScript (strict), CSS, next/font |
| API | Next.js route handlers, zod |
| Mobile | Expo SDK 54, Expo Router 6, React Native 0.81, react-native-svg |
| Tooling | ESLint 9 (flat config), Prettier, pnpm |
pnpm install
pnpm dev # http://localhost:3000Mobile app:
cd mobile
pnpm install
pnpm start # press i for iOS simulator, a for AndroidNo environment variables are required; both apps run on the bundled sample data.
.
├── app/ # routes: /, /features, /coach, /app, /pricing, /api/coach, /api/scores
│ ├── fonts/ # Bricolage Grotesque + Inter (next/font/local)
│ └── globals.css
├── components/
│ ├── brand/ # Mark, Wordmark, StoreButtons
│ ├── charts/ # Ring, Sparkline, Hypnogram, HeartRateChart, WeekBars
│ ├── phone/ # Phone frame, StatusBar, TabBar, CoachCard, screens/
│ ├── preview/ # PhonePreview (client carousel)
│ ├── home/ features/ coach/ pricing/
│ ├── layout/ # Header, Footer
│ └── ui/ # Button, SectionHead, TickList, CardGrid, Pill
├── lib/
│ ├── data/ # typed content: member day, nav, features, coach, pricing
│ ├── charts.ts # SVG geometry
│ ├── scoring.ts # zones, sleep need, strain target
│ └── coach.ts # CoachService + rules-based preview coach
├── types/
├── public/images/
└── mobile/
├── app/(tabs)/ # index (Today), sleep, strain, habits, coach
├── components/
├── constants/theme.ts
└── lib/ # mock-data, charts, format, types
| Command | Description |
|---|---|
pnpm dev |
Start the site with Turbopack |
pnpm build |
Production build |
pnpm start |
Serve the production build |
pnpm lint |
ESLint |
pnpm typecheck |
tsc --noEmit |
pnpm format |
Prettier |
In mobile/: pnpm start, pnpm ios, pnpm android, pnpm lint, pnpm typecheck.
