I was arguing with Alexa.

My exercise routine includes working with timed sets, not reps. Before Concrete Sets, I’d ask Alexa for a one minute timer, then ask her to extend it when the alarm went off. Admittedly, not the most efficient system. Sometimes she understood and sometimes she didn’t, and half the time I’d lose my focus asking her to do something that should have been automatic.
Then I mentioned this to a few people I train with and realised they had versions of the same problem. Different apps, different devices, same annoyance. They’d set a timer, lose focus, miss the transition and have to scramble back, or they’d do what I did with a voice assistant and just accept that managing the timer was part of the workout.
That’s when it stopped feeling like my quirky workflow and started feeling like a problem actually worth solving.
What I wanted was super simple. Set up a routine once, press start and let the app move from one exercise to the next without me managing anything.
The first version I sketched was barely an app at all. A list of movements, a duration for each one and a clock that kept going. That was it.

It had to work when I wasn’t looking at it and feel good enough that I wanted to come back.

I designed for simplicity and then started building, but once I actually used those early versions during a workout, two problems became obvious pretty quickly.
The first was practical. A workout timer is not much use if you have to keep checking whether it has moved on, because I wanted to focus on the movement rather than the screen. That meant the app had to tell me what was happening in other ways, so sound, haptics, the Watch and a very clear countdown eventually all became part of the interface. Sometimes, after all, the interface was sitting three metres away from me.
The second problem was less functional but just as real. The early versions worked, but they felt cheap and I did not particularly enjoy using them. For something that is supposed to become part of a repeated routine, that matters more than it might sound.
If I am going to open something several times a week, the visual experience becomes part of whether I want to come back, so the challenge became bigger than simply making the timer work. The app needed to disappear while I was training but still feel like somewhere I wanted to return to.

I stopped thinking about screens and started thinking about spaces and states.

A workout has a rhythm to it because you are doing something, preparing for the next thing, recovering and then moving again. Once I started thinking about that rhythm instead of treating the app as a series of screens, the whole product came together much more quickly.
I began to think of the app as a small environment made up of a few distinct spaces. There is the space where your routines live, the space where you build and update them, and then the workout space itself.
Inside the workout space, the important thing is not another set of screens but a sequence of states. You are active, resting, transitioning or finished, and each of those moments asks something slightly different of the person using the app.
That changed the questions I was asking. Where does the eye need to go right now? What does someone need to know before the next movement starts? What can disappear completely, and if the phone is across the room, what needs to follow onto the Watch instead?
The product became much clearer once each space had a purpose, each state had one job and the transitions between them started doing some of the work.
This way of thinking is probably the most spatial part of how I design because I tend to think of digital products as environments people move through rather than collections of screens they click through.

The body changes the interface.

Designing something to use while exercising is completely different from designing something to sit and stare at, so decisions that seem trivial while you are designing suddenly become quite important in use.
The timer has to be readable from a distance, while an exercise name someone adds can be short or ridiculously long. They may add an image or they may not, and during the workout rest might mean standing still, getting onto the floor, moving across the room or trying to find the chair you forgot you needed. Quite often the phone is not even the thing you are looking at.
Setup had to stay fast too because there is not much point building a beautiful workout system if creating a routine feels like doing your taxes before exercising. The same was true later on, because as you get stronger the routine changes, so updating the times or adjusting the order had to be quick rather than like rebuilding the whole workout.
I also wanted the app to be dependable in a much less glamorous way. Someone might not work out for six months and then, after finally finding the motivation to start again, open the app expecting their routine to still be there. They should not be greeted by an update process, a broken account or something that has quietly stopped working in the meantime. The product had to be able to sit there untouched and simply be ready when they came back.
Those constraints turned out to be useful because they kept pushing the design toward fewer decisions, stronger hierarchy and less noise, while also keeping the product small. There was less interface to learn, less complexity to build and, importantly, fewer things for me to break.

The space should have character, and the information cannot become decoration.

I wanted Concrete Sets to feel like somewhere you enter rather than another generic fitness app, so the concrete room gives it an actual place and atmosphere, while the workout information does almost the opposite. The timer stays flat, blunt and very large.
I tried more stylised numbers early on because, naturally, I wanted the timer to look interesting, but they started competing with the thing they were supposed to communicate. They also looked slightly kitschy, which was definitely not the ambition, so they disappeared.
The harder design problem turned out to be REST because rest is not really an empty state. If the next movement requires getting onto the floor, picking up a weight or finding a chair, it is not terribly helpful to discover that the second the timer starts again. You need to know beforehand.
So the rest screen ended up doing two things at once. The large number tells you that you are resting now, while the lower part of the screen quietly prepares you for what is coming next.
Images are optional, which meant the interface also had to work perfectly without them, so when there is no image the exercise name simply takes over that space and the structure stays the same.
Visually, I wanted energy without ending up in either pink wellness land or macho weightlifting land. I wanted it to feel strong and specific, but still quiet enough not to become the workout itself.

Every useful thing cannot be the most important thing.

A lot of the design came down to deciding what deserved attention and what did not. The timer obviously had to dominate, but not so completely that I lost sight of what was happening next, while images could make exercises easier to recognise without becoming necessary for the app to work.
Sound created a similar problem because it is extremely useful when you are not looking, but too much of it would simply turn the app into the thing I had been trying to escape in the first place.
The same thing happened with features. It would have been very easy to keep going and turn Concrete Sets into accounts, syncing, cloud storage, workout histories and eventually some kind of sprawling fitness platform, but none of those things made the first workout better.
They would, however, have made the product slower to build, harder to test, less stable and more expensive to maintain, so I kept coming back to one question.
Does this help someone move through the workout, or does it just give the product more features?

Coding with AI changed where the design process ended.

I designed Concrete Sets in Figma and then started moving constantly between the design, Claude, ChatGPT, Expo and eventually TestFlight.
AI did not make the design decisions for me, but it changed how quickly I could test them. Instead of spending too long discussing whether something might work, I could put it into the actual product, use it during a workout and find out.
Sometimes the AI proposed something that worked perfectly well technically and felt completely wrong, while sometimes my own idea turned out to be the bad one. That back and forth became part of the design process rather than something that happened after it.
The biggest shift was that code started to feel like another prototyping material, so I was no longer trying to resolve everything in Figma before something became real.
There is a downside to that speed though, because when it becomes this easy to make another version, it is also very easy to keep the conversation between yourself and the machine for too long.
That is something I want to change in the next stage with more real users and less talking to myself with a very capable robot.

At some point, another round of polishing is just another round of polishing.

There was always something else I could improve. That is probably true of any product, but it becomes especially dangerous when you are the designer and the person building it because nobody arrives to take it away from you.
Eventually v1 was working, I was using it for regular workouts, the serious bugs were dealt with and I had reached the point where keeping it private was teaching me less than letting it go.
More tweaking was not making it noticeably better and wasn’t going to tell me what happened when somebody else used it.
Shipping also meant dealing with all the things that disappear in a prototype. Real device behaviour, the Watch, privacy, TestFlight, App Store requirements and all the unglamorous little decisions required to make the whole system actually work.
There was also nobody downstream to hand the design to, which meant I was the person deciding whether it was ready.
Eventually I decided it was ready enough, which is probably the more useful definition anyway, and shipped the version I had knowing there would be another one.

Some good ideas did not deserve to ship.

I really wanted the app to announce each exercise. I built it, tested it and discovered that the available voices sounded wrong. The alternatives that sounded better introduced enough complexity that they simply did not make sense for the first version.
So voice disappeared.
Health integration was harder to give up because I genuinely wanted it. I was very tempted to squeeze it in right before shipping, which is of course exactly when one should probably stop adding things.
Adding it would have expanded the scope of v1 and delayed everything around it, so that disappeared too.
Accounts and cloud storage never made the cut in the first place. The routines live on the phone, the app works offline and there is nothing to sign into before you can exercise.
All of those decisions reduced the surface area of the first version. There was less to build, less to test and less to support.
Not everything that could make the product better makes this version better.

It became something I actually want to use.

The biggest win is not really that I built an iPhone and Apple Watch app. It is that I solved the thing that made me build it in the first place.
I no longer manage a timer while I am exercising. I set up the routine, press start and let it run, while the app tells me what I need when I need it and otherwise stays in the background.
One of the things I am happiest about is that the phone stopped being the centre of the experience. Between sound, haptics and the Watch, I can follow the workout without constantly checking the screen, which was the problem I was trying to solve in the first place.
It also stays with me when I lock my phone. The timer keeps moving, and the next state is there when I need it.
That sounds extremely obvious, but it is surprisingly easy to design the opposite.
It also became the kind of digital product I want to make. It has a strong visual identity, but it does not constantly demand attention. When I open it, it feels like entering somewhere. Once the workout begins, that space recedes and lets me get on with what I am actually there to do.
Even the ending mattered. The first builds simply stopped when the workout was finished, which was technically completely adequate and emotionally terrible.
V1 ends with an explosion.
Completely unnecessary in functional terms, but much better in use.
I am counting that as a design win too.

Now I want to find out what happens when it leaves my hands.

There is no shortage of things I could add next. Health integration is still high on the list. I would revisit voice if I could make it sound good enough, and the timer experience outside the main app could definitely become more useful.
But the next important step is not another feature.
The first version was designed largely through my own use, with a small amount of outside feedback. That was enough to make the product real, but it is not enough to tell me what the product should become.
What I need next is behavioural evidence.
I want to see where other people hesitate, what they ignore, what they use completely differently from me and which parts of the system actually matter once the workout is no longer mine.