← Back to projects
The Jigger shelf on a laptop, showing bottles with their status and how many cocktails each unlocks

Jigger

A home bar that knows what it can pour. University project, 2026

Role
Design and build, solo
Context
PROD353 User Interface Design, University of Canterbury
Duration
One semester, 2026
Deliverable
Design system and working prototype
Stack
Figma, HTML, CSS, JavaScript
Methods
Competitive analysis, sketching, contrast auditing

A home bar outgrows memory somewhere around forty bottles. You buy a fourth triple sec while the vermouth quietly oxidises, and you find out you are one ingredient short of a Negroni at the point you have already started making one.

The existing answer is a stocktake spreadsheet. It tracks volume and cost, it cannot tell you what you can make, and nobody keeps it updated. I wanted the opposite: something that treats stock as possibility rather than as a list.

The problem was three kinds of quantity

A bottle of gin is a continuous level. It empties gradually and you care roughly how much is left. Six limes are a discrete count: they go one at a time and the number is exact. A bottle of Angostura lasts about three years, so in practice it is have or do not have, and nobody has ever run out mid-drink.

Pick one model and you misrepresent two thirds of the shelf. Use three visual treatments and the screen looks like three products stitched together.

The decision

Separate the measure from the state. Everything reports its status the same way; only the detail underneath differs. Quantity became a count of pours rather than a volume, so a bottle reads 16 shots, bitters read 40 dashes, produce reads 6 limes. Same sentence, same position, same weight.

  • Favourite

    Tanqueray No. Ten

    Spirits · Gin

    In stock Gin 16 shots · 500 / 700 ml
    4/6 of 6 recipes
  • Limes

    Produce · Citrus

    Low Citrus 2 limes ·
    2/9 of 9 recipes
  • Favourite

    Angostura Aromatic

    Bitters · Aromatic

    In stock Aromatic 40 dashes ·
    4/4 of 4 recipes
  • Orgeat Syrup

    Syrups · Almond

    Out Almond 0 measures · 0 / 500 ml
    0/3 of 3 recipes
A level, a count, a duration and an absence, reading as one list. These are the product's own components, styled by the same stylesheet the prototype loads, so a change there shows up here. The markup is the row exactly as the prototype writes it, swipe panes and all, because a specimen missing half its parts is a screenshot with extra steps.

One component, three axes

Whichever dimension ran out

Two destinations, and no arrangement that works everywhere. A bottom bar wastes a row on a desktop; a header nav will not fit at 320 pixels. So which one appears is decided by whichever dimension ran out, not by device class.

In portrait, a bottom bar, because thumbs sit at the bottom and there is height to spare. On a desktop, in the header, near the pointer. On a short, wide viewport the header takes them over and the bar retires, handing 90 pixels back to the list. Below that, the bar turns on its side and pins right as a rail, because 64 pixels of width buys 60 pixels of height.

The same shelf on a phone, with the destinations in a bar at the bottom and the search field above the category tabs

At four hundred percent zoom, which is how WCAG reflow is actually assessed, the same shelf runs at 320 by 256: the header unsticks, the category tabs become a picker, search collapses to a button, the view toggle stands down, and nothing needs sideways scrolling.

Every accessibility failure came from fading something

I measured all forty-nine text and background pairs in the system against their real backdrop, with opacity folded into the calculation rather than checking each colour in isolation. That last part is what found the problem.

49pairs measured
29clear AAA
15clear AA
5failed

Not one failure came from a colour choice. All five came from fading. Out-of-stock rows were set at sixty percent opacity, which took the item name to 4.36:1, under the floor for a name you are meant to read.

The rule that came out of it

Fade what identifies the item. Never fade what carries its state. The name and the thumbnail recede on an out-of-stock row; the status pill stays at full strength, because it is the reason you are looking at that row at all. It is also why status is a tinted fill with dark ink rather than coloured text: fading text has nowhere left to go.

Sealed In stock Low Out
Four states, four marker shapes: a dot, a bar, a line and a ring. Status survives a greyscale print, a colourblind reader and a dim room, none of which colour alone would.

What I rejected

Rejected

A stepper in every row

At 148pt it took 43 percent of a 343pt row for a control used occasionally, and it truncated ordinary bottle names. Removing it took the row from 72pt to 64pt, which is more shelf on screen.

Rejected

A standalone sort control

Sort and filter are both infrequent, deliberate choices. Two entry points for one decision doubles the surface and halves the room each gets to explain itself.

Rejected

A dense spreadsheet table

Drawn in the fifth of eight rapid sketches, and it is the stocktake spreadsheet from my research: the thing this product exists to replace. Reproducing a competitor by accident turned out to be a useful signal.

It actually works

Seventy-eight real bottles, mixers and pieces of produce, and forty-two cocktails that know what they need. Pouring a drink spends every ingredient at once, with a bottle chosen per measure. There is full keyboard support, a print stylesheet that turns the shelf into a shopping list, and everything is stored in your own browser and nowhere else.

Open the prototype