- Record moves in standard algebraic notation (GameState.SanHistory), built at
move time in ChessService (captures, disambiguation, castling, promotion,
en passant, and the check/mate suffix)
- Add PgnExporter.ToPgn (seven-tag header + movetext + result) and a
GET /api/chess/{gameId}/pgn endpoint
- Show a Copy PGN button when a game ends on both the play and watch pages,
prefetching the PGN so it works during the post-game cleanup window
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
159 lines
2.8 KiB
CSS
159 lines
2.8 KiB
CSS
html, body {
|
|
background-color: #2b2c30;
|
|
color: #d6d6d6;
|
|
cursor: default;
|
|
height: 100%;
|
|
margin: 0;
|
|
}
|
|
|
|
#startGameBtn {
|
|
background-color: #8cd5ed;
|
|
color: #262626;
|
|
border-radius: 30px;
|
|
border: 0px;
|
|
cursor: pointer;
|
|
order: 1;
|
|
padding: 2vh;
|
|
margin: 2vh;
|
|
}
|
|
|
|
#startCPUGame {
|
|
background-color: #8cd5ed;
|
|
color: #262626;
|
|
border-radius: 30px;
|
|
border: 0px;
|
|
cursor: pointer;
|
|
order: 1;
|
|
padding: 2vh;
|
|
margin: 2vh;
|
|
}
|
|
|
|
#copyPgnBtn {
|
|
background-color: #8cd5ed;
|
|
color: #262626;
|
|
border-radius: 30px;
|
|
border: 0px;
|
|
cursor: pointer;
|
|
order: 1;
|
|
padding: 2vh;
|
|
margin: 2vh;
|
|
}
|
|
|
|
#watchLink {
|
|
color: #8cd5ed;
|
|
text-decoration: none;
|
|
margin: 2vh;
|
|
order: 2;
|
|
}
|
|
|
|
#watchLink:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
#chessContainer {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: space-evenly;
|
|
height: 100vh;
|
|
box-sizing: border-box;
|
|
padding: 5vw;
|
|
}
|
|
|
|
#chessBoard {
|
|
aspect-ratio: 1 / 1;
|
|
width: 90vw; /* use the smaller of width or height */
|
|
height: auto;
|
|
max-height: 90vw;
|
|
}
|
|
|
|
#boardContainer {
|
|
align-content: center;
|
|
flex-grow: 1;
|
|
}
|
|
|
|
.sideContent {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-content: center;
|
|
justify-content: center;
|
|
text-align: center;
|
|
}
|
|
|
|
#textContainer {
|
|
flex-direction: column;
|
|
order: -1;
|
|
flex-shrink: 1;
|
|
font-size: large;
|
|
margin: 5vw;
|
|
}
|
|
|
|
#buttonContainer {
|
|
flex-grow: 3;
|
|
}
|
|
|
|
/* Put UI to left/right when screen is short */
|
|
@media (min-aspect-ratio: 1/1) {
|
|
#chessContainer {
|
|
display: grid;
|
|
grid-template-columns: auto, auto;
|
|
grid-template-rows: auto, auto;
|
|
align-items: center;
|
|
flex-direction: row;
|
|
justify-content: center;
|
|
align-items: center;
|
|
height: 100vh;
|
|
padding: 0;
|
|
}
|
|
|
|
.sideContent {
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex-grow: 1;
|
|
flex-shrink: 0;
|
|
align-items: center;
|
|
text-align: center;
|
|
padding: min(5vw, 5vh);
|
|
}
|
|
|
|
#boardContainer {
|
|
grid-row: 1 / span 2;
|
|
grid-column: 1;
|
|
}
|
|
|
|
#textContainer {
|
|
grid-row: 1;
|
|
grid-column: 2;
|
|
text-align: center;
|
|
font-size: x-large;
|
|
}
|
|
|
|
#buttonContainer {
|
|
grid-row: 2;
|
|
grid-column: 2;
|
|
text-align: left;
|
|
align-self: start;
|
|
}
|
|
|
|
#startGameBtn {
|
|
padding: 1vw;
|
|
font-size: large;
|
|
}
|
|
|
|
#startCPUGame {
|
|
padding: 1vw;
|
|
margin: 1vw;
|
|
font-size: large;
|
|
}
|
|
|
|
#chessBoard {
|
|
aspect-ratio: 1 / 1;
|
|
flex-shrink: 1;
|
|
width: min(90vh, 90vw);
|
|
max-height: 90vh;
|
|
}
|
|
|
|
#difficultyButtonContainer {
|
|
grid-template-columns: repeat(10, 1fr);
|
|
}
|
|
} |