Back

3Wines

Gamified wine tastings at home

Try live demo

Problem

A guided wine tasting is a great plan with friends, but it needs a sommelier, a venue and a booking. Doing it at home usually means opening bottles with no structure: nobody knows what to look for, and the evening never becomes the shared experience it could be.

3Wines – host room with controls and participants
3Wines – TV room, nose phase with the sommelier
3Wines – player screen on the phone

Solution

3Wines is a platform for gamified wine tastings. A physical pack brings the wines home, and the tasting runs as a live game on the TV, with players joining from their own phones.


My role

The project started as a team build at a product hackathon, where it won the project competition. After that, I took it over on my own and rebuilt it as a 2.0 to fix scalability issues: I reworked the landing, host app, player app and TV mode, moved the database to my own project and audited it, and created a completely new branding, closer to the wine sector. I owned product design and the 2.0 build, with an AI agent writing the code under my direction and review.

What I did

  • Game design: session flow, phases, scoring and the sommelier script. Tools: Markdown specs, Claude Code, ElevenLabs
  • UX/UI for three screens in sync: TV room, player phone and host controls. New brand identity. Tools: Lovable, Claude Code, ShadCN (Tailwind CSS + Radix)
  • Real-time multiplayer with the host as the single source of truth. Tools: Claude Code, TanStack Start, Supabase
  • Checkout and order fulfilment. Tools: Stripe
  • Repository, database and deployments. Tools: Claude Code + MCP/CLI (Supabase, GitHub, Vercel)

How it works

  1. 1. Landing and packs
    3Wines – landing page 3Wines – Winelover pack card
  2. 2. Cart and Checkout
    3Wines – Stripe checkout 3Wines – cart with shipping details
  3. 3. Live game
    3Wines – TV room, sight phase 3Wines – host room with controls and participants
3Wines – Winelover pack, 80 € 3Wines – Enology pack, 120 € 3Wines – Deluxe pack, 160 €

The pack is the product

3Wines sells a physical pack and delivers a digital experience. The game is the reason to buy, but the business is the pack: three tiers (Winelover 80 €, Enology 120 €, Deluxe 160 €), each with three wines in numbered opaque sleeves for a blind tasting.

3Wines – TV lobby with the QR to join

From checkout to the first pour

Buying needs no account: pick a pack, pay with Stripe, and it arrives in 3 to 5 working days. The pack carries the URL that opens the host room, so there's nothing to install. A QR on the TV brings the rest of the table in, and Wina, the AI sommelier, takes it from there.

New wines, same game

Packs rotate every 3 months. Each rotation is a new reason to buy again, while the game stays the same: same rounds, phases and scoring, with new wines in the glass. Keeping that rotation cheap to run is what shaped the game engine.

Same game Rounds · phases · scoring No deploy
  1. 1Pick 3 new wines
  2. 2Import the wine data (CSV)
  3. 3Answer options built from the data
  4. 4New sommelier clips, routes updated
  5. 5Ship the new packs
↻ Every 3 months
3Wines – live tasting session at home, TV and phones at the table

Validated at real scope

The hackathon win validated the concept. The rebuild was validated by playing it: full sessions gameplay, real wine data and a TV. Demo mode allowed testing a full session without a pack, which made every iteration quick to check.

Some good product choices

A host who also plays

In a home tasting there's no game master on the side: the person running the evening is one of the players. The host needed to drive the session without leaving the game, managing the host app with a minimal interaction to keep focus on the player side.

Prompt
On /play, the host answers the same quiz as everyone else. On /room, a compact footer bar for gameplay management; left: label contains the player URL reminder; center: start, next phase, reveal all-in-one component; right: flat, icon-based volume and cast controls. The cast control has a tutorial tooltip on top.
The host's client is the single source of truth: it owns RoomState and
broadcasts it. Players and the TV only render what they receive and
send answers back. No player can advance the game.

The TV runs the session and the timers, and phones only show the active question. Everyone looks up at the same moment, which keeps the tasting social instead of six people staring at their phones.

3Wines – TV room, palate phase with the sommelier
Prompt
Decouple the quiz engine from the wines. Session structure (3 wines ×
sight / nose / palate / bet) stays in code. Questions, answers and wine
cards come from the database per pack, through a QuizSource interface.
Demo mode keeps a local source with the same contract.
Adding a new pack must not require a deploy.

That keeps every pack rotation a content job, not an engineering one: update the mp3 clips and their routes, and the game is ready.

The game is a shell

The hackathon version had the content as directly wired mp4 vids. To scale, the session structure had to stay fixed while the wines change: same rounds, phases and timers, with only the content of each wine swapped in the shape of light-weight, copy + AI-generated mp3 clips.

Code session.ts
// Fixed in code: 3 wines × 4 phases
export const WINE_COUNT = 3;
// sight · nose · palate · bet
export const FASES: readonly Fase[] =
  ["vista", "nariz", "boca", "bet"];

// reveal → next phase, or the wine's podium
const faseIdx = FASES.indexOf(state.fase);
const nextFase = FASES[faseIdx + 1];
if (nextFase) return {
  ...state, fase: nextFase, step: "quiz",
};
return { ...state, stage: "wine_podium" };
Code quiz-source.ts
// Swapped per pack: database or demo
export type QuizSource = {
  source: "bd" | "demo";
  // prompt + options, never the answer
  questionFor(wineIndex: number, fase: Fase):
    { prompt: string; options: string[] };
  closeQuiz(/* … */): Promise<CloseResult>;
};
  • +10 pts

    Sight

  • +10 pts

    Nose

  • +10 pts

    Palate

  • +20 pts

    Grape type

  • +30 pts

    Classification

  • +15 pts

    Price range

3Wines – TV room, podium with the sommelier

Points anyone can follow

The first scoring model gave a base score plus a speed bonus for the fastest correct answer. In play, it rewarded the fastest thumb rather than the best palate, and it didn't match what the landing promised.

Prompt
Replace the scoring model to match the landing's "How scoring works".
Sensory phases (sight, nose, palate) = 10 pts per correct answer.
The bet phase rotates by wine: grape type 20, classification 30,
price range 15. Remove the speed bonus: every correct
answer is worth the same, whoever sends it first.

Fixed points per phase are easy to explain at the table, and the landing and the game now promise the same thing.

How it was built

Rebuild QuiqueRG/3wines · 43 commits

Backend

  • Jul 08Schema moved to my own Supabase project
  • Jul 08Wine prices as decimal €, unused cost column dropped
  • Aug 05Security and performance audit fixes
  • Aug 05Storage policies per bucket, unused tables dropped

Game

  • Jun 25TV view with sommelier clips per phase
  • Aug 062.0: room, player and TV overhaul
  • Aug 06Fixed points per phase
  • Aug 06Audio unlock for the sommelier voice
  • Aug 07Final podium redesign with confetti

Brand and commerce

  • Aug 11Cart and checkout polish
  • Sep 14Rebrand to 3Wines, v2 landing

The quiz engine, edge functions and Stripe flow came from the hackathon build and stayed. The 2.0 work went into what players see and touch, and into a security pass the MVP never had.

Claude Code was connected to the stack through MCP and CLI (Supabase, GitHub, Vercel). A learnings.md log recorded every non-obvious fix, so the same mistake was never debugged twice.

From hackathon MVP to 2.0

3Wines started as a team build at a hackathon, planned from a PRD and shipped spec by spec. After it won, I forked it and carried it on alone. I moved the backend to my own Supabase project, audited it, and rebuilt the three screens, the scoring and the landing into a 2.0 under a new brand. Claude Code wrote the code; I set the direction, made the product calls, reviewed every change and hand-edited the CSS.

Audit security_and_performance_cleanup.sql
Trigger
Supabase's advisor audit flagged the inherited schema on my own project.
Fixes
  • Views run with the caller's permissions, not the owner's.
  • Any signed-in user could list admin IDs. Now only admins can.
  • Function search paths pinned, missing foreign-key indexes added, overlapping admin policies split per action.
Product decision
The public monthly ranking is served through one read-only function, so player tables stay closed.
Code styles-v2.css
/* Answer reveal on the player's phone */
@keyframes shake-x {
  0%, 100% { transform: translateX(0); }
  15%      { transform: translateX(-8px); }
  30%      { transform: translateX(7px); }
  /* … settles down to 1px */
}
._3w-answer-shake {
  animation: shake-x 0.55s
    cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}
._3w-answer-rubberband {
  animation: rubberband-x 0.9s ease-out both;
  transform-origin: center;
}

Takeaways

The game is only one step

Checkout, shipping and activation decide whether the evening ever starts. Designing the whole loop matters as much as designing the game.

Magic in a demo, a bill at scale

A live AI sommelier is impressive on stage and expensive at a thousand tables. Pre-rendered clips per phase keep the experience close at a fraction of the running cost.

One source of truth

With three screens in sync, letting a single host own the state removed a whole class of bugs before they appeared. A clear rule for coding is also the simplest one to build.