From c5e98dafb8faa9c9e1e1239ef6a03d45e31730bf Mon Sep 17 00:00:00 2001 From: Andre Padez Date: Wed, 22 Oct 2025 19:27:47 +0100 Subject: [PATCH] feat: add edit mode rules and use existing CSS classes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rules Implemented: 1. Can only enter edit mode on empty cells or user-entered cells 2. Pressing 'i' on a given cell (from algo) triggers red flash 3. Edit mode blocked on cells with 'given' class Visual Changes: - Use existing 'active' class for normal mode cursor (blue glow) - Use existing 'editing' class for edit mode (yellow/amber glow) - Removed custom cursor/cursor-edit classes - Matches original CSS design from src_old Cell Detection: - Check if cell has 'given' class before entering edit mode - Given cells: From puzzle generation (immutable) - Empty or user-entered cells: Can be edited Flow: 1. Navigate to given cell → Press 'i' → Red flash (blocked) 2. Navigate to empty cell → Press 'i' → Yellow editing glow 3. Navigate to user-entered cell → Press 'i' → Yellow editing glow 4. Press Escape → Return to blue active glow Phase 40.3.2 complete. --- src/game.css | 25 ------------------------- src/useCursor/useCursor.ts | 12 ++++++++++++ src/useCursor/useCursorRender.ts | 6 +++--- 3 files changed, 15 insertions(+), 28 deletions(-) diff --git a/src/game.css b/src/game.css index 16965b6..69e3fc4 100644 --- a/src/game.css +++ b/src/game.css @@ -255,31 +255,6 @@ } } -/* Cursor highlight - Normal mode */ -.sudoku-cell.cursor { - background-color: rgba(59, 130, 246, 0.3); - outline: 3px solid rgb(59, 130, 246); - outline-offset: -3px; - z-index: 10; - position: relative; -} - -/* Cursor highlight - Edit mode */ -.sudoku-cell.cursor-edit { - background-color: rgba(34, 197, 94, 0.3); - outline: 3px solid rgb(34, 197, 94); - animation: edit-pulse 1.5s ease-in-out infinite; -} - -@keyframes edit-pulse { - 0%, 100% { - outline-color: rgb(34, 197, 94); - } - 50% { - outline-color: rgb(74, 222, 128); - } -} - /* Invalid move flash */ .sudoku-cell.invalid-move { background-color: rgba(239, 68, 68, 0.4); diff --git a/src/useCursor/useCursor.ts b/src/useCursor/useCursor.ts index 7a8cd48..51af15f 100644 --- a/src/useCursor/useCursor.ts +++ b/src/useCursor/useCursor.ts @@ -102,6 +102,18 @@ export function useCursor(gameStatusManager: GameStatusManager, containerRef: Re } if (key === 'i') { + const container = containerRef.current; + if (!container) return; + + const cells = container.querySelectorAll('.sudoku-cell'); + const index = position.row * 9 + position.col; + const targetCell = cells[index]; + + if (targetCell && targetCell.classList.contains('given')) { + flashInvalidMove(); + return; + } + setMode('edit'); return; } diff --git a/src/useCursor/useCursorRender.ts b/src/useCursor/useCursorRender.ts index 244a9b2..3a0829d 100644 --- a/src/useCursor/useCursorRender.ts +++ b/src/useCursor/useCursorRender.ts @@ -19,7 +19,7 @@ export function useCursorRender( const cells = container.querySelectorAll('.sudoku-cell'); cells.forEach(cell => { - cell.classList.remove('cursor', 'cursor-edit'); + cell.classList.remove('active', 'editing'); }); const index = position.row * 9 + position.col; @@ -27,9 +27,9 @@ export function useCursorRender( if (targetCell) { if (mode === 'edit') { - targetCell.classList.add('cursor', 'cursor-edit'); + targetCell.classList.add('editing'); } else { - targetCell.classList.add('cursor'); + targetCell.classList.add('active'); } } }, [position, mode, containerRef, gameStatus, boardRendered]);