Compare commits

...

15 Commits

Author SHA1 Message Date
semantic-release-bot
60b3a788b3 chore(release): 4.57.8 [skip ci]
## [4.57.8](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.57.7...v4.57.8) (2025-10-21)

### Bug Fixes

* **homepage:** adjust responsive breakpoints to prevent skill card clipping ([62ff067](62ff067bb9))
2025-10-21 14:33:47 +00:00
Thomas Hallock
62ff067bb9 fix(homepage): adjust responsive breakpoints to prevent skill card clipping
Changed layout breakpoints from md (768px) to xl (1280px) to ensure:
- Skills section doesn't get clipped at medium viewport sizes
- Layout only switches to side-by-side when there's sufficient space
- Container min-width is responsive (100% below xl, 1400px at xl+)

This prevents the issue where content was overflowing at intermediate
viewport widths.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-21 09:32:33 -05:00
semantic-release-bot
3d774c8d82 chore(release): 4.57.7 [skip ci]
## [4.57.7](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.57.6...v4.57.7) (2025-10-21)

### Bug Fixes

* **homepage:** restructure layout to center 1400px wide demo section ([61403f2](61403f2f50))
* **homepage:** set min-width 1400px on container and remove max-width ([aa297d4](aa297d4ef7))
2025-10-21 03:07:11 +00:00
Thomas Hallock
61403f2f50 fix(homepage): restructure layout to center 1400px wide demo section
Moved "Learn by Doing" section outside the maxW:7xl container to allow
the demo div to be 1400px wide and properly centered with mx:auto.

Remaining content stays within the 7xl constrained container.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 22:06:02 -05:00
Thomas Hallock
aa297d4ef7 fix(homepage): set min-width 1400px on container and remove max-width
Added minW: '1400px' and removed maxW: '1200px' constraint to ensure
the "What You'll Learn" section is properly sized and centered.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 22:03:31 -05:00
semantic-release-bot
712d318e7c chore(release): 4.57.6 [skip ci]
## [4.57.6](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.57.5...v4.57.6) (2025-10-21)

### Bug Fixes

* **homepage:** increase skill cards container width to prevent title wrapping ([cd3eb61](cd3eb61cb5))
2025-10-21 02:36:21 +00:00
Thomas Hallock
cd3eb61cb5 fix(homepage): increase skill cards container width to prevent title wrapping
Increased container from 650px to 800px to ensure skill card titles
like "Friends techniques" don't wrap awkwardly across multiple lines.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 21:35:05 -05:00
semantic-release-bot
8871050990 chore(release): 4.57.5 [skip ci]
## [4.57.5](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.57.4...v4.57.5) (2025-10-21)

### Bug Fixes

* **homepage:** prevent text overflow in skill cards ([a6ac55b](a6ac55b7b1))
2025-10-21 02:23:27 +00:00
Thomas Hallock
a6ac55b7b1 fix(homepage): prevent text overflow in skill cards
Fixed text being cut off on the right side of skill cards by:
- Adding minWidth: '0' to text container to enable proper flex shrinking
- Adding flexWrap: 'wrap' to title/badge row for better wrapping behavior

This fixes the flexbox issue where text was overflowing the card boundaries.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 21:22:17 -05:00
semantic-release-bot
64e2464ec1 chore(release): 4.57.4 [skip ci]
## [4.57.4](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.57.3...v4.57.4) (2025-10-21)

### Bug Fixes

* **homepage:** align container width breakpoint with grid columns ([422bf3d](422bf3d968))
* **homepage:** make MiniAbacus fill container properly ([3b5d147](3b5d14765d))
* **homepage:** widen skill cards container to 650px ([bc1ad3a](bc1ad3a43a))
2025-10-21 00:30:13 +00:00
Thomas Hallock
422bf3d968 fix(homepage): align container width breakpoint with grid columns
Changed width breakpoint from md to lg to match when the grid switches
to 2 columns. This prevents overflow on medium-width screens where the
container was 650px wide but still showing 1-column layout.

Now:
- Below lg: 100% width, 1 column
- At lg+: 650px width, 2 columns

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 19:29:05 -05:00
Thomas Hallock
bc1ad3a43a fix(homepage): widen skill cards container to 650px
Increased the "What You'll Learn" container width from 420px to 650px
to give the 2-column grid of skill cards proper breathing room and
prevent cramped layouts.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 19:27:58 -05:00
Thomas Hallock
3b5d14765d fix(homepage): make MiniAbacus fill container properly
Fixed skill card abacus sizing by:
- Changing MiniAbacus to use width/height 100% instead of fixed 75px/80px
- Increased scale from 0.6 to 0.75 for better visibility
- Now properly fills the 120px/150px container set on the wrapper

This fixes the clipping issue by making the component hierarchy work correctly:
outer container (120px/150px) -> MiniAbacus (100%) -> scaled AbacusReact

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 19:26:45 -05:00
semantic-release-bot
9847f8f461 chore(release): 4.57.3 [skip ci]
## [4.57.3](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.57.2...v4.57.3) (2025-10-21)

### Bug Fixes

* **homepage:** increase abacus container width to 120px/150px ([57c212f](57c212f4f5))
2025-10-21 00:25:47 +00:00
Thomas Hallock
57c212f4f5 fix(homepage): increase abacus container width to 120px/150px
Increase abacus container width from 95px/110px to 120px (mobile) and
150px (desktop) to properly accommodate 3-column abacus visualizations
without clipping.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 19:24:37 -05:00
3 changed files with 242 additions and 191 deletions

View File

@@ -1,3 +1,48 @@
## [4.57.8](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.57.7...v4.57.8) (2025-10-21)
### Bug Fixes
* **homepage:** adjust responsive breakpoints to prevent skill card clipping ([62ff067](https://github.com/antialias/soroban-abacus-flashcards/commit/62ff067bb956b17a9b3569eadc2a32abd24c27b8))
## [4.57.7](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.57.6...v4.57.7) (2025-10-21)
### Bug Fixes
* **homepage:** restructure layout to center 1400px wide demo section ([61403f2](https://github.com/antialias/soroban-abacus-flashcards/commit/61403f2f506557b57716a298d4dc481d7853552f))
* **homepage:** set min-width 1400px on container and remove max-width ([aa297d4](https://github.com/antialias/soroban-abacus-flashcards/commit/aa297d4ef7559473a147934766bfa3868552f58d))
## [4.57.6](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.57.5...v4.57.6) (2025-10-21)
### Bug Fixes
* **homepage:** increase skill cards container width to prevent title wrapping ([cd3eb61](https://github.com/antialias/soroban-abacus-flashcards/commit/cd3eb61cb59e6faef37fbf609f37f7e2dc302e72))
## [4.57.5](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.57.4...v4.57.5) (2025-10-21)
### Bug Fixes
* **homepage:** prevent text overflow in skill cards ([a6ac55b](https://github.com/antialias/soroban-abacus-flashcards/commit/a6ac55b7b161e0dd33a4dd5acc0df647b2a513aa))
## [4.57.4](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.57.3...v4.57.4) (2025-10-21)
### Bug Fixes
* **homepage:** align container width breakpoint with grid columns ([422bf3d](https://github.com/antialias/soroban-abacus-flashcards/commit/422bf3d968b67e4683ac7ea7e487a84513f992f9))
* **homepage:** make MiniAbacus fill container properly ([3b5d147](https://github.com/antialias/soroban-abacus-flashcards/commit/3b5d14765dfb2d61a76f66ba3ae09695ce88bb6d))
* **homepage:** widen skill cards container to 650px ([bc1ad3a](https://github.com/antialias/soroban-abacus-flashcards/commit/bc1ad3a43a79570e1f9c61d5118d14ac4c201d71))
## [4.57.3](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.57.2...v4.57.3) (2025-10-21)
### Bug Fixes
* **homepage:** increase abacus container width to 120px/150px ([57c212f](https://github.com/antialias/soroban-abacus-flashcards/commit/57c212f4f5be591f712e1c5610e1f323e56e15dd))
## [4.57.2](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.57.1...v4.57.2) (2025-10-21)

View File

@@ -54,14 +54,14 @@ function MiniAbacus({
return (
<div
className={css({
width: '75px',
height: '80px',
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
})}
>
<div className={css({ transform: 'scale(0.6)', transformOrigin: 'center center' })}>
<div className={css({ transform: 'scale(0.75)', transformOrigin: 'center center' })}>
<AbacusReact
value={values[currentIndex] || 0}
columns={columns}
@@ -122,233 +122,239 @@ export default function HomePage() {
{/* Hero Section with Large Interactive Abacus */}
<HeroAbacus />
{/* Main content container */}
<div className={container({ maxW: '7xl', px: '4', py: '12' })}>
{/* Learn by Doing Section - with inline tutorial demo */}
<section className={stack({ gap: '8', mb: '16' })}>
<div className={css({ textAlign: 'center' })}>
<h2
className={css({
fontSize: { base: '2xl', md: '3xl' },
fontWeight: 'bold',
color: 'white',
mb: '2',
})}
>
Learn by Doing
</h2>
<p className={css({ color: 'gray.400', fontSize: 'md', maxW: '2xl', mx: 'auto' })}>
Interactive tutorials teach you step-by-step. Try this example right now:
</p>
</div>
{/* Live demo and learning objectives */}
<div
{/* Learn by Doing Section - with inline tutorial demo */}
<section className={stack({ gap: '8', mb: '16', px: '4', py: '12' })}>
<div className={css({ textAlign: 'center' })}>
<h2
className={css({
bg: 'rgba(0, 0, 0, 0.4)',
rounded: 'xl',
p: '8',
border: '1px solid',
borderColor: 'gray.700',
shadow: 'lg',
maxW: '1200px',
mx: 'auto',
fontSize: { base: '2xl', md: '3xl' },
fontWeight: 'bold',
color: 'white',
mb: '2',
})}
>
Learn by Doing
</h2>
<p className={css({ color: 'gray.400', fontSize: 'md', maxW: '2xl', mx: 'auto' })}>
Interactive tutorials teach you step-by-step. Try this example right now:
</p>
</div>
{/* Live demo and learning objectives */}
<div
className={css({
bg: 'rgba(0, 0, 0, 0.4)',
rounded: 'xl',
p: '8',
border: '1px solid',
borderColor: 'gray.700',
shadow: 'lg',
minW: { base: '100%', xl: '1400px' },
mx: 'auto',
})}
>
<div
className={css({
display: 'flex',
flexDirection: { base: 'column', xl: 'row' },
gap: '8',
alignItems: { base: 'center', xl: 'flex-start' },
})}
>
{/* Tutorial on the left */}
<div
className={css({
display: 'flex',
flexDirection: { base: 'column', md: 'row' },
gap: '8',
alignItems: { base: 'center', md: 'flex-start' },
flex: '1',
minW: { base: '100%', xl: '500px' },
maxW: { base: '100%', xl: '500px' },
})}
>
{/* Tutorial on the left */}
<div
className={css({
flex: '1',
minW: { base: '100%', md: '500px' },
maxW: { base: '100%', md: '500px' },
})}
>
<TutorialPlayer
key={selectedTutorial.id}
tutorial={selectedTutorial}
isDebugMode={false}
showDebugPanel={false}
hideNavigation={true}
hideTooltip={true}
silentErrors={true}
abacusColumns={1}
theme="dark"
/>
</div>
<TutorialPlayer
key={selectedTutorial.id}
tutorial={selectedTutorial}
isDebugMode={false}
showDebugPanel={false}
hideNavigation={true}
hideTooltip={true}
silentErrors={true}
abacusColumns={1}
theme="dark"
/>
</div>
{/* What you'll learn on the right */}
<div
{/* What you'll learn on the right */}
<div
className={css({
flex: '0 0 auto',
w: { base: '100%', lg: '800px' },
})}
>
<h3
className={css({
flex: '0 0 auto',
w: { base: '100%', md: '420px' },
fontSize: '2xl',
fontWeight: 'bold',
color: 'white',
mb: '6',
})}
>
<h3
className={css({
fontSize: '2xl',
fontWeight: 'bold',
color: 'white',
mb: '6',
})}
>
What You'll Learn
</h3>
<div className={grid({ columns: { base: 1, lg: 2 }, gap: '5' })}>
{[
{
title: '📖 Read and set numbers',
desc: 'Master abacus number representation from zero to thousands',
example: '0-9999',
badge: 'Foundation',
values: [0, 1, 2, 3, 4, 5, 10, 50, 100, 500, 999],
columns: 3,
},
{
title: '🤝 Friends techniques',
desc: 'Add and subtract using complement pairs and mental shortcuts',
example: '5 = 2+3',
badge: 'Core',
values: [2, 5, 3],
columns: 1,
},
{
title: ' Multiply & divide',
desc: 'Fluent multi-digit calculations with advanced techniques',
example: '12×34',
badge: 'Advanced',
values: [12, 24, 36, 48],
columns: 2,
},
{
title: '🧠 Mental calculation',
desc: 'Visualize and compute without the physical tool (Anzan)',
example: 'Speed math',
badge: 'Expert',
values: [7, 14, 21, 28, 35],
columns: 2,
},
].map((skill, i) => {
const isSelected = i === selectedSkillIndex
return (
<div
key={i}
onClick={() => setSelectedSkillIndex(i)}
className={css({
What You'll Learn
</h3>
<div className={grid({ columns: { base: 1, lg: 2 }, gap: '5' })}>
{[
{
title: '📖 Read and set numbers',
desc: 'Master abacus number representation from zero to thousands',
example: '0-9999',
badge: 'Foundation',
values: [0, 1, 2, 3, 4, 5, 10, 50, 100, 500, 999],
columns: 3,
},
{
title: '🤝 Friends techniques',
desc: 'Add and subtract using complement pairs and mental shortcuts',
example: '5 = 2+3',
badge: 'Core',
values: [2, 5, 3],
columns: 1,
},
{
title: ' Multiply & divide',
desc: 'Fluent multi-digit calculations with advanced techniques',
example: '12×34',
badge: 'Advanced',
values: [12, 24, 36, 48],
columns: 2,
},
{
title: '🧠 Mental calculation',
desc: 'Visualize and compute without the physical tool (Anzan)',
example: 'Speed math',
badge: 'Expert',
values: [7, 14, 21, 28, 35],
columns: 2,
},
].map((skill, i) => {
const isSelected = i === selectedSkillIndex
return (
<div
key={i}
onClick={() => setSelectedSkillIndex(i)}
className={css({
bg: isSelected
? 'linear-gradient(135deg, rgba(250, 204, 21, 0.15), rgba(250, 204, 21, 0.08))'
: 'linear-gradient(135deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.03))',
borderRadius: 'xl',
p: { base: '4', lg: '5' },
border: '1px solid',
borderColor: isSelected
? 'rgba(250, 204, 21, 0.4)'
: 'rgba(255, 255, 255, 0.15)',
boxShadow: isSelected
? '0 6px 16px rgba(250, 204, 21, 0.2)'
: '0 4px 12px rgba(0, 0, 0, 0.3)',
transition: 'all 0.2s',
cursor: 'pointer',
_hover: {
bg: isSelected
? 'linear-gradient(135deg, rgba(250, 204, 21, 0.15), rgba(250, 204, 21, 0.08))'
: 'linear-gradient(135deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.03))',
borderRadius: 'xl',
p: { base: '4', lg: '5' },
border: '1px solid',
? 'linear-gradient(135deg, rgba(250, 204, 21, 0.2), rgba(250, 204, 21, 0.12))'
: 'linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05))',
borderColor: isSelected
? 'rgba(250, 204, 21, 0.4)'
: 'rgba(255, 255, 255, 0.15)',
? 'rgba(250, 204, 21, 0.5)'
: 'rgba(255, 255, 255, 0.25)',
transform: 'translateY(-2px)',
boxShadow: isSelected
? '0 6px 16px rgba(250, 204, 21, 0.2)'
: '0 4px 12px rgba(0, 0, 0, 0.3)',
transition: 'all 0.2s',
cursor: 'pointer',
_hover: {
? '0 8px 20px rgba(250, 204, 21, 0.3)'
: '0 6px 16px rgba(0, 0, 0, 0.4)',
},
})}
>
<div className={hstack({ gap: '3', alignItems: 'flex-start' })}>
<div
className={css({
fontSize: '3xl',
width: { base: '120px', lg: '150px' },
minHeight: { base: '115px', lg: '140px' },
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
textAlign: 'center',
bg: isSelected
? 'linear-gradient(135deg, rgba(250, 204, 21, 0.2), rgba(250, 204, 21, 0.12))'
: 'linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05))',
borderColor: isSelected
? 'rgba(250, 204, 21, 0.5)'
: 'rgba(255, 255, 255, 0.25)',
transform: 'translateY(-2px)',
boxShadow: isSelected
? '0 8px 20px rgba(250, 204, 21, 0.3)'
: '0 6px 16px rgba(0, 0, 0, 0.4)',
},
})}
>
<div className={hstack({ gap: '3', alignItems: 'flex-start' })}>
? 'rgba(250, 204, 21, 0.15)'
: 'rgba(255, 255, 255, 0.1)',
borderRadius: 'lg',
})}
>
<MiniAbacus values={skill.values} columns={skill.columns} />
</div>
<div className={stack({ gap: '2', flex: '1', minWidth: '0' })}>
<div
className={css({
fontSize: '3xl',
width: { base: '95px', lg: '110px' },
minHeight: { base: '115px', lg: '140px' },
display: 'flex',
className={hstack({
gap: '2',
alignItems: 'center',
justifyContent: 'center',
textAlign: 'center',
bg: isSelected
? 'rgba(250, 204, 21, 0.15)'
: 'rgba(255, 255, 255, 0.1)',
borderRadius: 'lg',
flexWrap: 'wrap',
})}
>
<MiniAbacus values={skill.values} columns={skill.columns} />
</div>
<div className={stack({ gap: '2', flex: '1' })}>
<div className={hstack({ gap: '2', alignItems: 'center' })}>
<div
className={css({
color: 'white',
fontSize: 'md',
fontWeight: 'bold',
})}
>
{skill.title}
</div>
<div
className={css({
bg: 'rgba(250, 204, 21, 0.2)',
color: 'yellow.400',
fontSize: '2xs',
fontWeight: 'semibold',
px: '2',
py: '0.5',
borderRadius: 'md',
})}
>
{skill.badge}
</div>
</div>
<div
className={css({
color: 'gray.300',
fontSize: 'xs',
lineHeight: '1.5',
color: 'white',
fontSize: 'md',
fontWeight: 'bold',
})}
>
{skill.desc}
{skill.title}
</div>
<div
className={css({
bg: 'rgba(250, 204, 21, 0.2)',
color: 'yellow.400',
fontSize: 'xs',
fontFamily: 'mono',
fontSize: '2xs',
fontWeight: 'semibold',
mt: '1',
bg: 'rgba(250, 204, 21, 0.1)',
px: '2',
py: '1',
py: '0.5',
borderRadius: 'md',
w: 'fit-content',
})}
>
{skill.example}
{skill.badge}
</div>
</div>
<div
className={css({
color: 'gray.300',
fontSize: 'xs',
lineHeight: '1.5',
})}
>
{skill.desc}
</div>
<div
className={css({
color: 'yellow.400',
fontSize: 'xs',
fontFamily: 'mono',
fontWeight: 'semibold',
mt: '1',
bg: 'rgba(250, 204, 21, 0.1)',
px: '2',
py: '1',
borderRadius: 'md',
w: 'fit-content',
})}
>
{skill.example}
</div>
</div>
</div>
)
})}
</div>
</div>
)
})}
</div>
</div>
</div>
</section>
</div>
</section>
{/* Main content container */}
<div className={container({ maxW: '7xl', px: '4', py: '12' })}>
{/* Current Offerings Section */}
<section className={stack({ gap: '6', mb: '16' })}>
<div className={css({ textAlign: 'center' })}>

View File

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