Fixed bug where tutorial highlighting appeared in wrong column:
- placeValue 0 (ones place) now correctly maps to columnIndex 4 (rightmost)
- placeValue 1 (tens place) now correctly maps to columnIndex 3
- Added comprehensive test suite to catch highlighting regressions
Tutorial steps now highlight beads in the correct columns.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix highlighting logic bug where multiple beads in same column would overwrite each other
- Migrate TutorialStep interface from columnIndex to placeValue system
- Update tutorial data to use place values (0=ones, 1=tens, etc.)
- Fix bead validation logic to use place values instead of legacy columnIndex
- Enable proper multi-step tutorial highlighting for complement operations
Tutorial steps like "3 + 4 = 5 - 1" now correctly highlight both the heaven bead
(add 5) and earth bead (remove 1) simultaneously.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Implement 150ms debounced value change handler to prevent tutorial
system bottlenecks during rapid bead dragging
- Allow abacus to render smoothly by deferring expensive tutorial
operations (validation, state updates, event logging) until
gestures settle
- Add proper cleanup and ref synchronization for debounced values
- This should eliminate UI lag when dragging beads up and down rapidly
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Memoize custom styles calculation using useMemo to prevent expensive
recalculation on every render
- Move complex highlightBeads.reduce() operation out of inline prop
- Only recalculate when currentStep.highlightBeads actually changes
- This fixes sluggish gesture performance in tutorial abacus
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Moved navigation function declarations before useEffect hooks that reference
them to prevent 'Cannot access before initialization' error. Also updated
tutorial completion logic to use dispatch instead of logEvent.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replaced multiple useState hooks and complex useEffect dependencies with a
single useReducer that handles all state transitions deterministically.
Benefits:
- Eliminates circular dependencies between useEffects
- Centralized state management with predictable updates
- Reduced complexity and easier debugging
- Step initialization only happens through navigation, not reactive effects
- Events are managed as part of the single state tree
This architecture prevents infinite loops by design rather than working
around them with timing or flags.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replaced the 50ms setTimeout hack with a proper isProgrammaticChange ref
that synchronously tracks when value changes are initiated programmatically
vs by user interaction. This eliminates timing dependencies and race
conditions while maintaining the same functional behavior.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added isInitializing flag to prevent onValueChange callback feedback loop
during step transitions. When a new step initializes, AbacusReact would
call onValueChange with the startValue, causing TutorialPlayer to set the
same value again, creating an infinite loop.
Also removed problematic auto-click play function from EditingMode story
that was interfering with component state.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>