A daily challenge app. Everyone gets the same prompt each day, you snap a photo to prove you did it, and your streak goes up. Add friends to see who's actually doing it.
No account required. You get an anonymous session automatically. Google sign-in is optional and links the same account so you don't lose your streak.
Today: One shared challenge, revealed at noon Eastern. Snap a photo to mark it done and your streak updates immediately.
Streaks: Counts consecutive completed days. Doesn't break just because today is still open, only resets once a full day is actually missed.
Bingo: A shared 5x5 card each week, drawn from the challenge pool, fresh every Monday. Claim a square with a photo, same capture flow as the daily challenge. A full row, column, or diagonal wins, and your total wins show on your profile.
Groups: A crew with its own daily challenge, drawn from prompts the members write, plus its own feed with claps and comments. Group prompts are reportable just like photos. Private groups are invite-only (owner adds friends); public groups are open, anyone can find them in Discover and join. Public groups have a small twist: a challenge every member finishes with zero reports has a tiny chance of graduating into the main daily pool for everyone. Max 5 groups per person.
Social: Search friends by handle, send and accept requests. Split view: a Friends pane shows everyone's status, a Feed pane shows photos, captions, claps, and comments. Unread dot clears when you actually open the thread, not just on next load. No friends yet? The feed suggests people who've been doing challenges, one tap to send a request (their photos stay private until you're actually friends).
Claps + Comments: React to a friend's completion or leave a comment. Per-user toggles in Profile settings control who can interact with your posts.
Reporting: Flag a photo for one of several reasons. Three people reporting the same photo for the same reason hides it; mismatched reasons are ignored. Ten reports spread across at least three different posts triggers a ban. Rate limited to one report per person every two hours.
Friend profiles: /u/[handle] shows a friend's streak, posts, and friends list. Their friends list has an opt-out toggle in your own settings.
Push notifications: Get notified when a friend completes the challenge, claps your photo, or leaves a comment. Opt in per device; toggle off anytime from Profile.
Profile: Set a display name and upload an avatar. Shown across the Social tab and friends feed.
PWA: Installable on mobile and desktop home screens.
| Framework | Next.js 16 (App Router, Turbopack, React Compiler) |
| Language | TypeScript |
| Styling | Tailwind CSS v4 |
| Backend | Supabase (Postgres + Storage + Auth) |
| Deployment | Vercel |
npm installCreate .env.local in the project root (see .env.example):
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
For push notifications you'll also need VAPID keys:
NEXT_PUBLIC_VAPID_PUBLIC_KEY=...
VAPID_PRIVATE_KEY=...
VAPID_SUBJECT=mailto:[email protected]
Schema lives in supabase/migrations, applied straight to the hosted project. There's no local Docker DB for this one. Link your project and push:
npx supabase link --project-ref your-project-ref
npx supabase db pushnpm run devOnly run one dev server at a time. Turbopack watches the whole workspace, a second instance just doubles up on RAM for nothing.
The prompt pool is just rows in the challenges table. Add more from the Supabase dashboard, Table Editor, challenges, with active = true. One gets picked at random each day at noon Eastern (lib/challengeDate.ts).
Chalky, muted palette pulled from the outdoors (sage green, dusty sky blue, soft mustard yellow) on a warm paper background (#f7f4ea) with dark warm ink text (#393830). Comfortaa for the typeface. Real SVG icons throughout, no emoji.
See TODO.md.