Refactor to use server component composition pattern where DeploymentInfoContent (server component) imports build info JSON directly and is rendered as a child of DeploymentInfoModal (client component). Eliminates unnecessary API fetch.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add modal component to view deployment information (version, git commit, build time, etc.) accessible via Cmd/Ctrl+Shift+I keyboard shortcut throughout the app.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add API route to serve deployment information and TypeScript definitions for type safety.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add script to capture deployment metadata (git commit, branch, timestamp, version) at build time and integrate it into the build process.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- GamePhase: Convert Map to array, map numeric IDs to players
- GameCard: Use active players array for emoji lookup
- PlayerStatusBar: Fix Map.filter, fix duplicate className, fix type comparison
- ResultsPhase: Convert to array-based player lookup, add numericId mapping
- MemoryPairsContext: Create compatibility layer for numeric player IDs
- EmojiPicker: Update import path for PLAYER_EMOJIS
- EmojiPicker test: Update import path
Maintains backward compatibility with internal numeric player tracking
while using UUID-based players from GameModeContext
CircularTrack, LinearTrack, SteamTrainJourney:
- Convert Map to array for active player lookup
- Use player.emoji directly instead of profile.player1Emoji
- Remove hardcoded player ID switch statements
- Render player cards from Map instead of hardcoded 1-4
- Support arbitrary number of players
- Use player.color for theming
- Add React import for Fragment usage
- Update all player ID types from number to string
- Remove switch statements for player lookups
- Use Map/Set operations instead of array methods
- Support arbitrary number of players
- PlayerConfigDialog now accepts string IDs
GameModeContext:
- Use Map<string, Player> instead of array
- Use Set<string> for active player tracking
- Add migration support on initialization
- Remove hardcoded 1-4 player limit
UserProfileContext:
- Remove player1-4 fields (moved to GameModeContext)
- Keep only game statistics
- Add stats migration from V1
- Add Player interface with UUID-based id field
- Add PlayerStorageV2 format for new storage schema
- Add migration utilities to convert from V1 (indexed) to V2 (UUID)
- Add validation and rollback support
- Move PLAYER_EMOJIS to shared constants
Adds detailed console logging to capture all state during passenger
boarding and delivery in Steam Sprint mode. When passengers are left
behind, the entire log can be copied and pasted into a new Claude Code
session for immediate debugging.
Debug log includes:
- Train position, speed, momentum, and configuration
- All station positions and details
- Complete passenger states (waiting, boarded, delivered)
- Car positions and occupancy
- Passengers scheduled for delivery in current frame
- Detailed boarding attempt analysis for each waiting passenger
- Distance calculations and eligibility checks per car
- Actual boarding and delivery events
Enable by setting DEBUG_PASSENGER_BOARDING = true in useSteamJourney.ts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The bug occurred when a car reached a station where both:
- A passenger needed to be delivered
- A new passenger was waiting to board
The car appeared occupied during boarding check, then the passenger was delivered,
leaving the new passenger behind.
Fix: Identify passengers to be delivered BEFORE building the occupiedCars map,
and exclude them from the map. This makes cars that are about to become empty
immediately available for new passengers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace digital PSI readout with 3-column abacus display
- Replace tick mark labels (0, 50, 100, 150) with mini abacuses
- Use invisible column posts and proper sizing for readability
- Expand gauge dimensions to accommodate abacus labels without clipping
- Show inactive beads on dial indicators for place value clarity
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add hideInactiveBeads to AbacusTarget for cleaner minimal display
- Improve vertical centering with translateY adjustment in equations
- Apply changes consistently across practice, survival, and sprint modes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Apply global columnPosts property as fallback when rendering column rods
- Fix reckoning bar to span only across actual columns instead of full SVG width
- Column-specific columnPost styling still takes precedence over global
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
# [1.6.0](https://github.com/antialias/soroban-abacus-flashcards/compare/abacus-react-v1.5.1...abacus-react-v1.6.0) (2025-10-01)
### Bug Fixes
* align all bottom UI elements to same 20px baseline ([076c97a](076c97abac))
* align bottom-positioned UI elements ([227cfab](227cfabf11))
* change pressure gauge to fixed positioning to stay above terrain ([1b11031](1b11031598))
* change question display to fixed positioning with higher z-index ([4ac8758](4ac8758957))
* correct emoji category group IDs to match Unicode CLDR ([b2a21b7](b2a21b79ad))
* defer URL update until game starts ([12c54b2](12c54b27b7))
* delay passenger display update until train resets ([e06a750](e06a750454))
* eliminate rail jaggies on sharp curves by increasing sampling density ([46d4af2](46d4af2bda))
* ensure passengers only travel forward on train route ([8ad3144](8ad3144d2d))
* increase question display zIndex to stay above terrain ([8c8b8e0](8c8b8e08b4))
* move fontWeight to style object for station names ([05a3ddb](05a3ddb086))
* only show configuration gear icon for players 1 and 2 ([d0a3bc7](d0a3bc7dc1))
* passengers now board/disembark based on their car position, not locomotive ([96782b0](96782b0e7a))
* position tunnels at absolute viewBox edges ([1a5fa28](1a5fa2873b))
* prevent layout shift when selecting Steam Sprint mode ([73a5974](73a59745a5))
* prevent multiple passengers from boarding same car in single frame ([63b0b55](63b0b552a8))
* prevent premature passenger display during route transitions ([fe9ea67](fe9ea67f56))
* prevent random passenger repopulation during route transitions ([db56ce8](db56ce89ee))
* prevent route celebration from immediately reappearing ([1a80934](1a8093416e))
* reduce landmark size from 4.0x to 2.0x multiplier ([c928e90](c928e90785))
* remove double PageWithNav wrapper on matching page ([b58bcd9](b58bcd92ee))
* remove duplicate CAR_SPACING and MAX_CARS declarations ([e704a28](e704a28524))
* remove duplicate previousPassengersRef declaration ([fad8636](fad8636763))
* remove hard-coded car count from game loop ([6c90a68](6c90a68c49))
* remove unnecessary zIndex from question display ([db52e14](db52e14dfe))
* reset momentum and pressure when starting new route ([3ea88d7](3ea88d7a5a))
* smooth rail curves and deterministic track generation ([4f79c08](4f79c08d73))
* stabilize route completion threshold to prevent stuck trains ([b7233f9](b7233f9e4a))
* use displayPassengers for station rendering in RailroadTrackPath ([a9e0d19](a9e0d19734))
* use style fontSize instead of attribute for landmarks ([ebc6894](ebc6894746))
* wrap animated pressure value in animated.span to prevent React error ([5c5954b](5c5954be74))
### Features
* add category browsing and scrolling to emoji picker ([616a50e](616a50e234))
* add complement display options and unify equation display ([2ed7b2c](2ed7b2cbf8))
* add Complement Race game with three unique game modes ([582bce4](582bce411f))
* add configuration access to active player emojis in prominent nav ([6049a7f](6049a7f6b7))
* add configuration access to fullscreen player selection ([b85968b](b85968bcb6))
* add CSS animations and visual feedback system ([80e33e2](80e33e25b3))
* add direct URL routes for each game mode ([a08f053](a08f0535bf))
* add initialStyle prop to ComplementRaceProvider ([f3bc2f6](f3bc2f6d92))
* add interactive remove buttons for players in mini nav ([fa1cf96](fa1cf96789))
* add magnifying glass preview on emoji hover ([2c88b6b](2c88b6b5f3))
* add mini app nav to arcade page ([a854fe3](a854fe3dc9))
* add passenger boarding system with station-based pickup ([23a9016](23a9016245))
* add prominent game context display to mini nav with smooth transitions ([8792393](8792393956))
* add realistic mountains with peaks and ground terrain ([99cdfa8](99cdfa8a0b))
* add smooth spring animations to pressure gauge ([863a2e1](863a2e1319))
* add train car system with smooth boarding/disembarking animations ([1613912](1613912740))
* add Web Audio API sound effects system with 16 sound types ([90ba866](90ba86640c))
* create mode selection landing page for Complement Race ([1ff9695](1ff9695f69))
* create PlayerConfigDialog component for player customization ([4f2a661](4f2a661494))
* display passengers visually on train and at stations ([1599904](159990489f))
* dynamically calculate train cars based on max concurrent passengers ([9ea1553](9ea15535d1))
* enable prominent nav and fix layout on arcade page ([5c8c18c](5c8c18cbb8))
* enhance emoji picker with super powered magnifying glass and hide empty categories ([d8b4e42](d8b4e425bf))
* enhance passenger card UI with boarding status indicators ([4bbdabc](4bbdabc3b5))
* extend ground terrain to cover entire track area ([ee48417](ee48417abf))
* extend player customization to support all 4 players ([72f8dee](72f8dee183))
* extend railroad track to viewport edges ([eadd7da](eadd7da6db))
* extend track and tunnels to absolute viewport edges ([f7419bc](f7419bc6a0))
* implement smooth train exit with fade-out through right tunnel ([0176694](01766944f0))
* improve game availability logic and messaging ([9a3fa93](9a3fa93e53))
* increase landmark emoji size for better visibility ([0bcd7a3](0bcd7a30d4))
* integrate remaining game sound effects ([600bc35](600bc35bc3))
* integrate sound effects into game flow (countdown, answers, performance) ([8c3a855](8c3a855239))
* make Steam Sprint infinite mode ([32c3a35](32c3a35eab))
* make SVG span full viewport width for sprint mode ([7488bb3](7488bb3803))
* preserve track and passengers during route transitions ([f2e7165](f2e71657dc))
* redesign passenger cards with vintage train station aesthetic ([651bc21](651bc21583))
* skip countdown for train mode (sprint) ([65dafc9](65dafc9215))
* skip intro screen and start directly at game setup ([4b6888a](4b6888af05))
* sync URL with selected game mode ([3920bba](3920bbad33))
* UI polish for Sprint mode (viewport, backgrounds, data attributes) ([90ad789](90ad789ff1))
* use CSS transitions for smooth fullscreen player selection collapse ([3189832](31898328a3))
* wire player configuration through nav component hierarchy ([edfdd81](edfdd81227))
### Performance Improvements
* optimize React rendering with memoization and consolidated effects ([93cb070](93cb070ca5))
Problem: When multiple passengers were waiting at the same station and a car
arrived, they could all try to board the same car in the same game loop
iteration. This happened because currentBoardedPassengers was calculated once
at the start of each frame and didn't reflect passengers who boarded during
that same iteration.
Solution: Track which cars are assigned within each frame using a Set. Before
assigning a passenger to a car, check both:
1. currentBoardedPassengers (passengers from previous frames)
2. carsAssignedThisFrame (passengers assigned this frame)
This ensures only one passenger boards per car per frame, preventing the bug
where passengers get left behind at stations because the game thinks they've
already boarded when they haven't.
Tests: Added 6 comprehensive boarding logic tests that successfully reproduce
and verify the fix for various edge cases including:
- Single passenger boarding
- Multiple passengers with enough cars
- Fast-moving train scenarios
- Passenger left behind scenarios
- Single car with multiple passengers
- All passengers boarding before train passes
All tests pass (6/6).
Problem: Route completion threshold was recalculated every frame based on
current passengers. When passengers were auto-regenerated mid-route (after
all delivered), the maxCars value could change, shifting the threshold and
potentially causing the train to never cross it properly.
Solution:
- Store route exit threshold in a ref when route starts
- Only update threshold at route completion for next route
- Threshold remains stable throughout entire route even when passengers regenerate
This ensures trains always complete routes when reaching the exit threshold,
preventing situations where players get stuck answering problems after train
has disappeared.
- Track displayRouteRef to identify which route's passengers are shown
- Only update passengers when train resets (< 0) OR same route and in middle of track (10-90%)
- Exclude start/end transition zones to prevent premature passenger updates
- Add comprehensive unit tests (11 tests) covering edge cases:
- New passengers at position 0 with old route
- Passengers regenerated at 5% position
- Rapid route increment with position oscillation
- Multiple rapid gameplay updates during same route
- All 44 hook tests pass
- Use bezier curve paths instead of polylines for rails to eliminate jaggies on sharp turns
- Sample rail waypoints densely (every 2px) with gentle control points (0.33)
- Use longer lookahead distance (8px) for smoother perpendicular angle calculation
- Implement seeded random number generator for consistent tracks per route
- Each route generates a unique but deterministic track layout
The rails were rendered as polylines with points sampled at each tie position
(every 12 pixels). On sharp turns, the inside rail (smaller radius) didn't
have enough points to maintain smoothness, creating visible jaggies.
Solution: Separate tie generation from rail point generation. Ties still use
12px spacing (looks good), but rails now sample at 3px intervals (4x denser).
This provides enough points for smooth curves even on the inside rail of
sharp turns, while keeping tie density reasonable.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The useSteamJourney hook was still using hard-coded MAX_CARS = 5 for:
- Checking which cars should board passengers
- Checking which cars should deliver passengers
- Calculating when entire train exits (route completion)
This caused the game to wait for a 5-car train to exit even when there were
fewer passengers, making players answer problems well after the last visible
car had exited.
Now dynamically calculates maxCars in the game loop using the same
calculateMaxConcurrentPassengers() utility, ensuring route completion
happens as soon as the actual last car exits.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Instead of hard-coding 5 train cars, now calculate the number of cars needed
based on the maximum number of passengers that will be on the train at any
given moment during the route.
For example: if 8 total passengers exist, but only 4 board at the start, all
get off halfway, then the remaining 4 board and ride to the end, we only need
4 cars (not 8).
Added calculateMaxConcurrentPassengers() utility that:
- Tracks boarding/delivery events by station position
- Sorts events to handle same-station boarding/delivery correctly
- Returns the peak concurrent passenger count
Updated SteamTrainJourney to calculate maxCars dynamically using this utility.
Updated all hooks and tests to use required maxCars/carSpacing parameters.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Train mode now starts immediately when clicking "Start Your Race!" button,
bypassing the 3-2-1-GO countdown. Other game modes (practice, survival) still
show the countdown as expected.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Previously, passengers would update as soon as all cars exited (at 97%+),
causing new passengers to briefly appear on the old track before it changed.
Now passengers only update when:
1. Train resets to start position (< 0) - track has changed, OR
2. Same passengers (same route gameplay updates like boarding/delivering)
This eliminates the ephemeral passengers showing up after the last car
fades out but before the new track is displayed.
Updated test to verify passengers don't change until train resets.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fix the actual bug: passengers at stations and in passenger list were
switching to the new route once the locomotive exited, but before the
last train car exited.
Root cause: RailroadTrackPath was using state.passengers directly instead
of displayPassengers, which has transition logic to delay the switch until
all cars have exited.
The previous commit added the transition logic to useTrackManagement, but
RailroadTrackPath wasn't using the displayPassengers output - it was still
reading state.passengers directly.
Changes:
- SteamTrainJourney: Pass displayPassengers to RailroadTrackPath instead
of state.passengers
Note: usePassengerAnimations correctly continues to use state.passengers
for immediate animation triggering. boardedPassengers and
nonDeliveredPassengers already use displayPassengers correctly.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fix bug where new route passengers would appear on train cars before
all cars from the previous route had exited through the tunnel.
The issue occurred because passengers were switched when trainPosition < 0
(locomotive exits), but train cars trail behind by up to 35% (5 cars × 7%
spacing). This caused new passengers to briefly appear on the old cars that
were still fading out (positions 65-97%).
Solution: Calculate the last car's position and only switch passengers when:
1. Train has reset to start position (trainPosition < 0), OR
2. All cars have fully faded out (lastCarPosition >= 97%)
Changes:
- useTrackManagement: Added maxCars and carSpacing parameters
- Updated passenger display logic to check lastCarPosition >= fadeOutEnd
- SteamTrainJourney: Pass maxCars and carSpacing from useTrainTransforms
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Extract game HUD elements (route info, time, pressure gauge, passenger list,
question display) into a separate GameHUD component for better maintainability.
- Created GameHUD.tsx (190 lines)
- Reduced SteamTrainJourney.tsx from 412 to 283 lines (-129 lines, 31.3%)
- Preserved all HUD elements and functionality exactly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Extract train rendering (locomotive, cars, passenger animations) into
a separate TrainAndCars component for better maintainability.
- Created TrainAndCars.tsx (217 lines)
- Reduced SteamTrainJourney.tsx from 546 to 412 lines (-134 lines, 24.5%)
- Preserved all train elements and animations exactly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Extract track rendering (ties, rails, path, landmarks, stations) into
a separate RailroadTrackPath component for better maintainability.
- Created RailroadTrackPath.tsx (192 lines)
- Reduced SteamTrainJourney.tsx from 687 to 546 lines (-141 lines, 20.5%)
- Preserved all track elements and passenger rendering exactly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Extract terrain background rendering (ground, mountains, tunnels) into
a separate TrainTerrainBackground component for better maintainability.
- Created TrainTerrainBackground.tsx (203 lines)
- Reduced SteamTrainJourney.tsx from 857 to 687 lines (-170 lines, 19.8%)
- Preserved all visual elements and functionality exactly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Create dedicated hook for track generation and positioning logic
- Move 115+ lines of track/landmark/passenger display management to useTrackManagement.ts
- Consolidates track generation, ties/rails, station positions, landmarks, and passenger display transitions
- Reduce SteamTrainJourney.tsx from 959 to 857 lines (102 lines removed)
- Preserve all functionality exactly - no behavioral changes
Benefits:
- Centralizes all track-related state management
- Handles route transition logic in one place
- Makes track generation logic easier to test
- Improves overall code organization
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Create dedicated hook for train position and car transform calculations
- Move 71 lines of transform logic to useTrainTransforms.ts
- Extract train position useEffect, trainCars useMemo, and locomotiveOpacity useMemo
- Reduce SteamTrainJourney.tsx from 1023 to 959 lines (64 lines removed)
- Preserve all functionality exactly - no behavioral changes
Benefits:
- Separates transform calculations from presentation logic
- Makes train physics calculations easier to test
- Improves code organization and readability
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove duplicate ref declaration that was causing compilation error
- Use existing previousPassengersRef initialized with state.passengers
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Store pending track data and only apply when train resets to beginning
- Preserve passenger list display until entire train exits
- Prevent visual jumps by keeping old route data visible during fade-out
- Track transitions now seamless: old track/passengers persist until trainPosition < 0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
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>