Previously, passengers would board/disembark when the locomotive reached their
station, which was incorrect. Now:
**Boarding:**
- Passengers board when an EMPTY train car reaches their origin station
- Each passenger is assigned to the first available empty car (0-4)
- Car position calculated as: trainPosition - (carIndex + 1) * 7%
**Disembarking:**
- Passengers disembark when THEIR specific car reaches their destination
- Uses the passenger's position in the boardedPassengers array to find car index
- Each passenger's car position is independently checked against their destination
This creates more realistic train behavior where passengers interact with
individual train cars rather than just the locomotive.
Removed unused imports: findBoardablePassengers, findDeliverablePassengers
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Allow train position to exceed 100% so entire train can exit before route change
- Change route completion threshold from 100% to 135% (locomotive + 5 cars at 7% spacing)
- Add fade-out effect for locomotive and train cars between 92-97% position
- Symmetric with fade-in effect (3-8%) used for left tunnel entrance
- Prevents jarring snap-back when route changes mid-train
The train now smoothly fades out as it enters the right tunnel, with the route
only changing after the entire train (including all passenger cars) has fully
exited through the tunnel.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Memoize BoardingPassengerAnimation and DisembarkingPassengerAnimation with React.memo
- Memoize expensive calculations: train cars, filtered passengers, ground texture
- Consolidate boarding/disembarking useEffect hooks to reduce passenger array processing
- Wrap PassengerCard in React.memo to prevent unnecessary re-renders
- Add useMemo for boardedPassengers and nonDeliveredPassengers lists
These optimizations reduce unnecessary re-renders and recalculations during gameplay,
improving performance especially when multiple passengers are in transit.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implement a complete passenger train car system with animated boarding
and disembarking using react-spring.
Train Car System:
- Each passenger gets their own train car (🚃) following the track
- Cars follow curved track with proper rotation and spacing (7%)
- Cars fade in as they emerge from tunnel to avoid visual pile-up
- Compact car sizing (65px) and passenger sizing (42px)
- Maximum 5 cars per train for performance
Boarding Animations:
- Smooth spring-animated transitions from station to train car
- Passengers fly from station platform to assigned car (800ms)
- Passengers hidden from station and car during animation
- Animated passenger tracked separately to avoid flickering
Disembarking Animations:
- Reverse animation from train car to destination station
- Green glow effect for delivered passengers
- Celebration animation plays after landing at station
- Smooth transition prevents "ghost" effect
Station Passenger Display:
- Positioned directly above station circle (30px offset)
- Compact 55px size for better visual balance
- Tight horizontal spacing (28px) when multiple waiting
- Passengers properly excluded during boarding/disembarking
Visual Improvements:
- Removed decorative rock/bush elements from mountains
- Cleaner mountain tunnel appearance
- Better layering of animations between stations and train
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Redesign passenger information cards to match classic Grand Central
Terminal style with compact, elegant vintage design.
- Vintage color scheme: sepia, gold accents, dark backgrounds
- Courier New monospace font for mechanical board feel
- Compact layout with FROM/TO route information
- Shows origin station (was missing before)
- Status badges: WAIT, BOARD, DLVRD
- Color-coded by state (waiting/aboard/urgent/delivered)
- Art Deco gold borders and styling
- Much smaller footprint while showing more info
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Update passenger generation to only create passengers whose destination
stations are ahead of their origin stations (higher track position).
This prevents passengers from being stranded waiting for backwards travel.
- Exclude final station as possible origin (no stations ahead)
- Filter destination stations to only those with position > origin
- Maintains 40% depot start probability for variety
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Standardize positioning for all bottom-aligned elements:
- Pressure gauge: bottom 10px (fixed, z-index 1000)
- Question display: bottom 40px (fixed, z-index 1000)
- Passenger list: bottom 220px (fixed, z-index 1000)
Changed passenger list from absolute to fixed positioning and adjusted
bottom spacing to sit above the question display without overlapping.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Expand ground layer to span full viewport width and extend from
the top of the track (y=120) to the bottom of the viewport (y=650).
Changes:
- Ground now starts at y=120 (above highest track point at ~160)
- Height increased from 200 to 530 pixels
- Added scattered rock/pebble texture across ground surface
- Enhanced surface gradient from 40 to 60 pixels for better depth
The entire railroad track now sits on realistic earth terrain.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Enhanced tunnel entrances with proper mountain scenery:
Mountains:
- Added triangular mountain peaks rising above tunnel entrances
- Gradient shading for depth and dimension
- Rocky texture with vertical crack details
- Green vegetation/bushes at mountain base
Tunnels:
- Stone brick archways with brown/tan coloring
- Brick texture pattern on arch rim
- Dark interior for depth
Ground:
- Brown earth terrain extending full viewport width
- Gradient shading for ground surface depth
- Positioned below tunnel entrances
Train now emerges from/enters proper mountain tunnels set into
realistic terrain.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove constraints preventing full-width rendering:
- Remove 8px horizontal padding from track container in sprint mode
- Remove maxWidth: 1400px constraint from SVG
- Change justifyContent to 'stretch' for sprint mode
- Remove borderRadius from steam-train-journey container
Now the railroad track SVG truly spans the entire browser viewport
width, with tunnel entrances at the absolute edges.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Corrected tunnel positioning based on actual viewBox coordinates:
- viewBox is "-50 -50 900 700" (x: -50 to 850, y: -50 to 650)
- Left mountain face now starts at x=-50 (absolute left edge)
- Right mountain face now ends at x=850 (absolute right edge)
- Both mountain faces extend full viewport height
- Track waypoints adjusted to span from left tunnel (x=20) to right tunnel (x=780)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Extend track waypoints from x: -120 to x: 920 (beyond viewport)
- Add mountain face rectangles at absolute left and right edges
- Redesign tunnel entrances as proper mountain tunnels with:
- Gray stone mountain faces extending to viewport edges
- Dark tunnel interiors
- Arched stone openings
- Stone rim detail around arch
Train now truly emerges from and enters into mountain tunnels at
the viewport boundaries.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Modify track waypoints to span from left edge (x: -50) to right edge
(x: 850) of the viewport, creating a more expansive journey across
the full screen width.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Increase landmark size multiplier from 2.5x to 4.0x, making scenery
emojis more prominent and visually similar in scale to the player
avatar (96px default vs 70px player).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Use React Spring to animate pressure changes with natural physics-based
motion. The gauge needle, digital readout, and color all smoothly
interpolate to new values instead of jumping instantly.
Configuration:
- tension: 120 (responsive spring)
- friction: 14 (smooth damping)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove "How to Play" screen in favor of self-explanatory UX.
Users now land directly on the game configuration page where they
can immediately see and select their preferred game mode, style,
and difficulty.
The game mechanics are intuitive enough that they can be learned
through play rather than reading instructions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove 60-second time limit for infinite gameplay
- Auto-advance to next route upon completion instead of showing modal
- Time-of-day cycle now repeats every 60 seconds indefinitely
- Update documentation to reflect infinite mode behavior
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added momentum and pressure reset to START_NEW_ROUTE action.
Each new route now starts fresh with zero momentum/pressure,
preventing carryover from the previous route.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed race condition where route celebration modal would immediately
reappear after clicking 'Continue Journey'.
Root cause: trainPosition stayed >= 100 while showRouteCelebration
was toggled, causing the interval check to re-trigger COMPLETE_ROUTE.
Solution:
1. START_NEW_ROUTE now resets showRouteCelebration to false
2. Removed setTimeout delay and HIDE_ROUTE_CELEBRATION action
3. Single atomic state update prevents race condition
Now continuing to next route works smoothly without modal flickering.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Move router.push() from mode selection to game start button.
This prevents the game from rebooting when user is exploring
different race types in the setup screen.
Now the flow is:
1. User selects race type → background preview changes
2. User clicks 'Start Your Race!' → URL updates + game begins
This keeps the setup experience smooth while still providing
shareable URLs once the game starts.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove conditional padding that caused 12px upward shift when
selecting Steam Sprint. Now uses consistent 20px 8px padding
across all game modes for stable layout.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add Next.js router integration to update URL when user selects
a game mode in GameControls. Now when selecting:
- Practice Mode → URL becomes /games/complement-race/practice
- Steam Sprint → URL becomes /games/complement-race/sprint
- Survival Mode → URL becomes /games/complement-race/survival
This makes URLs shareable at any point in the setup flow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added complete animation system with Panda CSS:
1. Panda CSS Keyframe Animations (panda.config.ts):
- shake: Horizontal oscillation for errors (-5px to 5px)
- successPulse: Gentle scale for correct answers (1 to 1.05)
- errorShake: Stronger shake for errors (-10px to 10px)
- pulse: Continuous breathing effect (1 to 1.05)
- bounce: Vertical bounce (0 to -10px)
- bounceIn: Entry animation with scale and rotate
- glow: Expanding box shadow effect
All animations match exact timing and easing from original
Python implementation (web_generator.py lines 1996-6274)
2. Visual Feedback Integration (GameDisplay.tsx):
- Trigger successPulse animation on correct answers
- Trigger errorShake animation on incorrect answers
- Auto-clear animations after 500ms (matching duration)
- Applied to answer input element for clear visual feedback
- Synchronized with sound effects for multi-sensory feedback
Animations enhance user experience by providing immediate
visual confirmation of answer correctness alongside audio cues.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added 5 remaining sound effects across all game modes:
1. ai_turbo (0.12 volume) - Plays when AI enters desperate_catchup
mode (>10 units behind), matches line 11941
2. lap_celebration (0.6 volume) - Plays when player completes a lap
in survival mode circular track, matches line 12801
3. celebration (default volume) - Plays when:
- Player wins practice mode (reaches goal first)
- Route completes in sprint mode (with train_whistle)
Matches lines 14182, 13543
4. gameOver (default volume) - Plays when AI wins in practice mode
(AI reaches goal before player), matches line 14193
5. train_whistle (0.25-0.6 volume) - Plays in sprint mode when:
- Streak milestone: streak >= 5 and streak % 3 === 0 (0.4 volume)
- High momentum: momentum >= 90 (30% chance, 0.25 volume)
- Route completion: train reaches 100% (0.6 volume)
Matches lines 13222-13235, 13541
All sound integrations preserve exact timing and volume levels from
original Python implementation (web_generator.py).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Simplified flow:
- /games/complement-race goes directly to setup page (no redundant landing)
- Direct URLs (/practice, /sprint, /survival) pre-select game type
- Users configure all options on single fancy setup page
Enhanced GameControls with:
- Gradient background and hero title
- 3px borders with gradient fills on selected options
- Larger icons (24-28px) and better spacing
- Detailed descriptions for each race type explaining gameplay
- Color-coded sections (blue for number mode, green/amber/purple for race types, pink for difficulty)
- Prominent start button with gradient and emoji
- Professional shadows and hover effects throughout
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Create dedicated routes for each Complement Race game mode:
- /games/complement-race/practice - Practice Mode (race to 20)
- /games/complement-race/sprint - Steam Sprint (60 second momentum)
- /games/complement-race/survival - Survival Mode (endless laps)
Each route uses ComplementRaceProvider with initialStyle prop to set
the game mode, allowing users to share direct links to specific modes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add ComplementRaceProviderProps interface with optional initialStyle
- Accept initialStyle param ('practice' | 'sprint' | 'survival')
- Initialize game state with provided style or default to 'practice'
- Enables URL-based routing for different game modes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Wire up sound effects to game events:
Countdown & Start:
- Play countdown beep (0.4 volume) for 3-2-1
- Play race_start fanfare (0.6 volume) on GO!
Answer Feedback (matching original logic from web_generator.py):
- Streak sound: every 5th correct answer when streak > 0
- Whoosh sound: responses under 800ms (very fast!)
- Combo sound: responses under 1200ms when streak >= 3
- Correct sound: regular correct answers
- Incorrect sound: wrong answers
Sound triggering follows exact original logic (lines 11530-11542, 11589):
- Check streak % 5 first
- Then check response time < 800ms
- Then check response time < 1200ms AND streak >= 3
- Default to regular correct sound
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Previous session improvements:
- Add data-component attributes to all major components for debugging
- Fix viewport issues: set overflow:hidden, maxHeight:100vh to prevent scrolling
- Make backgrounds transparent for sprint mode (sky gradient at root level)
- Adjust padding for sprint mode (8px vs 20px)
- Redesign race configuration screen for responsive mobile-first layout
- Rebuild pressure gauge with proper 180° semicircular arc
- Make complement equation more prominent (96px font)
- Enlarge station names and icons for better visibility
- Fix viewport clipping issues with pressure gauge and question display
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Show boarded passengers riding on the train behind the engineer
- Position passengers at x=90+ with 35px spacing
- Size 28px, with urgent passengers having orange glow
- Display waiting passengers at their origin stations
- Large avatars (fontSize 80) above station platforms
- Urgent passengers have orange glow effect
- Positioned at y=-100 with 90px horizontal spacing
- Show delivered passengers celebrating at destination stations
- Same size as waiting passengers (fontSize 80)
- Green glow effect with celebrateDelivery animation
- 2-second celebration before fading away
- Add celebrateDelivery CSS animation with scale and translateY effects
- Update passenger list to show all non-delivered passengers (waiting + aboard)
- Add maxHeight and overflowY to passenger list container
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add visual status badges showing WAITING (⏳) or ABOARD (🚂) state
- Color code cards by passenger state:
- Gray gradient for waiting passengers
- Blue/orange gradient for boarded passengers
- Green gradient for delivered passengers
- Adjust opacity: 0.8 for waiting, 1.0 for aboard, 0.6 for delivered
- Show urgent warning (⚠️) only for boarded urgent passengers
- Update animations to only pulse when passenger is urgent and aboard
- Improve card layout with flex container for status badge positioning
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add BOARD_PASSENGER action to GameAction types
- Implement BOARD_PASSENGER reducer to mark passengers as boarded
- Add findBoardablePassengers helper to identify passengers ready to board
- Update useSteamJourney hook to automatically board passengers when train reaches their origin station
- Modify findDeliverablePassengers to only check boarded passengers for delivery
- Passengers now transition through complete lifecycle: waiting → boarding → aboard → delivery
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented a new complement arithmetic game with three distinct modes:
Practice Mode (Linear Track):
- Race against AI opponents on a straight track
- Fixed race goal with finish line
- Traditional racing format with visual progress indicators
Endless Circuit (Circular Track):
- Infinite laps around an oval track
- Continuous gameplay with lap tracking
- AI racers with personality-driven commentary system
Steam Sprint (Train Journey):
- 60-second timed challenge with momentum-based gameplay
- SVG railroad track with dynamic curved paths that vary by route
- Passenger delivery system with station stops
- Momentum decay mechanic balanced by skill level
- Animated sky gradient with time-of-day progression (dawn to night)
- Route progression system with 10 themed routes
- Enhanced pressure gauge and visual effects (steam, coal particles)
- Geographic landmarks themed to each route
Core Features:
- Adaptive difficulty system that learns user performance patterns
- Real-time feedback based on speed and accuracy
- Comprehensive state management with React Context
- Multiple track visualization systems (linear, circular, SVG-based)
- AI personality system with dynamic commentary
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Improve emoji selection UX by making hover preview more dramatic and removing empty category tabs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add large preview tooltip when hovering over emojis in picker:
- 72px magnified emoji preview in white card with blue glow
- Appears above hovered emoji with smooth scale-in animation
- Arrow indicator pointing to source emoji
- Fixed positioning follows cursor between emojis
- Helps users make informed decisions with small emoji buttons
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fix category filtering by using correct emojibase group IDs:
- Groups are 0-9, not 0-7
- Skip group 2 (Component - skin tone modifiers)
- Match Unicode CLDR standard group ordering
- Group 0: Smileys & Emotion (not Smileys & People)
- Group 1: People & Body (separate from smileys)
- Groups 3-9: Animals, Food, Travel, Activities, Objects, Symbols, Flags
Categories now correctly filter the right emojis.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Enhance emoji picker with better navigation and usability:
- Add 8 emoji category tabs with icons (Smileys, Animals, Food, etc.)
- Enable vertical scrolling in emoji grid with custom scrollbar styling
- Category pills with blue highlight for selected category
- Dynamic header showing category name and emoji count
- Horizontal scrolling for category tabs on smaller screens
- Fix overflow clipping issue by adding scrollable container
Users can now easily browse thousands of emojis by category.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Extend profile system and configuration UI to support all players:
- Add player3Emoji, player4Emoji, player3Name, player4Name to UserProfile
- Update PlayerConfigDialog to support players 1-4 with unique gradients
- Player 1: Blue, Player 2: Pink, Player 3: Purple, Player 4: Yellow
- Update EmojiPicker color schemes for all 4 players
- Revert gear icon restrictions - show for all players
- Update PageWithNav to use profile data for all players
All players now fully customizable with persistent storage.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>