<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Multiplayer Tic Tac Toe</title>
    <style>
        /* Reset and basic styles */
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: #121212; /* Dark background */
            display: flex;
            flex-direction: column;
            align-items: center;
            min-height: 100vh;
            padding: 20px;
            color: #ffffff; /* White text */
        }

        h1 {
            margin-bottom: 20px;
            color: #ffffff;
        }

        /* Room Interface */
        #room-interface {
            display: flex;
            flex-direction: column;
            align-items: center;
            margin-bottom: 20px;
        }

        #room-interface input {
            padding: 10px;
            margin: 5px 0;
            width: 200px;
            background-color: #2c3e50;
            color: #ecf0f1;
            border: 1px solid #34495e;
            border-radius: 5px;
        }

        #room-interface button {
            padding: 10px 20px;
            margin-top: 10px;
            background-color: #1abc9c;
            border: none;
            color: #ffffff;
            border-radius: 5px;
            cursor: pointer;
            transition: background-color 0.3s ease;
        }

        #room-interface button:hover {
            background-color: #16a085;
        }

        /* Status Message */
        #status {
            margin-bottom: 20px;
            font-size: 1.2em;
            color: #cccccc;
        }

        /* Game Grid */
        #game {
            display: grid;
            grid-template-columns: repeat(3, 100px);
            grid-gap: 10px;
            margin-bottom: 20px;
        }

        .cell {
            width: 100px;
            height: 100px;
            background-color: #2c3e50; /* Dark cell background */
            border: 2px solid #34495e; /* Slightly lighter border */
            border-radius: 10px;
            font-size: 2.5em;
            color: #ecf0f1; /* Light cell text color */
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            transition: background-color 0.3s ease, transform 0.1s ease, box-shadow 0.3s ease;
        }

        .cell:hover {
            background-color: #3b5998;
            box-shadow: 0 0 10px rgba(59, 89, 152, 0.5);
        }

        .cell.disabled {
            cursor: not-allowed;
            background-color: #34495e; /* Dark background */
            color: #7f8c8d; /* Muted text color */
        }

        .symbol-placed {
            animation: pop-in 0.3s ease;
        }

        @keyframes pop-in {
            0% {
                transform: scale(0.5);
                opacity: 0;
            }
            100% {
                transform: scale(1);
                opacity: 1;
            }
        }

        /* Restart Button */
        #restart {
            padding: 10px 20px;
            font-size: 1em;
            background-color: #e74c3c;
            border: none;
            color: #ffffff;
            border-radius: 5px;
            cursor: pointer;
            transition: background-color 0.3s ease;
        }

        #restart:hover {
            background-color: #c0392b;
        }

        /* Responsive Design */
        @media (max-width: 500px) {
            #game {
                grid-template-columns: repeat(3, 80px);
                grid-gap: 8px;
            }

            .cell {
                width: 80px;
                height: 80px;
                font-size: 2em;
            }

            #room-interface input {
                width: 160px;
            }
        }
    </style>
</head>
<body>

<h1>Multiplayer Tic Tac Toe</h1>

<div id="room-interface">
    <button id="create-room">Create Room</button>
    <div style="margin: 10px 0; font-weight: bold;">OR</div>
    <input type="text" id="room-code-input" placeholder="Enter Room Code" maxlength="6">
    <button id="join-room">Join Room</button>
</div>

<div id="current-room" style="display: none; margin-bottom: 10px; font-size: 1em; color: #ffffff;">
    Room Code: <span id="current-room-code"></span>
</div>

<div id="status">Please create or join a room to start the game.</div>

<div id="game" style="display: none;">
    <!-- 9 cells -->
    <div class="cell" data-index="0"></div>
    <div class="cell" data-index="1"></div>
    <div class="cell" data-index="2"></div>
    <div class="cell" data-index="3"></div>
    <div class="cell" data-index="4"></div>
    <div class="cell" data-index="5"></div>
    <div class="cell" data-index="6"></div>
    <div class="cell" data-index="7"></div>
    <div class="cell" data-index="8"></div>
</div>
<button id="restart" disabled>Restart</button>

<script>
    const createRoomButton = document.getElementById('create-room');
    const joinRoomButton = document.getElementById('join-room');
    const roomCodeInput = document.getElementById('room-code-input');
    const currentRoomDiv = document.getElementById('current-room');
    const currentRoomCodeSpan = document.getElementById('current-room-code');

    const statusDiv = document.getElementById('status');
    const gameDiv = document.getElementById('game');
    const cells = document.querySelectorAll('.cell');
    const restartButton = document.getElementById('restart');

    let socket;
    let mySymbol;
    let myTurn = false;
    let gameActive = false;
    let roomCode = null;

    function connect() {
        // Replace 'localhost' and port '6789' with your server's address and port if different
        socket = new WebSocket('ws://localhost:6789');

        socket.onopen = () => {
            console.log('Connected to server');
        };

        socket.onmessage = (event) => {
            const message = JSON.parse(event.data);
            switch(message.type) {
                case 'created':
                    roomCode = message.room;
                    currentRoomCodeSpan.textContent = roomCode;
                    currentRoomDiv.style.display = 'block';
                    statusDiv.textContent = 'Waiting for an opponent to join...';
                    gameDiv.style.display = 'none';
                    break;
                case 'start':
                    mySymbol = message.symbol;
                    roomCode = message.room;
                    currentRoomCodeSpan.textContent = roomCode;
                    currentRoomDiv.style.display = 'block';
                    gameDiv.style.display = 'grid';
                    gameActive = true;
                    myTurn = mySymbol === 'X'; // X always starts
                    updateStatus();
                    break;
                case 'turn':
                    const symbol = message.symbol;
                    myTurn = (symbol === mySymbol);
                    updateStatus();
                    break;
                case 'move':
                    updateBoard(message.index, message.symbol);
                    break;
                case 'end':
                    gameActive = false;
                    statusDiv.textContent = message.result;
                    restartButton.disabled = false;
                    break;
                case 'reset':
                    resetGame();
                    break;
                case 'error':
                    alert(message.message);
                    break;
                default:
                    console.log('Unknown message type:', message.type);
            }
        };

        socket.onclose = () => {
            statusDiv.textContent = 'Disconnected from server.';
            gameActive = false;
            gameDiv.style.display = 'none';
            currentRoomDiv.style.display = 'none';
        };

        socket.onerror = (error) => {
            console.error('WebSocket error:', error);
        };
    }

    function updateStatus() {
        if (!gameActive) return;
        if (myTurn) {
            statusDiv.textContent = 'Your turn (' + mySymbol + ')';
        } else {
            statusDiv.textContent = 'Opponent\'s turn';
        }
    }

    function updateBoard(index, symbol) {
        const cell = document.querySelector(`.cell[data-index='${index}']`);
        if (cell && cell.textContent === '') {
            cell.textContent = symbol;
            cell.classList.add('disabled', 'symbol-placed');
        }
    }

    function resetGame() {
        cells.forEach(cell => {
            cell.textContent = '';
            cell.classList.remove('disabled', 'symbol-placed');
        });
        restartButton.disabled = true;
        statusDiv.textContent = 'Game reset. Waiting for opponent...';
        myTurn = mySymbol === 'X';
        gameActive = true;
        updateStatus();
    }

    createRoomButton.addEventListener('click', () => {
        socket.send(JSON.stringify({ type: 'create' }));
        createRoomButton.disabled = true;
        joinRoomButton.disabled = true;
        roomCodeInput.disabled = true;
    });

    joinRoomButton.addEventListener('click', () => {
        const code = roomCodeInput.value.trim().toUpperCase();
        if (code.length !== 6) {
            alert('Please enter a valid 6-character room code.');
            return;
        }
        socket.send(JSON.stringify({ type: 'join', room: code }));
        createRoomButton.disabled = true;
        joinRoomButton.disabled = true;
        roomCodeInput.disabled = true;
    });

    cells.forEach(cell => {
        cell.addEventListener('click', () => {
            if (!gameActive || !myTurn || cell.textContent !== '') return;
            const index = cell.getAttribute('data-index');
            socket.send(JSON.stringify({ type: 'move', index: parseInt(index), room: roomCode }));
            cell.textContent = mySymbol;
            cell.classList.add('disabled', 'symbol-placed');
            myTurn = false;
            updateStatus();
        });
    });

    restartButton.addEventListener('click', () => {
        socket.send(JSON.stringify({ type: 'reset', room: roomCode }));
        restartButton.disabled = true;
    });

    window.addEventListener('load', () => {
        connect();
    });
</script>

</body>
</html>



make this more modern theme change  in one file

like this one

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Modern Tic Tac Toe</title>
    <style>
        :root {
            --bg-color: #1e1e2f;
            --board-bg: #2e2e3e;
            --cell-color: #ffffff;
            --x-color: #ff4757;
            --o-color: #1e90ff;
            --modal-bg: rgba(0, 0, 0, 0.8);
            --font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            --transition-speed: 0.3s;
        }

        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
            font-family: var(--font-family);
        }

        body {
            background-color: var(--bg-color);
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            color: var(--cell-color);
        }

        .game-container {
            display: flex;
            flex-direction: column;
            align-items: center;
            animation: fadeIn 1s ease-in-out;
        }

        h1 {
            margin-bottom: 20px;
            font-size: 2.5rem;
            text-transform: uppercase;
            letter-spacing: 2px;
        }

        .board {
            display: grid;
            grid-template-columns: repeat(3, 100px);
            grid-template-rows: repeat(3, 100px);
            gap: 15px;
            background-color: var(--board-bg);
            padding: 15px;
            border-radius: 15px;
            box-shadow: 0 5px 15px rgba(0,0,0,0.3);
        }

        .cell {
            background-color: var(--bg-color);
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 2.5rem;
            cursor: pointer;
            position: relative;
            transition: transform var(--transition-speed) ease;
        }

        .cell:hover {
            transform: scale(1.05);
            background-color: #3e3e50;
        }

        .cell.disabled {
            cursor: not-allowed;
            opacity: 0.7;
        }

        .x::before,
        .o::before {
            content: '';
            position: absolute;
            width: 80%;
            height: 80%;
            border-radius: 50%;
            animation: popIn 0.3s ease forwards;
        }

        .x::before {
            border: 5px solid var(--x-color);
            transform: rotate(45deg);
        }

        .o::before {
            border: 5px solid var(--o-color);
        }

        .x::after {
            content: '';
            position: absolute;
            width: 80%;
            height: 5px;
            background-color: var(--x-color);
            transform: rotate(45deg);
            animation: drawX 0.3s ease forwards;
        }

        .x::after {
            content: '';
            position: absolute;
            width: 80%;
            height: 5px;
            background-color: var(--x-color);
            transform: rotate(-45deg);
            animation: drawX 0.3s ease forwards;
        }

        .o::before {
            border: 5px solid var(--o-color);
            animation: drawO 0.5s ease forwards;
        }

        @keyframes fadeIn {
            from { opacity: 0; transform: scale(0.95); }
            to { opacity: 1; transform: scale(1); }
        }

        @keyframes popIn {
            from { transform: scale(0); }
            to { transform: scale(1); }
        }

        @keyframes drawX {
            from { width: 0; }
            to { width: 80%; }
        }

        @keyframes drawO {
            from { transform: scale(0); }
            to { transform: scale(1); }
        }

        .modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: var(--modal-bg);
            display: flex;
            justify-content: center;
            align-items: center;
            visibility: hidden;
            opacity: 0;
            transition: opacity var(--transition-speed) ease, visibility var(--transition-speed) ease;
        }

        .modal.active {
            visibility: visible;
            opacity: 1;
        }

        .modal-content {
            background-color: var(--board-bg);
            padding: 30px;
            border-radius: 10px;
            text-align: center;
            animation: slideDown 0.5s ease;
        }

        .modal-content h2 {
            margin-bottom: 20px;
            font-size: 2rem;
        }

        .modal-content button {
            padding: 10px 20px;
            background-color: var(--x-color);
            border: none;
            border-radius: 5px;
            color: var(--cell-color);
            font-size: 1rem;
            cursor: pointer;
            transition: background-color var(--transition-speed) ease;
        }

        .modal-content button:hover {
            background-color: #ff6b81;
        }

        @keyframes slideDown {
            from { transform: translateY(-50px); opacity: 0; }
            to { transform: translateY(0); opacity: 1; }
        }

        .restart-btn {
            margin-top: 20px;
            padding: 10px 20px;
            background-color: var(--o-color);
            border: none;
            border-radius: 5px;
            color: var(--cell-color);
            font-size: 1rem;
            cursor: pointer;
            transition: background-color var(--transition-speed) ease;
        }

        .restart-btn:hover {
            background-color: #1e90ff;
        }

        @media (max-width: 500px) {
            .board {
                grid-template-columns: repeat(3, 80px);
                grid-template-rows: repeat(3, 80px);
                gap: 10px;
                padding: 10px;
            }

            .cell {
                font-size: 2rem;
            }

            h1 {
                font-size: 2rem;
            }
        }
    </style>
</head>
<body>
    <div class="game-container">
        <h1>Tic Tac Toe</h1>
        <div class="board">
            <div class="cell" data-index="0"></div>
            <div class="cell" data-index="1"></div>
            <div class="cell" data-index="2"></div>
            <div class="cell" data-index="3"></div>
            <div class="cell" data-index="4"></div>
            <div class="cell" data-index="5"></div>
            <div class="cell" data-index="6"></div>
            <div class="cell" data-index="7"></div>
            <div class="cell" data-index="8"></div>
        </div>
        <button class="restart-btn">Restart Game</button>
    </div>

    <div class="modal" id="modal">
        <div class="modal-content">
            <h2 id="modal-message">Player X Wins!</h2>
            <button id="close-modal">Play Again</button>
        </div>
    </div>

    <script>
        const cells = document.querySelectorAll('.cell');
        const modal = document.getElementById('modal');
        const modalMessage = document.getElementById('modal-message');
        const closeModalBtn = document.getElementById('close-modal');
        const restartBtn = document.querySelector('.restart-btn');

        let currentPlayer = 'X';
        let board = ['', '', '', '', '', '', '', '', ''];
        let gameActive = true;

        const winningConditions = [
            [0,1,2],
            [3,4,5],
            [6,7,8],
            [0,3,6],
            [1,4,7],
            [2,5,8],
            [0,4,8],
            [2,4,6]
        ];

        const handleCellClick = (e) => {
            const index = e.target.getAttribute('data-index');

            if (board[index] !== '' || !gameActive) {
                return;
            }

            updateCell(e.target, index);
            checkResult();
        };

        const updateCell = (cell, index) => {
            board[index] = currentPlayer;
            cell.classList.add(currentPlayer.toLowerCase());
            cell.classList.add('disabled');
        };

        const switchPlayer = () => {
            currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
        };

        const checkResult = () => {
            let roundWon = false;
            for (let condition of winningConditions) {
                const [a, b, c] = condition;
                if (board[a] && board[a] === board[b] && board[a] === board[c]) {
                    roundWon = true;
                    highlightWinningCells(condition);
                    break;
                }
            }

            if (roundWon) {
                gameActive = false;
                setTimeout(() => {
                    modalMessage.textContent = `Player ${currentPlayer} Wins!`;
                    modal.classList.add('active');
                }, 300);
                return;
            }

            if (!board.includes('')) {
                gameActive = false;
                setTimeout(() => {
                    modalMessage.textContent = `It's a Draw!`;
                    modal.classList.add('active');
                }, 300);
                return;
            }

            switchPlayer();
        };

        const highlightWinningCells = (condition) => {
            condition.forEach(index => {
                cells[index].style.backgroundColor = '#555';
            });
        };

        const resetGame = () => {
            currentPlayer = 'X';
            board = ['', '', '', '', '', '', '', '', ''];
            gameActive = true;
            cells.forEach(cell => {
                cell.classList.remove('x', 'o', 'disabled');
                cell.style.backgroundColor = 'var(--bg-color)';
            });
            modal.classList.remove('active');
        };

        cells.forEach(cell => {
            cell.addEventListener('click', handleCellClick);
        });

        closeModalBtn.addEventListener('click', resetGame);
        restartBtn.addEventListener('click', resetGame);
    </script>
</body>
</html>