tiennm99 0fa7a58521 feat(mobile): portrait upward bias + landscape side-by-side layout
Portrait: add asymmetric padding-bottom: clamp(16px, 6vh, 56px) on
.play-stack so safe-center distributes the slack into the centroid,
lifting the play-group ~28px upward. Counters the perceptual "low"
feel caused by HUD top-weight + dock visual mass even though the
group is geometrically near-centered.

Landscape: flip .play-group to flex-direction: row so the dock
occupies a 160px right column instead of stacking below the board.
.mobile-dock switches to flex-direction: column with
justify-content: space-between (action stack on top, d-pad at bottom
for the natural two-handed thumb arc). On a Pixel 7 landscape
viewport this lifts Microban 1's tile size from 19px to 56px (3x
bigger) and brings the giant finale levels back into a playable
range.

computeTileSize now branches on orientation: landscape uses
chromeY=76 (HUD only) and reserves 160px of width for the side dock;
portrait keeps chromeY=295 (HUD + in-flow dock); desktop unchanged.
Orientation matchMedia listener wired into the existing pointer
listener so rotation reflows the tile budget live.

Touch targets unchanged (48px arrows, 48px action buttons). All
recent fixes (mistouch, top-aligned d-pad, LVLS grid, play-group
center) preserved — only the OUTER flex direction flips on
landscape; internal MobileControls grids are unaffected.
2026-04-29 00:05:01 +07:00
2026-04-27 20:51:37 +07:00
2026-04-20 16:01:04 +07:00
2025-04-26 23:07:35 +07:00
2025-04-26 22:44:57 +07:00

Sokoban

My from-scratch Sokoban game, built with Svelte 5 and Vite. The engine, UI, level parser, and progression system are all my own implementation. The puzzle layouts themselves come from David W. Skinner's freely distributable Microban set — I'm not reusing any of his code, only his level designs.

Play: https://tiennm99.github.io/sokoban/

Features

  • All 155 puzzles from the Microban set, from beginner teasers up to the giant "Take the long way home" maze and "The Dungeon" finale.
  • Paginated level select with progress tracking and best-move record per level.
  • Controls: Arrow keys or WASD on desktop; on-screen D-pad on mobile (bottom-right, one-handed). U / Z to undo, R to restart, Esc for menu.
  • Mobile-optimized: Touch-safe controls, haptic feedback (vibrate on push & win), safe-area insets for notches/nav bars, browser gesture blocking.
  • Installable PWA: Add to home screen on iOS/Android, play offline, standalone fullscreen mode.
  • Undo history, live move counter, animated moves.
  • Progress saved locally in localStorage (per browser, per device).
  • Responsive tile sizing so small and large levels both look right on any screen.

Development

npm install
npm run dev          # dev server on http://localhost:8080
npm run build        # production build

Project layout

See docs/codebase-summary.md.

Documentation

Credits

License

  • Source code: see LICENSE.
  • Puzzle layouts (Microban): see LICENSE-LEVELS.md — Skinner's free-distribution-with-credit terms, not the main project license.
S
Description
From-scratch Sokoban puzzle game — Svelte 5 + Vite, all 155 Microban levels, undo, progress tracking
Readme Apache-2.0
1.4 MiB
0 Stars 1 Watchers 0 Forks
Languages
Svelte 56.5%
JavaScript 38%
CSS 4.8%
HTML 0.7%