Clink Clink

Inspiration

“Clink Clink” originated from a very personal thought: I wanted to make a birthday gift for a friend I’ve known for over twenty years, but I didn’t want to just write a letter or create a one-time webpage.

My friend once said that our friendship is like wine—it takes on different flavors at different moments, and it has room for silence, change, and reunions. So I designed five shared memories as five drinks: the player chooses a “flavor” that reflects the present moment, and I secretly add a “mystery flavor” known only to me. With every sip, a shared memory surfaces; once all five drinks are finished, all the choices come together to form a “Today’s Drink Menu,” with a birthday letter on the back.

It’s not a product that teaches people how to mix drinks, but rather an emotional gift that can be personally experienced and slowly unfolded.

What it does

“Clink a Glass” is a mobile interactive narrative mini-game.

  • Players take turns completing five rounds of cocktail mixing, with each round posing a question centered on friendship, change, solitude, unspoken words, and the future.
  • Each round consists of four steps: choosing a flavor, adding a secret ingredient, naming the cocktail, and savoring the memories in three sips.
  • The user’s choices alter the drink’s dominant color and final name, giving each round a personal touch.
  • At the end, an interactive receipt featuring the five drinks is generated; flip it over to read a letter written for the recipient.

How I Built It

The project uses React + Vite for the front end, with CSS handling most of the visual and interactive animations, and integrates with Supabase to save game progress and each round’s selections.

  • I used a React state machine to manage the workflow for each glass of wine: selecting → pouring → mystifying → naming → sipping, allowing different stages to transition naturally in place rather than with abrupt page cuts.
  • Custom CSS variables control the liquid level, color, transition duration, and clipping shapes for different glass types; the liquid rises from half a glass to three-quarters full, then gradually decreases with each “three sips.”
  • Different glass types, flavor color palettes, and mystery flavors were designed for each of the five rounds, ensuring that visual changes serve the narrative rather than merely acting as cosmetic skins.
  • Use Supabase to log each game session, round-by-round selections, and drink names; during settlement, data is read asynchronously to generate a personalized receipt.
  • Game configuration supports loading different questions, memories, and letter contents via the game parameter in the URL; if loading fails, it automatically falls back to the default configuration to ensure an uninterrupted experience.
  • The final receipt includes print and pause prompts, as well as clickable and keyboard-activated flip interactions, accompanied by subtle sound effects.

Visually, I wanted it to resemble an indie movie poster that slowly unfolds, rather than a high-saturation beverage advertisement: low-saturation watercolor tones, paper grain, handwritten titles, restrained white space, and animation rhythms kept as calm as possible.

Challenges I Faced

The biggest challenge wasn’t “getting the features to work,” but ensuring the technology didn’t disrupt the emotional experience.

First, animations can easily come across as ordinary web page transitions. To avoid black screens, page jumps, and layout jitter, I broke each step down into distinct states and kept elements within the same stage as much as possible, using fade-ins, fade-outs, and transformations. In particular, the cup replacement, the rising liquid, the appearance of decorations, and the transition of memory text all required maintaining stability in position, size, and rhythm simultaneously.

Second, visual feedback is often subjective—comments like “It looks too much like an ad,” “The cup seems a bit floating,” or “The colors don’t look enough like watercolors.” I learned to translate these impressions into verifiable, small adjustments: first tweaking just one layer, one alignment, or one color weight, then reviewing the result—rather than overhauling the entire page at once.

Third, asynchronous data writes can disrupt immersion. During database cold starts or network fluctuations, if the page simply goes blank and waits, the emotional flow is broken. Therefore, during final checkout, the interface first enters a “Closing for the Day” transition, then completes saving and loading in the background, making the wait itself part of the narrative.

Finally, personalization also involves privacy boundaries. I reserve my most private and specific memories for configurable content; if displayed publicly, I anonymize chat screenshots, names, and sensitive information, retaining only the emotional structure of the work.

What I Learned

I’ve learned that the core of an emotional product isn’t necessarily complex features, but rather consistently answering one question: *Who does it want to make feel what?

Translated with DeepL.com (free version)

Built With

  • claude
  • gpt
  • minimax
Share this project:

Updates