- Add a toggle on the picture-in-picture window to swap the big board
with the mini view of the opponent's field
- Color-coded frame and badge identify whose board is currently shown
(blue = player 1, orange = player 2)
- Block building and rushing while spectating the opponent's board;
the PiP then shows your own field instead
- Clarify duel-mode descriptions in lobby and start screen, add hints
in the multiplayer bar
- Replace previous announcement banners so only one shows at a time
- Add CSP, frame and referrer headers for served static files
- Enforce WebSocket origin check to prevent cross-site hijacking
- Trust X-Forwarded-For only when the peer is from a private proxy network
- Limit concurrent connections (500 total / 20 per IP) and rooms (300)
- Add ALLOWED_ORIGINS env var for additional WebSocket origins
- Document reverse proxy setup (NPM/NPMplus) in README
- Add scripts/security-test.mjs to verify origin and limit behavior
- Add Dockerfile (multi-stage build, unprivileged user, healthcheck),
docker-compose.yml and .dockerignore
- Server now serves static dist/ frontend and WebSocket relay on a
single port (PORT, default 3001) with path-traversal protection,
immutable asset caching and SPA fallback
- Client connects via same origin in production; dedicated ws port is
only used for vite dev/preview
- Document Docker usage, env vars and manual production mode in README