diff --git a/package-lock.json b/package-lock.json index 3562939..323270f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@angular/forms": "^20.3.0", "@angular/platform-browser": "^20.3.0", "@angular/router": "^20.3.0", + "bootstrap": "^5.3.8", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.15.0" @@ -2969,6 +2970,17 @@ "license": "MIT", "optional": true }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.59.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", @@ -3820,6 +3832,25 @@ "dev": true, "license": "ISC" }, + "node_modules/bootstrap": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz", + "integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "license": "MIT", + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + }, "node_modules/brace-expansion": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", diff --git a/package.json b/package.json index 5678b25..0882715 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@angular/forms": "^20.3.0", "@angular/platform-browser": "^20.3.0", "@angular/router": "^20.3.0", + "bootstrap": "^5.3.8", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.15.0" @@ -45,4 +46,4 @@ "karma-jasmine-html-reporter": "~2.1.0", "typescript": "~5.9.2" } -} \ No newline at end of file +} diff --git a/src/app/components/chess-piece/chess-piece.component.css b/src/app/components/chess-piece/chess-piece.component.css index 92749ff..04ff130 100644 --- a/src/app/components/chess-piece/chess-piece.component.css +++ b/src/app/components/chess-piece/chess-piece.component.css @@ -1,7 +1,31 @@ .piece { - width: clamp(40px, 9cqh, 130px); - height: clamp(40px, 9cqh, 130px); + width: clamp(50px, 11cqh, 160px); + height: clamp(50px, 11cqh, 160px); display: block; object-fit: contain; pointer-events: none; } + +/* Tablets and below - reduce piece size */ +@media (max-width: 991px) { + .piece { + width: clamp(40px, 9cqh, 130px); + height: clamp(40px, 9cqh, 130px); + } +} + +/* Mobile - smaller pieces */ +@media (max-width: 768px) { + .piece { + width: clamp(32px, 8cqh, 100px); + height: clamp(32px, 8cqh, 100px); + } +} + +/* Small phones - even smaller */ +@media (max-width: 480px) { + .piece { + width: clamp(24px, 6cqh, 75px); + height: clamp(24px, 6cqh, 75px); + } +} diff --git a/src/app/pages/game/game.component.css b/src/app/pages/game/game.component.css index 7b5ad50..edf4e18 100644 --- a/src/app/pages/game/game.component.css +++ b/src/app/pages/game/game.component.css @@ -1,161 +1,253 @@ .game-shell { - height: 100dvh; + min-height: 100dvh; padding: clamp(0.75rem, 2vw, 1.5rem); - overflow: hidden; } .game-card { - max-width: 1100px; - height: 100%; + max-width: 1400px; margin: 0 auto; background: #F3C8A0; border: 2px solid #5A2C28; border-radius: 12px; - padding: clamp(0.75rem, 1.5vw, 1.25rem); + padding: clamp(1rem, 2vw, 1.5rem); box-shadow: 0 8px 24px rgba(90, 44, 40, 0.2); - display: flex; - flex-direction: column; - min-height: 0; } header { - margin-bottom: 1rem; + margin-bottom: 1.5rem; } h1, h2 { color: #5A2C28; margin: 0 0 0.5rem; + font-size: clamp(1.5rem, 4vw, 2rem); } .meta { - margin: 0; + color: #5A2C28; + font-size: 0.95rem; } .back-link { display: inline-block; margin-bottom: 0.5rem; color: #5A2C28; + text-decoration: none; + font-weight: 600; +} + +.back-link:hover { + text-decoration: underline; } .top-section { - display: grid; - gap: 0.5rem; - margin-bottom: 0.5rem; - flex: 0 0 auto; -} - -.content-layout { - flex: 1 1 auto; - min-height: 0; - display: grid; - grid-template-columns: minmax(220px, 0.95fr) minmax(0, 2.4fr) minmax(220px, 0.95fr); - gap: 0.75rem; -} - -.center-column { - min-width: 0; - min-height: 0; - display: flex; - flex-direction: column; + background: #F3C8A0; + padding: 0.75rem; + border-radius: 8px; + border: 1px solid #5A2C28; } .move-form { - display: flex; - flex-wrap: wrap; align-items: center; - gap: 0.75rem; +} + +.move-form label { + color: #5A2C28; + font-weight: 600; + white-space: nowrap; } .board-hint { - margin: 0; color: #5A2C28; + margin: 0; +} + +.center-column { + width: 100%; } .board-section { - flex: 1 1 auto; - min-height: 180px; - display: grid; - place-items: center; - container-type: size; - padding: clamp(0.35rem, 1vw, 0.75rem); - border-radius: 10px; - border: 2px solid #5A2C28; background: #B9DAD1; - overflow: hidden; + border: 2px solid #5A2C28; + border-radius: 10px; + padding: clamp(0.5rem, 1vw, 1rem); + min-height: 400px; + container-type: size; } .import-card { background: #E1EAA9; border: 2px solid #5A2C28; border-radius: 10px; - padding: 0.65rem; - display: grid; - align-self: start; - align-content: start; - gap: 0.5rem; + padding: 1rem; + display: flex; + flex-direction: column; + gap: 0.75rem; } .import-card label { color: #5A2C28; font-weight: 700; + margin-bottom: 0.25rem; } -input { +.import-card textarea { border: 2px solid #5A2C28; - border-radius: 10px; - background: #B9DAD1; - padding: 0.6rem 0.75rem; - min-width: 180px; -} - -textarea { - border: 2px solid #5A2C28; - border-radius: 10px; + border-radius: 8px; background: #B9DAD1; padding: 0.6rem 0.75rem; resize: vertical; - min-height: 80px; + min-height: 100px; + font-family: inherit; } -button { +.import-card input { border: 2px solid #5A2C28; - border-radius: 10px; + border-radius: 8px; + background: #B9DAD1; + padding: 0.6rem 0.75rem; + font-family: inherit; +} + +.btn { + border: 2px solid #5A2C28; + border-radius: 8px; background: #C19EF5; color: #5A2C28; padding: 0.6rem 1rem; cursor: pointer; + font-weight: 600; + transition: background-color 0.2s, color 0.2s; } -button:hover { +.btn:hover { background: #BA6D4B; color: #F3C8A0; } -.error { - margin-top: 0.5rem; - color: #5A2C28; - font-weight: 700; +.alert { + border-radius: 8px; + border: 2px solid #5A2C28; } -@media (max-width: 920px) { - .content-layout { - grid-template-columns: 1fr; - grid-template-areas: - "center" - "fen" - "pgn"; +@media (max-width: 991px) { + .game-card { + padding: clamp(0.75rem, 1.5vw, 1rem); } - .center-column { - grid-area: center; + .board-section { + min-height: 350px; } - .fen-card { - grid-area: fen; - } - - .pgn-card { - grid-area: pgn; + h1, + h2 { + font-size: clamp(1.25rem, 3vw, 1.75rem); + } +} + +@media (max-width: 768px) { + .game-shell { + padding: clamp(0.5rem, 1.5vw, 1rem); + } + + .game-card { + padding: clamp(0.5rem, 1vw, 0.75rem); + } + + header { + margin-bottom: 1rem; + } + + h1, + h2 { + font-size: 1.25rem; + } + + .meta { + font-size: 0.85rem; + } + + .top-section { + padding: 0.5rem; + margin-bottom: 0.75rem; + } + + .move-form { + flex-wrap: wrap; + } + + .move-form label { + flex-basis: 100%; + margin-bottom: 0.5rem; + } + + .board-section { + min-height: 300px; + } + + .import-card { + padding: 0.75rem; + gap: 0.5rem; + } + + .import-card label { + font-size: 0.9rem; + } + + .import-card textarea, + .import-card input { + min-height: 70px; + font-size: 0.9rem; + padding: 0.5rem; + } + + .btn { + padding: 0.5rem 0.75rem; + font-size: 0.9rem; + } +} + +@media (max-width: 480px) { + .game-shell { + padding: 0.5rem; + } + + .game-card { + padding: 0.5rem; + border-radius: 8px; + } + + header { + margin-bottom: 0.75rem; + } + + h1 { + font-size: 1.1rem; + } + + .meta { + font-size: 0.75rem; + } + + .top-section { + padding: 0.4rem; + margin-bottom: 0.5rem; + } + + .board-section { + min-height: 250px; + } + + .import-card { + padding: 0.5rem; + gap: 0.35rem; + } + + .import-card textarea, + .import-card input { + min-height: 50px; + font-size: 0.8rem; + padding: 0.4rem; } } diff --git a/src/app/pages/game/game.component.html b/src/app/pages/game/game.component.html index 64a6f81..41a3bc3 100644 --- a/src/app/pages/game/game.component.html +++ b/src/app/pages/game/game.component.html @@ -1,63 +1,80 @@
-
+
Back -

1 vs 1 Game

-

Game ID: {{ facade.gameId }}

+

1 vs 1 Game

+

Game ID: {{ facade.gameId }}

@if (facade.loading) {

Loading game state...

} @else if (facade.state) { -
- +
+
+ +
+ +
-
-
-
- - - -
-

Click your piece to highlight legal targets.

-
+ +
+
+
+
+ + + +
+

Click your piece to highlight legal targets.

+
-
- -
-
+
+ +
+
+
- -
+ +
+ +
+ + } @if (facade.errorMessage) { -

{{ facade.errorMessage }}

+

{{ facade.errorMessage }}

}
diff --git a/src/app/pages/welcome/welcome.component.css b/src/app/pages/welcome/welcome.component.css index b4afc80..1407a16 100644 --- a/src/app/pages/welcome/welcome.component.css +++ b/src/app/pages/welcome/welcome.component.css @@ -67,3 +67,77 @@ p { font-weight: 700; margin-top: 1rem; } + +@media (max-width: 768px) { + .welcome-shell { + padding: 1rem; + } + + .welcome-card { + padding: 1.5rem; + } + + h1 { + font-size: 1.5rem; + } + + p { + font-size: 0.875rem; + margin: 0 0 1rem; + } + + .mode-grid { + grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); + gap: 0.75rem; + } + + .mode { + padding: 0.75rem; + gap: 0.15rem; + } + + .mode span { + font-size: 1rem; + } + + .mode small { + font-size: 0.7rem; + } + + .error { + font-size: 0.75rem; + } +} + +@media (max-width: 480px) { + .welcome-shell { + padding: 0.5rem; + } + + .welcome-card { + padding: 1rem; + border-radius: 8px; + } + + h1 { + font-size: 1.25rem; + margin: 0 0 0.15rem; + } + + p { + font-size: 0.8rem; + margin: 0 0 0.75rem; + } + + .mode-grid { + grid-template-columns: 1fr; + } + + .mode { + padding: 0.65rem; + } + + .mode span { + font-size: 0.95rem; + } +} diff --git a/src/styles.css b/src/styles.css index 0bb4726..628021c 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1,3 +1,5 @@ +@import 'bootstrap/dist/css/bootstrap.min.css'; + :root { --warm-primary: #BA6D4B; --warm-dark: #5A2C28;