chore(frontend): shrink panel controls, configure Netlify deploy

- Shrink category cards and panel buttons for wider code view
- Add netlify.toml, document backend URL/port setup for Netlify deploys
This commit is contained in:
Gabriel Franco 2026-09-14 09:49:55 -03:00
parent 7a6df57ad0
commit faeede3447
5 changed files with 75 additions and 13 deletions

View file

@ -49,6 +49,29 @@ WebSocket server to it. Matchmaking and room/session logic are not
implemented yet — see `backend/src/matchmaking/README.md` and
`backend/src/rooms/README.md`.
## Deployment
The frontend (static Vite build) and backend (persistent Node
HTTP+WebSocket process) deploy independently and to different kinds of
host.
**Frontend on Netlify:** the root `netlify.toml` builds from
`frontend/` (`npm run build`, publish `frontend/dist`). Point this site
at your deployed backend by setting `VITE_WS_URL` under Site settings
-> Environment variables (or `netlify env:set VITE_WS_URL
wss://your-backend-host`) — it's read at build time by
`frontend/src/net/client.ts`. Use `wss://`, not `ws://`: once the
Netlify site is served over https, a plain `ws://` socket is blocked as
mixed content (the client warns in the console if this is
misconfigured). See `frontend/.env.example`.
**Backend:** Netlify doesn't run long-lived Node processes, so
`backend/` needs a real host (Fly.io, Render, Railway, a VPS, ...) that
can keep a WebSocket server alive. It listens on `process.env.PORT`
(see `backend/src/index.js`), which most such hosts set automatically;
override it manually if yours doesn't. Whatever host/port it ends up
on, put that address into the frontend's `VITE_WS_URL` above.
## Status
Single-player game: playable. Multiplayer: backend is a bare HTTP+WS

View file

@ -1 +1,13 @@
# Multiplayer WebSocket backend URL, read at build time via
# `import.meta.env.VITE_WS_URL` (see src/net/client.ts). Defaults to
# ws://localhost:8080 for local dev when unset.
#
# For a Netlify deploy, set this in Site settings -> Environment
# variables (or `netlify env:set VITE_WS_URL wss://your-backend-host`)
# to the deployed backend's address. Use wss:// (not ws://) once the
# Netlify site is served over https, or the browser blocks the
# connection as mixed content. The backend's own listen port is
# separately configurable via its host's PORT env var — see
# backend/src/index.js — and is not set here; it only affects which
# port the backend process binds to, not this URL.
VITE_WS_URL=ws://localhost:8080

View file

@ -10,6 +10,17 @@ const DEFAULT_WS_URL = 'ws://localhost:8080';
* dev backend. */
export const WS_URL = import.meta.env.VITE_WS_URL || DEFAULT_WS_URL;
// A page served over https can't open a plain ws:// socket (browsers
// block it as mixed content) — this only bites once VITE_WS_URL is
// left unset/misconfigured on an https deploy (e.g. Netlify), so warn
// loudly instead of failing silently as a closed connection.
if (typeof location !== 'undefined' && location.protocol === 'https:' && WS_URL.startsWith('ws://')) {
console.warn(
`[net] VITE_WS_URL is "${WS_URL}" but this page is served over https — ` +
'the browser will block it as mixed content. Set VITE_WS_URL to a wss:// URL.',
);
}
/** Lifecycle of the underlying socket. `closed` covers both a clean
* close and an error — reconnecting is out of scope here, callers that
* care just need to know the connection is gone. */

View file

@ -257,12 +257,12 @@ body {
}
.panel-col {
width: 330px;
flex: 0 0 330px;
width: 260px;
flex: 0 0 260px;
min-height: 0;
display: flex;
flex-direction: column;
gap: 8px;
gap: 6px;
}
.panel {
@ -271,7 +271,7 @@ body {
overflow-y: auto;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
gap: 6px;
align-content: start;
padding: 2px 6px 2px 2px;
}
@ -280,9 +280,9 @@ body {
flex: 0 0 auto;
display: flex;
flex-direction: column;
gap: 8px;
gap: 6px;
}
.panel-actions .btn { width: 100%; }
.panel-actions .btn { width: 100%; padding: 7px 10px; font-size: 9px; }
/* `game/multiplayerMatch.ts`'s mutual reveal-vote status line, shown
* below the Reveal button once the local player has voted to reveal
* early and is waiting on the opponent to do the same (or vice versa). */
@ -361,10 +361,10 @@ body {
.cat-card {
background: var(--panel-2);
border: 3px solid var(--ink);
padding: 8px;
padding: 5px 6px;
display: flex;
align-items: center;
gap: 8px;
gap: 6px;
cursor: pointer;
box-shadow: 3px 3px 0 var(--ink);
transition: transform .08s ease, box-shadow .08s ease;
@ -386,7 +386,7 @@ body {
}
.cat-swatch {
width: 24px; height: 24px;
width: 16px; height: 16px;
border: 2px solid var(--ink);
flex-shrink: 0;
background: repeating-conic-gradient(#4b4540 0% 25%, #302f2a 0% 50%) 0 0/8px 8px;
@ -401,15 +401,15 @@ body {
.cat-info { min-width: 0; }
.cat-label {
font-size: 8px;
line-height: 1.5;
font-size: 7px;
line-height: 1.4;
font-family: var(--pixel);
color: var(--fg);
white-space: normal;
display: block;
margin-bottom: 4px;
margin-bottom: 2px;
}
.cat-count { font-size: 10px; color: var(--fg-dim); }
.cat-count { font-size: 9px; color: var(--fg-dim); }
/* ---------- popover ---------- */

16
netlify.toml Normal file
View file

@ -0,0 +1,16 @@
[build]
base = "frontend"
command = "npm run build"
publish = "dist"
[build.environment]
NODE_VERSION = "20"
# The multiplayer WebSocket backend (backend/) is a persistent Node
# process — it does not run on Netlify. Deploy it separately (Fly.io,
# Render, Railway, a VPS, ...) and point this site at it by setting
# VITE_WS_URL in Site settings -> Environment variables (Netlify
# dashboard) or via `netlify env:set VITE_WS_URL wss://your-backend-host`.
# It must be `wss://` (not `ws://`) once this site is served over
# https, or browsers block the connection as mixed content. See
# frontend/.env.example and frontend/src/net/client.ts.