diff --git a/projects/pianotiles/index.html b/projects/pianotiles/index.html
index a5acbe6..34a6254 100644
--- a/projects/pianotiles/index.html
+++ b/projects/pianotiles/index.html
@@ -2,469 +2,119 @@
-
+
Piano Tiles
-
+
+
-
-
-
-
-
-
-
-
-
-
Game Over!
-
0
-
-
-
-
-
-
\ No newline at end of file
diff --git a/projects/pianotiles/script.js b/projects/pianotiles/script.js
new file mode 100644
index 0000000..0918f13
--- /dev/null
+++ b/projects/pianotiles/script.js
@@ -0,0 +1,578 @@
+
+ // Game variables
+ let score = 0;
+ let highScore = 0;
+ let gameActive = false;
+ let gamePaused = false;
+ let gameMode = 'classic';
+ let tileSpeed = 0.4; // Very slow initial speed
+ let speedIncrement = 0.005; // Much smaller speed increase
+ let tileRows = [];
+ let lastTileTime = 0;
+ let tileInterval = 3000; // Very long interval between tiles (3 seconds)
+ let animationId;
+ let audioContext;
+ let currentTheme = 'light';
+ let combo = 0;
+ let lastComboTime = 0;
+
+ // Statistics tracking
+ let gameStats = {
+ totalGames: 0,
+ allTimeHigh: 0,
+ totalScore: 0,
+ totalTiles: 0,
+ classicHigh: 0,
+ arcadeHigh: 0,
+ scoreHistory: []
+ };
+
+ // DOM elements
+ const gameArea = document.getElementById('game-area');
+ const scoreDisplay = document.getElementById('score-display');
+ const highScoreDisplay = document.getElementById('high-score');
+ const speedFill = document.getElementById('speed-fill');
+ const comboDisplay = document.getElementById('combo-display');
+ const pauseButton = document.getElementById('pause-button');
+ const startScreen = document.getElementById('start-screen');
+ const gameOverScreen = document.getElementById('game-over-screen');
+ const pauseScreen = document.getElementById('pause-screen');
+ const modeSelection = document.getElementById('mode-selection');
+ const statsScreen = document.getElementById('stats-screen');
+ const finalScoreDisplay = document.getElementById('final-score');
+ const highestScoreDisplay = document.getElementById('highest-score-display');
+ const newHighScoreDisplay = document.getElementById('new-high-score');
+ const modeSelectButton = document.getElementById('mode-select-button');
+ const backButton = document.getElementById('back-button');
+ const restartButton = document.getElementById('restart-button');
+ const menuButton = document.getElementById('menu-button');
+ const menuButtonPause = document.getElementById('menu-button-pause');
+ const resumeButton = document.getElementById('resume-button');
+ const themeToggle = document.getElementById('theme-toggle');
+ const statsButton = document.getElementById('stats-button');
+ const backFromStats = document.getElementById('back-from-stats');
+ const clearDataButton = document.getElementById('clear-data-button');
+
+ // Load saved data from localStorage
+ function loadGameData() {
+ // Load game statistics
+ const savedStats = localStorage.getItem('pianoTilesStats');
+ if (savedStats) {
+ gameStats = JSON.parse(savedStats);
+ updateStatsDisplay();
+ }
+
+ // Load theme preference
+ const savedTheme = localStorage.getItem('pianoTilesTheme');
+ if (savedTheme) {
+ currentTheme = savedTheme;
+ document.documentElement.setAttribute('data-theme', currentTheme);
+ updateThemeToggle();
+ }
+
+ // Update high score display
+ highScore = gameStats.allTimeHigh;
+ highScoreDisplay.textContent = highScore;
+ }
+
+ // Save game data to localStorage
+ function saveGameData() {
+ localStorage.setItem('pianoTilesStats', JSON.stringify(gameStats));
+ localStorage.setItem('pianoTilesTheme', currentTheme);
+ }
+
+ // Save current game score
+ function saveScore() {
+ // Update statistics
+ gameStats.totalGames++;
+ gameStats.totalScore += score;
+ gameStats.totalTiles += score;
+
+ // Update mode-specific high scores
+ if (gameMode === 'classic' && score > gameStats.classicHigh) {
+ gameStats.classicHigh = score;
+ } else if (gameMode === 'arcade' && score > gameStats.arcadeHigh) {
+ gameStats.arcadeHigh = score;
+ }
+
+ // Update all-time high score
+ if (score > gameStats.allTimeHigh) {
+ gameStats.allTimeHigh = score;
+ highScore = score;
+ highScoreDisplay.textContent = highScore;
+ }
+
+ // Add to score history (keep last 10 scores)
+ const scoreEntry = {
+ score: score,
+ mode: gameMode,
+ date: new Date().toISOString()
+ };
+ gameStats.scoreHistory.unshift(scoreEntry);
+ if (gameStats.scoreHistory.length > 10) {
+ gameStats.scoreHistory = gameStats.scoreHistory.slice(0, 10);
+ }
+
+ // Save to localStorage
+ saveGameData();
+ updateStatsDisplay();
+ }
+
+ // Update statistics display
+ function updateStatsDisplay() {
+ document.getElementById('total-games').textContent = gameStats.totalGames;
+ document.getElementById('all-time-high').textContent = gameStats.allTimeHigh;
+
+ // Calculate average score
+ const averageScore = gameStats.totalGames > 0
+ ? Math.round(gameStats.totalScore / gameStats.totalGames)
+ : 0;
+ document.getElementById('average-score').textContent = averageScore;
+
+ document.getElementById('total-tiles').textContent = gameStats.totalTiles;
+
+ // Determine best mode
+ let bestMode = '-';
+ if (gameStats.classicHigh > 0 || gameStats.arcadeHigh > 0) {
+ if (gameStats.classicHigh >= gameStats.arcadeHigh) {
+ bestMode = `Classic (${gameStats.classicHigh})`;
+ } else {
+ bestMode = `Arcade (${gameStats.arcadeHigh})`;
+ }
+ }
+ document.getElementById('best-mode').textContent = bestMode;
+
+ // Update score history
+ const historyList = document.getElementById('history-list');
+ historyList.innerHTML = '';
+
+ if (gameStats.scoreHistory.length === 0) {
+ historyList.innerHTML = 'No scores yet
';
+ } else {
+ gameStats.scoreHistory.forEach(entry => {
+ const item = document.createElement('div');
+ item.className = 'history-item';
+
+ const date = new Date(entry.date);
+ const timeString = date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
+
+ item.innerHTML = `
+ ${entry.score} pts - ${entry.mode.charAt(0).toUpperCase() + entry.mode.slice(1)}
+ ${timeString}
+ `;
+ historyList.appendChild(item);
+ });
+ }
+ }
+
+ // Initialize audio context
+ function initAudio() {
+ if (!audioContext) {
+ audioContext = new (window.AudioContext || window.webkitAudioContext)();
+ }
+ }
+
+ // Play a piano tone
+ function playTone(frequency = 440, duration = 200) {
+ if (!audioContext) return;
+
+ const oscillator = audioContext.createOscillator();
+ const gainNode = audioContext.createGain();
+
+ oscillator.connect(gainNode);
+ gainNode.connect(audioContext.destination);
+
+ oscillator.frequency.value = frequency;
+ oscillator.type = 'sine';
+
+ gainNode.gain.setValueAtTime(0.3, audioContext.currentTime);
+ gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + duration / 1000);
+
+ oscillator.start(audioContext.currentTime);
+ oscillator.stop(audioContext.currentTime + duration / 1000);
+ }
+
+ // Create enhanced particle effect
+ function createParticle(x, y) {
+ // Create multiple particles for better effect
+ for (let i = 0; i < 6; i++) {
+ const particle = document.createElement('div');
+ particle.className = 'particle';
+ particle.style.left = `${x}px`;
+ particle.style.top = `${y}px`;
+
+ const angle = (Math.PI * 2 * i) / 6;
+ const velocity = 50 + Math.random() * 50;
+ const tx = Math.cos(angle) * velocity;
+ const ty = Math.sin(angle) * velocity;
+
+ particle.style.setProperty('--tx', `${tx}px`);
+ particle.style.setProperty('--ty', `${ty}px`);
+ particle.style.animation = 'particle-animation 0.6s ease-out forwards';
+
+ document.body.appendChild(particle);
+
+ setTimeout(() => {
+ document.body.removeChild(particle);
+ }, 600);
+ }
+ }
+
+ // Create score popup animation
+ function createScorePopup(x, y) {
+ const popup = document.createElement('div');
+ popup.className = 'score-popup';
+ popup.textContent = '+1';
+ popup.style.left = `${x}px`;
+ popup.style.top = `${y}px`;
+
+ document.body.appendChild(popup);
+
+ setTimeout(() => {
+ document.body.removeChild(popup);
+ }, 1000);
+ }
+
+ // Show combo display
+ function showCombo() {
+ const now = Date.now();
+ if (now - lastComboTime < 2000) {
+ combo++;
+ if (combo > 1) {
+ comboDisplay.textContent = `${combo}x COMBO!`;
+ comboDisplay.classList.remove('show');
+ void comboDisplay.offsetWidth; // Trigger reflow
+ comboDisplay.classList.add('show');
+ }
+ } else {
+ combo = 1;
+ }
+ lastComboTime = now;
+ }
+
+ // Update speed indicator
+ function updateSpeedIndicator() {
+ const maxSpeed = 2.0;
+ const percentage = Math.min((tileSpeed / maxSpeed) * 100, 100);
+ speedFill.style.width = `${percentage}%`;
+ }
+
+ // Create a new tile row
+ function createTileRow() {
+ const row = document.createElement('div');
+ row.className = 'tile-row';
+ row.style.top = '-25vh';
+
+ // Random position for the active tile (0-3)
+ const activeTileIndex = Math.floor(Math.random() * 4);
+
+ for (let i = 0; i < 4; i++) {
+ const tile = document.createElement('div');
+ tile.className = 'tile';
+
+ if (i === activeTileIndex) {
+ tile.classList.add('active');
+
+ // Add both click and touch event listeners for better responsiveness
+ const handleTileClick = (e) => {
+ e.preventDefault();
+ if (!gameActive || gamePaused || tile.classList.contains('clicked')) return;
+
+ tile.classList.add('clicked');
+ score++;
+ scoreDisplay.textContent = score;
+
+ // Show combo
+ showCombo();
+
+ // Create particle effect at touch position
+ const rect = tile.getBoundingClientRect();
+ const x = e.clientX || (e.touches && e.touches[0].clientX) || rect.left + rect.width / 2;
+ const y = e.clientY || (e.touches && e.touches[0].clientY) || rect.top + rect.height / 2;
+ createParticle(x, y);
+ createScorePopup(x, y);
+
+ // Play a tone based on the tile position
+ const baseFrequency = 261.63; // C4
+ const frequency = baseFrequency * Math.pow(2, (3 - i) / 12);
+ playTone(frequency, 150);
+
+ // Update speed indicator
+ updateSpeedIndicator();
+
+ // Increase speed based on game mode (very gradual now)
+ if (gameMode === 'classic' && score % 50 === 0) { // Every 50 points
+ tileSpeed += speedIncrement;
+ } else if (gameMode === 'arcade' && score % 40 === 0) { // Every 40 points
+ tileSpeed += speedIncrement * 1.5;
+ }
+ };
+
+ // Multiple event listeners for better touch responsiveness
+ tile.addEventListener('click', handleTileClick);
+ tile.addEventListener('touchstart', handleTileClick, { passive: false });
+ tile.addEventListener('mousedown', handleTileClick);
+ }
+
+ row.appendChild(tile);
+ }
+
+ gameArea.appendChild(row);
+ tileRows.push({
+ element: row,
+ position: -25,
+ clicked: false
+ });
+ }
+
+ // Update tile positions
+ function updateTiles(timestamp) {
+ if (!gameActive || gamePaused) return;
+
+ // Create new tiles at intervals based on game mode
+ let currentTileInterval = tileInterval;
+
+ if (gameMode === 'arcade') {
+ currentTileInterval = 2500;
+ }
+
+ if (timestamp - lastTileTime > currentTileInterval) {
+ createTileRow();
+ lastTileTime = timestamp;
+
+ // Very gradual decrease in interval for arcade mode
+ if (gameMode === 'arcade' && currentTileInterval > 2000) {
+ tileInterval -= 30;
+ }
+ }
+
+ // Update existing tiles
+ for (let i = tileRows.length - 1; i >= 0; i--) {
+ const row = tileRows[i];
+ row.position += tileSpeed;
+ row.element.style.top = `${row.position}vh`;
+
+ // Check if any active tile was missed
+ if (row.position > 0 && !row.clicked) {
+ const activeTile = row.element.querySelector('.tile.active:not(.clicked)');
+ if (activeTile) {
+ activeTile.classList.add('missed');
+ combo = 0; // Reset combo on miss
+ endGame();
+ return;
+ }
+ }
+
+ // Remove tiles that are off screen
+ if (row.position > 100) {
+ gameArea.removeChild(row.element);
+ tileRows.splice(i, 1);
+ }
+ }
+
+ animationId = requestAnimationFrame(updateTiles);
+ }
+
+ // Start the game
+ function startGame(mode = 'classic') {
+ initAudio();
+ gameMode = mode;
+ score = 0;
+ combo = 0;
+ tileSpeed = gameMode === 'arcade' ? 0.5 : 0.4; // Very slow initial speeds
+ tileInterval = gameMode === 'arcade' ? 2500 : 3000; // Very long initial intervals
+ lastTileTime = 0;
+ scoreDisplay.textContent = score;
+ gameActive = true;
+ gamePaused = false;
+
+ // Reset speed indicator
+ updateSpeedIndicator();
+
+ // Clear any existing tiles
+ tileRows.forEach(row => {
+ gameArea.removeChild(row.element);
+ });
+ tileRows = [];
+
+ // Hide screens
+ startScreen.classList.add('hidden');
+ gameOverScreen.classList.add('hidden');
+ modeSelection.classList.add('hidden');
+ statsScreen.classList.add('hidden');
+ pauseScreen.classList.add('hidden');
+ newHighScoreDisplay.classList.add('hidden');
+
+ // Hide stats button during gameplay
+ statsButton.classList.add('hidden');
+
+ // Show pause button
+ pauseButton.classList.remove('hidden');
+
+ // Start the game loop
+ animationId = requestAnimationFrame(updateTiles);
+ }
+
+ // End the game
+ function endGame() {
+ gameActive = false;
+ gamePaused = false;
+ cancelAnimationFrame(animationId);
+
+ // Hide pause button
+ pauseButton.classList.add('hidden');
+
+ // Save the score
+ saveScore();
+
+ // Check for new high score
+ if (score > highScore) {
+ newHighScoreDisplay.classList.remove('hidden');
+ } else {
+ newHighScoreDisplay.classList.add('hidden');
+ }
+
+ // Show game over screen with highest score
+ finalScoreDisplay.textContent = `Final Score: ${score}`;
+ highestScoreDisplay.textContent = `Highest Score: ${gameStats.allTimeHigh}`;
+ gameOverScreen.classList.remove('hidden');
+
+ // Play game over sound
+ playTone(200, 500);
+ }
+
+ // Pause the game
+ function pauseGame() {
+ if (!gameActive || gamePaused) return;
+
+ gamePaused = true;
+ pauseScreen.classList.remove('hidden');
+ }
+
+ // Resume the game
+ function resumeGame() {
+ if (!gameActive || !gamePaused) return;
+
+ gamePaused = false;
+ pauseScreen.classList.add('hidden');
+ animationId = requestAnimationFrame(updateTiles);
+ }
+
+ // Toggle theme
+ function toggleTheme() {
+ currentTheme = currentTheme === 'light' ? 'dark' : 'light';
+ document.documentElement.setAttribute('data-theme', currentTheme);
+ updateThemeToggle();
+ saveGameData();
+ }
+
+ // Update theme toggle button
+ function updateThemeToggle() {
+ const icon = currentTheme === 'light' ? 'π' : 'βοΈ';
+ if (themeToggle) themeToggle.textContent = icon;
+ }
+
+ // Clear all data
+ function clearAllData() {
+ if (confirm('Are you sure you want to clear all game data? This cannot be undone.')) {
+ gameStats = {
+ totalGames: 0,
+ allTimeHigh: 0,
+ totalScore: 0,
+ totalTiles: 0,
+ classicHigh: 0,
+ arcadeHigh: 0,
+ scoreHistory: []
+ };
+ highScore = 0;
+ highScoreDisplay.textContent = highScore;
+ saveGameData();
+ updateStatsDisplay();
+ alert('All data has been cleared.');
+ }
+ }
+
+ // Show main menu
+ function showMainMenu() {
+ // Show stats button only on main menu
+ statsButton.classList.remove('hidden');
+
+ // Hide other screens
+ startScreen.classList.remove('hidden');
+ modeSelection.classList.add('hidden');
+ statsScreen.classList.add('hidden');
+ gameOverScreen.classList.add('hidden');
+ pauseScreen.classList.add('hidden');
+ }
+
+ // Event listeners with better touch handling
+ modeSelectButton.addEventListener('click', () => {
+ startScreen.classList.add('hidden');
+ modeSelection.classList.remove('hidden');
+ });
+
+ backButton.addEventListener('click', () => {
+ modeSelection.classList.add('hidden');
+ startScreen.classList.remove('hidden');
+ });
+
+ restartButton.addEventListener('click', () => startGame(gameMode));
+ menuButton.addEventListener('click', () => {
+ gameOverScreen.classList.add('hidden');
+ showMainMenu();
+ });
+
+ menuButtonPause.addEventListener('click', () => {
+ gameActive = false;
+ gamePaused = false;
+ cancelAnimationFrame(animationId);
+ pauseButton.classList.add('hidden');
+ pauseScreen.classList.add('hidden');
+ showMainMenu();
+ });
+
+ pauseButton.addEventListener('click', pauseGame);
+ resumeButton.addEventListener('click', resumeGame);
+
+ themeToggle.addEventListener('click', toggleTheme);
+
+ statsButton.addEventListener('click', () => {
+ startScreen.classList.add('hidden');
+ statsScreen.classList.remove('hidden');
+ updateStatsDisplay();
+ });
+
+ backFromStats.addEventListener('click', () => {
+ statsScreen.classList.add('hidden');
+ startScreen.classList.remove('hidden');
+ });
+
+ clearDataButton.addEventListener('click', clearAllData);
+
+ // Game mode buttons
+ document.querySelectorAll('.mode-button[data-mode]').forEach(button => {
+ button.addEventListener('click', () => {
+ const mode = button.getAttribute('data-mode');
+ startGame(mode);
+ });
+ });
+
+ // Prevent scrolling on mobile
+ document.addEventListener('touchmove', function(e) {
+ if (gameActive) {
+ e.preventDefault();
+ }
+ }, { passive: false });
+
+ // Prevent zooming on mobile
+ document.addEventListener('gesturestart', function(e) {
+ e.preventDefault();
+ });
+
+ // Prevent context menu on long press
+ document.addEventListener('contextmenu', function(e) {
+ e.preventDefault();
+ });
+
+ // Load game data on start
+ loadGameData();
diff --git a/projects/pianotiles/styles.css b/projects/pianotiles/styles.css
new file mode 100644
index 0000000..0e26991
--- /dev/null
+++ b/projects/pianotiles/styles.css
@@ -0,0 +1,633 @@
+
+ :root {
+ --bg-color: #f5f5f5;
+ --tile-color: #333;
+ --tile-active-color: #4CAF50;
+ --text-color: #333;
+ --game-bg: #fff;
+ --button-bg: #4CAF50;
+ --button-text: white;
+ --score-bg: rgba(255, 255, 255, 0.9);
+ --game-over-bg: rgba(0, 0, 0, 0.8);
+ --primary-color: #2196F3;
+ --accent-color: #FFC107;
+ }
+
+ [data-theme="dark"] {
+ --bg-color: #121212;
+ --tile-color: #e0e0e0;
+ --tile-active-color: #8BC34A;
+ --text-color: #f5f5f5;
+ --game-bg: #1e1e1e;
+ --button-bg: #8BC34A;
+ --button-text: #121212;
+ --score-bg: rgba(30, 30, 30, 0.9);
+ --game-over-bg: rgba(0, 0, 0, 0.9);
+ }
+
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ -webkit-tap-highlight-color: transparent;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ user-select: none;
+ }
+
+ body {
+ font-family: 'Arial', sans-serif;
+ background-color: var(--bg-color);
+ color: var(--text-color);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ min-height: 100vh;
+ transition: background-color 0.3s, color 0.3s;
+ overflow: hidden;
+ position: relative;
+ touch-action: manipulation;
+ }
+
+ header {
+ position: absolute;
+ top: 0;
+ width: 100%;
+ padding: 1rem;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 10;
+ }
+
+ .stats-button {
+ background: var(--score-bg);
+ border: none;
+ cursor: pointer;
+ font-size: 1.5rem;
+ color: var(--text-color);
+ padding: 0.5rem;
+ transition: transform 0.2s, opacity 0.2s;
+ min-width: 44px;
+ min-height: 44px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 50%;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+ position: absolute;
+ top: 1rem;
+ left: 1rem;
+ z-index: 100;
+ }
+
+ .stats-button:hover, .stats-button:active {
+ transform: scale(1.1);
+ opacity: 0.8;
+ }
+
+ main {
+ width: 100%;
+ max-width: 400px;
+ height: 100vh;
+ max-height: 600px;
+ position: relative;
+ overflow: hidden;
+ border-radius: 10px;
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
+ }
+
+ #game-container {
+ width: 100%;
+ height: 100%;
+ background-color: var(--game-bg);
+ position: relative;
+ overflow: hidden;
+ }
+
+ #game-area {
+ width: 100%;
+ height: 100%;
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ }
+
+ .tile-row {
+ display: flex;
+ width: 100%;
+ height: 25vh;
+ position: absolute;
+ }
+
+ .tile {
+ width: 25%;
+ height: 100%;
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ cursor: pointer;
+ transition: background-color 0.15s ease, transform 0.1s ease;
+ position: relative;
+ overflow: hidden;
+ -webkit-tap-highlight-color: transparent;
+ }
+
+ .tile.active {
+ background-color: var(--tile-color);
+ transform: scale(1);
+ box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.2);
+ }
+
+ .tile.active:hover {
+ background-color: #555;
+ transform: scale(0.98);
+ }
+
+ .tile.active:active, .tile.active.clicked {
+ background-color: var(--tile-active-color);
+ transform: scale(0.95);
+ box-shadow: 0 0 30px rgba(76, 175, 80, 0.6);
+ }
+
+ .tile.missed {
+ background-color: #F44336;
+ animation: shake 0.3s ease-in-out;
+ }
+
+ @keyframes shake {
+ 0%, 100% { transform: translateX(0); }
+ 25% { transform: translateX(-5px); }
+ 75% { transform: translateX(5px); }
+ }
+
+ /* Improved Score Display */
+ .game-ui {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ padding: 1rem;
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ z-index: 5;
+ pointer-events: none;
+ }
+
+ .score-container {
+ background: linear-gradient(135deg, var(--score-bg), rgba(255, 255, 255, 0.95));
+ padding: 12px 20px;
+ border-radius: 25px;
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ min-width: 120px;
+ backdrop-filter: blur(10px);
+ border: 1px solid rgba(255, 255, 255, 0.3);
+ }
+
+ .score-label {
+ font-size: 0.8rem;
+ opacity: 0.7;
+ margin-bottom: 2px;
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ }
+
+ .score-value {
+ font-size: 1.8rem;
+ font-weight: bold;
+ color: var(--primary-color);
+ line-height: 1;
+ }
+
+ .high-score-container {
+ background: linear-gradient(135deg, var(--accent-color), #FFD54F);
+ padding: 12px 20px;
+ border-radius: 25px;
+ box-shadow: 0 4px 15px rgba(255, 193, 7, 0.3);
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+ min-width: 120px;
+ backdrop-filter: blur(10px);
+ border: 1px solid rgba(255, 255, 255, 0.3);
+ }
+
+ .high-score-label {
+ font-size: 0.8rem;
+ opacity: 0.9;
+ margin-bottom: 2px;
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ color: #333;
+ }
+
+ .high-score-value {
+ font-size: 1.4rem;
+ font-weight: bold;
+ color: #333;
+ line-height: 1;
+ }
+
+ /* Combo Display */
+ .combo-display {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ font-size: 3rem;
+ font-weight: bold;
+ color: var(--accent-color);
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
+ opacity: 0;
+ pointer-events: none;
+ z-index: 20;
+ }
+
+ .combo-display.show {
+ animation: comboPopup 0.8s ease-out;
+ }
+
+ @keyframes comboPopup {
+ 0% {
+ opacity: 0;
+ transform: translate(-50%, -50%) scale(0.5);
+ }
+ 50% {
+ opacity: 1;
+ transform: translate(-50%, -50%) scale(1.2);
+ }
+ 100% {
+ opacity: 0;
+ transform: translate(-50%, -50%) scale(1);
+ }
+ }
+
+ /* Speed Indicator */
+ .speed-indicator {
+ position: absolute;
+ bottom: 20px;
+ left: 50%;
+ transform: translateX(-50%);
+ background: var(--score-bg);
+ padding: 8px 16px;
+ border-radius: 20px;
+ font-size: 0.9rem;
+ font-weight: bold;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ backdrop-filter: blur(10px);
+ }
+
+ .speed-bar {
+ width: 60px;
+ height: 6px;
+ background: rgba(0, 0, 0, 0.2);
+ border-radius: 3px;
+ overflow: hidden;
+ }
+
+ .speed-fill {
+ height: 100%;
+ background: linear-gradient(90deg, #4CAF50, #FFC107, #F44336);
+ width: 10%;
+ transition: width 0.3s ease;
+ }
+
+ /* Improved Pause Button - Moved to Bottom Left */
+ #pause-button {
+ position: absolute;
+ bottom: 20px;
+ left: 20px;
+ background: linear-gradient(135deg, #FF5722, #F44336);
+ border: none;
+ width: 50px;
+ height: 50px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ z-index: 15;
+ font-size: 1.3rem;
+ transition: transform 0.2s, box-shadow 0.2s, background 0.2s;
+ box-shadow: 0 4px 15px rgba(244, 67, 54, 0.3);
+ color: white;
+ }
+
+ #pause-button:hover {
+ transform: scale(1.1);
+ box-shadow: 0 6px 20px rgba(244, 67, 54, 0.4);
+ background: linear-gradient(135deg, #F44336, #E91E63);
+ }
+
+ #pause-button:active {
+ transform: scale(0.95);
+ box-shadow: 0 2px 8px rgba(244, 67, 54, 0.3);
+ }
+
+ /* Enhanced Particles */
+ .particle {
+ position: absolute;
+ width: 12px;
+ height: 12px;
+ background: radial-gradient(circle, var(--tile-active-color), rgba(76, 175, 80, 0.6));
+ border-radius: 50%;
+ pointer-events: none;
+ z-index: 100;
+ box-shadow: 0 0 10px rgba(76, 175, 80, 0.8);
+ }
+
+ @keyframes particle-animation {
+ 0% {
+ transform: translate(0, 0) scale(1);
+ opacity: 1;
+ }
+ 100% {
+ transform: translate(var(--tx), var(--ty)) scale(0);
+ opacity: 0;
+ }
+ }
+
+ /* Score Animation */
+ .score-popup {
+ position: absolute;
+ font-size: 1.5rem;
+ font-weight: bold;
+ color: var(--tile-active-color);
+ pointer-events: none;
+ z-index: 50;
+ animation: scoreFloat 1s ease-out forwards;
+ }
+
+ @keyframes scoreFloat {
+ 0% {
+ opacity: 1;
+ transform: translateY(0) scale(1);
+ }
+ 100% {
+ opacity: 0;
+ transform: translateY(-50px) scale(1.5);
+ }
+ }
+
+ #start-screen, #game-over-screen, #mode-selection, #stats-screen, #pause-screen {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ background-color: var(--game-over-bg);
+ color: white;
+ z-index: 10;
+ padding: 2rem;
+ overflow-y: auto;
+ }
+
+ h1 {
+ font-size: 2.5rem;
+ margin-bottom: 1rem;
+ text-align: center;
+ }
+
+ #game-over-screen h2 {
+ font-size: 2rem;
+ margin-bottom: 1rem;
+ }
+
+ #final-score {
+ font-size: 1.5rem;
+ margin-bottom: 2rem;
+ }
+
+ #highest-score-display {
+ font-size: 1.2rem;
+ margin-bottom: 2rem;
+ color: #FFC107;
+ font-weight: bold;
+ }
+
+ .game-modes {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ width: 100%;
+ max-width: 300px;
+ margin-bottom: 2rem;
+ }
+
+ .mode-button {
+ background-color: var(--button-bg);
+ color: var(--button-text);
+ border: none;
+ padding: 14px 24px;
+ font-size: 1rem;
+ border-radius: 30px;
+ cursor: pointer;
+ transition: transform 0.2s, box-shadow 0.2s, background-color 0.2s;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ min-height: 48px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
+ position: relative;
+ overflow: hidden;
+ }
+
+ .mode-button::before {
+ content: '';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 0;
+ height: 0;
+ border-radius: 50%;
+ background-color: rgba(255, 255, 255, 0.3);
+ transform: translate(-50%, -50%);
+ transition: width 0.3s, height 0.3s;
+ }
+
+ .mode-button:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
+ background-color: var(--button-bg);
+ }
+
+ .mode-button:active {
+ transform: translateY(0);
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
+ }
+
+ .mode-button:active::before {
+ width: 300px;
+ height: 300px;
+ }
+
+ .hidden {
+ display: none !important;
+ }
+
+ footer {
+ position: absolute;
+ bottom: 10px;
+ text-align: center;
+ font-size: 0.8rem;
+ opacity: 0.7;
+ pointer-events: none;
+ }
+
+ .stats-container {
+ background-color: rgba(255, 255, 255, 0.1);
+ border-radius: 10px;
+ padding: 1.5rem;
+ width: 100%;
+ max-width: 350px;
+ margin-bottom: 1rem;
+ }
+
+ .stat-item {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 0.8rem;
+ font-size: 1rem;
+ }
+
+ .stat-label {
+ opacity: 0.8;
+ }
+
+ .stat-value {
+ font-weight: bold;
+ }
+
+ .score-history {
+ background-color: rgba(255, 255, 255, 0.1);
+ border-radius: 10px;
+ padding: 1rem;
+ width: 100%;
+ max-width: 350px;
+ max-height: 200px;
+ overflow-y: auto;
+ }
+
+ .score-history h3 {
+ margin-bottom: 0.5rem;
+ text-align: center;
+ }
+
+ .history-item {
+ display: flex;
+ justify-content: space-between;
+ padding: 0.5rem 0;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+ font-size: 0.9rem;
+ }
+
+ .history-item:last-child {
+ border-bottom: none;
+ }
+
+ .clear-data-button {
+ background-color: #F44336;
+ color: white;
+ border: none;
+ padding: 10px 16px;
+ border-radius: 20px;
+ cursor: pointer;
+ font-size: 0.9rem;
+ margin-top: 1rem;
+ transition: background-color 0.3s, transform 0.2s;
+ min-height: 44px;
+ }
+
+ .clear-data-button:hover {
+ background-color: #D32F2F;
+ transform: translateY(-1px);
+ }
+
+ .clear-data-button:active {
+ transform: translateY(0);
+ }
+
+ .theme-toggle {
+ background: var(--score-bg);
+ border: none;
+ cursor: pointer;
+ font-size: 1.5rem;
+ color: var(--text-color);
+ padding: 0.5rem;
+ transition: transform 0.2s, opacity 0.2s;
+ min-width: 44px;
+ min-height: 44px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 50%;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+ margin-top: 1rem;
+ }
+
+ .theme-toggle:hover, .theme-toggle:active {
+ transform: scale(1.1);
+ opacity: 0.8;
+ }
+
+ @media (max-width: 480px) {
+ main {
+ max-width: 100%;
+ max-height: 100vh;
+ border-radius: 0;
+ }
+
+ h1 {
+ font-size: 2rem;
+ }
+
+ .game-modes {
+ max-width: 250px;
+ }
+
+ header {
+ padding: 0.5rem;
+ padding-top: 1rem;
+ }
+
+ #pause-button {
+ bottom: 1rem;
+ left: 1rem;
+ z-index: 15;
+ }
+
+ .score-container, .high-score-container {
+ min-width: 100px;
+ padding: 10px 15px;
+ }
+
+ .score-value {
+ font-size: 1.5rem;
+ }
+
+ .high-score-value {
+ font-size: 1.2rem;
+ }
+
+ .speed-indicator {
+ bottom: 80px; /* Adjusted to avoid overlap with pause button */
+ }
+ }
+
+ /* Touch feedback improvements */
+ @media (hover: none) {
+ .tile.active:hover {
+ background-color: var(--tile-color);
+ transform: scale(1);
+ }
+ }