How it’s built
A look under the hood: the libraries we lean on, the practices we hold ourselves to, and the architectural calls that shaped this app.
Stack
App Router with a catch-all route for instant client-side navigation.
Hooks-only, concurrent-ready function components.
Strict mode end-to-end. Domain modelled with discriminated unions and exhaustive switches.
Token-driven design system with motion tokens, brand palette, and custom easings.
Vendor-prefixing pipeline.
Hand-written shaders for the aurora background — FBM noise, spark cycle, custom palette.
Tiny WebGL helper for the ambient canvas burst layer.
Choreographed UI transitions that respect reduced-motion.
144 unit tests across game logic, scoring rules, persistence, and UI helpers.
End-to-end regression suite for refresh survival and game flow.
Browser-like environment for component-adjacent tests.
Coverage reports wired into CI scripts.
Next.js + TypeScript ruleset, no warnings tolerated.
Performance and accessibility budgets tracked between releases.
Practices
The standards we apply to every change. Quality is not a phase — it is the working method.
Every behaviour change starts with a failing test. The suite covers scoring rules, dealer rotation, elimination, persistence, and refresh survival — so refactors stay fearless.
Tests describe outcomes, not implementation. Factories build domain objects so specs stay readable and resistant to incidental change.
Game state, events, and rules are encoded as exhaustively-checked discriminated unions. Illegal states are unrepresentable.
The ambient WebGL layer respects prefers-reduced-motion, prefers-reduced-data, document visibility, and low-end device heuristics. No GPU work for users who do not want it.
No accounts, no server, no user database. Game state lives in your browser — analytics are aggregate-only.
New visual layers are gated by an explicit ≤ 30 kB gzipped delta budget. Performance is a constraint, not an afterthought.
Work is sliced into 1–3 hour increments using the expand-contract pattern. Every commit leaves the app shippable.
Optimised for learning and adaptation over prediction. Small batches, fast feedback, sustainable pace.
Architecture
A single [[...slug]] route hosts every game screen. Routing happens client-side for snappy transitions while still giving each page proper SEO, canonical URLs, and Open Graph metadata.
All state mutations flow through a typed reducer with named events (ADD_ROUND, TOGGLE_ELIMINATION, CHANGE_DEALER, …). Pure, testable, and trivially time-travel-able.
Game state is persisted locally with a versioned schema. A cache-busting orchestrator detects stale state on deploy and migrates or resets safely without surprising the user.
Ambient celebration bursts are emitted from game logic via a tiny module-level singleton. No React Context, no provider tree pollution — just a function call from the reducer touchpoint.
The scoreboard background is a fragment shader: layered FBM noise, a 22-second spark cycle, deep-navy → emerald → persimmon palette. Ported from the Wrume hero, unified across the studio.
Animations, ads, and graphics enhance the experience but are never load-bearing. The core game works on minimal hardware with motion off.
Built by Wrume
If this is the kind of work you appreciate, you can find more of it at wrume.com.