By the numbers

2 → 6
steps to an answer: mature Mirror to new shopper, same event, same catalog
74
real Amazon listings, pulled and judged at build time
97
self test checks, each one a real failure mode found wiring the catalog in
Product brief
Ecommerce can help with "gold low block heel, size 8, under $175." It cannot help with "I need to look right at Sarah's outdoor wedding on September 19." Mirror is built on the claim that the translation between those two sentences is the product.
It is a mobile prototype with a real catalog: 74 Amazon listings pulled at build time, Maya's own closet ranked against them, and a deterministic parser that answers offline and identically on every run. When it is confident, it shows one product and says "I'd start here." When it is not, it asks one question, never a form.
Two principles run through everything. The customer should not need to know what shoe she wants before the product can help her. And the smarter the system becomes, the less interface she should need.

2 → 6
steps to an answer: mature Mirror to new shopper, same event, same catalog
74
real Amazon listings, pulled and judged at build time
97
self test checks, each one a real failure mode found wiring the catalog in
I researched, designed, and built it: five research documents before any product code, the product model and its two principles, the state machine, the confidence gate, the Mirror, the design language and its enforced design system, the brand, the three sample shoppers, the generated image library, the catalog pipeline, the capture pipeline, and the audits that went looking for my own failures.
Role
Product Designer, Engineer
Timeframe
2026
Disciplines
Research, Product Design, Interaction Design, Design Systems, Brand
Live, on the real catalog, with the demo controls behind a flag. Six journeys from first launch to three months, two branches, four maturity rungs, three sample shoppers, two categories. Purchase is simulated at the last step. The deterministic parser is the floor; a Claude route handles phrasings it cannot map when a key is present.
Stack
Next.js 16, React 19, XState, Motion, GSAP, Base UI, Tailwind 4, Zod
Catalog
Canopy API over Amazon, enriched by Claude, cached to JSON
Platform
Phone first web app, no account, no network at runtime

































Build a shopping agent that helps before the shopper knows what to ask for, prove it is reasoning rather than staged, and make its principles enforced rather than asserted.
AI referred retail traffic grew 393% in a year and by early 2026 converted better than the rest of the web, yet the shipped products were chat boxes over search. The research said the winning shape is different: conversation carries intent, a generated interface carries refinement and commitment, and shoppers want an advisor within stated boundaries, not a proxy. Delegation is earned per category, per price band, over time. Mirror is a bet on that shape.
A shopper with an event does not have a product in mind; she has a date, a dress, a venue, a budget and a fear of getting it wrong. Every store makes her do the translation first. Fit is the primary axis, not an edge case: about half of apparel returns are size related. She needs the system to say what it knows, admit what it does not, never assert a size the data does not support, and volunteer the answer it earns nothing from when she already owns it.
The original brief was an agentic Amazon assistant for "a quiet mechanical keyboard under $100," a CLI with a cart link. Five research documents (about 6,300 lines, every figure tagged by source reliability, vendor statistics re-sourced before use) came before any product code. Then the brief was replaced outright and the old one left in git history. Keyboards became the event; Amazon became one source among six; frictionless checkout stopped being a virtue. The one idea that survived, reading one and two star reviews for hidden flaws, became the Evidence Lens. The CLI agent was kept as a working reference with its eleven case golden set and, stated plainly in the README, shares no code with the app.
The first spec said if confidence is at least 0.9, show one product. I rejected it in writing as a magic constant dressed as intelligence. Confidence is now derived from two things the system genuinely knows: the score margin between the top candidates, from the same function that ranked them, and the count of unresolved dimensions. It returns an ordinal band, so "94% match" is a compile error rather than a code review habit. On the real catalog that rule bit back: mass tier Amazon inventory is attribute uniform, so the top candidate never beat the runner up and "I'd start here" could not fire at any maturity. Review evidence, weighted by volume, became a bounded ranking term; two of five missions now answer with one product on the real catalog, and the page says "The closest I have" when they do not.
Maya's own shoes rank on merit against retail through the same scorer. Three of four lose and the interface says why; the black slingback legitimately places at $0. One owned answer maximum. Nora, the second shopper, owns nothing that qualifies, and the honest outcome is that the closet pass returns nothing and says so rather than surfacing a near miss to keep the feature visible. Same code, same rule, opposite result: a better test than a second winning $0 answer.
Three passes went looking for my own failures. The interaction pass hunted claims that outlived what made them true and controls that looked like affordances and were not: a comparison screen reassuring her about constraints nothing had applied, a fit verdict contradicting its own evidence, a "Forget this" control with no handler, 18px touch targets on the fastest route through the app. The first run audit found the empty start flow built, marked done, and unreachable: the default profile opened a brand new install into six months of someone else's history. A new shopper could answer the fork honestly, forever, and never be shown a recommendation. The polish round found "black loafers" leading with a gold shoe because the router kept the noun and dropped the adjective. Each is written down with its fix.
App
Catalog
Imagery and proof
The core path is a deterministic parser, not a model; the point to prove is that conversation changes the workspace, offline and identically every run, and the reference engine slots behind the same interface next. Profile states are fixed snapshots you switch between, not learned from you. Purchase is simulated at the final step. The public deploy runs without a model key, so it understands fewer sentences than the local build with one. Three sample shoppers, no user testing yet.