Add comprehensive exam requirements for each Kyu level displayed on
the left side of the abacus pane:
- Create kyuLevelDetails data file with English translations
- Display level details only for Kyu levels (hidden for Dan)
- Implement responsive font sizing based on abacus size
- Center abacus for Dan levels, right-align for Kyu
- Format details in clean, readable layout with bullet points
Details include:
- Addition/Subtraction requirements (rows, characters)
- Multiplication/Division requirements (digit counts, problem counts)
- Exam time limits and passing scores
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Change abacus display container from center to right-aligned layout for
better visual balance on the levels page.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Update animation speed progression to be more dramatic, reaching 10ms
(0.01 seconds) at 10th Dan instead of 50ms. Speed progression now runs
from 1st Dan to 10th Dan (not from Pre-1st Dan).
Speed progression:
- Kyu levels: 500ms (constant)
- Pre-1st Dan: 500ms
- 1st Dan: 500ms
- 10th Dan: 10ms
- Linear interpolation between 1st and 10th Dan
This creates an extremely fast blur effect at the highest mastery level,
better representing the extraordinary calculation speed expected at 10th Dan.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Increase abacus animation speed as Dan levels advance, creating a visual
representation of increasing mastery and speed. Animation interval changes
from 500ms at Kyu/Pre-1st Dan to 50ms at 10th Dan.
Changes:
- Kyu levels (10th-1st): constant 500ms animation interval
- Dan levels: linear interpolation from 500ms to 50ms
- Pre-1st Dan (index 10): 500ms
- 10th Dan (index 20): 50ms
- Effect now depends on currentIndex to update interval dynamically
- Add getAnimationInterval() helper for calculating speed
This creates a dramatic visual effect where the abacus becomes a blur of
movement at the highest mastery levels.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove horizontal padding (90px) from tick marks container to allow emoji
tick marks to spread across the full width of the slider. This provides
better visual distribution of level indicators.
Changes:
- Change px from '90px' to '0' on tick marks container
- Tick marks now use space-between across full slider width
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add automatic slider progression that advances one level every 3 seconds,
cycling back to the start when reaching the end. The auto-advance pauses
when the user's mouse is over the pane containing the slider and abacus,
allowing for manual exploration without interruption.
Changes:
- Add isPaneHovered state to track mouse position
- Add auto-advance effect with 3-second interval
- Pause auto-advance when isPaneHovered is true
- Add onMouseEnter/onMouseLeave handlers to pane container
- Cycle position back to 0 when reaching the last level
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Move level text further down (bottom: -80px) to prevent it from overlapping
with emoji characters. Previous positioning (-60px) was too close for Dan
level emojis, causing the text to cover the characters' chins.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add visual animation to the levels page abacus that simulates ongoing
calculations by randomly changing 1-3 adjacent columns every 0.5 seconds.
This creates a more dynamic, engaging visual that shows the abacus "working"
as users explore different skill levels.
Changes:
- Add animatedDigits state to track current digit values
- Initialize random digits when level changes
- Add interval effect to update 1-3 adjacent columns every 500ms
- Use animated digits instead of static pattern for AbacusReact display
- Adjacent column grouping simulates realistic calculation movements
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added mouse hover functionality to the slider so it responds as you move
your mouse across the track:
- Calculates hover position based on mouse X coordinate
- Updates slider value in real-time as you hover
- Tracks hover state with isHovering flag
- Slider thumb follows your mouse smoothly with CSS transitions
Now you can explore levels by simply hovering across the slider track,
in addition to clicking emoji tick marks or dragging the thumb.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added click handlers to emoji tick marks so you can click any emoji to jump to that level
- Added hover effects (opacity 0.6) and pointer cursor to tick marks
- Enabled pointer events on tick marks (parent has pointerEvents: 'none')
- Removed redundant "Drag or click the beads" instruction text
- Removed duplicated level info text below slider (info now only shows on slider thumb)
This simplifies the UI and makes the slider more interactive - you can now
click, drag, or hover over any emoji to explore different levels.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed slider transitions to be smooth but responsive:
- Balanced animation speeds (scale: tension 350/friction 45, emoji: 120ms)
- Added 0.3s CSS transition specifically for thumb position (left property)
- Removed complex React Spring state management that wasn't triggering re-renders
- Simplified to basic state management with CSS handling the smoothness
This gives a nice gliding effect when clicking between levels while
keeping the interface snappy and responsive.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Reduced animation timing across the board to make the slider feel snappier:
- Scale factor animation: increased tension (280→400), reduced friction (60→40)
- Emoji cross-fade: reduced duration from 150ms to 80ms
- Thumb hover: reduced transition from 0.2s to 0.1s with ease-out
This addresses user feedback that the slider felt sluggish.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
feat(levels): use StandaloneBead for slider thumb and decorative tick beads
fix(levels): make slider background transparent to prevent abacus clipping
Created StandaloneBead component that integrates with the abacus style context,
replacing hardcoded SVG diamonds with proper context-aware bead rendering.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replaced circular slider elements with proper diamond-shaped beads that
match the authentic abacus bead style:
**Slider Thumb (Drag Handle)**:
- Diamond SVG polygon matching AbacusReact bead geometry
- 28x28px size for easy grabbing
- Two-layer design: outer diamond + inner highlight for depth
- Black stroke (0.8px) matching abacus bead styling
- Color-coded: violet for Dan levels, green for Kyu levels
- Maintains grab/grabbing cursor states
**Decorative Tick Beads**:
- All 40 level markers now use diamond shapes instead of circles
- Sized 8px (inactive) to 14px (active)
- Same color scheme and styling as main beads
- Proper stroke colors matching active/inactive states
- Drop-shadow filter for active bead glow effect
This creates a cohesive visual language connecting the interactive
slider to the abacus display, making the page feel more integrated
and true to the abacus aesthetic.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replaced custom HTML input slider with Radix UI Slider for better
accessibility and consistency with the rest of the application.
Key changes:
- Integrated @radix-ui/react-slider for proper a11y support
- Maintained abacus-themed visual design with bead ticks
- Larger interactive area (h: '12' / 48px) for easier interaction
- Color-coded beads (green for Kyu, violet for Dan)
- Interactive thumb styled as a prominent bead with grab cursor
- Decorative beads for all 40 levels with pointer-events: none
- Smooth transitions and hover effects on thumb
- Removed custom hover handler in favor of Radix's built-in interaction
This provides a more robust and accessible slider while maintaining
the unique abacus aesthetic.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replaced standard slider with custom abacus-themed design:
- Added bead-like circular ticks for all 40 levels
- Color-coded beads (green for Kyu, violet for Dan)
- Active bead glows and scales up (16px) with shadow effect
- Inactive beads are semi-transparent (12px)
- Increased hit target with vertical padding (py: '6')
- Added horizontal "reckoning bar" as the track
- Smooth transitions on bead state changes
This creates a more forgiving hover/drag experience and prevents
confusion from minor cursor deviations while interacting.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed minimum scale factor from 1.5 to 1.2 for 30-column Dan abacuses
to prevent leftmost/rightmost columns from being clipped. Also reduced
container height from 900px to 700px to provide better visual balance
without excessive whitespace around the largest Kyu abacus.
Scale factor range is now 1.2 to 2.0, creating a 1.67x size difference.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed maximum scale factor from 3.0 to 2.0 for small Kyu abacuses.
This allows for a more compact fixed-height container while still
providing appropriate visual scaling across all levels.
Scale factor range is now 1.5 to 2.0, creating a 1.33x size difference
instead of the previous 2.0x difference.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed scale factor formula to use a constrained range (1.5 to 3.0)
instead of the previous unbounded formula that allowed much wider variation.
Previous formula: Math.min(2.5, 20 / digits)
- 2 columns (10 Kyu): 2.5
- 30 columns (Dan): 0.67
- Ratio: ~3.7x difference
New formula: Math.max(1.5, Math.min(3.0, 20 / digits))
- 2 columns (10 Kyu): 3.0
- 30 columns (Dan): 1.5
- Ratio: 2.0x difference
This reduces the excessive margin around Dan level abacuses while still
providing appropriate scaling for different column counts.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Increased the main level display container height from 700px to 900px
to provide more vertical space for the abacus display.
This prevents the top and bottom of the abacus from being clipped,
especially for levels with larger column counts.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Reverted the delayed column change approach (using displayedIndex state
and onRest callback) which was causing bugs. Went back to the simpler
direct approach where currentIndex immediately drives all changes.
Changes:
- Removed displayedIndex state and displayedLevel variable
- Removed onRest callback from React Spring configuration
- All UI elements now use currentLevel directly
- Kept overflow: 'hidden' on abacus container
The simpler approach provides better UX with immediate feedback while
React Spring still provides smooth scale transitions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed three layout issues with the levels page slider interaction:
1. Fixed height for level info section (160px with flexbox centering)
- Prevents slider from shifting vertically when switching between Kyu
and Dan levels (Dan levels have extra text for name + minScore)
- Keeps slider position stable during hover interaction
2. Changed abacus container overflow from 'auto' to 'visible'
- Prevents abacus from being clipped at container boundaries
- Allows full abacus display without scrollbars
3. Reduced spacing between sections for better layout balance
These changes ensure the slider stays perfectly under the mouse cursor
during hover interaction while the abacus smoothly animates.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Relocate the slider control from a separate container below the level
display to inside the level pane itself, positioned above the abacus.
Changes:
- Move slider markup into main level display pane
- Position between level info and abacus display
- Remove separate slider container that was below
- Adjust spacing for better visual hierarchy
Improves UX by keeping the control close to the content it affects.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fix slider hover interaction by making the entire level display pane
(including level info, abacus, and digit count) a fixed height. This
prevents the slider from moving when hovering over it.
Changes:
- Add fixed height of 700px on desktop (auto on mobile) to level pane
- Convert container to flexbox with column direction
- Make abacus display area flex: 1 to fill remaining space
- Slider now stays perfectly still under mouse during hover
This makes the hover interaction much more usable - you can now smoothly
move your mouse across the slider without it jumping away.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fix React Spring animation to only affect the abacus itself, not the
container with background and border. Also keep container height fixed.
Changes:
- Move animation from container div to inner wrapper around AbacusReact
- Add minHeight to container to prevent height changes
- Add alignItems: 'center' to vertically center the abacus
- Container background/border now stays fixed while abacus animates
This provides a cleaner, more polished animation where only the abacus
scales smoothly while the container remains stable.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add hover/touch support and smooth animations to the levels page slider
for an enhanced interactive experience.
Changes:
- Add hover/touch move handlers to slider for instant level preview
- Integrate React Spring for smooth scale transitions between levels
- Animate abacus container with smooth scale transformations
- Support both mouse and touch events for mobile compatibility
- Update UI text to mention hover, drag, and touch interactions
The slider now responds immediately to mouse/touch position, making it
easy to explore different levels by simply hovering over the slider.
React Spring provides smooth transitions when switching between levels
with different abacus sizes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add BigInt support to AbacusReact to handle 30-digit numbers without
precision loss (JavaScript's Number.MAX_SAFE_INTEGER is ~16 digits).
Changes:
- Update AbacusReact types to accept `value?: number | bigint`
- Modify useAbacusPlaceStates hook to use string-based digit parsing
- Add conditional BigInt arithmetic for >15 digits (maxPlaceValue > 14)
- Update levels page to pass BigInt for Dan levels (30 columns)
- Fix games page Date comparison (unrelated TypeScript error)
The implementation automatically detects when BigInt is needed based on
the number of digits, maintaining backward compatibility.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed abacus styling issues by matching homepage implementation:
- Use `fill` (not just `stroke`) for columnPosts and reckoningBar
- Changed from all zeros to interesting display value (123456...)
- Removed incorrect color customization causing mixed bead styles
- Now uses exact same darkStyles pattern as homepage MiniAbacus
Documentation update:
- Added MANDATORY section: "Read the Docs Before Customizing"
- Emphasized always reading packages/abacus-react/README.md
- Added references to homepage and storybook examples
- Included concrete example of correct darkStyles usage
- Key point: columnPosts and reckoningBar need `fill` property
This ensures columns and reckoning bar are now visible on dark backgrounds
and provides guidance to prevent similar issues in the future.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Improvements to the levels page abacus display:
- Added showNumbers={true} to show place value numbers
- Styled for dark background with light gray columns and reckoning bar
- Colored beads (blue heaven, green earth) for better visibility
- Dynamic scaling: large (2.5x) for Kyu levels, smaller for Dan levels
- Added horizontal overflow for very wide Dan level abacuses (30 columns)
- Formula: scaleFactor = Math.min(2.5, 20 / digits)
The abacus now fits gracefully at all levels and is clearly visible
on the dark page background.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed abacus not rendering by using the correct API:
- Removed non-existent useAbacusConfig import
- Changed from config object to direct props (value, columns, scaleFactor)
- Added scaleFactor=1.5 for better visibility
The abacus now properly displays with the appropriate number of columns
based on the selected kyu/dan level.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace static grid layout with an interactive range slider that allows
users to explore all 21 kyu and dan levels dynamically. The slider updates
a single AbacusReact component showing the appropriate number of columns
(2-30 digits) based on the selected rank.
Features:
- HTML range input slider from 10th Kyu to 10th Dan
- Dynamic abacus visualization using @soroban/abacus-react
- Real-time updates of level metadata (emoji, name, min score)
- Color-coded borders matching progression levels
- Reference markers for key ranks
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace carousel with actual horizontal slider showing all 21 ranks:
- Continuous scrollable view of 10 Kyu levels + 11 Dan levels
- Each level card displays:
- Level name, emoji, and metadata
- Visual abacus showing digit mastery (2-30 columns)
- Color-coded by progression (green→blue→violet→amber)
- Simplified abacus columns with proper visual structure
- Visual transition marker between Kyu and Dan sections
- Color legend for all four progression stages
- Fully mobile-responsive horizontal scrolling
Also add documentation note about using @soroban/abacus-react for all
abacus visualizations in the codebase.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace cluttered static grid of kyu level cards with an elegant horizontal slider.
Each level now features:
- Interactive slider with left/right navigation buttons
- Keyboard navigation support (arrow keys)
- Visual abacus showing digit mastery progression (2-10 columns)
- Clickable progress indicators
- Smooth transitions and hover effects
- Mobile-responsive design
The abacus visualizations provide an intuitive representation of the student's
progression through each level, showing the increasing number of digit columns
they master from 10th Kyu (2 digits) to 1st Kyu (10 digits).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive "About This Ranking System" section at the bottom of the
page explaining the Japan Abacus Federation ranking system and its purpose.
Features:
- Educational context about the JAF ranking system
- Explanation of progressive difficulty structure
- Clear disclaimer about educational vs certification purposes
- Professional styling matching the rest of the page
- Mobile-responsive padding and typography
Phase 6 complete: Final polish with educational context and disclaimers.
All phases complete! The /levels page now provides:
- Complete kyu level information (10th to 1st)
- Dan level ladder visualization (Pre-1st Dan to 10th Dan)
- Exam requirements and scoring details
- Educational context and disclaimers
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive Dan level section (Pre-1st Dan to 10th Dan) with score-based
ranking system. Display as vertical ladder showing progression from 90 to 290
points.
Features:
- Dan exam requirements box (30-digit problems, 3× 1st Kyu complexity)
- Ladder visualization with 11 Dan ranks
- Japanese names (Shodan, Nidan, etc.)
- Score thresholds for each rank
- Amber/gold color theme for master ranks
- Hover effects on each ladder rung
- Mobile-responsive design
Phase 4 complete: Full Dan ranking system with official JAF requirements.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive kyu level information from 10th to 1st Kyu with detailed
exam requirements. Display data in responsive grid of color-coded cards.
Data includes:
- Duration, pass thresholds, and point requirements
- Problem types with digit complexity for each operation
- Color-coded by difficulty (green → blue → violet)
- Hover effects and mobile-responsive layout
Phase 2 complete: All 10 kyu levels with official JAF requirements.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Transform the journey section into an interactive card that navigates to
/levels. Remove separate button in favor of whole-card clickability with
clear hover feedback.
Changes:
- Wrap entire card in Link component
- Add hover effects: lift, violet border, purple shadow
- Add subtle arrow indicator in top-right corner
- Update text: "Click to learn about the official Japanese ranking system"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Create new /levels page with hero section explaining the Japanese soroban
ranking system (10th Kyu to 10th Dan). Add navigation link from homepage
"Your Journey" section with violet-themed button styling.
Phase 1 complete: basic page structure and routing ready for content.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Increase emoji size from 3xl to 5xl for better visual presence.
Tighten spacing between emojis and labels by setting gap to 0 and
adding negative top margin (-2) to level labels.
Changes:
- Increase emoji fontSize from '3xl' to '5xl'
- Remove emoji bottom margin (mb: '0')
- Remove gap between emoji and labels (gap: '0')
- Add negative top margin to level labels (mt: '-2')
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed horizontal padding for all skill icon containers to ensure
consistent alignment across the "What You'll Learn" section.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Reduced vertical padding from token '5' to '4' in the "Read and set
numbers" card icon container for better visual balance.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace spread operator with direct conditional values for py and px
to ensure proper application with Panda CSS.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Use py: '5' and px: '3' instead of uniform padding to create visually
equal spacing on all sides of the animated abacus.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Double the padding from '3' to '5' for more generous vertical spacing
around the animated abacus.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Increase padding from '2' to '3' on the mini abacus icon container
to provide more vertical space between the abacus and the card border.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Set container height to 80px to prevent excess vertical space while
keeping the abacus fully visible and centered.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Use the correct pattern for AbacusReact:
- Call useAbacusConfig() without parameters for global config
- Pass individual props (value, columns, beadShape, styles) instead of config object
- No more timing hacks - the proper API doesn't have initialization issues
Fix display issues:
- Remove fixed height and overflow:hidden to prevent clipping
- Add dark theme styles for columnPosts and reckoningBar
- Reduce scale from 0.7 to 0.6 with proper transform origin
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fix "Cannot read properties of undefined (reading 'earthActive')" error by:
- Adding 500ms initialization delay before starting value cycling
- Starting with value 123 instead of 0 to show valid state immediately
- Splitting ready state management into separate useEffect
Also improve container sizing:
- Set explicit width (75px) and height (75px)
- Add transform scale(0.7) to fit better in card icon space
- Add overflow hidden to contain the component
- Increase cycle interval to 2.5s for smoother transitions
The error occurred because the AbacusReact component was trying to access
column states before they were fully initialized. The delay ensures proper
initialization before animation starts.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace static 🔢 emoji with a functional 3-column abacus that cycles through
random 3-digit numbers (0-999) every 2 seconds. Uses dark theme styling to
match the homepage aesthetic.
Changes:
- Create MiniAbacus component using AbacusReact
- Cycle through random numbers using useState/useEffect
- Constrain height to ~75px as specified
- Conditionally render in first skill card (i === 0)
- Use theme="dark" to match tutorial abacus styling
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace simple checklist with rich visual cards for each learning objective.
Each card now includes:
- Large prominent icon
- Title and description
- Example/demo text
- Hover effects
- Card-based layout with subtle borders
Makes the section more engaging and less text-heavy, better balanced with
the tutorial demo on the left.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Change tutorial tooltip z-index from 1000 to 50 so it scrolls under the
app nav bar (z-index 100) along with the abacus. This prevents the coaching
text from appearing layered above the nav while the abacus it points to is
hidden beneath it.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Restructure "Learn by Doing" section to display tutorial and "What You'll
Learn" side by side. Items now display vertically instead of in a 2x2 grid.
Changes:
- Tutorial positioned on left with flex: 1
- "What You'll Learn" section positioned on right
- Items arranged vertically using stack layout
- Increased container max-width from 900px to 1200px
- Responsive: stacks vertically on mobile, side-by-side on md+ screens
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add silentErrors prop to TutorialPlayer to allow suppressing "That's not
the highlighted bead" error messages. Used on homepage to provide a less
intrusive demo experience.
Changes:
- Add silentErrors prop to TutorialPlayerProps interface
- Conditionally skip error dispatch when silentErrors is true
- Pass silentErrors={true} from homepage TutorialPlayer
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed abacusColumns from 2 to 1 for the homepage tutorial demo.
Since the "Friends of 5" (2+3) demonstration only needs the ones place,
a single column is more focused and less distracting.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
**Changes:**
- Use Panda CSS token() function for dynamic color references instead of inline hex values
- Fix arrow positioning to be centered in gap between progression stages
- Document Panda CSS dynamic token usage pattern
**Color Token Fix:**
Panda CSS css() requires static values at build time. For dynamic token references,
use the token() function with inline styles:
- Import: token from styled-system/tokens
- Usage: style={{ color: token(stage.color) }}
- Token paths marked as const for TypeScript literal types
**Arrow Positioning Fix:**
Arrows between stages were positioned based on element width, not gap width.
Now properly centered using:
- left: 100% (position at right edge)
- marginLeft: 0.5rem (half of 1rem gap)
- transform: translate(-50%, -50%) (center on that point)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed progression level text from Panda CSS tokens to inline hex colors:
- 10 Kyu: #4ade80 (green)
- 5 Kyu: #60a5fa (blue)
- 1 Kyu: #a78bfa (purple)
- Dan: #fbbf24 (gold)
This ensures all text displays with proper colors regardless of CSS loading.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Switched from Panda CSS to direct inline styles with hex colors:
- Labels (Beginner/Intermediate/Advanced/Master): #e5e7eb (light gray)
- Subtitle: #e5e7eb (light gray)
- Arrows: #9ca3af (medium gray)
- Footer: #d1d5db (light gray)
This bypasses any CSS framework issues and applies colors directly.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove references to non-existent highlight.columnIndex property
- Remove references to removed currentStep.errorMessages property
- Use placeValue directly for highlight filtering and calculations
- Add generic error message for incorrect bead clicks
All changes maintain existing functionality while fixing type safety issues.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added position: 'relative' to parent containers to properly anchor the absolutely positioned arrow elements between progression levels. This ensures the arrows display correctly between stages.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Repositioned the learning objectives section to appear before the interactive tutorial for better visual hierarchy and user flow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added hideTooltip prop to TutorialPlayer to optionally hide guidance panels
- Enhanced coaching bar text for dark mode (brighter yellow with glow effect)
- Applied hideTooltip to homepage tutorial for cleaner presentation
- Updated dark mode header background for better integration
These changes are specific to the homepage dark theme instance while preserving default behavior for all other uses of the tutorial system.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added fill property to ColumnPostStyle and ReckoningBarStyle interfaces in abacus-react to enable high-contrast colors in dark mode. Updated TutorialPlayer to set fill colors for column posts (30% white) and reckoning bar (40% white) when in dark theme mode.
This improves visibility of the abacus frame elements in dark mode on the homepage tutorial.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed the dark mode styling to use the correct AbacusReact customStyles API:
Previous (incorrect):
- Used nested `frame` object that doesn't exist in the API
- `frame.column`, `frame.reckoningBar`, `frame.border`
Corrected (per AbacusReact.tsx interface):
- `columnPosts` - Global styling for all column dividers
- `reckoningBar` - Horizontal middle bar styling
Changes:
- Column dividers: rgba(255, 255, 255, 0.2) with 2px stroke
- Reckoning bar: rgba(255, 255, 255, 0.25) with 3px stroke
These properties are at the root level of customStyles, not nested
under a `frame` object. The styling will now properly apply to the
abacus frame elements in dark mode.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Enhanced the dark mode theme support for the tutorial player:
Coaching Bar:
- Updated instruction text color to use yellow.300 for dark mode instead of
hardcoded yellow.900
- Ensures coaching instructions are readable against dark backgrounds
Abacus Frame:
- Added custom frame styling for dark mode using customStyles prop
- Column dividers: rgba(255, 255, 255, 0.15) with 2px stroke
- Reckoning bar: rgba(255, 255, 255, 0.2) with 3px stroke
- Outer border: rgba(255, 255, 255, 0.15) with 2px stroke
- Provides subtle, elegant appearance that blends with dark theme
The frame styling is automatically applied when theme="dark" and does not
affect light mode or other tutorial instances.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed a critical bug where tooltip overlays were referencing invalid column
indices when using fewer than 5 columns. The issue occurred because column
index calculations assumed a 5-column layout (0-4), but when using
abacusColumns={2}, the valid indices should be 0-1.
Changes:
- Updated targetColumnIndex calculation to use (abacusColumns - 1) - placeValue
instead of hardcoded 4 - placeValue
- Fixed hasActiveBeadsToLeft logic to use abacusColumns for padding and
column index conversions
- All column index calculations now properly account for the actual number
of columns
This resolves the "Cannot read properties of undefined (reading 'heavenActive')"
error that occurred when using fewer than 5 columns on the homepage tutorial.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fix runtime error when abacusColumns < 5 by filtering all bead highlights
to only include columns that actually exist.
Changes:
- Filter highlightBeads prop to only include valid place values
- Filter stepBeadHighlights to only include valid place values
- Filter customStyles column highlights to only include valid columns
- Add abacusColumns to dependencies of relevant useMemo/useCallback
This prevents accessing undefined column states when rendering with
fewer than 5 columns (e.g., abacusColumns={2} for simple demos).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add `theme` and `abacusColumns` props to TutorialPlayer for better customization:
- theme: 'light' | 'dark' controls all color schemes
- abacusColumns: number controls abacus column count (default 5)
Updated homepage to use:
- abacusColumns={2} for simpler 2+3 demo
- theme="dark" for cohesive integration with dark page design
- Vertical layout with "What You'll Learn" below tutorial
Dark theme styling:
- Transparent dark backgrounds for all containers
- Muted text colors (gray.200-gray.400)
- Subtle borders and shadows
- Removed bright yellow/amber gradients
All changes maintain backward compatibility - defaults to light theme with 5 columns.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Apply visual improvements to homepage tutorial demo only (not tutorial system):
- Hide close (X) button in CoachBar - not needed on homepage
- Soften white backgrounds to light gray (#f9fafb)
- Mute text colors (h2 to gray.800, p to gray.600)
- Add transparency to guidance box (reduced opacity)
- Improve spacing and padding throughout
- Soften all shadows (reduced opacity)
- Mute amber/slate text colors for better dark theme integration
All changes scoped to .homepage-tutorial-demo wrapper via CSS overrides.
Tutorial system remains unchanged.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add `hideNavigation` prop to TutorialPlayer component that hides
the header and footer navigation controls, allowing the tutorial
content to be embedded cleanly without navigation chrome.
Perfect for single-step tutorial demos like the homepage.
Changes:
- Add hideNavigation prop to TutorialPlayerProps
- Wrap header section in conditional rendering
- Wrap navigation footer in conditional rendering
- Update homepage to use hideNavigation={true}
- Adjust minHeight when navigation is hidden
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Change tutorial container background from bright white to dark
semi-transparent black (rgba(0, 0, 0, 0.4)) with gray border to
match the homepage's dark aesthetic. Improves visual cohesion.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Change <p> tag to <div> tag to fix HTML nesting violation. The
<p> tag was containing <DecompositionWithReasons> which renders
a <div>, causing a hydration error. In HTML, <p> cannot contain
block-level elements like <div>.
Fixed: apps/web/src/components/tutorial/TutorialPlayer.tsx:1386
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replaced the simple FriendsOfFiveDemo component with the actual TutorialPlayer
from the existing tutorial system, showing the "Friends of 5" lesson (2+3=5).
Changes:
- Removed FriendsOfFiveDemo.tsx (redundant custom component)
- Updated homepage to use TutorialPlayer with filtered tutorial steps
- Added TUTORIAL_SYSTEM.md documentation explaining the full tutorial system
- Homepage now demonstrates the real learning system instead of a mock
The tutorial system includes:
- Step-by-step guidance with bead highlighting
- Real-time feedback and validation
- Multi-step instruction support
- Pedagogical decomposition
- Auto-advancement on correct completion
- Full tutorial editor at /tutorial-editor
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Redesigned the homepage to communicate the platform's educational
mission: providing a structured, self-directed path to soroban fluency
for students and families.
Key changes:
- New hero section with "Learn → Practice → Play → Master" journey
- Interactive Friends of 5 demo embedded directly on homepage
- Clear sections: Learn by Doing, Available Now, For Kids & Families
- Progression visualization (10 Kyu → Dan levels)
- Honest development status badge
- Removed aspirational language, focused on what's ready now
- Added comprehensive education roadmap documentation
The homepage now serves as both a visual introduction and working
demonstration of the learning system.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Documented the project's UI pattern requirements:
- Never use native browser dialogs (alert/confirm/prompt)
- Always use inline React-based confirmations
- Included pattern examples and migration checklist
- Referenced ModerationPanel.tsx for real examples
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
When ownership is transferred via the moderation modal, both the old
and new host now see the change immediately without requiring a page
reload.
Added missing socket event handler for 'ownership-transferred' event:
- Server already broadcasts event with updated members (route.ts:82)
- Client now listens and updates React Query cache in real-time
- All components using useRoomData() automatically re-render
- Both sessions see host status changes instantly
Fixes issue where ownership transfer required manual page refresh
to see updated host permissions (game selection, moderation access).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Only room hosts can select games. Added clear visual messaging:
- Host: "👑 You're the room host. Select a game to start playing."
- Non-host: "⏳ Waiting for [Host Name] to select a game..."
- Error: "⚠️ Only the room host can select a game. Ask [Host] to choose."
Changes:
- Detect host status via currentMember?.isCreator
- Disable game buttons for non-hosts (opacity 0.4, cursor not-allowed)
- Client-side permission check before API call
- Error messages auto-dismiss after 5 seconds
- Error handling in setRoomGame mutation callback
Fixes 403 errors when non-hosts attempt game selection.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Non-host room members were getting 403 errors when trying to select games.
Added proper UI restrictions and messaging to clarify only the host can
select games.
**Changes**:
1. **Host Detection**: Check if current user is room creator
- Find `currentMember` in `roomData.members`
- Check `isCreator` flag
2. **Visual Restrictions**:
- Game buttons disabled for non-hosts (opacity: 0.4, cursor: not-allowed)
- No hover effects when disabled
- Clear visual feedback
3. **Messaging**:
- **Host**: "👑 You're the room host. Select a game to start playing."
- **Non-host**: "⏳ Waiting for [Host Name] to select a game..."
- **Error**: "⚠️ Only the room host can select a game. Ask [Host] to choose."
4. **Error Handling**:
- Client-side check before API call
- Server error caught and displayed with host name
- Auto-dismiss after 5 seconds
**UX Flow**:
- Non-hosts see disabled games with clear "waiting for host" message
- If they somehow click, they get clear error message
- Host sees active games with confirmation they can select
Prevents confusing 403 errors and clarifies room permissions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit fixes two critical production issues:
1. **Flashcard generator dependencies** - Added all required dependencies to Dockerfile:
- Typst for PDF generation
- Python pip and setuptools
- Python packages (pyyaml, Pillow, imagehash)
- packages/core directory with generate.py script
2. **Deployment info modal** - Fixed git commit hash display on production:
- Modified generate-build-info.js to accept env vars as fallback when .git is unavailable
- Updated Dockerfile to accept GIT_* build arguments
- Updated GitHub Actions workflow to pass git information during Docker build
The deployment info modal (Ctrl+Shift+I) will now show the correct commit hash,
branch, and build time on production, matching the behavior on dev.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implement visual indicators and disabled states for spectator mode to
make it clear when users are watching vs playing.
**Provider.tsx**:
- Expose `localPlayerId` and `isSpectating` in context
- `isSpectating = !localPlayerId` (room members without active players)
**GameComponent.tsx**:
- Add spectator banner ("👀 Spectating [Player]'s game")
- Shows during playing/results phases for spectators
- Yellow gradient background with clear visual feedback
**PlayingPhase.tsx**:
- Disable all interactive elements for spectators:
- Available cards (opacity: 0.5, cursor: not-allowed)
- Position slots (opacity: 0.5, cursor: not-allowed)
- Insert buttons (disabled, visual feedback)
- Action buttons (Reveal, Check Solution, End Game)
- Block handlers early: `if (isSpectating) return`
- Remove hover effects when spectating
**User Experience**:
- Spectators see real-time game state updates
- All controls visually disabled (grayed out, not-allowed cursor)
- Cannot interact with game (click handlers blocked)
- Clear banner indicates spectator role
Completes spectator mode implementation per ARCADE_ARCHITECTURE.md.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Created comprehensive specification for optional spectator mode UI/UX
improvements to make spectator status clear and controls visually disabled.
**Five Enhancement Areas**:
1. **Context Exposure**
- Add `localPlayerId` and `isSpectating` to context
- Enable components to make spectator-aware UI decisions
2. **Spectator Indicator Banner**
- "👀 Spectating [Player]'s game" during playing/results
- "👤 Add a Player to Start" during setup
- Soft blue styling, non-intrusive
3. **Visual Disabled States**
- All buttons: opacity 0.5, cursor not-allowed
- All cards: opacity 0.6, pointer-events none
- Setup, playing, and results phases
4. **Spectator Mode Tests**
- Banner visibility tests
- Disabled control interaction tests
- State synchronization tests
- Context exposure tests
5. **Player Ownership Tests**
- Validate correct player can move
- Reject moves from non-active players
- Reject moves when user doesn't own player
- Reject spectator move attempts
**Includes**:
- Detailed code examples for all changes
- Visual mockups of UI states
- Implementation checklist (20 tasks)
- Success criteria
- Questions for user before implementation
Game is production-ready without these - enhancements are for improved UX.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Document spectator mode as a first-class feature in the arcade architecture.
**ARCADE_ARCHITECTURE.md**:
- Added "SPECTATOR" to core terminology
- Restructured sync modes to three patterns:
- Local Play (No Network Sync)
- Room-Based with Spectator Mode (RECOMMENDED)
- Pure Multiplayer (Room-Only)
- Added complete "Spectator Mode" section (297-603):
- Implementation patterns
- UI/UX considerations (indicators, disabled controls)
- When to use spectator mode
- Example scenarios (Family Game Night, Classroom)
- Server-side validation
- Testing requirements
- Migration path
**CARD_SORTING_AUDIT.md**:
- Updated to reflect room-based sync is CORRECT for spectator mode
- Changed from "CRITICAL ISSUE" to "CORRECT IMPLEMENTATION"
- Removed incorrect recommendation to use `roomId: undefined`
- Added enhancement recommendations (UI indicators, tests)
- Updated compliance checklist: 9/13 items passing
Card Sorting correctly enables spectator mode - room members without active
players can watch games in real-time, creating social/collaborative experiences.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added critical section to .claude/CLAUDE.md documenting that this
project uses Panda CSS, NOT Tailwind CSS.
This prevents future confusion and incorrect references to Tailwind
in code, comments, or documentation.
Includes:
- Framework identification and configuration locations
- Import patterns and token syntax
- Common mistakes to avoid with examples
- Reference to GAME_THEMES.md for arcade styling
This mistake was made earlier in this session when documenting the
game theme system, so documenting it now to prevent recurrence.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Corrected documentation and comments that incorrectly referenced
Tailwind CSS. This project uses Panda CSS for styling.
Fixed in:
- `/src/lib/arcade/game-themes.ts` - Updated all comments
- `.claude/GAME_THEMES.md` - Fixed documentation references
The color system uses Panda CSS's preset colors (blue.100, blue.200, etc.)
not Tailwind. The hex values are the same, but we should be accurate
about which framework we're using.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Create a centralized theme system to prevent inconsistent game card
styling. All games now use standard color presets instead of manually
specifying gradients.
## Changes
**New Theme System:**
- Created `/src/lib/arcade/game-themes.ts` with 10 standard themes
- All themes use Tailwind 100-200 colors for consistent pastel appearance
- Exported `getGameTheme()` helper and `GAME_THEMES` constants via SDK
- Added comprehensive documentation in `.claude/GAME_THEMES.md`
**Migrated All Games:**
- card-sorting: Uses `getGameTheme('teal')`
- memory-quiz: Uses `getGameTheme('blue')`
- matching: Uses `getGameTheme('purple')`
- complement-race: Uses `getGameTheme('blue')`
**Benefits:**
- ✅ Prevents future styling inconsistencies
- ✅ One-line theme setup instead of three properties
- ✅ TypeScript autocomplete for available themes
- ✅ Centralized maintenance - update all games by changing theme definition
- ✅ Clear documentation prevents mistakes
**Before:**
```typescript
color: 'teal',
gradient: 'linear-gradient(135deg, #99f6e4, #5eead4)', // Manual, error-prone
borderColor: 'teal.200',
```
**After:**
```typescript
...getGameTheme('teal') // Simple, consistent, discoverable
```
This fixes the root cause where card-sorting needed manual gradient
adjustments - now all games automatically get professional styling.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Change card sorting game to use the same blue gradient as Memory Lightning
and Speed Complement Race to ensure consistent appearance on game chooser.
Updated to: linear-gradient(135deg, #dbeafe, #bfdbfe) (blue-100 to blue-200)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Change card sorting game gradient from bright teal (teal-200 to teal-300)
to softer pastel teal (teal-100 to teal-200) to match the lighter gradient
style used by other arcade games (Memory Lightning, Matching Pairs).
Updated gradient: linear-gradient(135deg, #ccfbf1, #99f6e4)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed stats banner section as platform is still in development.
Also removed unused StatItem component.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed customStyles approach that wasn't working.
Added color: #1f2937 to container div - numerals inherit from parent.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
SVG foreign objects use CSS color property, not fill.
Changed numerals customStyle from fill to color for dark gray text.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added customStyles to make numerals dark gray (#1f2937) with bold weight
for good contrast on white background.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added useAbacusConfig() hook to get app-wide settings
- AbacusReact now respects beadShape, colorScheme, hideInactiveBeads from app config
- Removed "Click the beads to interact!" instruction text
- Simplified pane layout (just centered)
Now matches the styling/settings used throughout the rest of the app.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Changed background from dark to white for better contrast
- Removed duplicate number display (abacus has built-in numerals)
- Removed custom styles (defaults work well on light background)
- Updated instruction text color to gray.700 for readability
Abacus component isn't designed for dark mode yet, so light pane is simpler.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed critical issues based on storybook examples:
- Changed callback syntax: onValueChange prop directly (not in callbacks object)
- Added reckoningBar styling: golden stroke (#fbbf24, 4px width)
- Added columnPosts styling: purple stroke (#a78bfa, 3px width)
- Now structural elements are visible on dark background and interactive works
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Make card tiles larger to properly contain AbacusReact SVGs without overflow.
**Issue:**
Card tiles were too small (90px × 90px and 90px × 110px) to contain the
AbacusReact SVGs, causing abacuses to overflow their containers.
**Fix:**
- **Available cards**: Increased from 90px × 90px to 140px × 140px
- **Position slots**: Increased from 90px × 110px to 140px × 160px
**Result:**
Abacus SVGs now fit comfortably within their card containers without
overflowing, while maintaining the overflow: hidden constraint as a
safety measure.
src/arcade-games/card-sorting/components/PlayingPhase.tsx:283-284,419-420
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Make AbacusReact SVGs larger by allowing them to fill their containers.
**Issue:**
SVG containers were set to fixed small sizes (74px × 74px and 70px × 70px),
making the abacuses appear too small within their cards.
**Fix:**
- **Available cards**: Changed SVG container from 74px × 74px to 100% × 100%
to fill the entire 90px card (accounting for 8px padding)
- **Position slots**: Changed SVG container from 70px × 70px to flex: 1,
width: 100% to fill available space while leaving room for label
**Result:**
Abacuses now appear larger and fill their card containers better while
still being constrained by overflow: hidden to prevent breaking out.
src/arcade-games/card-sorting/components/PlayingPhase.tsx:314-329,456-473
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>