From 642f568ac6db7996eeb477c1b865b4adb714c54c Mon Sep 17 00:00:00 2001 From: truetype Date: Mon, 15 Jun 2026 18:40:07 +0200 Subject: [PATCH] Initial commit: CatDoku puzzle game with leaderboard --- .gitignore | 60 +++ README.md | 184 +++++++ WhatsApp Image 2026-06-15 at 11.41.31.jpeg | Bin 0 -> 71833 bytes docs/api.md | 447 ++++++++++++++++ docs/architecture.md | 216 ++++++++ docs/game-rules.md | 232 ++++++++ docs/generator.md | 299 +++++++++++ game.js | 592 +++++++++++++++++++++ index.html | 112 ++++ leaderboard.html | 404 ++++++++++++++ style.css | 442 +++++++++++++++ 11 files changed, 2988 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 WhatsApp Image 2026-06-15 at 11.41.31.jpeg create mode 100644 docs/api.md create mode 100644 docs/architecture.md create mode 100644 docs/game-rules.md create mode 100644 docs/generator.md create mode 100644 game.js create mode 100644 index.html create mode 100644 leaderboard.html create mode 100644 style.css diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b04e5ee --- /dev/null +++ b/.gitignore @@ -0,0 +1,60 @@ +# Dependencies +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Production +/dist +/build + +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Coverage directory +/coverage + +# Nyc for coverage +/.nyc_output + +# Environment +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db +desktop.ini + +# Browser +*.local + +# Testing +/test-results +/junit.xml + +# Misc +.cache +.temp +tmp/ +temp/ + +# Documentation generated +docs/api-generated/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..86c835a --- /dev/null +++ b/README.md @@ -0,0 +1,184 @@ +# CatDoku - Puzzle dei Gatti + +![CatDoku](https://img.shields.io/badge/version-1.0.0-blue) +![License](https://img.shields.io/badge/license-MIT-green) +![Platform](https://img.shields.io/badge/platform-Web-orange) + +## 📖 Descrizione + +**CatDoku** è un puzzle game ispirato al classico Sudoku, ma con una meccanica unica basata sul posizionamento di gatti su una griglia colorata. Il gioco combina logica, strategia e divertimento in un'esperienza web moderna e responsive. + +### 🎯 Obiettivo del Gioco + +Posizionare un gatto in ogni riga, colonna e regione colorata della griglia, rispettando il vincolo che nessun gatto può essere adiacente (in qualsiasi direzione, incluse le diagonali) ad un altro gatto. + +## ✨ Caratteristiche Principali + +### 🎮 Gameplay +- **Griglie dinamiche**: Supporto per griglie da 6×6 fino a 12×12 +- **Generazione procedurale**: Ogni partita genera un puzzle unico e sempre risolvibile +- **Regioni colorate contigue**: I colori formano aree connesse per una migliore esperienza visiva +- **Sistema di errori**: 3 tentativi massimi per livello con feedback visivo immediato +- **Suggerimenti**: 3 hint gratuiti per livello con sistema premium per suggerimenti aggiuntivi + +### Interfaccia +- **Design moderno**: UI pulita e intuitiva con animazioni fluide +- **Responsive**: Giocabile su desktop, tablet e mobile +- **Interazione touch**: Supporto completo per dispositivi touch + - Click singolo: posiziona/rimuove X + - Pressione prolungata (0.5s): posiziona/rimuove gatto +- **Feedback visivo**: Animazioni per errori, posizionamenti e vittorie + +### Sistema Player +- **Alias personalizzati**: Ogni giocatore può inserire il proprio nome/alias +- **Tracking tempo**: Timer per ogni livello con formato mm:ss +- **Salvataggio locale**: Progressi salvati in localStorage +- **Classifica**: Leaderboard completa con filtri e statistiche + +### 🏆 Leaderboard +- **Statistiche globali**: Partite giocate, giocatori unici, miglior tempo, miglior punteggio +- **Filtri avanzati**: Per giocatore, livello e dimensione griglia +- **Medaglie**: Prime 3 posizioni con medaglie d'oro, argento e bronzo +- **Cronologia**: Data e ora di ogni partita completata + +### 💎 Sistema Premium +- **Popup premium**: Attivato quando si esauriscono i suggerimenti +- **Countdown**: 5 secondi di attesa prima di poter ottenere un hint aggiuntivo +- **Design accattivante**: UI dorata con animazioni + +## 🚀 Installazione e Avvio + +### Requisiti +- Browser moderno con supporto JavaScript ES6+ +- Nessun server richiesto (funziona con file:// protocol) + +### Avvio Rapido + +1. **Clona il repository**: + ```bash + git clone http://192.168.0.183:8085/truetype/catdoku.git + cd catdoku + ``` + +2. **Apri il gioco**: + ```bash + # Metodo 1: Apri direttamente nel browser + open index.html + + # Metodo 2: Usa un server HTTP locale (opzionale) + python3 -m http.server 8000 + # Poi visita http://localhost:8000 + ``` + +3. **Inizia a giocare**: + - Inserisci il tuo nome/alias + - Seleziona la dimensione della griglia (6×6 fino a 12×12) + - Clicca "Nuova Partita" + +## 🎮 Come Giocare + +### Controlli + +| Azione | Mouse | Touch | +|--------|-------|-------| +| Posiziona/Rimuovi X | Click singolo | Tap singolo | +| Posiziona/Rimuovi Gatto | Pressione 0.5s | Pressione 0.5s | +| Cancella tutte le X | Pulsante gomma | Pulsante gomma | +| Suggerimento | Pulsante lampadina | Pulsante lampadina | + +### Regole del Gioco + +1. **Un gatto per riga**: Ogni riga deve contenere esattamente un gatto +2. **Un gatto per colonna**: Ogni colonna deve contenere esattamente un gatto +3. **Un gatto per colore**: Ogni regione colorata deve contenere esattamente un gatto +4. **Nessuna adiacenza**: I gatti non possono essere adiacenti (incluse diagonali) + +### Sistema di Punteggio + +Il punteggio viene calcolato in base a: +- **Errori rimanenti**: 10 punti per ogni errore non commesso +- **Suggerimenti rimanenti**: 5 punti per ogni hint non utilizzato +- **Tempo**: Non influisce sul punteggio ma viene tracciato per la leaderboard + +## 🛠️ Sviluppo + +### Struttura del Progetto + +``` +catdoku/ +├── index.html # Pagina principale del gioco +├── style.css # Stili e layout responsive +── game.js # Logica di gioco e generatore di puzzle +├── leaderboard.html # Pagina classifica +├── README.md # Documentazione principale +└── docs/ # Documentazione tecnica + ├── architecture.md # Architettura del sistema + ├── game-rules.md # Regole del gioco dettagliate + ├── generator.md # Algoritmo di generazione puzzle + └── api.md # API e struttura dati +``` + +### Tecnologie Utilizzate + +- **HTML5**: Struttura semantica +- **CSS3**: Stili moderni con Grid, Flexbox, animazioni +- **JavaScript ES6+**: Logica di gioco, generatore procedurale +- **localStorage API**: Persistenza dati locale + +### Architettura + +Il progetto segue un'architettura **MVC semplificata**: + +- **Model**: Stato del gioco (griglia, soluzione, punteggio, timer) +- **View**: Rendering DOM e gestione eventi UI +- **Controller**: Logica di gioco, validazione, generazione puzzle + +### Generatore di Puzzle + +Il generatore utilizza un algoritmo in 3 fasi: + +1. **Backtracking randomizzato**: Posiziona N gatti validi sulla griglia +2. **Flood fill simultaneo**: Espande regioni colorate contigue da ogni gatto +3. **Validazione**: Garantisce puzzle sempre risolvibile con soluzione unica + +## 📊 Roadmap Futura + +- [ ] Livelli predefiniti con difficoltà crescente +- [ ] Sistema di achievement/badge +- [ ] Modalità sfida a tempo +- [ ] Condivisione punteggi sui social +- [ ] Tema scuro +- [ ] Suoni ed effetti audio +- [ ] Multiplayer locale (2 giocatori) +- [ ] Esportazione/importazione record + +## 🤝 Contribuire + +Le contribuzioni sono benvenute! Per contribuire: + +1. Fork il progetto +2. Crea un branch per la tua feature (`git checkout -b feature/AmazingFeature`) +3. Commit le tue modifiche (`git commit -m 'Add some AmazingFeature'`) +4. Push sul branch (`git push origin feature/AmazingFeature`) +5. Apri una Pull Request + +## License + +Questo progetto è distribuito sotto licenza MIT. Vedi il file `LICENSE` per maggiori informazioni. + +## 👤 Autore + +**truetype** + +- Server Gitea: http://192.168.0.183:8085 +- Repository: http://192.168.0.183:8085/truetype/catdoku + +## 🙏 Ringraziamenti + +- Ispirato al gioco "Clash of Critters" +- Icone e emoji standard Unicode +- Font di sistema per massima compatibilità + +--- + +**Buon divertimento con CatDoku! 🐱** diff --git a/WhatsApp Image 2026-06-15 at 11.41.31.jpeg b/WhatsApp Image 2026-06-15 at 11.41.31.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..f39ed0253f42f6d98d5cd8859b4e8322f1ede4d7 GIT binary patch literal 71833 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 literal 0 HcmV?d00001 diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 0000000..c30b4a6 --- /dev/null +++ b/docs/api.md @@ -0,0 +1,447 @@ +# API e Struttura Dati + +## Panoramica + +Questo documento descrive la struttura dei dati, le interfacce e i moduli del gioco CatDoku. Essendo un'applicazione client-side, non ci sono API REST, ma il documento descrive le interfacce interne e la struttura di storage. + +## Struttura Dati Principali + +### Game State + +Oggetto principale che contiene tutto lo stato del gioco: + +```typescript +interface GameState { + size: number; // Dimensione griglia (6-12) + grid: Cell[][]; // Griglia 2D delle celle + solution: Position[]; // Array delle posizioni soluzione + errors: number; // Errori rimanenti (0-3) + maxErrors: number; // Errori massimi (3) + catsPlaced: number; // Numero gatti piazzati + totalCats: number; // Numero totale gatti (= size) + level: number; // Livello corrente (1+) + score: number; // Punteggio totale accumulato + hints: number; // Suggerimenti rimanenti (0-3) + gameOver: boolean; // Flag game over + won: boolean; // Flag vittoria livello + playerName: string; // Nome/alias del giocatore + levelStartTime: number; // Timestamp inizio livello (ms) + levelTime: number; // Tempo trascorso (secondi) + sessionRecords: LevelRecord[]; // Record della sessione corrente +} +``` + +### Cell + +Rappresenta una singola cella della griglia: + +```typescript +interface Cell { + color: number; // Indice colore (0-11) + hasCat: boolean; // Contiene un gatto? + hasX: boolean; // Contiene una X (marcatura giocatore)? + isSolution: boolean; // È parte della soluzione? +} +``` + +### Position + +Coordinate di una cella: + +```typescript +interface Position { + row: number; // Riga (0-indexed) + col: number; // Colonna (0-indexed) +} +``` + +### LevelRecord + +Record di un livello completato: + +```typescript +interface LevelRecord { + playerName: string; // Nome giocatore + level: number; // Livello completato + gridSize: number; // Dimensione griglia usata + time: number; // Tempo impiegato (secondi) + score: number; // Punteggio ottenuto + errors: number; // Errori commessi + hintsUsed: number; // Suggerimenti utilizzati + date: string; // Data ISO 8601 +} +``` + +## Interfacce dei Moduli + +### Generator Module + +```typescript +interface GeneratorModule { + generatePuzzle(size: number): Puzzle; + generateSolution(size: number): Position[]; + generateColors(size: number, solution: Position[]): number[][]; +} + +interface Puzzle { + grid: Cell[][]; + solution: Position[]; +} +``` + +#### generatePuzzle(size) +- **Input**: `size` - Dimensione griglia (6-12) +- **Output**: Oggetto `Puzzle` con griglia e soluzione +- **Effetti collaterali**: Nessuno +- **Eccezioni**: Nessuna (ha fallback deterministico) + +#### generateSolution(size) +- **Input**: `size` - Dimensione griglia +- **Output**: Array di `Position` (lunghezza = size) +- **Garantisce**: Soluzione valida (rispetta tutte le regole) +- **Eccezioni**: Nessuna + +#### generateColors(size, solution) +- **Input**: + - `size` - Dimensione griglia + - `solution` - Array di posizioni soluzione +- **Output**: Griglia 2D di indici colore +- **Garantisce**: Regioni contigue e bilanciate +- **Eccezioni**: Nessuna + +### Validation Module + +```typescript +interface ValidationModule { + isValidPlacement(row: number, col: number): boolean; + getCatCountInRow(row: number): number; + getCatCountInCol(col: number): number; + getCatCountInColor(color: number): number; + isCatAdjacent(row: number, col: number): boolean; +} +``` + +#### isValidPlacement(row, col) +- **Input**: Coordinate della cella +- **Output**: `true` se il posizionamento è valido +- **Controlla**: + 1. Cella non ha X + 2. Nessun gatto nella riga + 3. Nessun gatto nella colonna + 4. Nessun gatto nello stesso colore + 5. Nessun gatto adiacente (8 direzioni) + +#### getCatCountInRow(row) +- **Input**: Numero riga +- **Output**: Numero di gatti nella riga (0-1) + +#### getCatCountInCol(col) +- **Input**: Numero colonna +- **Output**: Numero di gatti nella colonna (0-1) + +#### getCatCountInColor(color) +- **Input**: Indice colore +- **Output**: Numero di gatti nel colore (0-1) + +#### isCatAdjacent(row, col) +- **Input**: Coordinate della cella +- **Output**: `true` se c'è un gatto adiacente (8 direzioni) + +### Game Logic Module + +```typescript +interface GameLogicModule { + initGame(): void; + placeCat(row: number, col: number): void; + toggleX(row: number, col: number): void; + useHint(): void; + startTimer(): void; + stopTimer(): void; + saveLevelRecord(): void; +} +``` + +#### initGame() +- **Input**: Nessuno (usa `state.size` e `state.playerName`) +- **Output**: Nessuno +- **Effetti**: + - Resetta stato livello + - Genera nuovo puzzle + - Avvia timer + - Renderizza griglia + +#### placeCat(row, col) +- **Input**: Coordinate della cella +- **Output**: Nessuno +- **Effetti**: + - Se gatto già presente: lo rimuove + - Se posizionamento valido: piazza gatto + - Se posizionamento invalido: decrementa errori, flash errore + - Se errori = 0: game over + - Se tutti i gatti piazzati: vittoria + +#### toggleX(row, col) +- **Input**: Coordinate della cella +- **Output**: Nessuno +- **Effetti**: + - Se cella ha gatto: nessuna azione + - Altrimenti: toggle stato X + +#### useHint() +- **Input**: Nessuno +- **Output**: Nessuno +- **Effetti**: + - Se hints = 0: mostra popup premium + - Altrimenti: piazza gatto soluzione, decrementa hints + +#### startTimer() +- **Input**: Nessuno +- **Output**: Nessuno +- **Effetti**: Avvia setInterval per aggiornamento tempo + +#### stopTimer() +- **Input**: Nessuno +- **Output**: Nessuno +- **Effetti**: Ferma timer + +#### saveLevelRecord() +- **Input**: Nessuno (usa stato corrente) +- **Output**: Nessuno +- **Effetti**: + - Crea record livello + - Salva in `state.sessionRecords` + - Salva in `localStorage` + +### UI Module + +```typescript +interface UIModule { + renderGrid(): void; + updateUI(): void; + updateTimeDisplay(): void; + showModal(title: string, message: string, btnText: string, callback: Function): void; + hideModal(): void; + showPremiumPopup(): void; + showNameInput(): void; + hideNameInput(): void; +} +``` + +#### renderGrid() +- **Input**: Nessuno (usa `state.grid`) +- **Output**: Nessuno +- **Effetti**: Ricostruisce DOM griglia con event listeners + +#### updateUI() +- **Input**: Nessuno (usa `state`) +- **Output**: Nessuno +- **Effetti**: Aggiorna tutti i contatori e indicatori UI + +#### showModal(title, message, btnText, callback) +- **Input**: Testo modal e callback +- **Output**: Nessuno +- **Effetti**: Mostra modal overlay + +#### hideModal() +- **Input**: Nessuno +- **Output**: Nessuno +- **Effetti**: Nasconde modal overlay + +#### showPremiumPopup() +- **Input**: Nessuno +- **Output**: Nessuno +- **Effetti**: Mostra popup premium con countdown 5s + +#### showNameInput() +- **Input**: Nessuno +- **Output**: Nessuno +- **Effetti**: Mostra modal input nome + +#### hideNameInput() +- **Input**: Nessuno +- **Output**: Nessuno +- **Effetti**: Nasconde modal input nome + +### Storage Module + +```typescript +interface StorageModule { + loadRecords(): LevelRecord[]; + saveRecords(records: LevelRecord[]): void; +} +``` + +#### loadRecords() +- **Input**: Nessuno +- **Output**: Array di `LevelRecord` +- **Source**: `localStorage` key `'catdoku_records'` + +#### saveRecords(records) +- **Input**: Array di `LevelRecord` +- **Output**: Nessuno +- **Destination**: `localStorage` key `'catdoku_records'` + +## Costanti + +### COLORS + +Array di colori per le regioni: + +```javascript +const COLORS = [ + '#6abf69', // Verde + '#4a90d9', // Blu + '#e8a838', // Arancione + '#c06dbf', // Viola + '#e06060', // Rosso + '#40b8c8', // Ciano + '#d4c830', // Giallo + '#8b6b4a', // Marrone + '#7088a0', // Grigio-blu + '#d04080', // Rosa + '#5060b0', // Blu scuro + '#30a080' // Verde acqua +]; +``` + +### LONG_PRESS_MS + +Durata pressione per attivare gatto: + +```javascript +const LONG_PRESS_MS = 500; // millisecondi +``` + +### STORAGE_KEY + +Key per localStorage: + +```javascript +const STORAGE_KEY = 'catdoku_records'; +``` + +## Eventi UI + +### Grid Cell Events + +| Evento | Azione | Condizione | +|--------|--------|------------| +| `mousedown` | Avvia timer long press | Button 0 (sinistro) | +| `mouseup` | Toggle X o place cat | Se long press non attivato → X | +| `mouseleave` | Cancella timer | Sempre | +| `touchstart` | Avvia timer long press | Prevent default | +| `touchend` | Toggle X o place cat | Se long press non attivato → X | +| `touchcancel` | Cancella timer | Sempre | +| `contextmenu` | Prevent default | Sempre (no menu contestuale) | + +### Button Events + +| Button | Evento | Azione | +|--------|--------|--------| +| `btn-new-game` | click | Reset partita, mostra input nome | +| `btn-hint` | click | Usa suggerimento o mostra premium | +| `btn-eraser` | click | Cancella tutte le X | +| `btn-back` | click | Naviga a leaderboard.html | +| `name-submit-btn` | click | Conferma nome, inizia gioco | +| `premium-btn` | click | Chiudi popup, aggiungi hint | +| `modal-btn` | click | Chiudi modal, esegui callback | + +## LocalStorage Schema + +### Key: `catdoku_records` + +**Type**: JSON string + +**Structure**: Array di `LevelRecord` + +**Example**: +```json +[ + { + "playerName": "Mario", + "level": 1, + "gridSize": 8, + "time": 125, + "score": 35, + "errors": 1, + "hintsUsed": 2, + "date": "2026-06-15T18:30:00.000Z" + }, + { + "playerName": "Mario", + "level": 2, + "gridSize": 8, + "time": 98, + "score": 40, + "errors": 0, + "hintsUsed": 1, + "date": "2026-06-15T18:35:00.000Z" + } +] +``` + +**Limiti**: +- Dimensione massima: ~5MB (limite browser) +- Persistenza: Fino a cancellazione manuale o cache clear +- Scope: Per-browser, per-origin + +## Error Handling + +### Errori di Gioco + +Gestiti tramite decremento `state.errors` e flash visivo. + +### Errori di Sistema + +- **Generazione fallita**: Fallback a posizionamento deterministico +- **localStorage pieno**: Nessun handling specifico (raro per questo uso) +- **Input invalido**: Trim e maxlength su nome giocatore + +## Security Considerations + +### Input Sanitization + +- **Nome giocatore**: `trim()` + `maxlength="20"` nell'HTML +- **Nessun eval()**: Tutto il codice è statico +- **No dynamic code**: Nessun `Function()` o `setTimeout()` con stringhe + +### Data Validation + +- **Dimensione griglia**: Validata da ` + + + + + + + + + + + +

+ + + + + + + + + diff --git a/leaderboard.html b/leaderboard.html new file mode 100644 index 0000000..d136ed0 --- /dev/null +++ b/leaderboard.html @@ -0,0 +1,404 @@ + + + + + + CatDoku - Classifica + + + + +
+
+ ← Torna al Gioco + +
+

🏆 Classifica CatDoku

+

I migliori tempi e punteggi di tutti i giocatori

+
+ +
+ +
+
+ + +
+
+ + +
+
+ + +
+ +
+ +
+
+
+ + + + diff --git a/style.css b/style.css new file mode 100644 index 0000000..f2868bc --- /dev/null +++ b/style.css @@ -0,0 +1,442 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: #f5f0eb; + min-height: 100vh; + display: flex; + justify-content: center; + align-items: flex-start; + padding: 10px; + user-select: none; + -webkit-user-select: none; +} + +#app { + max-width: 600px; + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + gap: 12px; +} + +header { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + padding: 8px 0; +} + +.header-center { + display: flex; + gap: 30px; +} + +.stat { + display: flex; + flex-direction: column; + align-items: center; +} + +.stat-label { + font-size: 14px; + color: #8b7355; + font-weight: 500; +} + +.stat-value { + font-size: 28px; + font-weight: 700; + color: #5d4e37; +} + +.header-right { + display: flex; + align-items: center; + gap: 10px; +} + +.player-name { + font-size: 14px; + color: #8b7355; + font-weight: 600; + max-width: 100px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.icon-btn { + width: 40px; + height: 40px; + border-radius: 50%; + border: 2px solid #d4c5b0; + background: #fff; + font-size: 20px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + color: #8b7355; + transition: background 0.2s; +} + +.icon-btn:hover { + background: #f0e8dc; +} + +.info-bar { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + padding: 8px 16px; + background: #fff; + border-radius: 12px; + box-shadow: 0 2px 8px rgba(0,0,0,0.06); +} + +.progress { + display: flex; + align-items: center; + gap: 8px; + font-size: 18px; + font-weight: 600; + color: #5d4e37; +} + +.cat-icon { + font-size: 24px; +} + +.errors { + display: flex; + gap: 4px; + font-size: 22px; +} + +.heart { + transition: opacity 0.3s; +} + +.heart.lost { + opacity: 0.2; +} + +.rules-bar { + display: flex; + gap: 8px; + width: 100%; + flex-wrap: wrap; + justify-content: center; +} + +.rule { + background: #fff; + padding: 6px 14px; + border-radius: 20px; + font-size: 13px; + color: #8b7355; + box-shadow: 0 1px 4px rgba(0,0,0,0.05); + white-space: nowrap; +} + +.grid-container { + display: grid; + gap: 2px; + background: #d4c5b0; + padding: 3px; + border-radius: 12px; + box-shadow: 0 4px 16px rgba(0,0,0,0.1); + width: 100%; + max-width: 500px; + aspect-ratio: 1; +} + +.cell { + aspect-ratio: 1; + display: flex; + align-items: center; + justify-content: center; + font-size: 20px; + cursor: pointer; + transition: transform 0.1s, filter 0.1s; + position: relative; + border-radius: 3px; +} + +.cell:hover { + filter: brightness(1.1); +} + +.cell:active { + transform: scale(0.95); +} + +.cell .cat { + font-size: 22px; + pointer-events: none; + animation: catPlace 0.3s ease; +} + +.cell .x-mark { + font-size: 18px; + color: rgba(255,255,255,0.85); + font-weight: 700; + pointer-events: none; + text-shadow: 0 1px 2px rgba(0,0,0,0.3); +} + +.cell.error-flash { + animation: errorFlash 0.5s ease; +} + +@keyframes catPlace { + 0% { transform: scale(0); opacity: 0; } + 50% { transform: scale(1.3); } + 100% { transform: scale(1); opacity: 1; } +} + +@keyframes errorFlash { + 0%, 100% { filter: brightness(1); } + 25% { filter: brightness(2) hue-rotate(320deg); } + 50% { filter: brightness(0.8); } + 75% { filter: brightness(1.5) hue-rotate(320deg); } +} + +.controls { + display: flex; + gap: 20px; + align-items: center; +} + +.tool-btn { + width: 50px; + height: 50px; + border-radius: 50%; + border: none; + background: #fff; + box-shadow: 0 2px 8px rgba(0,0,0,0.1); + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + font-size: 22px; + transition: transform 0.2s, box-shadow 0.2s; + position: relative; +} + +.tool-btn:hover { + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(0,0,0,0.15); +} + +.tool-btn:active { + transform: translateY(0); +} + +.hint-count { + position: absolute; + top: -4px; + right: -4px; + background: #e74c3c; + color: #fff; + font-size: 11px; + font-weight: 700; + width: 20px; + height: 20px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; +} + +.hint-count.zero { + background: #d4af37; + animation: pulse 2s infinite; +} + +@keyframes pulse { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.1); } +} + +.size-selector { + display: flex; + align-items: center; + gap: 10px; + flex-wrap: wrap; + justify-content: center; + padding: 10px; + background: #fff; + border-radius: 12px; + box-shadow: 0 2px 8px rgba(0,0,0,0.06); +} + +.size-selector label { + font-size: 14px; + color: #8b7355; + font-weight: 500; +} + +.size-selector select { + padding: 6px 10px; + border-radius: 8px; + border: 2px solid #d4c5b0; + font-size: 14px; + color: #5d4e37; + background: #fff; + cursor: pointer; +} + +.size-selector button { + padding: 8px 18px; + border-radius: 8px; + border: none; + background: #5d4e37; + color: #fff; + font-size: 14px; + font-weight: 600; + cursor: pointer; + transition: background 0.2s; +} + +.size-selector button:hover { + background: #7a6750; +} + +.modal-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0,0,0,0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 100; +} + +.modal-overlay.hidden { + display: none; +} + +.modal { + background: #fff; + border-radius: 16px; + padding: 30px 40px; + text-align: center; + max-width: 350px; + width: 90%; + box-shadow: 0 8px 32px rgba(0,0,0,0.2); +} + +.modal h2 { + font-size: 24px; + color: #5d4e37; + margin-bottom: 12px; +} + +.modal p { + font-size: 16px; + color: #8b7355; + margin-bottom: 20px; +} + +.modal-btn { + padding: 10px 30px; + border-radius: 10px; + border: none; + background: #5d4e37; + color: #fff; + font-size: 16px; + font-weight: 600; + cursor: pointer; + transition: background 0.2s; +} + +.modal-btn:hover { + background: #7a6750; +} + +/* Premium Modal Styles */ +.premium-modal { + background: linear-gradient(135deg, #fff 0%, #f8f4ff 100%); + border: 3px solid #d4af37; + box-shadow: 0 8px 32px rgba(212, 175, 55, 0.3); +} + +.premium-icon { + font-size: 60px; + margin-bottom: 10px; +} + +.premium-text { + font-size: 14px; + color: #666; + font-style: italic; + margin: 10px 0; +} + +.premium-timer { + font-size: 16px; + color: #5d4e37; + margin: 15px 0; + font-weight: 600; +} + +.timer-value { + font-size: 24px; + color: #e74c3c; + font-weight: 700; +} + +.premium-btn { + background: #d4af37; + transition: background 0.3s, opacity 0.3s; +} + +.premium-btn:hover:not(:disabled) { + background: #b8941f; +} + +.premium-btn:disabled { + background: #ccc; + cursor: not-allowed; + opacity: 0.6; +} + +/* Name Input Modal Styles */ +.name-modal { + background: linear-gradient(135deg, #fff 0%, #f0f8ff 100%); + border: 3px solid #4a90d9; + box-shadow: 0 8px 32px rgba(74, 144, 217, 0.3); +} + +.name-input { + width: 100%; + padding: 12px 16px; + border: 2px solid #d4c5b0; + border-radius: 10px; + font-size: 18px; + text-align: center; + margin: 15px 0; + outline: none; + transition: border-color 0.2s; +} + +.name-input:focus { + border-color: #4a90d9; +} + +.name-modal h2 { + color: #4a90d9; + margin-bottom: 10px; +}