Inspiration
Every café has the same shelf: near-expiry lavender syrup, half-used oat milk, a seasonal spice blend nobody ordered. The default is to bin it. Cafés lose an average of $1,200 a month to ingredient waste, not because they lack creativity, but because there is no tool that looks at what they actually have and says: here is a drink you can put on the menu tonight, here is what it costs, and here is exactly why it works.
We wanted to build that tool. And while we were at it, we wanted to solve the customer side too: the person standing at a counter who knows what mood they are in but has no way to describe it to a menu. Two real problems. One shared engine.
What it does
Untasted is a dual-mode AI drink invention engine. The core is a cosine similarity algorithm running over a hand-crafted 8-dimension flavor vector: sweetness, bitterness, roastiness, spice, brightness, creaminess, warmth, complexity. This is not a prompt wrapper. The matching is a real, inspectable computation.
Owner Mode is for the café operator with surplus stock:
- Ingredients with fewer than 3 days until expiry are flagged directly on the chip (⚠️ 2d). Selecting one triggers a live red banner: "Lavender Syrup, 2 days left, act now."
- Untasted builds a flavor profile from the selection, runs cosine similarity against 40+ ingredients, and surfaces the top 5 flavor-compatible matches.
- The output includes a named recipe with barista-precise steps, cost per cup, estimated sell price, margin per cup, a buildability check against current stock, and a count of how many near-expiry items the recipe rescues.
Creative Mode is for the customer or barista with a feeling, not a menu:
- Type a vibe: "something warm and mysterious, like a rainy afternoon in a library."
- An LLM parses that into a structured 8D flavor profile. During loading, the parsed values appear in real time: warmth 9/10, complexity 9/10, brightness 3/10. You can watch the algorithm thinking.
- The same cosine similarity engine selects ingredients, the LLM generates a named recipe with per-ingredient explanations grounded in the actual computed scores, and Pollinations.ai generates original AI artwork for the drink.
In both modes, an animated radar chart renders the full 8-dimension profile live. The reasoning is visible, not buried.
How we built it
Matching engine: Custom JavaScript cosine similarity, running in-process on a Vercel serverless function. No embedding API. No vector database. No paid similarity service. We hand-crafted flavor profiles for 40+ ingredients across all 8 dimensions, then built a diversity filter that drops same-category duplicates within 0.05 similarity score, so recipes read as intentional rather than redundant.
LLM layer: Groq API (llama-3.3-70b-versatile) handles two jobs: parsing vibe text into a structured flavor profile (Creative Mode), and generating the recipe, drink name, and per-ingredient explanations grounded in the actual cosine scores (both modes). Prompts enforce JSON-only output with defensive parsing and automatic fallback on failure.
Frontend: React plus Vite, with framer-motion for spring-physics transitions and Recharts for the animated 8D radar chart. The live radar in Owner Mode updates as you select ingredients. The vibe-parse card in Creative Mode reveals dimension scores as they are computed. Every interaction has a loading state, an error state, and a fallback.
Reliability layer: Three independent safety nets for live demos. A 14-second total timeout with automatic fallback to pre-generated results. Graceful degradation at every API boundary. A Shift+F keyboard shortcut that loads a curated example instantly from anywhere in the app without breaking the visual flow.
Stack cost: Zero. Groq free tier, Pollinations.ai with no API key, Vercel free tier. This runs indefinitely without a credit card.
Challenges we ran into
Making cosine similarity felt, not just explained. The algorithm is easy to describe in a whitepaper and hard to make visceral in 90 seconds. The answer was two moments: the live radar chart in Owner Mode that updates in real time as you select ingredients, and the vibe-parse card in Creative Mode that shows the parsed dimension scores appearing before the recipe loads. Both moments make the computation visible at exactly the right time.
Building honest numbers. Showing a cost estimate was easy. Showing a margin projection that a real café judge would believe was harder. We added the sell price and margin per cup with an explicit footnote disclosing the markup assumption, because a hospitality-industry judge will notice immediately if the numbers feel invented.
Demo safety without complexity. We wanted a system where nothing could visibly fail in front of judges, without building a complicated fallback architecture. Three independent layers turned out to be simpler than one complex one: timeout plus fallback JSON, plus a keyboard shortcut, plus artwork shimmer loading so there is never a blank space.
Accomplishments that we're proud of
The vibe-parse reveal. Watching "rainy afternoon in a library" become warmth: 9/10, complexity: 9/10, brightness: 3/10 in real time is the moment that makes a judge say "it is actually doing something." That moment did not exist in our first build. It took one focused session to make the algorithm legible at the exact point in the flow where a judge is paying closest attention.
The expiry urgency loop. Near-expiry chips show a countdown. Selecting one triggers a live banner. The output counts the rescued items. The waste-reduction story is not stated once and forgotten. It repeats at every step of the Owner Mode flow.
The completeness of the business case. Cost per cup. Estimated sell price. Margin per cup. Explicit markup disclaimer. Most hackathon projects stop at "here is a recipe." Untasted closes the loop to "here is whether it is worth putting on your menu."
Zero paid dependencies. The matching engine, the LLM calls, the artwork, and the hosting all run on free tiers. This is not a demo that requires a credit card to keep alive.
What we learned
Explainability is the product. Every coffee AI tool we reviewed was a black box that returned a recipe. Untasted's entire UX is built around showing the reasoning: the radar chart, the dimension scores, the vibe parse, the cost breakdown, the per-ingredient explanations grounded in actual computed values. Judges trust what they can see working. Customers do too.
We also learned that demo safety is a first-class engineering concern. The three-layer fallback system let us demo confidently regardless of API latency, because there was always a next line of defense. Building that in early, not as a last-minute patch, changed how the whole project felt to work on.
What's next for Untasted
Real inventory integration. Connect to Square, Toast, or Lightspeed POS to populate near-expiry stock automatically from actual purchase records, with real expiry dates instead of estimates.
Menu performance feedback loop. Track which Untasted-generated drinks sell and feed that signal back into the matching engine to improve recommendations over time.
Multi-location analytics. Aggregate which invented drinks perform across café locations to surface candidates for permanent menu additions.
Seasonal and trend mode. Generate drinks tied to real-time ingredient availability and current specialty coffee trends, so the engine stays relevant as seasons and menus change.
Built With
- cosine-similarity
- css
- framer-motion
- groq
- javascript
- llama-3.3-70b
- node.js
- pollinations.ai
- react
- recharts
- vercel
- vercel-serverless-functions
- vite


Log in or sign up for Devpost to join the conversation.