A Next.js (App Router, TypeScript, Tailwind) intake flow for Fitora, a fitness onboarding product. The flow is a 5-step, quiz-style intake that funnels visitors from landing → goal selection → demographics → activity → preferences → account registration.
🔗 Live demo: https://intake-xi-two.vercel.app/
- Next.js 15 (App Router) + React 19
- TypeScript
- Tailwind CSS v4
- Tabler Icons
- Client-side state only (no DB / API yet — the registration step logs to the console and shows a success screen)
- Visual system documented in
DESIGN.md: a Raycast-style dark canvas with hairline borders, Interss03typography, and a surface-color ladder for elevation (no shadows). - Brand twist: the universal primary CTA is gold (sampled from the bodybuilder logo) instead of Raycast's pure white.
| Token | Value | Usage |
|---|---|---|
--gold |
#D4A537 |
Primary CTA + active step indicator |
--gold-pressed |
#B88A24 |
Pressed state |
--gold-soft |
rgba(212, 165, 55, 0.15) |
Selection highlight on option cards |
| # | Path | Question | Input type |
|---|---|---|---|
| 1 | /intake/goal |
What's your primary fitness goal? | 4 option cards |
| 2 | /intake/about |
Tell us about yourself | age, sex, height, weight |
| 3 | /intake/activity |
How active are you today? | 4 option cards |
| 4 | /intake/preferences |
A few preferences | location, days/week, diet |
| 5 | /intake/register |
Create your Fitora account | name, email, password |
State lives in IntakeProvider (React Context + useReducer) and persists across
step navigation. The final step posts the assembled payload (today: console.log
- success view).
intake/
├── app/
│ ├── layout.tsx # Root layout, Inter font with ss03, dark canvas
│ ├── globals.css # Raycast dark tokens + gold accents
│ ├── page.tsx # Landing → "Start your intake" CTA
│ └── intake/
│ ├── layout.tsx # Intake shell: logo, progress bar, back button
│ ├── page.tsx # Redirects to /intake/goal
│ ├── goal/page.tsx # Step 1: primary fitness goal
│ ├── about/page.tsx # Step 2: age, sex, height, weight
│ ├── activity/page.tsx # Step 3: current activity level
│ ├── preferences/page.tsx # Step 4: location, days/week, diet
│ └── register/page.tsx # Step 5: name, email, password + submit
├── components/
│ ├── ui/ # Reusable, presentational primitives — no app state
│ ├── IntakeProvider.tsx # React Context for flow state
│ ├── Logo.tsx # Fitora logo + wordmark
│ └── StepShell.tsx # Step page chrome: title, content slot, footer CTA
├── lib/
│ ├── cn.ts # Tiny class-merge helper
│ └── steps.ts # Step metadata: order, paths, titles
├── public/ # Static assets (logo)
└── DESIGN.md # Raycast design system reference
npm install
npm run dev # http://localhost:3000Other scripts:
npm run build # production build
npm run start # serve the production build
npm run lint # run Next.js lintDeployed on Vercel — every push to main triggers a new
deployment. The current build is live at https://intake-xi-two.vercel.app/.
- keeps.com/quiz — single-question-per-step pacing, large illustrations, fixed bottom CTA
- quad.medvi.org/intake-nwpck — medical intake style ("branded shell + progress bar" treatment)