CJ Williams ← All Work

Case Study

Cards in Bars

A party game for bars. Your phone is your hand, the TV is the table, and there is nothing to install.

Cards in Bars
Client
Personal product — first venue is Innjoy in Logan Square, with its own deck of local cards
Role
Product Designer & Sole Developer
Timeline
Aug 2026 – Present
Team
Solo — design, front end, back end, deployment

Product Design · Multi-Surface UX · 10-Foot UI · Real-Time Systems · Full-Stack Development

The Challenge

A Cards Against Humanity–style party game built for bars. The venue puts a QR and a permanent code on a TV; patrons scan it, type a name, and are dealt in from their own phone.

The core problem: split one game across two surfaces — a private phone and a public screen — so each shows what its audience needs and nothing it shouldn't. In a loud room, ten feet from the TV, with a drink in one hand.

What I Did

01 Getting in without an app

Nobody installs an app to play one round. Every second between seeing the TV and holding cards is a chance to give up.

A permanent per-venue code and QR, printable on a table tent. Scanning drops you into the game; the only required step is a name. Accounts are optional and use a recovery code, not an email and password.

Start or join — scan, type a name, dealt in
Start or join — scan, type a name, dealt in

02 Two screens, one game

The phone is private, the TV is public. Show the wrong thing on either and the round is ruined — a leaked hand, or a shared moment trapped on one screen.

Each surface gets a different payload. Phones get their own hand and nothing else; the TV gets public state on a read-only channel.

Judging on the TV — every answer face-up for the room, while each phone shows only its own card
Judging on the TV — every answer face-up for the room, while each phone shows only its own card

03 Designing for ten feet

The TV was designed at desk distance. Supporting copy sat at 21px on a 1080p panel, and the QR — the only thing that turns a stranger into a player — had a third of the screen while a demo took two thirds.

A viewport-height type scale with a ~24px floor at 1080p, and a nested bento layout with the QR as the hero tile.

The table view — prompt, players, and round state sized for the back of the room
The table view — prompt, players, and round state sized for the back of the room

04 The review that found real bugs

The work had gone reactive — spot something, fix that one thing. Functional tests only prove code does what it was told to.

A screen-by-screen pass in player order, judged against measured values. It found a written card destroyed when a judge disconnected, a sheet advertising a swipe that did not exist, and an idle TV claiming someone was playing to an empty room.

Your hand — private to your phone
Your hand — private to your phone

How It Was Validated

  • A headless harness drives real games over sockets — 23 assertions covering the deal, rotation, round expiry, discards and the 20-round cap
  • A screen-by-screen design review of all 12 player screens and the TV, judged against measured values rather than impressions
  • Killed the server mid-round in production to confirm the table and every phone recovered

After Launch

  • Deployed on a persistent host with a mounted volume — games survive restarts and deploys
  • A Playwright rig drives a real game and photographs both surfaces, so every screenshot regenerates in one command
  • Next: the bar-facing admin screens, and a first full night at Innjoy

The Outcome

2,495Cards in the deck
0Installs to play
23Automated rule checks

Reviewing an interface properly turned out to be quality control, not decoration — walking every screen in the order a player meets it found three real bugs that functional tests had missed. Building it alone meant every design decision had to survive contact with the system implementing it.

Both Surfaces