Commit Graph
32 Commits
Author SHA1 Message Date
tiennm99 0570ca75f8 refactor: dedup dialog CSS and tighten focus management
- DonateModal: focus the dialog on open so screen readers announce it
  and Tab cycles within; restore focus to the previously-active element
  on close.
- Move shared overlay/dialog scaffolding to app.css so GameView's win
  dialog and DonateModal stop duplicating the same backdrop and frame.
- Move touch-action and tap-highlight neutralization to a global
  button rule; drop the per-component copies.
- level-parser: collapse the key/cellKey alias - export cellKey
  directly.
- BoardModel.isSolved: inline the empty-box-set guard into the return.
- LevelSelectView: completedCount is read once and never reassigned;
  drop the $state wrapper.
- Board: hoist the wall-trim DIRS array out of $derived so it isn't
  rebuilt every reactive recomputation.
2026-04-27 21:03:22 +07:00
dependabot[bot] 78eac20994 build(deps): bump rollup from 4.40.0 to 4.60.2 (#5)
Bumps [rollup](https://github.com/rollup/rollup) from 4.40.0 to 4.60.2.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.40.0...v4.60.2)

---
updated-dependencies:
- dependency-name: rollup
  dependency-version: 4.60.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-27 21:02:16 +07:00
dependabot[bot] 254514c2a6 build(deps-dev): bump postcss from 8.5.3 to 8.5.12 (#7)
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.3 to 8.5.12.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.3...8.5.12)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.12
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-27 20:59:13 +07:00
dependabot[bot] bc9854f16e build(deps): bump picomatch from 4.0.2 to 4.0.4 (#4)
Bumps [picomatch](https://github.com/micromatch/picomatch) from 4.0.2 to 4.0.4.
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/4.0.2...4.0.4)

---
updated-dependencies:
- dependency-name: picomatch
  dependency-version: 4.0.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-27 20:58:23 +07:00
tiennm99 44ba72b36a docs: housekeeping after whole-project review
- README: drop incorrect 'syncs across all devices' claim about
  localStorage progress.
- package.json: description still said Phaser 3; it's Svelte 5 now.
- Mark the two old plans as completed (work shipped long ago).
- Add the 4 review reports to plans/reports/.
2026-04-27 20:51:40 +07:00
tiennm99 dff4ea9eab fix: address review-pass findings
- GameView: ignore game keys (Esc/R/U/Z) while the donate modal is open
  so its own Escape no longer doubles as a navigate-to-levels.
- GameView: tag the win dialog with role/aria-modal/aria-labelledby so
  screen readers announce it correctly.
- LevelSelectView: read the progress snapshot once per page render
  instead of two localStorage parses per visible tile (40 reads -> 1).
- progress-store: add snapshot() method for batch reads.
- vite-plugin-pwa: include jpg in the workbox precache glob so the
  donation QR keeps working offline.
2026-04-27 20:51:37 +07:00
tiennm99 fe2d98e710 docs: document mobile comfort overhaul
Update codebase summary, system architecture, changelog, roadmap and
PDR to cover the new mobile input layer, haptics, gesture blocking
and PWA. Refresh README features. Add the brainstorm, plan and review
artifacts under plans/.
2026-04-27 20:38:23 +07:00
tiennm99 374422abdd feat(pwa): full offline support via vite-plugin-pwa
Register VitePWA in the production config with autoUpdate, Nord theme
colors, /sokoban/ start_url and scope, 192/512 plus a maskable icon.
Workbox precaches the built bundle so subsequent visits run offline.

Generate matching pwa-192/512 and apple-touch-icon PNGs in public/ so
"Add to Home Screen" picks up a proper icon on iOS and Android.
2026-04-27 20:38:23 +07:00
tiennm99 bb720327a0 feat(mobile): comfort overhaul - D-pad, gesture blocking, haptics
Add on-screen D-pad (bottom-right) and action stack (UNDO / RESET /
LVLS, bottom-left), shown only on coarse-pointer devices. Hide the
duplicated header actions on touch.

Block iOS/Android browser quirks: pull-to-refresh, double-tap zoom,
long-press selection and callout. Game stays inside the viewport via
overscroll-behavior and per-element touch-action rules; viewport zoom
is left enabled for accessibility.

Add navigator.vibrate wrapper (haptics.pulse) and fire short pulses on
box push and longer pulse on level solve. Silent no-op where the API
is missing.

Reserve room for the bottom controls in computeTileSize on coarse
pointer; raise minTile to 16 for legibility on small phones.
2026-04-27 20:37:27 +07:00
dependabot[bot] a1beee1dd0 build(deps-dev): bump vite from 6.3.6 to 6.4.2 (#3)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.3.6 to 6.4.2.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v6.4.2/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v6.4.2/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 6.4.2
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 17:56:04 +07:00
tiennm99 501fc7bc76 feat: add code-server dev profile
Adds npm run dev:codeserver with Vite config tuned for code-server's
/absproxy/<port>/ route: host binding, allowedHosts from env, and HMR
over wss on clientPort 443. Host/port read from .env.local (gitignored);
.env.example documents required vars.
2026-04-20 16:01:04 +07:00
tiennm99 dc1d51c253 feat: add donate QR modal and site footer (#6)
Menu exposes a Donate button; the win dialog offers a Buy Me a Coffee
link. Both open a shared modal showing the VietQR code from
public/assets/qr.jpg. A persistent footer credits miti99.com.
2026-04-18 21:54:20 +07:00
tiennm99 4d69ef979d fix: prevent left-side clipping on large boards
Replace flex centering on scroll container with margin auto on the
board element so overflowing boards remain fully scrollable.
2026-04-12 09:47:09 +07:00
tiennm99 d46ccb6d50 fix: prevent large levels from overflowing the viewport
Add scrollable overflow to board wrapper, use safe centering to avoid
top-cropping, and lower minimum tile size from 16px to 10px.
2026-04-12 09:35:28 +07:00
tiennm99 8a3d4b4a9d feat!: rewrite on Svelte 5, drop Phaser
Replace Phaser 3 with Svelte 5 as the rendering and UI layer. The
framework-agnostic core (level parser, board model, progress store,
microban level data) moves from src/game/core → src/lib/core with zero
code changes. Scenes and the hand-rolled button factory are gone; in
their place:

- src/App.svelte            root router (menu / levels / game)
- src/views/MenuView        title + play + progress + hints
- src/views/LevelSelectView paginated 5x4 grid with native <button>s
- src/views/GameView        owns BoardModel, handles input, HUD, win
- src/views/Board           purely presentational DOM renderer
- src/views/AppButton       shared themed wrapper for native <button>
- src/app.css               Nord palette ported to CSS variables

GameView uses a non-reactive BoardModel ref and syncs plain snapshot
fields (player, boxes, moves, won) into $state after every mutation —
Board consumes only plain props, so Svelte reactivity stays predictable
and the core class stays framework-agnostic. GameView is keyed on
levelIndex in App, so changing level remounts with fresh state.

Native <button> everywhere kills the click-hitbox class of bugs.
Animations are now CSS transform transitions (110ms) instead of tweens.

Bundle shrinks from ~1.5 MB Phaser to ~65 kB JS / 23 kB gzipped — about
60x smaller. Removed: phaser, terser, src/game, log.js (analytics
ping), phasermsg vite plugin, manual Phaser chunks, terser config,
public/style.css. Scripts simplified to dev/build.

Docs updated: codebase summary, architecture, code standards,
changelog, roadmap, README.
2026-04-12 00:50:46 +07:00
tiennm99 94fee81e6b chore: set package.json license to Apache-2.0
Match the LICENSE file, which has always been Apache-2.0. The prior
"MIT" declaration in package.json was a mismatch with the actual
license text shipped in the repo.
2026-04-11 23:44:19 +07:00
tiennm99 497d114424 docs: add LICENSE-LEVELS for Microban layout attribution
Separate the puzzle-data licensing from the main repo license. The
Microban layouts are David W. Skinner's copyright, used under his
free-redistribution-with-credit permission — not covered by this
repository's main LICENSE. New LICENSE-LEVELS.md spells that out and
lists where credit is preserved (data file header, menu scene, README,
PDR). README now links to both files.
2026-04-11 23:41:02 +07:00
tiennm99 2ee7ac886a feat(levels): ship the full 155-puzzle Microban set
Expand the level data from the first 100 Microban layouts to the complete
set, up through the two oversized finale mazes ("Take the long way home"
and "The Dungeon"). Responsive tile sizing already handles the large
grids — no rendering changes needed.

Update credit language in README, PDR, changelog, roadmap, codebase
summary, menu subtitle, and the data file header to reflect the full
set. Credit for David W. Skinner's layouts remains prominent; ownership
of the engine, UI, parser, and progression code stays explicit.

Verified all 155 layouts parse cleanly, have a player, matching box/goal
counts, and none start already solved.
2026-04-11 23:36:34 +07:00
tiennm99 97d43d0d57 docs: scope Microban credit to level layouts only
Reword README, PDR, menu scene, and the data file header so the Microban
credit clearly covers only the puzzle layouts borrowed from David W.
Skinner. The parser, renderer, UI, and progression code are original, and
ownership is now stated explicitly. Attribution for Skinner is preserved
everywhere it appeared.
2026-04-11 22:55:07 +07:00
tiennm99 34eaf1b2a7 fix(ui): make buttons reliably clickable
Remove the scale-on-press animation from the shared button factory. Scaling
the container also scaled its hit rectangle, so any small pointer drift
between pointerdown and pointerup landed outside the shrunken hitbox and
the click was silently dropped. Releasing off the button also left it
visually stuck at 0.96 scale.

Fire the callback on pointerdown instead — snappy, no release tracking,
identical behaviour for mouse, touch, and fast clicks. Hover colour change
still provides press feedback.
2026-04-11 22:55:02 +07:00
tiennm99 1d2fff6bf8 feat: ship 100 Microban levels with overhauled UI and modular core
Replace the 3 hand-crafted JSON levels with the full Microban set (100 solvable
puzzles by David W. Skinner) stored as XSB text and parsed at runtime. Rework
the game into kebab-case modules under a 200-LOC budget:

- core/level-parser: XSB parse with flood-fill interior detection
- core/board-model: pure move/undo/win logic, Phaser-free
- core/progress-store: localStorage persistence with graceful fallback
- core/theme: Nord palette, fonts, responsive tile sizer
- ui/button-factory: one rounded button impl with hover/press
- ui/board-renderer: animated tile/wall/goal/box/player drawing
- scenes: menu, paginated level select (5x4 grid, 5 pages), game

Add WASD movement, U/Z undo, R restart, Esc to menu, live move counter,
best-move tracking per level, win overlay with next/levels actions, and a
radial-gradient CSS backdrop.

Drop the dead Arcade Physics wiring, the broken manual shutdown/destroy code,
the unused main.js self-import, and the hardcoded 3-level registry state.

Add docs/ and refresh README.
2026-04-11 21:58:00 +07:00
Tien Nguyen Minh a61d5a2410 Merge pull request #2 from tiennm99/dependabot/npm_and_yarn/vite-6.3.6
build(deps-dev): bump vite from 6.3.4 to 6.3.6
2025-09-30 09:32:11 +07:00
dependabot[bot] 94082195e1 build(deps-dev): bump vite from 6.3.4 to 6.3.6
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.3.4 to 6.3.6.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v6.3.6/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v6.3.6/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 6.3.6
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-10 01:40:13 +00:00
Tien Nguyen Minh fadee80c82 Merge pull request #1 from tiennm99/dependabot/npm_and_yarn/vite-6.3.4
build(deps-dev): bump vite from 6.3.2 to 6.3.4
2025-05-06 10:31:51 +07:00
dependabot[bot] 044ef4864d build(deps-dev): bump vite from 6.3.2 to 6.3.4
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.3.2 to 6.3.4.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v6.3.4/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 6.3.4
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-30 17:59:14 +00:00
tiennm99 9e017f22db feat: update level 3 2025-04-27 11:55:43 +07:00
tiennm99 0fe4e7cbcf fix: not response after change level 2025-04-27 11:51:49 +07:00
tiennm99 d0140de19a refactor: use default format from vite web bundler 2025-04-27 11:46:30 +07:00
tiennm99 b7a38ce3da fix(pages): load levels 2025-04-27 00:57:51 +07:00
tiennm99 40fe7bc1b7 feat(pages): deploy 2025-04-26 23:16:12 +07:00
tiennm99 361f558e19 feat: init 2025-04-26 23:07:35 +07:00
Tien Nguyen Minh a878bdc6b5 Initial commit 2025-04-26 22:44:57 +07:00