Skip to content
homeworkplayaboutcontact
resume
homeworkplayaboutcontact

This is a footer (ew stinky...)
work about contact flowerboxes linkedin x
josue:~$ Josué Avalos Jiménez · Designer · Prev. @ Nintendo · Open to work © 2026 · built from scratch · press

This is a footer (ew stinky...)
work about contact flowerboxes
@1kind.px @josueava.los linkedin x
Josué Avalos Jiménez · Designer · Prev. @ Nintendo · Open to work © 2026 · built from scratch
cover slide titled Designing for Mental Clarity, showing app screens for the stat dashboard, session timer, and completed session

StatBar

Project Mobile App + Design System

YearFall 2025 to 2026

Team Josué Avalos Jiménez (kelpbro)

Type
ProductDesign SystemsCase StudyPixels
skip to the running app how AI was used here

Overview

StatBar turns looking after yourself into an RPG. Five stats and a focus session. Finish one and the stat you spent it on goes up a level.

That is the version that works. The first version, built solo in two weeks for a studio class, ranked you against your friends and called your own life dangerously low. The brief had asked for a tool that reduces mental clutter without adding to it.

project brief slide: design a subtle, intelligent tool that reduces mental clutter without adding cognitive loadproject brief slide: design a subtle, intelligent tool that reduces mental clutter without adding cognitive load

A year later I audited it against its own research, rebuilt it as a real SwiftUI app, then ported that app to the web accurately enough to diff against screenshots of it.

P.S. Yes, my username is Kelpbro.


01 · What shipped in 2025, in its own words

The copy is the argument, so it goes first and unedited. The dashboard opened on a nudge card.

Hey, listen!YourAcademicstat bar is dangerously low.
Boost my statsNot now

"Hey, listen!" is Navi's line from Ocarina of Time. The buttons are "Boost my stats" and "Not now", so the only way out is to admit you are choosing not to.

"Dangerously low" is the real damage: a status effect from a game, applied to somebody's health, on a screen they open every day.

profile screen with a Friend Leaderboard ranking Kelpbro at level 43 above three other players
session complete screen reading Keep farming! with Total XP 13, Time spent 30, and Focus score 78, above a Claim XP button
Two screens from the 2025 build: the friend leaderboard, and the screen that ended a session.

A leaderboard sorts people by how much of their life they logged. The reward screen closes the loop: "Keep farming!", then Total XP 13, Time spent 30, Focus score 78.

A focus score. The app graded how well you paid attention, out of a hundred, from a timer that only knew whether the screen was on.


02 · The research it argued with

The research came first, and it said the opposite. Six articles on invisible UX and AI-native patterns, plus a read of Headspace, Calm, Oura and Apple Health. A nudge should sit inside a flow. A system should suggest, not command. Progress framing beats data framing.

I shipped an interruption, phrased as a command, resolving to three raw numbers.

research takeaways and applications from three articles: AI as a design material, Copilot productivity habits, and designing for disappearanceresearch takeaways and applications from three articles: AI as a design material, Copilot productivity habits, and designing for disappearance
research takeaways and applications from three more articles: invisible UX, trending AI-UX patterns, and designing for intent over interfacesresearch takeaways and applications from three more articles: invisible UX, trending AI-UX patterns, and designing for intent over interfaces
Sources

03 · The law that replaced it

The audit produced four rules. They live in the app's repo, and every feature gets checked against them.

No decay. A bar never goes down. An app that punishes you for a bad week is an app you delete during a bad week.

No shame copy. Nothing describes a person, or part of one, as low, behind or at risk.

No ranks, no leaderboards. Nobody is sorted against anybody.

Levelling stays numeric. A finished session is worth one level, never scaled by length. The floor is five minutes: at one minute a stat goes empty to 10/10 in ten, and the bar stops meaning anything.

They have deleted real work since. The leaderboard, a week grid, and an XP counter I rebuilt without noticing it was the exact mechanic rule one forbids.

the session complete screen as it works now
Session complete, as it works now

The same moment as "Keep farming!", four rules later. No score, no XP, no claim button. The bar moves one cell and the screen names the stat and the level.

That figure is the running app and not a picture of it, which is why the heart is beating. It is the only thing on it you can do: a screen addressed directly has nowhere to send you, so this one is here to be watched. The whole app is further down.


04 · The app, running

The real thing, ported from the SwiftUI source and running here. Start a session, open Friends, switch it to dark. The lists inside pull with a mouse, the way they would with a thumb.

The controls beside the phone belong to this page, not the app. A session inside the phone is a real timer, because that is the product. Skipping is something a demo needs, so it lives out here.

StatBar, running
The app, rebuilt for the web and running here. Speed it up to reach the end of a session. · open full screen

The nudge kept its greeting. It still opens "Hey, listen!", and then tells you your Personal side is ready when you are.


05 · The system outlived the concept that commissioned it

The system is the part the audit left alone, and the part that then had to move.

Main · Poison

  • 50#F4F1FF
  • 100#ECE5FF
  • 200#DBCEFF
  • 300#C1A6FF
  • 400#A574FF
  • 500#8B3CFF
  • 600#8115FF
  • 700#7503FE
  • 800#6102D5
  • 900#4104AD
  • 950#310077

Complementary · Acid

  • 50#F7FFE5
  • 100#ECFFC7
  • 200#D8FF90
  • 300#BFFF4D
  • 400#A6FF1A
  • 500#8CD900
  • 600#75B300
  • 700#5C8C00
  • 800#466600
  • 900#334400
  • 950#1A2200

Neutrals

  • 50#FFFFFF
  • 100#F9F9F9
  • 200#F0F0F0
  • 300#D9D9D9
  • 400#BFBFBF
  • 500#999999
  • 600#737373
  • 700#4D4D4D
  • 800#262626
  • 900#0D0D0D
  • 950#000000
Three ramps, thirty three rungs, read out of the stylesheet the running prototype uses rather than exported as a picture of it.

Figma to SwiftUI is a platform change, and a system that only works in the file it was drawn in is a mood board. Icons became a generated catalogue and ramps became tokens. Nothing in dark mode was picked by eye.

The atoms were drawn once and have been running ever since. Switch this and check it yourself.

The tab bar. One purple square for the whole row, so it travels rather than blinking out here and in again there.

The stat picker. Every option is its own stepped block, which is why the open list’s edge alternates.

The buttons. A 22pt slot is reserved for a leading glyph, so the label starts in the same place with or without one.

Appearance, the app’s own setting. System is this page, so these controls follow it until you say otherwise.

design atom components: skill-category dropdowns, timer inputs, nav icon states, and button variants in filled and outline styles
Four of the app’s controls, and a picture of them. Switch this site to dark and only one side follows.

Each dark value mirrors the relationship its light counterpart has to its own ground. A filled track cell in dark is Main 300, not the Main 500 that looked obvious: light separates filled from empty by 47.1 in L*, and Main 500 manages 14.1, under the system's floor of 17.3.

The icons went the same way. They are not a picture on this page: the grid below is drawn from the cells the app ships, so redrawing a glyph in the app changes this figure too.

  • arrow-up18×22
  • bottle22×20
  • chevron-down22×16
  • chevron-left16×22
  • chevron-right16×22
  • chevron-up22×16
  • clock22×22
  • energy18×22
  • exclamation14×22
  • flower22×22
  • friends28×20
  • graph22×20
  • heart22×20
  • home22×20
  • pencil22×22
  • plus20×20
  • sliders24×20
  • user20×20
  • x22×22
  • zzz20×20
  • stat-bar126×16
Twenty one glyphs, two layers each, drawn from the artwork the app ships rather than exported as a picture of it. The measurements are the artwork's own, which is how clock turned up 0.0003 wide of square: a float that survived the Figma export, and that nothing had put beside a correct one until this sheet existed. It is squared at the source now.
42

icon layers in the set, two to a glyph. Seven of the twenty one appear on no screen in the product, and nothing had drawn them beside a correct one until this sheet existed

Finish a session and the stat you spent it on celebrates itself, in a way that belongs to that stat.

These are running, not filmed. Each is an explicit function of time in the Swift, and the page replays that same function. No cubic-bezier is a smoothstep, so the alternative was picking the closest easing and hoping.

  • Academic86 frames, measured off the source comp

  • Sociala hop, squashing as it lands

  • Healthlub-dub, then a rest twice as long

  • Personalsixteen ballistic pixels

  • Restthree Z’s breathing in sequence

The pencil is the odd one. It is not authored at all: it is 86 frames of the original comp, measured by the sprite's centroid and its angle, replayed onto a vector. The area varies by 0.2% across all 86, so the sprite is rigid, and for a rigid body those two numbers are not an approximation of the motion. They are the whole of it.


06 · Rebuilt for the web, and measured

The prototype above is a port of the SwiftUI app, scored by pixel against captures of the real one.

0.47%

of pixels differ between the running session screen and a capture of the real iOS app

Ten screens score between 0.47% and 3.11%.

Home sat at 2.43% for a week under a note saying the rest was antialiasing and the floor for this method. A quarter of it was a line height.

Space Grotesk's metrics give a 1.276 ratio, and CoreText rounds every line box up to a whole device pixel, so a 15pt line is 19.333, not 19.14. A Friends row is 8 plus 19.333 plus 4 plus 19.333 plus 8, and the reference measures 58.67 exactly. Rows were six tenths short each. Fixing it moved every screen at once.

1.216

peak scale of the heart flourish, measured off the web port and off the real iOS app. Both agree. The Swift source says 1.22

Motion got the same treatment, generated from the app's own timing functions.

The icons, the components and the artwork are mine, drawn in Figma before any of this ran. That file is the source for everything on this page. The glyph sheet above is the app's own cells, and the app's cells came out of the Figma.

What I handed over was the carrying across. Figma to SwiftUI, then SwiftUI to the web, each port measured against captures instead of eyeballed. It generated the flourishes from the app's own timing functions, read the build back against the four rules and the brief that started it, and worked the small interactions up from what the drawings already implied. The pencil is the exception: those 86 frames are mine, animated in After Effects, and the page replays the comp rather than reauthoring it.

Which half is which matters. The drawing is mine, and so is the audit's verdict. The translation, the consistency pass and the measuring are where the machine did the work.


07 · Rest is a stat you level up

The least obvious idea in the product, and the app never says it out loud, so it gets said here.

Rest sits in a list of five things you level up, and a new person has to work out for themselves that stopping counts as building. Every other stat rewards output. Rest rewards stopping, and it is worth the same one level as anything else, because the moment it is worth less it becomes the thing you skip.

the session complete screen after a Rest session
Twenty five minutes of rest, worth one level, same as anything else

Running here too, and the only thing separating it from the screen in section three is which stat the session was spent on. Rest gets a celebration because Rest earned one.


08 · The gap I have not closed

Lock the phone mid-session and forty five seconds later the session has ended, recorded as stepped away. The thirty second grace period was built for glancing at a notification, not for putting the phone down and going to work, which is the behaviour the product exists to reward.

The app built to reward putting your phone down does not survive you putting your phone down. Closing it is architecture: a Live Activity and a local notification, and a grace rule rethought around both.


Reflection

What I would not repeat is the year of not reading my own research. "Dangerously low" was not something I missed. It was something I wrote, next to a slide saying the opposite.

Every number here started as a sentence I believed. The line height sat behind a comment I wrote saying there was nothing left to find, and the flourish I kept rejecting turned out to be fine, because the way I was looking at it was wrong. Neither would have turned up in a screenshot I approved myself.


Panelware Mitosis Diagrams

all work