Inspiration

We're just as guilty as everyone else of buying the latest eye-catching trend, only months later to accidentally stumble across it in the back of the closet. That closet is a graveyard of good intentions - clothes we adored for a week and then just forgot about. And once we started paying attention to why, we noticed something smaller but just as frustrating: it is hard to beat that hit of dopamine from something brand new. We wanted to bring that spark back to our clothes so we don't fall into the endless cycle of consumption. How, you ask? By changing our perspective so much on the clothes we've gotten tired of seeing that they feel brand new again. And to do that, we went back to the basics of color theory and fashion. We wanted color measured as a number, a styling engine that explains itself in one honest sentence, and the outfit shown on an avatar cut from an actual photo of the person, not a mannequin who looks nothing like us.

How we built it

Once we knew what we wanted, the build turned into three separate problems that all had to agree with each other, perfect for parallel agents. We split the backend into three lanes, vision, styling, and avatar generation, and forced them to only ever communicate through a contract we froze early on, shared with our Next.js frontend, so nobody ended up wasting tokens reverse-engineering someone else's half-finished work. The vision side takes a retail photo, segments it into three candidate cutouts, and measures the one we keep in CIELAB color space using k-means clustering; then, instead of spitting out coordinates nobody can picture, it hands back a name a person would actually use, pulled from the xkcd color survey. From there, six different color-theory strategies generate candidate outfits, and a deterministic scorer, no network calls, nothing probabilistic, ranks them, so the same inputs always give you the same honest answer. The avatar piece was a part we were very proud of solving well: one body scan produces an instant local composite. Everything lives in MongoDB Atlas with GridFS handling the images, the backend runs Dockerized on DigitalOcean, the frontend sits on Vercel, and we wrote over 130 tests that run entirely offline.

Challenges we ran into

If you'd told us at the start that deployment would be harder than the computer vision, we wouldn't have believed you. A setting buried in our App Platform spec was quietly telling DigitalOcean to ignore our own Dockerfile and fall back to its generic buildpack instead, so it deployed a placeholder scaffold app in place of our real backend. It built successfully and only failed once it actually tried to run, so we lost real hours debugging the wrong layer before we tracked it down to that one line. Separately, we ran into a much quieter issue: tightly-cropped retail photos gave our pose model nothing to anchor a bottom garment to, creating a new style of upside down jeans on models, and it took a fair amount of trial and error to work around. And then there was the moment our color-distance verification flagged two clearly different garments as indistinguishable; dark indigo jeans and black sweatpants sat numerically too close for it to tell apart. That was the moment we realized we'd wandered into a garment-identity problem that color alone was never going to fully solve, no matter how precise our measurements were.

What we learned

Looking back, it wasn't the color science or the CV work that ate our weekend: it was the unglamorous stuff. A missing library nobody warns you about. A buildpack that reports success while quietly building something broken. A crop that looked fine to a human eye and meant nothing to a pose model. We walked away with a healthy respect for the gap between "close enough" and "actually correct" — and a real lesson in humility: a fallback only works if you design it first and treat it like the real product, not something you quietly bolt on after the flashier AI feature fails. AI cannot replicate a human eye.

Built With

Share this project:

Updates

Submission history