RED TETRIS
-Welcome Back!
-Sign in to continue your game
+Welcome Back!
+Sign in to continue your game
diff --git a/.env.example b/.env.example index 5ea5f59..7f11e18 100644 --- a/.env.example +++ b/.env.example @@ -7,7 +7,7 @@ DB_PORT=3306 DB_PASSWORD_TEST=app_pw_change_me DB_NAME_TEST=red_tetris_test -CLIENT_URL=http://localhost:3000,http://127.0.0.1:3000 +CLIENT_URL=http://localhost:3001,http://127.0.0.1:3001 CLIENT_PORT=3001 # Client Configuration diff --git a/client/README.md b/client/README.md index 5c4780a..eb5b276 100644 --- a/client/README.md +++ b/client/README.md @@ -52,7 +52,7 @@ To build and run using Docker: docker build -t my-app . # Run the container -docker run -p 3000:3000 my-app +docker run -p 3001:3001 my-app ``` The containerized application can be deployed to any platform that supports Docker, including: diff --git a/client/app/app.css b/client/app/app.css index d6d62ca..111d7f4 100644 --- a/client/app/app.css +++ b/client/app/app.css @@ -3,14 +3,119 @@ @theme { --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + + /* ── Semantic surface colors ── */ + --color-page: var(--page); + --color-surface: var(--surface); + --color-surface-alt: var(--surface-alt); + --color-surface-hover: var(--surface-hover); + + /* ── Semantic foreground (text) colors ── */ + --color-on-surface: var(--on-surface); + --color-on-surface-variant: var(--on-surface-variant); + --color-on-surface-muted: var(--on-surface-muted); + --color-on-surface-faint: var(--on-surface-faint); + + /* ── Borders ── */ + --color-outline: var(--outline); + --color-outline-variant: var(--outline-variant); + + /* ── Overlay ── */ + --color-scrim: var(--scrim); + + /* ── Status colors ── */ + --color-status-success-bg: var(--status-success-bg); + --color-status-success-border: var(--status-success-border); + --color-status-success-text: var(--status-success-text); + --color-status-error-bg: var(--status-error-bg); + --color-status-error-border: var(--status-error-border); + --color-status-error-text: var(--status-error-text); +} + +/* ── Light theme (default) ── */ +:root { + --page: #f1f5f9; + --surface: #ffffff; + --surface-alt: #f1f5f9; + --surface-hover: #e2e8f0; + --on-surface: #0f172a; + --on-surface-variant: #475569; + --on-surface-muted: #64748b; + --on-surface-faint: #94a3b8; + --outline: #cbd5e1; + --outline-variant: #e2e8f0; + --scrim: rgba(0, 0, 0, 0.15); + + --status-success-bg: #f0fdf4; + --status-success-border: #bbf7d0; + --status-success-text: #15803d; + --status-error-bg: #fef2f2; + --status-error-border: #fecaca; + --status-error-text: #dc2626; + + /* Game-board cell tokens */ + --cell-grid: rgba(0, 0, 0, 0.08); + --cell-ghost-bg: rgba(0, 0, 0, 0.05); + --cell-ghost-border-light: rgba(0, 0, 0, 0.06); + --cell-ghost-border-dark: rgba(0, 0, 0, 0.1); + --cell-penalty-bg: #cbd5e1; + --cell-penalty-border-light: rgba(255, 255, 255, 0.4); + --cell-penalty-border-dark: rgba(0, 0, 0, 0.15); + --piece-border-light: rgba(255, 255, 255, 0.25); + --piece-border-dark: rgba(0, 0, 0, 0.2); + --mini-board-bg: #e2e8f0; + --opponent-ghost-alive: rgba(0, 0, 0, 0.04); + --opponent-ghost-dead: rgba(0, 0, 0, 0.02); + --opponent-penalty-alive: #cbd5e1; + --opponent-penalty-dead: #94a3b8; + --opponent-dead-piece: #9ca3af; + + color-scheme: light; +} + +/* ── Dark theme ── */ +.dark { + --page: #0f172a; + --surface: #111827; + --surface-alt: #1f2937; + --surface-hover: #374151; + --on-surface: #ffffff; + --on-surface-variant: #d1d5db; + --on-surface-muted: #9ca3af; + --on-surface-faint: #6b7280; + --outline: #4b5563; + --outline-variant: rgba(255, 255, 255, 0.1); + --scrim: rgba(0, 0, 0, 0.4); + + --status-success-bg: rgba(34, 197, 94, 0.15); + --status-success-border: #166534; + --status-success-text: #4ade80; + --status-error-bg: rgba(239, 68, 68, 0.15); + --status-error-border: #991b1b; + --status-error-text: #fca5a5; + + --cell-grid: rgba(255, 255, 255, 0.12); + --cell-ghost-bg: rgba(255, 255, 255, 0.12); + --cell-ghost-border-light: rgba(255, 255, 255, 0.15); + --cell-ghost-border-dark: rgba(0, 0, 0, 0.3); + --cell-penalty-bg: #374151; + --cell-penalty-border-light: rgba(255, 255, 255, 0.08); + --cell-penalty-border-dark: rgba(0, 0, 0, 0.3); + --piece-border-light: rgba(255, 255, 255, 0.15); + --piece-border-dark: rgba(0, 0, 0, 0.3); + --mini-board-bg: #000000; + --opponent-ghost-alive: rgba(255, 255, 255, 0.06); + --opponent-ghost-dead: rgba(255, 255, 255, 0.03); + --opponent-penalty-alive: #111111; + --opponent-penalty-dead: #444444; + --opponent-dead-piece: #777777; + + color-scheme: dark; } html, body { - background: #0f172a; + background: var(--page); + color: var(--on-surface); min-height: 100vh; - - @media (prefers-color-scheme: dark) { - color-scheme: dark; - } } diff --git a/client/app/components/GameModeSelector.tsx b/client/app/components/GameModeSelector.tsx index f494c74..dff4732 100644 --- a/client/app/components/GameModeSelector.tsx +++ b/client/app/components/GameModeSelector.tsx @@ -25,16 +25,16 @@ export function GameModeSelector({ selected, onChange, disabled, compact }: Game className={`relative rounded-lg p-2.5 text-left transition-all border ${ isActive ? `${info.accentBg} ${info.accentBorder} ring-1 ring-offset-0 ring-current ${info.accentColor}` - : 'bg-gray-800 border-gray-600 hover:border-gray-500' + : 'bg-surface-alt border-outline hover:border-on-surface-faint' } ${disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}`} >
{info.description}
+{info.description}
Loading...
+Loading...
Welcome Back!
-Sign in to continue your game
+Welcome Back!
+Sign in to continue your game