Compare commits

...

10 Commits

Author SHA1 Message Date
semantic-release-bot
276f6f0744 chore(release): 4.30.0 [skip ci]
## [4.30.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.29.0...v4.30.0) (2025-10-20)

### Features

* **levels:** create true horizontal slider with abacus visualizations ([6d734f1](6d734f1d51))
2025-10-20 12:34:34 +00:00
Thomas Hallock
6d734f1d51 feat(levels): create true horizontal slider with abacus visualizations
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>
2025-10-20 07:33:36 -05:00
semantic-release-bot
03b9b1228b chore(release): 4.29.0 [skip ci]
## [4.29.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.28.0...v4.29.0) (2025-10-20)

### Features

* **levels:** replace kyu grid with interactive slider and abacus visualizations ([10978e8](10978e890b))
2025-10-20 12:30:16 +00:00
Thomas Hallock
10978e890b feat(levels): replace kyu grid with interactive slider and abacus visualizations
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>
2025-10-20 07:29:11 -05:00
semantic-release-bot
6d86281c63 chore(release): 4.28.0 [skip ci]
## [4.28.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.27.0...v4.28.0) (2025-10-20)

### Features

* **levels:** add informational footer section ([0b1bff7](0b1bff7eab))
2025-10-20 12:24:15 +00:00
Thomas Hallock
0b1bff7eab feat(levels): add informational footer section
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>
2025-10-20 07:23:10 -05:00
semantic-release-bot
f70ded30b9 chore(release): 4.27.0 [skip ci]
## [4.27.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.26.0...v4.27.0) (2025-10-20)

### Features

* **levels:** add Dan levels ladder visualization ([c18012c](c18012cb50))
2025-10-20 12:18:57 +00:00
Thomas Hallock
c18012cb50 feat(levels): add Dan levels ladder visualization
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>
2025-10-20 07:17:51 -05:00
semantic-release-bot
25a3356547 chore(release): 4.26.0 [skip ci]
## [4.26.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.25.1...v4.26.0) (2025-10-20)

### Features

* **levels:** add kyu level data and cards ([6463a3b](6463a3b2f6))
2025-10-20 12:15:15 +00:00
Thomas Hallock
6463a3b2f6 feat(levels): add kyu level data and cards
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>
2025-10-20 07:14:16 -05:00
4 changed files with 373 additions and 63 deletions

View File

@@ -1,3 +1,38 @@
## [4.30.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.29.0...v4.30.0) (2025-10-20)
### Features
* **levels:** create true horizontal slider with abacus visualizations ([6d734f1](https://github.com/antialias/soroban-abacus-flashcards/commit/6d734f1d51f5ba1367f55923e58bd977413d754e))
## [4.29.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.28.0...v4.29.0) (2025-10-20)
### Features
* **levels:** replace kyu grid with interactive slider and abacus visualizations ([10978e8](https://github.com/antialias/soroban-abacus-flashcards/commit/10978e890beee65dea78ddcce52cfe5315d58063))
## [4.28.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.27.0...v4.28.0) (2025-10-20)
### Features
* **levels:** add informational footer section ([0b1bff7](https://github.com/antialias/soroban-abacus-flashcards/commit/0b1bff7eab8f5da84ae309dbda336e168c2fe3fd))
## [4.27.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.26.0...v4.27.0) (2025-10-20)
### Features
* **levels:** add Dan levels ladder visualization ([c18012c](https://github.com/antialias/soroban-abacus-flashcards/commit/c18012cb505a1f2a86ebed7579b379a4d7d97f2c))
## [4.26.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.25.1...v4.26.0) (2025-10-20)
### Features
* **levels:** add kyu level data and cards ([6463a3b](https://github.com/antialias/soroban-abacus-flashcards/commit/6463a3b2f6371ebebac1048197fb44178997d2ef))
## [4.25.1](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.25.0...v4.25.1) (2025-10-20)

View File

@@ -121,6 +121,31 @@ className="bg-blue-200 border-gray-300 text-brand-600"
See `.claude/GAME_THEMES.md` for standardized color theme usage in arcade games.
## Abacus Visualizations
**CRITICAL: This project uses @soroban/abacus-react for all abacus visualizations.**
- All abacus displays MUST use components from `@soroban/abacus-react`
- Package location: `packages/abacus-react`
- Main components: `AbacusReact`, `useAbacusConfig`, `useAbacusDisplay`
- DO NOT create custom abacus visualizations
- DO NOT manually draw abacus columns, beads, or bars
**Common Mistakes to Avoid:**
- ❌ Don't create custom abacus components or SVGs
- ❌ Don't manually render abacus beads or columns
- ✅ Always use `AbacusReact` from `@soroban/abacus-react`
- ✅ Use `useAbacusConfig` for abacus configuration
- ✅ Use `useAbacusDisplay` for reading abacus state
**Example Usage:**
```typescript
import { AbacusReact, useAbacusConfig } from '@soroban/abacus-react'
const config = useAbacusConfig({ columns: 5 })
<AbacusReact config={config} initialNumber={123} />
```
## Known Issues
### @soroban/abacus-react TypeScript Module Resolution

View File

@@ -4,6 +4,183 @@ import { PageWithNav } from '@/components/PageWithNav'
import { css } from '../../../styled-system/css'
import { container, stack } from '../../../styled-system/patterns'
// Kyu level data from the Japan Abacus Federation
const kyuLevels = [
{ level: '10th Kyu', emoji: '🧒', color: 'green', digits: 2 },
{ level: '9th Kyu', emoji: '🧒', color: 'green', digits: 2 },
{ level: '8th Kyu', emoji: '🧒', color: 'green', digits: 3 },
{ level: '7th Kyu', emoji: '🧒', color: 'green', digits: 4 },
{ level: '6th Kyu', emoji: '🧑', color: 'blue', digits: 5 },
{ level: '5th Kyu', emoji: '🧑', color: 'blue', digits: 6 },
{ level: '4th Kyu', emoji: '🧑', color: 'blue', digits: 7 },
{ level: '3rd Kyu', emoji: '🧔', color: 'violet', digits: 8 },
{ level: '2nd Kyu', emoji: '🧔', color: 'violet', digits: 9 },
{ level: '1st Kyu', emoji: '🧔', color: 'violet', digits: 10 },
] as const
// Dan level data - all use 30-digit calculations
const danLevels = [
{ level: 'Pre-1st Dan', name: 'Jun-Shodan', minScore: 90, emoji: '🧙', digits: 30 },
{ level: '1st Dan', name: 'Shodan', minScore: 100, emoji: '🧙', digits: 30 },
{ level: '2nd Dan', name: 'Nidan', minScore: 120, emoji: '🧙‍♂️', digits: 30 },
{ level: '3rd Dan', name: 'Sandan', minScore: 140, emoji: '🧙‍♂️', digits: 30 },
{ level: '4th Dan', name: 'Yondan', minScore: 160, emoji: '🧙‍♀️', digits: 30 },
{ level: '5th Dan', name: 'Godan', minScore: 180, emoji: '🧙‍♀️', digits: 30 },
{ level: '6th Dan', name: 'Rokudan', minScore: 200, emoji: '🧝', digits: 30 },
{ level: '7th Dan', name: 'Nanadan', minScore: 220, emoji: '🧝', digits: 30 },
{ level: '8th Dan', name: 'Hachidan', minScore: 250, emoji: '🧝‍♂️', digits: 30 },
{ level: '9th Dan', name: 'Kudan', minScore: 270, emoji: '🧝‍♀️', digits: 30 },
{ level: '10th Dan', name: 'Judan', minScore: 290, emoji: '👑', digits: 30 },
] as const
// Compact abacus column component
function AbacusColumn({ color }: { color: string }) {
return (
<div
className={css({
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: '0.5',
w: '2',
})}
>
{/* Top bead */}
<div
className={css({
w: '2',
h: '2',
rounded: 'full',
bg:
color === 'green'
? 'green.500'
: color === 'blue'
? 'blue.500'
: color === 'violet'
? 'violet.500'
: 'amber.500',
opacity: 0.7,
})}
/>
{/* Divider */}
<div className={css({ w: '2', h: '0.5', bg: 'gray.600' })} />
{/* Bottom beads */}
{[0, 1, 2, 3].map((i) => (
<div
key={i}
className={css({
w: '2',
h: '2',
rounded: 'full',
bg:
color === 'green'
? 'green.500'
: color === 'blue'
? 'blue.500'
: color === 'violet'
? 'violet.500'
: 'amber.500',
opacity: 0.7,
})}
/>
))}
</div>
)
}
// Level card component for the slider
function LevelCard({
level,
emoji,
color,
digits,
subtitle,
}: {
level: string
emoji: string
color: string
digits: number
subtitle?: string
}) {
// Limit display for very high digit counts
const displayDigits = Math.min(digits, 15)
const showEllipsis = digits > 15
return (
<div
className={css({
minW: { base: '64', md: '80' },
bg: 'rgba(0, 0, 0, 0.4)',
border: '2px solid',
borderColor:
color === 'green'
? 'green.500'
: color === 'blue'
? 'blue.500'
: color === 'violet'
? 'violet.500'
: 'amber.500',
rounded: 'xl',
p: { base: '4', md: '6' },
transition: 'all 0.2s',
_hover: {
transform: 'translateY(-4px)',
boxShadow: '0 8px 16px rgba(0, 0, 0, 0.4)',
},
})}
>
{/* Header */}
<div className={css({ textAlign: 'center', mb: '4' })}>
<div className={css({ fontSize: { base: '3xl', md: '4xl' }, mb: '2' })}>{emoji}</div>
<div
className={css({
fontSize: { base: 'lg', md: 'xl' },
fontWeight: 'bold',
color:
color === 'green'
? 'green.400'
: color === 'blue'
? 'blue.400'
: color === 'violet'
? 'violet.400'
: 'amber.400',
mb: '1',
})}
>
{level}
</div>
{subtitle && <div className={css({ fontSize: 'sm', color: 'gray.400' })}>{subtitle}</div>}
</div>
{/* Abacus Visualization */}
<div
className={css({
display: 'flex',
gap: '1.5',
justifyContent: 'center',
alignItems: 'center',
p: '4',
bg: 'rgba(0, 0, 0, 0.3)',
rounded: 'lg',
minH: '32',
})}
>
{Array.from({ length: displayDigits }).map((_, i) => (
<AbacusColumn key={i} color={color} />
))}
{showEllipsis && (
<div className={css({ color: 'gray.500', fontSize: '2xl', px: '2' })}>...</div>
)}
</div>
{/* Digit count label */}
<div className={css({ textAlign: 'center', mt: '3', fontSize: 'sm', color: 'gray.400' })}>
{digits} {digits === 1 ? 'digit' : 'digits'}
</div>
</div>
)
}
export default function LevelsPage() {
return (
<PageWithNav navTitle="Kyu & Dan Levels" navEmoji="📊">
@@ -19,7 +196,6 @@ export default function LevelsPage() {
overflow: 'hidden',
})}
>
{/* Background pattern */}
<div
className={css({
position: 'absolute',
@@ -33,7 +209,6 @@ export default function LevelsPage() {
<div className={container({ maxW: '6xl', px: '4', position: 'relative' })}>
<div className={css({ textAlign: 'center', maxW: '5xl', mx: 'auto' })}>
{/* Main headline */}
<h1
className={css({
fontSize: { base: '3xl', md: '5xl', lg: '6xl' },
@@ -48,7 +223,6 @@ export default function LevelsPage() {
Understanding Kyu & Dan Levels
</h1>
{/* Subtitle */}
<p
className={css({
fontSize: { base: 'lg', md: 'xl' },
@@ -59,61 +233,15 @@ export default function LevelsPage() {
lineHeight: '1.6',
})}
>
Learn about the official Japanese soroban ranking system used by the Japan Abacus
Federation
Explore the progression from beginner to master
</p>
{/* Journey progression emojis */}
<div
className={css({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
gap: '4',
mb: '8',
flexWrap: 'wrap',
})}
>
{[
{ emoji: '🧒', label: '10 Kyu' },
{ emoji: '→', label: '', isArrow: true },
{ emoji: '🧑', label: '5 Kyu' },
{ emoji: '→', label: '', isArrow: true },
{ emoji: '🧔', label: '1 Kyu' },
{ emoji: '→', label: '', isArrow: true },
{ emoji: '🧙', label: 'Dan' },
].map((step, i) => (
<div
key={i}
className={css({
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: '1',
opacity: step.isArrow ? 0.5 : 1,
})}
>
<div
className={css({
fontSize: step.isArrow ? 'xl' : '4xl',
color: step.isArrow ? 'gray.500' : 'yellow.400',
})}
>
{step.emoji}
</div>
{step.label && (
<div className={css({ fontSize: 'xs', color: 'gray.400' })}>{step.label}</div>
)}
</div>
))}
</div>
</div>
</div>
</div>
{/* Main content container */}
<div className={container({ maxW: '7xl', px: '4', py: '12' })}>
{/* Placeholder for Phase 2 */}
{/* Journey Slider */}
<section className={stack({ gap: '8' })}>
<div className={css({ textAlign: 'center' })}>
<h2
@@ -124,30 +252,152 @@ export default function LevelsPage() {
mb: '4',
})}
>
Kyu Levels (10th to 1st)
The Complete Journey
</h2>
<p className={css({ color: 'gray.400', fontSize: 'md', mb: '8' })}>
Content coming in Phase 2...
Slide through all ranks from 10th Kyu to 10th Dan
</p>
</div>
{/* Placeholder card */}
{/* Horizontal Slider */}
<div
className={css({
w: '100%',
overflowX: 'auto',
overflowY: 'hidden',
pb: '4',
})}
>
<div className={css({ display: 'flex', gap: '4', pb: '2' })}>
{/* Kyu Levels */}
{kyuLevels.map((kyu, index) => (
<LevelCard
key={index}
level={kyu.level}
emoji={kyu.emoji}
color={kyu.color}
digits={kyu.digits}
/>
))}
{/* Transition marker */}
<div
className={css({
minW: '20',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: '4xl',
color: 'gray.500',
})}
>
</div>
{/* Dan Levels */}
{danLevels.map((dan, index) => (
<LevelCard
key={index}
level={dan.level}
emoji={dan.emoji}
color="amber"
digits={dan.digits}
subtitle={`${dan.minScore}+ pts`}
/>
))}
</div>
</div>
{/* Legend */}
<div
className={css({
display: 'flex',
flexWrap: 'wrap',
gap: '6',
justifyContent: 'center',
mt: '6',
p: '6',
bg: 'rgba(0, 0, 0, 0.3)',
rounded: 'lg',
})}
>
<div className={css({ display: 'flex', alignItems: 'center', gap: '2' })}>
<div className={css({ w: '4', h: '4', bg: 'green.500', rounded: 'sm' })} />
<span className={css({ fontSize: 'sm', color: 'gray.300' })}>
Beginner (10-7 Kyu)
</span>
</div>
<div className={css({ display: 'flex', alignItems: 'center', gap: '2' })}>
<div className={css({ w: '4', h: '4', bg: 'blue.500', rounded: 'sm' })} />
<span className={css({ fontSize: 'sm', color: 'gray.300' })}>
Intermediate (6-4 Kyu)
</span>
</div>
<div className={css({ display: 'flex', alignItems: 'center', gap: '2' })}>
<div className={css({ w: '4', h: '4', bg: 'violet.500', rounded: 'sm' })} />
<span className={css({ fontSize: 'sm', color: 'gray.300' })}>
Advanced (3-1 Kyu)
</span>
</div>
<div className={css({ display: 'flex', alignItems: 'center', gap: '2' })}>
<div className={css({ w: '4', h: '4', bg: 'amber.500', rounded: 'sm' })} />
<span className={css({ fontSize: 'sm', color: 'gray.300' })}>
Master (Dan ranks)
</span>
</div>
</div>
</section>
{/* Additional Information Section */}
<section className={stack({ gap: '8', mt: '16', pb: '12' })}>
<div
className={css({
bg: 'rgba(0, 0, 0, 0.4)',
border: '1px solid',
borderColor: 'gray.700',
rounded: 'xl',
p: '8',
textAlign: 'center',
p: { base: '6', md: '8' },
})}
>
<p className={css({ color: 'gray.300' })}>
Phase 1 Complete! Basic page structure and routing are ready for testing.
</p>
<p className={css({ color: 'gray.400', mt: '2', fontSize: 'sm' })}>
Test by visiting: <code>/levels</code>
</p>
<h3
className={css({
fontSize: { base: 'xl', md: '2xl' },
fontWeight: 'bold',
color: 'white',
mb: '4',
})}
>
About This Ranking System
</h3>
<div className={stack({ gap: '4' })}>
<p className={css({ color: 'gray.300', lineHeight: '1.6' })}>
This ranking system is based on the official examination structure used by the{' '}
<strong className={css({ color: 'white' })}>Japan Abacus Federation</strong>. It
represents a standardized progression from beginner (10th Kyu) to master level
(10th Dan), used internationally for soroban proficiency assessment.
</p>
<p className={css({ color: 'gray.300', lineHeight: '1.6' })}>
The system is designed to gradually increase in difficulty. Kyu levels progress
from 2-digit calculations at 10th Kyu to 10-digit calculations at 1st Kyu. Dan
levels all require mastery of 30-digit calculations, with ranks awarded based on
exam scores.
</p>
<div
className={css({
mt: '4',
pt: '4',
borderTop: '1px solid',
borderColor: 'gray.700',
fontSize: 'sm',
color: 'gray.400',
fontStyle: 'italic',
})}
>
Note: This page provides information about the official Japanese ranking system
for educational purposes. This application does not administer official
examinations or certifications.
</div>
</div>
</div>
</section>
</div>

View File

@@ -1,6 +1,6 @@
{
"name": "soroban-monorepo",
"version": "4.25.1",
"version": "4.30.0",
"private": true,
"description": "Beautiful Soroban Flashcard Generator - Monorepo",
"workspaces": [