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>
This commit is contained in:
@@ -2,7 +2,158 @@
|
||||
|
||||
import { PageWithNav } from '@/components/PageWithNav'
|
||||
import { css } from '../../../styled-system/css'
|
||||
import { container, stack } from '../../../styled-system/patterns'
|
||||
import { container, grid, stack } from '../../../styled-system/patterns'
|
||||
|
||||
// Kyu level data from the Japan Abacus Federation
|
||||
const kyuLevels = [
|
||||
{
|
||||
level: '10th Kyu',
|
||||
emoji: '🧒',
|
||||
color: 'green',
|
||||
duration: '20 min',
|
||||
passThreshold: '30%',
|
||||
points: '60/200',
|
||||
sections: [
|
||||
{ name: 'Addition', digits: '2-digit', problems: 10, points: 10 },
|
||||
{ name: 'Subtraction', digits: '2-digit', problems: 10, points: 10 },
|
||||
],
|
||||
notes: 'No division at this level',
|
||||
},
|
||||
{
|
||||
level: '9th Kyu',
|
||||
emoji: '🧒',
|
||||
color: 'green',
|
||||
duration: '20 min',
|
||||
passThreshold: '60%',
|
||||
points: '120/200',
|
||||
sections: [
|
||||
{ name: 'Addition', digits: '2-digit', problems: 10, points: 10 },
|
||||
{ name: 'Subtraction', digits: '2-digit', problems: 10, points: 10 },
|
||||
{ name: 'Multiplication', digits: '1×1', problems: 10, points: 10 },
|
||||
],
|
||||
notes: 'Introduces multiplication',
|
||||
},
|
||||
{
|
||||
level: '8th Kyu',
|
||||
emoji: '🧒',
|
||||
color: 'green',
|
||||
duration: '20 min',
|
||||
passThreshold: '60%',
|
||||
points: '120/200',
|
||||
sections: [
|
||||
{ name: 'Addition', digits: '3-digit', problems: 10, points: 10 },
|
||||
{ name: 'Subtraction', digits: '3-digit', problems: 10, points: 10 },
|
||||
{ name: 'Multiplication', digits: '2×1', problems: 10, points: 10 },
|
||||
{ name: 'Division', digits: '2÷1', problems: 10, points: 10 },
|
||||
],
|
||||
notes: 'Introduces division',
|
||||
},
|
||||
{
|
||||
level: '7th Kyu',
|
||||
emoji: '🧒',
|
||||
color: 'green',
|
||||
duration: '20 min',
|
||||
passThreshold: '60%',
|
||||
points: '120/200',
|
||||
sections: [
|
||||
{ name: 'Addition', digits: '4-digit', problems: 10, points: 10 },
|
||||
{ name: 'Subtraction', digits: '4-digit', problems: 10, points: 10 },
|
||||
{ name: 'Multiplication', digits: '3×1', problems: 10, points: 10 },
|
||||
{ name: 'Division', digits: '3÷1', problems: 10, points: 10 },
|
||||
],
|
||||
notes: 'All four operations',
|
||||
},
|
||||
{
|
||||
level: '6th Kyu',
|
||||
emoji: '🧑',
|
||||
color: 'blue',
|
||||
duration: '30 min',
|
||||
passThreshold: '70%',
|
||||
points: '210/300',
|
||||
sections: [
|
||||
{ name: 'Addition', digits: '5-digit', problems: 10, points: 10 },
|
||||
{ name: 'Subtraction', digits: '5-digit', problems: 10, points: 10 },
|
||||
{ name: 'Multiplication', digits: '4×2', problems: 10, points: 10 },
|
||||
{ name: 'Division', digits: '5÷2', problems: 10, points: 10 },
|
||||
],
|
||||
notes: 'Longer exam time',
|
||||
},
|
||||
{
|
||||
level: '5th Kyu',
|
||||
emoji: '🧑',
|
||||
color: 'blue',
|
||||
duration: '30 min',
|
||||
passThreshold: '70%',
|
||||
points: '210/300',
|
||||
sections: [
|
||||
{ name: 'Addition', digits: '6-digit', problems: 10, points: 10 },
|
||||
{ name: 'Subtraction', digits: '6-digit', problems: 10, points: 10 },
|
||||
{ name: 'Multiplication', digits: '5×2', problems: 10, points: 10 },
|
||||
{ name: 'Division', digits: '6÷2', problems: 10, points: 10 },
|
||||
],
|
||||
notes: 'Mid-level proficiency',
|
||||
},
|
||||
{
|
||||
level: '4th Kyu',
|
||||
emoji: '🧑',
|
||||
color: 'blue',
|
||||
duration: '30 min',
|
||||
passThreshold: '70%',
|
||||
points: '210/300',
|
||||
sections: [
|
||||
{ name: 'Addition', digits: '7-digit', problems: 10, points: 10 },
|
||||
{ name: 'Subtraction', digits: '7-digit', problems: 10, points: 10 },
|
||||
{ name: 'Multiplication', digits: '6×2', problems: 10, points: 10 },
|
||||
{ name: 'Division', digits: '7÷2', problems: 10, points: 10 },
|
||||
],
|
||||
notes: 'Advanced intermediate',
|
||||
},
|
||||
{
|
||||
level: '3rd Kyu',
|
||||
emoji: '🧔',
|
||||
color: 'violet',
|
||||
duration: '30 min',
|
||||
passThreshold: '80%',
|
||||
points: '240/300',
|
||||
sections: [
|
||||
{ name: 'Addition', digits: '8-digit', problems: 10, points: 10 },
|
||||
{ name: 'Subtraction', digits: '8-digit', problems: 10, points: 10 },
|
||||
{ name: 'Multiplication', digits: '7×2', problems: 10, points: 10 },
|
||||
{ name: 'Division', digits: '8÷2', problems: 10, points: 10 },
|
||||
],
|
||||
notes: 'Higher pass threshold (80%)',
|
||||
},
|
||||
{
|
||||
level: '2nd Kyu',
|
||||
emoji: '🧔',
|
||||
color: 'violet',
|
||||
duration: '30 min',
|
||||
passThreshold: '80%',
|
||||
points: '240/300',
|
||||
sections: [
|
||||
{ name: 'Addition', digits: '9-digit', problems: 10, points: 10 },
|
||||
{ name: 'Subtraction', digits: '9-digit', problems: 10, points: 10 },
|
||||
{ name: 'Multiplication', digits: '8×2', problems: 10, points: 10 },
|
||||
{ name: 'Division', digits: '9÷2', problems: 10, points: 10 },
|
||||
],
|
||||
notes: 'Near-mastery level',
|
||||
},
|
||||
{
|
||||
level: '1st Kyu',
|
||||
emoji: '🧔',
|
||||
color: 'violet',
|
||||
duration: '30 min',
|
||||
passThreshold: '80%',
|
||||
points: '240/300',
|
||||
sections: [
|
||||
{ name: 'Addition', digits: '10-digit', problems: 10, points: 10 },
|
||||
{ name: 'Subtraction', digits: '10-digit', problems: 10, points: 10 },
|
||||
{ name: 'Multiplication', digits: '9×2', problems: 10, points: 10 },
|
||||
{ name: 'Division', digits: '10÷2', problems: 10, points: 10 },
|
||||
],
|
||||
notes: 'Highest Kyu level before Dan',
|
||||
},
|
||||
] as const
|
||||
|
||||
export default function LevelsPage() {
|
||||
return (
|
||||
@@ -113,7 +264,7 @@ export default function LevelsPage() {
|
||||
|
||||
{/* Main content container */}
|
||||
<div className={container({ maxW: '7xl', px: '4', py: '12' })}>
|
||||
{/* Placeholder for Phase 2 */}
|
||||
{/* Kyu Levels Section */}
|
||||
<section className={stack({ gap: '8' })}>
|
||||
<div className={css({ textAlign: 'center' })}>
|
||||
<h2
|
||||
@@ -127,27 +278,142 @@ export default function LevelsPage() {
|
||||
Kyu Levels (10th to 1st)
|
||||
</h2>
|
||||
<p className={css({ color: 'gray.400', fontSize: 'md', mb: '8' })}>
|
||||
Content coming in Phase 2...
|
||||
Progress from beginner to advanced mastery
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Placeholder card */}
|
||||
<div
|
||||
className={css({
|
||||
bg: 'rgba(0, 0, 0, 0.4)',
|
||||
border: '1px solid',
|
||||
borderColor: 'gray.700',
|
||||
rounded: 'xl',
|
||||
p: '8',
|
||||
textAlign: 'center',
|
||||
})}
|
||||
>
|
||||
<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>
|
||||
{/* Kyu Level Cards */}
|
||||
<div className={grid({ columns: { base: 1, md: 2, lg: 3 }, gap: '6' })}>
|
||||
{kyuLevels.map((kyu, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={css({
|
||||
bg: 'rgba(0, 0, 0, 0.4)',
|
||||
border: '1px solid',
|
||||
borderColor:
|
||||
kyu.color === 'green'
|
||||
? 'green.700'
|
||||
: kyu.color === 'blue'
|
||||
? 'blue.700'
|
||||
: 'violet.700',
|
||||
rounded: 'xl',
|
||||
p: '6',
|
||||
transition: 'all 0.2s',
|
||||
_hover: {
|
||||
bg: 'rgba(0, 0, 0, 0.5)',
|
||||
borderColor:
|
||||
kyu.color === 'green'
|
||||
? 'green.500'
|
||||
: kyu.color === 'blue'
|
||||
? 'blue.500'
|
||||
: 'violet.500',
|
||||
transform: 'translateY(-2px)',
|
||||
},
|
||||
})}
|
||||
>
|
||||
{/* Card Header */}
|
||||
<div
|
||||
className={css({ display: 'flex', alignItems: 'center', gap: '3', mb: '4' })}
|
||||
>
|
||||
<div className={css({ fontSize: '3xl' })}>{kyu.emoji}</div>
|
||||
<div>
|
||||
<h3
|
||||
className={css({
|
||||
fontSize: 'xl',
|
||||
fontWeight: 'bold',
|
||||
color:
|
||||
kyu.color === 'green'
|
||||
? 'green.400'
|
||||
: kyu.color === 'blue'
|
||||
? 'blue.400'
|
||||
: 'violet.400',
|
||||
})}
|
||||
>
|
||||
{kyu.level}
|
||||
</h3>
|
||||
<p className={css({ fontSize: 'sm', color: 'gray.400' })}>{kyu.notes}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Exam Details */}
|
||||
<div className={stack({ gap: '3' })}>
|
||||
<div
|
||||
className={css({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
fontSize: 'sm',
|
||||
})}
|
||||
>
|
||||
<span className={css({ color: 'gray.400' })}>Duration:</span>
|
||||
<span className={css({ color: 'white', fontWeight: '500' })}>
|
||||
{kyu.duration}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className={css({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
fontSize: 'sm',
|
||||
})}
|
||||
>
|
||||
<span className={css({ color: 'gray.400' })}>Pass Threshold:</span>
|
||||
<span className={css({ color: 'amber.400', fontWeight: '600' })}>
|
||||
{kyu.passThreshold}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className={css({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
fontSize: 'sm',
|
||||
})}
|
||||
>
|
||||
<span className={css({ color: 'gray.400' })}>Points Needed:</span>
|
||||
<span className={css({ color: 'white', fontWeight: '500' })}>
|
||||
{kyu.points}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Sections */}
|
||||
<div
|
||||
className={css({
|
||||
mt: '4',
|
||||
pt: '4',
|
||||
borderTop: '1px solid',
|
||||
borderColor: 'gray.700',
|
||||
})}
|
||||
>
|
||||
<div
|
||||
className={css({
|
||||
fontSize: 'xs',
|
||||
color: 'gray.500',
|
||||
mb: '2',
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '0.05em',
|
||||
})}
|
||||
>
|
||||
Problem Types
|
||||
</div>
|
||||
{kyu.sections.map((section, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={css({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
fontSize: 'sm',
|
||||
py: '1',
|
||||
})}
|
||||
>
|
||||
<span className={css({ color: 'gray.300' })}>{section.name}</span>
|
||||
<span className={css({ color: 'gray.400', fontSize: 'xs' })}>
|
||||
{section.digits}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user