End-to-end design · Frontend
A local-first system for understanding pain over time
A self-awareness tool and health companion that helps users recognise patterns influencing their health.

Pain is subjective, episodic, and non-linear. It evolves, overlaps with other signals, and is often described retrospectively in ways that are hard to reason about.
Most tracking tools flatten this complexity into static logs, or prematurely interpret patterns, producing insights that feel intelligent but are not actually supported by evidence.
Design question
How can a system turn ambiguous, evolving input into reliable insights over time?
Trust grows when nothing is hidden behind a black box. Users can understand how the system reaches its conclusions.
The system explains itself through use. Clear structure and familiar mental models eliminate the need for instructions.
Insights are shown only when the data supports them. When evidence is insufficient, the system stays quiet.
The first version focused purely on episode tracking: when pain started, how intense it was, and when it ended. The MVP goal was to validate the core logic: episode tracking and pattern identification over time.
User testing led to the introduction of spatial selection (tapping head regions on a map), expanded symptom tracking, and contextual signals — factors surrounding pain, such as stress and poor sleep.
For headaches, a map allows multiple areas to be selected, supporting realities like spreading or bilateral pain.

The product was designed to match users' mental models of migraine episodes.
A headache can evolve over time. That's why headaches have two states: no headache and in progress. Each update during an active episode creates a snapshot of the state, including intensity, symptoms, location, and context.
After the episode ends, these snapshots are compared chronologically to produce an evolution timeline. This timeline explains what happened during the episode and tracks its duration.
It reports everything that changed between two updates: areas the pain spread to or eased at, intensity, symptoms that appeared or stopped, medication, and what was noted before the headache.
Users highlighted Headache evolution as a very useful way to understand whether anything was helping to alleviate the pain or making it worse.
System output


Episodes represent what happened. Patterns represent what repeats. These two layers are deliberately independent by design.
Patterns only emerge across episodes, and only when explicit thresholds are met. If the data is insufficient, the system stays quiet.
In practice, this means patterns are not shown at all, rather than displaying speculative or placeholder insights. Empty states are treated as valid outcomes, not failures.
After user testing, patterns were integrated into the headache map, as this is where users most often focused when checking insights.
Reorganising outputs as the system matured
The cards on the homepage were reordered and grouped based on observation of users using the website.
Patterns belonged to headache map, and this was more relevant than number of headaches and average intensity which was more nice-to-have information.
Recent headaches needed to be right after the headache map so users could check the last log and understand what happened.


I reviewed the logic and realised patterns were limited to three, even though more could exist.
I tested placing patterns inside the headache map card, but it felt too heavy. I moved them into their own card instead, without a "Patterns" label, which I intentionally avoided to reduce cognitive load.
I reused a lightbulb icon to signal insights. It scales well and stays consistent across the app: patterns and summaries.
All data referred to the last 30 days, and that context was repeated. I grouped everything under a single 30-day header and removed the title from the individual cards.
Free-text descriptions were intentionally avoided to prevent ambiguity during data processing and reduce the risk of false or misleading insights. Instead, pain location is captured through spatial selection, and insights are derived from structured input.
The map is not decorative; it is a data input mechanism that enables aggregation and allows users to see intensity at a glance.
Intensity is represented using five blue tones. Gradients were explored but discarded due to poor scalability when printing reports, and a traffic-light system was avoided to prevent alarming users, as the goal is to create a safe, calm logging experience.

A front and a back view hide the sides of the head. Temples, ears, jaw and the back of the neck sit at the edges, where they are hard to find. I explored mapping pain on a 3D head in a separate prototype, then brought it into Vagalume.
No record was rewritten. Each headache keeps the areas it was saved with, and the app translates them when it reads them, so headaches logged on the flat map appear on the 3D head. Devices without 3D support still get the flat map.
Intensity became density: each area is a soft patch that gets denser the more it hurt. Gradients had been ruled out because they printed badly. The doctor PDF now renders the head from four fixed angles, with the pain drawn stronger for print, which removed that problem.



I expanded the system to body pain, and spatial modelling became the primary design challenge. Unlike the head, the body introduces multiple regions.
Rather than aiming for anatomical completeness, I chose a deliberately coarse spatial model: regions large enough to remain tappable on mobile, but limited enough to stay cognitively manageable.
System output

Not all the body areas are selectable.
I intentionally reduced the number of body pain areas users can register to handle the input in a more manageable way and reduce the amount of data the system needs to process when displaying patterns.
For example, selecting "left knee" effectively includes both the front and back of the knee. In the case of back pain, however, more granularity was necessary due to the number of users reporting pain in specific back areas, so I designed the selectable regions to be detailed enough to accurately specify the pain.
System output
Body pain tracking deliberately diverges in one key way: the system supports logging and aggregating body pain signals without imposing a lifecycle.
Headaches naturally fit an episodic mental model, body pain does not always. Through testing and feedback, it became clear that many users do not experience body pain as discrete episodes. Forcing that structure would have introduced friction and distorted the data.
All daily logs are summarised in a daily pain view, whereas headaches are conceptualised as episodes.
An empty day in the calendar meant one of two things: no headache, or nobody opened the app. Patterns could not tell them apart.
A one-tap check-in, "How's your head today?", records headache-free days on the device. A daily reminder brings people back to it through their own calendar (Google, Apple or Outlook), so it needs no account and sends nothing anywhere.
All data is stored locally. This simplifies trust decisions and forces the system logic to remain explicit and inspectable.
There is no onboarding that asks users to declare patterns or typical pain upfront. This is intentional: the product is designed to be self-explanatory. A first visit plays a short example on the head instead: a few areas are tapped, they soften into history, and an example calendar and summary appear.
There are no predictions, causal claims, or external correlations. Each of these would have expanded scope while weakening integrity in some cases.

The simple, clean design, without illustrations and with restrained use of colour, is intentional.
People experiencing pain or migraines can easily be distracted or overstimulated by motion design, or bright, highly saturated colours in the UI.
I also deliberately avoided using orange or red for intensity scales to prevent conveying a sense of error, urgency, or alarm. The intent of the web is to accompany and inform, not to diagnose or alarm.
The 3D head follows the same rule: an ivory porcelain bust with no skin tone or anatomical detail, and blue kept for pain only.
The product is focused on people experiencing pain, regardless of age. This became clearer through beta testing over 8 weeks.
The doctor report was the most requested addition, validating the need for medical communication — not just self-tracking.
The appropriate timeline for users was initially an open question; 30 days appears to be sufficient to get the signals they need.
I can go to the doctor and show exactly what happened.
The report has since become a one-page PDF: the head from four sides, the facts, the 30-day calendar and how each headache changed. Sharing with family or friends sends a short text instead, through WhatsApp, Messages or email. The two needs turned out to be different.
Why this work matters
Although this is a B2C health product, the problems it explores are the same ones I work on in AI-powered analytics systems: when to ask for user input, how to do it, and when to display output — while maintaining user trust throughout the journey.
What this work taught me
Implementation surfaced architectural constraints that shaped the episodic model.
Different problems required different system structures. Forcing consistency reduced clarity.
Designed and implemented end-to-end, mobile-first, using AI-assisted frontend development to validate the system in practice.
More on how the 3D pain-mapping exploration came together, and what user research revealed along the way, in How do you represent something invisible?
If insight hasn't been earned, it isn't shown.