Designing a non-punitive habit tracker
Four people, three weeks, and one very patient sunflower.
- Role Visual design & prototyping lead
- Industry Wellbeing / habit building
- Challenge Make small, imperfect effort feel like real progress with an MVP
- Research Persona and empathy mapping, 6 moderated user testing sessions
- Duration One week of planning, two weeks of sprint execution
- Tools Claude, Figma, Codex, GitHub, Visual Studio Code, Vercel
How it all started
During my Project Management with AI training at Fired Up, I worked in a team of four in an agile setup for three weeks. I brought experience in designing and building digital products. Two teammates brought experience in operations, processes, and business strategy, while another had a background in art curation and exhibition management.
The PM rotated each week and their main role was to facilitate the meetings and submit the deliverables for each week. The rest of the work was collaborative. I chose not to take a turn as a PM so I could focus on helping the team design and build.
The challenge
At first, we were given a broad challenge:
Design a way to help people start or stick with a habit that improves mental or physical wellbeing.
We conducted research individually around habits: pain points, strategies, existing solutions. We then met in person to discuss our findings and share our own personal experiences.
I set up a FigJam for the team so we could document all our work there, as well as work collaboratively in an easy way. Then, I connected Claude to Figma and instructed it to build an affinity map from all our research findings.
Affinity mapping of initial research
Restart Rosa
As a next step, we defined our problem statement together and then instructed Claude to create a persona for us to focus on.
Problem statement
Claude came up with Restart Rosa, the serial restarter as our persona. She is 28 to 38, lives in a big city, works full time, and time is her scarcest resource. She starts habits with real excitement, but her motivation fades within weeks.
After this, I instructed Claude to fill in the Empathy Map template in FigJam referring back to the original research.
The empathy map that shaped the product tone
The crazy 8
To come up with a solution to our problem, we first brainstormed together using the Crazy 8 technique.
The Crazy 8 affinity mapping and voting
Each of us then proposed a product concept. We voted again, and Keep It Alive won.
Instead of a streak counter waiting to punish you, your habit lives as something that grows, a little plant that gently gets stronger every time you show up, even in the smallest way.
The Impact-Effort Matrix
Next, we brainstormed ways to bring Keep It Alive to life, then used an Impact-Effort Matrix to prioritise features for the MVP.
The Impact-Effort Matrix
The PM of the week refined the High-Impact/Low-Effort stickies into our sprint epics:
- Check-ins & Tracking
- Non-Punitive Recovery
- Visuals & Growth
- Personalisation & Socials
Each epic was assigned to one of us to complete with user stories and success metrics. During this planning phase I owned Personalisation & Socials. During the execution phase later on, I owned Visuals & Growth.
Success metrics defined upfront
We finalised (together with Claude) the following metrics to track at the end of the sprint. These metrics guided us not only to conduct successful user testing, but also to keep our solution as simple as possible.
The sprint is on
During the sprint, I owned the following user stories:
- As a user building a habit, I want my plant to move through Seedling, Sprouting, Growing, and Blooming stages, so that I can see progress without checking numbers.
- As a user on a hard day, I want my small-effort check-in to still visibly progress the plant, so that small effort isn't treated as "not counting".
My Visuals & Growth stories depended on decisions in the Check-ins & Tracking epic, owned by another teammate. We coordinated and decided that for the MVP, the user would only be able to check in a full effort or a small effort. This influenced the design of the plant's intermediate growth stages.
Additionally, I owned the visual identity of our product, as well as defining design guidelines, so in the end everything looked and felt consistent.
Re: visual identity, I proposed that we follow a similar vibe to Cat On Chair and everyone was on board. We chose the sunflower as our starting plant, since it represents growth and resilience.
Re: the design system, I found one in Figma Community that matched my vision and adjusted it with the colours and typography that I defined myself, leaving spacing and other specs untouched. The md file below was generated by Claude based on Figma.
Keep It Alive — Figma Make Design System
illustrated, cozy habit-growth app · “pause, not reset”
Use this file as the system prompt / reference doc when generating screens in Figma Make. Every prompt should build from these tokens and components — never invent new colors, fonts, or shapes.
Prototype Scope (this sprint)
- Single default onboarding flow (no personalization branching)
- Check-in flow: ≤10 second log, Tiny (+1 step / 20%) vs Full (+2 steps / 40%) effort
- Growth visual: 3–4 static plant stages (Seedling → Sprouting → Growing → Blooming), stage completes at 5 steps
- Non-punitive recovery after a missed day — progress never resets, only pauses
- Plant/room scene must always reflect the actual current growth state — never hardcode a stage
- No shadows, no sharp corners, no streak-shaming red, no aggressive motion
Tokens — Colors
Neutrals
| Name | Value | Role |
|---|---|---|
| White | #F4F4F4 | Page/canvas background |
| Gray 1 | #F0EFEC | Card/section background |
| Gray 2 | #E7E5E1 | Fills, dividers, default stroke |
| Gray 3 | #C2C2C2 | Disabled elements |
| Gray 4 | #969696 | Muted text |
| Gray 5 | #656565 | Secondary text |
| Gray 6 | #454545 | Near-black text/icons |
| Black | #1B1B1B | Primary text, strokes, icons |
Accent (Crayola)
| Name | Value | Role |
|---|---|---|
| Red | #954A2E | True alert/error only — never a general accent |
| Orange | #C9754E | Decorative accent |
| Sunflower | #DBB155 | The one saturated action color — Solid button fill |
| Green | #516924 | Decorative accent |
| Teal | #67A6AC | Decorative accent |
| Purple | #8D4F7B | Decorative accent |
Tokens — Typography
Single font family: Winky Rough (fallback system-ui, sans-serif) — used for every text style, no secondary font. Weights: 400/500/600/700.
| Role | Size | Line Height | Letter Spacing | Weight |
|---|---|---|---|---|
| Display Lg | 64px | 1.2 | 0 | Bold |
| Display | 48px | 60px | 0 | SemiBold |
| Header 1 | 34px | 1.0 | 0 | Medium |
| Header 2 | 28px | 1.2 | 0 | Medium |
| Header 3 | 24px | 1.0 | 0 | Medium |
| Body Lg | 22px | 28px | 0 | Regular |
| Body | 18px | 24px | 0.18px | Regular |
| Caption | 16px | 1.0 | 0.32px | Regular |
| Tiny | 14px | 18px | 0.28px | Regular |
| Uppercase Lg | 20px | 24px | 0.4px, uppercase | Regular |
| Uppercase | 16px | 20px | 0.32px, uppercase | Regular |
Tokens — Spacing & Shape
Spacing scale (px): 4, 5, 6, 8, 10, 12, 14, 16, 20, 24, 32, 40, 48, 56, 64, 80
Common patterns
| Use | Spacing |
|---|---|
| Tightly related text | 4px |
| Within a group, heading → supporting copy, icon → label | 8px |
| Between list rows | 8–12px |
| Between content groups or before actions | 16px |
| Card padding | 12–24px |
| Screen padding | 24px horizontal / 32px vertical, plus safe-area insets |
| Between major sections | 24–32px |
Keep related content closer together than separate groups. On smaller screens, reduce flexible outer space first and keep internal gaps consistent. Reserve larger spacing values for roomy layouts and illustrations.
Border radius
| Element | Value |
|---|---|
| Checkbox | 4px |
| Small/medium buttons, small dropdown | 6px |
| Large buttons, text/search fields, dropdowns, alert modal | 8px |
| Outer cards/containers | 16px |
| Switches, radio circles | 44px or 200px (fully rounded) |
Stroke: 2px standard border everywhere. 7px heavier ring only for radio “selected, not yet checked” state.
Shadows: none — elevation comes from surface color steps only (White → Gray 1 → Gray 2).
Sizing: icons 20px (small/medium) or 24px (large) · button height 32px (small) / hugs content (medium) / 52px (large) · switch 28×14px track, 20px thumb · mobile frame 402×874px
Core Components (build as reusable Figma Make components)
| Component | Key spec |
|---|---|
| Button | Large 52px / Medium hug / Small 32px × Solid (Sunflower fill) / Outline / Ghost (Black stroke or text) |
| Floating Action Button | Circular, same Solid/Outline/Ghost language |
| Checkbox | 4px radius, 2px stroke, Unchecked/Indeterminate/Checked |
| Checklist item | Full-row, label + checkbox |
| Radio | Default/Selected (7px ring)/Checked |
| Radio button item | Full-row single-select, e.g. anchor picker |
| Switch | 28×14px track, 20px thumb, Off/On |
| Dropdown | Default/Small, 6–8px radius |
| Search field | Leading icon, reused as list-row shell for habit/anchor pickers |
| Text field / Text box | 8px radius, 2px stroke, 16px padding (14px w/ leading icon) |
| Text field group / Text box group | Label → field → hint, 6px gap |
| Toast | Light/Dark |
| Tooltip | Light/Dark |
| Tag | Leading icon/Label × Invert |
| Text Badge | Default/White/Black style, pill shape |
| Numbered Badge | Number (auto)/Number (fixed)/Dot |
| Alert Modal | 8px radius, blocking confirm dialog (used for check-in + drop-habit) |
| Progress bar | XS–XL × 0–100% |
| Calendar / CalendarBase | Month/week grid, day cell states |
Plant Growth & Room Illustration Rules
- Use the Pot + Plant illustration components directly for any plant visual — never sketch a new plant shape
- 5 stages × ~5 fill percentages: Seedling (100 only), Sprouting/Growing/Blooming (20/40/60/80/100), Bloom (100 only)
- Room scene (carpet, sofa, table, pot, plant) progressively zooms out as the plant grows
- Zoom level must be identical between the check-in screen and the result screen — result screen mounts at the same zoom step before animating forward
- Plant always reflects the live current growth state — never hardcode a stage in a screen
- Phase-up celebration only fires at bloom-100
Do’s and Don’ts
Do
- Set every text style in Winky Rough — headers and body alike
- Use Sunflower as the one saturated Solid-button fill; keep Outline/Ghost in Black
- Keep radii soft: 4–8px functional, fully rounded on switches/radios
- Reuse seedling/sprouting/growing/blooming stage names as real product vocabulary
- Pull icons from the Streamline Freehand set before reaching for a different style
Don’t
- Don’t substitute pure white (
#FFFFFF) — the warm White (#F4F4F4) is signature - Don’t use Red as a general accent — reserved for true alerts/errors
- Don’t add drop shadows to cards or buttons
- Don’t introduce hard/sharp corners anywhere
- Don’t use streak-shaming red, harsh corners, or aggressive motion — breaks “pause, not reset”
Copy Principles
- Journalistic/warm tone, never punitive or binary (“only this, only that”)
- No em dashes in any copy
- Message rotation is per-screen, not per-group
- Effort picker question: “How much did you nurture your habit today?” → “plenty” / “a tiny bit”
Figma Make Prompt Rules
- Every prompt is self-contained — no forward references to screens/components not yet defined in that prompt
- Use design tokens (colors, spacing, radii above) — never hardcoded arbitrary values
- Build reusable components (Button, Plant, Card) rather than one-off shapes per screen
- State that must persist across screens (growth %, stage, streak-free status) should be passed explicitly, not assumed
- For interactive prototypes, wire real click-through logic for the 3 core-loop screens: onboarding → check-in → result/recovery
Quick Start — CSS Custom Properties
:root {
--color-white: #F4F4F4;
--color-gray-1: #F0EFEC;
--color-gray-2: #E7E5E1;
--color-gray-3: #C2C2C2;
--color-gray-4: #969696;
--color-gray-5: #656565;
--color-gray-6: #454545;
--color-black: #1B1B1B;
--color-red: #954A2E;
--color-orange: #C9754E;
--color-sunflower: #DBB155;
--color-green: #516924;
--color-teal: #67A6AC;
--color-purple: #8D4F7B;
--font-winky-rough: 'Winky Rough', system-ui, sans-serif;
--text-display-lg: 64px; --leading-display-lg: 1.2;
--text-display: 48px; --leading-display: 60px;
--text-header-1: 34px; --leading-header-1: 1.0;
--text-header-2: 28px; --leading-header-2: 1.2;
--text-header-3: 24px; --leading-header-3: 1.0;
--text-body-lg: 22px; --leading-body-lg: 28px;
--text-body: 18px; --leading-body: 24px; --tracking-body: 0.18px;
--text-caption: 16px; --leading-caption: 1.0; --tracking-caption: 0.32px;
--text-tiny: 14px; --leading-tiny: 18px; --tracking-tiny: 0.28px;
--text-uppercase-lg: 20px; --leading-uppercase-lg: 24px; --tracking-uppercase-lg: 0.4px;
--text-uppercase: 16px; --leading-uppercase: 20px; --tracking-uppercase: 0.32px;
--font-weight-regular: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--spacing-4: 4px; --spacing-5: 5px; --spacing-6: 6px; --spacing-8: 8px;
--spacing-10: 10px; --spacing-12: 12px; --spacing-14: 14px; --spacing-16: 16px;
--spacing-20: 20px; --spacing-24: 24px; --spacing-32: 32px; --spacing-40: 40px;
--spacing-48: 48px; --spacing-56: 56px; --spacing-64: 64px; --spacing-80: 80px;
--radius-checkbox: 4px;
--radius-sm: 6px;
--radius-md: 8px;
--radius-card: 16px;
--radius-full: 44px;
--radius-full-2: 200px;
--stroke-standard: 2px;
--stroke-radio-selected: 7px;
--surface-white: #F4F4F4;
--surface-gray-1: #F0EFEC;
--surface-gray-2: #E7E5E1;
--surface-black: #1B1B1B;
}
Source of Truth
Figma file UI-Kit (fileKey: Zrhel2zbUqVypc7yap4VWu). Components frame 7605:6309 · Icons 7612:3128 · Illustrations 7578:3311 · Onboarding screens 7726:2362 · Resume/check-in flow 7726:1208. Pull live specs with Figma:get_design_context rather than guessing when a value isn’t listed above.
The growth logic
-
Seedling
The starting stage.
-
100%
-
-
Sprouting
First growth stage.
-
20%
-
40%
-
60%
-
80%
-
100%
-
-
Growing
Second growth stage.
-
20%
-
40%
-
60%
-
80%
-
100%
-
-
Blooming
Third growth stage.
-
20%
-
40%
-
60%
-
80%
-
100%
-
-
Full bloom
Added retrospectively to reach 21 full-effort check-ins.
-
100%
-
For every small-effort check-in the sunflower would grow by 20%. For every full-effort check-in the sunflower would grow by 40%.
For the sake of testing the prototype, together with the Check-ins & Tracking epic owner, we capped visual growth at three sunflower cycles: 21 full-effort check-ins or 45 small-effort check-ins. Beyond that, the user could still check in, but no new sunflower would grow.
After the sprint was done, I removed the 21-full-check-in limit, as science says 21-day habit rule is anecdotal. Instead, I added a milestone celebration at 66 check-ins, regardless of the growth stage, then let the sunflower reach the full bloom stage one final time.
Design mindfully first!
Another team member, inspired by the defined visual identity, sketched the room, which I then digitised and used as our final room design.
I designed the following screens in Figma myself, and then asked Claude to follow the design system as well as my layouts to add all the growth stages across both the small-effort and full-effort paths. The copy in the check-in confirmation screens is fully AI-generated, while the copy of the CTAs and the check-in screen itself was defined by me.





The onboarding screens were designed by two teammates in Claude Design. I again instructed Claude to redesign the screens using our design guidelines. Overall it worked well, but I still had to make a few adjustments:
- layout: spacing between and around elements
- visual: distinguishing habit vs. anchor by colours
- interaction: the ability to navigate back
- content: rewriting a critical CTA
Welcome screen
Name your plant
Choose a habit
Choose an anchor
I designed the Non-Punitive Recovery screens in Figma together with the teammate who owned that epic. While, the screens for progress-tracking (a.k.a the Garden) were added directly with prompts in Figma Make. This time, I let the AI take over.
The prototype
As a team, we used Figma Make to generate a clickable prototype from the design guidelines and the screens. Since we were working simultaneously and had limited tokens, we decided to create three mini prototypes separately: Onboarding, Check-ins & Tracking, and then Recovery.
We used Figma Make's default model to save tokens and overall the results were acceptable. However, it struggled with the positioning of the room when zoomed in for a check-in. It wasn't perfect, but it was testable.
The end-to-end XP
We still wanted a full end-to-end experience that we could share at the end of the sprint. Being the only one with the relevant experience in the team, I built it with Codex, GitHub, and Vercel.
On top of our designed screens, I enhanced the experience with more animations to make it feel ALIVE!
Try it out!
User testing
To recruit course participants who matched our persona, I posted this message on Slack:
Hello everyone,
are you a Restart Rosa and want to participate in the user testing of our product Keep It Alive?
Rosa starts a new habit with real excitement and a big goal in mind, but there is no fixed regular trigger, so the habit competes with everything else in her life. As motivation drops, effort feels heavier, and missed times turn into forgetting. When she comes back, she restarts from zero and loses every bit of progress she had built. Perfectionism makes it worse: if it does not look or feel good quickly, she drops it. Aggressive reminders push her away instead of pulling her back.
React with:
- ✅ Yep, count me in
- 🚫 Nah, I am a Rhythm Rae
Thank you! Details will follow as DM.
We ran the sessions separately, each moderating and taking notes during our own time slots. We prepared a shared script and note-taking template beforehand.
We measured the success metrics that we defined during the planning phase. Here are the results:
Changes during the sprint
4/6 testers didn't understand the value of showing a % in each check-in log. They felt the percentages clashed with the rest of the concept by shifting the focus back to numbers. Additionally, they found the visuals too small to have an impact.
This was the only screen we generated entirely through a prompt and kept exactly as the AI created it. Very important lesson!
Even though only one tester felt the recovery message predicted failure, our goal was for no one to feel that way, so we rewrote that too.
The next sprint
6/6 testers understood the check-in and the growth metaphor, however 4/6 pointed out that they would like at least a third option to log: "None at all".
The decision to log only two options was deliberate, as designing for more nuanced progress also requires more intermediate illustrations. However, adding the option for "None at all" didn't occur to us. That won't have an effect on the illustrations and it would add a lot of value to our concept. This is the beauty of testing with real people, as you reach that "aha" moment yourself as a designer.
We moved this to the next sprint so we could think through where the option belongs on the check-in screen and which confirmation messages to show.