I have some bugs in my Tetris game, please help me fix them and give some suggestions then implement to make the GUI more beautiful.

Below is a Tetris game implemented in JavaScript with a simple but functional GUI using HTML5 and CSS.

### HTML (index.html)
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tetris</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="container">
        <canvas id="gameBoard" width="300" height="600"></canvas>
        <div class="info">
            <h1>Tetris</h1>
            <p>Use Arrow Keys to move and rotate the pieces.</p>
            <p>Score: <span id="score">0</span></p>
            <button id="playButton">Play</button>
        </div>
    </div>
    <script src="tetris.js"></script>
</body>
</html>
```

### CSS (styles.css)
```css
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

body {
    font-family: Arial, sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background-color: #222;
    color: white;
}

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

canvas {
    background-color: #111;
    border: 4px solid #3e3e3e;
    margin-bottom: 20px;
}

.info {
    text-align: center;
}

button {
    background-color: #ff4081;
    color: white;
    border: none;
    padding: 10px 20px;
    font-size: 1rem;
    cursor: pointer;
    margin-top: 10px;
    border-radius: 5px;
}

button:hover {
    background-color: #ff79a1;
}
```

### JavaScript (tetris.js)
```javascript
const canvas = document.getElementById('gameBoard');
const ctx = canvas.getContext('2d');
const playButton = document.getElementById('playButton');
const scoreDisplay = document.getElementById('score');

const ROWS = 20;
const COLS = 10;
const BLOCK_SIZE = 30;
const EMPTY_COLOR = '#111';
const COLORS = ['#FF5733', '#33FF57', '#3357FF', '#FF33A8', '#FF8F33', '#FFD433', '#33FFF6'];

let board = [];
let currentPiece;
let score = 0;
let gameInterval;

// Tetromino shapes
const SHAPES = [
    [[1, 1, 1, 1]], // I
    [[1, 1], [1, 1]], // O
    [[0, 1, 1], [1, 1, 0]], // S
    [[1, 1, 0], [0, 1, 1]], // Z
    [[1, 1, 1], [0, 1, 0]], // T
    [[1, 1, 1], [1, 0, 0]], // L
    [[1, 1, 1], [0, 0, 1]]  // J
];

// Create and initialize the board
function createBoard() {
    board = Array.from({ length: ROWS }, () => Array(COLS).fill(EMPTY_COLOR));
}

// Draw a single block at (x, y) with the specified color
function drawBlock(x, y, color) {
    ctx.fillStyle = color;
    ctx.fillRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
    ctx.strokeStyle = '#333';
    ctx.strokeRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
}

// Clear the entire canvas
function clearCanvas() {
    ctx.fillStyle = EMPTY_COLOR;
    ctx.fillRect(0, 0, canvas.width, canvas.height);
}

// Render the board and the current piece
function render() {
    clearCanvas();
    drawBoard();
    if (currentPiece) {
        currentPiece.draw();
    }
}

// Draw the board blocks
function drawBoard() {
    for (let row = 0; row < ROWS; row++) {
        for (let col = 0; col < COLS; col++) {
            if (board[row][col] !== EMPTY_COLOR) {
                drawBlock(col, row, board[row][col]);
            }
        }
    }
}

// Generate a random Tetromino piece
function randomPiece() {
    const shape = SHAPES[Math.floor(Math.random() * SHAPES.length)];
    const color = COLORS[Math.floor(Math.random() * COLORS.length)];
    return new Piece(shape, color);
}

// Piece class representing a Tetromino
class Piece {
    constructor(shape, color) {
        this.shape = shape;
        this.color = color;
        this.x = Math.floor(COLS / 2) - Math.floor(this.shape[0].length / 2);
        this.y = 0;
    }

    // Draw the piece on the canvas
    draw() {
        this.shape.forEach((row, dy) => {
            row.forEach((value, dx) => {
                if (value) {
                    drawBlock(this.x + dx, this.y + dy, this.color);
                }
            });
        });
    }

    // Move the piece by (dx, dy)
    move(dx, dy) {
        if (!this.collides(this.x + dx, this.y + dy, this.shape)) {
            this.x += dx;
            this.y += dy;
            return true;
        }
        return false;
    }

    // Rotate the piece clockwise
    rotate() {
        const rotatedShape = this.shape[0].map((_, i) => this.shape.map(row => row[i]).reverse());
        if (!this.collides(this.x, this.y, rotatedShape)) {
            this.shape = rotatedShape;
        } else {
            // Attempt to shift piece to the left or right if rotation causes collision
            if (!this.collides(this.x - 1, this.y, rotatedShape)) {
                this.x -= 1;
                this.shape = rotatedShape;
            } else if (!this.collides(this.x + 1, this.y, rotatedShape)) {
                this.x += 1;
                this.shape = rotatedShape;
            }
        }
    }

    // Check if the piece collides with the board or boundaries
    collides(x, y, shape) {
        return shape.some((row, dy) => {
            return row.some((value, dx) => {
                let newX = x + dx;
                let newY = y + dy;
                return (
                    value &&
                    (newX < 0 || newX >= COLS || newY >= ROWS || (newY >= 0 && board[newY][newX] !== EMPTY_COLOR))
                );
            });
        });
    }

    // Lock the piece into the board
    lock() {
        this.shape.forEach((row, dy) => {
            row.forEach((value, dx) => {
                if (value) {
                    const newY = this.y + dy;
                    const newX = this.x + dx;
                    if (newY >= 0 && newY < ROWS && newX >= 0 && newX < COLS) {
                        board[newY][newX] = this.color;
                    }
                }
            });
        });
    }
}

// Clear completed lines and update the score
function clearLines() {
    let linesCleared = 0;
    for (let row = ROWS - 1; row >= 0; row--) {
        if (board[row].every(cell => cell !== EMPTY_COLOR)) {
            board.splice(row, 1);
            board.unshift(Array(COLS).fill(EMPTY_COLOR));
            linesCleared++;
            row++; // Re-check the same row after shifting
        }
    }
    if (linesCleared > 0) {
        score += linesCleared * 10;
        scoreDisplay.textContent = score;
    }
    if (linesCleared > 0) {
        render();
    }
}

// The main game loop that updates the game state
function gameLoop() {
    if (!currentPiece.move(0, 1)) {
        currentPiece.lock();
        clearLines();
        if (board[0].some(cell => cell !== EMPTY_COLOR)) {
            gameOver();
            return;
        }
        currentPiece = randomPiece();
        if (currentPiece.collides(currentPiece.x, currentPiece.y, currentPiece.shape)) {
            gameOver();
            return;
        }
    }
    render();
}

// Handle game over state
function gameOver() {
    clearInterval(gameInterval);
    alert('Game Over! Your score: ' + score);
    playButton.style.display = 'block';
}

// Handle user input for controlling the Tetromino
document.addEventListener('keydown', (e) => {
    if (!currentPiece) return;
    let moved = false;
    switch (e.key) {
        case 'ArrowLeft':
            moved = currentPiece.move(-1, 0);
            break;
        case 'ArrowRight':
            moved = currentPiece.move(1, 0);
            break;
        case 'ArrowDown':
            moved = currentPiece.move(0, 1);
            break;
        case 'ArrowUp':
            currentPiece.rotate();
            moved = true;
            break;
    }
    if (moved) {
        render();
    }
});

// Start or restart the game
function startGame() {
    createBoard();
    currentPiece = randomPiece();
    score = 0;
    scoreDisplay.textContent = score;
    playButton.style.display = 'none';
    clearInterval(gameInterval);
    gameInterval = setInterval(gameLoop, 500);
    render();
}

// Play button event listener
playButton.addEventListener('click', startGame);
```