diff --git a/MOBILE_SETUP.md b/MOBILE_SETUP.md
new file mode 100644
index 0000000..ac5bdf0
--- /dev/null
+++ b/MOBILE_SETUP.md
@@ -0,0 +1,55 @@
+# Mobile vs Desktop Setup
+
+The crossword puzzle now has separate optimized versions for mobile and desktop/tablet devices.
+
+## Files
+
+### Mobile Version (< 768px width)
+- **mobile.html** - Simplified mobile-optimized layout
+- **mobile.css** - Mobile-first CSS with compact design
+- **mobile.js** - Simplified game logic optimized for touch
+
+### Desktop/Tablet Version (>= 768px width)
+- **index.html** - Full-featured desktop layout
+- **styles_v5.css** - Desktop/tablet responsive CSS
+- **game.js** - Full game logic with advanced features
+
+### Shared Files
+- **puzzleData.js** - Puzzle data used by both versions
+- **redirect.js** - Automatic device detection and redirection
+
+## How It Works
+
+1. User visits the site (index.html or mobile.html)
+2. `redirect.js` detects device type
+3. Automatically redirects to appropriate version:
+ - Mobile devices → mobile.html
+ - Desktop/tablet → index.html
+
+## Key Differences
+
+### Mobile Version Features:
+- Compact header (50px)
+- Simplified controls
+- Touch-optimized grid (30-42px cells)
+- Minimal padding for maximum grid space
+- Single-column layout
+- Streamlined UI
+
+### Desktop Version Features:
+- Full header with stats
+- Larger grid (40-120px cells)
+- More detailed UI elements
+- Better spacing and padding
+- Advanced features
+
+## Testing
+
+To test mobile version on desktop:
+1. Open browser dev tools
+2. Toggle device emulation
+3. Refresh page - should auto-redirect to mobile.html
+
+To force a specific version:
+- Mobile: Go directly to `/mobile.html`
+- Desktop: Go directly to `/index.html`
diff --git a/public/index.html b/public/index.html
index 0ce6822..179d645 100644
--- a/public/index.html
+++ b/public/index.html
@@ -4,6 +4,7 @@
Kruiswoord Pro: Zweedse puzzel
+
diff --git a/public/mobile.css b/public/mobile.css
new file mode 100644
index 0000000..d0a76f0
--- /dev/null
+++ b/public/mobile.css
@@ -0,0 +1,403 @@
+/* Mobile-First Reset */
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ -webkit-tap-highlight-color: transparent;
+}
+
+body {
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ min-height: 100vh;
+ overflow-x: hidden;
+ touch-action: manipulation;
+}
+
+.mobile-container {
+ width: 100vw;
+ height: 100vh;
+ background: white;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+}
+
+/* Compact Header */
+.mobile-header {
+ background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
+ color: white;
+ padding: 8px 10px;
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+ flex-shrink: 0;
+}
+
+.menu-icon {
+ background: rgba(255,255,255,0.2);
+ border: none;
+ color: white;
+ width: 36px;
+ height: 36px;
+ border-radius: 8px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 18px;
+ cursor: pointer;
+}
+
+.header-info {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+}
+
+.level {
+ font-weight: 600;
+ font-size: 14px;
+}
+
+.resources {
+ display: flex;
+ gap: 12px;
+ font-size: 12px;
+}
+
+.coins, .hints {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ background: rgba(255,255,255,0.2);
+ padding: 2px 8px;
+ border-radius: 10px;
+}
+
+/* Compact Progress */
+.progress-compact {
+ background: #f8f9fa;
+ padding: 6px 10px;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ border-bottom: 1px solid #e9ecef;
+ flex-shrink: 0;
+}
+
+.progress-bar {
+ flex: 1;
+ height: 6px;
+ background: #e9ecef;
+ border-radius: 3px;
+ overflow: hidden;
+}
+
+.progress-fill {
+ height: 100%;
+ background: linear-gradient(90deg, #48bb78, #38a169);
+ width: 0%;
+ transition: width 0.3s ease;
+}
+
+.progress-text {
+ font-size: 11px;
+ font-weight: 600;
+ color: #4a5568;
+ min-width: 35px;
+}
+
+/* Grid Section - Optimized for Mobile */
+.grid-section {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 5px;
+ overflow: hidden;
+ background: #f8f9fa;
+}
+
+.grid-wrapper {
+ display: grid;
+ background: #a0aec0;
+ padding: 3px;
+ border-radius: 6px;
+ gap: 1px;
+ max-width: 100%;
+ max-height: 100%;
+}
+
+.grid-cell {
+ background: white;
+ border: 1px solid #cbd5e0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ font-size: 16px;
+ font-weight: bold;
+}
+
+.grid-cell.clue-cell {
+ background: linear-gradient(135deg, #4a5568, #2d3748);
+ color: white;
+ padding: 2px;
+ font-size: 7px;
+ font-weight: 600;
+ line-height: 1.1;
+ text-align: left;
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: flex-start;
+ overflow: hidden;
+}
+
+.clue-text {
+ font-size: 7px;
+ line-height: 1.1;
+ word-wrap: break-word;
+ width: 100%;
+ z-index: 1;
+}
+
+.arrow {
+ position: absolute;
+ color: #4299e1;
+ font-weight: bold;
+ font-size: 12px;
+}
+
+.arrow-right {
+ right: 2px;
+ top: 50%;
+ transform: translateY(-50%);
+}
+
+.grid-cell.blocked-cell {
+ background: #2d3748;
+ border-color: #2d3748;
+}
+
+.grid-cell.input-cell {
+ background: white;
+}
+
+.grid-cell.input-cell.active {
+ background: #ebf8ff;
+ border-color: #3182ce;
+ box-shadow: 0 0 0 2px rgba(66, 153, 225, 0.3);
+}
+
+.grid-cell.correct {
+ background: #c6f6d5;
+ border-color: #48bb78;
+}
+
+.grid-cell.incorrect {
+ background: #fed7d7;
+ border-color: #f56565;
+}
+
+.grid-cell input {
+ width: 100%;
+ height: 100%;
+ border: none;
+ background: transparent;
+ text-align: center;
+ font-weight: bold;
+ color: #2d3748;
+ text-transform: uppercase;
+ font-size: inherit;
+ outline: none;
+}
+
+/* Mobile Controls */
+.mobile-controls {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: 6px;
+ padding: 8px;
+ background: white;
+ border-top: 1px solid #e9ecef;
+ flex-shrink: 0;
+}
+
+.control-btn {
+ background: linear-gradient(135deg, #667eea, #764ba2);
+ color: white;
+ border: none;
+ border-radius: 8px;
+ padding: 10px 6px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 3px;
+ cursor: pointer;
+ font-weight: 600;
+ font-size: 10px;
+ transition: transform 0.2s;
+}
+
+.control-btn:active {
+ transform: scale(0.95);
+}
+
+.control-btn i {
+ font-size: 16px;
+}
+
+.control-btn.hint {
+ background: linear-gradient(135deg, #ed8936, #dd6b20);
+}
+
+/* Side Menu */
+.side-menu {
+ position: fixed;
+ top: 0;
+ left: -250px;
+ width: 250px;
+ height: 100vh;
+ background: white;
+ box-shadow: 2px 0 10px rgba(0,0,0,0.2);
+ transition: left 0.3s ease;
+ z-index: 1000;
+}
+
+.side-menu.active {
+ left: 0;
+}
+
+.menu-header {
+ background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
+ color: white;
+ padding: 15px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.close-menu {
+ background: none;
+ border: none;
+ color: white;
+ font-size: 20px;
+ cursor: pointer;
+}
+
+.menu-items {
+ padding: 10px 0;
+}
+
+.menu-item {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 12px 15px;
+ border: none;
+ background: none;
+ width: 100%;
+ text-align: left;
+ cursor: pointer;
+ font-size: 14px;
+ transition: background 0.2s;
+}
+
+.menu-item:active {
+ background: #f8f9fa;
+}
+
+.menu-item i {
+ width: 18px;
+ color: #4facfe;
+}
+
+/* Modals */
+.modal {
+ display: none;
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(0,0,0,0.6);
+ z-index: 2000;
+ justify-content: center;
+ align-items: center;
+ padding: 20px;
+}
+
+.modal.active {
+ display: flex;
+}
+
+.modal-content {
+ background: white;
+ border-radius: 16px;
+ padding: 24px;
+ text-align: center;
+ max-width: 320px;
+ width: 100%;
+ box-shadow: 0 10px 30px rgba(0,0,0,0.3);
+}
+
+.success-icon {
+ font-size: 48px;
+ color: #48bb78;
+ margin-bottom: 12px;
+}
+
+.modal-content h2 {
+ color: #2d3748;
+ margin-bottom: 8px;
+ font-size: 20px;
+}
+
+.modal-content h3 {
+ color: #2d3748;
+ margin-bottom: 12px;
+ font-size: 18px;
+}
+
+.modal-content p {
+ color: #4a5568;
+ margin-bottom: 16px;
+ font-size: 14px;
+}
+
+.modal-btns {
+ display: flex;
+ gap: 8px;
+ margin-top: 16px;
+}
+
+.btn-primary {
+ background: linear-gradient(135deg, #48bb78, #38a169);
+ color: white;
+ border: none;
+ border-radius: 8px;
+ padding: 12px 20px;
+ cursor: pointer;
+ font-weight: 600;
+ font-size: 14px;
+ flex: 1;
+}
+
+.btn-secondary {
+ background: #e2e8f0;
+ color: #4a5568;
+ border: none;
+ border-radius: 8px;
+ padding: 12px 20px;
+ cursor: pointer;
+ font-weight: 600;
+ font-size: 14px;
+ flex: 1;
+}
+
+.btn-primary:active,
+.btn-secondary:active {
+ transform: scale(0.98);
+}
diff --git a/public/mobile.html b/public/mobile.html
new file mode 100644
index 0000000..f15c7f7
--- /dev/null
+++ b/public/mobile.html
@@ -0,0 +1,108 @@
+
+
+
+
+
+ Kruiswoord Pro - Mobile
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Check
+
+
+
+ Wis
+
+
+
+ Hint
+
+
+
+ Skip
+
+
+
+
+
+
+
+
+
+
+
+
+
Gefeliciteerd!
+
+50 Munten | +1 Hint
+
Volgende
+
+
+
+
+
+
+
Hint Gebruiken?
+
Kost 1 hint
+
+ Ja
+ Nee
+
+
+
+
+
+
+
+
+
diff --git a/public/mobile.js b/public/mobile.js
new file mode 100644
index 0000000..59c65af
--- /dev/null
+++ b/public/mobile.js
@@ -0,0 +1,442 @@
+// Mobile-Optimized Crossword Game
+class MobileCrosswordGame {
+ constructor() {
+ this.currentLevel = 1
+ this.coins = 100
+ this.hints = 3
+ this.currentPuzzle = null
+ this.userAnswers = {}
+ this.selectedCell = null
+ this.gridElement = document.getElementById('crosswordGrid')
+
+ this.init()
+ }
+
+ init() {
+ this.loadPuzzle(this.currentLevel)
+ this.setupEventListeners()
+ this.updateUI()
+ }
+
+ setupEventListeners() {
+ // Menu
+ document.getElementById('menuBtn').addEventListener('click', () => {
+ document.getElementById('sideMenu').classList.add('active')
+ })
+ document.getElementById('closeMenu').addEventListener('click', () => {
+ document.getElementById('sideMenu').classList.remove('active')
+ })
+
+ // Controls
+ document.getElementById('checkBtn').addEventListener('click', () => this.checkAnswers())
+ document.getElementById('clearBtn').addEventListener('click', () => this.clearGrid())
+ document.getElementById('hintBtn').addEventListener('click', () => this.showHintModal())
+ document.getElementById('skipBtn').addEventListener('click', () => this.skipPuzzle())
+
+ // Modals
+ document.getElementById('useHintBtn').addEventListener('click', () => this.useHint())
+ document.getElementById('cancelHintBtn').addEventListener('click', () => this.hideHintModal())
+ document.getElementById('nextBtn').addEventListener('click', () => this.nextPuzzle())
+
+ // Menu items
+ document.getElementById('dailyPuzzle').addEventListener('click', () => {
+ this.showFeedback('Dagelijkse puzzel komt binnenkort!')
+ document.getElementById('sideMenu').classList.remove('active')
+ })
+ document.getElementById('levelSelect').addEventListener('click', () => {
+ this.showFeedback('Niveau selectie komt binnenkort!')
+ document.getElementById('sideMenu').classList.remove('active')
+ })
+ }
+
+ loadPuzzle(level) {
+ // Use puzzles from puzzleData.js
+ if (typeof DUTCH_PUZZLES !== 'undefined') {
+ this.currentPuzzle = DUTCH_PUZZLES[`level${level}`] || DUTCH_PUZZLES.level1
+ }
+
+ this.userAnswers = {}
+ this.renderGrid()
+ this.updateProgress()
+ this.updateUI()
+ }
+
+ renderGrid() {
+ if (!this.currentPuzzle) return
+
+ const grid = this.currentPuzzle.grid
+ const words = this.currentPuzzle.words
+
+ this.gridElement.innerHTML = ''
+
+ // Calculate grid dimensions (add 1 column for clues)
+ const rows = grid.length
+ const cols = Math.max(...grid.map(row => row.length)) + 1
+
+ // Calculate optimal cell size for mobile
+ const cellSize = this.calculateCellSize(rows, cols)
+
+ // Set grid styles
+ this.gridElement.style.gridTemplateColumns = `repeat(${cols}, ${cellSize}px)`
+ this.gridElement.style.gridTemplateRows = `repeat(${rows}, ${cellSize}px)`
+
+ // Create grid cells
+ for (let row = 0; row < rows; row++) {
+ for (let col = 0; col < cols; col++) {
+ if (col === 0) {
+ // First column: clue cells
+ const clueData = this.getClueForRow(row, words)
+ this.gridElement.appendChild(this.createClueCell(clueData, cellSize))
+ } else {
+ // Data columns
+ const gridCol = col - 1
+ const cellValue = grid[row]?.[gridCol] || '#'
+ this.gridElement.appendChild(this.createCell(cellValue, row, gridCol, words, cellSize))
+ }
+ }
+ }
+
+ this.attachCellListeners()
+ }
+
+ calculateCellSize(rows, cols) {
+ // Mobile-specific calculation
+ const headerHeight = 50
+ const progressHeight = 35
+ const controlsHeight = 75
+ const padding = 16
+
+ const availableHeight = window.innerHeight - headerHeight - progressHeight - controlsHeight - padding
+ const availableWidth = window.innerWidth - padding
+
+ const maxFromHeight = Math.floor(availableHeight / rows)
+ const maxFromWidth = Math.floor(availableWidth / cols)
+
+ let cellSize = Math.min(maxFromHeight, maxFromWidth)
+
+ // Constrain to 30-42px for mobile readability
+ cellSize = Math.max(30, Math.min(42, cellSize))
+
+ return cellSize
+ }
+
+ getClueForRow(row, words) {
+ return words.find(w => w.direction === 'horizontal' && w.startRow === row)
+ }
+
+ createClueCell(clueData, cellSize) {
+ const cell = document.createElement('div')
+ cell.className = 'grid-cell clue-cell'
+ cell.style.width = `${cellSize}px`
+ cell.style.height = `${cellSize}px`
+
+ if (clueData) {
+ const text = document.createElement('div')
+ text.className = 'clue-text'
+ text.textContent = clueData.clue
+
+ const arrow = document.createElement('div')
+ arrow.className = 'arrow arrow-right'
+ arrow.textContent = '→'
+
+ cell.appendChild(text)
+ cell.appendChild(arrow)
+ } else {
+ cell.classList.add('blocked-cell')
+ }
+
+ return cell
+ }
+
+ createCell(value, row, col, words, cellSize) {
+ const cell = document.createElement('div')
+ cell.className = 'grid-cell'
+ cell.style.width = `${cellSize}px`
+ cell.style.height = `${cellSize}px`
+ cell.dataset.row = row
+ cell.dataset.col = col
+
+ if (value === '#') {
+ // Check if it's a clue cell for second word
+ const clueData = this.getClueAtPosition(row, col, words)
+ if (clueData) {
+ cell.classList.add('clue-cell')
+
+ const text = document.createElement('div')
+ text.className = 'clue-text'
+ text.textContent = clueData.clue
+
+ const arrow = document.createElement('div')
+ arrow.className = 'arrow arrow-right'
+ arrow.textContent = '→'
+
+ cell.appendChild(text)
+ cell.appendChild(arrow)
+ } else {
+ cell.classList.add('blocked-cell')
+ }
+ } else {
+ // Input cell
+ cell.classList.add('input-cell')
+ const input = document.createElement('input')
+ input.type = 'text'
+ input.maxLength = 1
+ input.setAttribute('inputmode', 'text')
+ input.dataset.row = row
+ input.dataset.col = col
+
+ const fontSize = Math.max(14, Math.min(22, cellSize * 0.5))
+ input.style.fontSize = `${fontSize}px`
+
+ const key = `${row}-${col}`
+ if (this.userAnswers[key]) {
+ input.value = this.userAnswers[key]
+ }
+
+ cell.appendChild(input)
+ }
+
+ return cell
+ }
+
+ getClueAtPosition(row, col, words) {
+ for (const word of words) {
+ if (word.direction === 'horizontal' && word.startRow === row && word.startCol - 1 === col) {
+ return word
+ }
+ }
+ return null
+ }
+
+ attachCellListeners() {
+ const inputs = this.gridElement.querySelectorAll('input')
+
+ inputs.forEach(input => {
+ input.addEventListener('input', (e) => this.handleInput(e))
+ input.addEventListener('focus', (e) => this.selectCell(e.target))
+ })
+ }
+
+ handleInput(e) {
+ const input = e.target
+ const value = input.value.toUpperCase()
+ input.value = value
+
+ const row = parseInt(input.dataset.row)
+ const col = parseInt(input.dataset.col)
+ const key = `${row}-${col}`
+
+ this.userAnswers[key] = value
+
+ if (value && value.length === 1) {
+ this.moveToNextCell(input)
+ }
+
+ this.updateProgress()
+ }
+
+ selectCell(input) {
+ document.querySelectorAll('.grid-cell.input-cell').forEach(cell => {
+ cell.classList.remove('active')
+ })
+ input.parentElement.classList.add('active')
+ this.selectedCell = input
+ }
+
+ moveToNextCell(currentInput) {
+ const inputs = Array.from(this.gridElement.querySelectorAll('input'))
+ const currentIndex = inputs.indexOf(currentInput)
+
+ if (currentIndex !== -1 && currentIndex < inputs.length - 1) {
+ const nextInput = inputs[currentIndex + 1]
+ nextInput.focus()
+ }
+ }
+
+ checkAnswers() {
+ let correct = 0
+ let total = 0
+
+ const inputs = this.gridElement.querySelectorAll('input')
+ inputs.forEach(input => {
+ const row = parseInt(input.dataset.row)
+ const col = parseInt(input.dataset.col)
+ const userAnswer = input.value.toUpperCase()
+ const correctAnswer = this.getCorrectAnswer(row, col)
+
+ if (correctAnswer) {
+ total++
+ const cell = input.parentElement
+ if (userAnswer === correctAnswer) {
+ correct++
+ cell.classList.add('correct')
+ cell.classList.remove('incorrect')
+ } else if (userAnswer) {
+ cell.classList.add('incorrect')
+ cell.classList.remove('correct')
+ }
+ }
+ })
+
+ const percentage = total > 0 ? Math.round((correct / total) * 100) : 0
+
+ if (percentage === 100) {
+ this.showSuccess()
+ } else {
+ this.showFeedback(`${correct}/${total} correct (${percentage}%)`)
+ }
+ }
+
+ getCorrectAnswer(row, col) {
+ for (const word of this.currentPuzzle.words) {
+ if (word.direction === 'horizontal') {
+ if (word.startRow === row && col >= word.startCol && col < word.startCol + word.answer.length) {
+ return word.answer[col - word.startCol]
+ }
+ } else if (word.direction === 'vertical') {
+ if (word.startCol === col && row >= word.startRow && row < word.startRow + word.answer.length) {
+ return word.answer[row - word.startRow]
+ }
+ }
+ }
+ return null
+ }
+
+ clearGrid() {
+ if (confirm('Alles wissen?')) {
+ this.userAnswers = {}
+ const inputs = this.gridElement.querySelectorAll('input')
+ inputs.forEach(input => {
+ input.value = ''
+ input.parentElement.classList.remove('correct', 'incorrect')
+ })
+ this.updateProgress()
+ this.showFeedback('Gewist')
+ }
+ }
+
+ showHintModal() {
+ if (this.hints <= 0) {
+ this.showFeedback('Geen hints meer!')
+ return
+ }
+ document.getElementById('hintModal').classList.add('active')
+ }
+
+ hideHintModal() {
+ document.getElementById('hintModal').classList.remove('active')
+ }
+
+ useHint() {
+ if (this.hints <= 0) return
+
+ const inputs = Array.from(this.gridElement.querySelectorAll('input'))
+ const emptyInputs = inputs.filter(input => !input.value)
+
+ if (emptyInputs.length === 0) {
+ this.showFeedback('Alles al ingevuld!')
+ this.hideHintModal()
+ return
+ }
+
+ const randomInput = emptyInputs[Math.floor(Math.random() * emptyInputs.length)]
+ const row = parseInt(randomInput.dataset.row)
+ const col = parseInt(randomInput.dataset.col)
+ const correctAnswer = this.getCorrectAnswer(row, col)
+
+ if (correctAnswer) {
+ randomInput.value = correctAnswer
+ this.userAnswers[`${row}-${col}`] = correctAnswer
+
+ this.hints--
+ this.updateUI()
+ this.updateProgress()
+ this.showFeedback('Letter onthuld!')
+ this.hideHintModal()
+ }
+ }
+
+ showSuccess() {
+ this.coins += 50
+ this.hints += 1
+ this.updateUI()
+ document.getElementById('successModal').classList.add('active')
+ }
+
+ nextPuzzle() {
+ document.getElementById('successModal').classList.remove('active')
+ this.currentLevel++
+ this.loadPuzzle(this.currentLevel)
+ this.showFeedback(`Niveau ${this.currentLevel}`)
+ }
+
+ skipPuzzle() {
+ if (confirm('Overslaan?')) {
+ this.currentLevel++
+ this.loadPuzzle(this.currentLevel)
+ this.showFeedback('Overgeslagen')
+ }
+ }
+
+ updateProgress() {
+ const inputs = this.gridElement.querySelectorAll('input')
+ let filled = 0
+ let total = 0
+
+ inputs.forEach(input => {
+ total++
+ if (input.value) filled++
+ })
+
+ const progress = total > 0 ? Math.round((filled / total) * 100) : 0
+ document.getElementById('progressFill').style.width = `${progress}%`
+ document.getElementById('progressText').textContent = `${progress}%`
+ }
+
+ updateUI() {
+ document.getElementById('coinsCount').textContent = this.coins
+ document.getElementById('hintsCount').textContent = this.hints
+ document.getElementById('levelNum').textContent = this.currentLevel
+ }
+
+ showFeedback(message) {
+ // Simple alert for mobile
+ const feedback = document.createElement('div')
+ feedback.style.cssText = `
+ position: fixed;
+ top: 60px;
+ left: 50%;
+ transform: translateX(-50%);
+ background: rgba(0,0,0,0.8);
+ color: white;
+ padding: 10px 20px;
+ border-radius: 20px;
+ font-size: 14px;
+ z-index: 9999;
+ animation: fadeInOut 2s ease;
+ `
+ feedback.textContent = message
+ document.body.appendChild(feedback)
+
+ setTimeout(() => {
+ feedback.remove()
+ }, 2000)
+ }
+}
+
+// Add fade animation
+const style = document.createElement('style')
+style.textContent = `
+ @keyframes fadeInOut {
+ 0% { opacity: 0; transform: translateX(-50%) translateY(-10px); }
+ 20% { opacity: 1; transform: translateX(-50%) translateY(0); }
+ 80% { opacity: 1; transform: translateX(-50%) translateY(0); }
+ 100% { opacity: 0; transform: translateX(-50%) translateY(-10px); }
+ }
+`
+document.head.appendChild(style)
+
+// Initialize game
+document.addEventListener('DOMContentLoaded', () => {
+ new MobileCrosswordGame()
+})
diff --git a/public/redirect.js b/public/redirect.js
new file mode 100644
index 0000000..30529a3
--- /dev/null
+++ b/public/redirect.js
@@ -0,0 +1,16 @@
+// Device Detection and Redirect
+(function() {
+ // Check if we're already on the correct page
+ const currentPage = window.location.pathname.split('/').pop() || 'index.html'
+
+ // Detect mobile device
+ const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
+ || window.innerWidth < 768
+
+ // Only redirect if needed and not in an infinite loop
+ if (isMobile && !currentPage.includes('mobile.html')) {
+ window.location.href = 'mobile.html'
+ } else if (!isMobile && currentPage.includes('mobile.html')) {
+ window.location.href = 'index.html'
+ }
+})()