🍻 Juomapeli

July 25, 2026 · View on GitHub

🍻 Juomapeli

A fast, browser-based drinking card game for Finnish game nights.

React TypeScript Styled Components

Play online · Report a bug · Suggest a card

About

Juomapeli draws randomized Finnish-language challenge cards for a group of players. Start a quick game immediately or add player names to track turns and ongoing card effects.

Features

  • 235 challenge cards across four visible rarity tiers
  • Quick play without player setup
  • Player mode with automatic turn tracking
  • Continuous effects tracked per player
  • No immediate repeats from the recent card history
  • Resume an interrupted game from the start screen
  • Keyboard controls — the space bar draws the next card, Escape closes overlays
  • Dark, mobile-first UI that scales from a 320 px phone to a wide desktop

Interface

The UI is built for a dim room and a phone passed around a table:

  • Dark theme with a neon accent, so nobody gets a white flash at midnight
  • The card is the screen — tap it anywhere to draw, or use the button below it
  • Rarity is visible: each card is tinted by tier (Tavallinen, Epätavallinen, Harvinainen, Legendaarinen), and legendary draws get a shimmer
  • Mobile puts turn order in a scrolling rail and moves the player and effect lists into bottom sheets
  • Desktop shows those lists as side rails flanking the card
  • Text and controls meet WCAG AA contrast, respect prefers-reduced-motion, and honour safe-area insets

Getting started

Requirements

Installation

git clone https://github.com/roqqq3/card-game.git
cd card-game
npm ci

Start the development server:

npm run dev

Open http://localhost:3000 in your browser. The page reloads automatically when you edit the source files.

Available commands

CommandDescription
npm run devStart the development server
npm run buildCreate an optimized production build in build/
npm startServe the existing production build
npm testRun tests in interactive watch mode

To run the production version locally:

npm run build
npm start

Adding cards

Cards live in src/cards/cardsData.js. Add a new object to cardsDataWithoutIds:

{
  "name": "Example card",
  "description": "Describe the challenge here.",
  "rarity": 20,
  "continuous": false
}
FieldMeaning
nameShort title displayed on the card
descriptionInstructions shown to the players
rarityDraw threshold from 0 (common) to 100 (extremely rare)
continuousWhether the effect remains active for the assigned player

Card IDs are generated automatically from their position in the array, so they should not be added manually.

The rarity value also drives the card's appearance. The tier boundaries live in src/cards/rarity.ts:

rarityTier
019Tavallinen
2049Epätavallinen
5069Harvinainen
70+Legendaarinen

Project structure

src/
├── cards/          # Card data, types and rarity tiers
├── components/     # Game screens and reusable UI components
├── copy/           # Start-screen quotes
├── types/          # Shared TypeScript types
├── utils/          # Session persistence and player-name rules
├── App.css         # App shell layout (menu column, game board grid)
├── index.css       # Design tokens, reset and global styles
├── App.tsx         # Game state, card selection, keyboard handling
└── index.tsx       # Application entry point

Styling is split deliberately: index.css owns the design tokens (colour, type, radii, motion) and App.css owns the page-level layout, while individual components use styled-components that read those tokens as CSS variables.

Built with


Made for game nights in Finland 🇫🇮