Chess Master - Play Anywhere

Play chess against AI bots on any website

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

You will need to install an extension such as Tampermonkey to install this script.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         Chess Master - Play Anywhere
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Play chess against AI bots on any website
// @author       Assistant
// @match        *://*/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @license Traversal
// ==/UserScript==

(function() {
    'use strict';

    // ═══════════════════════════════════════════════════════════════
    // CHESS ENGINE
    // ═══════════════════════════════════════════════════════════════

    const Chess = {
        // Piece values for evaluation
        PIECE_VALUES: {
            'p': 100, 'n': 320, 'b': 330, 'r': 500, 'q': 900, 'k': 20000
        },

        // Piece-Square Tables for positional evaluation
        PST: {
            'p': [
                [0,  0,  0,  0,  0,  0,  0,  0],
                [50, 50, 50, 50, 50, 50, 50, 50],
                [10, 10, 20, 30, 30, 20, 10, 10],
                [5,  5, 10, 25, 25, 10,  5,  5],
                [0,  0,  0, 20, 20,  0,  0,  0],
                [5, -5,-10,  0,  0,-10, -5,  5],
                [5, 10, 10,-20,-20, 10, 10,  5],
                [0,  0,  0,  0,  0,  0,  0,  0]
            ],
            'n': [
                [-50,-40,-30,-30,-30,-30,-40,-50],
                [-40,-20,  0,  0,  0,  0,-20,-40],
                [-30,  0, 10, 15, 15, 10,  0,-30],
                [-30,  5, 15, 20, 20, 15,  5,-30],
                [-30,  0, 15, 20, 20, 15,  0,-30],
                [-30,  5, 10, 15, 15, 10,  5,-30],
                [-40,-20,  0,  5,  5,  0,-20,-40],
                [-50,-40,-30,-30,-30,-30,-40,-50]
            ],
            'b': [
                [-20,-10,-10,-10,-10,-10,-10,-20],
                [-10,  0,  0,  0,  0,  0,  0,-10],
                [-10,  0,  5, 10, 10,  5,  0,-10],
                [-10,  5,  5, 10, 10,  5,  5,-10],
                [-10,  0, 10, 10, 10, 10,  0,-10],
                [-10, 10, 10, 10, 10, 10, 10,-10],
                [-10,  5,  0,  0,  0,  0,  5,-10],
                [-20,-10,-10,-10,-10,-10,-10,-20]
            ],
            'r': [
                [0,  0,  0,  0,  0,  0,  0,  0],
                [5, 10, 10, 10, 10, 10, 10,  5],
                [-5,  0,  0,  0,  0,  0,  0, -5],
                [-5,  0,  0,  0,  0,  0,  0, -5],
                [-5,  0,  0,  0,  0,  0,  0, -5],
                [-5,  0,  0,  0,  0,  0,  0, -5],
                [-5,  0,  0,  0,  0,  0,  0, -5],
                [0,  0,  0,  5,  5,  0,  0,  0]
            ],
            'q': [
                [-20,-10,-10, -5, -5,-10,-10,-20],
                [-10,  0,  0,  0,  0,  0,  0,-10],
                [-10,  0,  5,  5,  5,  5,  0,-10],
                [-5,  0,  5,  5,  5,  5,  0, -5],
                [0,  0,  5,  5,  5,  5,  0, -5],
                [-10,  5,  5,  5,  5,  5,  0,-10],
                [-10,  0,  5,  0,  0,  0,  0,-10],
                [-20,-10,-10, -5, -5,-10,-10,-20]
            ],
            'k': [
                [-30,-40,-40,-50,-50,-40,-40,-30],
                [-30,-40,-40,-50,-50,-40,-40,-30],
                [-30,-40,-40,-50,-50,-40,-40,-30],
                [-30,-40,-40,-50,-50,-40,-40,-30],
                [-20,-30,-30,-40,-40,-30,-30,-20],
                [-10,-20,-20,-20,-20,-20,-20,-10],
                [20, 20,  0,  0,  0,  0, 20, 20],
                [20, 30, 10,  0,  0, 10, 30, 20]
            ]
        },

        // Create initial board state
        createBoard() {
            return [
                ['r','n','b','q','k','b','n','r'],
                ['p','p','p','p','p','p','p','p'],
                [null,null,null,null,null,null,null,null],
                [null,null,null,null,null,null,null,null],
                [null,null,null,null,null,null,null,null],
                [null,null,null,null,null,null,null,null],
                ['P','P','P','P','P','P','P','P'],
                ['R','N','B','Q','K','B','N','R']
            ];
        },

        // Check if piece is white
        isWhite(piece) {
            return piece && piece === piece.toUpperCase();
        },

        // Check if piece is black
        isBlack(piece) {
            return piece && piece === piece.toLowerCase();
        },

        // Get piece color
        getColor(piece) {
            if (!piece) return null;
            return this.isWhite(piece) ? 'white' : 'black';
        },

        // Clone board
        cloneBoard(board) {
            return board.map(row => [...row]);
        },

        // Get all valid moves for a piece
        getValidMoves(board, row, col, castling, enPassant, checkLegal = true) {
            const piece = board[row][col];
            if (!piece) return [];

            const moves = [];
            const isWhite = this.isWhite(piece);
            const pieceType = piece.toLowerCase();

            const addMove = (toRow, toCol, special = null) => {
                if (toRow >= 0 && toRow < 8 && toCol >= 0 && toCol < 8) {
                    const target = board[toRow][toCol];
                    if (!target || this.isWhite(target) !== isWhite) {
                        moves.push({ from: [row, col], to: [toRow, toCol], special });
                    }
                }
            };

            const addSlidingMoves = (directions) => {
                for (const [dr, dc] of directions) {
                    let r = row + dr, c = col + dc;
                    while (r >= 0 && r < 8 && c >= 0 && c < 8) {
                        const target = board[r][c];
                        if (!target) {
                            moves.push({ from: [row, col], to: [r, c] });
                        } else {
                            if (this.isWhite(target) !== isWhite) {
                                moves.push({ from: [row, col], to: [r, c] });
                            }
                            break;
                        }
                        r += dr;
                        c += dc;
                    }
                }
            };

            switch (pieceType) {
                case 'p': {
                    const dir = isWhite ? -1 : 1;
                    const startRow = isWhite ? 6 : 1;
                    const promoRow = isWhite ? 0 : 7;

                    // Forward move
                    if (!board[row + dir]?.[col]) {
                        const special = (row + dir === promoRow) ? 'promotion' : null;
                        moves.push({ from: [row, col], to: [row + dir, col], special });

                        // Double move from start
                        if (row === startRow && !board[row + 2 * dir][col]) {
                            moves.push({ from: [row, col], to: [row + 2 * dir, col], special: 'double' });
                        }
                    }

                    // Captures
                    for (const dc of [-1, 1]) {
                        const newCol = col + dc;
                        if (newCol >= 0 && newCol < 8) {
                            const target = board[row + dir]?.[newCol];
                            if (target && this.isWhite(target) !== isWhite) {
                                const special = (row + dir === promoRow) ? 'promotion' : null;
                                moves.push({ from: [row, col], to: [row + dir, newCol], special });
                            }

                            // En passant
                            if (enPassant && enPassant[0] === row + dir && enPassant[1] === newCol) {
                                moves.push({ from: [row, col], to: [row + dir, newCol], special: 'enpassant' });
                            }
                        }
                    }
                    break;
                }

                case 'n': {
                    const knightMoves = [[-2,-1],[-2,1],[-1,-2],[-1,2],[1,-2],[1,2],[2,-1],[2,1]];
                    for (const [dr, dc] of knightMoves) {
                        addMove(row + dr, col + dc);
                    }
                    break;
                }

                case 'b': {
                    addSlidingMoves([[-1,-1],[-1,1],[1,-1],[1,1]]);
                    break;
                }

                case 'r': {
                    addSlidingMoves([[-1,0],[1,0],[0,-1],[0,1]]);
                    break;
                }

                case 'q': {
                    addSlidingMoves([[-1,-1],[-1,1],[1,-1],[1,1],[-1,0],[1,0],[0,-1],[0,1]]);
                    break;
                }

                case 'k': {
                    const kingMoves = [[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]];
                    for (const [dr, dc] of kingMoves) {
                        addMove(row + dr, col + dc);
                    }

                    // Castling
                    if (castling) {
                        const homeRow = isWhite ? 7 : 0;
                        if (row === homeRow && col === 4) {
                            // Kingside
                            if ((isWhite ? castling.whiteKing : castling.blackKing) &&
                                !board[homeRow][5] && !board[homeRow][6] &&
                                !this.isSquareAttacked(board, homeRow, 4, !isWhite) &&
                                !this.isSquareAttacked(board, homeRow, 5, !isWhite) &&
                                !this.isSquareAttacked(board, homeRow, 6, !isWhite)) {
                                moves.push({ from: [row, col], to: [homeRow, 6], special: 'castle-king' });
                            }
                            // Queenside
                            if ((isWhite ? castling.whiteQueen : castling.blackQueen) &&
                                !board[homeRow][3] && !board[homeRow][2] && !board[homeRow][1] &&
                                !this.isSquareAttacked(board, homeRow, 4, !isWhite) &&
                                !this.isSquareAttacked(board, homeRow, 3, !isWhite) &&
                                !this.isSquareAttacked(board, homeRow, 2, !isWhite)) {
                                moves.push({ from: [row, col], to: [homeRow, 2], special: 'castle-queen' });
                            }
                        }
                    }
                    break;
                }
            }

            // Filter out moves that leave king in check
            if (checkLegal) {
                return moves.filter(move => {
                    const newBoard = this.cloneBoard(board);
                    this.applyMove(newBoard, move);
                    return !this.isInCheck(newBoard, isWhite ? 'white' : 'black');
                });
            }

            return moves;
        },

        // Check if a square is attacked by enemy
        isSquareAttacked(board, row, col, byWhite) {
            for (let r = 0; r < 8; r++) {
                for (let c = 0; c < 8; c++) {
                    const piece = board[r][c];
                    if (piece && this.isWhite(piece) === byWhite) {
                        const moves = this.getValidMoves(board, r, c, null, null, false);
                        if (moves.some(m => m.to[0] === row && m.to[1] === col)) {
                            return true;
                        }
                    }
                }
            }
            return false;
        },

        // Find king position
        findKing(board, color) {
            const king = color === 'white' ? 'K' : 'k';
            for (let r = 0; r < 8; r++) {
                for (let c = 0; c < 8; c++) {
                    if (board[r][c] === king) return [r, c];
                }
            }
            return null;
        },

        // Check if color is in check
        isInCheck(board, color) {
            const kingPos = this.findKing(board, color);
            if (!kingPos) return false;
            return this.isSquareAttacked(board, kingPos[0], kingPos[1], color === 'white' ? false : true);
        },

        // Apply move to board
        applyMove(board, move) {
            const piece = board[move.from[0]][move.from[1]];
            board[move.from[0]][move.from[1]] = null;
            board[move.to[0]][move.to[1]] = piece;

            // Handle special moves
            if (move.special === 'enpassant') {
                const dir = this.isWhite(piece) ? 1 : -1;
                board[move.to[0] + dir][move.to[1]] = null;
            } else if (move.special === 'castle-king') {
                const row = move.to[0];
                board[row][5] = board[row][7];
                board[row][7] = null;
            } else if (move.special === 'castle-queen') {
                const row = move.to[0];
                board[row][3] = board[row][0];
                board[row][0] = null;
            } else if (move.special === 'promotion') {
                board[move.to[0]][move.to[1]] = this.isWhite(piece) ? 'Q' : 'q';
            }

            return board;
        },

        // Get all legal moves for a color
        getAllMoves(board, color, castling, enPassant) {
            const moves = [];
            for (let r = 0; r < 8; r++) {
                for (let c = 0; c < 8; c++) {
                    const piece = board[r][c];
                    if (piece && this.getColor(piece) === color) {
                        moves.push(...this.getValidMoves(board, r, c, castling, enPassant));
                    }
                }
            }
            return moves;
        },

        // Evaluate board position
        evaluate(board) {
            let score = 0;

            for (let r = 0; r < 8; r++) {
                for (let c = 0; c < 8; c++) {
                    const piece = board[r][c];
                    if (!piece) continue;

                    const pieceType = piece.toLowerCase();
                    const isWhite = this.isWhite(piece);
                    const value = this.PIECE_VALUES[pieceType];
                    const pstRow = isWhite ? r : 7 - r;
                    const pstValue = this.PST[pieceType][pstRow][c];

                    if (isWhite) {
                        score += value + pstValue;
                    } else {
                        score -= value + pstValue;
                    }
                }
            }

            return score;
        },

        // Minimax with alpha-beta pruning
        minimax(board, depth, alpha, beta, isMaximizing, castling, enPassant) {
            if (depth === 0) {
                return { score: this.evaluate(board) };
            }

            const color = isMaximizing ? 'white' : 'black';
            const moves = this.getAllMoves(board, color, castling, enPassant);

            if (moves.length === 0) {
                if (this.isInCheck(board, color)) {
                    return { score: isMaximizing ? -100000 + depth : 100000 - depth };
                }
                return { score: 0 }; // Stalemate
            }

            // Move ordering - captures first
            moves.sort((a, b) => {
                const captureA = board[a.to[0]][a.to[1]] ? 1 : 0;
                const captureB = board[b.to[0]][b.to[1]] ? 1 : 0;
                return captureB - captureA;
            });

            let bestMove = moves[0];

            if (isMaximizing) {
                let maxScore = -Infinity;
                for (const move of moves) {
                    const newBoard = this.cloneBoard(board);
                    this.applyMove(newBoard, move);
                    const result = this.minimax(newBoard, depth - 1, alpha, beta, false, castling, null);
                    if (result.score > maxScore) {
                        maxScore = result.score;
                        bestMove = move;
                    }
                    alpha = Math.max(alpha, result.score);
                    if (beta <= alpha) break;
                }
                return { score: maxScore, move: bestMove };
            } else {
                let minScore = Infinity;
                for (const move of moves) {
                    const newBoard = this.cloneBoard(board);
                    this.applyMove(newBoard, move);
                    const result = this.minimax(newBoard, depth - 1, alpha, beta, true, castling, null);
                    if (result.score < minScore) {
                        minScore = result.score;
                        bestMove = move;
                    }
                    beta = Math.min(beta, result.score);
                    if (beta <= alpha) break;
                }
                return { score: minScore, move: bestMove };
            }
        },

        // Get AI move
        getAIMove(board, castling, enPassant, difficulty) {
            const depths = { easy: 1, medium: 2, hard: 3, master: 4 };
            const depth = depths[difficulty] || 2;

            // Add randomness for easier difficulties
            if (difficulty === 'easy' && Math.random() < 0.3) {
                const moves = this.getAllMoves(board, 'black', castling, enPassant);
                if (moves.length > 0) {
                    return moves[Math.floor(Math.random() * moves.length)];
                }
            }

            const result = this.minimax(board, depth, -Infinity, Infinity, false, castling, enPassant);
            return result.move;
        }
    };

    // ═══════════════════════════════════════════════════════════════
    // STYLES
    // ═══════════════════════════════════════════════════════════════

    GM_addStyle(`
        /* Chess Widget Container */
        .chess-widget {
            --bg-primary: #1a1b26;
            --bg-secondary: #24283b;
            --bg-tertiary: #1f2335;
            --text-primary: #c0caf5;
            --text-secondary: #565f89;
            --accent: #7aa2f7;
            --accent-hover: #89b4fa;
            --success: #9ece6a;
            --error: #f7768e;
            --warning: #e0af68;
            --light-square: #eeeed2;
            --dark-square: #769656;
            --highlight: rgba(255, 255, 0, 0.4);
            --move-hint: rgba(0, 0, 0, 0.2);
            --border: #3b4261;
            --shadow: rgba(0, 0, 0, 0.5);

            font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
            position: fixed;
            z-index: 2147483647;
        }

        .chess-widget * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        /* Theme Variants */
        .chess-widget[data-theme="classic"] {
            --light-square: #f0d9b5;
            --dark-square: #b58863;
        }

        .chess-widget[data-theme="blue"] {
            --light-square: #dee3e6;
            --dark-square: #8ca2ad;
        }

        .chess-widget[data-theme="green"] {
            --light-square: #eeeed2;
            --dark-square: #769656;
        }

        .chess-widget[data-theme="purple"] {
            --light-square: #e8dff0;
            --dark-square: #9573a6;
        }

        /* Floating Button */
        .chess-fab {
            width: 60px;
            height: 60px;
            border-radius: 16px;
            background: linear-gradient(135deg, var(--accent), #bb9af7);
            border: none;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            box-shadow: 0 4px 20px var(--shadow);
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            font-size: 28px;
        }

        .chess-fab:hover {
            transform: scale(1.1) rotate(-5deg);
            box-shadow: 0 6px 30px var(--shadow);
        }

        .chess-fab:active {
            transform: scale(0.95);
        }

        /* Game Window */
        .chess-window {
            position: absolute;
            bottom: 75px;
            right: 0;
            width: 500px;
            background: var(--bg-primary);
            border-radius: 20px;
            box-shadow: 0 25px 80px var(--shadow);
            display: flex;
            flex-direction: column;
            overflow: hidden;
            opacity: 0;
            visibility: hidden;
            transform: translateY(20px) scale(0.95);
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            border: 1px solid var(--border);
        }

        .chess-window.open {
            opacity: 1;
            visibility: visible;
            transform: translateY(0) scale(1);
        }

        /* Header */
        .chess-header {
            background: var(--bg-secondary);
            padding: 16px 20px;
            display: flex;
            align-items: center;
            justify-content: space-between;
            border-bottom: 1px solid var(--border);
        }

        .chess-header-left {
            display: flex;
            align-items: center;
            gap: 12px;
        }

        .chess-header-left h3 {
            color: var(--text-primary);
            font-size: 18px;
            font-weight: 600;
        }

        .chess-header-left span {
            font-size: 24px;
        }

        .chess-header-actions {
            display: flex;
            gap: 8px;
        }

        .chess-btn {
            padding: 8px 12px;
            border-radius: 8px;
            background: var(--bg-tertiary);
            border: 1px solid var(--border);
            color: var(--text-primary);
            font-size: 13px;
            cursor: pointer;
            transition: all 0.2s;
            display: flex;
            align-items: center;
            gap: 6px;
        }

        .chess-btn:hover {
            background: var(--accent);
            border-color: var(--accent);
        }

        .chess-btn.icon-only {
            padding: 8px;
        }

        /* Game Area */
        .chess-game {
            display: flex;
            flex-direction: column;
            padding: 16px;
            gap: 12px;
        }

        /* Status Bar */
        .chess-status {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 10px 16px;
            background: var(--bg-secondary);
            border-radius: 12px;
        }

        .chess-player {
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .chess-player-icon {
            width: 36px;
            height: 36px;
            border-radius: 8px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 20px;
        }

        .chess-player-icon.white { background: #fff; }
        .chess-player-icon.black { background: #333; }

        .chess-player-info {
            display: flex;
            flex-direction: column;
        }

        .chess-player-name {
            color: var(--text-primary);
            font-weight: 600;
            font-size: 14px;
        }

        .chess-player-status {
            color: var(--text-secondary);
            font-size: 12px;
        }

        .chess-player.active .chess-player-name {
            color: var(--accent);
        }

        .chess-turn-indicator {
            padding: 6px 12px;
            background: var(--accent);
            color: #fff;
            border-radius: 20px;
            font-size: 12px;
            font-weight: 600;
        }

        /* Board Container */
        .chess-board-container {
            display: flex;
            gap: 12px;
        }

        /* Captured Pieces */
        .chess-captured {
            display: flex;
            flex-direction: column;
            gap: 8px;
            width: 30px;
        }

        .chess-captured-group {
            display: flex;
            flex-direction: column;
            font-size: 16px;
            line-height: 1.2;
        }

        /* Board */
        .chess-board {
            display: grid;
            grid-template-columns: repeat(8, 1fr);
            border-radius: 8px;
            overflow: hidden;
            box-shadow: 0 4px 20px var(--shadow);
            flex: 1;
            aspect-ratio: 1;
        }

        .chess-square {
            aspect-ratio: 1;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 40px;
            cursor: pointer;
            position: relative;
            transition: background-color 0.15s;
            user-select: none;
        }

        .chess-square.light { background: var(--light-square); }
        .chess-square.dark { background: var(--dark-square); }

        .chess-square.selected {
            background: var(--highlight) !important;
        }

        .chess-square.last-move {
            background: rgba(255, 255, 0, 0.3) !important;
        }

        .chess-square.check {
            background: radial-gradient(circle, var(--error) 0%, transparent 70%) !important;
        }

        .chess-square.valid-move::after {
            content: '';
            position: absolute;
            width: 30%;
            height: 30%;
            background: var(--move-hint);
            border-radius: 50%;
        }

        .chess-square.valid-capture::after {
            content: '';
            position: absolute;
            inset: 4px;
            border: 4px solid var(--move-hint);
            border-radius: 50%;
            background: transparent;
        }

        .chess-square:hover {
            filter: brightness(1.1);
        }

        .chess-piece {
            font-size: inherit;
            line-height: 1;
            text-shadow: 1px 1px 2px rgba(0,0,0,0.3);
            transition: transform 0.1s;
        }

        .chess-square:active .chess-piece {
            transform: scale(1.1);
        }

        /* Coordinates */
        .chess-square .coord-file {
            position: absolute;
            bottom: 2px;
            right: 4px;
            font-size: 10px;
            font-weight: 600;
            opacity: 0.7;
        }

        .chess-square .coord-rank {
            position: absolute;
            top: 2px;
            left: 4px;
            font-size: 10px;
            font-weight: 600;
            opacity: 0.7;
        }

        .chess-square.light .coord-file,
        .chess-square.light .coord-rank { color: var(--dark-square); }
        .chess-square.dark .coord-file,
        .chess-square.dark .coord-rank { color: var(--light-square); }

        /* Controls */
        .chess-controls {
            display: flex;
            gap: 8px;
            flex-wrap: wrap;
        }

        .chess-controls .chess-btn {
            flex: 1;
            justify-content: center;
            min-width: 80px;
        }

        /* Move History */
        .chess-history {
            background: var(--bg-secondary);
            border-radius: 12px;
            padding: 12px;
            max-height: 100px;
            overflow-y: auto;
        }

        .chess-history-title {
            color: var(--text-secondary);
            font-size: 11px;
            text-transform: uppercase;
            letter-spacing: 0.5px;
            margin-bottom: 8px;
        }

        .chess-moves {
            display: flex;
            flex-wrap: wrap;
            gap: 4px;
            font-family: 'Courier New', monospace;
            font-size: 13px;
        }

        .chess-move {
            padding: 2px 6px;
            background: var(--bg-tertiary);
            border-radius: 4px;
            color: var(--text-primary);
        }

        .chess-move-number {
            color: var(--text-secondary);
        }

        /* Settings Panel */
        .chess-settings {
            position: absolute;
            inset: 0;
            background: var(--bg-primary);
            transform: translateX(100%);
            transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            display: flex;
            flex-direction: column;
        }

        .chess-settings.open {
            transform: translateX(0);
        }

        .chess-settings-header {
            padding: 16px 20px;
            background: var(--bg-secondary);
            border-bottom: 1px solid var(--border);
            display: flex;
            align-items: center;
            gap: 12px;
        }

        .chess-settings-header h3 {
            color: var(--text-primary);
            font-size: 18px;
        }

        .chess-settings-body {
            padding: 20px;
            overflow-y: auto;
            flex: 1;
        }

        .chess-setting-group {
            margin-bottom: 20px;
        }

        .chess-setting-group h4 {
            color: var(--text-secondary);
            font-size: 12px;
            text-transform: uppercase;
            letter-spacing: 0.5px;
            margin-bottom: 12px;
        }

        .chess-setting-options {
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
        }

        .chess-setting-option {
            padding: 10px 16px;
            background: var(--bg-secondary);
            border: 2px solid var(--border);
            border-radius: 10px;
            color: var(--text-primary);
            cursor: pointer;
            transition: all 0.2s;
            font-size: 14px;
        }

        .chess-setting-option:hover {
            border-color: var(--accent);
        }

        .chess-setting-option.active {
            border-color: var(--accent);
            background: rgba(122, 162, 247, 0.2);
        }

        /* Board Theme Options */
        .chess-theme-option {
            width: 60px;
            height: 40px;
            border-radius: 8px;
            overflow: hidden;
            display: grid;
            grid-template-columns: 1fr 1fr;
            cursor: pointer;
            border: 2px solid var(--border);
            transition: all 0.2s;
        }

        .chess-theme-option:hover,
        .chess-theme-option.active {
            border-color: var(--accent);
            transform: scale(1.05);
        }

        .chess-theme-option .light,
        .chess-theme-option .dark {
            width: 100%;
            height: 100%;
        }

        .chess-theme-option[data-theme="classic"] .light { background: #f0d9b5; }
        .chess-theme-option[data-theme="classic"] .dark { background: #b58863; }
        .chess-theme-option[data-theme="blue"] .light { background: #dee3e6; }
        .chess-theme-option[data-theme="blue"] .dark { background: #8ca2ad; }
        .chess-theme-option[data-theme="green"] .light { background: #eeeed2; }
        .chess-theme-option[data-theme="green"] .dark { background: #769656; }
        .chess-theme-option[data-theme="purple"] .light { background: #e8dff0; }
        .chess-theme-option[data-theme="purple"] .dark { background: #9573a6; }

        /* Game Over Modal */
        .chess-modal {
            position: absolute;
            inset: 0;
            background: rgba(0, 0, 0, 0.8);
            display: flex;
            align-items: center;
            justify-content: center;
            opacity: 0;
            visibility: hidden;
            transition: all 0.3s;
        }

        .chess-modal.open {
            opacity: 1;
            visibility: visible;
        }

        .chess-modal-content {
            background: var(--bg-secondary);
            padding: 30px 40px;
            border-radius: 20px;
            text-align: center;
            transform: scale(0.9);
            transition: transform 0.3s;
        }

        .chess-modal.open .chess-modal-content {
            transform: scale(1);
        }

        .chess-modal-icon {
            font-size: 60px;
            margin-bottom: 16px;
        }

        .chess-modal h2 {
            color: var(--text-primary);
            font-size: 24px;
            margin-bottom: 8px;
        }

        .chess-modal p {
            color: var(--text-secondary);
            font-size: 16px;
            margin-bottom: 24px;
        }

        .chess-modal-buttons {
            display: flex;
            gap: 12px;
            justify-content: center;
        }

        .chess-modal .chess-btn {
            padding: 12px 24px;
            font-size: 15px;
        }

        .chess-modal .chess-btn.primary {
            background: var(--accent);
            border-color: var(--accent);
        }

        /* Scrollbar */
        .chess-widget ::-webkit-scrollbar {
            width: 6px;
        }

        .chess-widget ::-webkit-scrollbar-track {
            background: transparent;
        }

        .chess-widget ::-webkit-scrollbar-thumb {
            background: var(--border);
            border-radius: 3px;
        }

        /* Responsive */
        @media (max-width: 540px) {
            .chess-window {
                width: calc(100vw - 20px);
                right: -10px;
            }
            .chess-square { font-size: 28px; }
        }
    `);

    // ═══════════════════════════════════════════════════════════════
    // PIECE UNICODE SYMBOLS
    // ═══════════════════════════════════════════════════════════════

    const PIECES = {
        'K': '♔', 'Q': '♕', 'R': '♖', 'B': '♗', 'N': '♘', 'P': '♙',
        'k': '♚', 'q': '♛', 'r': '♜', 'b': '♝', 'n': '♞', 'p': '♟'
    };

    // ═══════════════════════════════════════════════════════════════
    // GAME STATE
    // ═══════════════════════════════════════════════════════════════

    let gameState = {
        board: Chess.createBoard(),
        turn: 'white',
        selectedSquare: null,
        validMoves: [],
        castling: { whiteKing: true, whiteQueen: true, blackKing: true, blackQueen: true },
        enPassant: null,
        moveHistory: [],
        capturedWhite: [],
        capturedBlack: [],
        isOpen: false,
        isSettingsOpen: false,
        difficulty: 'medium',
        boardTheme: 'green',
        isFlipped: false,
        lastMove: null,
        gameOver: false,
        gameResult: null
    };

    // Load saved settings
    const savedState = GM_getValue('chess_game_state');
    if (savedState) {
        const parsed = JSON.parse(savedState);
        gameState.difficulty = parsed.difficulty || 'medium';
        gameState.boardTheme = parsed.boardTheme || 'green';
    }

    function saveSettings() {
        GM_setValue('chess_game_state', JSON.stringify({
            difficulty: gameState.difficulty,
            boardTheme: gameState.boardTheme
        }));
    }

    // ═══════════════════════════════════════════════════════════════
    // CREATE WIDGET
    // ═══════════════════════════════════════════════════════════════

    function createWidget() {
        const widget = document.createElement('div');
        widget.className = 'chess-widget';
        widget.dataset.theme = gameState.boardTheme;
        widget.style.cssText = 'right: 20px; bottom: 20px;';

        widget.innerHTML = `
            <button class="chess-fab" id="chess-fab">♟️</button>

            <div class="chess-window" id="chess-window">
                <!-- Header -->
                <div class="chess-header">
                    <div class="chess-header-left">
                        <span>♟️</span>
                        <h3>Chess Master</h3>
                    </div>
                    <div class="chess-header-actions">
                        <button class="chess-btn icon-only" id="chess-settings-btn" title="Settings">⚙️</button>
                        <button class="chess-btn icon-only" id="chess-close-btn" title="Close">✕</button>
                    </div>
                </div>

                <!-- Game Area -->
                <div class="chess-game">
                    <!-- Status -->
                    <div class="chess-status">
                        <div class="chess-player ${gameState.turn === 'black' ? 'active' : ''}" id="black-player">
                            <div class="chess-player-icon black">♚</div>
                            <div class="chess-player-info">
                                <span class="chess-player-name">Bot (<span id="difficulty-label">${gameState.difficulty}</span>)</span>
                                <span class="chess-player-status">Black</span>
                            </div>
                        </div>
                        <div class="chess-turn-indicator" id="turn-indicator">
                            ${gameState.turn === 'white' ? 'Your turn' : 'Bot thinking...'}
                        </div>
                        <div class="chess-player ${gameState.turn === 'white' ? 'active' : ''}" id="white-player">
                            <div class="chess-player-info" style="text-align: right;">
                                <span class="chess-player-name">You</span>
                                <span class="chess-player-status">White</span>
                            </div>
                            <div class="chess-player-icon white">♔</div>
                        </div>
                    </div>

                    <!-- Board Container -->
                    <div class="chess-board-container">
                        <div class="chess-captured" id="captured-white"></div>
                        <div class="chess-board" id="chess-board"></div>
                        <div class="chess-captured" id="captured-black"></div>
                    </div>

                    <!-- Controls -->
                    <div class="chess-controls">
                        <button class="chess-btn" id="new-game-btn">🔄 New Game</button>
                        <button class="chess-btn" id="undo-btn">↩️ Undo</button>
                        <button class="chess-btn" id="flip-btn">🔃 Flip</button>
                        <button class="chess-btn" id="hint-btn">💡 Hint</button>
                    </div>

                    <!-- Move History -->
                    <div class="chess-history">
                        <div class="chess-history-title">Move History</div>
                        <div class="chess-moves" id="move-history"></div>
                    </div>
                </div>

                <!-- Settings Panel -->
                <div class="chess-settings" id="chess-settings">
                    <div class="chess-settings-header">
                        <button class="chess-btn icon-only" id="settings-back-btn">←</button>
                        <h3>Settings</h3>
                    </div>
                    <div class="chess-settings-body">
                        <div class="chess-setting-group">
                            <h4>Difficulty</h4>
                            <div class="chess-setting-options" id="difficulty-options">
                                <div class="chess-setting-option ${gameState.difficulty === 'easy' ? 'active' : ''}" data-difficulty="easy">
                                    🌱 Easy
                                </div>
                                <div class="chess-setting-option ${gameState.difficulty === 'medium' ? 'active' : ''}" data-difficulty="medium">
                                    🌿 Medium
                                </div>
                                <div class="chess-setting-option ${gameState.difficulty === 'hard' ? 'active' : ''}" data-difficulty="hard">
                                    🌳 Hard
                                </div>
                                <div class="chess-setting-option ${gameState.difficulty === 'master' ? 'active' : ''}" data-difficulty="master">
                                    👑 Master
                                </div>
                            </div>
                        </div>

                        <div class="chess-setting-group">
                            <h4>Board Theme</h4>
                            <div class="chess-setting-options" id="theme-options">
                                <div class="chess-theme-option ${gameState.boardTheme === 'classic' ? 'active' : ''}" data-theme="classic">
                                    <div class="light"></div>
                                    <div class="dark"></div>
                                </div>
                                <div class="chess-theme-option ${gameState.boardTheme === 'blue' ? 'active' : ''}" data-theme="blue">
                                    <div class="light"></div>
                                    <div class="dark"></div>
                                </div>
                                <div class="chess-theme-option ${gameState.boardTheme === 'green' ? 'active' : ''}" data-theme="green">
                                    <div class="light"></div>
                                    <div class="dark"></div>
                                </div>
                                <div class="chess-theme-option ${gameState.boardTheme === 'purple' ? 'active' : ''}" data-theme="purple">
                                    <div class="light"></div>
                                    <div class="dark"></div>
                                </div>
                            </div>
                        </div>

                        <div class="chess-setting-group">
                            <h4>Play As</h4>
                            <div class="chess-setting-options">
                                <div class="chess-setting-option active" data-color="white">⬜ White</div>
                                <div class="chess-setting-option" data-color="black">⬛ Black</div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- Game Over Modal -->
                <div class="chess-modal" id="game-over-modal">
                    <div class="chess-modal-content">
                        <div class="chess-modal-icon" id="modal-icon">🏆</div>
                        <h2 id="modal-title">Game Over!</h2>
                        <p id="modal-message">You won by checkmate!</p>
                        <div class="chess-modal-buttons">
                            <button class="chess-btn" id="modal-close-btn">Close</button>
                            <button class="chess-btn primary" id="modal-new-game-btn">New Game</button>
                        </div>
                    </div>
                </div>
            </div>
        `;

        document.body.appendChild(widget);
        return widget;
    }

    // ═══════════════════════════════════════════════════════════════
    // RENDER FUNCTIONS
    // ═══════════════════════════════════════════════════════════════

    function renderBoard() {
        const boardEl = document.getElementById('chess-board');
        boardEl.innerHTML = '';

        for (let r = 0; r < 8; r++) {
            for (let c = 0; c < 8; c++) {
                const row = gameState.isFlipped ? 7 - r : r;
                const col = gameState.isFlipped ? 7 - c : c;
                const piece = gameState.board[row][col];
                const isLight = (row + col) % 2 === 0;

                const square = document.createElement('div');
                square.className = `chess-square ${isLight ? 'light' : 'dark'}`;
                square.dataset.row = row;
                square.dataset.col = col;

                // Highlight selected square
                if (gameState.selectedSquare &&
                    gameState.selectedSquare[0] === row &&
                    gameState.selectedSquare[1] === col) {
                    square.classList.add('selected');
                }

                // Highlight last move
                if (gameState.lastMove) {
                    if ((gameState.lastMove.from[0] === row && gameState.lastMove.from[1] === col) ||
                        (gameState.lastMove.to[0] === row && gameState.lastMove.to[1] === col)) {
                        square.classList.add('last-move');
                    }
                }

                // Show valid moves
                const validMove = gameState.validMoves.find(m => m.to[0] === row && m.to[1] === col);
                if (validMove) {
                    if (gameState.board[row][col]) {
                        square.classList.add('valid-capture');
                    } else {
                        square.classList.add('valid-move');
                    }
                }

                // Check indicator
                if (piece && piece.toLowerCase() === 'k') {
                    const color = Chess.isWhite(piece) ? 'white' : 'black';
                    if (Chess.isInCheck(gameState.board, color)) {
                        square.classList.add('check');
                    }
                }

                // Add piece
                if (piece) {
                    const pieceEl = document.createElement('span');
                    pieceEl.className = 'chess-piece';
                    pieceEl.textContent = PIECES[piece];
                    square.appendChild(pieceEl);
                }

                // Add coordinates
                if (col === (gameState.isFlipped ? 0 : 7)) {
                    const rank = document.createElement('span');
                    rank.className = 'coord-rank';
                    rank.textContent = 8 - row;
                    square.appendChild(rank);
                }
                if (row === (gameState.isFlipped ? 0 : 7)) {
                    const file = document.createElement('span');
                    file.className = 'coord-file';
                    file.textContent = 'abcdefgh'[col];
                    square.appendChild(file);
                }

                square.addEventListener('click', () => handleSquareClick(row, col));
                boardEl.appendChild(square);
            }
        }
    }

    function renderCaptured() {
        document.getElementById('captured-white').innerHTML =
            `<div class="chess-captured-group">${gameState.capturedWhite.map(p => PIECES[p]).join('')}</div>`;
        document.getElementById('captured-black').innerHTML =
            `<div class="chess-captured-group">${gameState.capturedBlack.map(p => PIECES[p]).join('')}</div>`;
    }

    function renderMoveHistory() {
        const historyEl = document.getElementById('move-history');
        historyEl.innerHTML = '';

        for (let i = 0; i < gameState.moveHistory.length; i += 2) {
            const moveNum = Math.floor(i / 2) + 1;
            const whiteMove = gameState.moveHistory[i];
            const blackMove = gameState.moveHistory[i + 1];

            const moveEl = document.createElement('span');
            moveEl.className = 'chess-move';
            moveEl.innerHTML = `<span class="chess-move-number">${moveNum}.</span> ${whiteMove}${blackMove ? ' ' + blackMove : ''}`;
            historyEl.appendChild(moveEl);
        }

        historyEl.scrollLeft = historyEl.scrollWidth;
    }

    function updateStatus() {
        const turnIndicator = document.getElementById('turn-indicator');
        const whitePlayer = document.getElementById('white-player');
        const blackPlayer = document.getElementById('black-player');

        if (gameState.gameOver) {
            turnIndicator.textContent = 'Game Over';
        } else if (gameState.turn === 'white') {
            turnIndicator.textContent = 'Your turn';
            whitePlayer.classList.add('active');
            blackPlayer.classList.remove('active');
        } else {
            turnIndicator.textContent = 'Bot thinking...';
            blackPlayer.classList.add('active');
            whitePlayer.classList.remove('active');
        }
    }

    // ═══════════════════════════════════════════════════════════════
    // GAME LOGIC
    // ═══════════════════════════════════════════════════════════════

    function getMoveNotation(move, piece) {
        const files = 'abcdefgh';
        const ranks = '87654321';
        const pieceSymbols = { 'n': 'N', 'b': 'B', 'r': 'R', 'q': 'Q', 'k': 'K', 'p': '' };
        const pieceType = piece.toLowerCase();

        let notation = pieceSymbols[pieceType];

        if (move.special === 'castle-king') return 'O-O';
        if (move.special === 'castle-queen') return 'O-O-O';

        const isCapture = gameState.board[move.to[0]][move.to[1]] || move.special === 'enpassant';
        if (isCapture) {
            if (pieceType === 'p') {
                notation = files[move.from[1]];
            }
            notation += 'x';
        }

        notation += files[move.to[1]] + ranks[move.to[0]];

        if (move.special === 'promotion') notation += '=Q';

        return notation;
    }

    function handleSquareClick(row, col) {
        if (gameState.gameOver || gameState.turn !== 'white') return;

        const piece = gameState.board[row][col];

        // If clicking on a valid move destination
        const validMove = gameState.validMoves.find(m => m.to[0] === row && m.to[1] === col);
        if (validMove) {
            makeMove(validMove);
            return;
        }

        // If clicking on own piece, select it
        if (piece && Chess.isWhite(piece)) {
            gameState.selectedSquare = [row, col];
            gameState.validMoves = Chess.getValidMoves(
                gameState.board, row, col,
                gameState.castling, gameState.enPassant
            );
        } else {
            gameState.selectedSquare = null;
            gameState.validMoves = [];
        }

        renderBoard();
    }

    function makeMove(move) {
        const piece = gameState.board[move.from[0]][move.from[1]];
        const captured = gameState.board[move.to[0]][move.to[1]];

        // Track captured pieces
        if (captured) {
            if (Chess.isWhite(captured)) {
                gameState.capturedWhite.push(captured);
            } else {
                gameState.capturedBlack.push(captured);
            }
        }

        // Handle en passant capture
        if (move.special === 'enpassant') {
            const dir = Chess.isWhite(piece) ? 1 : -1;
            const capturedPawn = gameState.board[move.to[0] + dir][move.to[1]];
            if (Chess.isWhite(capturedPawn)) {
                gameState.capturedWhite.push(capturedPawn);
            } else {
                gameState.capturedBlack.push(capturedPawn);
            }
        }

        // Update castling rights
        if (piece === 'K') {
            gameState.castling.whiteKing = false;
            gameState.castling.whiteQueen = false;
        } else if (piece === 'k') {
            gameState.castling.blackKing = false;
            gameState.castling.blackQueen = false;
        } else if (piece === 'R') {
            if (move.from[0] === 7 && move.from[1] === 0) gameState.castling.whiteQueen = false;
            if (move.from[0] === 7 && move.from[1] === 7) gameState.castling.whiteKing = false;
        } else if (piece === 'r') {
            if (move.from[0] === 0 && move.from[1] === 0) gameState.castling.blackQueen = false;
            if (move.from[0] === 0 && move.from[1] === 7) gameState.castling.blackKing = false;
        }

        // Set en passant square
        if (move.special === 'double') {
            const epRow = Chess.isWhite(piece) ? move.to[0] + 1 : move.to[0] - 1;
            gameState.enPassant = [epRow, move.to[1]];
        } else {
            gameState.enPassant = null;
        }

        // Record move notation
        const notation = getMoveNotation(move, piece);
        gameState.moveHistory.push(notation);

        // Apply move
        Chess.applyMove(gameState.board, move);
        gameState.lastMove = move;
        gameState.selectedSquare = null;
        gameState.validMoves = [];

        // Switch turn
        gameState.turn = gameState.turn === 'white' ? 'black' : 'white';

        // Check for game end
        checkGameEnd();

        // Render updates
        renderBoard();
        renderCaptured();
        renderMoveHistory();
        updateStatus();

        // AI move
        if (!gameState.gameOver && gameState.turn === 'black') {
            setTimeout(makeAIMove, 500);
        }
    }

    function makeAIMove() {
        const aiMove = Chess.getAIMove(
            gameState.board,
            gameState.castling,
            gameState.enPassant,
            gameState.difficulty
        );

        if (aiMove) {
            makeMove(aiMove);
        }
    }

    function checkGameEnd() {
        const currentColor = gameState.turn;
        const moves = Chess.getAllMoves(
            gameState.board, currentColor,
            gameState.castling, gameState.enPassant
        );

        if (moves.length === 0) {
            gameState.gameOver = true;
            if (Chess.isInCheck(gameState.board, currentColor)) {
                // Checkmate
                gameState.gameResult = currentColor === 'white' ? 'black' : 'white';
                showGameOverModal(
                    gameState.gameResult === 'white' ? '🏆' : '😔',
                    'Checkmate!',
                    gameState.gameResult === 'white' ? 'You won!' : 'Bot wins!'
                );
            } else {
                // Stalemate
                gameState.gameResult = 'draw';
                showGameOverModal('🤝', 'Stalemate!', 'The game is a draw.');
            }
        }
    }

    function showGameOverModal(icon, title, message) {
        document.getElementById('modal-icon').textContent = icon;
        document.getElementById('modal-title').textContent = title;
        document.getElementById('modal-message').textContent = message;
        document.getElementById('game-over-modal').classList.add('open');
    }

    function newGame() {
        gameState.board = Chess.createBoard();
        gameState.turn = 'white';
        gameState.selectedSquare = null;
        gameState.validMoves = [];
        gameState.castling = { whiteKing: true, whiteQueen: true, blackKing: true, blackQueen: true };
        gameState.enPassant = null;
        gameState.moveHistory = [];
        gameState.capturedWhite = [];
        gameState.capturedBlack = [];
        gameState.lastMove = null;
        gameState.gameOver = false;
        gameState.gameResult = null;

        document.getElementById('game-over-modal').classList.remove('open');
        renderBoard();
        renderCaptured();
        renderMoveHistory();
        updateStatus();
    }

    function undoMove() {
        if (gameState.moveHistory.length < 2 || gameState.gameOver) return;

        // Reset to starting position and replay all moves except last two
        gameState.board = Chess.createBoard();
        gameState.castling = { whiteKing: true, whiteQueen: true, blackKing: true, blackQueen: true };
        gameState.enPassant = null;
        gameState.capturedWhite = [];
        gameState.capturedBlack = [];

        // Remove last two moves (player and AI)
        gameState.moveHistory = gameState.moveHistory.slice(0, -2);
        gameState.turn = 'white';
        gameState.selectedSquare = null;
        gameState.validMoves = [];
        gameState.lastMove = null;

        renderBoard();
        renderCaptured();
        renderMoveHistory();
        updateStatus();
    }

    function showHint() {
        if (gameState.turn !== 'white' || gameState.gameOver) return;

        // Use AI to find best move for white
        const hint = Chess.minimax(
            gameState.board, 2, -Infinity, Infinity, true,
            gameState.castling, gameState.enPassant
        );

        if (hint.move) {
            gameState.selectedSquare = hint.move.from;
            gameState.validMoves = [hint.move];
            renderBoard();

            setTimeout(() => {
                gameState.selectedSquare = null;
                gameState.validMoves = [];
                renderBoard();
            }, 2000);
        }
    }

    // ═══════════════════════════════════════════════════════════════
    // EVENT LISTENERS
    // ═══════════════════════════════════════════════════════════════

    function setupEventListeners(widget) {
        const fab = document.getElementById('chess-fab');
        const window = document.getElementById('chess-window');
        const closeBtn = document.getElementById('chess-close-btn');
        const settingsBtn = document.getElementById('chess-settings-btn');
        const settingsPanel = document.getElementById('chess-settings');
        const settingsBackBtn = document.getElementById('settings-back-btn');
        const newGameBtn = document.getElementById('new-game-btn');
        const undoBtn = document.getElementById('undo-btn');
        const flipBtn = document.getElementById('flip-btn');
        const hintBtn = document.getElementById('hint-btn');
        const modalCloseBtn = document.getElementById('modal-close-btn');
        const modalNewGameBtn = document.getElementById('modal-new-game-btn');

        // Toggle game window
        fab.addEventListener('click', () => {
            gameState.isOpen = !gameState.isOpen;
            window.classList.toggle('open', gameState.isOpen);
        });

        closeBtn.addEventListener('click', () => {
            gameState.isOpen = false;
            window.classList.remove('open');
        });

        // Settings panel
        settingsBtn.addEventListener('click', () => {
            settingsPanel.classList.add('open');
        });

        settingsBackBtn.addEventListener('click', () => {
            settingsPanel.classList.remove('open');
        });

        // Difficulty selection
        document.getElementById('difficulty-options').addEventListener('click', (e) => {
            const option = e.target.closest('.chess-setting-option');
            if (!option) return;

            document.querySelectorAll('#difficulty-options .chess-setting-option')
                .forEach(o => o.classList.remove('active'));
            option.classList.add('active');

            gameState.difficulty = option.dataset.difficulty;
            document.getElementById('difficulty-label').textContent = gameState.difficulty;
            saveSettings();
        });

        // Theme selection
        document.getElementById('theme-options').addEventListener('click', (e) => {
            const option = e.target.closest('.chess-theme-option');
            if (!option) return;

            document.querySelectorAll('.chess-theme-option')
                .forEach(o => o.classList.remove('active'));
            option.classList.add('active');

            gameState.boardTheme = option.dataset.theme;
            widget.dataset.theme = option.dataset.theme;
            saveSettings();
        });

        // Game controls
        newGameBtn.addEventListener('click', newGame);
        undoBtn.addEventListener('click', undoMove);
        flipBtn.addEventListener('click', () => {
            gameState.isFlipped = !gameState.isFlipped;
            renderBoard();
        });
        hintBtn.addEventListener('click', showHint);

        // Modal buttons
        modalCloseBtn.addEventListener('click', () => {
            document.getElementById('game-over-modal').classList.remove('open');
        });
        modalNewGameBtn.addEventListener('click', newGame);

        // Keyboard shortcuts
        document.addEventListener('keydown', (e) => {
            if (!gameState.isOpen) return;

            if (e.key === 'Escape') {
                if (settingsPanel.classList.contains('open')) {
                    settingsPanel.classList.remove('open');
                } else {
                    gameState.isOpen = false;
                    window.classList.remove('open');
                }
            } else if (e.key === 'n' && e.ctrlKey) {
                e.preventDefault();
                newGame();
            } else if (e.key === 'z' && e.ctrlKey) {
                e.preventDefault();
                undoMove();
            } else if (e.key === 'h' && e.ctrlKey) {
                e.preventDefault();
                showHint();
            }
        });

        // Draggable widget
        let isDragging = false;
        let startX, startY, startRight, startBottom;

        fab.addEventListener('mousedown', (e) => {
            if (e.button !== 0) return;
            isDragging = true;
            startX = e.clientX;
            startY = e.clientY;
            startRight = parseInt(widget.style.right);
            startBottom = parseInt(widget.style.bottom);
        });

        document.addEventListener('mousemove', (e) => {
            if (!isDragging) return;
            const deltaX = startX - e.clientX;
            const deltaY = startY - e.clientY;
            widget.style.right = Math.max(0, startRight + deltaX) + 'px';
            widget.style.bottom = Math.max(0, startBottom + deltaY) + 'px';
        });

        document.addEventListener('mouseup', () => {
            isDragging = false;
        });
    }

    // ═══════════════════════════════════════════════════════════════
    // INITIALIZATION
    // ═══════════════════════════════════════════════════════════════

    function init() {
        const widget = createWidget();
        setupEventListeners(widget);
        renderBoard();
        renderCaptured();
        renderMoveHistory();
        updateStatus();

        console.log('%c♟️ Chess Master loaded! Click the floating button to play.',
            'color: #7aa2f7; font-weight: bold; font-size: 14px;');
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

})();