fit-lab: Designing a Fitness Assessment That Has to Show Its Work

A free, evidence-based body and movement assessment built for India

16 min read

Most fitness onboarding asks what body part you want to train, gives you a BMI label, and turns a few preferences into a confident-looking plan. fit-lab starts from the opposite position. It asks only for measurements that change an answer, screens for reasons a generic plan may be unsafe, checks whether the goal and timeline agree, then prescribes a complete movement foundation with its evidence and limits attached.

The fit-lab introduction showing a measured 3D body, the statement that the assessment uses the user's measurements, and a Start the scan action.
The opening makes one promise: a body built from measurements and an honest read. No account is required and nothing leaves the device.Kousik DuttaOriginal product screenshot

What the product actually does

fit-lab is a free, mobile-first fitness assessment for India. It combines height, weight, waist, neck, age, sex at birth and, where applicable, hip circumference into a body-fat range and practical risk context rather than pretending BMI is the whole answer. It runs a PAR-Q+-informed readiness screen and a SCOFF-informed food-risk screen before discussing a goal. Then it checks whether the requested weight change and timeline are plausible.

The shortcut
  • Treat BMI as the assessment
  • Let the user pick muscles
  • Turn a seeded slider into an answer
  • Hide caveats in generic fine print
The fit-lab rule
  • Use the measurements that change the read
  • Prescribe complete movement coverage
  • Require an explicit answer or interaction
  • Put evidence and limits beside the claim
The product is designed to remove false precision, not decorate it.

My role

I designed and built the experiment end to end: assessment logic, safety flow, anthropometric deformation, male and female body assets, anatomy coverage, exercise catalogue, dosing, responsive interaction, visual system, source registry, validators, tests and GitHub Pages deployment. It was a solo build, and the honest story is not a straight line from idea to polish. Several of the most important decisions came from admitting that an implementation was wrong and replacing it.

3
required data moments: body, safety and goal
270+
unit checks across deterministic product engines
2
sex-aware base meshes loaded by profile
1
rule: no verified guide, no shipped exercise
The assessment is deliberately short at the surface and unusually strict underneath it.

The architecture is an evidence chain

The assessment is deterministic. Measurements and explicit answers become a typed profile. Screening decides whether the product should stop, caution or proceed. Goal logic checks feasibility. The foundation engine selects complete movement capacities for the available environment. The dose engine assigns goal- and training-age-specific sets, reps, RIR and progression. Validators then refuse to ship a broken link between the recommendation, anatomy and source.

Body, safety, goal

Risk and feasibility

Full-body capacity foundation

Sets, reps, RIR, progression

Weekly schedule

Sources and methods registry

Verified technique guides

Renderable anatomy coverage

Build validators

Nothing reaches the result as an isolated claim. Every layer has a source or a validator that can stop the build.
LayerWhat it decidesHow it stays honest
BodyBody-fat range, waist context, percentiles and the visible figureMeasured inputs, sex-aware formulae, uncertainty bands and mesh limit notes
SafetyWhether to stop, caution or proceedExplicit group closure; untouched means unanswered, never no
GoalWhether a target and timeline agreeRate models use goal type and training age instead of motivational copy
FoundationWhich movement capacities and variants are requiredAutomatic full-body coverage, anatomy validation and verified external guides
DoseSets, reps, effort, progression and weekly distributionDeterministic rules with goal-specific tests and overlap caps
The interface is the final expression of a set of product rules, not the place those rules are improvised.

The body model had to be rebuilt, not tuned

The fit-lab body stage showing a sex-aware 3D figure, entered measurements, a neck measurement control and the local-device privacy note.
The figure responds to the readings as they are entered. The rail reports only touched values; a slider's starting position is not silently accepted as data.Kousik DuttaOriginal product screenshot

The first deformation system scaled whole horizontal slices of the mesh. That was mathematically convenient and visually dishonest. Moving a waist measurement could pull the arms and hands with it. Shoulder changes could leak into the skull. Weight could make unrelated regions swell because the algorithm knew height bands, not anatomy.

I replaced it with region-aware deformation. Waist, shoulder, weight, neck and other measurements now act through per-region masks with controlled falloff, so a local measurement stays local. The rebuild also added honest limit notes. If a combination of measurements pushes beyond what the base mesh can represent cleanly, the product says so instead of presenting a distorted render as measurement truth.

FailureWhy patching was not enoughReplacement
Waist changed arms and handsHorizontal slices had no concept of anatomical ownershipWaist and torso masks with bounded falloff
Shoulder edits reached the skullVertices were grouped by height rather than body regionShoulder, neck and head regions separated explicitly
Extreme inputs looked preciseThe renderer had no language for the asset's representational limitProfile validation plus visible limit notes
One base body stood in for everybodyRatios cannot turn a male topology into a female bodySex-aware mesh and profile loading
The core fix was changing the model of the problem: from slices to regions, and from one universal mesh to sex-aware assets.

One redesign failed hard enough to freeze and roll back

A large in-flight redesign and deformation rewrite became tangled. The live preview was badly broken, and each attempted rescue mixed new visual work with uncertain body logic. The responsible move was not to keep polishing the branch until it looked plausible. I froze the work as a git stash, rolled back to a known-good commit, and restarted the deformation work with smaller boundaries and explicit validators.

The onboarding got smaller because most of it did no work

The original flow was dense: character customization, a personality inventory, redundant sliders and questions that did not change the result. I cut it to three visual data moments - body, safety and goal. Every remaining field now has to move a formula, threshold, safety state, mesh or exercise variant.

Mobile fit-lab body assessment at 390 pixels wide with the 3D body, entered measurements, neck control, measurement help and Continue action.
Mobile Body at 390 x 844. The figure stays central while the active reading, privacy note and next action remain reachable.Kousik DuttaOriginal product screenshot

The cuts required rules, not just fewer screens. A seeded slider value is not an answer until the person touches it. Selecting female adds the hip measurement because the formula uses it; selecting male removes it. Changing sex invalidates safety answers when the applicable question set changes, so a stale 'none apply' cannot silently answer a newly visible pregnancy question.

Before
  • Twenty-eight asks to use nine answers
  • Character details mistaken for assessment data
  • Prefilled controls treated as user intent
  • Safety state survived a changed question set
After
  • Body, safety and goal only
  • Every field changes a visible output
  • Untouched values remain unanswered
  • Inapplicable safety state is invalidated
The shorter flow is stricter about consent and state because it no longer hides assumptions inside convenience defaults.

Users do not pick muscles anymore

The exercise system began as a muscle picker. That sounds empowering, but it produces incomplete plans and lets preference masquerade as evidence. Someone can select chest and arms while omitting squat, hinge, pull, carry, aerobic base, balance or mobility capacities. I replaced that interaction with an automatic full-body foundation.

The foundation covers strength, aerobic base, balance, mobility, yoga and calisthenics, with optional running, boxing and outdoors emphasis. The user's training environment selects viable variants; it does not decide whether a capacity matters. A custom anatomy-coverage validator now fails the build if a recommended capacity cannot be represented in the 3D anatomy scene.

The fit-lab result showing a goal-feasibility verdict, requested and realistic timelines, BMI, waist-to-height ratio, body-fat range, safety status and measured body.
The result leads with feasibility and safety, then the body evidence, then the movement prescription. It does not begin with exercises before checking whether the premise is sound.Kousik DuttaOriginal product screenshot

Every exercise has to earn a live, specific technique guide

An exercise cannot ship with an invented tutorial, a dead link or a generic channel homepage. Every recommendation requires an exact external technique guide URL. The build checks that the URL is live; when the source is YouTube, it verifies the video identity through oEmbed. If the guide cannot be verified, the exercise does not ship.

Evidence surfaceBuild ruleWhat the user can inspect
Technique guideExact URL, live response and verified identity where applicableThe external guide attached to the prescribed exercise
Formula or thresholdRegistered source and evidence kindWhy the number exists and where it came from
Exercise evidenceCatalogue entry linked to the source registryGuideline, meta-analysis, study or editorial basis
DatasetSource, transformation and limitation recordedPopulation context behind percentiles or ranges
3D assetLicence file and profile validation requiredMesh and anatomy provenance
The in-app Sources & methods registry grades evidence as guideline, RCT/meta-analysis, observational, biomechanical or editorial, so a user can distinguish authority from interpretation.

The dose engine had a real hypertrophy bug

The first goal-specific engine gave beginners who selected build muscle only four sets per muscle per week. That number resembles a bare maintenance floor, not a useful hypertrophy prescription. The output looked tidy and the code was deterministic, but the product advice was wrong.

I caught it late and retuned weekly volume by training age into evidence-backed hypertrophy ranges, while preserving overlap caps so compound exercises do not create absurd totals. Sets, reps, RIR, progression and weekly scheduling are now generated together and tested as a system rather than copied into cards independently.

Research does not count until it reaches the shipped catalogue

A late systematic audit found a different kind of failure. Useful research on yoga, calisthenics, a strong sit-to-stand and mortality finding, and neck, arm and lumbar capacities had been gathered but never connected to the shipped data. The notes existed; the product did not know them.

I audited the research set against the exercise and capacity catalogues, added the missing material, and kept the same gate: no verified guide, no shipped exercise. The source-registry validator now catches orphaned claims and broken references so research cannot look complete merely because it exists in a document.

The design-system migration exposed a token collision

I adopted shadcn/ui and Radix primitives to build a proper light/dark system around the orange action accent. The migration surfaced a subtle failure: shadcn's --muted and --radius names collided with pre-existing fit-lab variables using the same names for different purposes. Most secondary text became nearly invisible in light mode without producing a compile error.

The bug was caught by before-and-after visual comparison, not by assuming a component library's defaults were safe. I separated the legacy and shadcn token roles, then rechecked the assessment in both themes. The lesson was not to avoid the library. It was to treat token adoption like an API migration with namespace and contrast consequences.

Accessibility changed the implementation

The release sweep combined axe-core with a manual keyboard and screen-reader walk across every stage, both themes and two viewport sizes. It found contrast pairs that technically failed WCAG AA, a generated accordion without a visible focus treatment, and an ARIA state mismatch introduced while replacing hand-rolled toggles with Radix primitives.

WebGL is also not required to understand the body. The Three.js and React Three Fiber scene has an accessible flat-SVG fallback for unavailable WebGL, while labels describe the entered measurements rather than asking assistive technology to interpret a canvas. The goal was not to claim clinical or assistive-technology certification. It was to make the tested path operable and honest about what the visual can and cannot communicate.

Mobile fit-lab result at 390 pixels wide showing the goal verdict, timeline comparison, body metrics, safety status and measured body in a single reading flow.
Mobile Result at 390 x 844. Feasibility, safety and measurement evidence remain in the first reading sequence before the longer plan.Kousik DuttaOriginal product screenshot

Publishing failed for an operational reason

The first Pages push was blocked by a 403. The environment's default GitHub credential was read-only for the repository. The fix was not a deployment workaround or a copied token in a script; it was authenticating as the actual repository-owner account for push and Pages operations, then keeping deployment in GitHub Actions as a static Vite build.

What is under the interface

The app uses React, TypeScript, Vite and Tailwind. Three.js and React Three Fiber render the body and anatomy scene, with a flat SVG fallback. shadcn/ui and Radix provide interaction primitives, Recharts draws the gauges, and Framer Motion handles transitions. Deterministic evidence, dose, goal, screening, capacity and schedule engines are covered by more than 270 tests.

Custom build validators inspect body-mesh assets, anatomy coverage, technique-guide link integrity and source-registry integrity. GitHub Actions builds the static site and deploys it to GitHub Pages. The operational shape is intentionally simple; the product rules are where the complexity belongs.

What I can and cannot claim

fit-lab is a working v1, not a finished clinical product. It can show that the assessment logic, evidence links, body assets, anatomy coverage, responsive flow, themes and tested accessibility paths work as designed. It cannot diagnose, replace a clinician or prove health outcomes. There is no usage analytics yet, so I cannot honestly claim completion rates or behavior change.

What I would fix next

The clearest product gap is language. The product is India-first, but the verified technique-guide catalogue is English-only. That excludes people the product is supposedly designed for. The next version should add verified guides in major Indian languages without relaxing the identity and link-integrity checks. I would also add privacy-respecting usage analytics, broaden assistive-technology testing, and test the assessment with clinicians and people using it over time.