commit dc9985bbc84b29dd38acf9ad58504ab5e21a85fd Author: Nishita Date: Tue Sep 9 17:57:03 2025 +0000 Upload files to "/" Word Search Stories At Eduspire, we believe learning English should be fun, interactive, and creative. That’s why we developed Word Search Stories – a playful and educational game designed for students from grades 3 to 6. This game helps children enhance their vocabulary, spelling, reading comprehension, and pattern recognition while enjoying engaging, themed stories. In Word Search Stories, students first select their grade level and a theme, such as Farm Life, Animals, or Space Adventure. The game then presents a colorful and interactive letter grid where children must find hidden words related to the selected theme. Words can appear horizontally, vertically, or diagonally, making the game challenging yet fun. A real-time progress tracker shows how many words have been found, while the Hint button allows students to briefly highlight one of the remaining words, encouraging learning without frustration. Once all words are found, a short story related to the theme is unlocked. This story is presented in a playful pop-up animation, helping students connect the vocabulary they discovered with real language in context. The game is designed to be vibrant, visually appealing, and intuitive, featuring colorful cells, easy drag-and-select controls, and responsive layout that works on both desktop and touch devices. Tech Stack: HTML – structures the game, grid, buttons, and story popups. CSS – adds vibrant colors, animations, and kid-friendly design. JavaScript – handles word placement, grid logic, selection tracking, hints, and story reveal. Optional Enhancements: Three.js for 3D effects, Web Audio API for future sound and voice-over support. The game is fully iframe compatible, meaning it can easily be embedded into any website or digital learning platform. Its modular design separates structure (index.html), styles (style.css), and logic (script.js) for maintainability and easy collaboration. diff --git a/index.html b/index.html new file mode 100644 index 0000000..035d9fd --- /dev/null +++ b/index.html @@ -0,0 +1,104 @@ + + + + + + Story Word-Search — Learn English (Grades 3–6) + + + + + +
+ +
+

📚 Story Word-Search — Grades 3–6

+
+ +
+ + +
+ + +
+
+ + +
+
+ Words to find + 0 / 0 +
+
+ + +
+ + +
+ + +
+
+
Theme + +
+
Grid size + +
+
Sound + +
+
+
+
+ + +
+
+ Find the words in the grid! +
Tap and drag to select — works with mouse/touch.
+
+
+
+
+
+ + +
+ + + + + + + + diff --git a/script.js b/script.js new file mode 100644 index 0000000..419f891 --- /dev/null +++ b/script.js @@ -0,0 +1,221 @@ +/* ====================== + SCRIPT.JS + - Working Word Search Game with HINT button + ====================== */ + +/* ---------- Data: words & stories ---------- */ +const data = { + farm: { + 3: { + words: ["COW", "HEN", "BARN", "MILK", "EGGS"], + storyTitle: "Maya and the Friendly Cow", + story: "Maya went to the barn. She saw a cow and a hen. The hen gave eggs. Maya drank warm milk and smiled." + }, + 4: { + words: ["FARMER", "TRACTOR", "FIELD", "CORN", "SHEEP"], + storyTitle: "The Busy Farmer", + story: "The farmer drove the tractor to the field. The sheep grazed while the farmer planted corn. Everyone helped in the barn." + } + } +}; + +/* ---------- Global Variables ---------- */ +let gridSize = 14; +let grid = []; +let placements = []; +let wordsToFind = []; +let foundWords = new Set(); +let selecting = false; +let selectedCells = []; + +const gridEl = document.getElementById('grid'); +const wordListEl = document.getElementById('wordList'); +const progressEl = document.getElementById('progress'); +const overlay = document.getElementById('overlay'); +const storyText = document.getElementById('storyText'); +const storyTitle = document.getElementById('storyTitle'); + +/* ---------- Helper: random letter ---------- */ +function randLetter() { + const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + return letters[Math.floor(Math.random() * letters.length)]; +} + +/* ---------- Grid Setup ---------- */ +function makeEmptyGrid(size) { + grid = Array(size).fill(null).map(() => Array(size).fill("")); +} + +function placeWord(word, size) { + const dirs = [ + [1, 0], [0, 1], [1, 1], [-1, 1] + ]; + for (let tries = 0; tries < 200; tries++) { + const dir = dirs[Math.floor(Math.random() * dirs.length)]; + const row = Math.floor(Math.random() * size); + const col = Math.floor(Math.random() * size); + let r = row, c = col, ok = true; + for (let ch of word) { + if (r < 0 || r >= size || c < 0 || c >= size || (grid[r][c] && grid[r][c] !== ch)) { + ok = false; break; + } + r += dir[0]; c += dir[1]; + } + if (!ok) continue; + r = row; c = col; + for (let ch of word) { + grid[r][c] = ch; + r += dir[0]; c += dir[1]; + } + placements.push({ word, row, col, dir }); + return true; + } + return false; +} + +function fillRandom(size) { + for (let r = 0; r < size; r++) { + for (let c = 0; c < size; c++) { + if (!grid[r][c]) grid[r][c] = randLetter(); + } + } +} + +function renderGrid(size) { + gridEl.style.gridTemplateColumns = `repeat(${size}, 1fr)`; + gridEl.innerHTML = ""; + for (let r = 0; r < size; r++) { + for (let c = 0; c < size; c++) { + const cell = document.createElement("div"); + cell.className = "cell"; + cell.textContent = grid[r][c]; + cell.dataset.row = r; + cell.dataset.col = c; + gridEl.appendChild(cell); + } + } +} + +/* ---------- Word List UI ---------- */ +function updateWordListUI() { + wordListEl.innerHTML = ""; + wordsToFind.forEach(w => { + const el = document.createElement("div"); + el.className = "worditem"; + el.textContent = w; + if (foundWords.has(w)) el.classList.add("done"); + wordListEl.appendChild(el); + }); + progressEl.textContent = `${foundWords.size} / ${wordsToFind.length}`; +} + +/* ---------- Selection Handling ---------- */ +function attachSelectionHandlers() { + gridEl.addEventListener("mousedown", e => { + if (!e.target.classList.contains("cell")) return; + selecting = true; + selectedCells = [e.target]; + e.target.classList.add("sel"); + }); + gridEl.addEventListener("mouseover", e => { + if (!selecting || !e.target.classList.contains("cell")) return; + if (!selectedCells.includes(e.target)) { + selectedCells.push(e.target); + e.target.classList.add("sel"); + } + }); + document.addEventListener("mouseup", () => { + if (!selecting) return; + finalizeSelection(); + selecting = false; + }); +} + +function finalizeSelection() { + const letters = selectedCells.map(c => c.textContent).join(""); + const reverse = [...letters].reverse().join(""); + const match = wordsToFind.find(w => w === letters || w === reverse); + if (match && !foundWords.has(match)) { + foundWords.add(match); + selectedCells.forEach(c => c.classList.add("found")); + updateWordListUI(); + if (foundWords.size === wordsToFind.length) { + revealStory(); + } + } + selectedCells.forEach(c => c.classList.remove("sel")); + selectedCells = []; +} + +/* ---------- Story Popup ---------- */ +function revealStory() { + overlay.classList.add("show"); + storyTitle.textContent = currentStory.storyTitle; + storyText.textContent = currentStory.story; +} +function closeStory() { + overlay.classList.remove("show"); +} + +/* ---------- Hint Feature ---------- */ +function giveHint() { + // Get words that are not yet found + const remaining = wordsToFind.filter(w => !foundWords.has(w)); + if (remaining.length === 0) return; + const hintWord = remaining[Math.floor(Math.random() * remaining.length)]; + const placement = placements.find(p => p.word === hintWord); + if (!placement) return; + + // Highlight cells temporarily + let r = placement.row, c = placement.col; + const cells = []; + for (let ch of placement.word) { + const cell = [...gridEl.children].find( + el => parseInt(el.dataset.row) === r && parseInt(el.dataset.col) === c + ); + if (cell) { + cell.classList.add("sel"); + cells.push(cell); + } + r += placement.dir[0]; + c += placement.dir[1]; + } + + // Remove highlight after 1 second + setTimeout(() => { + cells.forEach(cell => cell.classList.remove("sel")); + }, 1000); +} + +/* ---------- Game Init ---------- */ +let currentStory; +function generate() { + gridSize = parseInt(document.getElementById("sizeSelect").value) || 14; + const grade = parseInt(document.getElementById("gradeSelect").value); + const theme = document.getElementById("themeSelect").value; + const storyObj = data[theme]?.[grade]; + if (!storyObj) { + alert("No story data for this grade & theme!"); + return; + } + currentStory = storyObj; + wordsToFind = storyObj.words; + foundWords.clear(); + placements = []; + + makeEmptyGrid(gridSize); + wordsToFind.forEach(w => placeWord(w, gridSize)); + fillRandom(gridSize); + renderGrid(gridSize); + updateWordListUI(); +} + +/* ---------- Button Events ---------- */ +document.getElementById('newBtn').addEventListener('click', generate); +document.getElementById('hintBtn').addEventListener('click', giveHint); +document.getElementById('closeStory').addEventListener('click', closeStory); +document.getElementById('againBtn').addEventListener('click', () => { closeStory(); generate(); }); + +/* ---------- Init ---------- */ +attachSelectionHandlers(); +generate(); diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..66b21d1 --- /dev/null +++ b/styles.css @@ -0,0 +1,1011 @@ +/* ====================== + STYLE.CSS - ULTIMATE KIDS ATTRACTION VERSION! 🎨✨ + - Maximum visual appeal, responsiveness, and attention-grabbing design + ====================== */ + +:root { + --bg-primary: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + --bg-secondary: linear-gradient(315deg, #ff9a9e 0%, #fecfef 50%, #fecfef 100%); + --card: linear-gradient(145deg, #ffffff 0%, #f8f9ff 100%); + --accent: linear-gradient(45deg, #ff6b6b, #ff8e53, #ffd93d); + --accent2: linear-gradient(45deg, #4ecdc4, #44a08d, #38d9a9); + --accent3: linear-gradient(45deg, #a8edea, #fed6e3, #d299c2); + --text: #2d3748; + --found: linear-gradient(45deg, #68d391, #38b2ac, #48bb78); + --grid-gap: min(8px, 1.5vw); + --primary-purple: #9f7aea; + --primary-pink: #ed64a6; + --primary-orange: #ed8936; + --primary-blue: #4299e1; + --primary-green: #48bb78; + --shadow-magical: 0 20px 40px -10px rgba(0, 0, 0, 0.15), 0 10px 20px -5px rgba(0, 0, 0, 0.1); + --border-radius: clamp(15px, 3vw, 30px); +} + +/* Magical animated background with floating elements */ +html, body { + height: 100%; + margin: 0; + font-family: 'Comic Sans MS', cursive, 'Bubblegum Sans', system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial; + background: var(--bg-primary); + background-attachment: fixed; + display: flex; + align-items: center; + justify-content: center; + padding: clamp(10px, 3vw, 25px); + position: relative; + overflow-x: hidden; + min-height: 100vh; +} + +/* Multiple layers of floating stickers for maximum appeal */ +html::before { + content: "🌟⭐🎈🎨🦄🌈✨🎯🎪🎭🚀🎮🎊🎉🔥💫🌸🦋🍭🎂"; + position: fixed; + top: -100px; + left: -100px; + right: -100px; + height: 120vh; + font-size: clamp(1.5rem, 4vw, 3rem); + opacity: 0.12; + animation: float-stickers 25s infinite linear; + pointer-events: none; + z-index: 1; + letter-spacing: clamp(2rem, 5vw, 4rem); + line-height: clamp(5rem, 10vw, 10rem); +} + +html::after { + content: "🎨🌟✨🎈🦄🌈🎯🎪⭐🎭🚀🎮🎊"; + position: fixed; + top: 50%; + left: -50px; + right: -50px; + height: 60vh; + font-size: clamp(1rem, 3vw, 2rem); + opacity: 0.08; + animation: float-reverse 30s infinite linear reverse; + pointer-events: none; + z-index: 1; + letter-spacing: clamp(3rem, 6vw, 5rem); + line-height: clamp(6rem, 12vw, 12rem); +} + +@keyframes float-stickers { + 0% { transform: translateY(120vh) rotate(0deg); } + 100% { transform: translateY(-200px) rotate(360deg); } +} + +@keyframes float-reverse { + 0% { transform: translateY(-200px) rotate(0deg) translateX(0); } + 100% { transform: translateY(120vh) rotate(-360deg) translateX(100px); } +} + +/* Pulsing rainbow border effect */ +body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(45deg, #ff0000, #ff8000, #ffff00, #80ff00, #00ff00, #00ff80, #00ffff, #0080ff, #0000ff, #8000ff, #ff00ff, #ff0080); + background-size: 400% 400%; + animation: rainbow-border 8s ease infinite; + z-index: 0; + opacity: 0.1; + pointer-events: none; +} + +@keyframes rainbow-border { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +/* APP LAYOUT - fully responsive and magical */ +.app { + width: 100%; + max-width: min(1200px, 95vw); + background: linear-gradient(145deg, #ffffff, #f7fafc); + border-radius: var(--border-radius); + box-shadow: var(--shadow-magical), 0 0 0 clamp(3px, 1vw, 6px) rgba(255, 255, 255, 0.8); + display: grid; + grid-template-columns: minmax(300px, 380px) 1fr; + gap: clamp(15px, 3vw, 30px); + padding: clamp(15px, 3vw, 30px); + position: relative; + z-index: 2; + border: clamp(3px, 1vw, 8px) solid transparent; + background-clip: padding-box; + animation: magical-entrance 1.5s cubic-bezier(0.68, -0.55, 0.265, 1.55), gentle-float 6s ease-in-out infinite; + min-height: min(600px, 80vh); +} + +@keyframes magical-entrance { + 0% { + transform: scale(0.8) rotate(-5deg) translateY(50px); + opacity: 0; + } + 50% { + transform: scale(1.05) rotate(2deg) translateY(-10px); + opacity: 0.8; + } + 100% { + transform: scale(1) rotate(0deg) translateY(0); + opacity: 1; + } +} + +@keyframes gentle-float { + 0%, 100% { transform: translateY(0px) scale(1); } + 33% { transform: translateY(-3px) scale(1.002); } + 66% { transform: translateY(2px) scale(0.998); } +} + +/* Glowing header with maximum appeal */ +header { + grid-column: 1/-1; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding: clamp(12px, 3vw, 20px); + background: linear-gradient(135deg, #667eea, #764ba2, #f093fb); + background-size: 300% 300%; + animation: gradient-shift 4s ease infinite; + border-radius: clamp(15px, 3vw, 25px); + color: white; + box-shadow: var(--shadow-magical), inset 0 1px 0 rgba(255,255,255,0.3); + position: relative; + overflow: hidden; + min-height: clamp(60px, 10vw, 80px); +} + +@keyframes gradient-shift { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +header::before { + content: "🎮🎯🌟✨🎈🎪🦄"; + position: absolute; + top: -15px; + right: -30px; + font-size: clamp(1rem, 3vw, 2rem); + opacity: 0.4; + animation: header-sparkle 3s ease-in-out infinite; + z-index: 1; +} + +@keyframes header-sparkle { + 0%, 100% { transform: rotate(0deg) scale(1) translateX(0); } + 25% { transform: rotate(90deg) scale(1.1) translateX(5px); } + 50% { transform: rotate(180deg) scale(1.2) translateX(-5px); } + 75% { transform: rotate(270deg) scale(1.1) translateX(5px); } +} + +h1 { + font-size: clamp(16px, 4vw, 28px); + margin: 0; + font-weight: 900; + display: flex; + flex-wrap: wrap; + gap: clamp(8px, 2vw, 15px); + align-items: center; + text-shadow: 3px 3px 6px rgba(0,0,0,0.3); + animation: title-bounce 2s ease-out; + position: relative; + z-index: 2; + line-height: 1.2; +} + +@keyframes title-bounce { + 0% { transform: translateY(-30px) scale(0.8); opacity: 0; } + 50% { transform: translateY(8px) scale(1.1); opacity: 0.9; } + 100% { transform: translateY(0) scale(1); opacity: 1; } +} + +.controls { + display: flex; + flex-wrap: wrap; + gap: clamp(8px, 2vw, 15px); + align-items: center; + margin-top: clamp(5px, 1vw, 0); +} + +/* Ultra-appealing buttons with maximum interaction feedback */ +.btn { + border: none; + padding: clamp(10px, 2.5vw, 16px) clamp(14px, 3vw, 22px); + border-radius: clamp(20px, 4vw, 30px); + background: var(--accent); + background-size: 300% 300%; + animation: button-gradient 3s ease infinite; + color: white; + font-weight: 800; + cursor: pointer; + font-size: clamp(12px, 2.5vw, 16px); + text-transform: uppercase; + letter-spacing: clamp(0.3px, 0.1vw, 1px); + box-shadow: 0 clamp(6px, 2vw, 12px) clamp(15px, 4vw, 25px) rgba(255,107,107,0.4); + transition: all 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55); + position: relative; + overflow: hidden; + text-shadow: 1px 1px 2px rgba(0,0,0,0.3); +} + +@keyframes button-gradient { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +.btn::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255,255,255,0.6), transparent); + transition: left 0.6s; +} + +.btn::after { + content: '✨'; + position: absolute; + top: -5px; + right: -5px; + font-size: clamp(8px, 1.5vw, 12px); + animation: button-sparkle 2s ease-in-out infinite; +} + +@keyframes button-sparkle { + 0%, 100% { transform: rotate(0deg) scale(1); opacity: 0.7; } + 50% { transform: rotate(180deg) scale(1.3); opacity: 1; } +} + +.btn:hover::before { + left: 100%; +} + +.btn:hover { + transform: translateY(clamp(-2px, -1vw, -5px)) scale(1.08); + box-shadow: 0 clamp(10px, 3vw, 18px) clamp(20px, 5vw, 35px) rgba(255,107,107,0.6); + filter: brightness(1.2); +} + +.btn:active { + transform: translateY(0) scale(1.05); + animation: button-press 0.2s ease-out; +} + +@keyframes button-press { + 0% { transform: scale(1.08); } + 50% { transform: scale(0.95); } + 100% { transform: scale(1.05); } +} + +.small { + padding: clamp(6px, 1.5vw, 10px) clamp(10px, 2vw, 16px); + border-radius: clamp(15px, 3vw, 25px); + background: var(--accent2); + background-size: 300% 300%; + animation: small-button-gradient 4s ease infinite; + color: white; + font-weight: 700; + cursor: pointer; + border: none; + font-size: clamp(11px, 2vw, 14px); + box-shadow: 0 clamp(4px, 1.5vw, 8px) clamp(10px, 3vw, 18px) rgba(78, 205, 196, 0.4); + transition: all 0.35s cubic-bezier(0.68, -0.55, 0.265, 1.55); + text-transform: uppercase; + letter-spacing: clamp(0.2px, 0.1vw, 0.5px); + position: relative; +} + +@keyframes small-button-gradient { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +.small::after { + content: '🎯'; + position: absolute; + top: -3px; + right: -3px; + font-size: clamp(6px, 1.2vw, 10px); + animation: small-button-icon 3s ease-in-out infinite; +} + +@keyframes small-button-icon { + 0%, 100% { transform: rotate(0deg); } + 50% { transform: rotate(360deg); } +} + +.small:hover { + transform: translateY(clamp(-1px, -0.5vw, -3px)) rotate(clamp(-1deg, -0.5deg, -3deg)) scale(1.05); + box-shadow: 0 clamp(6px, 2vw, 12px) clamp(15px, 4vw, 25px) rgba(78, 205, 196, 0.6); + filter: brightness(1.15); +} + +/* Magical panels with sticker decorations */ +.panel { + background: var(--card); + padding: clamp(12px, 3vw, 25px); + border-radius: var(--border-radius); + box-shadow: var(--shadow-magical); + border: clamp(2px, 0.5vw, 4px) solid #e2e8f0; + position: relative; + transition: all 0.4s ease; + overflow: visible; +} + +.panel:hover { + transform: translateY(clamp(-1px, -0.5vw, -3px)) scale(1.01); + box-shadow: 0 clamp(15px, 4vw, 25px) clamp(30px, 6vw, 50px) rgba(0,0,0,0.15); +} + +.panel::after { + content: "🎨"; + position: absolute; + top: clamp(-8px, -2vw, -15px); + right: clamp(-8px, -2vw, -15px); + font-size: clamp(1rem, 2.5vw, 2rem); + background: linear-gradient(45deg, #ffffff, #f0f8ff); + border-radius: 50%; + padding: clamp(4px, 1vw, 8px); + box-shadow: 0 clamp(3px, 1vw, 6px) clamp(8px, 2vw, 15px) rgba(0,0,0,0.2); + animation: panel-sticker 3s ease-in-out infinite; + border: clamp(1px, 0.2vw, 3px) solid #e2e8f0; +} + +@keyframes panel-sticker { + 0%, 100% { transform: rotate(-5deg) scale(1); } + 25% { transform: rotate(5deg) scale(1.1); } + 50% { transform: rotate(-3deg) scale(1.05); } + 75% { transform: rotate(3deg) scale(1.08); } +} + +.left { + display: flex; + flex-direction: column; + gap: clamp(12px, 3vw, 20px); + min-width: 0; +} + +/* Ultra-responsive colorful grid */ +.gridwrap { + display: flex; + flex-direction: column; + gap: clamp(8px, 2vw, 15px); + align-items: center; + padding: clamp(8px, 2vw, 15px); + border-radius: clamp(12px, 3vw, 20px); + background: linear-gradient(135deg, #ffecd2, #fcb69f, #ff9a9e); + background-size: 300% 300%; + animation: gridwrap-gradient 5s ease infinite; + position: relative; + overflow: hidden; +} + +@keyframes gridwrap-gradient { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +.gridwrap::before { + content: '🌈✨🎯'; + position: absolute; + top: clamp(5px, 1vw, 10px); + left: clamp(5px, 1vw, 10px); + font-size: clamp(0.8rem, 2vw, 1.2rem); + opacity: 0.6; + animation: gridwrap-decoration 4s ease-in-out infinite; +} + +@keyframes gridwrap-decoration { + 0%, 100% { transform: rotate(0deg) translateY(0); } + 50% { transform: rotate(10deg) translateY(-2px); } +} + +.grid { + display: grid; + touch-action: none; + user-select: none; + gap: var(--grid-gap); + padding: clamp(10px, 2vw, 20px); + border-radius: clamp(10px, 2vw, 18px); + background: rgba(255, 255, 255, 0.95); + box-shadow: inset 0 clamp(2px, 1vw, 6px) clamp(8px, 2vw, 15px) rgba(0,0,0,0.08); + backdrop-filter: blur(10px); + max-width: 100%; + overflow: hidden; +} + +.cell { + width: clamp(35px, 8vw, 55px); + height: clamp(35px, 8vw, 55px); + display: flex; + align-items: center; + justify-content: center; + border-radius: clamp(8px, 2vw, 15px); + font-weight: 900; + font-size: clamp(14px, 3.5vw, 24px); + color: var(--text); + background: linear-gradient(145deg, #ffffff, #f1f5f9); + box-shadow: 0 clamp(3px, 1vw, 6px) clamp(8px, 2vw, 15px) rgba(0,0,0,0.12), inset 0 1px 2px rgba(255,255,255,0.8); + cursor: pointer; + transition: all 0.25s cubic-bezier(0.68, -0.55, 0.265, 1.55); + border: clamp(1px, 0.3vw, 3px) solid transparent; + position: relative; + text-shadow: 1px 1px 2px rgba(0,0,0,0.1); +} + +.cell::before { + content: ''; + position: absolute; + inset: 0; + border-radius: inherit; + background: linear-gradient(45deg, transparent, rgba(255,255,255,0.3), transparent); + opacity: 0; + transition: opacity 0.3s; +} + +.cell:hover::before { + opacity: 1; +} + +.cell:hover { + transform: translateY(clamp(-2px, -1vw, -4px)) scale(1.08); + box-shadow: 0 clamp(6px, 2vw, 12px) clamp(15px, 4vw, 25px) rgba(0,0,0,0.2); + background: linear-gradient(145deg, #ffd1dc, #ffb6c1); + border-color: var(--primary-pink); + filter: brightness(1.1); +} + +.cell:active { + transform: translateY(0) scale(1.05); + animation: cell-press 0.2s ease-out; +} + +@keyframes cell-press { + 0% { transform: scale(1.08); } + 50% { transform: scale(0.95); } + 100% { transform: scale(1.05); } +} + +.cell.found { + background: var(--found); + background-size: 200% 200%; + animation: found-celebration 1s ease-out, found-gradient 3s ease infinite; + color: white; + border-color: #38b2ac; + box-shadow: 0 clamp(4px, 1.5vw, 8px) clamp(12px, 3vw, 20px) rgba(56, 178, 172, 0.5); + text-shadow: 2px 2px 4px rgba(0,0,0,0.3); +} + +@keyframes found-celebration { + 0% { transform: scale(1); } + 25% { transform: scale(1.25) rotate(10deg); } + 50% { transform: scale(1.3) rotate(-5deg); } + 75% { transform: scale(1.15) rotate(5deg); } + 100% { transform: scale(1) rotate(0deg); } +} + +@keyframes found-gradient { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +.cell.sel { + outline: none; + border: clamp(2px, 0.8vw, 4px) solid var(--primary-orange); + transform: translateY(clamp(-1px, -0.5vw, -3px)) scale(1.12); + background: linear-gradient(145deg, #fed7aa, #fdba74); + box-shadow: 0 clamp(6px, 2vw, 12px) clamp(15px, 4vw, 25px) rgba(237, 137, 54, 0.5); + animation: selection-pulse 0.4s ease-out; + z-index: 10; +} + +@keyframes selection-pulse { + 0% { transform: translateY(clamp(-1px, -0.5vw, -3px)) scale(1); } + 50% { transform: translateY(clamp(-3px, -1.5vw, -6px)) scale(1.18); } + 100% { transform: translateY(clamp(-1px, -0.5vw, -3px)) scale(1.12); } +} + +/* Ultra-colorful word list */ +.wordlist { + display: flex; + flex-direction: column; + gap: clamp(6px, 1.5vw, 10px); + max-height: clamp(250px, 40vh, 400px); + overflow-y: auto; + padding: clamp(3px, 1vw, 8px); + scrollbar-width: thin; + scrollbar-color: var(--primary-purple) transparent; +} + +.wordlist::-webkit-scrollbar { + width: clamp(4px, 1vw, 8px); +} + +.wordlist::-webkit-scrollbar-track { + background: rgba(0,0,0,0.05); + border-radius: 10px; +} + +.wordlist::-webkit-scrollbar-thumb { + background: var(--accent); + border-radius: 10px; +} + +.worditem { + padding: clamp(8px, 2vw, 15px) clamp(12px, 3vw, 20px); + border-radius: clamp(10px, 2.5vw, 18px); + font-weight: 800; + font-size: clamp(13px, 3vw, 18px); + background: linear-gradient(135deg, #a8edea, #fed6e3); + background-size: 200% 200%; + animation: worditem-gradient 4s ease infinite; + color: var(--text); + box-shadow: 0 clamp(3px, 1vw, 6px) clamp(8px, 2vw, 15px) rgba(0,0,0,0.12); + transition: all 0.35s cubic-bezier(0.68, -0.55, 0.265, 1.55); + border-left: clamp(3px, 1vw, 6px) solid var(--primary-blue); + position: relative; + text-shadow: 1px 1px 2px rgba(255,255,255,0.8); + letter-spacing: clamp(0.2px, 0.1vw, 0.5px); +} + +@keyframes worditem-gradient { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +.worditem::before { + content: "🔍"; + position: absolute; + left: clamp(-6px, -1.5vw, -12px); + top: 50%; + transform: translateY(-50%); + background: linear-gradient(45deg, #ffffff, #f0f8ff); + border-radius: 50%; + padding: clamp(2px, 0.5vw, 4px); + font-size: clamp(10px, 2vw, 16px); + box-shadow: 0 2px 8px rgba(0,0,0,0.15); + animation: search-icon 2s ease-in-out infinite; +} + +@keyframes search-icon { + 0%, 100% { transform: translateY(-50%) rotate(0deg) scale(1); } + 50% { transform: translateY(-50%) rotate(180deg) scale(1.1); } +} + +.worditem:hover { + transform: translateX(clamp(3px, 1vw, 8px)) scale(1.02); + box-shadow: 0 clamp(5px, 1.5vw, 10px) clamp(12px, 3vw, 20px) rgba(0,0,0,0.18); + filter: brightness(1.1); +} + +.worditem.done { + background: linear-gradient(135deg, #c6f6d5, #9ae6b4); + background-size: 200% 200%; + animation: completion-gradient 3s ease infinite, completion-celebration 1s ease-out; + text-decoration: line-through; + border-left-color: var(--primary-green); + filter: brightness(1.2); +} + +.worditem.done::before { + content: "✅"; + animation: checkmark-bounce 0.6s ease-out; +} + +@keyframes completion-gradient { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +@keyframes completion-celebration { + 0% { transform: scale(1); } + 25% { transform: scale(1.08) rotate(3deg); } + 50% { transform: scale(1.12) rotate(-2deg); } + 75% { transform: scale(1.05) rotate(1deg); } + 100% { transform: scale(1) rotate(0deg); } +} + +@keyframes checkmark-bounce { + 0% { transform: translateY(-50%) scale(0.5); } + 50% { transform: translateY(-50%) scale(1.3); } + 100% { transform: translateY(-50%) scale(1); } +} + +/* Animated progress indicator */ +#progress { + background: var(--accent); + background-size: 300% 300%; + animation: progress-gradient 3s ease infinite; + color: white; + padding: clamp(5px, 1.5vw, 10px) clamp(8px, 2vw, 15px); + border-radius: clamp(15px, 3vw, 25px); + font-weight: 800; + font-size: clamp(12px, 2.5vw, 16px); + box-shadow: 0 clamp(3px, 1vw, 6px) clamp(8px, 2vw, 15px) rgba(255,107,107,0.4); + text-shadow: 1px 1px 2px rgba(0,0,0,0.3); + position: relative; + overflow: hidden; +} + +@keyframes progress-gradient { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +#progress::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent); + animation: progress-shine 2s ease-in-out infinite; +} + +@keyframes progress-shine { + 0% { left: -100%; } + 100% { left: 100%; } +} + +/* Fun footer */ +.footer { + grid-column: 1/-1; + text-align: center; + padding: clamp(10px, 2.5vw, 18px); + color: #4a5568; + font-size: clamp(12px, 2.5vw, 16px); + font-weight: 700; + background: linear-gradient(135deg, #ffecd2, #fcb69f, #ff9a9e); + background-size: 300% 300%; + animation: footer-gradient 6s ease infinite; + border-radius: clamp(10px, 2vw, 18px); + margin-top: clamp(8px, 2vw, 15px); + box-shadow: 0 clamp(3px, 1vw, 6px) clamp(8px, 2vw, 12px) rgba(0,0,0,0.1); + text-shadow: 1px 1px 2px rgba(255,255,255,0.8); + position: relative; +} + +@keyframes footer-gradient { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +.footer::before { + content: '💖✨'; + position: absolute; + left: clamp(10px, 2vw, 20px); + top: 50%; + transform: translateY(-50%); + font-size: clamp(1rem, 2vw, 1.5rem); + animation: footer-hearts 2s ease-in-out infinite; +} + +.footer::after { + content: '🌟🎈'; + position: absolute; + right: clamp(10px, 2vw, 20px); + top: 50%; + transform: translateY(-50%); + font-size: clamp(1rem, 2vw, 1.5rem); + animation: footer-stars 2.5s ease-in-out infinite reverse; +} + +@keyframes footer-hearts { + 0%, 100% { transform: translateY(-50%) scale(1); } + 50% { transform: translateY(-50%) scale(1.2); } +} + +@keyframes footer-stars { + 0%, 100% { transform: translateY(-50%) rotate(0deg); } + 50% { transform: translateY(-50%) rotate(180deg); } +} + +/* MAGICAL STORY OVERLAY - maximum wow factor */ +.overlay { + position: fixed; + left: 0; + top: 0; + right: 0; + bottom: 0; + background: linear-gradient(135deg, rgba(102, 126, 234, 0.95), rgba(118, 75, 162, 0.95), rgba(255, 154, 158, 0.9)); + background-size: 400% 400%; + animation: overlay-gradient 8s ease infinite; + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + opacity: 0; + pointer-events: none; + transition: all 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55); + backdrop-filter: blur(15px); + padding: clamp(10px, 2vw, 20px); +} + +@keyframes overlay-gradient { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +.overlay.show { + opacity: 1; + pointer-events: auto; +} + +.overlay::before { + content: '🎊🎉✨🌟⭐🎈🎯🦄🌈💫'; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + font-size: clamp(2rem, 5vw, 4rem); + opacity: 0.2; + animation: celebration-float 15s linear infinite; + pointer-events: none; + letter-spacing: clamp(3rem, 8vw, 6rem); + line-height: clamp(6rem, 12vw, 10rem); + overflow: hidden; +} + +@keyframes celebration-float { + 0% { transform: translateY(100vh) rotate(0deg); } + 100% { transform: translateY(-200px) rotate(360deg); } +} + +.storybox { + width: min(clamp(400px, 90vw, 800px), 95%); + max-height: 90vh; + overflow-y: auto; + background: linear-gradient(145deg, #ffffff, #f7fafc); + padding: clamp(20px, 5vw, 40px); + border-radius: clamp(20px, 4vw, 35px); + text-align: center; + transform: translateY(50px) scale(0.8) rotate(5deg); + transition: all 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55); + box-shadow: 0 clamp(20px, 5vw, 40px) clamp(60px, 12vw, 100px) rgba(0,0,0,0.4); + border: clamp(4px, 1vw, 8px) solid white; + position: relative; + z-index: 1001; +} + +.storybox::before { + content: "🎉🎊✨🌟🎈🦄🌈"; + position: absolute; + top: clamp(-15px, -3vw, -25px); + left: 50%; + transform: translateX(-50%); + font-size: clamp(1.5rem, 4vw, 3rem); + animation: storybox-celebration 2s ease-out infinite alternate; + z-index: 1; +} + +@keyframes storybox-celebration { + 0% { transform: translateX(-50%) translateY(0) rotate(-10deg) scale(1); } + 100% { transform: translateX(-50%) translateY(clamp(-3px, -1vw, -8px)) rotate(10deg) scale(1.1); } +} + +.overlay.show .storybox { + transform: translateY(0) scale(1) rotate(0deg); +} + +.storybox h2 { + font-size: clamp(18px, 4vw, 28px); + margin: 0 0 clamp(15px, 3vw, 25px) 0; + color: var(--text); + text-shadow: 2px 2px 4px rgba(0,0,0,0.1); + font-weight: 900; +} + +.story-text { + font-size: clamp(16px, 3.5vw, 22px); + color: var(--text); + line-height: 1.6; + margin: clamp(15px, 3vw, 25px) 0; + padding: clamp(15px, 3vw, 25px); + background: linear-gradient(135deg, #ffecd2, #fcb69f); + background-size: 200% 200%; + animation: story-gradient 4s ease infinite; + border-radius: clamp(12px, 3vw, 20px); + border-left: clamp(4px, 1vw, 8px) solid var(--primary-orange); + box-shadow: inset 0 2px 8px rgba(0,0,0,0.05); + text-shadow: 1px 1px 2px rgba(255,255,255,0.8); + font-weight: 600; +} + +@keyframes story-gradient { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +/* CONFETTI CANVAS */ +.confetti-canvas { + position: fixed; + left: 0; + top: 0; + right: 0; + bottom: 0; + pointer-events: none; + z-index: 999; +} + +/* COLORFUL SETTINGS */ +.settings { + display: flex; + flex-direction: column; + gap: clamp(10px, 2vw, 15px); + padding: clamp(12px, 3vw, 20px); + background: linear-gradient(135deg, #e0e7ff, #c7d2fe, #a5b4fc); + background-size: 300% 300%; + animation: settings-gradient 5s ease infinite; + border-radius: clamp(12px, 3vw, 18px); + border: clamp(2px, 0.5vw, 4px) solid #a5b4fc; + box-shadow: 0 clamp(4px, 1vw, 8px) clamp(12px, 3vw, 20px) rgba(165, 180, 252, 0.3); + position: relative; + overflow: hidden; +} + +@keyframes settings-gradient { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +.settings::before { + content: '⚙️🎛️'; + position: absolute; + top: clamp(5px, 1vw, 10px); + right: clamp(5px, 1vw, 10px); + font-size: clamp(1rem, 2vw, 1.5rem); + opacity: 0.6; + animation: settings-icons 3s ease-in-out infinite; +} + +@keyframes settings-icons { + 0%, 100% { transform: rotate(0deg); } + 50% { transform: rotate(180deg); } +} + +.row { + display: flex; + flex-wrap: wrap; + gap: clamp(8px, 2vw, 15px); + align-items: center; + min-height: clamp(30px, 6vw, 40px); +} + +.label { + font-size: clamp(12px, 2.5vw, 16px); + color: #4c51bf; + font-weight: 800; + text-transform: uppercase; + letter-spacing: clamp(0.3px, 0.1vw, 0.8px); + text-shadow: 1px 1px 2px rgba(255,255,255,0.8); + min-width: clamp(60px, 15vw, 80px); +} + +select, input[type=range] { + flex: 1; + min-width: clamp(80px, 20vw, 120px); + padding: clamp(6px, 1.5vw, 12px); + border-radius: clamp(8px, 2vw, 15px); + border: clamp(2px, 0.5vw, 3px) solid #cbd5e0; + background: linear-gradient(145deg, #ffffff, #f8f9fa); + font-weight: 600; + font-size: clamp(12px, 2.5vw, 14px); + transition: all 0.3s ease; + box-shadow: 0 2px 6px rgba(0,0,0,0.1); +} + +select:focus, input[type=range]:focus { + outline: none; + border-color: var(--primary-purple); + box-shadow: 0 0 0 clamp(2px, 0.5vw, 4px) rgba(159, 122, 234, 0.3); + transform: scale(1.02); +} + +input[type=checkbox] { + transform: scale(clamp(1.2, 0.3vw + 1, 2)); + accent-color: var(--primary-pink); + cursor: pointer; +} + +/* ULTRA RESPONSIVE DESIGN */ +@media (max-width: 1200px) { + .app { + max-width: 95vw; + grid-template-columns: minmax(280px, 350px) 1fr; + } +} + +@media (max-width: 900px) { + .app { + grid-template-columns: 1fr; + max-width: 100%; + gap: clamp(15px, 3vw, 25px); + } + .left { + order: 2; + } + .grid { + justify-self: center; + } + .controls { + justify-content: center; + } + header { + flex-direction: column; + gap: clamp(10px, 2vw, 15px); + text-align: center; + } +} + +@media (max-width: 600px) { + .app { + padding: clamp(10px, 3vw, 20px); + } + .cell { + width: clamp(28px, 7vw, 40px); + height: clamp(28px, 7vw, 40px); + font-size: clamp(12px, 3vw, 18px); + } + .controls { + flex-direction: column; + width: 100%; + } + .btn, .small { + width: 100%; + max-width: 200px; + } +} + +@media (max-width: 400px) { + html, body { + padding: 5px; + } + .app { + min-height: 95vh; + } + .storybox { + margin: 10px; + padding: clamp(15px, 4vw, 25px); + } +} + +/* High contrast mode support */ +@media (prefers-contrast: high) { + :root { + --text: #000000; + --bg-primary: #ffffff; + } + .cell { + border: 2px solid #000000; + } +} + +/* Reduced motion support */ +@media (prefers-reduced-motion: reduce) { + *, *::before, *::after { + animation-duration: 0.01s !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01s !important; + } +} + +/* Print styles */ +@media print { + .overlay, html::before, html::after, body::before { + display: none !important; + } + .app { + box-shadow: none; + background: white; + } +} \ No newline at end of file