suvasis's picture
code add
e4d7d50
/**
* ChessBoard component — live chess board with piece animations
* Design: Quantitative Finance Dark — cream/brown squares, high-contrast pieces
*
* FIX: Black pieces now use #FFD700 (gold) instead of #1a1a2e (invisible on dark squares)
* FIX: Square colors changed to classic chess cream (#F0D9B5) and brown (#B58863)
* FIX: Larger font size and stronger shadows for visibility
*/
import { useEffect, useState } from "react";
import { PIECES, type GameState } from "@/lib/simulation";
interface ChessBoardProps {
state: GameState;
}
export default function ChessBoard({ state }: ChessBoardProps) {
const [lastMove, setLastMove] = useState<{ from: string; to: string } | null>(null);
const [prevMoves, setPrevMoves] = useState<string[]>([]);
useEffect(() => {
if (state.moves.length > prevMoves.length) {
setPrevMoves(state.moves);
}
}, [state.moves]);
const files = "abcdefgh";
const ranks = "87654321";
const getSquareClass = (rank: number, file: number) => {
const isLight = (rank + file) % 2 === 0;
return isLight ? "chess-square-light" : "chess-square-dark";
};
return (
<div className="flex flex-col gap-1">
{/* Rank labels + board */}
<div className="flex gap-1">
{/* Rank labels */}
<div className="flex flex-col justify-around w-4">
{ranks.split("").map((r) => (
<span key={r} className="text-center font-mono leading-none" style={{ fontSize: "10px", fontWeight: 600, color: "#c8c8c8" }}>
{r}
</span>
))}
</div>
{/* Board */}
<div className="chess-board flex-1 aspect-square">
{state.board.map((row, rankIdx) =>
row.map((piece, fileIdx) => {
const squareClass = getSquareClass(rankIdx, fileIdx);
return (
<div
key={`${rankIdx}-${fileIdx}`}
className={`${squareClass} flex items-center justify-center relative`}
style={{ aspectRatio: "1" }}
>
{piece && (
<span
className="chess-piece select-none"
style={{
fontSize: "clamp(16px, 3vw, 32px)",
// White pieces: bright white; Black pieces: vivid goldboth visible on any square
color: piece === piece.toUpperCase() ? "#ffffff" : "#FFD700",
textShadow: piece === piece.toUpperCase()
? "0 1px 3px rgba(0,0,0,0.9), 0 0 8px rgba(180,210,255,0.7)"
: "0 1px 3px rgba(0,0,0,0.9), 0 0 10px rgba(255,215,0,0.8)",
filter: piece === piece.toUpperCase()
? "drop-shadow(0 0 4px rgba(180,210,255,0.6))"
: "drop-shadow(0 0 5px rgba(255,215,0,0.9))",
}}
>
{PIECES[piece] ?? piece}
</span>
)}
</div>
);
})
)}
</div>
</div>
{/* File labels */}
<div className="flex ml-5">
{files.split("").map((f) => (
<span key={f} className="flex-1 text-center font-mono" style={{ fontSize: "10px", fontWeight: 600, color: "#c8c8c8" }}>
{f}
</span>
))}
</div>
</div>
);
}