← Back to updates

See more. Lose less.

The follow-up to v1.7.3's adaptive-training kickoff — deload cycles and ease-back-in went live, users started seeing softer targets on planned recovery weeks, and the pattern held up. This build is the polish batch. Smaller signals, fewer lost keystrokes, less visual clutter. Nothing dramatic; a lot of small things that add up.

Your progression, on Home

If you're on the Foundations cycle, the biggest visible change is a new card sitting on Home between the workout hero and the week-progress bar. It's called Your progression, and it shows where you are on each movement ladder:

PUSH
Wall Push-up · Rung 1 of 7
↗ Next: Counter-top Push-up

Five rows, one per movement family — push, pull, squat, hinge, core. Each with the current exercise name, position on that ladder ("rung 3 of 7"), and a preview of what comes next when you crush the current one.

The intent: beginners were seeing "rung 1" in a bump toast and asking "OK but what's rung 2?" — the ladder was invisible unless you dug into the docs. Now it's on Home, front and center. The next step is always a name, not just a number.

Top-of-ladder rungs (where there's nothing above) render as "Top of the ladder" instead of a hollow "next: —" — small piece of language work, but matters for the users who make it up there.

Duration on every program card

You used to have to tap into a program to know how long its workouts take. That "~45 min" estimate lived on the StartProgram preview screen and nowhere else. In v1.7.4 it's on every program card, everywhere you browse.

Push & Skill
Strength split · ~35 min

Front Lever Focus
Level 2 / 5 · ~50 min

The number is level-aware — a Front Lever level-1 estimate is different from a level-5 estimate because the workouts change. For multi-level programs the card shows the estimate for your next level (completed + 1), so if you've done level 3 you see the time commitment for level 4.

Under the hood: the estimator that used to live on iOS is now also on the backend, running at seed time. Program cards get the pre-computed number in the same API response as the rest of the program metadata — no extra fetch, no exercise-list load, no waiting spinner.

Warm-up cards get an info icon

Warm-up is where beginners get the most confused, because half the exercises are things they've never heard of. "Scapular pull?" "Dead hang?" "T-spine rotation?" The Foundations content ships with descriptions for all of them — but until v1.7.4, you had to already know an exercise's name to find its description.

Now there's a small info icon on the right side of every warm-up card. Tap it, get a sheet with the description, execution steps, and one-tap YouTube + Google links. Warm-up cards without descriptions (rare) hide the icon so it doesn't lead to an empty sheet.

The card body still toggles the check on/off like before — the info icon is a separate tap zone on the right so the two gestures don't fight.

Achievements celebrate one at a time

Old flow: you unlock 3 achievements in the same workout, the celebration sheet shows the primary one and hides the other two behind a small "+ 2 more" line. You tap Not now, the sheet closes, and you never see the other two. Also, the multi-unlock case is especially common on calibration + first-workout sessions, so beginners were often hitting it right when they most deserved the celebration.

New flow: same sheet, but the primary CTA is now "Next unlock →" when there's more in the queue. Tapping it advances to the next unlock. Content updates in place, no dismiss/re-present animation. Last unlock's CTA reverts to "Not now" to dismiss the sheet.

The share paths (Instagram Stories + system share) still dismiss all remaining unlocks — sharing implicitly means "I've celebrated this one, I'm done".

Typed reps don't get lost

Small annoying bug that had been around forever: you type "12" into a set field, tap "Next exercise" before hitting the checkmark, come back to that exercise later, and the field is empty. Your data was silently thrown away.

Root cause: the row's text state was @State in SwiftUI — local to the row's lifetime. Dismounting the row on navigation discarded whatever hadn't been committed. Now the row has an .onDisappear handler that auto-commits any pending typed value before the view goes away.

Related fix: tapping the checkmark on a set with 0 reps in the field used to mark the set as done at 0 reps. Contradictory UX — the app treats 0-rep sets as "not done" in every other place. Now tapping checkmark on 0 does nothing; you have to actually enter a rep count for the checkmark to commit.

Deload / ease-back-in placement

v1.7.3 shipped the deload + ease-back-in banners as full-width three-line cards on Home, above the workout CTA. That worked for the launch — everyone saw the signal — but the banner ate a lot of screen space. Especially during deload weeks, which last a full week and mean users see the banner 3-5 times.

In v1.7.4 the banner is compressed to a small pill inside the workout card. It sits between the "Mid-cycle" subtitle and the progress dots:

NEXT IN YOUR SPLIT
Conditioning & Cardio
Mid-cycle
🔄 Deload week · softer targets
●●●○○
[ Start workout ]

Same signal, same tint, same icon language. But now it's co-located with the CTA it modifies rather than floating above it as a separate concern. Frees up ~90px of vertical space and puts the "this workout has softer targets" message where you're about to decide to start the workout.

Invisible: program images now live in backend

Refactor with no user-visible effect (in a good way). Program hero images used to be selected via a hardcoded Swift switch — id "1" → .upperbody, id "2" → .lowerbody, etc. Adding a new program required an iOS release just to teach the switch about the new ID.

Now the mapping lives in the backend content JSON. Each program has an image key ("upperbody", "planche", etc.) that iOS reads and maps to a bundle-shipped asset. New programs pick up their image on the next backend deploy, no iOS release needed. Old builds still work — the legacy Swift switch is kept as a fallback for pre-migration API responses.

What's next

Adaptive v2 planning is starting: calibration aging-nudge (re-test prompt after 90 days or 30 sessions), variant-graduation when rep targets get absurdly high, and mesocycle patterns on the Skill Focus Splits (weeks 1/2/3 build, week 4 deload — matching the Foundations pattern). Also more test infrastructure for the backend so we can move faster without regressions.

Feedback goes to support@zenmotion.app or Instagram.

Train well.