Skip to content

kong33/kiosk

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

205 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Heavenly Cocktail Kiosk

Heavenly Cocktail — A Kiosk Experience for Scent Discovery

A diffuser brand that translates the stories of mythological gods into scent — expressed through cocktail-inspired colors.

production link


Why we built it

📈 Market Opportunity

South Korea's fragrance market grew over 30% in just three years
—from ₩603.5B (2019) to a projected ₩1T by 2025 (Euromonitor).

With the rise of:

  • 🌿 Niche perfume brands
  • 🕯 Home fragrance products
  • 💰 “향테크” (scent as investment culture)

Consumers are seeking a more thoughtful and personalized way to discover their scent.

❗ The Problem

Fragrance discovery is inefficient, sensory-dependent, and overwhelming.

Consumers must smell dozens of products
just to understand what they like.


💡 The Solution

Heavenly Cocktail reimagines scent discovery as a
visual, preference-driven kiosk experience —
eliminating the need for trial-and-error sniffing.


Demo

Demo GIF


🛠 Tech Stack

JavaScript React Million.js Wouter Emotion


⚙️ Technical Highlights


🚀 Rendering Optimization — Million.js

Traditional Virtual DOM reconciliation compares large portions of the tree on every update.

We integrated Million.js, which uses a block-based rendering strategy to track and update only the parts of the UI that actually change.

Million.js comparison

Impact

  • Reduced unnecessary re-renders across the kiosk interaction flow
  • Improved touch responsiveness
  • Delivered smoother UI performance under rapid state updates

🧭 Lean Routing — Wouter over React Router

//App.jsx
import { Redirect, Route, Switch } from 'wouter'
...
return (
    <UserPreference.Provider value={[userPreference, (nextState, delayed = false) => setUserPreference({ ...nextState, delayed })]}>
      <ScentSelectionStatus.Provider value={{ pos, setPos }}>
        <Switch>
          <Route exact path='/starting' component={Starting} />
          <Route path='/choosing' component={Choosing} />
        ...
          <Route path='/product/:product/receipt' component={Receipt} />


          <Route><Redirect to='/starting' /> {/** Or should we redirect to 404 page? */}</Route>
        </Switch>
      </ScentSelectionStatus.Provider>
    </UserPreference.Provider>
  )

Instead of using a heavier routing solution, we adopted Wouter to:

  • Minimize bundle size
  • Reduce abstraction overhead
  • Maintain a simpler mental model

This decision prioritized architectural clarity over ecosystem popularity.


🖼 Image Compression Strategy

User perception research shows minimal visible difference between 100% and 75% image quality.

Below 75%, perceptible degradation increases.

After compression

Engineering Decision

  • Standardized all images at 75% compression
  • Reduced asset weight without compromising user experience

📊 Measured Impact

  • 61.6% reduction in image payload
  • Eliminated redundant renders in kiosk step transitions
  • Reduced routing abstraction weight

Before compression

🧴 Beyond Functionality

Fragrance is not only sensory — it is visual and spatial.

The bottle was designed as a decorative object,
encouraging long-term display rather than short-term consumption.

This transforms the product from a consumable into a lifestyle artifact.

Packaging design


🏆 AWARDS

  • Grand Prize, Artistic Software Competition | Kyung Hee Univ. (2023)
  • Excellence Award, Software Festival | Kyung Hee Univ. (2023)

About

kiosk codebase

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • JavaScript 92.6%
  • CSS 5.8%
  • HTML 1.6%