Puff

Puff

Puff

One reminder at a time

One reminder at a time

One reminder at a time

Set one reminder. Puff naps until it's time, then wakes you up gently. A focus companion that lives in your Chrome side panel.

Set one reminder. Puff naps until it's time, then wakes you up gently. A focus companion that lives in your Chrome side panel.

TIMELINE

2 months on and off, including Chrome Store submission and review

STACK

Vanilla JS · Custom state machine · Chrome Extension APIs · Claude Code · Codex

STATUS

Live, and napping well

Where it started

Too many tabs, too little memory

Too many tabs, too little memory

Puff began with a question: how do you hold one small intention without adding pressure, noise, or another list to manage?

When I'm deep in focused work, especially jumping between tabs down one research rabbit hole after another, I lose track of time and basic self-care, the small breaks I meant to take. Most reminder tools assume you want a planner or task system. But a big task list can become visual evidence of failure, not a useful plan, and notifications feel loud, demanding, easy to dismiss.

I wanted to try removing scanning, prioritizing, and guilt by design. Not "help you get more done," just help you hold one fragile intention without losing it.

The judgment calls

Getting Puff to feel like someone

Getting Puff to feel like someone

A few of the decisions along the way.

1. Choosing presence over popularity

Early on, I had to decide how Puff should actually show up in the browser. Claude flagged a constraint early on: Chrome extensions can't be truly always-on-top, they only show when you click the icon, unless popped into a separate window. It asked directly: should Puff be a quick popup you glance at, or does it need constant visibility?

Neither felt quite right to me on its own. After digging more in Chrome extension docs, I chose to go with the side panel instead. 

This way Puff would stay visible while you work, without needing its own floating window. It meant a few things had to be true: holding one thing in working memory is a simpler mental model than a list, since a task or intention can disappear the moment your attention shifts. Keeping the reminder beside your actual browser tab removes the cost of remembering to check somewhere else entirely. And staying visually calm, no extra notifications or badges, mattered more than staying loud.

2. From looped animation to a character

This was my first Chrome extension, so I was learning the platform as I went. Claude's first pass at Puff's facial animation was a quick, easy loop, two or three expressions cycling on repeat. It worked, technically, but it made Puff feel like a looped GIF, not a character.

I redirected the approach: broke each expression into its own clip, like Lego pieces, and recombined them so the timing never quite repeated. That's what made Puff feel alive instead of automated.

To get there, I split the work into two parallel tracks:

Track A — the shell

A blank side panel that opens. Nothing else yet. I got the manifest, permissions, and plumbing working cleanly first, then built out the four reminder states: Awake, Nap, Remind, Done.

Track B — the animation 

I took Claude's original looped animation apart completely and decoupled it into individual clips, like Lego pieces, so I could recombine them freely instead of being stuck with one fixed cycle.

First, a facial study: building each individual expression on its own, a smile, a wink, a blink, each one tuned in isolation until it felt right by itself.

Then a separate sandbox for sequencing, combining those pieces into actual behavior. I built it so the number of clips used could vary, a shorter mix for a quick moment, a longer one when Puff had more time to react, and made sure any combination could mix and match cleanly, not just a few pre-set sequences. 

Every scene got checked too, not just Puff's face, but where Puff sits relative to the sea, how active the waves are, what the background mood feels like.

Once every state held up on its own and the sequences felt right, I merged Track B into Track A, animation into shell. That's the moment the extension stopped being a blank panel and started being Puff.

Results

Done, Then Onward

This one took longer than PikGarden while building alongside other projects, since the animation system alone needed real iteration. It shipped live on the Chrome Web Store this past summer, and it's still there now, quietly, a small tool built more for myself and anyone who finds it useful than for scale → Puff

A note on process

I used Codex and Claude Code as coding partners throughout. My workflow for this particular project looked like:

Chat with Claude to get started → build both tracks in Codex and Claude Code

I didn't open Figma at all until the very end, just to make screenshots for the Chrome Web Store submission. The workflow itself looked simple, but there was a lot of tuning inside that loop.

What I learned is that spotting an opportunity to use AI is really only half the job. The harder, more valuable part is staying patient enough to keep drilling into and polishing what AI hands you, instead of accepting the first version that technically works. That's the instinct I trust most now, moving fast, but noticing when fast and right aren't quite the same thing.

Email me

© 2026 | Nevermai(nd) the mess. Make it Work.

(Small print: Elegance sold separately.)

Email me

© 2026 | Nevermai(nd) the mess. Make it Work.

(Small print: Elegance sold separately.)

Email me

© 2026 | Nevermai(nd) the mess. Make it Work.

(Small print: Elegance sold separately.)

Email me

© 2026 | Nevermai(nd) the mess. Make it Work.

(Small print: Elegance sold separately.)