Mobile-responsive Nonogram web app built with React, TypeScript, and Tailwind CSS.
- 🎨 95 Curated Puzzles — 5×5, 10×10, 15x15 and 20×20 grids.
- 📱 Mobile Friendly — Fill / X mode toggle for touch devices.
- 🖱️ Desktop Enhanced — Left-click to fill, right-click to mark X.
- 💾 Persistence — Game state and progress saved in
localStorage. - ↩️ Undo — 50-step undo history.
- 🔄 Reset — Restart any puzzle from scratch.
- 👁️ Visual Feedback — Clues dim when satisfied.
- 🎉 Victory Modal — Celebration when a puzzle is solved.
| Layer | Tool |
|---|---|
| Framework | React 19 + Vite |
| Language | TypeScript |
| Styling | Tailwind CSS |
| Icons | Lucide React |
| Testing | Vitest + Testing Library + Playwright |
pnpm install # install dependencies
pnpm dev # start dev server
pnpm test # run unit tests
pnpm test:e2e # run E2E tests (Playwright)
pnpm build # production builddocker compose run --rm coverage # unit test coverage
docker compose run --rm e2e # E2E tests (Playwright + Chromium)Cloudflare Pages Git integration must always have a deployable dist/ directory in the repository.
pnpm build # rebuild dist/
pnpm check:pages-config # verify wrangler.toml and that dist/ is committed and currentCI enforces that dist/ stays in sync with the source so Pages can deploy even when its build command is not available from repository configuration alone.
| File | Description |
|---|---|
src/lib/game-logic.ts |
Nonogram rules, clue generation, win checks |
src/lib/persistence.ts |
LocalStorage management |
src/data/puzzles.ts |
Curated puzzle definitions |
src/App.tsx |
Main UI, routing, and game loop |
src/index.css |
Global styles and Tailwind directives |
Puzzles follow this structure — clues are derived from solution at runtime:
{
id: string;
title: string;
width: number;
height: number;
solution: boolean[][]; // 2D grid of the solved state
}| ✅ In Scope | ❌ Out of Scope |
|---|---|
| Solving puzzles | Puzzle generator / editor |
| Persistence & undo | User accounts / cloud sync |
| Responsive UI | Hints / cheats |