Adds vitest + happy-dom as devDependencies and npm scripts test
(one-shot) and test:watch. No SvelteKit/vite reconfig needed —
vitest auto-picks up the existing vite plugin chain.
game-logic.test.js (26 tests): generateGrid shape invariants
(9x9, exact 5/row, exact 5/col, no duplicates) over 200 random
trials; per-column number ranges (col 0 = 1-9, col 8 = 80-90);
ascending-within-column rule; isRowComplete/getWaitingNumber edge
cases; full save/load roundtrip for the persistence layer
including corrupt-JSON and wrong-shape rejection.
settings-store.test.js (12 tests): defaults frozen, load with
valid/invalid/corrupt payloads, hex regex rejects shorthand,
save persists to localStorage and pushes CSS var, reset returns
to brown default. Uses happy-dom env for localStorage and
documentElement.
code-standards.md: documents the rune globals declaration and the
.svelte.js convention for rune-using non-component modules.
Cloudflare Pages build failed with:
Error: Cannot find module '../lightningcss.linux-x64-gnu.node'
Tailwind 4 → @tailwindcss/vite → lightningcss has per-platform native
binaries shipped as optional npm packages. The lockfile generated on
this dev box (linux-arm64) only carried the arm64 binaries, so CF on
linux-x64 was missing the matching platform-specific package.
Adding lightningcss-linux-x64-gnu to optionalDependencies pins it into
the lockfile. On non-x64-linux machines npm skips it silently due to
the platform mismatch; CF Pages on linux-x64 will install it.
Pinned to 1.32.0 to match the parent dep already resolved.
- Default `npm run build` now produces a root-relative build (CF Pages
custom domain at loto.miti99.com). The /loto basePath is opt-in via
`npm run build:gh` for the rare manual GH Pages export.
- Removed both GitHub Actions deploy workflows (.github/workflows/) and
the dangling `build:cf` script (it was identical to `build` after the
default flip).
- next.config.mjs: simplified basePath logic — only `BUILD_PROFILE=gh`
toggles a non-empty path; everything else (CF, local dev) is root.
Two named build scripts replace the prior CF_PAGES auto-detect:
npm run build:gh → BUILD_PROFILE=gh, basePath /loto
target: https://tiennm99.github.io/loto
npm run build:cf → BUILD_PROFILE=cf, basePath ""
target: https://loto.miti99.com (CF Pages custom domain)
Both deploy workflows now use the matching profile script. The legacy
`npm run build` keeps its prior behaviour (defaults to /loto basePath) so
nothing else in the toolchain breaks. NEXT_BASE_PATH still wins for any
one-off custom-domain build.
CF_PAGES auto-detection removed — explicit profiles are clearer than
relying on the host injecting a magic env var, and dashboard users should
just set the build command to `npm run build:cf`.
`app/` should hold route segments only. Game logic and the player-card
component are imported by both routes, so they belong outside:
app/loto-game-logic.ts -> lib/game-logic.ts
app/loto-player-board.tsx -> components/player-board.tsx
Imports use the existing @/* alias. Drops the redundant `loto-` prefix.
Also fixes the package name from the scaffold default.
NEXT_DEV_PROFILE=codeserver wires basePath, assetPrefix, and
allowedDevOrigins from CODESERVER_HOST/PORT in .env.local. Use
/absproxy/{port} so code-server preserves the path prefix and Next's
basePath matches the incoming request.
Run with `npm run dev:codeserver` and access via
https://<host>/absproxy/<port>/.
Replace vanilla HTML/JS/CSS with Next.js App Router, TypeScript,
and Tailwind CSS. Responsive design with dark mode support.
All original game logic preserved: grid generation, click-to-cross,
localStorage persistence.